2 This file is part of GNUnet
3 Copyright (C) 2014,2016,2019 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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file util/crypto_rsa.c
23 * @brief Chaum-style Blind signatures based on RSA
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25 * @author Christian Grothoff
26 * @author Jeffrey Burdges <burdges@gnunet.org>
30 #include "gnunet_crypto_lib.h"
31 #include "benchmark.h"
33 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
37 * The private information of an RSA key pair.
39 struct GNUNET_CRYPTO_RsaPrivateKey
42 * Libgcrypt S-expression for the RSA private key.
49 * The public information of an RSA key pair.
51 struct GNUNET_CRYPTO_RsaPublicKey
54 * Libgcrypt S-expression for the RSA public key.
61 * @brief an RSA signature
63 struct GNUNET_CRYPTO_RsaSignature
66 * Libgcrypt S-expression for the RSA signature.
73 * @brief RSA blinding key
78 * Random value used for blinding.
85 * Extract values from an S-expression.
87 * @param array where to store the result(s)
88 * @param sexp S-expression to parse
89 * @param topname top-level name in the S-expression that is of interest
90 * @param elems names of the elements to extract
91 * @return 0 on success
94 key_from_sexp (gcry_mpi_t *array,
104 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
106 l2 = gcry_sexp_cadr (list);
107 gcry_sexp_release (list);
112 for (s = elems; *s; s++, idx++)
114 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
116 for (unsigned int i = 0; i < idx; i++)
118 gcry_free (array[i]);
121 gcry_sexp_release (list);
122 return 3; /* required parameter not found */
124 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
125 gcry_sexp_release (l2);
128 for (unsigned int i = 0; i < idx; i++)
130 gcry_free (array[i]);
133 gcry_sexp_release (list);
134 return 4; /* required parameter is invalid */
137 gcry_sexp_release (list);
143 * Create a new private key. Caller must free return value.
145 * @param len length of the key in bits (i.e. 2048)
146 * @return fresh private key
148 struct GNUNET_CRYPTO_RsaPrivateKey *
149 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
151 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
153 gcry_sexp_t s_keyparam;
155 BENCHMARK_START (rsa_private_key_create);
158 gcry_sexp_build (&s_keyparam,
160 "(genkey(rsa(nbits %d)))",
163 gcry_pk_genkey (&s_key,
165 gcry_sexp_release (s_keyparam);
168 gcry_pk_testkey (s_key));
170 ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
172 BENCHMARK_END (rsa_private_key_create);
178 * Free memory occupied by the private key.
180 * @param key pointer to the memory to free
183 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
185 gcry_sexp_release (key->sexp);
191 * Encode the private key in a format suitable for
192 * storing it into a file.
194 * @param key the private key
195 * @param[out] buffer set to a buffer with the encoded key
196 * @return size of memory allocated in @a buffer
199 GNUNET_CRYPTO_rsa_private_key_encode (const struct
200 GNUNET_CRYPTO_RsaPrivateKey *key,
206 n = gcry_sexp_sprint (key->sexp,
207 GCRYSEXP_FMT_DEFAULT,
210 b = GNUNET_malloc (n);
211 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
212 gcry_sexp_sprint (key->sexp,
213 GCRYSEXP_FMT_DEFAULT,
222 * Decode the private key from the data-format back
223 * to the "normal", internal format.
225 * @param buf the buffer where the private key data is stored
226 * @param len the length of the data in @a buf
227 * @return NULL on error
229 struct GNUNET_CRYPTO_RsaPrivateKey *
230 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
233 struct GNUNET_CRYPTO_RsaPrivateKey *key;
235 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
237 gcry_sexp_new (&key->sexp,
242 LOG (GNUNET_ERROR_TYPE_WARNING,
243 "Decoded private key is not valid\n");
247 if (0 != gcry_pk_testkey (key->sexp))
249 LOG (GNUNET_ERROR_TYPE_WARNING,
250 "Decoded private key is not valid\n");
251 GNUNET_CRYPTO_rsa_private_key_free (key);
259 * Extract the public key of the given private key.
261 * @param priv the private key
262 * @retur NULL on error, otherwise the public key
264 struct GNUNET_CRYPTO_RsaPublicKey *
265 GNUNET_CRYPTO_rsa_private_key_get_public (const struct
266 GNUNET_CRYPTO_RsaPrivateKey *priv)
268 struct GNUNET_CRYPTO_RsaPublicKey *pub;
273 BENCHMARK_START (rsa_private_key_get_public);
275 rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
277 rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
279 rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
285 rc = gcry_sexp_build (&result,
287 "(public-key(rsa(n %m)(e %m)))",
290 gcry_mpi_release (ne[0]);
291 gcry_mpi_release (ne[1]);
292 pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
294 BENCHMARK_END (rsa_private_key_get_public);
300 * Free memory occupied by the public key.
302 * @param key pointer to the memory to free
305 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
307 gcry_sexp_release (key->sexp);
312 GNUNET_NETWORK_STRUCT_BEGIN
315 * Format of the header of a serialized RSA public key.
317 struct GNUNET_CRYPTO_RsaPublicKeyHeaderP
320 * length of modulus 'n' in bytes, in NBO
322 uint16_t modulus_length GNUNET_PACKED;
325 * length of exponent in bytes, in NBO
327 uint16_t public_exponent_length GNUNET_PACKED;
329 /* followed by variable-size modulus and
330 public exponent follows as big-endian encoded
334 GNUNET_NETWORK_STRUCT_END
338 * Encode the public key in a format suitable for
339 * storing it into a file.
341 * @param key the private key
342 * @param[out] buffer set to a buffer with the encoded key
343 * @return size of memory allocated in @a buffer
346 GNUNET_CRYPTO_rsa_public_key_encode (const struct
347 GNUNET_CRYPTO_RsaPublicKey *key,
356 struct GNUNET_CRYPTO_RsaPublicKeyHeaderP hdr;
359 ret = key_from_sexp (ne, key->sexp, "public-key", "ne");
361 ret = key_from_sexp (ne, key->sexp, "rsa", "ne");
368 gcry_mpi_print (GCRYMPI_FMT_USG,
373 gcry_mpi_print (GCRYMPI_FMT_USG,
378 if ( (e_size > UINT16_MAX) ||
379 (n_size > UINT16_MAX) )
383 gcry_mpi_release (ne[0]);
384 gcry_mpi_release (ne[1]);
387 buf_size = n_size + e_size + sizeof (hdr);
388 buf = GNUNET_malloc (buf_size);
389 hdr.modulus_length = htons ((uint16_t) n_size);
390 hdr.public_exponent_length = htons ((uint16_t) e_size);
391 memcpy (buf, &hdr, sizeof (hdr));
393 gcry_mpi_print (GCRYMPI_FMT_USG,
394 (unsigned char *) &buf[sizeof (hdr)],
400 gcry_mpi_print (GCRYMPI_FMT_USG,
401 (unsigned char *) &buf[sizeof (hdr) + n_size],
406 gcry_mpi_release (ne[0]);
407 gcry_mpi_release (ne[1]);
413 * Compute hash over the public key.
415 * @param key public key to hash
416 * @param hc where to store the hash code
419 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
420 struct GNUNET_HashCode *hc)
425 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
427 GNUNET_CRYPTO_hash (buf,
435 * Decode the public key from the data-format back
436 * to the "normal", internal format.
438 * @param buf the buffer where the public key data is stored
439 * @param len the length of the data in @a buf
440 * @return NULL on error
442 struct GNUNET_CRYPTO_RsaPublicKey *
443 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
446 struct GNUNET_CRYPTO_RsaPublicKey *key;
447 struct GNUNET_CRYPTO_RsaPublicKeyHeaderP hdr;
454 if (len < sizeof (hdr))
459 memcpy (&hdr, buf, sizeof (hdr));
460 n_size = ntohs (hdr.modulus_length);
461 e_size = ntohs (hdr.public_exponent_length);
462 if (len != sizeof (hdr) + e_size + n_size)
480 &buf[sizeof (hdr) + n_size],
485 gcry_mpi_release (n);
490 gcry_sexp_build (&data,
492 "(public-key(rsa(n %m)(e %m)))",
497 gcry_mpi_release (n);
498 gcry_mpi_release (e);
501 gcry_mpi_release (n);
502 gcry_mpi_release (e);
503 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
510 * Test for malicious RSA key.
512 * Assuming n is an RSA modulous and r is generated using a call to
513 * GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a
514 * malicious RSA key designed to deanomize the user.
516 * @param r KDF result
517 * @param n RSA modulus
518 * @return True if gcd(r,n) = 1, False means RSA key is malicious
521 rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n)
526 g = gcry_mpi_new (0);
527 t = gcry_mpi_gcd (g, r, n);
528 gcry_mpi_release (g);
534 * Create a blinding key
536 * @param len length of the key in bits (i.e. 2048)
537 * @param bks pre-secret to use to derive the blinding key
538 * @return the newly created blinding key, NULL if RSA key is malicious
540 static struct RsaBlindingKey *
541 rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
542 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
544 char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */
545 struct RsaBlindingKey *blind;
548 blind = GNUNET_new (struct RsaBlindingKey);
549 GNUNET_assert (NULL != blind);
551 /* Extract the composite n from the RSA public key */
552 GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
553 /* Assert that it at least looks like an RSA key */
554 GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
556 GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
561 if (0 == rsa_gcd_validate (blind->r, n))
567 gcry_mpi_release (n);
573 We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
576 There was previously a call to GNUNET_CRYPTO_kdf in
577 bkey = rsa_blinding_key_derive (len, bks);
578 that gives exactly len bits where
579 len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
581 Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
582 okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
583 pkey.n making the effective bkey be
584 bkey mod pkey.n = bkey - pkey.n
585 so the effective bkey has its high bit set with probability r/2.
587 We expect r to be close to 1/2 if the exchange is honest, but the
588 exchange can choose r otherwise.
590 In blind signing, the exchange sees
591 B = bkey * S mod pkey.n
592 On deposit, the exchange sees S so they can compute bkey' = B/S mod
593 pkey.n for all B they recorded to see if bkey' has it's high bit set.
594 Also, note the exchange can compute 1/S efficiently since they know the
597 I suppose that happens with probability r/(1+r) if its the wrong B, not
598 completely sure. If otoh we've the right B, then we've the probability
599 r/2 of a set high bit in the effective bkey.
601 Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
602 the wrong and right probabilities 1/3 and 1/4, respectively.
604 I feared this gives the exchange a meaningful fraction of a bit of
605 information per coin involved in the transaction. It sounds damaging if
606 numerous coins were involved. And it could run across transactions in
609 We fixed this by using a more uniform deterministic pseudo-random number
610 generator for blinding factors. I do not believe this to be a problem
611 for the rsa_full_domain_hash routine, but better safe than sorry.
616 * Compare the values of two signatures.
618 * @param s1 one signature
619 * @param s2 the other signature
620 * @return 0 if the two are equal
623 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
624 struct GNUNET_CRYPTO_RsaSignature *s2)
632 z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
634 z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
649 * Compare the values of two public keys.
651 * @param p1 one public key
652 * @param p2 the other public key
653 * @return 0 if the two are equal
656 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
657 struct GNUNET_CRYPTO_RsaPublicKey *p2)
665 z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
667 z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
682 * Compare the values of two private keys.
684 * @param p1 one private key
685 * @param p2 the other private key
686 * @return 0 if the two are equal
689 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
690 struct GNUNET_CRYPTO_RsaPrivateKey *p2)
698 z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
700 z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
715 * Obtain the length of the RSA key in bits.
717 * @param key the public key to introspect
718 * @return length of the key in bits
721 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
726 if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
727 { /* Not an RSA public key */
731 rval = gcry_mpi_get_nbits (n);
732 gcry_mpi_release (n);
738 * Destroy a blinding key
740 * @param bkey the blinding key to destroy
743 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
745 gcry_mpi_release (bkey->r);
751 * Print an MPI to a newly created buffer
753 * @param v MPI to print.
754 * @param[out] newly allocated buffer containing the result
755 * @return number of bytes stored in @a buffer
758 numeric_mpi_alloc_n_print (gcry_mpi_t v,
765 gcry_mpi_print (GCRYMPI_FMT_USG,
770 b = GNUNET_malloc (n);
772 gcry_mpi_print (GCRYMPI_FMT_USG,
783 * Computes a full domain hash seeded by the given public key.
784 * This gives a measure of provable security to the Taler exchange
785 * against one-more forgery attacks. See:
786 * https://eprint.iacr.org/2001/002.pdf
787 * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
789 * @param hash initial hash of the message to sign
790 * @param pkey the public key of the signer
791 * @param rsize If not NULL, the number of bytes actually stored in buffer
792 * @return MPI value set to the FDH, NULL if RSA key is malicious
795 rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
796 const struct GNUNET_HashCode *hash)
803 /* Extract the composite n from the RSA public key */
804 GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
805 /* Assert that it at least looks like an RSA key */
806 GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
808 /* We key with the public denomination key as a homage to RSA-PSS by *
809 * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
810 * of the hypothetical polyomial-time attack on RSA-KTI created by a *
811 * polynomial-time one-more forgary attack. Yey seeding! */
812 xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
814 GNUNET_CRYPTO_kdf_mod_mpi (&r,
821 ok = rsa_gcd_validate (r, n);
822 gcry_mpi_release (n);
825 gcry_mpi_release (r);
831 * Blinds the given message with the given blinding key
833 * @param hash hash of the message to sign
834 * @param bkey the blinding key
835 * @param pkey the public key of the signer
836 * @param[out] buf set to a buffer with the blinded message to be signed
837 * @param[out] buf_size number of bytes stored in @a buf
838 * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious
841 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
842 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
843 struct GNUNET_CRYPTO_RsaPublicKey *pkey,
844 char **buf, size_t *buf_size)
846 struct RsaBlindingKey *bkey;
853 BENCHMARK_START (rsa_blind);
855 GNUNET_assert (buf != NULL && buf_size != NULL);
856 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
858 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
867 data = rsa_full_domain_hash (pkey, hash);
869 goto rsa_gcd_validate_failure;
871 bkey = rsa_blinding_key_derive (pkey, bks);
874 gcry_mpi_release (data);
875 goto rsa_gcd_validate_failure;
878 r_e = gcry_mpi_new (0);
883 data_r_e = gcry_mpi_new (0);
884 gcry_mpi_mulm (data_r_e,
888 gcry_mpi_release (data);
889 gcry_mpi_release (ne[0]);
890 gcry_mpi_release (ne[1]);
891 gcry_mpi_release (r_e);
892 rsa_blinding_key_free (bkey);
894 *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf);
895 gcry_mpi_release (data_r_e);
897 BENCHMARK_END (rsa_blind);
901 rsa_gcd_validate_failure:
902 /* We know the RSA key is malicious here, so warn the wallet. */
903 /* GNUNET_break_op (0); */
904 gcry_mpi_release (ne[0]);
905 gcry_mpi_release (ne[1]);
913 * Convert an MPI to an S-expression suitable for signature operations.
915 * @param value pointer to the data to convert
916 * @return converted s-expression
919 mpi_to_sexp (gcry_mpi_t value)
921 gcry_sexp_t data = NULL;
924 gcry_sexp_build (&data,
926 "(data (flags raw) (value %M))",
933 * Sign the given MPI.
935 * @param key private key to use for the signing
936 * @param value the MPI to sign
937 * @return NULL on error, signature on success
939 static struct GNUNET_CRYPTO_RsaSignature *
940 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
943 struct GNUNET_CRYPTO_RsaSignature *sig;
948 data = mpi_to_sexp (value);
951 (rc = gcry_pk_sign (&result,
955 LOG (GNUNET_ERROR_TYPE_WARNING,
956 _ ("RSA signing failed at %s:%d: %s\n"),
964 /* Lenstra protection was first added to libgcrypt 1.6.4
965 * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
967 #if GCRYPT_VERSION_NUMBER < 0x010604
968 /* verify signature (guards against Lenstra's attack with fault injection...) */
969 struct GNUNET_CRYPTO_RsaPublicKey *public_key =
970 GNUNET_CRYPTO_rsa_private_key_get_public (key);
972 gcry_pk_verify (result,
977 GNUNET_CRYPTO_rsa_public_key_free (public_key);
978 gcry_sexp_release (data);
979 gcry_sexp_release (result);
982 GNUNET_CRYPTO_rsa_public_key_free (public_key);
985 /* return signature */
986 gcry_sexp_release (data);
987 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
994 * Sign a blinded value, which must be a full domain hash of a message.
996 * @param key private key to use for the signing
997 * @param msg the message to sign
998 * @param msg_len number of bytes in @a msg to sign
999 * @return NULL on error, signature on success
1001 struct GNUNET_CRYPTO_RsaSignature *
1002 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
1006 gcry_mpi_t v = NULL;
1007 struct GNUNET_CRYPTO_RsaSignature *sig;
1009 BENCHMARK_START (rsa_sign_blinded);
1018 sig = rsa_sign_mpi (key, v);
1019 gcry_mpi_release (v);
1020 BENCHMARK_END (rsa_sign_blinded);
1026 * Create and sign a full domain hash of a message.
1028 * @param key private key to use for the signing
1029 * @param hash the hash of the message to sign
1030 * @return NULL on error, including a malicious RSA key, signature on success
1032 struct GNUNET_CRYPTO_RsaSignature *
1033 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
1034 const struct GNUNET_HashCode *hash)
1036 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
1037 gcry_mpi_t v = NULL;
1038 struct GNUNET_CRYPTO_RsaSignature *sig;
1040 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
1041 v = rsa_full_domain_hash (pkey, hash);
1042 GNUNET_CRYPTO_rsa_public_key_free (pkey);
1043 if (NULL == v) /* rsa_gcd_validate failed meaning */
1044 return NULL; /* our *own* RSA key is malicious. */
1046 sig = rsa_sign_mpi (key, v);
1047 gcry_mpi_release (v);
1053 * Free memory occupied by signature.
1055 * @param sig memory to freee
1058 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
1060 gcry_sexp_release (sig->sexp);
1066 * Encode the given signature in a format suitable for storing it into a file.
1068 * @param sig the signature
1069 * @param[out] buffer set to a buffer with the encoded key
1070 * @return size of memory allocated in @a buffer
1073 GNUNET_CRYPTO_rsa_signature_encode (const struct
1074 GNUNET_CRYPTO_RsaSignature *sig,
1083 ret = key_from_sexp (&s,
1088 ret = key_from_sexp (&s,
1092 GNUNET_assert (0 == ret);
1093 gcry_mpi_print (GCRYMPI_FMT_USG,
1098 buf = GNUNET_malloc (buf_size);
1100 gcry_mpi_print (GCRYMPI_FMT_USG,
1105 GNUNET_assert (rsize == buf_size);
1106 *buffer = (char *) buf;
1112 * Decode the signature from the data-format back to the "normal", internal
1115 * @param buf the buffer where the public key data is stored
1116 * @param len the length of the data in @a buf
1117 * @return NULL on error
1119 struct GNUNET_CRYPTO_RsaSignature *
1120 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
1123 struct GNUNET_CRYPTO_RsaSignature *sig;
1134 GNUNET_break_op (0);
1139 gcry_sexp_build (&data,
1141 "(sig-val(rsa(s %M)))",
1145 gcry_mpi_release (s);
1148 gcry_mpi_release (s);
1149 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1156 * Duplicate the given public key
1158 * @param key the public key to duplicate
1159 * @return the duplicate key; NULL upon error
1161 struct GNUNET_CRYPTO_RsaPublicKey *
1162 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
1164 struct GNUNET_CRYPTO_RsaPublicKey *dup;
1165 gcry_sexp_t dup_sexp;
1168 /* check if we really are exporting a public key */
1169 dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1170 GNUNET_assert (NULL != dup_sexp);
1171 gcry_sexp_release (dup_sexp);
1173 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1174 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1175 dup->sexp = dup_sexp;
1181 * Unblind a blind-signed signature. The signature should have been generated
1182 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1183 * #GNUNET_CRYPTO_rsa_blind().
1185 * @param sig the signature made on the blinded signature purpose
1186 * @param bks the blinding key secret used to blind the signature purpose
1187 * @param pkey the public key of the signer
1188 * @return unblinded signature on success, NULL if RSA key is bad or malicious.
1190 struct GNUNET_CRYPTO_RsaSignature *
1191 GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig,
1192 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1193 struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1195 struct RsaBlindingKey *bkey;
1201 struct GNUNET_CRYPTO_RsaSignature *sret;
1203 BENCHMARK_START (rsa_unblind);
1205 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1207 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1210 GNUNET_break_op (0);
1213 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1215 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1218 gcry_mpi_release (n);
1219 GNUNET_break_op (0);
1223 bkey = rsa_blinding_key_derive (pkey, bks);
1226 /* RSA key is malicious since rsa_gcd_validate failed here.
1227 * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1228 * so the exchange is being malicious in an unfamilair way, maybe
1229 * just trying to crash us. */
1230 GNUNET_break_op (0);
1231 gcry_mpi_release (n);
1232 gcry_mpi_release (s);
1236 r_inv = gcry_mpi_new (0);
1238 gcry_mpi_invm (r_inv,
1242 /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1243 * caught above, but we handle it the same here. */
1244 GNUNET_break_op (0);
1245 gcry_mpi_release (r_inv);
1246 rsa_blinding_key_free (bkey);
1247 gcry_mpi_release (n);
1248 gcry_mpi_release (s);
1252 ubsig = gcry_mpi_new (0);
1253 gcry_mpi_mulm (ubsig, s, r_inv, n);
1254 gcry_mpi_release (n);
1255 gcry_mpi_release (r_inv);
1256 gcry_mpi_release (s);
1257 rsa_blinding_key_free (bkey);
1259 sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1261 gcry_sexp_build (&sret->sexp,
1263 "(sig-val (rsa (s %M)))",
1265 gcry_mpi_release (ubsig);
1266 BENCHMARK_END (rsa_unblind);
1272 * Verify whether the given hash corresponds to the given signature and
1273 * the signature is valid with respect to the given public key.
1275 * @param hash hash of the message to verify to match the @a sig
1276 * @param sig signature that is being validated
1277 * @param pkey public key of the signer
1278 * @returns #GNUNET_YES if ok, #GNUNET_NO if RSA key is malicious, #GNUNET_SYSERR if signature is invalid
1281 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1282 const struct GNUNET_CRYPTO_RsaSignature *sig,
1283 const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1289 BENCHMARK_START (rsa_verify);
1291 r = rsa_full_domain_hash (pkey, hash);
1294 GNUNET_break_op (0);
1295 /* RSA key is malicious since rsa_gcd_validate failed here.
1296 * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1297 * so the exchange is being malicious in an unfamilair way, maybe
1298 * just trying to crash us. Arguably, we've only an internal error
1299 * though because we should've detected this in our previous call
1300 * to GNUNET_CRYPTO_rsa_unblind. */return GNUNET_NO;
1303 data = mpi_to_sexp (r);
1304 gcry_mpi_release (r);
1306 rc = gcry_pk_verify (sig->sexp,
1309 gcry_sexp_release (data);
1312 LOG (GNUNET_ERROR_TYPE_WARNING,
1313 _ ("RSA signature verification failed at %s:%d: %s\n"),
1316 gcry_strerror (rc));
1317 return GNUNET_SYSERR;
1318 BENCHMARK_END (rsa_verify);
1320 BENCHMARK_END (rsa_verify);
1326 * Duplicate the given private key
1328 * @param key the private key to duplicate
1329 * @return the duplicate key; NULL upon error
1331 struct GNUNET_CRYPTO_RsaPrivateKey *
1332 GNUNET_CRYPTO_rsa_private_key_dup (const struct
1333 GNUNET_CRYPTO_RsaPrivateKey *key)
1335 struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1336 gcry_sexp_t dup_sexp;
1339 /* check if we really are exporting a private key */
1340 dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1341 GNUNET_assert (NULL != dup_sexp);
1342 gcry_sexp_release (dup_sexp);
1344 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1345 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1346 dup->sexp = dup_sexp;
1352 * Duplicate the given private key
1354 * @param key the private key to duplicate
1355 * @return the duplicate key; NULL upon error
1357 struct GNUNET_CRYPTO_RsaSignature *
1358 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1360 struct GNUNET_CRYPTO_RsaSignature *dup;
1361 gcry_sexp_t dup_sexp;
1366 /* verify that this is an RSA signature */
1367 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1369 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1370 GNUNET_assert (0 == ret);
1371 gcry_mpi_release (s);
1373 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1374 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1375 dup->sexp = dup_sexp;
1380 /* end of util/rsa.c */