GNUnet  0.10.x
crypto_rsa.c
Go to the documentation of this file.
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
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 
43  gcry_sexp_t sexp;
44 };
45 
46 
54  gcry_sexp_t sexp;
55 };
56 
57 
65  gcry_sexp_t sexp;
66 };
67 
68 
76  gcry_mpi_t r;
77 };
78 
79 
89 static int
90 key_from_sexp(gcry_mpi_t *array,
91  gcry_sexp_t sexp,
92  const char *topname,
93  const char *elems)
94 {
95  gcry_sexp_t list;
96  gcry_sexp_t l2;
97  const char *s;
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 (unsigned int 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 (unsigned int 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 
146 {
148  gcry_sexp_t s_key;
149  gcry_sexp_t s_keyparam;
150 
151  BENCHMARK_START(rsa_private_key_create);
152 
153  GNUNET_assert(0 ==
154  gcry_sexp_build(&s_keyparam,
155  NULL,
156  "(genkey(rsa(nbits %d)))",
157  len));
158  GNUNET_assert(0 ==
159  gcry_pk_genkey(&s_key,
160  s_keyparam));
161  gcry_sexp_release(s_keyparam);
162 #if EXTRA_CHECKS
163  GNUNET_assert(0 ==
164  gcry_pk_testkey(s_key));
165 #endif
167  ret->sexp = s_key;
168  BENCHMARK_END(rsa_private_key_create);
169  return ret;
170 }
171 
172 
178 void
180 {
181  gcry_sexp_release(key->sexp);
182  GNUNET_free(key);
183 }
184 
185 
194 size_t
196  char **buffer)
197 {
198  size_t n;
199  char *b;
200 
201  n = gcry_sexp_sprint(key->sexp,
202  GCRYSEXP_FMT_DEFAULT,
203  NULL,
204  0);
205  b = GNUNET_malloc(n);
206  GNUNET_assert((n - 1) == /* since the last byte is \0 */
207  gcry_sexp_sprint(key->sexp,
208  GCRYSEXP_FMT_DEFAULT,
209  b,
210  n));
211  *buffer = b;
212  return n;
213 }
214 
215 
226  size_t len)
227 {
229 
231  if (0 !=
232  gcry_sexp_new(&key->sexp,
233  buf,
234  len,
235  0))
236  {
238  "Decoded private key is not valid\n");
239  GNUNET_free(key);
240  return NULL;
241  }
242  if (0 != gcry_pk_testkey(key->sexp))
243  {
245  "Decoded private key is not valid\n");
247  return NULL;
248  }
249  return key;
250 }
251 
252 
261 {
263  gcry_mpi_t ne[2];
264  int rc;
265  gcry_sexp_t result;
266 
267  BENCHMARK_START(rsa_private_key_get_public);
268 
269  rc = key_from_sexp(ne, priv->sexp, "public-key", "ne");
270  if (0 != rc)
271  rc = key_from_sexp(ne, priv->sexp, "private-key", "ne");
272  if (0 != rc)
273  rc = key_from_sexp(ne, priv->sexp, "rsa", "ne");
274  if (0 != rc)
275  {
276  GNUNET_break_op(0);
277  return NULL;
278  }
279  rc = gcry_sexp_build(&result,
280  NULL,
281  "(public-key(rsa(n %m)(e %m)))",
282  ne[0],
283  ne[1]);
284  gcry_mpi_release(ne[0]);
285  gcry_mpi_release(ne[1]);
287  pub->sexp = result;
288  BENCHMARK_END(rsa_private_key_get_public);
289  return pub;
290 }
291 
292 
298 void
300 {
301  gcry_sexp_release(key->sexp);
302  GNUNET_free(key);
303 }
304 
305 
314 size_t
316  char **buffer)
317 {
318  size_t n;
319  char *b;
320 
321  n = gcry_sexp_sprint(key->sexp,
322  GCRYSEXP_FMT_ADVANCED,
323  NULL,
324  0);
325  b = GNUNET_malloc(n);
326  GNUNET_assert((n - 1) == /* since the last byte is \0 */
327  gcry_sexp_sprint(key->sexp,
328  GCRYSEXP_FMT_ADVANCED,
329  b,
330  n));
331  *buffer = b;
332  return n;
333 }
334 
335 
342 void
344  struct GNUNET_HashCode *hc)
345 {
346  char *buf;
347  size_t buf_size;
348 
350  &buf);
351  GNUNET_CRYPTO_hash(buf,
352  buf_size,
353  hc);
354  GNUNET_free(buf);
355 }
356 
357 
368  size_t len)
369 {
371  gcry_mpi_t n;
372  int ret;
373 
375  if (0 !=
376  gcry_sexp_new(&key->sexp,
377  buf,
378  len,
379  0))
380  {
381  GNUNET_break_op(0);
382  GNUNET_free(key);
383  return NULL;
384  }
385  /* verify that this is an RSA public key */
386  ret = key_from_sexp(&n, key->sexp, "public-key", "n");
387  if (0 != ret)
388  ret = key_from_sexp(&n, key->sexp, "rsa", "n");
389  if (0 != ret)
390  {
391  /* this is no public RSA key */
392  GNUNET_break(0);
393  gcry_sexp_release(key->sexp);
394  GNUNET_free(key);
395  return NULL;
396  }
397  gcry_mpi_release(n);
398  return key;
399 }
400 
401 
413 static int
414 rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
415 {
416  gcry_mpi_t g;
417  int t;
418 
419  g = gcry_mpi_new(0);
420  t = gcry_mpi_gcd(g, r, n);
421  gcry_mpi_release(g);
422  return t;
423 }
424 
425 
433 static struct RsaBlindingKey *
435  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
436 {
437  char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */
438  struct RsaBlindingKey *blind;
439  gcry_mpi_t n;
440 
441  blind = GNUNET_new(struct RsaBlindingKey);
442  GNUNET_assert(NULL != blind);
443 
444  /* Extract the composite n from the RSA public key */
445  GNUNET_assert(0 == key_from_sexp(&n, pkey->sexp, "rsa", "n"));
446  /* Assert that it at least looks like an RSA key */
447  GNUNET_assert(0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE));
448 
450  n,
451  xts, strlen(xts),
452  bks, sizeof(*bks),
453  "Blinding KDF");
454  if (0 == rsa_gcd_validate(blind->r, n))
455  {
456  GNUNET_free(blind);
457  blind = NULL;
458  }
459 
460  gcry_mpi_release(n);
461  return blind;
462 }
463 
464 
465 /*
466  We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
467  previous routine.
468 
469  There was previously a call to GNUNET_CRYPTO_kdf in
470  bkey = rsa_blinding_key_derive (len, bks);
471  that gives exactly len bits where
472  len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
473 
474  Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
475  okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
476  pkey.n making the effective bkey be
477  bkey mod pkey.n = bkey - pkey.n
478  so the effective bkey has its high bit set with probability r/2.
479 
480  We expect r to be close to 1/2 if the exchange is honest, but the
481  exchange can choose r otherwise.
482 
483  In blind signing, the exchange sees
484  B = bkey * S mod pkey.n
485  On deposit, the exchange sees S so they can compute bkey' = B/S mod
486  pkey.n for all B they recorded to see if bkey' has it's high bit set.
487  Also, note the exchange can compute 1/S efficiently since they know the
488  factors of pkey.n.
489 
490  I suppose that happens with probability r/(1+r) if its the wrong B, not
491  completely sure. If otoh we've the right B, then we've the probability
492  r/2 of a set high bit in the effective bkey.
493 
494  Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
495  the wrong and right probabilities 1/3 and 1/4, respectively.
496 
497  I feared this gives the exchange a meaningful fraction of a bit of
498  information per coin involved in the transaction. It sounds damaging if
499  numerous coins were involved. And it could run across transactions in
500  some scenarios.
501 
502  We fixed this by using a more uniform deterministic pseudo-random number
503  generator for blinding factors. I do not believe this to be a problem
504  for the rsa_full_domain_hash routine, but better safe than sorry.
505  */
506 
507 
515 int
517  struct GNUNET_CRYPTO_RsaSignature *s2)
518 {
519  char *b1;
520  char *b2;
521  size_t z1;
522  size_t z2;
523  int ret;
524 
526  &b1);
528  &b2);
529  if (z1 != z2)
530  ret = 1;
531  else
532  ret = memcmp(b1,
533  b2,
534  z1);
535  GNUNET_free(b1);
536  GNUNET_free(b2);
537  return ret;
538 }
539 
540 
548 int
550  struct GNUNET_CRYPTO_RsaPublicKey *p2)
551 {
552  char *b1;
553  char *b2;
554  size_t z1;
555  size_t z2;
556  int ret;
557 
559  &b1);
561  &b2);
562  if (z1 != z2)
563  ret = 1;
564  else
565  ret = memcmp(b1,
566  b2,
567  z1);
568  GNUNET_free(b1);
569  GNUNET_free(b2);
570  return ret;
571 }
572 
573 
581 int
583  struct GNUNET_CRYPTO_RsaPrivateKey *p2)
584 {
585  char *b1;
586  char *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 
613 unsigned int
615 {
616  gcry_mpi_t n;
617  unsigned int rval;
618 
619  if (0 != key_from_sexp(&n, key->sexp, "rsa", "n"))
620  { /* Not an RSA public key */
621  GNUNET_break(0);
622  return 0;
623  }
624  rval = gcry_mpi_get_nbits(n);
625  gcry_mpi_release(n);
626  return rval;
627 }
628 
629 
635 static void
637 {
638  gcry_mpi_release(bkey->r);
639  GNUNET_free(bkey);
640 }
641 
642 
650 static size_t
652  char **buffer)
653 {
654  size_t n;
655  char *b;
656  size_t rsize;
657 
658  gcry_mpi_print(GCRYMPI_FMT_USG,
659  NULL,
660  0,
661  &n,
662  v);
663  b = GNUNET_malloc(n);
664  GNUNET_assert(0 ==
665  gcry_mpi_print(GCRYMPI_FMT_USG,
666  (unsigned char *)b,
667  n,
668  &rsize,
669  v));
670  *buffer = b;
671  return n;
672 }
673 
674 
687 static gcry_mpi_t
689  const struct GNUNET_HashCode *hash)
690 {
691  gcry_mpi_t r, n;
692  char *xts;
693  size_t xts_len;
694  int ok;
695 
696  /* Extract the composite n from the RSA public key */
697  GNUNET_assert(0 == key_from_sexp(&n, pkey->sexp, "rsa", "n"));
698  /* Assert that it at least looks like an RSA key */
699  GNUNET_assert(0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE));
700 
701  /* We key with the public denomination key as a homage to RSA-PSS by *
702  * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
703  * of the hypothetical polyomial-time attack on RSA-KTI created by a *
704  * polynomial-time one-more forgary attack. Yey seeding! */
705  xts_len = GNUNET_CRYPTO_rsa_public_key_encode(pkey, &xts);
706 
708  n,
709  xts, xts_len,
710  hash, sizeof(*hash),
711  "RSA-FDA FTpsW!");
712  GNUNET_free(xts);
713 
714  ok = rsa_gcd_validate(r, n);
715  gcry_mpi_release(n);
716  if (ok)
717  return r;
718  gcry_mpi_release(r);
719  return NULL;
720 }
721 
722 
733 int
735  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
737  char **buf, size_t *buf_size)
738 {
739  struct RsaBlindingKey *bkey;
740  gcry_mpi_t data;
741  gcry_mpi_t ne[2];
742  gcry_mpi_t r_e;
743  gcry_mpi_t data_r_e;
744  int ret;
745 
746  BENCHMARK_START(rsa_blind);
747 
748  GNUNET_assert(buf != NULL && buf_size != NULL);
749  ret = key_from_sexp(ne, pkey->sexp, "public-key", "ne");
750  if (0 != ret)
751  ret = key_from_sexp(ne, pkey->sexp, "rsa", "ne");
752  if (0 != ret)
753  {
754  GNUNET_break(0);
755  *buf = NULL;
756  *buf_size = 0;
757  return 0;
758  }
759 
760  data = rsa_full_domain_hash(pkey, hash);
761  if (NULL == data)
762  goto rsa_gcd_validate_failure;
763 
764  bkey = rsa_blinding_key_derive(pkey, bks);
765  if (NULL == bkey)
766  {
767  gcry_mpi_release(data);
768  goto rsa_gcd_validate_failure;
769  }
770 
771  r_e = gcry_mpi_new(0);
772  gcry_mpi_powm(r_e,
773  bkey->r,
774  ne[1],
775  ne[0]);
776  data_r_e = gcry_mpi_new(0);
777  gcry_mpi_mulm(data_r_e,
778  data,
779  r_e,
780  ne[0]);
781  gcry_mpi_release(data);
782  gcry_mpi_release(ne[0]);
783  gcry_mpi_release(ne[1]);
784  gcry_mpi_release(r_e);
785  rsa_blinding_key_free(bkey);
786 
787  *buf_size = numeric_mpi_alloc_n_print(data_r_e, buf);
788  gcry_mpi_release(data_r_e);
789 
790  BENCHMARK_END(rsa_blind);
791 
792  return GNUNET_YES;
793 
794 rsa_gcd_validate_failure:
795  /* We know the RSA key is malicious here, so warn the wallet. */
796  /* GNUNET_break_op (0); */
797  gcry_mpi_release(ne[0]);
798  gcry_mpi_release(ne[1]);
799  *buf = NULL;
800  *buf_size = 0;
801  return GNUNET_NO;
802 }
803 
804 
811 static gcry_sexp_t
812 mpi_to_sexp(gcry_mpi_t value)
813 {
814  gcry_sexp_t data = NULL;
815 
816  GNUNET_assert(0 ==
817  gcry_sexp_build(&data,
818  NULL,
819  "(data (flags raw) (value %M))",
820  value));
821  return data;
822 }
823 
824 
832 static struct GNUNET_CRYPTO_RsaSignature *
834  gcry_mpi_t value)
835 {
836  struct GNUNET_CRYPTO_RsaSignature *sig;
837  gcry_sexp_t data;
838  gcry_sexp_t result;
839  int rc;
840 
841  data = mpi_to_sexp(value);
842 
843  if (0 !=
844  (rc = gcry_pk_sign(&result,
845  data,
846  key->sexp)))
847  {
849  _("RSA signing failed at %s:%d: %s\n"),
850  __FILE__,
851  __LINE__,
852  gcry_strerror(rc));
853  GNUNET_break(0);
854  return NULL;
855  }
856 
857  /* Lenstra protection was first added to libgcrypt 1.6.4
858  * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
859  */
860 #if GCRYPT_VERSION_NUMBER < 0x010604
861  /* verify signature (guards against Lenstra's attack with fault injection...) */
863  if (0 !=
864  gcry_pk_verify(result,
865  data,
866  public_key->sexp))
867  {
868  GNUNET_break(0);
870  gcry_sexp_release(data);
871  gcry_sexp_release(result);
872  return NULL;
873  }
875 #endif
876 
877  /* return signature */
878  gcry_sexp_release(data);
880  sig->sexp = result;
881  return sig;
882 }
883 
884 
895  const void *msg,
896  size_t msg_len)
897 {
898  gcry_mpi_t v = NULL;
899  struct GNUNET_CRYPTO_RsaSignature *sig;
900 
901  BENCHMARK_START(rsa_sign_blinded);
902 
903  GNUNET_assert(0 ==
904  gcry_mpi_scan(&v,
905  GCRYMPI_FMT_USG,
906  msg,
907  msg_len,
908  NULL));
909 
910  sig = rsa_sign_mpi(key, v);
911  gcry_mpi_release(v);
912  BENCHMARK_END(rsa_sign_blinded);
913  return sig;
914 }
915 
916 
926  const struct GNUNET_HashCode *hash)
927 {
929  gcry_mpi_t v = NULL;
930  struct GNUNET_CRYPTO_RsaSignature *sig;
931 
933  v = rsa_full_domain_hash(pkey, hash);
935  if (NULL == v) /* rsa_gcd_validate failed meaning */
936  return NULL; /* our *own* RSA key is malicious. */
937 
938  sig = rsa_sign_mpi(key, v);
939  gcry_mpi_release(v);
940  return sig;
941 }
942 
943 
949 void
951 {
952  gcry_sexp_release(sig->sexp);
953  GNUNET_free(sig);
954 }
955 
956 
964 size_t
966  char **buffer)
967 {
968  size_t n;
969  char *b;
970 
971  n = gcry_sexp_sprint(sig->sexp,
972  GCRYSEXP_FMT_ADVANCED,
973  NULL,
974  0);
975  b = GNUNET_malloc(n);
976  GNUNET_assert((n - 1) == /* since the last byte is \0 */
977  gcry_sexp_sprint(sig->sexp,
978  GCRYSEXP_FMT_ADVANCED,
979  b,
980  n));
981  *buffer = b;
982  return n;
983 }
984 
985 
996  size_t len)
997 {
998  struct GNUNET_CRYPTO_RsaSignature *sig;
999  int ret;
1000  gcry_mpi_t s;
1001 
1002  sig = GNUNET_new(struct GNUNET_CRYPTO_RsaSignature);
1003  if (0 !=
1004  gcry_sexp_new(&sig->sexp,
1005  buf,
1006  len,
1007  0))
1008  {
1009  GNUNET_break_op(0);
1010  GNUNET_free(sig);
1011  return NULL;
1012  }
1013  /* verify that this is an RSA signature */
1014  ret = key_from_sexp(&s, sig->sexp, "sig-val", "s");
1015  if (0 != ret)
1016  ret = key_from_sexp(&s, sig->sexp, "rsa", "s");
1017  if (0 != ret)
1018  {
1019  /* this is no RSA Signature */
1020  GNUNET_break_op(0);
1021  gcry_sexp_release(sig->sexp);
1022  GNUNET_free(sig);
1023  return NULL;
1024  }
1025  gcry_mpi_release(s);
1026  return sig;
1027 }
1028 
1029 
1038 {
1039  struct GNUNET_CRYPTO_RsaPublicKey *dup;
1040  gcry_sexp_t dup_sexp;
1041  size_t erroff;
1042 
1043  /* check if we really are exporting a public key */
1044  dup_sexp = gcry_sexp_find_token(key->sexp, "public-key", 0);
1045  GNUNET_assert(NULL != dup_sexp);
1046  gcry_sexp_release(dup_sexp);
1047  /* copy the sexp */
1048  GNUNET_assert(0 == gcry_sexp_build(&dup_sexp, &erroff, "%S", key->sexp));
1049  dup = GNUNET_new(struct GNUNET_CRYPTO_RsaPublicKey);
1050  dup->sexp = dup_sexp;
1051  return dup;
1052 }
1053 
1054 
1067  const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1069 {
1070  struct RsaBlindingKey *bkey;
1071  gcry_mpi_t n;
1072  gcry_mpi_t s;
1073  gcry_mpi_t r_inv;
1074  gcry_mpi_t ubsig;
1075  int ret;
1076  struct GNUNET_CRYPTO_RsaSignature *sret;
1077 
1078  BENCHMARK_START(rsa_unblind);
1079 
1080  ret = key_from_sexp(&n, pkey->sexp, "public-key", "n");
1081  if (0 != ret)
1082  ret = key_from_sexp(&n, pkey->sexp, "rsa", "n");
1083  if (0 != ret)
1084  {
1085  GNUNET_break_op(0);
1086  return NULL;
1087  }
1088  ret = key_from_sexp(&s, sig->sexp, "sig-val", "s");
1089  if (0 != ret)
1090  ret = key_from_sexp(&s, sig->sexp, "rsa", "s");
1091  if (0 != ret)
1092  {
1093  gcry_mpi_release(n);
1094  GNUNET_break_op(0);
1095  return NULL;
1096  }
1097 
1098  bkey = rsa_blinding_key_derive(pkey, bks);
1099  if (NULL == bkey)
1100  {
1101  /* RSA key is malicious since rsa_gcd_validate failed here.
1102  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1103  * so the exchange is being malicious in an unfamilair way, maybe
1104  * just trying to crash us. */
1105  GNUNET_break_op(0);
1106  gcry_mpi_release(n);
1107  gcry_mpi_release(s);
1108  return NULL;
1109  }
1110 
1111  r_inv = gcry_mpi_new(0);
1112  if (1 !=
1113  gcry_mpi_invm(r_inv,
1114  bkey->r,
1115  n))
1116  {
1117  /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1118  * caught above, but we handle it the same here. */
1119  GNUNET_break_op(0);
1120  gcry_mpi_release(r_inv);
1121  rsa_blinding_key_free(bkey);
1122  gcry_mpi_release(n);
1123  gcry_mpi_release(s);
1124  return NULL;
1125  }
1126 
1127  ubsig = gcry_mpi_new(0);
1128  gcry_mpi_mulm(ubsig, s, r_inv, n);
1129  gcry_mpi_release(n);
1130  gcry_mpi_release(r_inv);
1131  gcry_mpi_release(s);
1132  rsa_blinding_key_free(bkey);
1133 
1134  sret = GNUNET_new(struct GNUNET_CRYPTO_RsaSignature);
1135  GNUNET_assert(0 ==
1136  gcry_sexp_build(&sret->sexp,
1137  NULL,
1138  "(sig-val (rsa (s %M)))",
1139  ubsig));
1140  gcry_mpi_release(ubsig);
1141  BENCHMARK_END(rsa_unblind);
1142  return sret;
1143 }
1144 
1145 
1155 int
1157  const struct GNUNET_CRYPTO_RsaSignature *sig,
1158  const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1159 {
1160  gcry_sexp_t data;
1161  gcry_mpi_t r;
1162  int rc;
1163 
1164  BENCHMARK_START(rsa_verify);
1165 
1166  r = rsa_full_domain_hash(pkey, hash);
1167  if (NULL == r)
1168  {
1169  GNUNET_break_op(0);
1170  /* RSA key is malicious since rsa_gcd_validate failed here.
1171  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1172  * so the exchange is being malicious in an unfamilair way, maybe
1173  * just trying to crash us. Arguably, we've only an internal error
1174  * though because we should've detected this in our previous call
1175  * to GNUNET_CRYPTO_rsa_unblind. */
1176  return GNUNET_NO;
1177  }
1178 
1179  data = mpi_to_sexp(r);
1180  gcry_mpi_release(r);
1181 
1182  rc = gcry_pk_verify(sig->sexp,
1183  data,
1184  pkey->sexp);
1185  gcry_sexp_release(data);
1186  if (0 != rc)
1187  {
1189  _("RSA signature verification failed at %s:%d: %s\n"),
1190  __FILE__,
1191  __LINE__,
1192  gcry_strerror(rc));
1193  return GNUNET_SYSERR;
1194  BENCHMARK_END(rsa_verify);
1195  }
1196  BENCHMARK_END(rsa_verify);
1197  return GNUNET_OK;
1198 }
1199 
1200 
1209 {
1210  struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1211  gcry_sexp_t dup_sexp;
1212  size_t erroff;
1213 
1214  /* check if we really are exporting a private key */
1215  dup_sexp = gcry_sexp_find_token(key->sexp, "private-key", 0);
1216  GNUNET_assert(NULL != dup_sexp);
1217  gcry_sexp_release(dup_sexp);
1218  /* copy the sexp */
1219  GNUNET_assert(0 == gcry_sexp_build(&dup_sexp, &erroff, "%S", key->sexp));
1221  dup->sexp = dup_sexp;
1222  return dup;
1223 }
1224 
1225 
1234 {
1235  struct GNUNET_CRYPTO_RsaSignature *dup;
1236  gcry_sexp_t dup_sexp;
1237  size_t erroff;
1238  gcry_mpi_t s;
1239  int ret;
1240 
1241  /* verify that this is an RSA signature */
1242  ret = key_from_sexp(&s, sig->sexp, "sig-val", "s");
1243  if (0 != ret)
1244  ret = key_from_sexp(&s, sig->sexp, "rsa", "s");
1245  GNUNET_assert(0 == ret);
1246  gcry_mpi_release(s);
1247  /* copy the sexp */
1248  GNUNET_assert(0 == gcry_sexp_build(&dup_sexp, &erroff, "%S", sig->sexp));
1249  dup = GNUNET_new(struct GNUNET_CRYPTO_RsaSignature);
1250  dup->sexp = dup_sexp;
1251  return dup;
1252 }
1253 
1254 
1255 /* end of util/rsa.c */
int GNUNET_CRYPTO_rsa_blind(const struct GNUNET_HashCode *hash, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey, char **buf, size_t *buf_size)
Blinds the given message with the given blinding key.
Definition: crypto_rsa.c:734
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:90
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:614
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:434
size_t GNUNET_CRYPTO_rsa_signature_encode(const struct GNUNET_CRYPTO_RsaSignature *sig, char **buffer)
Encode the given signature in a format suitable for storing it into a file.
Definition: crypto_rsa.c:965
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 private key.
Definition: crypto_rsa.c:1233
an RSA signature
Definition: crypto_rsa.c:61
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:688
#define BENCHMARK_START(opname)
Definition: benchmark.h:53
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:128
size_t GNUNET_CRYPTO_rsa_public_key_encode(const struct GNUNET_CRYPTO_RsaPublicKey *key, char **buffer)
Encode the public key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:315
size_t GNUNET_CRYPTO_rsa_private_key_encode(const struct GNUNET_CRYPTO_RsaPrivateKey *key, char **buffer)
Encode the private key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:195
int GNUNET_CRYPTO_rsa_public_key_cmp(struct GNUNET_CRYPTO_RsaPublicKey *p1, struct GNUNET_CRYPTO_RsaPublicKey *p2)
Compare the values of two public keys.
Definition: crypto_rsa.c:549
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_decode(const char *buf, size_t len)
Decode the private key from the data-format back to the "normal", internal format.
Definition: crypto_rsa.c:225
#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:76
#define BENCHMARK_END(opname)
Definition: benchmark.h:54
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:299
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:260
static int ok
Return value from &#39;main&#39; (0 == success)
#define GNUNET_NO
Definition: gnunet_common.h:78
int GNUNET_CRYPTO_rsa_signature_cmp(struct GNUNET_CRYPTO_RsaSignature *s1, struct GNUNET_CRYPTO_RsaSignature *s2)
Compare the values of two signatures.
Definition: crypto_rsa.c:516
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int ret
Final status code.
Definition: gnunet-arm.c:89
The public information of an RSA key pair.
Definition: crypto_rsa.c:50
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_decode(const char *buf, size_t len)
Decode the signature from the data-format back to the "normal", internal format.
Definition: crypto_rsa.c:995
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:812
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
cryptographic primitives for GNUnet
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA private key.
Definition: crypto_rsa.c:43
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:367
int 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:1156
int GNUNET_CRYPTO_rsa_private_key_cmp(struct GNUNET_CRYPTO_RsaPrivateKey *p1, struct GNUNET_CRYPTO_RsaPrivateKey *p2)
Compare the values of two private keys.
Definition: crypto_rsa.c:582
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:651
#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:44
struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_create(unsigned int len)
Create a new private key.
Definition: crypto_rsa.c:145
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:414
static int result
Global testing status.
A 512-bit hashcode.
RSA blinding key.
Definition: crypto_rsa.c:72
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:833
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:343
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static void rsa_blinding_key_free(struct RsaBlindingKey *bkey)
Destroy a blinding key.
Definition: crypto_rsa.c:636
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA signature.
Definition: crypto_rsa.c:65
void GNUNET_CRYPTO_rsa_signature_free(struct GNUNET_CRYPTO_RsaSignature *sig)
Free memory occupied by signature.
Definition: crypto_rsa.c:950
void GNUNET_CRYPTO_rsa_private_key_free(struct GNUNET_CRYPTO_RsaPrivateKey *key)
Free memory occupied by the private key.
Definition: crypto_rsa.c:179
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA public key.
Definition: crypto_rsa.c:54
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:39
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:1208
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:1037
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:1066
Constant-size pre-secret for blinding key generation.
#define GNUNET_YES
Definition: gnunet_common.h:77
benchmarking for various operations
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:925
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:64
#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:894
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...