handle errors better
[oweals/gnunet.git] / src / util / crypto_ksk.c
index 7dcdccd233843c3e79103bec5a178b85e9f9ff2c..4960df9e2eb642684c80c71da0a95c3081c0f9f4 100644 (file)
@@ -156,48 +156,23 @@ static uint16_t small_prime_numbers[] = {
 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
 
 
-     static unsigned int
-     get_nbits (mpz_t a)
+static unsigned int
+get_nbits (mpz_t a)
 {
   return mpz_sizeinbase (a, 2);
 }
 
-/**
- * Count the number of zerobits at the low end of A
- */
-static unsigned int
-get_trailing_zeros (mpz_t a)
-{
-  unsigned int count = 0;
-  unsigned int nbits = get_nbits (a);
-
-  while ((mpz_tstbit (a, count)) && (count < nbits))
-    count++;
-  return count;
-}
-
-/**
- * Set bit N of A. and clear all bits above
- */
-static void
-set_highbit (mpz_t a, unsigned int n)
-{
-  unsigned int nbits;
-
-  nbits = get_nbits (a);
-  while (nbits > n)
-    mpz_clrbit (a, nbits--);
-  mpz_setbit (a, n);
-}
 
 static void
 mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd)
 {
   GNUNET_HashCode *tmp;
+  int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
   int cnt;
   int i;
 
-  cnt = (nbits / sizeof (GNUNET_HashCode) / 8) + 1;
+  GNUNET_assert (nbits > 0);
+  cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
   tmp = GNUNET_malloc (sizeof (GNUNET_HashCode) * cnt);
 
   tmp[0] = *rnd;
@@ -205,13 +180,13 @@ mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd)
     {
       GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), &tmp[i + 1]);
     }
-  *rnd = tmp[cnt - 1];
+  GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), rnd);
   mpz_import (n, cnt * sizeof (GNUNET_HashCode) / sizeof (unsigned int),
               1, sizeof (unsigned int), 1, 0, tmp);
   GNUNET_free (tmp);
   i = get_nbits (n);
   while (i > nbits)
-    mpz_clrbit (n, i--);
+    mpz_clrbit (n, --i);
 }
 
 /**
@@ -240,7 +215,7 @@ is_prime (mpz_t n, int steps, GNUNET_HashCode * hc)
 
   /* Find q and k, so that n = 1 + 2^k * q . */
   mpz_init_set (q, nminus1);
-  k = get_trailing_zeros (q);
+  k = mpz_scan1 (q, 0);
   mpz_tdiv_q_2exp (q, q, k);
 
   for (i = 0; i < steps; i++)
@@ -251,19 +226,7 @@ is_prime (mpz_t n, int steps, GNUNET_HashCode * hc)
         }
       else
         {
-          mpz_randomize (x, nbits, hc);
-
-          /* Make sure that the number is smaller than the prime and
-             keep the randomness of the high bit. */
-          if (mpz_tstbit (x, nbits - 2))
-            {
-              set_highbit (x, nbits - 2);       /* Clear all higher bits. */
-            }
-          else
-            {
-              set_highbit (x, nbits - 2);
-              mpz_clrbit (x, nbits - 2);
-            }
+          mpz_randomize (x, nbits - 1, hc);
           GNUNET_assert (mpz_cmp (x, nminus1) < 0 && mpz_cmp_ui (x, 1) > 0);
         }
       mpz_powm (y, x, q, n);
@@ -319,7 +282,7 @@ gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
          generating a secret prime we are most probably doing that
          for RSA, to make sure that the modulus does have the
          requested key size we set the 2 high order bits. */
-      set_highbit (prime, nbits - 1);
+      mpz_setbit (prime, nbits - 1);
       mpz_setbit (prime, nbits - 2);
       mpz_setbit (prime, 0);
 
@@ -763,40 +726,71 @@ GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
 }
 
 
-#ifdef gcry_register_random_progress
+/**
+ * Process ID of the "find" process that we use for
+ * entropy gathering.
+ */
+static pid_t genproc;
+
 /**
  * Function called by libgcrypt whenever we are
  * blocked gathering entropy.
  */
 static void
-entropy_generator (void *cls, 
-                  const char *what,
-                  int printchar,
-                  int current,
-                  int total)
+entropy_generator (void *cls,
+                   const char *what, int printchar, int current, int total)
 {
-  static pid_t genproc;
+  unsigned long code;
+  enum GNUNET_OS_ProcessStatusType type;
+  int ret;
+
   if (0 != strcmp (what, "need_entropy"))
     return;
   if (current == total)
     {
       if (genproc != 0)
-       {
-         PLIBC_KILL(genproc, SIGKILL);
-         GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
-         genproc = 0;
-       }
+        {
+          if (0 != PLIBC_KILL (genproc, SIGTERM))
+            GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
+          GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
+          genproc = 0;
+        }
       return;
     }
-  genproc = GNUNET_OS_start_process ("find",
-                                    "find",
-                                    "-type",
-                                    "s",
-                                    "-fprint",
-                                    "/dev/null",
-                                    NULL);                                
+  if (genproc != 0)
+    {
+      ret = GNUNET_OS_process_status (genproc, &type, &code);
+      if (ret == GNUNET_NO)
+        return;                 /* still running */
+      if (ret == GNUNET_SYSERR)
+        {
+          GNUNET_break (0);
+          return;
+        }
+      if (0 != PLIBC_KILL (genproc, SIGTERM))
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
+      GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
+      genproc = 0;
+    }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              _("Starting `%s' process to generate entropy\n"), "find");
+  genproc = GNUNET_OS_start_process (NULL, NULL, "sh",
+                                     "sh",
+                                     "-c",
+                                     "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null",
+                                     NULL);
+}
+
+
+static void
+killfind ()
+{
+  if (genproc != 0)
+    {
+      PLIBC_KILL (genproc, SIGKILL);
+      genproc = 0;
+    }
 }
-#endif
 
 
 void __attribute__ ((constructor)) GNUNET_CRYPTO_ksk_init ()
@@ -813,11 +807,11 @@ void __attribute__ ((constructor)) GNUNET_CRYPTO_ksk_init ()
 #ifdef gcry_fast_random_poll
   gcry_fast_random_poll ();
 #endif
-#ifdef gcry_register_random_progress
-  gcry_register_random_progress (&entropy_generator, NULL);
-#endif
+  gcry_set_progress_handler (&entropy_generator, NULL);
+  atexit (&killfind);
 }
 
+
 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
 {
   int i;
@@ -828,9 +822,7 @@ void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
       GNUNET_free (cache[i]);
     }
   GNUNET_array_grow (cache, cacheSize, 0);
-#ifdef gcry_register_random_progress
-  gcry_register_random_progress (NULL, NULL);
-#endif
+  gcry_set_progress_handler (NULL, NULL);
 }
 
 /* end of kblockkey.c */