tolerate additional IPv4 address now available for gnunet.org
[oweals/gnunet.git] / src / util / crypto_rsa.c
index 443d597e4c9fad659182a3d3929111854edc8514..8cb0fe6c687e8e1be3f3af31992d30e83705aa12 100644 (file)
@@ -2,16 +2,20 @@
   This file is part of GNUnet
   Copyright (C) 2014,2016 GNUnet e.V.
 
-  GNUnet is free software; you can redistribute it and/or modify it under the
-  terms of the GNU General Public License as published by the Free Software
-  Foundation; either version 3, or (at your option) any later version.
-
-  GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  GNUnet is free software: you can redistribute it and/or modify it
+  under the terms of the GNU Affero General Public License as published
+  by the Free Software Foundation, either version 3 of the License,
+  or (at your option) any later version.
+
+  GNUnet is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Affero General Public License for more details.
+  You should have received a copy of the GNU Affero General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-  You should have received a copy of the GNU General Public License along with
-  GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
@@ -24,8 +28,9 @@
 #include "platform.h"
 #include <gcrypt.h>
 #include "gnunet_crypto_lib.h"
+#include "benchmark.h"
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
 
 
 /**
@@ -94,7 +99,6 @@ key_from_sexp (gcry_mpi_t *array,
   gcry_sexp_t list;
   gcry_sexp_t l2;
   const char *s;
-  unsigned int i;
   unsigned int idx;
 
   if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
@@ -109,7 +113,7 @@ key_from_sexp (gcry_mpi_t *array,
   {
     if (! (l2 = gcry_sexp_find_token (list, s, 1)))
     {
-      for (i = 0; i < idx; i++)
+      for (unsigned int i = 0; i < idx; i++)
       {
         gcry_free (array[i]);
         array[i] = NULL;
@@ -121,7 +125,7 @@ key_from_sexp (gcry_mpi_t *array,
     gcry_sexp_release (l2);
     if (! array[idx])
     {
-      for (i = 0; i < idx; i++)
+      for (unsigned int i = 0; i < idx; i++)
       {
         gcry_free (array[i]);
         array[i] = NULL;
@@ -148,6 +152,8 @@ GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
   gcry_sexp_t s_key;
   gcry_sexp_t s_keyparam;
 
+  BENCHMARK_START (rsa_private_key_create);
+
   GNUNET_assert (0 ==
                  gcry_sexp_build (&s_keyparam,
                                   NULL,
@@ -163,6 +169,7 @@ GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
 #endif
   ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
   ret->sexp = s_key;
+  BENCHMARK_END (rsa_private_key_create);
   return ret;
 }
 
@@ -260,6 +267,8 @@ GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateK
   int rc;
   gcry_sexp_t result;
 
+  BENCHMARK_START (rsa_private_key_get_public);
+
   rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
   if (0 != rc)
     rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
@@ -279,6 +288,7 @@ GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateK
   gcry_mpi_release (ne[1]);
   pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
   pub->sexp = result;
+  BENCHMARK_END (rsa_private_key_get_public);
   return pub;
 }
 
@@ -430,7 +440,7 @@ rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
   char *xts = "Blinding KDF extrator HMAC key";  /* Trusts bks' randomness more */
   struct RsaBlindingKey *blind;
   gcry_mpi_t n;
+
   blind = GNUNET_new (struct RsaBlindingKey);
   GNUNET_assert( NULL != blind );
 
@@ -454,25 +464,25 @@ rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
 }
 
 
-/* 
+/*
 We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
 previous routine.
 
-There was previously a call to GNUNET_CRYPTO_kdf in 
+There was previously a call to GNUNET_CRYPTO_kdf in
   bkey = rsa_blinding_key_derive (len, bks);
-that gives exactly len bits where 
+that gives exactly len bits where
   len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
 
 Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
 okay, meaning bkey < pkey.n.  It follows that (1-r)/2 of the time bkey >
-pkey.n making the effective bkey be 
+pkey.n making the effective bkey be
   bkey mod pkey.n = bkey - pkey.n
 so the effective bkey has its high bit set with probability r/2.
 
 We expect r to be close to 1/2 if the exchange is honest, but the
 exchange can choose r otherwise.
 
-In blind signing, the exchange sees  
+In blind signing, the exchange sees
   B = bkey * S mod pkey.n
 On deposit, the exchange sees S so they can compute bkey' = B/S mod
 pkey.n for all B they recorded to see if bkey' has it's high bit set.
@@ -489,7 +499,7 @@ the wrong and right probabilities 1/3 and 1/4, respectively.
 I feared this gives the exchange a meaningful fraction of a bit of
 information per coin involved in the transaction.  It sounds damaging if
 numerous coins were involved.  And it could run across transactions in
-some scenarios. 
+some scenarios.
 
 We fixed this by using a more uniform deterministic pseudo-random number
 generator for blinding factors.  I do not believe this to be a problem
@@ -720,7 +730,7 @@ rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
  * @param pkey the public key of the signer
  * @param[out] buf set to a buffer with the blinded message to be signed
  * @param[out] buf_size number of bytes stored in @a buf
- * @return GNUNET_YES if successful, GNUNET_NO if RSA key is malicious
+ * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious
  */
 int
 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
@@ -735,6 +745,8 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
   gcry_mpi_t data_r_e;
   int ret;
 
+  BENCHMARK_START (rsa_blind);
+
   GNUNET_assert (buf != NULL && buf_size != NULL);
   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
   if (0 != ret)
@@ -748,7 +760,7 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
   }
 
   data = rsa_full_domain_hash (pkey, hash);
-  if (NULL == data) 
+  if (NULL == data)
     goto rsa_gcd_validate_failure;
 
   bkey = rsa_blinding_key_derive (pkey, bks);
@@ -771,10 +783,13 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
   gcry_mpi_release (ne[0]);
   gcry_mpi_release (ne[1]);
   gcry_mpi_release (r_e);
-  rsa_blinding_key_free (bkey);  
+  rsa_blinding_key_free (bkey);
 
   *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf);
   gcry_mpi_release (data_r_e);
+
+  BENCHMARK_END (rsa_blind);
+
   return GNUNET_YES;
 
 rsa_gcd_validate_failure:
@@ -884,6 +899,8 @@ GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
   gcry_mpi_t v = NULL;
   struct GNUNET_CRYPTO_RsaSignature *sig;
 
+  BENCHMARK_START (rsa_sign_blinded);
+
   GNUNET_assert (0 ==
                  gcry_mpi_scan (&v,
                                 GCRYMPI_FMT_USG,
@@ -893,6 +910,7 @@ GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
 
   sig = rsa_sign_mpi (key, v);
   gcry_mpi_release (v);
+  BENCHMARK_END (rsa_sign_blinded);
   return sig;
 }
 
@@ -917,7 +935,7 @@ GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
   GNUNET_CRYPTO_rsa_public_key_free (pkey);
   if (NULL == v)   /* rsa_gcd_validate failed meaning */
     return NULL;   /* our *own* RSA key is malicious. */
+
   sig = rsa_sign_mpi (key, v);
   gcry_mpi_release (v);
   return sig;
@@ -1046,7 +1064,7 @@ GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
  * @return unblinded signature on success, NULL if RSA key is bad or malicious.
  */
 struct GNUNET_CRYPTO_RsaSignature *
-GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
+GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig,
                            const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
                            struct GNUNET_CRYPTO_RsaPublicKey *pkey)
 {
@@ -1058,6 +1076,8 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
   int ret;
   struct GNUNET_CRYPTO_RsaSignature *sret;
 
+  BENCHMARK_START (rsa_unblind);
+
   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
   if (0 != ret)
     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
@@ -1077,11 +1097,11 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
   }
 
   bkey = rsa_blinding_key_derive (pkey, bks);
-  if (NULL == bkey) 
+  if (NULL == bkey)
   {
-    /* RSA key is malicious since rsa_gcd_validate failed here. 
+    /* RSA key is malicious since rsa_gcd_validate failed here.
      * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
-     * so the exchange is being malicious in an unfamilair way, maybe 
+     * so the exchange is being malicious in an unfamilair way, maybe
      * just trying to crash us.  */
     GNUNET_break_op (0);
     gcry_mpi_release (n);
@@ -1096,10 +1116,10 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
                      n))
   {
     /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
-     * caught above, but we handle it the same here.              */  
+     * caught above, but we handle it the same here.              */
     GNUNET_break_op (0);
     gcry_mpi_release (r_inv);
-    rsa_blinding_key_free (bkey);  
+    rsa_blinding_key_free (bkey);
     gcry_mpi_release (n);
     gcry_mpi_release (s);
     return NULL;
@@ -1119,6 +1139,7 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
                                   "(sig-val (rsa (s %M)))",
                                   ubsig));
   gcry_mpi_release (ubsig);
+  BENCHMARK_END (rsa_unblind);
   return sret;
 }
 
@@ -1141,14 +1162,16 @@ GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
   gcry_mpi_t r;
   int rc;
 
+  BENCHMARK_START (rsa_verify);
+
   r = rsa_full_domain_hash (pkey, hash);
   if (NULL == r) {
     GNUNET_break_op (0);
-    /* RSA key is malicious since rsa_gcd_validate failed here. 
+    /* RSA key is malicious since rsa_gcd_validate failed here.
      * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
-     * so the exchange is being malicious in an unfamilair way, maybe 
+     * so the exchange is being malicious in an unfamilair way, maybe
      * just trying to crash us.  Arguably, we've only an internal error
-     * though because we should've detected this in our previous call 
+     * though because we should've detected this in our previous call
      * to GNUNET_CRYPTO_rsa_unblind. */
     return GNUNET_NO;
   }
@@ -1168,7 +1191,9 @@ GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
          __LINE__,
          gcry_strerror (rc));
     return GNUNET_SYSERR;
+    BENCHMARK_END (rsa_verify);
   }
+  BENCHMARK_END (rsa_verify);
   return GNUNET_OK;
 }