New free counter noise generator, for use if /dev/random is
authormdw <mdw>
Sat, 17 Jun 2000 12:57:47 +0000 (12:57 +0000)
committermdw <mdw>
Sat, 17 Jun 2000 12:57:47 +0000 (12:57 +0000)
unavailable.

acconfig.h
configure.in
noise.c
noise.h

index 8de2795..a9f3737 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: acconfig.h,v 1.2 1999/12/10 23:30:08 mdw Exp $
+ * $Id: acconfig.h,v 1.3 2000/06/17 12:57:46 mdw Exp $
  *
  * Configuration header for Catacomb
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: acconfig.h,v $
+ * Revision 1.3  2000/06/17 12:57:46  mdw
+ * New free counter noise generator, for use if /dev/random is
+ * unavailable.
+ *
  * Revision 1.2  1999/12/10 23:30:08  mdw
  * Change header file guard names.
  *
  * representing time.  (Probably `long'.)  */
 #undef time_t
 
+/* Define if you have working `setitimer' and `sigsetjmp' functions.  This
+ * sill enable the free counter noise generator.  */
+#define USE_FREEWHEEL
+
 @BOTTOM@
 
 /*----- That's all, folks -------------------------------------------------*/
index 13c0c22..bef9b1b 100644 (file)
@@ -1,6 +1,6 @@
 dnl -*-fundamental-*-
 dnl
-dnl $Id: configure.in,v 1.11 2000/06/17 10:51:23 mdw Exp $
+dnl $Id: configure.in,v 1.12 2000/06/17 12:57:47 mdw Exp $
 dnl
 dnl Autoconfiguration for Catacomb
 dnl
@@ -29,6 +29,10 @@ dnl MA 02111-1307, USA.
 dnl ----- Revision history --------------------------------------------------
 dnl
 dnl $Log: configure.in,v $
+dnl Revision 1.12  2000/06/17 12:57:47  mdw
+dnl New free counter noise generator, for use if /dev/random is
+dnl unavailable.
+dnl
 dnl Revision 1.11  2000/06/17 10:51:23  mdw
 dnl Version number changes.  Find maths library for Maurer's test.
 dnl
@@ -62,7 +66,7 @@ dnl
 dnl --- Boring boilerplate ---
 
 AC_INIT(blkc.h)
-AM_INIT_AUTOMAKE(catacomb, 2.0.0)
+AM_INIT_AUTOMAKE(catacomb, 2.0.0pre1)
 AM_CONFIG_HEADER(config.h)
 
 dnl --- Make sure I can compile and build libraries ---
@@ -91,12 +95,26 @@ dnl --- The maths library, for Maurer's test ---
 mdw_CHECK_MANYLIBS(log, m,,, [#include <math.h>], [2])
 mdw_CHECK_MANYLIBS(sqrt, m,,, [#include <math.h>], [2])
 
-dnl --- Can I call `initgroups'? ---
-dnl
-dnl This is used in noise-gathering.
+dnl --- Functions used for noise-gathering ---
 
 AC_CHECK_FUNCS(setgroups)
 
+AC_CACHE_CHECK([whether the freewheel noise generator will work],
+[catacomb_cv_freewheel],
+[AC_TRY_LINK([
+#include <setjmp.h>
+#include <sys/time.h>
+],
+[struct itimerval itv = { { 0, 0 }, { 0, 5000 } };
+jmp_buf j;
+setitimer(ITIMER_REAL, &itv, 0);
+sigsetjmp(j, 1);],
+[catacomb_cv_freewheel=yes],
+[catacomb_cv_freewheel=no])])
+if test "$catacomb_cv_freewheel" = "yes"; then
+  AC_DEFINE([USE_FREEWHEEL])
+fi
+
 dnl --- Support for the passphrase pixie ---
 
 mdw_CHECK_MANYLIBS(socket, socket)
diff --git a/noise.c b/noise.c
index ed2d83c..a4648f8 100644 (file)
--- a/noise.c
+++ b/noise.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: noise.c,v 1.5 1999/12/22 15:57:55 mdw Exp $
+ * $Id: noise.c,v 1.6 2000/06/17 12:57:47 mdw Exp $
  *
  * Acquisition of environmental noise (Unix-specific)
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: noise.c,v $
+ * Revision 1.6  2000/06/17 12:57:47  mdw
+ * New free counter noise generator, for use if /dev/random is
+ * unavailable.
+ *
  * Revision 1.5  1999/12/22 15:57:55  mdw
  * Label system-specific parts more clearly.
  *
@@ -51,6 +55,7 @@
 
 #include "config.h"
 
+#include <setjmp.h>
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
@@ -120,7 +125,7 @@ static int bitcount(unsigned long x)
  * Arguments:  @rand_pool *r@ = pointer to randomness pool
  *             @struct timeval *tv@ = pointer to time block
  *
- * Returns:    Nonzer if some randomness was contributed.
+ * Returns:    Nonzero if some randomness was contributed.
  *
  * Use:                Low-level timer contributor.
  */
@@ -187,7 +192,9 @@ int noise_devrandom(rand_pool *r)
    * needs to get some more entropy from somewhere.
    */
 
-  if ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) >= 0) {
+  if ((fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK)) >= 0 ||
+      (fd = open("/dev/arandom", O_RDONLY | O_NONBLOCK)) >= 0 ||
+      (fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) >= 0) {
     if ((len = read(fd, buf, sizeof(buf))) > 0) {
       rand_add(r, buf, len, len * 8);
       BURN(buf);
@@ -364,6 +371,94 @@ int noise_filter(rand_pool *r, int good, const char *c)
   return (ret);
 }
 
+/* --- @noise_freewheel@ --- *
+ *
+ * Arguments:  @rand_pool *r@ = pointer to a randomness pool
+ *
+ * Returns:    Nonzero if some randomness was contributed.
+ *
+ * Use:                Runs a free counter for a short while as a desparate attempt
+ *             to get randomness from somewhere.  This is actually quite
+ *             effective.
+ */
+
+#ifdef USE_FREEWHEEL
+
+static jmp_buf fwjmp;
+
+static void fwalarm(int sig)
+{
+  siglongjmp(fwjmp, 1);
+}
+
+int noise_freewheel(rand_pool *r)
+{
+  void (*sigal)(int) = 0;
+  struct itimerval oitv, itv = { { 0, 0 }, { 0, 5000 } };
+  int rc = 0;
+  volatile uint32 fwcount = 0;
+
+  if (!sigsetjmp(fwjmp, 1)) {
+    if ((sigal = signal(SIGALRM, fwalarm)) == SIG_ERR)
+      return (0);
+    if (setitimer(ITIMER_REAL, &itv, &oitv))
+      goto done;
+    for (;;)
+      fwcount++;
+  } else {
+    octet buf[4];
+    STORE32(buf, fwcount);
+    rand_add(r, buf, sizeof(buf), 16);
+    rc = 1;
+  }
+
+done:
+  signal(SIGALRM, sigal);
+  TV_SUB(&oitv.it_value, &oitv.it_value, &itv.it_value);
+  setitimer(ITIMER_REAL, &oitv, 0);
+  return (rc);
+}
+
+#else
+
+int noise_freewheel(rand_pool *r)
+{
+  return (0);
+}
+
+#endif
+
+/* --- @noise_enquire@ --- *
+ *
+ * Arguments:  @rand_pool *r@ = pointer to a randomness pool
+ *
+ * Returns:    Nonzero if some randomness was contributed.
+ *
+ * Use:                Runs some shell commands to enquire about the prevailing
+ *             environment.  This can gather quite a lot of low-quality
+ *             entropy.
+ */
+
+int noise_enquire(rand_pool *r)
+{
+  struct tab {
+    const char *cmd;
+    unsigned rate;
+  } tab[] = {
+    { "ps alxww || ps -elf",   16 },
+    { "netstat -n",             6 },
+    { "df",                    20 },
+    { "w",                      6 },
+    { "ls -align /tmp/.",      10 },
+    { 0,                        0 }
+  };
+  int i;
+
+  for (i = 0; tab[i].cmd; i++)
+    noise_filter(r, tab[i].rate, tab[i].cmd);
+  return (1);
+}
+
 /* --- @noise_acquire@ --- *
  *
  * Arguments:  @rand_pool *r@ = pointer to a randomness pool
@@ -375,33 +470,13 @@ int noise_filter(rand_pool *r, int good, const char *c)
 
 void noise_acquire(rand_pool *r)
 {
+  unsigned i;
+  for (i = 0; i < 8; i++)
+    noise_freewheel(r);
   if (!noise_devrandom(r)) {
-
-    /* --- Output of `ps' --- *
-     *
-     * This is a hopefully cheap way of getting a bit of noise.  I'm guessing
-     * the good bit ratio based on about 90 bytes per line of output, and
-     * each line containing maybe 12 bits worth of interesting data.  (Some
-     * quick experiments with gzip seem to bear this idea out.)  So, 12 good
-     * bits per 90 bytes of output gives slightly more than 17 good bits per
-     * 1024 bits of output.  So I'll be a pessimist and say 16 bits.
-     */
-
-    (void)
-      (noise_filter(r, 16, "ps alxww") ||
-       noise_filter(r, 16, "ps -elf"));
-
-    /* --- Output of `netstat' --- *
-     *
-     * Another possibly cheap way of getting noise.  My output has about
-     * 72 bytes per line of output.  My wild guesses are telling me that
-     * there are probably only about four good bits per line (gzip tells
-     * me there's six, but I want to underestimate).  Four bits per 72 bytes
-     * is 7 good bits per 1024 bits of output.  Pessimist that I am, I'll
-     * call it six.
-     */
-
-    noise_filter(r, 6, "netstat -n");
+    noise_enquire(r);
+    for (i = 0; i < 8; i++)
+      noise_freewheel(r);
   }
 }
 
diff --git a/noise.h b/noise.h
index b8a0050..3777a6f 100644 (file)
--- a/noise.h
+++ b/noise.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: noise.h,v 1.3 1999/12/22 15:57:55 mdw Exp $
+ * $Id: noise.h,v 1.4 2000/06/17 12:57:47 mdw Exp $
  *
  * Acquisition of environmental noise (Unix-specific)
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: noise.h,v $
+ * Revision 1.4  2000/06/17 12:57:47  mdw
+ * New free counter noise generator, for use if /dev/random is
+ * unavailable.
+ *
  * Revision 1.3  1999/12/22 15:57:55  mdw
  * Label system-specific parts more clearly.
  *
@@ -133,6 +137,32 @@ extern void noise_setid(uid_t /*uid*/, gid_t /*gid*/);
 
 extern int noise_filter(rand_pool */*r*/, int /*good*/, const char */*c*/);
 
+/* --- @noise_freewheel@ --- *
+ *
+ * Arguments:  @rand_pool *r@ = pointer to a randomness pool
+ *
+ * Returns:    Nonzero if some randomness was contributed.
+ *
+ * Use:                Runs a free counter for a short while as a desparate attempt
+ *             to get randomness from somewhere.  This is actually quite
+ *             effective.
+ */
+
+int noise_freewheel(rand_pool */*r*/);
+
+/* --- @noise_enquire@ --- *
+ *
+ * Arguments:  @rand_pool *r@ = pointer to a randomness pool
+ *
+ * Returns:    Nonzero if some randomness was contributed.
+ *
+ * Use:                Runs some shell commands to enquire about the prevailing
+ *             environment.  This can gather quite a lot of low-quality
+ *             entropy.
+ */
+
+extern int noise_enquire(rand_pool */*r*/);
+
 /* --- @noise_acquire@ --- *
  *
  * Arguments:  @rand_pool *r@ = pointer to a randomness pool