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]);
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 {
285 
290 
291  /* followed by variable-size modulus and
292  public exponent follows as big-endian encoded
293  integers */
294 };
295 
297 
298 
299 bool
301  const struct GNUNET_CRYPTO_RsaPublicKey *key)
302 {
303  gcry_mpi_t ne[2];
304  int ret;
305 
306  ret = key_from_sexp (ne,
307  key->sexp,
308  "public-key",
309  "ne");
310  if (0 != ret)
311  ret = key_from_sexp (ne,
312  key->sexp,
313  "rsa",
314  "ne");
315  if (0 != ret)
316  return false;
317  gcry_mpi_release (ne[0]);
318  gcry_mpi_release (ne[1]);
319  return true;
320 }
321 
322 
323 size_t
325  const struct GNUNET_CRYPTO_RsaPublicKey *key,
326  void **buffer)
327 {
328  gcry_mpi_t ne[2];
329  size_t n_size;
330  size_t e_size;
331  size_t rsize;
332  size_t buf_size;
333  char *buf;
335  int ret;
336 
337  ret = key_from_sexp (ne,
338  key->sexp,
339  "public-key",
340  "ne");
341  if (0 != ret)
342  ret = key_from_sexp (ne,
343  key->sexp,
344  "rsa",
345  "ne");
346  if (0 != ret)
347  {
348  GNUNET_break (0);
349  *buffer = NULL;
350  return 0;
351  }
352  gcry_mpi_print (GCRYMPI_FMT_USG,
353  NULL,
354  0,
355  &n_size,
356  ne[0]);
357  gcry_mpi_print (GCRYMPI_FMT_USG,
358  NULL,
359  0,
360  &e_size,
361  ne[1]);
362  if ( (e_size > UINT16_MAX) ||
363  (n_size > UINT16_MAX) )
364  {
365  GNUNET_break (0);
366  if (NULL != buffer)
367  *buffer = NULL;
368  gcry_mpi_release (ne[0]);
369  gcry_mpi_release (ne[1]);
370  return 0;
371  }
372  buf_size = n_size + e_size + sizeof (hdr);
373  if (NULL == buffer)
374  {
375  gcry_mpi_release (ne[0]);
376  gcry_mpi_release (ne[1]);
377  return buf_size;
378  }
379  buf = GNUNET_malloc (buf_size);
380  hdr.modulus_length = htons ((uint16_t) n_size);
381  hdr.public_exponent_length = htons ((uint16_t) e_size);
382  memcpy (buf,
383  &hdr,
384  sizeof (hdr));
385  GNUNET_assert (0 ==
386  gcry_mpi_print (GCRYMPI_FMT_USG,
387  (unsigned char *) &buf[sizeof (hdr)],
388  n_size,
389  &rsize,
390  ne[0]));
391 
392  GNUNET_assert (0 ==
393  gcry_mpi_print (GCRYMPI_FMT_USG,
394  (unsigned char *) &buf[sizeof (hdr) + n_size],
395  e_size,
396  &rsize,
397  ne[1]));
398  *buffer = buf;
399  gcry_mpi_release (ne[0]);
400  gcry_mpi_release (ne[1]);
401  return buf_size;
402 }
403 
404 
405 void
407  struct GNUNET_HashCode *hc)
408 {
409  void *buf;
410  size_t buf_size;
411 
413  &buf);
415  buf_size,
416  hc);
417  GNUNET_free (buf);
418 }
419 
420 
423  size_t len)
424 {
427  size_t e_size;
428  size_t n_size;
429  gcry_mpi_t n;
430  gcry_mpi_t e;
431  gcry_sexp_t data;
432 
433  if (len < sizeof (hdr))
434  {
435  GNUNET_break_op (0);
436  return NULL;
437  }
438  memcpy (&hdr, buf, sizeof (hdr));
439  n_size = ntohs (hdr.modulus_length);
440  e_size = ntohs (hdr.public_exponent_length);
441  if (len != sizeof (hdr) + e_size + n_size)
442  {
443  GNUNET_break_op (0);
444  return NULL;
445  }
446  if (0 !=
447  gcry_mpi_scan (&n,
448  GCRYMPI_FMT_USG,
449  &buf[sizeof (hdr)],
450  n_size,
451  NULL))
452  {
453  GNUNET_break_op (0);
454  return NULL;
455  }
456  if (0 !=
457  gcry_mpi_scan (&e,
458  GCRYMPI_FMT_USG,
459  &buf[sizeof (hdr) + n_size],
460  e_size,
461  NULL))
462  {
463  GNUNET_break_op (0);
464  gcry_mpi_release (n);
465  return NULL;
466  }
467 
468  if (0 !=
469  gcry_sexp_build (&data,
470  NULL,
471  "(public-key(rsa(n %m)(e %m)))",
472  n,
473  e))
474  {
475  GNUNET_break (0);
476  gcry_mpi_release (n);
477  gcry_mpi_release (e);
478  return NULL;
479  }
480  gcry_mpi_release (n);
481  gcry_mpi_release (e);
483  key->sexp = data;
484  return key;
485 }
486 
487 
499 static int
500 rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n)
501 {
502  gcry_mpi_t g;
503  int t;
504 
505  g = gcry_mpi_new (0);
506  t = gcry_mpi_gcd (g, r, n);
507  gcry_mpi_release (g);
508  return t;
509 }
510 
511 
519 static struct RsaBlindingKey *
521  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
522 {
523  char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */
524  struct RsaBlindingKey *blind;
525  gcry_mpi_t n;
526 
527  blind = GNUNET_new (struct RsaBlindingKey);
528  GNUNET_assert (NULL != blind);
529 
530  /* Extract the composite n from the RSA public key */
531  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
532  /* Assert that it at least looks like an RSA key */
533  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
534 
535  GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
536  n,
537  xts, strlen (xts),
538  bks, sizeof(*bks),
539  "Blinding KDF");
540  if (0 == rsa_gcd_validate (blind->r, n))
541  {
542  GNUNET_free (blind);
543  blind = NULL;
544  }
545 
546  gcry_mpi_release (n);
547  return blind;
548 }
549 
550 
551 /*
552  We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benefit of the
553  previous routine.
554 
555  There was previously a call to GNUNET_CRYPTO_kdf in
556  bkey = rsa_blinding_key_derive (len, bks);
557  that gives exactly len bits where
558  len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
559 
560  Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
561  okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
562  pkey.n making the effective bkey be
563  bkey mod pkey.n = bkey - pkey.n
564  so the effective bkey has its high bit set with probability r/2.
565 
566  We expect r to be close to 1/2 if the exchange is honest, but the
567  exchange can choose r otherwise.
568 
569  In blind signing, the exchange sees
570  B = bkey * S mod pkey.n
571  On deposit, the exchange sees S so they can compute bkey' = B/S mod
572  pkey.n for all B they recorded to see if bkey' has it's high bit set.
573  Also, note the exchange can compute 1/S efficiently since they know the
574  factors of pkey.n.
575 
576  I suppose that happens with probability r/(1+r) if its the wrong B, not
577  completely sure. If otoh we've the right B, then we've the probability
578  r/2 of a set high bit in the effective bkey.
579 
580  Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
581  the wrong and right probabilities 1/3 and 1/4, respectively.
582 
583  I feared this gives the exchange a meaningful fraction of a bit of
584  information per coin involved in the transaction. It sounds damaging if
585  numerous coins were involved. And it could run across transactions in
586  some scenarios.
587 
588  We fixed this by using a more uniform deterministic pseudo-random number
589  generator for blinding factors. I do not believe this to be a problem
590  for the rsa_full_domain_hash routine, but better safe than sorry.
591  */
592 
593 
594 int
596  const struct GNUNET_CRYPTO_RsaSignature *s2)
597 {
598  void *b1;
599  void *b2;
600  size_t z1;
601  size_t z2;
602  int ret;
603 
605  &b1);
607  &b2);
608  if (z1 != z2)
609  ret = 1;
610  else
611  ret = memcmp (b1,
612  b2,
613  z1);
614  GNUNET_free (b1);
615  GNUNET_free (b2);
616  return ret;
617 }
618 
619 
620 int
622  const struct GNUNET_CRYPTO_RsaPublicKey *p2)
623 {
624  void *b1;
625  void *b2;
626  size_t z1;
627  size_t z2;
628  int ret;
629 
631  &b1);
633  &b2);
634  if (z1 != z2)
635  ret = 1;
636  else
637  ret = memcmp (b1,
638  b2,
639  z1);
640  GNUNET_free (b1);
641  GNUNET_free (b2);
642  return ret;
643 }
644 
645 
646 int
648  const struct GNUNET_CRYPTO_RsaPrivateKey *p2)
649 {
650  void *b1;
651  void *b2;
652  size_t z1;
653  size_t z2;
654  int ret;
655 
657  &b1);
659  &b2);
660  if (z1 != z2)
661  ret = 1;
662  else
663  ret = memcmp (b1,
664  b2,
665  z1);
666  GNUNET_free (b1);
667  GNUNET_free (b2);
668  return ret;
669 }
670 
671 
672 unsigned int
674 {
675  gcry_mpi_t n;
676  unsigned int rval;
677 
678  if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
679  { /* Not an RSA public key */
680  GNUNET_break (0);
681  return 0;
682  }
683  rval = gcry_mpi_get_nbits (n);
684  gcry_mpi_release (n);
685  return rval;
686 }
687 
688 
694 static void
696 {
697  gcry_mpi_release (bkey->r);
698  GNUNET_free (bkey);
699 }
700 
701 
709 static size_t
711  char **buffer)
712 {
713  size_t n;
714  char *b;
715  size_t rsize;
716 
717  gcry_mpi_print (GCRYMPI_FMT_USG,
718  NULL,
719  0,
720  &n,
721  v);
722  b = GNUNET_malloc (n);
723  GNUNET_assert (0 ==
724  gcry_mpi_print (GCRYMPI_FMT_USG,
725  (unsigned char *) b,
726  n,
727  &rsize,
728  v));
729  *buffer = b;
730  return n;
731 }
732 
733 
746 static gcry_mpi_t
748  const struct GNUNET_HashCode *hash)
749 {
750  gcry_mpi_t r, n;
751  void *xts;
752  size_t xts_len;
753  int ok;
754 
755  /* Extract the composite n from the RSA public key */
756  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
757  /* Assert that it at least looks like an RSA key */
758  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
759 
760  /* We key with the public denomination key as a homage to RSA-PSS by *
761  * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
762  * of the hypothetical polyomial-time attack on RSA-KTI created by a *
763  * polynomial-time one-more forgary attack. Yey seeding! */
764  xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
765 
767  n,
768  xts, xts_len,
769  hash, sizeof(*hash),
770  "RSA-FDA FTpsW!");
771  GNUNET_free (xts);
772 
773  ok = rsa_gcd_validate (r, n);
774  gcry_mpi_release (n);
775  if (ok)
776  return r;
777  gcry_mpi_release (r);
778  return NULL;
779 }
780 
781 
783 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
784  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
786  void **buf,
787  size_t *buf_size)
788 {
789  struct RsaBlindingKey *bkey;
790  gcry_mpi_t data;
791  gcry_mpi_t ne[2];
792  gcry_mpi_t r_e;
793  gcry_mpi_t data_r_e;
794  int ret;
795 
796  BENCHMARK_START (rsa_blind);
797 
798  GNUNET_assert (buf != NULL);
799  GNUNET_assert (buf_size != NULL);
800  ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
801  if (0 != ret)
802  ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
803  if (0 != ret)
804  {
805  GNUNET_break (0);
806  *buf = NULL;
807  *buf_size = 0;
808  return GNUNET_NO;
809  }
810 
811  data = rsa_full_domain_hash (pkey, hash);
812  if (NULL == data)
813  goto rsa_gcd_validate_failure;
814 
815  bkey = rsa_blinding_key_derive (pkey, bks);
816  if (NULL == bkey)
817  {
818  gcry_mpi_release (data);
819  goto rsa_gcd_validate_failure;
820  }
821 
822  r_e = gcry_mpi_new (0);
823  gcry_mpi_powm (r_e,
824  bkey->r,
825  ne[1],
826  ne[0]);
827  data_r_e = gcry_mpi_new (0);
828  gcry_mpi_mulm (data_r_e,
829  data,
830  r_e,
831  ne[0]);
832  gcry_mpi_release (data);
833  gcry_mpi_release (ne[0]);
834  gcry_mpi_release (ne[1]);
835  gcry_mpi_release (r_e);
836  rsa_blinding_key_free (bkey);
837 
838  *buf_size = numeric_mpi_alloc_n_print (data_r_e,
839  (char **) buf);
840  gcry_mpi_release (data_r_e);
841 
842  BENCHMARK_END (rsa_blind);
843 
844  return GNUNET_YES;
845 
846 rsa_gcd_validate_failure:
847  /* We know the RSA key is malicious here, so warn the wallet. */
848  /* GNUNET_break_op (0); */
849  gcry_mpi_release (ne[0]);
850  gcry_mpi_release (ne[1]);
851  *buf = NULL;
852  *buf_size = 0;
853  return GNUNET_NO;
854 }
855 
856 
863 static gcry_sexp_t
864 mpi_to_sexp (gcry_mpi_t value)
865 {
866  gcry_sexp_t data = NULL;
867 
868  GNUNET_assert (0 ==
869  gcry_sexp_build (&data,
870  NULL,
871  "(data (flags raw) (value %M))",
872  value));
873  return data;
874 }
875 
876 
884 static struct GNUNET_CRYPTO_RsaSignature *
886  gcry_mpi_t value)
887 {
888  struct GNUNET_CRYPTO_RsaSignature *sig;
889  gcry_sexp_t data;
890  gcry_sexp_t result;
891  int rc;
892 
893  data = mpi_to_sexp (value);
894 
895  if (0 !=
896  (rc = gcry_pk_sign (&result,
897  data,
898  key->sexp)))
899  {
901  _ ("RSA signing failed at %s:%d: %s\n"),
902  __FILE__,
903  __LINE__,
904  gcry_strerror (rc));
905  gcry_sexp_release (data);
906  GNUNET_break (0);
907  return NULL;
908  }
909 
910  /* Lenstra protection was first added to libgcrypt 1.6.4
911  * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
912  */
913 #if GCRYPT_VERSION_NUMBER < 0x010604
914  /* verify signature (guards against Lenstra's attack with fault injection...) */
915  struct GNUNET_CRYPTO_RsaPublicKey *public_key =
917  if (0 !=
918  gcry_pk_verify (result,
919  data,
920  public_key->sexp))
921  {
922  GNUNET_break (0);
924  gcry_sexp_release (data);
925  gcry_sexp_release (result);
926  return NULL;
927  }
929 #endif
930 
931  /* return signature */
932  gcry_sexp_release (data);
933  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
934  sig->sexp = result;
935  return sig;
936 }
937 
938 
941  const void *msg,
942  size_t msg_len)
943 {
944  gcry_mpi_t v = NULL;
945  struct GNUNET_CRYPTO_RsaSignature *sig;
946 
947  BENCHMARK_START (rsa_sign_blinded);
948 
949  GNUNET_assert (0 ==
950  gcry_mpi_scan (&v,
951  GCRYMPI_FMT_USG,
952  msg,
953  msg_len,
954  NULL));
955 
956  sig = rsa_sign_mpi (key, v);
957  gcry_mpi_release (v);
958  BENCHMARK_END (rsa_sign_blinded);
959  return sig;
960 }
961 
962 
965  const struct GNUNET_HashCode *hash)
966 {
968  gcry_mpi_t v = NULL;
969  struct GNUNET_CRYPTO_RsaSignature *sig;
970 
972  v = rsa_full_domain_hash (pkey, hash);
974  if (NULL == v) /* rsa_gcd_validate failed meaning */
975  return NULL; /* our *own* RSA key is malicious. */
976 
977  sig = rsa_sign_mpi (key, v);
978  gcry_mpi_release (v);
979  return sig;
980 }
981 
982 
983 void
985 {
986  gcry_sexp_release (sig->sexp);
987  GNUNET_free (sig);
988 }
989 
990 
991 size_t
993  const struct GNUNET_CRYPTO_RsaSignature *sig,
994  void **buffer)
995 {
996  gcry_mpi_t s;
997  size_t buf_size;
998  size_t rsize;
999  unsigned char *buf;
1000  int ret;
1001 
1002  ret = key_from_sexp (&s,
1003  sig->sexp,
1004  "sig-val",
1005  "s");
1006  if (0 != ret)
1007  ret = key_from_sexp (&s,
1008  sig->sexp,
1009  "rsa",
1010  "s");
1011  GNUNET_assert (0 == ret);
1012  gcry_mpi_print (GCRYMPI_FMT_USG,
1013  NULL,
1014  0,
1015  &buf_size,
1016  s);
1017  buf = GNUNET_malloc (buf_size);
1018  GNUNET_assert (0 ==
1019  gcry_mpi_print (GCRYMPI_FMT_USG,
1020  buf,
1021  buf_size,
1022  &rsize,
1023  s));
1024  GNUNET_assert (rsize == buf_size);
1025  *buffer = (void *) buf;
1026  gcry_mpi_release (s);
1027  return buf_size;
1028 }
1029 
1030 
1033  size_t buf_size)
1034 {
1035  struct GNUNET_CRYPTO_RsaSignature *sig;
1036  gcry_mpi_t s;
1037  gcry_sexp_t data;
1038 
1039  if (0 !=
1040  gcry_mpi_scan (&s,
1041  GCRYMPI_FMT_USG,
1042  buf,
1043  buf_size,
1044  NULL))
1045  {
1046  GNUNET_break_op (0);
1047  return NULL;
1048  }
1049 
1050  if (0 !=
1051  gcry_sexp_build (&data,
1052  NULL,
1053  "(sig-val(rsa(s %M)))",
1054  s))
1055  {
1056  GNUNET_break (0);
1057  gcry_mpi_release (s);
1058  return NULL;
1059  }
1060  gcry_mpi_release (s);
1061  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1062  sig->sexp = data;
1063  return sig;
1064 }
1065 
1066 
1069 {
1070  struct GNUNET_CRYPTO_RsaPublicKey *dup;
1071  gcry_sexp_t dup_sexp;
1072  size_t erroff;
1073 
1074  /* check if we really are exporting a public key */
1075  dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1076  GNUNET_assert (NULL != dup_sexp);
1077  gcry_sexp_release (dup_sexp);
1078  /* copy the sexp */
1079  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1080  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1081  dup->sexp = dup_sexp;
1082  return dup;
1083 }
1084 
1085 
1088  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1090 {
1091  struct RsaBlindingKey *bkey;
1092  gcry_mpi_t n;
1093  gcry_mpi_t s;
1094  gcry_mpi_t r_inv;
1095  gcry_mpi_t ubsig;
1096  int ret;
1097  struct GNUNET_CRYPTO_RsaSignature *sret;
1098 
1099  BENCHMARK_START (rsa_unblind);
1100 
1101  ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1102  if (0 != ret)
1103  ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1104  if (0 != ret)
1105  {
1106  GNUNET_break_op (0);
1107  return NULL;
1108  }
1109  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1110  if (0 != ret)
1111  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1112  if (0 != ret)
1113  {
1114  gcry_mpi_release (n);
1115  GNUNET_break_op (0);
1116  return NULL;
1117  }
1118 
1119  bkey = rsa_blinding_key_derive (pkey, bks);
1120  if (NULL == bkey)
1121  {
1122  /* RSA key is malicious since rsa_gcd_validate failed here.
1123  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1124  * so the exchange is being malicious in an unfamilair way, maybe
1125  * just trying to crash us. */
1126  GNUNET_break_op (0);
1127  gcry_mpi_release (n);
1128  gcry_mpi_release (s);
1129  return NULL;
1130  }
1131 
1132  r_inv = gcry_mpi_new (0);
1133  if (1 !=
1134  gcry_mpi_invm (r_inv,
1135  bkey->r,
1136  n))
1137  {
1138  /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1139  * caught above, but we handle it the same here. */
1140  GNUNET_break_op (0);
1141  gcry_mpi_release (r_inv);
1142  rsa_blinding_key_free (bkey);
1143  gcry_mpi_release (n);
1144  gcry_mpi_release (s);
1145  return NULL;
1146  }
1147 
1148  ubsig = gcry_mpi_new (0);
1149  gcry_mpi_mulm (ubsig, s, r_inv, n);
1150  gcry_mpi_release (n);
1151  gcry_mpi_release (r_inv);
1152  gcry_mpi_release (s);
1153  rsa_blinding_key_free (bkey);
1154 
1155  sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1156  GNUNET_assert (0 ==
1157  gcry_sexp_build (&sret->sexp,
1158  NULL,
1159  "(sig-val (rsa (s %M)))",
1160  ubsig));
1161  gcry_mpi_release (ubsig);
1162  BENCHMARK_END (rsa_unblind);
1163  return sret;
1164 }
1165 
1166 
1168 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1169  const struct GNUNET_CRYPTO_RsaSignature *sig,
1170  const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1171 {
1172  gcry_sexp_t data;
1173  gcry_mpi_t r;
1174  int rc;
1175 
1176  BENCHMARK_START (rsa_verify);
1177 
1178  r = rsa_full_domain_hash (pkey, hash);
1179  if (NULL == r)
1180  {
1181  GNUNET_break_op (0);
1182  /* RSA key is malicious since rsa_gcd_validate failed here.
1183  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1184  * so the exchange is being malicious in an unfamilair way, maybe
1185  * just trying to crash us. Arguably, we've only an internal error
1186  * though because we should've detected this in our previous call
1187  * to GNUNET_CRYPTO_rsa_unblind. *///
1188  return GNUNET_NO;
1189  }
1190 
1191  data = mpi_to_sexp (r);
1192  gcry_mpi_release (r);
1193 
1194  rc = gcry_pk_verify (sig->sexp,
1195  data,
1196  pkey->sexp);
1197  gcry_sexp_release (data);
1198  if (0 != rc)
1199  {
1201  _ ("RSA signature verification failed at %s:%d: %s\n"),
1202  __FILE__,
1203  __LINE__,
1204  gcry_strerror (rc));
1205  BENCHMARK_END (rsa_verify);
1206  return GNUNET_SYSERR;
1207  }
1208  BENCHMARK_END (rsa_verify);
1209  return GNUNET_OK;
1210 }
1211 
1212 
1215  const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1216 {
1217  struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1218  gcry_sexp_t dup_sexp;
1219  size_t erroff;
1220 
1221  /* check if we really are exporting a private key */
1222  dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1223  GNUNET_assert (NULL != dup_sexp);
1224  gcry_sexp_release (dup_sexp);
1225  /* copy the sexp */
1226  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1227  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1228  dup->sexp = dup_sexp;
1229  return dup;
1230 }
1231 
1232 
1235 {
1236  struct GNUNET_CRYPTO_RsaSignature *dup;
1237  gcry_sexp_t dup_sexp;
1238  size_t erroff;
1239  gcry_mpi_t s;
1240  int ret;
1241 
1242  /* verify that this is an RSA signature */
1243  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1244  if (0 != ret)
1245  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1246  GNUNET_assert (0 == ret);
1247  gcry_mpi_release (s);
1248  /* copy the sexp */
1249  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1250  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1251  dup->sexp = dup_sexp;
1252  return dup;
1253 }
1254 
1255 
1256 /* end of util/rsa.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
benchmarking for various operations
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
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:1068
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
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:1032
void GNUNET_CRYPTO_rsa_signature_free(struct GNUNET_CRYPTO_RsaSignature *sig)
Free memory occupied by signature.
Definition: crypto_rsa.c:984
void GNUNET_CRYPTO_rsa_private_key_free(struct GNUNET_CRYPTO_RsaPrivateKey *key)
Free memory occupied by the private key.
Definition: crypto_rsa.c:172
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:783
static void rsa_blinding_key_free(struct RsaBlindingKey *bkey)
Destroy a blinding key.
Definition: crypto_rsa.c:695
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
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:1087
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:595
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:673
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:406
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:864
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:267
GNUNET_NETWORK_STRUCT_END bool GNUNET_CRYPTO_rsa_public_key_check(const struct GNUNET_CRYPTO_RsaPublicKey *key)
Check if key is well-formed.
Definition: crypto_rsa.c:300
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:422
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:885
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:324
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:647
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:747
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:992
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_dup(const struct GNUNET_CRYPTO_RsaSignature *sig)
Duplicate the given rsa signature.
Definition: crypto_rsa.c:1234
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:964
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:520
#define LOG(kind,...)
Definition: crypto_rsa.c:33
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:621
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:1168
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 rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
Test for malicious RSA key.
Definition: crypto_rsa.c:500
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:710
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
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_create(unsigned int len)
Create a new private key.
Definition: crypto_rsa.c:143
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:1214
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:940
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
static struct Experiment * e
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * pkey
Public key of the zone to look in, in ASCII.
static char * value
Value of the record to add/remove.
static int ok
Return value from 'main' (0 == success)
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
static char buf[2048]
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_PACKED
gcc-ism to get packed structs.
cryptographic primitives for GNUnet
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
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
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Constant-size pre-secret for blinding key generation.
The private information of an RSA key pair.
Definition: crypto_rsa.c:40
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA private key.
Definition: crypto_rsa.c:44
Format of the header of a serialized RSA public key.
Definition: crypto_rsa.c:280
uint16_t public_exponent_length
length of exponent in bytes, in NBO
Definition: crypto_rsa.c:289
uint16_t modulus_length
length of modulus 'n' in bytes, in NBO
Definition: crypto_rsa.c:284
The public information of an RSA key pair.
Definition: crypto_rsa.c:52
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA public key.
Definition: crypto_rsa.c:56
an RSA signature
Definition: crypto_rsa.c:64
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA signature.
Definition: crypto_rsa.c:68
A 512-bit hashcode.
RSA blinding key.
Definition: crypto_rsa.c:76
gcry_mpi_t r
Random value used for blinding.
Definition: crypto_rsa.c:80