diff options
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_ameth.c')
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_ameth.c | 351 |
1 files changed, 350 insertions, 1 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c index 8c3209885e..2460910ab2 100644 --- a/src/lib/libcrypto/rsa/rsa_ameth.c +++ b/src/lib/libcrypto/rsa/rsa_ameth.c | |||
@@ -265,6 +265,147 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, | |||
265 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); | 265 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); |
266 | } | 266 | } |
267 | 267 | ||
268 | static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, | ||
269 | X509_ALGOR **pmaskHash) | ||
270 | { | ||
271 | const unsigned char *p; | ||
272 | int plen; | ||
273 | RSA_PSS_PARAMS *pss; | ||
274 | |||
275 | *pmaskHash = NULL; | ||
276 | |||
277 | if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) | ||
278 | return NULL; | ||
279 | p = alg->parameter->value.sequence->data; | ||
280 | plen = alg->parameter->value.sequence->length; | ||
281 | pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); | ||
282 | |||
283 | if (!pss) | ||
284 | return NULL; | ||
285 | |||
286 | if (pss->maskGenAlgorithm) | ||
287 | { | ||
288 | ASN1_TYPE *param = pss->maskGenAlgorithm->parameter; | ||
289 | if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 | ||
290 | && param->type == V_ASN1_SEQUENCE) | ||
291 | { | ||
292 | p = param->value.sequence->data; | ||
293 | plen = param->value.sequence->length; | ||
294 | *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | return pss; | ||
299 | } | ||
300 | |||
301 | static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, | ||
302 | X509_ALGOR *maskHash, int indent) | ||
303 | { | ||
304 | int rv = 0; | ||
305 | if (!pss) | ||
306 | { | ||
307 | if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) | ||
308 | return 0; | ||
309 | return 1; | ||
310 | } | ||
311 | if (BIO_puts(bp, "\n") <= 0) | ||
312 | goto err; | ||
313 | if (!BIO_indent(bp, indent, 128)) | ||
314 | goto err; | ||
315 | if (BIO_puts(bp, "Hash Algorithm: ") <= 0) | ||
316 | goto err; | ||
317 | |||
318 | if (pss->hashAlgorithm) | ||
319 | { | ||
320 | if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) | ||
321 | goto err; | ||
322 | } | ||
323 | else if (BIO_puts(bp, "sha1 (default)") <= 0) | ||
324 | goto err; | ||
325 | |||
326 | if (BIO_puts(bp, "\n") <= 0) | ||
327 | goto err; | ||
328 | |||
329 | if (!BIO_indent(bp, indent, 128)) | ||
330 | goto err; | ||
331 | |||
332 | if (BIO_puts(bp, "Mask Algorithm: ") <= 0) | ||
333 | goto err; | ||
334 | if (pss->maskGenAlgorithm) | ||
335 | { | ||
336 | if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) | ||
337 | goto err; | ||
338 | if (BIO_puts(bp, " with ") <= 0) | ||
339 | goto err; | ||
340 | if (maskHash) | ||
341 | { | ||
342 | if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) | ||
343 | goto err; | ||
344 | } | ||
345 | else if (BIO_puts(bp, "INVALID") <= 0) | ||
346 | goto err; | ||
347 | } | ||
348 | else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) | ||
349 | goto err; | ||
350 | BIO_puts(bp, "\n"); | ||
351 | |||
352 | if (!BIO_indent(bp, indent, 128)) | ||
353 | goto err; | ||
354 | if (BIO_puts(bp, "Salt Length: ") <= 0) | ||
355 | goto err; | ||
356 | if (pss->saltLength) | ||
357 | { | ||
358 | if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) | ||
359 | goto err; | ||
360 | } | ||
361 | else if (BIO_puts(bp, "20 (default)") <= 0) | ||
362 | goto err; | ||
363 | BIO_puts(bp, "\n"); | ||
364 | |||
365 | if (!BIO_indent(bp, indent, 128)) | ||
366 | goto err; | ||
367 | if (BIO_puts(bp, "Trailer Field: ") <= 0) | ||
368 | goto err; | ||
369 | if (pss->trailerField) | ||
370 | { | ||
371 | if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) | ||
372 | goto err; | ||
373 | } | ||
374 | else if (BIO_puts(bp, "0xbc (default)") <= 0) | ||
375 | goto err; | ||
376 | BIO_puts(bp, "\n"); | ||
377 | |||
378 | rv = 1; | ||
379 | |||
380 | err: | ||
381 | return rv; | ||
382 | |||
383 | } | ||
384 | |||
385 | static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, | ||
386 | const ASN1_STRING *sig, | ||
387 | int indent, ASN1_PCTX *pctx) | ||
388 | { | ||
389 | if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) | ||
390 | { | ||
391 | int rv; | ||
392 | RSA_PSS_PARAMS *pss; | ||
393 | X509_ALGOR *maskHash; | ||
394 | pss = rsa_pss_decode(sigalg, &maskHash); | ||
395 | rv = rsa_pss_param_print(bp, pss, maskHash, indent); | ||
396 | if (pss) | ||
397 | RSA_PSS_PARAMS_free(pss); | ||
398 | if (maskHash) | ||
399 | X509_ALGOR_free(maskHash); | ||
400 | if (!rv) | ||
401 | return 0; | ||
402 | } | ||
403 | else if (!sig && BIO_puts(bp, "\n") <= 0) | ||
404 | return 0; | ||
405 | if (sig) | ||
406 | return X509_signature_dump(bp, sig, indent); | ||
407 | return 1; | ||
408 | } | ||
268 | 409 | ||
269 | static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | 410 | static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) |
270 | { | 411 | { |
@@ -310,6 +451,211 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | |||
310 | 451 | ||
311 | } | 452 | } |
312 | 453 | ||
454 | /* Customised RSA item verification routine. This is called | ||
455 | * when a signature is encountered requiring special handling. We | ||
456 | * currently only handle PSS. | ||
457 | */ | ||
458 | |||
459 | |||
460 | static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, | ||
461 | X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, | ||
462 | EVP_PKEY *pkey) | ||
463 | { | ||
464 | int rv = -1; | ||
465 | int saltlen; | ||
466 | const EVP_MD *mgf1md = NULL, *md = NULL; | ||
467 | RSA_PSS_PARAMS *pss; | ||
468 | X509_ALGOR *maskHash; | ||
469 | EVP_PKEY_CTX *pkctx; | ||
470 | /* Sanity check: make sure it is PSS */ | ||
471 | if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) | ||
472 | { | ||
473 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); | ||
474 | return -1; | ||
475 | } | ||
476 | /* Decode PSS parameters */ | ||
477 | pss = rsa_pss_decode(sigalg, &maskHash); | ||
478 | |||
479 | if (pss == NULL) | ||
480 | { | ||
481 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); | ||
482 | goto err; | ||
483 | } | ||
484 | /* Check mask and lookup mask hash algorithm */ | ||
485 | if (pss->maskGenAlgorithm) | ||
486 | { | ||
487 | if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) | ||
488 | { | ||
489 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); | ||
490 | goto err; | ||
491 | } | ||
492 | if (!maskHash) | ||
493 | { | ||
494 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); | ||
495 | goto err; | ||
496 | } | ||
497 | mgf1md = EVP_get_digestbyobj(maskHash->algorithm); | ||
498 | if (mgf1md == NULL) | ||
499 | { | ||
500 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); | ||
501 | goto err; | ||
502 | } | ||
503 | } | ||
504 | else | ||
505 | mgf1md = EVP_sha1(); | ||
506 | |||
507 | if (pss->hashAlgorithm) | ||
508 | { | ||
509 | md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); | ||
510 | if (md == NULL) | ||
511 | { | ||
512 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); | ||
513 | goto err; | ||
514 | } | ||
515 | } | ||
516 | else | ||
517 | md = EVP_sha1(); | ||
518 | |||
519 | if (pss->saltLength) | ||
520 | { | ||
521 | saltlen = ASN1_INTEGER_get(pss->saltLength); | ||
522 | |||
523 | /* Could perform more salt length sanity checks but the main | ||
524 | * RSA routines will trap other invalid values anyway. | ||
525 | */ | ||
526 | if (saltlen < 0) | ||
527 | { | ||
528 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); | ||
529 | goto err; | ||
530 | } | ||
531 | } | ||
532 | else | ||
533 | saltlen = 20; | ||
534 | |||
535 | /* low-level routines support only trailer field 0xbc (value 1) | ||
536 | * and PKCS#1 says we should reject any other value anyway. | ||
537 | */ | ||
538 | if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) | ||
539 | { | ||
540 | RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); | ||
541 | goto err; | ||
542 | } | ||
543 | |||
544 | /* We have all parameters now set up context */ | ||
545 | |||
546 | if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) | ||
547 | goto err; | ||
548 | |||
549 | if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) | ||
550 | goto err; | ||
551 | |||
552 | if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) | ||
553 | goto err; | ||
554 | |||
555 | if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) | ||
556 | goto err; | ||
557 | /* Carry on */ | ||
558 | rv = 2; | ||
559 | |||
560 | err: | ||
561 | RSA_PSS_PARAMS_free(pss); | ||
562 | if (maskHash) | ||
563 | X509_ALGOR_free(maskHash); | ||
564 | return rv; | ||
565 | } | ||
566 | |||
567 | static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, | ||
568 | X509_ALGOR *alg1, X509_ALGOR *alg2, | ||
569 | ASN1_BIT_STRING *sig) | ||
570 | { | ||
571 | int pad_mode; | ||
572 | EVP_PKEY_CTX *pkctx = ctx->pctx; | ||
573 | if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) | ||
574 | return 0; | ||
575 | if (pad_mode == RSA_PKCS1_PADDING) | ||
576 | return 2; | ||
577 | if (pad_mode == RSA_PKCS1_PSS_PADDING) | ||
578 | { | ||
579 | const EVP_MD *sigmd, *mgf1md; | ||
580 | RSA_PSS_PARAMS *pss = NULL; | ||
581 | X509_ALGOR *mgf1alg = NULL; | ||
582 | ASN1_STRING *os1 = NULL, *os2 = NULL; | ||
583 | EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); | ||
584 | int saltlen, rv = 0; | ||
585 | sigmd = EVP_MD_CTX_md(ctx); | ||
586 | if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) | ||
587 | goto err; | ||
588 | if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) | ||
589 | goto err; | ||
590 | if (saltlen == -1) | ||
591 | saltlen = EVP_MD_size(sigmd); | ||
592 | else if (saltlen == -2) | ||
593 | { | ||
594 | saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; | ||
595 | if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) | ||
596 | saltlen--; | ||
597 | } | ||
598 | pss = RSA_PSS_PARAMS_new(); | ||
599 | if (!pss) | ||
600 | goto err; | ||
601 | if (saltlen != 20) | ||
602 | { | ||
603 | pss->saltLength = ASN1_INTEGER_new(); | ||
604 | if (!pss->saltLength) | ||
605 | goto err; | ||
606 | if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) | ||
607 | goto err; | ||
608 | } | ||
609 | if (EVP_MD_type(sigmd) != NID_sha1) | ||
610 | { | ||
611 | pss->hashAlgorithm = X509_ALGOR_new(); | ||
612 | if (!pss->hashAlgorithm) | ||
613 | goto err; | ||
614 | X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); | ||
615 | } | ||
616 | if (EVP_MD_type(mgf1md) != NID_sha1) | ||
617 | { | ||
618 | ASN1_STRING *stmp = NULL; | ||
619 | /* need to embed algorithm ID inside another */ | ||
620 | mgf1alg = X509_ALGOR_new(); | ||
621 | X509_ALGOR_set_md(mgf1alg, mgf1md); | ||
622 | if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), | ||
623 | &stmp)) | ||
624 | goto err; | ||
625 | pss->maskGenAlgorithm = X509_ALGOR_new(); | ||
626 | if (!pss->maskGenAlgorithm) | ||
627 | goto err; | ||
628 | X509_ALGOR_set0(pss->maskGenAlgorithm, | ||
629 | OBJ_nid2obj(NID_mgf1), | ||
630 | V_ASN1_SEQUENCE, stmp); | ||
631 | } | ||
632 | /* Finally create string with pss parameter encoding. */ | ||
633 | if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) | ||
634 | goto err; | ||
635 | if (alg2) | ||
636 | { | ||
637 | os2 = ASN1_STRING_dup(os1); | ||
638 | if (!os2) | ||
639 | goto err; | ||
640 | X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), | ||
641 | V_ASN1_SEQUENCE, os2); | ||
642 | } | ||
643 | X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), | ||
644 | V_ASN1_SEQUENCE, os1); | ||
645 | os1 = os2 = NULL; | ||
646 | rv = 3; | ||
647 | err: | ||
648 | if (mgf1alg) | ||
649 | X509_ALGOR_free(mgf1alg); | ||
650 | if (pss) | ||
651 | RSA_PSS_PARAMS_free(pss); | ||
652 | if (os1) | ||
653 | ASN1_STRING_free(os1); | ||
654 | return rv; | ||
655 | |||
656 | } | ||
657 | return 2; | ||
658 | } | ||
313 | 659 | ||
314 | const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = | 660 | const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = |
315 | { | 661 | { |
@@ -335,10 +681,13 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = | |||
335 | 681 | ||
336 | 0,0,0,0,0,0, | 682 | 0,0,0,0,0,0, |
337 | 683 | ||
684 | rsa_sig_print, | ||
338 | int_rsa_free, | 685 | int_rsa_free, |
339 | rsa_pkey_ctrl, | 686 | rsa_pkey_ctrl, |
340 | old_rsa_priv_decode, | 687 | old_rsa_priv_decode, |
341 | old_rsa_priv_encode | 688 | old_rsa_priv_encode, |
689 | rsa_item_verify, | ||
690 | rsa_item_sign | ||
342 | }, | 691 | }, |
343 | 692 | ||
344 | { | 693 | { |