3 Copyright (C) 2002 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
20 or both in parallel, as here.
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
46 /* string.h must be included before gmp.h */
54 #include "rsa-session.h"
59 rsa_session_set_encrypt_key(struct rsa_session *ctx,
60 const struct rsa_session_info *key)
62 const uint8_t *aes_key = SESSION_AES_KEY(key);
63 const uint8_t *iv = SESSION_IV(key);
64 const uint8_t *hmac_key = SESSION_HMAC_KEY(key);
66 aes256_set_encrypt_key(&ctx->aes.ctx, aes_key);
67 CBC_SET_IV(&ctx->aes, iv);
68 hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key);
72 write_uint32(FILE *f, uint32_t n)
75 WRITE_UINT32(buffer, n);
77 return write_data(f, sizeof(buffer), buffer);
81 write_version(FILE *f)
83 return write_uint32(f, 1);
87 write_bignum(FILE *f, mpz_t x)
89 unsigned size = nettle_mpz_sizeinbase_256_u(x);
93 if (!write_uint32(f, size))
97 nettle_mpz_get_str_256(size, p, x);
99 res = write_data(f, size, p);
104 #define BLOCK_SIZE (AES_BLOCK_SIZE * 100)
107 process_file(struct rsa_session *ctx,
110 uint8_t buffer[BLOCK_SIZE + SHA1_DIGEST_SIZE];
114 size_t size = fread(buffer, 1, BLOCK_SIZE, in);
115 hmac_sha1_update(&ctx->hmac, size, buffer);
117 if (size < BLOCK_SIZE)
124 werror("Reading input failed: %s\n", strerror(errno));
128 leftover = size % AES_BLOCK_SIZE;
129 padding = AES_BLOCK_SIZE - leftover;
131 assert (size + padding <= BLOCK_SIZE);
134 yarrow256_random(&ctx->yarrow, padding - 1, buffer + size);
138 buffer[size - 1] = padding;
139 CBC_ENCRYPT(&ctx->aes, aes256_encrypt, size, buffer, buffer);
141 assert (size + SHA1_DIGEST_SIZE <= sizeof(buffer));
143 hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + size);
144 size += SHA1_DIGEST_SIZE;
146 if (!write_data(out, size, buffer))
148 werror("Writing output failed: %s\n", strerror(errno));
154 CBC_ENCRYPT(&ctx->aes, aes256_encrypt, size, buffer, buffer);
155 if (!write_data(out, size, buffer))
157 werror("Writing output failed: %s\n", strerror(errno));
166 fprintf (out, "Usage: rsa-encrypt [OPTIONS] PUBLIC-KEY < cleartext\n"
168 " -r, --random=FILE seed file for randomness generator\n"
169 " --help display this help\n");
173 main(int argc, char **argv)
175 struct rsa_session ctx;
176 struct rsa_session_info info;
178 struct rsa_public_key key;
182 const char *random_name = NULL;
184 enum { OPT_HELP = 300 };
186 static const struct option options[] =
188 /* Name, args, flag, val */
189 { "help", no_argument, NULL, OPT_HELP },
190 { "random", required_argument, NULL, 'r' },
194 while ( (c = getopt_long(argc, argv, "o:r:", options, NULL)) != -1)
198 random_name = optarg;
220 rsa_public_key_init(&key);
222 if (!read_rsa_key(argv[0], &key, NULL))
224 werror("Invalid key\n");
228 /* NOTE: No sources */
229 yarrow256_init(&ctx.yarrow, 0, NULL);
231 /* Read some data to seed the generator */
232 if (!simple_random(&ctx.yarrow, random_name))
234 werror("Initialization of randomness generator failed.\n");
238 WRITE_UINT32(SESSION_VERSION(&info), RSA_VERSION);
240 yarrow256_random(&ctx.yarrow, sizeof(info.key) - 4, info.key + 4);
242 rsa_session_set_encrypt_key(&ctx, &info);
245 _setmode(0, O_BINARY);
246 _setmode(1, O_BINARY);
249 write_version(stdout);
253 if (!rsa_encrypt(&key,
254 &ctx.yarrow, (nettle_random_func *) yarrow256_random,
255 sizeof(info.key), info.key,
258 werror("RSA encryption failed.\n");
262 write_bignum(stdout, x);
266 if (!process_file(&ctx,
270 rsa_public_key_clear(&key);