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
);