GNUnet  0.11.x
crypto_rsa.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2014,2016,2019 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
28 #include "platform.h"
29 #include <gcrypt.h>
30 #include "gnunet_crypto_lib.h"
31 #include "benchmark.h"
32 
33 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
34 
35 
40 {
44  gcry_sexp_t sexp;
45 };
46 
47 
52 {
56  gcry_sexp_t sexp;
57 };
58 
59 
64 {
68  gcry_sexp_t sexp;
69 };
70 
71 
76 {
80  gcry_mpi_t r;
81 };
82 
83 
93 static int
94 key_from_sexp (gcry_mpi_t *array,
95  gcry_sexp_t sexp,
96  const char *topname,
97  const char *elems)
98 {
99  gcry_sexp_t list;
100  gcry_sexp_t l2;
101  const char *s;
102  unsigned int idx;
103 
104  if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
105  return 1;
106  l2 = gcry_sexp_cadr (list);
107  gcry_sexp_release (list);
108  list = l2;
109  if (! list)
110  return 2;
111  idx = 0;
112  for (s = elems; *s; s++, idx++)
113  {
114  if (! (l2 = gcry_sexp_find_token (list, s, 1)))
115  {
116  for (unsigned int i = 0; i < idx; i++)
117  {
118  gcry_free (array[i]);
119  array[i] = NULL;
120  }
121  gcry_sexp_release (list);
122  return 3; /* required parameter not found */
123  }
124  array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
125  gcry_sexp_release (l2);
126  if (! array[idx])
127  {
128  for (unsigned int i = 0; i < idx; i++)
129  {
130  gcry_free (array[i]);
131  array[i] = NULL;
132  }
133  gcry_sexp_release (list);
134  return 4; /* required parameter is invalid */
135  }
136  }
137  gcry_sexp_release (list);
138  return 0;
139 }
140 
141 
144 {
146  gcry_sexp_t s_key;
147  gcry_sexp_t s_keyparam;
148 
149  BENCHMARK_START (rsa_private_key_create);
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
165  ret->sexp = s_key;
166  BENCHMARK_END (rsa_private_key_create);
167  return ret;
168 }
169 
170 
171 void
173 {
174  gcry_sexp_release (key->sexp);
175  GNUNET_free (key);
176 }
177 
178 
179 size_t
182  void **buffer)
183 {
184  size_t n;
185  char *b;
186 
187  n = gcry_sexp_sprint (key->sexp,
188  GCRYSEXP_FMT_DEFAULT,
189  NULL,
190  0);
191  b = GNUNET_malloc (n);
192  GNUNET_assert ((n - 1) == /* since the last byte is \0 */
193  gcry_sexp_sprint (key->sexp,
194  GCRYSEXP_FMT_DEFAULT,
195  b,
196  n));
197  *buffer = b;
198  return n;
199 }
200 
201 
204  size_t buf_size)
205 {
207 
209  if (0 !=
210  gcry_sexp_new (&key->sexp,
211  buf,
212  buf_size,
213  0))
214  {
216  "Decoded private key is not valid\n");
217  GNUNET_free (key);
218  return NULL;
219  }
220  if (0 != gcry_pk_testkey (key->sexp))
221  {
223  "Decoded private key is not valid\n");
225  return NULL;
226  }
227  return key;
228 }
229 
230 
233  const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
234 {
236  gcry_mpi_t ne[2];
237  int rc;
238  gcry_sexp_t result;
239 
240  BENCHMARK_START (rsa_private_key_get_public);
241 
242  rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
243  if (0 != rc)
244  rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
245  if (0 != rc)
246  rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
247  if (0 != rc)
248  {
249  GNUNET_break_op (0);
250  return NULL;
251  }
252  rc = gcry_sexp_build (&result,
253  NULL,
254  "(public-key(rsa(n %m)(e %m)))",
255  ne[0],
256  ne[1]);
257  gcry_mpi_release (ne[0]);
258  gcry_mpi_release (ne[1]);
259  pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
260  pub->sexp = result;
261  BENCHMARK_END (rsa_private_key_get_public);
262  return pub;
263 }
264 
265 
266 void
268 {
269  gcry_sexp_release (key->sexp);
270  GNUNET_free (key);
271 }
272 
273 
275 
280 {
284  uint16_t modulus_length GNUNET_PACKED;
285 
289  uint16_t public_exponent_length GNUNET_PACKED;
290 
291  /* followed by variable-size modulus and
292  public exponent follows as big-endian encoded
293  integers */
294 };
295 
297 
298 
299 size_t
301  const struct GNUNET_CRYPTO_RsaPublicKey *key,
302  void **buffer)
303 {
304  gcry_mpi_t ne[2];
305  size_t n_size;
306  size_t e_size;
307  size_t rsize;
308  size_t buf_size;
309  char *buf;
311  int ret;
312 
313  ret = key_from_sexp (ne, key->sexp, "public-key", "ne");
314  if (0 != ret)
315  ret = key_from_sexp (ne, key->sexp, "rsa", "ne");
316  if (0 != ret)
317  {
318  GNUNET_break (0);
319  *buffer = NULL;
320  return 0;
321  }
322  gcry_mpi_print (GCRYMPI_FMT_USG,
323  NULL,
324  0,
325  &n_size,
326  ne[0]);
327  gcry_mpi_print (GCRYMPI_FMT_USG,
328  NULL,
329  0,
330  &e_size,
331  ne[1]);
332  if ( (e_size > UINT16_MAX) ||
333  (n_size > UINT16_MAX) )
334  {
335  GNUNET_break (0);
336  *buffer = NULL;
337  gcry_mpi_release (ne[0]);
338  gcry_mpi_release (ne[1]);
339  return 0;
340  }
341  buf_size = n_size + e_size + sizeof (hdr);
342  buf = GNUNET_malloc (buf_size);
343  hdr.modulus_length = htons ((uint16_t) n_size);
344  hdr.public_exponent_length = htons ((uint16_t) e_size);
345  memcpy (buf, &hdr, sizeof (hdr));
346  GNUNET_assert (0 ==
347  gcry_mpi_print (GCRYMPI_FMT_USG,
348  (unsigned char *) &buf[sizeof (hdr)],
349  n_size,
350  &rsize,
351  ne[0]));
352 
353  GNUNET_assert (0 ==
354  gcry_mpi_print (GCRYMPI_FMT_USG,
355  (unsigned char *) &buf[sizeof (hdr) + n_size],
356  e_size,
357  &rsize,
358  ne[1]));
359  *buffer = buf;
360  gcry_mpi_release (ne[0]);
361  gcry_mpi_release (ne[1]);
362  return buf_size;
363 }
364 
365 
366 void
368  struct GNUNET_HashCode *hc)
369 {
370  void *buf;
371  size_t buf_size;
372 
373  buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
374  &buf);
375  GNUNET_CRYPTO_hash (buf,
376  buf_size,
377  hc);
378  GNUNET_free (buf);
379 }
380 
381 
384  size_t len)
385 {
388  size_t e_size;
389  size_t n_size;
390  gcry_mpi_t n;
391  gcry_mpi_t e;
392  gcry_sexp_t data;
393 
394  if (len < sizeof (hdr))
395  {
396  GNUNET_break_op (0);
397  return NULL;
398  }
399  memcpy (&hdr, buf, sizeof (hdr));
400  n_size = ntohs (hdr.modulus_length);
401  e_size = ntohs (hdr.public_exponent_length);
402  if (len != sizeof (hdr) + e_size + n_size)
403  {
404  GNUNET_break_op (0);
405  return NULL;
406  }
407  if (0 !=
408  gcry_mpi_scan (&n,
409  GCRYMPI_FMT_USG,
410  &buf[sizeof (hdr)],
411  n_size,
412  NULL))
413  {
414  GNUNET_break_op (0);
415  return NULL;
416  }
417  if (0 !=
418  gcry_mpi_scan (&e,
419  GCRYMPI_FMT_USG,
420  &buf[sizeof (hdr) + n_size],
421  e_size,
422  NULL))
423  {
424  GNUNET_break_op (0);
425  gcry_mpi_release (n);
426  return NULL;
427  }
428 
429  if (0 !=
430  gcry_sexp_build (&data,
431  NULL,
432  "(public-key(rsa(n %m)(e %m)))",
433  n,
434  e))
435  {
436  GNUNET_break (0);
437  gcry_mpi_release (n);
438  gcry_mpi_release (e);
439  return NULL;
440  }
441  gcry_mpi_release (n);
442  gcry_mpi_release (e);
443  key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
444  key->sexp = data;
445  return key;
446 }
447 
448 
460 static int
461 rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n)
462 {
463  gcry_mpi_t g;
464  int t;
465 
466  g = gcry_mpi_new (0);
467  t = gcry_mpi_gcd (g, r, n);
468  gcry_mpi_release (g);
469  return t;
470 }
471 
472 
480 static struct RsaBlindingKey *
482  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
483 {
484  char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */
485  struct RsaBlindingKey *blind;
486  gcry_mpi_t n;
487 
488  blind = GNUNET_new (struct RsaBlindingKey);
489  GNUNET_assert (NULL != blind);
490 
491  /* Extract the composite n from the RSA public key */
492  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
493  /* Assert that it at least looks like an RSA key */
494  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
495 
496  GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
497  n,
498  xts, strlen (xts),
499  bks, sizeof(*bks),
500  "Blinding KDF");
501  if (0 == rsa_gcd_validate (blind->r, n))
502  {
503  GNUNET_free (blind);
504  blind = NULL;
505  }
506 
507  gcry_mpi_release (n);
508  return blind;
509 }
510 
511 
512 /*
513  We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benefit of the
514  previous routine.
515 
516  There was previously a call to GNUNET_CRYPTO_kdf in
517  bkey = rsa_blinding_key_derive (len, bks);
518  that gives exactly len bits where
519  len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
520 
521  Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
522  okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
523  pkey.n making the effective bkey be
524  bkey mod pkey.n = bkey - pkey.n
525  so the effective bkey has its high bit set with probability r/2.
526 
527  We expect r to be close to 1/2 if the exchange is honest, but the
528  exchange can choose r otherwise.
529 
530  In blind signing, the exchange sees
531  B = bkey * S mod pkey.n
532  On deposit, the exchange sees S so they can compute bkey' = B/S mod
533  pkey.n for all B they recorded to see if bkey' has it's high bit set.
534  Also, note the exchange can compute 1/S efficiently since they know the
535  factors of pkey.n.
536 
537  I suppose that happens with probability r/(1+r) if its the wrong B, not
538  completely sure. If otoh we've the right B, then we've the probability
539  r/2 of a set high bit in the effective bkey.
540 
541  Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
542  the wrong and right probabilities 1/3 and 1/4, respectively.
543 
544  I feared this gives the exchange a meaningful fraction of a bit of
545  information per coin involved in the transaction. It sounds damaging if
546  numerous coins were involved. And it could run across transactions in
547  some scenarios.
548 
549  We fixed this by using a more uniform deterministic pseudo-random number
550  generator for blinding factors. I do not believe this to be a problem
551  for the rsa_full_domain_hash routine, but better safe than sorry.
552  */
553 
554 
555 int
557  const struct GNUNET_CRYPTO_RsaSignature *s2)
558 {
559  void *b1;
560  void *b2;
561  size_t z1;
562  size_t z2;
563  int ret;
564 
566  &b1);
568  &b2);
569  if (z1 != z2)
570  ret = 1;
571  else
572  ret = memcmp (b1,
573  b2,
574  z1);
575  GNUNET_free (b1);
576  GNUNET_free (b2);
577  return ret;
578 }
579 
580 
581 int
583  const struct GNUNET_CRYPTO_RsaPublicKey *p2)
584 {
585  void *b1;
586  void *b2;
587  size_t z1;
588  size_t z2;
589  int ret;
590 
592  &b1);
594  &b2);
595  if (z1 != z2)
596  ret = 1;
597  else
598  ret = memcmp (b1,
599  b2,
600  z1);
601  GNUNET_free (b1);
602  GNUNET_free (b2);
603  return ret;
604 }
605 
606 
607 int
609  const struct GNUNET_CRYPTO_RsaPrivateKey *p2)
610 {
611  void *b1;
612  void *b2;
613  size_t z1;
614  size_t z2;
615  int ret;
616 
618  &b1);
620  &b2);
621  if (z1 != z2)
622  ret = 1;
623  else
624  ret = memcmp (b1,
625  b2,
626  z1);
627  GNUNET_free (b1);
628  GNUNET_free (b2);
629  return ret;
630 }
631 
632 
633 unsigned int
635 {
636  gcry_mpi_t n;
637  unsigned int rval;
638 
639  if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
640  { /* Not an RSA public key */
641  GNUNET_break (0);
642  return 0;
643  }
644  rval = gcry_mpi_get_nbits (n);
645  gcry_mpi_release (n);
646  return rval;
647 }
648 
649 
655 static void
657 {
658  gcry_mpi_release (bkey->r);
659  GNUNET_free (bkey);
660 }
661 
662 
670 static size_t
672  char **buffer)
673 {
674  size_t n;
675  char *b;
676  size_t rsize;
677 
678  gcry_mpi_print (GCRYMPI_FMT_USG,
679  NULL,
680  0,
681  &n,
682  v);
683  b = GNUNET_malloc (n);
684  GNUNET_assert (0 ==
685  gcry_mpi_print (GCRYMPI_FMT_USG,
686  (unsigned char *) b,
687  n,
688  &rsize,
689  v));
690  *buffer = b;
691  return n;
692 }
693 
694 
707 static gcry_mpi_t
709  const struct GNUNET_HashCode *hash)
710 {
711  gcry_mpi_t r, n;
712  void *xts;
713  size_t xts_len;
714  int ok;
715 
716  /* Extract the composite n from the RSA public key */
717  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
718  /* Assert that it at least looks like an RSA key */
719  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
720 
721  /* We key with the public denomination key as a homage to RSA-PSS by *
722  * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
723  * of the hypothetical polyomial-time attack on RSA-KTI created by a *
724  * polynomial-time one-more forgary attack. Yey seeding! */
725  xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
726 
728  n,
729  xts, xts_len,
730  hash, sizeof(*hash),
731  "RSA-FDA FTpsW!");
732  GNUNET_free (xts);
733 
734  ok = rsa_gcd_validate (r, n);
735  gcry_mpi_release (n);
736  if (ok)
737  return r;
738  gcry_mpi_release (r);
739  return NULL;
740 }
741 
742 
745  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
747  void **buf,
748  size_t *buf_size)
749 {
750  struct RsaBlindingKey *bkey;
751  gcry_mpi_t data;
752  gcry_mpi_t ne[2];
753  gcry_mpi_t r_e;
754  gcry_mpi_t data_r_e;
755  int ret;
756 
757  BENCHMARK_START (rsa_blind);
758 
759  GNUNET_assert (buf != NULL);
760  GNUNET_assert (buf_size != NULL);
761  ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
762  if (0 != ret)
763  ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
764  if (0 != ret)
765  {
766  GNUNET_break (0);
767  *buf = NULL;
768  *buf_size = 0;
769  return GNUNET_NO;
770  }
771 
772  data = rsa_full_domain_hash (pkey, hash);
773  if (NULL == data)
774  goto rsa_gcd_validate_failure;
775 
776  bkey = rsa_blinding_key_derive (pkey, bks);
777  if (NULL == bkey)
778  {
779  gcry_mpi_release (data);
780  goto rsa_gcd_validate_failure;
781  }
782 
783  r_e = gcry_mpi_new (0);
784  gcry_mpi_powm (r_e,
785  bkey->r,
786  ne[1],
787  ne[0]);
788  data_r_e = gcry_mpi_new (0);
789  gcry_mpi_mulm (data_r_e,
790  data,
791  r_e,
792  ne[0]);
793  gcry_mpi_release (data);
794  gcry_mpi_release (ne[0]);
795  gcry_mpi_release (ne[1]);
796  gcry_mpi_release (r_e);
797  rsa_blinding_key_free (bkey);
798 
799  *buf_size = numeric_mpi_alloc_n_print (data_r_e,
800  (char **) buf);
801  gcry_mpi_release (data_r_e);
802 
803  BENCHMARK_END (rsa_blind);
804 
805  return GNUNET_YES;
806 
807 rsa_gcd_validate_failure:
808  /* We know the RSA key is malicious here, so warn the wallet. */
809  /* GNUNET_break_op (0); */
810  gcry_mpi_release (ne[0]);
811  gcry_mpi_release (ne[1]);
812  *buf = NULL;
813  *buf_size = 0;
814  return GNUNET_NO;
815 }
816 
817 
824 static gcry_sexp_t
825 mpi_to_sexp (gcry_mpi_t value)
826 {
827  gcry_sexp_t data = NULL;
828 
829  GNUNET_assert (0 ==
830  gcry_sexp_build (&data,
831  NULL,
832  "(data (flags raw) (value %M))",
833  value));
834  return data;
835 }
836 
837 
845 static struct GNUNET_CRYPTO_RsaSignature *
847  gcry_mpi_t value)
848 {
849  struct GNUNET_CRYPTO_RsaSignature *sig;
850  gcry_sexp_t data;
851  gcry_sexp_t result;
852  int rc;
853 
854  data = mpi_to_sexp (value);
855 
856  if (0 !=
857  (rc = gcry_pk_sign (&result,
858  data,
859  key->sexp)))
860  {
862  _ ("RSA signing failed at %s:%d: %s\n"),
863  __FILE__,
864  __LINE__,
865  gcry_strerror (rc));
866  GNUNET_break (0);
867  return NULL;
868  }
869 
870  /* Lenstra protection was first added to libgcrypt 1.6.4
871  * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
872  */
873 #if GCRYPT_VERSION_NUMBER < 0x010604
874  /* verify signature (guards against Lenstra's attack with fault injection...) */
875  struct GNUNET_CRYPTO_RsaPublicKey *public_key =
877  if (0 !=
878  gcry_pk_verify (result,
879  data,
880  public_key->sexp))
881  {
882  GNUNET_break (0);
884  gcry_sexp_release (data);
885  gcry_sexp_release (result);
886  return NULL;
887  }
889 #endif
890 
891  /* return signature */
892  gcry_sexp_release (data);
893  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
894  sig->sexp = result;
895  return sig;
896 }
897 
898 
901  const void *msg,
902  size_t msg_len)
903 {
904  gcry_mpi_t v = NULL;
905  struct GNUNET_CRYPTO_RsaSignature *sig;
906 
907  BENCHMARK_START (rsa_sign_blinded);
908 
909  GNUNET_assert (0 ==
910  gcry_mpi_scan (&v,
911  GCRYMPI_FMT_USG,
912  msg,
913  msg_len,
914  NULL));
915 
916  sig = rsa_sign_mpi (key, v);
917  gcry_mpi_release (v);
918  BENCHMARK_END (rsa_sign_blinded);
919  return sig;
920 }
921 
922 
925  const struct GNUNET_HashCode *hash)
926 {
928  gcry_mpi_t v = NULL;
929  struct GNUNET_CRYPTO_RsaSignature *sig;
930 
932  v = rsa_full_domain_hash (pkey, hash);
934  if (NULL == v) /* rsa_gcd_validate failed meaning */
935  return NULL; /* our *own* RSA key is malicious. */
936 
937  sig = rsa_sign_mpi (key, v);
938  gcry_mpi_release (v);
939  return sig;
940 }
941 
942 
943 void
945 {
946  gcry_sexp_release (sig->sexp);
947  GNUNET_free (sig);
948 }
949 
950 
951 size_t
953  const struct GNUNET_CRYPTO_RsaSignature *sig,
954  void **buffer)
955 {
956  gcry_mpi_t s;
957  size_t buf_size;
958  size_t rsize;
959  unsigned char *buf;
960  int ret;
961 
962  ret = key_from_sexp (&s,
963  sig->sexp,
964  "sig-val",
965  "s");
966  if (0 != ret)
967  ret = key_from_sexp (&s,
968  sig->sexp,
969  "rsa",
970  "s");
971  GNUNET_assert (0 == ret);
972  gcry_mpi_print (GCRYMPI_FMT_USG,
973  NULL,
974  0,
975  &buf_size,
976  s);
977  buf = GNUNET_malloc (buf_size);
978  GNUNET_assert (0 ==
979  gcry_mpi_print (GCRYMPI_FMT_USG,
980  buf,
981  buf_size,
982  &rsize,
983  s));
984  GNUNET_assert (rsize == buf_size);
985  *buffer = (void *) buf;
986  gcry_mpi_release (s);
987  return buf_size;
988 }
989 
990 
993  size_t buf_size)
994 {
995  struct GNUNET_CRYPTO_RsaSignature *sig;
996  gcry_mpi_t s;
997  gcry_sexp_t data;
998 
999  if (0 !=
1000  gcry_mpi_scan (&s,
1001  GCRYMPI_FMT_USG,
1002  buf,
1003  buf_size,
1004  NULL))
1005  {
1006  GNUNET_break_op (0);
1007  return NULL;
1008  }
1009 
1010  if (0 !=
1011  gcry_sexp_build (&data,
1012  NULL,
1013  "(sig-val(rsa(s %M)))",
1014  s))
1015  {
1016  GNUNET_break (0);
1017  gcry_mpi_release (s);
1018  return NULL;
1019  }
1020  gcry_mpi_release (s);
1021  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1022  sig->sexp = data;
1023  return sig;
1024 }
1025 
1026 
1029 {
1030  struct GNUNET_CRYPTO_RsaPublicKey *dup;
1031  gcry_sexp_t dup_sexp;
1032  size_t erroff;
1033 
1034  /* check if we really are exporting a public key */
1035  dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1036  GNUNET_assert (NULL != dup_sexp);
1037  gcry_sexp_release (dup_sexp);
1038  /* copy the sexp */
1039  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1040  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1041  dup->sexp = dup_sexp;
1042  return dup;
1043 }
1044 
1045 
1048  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1050 {
1051  struct RsaBlindingKey *bkey;
1052  gcry_mpi_t n;
1053  gcry_mpi_t s;
1054  gcry_mpi_t r_inv;
1055  gcry_mpi_t ubsig;
1056  int ret;
1057  struct GNUNET_CRYPTO_RsaSignature *sret;
1058 
1059  BENCHMARK_START (rsa_unblind);
1060 
1061  ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1062  if (0 != ret)
1063  ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1064  if (0 != ret)
1065  {
1066  GNUNET_break_op (0);
1067  return NULL;
1068  }
1069  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1070  if (0 != ret)
1071  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1072  if (0 != ret)
1073  {
1074  gcry_mpi_release (n);
1075  GNUNET_break_op (0);
1076  return NULL;
1077  }
1078 
1079  bkey = rsa_blinding_key_derive (pkey, bks);
1080  if (NULL == bkey)
1081  {
1082  /* RSA key is malicious since rsa_gcd_validate failed here.
1083  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1084  * so the exchange is being malicious in an unfamilair way, maybe
1085  * just trying to crash us. */
1086  GNUNET_break_op (0);
1087  gcry_mpi_release (n);
1088  gcry_mpi_release (s);
1089  return NULL;
1090  }
1091 
1092  r_inv = gcry_mpi_new (0);
1093  if (1 !=
1094  gcry_mpi_invm (r_inv,
1095  bkey->r,
1096  n))
1097  {
1098  /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1099  * caught above, but we handle it the same here. */
1100  GNUNET_break_op (0);
1101  gcry_mpi_release (r_inv);
1102  rsa_blinding_key_free (bkey);
1103  gcry_mpi_release (n);
1104  gcry_mpi_release (s);
1105  return NULL;
1106  }
1107 
1108  ubsig = gcry_mpi_new (0);
1109  gcry_mpi_mulm (ubsig, s, r_inv, n);
1110  gcry_mpi_release (n);
1111  gcry_mpi_release (r_inv);
1112  gcry_mpi_release (s);
1113  rsa_blinding_key_free (bkey);
1114 
1115  sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1116  GNUNET_assert (0 ==
1117  gcry_sexp_build (&sret->sexp,
1118  NULL,
1119  "(sig-val (rsa (s %M)))",
1120  ubsig));
1121  gcry_mpi_release (ubsig);
1122  BENCHMARK_END (rsa_unblind);
1123  return sret;
1124 }
1125 
1126 
1129  const struct GNUNET_CRYPTO_RsaSignature *sig,
1130  const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1131 {
1132  gcry_sexp_t data;
1133  gcry_mpi_t r;
1134  int rc;
1135 
1136  BENCHMARK_START (rsa_verify);
1137 
1138  r = rsa_full_domain_hash (pkey, hash);
1139  if (NULL == r)
1140  {
1141  GNUNET_break_op (0);
1142  /* RSA key is malicious since rsa_gcd_validate failed here.
1143  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1144  * so the exchange is being malicious in an unfamilair way, maybe
1145  * just trying to crash us. Arguably, we've only an internal error
1146  * though because we should've detected this in our previous call
1147  * to GNUNET_CRYPTO_rsa_unblind. *///
1148  return GNUNET_NO;
1149  }
1150 
1151  data = mpi_to_sexp (r);
1152  gcry_mpi_release (r);
1153 
1154  rc = gcry_pk_verify (sig->sexp,
1155  data,
1156  pkey->sexp);
1157  gcry_sexp_release (data);
1158  if (0 != rc)
1159  {
1161  _ ("RSA signature verification failed at %s:%d: %s\n"),
1162  __FILE__,
1163  __LINE__,
1164  gcry_strerror (rc));
1165  BENCHMARK_END (rsa_verify);
1166  return GNUNET_SYSERR;
1167  }
1168  BENCHMARK_END (rsa_verify);
1169  return GNUNET_OK;
1170 }
1171 
1172 
1175  const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1176 {
1177  struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1178  gcry_sexp_t dup_sexp;
1179  size_t erroff;
1180 
1181  /* check if we really are exporting a private key */
1182  dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1183  GNUNET_assert (NULL != dup_sexp);
1184  gcry_sexp_release (dup_sexp);
1185  /* copy the sexp */
1186  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1187  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1188  dup->sexp = dup_sexp;
1189  return dup;
1190 }
1191 
1192 
1195 {
1196  struct GNUNET_CRYPTO_RsaSignature *dup;
1197  gcry_sexp_t dup_sexp;
1198  size_t erroff;
1199  gcry_mpi_t s;
1200  int ret;
1201 
1202  /* verify that this is an RSA signature */
1203  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1204  if (0 != ret)
1205  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1206  GNUNET_assert (0 == ret);
1207  gcry_mpi_release (s);
1208  /* copy the sexp */
1209  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1210  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1211  dup->sexp = dup_sexp;
1212  return dup;
1213 }
1214 
1215 
1216 /* end of util/rsa.c */
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
Definition: crypto_rsa.c:94
unsigned int GNUNET_CRYPTO_rsa_public_key_len(const struct GNUNET_CRYPTO_RsaPublicKey *key)
Obtain the length of the RSA key in bits.
Definition: crypto_rsa.c:634
static struct RsaBlindingKey * rsa_blinding_key_derive(const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
Create a blinding key.
Definition: crypto_rsa.c:481
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_verify(const struct GNUNET_HashCode *hash, const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
Verify whether the given hash corresponds to the given signature and the signature is valid with resp...
Definition: crypto_rsa.c:1128
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * pkey
Public key of the zone to look in, in ASCII.
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_dup(const struct GNUNET_CRYPTO_RsaSignature *sig)
Duplicate the given rsa signature.
Definition: crypto_rsa.c:1194
an RSA signature
Definition: crypto_rsa.c:63
static gcry_mpi_t rsa_full_domain_hash(const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_HashCode *hash)
Computes a full domain hash seeded by the given public key.
Definition: crypto_rsa.c:708
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
void GNUNET_CRYPTO_kdf_mod_mpi(gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx)
Deterministically generate a pseudo-random number uniformly from the integers modulo a libgcrypt mpi...
Definition: crypto_kdf.c:127
uint16_t modulus_length
length of modulus &#39;n&#39; in bytes, in NBO
Definition: crypto_rsa.c:284
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
gcry_mpi_t r
Random value used for blinding.
Definition: crypto_rsa.c:80
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:267
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_private_key_get_public(const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
Extract the public key of the given private key.
Definition: crypto_rsa.c:232
static int ok
Return value from &#39;main&#39; (0 == success)
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:83
static struct Experiment * e
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_decode(const void *buf, size_t buf_size)
Decode the signature from the data-format back to the "normal", internal format.
Definition: crypto_rsa.c:992
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t public_exponent_length
length of exponent in bytes, in NBO
Definition: crypto_rsa.c:289
int GNUNET_CRYPTO_rsa_private_key_cmp(const struct GNUNET_CRYPTO_RsaPrivateKey *p1, const struct GNUNET_CRYPTO_RsaPrivateKey *p2)
Compare the values of two private keys.
Definition: crypto_rsa.c:608
The public information of an RSA key pair.
Definition: crypto_rsa.c:51
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
static gcry_sexp_t mpi_to_sexp(gcry_mpi_t value)
Convert an MPI to an S-expression suitable for signature operations.
Definition: crypto_rsa.c:825
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
cryptographic primitives for GNUnet
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA private key.
Definition: crypto_rsa.c:44
static char * value
Value of the record to add/remove.
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_public_key_decode(const char *buf, size_t len)
Decode the public key from the data-format back to the "normal", internal format. ...
Definition: crypto_rsa.c:383
static size_t numeric_mpi_alloc_n_print(gcry_mpi_t v, char **buffer)
Print an MPI to a newly created buffer.
Definition: crypto_rsa.c:671
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_create(unsigned int len)
Create a new private key.
Definition: crypto_rsa.c:143
static char buf[2048]
#define LOG(kind,...)
Definition: crypto_rsa.c:33
static int rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
Test for malicious RSA key.
Definition: crypto_rsa.c:461
static int result
Global testing status.
A 512-bit hashcode.
RSA blinding key.
Definition: crypto_rsa.c:75
static struct GNUNET_CRYPTO_RsaSignature * rsa_sign_mpi(const struct GNUNET_CRYPTO_RsaPrivateKey *key, gcry_mpi_t value)
Sign the given MPI.
Definition: crypto_rsa.c:846
Format of the header of a serialized RSA public key.
Definition: crypto_rsa.c:279
void GNUNET_CRYPTO_rsa_public_key_hash(const struct GNUNET_CRYPTO_RsaPublicKey *key, struct GNUNET_HashCode *hc)
Compute hash over the public key.
Definition: crypto_rsa.c:367
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_decode(const void *buf, size_t buf_size)
Decode the private key from the data-format back to the "normal", internal format.
Definition: crypto_rsa.c:203
static void rsa_blinding_key_free(struct RsaBlindingKey *bkey)
Destroy a blinding key.
Definition: crypto_rsa.c:656
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA signature.
Definition: crypto_rsa.c:68
size_t GNUNET_CRYPTO_rsa_private_key_encode(const struct GNUNET_CRYPTO_RsaPrivateKey *key, void **buffer)
Encode the private key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:180
void GNUNET_CRYPTO_rsa_signature_free(struct GNUNET_CRYPTO_RsaSignature *sig)
Free memory occupied by signature.
Definition: crypto_rsa.c:944
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
#define GNUNET_PACKED
gcc-ism to get packed structs.
void GNUNET_CRYPTO_rsa_private_key_free(struct GNUNET_CRYPTO_RsaPrivateKey *key)
Free memory occupied by the private key.
Definition: crypto_rsa.c:172
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA public key.
Definition: crypto_rsa.c:56
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
The private information of an RSA key pair.
Definition: crypto_rsa.c:39
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_dup(const struct GNUNET_CRYPTO_RsaPrivateKey *key)
Duplicate the given private key.
Definition: crypto_rsa.c:1174
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_public_key_dup(const struct GNUNET_CRYPTO_RsaPublicKey *key)
Duplicate the given public key.
Definition: crypto_rsa.c:1028
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_unblind(const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey)
Unblind a blind-signed signature.
Definition: crypto_rsa.c:1047
Constant-size pre-secret for blinding key generation.
benchmarking for various operations
int GNUNET_CRYPTO_rsa_public_key_cmp(const struct GNUNET_CRYPTO_RsaPublicKey *p1, const struct GNUNET_CRYPTO_RsaPublicKey *p2)
Compare the values of two public keys.
Definition: crypto_rsa.c:582
GNUNET_NETWORK_STRUCT_END size_t GNUNET_CRYPTO_rsa_public_key_encode(const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer)
Encode the public key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:300
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_blind(const struct GNUNET_HashCode *hash, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey, void **buf, size_t *buf_size)
Blinds the given message with the given blinding key.
Definition: crypto_rsa.c:744
size_t GNUNET_CRYPTO_rsa_signature_encode(const struct GNUNET_CRYPTO_RsaSignature *sig, void **buffer)
Encode the given signature in a format suitable for storing it into a file.
Definition: crypto_rsa.c:952
uint32_t data
The data value.
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_sign_fdh(const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_HashCode *hash)
Create and sign a full domain hash of a message.
Definition: crypto_rsa.c:924
int GNUNET_CRYPTO_rsa_signature_cmp(const struct GNUNET_CRYPTO_RsaSignature *s1, const struct GNUNET_CRYPTO_RsaSignature *s2)
Compare the values of two signatures.
Definition: crypto_rsa.c:556
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_sign_blinded(const struct GNUNET_CRYPTO_RsaPrivateKey *key, const void *msg, size_t msg_len)
Sign a blinded value, which must be a full domain hash of a message.
Definition: crypto_rsa.c:900
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...