Use a uniform random number mod an RSA composites for both
[oweals/gnunet.git] / src / util / crypto_rsa.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014,2016 GNUnet e.V.
4
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.
8
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.
12
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/>
15 */
16
17 /**
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
22  * @author Jeffrey Burdges <burdges@gnunet.org>
23  */
24 #include "platform.h"
25 #include <gcrypt.h>
26 #include "gnunet_crypto_lib.h"
27
28 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
29
30
31 /**
32  * The private information of an RSA key pair.
33  */
34 struct GNUNET_CRYPTO_RsaPrivateKey
35 {
36   /**
37    * Libgcrypt S-expression for the RSA private key.
38    */
39   gcry_sexp_t sexp;
40 };
41
42
43 /**
44  * The public information of an RSA key pair.
45  */
46 struct GNUNET_CRYPTO_RsaPublicKey
47 {
48   /**
49    * Libgcrypt S-expression for the RSA public key.
50    */
51   gcry_sexp_t sexp;
52 };
53
54
55 /**
56  * @brief an RSA signature
57  */
58 struct GNUNET_CRYPTO_RsaSignature
59 {
60   /**
61    * Libgcrypt S-expression for the RSA signature.
62    */
63   gcry_sexp_t sexp;
64 };
65
66
67 /**
68  * @brief RSA blinding key
69  */
70 struct RsaBlindingKey
71 {
72   /**
73    * Random value used for blinding.
74    */
75   gcry_mpi_t r;
76 };
77
78
79 /**
80  * Extract values from an S-expression.
81  *
82  * @param array where to store the result(s)
83  * @param sexp S-expression to parse
84  * @param topname top-level name in the S-expression that is of interest
85  * @param elems names of the elements to extract
86  * @return 0 on success
87  */
88 static int
89 key_from_sexp (gcry_mpi_t *array,
90                gcry_sexp_t sexp,
91                const char *topname,
92                const char *elems)
93 {
94   gcry_sexp_t list;
95   gcry_sexp_t l2;
96   const char *s;
97   unsigned int i;
98   unsigned int idx;
99
100   if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
101     return 1;
102   l2 = gcry_sexp_cadr (list);
103   gcry_sexp_release (list);
104   list = l2;
105   if (! list)
106     return 2;
107   idx = 0;
108   for (s = elems; *s; s++, idx++)
109   {
110     if (! (l2 = gcry_sexp_find_token (list, s, 1)))
111     {
112       for (i = 0; i < idx; i++)
113       {
114         gcry_free (array[i]);
115         array[i] = NULL;
116       }
117       gcry_sexp_release (list);
118       return 3;                 /* required parameter not found */
119     }
120     array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
121     gcry_sexp_release (l2);
122     if (! array[idx])
123     {
124       for (i = 0; i < idx; i++)
125       {
126         gcry_free (array[i]);
127         array[i] = NULL;
128       }
129       gcry_sexp_release (list);
130       return 4;                 /* required parameter is invalid */
131     }
132   }
133   gcry_sexp_release (list);
134   return 0;
135 }
136
137
138 /**
139  * Create a new private key. Caller must free return value.
140  *
141  * @param len length of the key in bits (i.e. 2048)
142  * @return fresh private key
143  */
144 struct GNUNET_CRYPTO_RsaPrivateKey *
145 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
146 {
147   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
148   gcry_sexp_t s_key;
149   gcry_sexp_t s_keyparam;
150
151   GNUNET_assert (0 ==
152                  gcry_sexp_build (&s_keyparam,
153                                   NULL,
154                                   "(genkey(rsa(nbits %d)))",
155                                   len));
156   GNUNET_assert (0 ==
157                  gcry_pk_genkey (&s_key,
158                                  s_keyparam));
159   gcry_sexp_release (s_keyparam);
160 #if EXTRA_CHECKS
161   GNUNET_assert (0 ==
162                  gcry_pk_testkey (s_key));
163 #endif
164   ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
165   ret->sexp = s_key;
166   return ret;
167 }
168
169
170 /**
171  * Free memory occupied by the private key.
172  *
173  * @param key pointer to the memory to free
174  */
175 void
176 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
177 {
178   gcry_sexp_release (key->sexp);
179   GNUNET_free (key);
180 }
181
182
183 /**
184  * Encode the private key in a format suitable for
185  * storing it into a file.
186  *
187  * @param key the private key
188  * @param[out] buffer set to a buffer with the encoded key
189  * @return size of memory allocated in @a buffer
190  */
191 size_t
192 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
193                                       char **buffer)
194 {
195   size_t n;
196   char *b;
197
198   n = gcry_sexp_sprint (key->sexp,
199                         GCRYSEXP_FMT_DEFAULT,
200                         NULL,
201                         0);
202   b = GNUNET_malloc (n);
203   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
204                  gcry_sexp_sprint (key->sexp,
205                                    GCRYSEXP_FMT_DEFAULT,
206                                    b,
207                                    n));
208   *buffer = b;
209   return n;
210 }
211
212
213 /**
214  * Decode the private key from the data-format back
215  * to the "normal", internal format.
216  *
217  * @param buf the buffer where the private key data is stored
218  * @param len the length of the data in @a buf
219  * @return NULL on error
220  */
221 struct GNUNET_CRYPTO_RsaPrivateKey *
222 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
223                                       size_t len)
224 {
225   struct GNUNET_CRYPTO_RsaPrivateKey *key;
226   key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
227   if (0 !=
228       gcry_sexp_new (&key->sexp,
229                      buf,
230                      len,
231                      0))
232   {
233     LOG (GNUNET_ERROR_TYPE_WARNING,
234          "Decoded private key is not valid\n");
235     GNUNET_free (key);
236     return NULL;
237   }
238   if (0 != gcry_pk_testkey (key->sexp))
239   {
240     LOG (GNUNET_ERROR_TYPE_WARNING,
241          "Decoded private key is not valid\n");
242     GNUNET_CRYPTO_rsa_private_key_free (key);
243     return NULL;
244   }
245   return key;
246 }
247
248
249 /**
250  * Extract the public key of the given private key.
251  *
252  * @param priv the private key
253  * @retur NULL on error, otherwise the public key
254  */
255 struct GNUNET_CRYPTO_RsaPublicKey *
256 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
257 {
258   struct GNUNET_CRYPTO_RsaPublicKey *pub;
259   gcry_mpi_t ne[2];
260   int rc;
261   gcry_sexp_t result;
262
263   rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
264   if (0 != rc)
265     rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
266   if (0 != rc)
267     rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
268   if (0 != rc)
269   {
270     GNUNET_break_op (0);
271     return NULL;
272   }
273   rc = gcry_sexp_build (&result,
274                         NULL,
275                         "(public-key(rsa(n %m)(e %m)))",
276                         ne[0],
277                         ne[1]);
278   gcry_mpi_release (ne[0]);
279   gcry_mpi_release (ne[1]);
280   pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
281   pub->sexp = result;
282   return pub;
283 }
284
285
286 /**
287  * Free memory occupied by the public key.
288  *
289  * @param key pointer to the memory to free
290  */
291 void
292 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
293 {
294   gcry_sexp_release (key->sexp);
295   GNUNET_free (key);
296 }
297
298
299 /**
300  * Encode the public key in a format suitable for
301  * storing it into a file.
302  *
303  * @param key the private key
304  * @param[out] buffer set to a buffer with the encoded key
305  * @return size of memory allocated in @a buffer
306  */
307 size_t
308 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key,
309                                      char **buffer)
310 {
311   size_t n;
312   char *b;
313
314   n = gcry_sexp_sprint (key->sexp,
315                         GCRYSEXP_FMT_ADVANCED,
316                         NULL,
317                         0);
318   b = GNUNET_malloc (n);
319   GNUNET_assert ((n -1) ==      /* since the last byte is \0 */
320                  gcry_sexp_sprint (key->sexp,
321                                    GCRYSEXP_FMT_ADVANCED,
322                                    b,
323                                    n));
324   *buffer = b;
325   return n;
326 }
327
328
329 /**
330  * Compute hash over the public key.
331  *
332  * @param key public key to hash
333  * @param hc where to store the hash code
334  */
335 void
336 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
337                                    struct GNUNET_HashCode *hc)
338 {
339   char *buf;
340   size_t buf_size;
341
342   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
343                                                   &buf);
344   GNUNET_CRYPTO_hash (buf,
345                       buf_size,
346                       hc);
347   GNUNET_free (buf);
348 }
349
350
351 /**
352  * Decode the public key from the data-format back
353  * to the "normal", internal format.
354  *
355  * @param buf the buffer where the public key data is stored
356  * @param len the length of the data in @a buf
357  * @return NULL on error
358  */
359 struct GNUNET_CRYPTO_RsaPublicKey *
360 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
361                                      size_t len)
362 {
363   struct GNUNET_CRYPTO_RsaPublicKey *key;
364   gcry_mpi_t n;
365   int ret;
366
367   key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
368   if (0 !=
369       gcry_sexp_new (&key->sexp,
370                      buf,
371                      len,
372                      0))
373   {
374     GNUNET_break_op (0);
375     GNUNET_free (key);
376     return NULL;
377   }
378   /* verify that this is an RSA public key */
379   ret = key_from_sexp (&n, key->sexp, "public-key", "n");
380   if (0 != ret)
381     ret = key_from_sexp (&n, key->sexp, "rsa", "n");
382   if (0 != ret)
383   {
384     /* this is no public RSA key */
385     GNUNET_break (0);
386     gcry_sexp_release (key->sexp);
387     GNUNET_free (key);
388     return NULL;
389   }
390   gcry_mpi_release (n);
391   return key;
392 }
393
394
395 /**
396  * Create a blinding key
397  *
398  * @param len length of the key in bits (i.e. 2048)
399  * @param bks pre-secret to use to derive the blinding key
400  * @return the newly created blinding key
401  */
402 static struct RsaBlindingKey *
403 rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
404                          const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
405 {
406   char *xts = "Blinding KDF extrator HMAC key";  /* Trusts bks' randomness more */
407   struct RsaBlindingKey *blind;
408   gcry_mpi_t n;
409
410   blind = GNUNET_new (struct RsaBlindingKey);
411
412   /* Extract the composite n from the RSA public key */
413   GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
414   GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
415
416   GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
417                              n,
418                              xts,  strlen(xts),
419                              bks,  sizeof(*bks),
420                              "Blinding KDF");
421   return blind;
422 }
423
424
425 /**
426  * Compare the values of two signatures.
427  *
428  * @param s1 one signature
429  * @param s2 the other signature
430  * @return 0 if the two are equal
431  */
432 int
433 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
434                                  struct GNUNET_CRYPTO_RsaSignature *s2)
435 {
436   char *b1;
437   char *b2;
438   size_t z1;
439   size_t z2;
440   int ret;
441
442   z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
443                                            &b1);
444   z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
445                                            &b2);
446   if (z1 != z2)
447     ret = 1;
448   else
449     ret = memcmp (b1,
450                   b2,
451                   z1);
452   GNUNET_free (b1);
453   GNUNET_free (b2);
454   return ret;
455 }
456
457
458 /**
459  * Compare the values of two public keys.
460  *
461  * @param p1 one public key
462  * @param p2 the other public key
463  * @return 0 if the two are equal
464  */
465 int
466 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
467                                   struct GNUNET_CRYPTO_RsaPublicKey *p2)
468 {
469   char *b1;
470   char *b2;
471   size_t z1;
472   size_t z2;
473   int ret;
474
475   z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
476                                             &b1);
477   z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
478                                             &b2);
479   if (z1 != z2)
480     ret = 1;
481   else
482     ret = memcmp (b1,
483                   b2,
484                   z1);
485   GNUNET_free (b1);
486   GNUNET_free (b2);
487   return ret;
488 }
489
490
491 /**
492  * Compare the values of two private keys.
493  *
494  * @param p1 one private key
495  * @param p2 the other private key
496  * @return 0 if the two are equal
497  */
498 int
499 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
500                                    struct GNUNET_CRYPTO_RsaPrivateKey *p2)
501 {
502   char *b1;
503   char *b2;
504   size_t z1;
505   size_t z2;
506   int ret;
507
508   z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
509                                             &b1);
510   z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
511                                             &b2);
512   if (z1 != z2)
513     ret = 1;
514   else
515     ret = memcmp (b1,
516                   b2,
517                   z1);
518   GNUNET_free (b1);
519   GNUNET_free (b2);
520   return ret;
521 }
522
523
524 /**
525  * Obtain the length of the RSA key in bits.
526  *
527  * @param key the public key to introspect
528  * @return length of the key in bits
529  */
530 unsigned int
531 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
532 {
533   gcry_mpi_t n;
534   unsigned int rval;
535
536   if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
537   { /* Not an RSA public key */
538     GNUNET_break (0);
539     return 0;
540   }
541   rval = gcry_mpi_get_nbits (n);
542   gcry_mpi_release (n);
543   return rval;
544 }
545
546
547 /**
548  * Destroy a blinding key
549  *
550  * @param bkey the blinding key to destroy
551  */
552 static void
553 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
554 {
555   gcry_mpi_release (bkey->r);
556   GNUNET_free (bkey);
557 }
558
559
560 /**
561  * Print an MPI to a newly created buffer
562  *
563  * @param v MPI to print.
564  * @param[out] newly allocated buffer containing the result
565  * @return number of bytes stored in @a buffer
566  */
567 static size_t
568 numeric_mpi_alloc_n_print (gcry_mpi_t v,
569                            char **buffer)
570 {
571   size_t n;
572   char *b;
573   size_t rsize;
574
575   gcry_mpi_print (GCRYMPI_FMT_USG,
576                   NULL,
577                   0,
578                   &n,
579                   v);
580   b = GNUNET_malloc (n);
581   GNUNET_assert (0 ==
582                  gcry_mpi_print (GCRYMPI_FMT_USG,
583                                  (unsigned char *) b,
584                                  n,
585                                  &rsize,
586                                  v));
587   *buffer = b;
588   return n;
589 }
590
591
592 /**
593  * Computes a full domain hash seeded by the given public key.
594  * This gives a measure of provable security to the Taler exchange
595  * against one-more forgery attacks.  See:
596  *   https://eprint.iacr.org/2001/002.pdf
597  *   http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
598  *
599  * @param[out] r MPI value set to the FDH
600  * @param hash initial hash of the message to sign
601  * @param pkey the public key of the signer
602  * @param rsize If not NULL, the number of bytes actually stored in buffer
603  */
604 static void
605 rsa_full_domain_hash (gcry_mpi_t *r,
606                                     const struct GNUNET_HashCode *hash,
607                                     const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
608 {
609   gcry_mpi_t n;
610   char *xts;
611   size_t xts_len;
612
613   /* Extract the composite n from the RSA public key */
614   GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
615   GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
616
617   /* We key with the public denomination key as a homage to RSA-PSS by  *
618    * Mihir Bellare and Phillip Rogaway.  Doing this lowers the degree   *
619    * of the hypothetical polyomial-time attack on RSA-KTI created by a  *
620    * polynomial-time one-more forgary attack.  Yey seeding!             */
621   xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
622
623   GNUNET_CRYPTO_kdf_mod_mpi (r,
624                              n,
625                              xts,  xts_len,
626                              hash,  sizeof(*hash),
627                              "RSA-FDA FTpsW!");
628
629   GNUNET_free (xts);
630 }
631
632
633 /**
634  * Blinds the given message with the given blinding key
635  *
636  * @param hash hash of the message to sign
637  * @param bkey the blinding key
638  * @param pkey the public key of the signer
639  * @param[out] buffer set to a buffer with the blinded message to be signed
640  * @return number of bytes stored in @a buffer
641  */
642 size_t
643 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
644                          const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
645                          struct GNUNET_CRYPTO_RsaPublicKey *pkey,
646                          char **buffer)
647 {
648   struct RsaBlindingKey *bkey;
649   gcry_mpi_t data;
650   gcry_mpi_t ne[2];
651   gcry_mpi_t r_e;
652   gcry_mpi_t data_r_e;
653   size_t n;
654   int ret;
655
656   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
657   if (0 != ret)
658     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
659   if (0 != ret)
660   {
661     GNUNET_break (0);
662     *buffer = NULL;
663     return 0;
664   }
665
666   rsa_full_domain_hash (&data, hash, pkey);
667   bkey = rsa_blinding_key_derive (pkey,
668                                   bks);
669   r_e = gcry_mpi_new (0);
670   gcry_mpi_powm (r_e,
671                  bkey->r,
672                  ne[1],
673                  ne[0]);
674   data_r_e = gcry_mpi_new (0);
675   gcry_mpi_mulm (data_r_e,
676                  data,
677                  r_e,
678                  ne[0]);
679   gcry_mpi_release (data);
680   gcry_mpi_release (ne[0]);
681   gcry_mpi_release (ne[1]);
682   gcry_mpi_release (r_e);
683   rsa_blinding_key_free (bkey);  
684
685   n = numeric_mpi_alloc_n_print (data_r_e, buffer);
686   gcry_mpi_release (data_r_e);
687   return n;
688 }
689
690
691 /**
692  * Convert an MPI to an S-expression suitable for signature operations.
693  *
694  * @param value pointer to the data to convert
695  * @return converted s-expression
696  */
697 static gcry_sexp_t
698 mpi_to_sexp (gcry_mpi_t value)
699 {
700   gcry_sexp_t data = NULL;
701
702   GNUNET_assert (0 ==
703                  gcry_sexp_build (&data,
704                                   NULL,
705                                   "(data (flags raw) (value %M))",
706                                   value));
707   return data;
708 }
709
710
711 /**
712  * Sign the given MPI.
713  *
714  * @param key private key to use for the signing
715  * @param value the MPI to sign
716  * @return NULL on error, signature on success
717  */
718 static struct GNUNET_CRYPTO_RsaSignature *
719 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
720               gcry_mpi_t value)
721 {
722   struct GNUNET_CRYPTO_RsaSignature *sig;
723   struct GNUNET_CRYPTO_RsaPublicKey *public_key;
724   gcry_sexp_t data;
725   gcry_sexp_t result;
726   int rc;
727
728   data = mpi_to_sexp (value);
729
730   if (0 !=
731       (rc = gcry_pk_sign (&result,
732                           data,
733                           key->sexp)))
734   {
735     LOG (GNUNET_ERROR_TYPE_WARNING,
736          _("RSA signing failed at %s:%d: %s\n"),
737          __FILE__,
738          __LINE__,
739          gcry_strerror (rc));
740     GNUNET_break (0);
741     return NULL;
742   }
743
744   /* verify signature (guards against Lenstra's attack with fault injection...) */
745   public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
746   if (0 !=
747       gcry_pk_verify (result,
748                       data,
749                       public_key->sexp))
750   {
751     GNUNET_break (0);
752     GNUNET_CRYPTO_rsa_public_key_free (public_key);
753     gcry_sexp_release (data);
754     gcry_sexp_release (result);
755     return NULL;
756   }
757   GNUNET_CRYPTO_rsa_public_key_free (public_key);
758
759   /* return signature */
760   gcry_sexp_release (data);
761   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
762   sig->sexp = result;
763   return sig;
764 }
765
766
767 /**
768  * Sign a blinded value, which must be a full domain hash of a message.
769  *
770  * @param key private key to use for the signing
771  * @param msg the message to sign
772  * @param msg_len number of bytes in @a msg to sign
773  * @return NULL on error, signature on success
774  */
775 struct GNUNET_CRYPTO_RsaSignature *
776 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
777                                 const void *msg,
778                                 size_t msg_len)
779 {
780   gcry_mpi_t v = NULL;
781   struct GNUNET_CRYPTO_RsaSignature *sig;
782
783   GNUNET_assert (0 ==
784                  gcry_mpi_scan (&v,
785                                 GCRYMPI_FMT_USG,
786                                 msg,
787                                 msg_len,
788                                 NULL));
789
790   sig = rsa_sign_mpi (key, v);
791   gcry_mpi_release (v);
792   return sig;
793 }
794
795
796 /**
797  * Create and sign a full domain hash of a message.
798  *
799  * @param key private key to use for the signing
800  * @param hash the hash of the message to sign
801  * @return NULL on error, signature on success
802  */
803 struct GNUNET_CRYPTO_RsaSignature *
804 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
805                             const struct GNUNET_HashCode *hash)
806 {
807   struct GNUNET_CRYPTO_RsaPublicKey *pkey;
808   gcry_mpi_t v = NULL;
809   struct GNUNET_CRYPTO_RsaSignature *sig;
810
811   pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
812   rsa_full_domain_hash (&v, hash, pkey);
813   GNUNET_CRYPTO_rsa_public_key_free (pkey);
814
815   sig = rsa_sign_mpi (key, v);
816   gcry_mpi_release (v);
817   return sig;
818
819 }
820
821
822 /**
823  * Free memory occupied by signature.
824  *
825  * @param sig memory to freee
826  */
827 void
828 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
829 {
830   gcry_sexp_release (sig->sexp);
831   GNUNET_free (sig);
832 }
833
834
835 /**
836  * Encode the given signature in a format suitable for storing it into a file.
837  *
838  * @param sig the signature
839  * @param[out] buffer set to a buffer with the encoded key
840  * @return size of memory allocated in @a buffer
841  */
842 size_t
843 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
844                                     char **buffer)
845 {
846   size_t n;
847   char *b;
848
849   n = gcry_sexp_sprint (sig->sexp,
850                         GCRYSEXP_FMT_ADVANCED,
851                         NULL,
852                         0);
853   b = GNUNET_malloc (n);
854   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
855                  gcry_sexp_sprint (sig->sexp,
856                                    GCRYSEXP_FMT_ADVANCED,
857                                    b,
858                                    n));
859   *buffer = b;
860   return n;
861 }
862
863
864 /**
865  * Decode the signature from the data-format back to the "normal", internal
866  * format.
867  *
868  * @param buf the buffer where the public key data is stored
869  * @param len the length of the data in @a buf
870  * @return NULL on error
871  */
872 struct GNUNET_CRYPTO_RsaSignature *
873 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
874                                     size_t len)
875 {
876   struct GNUNET_CRYPTO_RsaSignature *sig;
877   int ret;
878   gcry_mpi_t s;
879
880   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
881   if (0 !=
882       gcry_sexp_new (&sig->sexp,
883                      buf,
884                      len,
885                      0))
886   {
887     GNUNET_break_op (0);
888     GNUNET_free (sig);
889     return NULL;
890   }
891   /* verify that this is an RSA signature */
892   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
893   if (0 != ret)
894     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
895   if (0 != ret)
896   {
897     /* this is no RSA Signature */
898     GNUNET_break_op (0);
899     gcry_sexp_release (sig->sexp);
900     GNUNET_free (sig);
901     return NULL;
902   }
903   gcry_mpi_release (s);
904   return sig;
905 }
906
907
908 /**
909  * Duplicate the given public key
910  *
911  * @param key the public key to duplicate
912  * @return the duplicate key; NULL upon error
913  */
914 struct GNUNET_CRYPTO_RsaPublicKey *
915 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
916 {
917   struct GNUNET_CRYPTO_RsaPublicKey *dup;
918   gcry_sexp_t dup_sexp;
919   size_t erroff;
920
921   /* check if we really are exporting a public key */
922   dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
923   GNUNET_assert (NULL != dup_sexp);
924   gcry_sexp_release (dup_sexp);
925   /* copy the sexp */
926   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
927   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
928   dup->sexp = dup_sexp;
929   return dup;
930 }
931
932
933 /**
934  * Unblind a blind-signed signature.  The signature should have been generated
935  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
936  * #GNUNET_CRYPTO_rsa_blind().
937  *
938  * @param sig the signature made on the blinded signature purpose
939  * @param bks the blinding key secret used to blind the signature purpose
940  * @param pkey the public key of the signer
941  * @return unblinded signature on success, NULL on error
942  */
943 struct GNUNET_CRYPTO_RsaSignature *
944 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
945                            const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
946                            struct GNUNET_CRYPTO_RsaPublicKey *pkey)
947 {
948   struct RsaBlindingKey *bkey;
949   gcry_mpi_t n;
950   gcry_mpi_t s;
951   gcry_mpi_t r_inv;
952   gcry_mpi_t ubsig;
953   int ret;
954   struct GNUNET_CRYPTO_RsaSignature *sret;
955
956   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
957   if (0 != ret)
958     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
959   if (0 != ret)
960   {
961     GNUNET_break_op (0);
962     return NULL;
963   }
964   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
965   if (0 != ret)
966     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
967   if (0 != ret)
968   {
969     gcry_mpi_release (n);
970     GNUNET_break_op (0);
971     return NULL;
972   }
973   bkey = rsa_blinding_key_derive (pkey,
974                                   bks);
975
976   r_inv = gcry_mpi_new (0);
977   if (1 !=
978       gcry_mpi_invm (r_inv,
979                      bkey->r,
980                      n))
981   {
982     GNUNET_break_op (0);
983     gcry_mpi_release (n);
984     gcry_mpi_release (r_inv);
985     gcry_mpi_release (s);
986     rsa_blinding_key_free (bkey);  
987     return NULL;
988   }
989   ubsig = gcry_mpi_new (0);
990   gcry_mpi_mulm (ubsig, s, r_inv, n);
991   gcry_mpi_release (n);
992   gcry_mpi_release (r_inv);
993   gcry_mpi_release (s);
994   rsa_blinding_key_free (bkey);
995
996   sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
997   GNUNET_assert (0 ==
998                  gcry_sexp_build (&sret->sexp,
999                                   NULL,
1000                                   "(sig-val (rsa (s %M)))",
1001                                   ubsig));
1002   gcry_mpi_release (ubsig);
1003   return sret;
1004 }
1005
1006
1007 /**
1008  * Verify whether the given hash corresponds to the given signature and the
1009  * signature is valid with respect to the given public key.
1010  *
1011  * @param hash hash of the message to verify to match the @a sig
1012  * @param sig signature that is being validated
1013  * @param pkey public key of the signer
1014  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1015  */
1016 int
1017 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1018                           const struct GNUNET_CRYPTO_RsaSignature *sig,
1019                           const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1020 {
1021   gcry_sexp_t data;
1022   gcry_mpi_t r;
1023   int rc;
1024
1025   rsa_full_domain_hash (&r, hash, pkey);
1026   data = mpi_to_sexp(r);
1027   gcry_mpi_release (r);
1028
1029   rc = gcry_pk_verify (sig->sexp,
1030                        data,
1031                        pkey->sexp);
1032   gcry_sexp_release (data);
1033   if (0 != rc)
1034   {
1035     LOG (GNUNET_ERROR_TYPE_WARNING,
1036          _("RSA signature verification failed at %s:%d: %s\n"),
1037          __FILE__,
1038          __LINE__,
1039          gcry_strerror (rc));
1040     return GNUNET_SYSERR;
1041   }
1042   return GNUNET_OK;
1043 }
1044
1045
1046 /**
1047  * Duplicate the given private key
1048  *
1049  * @param key the private key to duplicate
1050  * @return the duplicate key; NULL upon error
1051  */
1052 struct GNUNET_CRYPTO_RsaPrivateKey *
1053 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1054 {
1055   struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1056   gcry_sexp_t dup_sexp;
1057   size_t erroff;
1058
1059   /* check if we really are exporting a private key */
1060   dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1061   GNUNET_assert (NULL != dup_sexp);
1062   gcry_sexp_release (dup_sexp);
1063   /* copy the sexp */
1064   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1065   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1066   dup->sexp = dup_sexp;
1067   return dup;
1068 }
1069
1070
1071 /**
1072  * Duplicate the given private key
1073  *
1074  * @param key the private key to duplicate
1075  * @return the duplicate key; NULL upon error
1076  */
1077 struct GNUNET_CRYPTO_RsaSignature *
1078 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1079 {
1080   struct GNUNET_CRYPTO_RsaSignature *dup;
1081   gcry_sexp_t dup_sexp;
1082   size_t erroff;
1083   gcry_mpi_t s;
1084   int ret;
1085
1086   /* verify that this is an RSA signature */
1087   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1088   if (0 != ret)
1089     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1090   GNUNET_assert (0 == ret);
1091   gcry_mpi_release (s);
1092   /* copy the sexp */
1093   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1094   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1095   dup->sexp = dup_sexp;
1096   return dup;
1097 }
1098
1099
1100 /* end of util/rsa.c */