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