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 */