5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2002 Niels Möller
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,
39 /* string.h must be included before gmp.h */
47 #include "rsa-session.h"
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);
65 write_uint32(FILE *f, uint32_t n)
68 WRITE_UINT32(buffer, n);
70 return write_string(f, sizeof(buffer), buffer);
74 write_version(FILE *f)
76 return write_uint32(f, 1);
80 write_bignum(FILE *f, mpz_t x)
82 unsigned size = nettle_mpz_sizeinbase_256_u(x);
86 if (!write_uint32(f, size))
90 nettle_mpz_get_str_256(size, p, x);
92 res = write_string(f, size, p);
97 #define BLOCK_SIZE (AES_BLOCK_SIZE * 100)
100 process_file(struct rsa_session *ctx,
103 uint8_t buffer[BLOCK_SIZE + SHA1_DIGEST_SIZE];
107 size_t size = fread(buffer, 1, BLOCK_SIZE, in);
108 hmac_sha1_update(&ctx->hmac, size, buffer);
110 if (size < BLOCK_SIZE)
117 werror("Reading input failed: %s\n", strerror(errno));
121 leftover = size % AES_BLOCK_SIZE;
122 padding = AES_BLOCK_SIZE - leftover;
124 assert (size + padding <= BLOCK_SIZE);
127 yarrow256_random(&ctx->yarrow, padding - 1, buffer + size);
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));
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));
159 fprintf (out, "Usage: rsa-encrypt [OPTIONS] PUBLIC-KEY < cleartext\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;
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' },
187 while ( (c = getopt_long(argc, argv, "o:r:", options, NULL)) != -1)
191 random_name = optarg;
213 rsa_public_key_init(&key);
215 if (!read_rsa_key(argv[0], &key, NULL))
217 werror("Invalid key\n");
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");
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);
238 _setmode(0, O_BINARY);
239 _setmode(1, O_BINARY);
242 write_version(stdout);
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");
255 write_bignum(stdout, x);
259 if (!process_file(&ctx,
263 rsa_public_key_clear(&key);