comparison rsa.c @ 219:654bc8327787

merge of 9522146cb07d4576f161fc4567c2c2fbd6f61fbb and b11630c15bc4d0649dba51c3572cac6f44e0ab0e
author Matt Johnston <matt@ucc.asn.au>
date Fri, 08 Jul 2005 13:28:03 +0000
parents ea9277442ef2
children c5d3ef11155f
comparison
equal deleted inserted replaced
218:3ee0c2f85e1e 219:654bc8327787
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 #ifdef RSA_BLINDING
279
280 /* With blinding, s = (r^(-1))((em)*r^e)^d mod n */
281
282 /* generate the r blinding value */
283 /* rsa_tmp2 is r */
284 gen_random_mpint(key->n, &rsa_tmp2);
285
286 /* rsa_tmp1 is em */
287 /* em' = em * r^e mod n */
288
289 mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/
290 mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3);
291 mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2);
292
293 /* rsa_tmp2 is em' */
294 /* s' = (em')^d mod n */
295 mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1);
296
297 /* rsa_tmp1 is s' */
298 /* rsa_tmp3 is r^(-1) mod n */
299 /* s = (s')r^(-1) mod n */
300 mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s);
301
302 #else
303
277 /* s = em^d mod n */ 304 /* s = em^d mod n */
278 if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) { 305 /* rsa_tmp1 is em */
306 if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) {
279 dropbear_exit("rsa error"); 307 dropbear_exit("rsa error");
280 } 308 }
281 mp_clear(rsa_em); 309
282 m_free(rsa_em); 310 #endif /* RSA_BLINDING */
311
312 mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
283 313
284 /* create the signature to return */ 314 /* create the signature to return */
285 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); 315 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
286 316
287 nsize = mp_unsigned_bin_size(key->n); 317 nsize = mp_unsigned_bin_size(key->n);
300 } 330 }
301 buf_incrwritepos(buf, ssize); 331 buf_incrwritepos(buf, ssize);
302 mp_clear(&rsa_s); 332 mp_clear(&rsa_s);
303 333
304 #if defined(DEBUG_RSA) && defined(DEBUG_TRACE) 334 #if defined(DEBUG_RSA) && defined(DEBUG_TRACE)
305 printhex(buf->data, buf->len); 335 printhex("RSA sig", buf->data, buf->len);
306 #endif 336 #endif
307 337
308 338
309 TRACE(("leave buf_put_rsa_sign")) 339 TRACE(("leave buf_put_rsa_sign"))
310 } 340 }
316 * where FF is repeated enough times to make EM one byte 346 * where FF is repeated enough times to make EM one byte
317 * shorter than the size of key->n 347 * shorter than the size of key->n
318 * 348 *
319 * prefix is the ASN1 designator prefix, 349 * prefix is the ASN1 designator prefix,
320 * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 350 * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14
351 *
352 * rsa_em must be a pointer to an initialised mp_int.
321 */ 353 */
322 static mp_int * rsa_pad_em(rsa_key * key, 354 static void rsa_pad_em(rsa_key * key,
323 const unsigned char * data, unsigned int len) { 355 const unsigned char * data, unsigned int len,
356 mp_int * rsa_em) {
324 357
325 /* ASN1 designator (including the 0x00 preceding) */ 358 /* ASN1 designator (including the 0x00 preceding) */
326 const char rsa_asn1_magic[] = 359 const unsigned char rsa_asn1_magic[] =
327 {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 360 {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
328 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; 361 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
329 #define RSA_ASN1_MAGIC_LEN 16 362 const unsigned int RSA_ASN1_MAGIC_LEN = 16;
363
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 */