Mercurial > dropbear
comparison rsa.c @ 188:c9483550701b
- refactored random mp_int generation and byte->mp_int code
- added RSA blinding
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 05 May 2005 03:58:21 +0000 |
parents | 0cfba3034be5 |
children | 65585699d980 |
comparison
equal
deleted
inserted
replaced
187:c44df7123b0a | 188:c9483550701b |
---|---|
36 #include "ssh.h" | 36 #include "ssh.h" |
37 #include "random.h" | 37 #include "random.h" |
38 | 38 |
39 #ifdef DROPBEAR_RSA | 39 #ifdef DROPBEAR_RSA |
40 | 40 |
41 static mp_int * rsa_pad_em(rsa_key * key, | 41 static void rsa_pad_em(rsa_key * key, |
42 const unsigned char * data, unsigned int len); | 42 const unsigned char * data, unsigned int len, |
43 mp_int * rsa_em); | |
43 | 44 |
44 /* Load a public rsa key from a buffer, initialising the values. | 45 /* Load a public rsa key from a buffer, initialising the values. |
45 * The key will have the same format as buf_put_rsa_key. | 46 * The key will have the same format as buf_put_rsa_key. |
46 * These should be freed with rsa_key_free. | 47 * These should be freed with rsa_key_free. |
47 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
201 unsigned int len) { | 202 unsigned int len) { |
202 | 203 |
203 unsigned int slen; | 204 unsigned int slen; |
204 DEF_MP_INT(rsa_s); | 205 DEF_MP_INT(rsa_s); |
205 DEF_MP_INT(rsa_mdash); | 206 DEF_MP_INT(rsa_mdash); |
206 mp_int *rsa_em = NULL; | 207 DEF_MP_INT(rsa_em); |
207 int ret = DROPBEAR_FAILURE; | 208 int ret = DROPBEAR_FAILURE; |
208 | 209 |
209 TRACE(("enter buf_rsa_verify")) | 210 TRACE(("enter buf_rsa_verify")) |
210 | 211 |
211 assert(key != NULL); | 212 assert(key != NULL); |
212 | 213 |
213 m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); | 214 m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); |
214 | 215 |
215 slen = buf_getint(buf); | 216 slen = buf_getint(buf); |
216 if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { | 217 if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { |
217 TRACE(("bad size")) | 218 TRACE(("bad size")) |
218 goto out; | 219 goto out; |
229 TRACE(("s > n-1")) | 230 TRACE(("s > n-1")) |
230 goto out; | 231 goto out; |
231 } | 232 } |
232 | 233 |
233 /* create the magic PKCS padded value */ | 234 /* create the magic PKCS padded value */ |
234 rsa_em = rsa_pad_em(key, data, len); | 235 rsa_pad_em(key, data, len, &rsa_em); |
235 | 236 |
236 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { | 237 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { |
237 TRACE(("failed exptmod rsa_s")) | 238 TRACE(("failed exptmod rsa_s")) |
238 goto out; | 239 goto out; |
239 } | 240 } |
240 | 241 |
241 if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { | 242 if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) { |
242 /* signature is valid */ | 243 /* signature is valid */ |
243 TRACE(("success!")) | 244 TRACE(("success!")) |
244 ret = DROPBEAR_SUCCESS; | 245 ret = DROPBEAR_SUCCESS; |
245 } | 246 } |
246 | 247 |
247 out: | 248 out: |
248 if (rsa_em) { | 249 mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); |
249 mp_clear(rsa_em); | |
250 m_free(rsa_em); | |
251 } | |
252 mp_clear_multi(&rsa_mdash, &rsa_s, NULL); | |
253 TRACE(("leave buf_rsa_verify: ret %d", ret)) | 250 TRACE(("leave buf_rsa_verify: ret %d", ret)) |
254 return ret; | 251 return ret; |
255 | 252 } |
256 } | 253 |
257 #endif /* DROPBEAR_SIGNKEY_VERIFY */ | 254 #endif /* DROPBEAR_SIGNKEY_VERIFY */ |
258 | 255 |
259 /* Sign the data presented with key, writing the signature contents | 256 /* Sign the data presented with key, writing the signature contents |
260 * to the buffer */ | 257 * to the buffer */ |
261 void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, | 258 void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, |
262 unsigned int len) { | 259 unsigned int len) { |
263 | 260 |
264 unsigned int nsize, ssize; | 261 unsigned int nsize, ssize; |
265 unsigned int i; | 262 unsigned int i; |
266 DEF_MP_INT(rsa_s); | 263 DEF_MP_INT(rsa_s); |
267 mp_int *rsa_em = NULL; | 264 DEF_MP_INT(rsa_tmp1); |
265 DEF_MP_INT(rsa_tmp2); | |
266 DEF_MP_INT(rsa_tmp3); | |
267 unsigned char *tmpbuf; | |
268 | 268 |
269 TRACE(("enter buf_put_rsa_sign")) | 269 TRACE(("enter buf_put_rsa_sign")) |
270 assert(key != NULL); | 270 assert(key != NULL); |
271 | 271 |
272 rsa_em = rsa_pad_em(key, data, len); | 272 m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); |
273 | 273 |
274 m_mp_init(&rsa_s); | 274 rsa_pad_em(key, data, len, &rsa_tmp1); |
275 | 275 |
276 /* the actual signing of the padded data */ | 276 /* the actual signing of the padded data */ |
277 | |
278 #define RSA_BLINDING | |
279 #ifdef RSA_BLINDING | |
280 | |
281 /* With blinding, s = (r^(-1))((em)*r^e)^d mod n */ | |
282 | |
283 /* generate the r blinding value */ | |
284 /* rsa_tmp2 is r */ | |
285 gen_random_mpint(key->n, &rsa_tmp2); | |
286 | |
287 /* rsa_tmp1 is em */ | |
288 /* em' = em * r^e mod n */ | |
289 | |
290 mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/ | |
291 mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3); | |
292 mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2); | |
293 | |
294 /* rsa_tmp2 is em' */ | |
295 /* s' = (em')^d mod n */ | |
296 mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1); | |
297 | |
298 /* rsa_tmp1 is s' */ | |
299 /* rsa_tmp3 is r^(-1) mod n */ | |
300 /* s = (s')r^(-1) mod n */ | |
301 mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s); | |
302 | |
303 #else | |
304 | |
277 /* s = em^d mod n */ | 305 /* s = em^d mod n */ |
278 if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) { | 306 /* rsa_tmp1 is em */ |
307 if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) { | |
279 dropbear_exit("rsa error"); | 308 dropbear_exit("rsa error"); |
280 } | 309 } |
281 mp_clear(rsa_em); | 310 |
282 m_free(rsa_em); | 311 #endif /* RSA_BLINDING */ |
312 | |
313 mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); | |
283 | 314 |
284 /* create the signature to return */ | 315 /* create the signature to return */ |
285 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); | 316 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); |
286 | 317 |
287 nsize = mp_unsigned_bin_size(key->n); | 318 nsize = mp_unsigned_bin_size(key->n); |
316 * where FF is repeated enough times to make EM one byte | 347 * where FF is repeated enough times to make EM one byte |
317 * shorter than the size of key->n | 348 * shorter than the size of key->n |
318 * | 349 * |
319 * prefix is the ASN1 designator prefix, | 350 * prefix is the ASN1 designator prefix, |
320 * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 | 351 * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 |
352 * | |
353 * rsa_em must be a pointer to an initialised mp_int. | |
321 */ | 354 */ |
322 static mp_int * rsa_pad_em(rsa_key * key, | 355 static void rsa_pad_em(rsa_key * key, |
323 const unsigned char * data, unsigned int len) { | 356 const unsigned char * data, unsigned int len, |
357 mp_int * rsa_em) { | |
324 | 358 |
325 /* ASN1 designator (including the 0x00 preceding) */ | 359 /* ASN1 designator (including the 0x00 preceding) */ |
326 const char rsa_asn1_magic[] = | 360 const char rsa_asn1_magic[] = |
327 {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, | 361 {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, |
328 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; | 362 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; |
329 #define RSA_ASN1_MAGIC_LEN 16 | 363 #define RSA_ASN1_MAGIC_LEN 16 |
330 buffer * rsa_EM = NULL; | 364 buffer * rsa_EM = NULL; |
331 hash_state hs; | 365 hash_state hs; |
332 unsigned int nsize; | 366 unsigned int nsize; |
333 mp_int * rsa_em = NULL; | |
334 | 367 |
335 assert(key != NULL); | 368 assert(key != NULL); |
336 assert(data != NULL); | 369 assert(data != NULL); |
337 nsize = mp_unsigned_bin_size(key->n); | 370 nsize = mp_unsigned_bin_size(key->n); |
338 | 371 |
356 | 389 |
357 assert(rsa_EM->pos == rsa_EM->size); | 390 assert(rsa_EM->pos == rsa_EM->size); |
358 | 391 |
359 /* Create the mp_int from the encoded bytes */ | 392 /* Create the mp_int from the encoded bytes */ |
360 buf_setpos(rsa_EM, 0); | 393 buf_setpos(rsa_EM, 0); |
361 rsa_em = (mp_int*)m_malloc(sizeof(mp_int)); | 394 bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), |
362 m_mp_init(rsa_em); | 395 rsa_EM->size); |
363 if (mp_read_unsigned_bin(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), | |
364 rsa_EM->size) != MP_OKAY) { | |
365 dropbear_exit("rsa error"); | |
366 } | |
367 buf_free(rsa_EM); | 396 buf_free(rsa_EM); |
368 | |
369 return rsa_em; | |
370 | |
371 } | 397 } |
372 | 398 |
373 #endif /* DROPBEAR_RSA */ | 399 #endif /* DROPBEAR_RSA */ |