2 This file is part of GNUnet
3 (C) 2014 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
18 * @file util/crypto_rsa.c
19 * @brief Chaum-style Blind signatures based on RSA
20 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
21 * @author Christian Grothoff
25 #include "gnunet_util_lib.h"
27 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
31 * The private information of an RSA key pair.
33 struct GNUNET_CRYPTO_rsa_PrivateKey
36 * Libgcrypt S-expression for the RSA private key.
43 * The public information of an RSA key pair.
45 struct GNUNET_CRYPTO_rsa_PublicKey
48 * Libgcrypt S-expression for the RSA public key.
55 * @brief an RSA signature
57 struct GNUNET_CRYPTO_rsa_Signature
60 * Libgcrypt S-expression for the RSA signature.
67 * @brief RSA blinding key
69 struct GNUNET_CRYPTO_rsa_BlindingKey
72 * Random value used for blinding.
79 * Extract values from an S-expression.
81 * @param array where to store the result(s)
82 * @param sexp S-expression to parse
83 * @param topname top-level name in the S-expression that is of interest
84 * @param elems names of the elements to extract
85 * @return 0 on success
88 key_from_sexp (gcry_mpi_t *array,
99 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
101 l2 = gcry_sexp_cadr (list);
102 gcry_sexp_release (list);
107 for (s = elems; *s; s++, idx++)
109 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
111 for (i = 0; i < idx; i++)
113 gcry_free (array[i]);
116 gcry_sexp_release (list);
117 return 3; /* required parameter not found */
119 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
120 gcry_sexp_release (l2);
123 for (i = 0; i < idx; i++)
125 gcry_free (array[i]);
128 gcry_sexp_release (list);
129 return 4; /* required parameter is invalid */
132 gcry_sexp_release (list);
138 * Create a new private key. Caller must free return value.
140 * @param len length of the key in bits (i.e. 2048)
141 * @return fresh private key
143 struct GNUNET_CRYPTO_rsa_PrivateKey *
144 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
146 struct GNUNET_CRYPTO_rsa_PrivateKey *ret;
148 gcry_sexp_t s_keyparam;
151 gcry_sexp_build (&s_keyparam,
153 "(genkey(rsa(nbits %d)))",
156 gcry_pk_genkey (&s_key,
158 gcry_sexp_release (s_keyparam);
161 gcry_pk_testkey (s_key));
163 ret = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
170 * Free memory occupied by the private key.
172 * @param key pointer to the memory to free
175 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_rsa_PrivateKey *key)
177 gcry_sexp_release (key->sexp);
183 * Encode the private key in a format suitable for
184 * storing it into a file.
186 * @param key the private key
187 * @param[out] buffer set to a buffer with the encoded key
188 * @return size of memory allocated in @a buffer
191 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
197 n = gcry_sexp_sprint (key->sexp,
198 GCRYSEXP_FMT_DEFAULT,
201 b = GNUNET_malloc (n);
203 gcry_sexp_sprint (key->sexp,
204 GCRYSEXP_FMT_DEFAULT,
213 * Decode the private key from the data-format back
214 * to the "normal", internal format.
216 * @param buf the buffer where the private key data is stored
217 * @param len the length of the data in @a buf
218 * @return NULL on error
220 struct GNUNET_CRYPTO_rsa_PrivateKey *
221 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
224 struct GNUNET_CRYPTO_rsa_PrivateKey *key;
226 key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
228 gcry_sexp_new (&key->sexp,
237 /* FIXME: verify that this is an RSA private key */
243 * Extract the public key of the given private key.
245 * @param priv the private key
246 * @retur NULL on error, otherwise the public key
248 struct GNUNET_CRYPTO_rsa_PublicKey *
249 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_rsa_PrivateKey *priv)
251 struct GNUNET_CRYPTO_rsa_PublicKey *pub;
256 rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
258 rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
260 rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
266 rc = gcry_sexp_build (&result,
268 "(public-key(rsa(n %m)(e %m)))",
271 gcry_mpi_release (ne[0]);
272 gcry_mpi_release (ne[1]);
273 pub = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
280 * Free memory occupied by the public key.
282 * @param key pointer to the memory to free
285 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_rsa_PublicKey *key)
287 gcry_sexp_release (key->sexp);
293 * Encode the public key in a format suitable for
294 * storing it into a file.
296 * @param key the private key
297 * @param[out] buffer set to a buffer with the encoded key
298 * @return size of memory allocated in @a buffer
301 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
307 n = gcry_sexp_sprint (key->sexp,
308 GCRYSEXP_FMT_ADVANCED,
311 b = GNUNET_malloc (n);
313 gcry_sexp_sprint (key->sexp,
314 GCRYSEXP_FMT_ADVANCED,
323 * Decode the public key from the data-format back
324 * to the "normal", internal format.
326 * @param buf the buffer where the public key data is stored
327 * @param len the length of the data in @a buf
328 * @return NULL on error
330 struct GNUNET_CRYPTO_rsa_PublicKey *
331 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
334 struct GNUNET_CRYPTO_rsa_PublicKey *key;
338 key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
340 gcry_sexp_new (&key->sexp,
349 /* verify that this is an RSA public key */
350 ret = key_from_sexp (&n, key->sexp, "public-key", "n");
352 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
355 /* this is no public RSA key */
357 gcry_sexp_release (key->sexp);
361 gcry_mpi_release (n);
367 * Create a blinding key
369 * @param len length of the key in bits (i.e. 2048)
370 * @return the newly created blinding key
372 struct GNUNET_CRYPTO_rsa_BlindingKey *
373 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
375 struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
377 blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
378 blind->r = gcry_mpi_new (len);
379 gcry_mpi_randomize (blind->r,
387 * Destroy a blinding key
389 * @param bkey the blinding key to destroy
392 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
394 gcry_mpi_release (bkey->r);
400 * Encode the blinding key in a format suitable for
401 * storing it into a file.
403 * @param bkey the blinding key
404 * @param[out] buffer set to a buffer with the encoded key
405 * @return size of memory allocated in @a buffer
408 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
415 gcry_mpi_print (GCRYMPI_FMT_USG,
420 b = GNUNET_malloc (n);
422 gcry_mpi_print (GCRYMPI_FMT_USG,
433 * Decode the blinding key from the data-format back
434 * to the "normal", internal format.
436 * @param buf the buffer where the public key data is stored
437 * @param len the length of the data in @a buf
438 * @return NULL on error
440 struct GNUNET_CRYPTO_rsa_BlindingKey *
441 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
444 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
447 bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
449 gcry_mpi_scan (&bkey->r,
451 (const unsigned char *) buf,
464 * Blinds the given message with the given blinding key
466 * @param hash hash of the message to sign
467 * @param bkey the blinding key
468 * @param pkey the public key of the signer
469 * @param[out] buffer set to a buffer with the blinded message to be signed
470 * @return number of bytes stored in @a buffer
473 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
474 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
475 struct GNUNET_CRYPTO_rsa_PublicKey *pkey,
488 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
490 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
497 if (0 != (rc = gcry_mpi_scan (&data,
499 (const unsigned char *) hash,
500 sizeof (struct GNUNET_HashCode),
504 gcry_mpi_release (ne[0]);
505 gcry_mpi_release (ne[1]);
509 r_e = gcry_mpi_new (0);
514 data_r_e = gcry_mpi_new (0);
515 gcry_mpi_mulm (data_r_e,
519 gcry_mpi_release (ne[0]);
520 gcry_mpi_release (ne[1]);
521 gcry_mpi_release (r_e);
523 gcry_mpi_print (GCRYMPI_FMT_USG,
528 b = GNUNET_malloc (n);
529 rc = gcry_mpi_print (GCRYMPI_FMT_USG,
534 gcry_mpi_release (data_r_e);
541 * Convert the data specified in the given purpose argument to an
542 * S-expression suitable for signature operations.
544 * @param ptr pointer to the data to convert
545 * @param size the size of the data
546 * @return converted s-expression
549 data_to_sexp (const void *ptr, size_t size)
557 gcry_mpi_scan (&value,
563 gcry_sexp_build (&data,
565 "(data (flags raw) (value %M))",
567 gcry_mpi_release (value);
573 * Sign the given message.
575 * @param key private key to use for the signing
576 * @param msg the message to sign
577 * @param msg_len number of bytes in @a msg to sign
578 * @return NULL on error, signature on success
580 struct GNUNET_CRYPTO_rsa_Signature *
581 GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
585 struct GNUNET_CRYPTO_rsa_Signature *sig;
589 data = data_to_sexp (msg,
592 gcry_pk_sign (&result,
599 gcry_sexp_release (data);
600 sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
607 * Free memory occupied by signature.
609 * @param sig memory to freee
612 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_rsa_Signature *sig)
614 gcry_sexp_release (sig->sexp);
620 * Encode the signature key in a format suitable for
621 * storing it into a file.
623 * @param sig the signature
624 * @param[out] buffer set to a buffer with the encoded key
625 * @return size of memory allocated in @a buffer
628 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_rsa_Signature *sig,
634 n = gcry_sexp_sprint (sig->sexp,
635 GCRYSEXP_FMT_ADVANCED,
638 b = GNUNET_malloc (n);
640 gcry_sexp_sprint (sig->sexp,
641 GCRYSEXP_FMT_ADVANCED,
650 * Decode the public key from the data-format back
651 * to the "normal", internal format.
653 * @param buf the buffer where the public key data is stored
654 * @param len the length of the data in @a buf
655 * @return NULL on error
657 struct GNUNET_CRYPTO_rsa_Signature *
658 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
661 struct GNUNET_CRYPTO_rsa_Signature *sig;
665 sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
667 gcry_sexp_new (&sig->sexp,
676 /* verify that this is an RSA signature */
677 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
679 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
682 /* this is no RSA Signature */
684 gcry_sexp_release (sig->sexp);
688 gcry_mpi_release (s);
694 * Unblind a signature made on blinding signature purpose. The signature
695 * purpose should have been generated with #GNUNET_CRYPTO_rsa_sign() using
696 * a message that was generated with #GNUNET_CRYPTO_rsa_blind().
698 * @param sig the signature made on the blinded signature purpose
699 * @param bkey the blinding key used to blind the signature purpose
700 * @param pkey the public key of the signer
701 * @return unblinded signature on success, NULL on error
703 struct GNUNET_CRYPTO_rsa_Signature *
704 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
705 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
706 struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
713 struct GNUNET_CRYPTO_rsa_Signature *sret;
715 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
717 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
723 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
725 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
728 gcry_mpi_release (n);
732 r_inv = gcry_mpi_new (0);
734 gcry_mpi_invm (r_inv,
739 gcry_mpi_release (n);
740 gcry_mpi_release (r_inv);
741 gcry_mpi_release (s);
744 ubsig = gcry_mpi_new (0);
745 gcry_mpi_mulm (ubsig, s, r_inv, n);
746 gcry_mpi_release (n);
747 gcry_mpi_release (r_inv);
748 gcry_mpi_release (s);
750 sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
752 gcry_sexp_build (&sret->sexp,
754 "(sig-val (rsa (s %M)))",
756 gcry_mpi_release (ubsig);
762 * Verify signature with the given hash.
764 * @param hash hash of the message to verify to match the @a sig
765 * @param sig signature that is being validated
766 * @param public_key public key of the signer
767 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
770 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
771 const struct GNUNET_CRYPTO_rsa_Signature *sig,
772 const struct GNUNET_CRYPTO_rsa_PublicKey *public_key)
777 data = data_to_sexp (hash,
778 sizeof (struct GNUNET_HashCode));
779 rc = gcry_pk_verify (sig->sexp,
782 gcry_sexp_release (data);
785 LOG (GNUNET_ERROR_TYPE_WARNING,
786 _("RSA signature verification failed at %s:%d: %s\n"),
790 return GNUNET_SYSERR;
796 /* end of util/rsa.c */