Add clean sources of nettle. 2.7.1 for DNSSEC.
[tomato.git] / release / src / router / nettle / examples / rsa-encrypt.c
blobc0caba32d632cb9aee83e44f81fabbf3ec87f20a
1 /* rsa-encrypt.c
3 */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2002 Niels Möller
8 *
9 * The nettle library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or (at your
12 * option) any later version.
14 * The nettle library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the nettle library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02111-1301, USA.
25 #if HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <assert.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #ifdef WIN32
36 #include <fcntl.h>
37 #endif
39 /* string.h must be included before gmp.h */
40 #include "bignum.h"
41 #include "buffer.h"
42 #include "macros.h"
43 #include "rsa.h"
44 #include "yarrow.h"
46 #include "io.h"
47 #include "rsa-session.h"
49 #include "getopt.h"
51 void
52 rsa_session_set_encrypt_key(struct rsa_session *ctx,
53 const struct rsa_session_info *key)
55 const uint8_t *aes_key = SESSION_AES_KEY(key);
56 const uint8_t *iv = SESSION_IV(key);
57 const uint8_t *hmac_key = SESSION_HMAC_KEY(key);
59 aes_set_encrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key);
60 CBC_SET_IV(&ctx->aes, iv);
61 hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key);
64 static int
65 write_uint32(FILE *f, uint32_t n)
67 uint8_t buffer[4];
68 WRITE_UINT32(buffer, n);
70 return write_string(f, sizeof(buffer), buffer);
73 static int
74 write_version(FILE *f)
76 return write_uint32(f, 1);
79 static int
80 write_bignum(FILE *f, mpz_t x)
82 unsigned size = nettle_mpz_sizeinbase_256_u(x);
83 uint8_t *p;
84 int res;
86 if (!write_uint32(f, size))
87 return 0;
89 p = xalloc(size);
90 nettle_mpz_get_str_256(size, p, x);
92 res = write_string(f, size, p);
93 free(p);
94 return res;
97 #define BLOCK_SIZE (AES_BLOCK_SIZE * 100)
99 static int
100 process_file(struct rsa_session *ctx,
101 FILE *in, FILE *out)
103 uint8_t buffer[BLOCK_SIZE + SHA1_DIGEST_SIZE];
105 for (;;)
107 size_t size = fread(buffer, 1, BLOCK_SIZE, in);
108 hmac_sha1_update(&ctx->hmac, size, buffer);
110 if (size < BLOCK_SIZE)
112 unsigned leftover;
113 unsigned padding;
115 if (ferror(in))
117 werror("Reading input failed: %s\n", strerror(errno));
118 return 0;
121 leftover = size % AES_BLOCK_SIZE;
122 padding = AES_BLOCK_SIZE - leftover;
124 assert (size + padding <= BLOCK_SIZE);
126 if (padding > 1)
127 yarrow256_random(&ctx->yarrow, padding - 1, buffer + size);
129 size += padding;
131 buffer[size - 1] = padding;
132 CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer);
134 assert (size + SHA1_DIGEST_SIZE <= sizeof(buffer));
136 hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + size);
137 size += SHA1_DIGEST_SIZE;
139 if (!write_string(out, size, buffer))
141 werror("Writing output failed: %s\n", strerror(errno));
142 return 0;
144 return 1;
147 CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer);
148 if (!write_string(out, size, buffer))
150 werror("Writing output failed: %s\n", strerror(errno));
151 return 0;
156 static void
157 usage (FILE *out)
159 fprintf (out, "Usage: rsa-encrypt [OPTIONS] PUBLIC-KEY < cleartext\n"
160 "Options:\n"
161 " -r, --random=FILE seed file for randomness generator\n"
162 " --help display this help\n");
166 main(int argc, char **argv)
168 struct rsa_session ctx;
169 struct rsa_session_info info;
171 struct rsa_public_key key;
172 mpz_t x;
174 int c;
175 const char *random_name = NULL;
177 enum { OPT_HELP = 300 };
179 static const struct option options[] =
181 /* Name, args, flag, val */
182 { "help", no_argument, NULL, OPT_HELP },
183 { "random", required_argument, NULL, 'r' },
184 { NULL, 0, NULL, 0}
187 while ( (c = getopt_long(argc, argv, "o:r:", options, NULL)) != -1)
188 switch (c)
190 case 'r':
191 random_name = optarg;
192 break;
194 case '?':
195 return EXIT_FAILURE;
197 case OPT_HELP:
198 usage(stdout);
199 return EXIT_SUCCESS;
200 default:
201 abort();
204 argv += optind;
205 argc -= optind;
207 if (argc != 1)
209 usage (stderr);
210 return EXIT_FAILURE;
213 rsa_public_key_init(&key);
215 if (!read_rsa_key(argv[0], &key, NULL))
217 werror("Invalid key\n");
218 return EXIT_FAILURE;
221 /* NOTE: No sources */
222 yarrow256_init(&ctx.yarrow, 0, NULL);
224 /* Read some data to seed the generator */
225 if (!simple_random(&ctx.yarrow, random_name))
227 werror("Initialization of randomness generator failed.\n");
228 return EXIT_FAILURE;
231 WRITE_UINT32(SESSION_VERSION(&info), RSA_VERSION);
233 yarrow256_random(&ctx.yarrow, sizeof(info.key) - 4, info.key + 4);
235 rsa_session_set_encrypt_key(&ctx, &info);
237 #ifdef WIN32
238 _setmode(0, O_BINARY);
239 _setmode(1, O_BINARY);
240 #endif
242 write_version(stdout);
244 mpz_init(x);
246 if (!rsa_encrypt(&key,
247 &ctx.yarrow, (nettle_random_func *) yarrow256_random,
248 sizeof(info.key), info.key,
251 werror("RSA encryption failed.\n");
252 return EXIT_FAILURE;
255 write_bignum(stdout, x);
257 mpz_clear (x);
259 if (!process_file(&ctx,
260 stdin, stdout))
261 return EXIT_FAILURE;
263 rsa_public_key_clear(&key);
265 return EXIT_SUCCESS;