Code cleanups.
authorWerner Koch <wk@gnupg.org>
Wed, 14 Mar 2007 16:05:58 +0000 (16:05 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 14 Mar 2007 16:05:58 +0000 (16:05 +0000)
More documentation.

cipher/ChangeLog
cipher/rand-internal.h
cipher/random.c
cipher/rndegd.c
cipher/rndlinux.c
cipher/rndunix.c
cipher/rndw32.c

index 3e9205b..e0978ac 100644 (file)
@@ -1,3 +1,25 @@
+2007-03-14  Werner Koch  <wk@g10code.com>
+
+       * random.c (MASK_LEVEL): Removed macro as it was used only at one
+       place.  Open coded it there.
+       (gcry_randomize, _gcry_update_random_seed_file)
+       (_gcry_fast_random_poll): Factor lock code out to ..
+       (lock_pool, unlock_pool): .. new.
+       (initialize): Look the pool while allocating.  Still not
+       sufficiently thread-safe due to the unprotected is_initialized.
+       (read_random_source, do_fast_random_poll): Moved intialization to ...
+       (initialize): .. here.
+       (_gcry_enable_quick_random_gen): No more need for initialization.
+       
+       * random.c (enum random_origins): Moved to ..
+       * rand-internal.h: .. here.
+       * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
+       for ORIGIN and renamed REQUESTOR to ORIGIN.
+       * rndegd.c (_gcry_rndegd_gather_random): Ditto.
+       * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
+       * rndw32.c (_gcry_rndw32_gather_random): Ditto.
+       (_gcry_rndw32_gather_random_fast): Ditto.
+
 2007-03-13  Werner Koch  <wk@g10code.com>
 
        * random.c (enum random_origins): New.
index 10472a3..aa292ff 100644 (file)
 #define G10_RAND_INTERNAL_H
 
 
+/* Constants used to define the origin of random added to the pool.
+   The code is sensitive to the order of the values.  */
+enum random_origins 
+  {
+    RANDOM_ORIGIN_INIT = 0,      /* Used only for initialization. */
+    RANDOM_ORIGIN_FASTPOLL = 1,  /* Fast random poll function.  */
+    RANDOM_ORIGIN_SLOWPOLL = 2,  /* Slow poll function.  */
+    RANDOM_ORIGIN_EXTRAPOLL = 3  /* Used to mark an extra pool seed
+                                    due to a GCRY_VERY_STRONG_RANDOM
+                                    random request.  */
+  };
+
 
 
 
@@ -28,17 +40,26 @@ void _gcry_random_progress (const char *what, int printchar,
                             int current, int total);
 
 
-int _gcry_rndlinux_gather_random (void (*add) (const void *, size_t, int),
-                                  int requester, size_t length, int level);
-int _gcry_rndunix_gather_random (void (*add) (const void *, size_t, int),
-                                 int requester, size_t length, int level);
-int _gcry_rndegd_gather_random (void (*add) (const void *, size_t, int),
-                                int requester, size_t length, int level);
+int _gcry_rndlinux_gather_random (void (*add) (const void *, size_t,
+                                               enum random_origins),
+                                   enum random_origins origin,
+                                  size_t length, int level);
+int _gcry_rndunix_gather_random (void (*add) (const void *, size_t,
+                                              enum random_origins),
+                                 enum random_origins origin,
+                                 size_t length, int level);
+int _gcry_rndegd_gather_random (void (*add) (const void *, size_t,
+                                             enum random_origins),
+                                enum random_origins origin,
+                                size_t length, int level);
 int _gcry_rndegd_connect_socket (int nofail);
-int _gcry_rndw32_gather_random (void (*add) (const void *, size_t, int),
-                                int requester, size_t length, int level);
-void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int),
-                                      int requester );
+int _gcry_rndw32_gather_random (void (*add) (const void *, size_t,
+                                             enum random_origins),
+                                enum random_origins origin,
+                                size_t length, int level);
+void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, 
+                                                  enum random_origins),
+                                      enum random_origins origin );
 
 
 
index e16ee75..fdf3445 100644 (file)
 #include "rmd.h"
 #include "random.h"
 #include "rand-internal.h"
-#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
+#include "cipher.h" /* Required for the rmd160_hash_buffer() prototype.  */
 #include "ath.h"
 
-#ifndef RAND_MAX   /* for SunOS */
+#ifndef RAND_MAX   /* For SunOS. */
 #define RAND_MAX 32767
 #endif
 
@@ -69,7 +69,7 @@
 #define LOCK_SEED_FILE 0
 #endif
 
-
+/* Define the constant we use for transforming the pool at read-out. */
 #if SIZEOF_UNSIGNED_LONG == 8
 #define ADD_VALUE 0xa5a5a5a5a5a5a5a5
 #elif SIZEOF_UNSIGNED_LONG == 4
 #error weird size for an unsigned long
 #endif
 
+/* Contstants pertaining to the hash pool. */
 #define BLOCKLEN  64   /* Hash this amount of bytes... */
 #define DIGESTLEN 20   /* ... into a digest of this length (rmd160). */
-/* POOLBLOCKS is the number of digests which make up the pool and
-   POOLSIZE must be a multiple of the digest length to make the AND
+/* POOLBLOCKS is the number of digests which make up the pool.  */
+#define POOLBLOCKS 30
+/* POOLSIZE must be a multiple of the digest length to make the AND
    operations faster, the size should also be a multiple of unsigned
    long.  */
-#define POOLBLOCKS 30
 #define POOLSIZE (POOLBLOCKS*DIGESTLEN)
 #if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
 #error Please make sure that poolsize is a multiple of unsigned long
 #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
 
 
-/* Constants used to define the origin of random added to the pool.
-   The code is sensitive to the order of the values.  */
-enum random_origins 
-  {
-    RANDOM_ORIGIN_INIT = 0,      /* Used only for initialization. */
-    RANDOM_ORIGIN_FASTPOLL = 1,  /* Fast random poll function.  */
-    RANDOM_ORIGIN_SLOWPOLL = 2,  /* Slow poll function.  */
-    RANDOM_ORIGIN_EXTRAPOLL = 3  /* Used to mark an extra pool seed
-                                    due to a GCRY_VERY_STRONG_RANDOM
-                                    random request.  */
-  };
-
 /* Flag to tell whether this module has been initialized.  */
 static int is_initialized;
 
-#define MASK_LEVEL(a) do { (a) &= 3; } while(0)
-static unsigned char *rndpool; /* Allocated size is POOLSIZE+BLOCKLEN.  */
-static unsigned char *keypool; /* Allocated size is POOLSIZE+BLOCKLEN.  */
-static size_t pool_readpos;
+
+/* RNDPOOL is the pool we use to collect the entropy and to stir it
+   up.  Its allocated size is POOLSIZE+BLOCKLEN.  */
+static unsigned char *rndpool; 
+/* KEYPOOL is used as a scratch copy to read out random from RNDPOOL.
+   Its allocated size is also POOLSIZE+BLOCKLEN.  */
+static unsigned char *keypool; 
+
+/* This is the offset into RNDPOOL where the next random bytes are to
+   be mixed in.  */
 static size_t pool_writepos;
-static int pool_filled;
-static int pool_balance;
-static int just_mixed;
-static int did_initial_extra_seeding;
-static char *seed_file_name;
-static int allow_seed_file_update;
 
+/* When reading data out of KEYPOOL, we start the read at different
+   positions.  This variable keeps track on where to read next.  */
+static size_t pool_readpos;
 
-#ifdef USE_RANDOM_DAEMON
+/* This flag is set to true as soon as the pool has been completely
+   filles.  This may happen either by rerading a seed file or by
+   adding enough entropy.  */
+static int pool_filled;
 
-/* If ALLOW_DAEMON is true, the module will try to use the random
-   daemon first.  If the daemon has failed, this variable is set to
-   back to false and the codecontinues as normal.  Note, we don't test
-   this flag in a locked state because a wrong value does not harm and
-   the trhead will find out itself that the daemon does not work and
-   set it (again) to false.  */
-static int allow_daemon;       
+/* If random of level GCRY_VERY_STRONG_RANDOM has been requested we
+   have stricter requirements on what kind of entropy is in the pool.
+   In particular POOL_FILLED is not sufficient.  Thus we add some
+   extra seeding and set this flag to true if the extra seeding has
+   been done.  */
+static int did_initial_extra_seeding;
 
-/* During initialization, the user may set a non-default socket name
-   for accessing the random daemon.  If this value is NULL, the
-   default name will be used. */
-static char *daemon_socket_name;
+/* This variable is used to estimated the amount of fresh entropy
+   available in RNDPOOL.  */
+static int pool_balance;
 
-#endif /*USE_RANDOM_DAEMON*/
+/* After a mixing operation this variable will be set to true and
+   cleared if new entropy has been added or a remix is required for
+   otehr reasons.  */
+static int just_mixed;
 
+/* The name of the seed file or NULL if no seed file has been defined.
+   The seed file needs to be regsitered at initialiation time.  we
+   keep a malloced copy here.  */
+static char *seed_file_name;
+
+/* If a seed file has been registered and maybe updated on exit this
+   flag set. */
+static int allow_seed_file_update;
 
+/* Option flag set at initialiation time to force allocation of the
+   pool in secure memory.  */
 static int secure_alloc;
+
+/* This function pointer is set to the actual entropy gathering
+   function during initailization.  After initialization it is
+   guaranteed to point to function.  (On systems without a random
+   gatherer module a dummy function is used).*/
+static int (*slow_gather_fnc)(void (*)(const void*, size_t,
+                                       enum random_origins),
+                              enum random_origins, size_t, int);
+
+/* This function is set to the actual fast entropy gathering fucntion
+   during initialization.  If it is NULL, no such function is
+   available. */
+static void (*fast_gather_fnc)(void (*)(const void*, size_t,
+                                        enum random_origins),
+                               enum random_origins);
+
+
+/* Option flag useful for debugging and the test suite.  If set
+   requests for very strong random are degraded to strong random.  Not
+   used by regualr applications.  */
 static int quick_test;
+
+/* On systems without entropy gathering modules, this flag is set to
+   indicate that the random generator is not working properly.  A
+   warning message is issued as well.  This is useful only for
+   debugging and during development.  */
 static int faked_rng;
 
+/* This is the lock we use to protect all pool operations.  */
 static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
 
-static int pool_is_locked; /* Only used to assert that functions are
-                              called in a locked state.  It is not
-                              meant to be a thread-safe fucntion */
+/* This is a helper for assert calls.  These calls are used to assert
+   that functions are called in a locked state.  It is not meant to be
+   thread-safe but as a method to get aware of missing locks in the
+   test suite.  */
+static int pool_is_locked;
 
+/* This is the lock we use to protect the buffer used by the nonce
+   generation.  */
 static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
 
-static void read_pool( byte *buffer, size_t length, int level );
-static void add_randomness (const void *buffer, size_t length, int origin);
-static void random_poll(void);
-static void do_fast_random_poll (void);
-static void read_random_source( int origin, size_t length, int level);
-static int gather_faked( void (*add)(const void*, size_t, int), int requester,
-                                                   size_t length, int level );
 
+/* We keep some counters in this structure for the sake of the
+   _gcry_random_dump_stats () function.  */
 static struct
 {
   unsigned long mixrnd;
@@ -172,11 +203,61 @@ static struct
   unsigned long naddbytes;
 } rndstats;
 
+
+/* If not NULL a progress function called from certain places and the
+   opaque value passed along.  Registred by
+   _gcry_register_random_progress (). */
 static void (*progress_cb) (void *,const char*,int,int, int );
 static void *progress_cb_data;
 
-/* Note, we assume that this function is used before any concurrent
-   access happens. */
+
+/* --- Stuff pertaining to the random daemon support. --- */
+#ifdef USE_RANDOM_DAEMON
+
+/* If ALLOW_DAEMON is true, the module will try to use the random
+   daemon first.  If the daemon has failed, this variable is set to
+   back to false and the code continues as normal.  Note, we don't
+   test this flag in a locked state because a wrong value does not
+   harm and the trhead will find out itself that the daemon does not
+   work and set it (again) to false.  */
+static int allow_daemon;       
+
+/* During initialization, the user may set a non-default socket name
+   for accessing the random daemon.  If this value is NULL, the
+   default name will be used. */
+static char *daemon_socket_name;
+
+#endif /*USE_RANDOM_DAEMON*/
+
+
+
+/* ---  Prototypes  --- */
+static void read_pool (byte *buffer, size_t length, int level );
+static void add_randomness (const void *buffer, size_t length, 
+                            enum random_origins origin);
+static void random_poll (void);
+static void do_fast_random_poll (void);
+static int (*getfnc_gather_random (void))(void (*)(const void*, size_t, 
+                                                   enum random_origins), 
+                                          enum random_origins, size_t, int);
+static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t,
+                                                       enum random_origins),
+                                              enum random_origins);
+static void read_random_source (enum random_origins origin,
+                                size_t length, int level);
+static int gather_faked (void (*add)(const void*, size_t, enum random_origins),
+                         enum random_origins, size_t length, int level );
+
+
+\f
+/* ---  Functions  --- */
+
+
+/* Basic initialization which is required to initialize mutexes and
+   such.  It does not run a full initialization so that the filling of
+   the random pool can be delayed until it is actually needed.  We
+   assume that this function is used before any concurrent access
+   happens. */
 static void
 initialize_basics(void)
 {
@@ -207,19 +288,65 @@ initialize_basics(void)
     }
 }
 
+/* Take the pool lock. */
+static void
+lock_pool (void)
+{
+  int err; 
+
+  err = ath_mutex_lock (&pool_lock);
+  if (err)
+    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
+  pool_is_locked = 1;
+}
 
+/* Release the pool lock. */
+static void
+unlock_pool (void)
+{
+  int err; 
+
+  pool_is_locked = 0;
+  err = ath_mutex_unlock (&pool_lock);
+  if (err)
+    log_fatal ("failed to release the pool lock: %s\n", strerror (err));
+}
+
+
+/* Full initialization of this module. */
 static void
 initialize(void)
 {
   initialize_basics ();
-  /* The data buffer is allocated somewhat larger, so that we can use
-     this extra space (which is allocated in secure memory) as a
-     temporary hash buffer */
-  rndpool = secure_alloc ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
-                         : gcry_xcalloc (1, POOLSIZE + BLOCKLEN);
-  keypool = secure_alloc ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
-                         : gcry_xcalloc (1, POOLSIZE + BLOCKLEN);
-  is_initialized = 1;
+
+  lock_pool ();
+  if (!rndpool)
+    {
+      /* The data buffer is allocated somewhat larger, so that we can
+         use this extra space (which is allocated in secure memory) as
+         a temporary hash buffer */
+      rndpool = (secure_alloc
+                 ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+                 : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+      keypool = (secure_alloc
+                 ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+                 : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+      is_initialized = 1;
+
+      /* Setup the slow entropy gathering function.  The code requires
+         that this function exists. */
+      slow_gather_fnc = getfnc_gather_random ();
+      if (!slow_gather_fnc)
+        {
+          faked_rng = 1;
+          slow_gather_fnc = gather_faked;
+       }
+      
+      /* Setup the fast entropy gathering function.  */
+      fast_gather_fnc = getfnc_fast_random_poll ();
+
+    }
+  unlock_pool ();
 
 }
 
@@ -259,34 +386,36 @@ _gcry_random_initialize (int full)
 
 
 void
-_gcry_random_dump_stats()
+_gcry_random_dump_stats ()
 {
-  /* FIXME: don't we need proper locking here? -mo */
+  /* FIXME: don't we need proper locking here? -mo.  
+     Yes. However this is usually called during cleanup and thenwe _
+     might_ run into problems.  Needs to be checked.  -wk */
 
-    log_info (
-           "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
+  log_info ("random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
            "              outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n",
-       POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
-                 rndstats.naddbytes, rndstats.addbytes,
-       rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
-                   rndstats.ngetbytes2, rndstats.getbytes2 );
+            POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
+            rndstats.naddbytes, rndstats.addbytes,
+            rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
+            rndstats.ngetbytes2, rndstats.getbytes2 );
 }
 
 
+/* This function should be called during initialization and beore
+   intialization of this module to palce the random pools into secure
+   memory.  */
 void
 _gcry_secure_random_alloc()
 {
-    secure_alloc = 1;
+  secure_alloc = 1;
 }
 
 
+/* This may be called before full initialization to degrade the
+   quality of the RNG for the sake of a faster running test suite.  */
 void
 _gcry_enable_quick_random_gen (void)
 {
-  /* No need to lock it here because we are only initializing.  A
-     prerequisite of the entire code is that it has already been
-     initialized before any possible concurrent access.  */
-  read_random_source (RANDOM_ORIGIN_INIT, 0, GCRY_WEAK_RANDOM); /* Init */
   quick_test = 1;
 }
 
@@ -326,6 +455,8 @@ _gcry_use_random_daemon (int onoff)
 }
 
 
+/* This function returns true if no real RNG is available or the
+   quality of the RNG has been degraded for test purposes.  */
 int
 _gcry_random_is_faked()
 {
@@ -358,6 +489,7 @@ gcry_random_add_bytes (const void * buf, size_t buflen, int quality)
 #endif
   return err;
 }   
+
     
 /* The public function to return random data of the quality LEVEL.
    Returns a pointer to a newly allocated and randomized buffer of
@@ -376,6 +508,7 @@ gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
   return buffer;
 }
 
+
 /* The public function to return random data of the quality LEVEL;
    this version of the function returns the random in a buffer allocated
    in secure memory.  Caller must free the buffer. */
@@ -404,7 +537,6 @@ void
 gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
 {
   unsigned char *p;
-  int err;
 
   /* Make sure we are initialized. */
   if (!is_initialized)
@@ -415,7 +547,7 @@ gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
     level = GCRY_STRONG_RANDOM;
 
   /* Make sure the level is okay. */
-  MASK_LEVEL(level);
+  level &= 3;
 
 #ifdef USE_RANDOM_DAEMON
   if (allow_daemon
@@ -425,10 +557,7 @@ gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
 #endif /*USE_RANDOM_DAEMON*/
 
   /* Acquire the pool lock. */
-  err = ath_mutex_lock (&pool_lock);
-  if (err)
-    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
-  pool_is_locked = 1;
+  lock_pool ();
 
   /* Update the statistics. */
   if (level >= GCRY_VERY_STRONG_RANDOM)
@@ -454,11 +583,7 @@ gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
     }
 
   /* Release the pool lock. */
-  pool_is_locked = 0;
-  err = ath_mutex_unlock (&pool_lock);
-  if (err)
-    log_fatal ("failed to release the pool lock: %s\n", strerror (err));
-
+  unlock_pool ();
 }
 
 
@@ -618,10 +743,8 @@ lock_seed_file (int fd, const char *fname, int for_write)
 }
 
 
-/*
-  Read in a seed form the random_seed file
-  and return true if this was successful.
- */
+/* Read in a seed form the random_seed file
+   and return true if this was successful.   */
 static int
 read_seed_file (void)
 {
@@ -729,7 +852,6 @@ _gcry_update_random_seed_file()
 {
   unsigned long *sp, *dp;
   int fd, i;
-  int err;
   
   if ( !seed_file_name || !is_initialized || !pool_filled )
     return;
@@ -739,10 +861,7 @@ _gcry_update_random_seed_file()
       return;
     }
 
-  err = ath_mutex_lock (&pool_lock);
-  if (err)
-    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
-  pool_is_locked = 1;
+  lock_pool ();
 
   /* Copy the entropy pool to a scratch pool and mix both of them. */
   for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
@@ -790,11 +909,7 @@ _gcry_update_random_seed_file()
         log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno));
     }
   
-  pool_is_locked = 0;
-  err = ath_mutex_unlock (&pool_lock);
-  if (err)
-    log_fatal ("failed to release the pool lock: %s\n", strerror (err));
-
+  unlock_pool ();
 }
 
 
@@ -948,7 +1063,7 @@ read_pool (byte *buffer, size_t length, int level)
    used to specify the randomness origin.  This is one of the
    RANDOM_ORIGIN_* values. */
 static void
-add_randomness( const void *buffer, size_t length, int origin )
+add_randomness (const void *buffer, size_t length, enum random_origins origin)
 {
   const unsigned char *p = buffer;
 
@@ -983,11 +1098,14 @@ random_poll()
 }
 
 
+/* Runtime determination of the slow entropy gathering module.  */
 static int (*
-getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
-                            size_t, int)
+getfnc_gather_random (void))(void (*)(const void*, size_t, 
+                                      enum random_origins), 
+                             enum random_origins, size_t, int)
 {
-  int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int);
+  int (*fnc)(void (*)(const void*, size_t, enum random_origins), 
+             enum random_origins, size_t, int);
   
 #if USE_RNDLINUX
   if ( !access (NAME_OF_DEV_RANDOM, R_OK)
@@ -1021,8 +1139,12 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
   return NULL; /*NOTREACHED*/
 }
 
+/* Runtime determination of the fast entropy gathering function.
+   (Currently a compile time method is used.)  */
 static void (*
-getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t,
+                                          enum random_origins),
+                                 enum random_origins)
 {
 #if USE_RNDW32
   return _gcry_rndw32_gather_random_fast;
@@ -1035,23 +1157,12 @@ getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
 static void
 do_fast_random_poll (void)
 {
-  static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
-  static int initialized = 0;
-
   assert (pool_is_locked);
 
   rndstats.fastpolls++;
 
-  if (!initialized )
-    {
-      if (!is_initialized )
-        initialize();
-      initialized = 1;
-      fnc = getfnc_fast_random_poll ();
-    }
-
-  if (fnc)
-    (*fnc)( add_randomness, RANDOM_ORIGIN_FASTPOLL );
+  if (fast_gather_fnc)
+    fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL);
 
   /* Continue with the generic functions. */
 #if HAVE_GETHRTIME
@@ -1126,56 +1237,30 @@ do_fast_random_poll (void)
 void
 _gcry_fast_random_poll (void)
 {
-  int err;
-
   if (!is_initialized)
     return;
 
-  err = ath_mutex_lock (&pool_lock);
-  if (err)
-    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
-  pool_is_locked = 1;
-
+  lock_pool ();
   do_fast_random_poll ();
-
-  pool_is_locked = 0;
-  err = ath_mutex_unlock (&pool_lock);
-  if (err)
-    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
-
+  unlock_pool ();
 }
 
 
 
 static void
-read_random_source ( int orgin, size_t length, int level )
+read_random_source (enum random_origins orgin, size_t length, int level )
 {
-  static int (*fnc)(void (*)(const void*, size_t, int), int,
-                             size_t, int) = NULL;
-  if (!fnc ) 
-    {
-      if (!is_initialized )
-        initialize();
-
-      fnc = getfnc_gather_random ();
-
-      if (!fnc)
-        {
-          faked_rng = 1;
-          fnc = gather_faked;
-       }
-      if (!orgin && !length && !level)
-        return; /* Just the init was requested. */
-    }
+  if ( !slow_gather_fnc )
+    log_fatal ("Slow entropy gathering module not yet initialized\n");
 
-  if ((*fnc)( add_randomness, orgin, length, level ) < 0)
+  if ( slow_gather_fnc (add_randomness, orgin, length, level) < 0)
     log_fatal ("No way to gather entropy for the RNG\n");
 }
 
 
 static int
-gather_faked( void (*add)(const void*, size_t, int), int origin,
-             size_t length, int level )
+gather_faked (void (*add)(const void*, size_t, enum random_origins),
+              enum random_origins origin, size_t length, int level )
 {
   static int initialized=0;
   size_t n;
index 791b909..f4a444c 100644 (file)
@@ -176,8 +176,9 @@ _gcry_rndegd_connect_socket (int nofail)
  * to the pool.  So this is just a dummy for EGD.
  */
 int
-_gcry_rndegd_gather_random (void (*add)(const void*, size_t, int),
-                            int requester,
+_gcry_rndegd_gather_random (void (*add)(const void*, size_t,
+                                        enum random_origins),
+                            enum random_origins origin,
                             size_t length, int level )
 {
   int fd = egd_socket;
@@ -220,7 +221,7 @@ _gcry_rndegd_gather_random (void (*add)(const void*, size_t, int),
           do_restart = 1;
           goto restart;
        }
-      (*add)( buffer, n, requester );
+      (*add)( buffer, n, origin );
       length -= n;
     }
 
@@ -246,7 +247,7 @@ _gcry_rndegd_gather_random (void (*add)(const void*, size_t, int),
           do_restart = 1;
           goto restart;
        }
-      (*add)( buffer, n, requester );
+      (*add)( buffer, n, origin );
       length -= n;
     }
   memset(buffer, 0, sizeof(buffer) );
index d36491c..76cf918 100644 (file)
@@ -37,9 +37,6 @@
 #include "rand-internal.h"
 
 static int open_device ( const char *name );
-int _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, int),
-                                  int requester,
-                                  size_t length, int level );
 
 
 static int
@@ -88,8 +85,9 @@ open_device ( const char *name )
 
 
 int
-_gcry_rndlinux_gather_random (void (*add)(const void*, size_t, int),
-                              int requester,
+_gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
+                                          enum random_origins),
+                              enum random_origins origin,
                               size_t length, int level )
 {
   static int fd_urandom = -1;
@@ -150,7 +148,7 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, int),
         while( n == -1 && errno == EINTR );
        if( n == -1 )
           log_fatal("read error on random device: %s\n", strerror(errno));
-       (*add)( buffer, n, requester );
+       (*add)( buffer, n, origin );
        length -= n;
     }
   memset(buffer, 0, sizeof(buffer) );
index 7964f3f..7b21a7f 100644 (file)
@@ -768,8 +768,9 @@ read_a_msg( int fd, GATHER_MSG *msg )
  * to the pool.  So this is just a dummy for this gatherer.
  */
 int
-_gcry_rndunix_gather_random (void (*add)(const void*, size_t, int),
-                             int requester,
+_gcry_rndunix_gather_random (void (*add)(const void*, size_t,
+                                         enum random_origins),
+                             enum random_origins origin,
                              size_t length, int level )
 {
     static pid_t gatherer_pid = 0;
@@ -835,7 +836,7 @@ _gcry_rndunix_gather_random (void (*add)(const void*, size_t, int),
        n = msg.ndata;
        if( n > length )
            n = length;
-       (*add)( msg.data, n, requester );
+       (*add)( msg.data, n, origin );
 
        /* this is the trick how we cope with the goodness */
        subtract = (ulong)n * goodness / 100;
index 1c2ff20..d21dc12 100644 (file)
@@ -1,6 +1,6 @@
 /* rndw32.c  - W32 entropy gatherer
- *     Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
- *     Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
+ * Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
+ * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
  *
  * This file is part of Libgcrypt.
  *
@@ -497,185 +497,202 @@ slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
 
 
 int
-_gcry_rndw32_gather_random( void (*add)(const void*, size_t, int),
-                            int requester,
+_gcry_rndw32_gather_random (void (*add)(const void*, size_t,
+                                        enum random_origins),
+                            enum random_origins origin,
                             size_t length, int level )
 {
-    static int is_initialized;
-    static int is_windowsNT, has_toolhelp;
+  static int is_initialized;
+  static int is_windowsNT, has_toolhelp;
 
 
-    if( !level )
-       return 0;
-    /* We don't differentiate between level 1 and 2 here because
-     * there is no internal entropy pool as a scary resource.  It may
-     * all work slower, but because our entropy source will never
-     * block but deliver some not easy to measure entropy, we assume level 2
-     */
-
-
-    if ( !is_initialized ) {
-       OSVERSIONINFO osvi = { sizeof( osvi ) };
-       DWORD platform;
-
-       GetVersionEx( &osvi );
-       platform = osvi.dwPlatformId;
-        is_windowsNT = platform == VER_PLATFORM_WIN32_NT;
-        has_toolhelp = (platform == VER_PLATFORM_WIN32_WINDOWS
-                        || (is_windowsNT && osvi.dwMajorVersion >= 5));
-
-       if ( platform == VER_PLATFORM_WIN32s ) {
-           log_fatal("can't run on a W32s platform\n" );
-       }
-       is_initialized = 1;
-       if ( debug_me )
-           log_debug ("rndw32#gather_random: platform=%d\n", (int)platform );
-    }
-
-
-    if ( debug_me )
-       log_debug ("rndw32#gather_random: req=%d len=%u lvl=%d\n",
-                          requester, (unsigned int)length, level );
-
-    if ( has_toolhelp ) {
-        slow_gatherer_windows95 ( add, requester );
-    }
-    if ( is_windowsNT ) {
-        slow_gatherer_windowsNT ( add, requester );
-    }
-
+  if ( !level )
     return 0;
+  /* We don't differentiate between level 1 and 2 here because there
+     is no internal entropy pool as a scary resource.  It may all work
+     slower, but because our entropy source will never block but
+     deliver some not easy to measure entropy, we assume level 2.  */
+
+  if ( !is_initialized )
+    {
+      OSVERSIONINFO osvi = { sizeof( osvi ) };
+      DWORD platform;
+      
+      GetVersionEx( &osvi );
+      platform = osvi.dwPlatformId;
+      is_windowsNT = platform == VER_PLATFORM_WIN32_NT;
+      has_toolhelp = (platform == VER_PLATFORM_WIN32_WINDOWS
+                      || (is_windowsNT && osvi.dwMajorVersion >= 5));
+
+      if ( platform == VER_PLATFORM_WIN32s ) 
+        log_fatal("can't run on a W32s platform\n" );
+      is_initialized = 1;
+      if ( debug_me )
+        log_debug ("rndw32#gather_random: platform=%d\n", (int)platform );
+    }
+  
+  
+  if ( debug_me )
+    log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
+               origin, (unsigned int)length, level );
+  
+  if ( has_toolhelp )
+    slow_gatherer_windows95 ( add, origin );
+  if ( is_windowsNT )
+    slow_gatherer_windowsNT ( add, origin );
+  
+  return 0;
 }
 
 
 void
-_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int),
-                                 int requester )
+_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, 
+                                             enum random_origins),
+                                 enum random_origins origin)
 {
-    static int addedFixedItems = 0;
-
-    if ( debug_me )
-       log_debug ("rndw32#gather_random_fast: req=%d\n", requester );
-
-    /* Get various basic pieces of system information: Handle of active
-     * window, handle of window with mouse capture, handle of clipboard owner
-     * handle of start of clpboard viewer list, pseudohandle of current
-     * process, current process ID, pseudohandle of current thread, current
-     * thread ID, handle of desktop window, handle  of window with keyboard
-     * focus, whether system queue has any events, cursor position for last
-     * message, 1 ms time for last message, handle of window with clipboard
-     * open, handle of process heap, handle of procs window station, types of
-     * events in input queue, and milliseconds since Windows was started */
-    {  byte buffer[20*sizeof(ulong)], *bufptr;
-       bufptr = buffer;
-#define ADD(f)  do { ulong along = (ulong)(f);               \
-                          memcpy (bufptr, &along, sizeof (along) );  \
-                          bufptr += sizeof (along); } while (0)
-       ADD ( GetActiveWindow ());
-       ADD ( GetCapture ());
-       ADD ( GetClipboardOwner ());
-       ADD ( GetClipboardViewer ());
-       ADD ( GetCurrentProcess ());
-       ADD ( GetCurrentProcessId ());
-       ADD ( GetCurrentThread ());
-       ADD ( GetCurrentThreadId ());
-       ADD ( GetDesktopWindow ());
-       ADD ( GetFocus ());
-       ADD ( GetInputState ());
-       ADD ( GetMessagePos ());
-       ADD ( GetMessageTime ());
-       ADD ( GetOpenClipboardWindow ());
-       ADD ( GetProcessHeap ());
-       ADD ( GetProcessWindowStation ());
-       ADD ( GetQueueStatus (QS_ALLEVENTS));
-       ADD ( GetTickCount ());
-
-       assert ( bufptr-buffer < sizeof (buffer) );
-       (*add) ( buffer, bufptr-buffer, requester );
+  static int addedFixedItems = 0;
+  
+  if ( debug_me )
+    log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );
+  
+  /* Get various basic pieces of system information: Handle of active
+     window, handle of window with mouse capture, handle of clipboard
+     owner handle of start of clpboard viewer list, pseudohandle of
+     current process, current process ID, pseudohandle of current
+     thread, current thread ID, handle of desktop window, handle of
+     window with keyboard focus, whether system queue has any events,
+     cursor position for last message, 1 ms time for last message,
+     handle of window with clipboard open, handle of process heap,
+     handle of procs window station, types of events in input queue,
+     and milliseconds since Windows was started.  */
+  
+  {
+    byte buffer[20*sizeof(ulong)], *bufptr;
+
+    bufptr = buffer;
+#define ADD(f)  do { ulong along = (ulong)(f);                 \
+                    memcpy (bufptr, &along, sizeof (along) );  \
+                    bufptr += sizeof (along);                  \
+                   } while (0)
+
+    ADD ( GetActiveWindow ());
+    ADD ( GetCapture ());
+    ADD ( GetClipboardOwner ());
+    ADD ( GetClipboardViewer ());
+    ADD ( GetCurrentProcess ());
+    ADD ( GetCurrentProcessId ());
+    ADD ( GetCurrentThread ());
+    ADD ( GetCurrentThreadId ());
+    ADD ( GetDesktopWindow ());
+    ADD ( GetFocus ());
+    ADD ( GetInputState ());
+    ADD ( GetMessagePos ());
+    ADD ( GetMessageTime ());
+    ADD ( GetOpenClipboardWindow ());
+    ADD ( GetProcessHeap ());
+    ADD ( GetProcessWindowStation ());
+    ADD ( GetQueueStatus (QS_ALLEVENTS));
+    ADD ( GetTickCount ());
+    
+    assert ( bufptr-buffer < sizeof (buffer) );
+    (*add) ( buffer, bufptr-buffer, origin );
 #undef ADD
+  }
+
+  /* Get multiword system information: Current caret position, current
+     mouse cursor position.  */
+  {    
+    POINT point;
+    
+    GetCaretPos (&point);
+    (*add) ( &point, sizeof (point), origin );
+    GetCursorPos (&point);
+    (*add) ( &point, sizeof (point), origin );
+  }
+
+  /* Get percent of memory in use, bytes of physical memory, bytes of
+     free physical memory, bytes in paging file, free bytes in paging
+     file, user bytes of address space, and free user bytes.  */
+  {    
+    MEMORYSTATUS memoryStatus;
+
+    memoryStatus.dwLength = sizeof (MEMORYSTATUS);
+    GlobalMemoryStatus (&memoryStatus);
+    (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
+  }
+
+  /* Get thread and process creation time, exit time, time in kernel
+     mode, and time in user mode in 100ns intervals.  */
+  {
+    HANDLE handle;
+    FILETIME creationTime, exitTime, kernelTime, userTime;
+    DWORD minimumWorkingSetSize, maximumWorkingSetSize;
+
+    handle = GetCurrentThread ();
+    GetThreadTimes (handle, &creationTime, &exitTime,
+                    &kernelTime, &userTime);
+    (*add) ( &creationTime, sizeof (creationTime), origin );
+    (*add) ( &exitTime, sizeof (exitTime), origin );
+    (*add) ( &kernelTime, sizeof (kernelTime), origin );
+    (*add) ( &userTime, sizeof (userTime), origin );
+    
+    handle = GetCurrentProcess ();
+    GetProcessTimes (handle, &creationTime, &exitTime,
+                     &kernelTime, &userTime);
+    (*add) ( &creationTime, sizeof (creationTime), origin );
+    (*add) ( &exitTime, sizeof (exitTime), origin );
+    (*add) ( &kernelTime, sizeof (kernelTime), origin );
+    (*add) ( &userTime, sizeof (userTime), origin );
+    
+    /* Get the minimum and maximum working set size for the current
+       process.  */
+    GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
+                              &maximumWorkingSetSize);
+    (*add) ( &minimumWorkingSetSize,
+             sizeof (minimumWorkingSetSize), origin );
+    (*add) ( &maximumWorkingSetSize,
+             sizeof (maximumWorkingSetSize), origin );
+  }
+  
+
+  /* The following are fixed for the lifetime of the process so we only
+   * add them once */
+  if (!addedFixedItems)
+    {
+      STARTUPINFO startupInfo;
+
+      /* Get name of desktop, console window title, new window
+        position and size, window flags, and handles for stdin,
+        stdout, and stderr.  */
+      startupInfo.cb = sizeof (STARTUPINFO);
+      GetStartupInfo (&startupInfo);
+      (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
+      addedFixedItems = 1;
     }
 
-    /* Get multiword system information: Current caret position, current
-     * mouse cursor position */
-    {  POINT point;
-       GetCaretPos (&point);
-       (*add) ( &point, sizeof (point), requester );
-       GetCursorPos (&point);
-       (*add) ( &point, sizeof (point), requester );
-    }
-
-    /* Get percent of memory in use, bytes of physical memory, bytes of free
-     * physical memory, bytes in paging file, free bytes in paging file, user
-     * bytes of address space, and free user bytes */
-    {  MEMORYSTATUS memoryStatus;
-       memoryStatus.dwLength = sizeof (MEMORYSTATUS);
-       GlobalMemoryStatus (&memoryStatus);
-       (*add) ( &memoryStatus, sizeof (memoryStatus), requester );
-    }
-
-    /* Get thread and process creation time, exit time, time in kernel mode,
-       and time in user mode in 100ns intervals */
-    {  HANDLE handle;
-       FILETIME creationTime, exitTime, kernelTime, userTime;
-       DWORD minimumWorkingSetSize, maximumWorkingSetSize;
-
-       handle = GetCurrentThread ();
-       GetThreadTimes (handle, &creationTime, &exitTime,
-                                              &kernelTime, &userTime);
-       (*add) ( &creationTime, sizeof (creationTime), requester );
-       (*add) ( &exitTime, sizeof (exitTime), requester );
-       (*add) ( &kernelTime, sizeof (kernelTime), requester );
-       (*add) ( &userTime, sizeof (userTime), requester );
-
-       handle = GetCurrentProcess ();
-       GetProcessTimes (handle, &creationTime, &exitTime,
-                                               &kernelTime, &userTime);
-       (*add) ( &creationTime, sizeof (creationTime), requester );
-       (*add) ( &exitTime, sizeof (exitTime), requester );
-       (*add) ( &kernelTime, sizeof (kernelTime), requester );
-       (*add) ( &userTime, sizeof (userTime), requester );
-
-       /* Get the minimum and maximum working set size for the
-           current process */
-       GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
-                                         &maximumWorkingSetSize);
-       (*add) ( &minimumWorkingSetSize,
-                                  sizeof (minimumWorkingSetSize), requester );
-       (*add) ( &maximumWorkingSetSize,
-                                  sizeof (maximumWorkingSetSize), requester );
-    }
-
-
-    /* The following are fixed for the lifetime of the process so we only
-     * add them once */
-    if (!addedFixedItems) {
-       STARTUPINFO startupInfo;
-
-       /* Get name of desktop, console window title, new window position and
-        * size, window flags, and handles for stdin, stdout, and stderr */
-       startupInfo.cb = sizeof (STARTUPINFO);
-       GetStartupInfo (&startupInfo);
-       (*add) ( &startupInfo, sizeof (STARTUPINFO), requester );
-       addedFixedItems = 1;
-    }
-
-    /* The performance of QPC varies depending on the architecture it's
-     * running on and on the OS.  Under NT it reads the CPU's 64-bit timestamp
-     * counter (at least on a Pentium and newer '486's, it hasn't been tested
-     * on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC
-     * timer.  There are vague mumblings in the docs that it may fail if the
-     * appropriate hardware isn't available (possibly '386's or MIPS machines
-     * running NT), but who's going to run NT on a '386? */
-    {  LARGE_INTEGER performanceCount;
-       if (QueryPerformanceCounter (&performanceCount)) {
-           if ( debug_me )
-               log_debug ("rndw32#gather_random_fast: perf data\n");
-           (*add) (&performanceCount, sizeof (performanceCount), requester);
-       }
-       else { /* Millisecond accuracy at best... */
-           DWORD aword = GetTickCount ();
-           (*add) (&aword, sizeof (aword), requester );
-       }
-    }
+  /* The performance of QPC varies depending on the architecture it's
+     running on and on the OS.  Under NT it reads the CPU's 64-bit
+     timestamp counter (at least on a Pentium and newer '486's, it
+     hasn't been tested on anything without a TSC), under Win95 it
+     reads the 1.193180 MHz PIC timer.  There are vague mumblings in
+     the docs that it may fail if the appropriate hardware isn't
+     available (possibly '386's or MIPS machines running NT), but
+     who's going to run NT on a '386?.  */
+  {    
+    LARGE_INTEGER performanceCount;
+    
+    if (QueryPerformanceCounter (&performanceCount))
+      {
+        if ( debug_me )
+          log_debug ("rndw32#gather_random_fast: perf data\n");
+        (*add) (&performanceCount, sizeof (performanceCount), origin);
+      }
+    else
+      { 
+        /* Millisecond accuracy at best... */
+        DWORD aword = GetTickCount ();
+        (*add) (&aword, sizeof (aword), origin );
+      }
+  }
 }