2 This file is part of GNUnet
3 Copyright (C) 2014,2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file util/crypto_rsa.c
21 * @brief Chaum-style Blind signatures based on RSA
22 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
23 * @author Christian Grothoff
24 * @author Jeffrey Burdges <burdges@gnunet.org>
28 #include "gnunet_crypto_lib.h"
29 #include "benchmark.h"
31 #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
35 * The private information of an RSA key pair.
37 struct GNUNET_CRYPTO_RsaPrivateKey
40 * Libgcrypt S-expression for the RSA private key.
47 * The public information of an RSA key pair.
49 struct GNUNET_CRYPTO_RsaPublicKey
52 * Libgcrypt S-expression for the RSA public key.
59 * @brief an RSA signature
61 struct GNUNET_CRYPTO_RsaSignature
64 * Libgcrypt S-expression for the RSA signature.
71 * @brief RSA blinding key
76 * Random value used for blinding.
83 * Extract values from an S-expression.
85 * @param array where to store the result(s)
86 * @param sexp S-expression to parse
87 * @param topname top-level name in the S-expression that is of interest
88 * @param elems names of the elements to extract
89 * @return 0 on success
92 key_from_sexp (gcry_mpi_t *array,
102 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
104 l2 = gcry_sexp_cadr (list);
105 gcry_sexp_release (list);
110 for (s = elems; *s; s++, idx++)
112 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
114 for (unsigned int i = 0; i < idx; i++)
116 gcry_free (array[i]);
119 gcry_sexp_release (list);
120 return 3; /* required parameter not found */
122 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
123 gcry_sexp_release (l2);
126 for (unsigned int i = 0; i < idx; i++)
128 gcry_free (array[i]);
131 gcry_sexp_release (list);
132 return 4; /* required parameter is invalid */
135 gcry_sexp_release (list);
141 * Create a new private key. Caller must free return value.
143 * @param len length of the key in bits (i.e. 2048)
144 * @return fresh private key
146 struct GNUNET_CRYPTO_RsaPrivateKey *
147 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
149 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
151 gcry_sexp_t s_keyparam;
153 BENCHMARK_START (rsa_private_key_create);
156 gcry_sexp_build (&s_keyparam,
158 "(genkey(rsa(nbits %d)))",
161 gcry_pk_genkey (&s_key,
163 gcry_sexp_release (s_keyparam);
166 gcry_pk_testkey (s_key));
168 ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
170 BENCHMARK_END (rsa_private_key_create);
176 * Free memory occupied by the private key.
178 * @param key pointer to the memory to free
181 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
183 gcry_sexp_release (key->sexp);
189 * Encode the private key in a format suitable for
190 * storing it into a file.
192 * @param key the private key
193 * @param[out] buffer set to a buffer with the encoded key
194 * @return size of memory allocated in @a buffer
197 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
203 n = gcry_sexp_sprint (key->sexp,
204 GCRYSEXP_FMT_DEFAULT,
207 b = GNUNET_malloc (n);
208 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
209 gcry_sexp_sprint (key->sexp,
210 GCRYSEXP_FMT_DEFAULT,
219 * Decode the private key from the data-format back
220 * to the "normal", internal format.
222 * @param buf the buffer where the private key data is stored
223 * @param len the length of the data in @a buf
224 * @return NULL on error
226 struct GNUNET_CRYPTO_RsaPrivateKey *
227 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
230 struct GNUNET_CRYPTO_RsaPrivateKey *key;
231 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
233 gcry_sexp_new (&key->sexp,
238 LOG (GNUNET_ERROR_TYPE_WARNING,
239 "Decoded private key is not valid\n");
243 if (0 != gcry_pk_testkey (key->sexp))
245 LOG (GNUNET_ERROR_TYPE_WARNING,
246 "Decoded private key is not valid\n");
247 GNUNET_CRYPTO_rsa_private_key_free (key);
255 * Extract the public key of the given private key.
257 * @param priv the private key
258 * @retur NULL on error, otherwise the public key
260 struct GNUNET_CRYPTO_RsaPublicKey *
261 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
263 struct GNUNET_CRYPTO_RsaPublicKey *pub;
268 BENCHMARK_START (rsa_private_key_get_public);
270 rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
272 rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
274 rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
280 rc = gcry_sexp_build (&result,
282 "(public-key(rsa(n %m)(e %m)))",
285 gcry_mpi_release (ne[0]);
286 gcry_mpi_release (ne[1]);
287 pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
289 BENCHMARK_END (rsa_private_key_get_public);
295 * Free memory occupied by the public key.
297 * @param key pointer to the memory to free
300 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
302 gcry_sexp_release (key->sexp);
308 * Encode the public key in a format suitable for
309 * storing it into a file.
311 * @param key the private key
312 * @param[out] buffer set to a buffer with the encoded key
313 * @return size of memory allocated in @a buffer
316 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key,
322 n = gcry_sexp_sprint (key->sexp,
323 GCRYSEXP_FMT_ADVANCED,
326 b = GNUNET_malloc (n);
327 GNUNET_assert ((n -1) == /* since the last byte is \0 */
328 gcry_sexp_sprint (key->sexp,
329 GCRYSEXP_FMT_ADVANCED,
338 * Compute hash over the public key.
340 * @param key public key to hash
341 * @param hc where to store the hash code
344 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
345 struct GNUNET_HashCode *hc)
350 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
352 GNUNET_CRYPTO_hash (buf,
360 * Decode the public key from the data-format back
361 * to the "normal", internal format.
363 * @param buf the buffer where the public key data is stored
364 * @param len the length of the data in @a buf
365 * @return NULL on error
367 struct GNUNET_CRYPTO_RsaPublicKey *
368 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
371 struct GNUNET_CRYPTO_RsaPublicKey *key;
375 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
377 gcry_sexp_new (&key->sexp,
386 /* verify that this is an RSA public key */
387 ret = key_from_sexp (&n, key->sexp, "public-key", "n");
389 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
392 /* this is no public RSA key */
394 gcry_sexp_release (key->sexp);
398 gcry_mpi_release (n);
404 * Test for malicious RSA key.
406 * Assuming n is an RSA modulous and r is generated using a call to
407 * GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a
408 * malicious RSA key designed to deanomize the user.
410 * @param r KDF result
411 * @param n RSA modulus
412 * @return True if gcd(r,n) = 1, False means RSA key is malicious
415 rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
420 g = gcry_mpi_new (0);
421 t = gcry_mpi_gcd(g,r,n);
422 gcry_mpi_release (g);
428 * Create a blinding key
430 * @param len length of the key in bits (i.e. 2048)
431 * @param bks pre-secret to use to derive the blinding key
432 * @return the newly created blinding key, NULL if RSA key is malicious
434 static struct RsaBlindingKey *
435 rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
436 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
438 char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */
439 struct RsaBlindingKey *blind;
442 blind = GNUNET_new (struct RsaBlindingKey);
443 GNUNET_assert( NULL != blind );
445 /* Extract the composite n from the RSA public key */
446 GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
447 /* Assert that it at least looks like an RSA key */
448 GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
450 GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
455 if (0 == rsa_gcd_validate(blind->r, n)) {
460 gcry_mpi_release (n);
466 We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
469 There was previously a call to GNUNET_CRYPTO_kdf in
470 bkey = rsa_blinding_key_derive (len, bks);
471 that gives exactly len bits where
472 len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
474 Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
475 okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
476 pkey.n making the effective bkey be
477 bkey mod pkey.n = bkey - pkey.n
478 so the effective bkey has its high bit set with probability r/2.
480 We expect r to be close to 1/2 if the exchange is honest, but the
481 exchange can choose r otherwise.
483 In blind signing, the exchange sees
484 B = bkey * S mod pkey.n
485 On deposit, the exchange sees S so they can compute bkey' = B/S mod
486 pkey.n for all B they recorded to see if bkey' has it's high bit set.
487 Also, note the exchange can compute 1/S efficiently since they know the
490 I suppose that happens with probability r/(1+r) if its the wrong B, not
491 completely sure. If otoh we've the right B, then we've the probability
492 r/2 of a set high bit in the effective bkey.
494 Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
495 the wrong and right probabilities 1/3 and 1/4, respectively.
497 I feared this gives the exchange a meaningful fraction of a bit of
498 information per coin involved in the transaction. It sounds damaging if
499 numerous coins were involved. And it could run across transactions in
502 We fixed this by using a more uniform deterministic pseudo-random number
503 generator for blinding factors. I do not believe this to be a problem
504 for the rsa_full_domain_hash routine, but better safe than sorry.
509 * Compare the values of two signatures.
511 * @param s1 one signature
512 * @param s2 the other signature
513 * @return 0 if the two are equal
516 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
517 struct GNUNET_CRYPTO_RsaSignature *s2)
525 z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
527 z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
542 * Compare the values of two public keys.
544 * @param p1 one public key
545 * @param p2 the other public key
546 * @return 0 if the two are equal
549 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
550 struct GNUNET_CRYPTO_RsaPublicKey *p2)
558 z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
560 z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
575 * Compare the values of two private keys.
577 * @param p1 one private key
578 * @param p2 the other private key
579 * @return 0 if the two are equal
582 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
583 struct GNUNET_CRYPTO_RsaPrivateKey *p2)
591 z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
593 z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
608 * Obtain the length of the RSA key in bits.
610 * @param key the public key to introspect
611 * @return length of the key in bits
614 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
619 if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
620 { /* Not an RSA public key */
624 rval = gcry_mpi_get_nbits (n);
625 gcry_mpi_release (n);
631 * Destroy a blinding key
633 * @param bkey the blinding key to destroy
636 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
638 gcry_mpi_release (bkey->r);
644 * Print an MPI to a newly created buffer
646 * @param v MPI to print.
647 * @param[out] newly allocated buffer containing the result
648 * @return number of bytes stored in @a buffer
651 numeric_mpi_alloc_n_print (gcry_mpi_t v,
658 gcry_mpi_print (GCRYMPI_FMT_USG,
663 b = GNUNET_malloc (n);
665 gcry_mpi_print (GCRYMPI_FMT_USG,
676 * Computes a full domain hash seeded by the given public key.
677 * This gives a measure of provable security to the Taler exchange
678 * against one-more forgery attacks. See:
679 * https://eprint.iacr.org/2001/002.pdf
680 * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
682 * @param hash initial hash of the message to sign
683 * @param pkey the public key of the signer
684 * @param rsize If not NULL, the number of bytes actually stored in buffer
685 * @return MPI value set to the FDH, NULL if RSA key is malicious
688 rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
689 const struct GNUNET_HashCode *hash)
696 /* Extract the composite n from the RSA public key */
697 GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
698 /* Assert that it at least looks like an RSA key */
699 GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
701 /* We key with the public denomination key as a homage to RSA-PSS by *
702 * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
703 * of the hypothetical polyomial-time attack on RSA-KTI created by a *
704 * polynomial-time one-more forgary attack. Yey seeding! */
705 xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
707 GNUNET_CRYPTO_kdf_mod_mpi (&r,
714 ok = rsa_gcd_validate(r,n);
715 gcry_mpi_release (n);
718 gcry_mpi_release (r);
724 * Blinds the given message with the given blinding key
726 * @param hash hash of the message to sign
727 * @param bkey the blinding key
728 * @param pkey the public key of the signer
729 * @param[out] buf set to a buffer with the blinded message to be signed
730 * @param[out] buf_size number of bytes stored in @a buf
731 * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious
734 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
735 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
736 struct GNUNET_CRYPTO_RsaPublicKey *pkey,
737 char **buf, size_t *buf_size)
739 struct RsaBlindingKey *bkey;
746 BENCHMARK_START (rsa_blind);
748 GNUNET_assert (buf != NULL && buf_size != NULL);
749 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
751 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
760 data = rsa_full_domain_hash (pkey, hash);
762 goto rsa_gcd_validate_failure;
764 bkey = rsa_blinding_key_derive (pkey, bks);
766 gcry_mpi_release (data);
767 goto rsa_gcd_validate_failure;
770 r_e = gcry_mpi_new (0);
775 data_r_e = gcry_mpi_new (0);
776 gcry_mpi_mulm (data_r_e,
780 gcry_mpi_release (data);
781 gcry_mpi_release (ne[0]);
782 gcry_mpi_release (ne[1]);
783 gcry_mpi_release (r_e);
784 rsa_blinding_key_free (bkey);
786 *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf);
787 gcry_mpi_release (data_r_e);
789 BENCHMARK_END (rsa_blind);
793 rsa_gcd_validate_failure:
794 /* We know the RSA key is malicious here, so warn the wallet. */
795 /* GNUNET_break_op (0); */
796 gcry_mpi_release (ne[0]);
797 gcry_mpi_release (ne[1]);
805 * Convert an MPI to an S-expression suitable for signature operations.
807 * @param value pointer to the data to convert
808 * @return converted s-expression
811 mpi_to_sexp (gcry_mpi_t value)
813 gcry_sexp_t data = NULL;
816 gcry_sexp_build (&data,
818 "(data (flags raw) (value %M))",
825 * Sign the given MPI.
827 * @param key private key to use for the signing
828 * @param value the MPI to sign
829 * @return NULL on error, signature on success
831 static struct GNUNET_CRYPTO_RsaSignature *
832 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
835 struct GNUNET_CRYPTO_RsaSignature *sig;
840 data = mpi_to_sexp (value);
843 (rc = gcry_pk_sign (&result,
847 LOG (GNUNET_ERROR_TYPE_WARNING,
848 _("RSA signing failed at %s:%d: %s\n"),
856 /* Lenstra protection was first added to libgcrypt 1.6.4
857 * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
859 #if GCRYPT_VERSION_NUMBER < 0x010604
860 /* verify signature (guards against Lenstra's attack with fault injection...) */
861 struct GNUNET_CRYPTO_RsaPublicKey *public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
863 gcry_pk_verify (result,
868 GNUNET_CRYPTO_rsa_public_key_free (public_key);
869 gcry_sexp_release (data);
870 gcry_sexp_release (result);
873 GNUNET_CRYPTO_rsa_public_key_free (public_key);
876 /* return signature */
877 gcry_sexp_release (data);
878 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
885 * Sign a blinded value, which must be a full domain hash of a message.
887 * @param key private key to use for the signing
888 * @param msg the message to sign
889 * @param msg_len number of bytes in @a msg to sign
890 * @return NULL on error, signature on success
892 struct GNUNET_CRYPTO_RsaSignature *
893 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
898 struct GNUNET_CRYPTO_RsaSignature *sig;
900 BENCHMARK_START (rsa_sign_blinded);
909 sig = rsa_sign_mpi (key, v);
910 gcry_mpi_release (v);
911 BENCHMARK_END (rsa_sign_blinded);
917 * Create and sign a full domain hash of a message.
919 * @param key private key to use for the signing
920 * @param hash the hash of the message to sign
921 * @return NULL on error, including a malicious RSA key, signature on success
923 struct GNUNET_CRYPTO_RsaSignature *
924 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
925 const struct GNUNET_HashCode *hash)
927 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
929 struct GNUNET_CRYPTO_RsaSignature *sig;
931 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
932 v = rsa_full_domain_hash (pkey, hash);
933 GNUNET_CRYPTO_rsa_public_key_free (pkey);
934 if (NULL == v) /* rsa_gcd_validate failed meaning */
935 return NULL; /* our *own* RSA key is malicious. */
937 sig = rsa_sign_mpi (key, v);
938 gcry_mpi_release (v);
944 * Free memory occupied by signature.
946 * @param sig memory to freee
949 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
951 gcry_sexp_release (sig->sexp);
957 * Encode the given signature in a format suitable for storing it into a file.
959 * @param sig the signature
960 * @param[out] buffer set to a buffer with the encoded key
961 * @return size of memory allocated in @a buffer
964 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
970 n = gcry_sexp_sprint (sig->sexp,
971 GCRYSEXP_FMT_ADVANCED,
974 b = GNUNET_malloc (n);
975 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
976 gcry_sexp_sprint (sig->sexp,
977 GCRYSEXP_FMT_ADVANCED,
986 * Decode the signature from the data-format back to the "normal", internal
989 * @param buf the buffer where the public key data is stored
990 * @param len the length of the data in @a buf
991 * @return NULL on error
993 struct GNUNET_CRYPTO_RsaSignature *
994 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
997 struct GNUNET_CRYPTO_RsaSignature *sig;
1001 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1003 gcry_sexp_new (&sig->sexp,
1008 GNUNET_break_op (0);
1012 /* verify that this is an RSA signature */
1013 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1015 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1018 /* this is no RSA Signature */
1019 GNUNET_break_op (0);
1020 gcry_sexp_release (sig->sexp);
1024 gcry_mpi_release (s);
1030 * Duplicate the given public key
1032 * @param key the public key to duplicate
1033 * @return the duplicate key; NULL upon error
1035 struct GNUNET_CRYPTO_RsaPublicKey *
1036 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
1038 struct GNUNET_CRYPTO_RsaPublicKey *dup;
1039 gcry_sexp_t dup_sexp;
1042 /* check if we really are exporting a public key */
1043 dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1044 GNUNET_assert (NULL != dup_sexp);
1045 gcry_sexp_release (dup_sexp);
1047 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1048 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1049 dup->sexp = dup_sexp;
1055 * Unblind a blind-signed signature. The signature should have been generated
1056 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1057 * #GNUNET_CRYPTO_rsa_blind().
1059 * @param sig the signature made on the blinded signature purpose
1060 * @param bks the blinding key secret used to blind the signature purpose
1061 * @param pkey the public key of the signer
1062 * @return unblinded signature on success, NULL if RSA key is bad or malicious.
1064 struct GNUNET_CRYPTO_RsaSignature *
1065 GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig,
1066 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1067 struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1069 struct RsaBlindingKey *bkey;
1075 struct GNUNET_CRYPTO_RsaSignature *sret;
1077 BENCHMARK_START (rsa_unblind);
1079 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1081 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1084 GNUNET_break_op (0);
1087 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1089 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1092 gcry_mpi_release (n);
1093 GNUNET_break_op (0);
1097 bkey = rsa_blinding_key_derive (pkey, bks);
1100 /* RSA key is malicious since rsa_gcd_validate failed here.
1101 * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1102 * so the exchange is being malicious in an unfamilair way, maybe
1103 * just trying to crash us. */
1104 GNUNET_break_op (0);
1105 gcry_mpi_release (n);
1106 gcry_mpi_release (s);
1110 r_inv = gcry_mpi_new (0);
1112 gcry_mpi_invm (r_inv,
1116 /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1117 * caught above, but we handle it the same here. */
1118 GNUNET_break_op (0);
1119 gcry_mpi_release (r_inv);
1120 rsa_blinding_key_free (bkey);
1121 gcry_mpi_release (n);
1122 gcry_mpi_release (s);
1126 ubsig = gcry_mpi_new (0);
1127 gcry_mpi_mulm (ubsig, s, r_inv, n);
1128 gcry_mpi_release (n);
1129 gcry_mpi_release (r_inv);
1130 gcry_mpi_release (s);
1131 rsa_blinding_key_free (bkey);
1133 sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1135 gcry_sexp_build (&sret->sexp,
1137 "(sig-val (rsa (s %M)))",
1139 gcry_mpi_release (ubsig);
1140 BENCHMARK_END (rsa_unblind);
1146 * Verify whether the given hash corresponds to the given signature and
1147 * the signature is valid with respect to the given public key.
1149 * @param hash hash of the message to verify to match the @a sig
1150 * @param sig signature that is being validated
1151 * @param pkey public key of the signer
1152 * @returns #GNUNET_YES if ok, #GNUNET_NO if RSA key is malicious, #GNUNET_SYSERR if signature is invalid
1155 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1156 const struct GNUNET_CRYPTO_RsaSignature *sig,
1157 const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1163 BENCHMARK_START (rsa_verify);
1165 r = rsa_full_domain_hash (pkey, hash);
1167 GNUNET_break_op (0);
1168 /* RSA key is malicious since rsa_gcd_validate failed here.
1169 * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1170 * so the exchange is being malicious in an unfamilair way, maybe
1171 * just trying to crash us. Arguably, we've only an internal error
1172 * though because we should've detected this in our previous call
1173 * to GNUNET_CRYPTO_rsa_unblind. */
1177 data = mpi_to_sexp(r);
1178 gcry_mpi_release (r);
1180 rc = gcry_pk_verify (sig->sexp,
1183 gcry_sexp_release (data);
1186 LOG (GNUNET_ERROR_TYPE_WARNING,
1187 _("RSA signature verification failed at %s:%d: %s\n"),
1190 gcry_strerror (rc));
1191 return GNUNET_SYSERR;
1192 BENCHMARK_END (rsa_verify);
1194 BENCHMARK_END (rsa_verify);
1200 * Duplicate the given private key
1202 * @param key the private key to duplicate
1203 * @return the duplicate key; NULL upon error
1205 struct GNUNET_CRYPTO_RsaPrivateKey *
1206 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1208 struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1209 gcry_sexp_t dup_sexp;
1212 /* check if we really are exporting a private key */
1213 dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1214 GNUNET_assert (NULL != dup_sexp);
1215 gcry_sexp_release (dup_sexp);
1217 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1218 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1219 dup->sexp = dup_sexp;
1225 * Duplicate the given private key
1227 * @param key the private key to duplicate
1228 * @return the duplicate key; NULL upon error
1230 struct GNUNET_CRYPTO_RsaSignature *
1231 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1233 struct GNUNET_CRYPTO_RsaSignature *dup;
1234 gcry_sexp_t dup_sexp;
1239 /* verify that this is an RSA signature */
1240 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1242 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1243 GNUNET_assert (0 == ret);
1244 gcry_mpi_release (s);
1246 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1247 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1248 dup->sexp = dup_sexp;
1253 /* end of util/rsa.c */