Testcases for KDF mod n
[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 We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
427 previous routine.
428
429 There was previously a call to GNUNET_CRYPTO_kdf in 
430   bkey = rsa_blinding_key_derive (len, bks);
431 that gives exactly len bits where 
432   len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
433
434 Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
435 okay, meaning bkey < pkey.n.  It follows that (1-r)/2 of the time bkey >
436 pkey.n making the effective bkey be 
437   bkey mod pkey.n = bkey - pkey.n
438 so the effective bkey has its high bit set with probability r/2.
439
440 We expect r to be close to 1/2 if the exchange is honest, but the
441 exchange can choose r otherwise.
442
443 In blind signing, the exchange sees  
444   B = bkey * S mod pkey.n
445 On deposit, the exchange sees S so they can compute bkey' = B/S mod
446 pkey.n for all B they recorded to see if bkey' has it's high bit set.
447 Also, note the exchange can compute 1/S efficiently since they know the
448 factors of pkey.n.
449
450 I suppose that happens with probability r/(1+r) if its the wrong B, not
451 completely sure.  If otoh we've the right B, then we've the probability
452 r/2 of a set high bit in the effective bkey.
453
454 Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
455 the wrong and right probabilities 1/3 and 1/4, respectively.
456
457 I feared this gives the exchange a meaningful fraction of a bit of
458 information per coin involved in the transaction.  It sounds damaging if
459 numerous coins were involved.  And it could run across transactions in
460 some scenarios. 
461
462 We fixed this by using a more uniform deterministic pseudo-random number
463 generator for blinding factors.  I do not believe this to be a problem
464 for the rsa_full_domain_hash routine, but better safe than sorry.
465 */
466
467
468 /**
469  * Compare the values of two signatures.
470  *
471  * @param s1 one signature
472  * @param s2 the other signature
473  * @return 0 if the two are equal
474  */
475 int
476 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
477                                  struct GNUNET_CRYPTO_RsaSignature *s2)
478 {
479   char *b1;
480   char *b2;
481   size_t z1;
482   size_t z2;
483   int ret;
484
485   z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
486                                            &b1);
487   z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
488                                            &b2);
489   if (z1 != z2)
490     ret = 1;
491   else
492     ret = memcmp (b1,
493                   b2,
494                   z1);
495   GNUNET_free (b1);
496   GNUNET_free (b2);
497   return ret;
498 }
499
500
501 /**
502  * Compare the values of two public keys.
503  *
504  * @param p1 one public key
505  * @param p2 the other public key
506  * @return 0 if the two are equal
507  */
508 int
509 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
510                                   struct GNUNET_CRYPTO_RsaPublicKey *p2)
511 {
512   char *b1;
513   char *b2;
514   size_t z1;
515   size_t z2;
516   int ret;
517
518   z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
519                                             &b1);
520   z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
521                                             &b2);
522   if (z1 != z2)
523     ret = 1;
524   else
525     ret = memcmp (b1,
526                   b2,
527                   z1);
528   GNUNET_free (b1);
529   GNUNET_free (b2);
530   return ret;
531 }
532
533
534 /**
535  * Compare the values of two private keys.
536  *
537  * @param p1 one private key
538  * @param p2 the other private key
539  * @return 0 if the two are equal
540  */
541 int
542 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
543                                    struct GNUNET_CRYPTO_RsaPrivateKey *p2)
544 {
545   char *b1;
546   char *b2;
547   size_t z1;
548   size_t z2;
549   int ret;
550
551   z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
552                                             &b1);
553   z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
554                                             &b2);
555   if (z1 != z2)
556     ret = 1;
557   else
558     ret = memcmp (b1,
559                   b2,
560                   z1);
561   GNUNET_free (b1);
562   GNUNET_free (b2);
563   return ret;
564 }
565
566
567 /**
568  * Obtain the length of the RSA key in bits.
569  *
570  * @param key the public key to introspect
571  * @return length of the key in bits
572  */
573 unsigned int
574 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
575 {
576   gcry_mpi_t n;
577   unsigned int rval;
578
579   if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
580   { /* Not an RSA public key */
581     GNUNET_break (0);
582     return 0;
583   }
584   rval = gcry_mpi_get_nbits (n);
585   gcry_mpi_release (n);
586   return rval;
587 }
588
589
590 /**
591  * Destroy a blinding key
592  *
593  * @param bkey the blinding key to destroy
594  */
595 static void
596 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
597 {
598   gcry_mpi_release (bkey->r);
599   GNUNET_free (bkey);
600 }
601
602
603 /**
604  * Print an MPI to a newly created buffer
605  *
606  * @param v MPI to print.
607  * @param[out] newly allocated buffer containing the result
608  * @return number of bytes stored in @a buffer
609  */
610 static size_t
611 numeric_mpi_alloc_n_print (gcry_mpi_t v,
612                            char **buffer)
613 {
614   size_t n;
615   char *b;
616   size_t rsize;
617
618   gcry_mpi_print (GCRYMPI_FMT_USG,
619                   NULL,
620                   0,
621                   &n,
622                   v);
623   b = GNUNET_malloc (n);
624   GNUNET_assert (0 ==
625                  gcry_mpi_print (GCRYMPI_FMT_USG,
626                                  (unsigned char *) b,
627                                  n,
628                                  &rsize,
629                                  v));
630   *buffer = b;
631   return n;
632 }
633
634
635 /**
636  * Computes a full domain hash seeded by the given public key.
637  * This gives a measure of provable security to the Taler exchange
638  * against one-more forgery attacks.  See:
639  *   https://eprint.iacr.org/2001/002.pdf
640  *   http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
641  *
642  * @param[out] r MPI value set to the FDH
643  * @param hash initial hash of the message to sign
644  * @param pkey the public key of the signer
645  * @param rsize If not NULL, the number of bytes actually stored in buffer
646  */
647 static void
648 rsa_full_domain_hash (gcry_mpi_t *r,
649                                     const struct GNUNET_HashCode *hash,
650                                     const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
651 {
652   gcry_mpi_t n;
653   char *xts;
654   size_t xts_len;
655
656   /* Extract the composite n from the RSA public key */
657   GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
658   GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
659
660   /* We key with the public denomination key as a homage to RSA-PSS by  *
661    * Mihir Bellare and Phillip Rogaway.  Doing this lowers the degree   *
662    * of the hypothetical polyomial-time attack on RSA-KTI created by a  *
663    * polynomial-time one-more forgary attack.  Yey seeding!             */
664   xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
665
666   GNUNET_CRYPTO_kdf_mod_mpi (r,
667                              n,
668                              xts,  xts_len,
669                              hash,  sizeof(*hash),
670                              "RSA-FDA FTpsW!");
671
672   GNUNET_free (xts);
673 }
674
675
676 /**
677  * Blinds the given message with the given blinding key
678  *
679  * @param hash hash of the message to sign
680  * @param bkey the blinding key
681  * @param pkey the public key of the signer
682  * @param[out] buffer set to a buffer with the blinded message to be signed
683  * @return number of bytes stored in @a buffer
684  */
685 size_t
686 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
687                          const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
688                          struct GNUNET_CRYPTO_RsaPublicKey *pkey,
689                          char **buffer)
690 {
691   struct RsaBlindingKey *bkey;
692   gcry_mpi_t data;
693   gcry_mpi_t ne[2];
694   gcry_mpi_t r_e;
695   gcry_mpi_t data_r_e;
696   size_t n;
697   int ret;
698
699   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
700   if (0 != ret)
701     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
702   if (0 != ret)
703   {
704     GNUNET_break (0);
705     *buffer = NULL;
706     return 0;
707   }
708
709   rsa_full_domain_hash (&data, hash, pkey);
710   bkey = rsa_blinding_key_derive (pkey,
711                                   bks);
712   r_e = gcry_mpi_new (0);
713   gcry_mpi_powm (r_e,
714                  bkey->r,
715                  ne[1],
716                  ne[0]);
717   data_r_e = gcry_mpi_new (0);
718   gcry_mpi_mulm (data_r_e,
719                  data,
720                  r_e,
721                  ne[0]);
722   gcry_mpi_release (data);
723   gcry_mpi_release (ne[0]);
724   gcry_mpi_release (ne[1]);
725   gcry_mpi_release (r_e);
726   rsa_blinding_key_free (bkey);  
727
728   n = numeric_mpi_alloc_n_print (data_r_e, buffer);
729   gcry_mpi_release (data_r_e);
730   return n;
731 }
732
733
734 /**
735  * Convert an MPI to an S-expression suitable for signature operations.
736  *
737  * @param value pointer to the data to convert
738  * @return converted s-expression
739  */
740 static gcry_sexp_t
741 mpi_to_sexp (gcry_mpi_t value)
742 {
743   gcry_sexp_t data = NULL;
744
745   GNUNET_assert (0 ==
746                  gcry_sexp_build (&data,
747                                   NULL,
748                                   "(data (flags raw) (value %M))",
749                                   value));
750   return data;
751 }
752
753
754 /**
755  * Sign the given MPI.
756  *
757  * @param key private key to use for the signing
758  * @param value the MPI to sign
759  * @return NULL on error, signature on success
760  */
761 static struct GNUNET_CRYPTO_RsaSignature *
762 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
763               gcry_mpi_t value)
764 {
765   struct GNUNET_CRYPTO_RsaSignature *sig;
766   struct GNUNET_CRYPTO_RsaPublicKey *public_key;
767   gcry_sexp_t data;
768   gcry_sexp_t result;
769   int rc;
770
771   data = mpi_to_sexp (value);
772
773   if (0 !=
774       (rc = gcry_pk_sign (&result,
775                           data,
776                           key->sexp)))
777   {
778     LOG (GNUNET_ERROR_TYPE_WARNING,
779          _("RSA signing failed at %s:%d: %s\n"),
780          __FILE__,
781          __LINE__,
782          gcry_strerror (rc));
783     GNUNET_break (0);
784     return NULL;
785   }
786
787   /* verify signature (guards against Lenstra's attack with fault injection...) */
788   public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
789   if (0 !=
790       gcry_pk_verify (result,
791                       data,
792                       public_key->sexp))
793   {
794     GNUNET_break (0);
795     GNUNET_CRYPTO_rsa_public_key_free (public_key);
796     gcry_sexp_release (data);
797     gcry_sexp_release (result);
798     return NULL;
799   }
800   GNUNET_CRYPTO_rsa_public_key_free (public_key);
801
802   /* return signature */
803   gcry_sexp_release (data);
804   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
805   sig->sexp = result;
806   return sig;
807 }
808
809
810 /**
811  * Sign a blinded value, which must be a full domain hash of a message.
812  *
813  * @param key private key to use for the signing
814  * @param msg the message to sign
815  * @param msg_len number of bytes in @a msg to sign
816  * @return NULL on error, signature on success
817  */
818 struct GNUNET_CRYPTO_RsaSignature *
819 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
820                                 const void *msg,
821                                 size_t msg_len)
822 {
823   gcry_mpi_t v = NULL;
824   struct GNUNET_CRYPTO_RsaSignature *sig;
825
826   GNUNET_assert (0 ==
827                  gcry_mpi_scan (&v,
828                                 GCRYMPI_FMT_USG,
829                                 msg,
830                                 msg_len,
831                                 NULL));
832
833   sig = rsa_sign_mpi (key, v);
834   gcry_mpi_release (v);
835   return sig;
836 }
837
838
839 /**
840  * Create and sign a full domain hash of a message.
841  *
842  * @param key private key to use for the signing
843  * @param hash the hash of the message to sign
844  * @return NULL on error, signature on success
845  */
846 struct GNUNET_CRYPTO_RsaSignature *
847 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
848                             const struct GNUNET_HashCode *hash)
849 {
850   struct GNUNET_CRYPTO_RsaPublicKey *pkey;
851   gcry_mpi_t v = NULL;
852   struct GNUNET_CRYPTO_RsaSignature *sig;
853
854   pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
855   rsa_full_domain_hash (&v, hash, pkey);
856   GNUNET_CRYPTO_rsa_public_key_free (pkey);
857
858   sig = rsa_sign_mpi (key, v);
859   gcry_mpi_release (v);
860   return sig;
861
862 }
863
864
865 /**
866  * Free memory occupied by signature.
867  *
868  * @param sig memory to freee
869  */
870 void
871 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
872 {
873   gcry_sexp_release (sig->sexp);
874   GNUNET_free (sig);
875 }
876
877
878 /**
879  * Encode the given signature in a format suitable for storing it into a file.
880  *
881  * @param sig the signature
882  * @param[out] buffer set to a buffer with the encoded key
883  * @return size of memory allocated in @a buffer
884  */
885 size_t
886 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
887                                     char **buffer)
888 {
889   size_t n;
890   char *b;
891
892   n = gcry_sexp_sprint (sig->sexp,
893                         GCRYSEXP_FMT_ADVANCED,
894                         NULL,
895                         0);
896   b = GNUNET_malloc (n);
897   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
898                  gcry_sexp_sprint (sig->sexp,
899                                    GCRYSEXP_FMT_ADVANCED,
900                                    b,
901                                    n));
902   *buffer = b;
903   return n;
904 }
905
906
907 /**
908  * Decode the signature from the data-format back to the "normal", internal
909  * format.
910  *
911  * @param buf the buffer where the public key data is stored
912  * @param len the length of the data in @a buf
913  * @return NULL on error
914  */
915 struct GNUNET_CRYPTO_RsaSignature *
916 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
917                                     size_t len)
918 {
919   struct GNUNET_CRYPTO_RsaSignature *sig;
920   int ret;
921   gcry_mpi_t s;
922
923   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
924   if (0 !=
925       gcry_sexp_new (&sig->sexp,
926                      buf,
927                      len,
928                      0))
929   {
930     GNUNET_break_op (0);
931     GNUNET_free (sig);
932     return NULL;
933   }
934   /* verify that this is an RSA signature */
935   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
936   if (0 != ret)
937     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
938   if (0 != ret)
939   {
940     /* this is no RSA Signature */
941     GNUNET_break_op (0);
942     gcry_sexp_release (sig->sexp);
943     GNUNET_free (sig);
944     return NULL;
945   }
946   gcry_mpi_release (s);
947   return sig;
948 }
949
950
951 /**
952  * Duplicate the given public key
953  *
954  * @param key the public key to duplicate
955  * @return the duplicate key; NULL upon error
956  */
957 struct GNUNET_CRYPTO_RsaPublicKey *
958 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
959 {
960   struct GNUNET_CRYPTO_RsaPublicKey *dup;
961   gcry_sexp_t dup_sexp;
962   size_t erroff;
963
964   /* check if we really are exporting a public key */
965   dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
966   GNUNET_assert (NULL != dup_sexp);
967   gcry_sexp_release (dup_sexp);
968   /* copy the sexp */
969   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
970   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
971   dup->sexp = dup_sexp;
972   return dup;
973 }
974
975
976 /**
977  * Unblind a blind-signed signature.  The signature should have been generated
978  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
979  * #GNUNET_CRYPTO_rsa_blind().
980  *
981  * @param sig the signature made on the blinded signature purpose
982  * @param bks the blinding key secret used to blind the signature purpose
983  * @param pkey the public key of the signer
984  * @return unblinded signature on success, NULL on error
985  */
986 struct GNUNET_CRYPTO_RsaSignature *
987 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
988                            const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
989                            struct GNUNET_CRYPTO_RsaPublicKey *pkey)
990 {
991   struct RsaBlindingKey *bkey;
992   gcry_mpi_t n;
993   gcry_mpi_t s;
994   gcry_mpi_t r_inv;
995   gcry_mpi_t ubsig;
996   int ret;
997   struct GNUNET_CRYPTO_RsaSignature *sret;
998
999   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1000   if (0 != ret)
1001     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1002   if (0 != ret)
1003   {
1004     GNUNET_break_op (0);
1005     return NULL;
1006   }
1007   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1008   if (0 != ret)
1009     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1010   if (0 != ret)
1011   {
1012     gcry_mpi_release (n);
1013     GNUNET_break_op (0);
1014     return NULL;
1015   }
1016   bkey = rsa_blinding_key_derive (pkey,
1017                                   bks);
1018
1019   r_inv = gcry_mpi_new (0);
1020   if (1 !=
1021       gcry_mpi_invm (r_inv,
1022                      bkey->r,
1023                      n))
1024   {
1025     GNUNET_break_op (0);
1026     gcry_mpi_release (n);
1027     gcry_mpi_release (r_inv);
1028     gcry_mpi_release (s);
1029     rsa_blinding_key_free (bkey);  
1030     return NULL;
1031   }
1032   ubsig = gcry_mpi_new (0);
1033   gcry_mpi_mulm (ubsig, s, r_inv, n);
1034   gcry_mpi_release (n);
1035   gcry_mpi_release (r_inv);
1036   gcry_mpi_release (s);
1037   rsa_blinding_key_free (bkey);
1038
1039   sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1040   GNUNET_assert (0 ==
1041                  gcry_sexp_build (&sret->sexp,
1042                                   NULL,
1043                                   "(sig-val (rsa (s %M)))",
1044                                   ubsig));
1045   gcry_mpi_release (ubsig);
1046   return sret;
1047 }
1048
1049
1050 /**
1051  * Verify whether the given hash corresponds to the given signature and the
1052  * signature is valid with respect to the given public key.
1053  *
1054  * @param hash hash of the message to verify to match the @a sig
1055  * @param sig signature that is being validated
1056  * @param pkey public key of the signer
1057  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1058  */
1059 int
1060 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1061                           const struct GNUNET_CRYPTO_RsaSignature *sig,
1062                           const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1063 {
1064   gcry_sexp_t data;
1065   gcry_mpi_t r;
1066   int rc;
1067
1068   rsa_full_domain_hash (&r, hash, pkey);
1069   data = mpi_to_sexp(r);
1070   gcry_mpi_release (r);
1071
1072   rc = gcry_pk_verify (sig->sexp,
1073                        data,
1074                        pkey->sexp);
1075   gcry_sexp_release (data);
1076   if (0 != rc)
1077   {
1078     LOG (GNUNET_ERROR_TYPE_WARNING,
1079          _("RSA signature verification failed at %s:%d: %s\n"),
1080          __FILE__,
1081          __LINE__,
1082          gcry_strerror (rc));
1083     return GNUNET_SYSERR;
1084   }
1085   return GNUNET_OK;
1086 }
1087
1088
1089 /**
1090  * Duplicate the given private key
1091  *
1092  * @param key the private key to duplicate
1093  * @return the duplicate key; NULL upon error
1094  */
1095 struct GNUNET_CRYPTO_RsaPrivateKey *
1096 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1097 {
1098   struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1099   gcry_sexp_t dup_sexp;
1100   size_t erroff;
1101
1102   /* check if we really are exporting a private key */
1103   dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1104   GNUNET_assert (NULL != dup_sexp);
1105   gcry_sexp_release (dup_sexp);
1106   /* copy the sexp */
1107   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1108   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1109   dup->sexp = dup_sexp;
1110   return dup;
1111 }
1112
1113
1114 /**
1115  * Duplicate the given private key
1116  *
1117  * @param key the private key to duplicate
1118  * @return the duplicate key; NULL upon error
1119  */
1120 struct GNUNET_CRYPTO_RsaSignature *
1121 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1122 {
1123   struct GNUNET_CRYPTO_RsaSignature *dup;
1124   gcry_sexp_t dup_sexp;
1125   size_t erroff;
1126   gcry_mpi_t s;
1127   int ret;
1128
1129   /* verify that this is an RSA signature */
1130   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1131   if (0 != ret)
1132     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1133   GNUNET_assert (0 == ret);
1134   gcry_mpi_release (s);
1135   /* copy the sexp */
1136   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1137   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1138   dup->sexp = dup_sexp;
1139   return dup;
1140 }
1141
1142
1143 /* end of util/rsa.c */