Mercurial > dropbear
comparison rsa.c @ 1674:ba6fc7afe1c5
use sigtype where appropriate
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 06 Apr 2020 23:18:26 +0800 |
parents | bb8eaa26bc93 |
children | ae41624c2198 |
comparison
equal
deleted
inserted
replaced
1668:49cb3cf4bd6f | 1674:ba6fc7afe1c5 |
---|---|
33 #include "bignum.h" | 33 #include "bignum.h" |
34 #include "rsa.h" | 34 #include "rsa.h" |
35 #include "buffer.h" | 35 #include "buffer.h" |
36 #include "ssh.h" | 36 #include "ssh.h" |
37 #include "dbrandom.h" | 37 #include "dbrandom.h" |
38 #include "signkey.h" | |
38 | 39 |
39 #if DROPBEAR_RSA | 40 #if DROPBEAR_RSA |
40 | 41 |
42 #if !(DROPBEAR_RSA_SHA1 || DROPBEAR_RSA_SHA256) | |
43 #error Somehow RSA was enabled with neither DROPBEAR_RSA_SHA1 nor DROPBEAR_RSA_SHA256 | |
44 #endif | |
45 | |
41 static void rsa_pad_em(const dropbear_rsa_key * key, | 46 static void rsa_pad_em(const dropbear_rsa_key * key, |
42 const buffer *data_buf, mp_int * rsa_em); | 47 const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype); |
43 | 48 |
44 /* Load a public rsa key from a buffer, initialising the values. | 49 /* Load a public rsa key from a buffer, initialising the values. |
45 * The key will have the same format as buf_put_rsa_key. | 50 * The key will have the same format as buf_put_rsa_key. |
46 * These should be freed with rsa_key_free. | 51 * These should be freed with rsa_key_free. |
47 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 52 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
189 } | 194 } |
190 | 195 |
191 #if DROPBEAR_SIGNKEY_VERIFY | 196 #if DROPBEAR_SIGNKEY_VERIFY |
192 /* Verify a signature in buf, made on data by the key given. | 197 /* Verify a signature in buf, made on data by the key given. |
193 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 198 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
194 int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key, const buffer *data_buf) { | 199 int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key, |
200 enum signkey_type sigtype, const buffer *data_buf) { | |
195 unsigned int slen; | 201 unsigned int slen; |
196 DEF_MP_INT(rsa_s); | 202 DEF_MP_INT(rsa_s); |
197 DEF_MP_INT(rsa_mdash); | 203 DEF_MP_INT(rsa_mdash); |
198 DEF_MP_INT(rsa_em); | 204 DEF_MP_INT(rsa_em); |
199 int ret = DROPBEAR_FAILURE; | 205 int ret = DROPBEAR_FAILURE; |
221 TRACE(("s > n-1")) | 227 TRACE(("s > n-1")) |
222 goto out; | 228 goto out; |
223 } | 229 } |
224 | 230 |
225 /* create the magic PKCS padded value */ | 231 /* create the magic PKCS padded value */ |
226 rsa_pad_em(key, data_buf, &rsa_em); | 232 rsa_pad_em(key, data_buf, &rsa_em, sigtype); |
227 | 233 |
228 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { | 234 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { |
229 TRACE(("failed exptmod rsa_s")) | 235 TRACE(("failed exptmod rsa_s")) |
230 goto out; | 236 goto out; |
231 } | 237 } |
244 | 250 |
245 #endif /* DROPBEAR_SIGNKEY_VERIFY */ | 251 #endif /* DROPBEAR_SIGNKEY_VERIFY */ |
246 | 252 |
247 /* Sign the data presented with key, writing the signature contents | 253 /* Sign the data presented with key, writing the signature contents |
248 * to the buffer */ | 254 * to the buffer */ |
249 void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key, const buffer *data_buf) { | 255 void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key, |
250 unsigned int nsize, ssize; | 256 enum signkey_type sigtype, const buffer *data_buf) { |
257 const char *name = NULL; | |
258 unsigned int nsize, ssize, namelen = 0; | |
251 unsigned int i; | 259 unsigned int i; |
252 DEF_MP_INT(rsa_s); | 260 DEF_MP_INT(rsa_s); |
253 DEF_MP_INT(rsa_tmp1); | 261 DEF_MP_INT(rsa_tmp1); |
254 DEF_MP_INT(rsa_tmp2); | 262 DEF_MP_INT(rsa_tmp2); |
255 DEF_MP_INT(rsa_tmp3); | 263 DEF_MP_INT(rsa_tmp3); |
257 TRACE(("enter buf_put_rsa_sign")) | 265 TRACE(("enter buf_put_rsa_sign")) |
258 dropbear_assert(key != NULL); | 266 dropbear_assert(key != NULL); |
259 | 267 |
260 m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); | 268 m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); |
261 | 269 |
262 rsa_pad_em(key, data_buf, &rsa_tmp1); | 270 rsa_pad_em(key, data_buf, &rsa_tmp1, sigtype); |
263 | 271 |
264 /* the actual signing of the padded data */ | 272 /* the actual signing of the padded data */ |
265 | 273 |
266 #if DROPBEAR_RSA_BLINDING | 274 #if DROPBEAR_RSA_BLINDING |
267 | 275 |
309 #endif /* DROPBEAR_RSA_BLINDING */ | 317 #endif /* DROPBEAR_RSA_BLINDING */ |
310 | 318 |
311 mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); | 319 mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); |
312 | 320 |
313 /* create the signature to return */ | 321 /* create the signature to return */ |
314 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); | 322 name = signature_name_from_type(sigtype, &namelen); |
323 buf_putstring(buf, name, namelen); | |
315 | 324 |
316 nsize = mp_unsigned_bin_size(key->n); | 325 nsize = mp_unsigned_bin_size(key->n); |
317 | 326 |
318 /* string rsa_signature_blob length */ | 327 /* string rsa_signature_blob length */ |
319 buf_putint(buf, nsize); | 328 buf_putint(buf, nsize); |
338 | 347 |
339 | 348 |
340 TRACE(("leave buf_put_rsa_sign")) | 349 TRACE(("leave buf_put_rsa_sign")) |
341 } | 350 } |
342 | 351 |
343 /* Creates the message value as expected by PKCS, see rfc2437 etc */ | 352 /* Creates the message value as expected by PKCS, |
344 /* format to be padded to is: | 353 see rfc8017 section 9.2 */ |
345 * EM = 01 | FF* | 00 | prefix | hash | |
346 * | |
347 * where FF is repeated enough times to make EM one byte | |
348 * shorter than the size of key->n | |
349 * | |
350 * prefix is the ASN1 designator prefix, | |
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. | |
354 */ | |
355 static void rsa_pad_em(const dropbear_rsa_key * key, | 354 static void rsa_pad_em(const dropbear_rsa_key * key, |
356 const buffer *data_buf, mp_int * rsa_em) { | 355 const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype) { |
357 | 356 /* EM = 0x00 || 0x01 || PS || 0x00 || T |
358 /* ASN1 designator (including the 0x00 preceding) */ | 357 PS is padding of 0xff to make EM the size of key->n |
359 const unsigned char rsa_asn1_magic[] = | 358 |
360 {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, | 359 T is the DER encoding of the hash alg (sha1 or sha256) |
360 */ | |
361 | |
362 /* From rfc8017 page 46 */ | |
363 #if DROPBEAR_RSA_SHA1 | |
364 const unsigned char T_sha1[] = | |
365 {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, | |
361 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; | 366 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; |
362 const unsigned int RSA_ASN1_MAGIC_LEN = 16; | 367 #endif |
363 | 368 #if DROPBEAR_RSA_SHA256 |
369 const unsigned char T_sha256[] = | |
370 {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, | |
371 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; | |
372 #endif | |
373 | |
374 int Tlen = 0; | |
375 const unsigned char *T = NULL; | |
376 const struct ltc_hash_descriptor *hash_desc = NULL; | |
364 buffer * rsa_EM = NULL; | 377 buffer * rsa_EM = NULL; |
365 hash_state hs; | 378 hash_state hs; |
366 unsigned int nsize; | 379 unsigned int nsize; |
367 | 380 |
368 dropbear_assert(key != NULL); | 381 switch (sigtype) { |
382 #if DROPBEAR_RSA_SHA1 | |
383 case DROPBEAR_SIGNKEY_RSA: | |
384 Tlen = sizeof(T_sha1); | |
385 T = T_sha1; | |
386 hash_desc = &sha1_desc; | |
387 break; | |
388 #endif | |
389 #if DROPBEAR_RSA_SHA256 | |
390 case DROPBEAR_SIGNKEY_RSA_SHA256: | |
391 Tlen = sizeof(T_sha256); | |
392 T = T_sha256; | |
393 hash_desc = &sha256_desc; | |
394 break; | |
395 #endif | |
396 default: | |
397 assert(0); | |
398 } | |
399 | |
369 nsize = mp_unsigned_bin_size(key->n); | 400 nsize = mp_unsigned_bin_size(key->n); |
370 | 401 |
371 rsa_EM = buf_new(nsize-1); | 402 rsa_EM = buf_new(nsize); |
372 /* type byte */ | 403 /* type byte */ |
404 buf_putbyte(rsa_EM, 0x00); | |
373 buf_putbyte(rsa_EM, 0x01); | 405 buf_putbyte(rsa_EM, 0x01); |
374 /* Padding with 0xFF bytes */ | 406 /* Padding with PS 0xFF bytes */ |
375 while(rsa_EM->pos != rsa_EM->size - RSA_ASN1_MAGIC_LEN - SHA1_HASH_SIZE) { | 407 while(rsa_EM->pos != rsa_EM->size - (1 + Tlen + hash_desc->hashsize)) { |
376 buf_putbyte(rsa_EM, 0xff); | 408 buf_putbyte(rsa_EM, 0xff); |
377 } | 409 } |
410 buf_putbyte(rsa_EM, 0x00); | |
378 /* Magic ASN1 stuff */ | 411 /* Magic ASN1 stuff */ |
379 memcpy(buf_getwriteptr(rsa_EM, RSA_ASN1_MAGIC_LEN), | 412 buf_putbytes(rsa_EM, T, Tlen); |
380 rsa_asn1_magic, RSA_ASN1_MAGIC_LEN); | |
381 buf_incrwritepos(rsa_EM, RSA_ASN1_MAGIC_LEN); | |
382 | 413 |
383 /* The hash of the data */ | 414 /* The hash of the data */ |
384 sha1_init(&hs); | 415 hash_desc->init(&hs); |
385 sha1_process(&hs, data_buf->data, data_buf->len); | 416 hash_desc->process(&hs, data_buf->data, data_buf->len); |
386 sha1_done(&hs, buf_getwriteptr(rsa_EM, SHA1_HASH_SIZE)); | 417 hash_desc->done(&hs, buf_getwriteptr(rsa_EM, hash_desc->hashsize)); |
387 buf_incrwritepos(rsa_EM, SHA1_HASH_SIZE); | 418 buf_incrwritepos(rsa_EM, hash_desc->hashsize); |
388 | 419 |
389 dropbear_assert(rsa_EM->pos == rsa_EM->size); | 420 dropbear_assert(rsa_EM->pos == rsa_EM->size); |
390 | 421 |
391 /* Create the mp_int from the encoded bytes */ | 422 /* Create the mp_int from the encoded bytes */ |
392 buf_setpos(rsa_EM, 0); | 423 buf_setpos(rsa_EM, 0); |