diff options
Diffstat (limited to 'src/util/crypto_rsa.c')
-rw-r--r-- | src/util/crypto_rsa.c | 173 |
1 files changed, 44 insertions, 129 deletions
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index ab3ce6fe7..4415f20f6 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -400,31 +400,24 @@ GNUNET_CRYPTO_rsa_public_key_decode (const char *buf, | |||
400 | * @return the newly created blinding key | 400 | * @return the newly created blinding key |
401 | */ | 401 | */ |
402 | static struct RsaBlindingKey * | 402 | static struct RsaBlindingKey * |
403 | rsa_blinding_key_derive (unsigned int len, | 403 | rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, |
404 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks) | 404 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks) |
405 | { | 405 | { |
406 | char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */ | ||
406 | struct RsaBlindingKey *blind; | 407 | struct RsaBlindingKey *blind; |
407 | uint8_t buf[len / 8]; | 408 | gcry_mpi_t n; |
408 | int rc; | ||
409 | size_t rsize; | ||
410 | 409 | ||
411 | blind = GNUNET_new (struct RsaBlindingKey); | 410 | blind = GNUNET_new (struct RsaBlindingKey); |
412 | /* FIXME: #4483: actually derive key from bks! - Jeff, | 411 | |
413 | check that you're happy with this!*/ | 412 | /* Extract the composite n from the RSA public key */ |
414 | GNUNET_assert (GNUNET_YES == | 413 | GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") ); |
415 | GNUNET_CRYPTO_kdf (buf, | 414 | GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) ); |
416 | sizeof (buf), | 415 | |
417 | "blinding-kdf", | 416 | GNUNET_CRYPTO_kdf_mod_mpi (&blind->r, |
418 | strlen ("blinding-kdf"), | 417 | n, |
419 | bks, | 418 | xts, strlen(xts), |
420 | sizeof (*bks), | 419 | bks, sizeof(*bks), |
421 | NULL, 0)); | 420 | "Blinding KDF"); |
422 | rc = gcry_mpi_scan (&blind->r, | ||
423 | GCRYMPI_FMT_USG, | ||
424 | (const unsigned char *) buf, | ||
425 | sizeof (buf), | ||
426 | &rsize); | ||
427 | GNUNET_assert (0 == rc); | ||
428 | return blind; | 421 | return blind; |
429 | } | 422 | } |
430 | 423 | ||
@@ -538,13 +531,10 @@ unsigned int | |||
538 | GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key) | 531 | GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key) |
539 | { | 532 | { |
540 | gcry_mpi_t n; | 533 | gcry_mpi_t n; |
541 | int ret; | ||
542 | unsigned int rval; | 534 | unsigned int rval; |
543 | 535 | ||
544 | ret = key_from_sexp (&n, key->sexp, "rsa", "n"); | 536 | if (0 != key_from_sexp (&n, key->sexp, "rsa", "n")) |
545 | if (0 != ret) | 537 | { /* Not an RSA public key */ |
546 | { | ||
547 | /* this is no public RSA key */ | ||
548 | GNUNET_break (0); | 538 | GNUNET_break (0); |
549 | return 0; | 539 | return 0; |
550 | } | 540 | } |
@@ -610,91 +600,33 @@ numeric_mpi_alloc_n_print (gcry_mpi_t v, | |||
610 | * @param hash initial hash of the message to sign | 600 | * @param hash initial hash of the message to sign |
611 | * @param pkey the public key of the signer | 601 | * @param pkey the public key of the signer |
612 | * @param rsize If not NULL, the number of bytes actually stored in buffer | 602 | * @param rsize If not NULL, the number of bytes actually stored in buffer |
613 | * @return libgcrypt error that to represent an allocation failure | ||
614 | */ | 603 | */ |
615 | /* FIXME: exported symbol without proper prefix... */ | 604 | static void |
616 | gcry_error_t | ||
617 | rsa_full_domain_hash (gcry_mpi_t *r, | 605 | rsa_full_domain_hash (gcry_mpi_t *r, |
618 | const struct GNUNET_HashCode *hash, | 606 | const struct GNUNET_HashCode *hash, |
619 | const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | 607 | const struct GNUNET_CRYPTO_RsaPublicKey *pkey) |
620 | size_t *rsize) | ||
621 | { | 608 | { |
622 | unsigned int i; | 609 | gcry_mpi_t n; |
623 | unsigned int nbits; | 610 | char *xts; |
624 | unsigned int nhashes; | 611 | size_t xts_len; |
625 | gcry_error_t rc; | 612 | |
626 | char *buf; | 613 | /* Extract the composite n from the RSA public key */ |
627 | size_t buf_len; | 614 | GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") ); |
628 | gcry_md_hd_t h; | 615 | GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) ); |
629 | gcry_md_hd_t h0; | 616 | |
630 | struct GNUNET_HashCode *hs; | 617 | /* We key with the public denomination key as a homage to RSA-PSS by * |
631 | 618 | * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree * | |
632 | /* Uncomment the following to debug without using the full domain hash */ | 619 | * of the hypothetical polyomial-time attack on RSA-KTI created by a * |
633 | /* | 620 | * polynomial-time one-more forgary attack. Yey seeding! */ |
634 | rc = gcry_mpi_scan (r, | 621 | xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts); |
635 | GCRYMPI_FMT_USG, | 622 | |
636 | (const unsigned char *)hash, | 623 | GNUNET_CRYPTO_kdf_mod_mpi (r, |
637 | sizeof(struct GNUNET_HashCode), | 624 | n, |
638 | rsize); | 625 | xts, xts_len, |
639 | return rc; | 626 | hash, sizeof(*hash), |
640 | */ | 627 | "RSA-FDA FTpsW!"); |
641 | 628 | ||
642 | nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey); | 629 | GNUNET_free (xts); |
643 | if (nbits < 512) | ||
644 | nbits = 512; | ||
645 | |||
646 | /* Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC. */ | ||
647 | rc = gcry_md_open (&h, GCRY_MD_SHA512, 0); | ||
648 | if (0 != rc) | ||
649 | return rc; | ||
650 | |||
651 | /* We seed with the public denomination key as a homage to RSA-PSS by * | ||
652 | * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree * | ||
653 | * of the hypothetical polyomial-time attack on RSA-KTI created by a * | ||
654 | * polynomial-time one-more forgary attack. Yey seeding! */ | ||
655 | buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf); | ||
656 | gcry_md_write (h, buf, buf_len); | ||
657 | GNUNET_free (buf); | ||
658 | |||
659 | nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1; | ||
660 | hs = GNUNET_new_array (nhashes, | ||
661 | struct GNUNET_HashCode); | ||
662 | for (i=0; i<nhashes; i++) | ||
663 | { | ||
664 | gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode)); | ||
665 | rc = gcry_md_copy (&h0, h); | ||
666 | if (0 != rc) | ||
667 | { | ||
668 | gcry_md_close (h0); | ||
669 | break; | ||
670 | } | ||
671 | gcry_md_putc (h0, i % 256); | ||
672 | memcpy (&hs[i], | ||
673 | gcry_md_read (h0, GCRY_MD_SHA512), | ||
674 | sizeof(struct GNUNET_HashCode)); | ||
675 | gcry_md_close (h0); | ||
676 | } | ||
677 | gcry_md_close (h); | ||
678 | if (0 != rc) | ||
679 | { | ||
680 | GNUNET_free (hs); | ||
681 | return rc; | ||
682 | } | ||
683 | |||
684 | rc = gcry_mpi_scan (r, | ||
685 | GCRYMPI_FMT_USG, | ||
686 | (const unsigned char *) hs, | ||
687 | nhashes * sizeof(struct GNUNET_HashCode), | ||
688 | rsize); | ||
689 | GNUNET_free (hs); | ||
690 | if (0 != rc) | ||
691 | return rc; | ||
692 | |||
693 | /* Do not allow *r to exceed n or signatures fail to verify unpredictably. * | ||
694 | * This happening with gcry_mpi_clear_highbit (*r, nbits-1) so maybe * | ||
695 | * gcry_mpi_clear_highbit is broken, but setting the highbit sounds good. */ | ||
696 | gcry_mpi_set_highbit (*r, nbits-2); | ||
697 | return rc; | ||
698 | } | 630 | } |
699 | 631 | ||
700 | 632 | ||
@@ -718,11 +650,8 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | |||
718 | gcry_mpi_t ne[2]; | 650 | gcry_mpi_t ne[2]; |
719 | gcry_mpi_t r_e; | 651 | gcry_mpi_t r_e; |
720 | gcry_mpi_t data_r_e; | 652 | gcry_mpi_t data_r_e; |
721 | size_t rsize; | ||
722 | size_t n; | 653 | size_t n; |
723 | gcry_error_t rc; | ||
724 | int ret; | 654 | int ret; |
725 | unsigned int len; | ||
726 | 655 | ||
727 | ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne"); | 656 | ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne"); |
728 | if (0 != ret) | 657 | if (0 != ret) |
@@ -734,17 +663,8 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | |||
734 | return 0; | 663 | return 0; |
735 | } | 664 | } |
736 | 665 | ||
737 | rc = rsa_full_domain_hash (&data, hash, pkey, &rsize); | 666 | rsa_full_domain_hash (&data, hash, pkey); |
738 | if (0 != rc) /* Allocation error in libgcrypt */ | 667 | bkey = rsa_blinding_key_derive (pkey, |
739 | { | ||
740 | GNUNET_break (0); | ||
741 | gcry_mpi_release (ne[0]); | ||
742 | gcry_mpi_release (ne[1]); | ||
743 | *buffer = NULL; | ||
744 | return 0; | ||
745 | } | ||
746 | len = GNUNET_CRYPTO_rsa_public_key_len (pkey); | ||
747 | bkey = rsa_blinding_key_derive (len, | ||
748 | bks); | 668 | bks); |
749 | r_e = gcry_mpi_new (0); | 669 | r_e = gcry_mpi_new (0); |
750 | gcry_mpi_powm (r_e, | 670 | gcry_mpi_powm (r_e, |
@@ -886,13 +806,11 @@ GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | |||
886 | { | 806 | { |
887 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; | 807 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; |
888 | gcry_mpi_t v = NULL; | 808 | gcry_mpi_t v = NULL; |
889 | gcry_error_t rc; | ||
890 | struct GNUNET_CRYPTO_RsaSignature *sig; | 809 | struct GNUNET_CRYPTO_RsaSignature *sig; |
891 | 810 | ||
892 | pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key); | 811 | pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key); |
893 | rc = rsa_full_domain_hash (&v, hash, pkey, NULL); | 812 | rsa_full_domain_hash (&v, hash, pkey); |
894 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | 813 | GNUNET_CRYPTO_rsa_public_key_free (pkey); |
895 | GNUNET_assert (0 == rc); | ||
896 | 814 | ||
897 | sig = rsa_sign_mpi (key, v); | 815 | sig = rsa_sign_mpi (key, v); |
898 | gcry_mpi_release (v); | 816 | gcry_mpi_release (v); |
@@ -1034,7 +952,6 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | |||
1034 | gcry_mpi_t ubsig; | 952 | gcry_mpi_t ubsig; |
1035 | int ret; | 953 | int ret; |
1036 | struct GNUNET_CRYPTO_RsaSignature *sret; | 954 | struct GNUNET_CRYPTO_RsaSignature *sret; |
1037 | unsigned int len; | ||
1038 | 955 | ||
1039 | ret = key_from_sexp (&n, pkey->sexp, "public-key", "n"); | 956 | ret = key_from_sexp (&n, pkey->sexp, "public-key", "n"); |
1040 | if (0 != ret) | 957 | if (0 != ret) |
@@ -1053,8 +970,7 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | |||
1053 | GNUNET_break_op (0); | 970 | GNUNET_break_op (0); |
1054 | return NULL; | 971 | return NULL; |
1055 | } | 972 | } |
1056 | len = GNUNET_CRYPTO_rsa_public_key_len (pkey); | 973 | bkey = rsa_blinding_key_derive (pkey, |
1057 | bkey = rsa_blinding_key_derive (len, | ||
1058 | bks); | 974 | bks); |
1059 | 975 | ||
1060 | r_inv = gcry_mpi_new (0); | 976 | r_inv = gcry_mpi_new (0); |
@@ -1106,8 +1022,7 @@ GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash, | |||
1106 | gcry_mpi_t r; | 1022 | gcry_mpi_t r; |
1107 | int rc; | 1023 | int rc; |
1108 | 1024 | ||
1109 | rc = rsa_full_domain_hash (&r, hash, pkey, NULL); | 1025 | rsa_full_domain_hash (&r, hash, pkey); |
1110 | GNUNET_assert (0 == rc); /* Allocation error in libgcrypt */ | ||
1111 | data = mpi_to_sexp(r); | 1026 | data = mpi_to_sexp(r); |
1112 | gcry_mpi_release (r); | 1027 | gcry_mpi_release (r); |
1113 | 1028 | ||