Move nonce creation from csprng backend to random main module.
authorWerner Koch <wk@gnupg.org>
Fri, 30 Nov 2012 17:16:34 +0000 (18:16 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 3 Dec 2012 19:47:38 +0000 (20:47 +0100)
* random/random-csprng.c (_gcry_rngcsprng_create_nonce): Remove.
(nonce_buffer_lock): Remove.
(initialize_basics): Remove init of nonce_buffer_lock.
* random/random.c: Add a few header files.
(nonce_buffer_lock):  New.
(_gcry_random_initialize): Init nonce_buffer_lock.
(gcry_create_nonce): Add code from _gcry_rngcsprng_create_nonce.

* random/random-daemon.c (_gcry_daemon_create_nonce): Remove.
--

The nonce generation code is useful for all RNG types and thus it
should be in random.c.  The only exception is the fips-mode, which
requires the use of the fips nonce generator.

random/rand-internal.h
random/random-csprng.c
random/random-daemon.c
random/random.c
random/random.h

index a04a2d4..a72d88c 100644 (file)
@@ -61,18 +61,13 @@ void _gcry_rngcsprng_randomize (void *buffer, size_t length,
 void _gcry_rngcsprng_set_seed_file (const char *name);
 void _gcry_rngcsprng_update_seed_file (void);
 void _gcry_rngcsprng_fast_poll (void);
-void _gcry_rngcsprng_create_nonce (void *buffer, size_t length);
 
-/*-- random-rngcsprng.c --*/
+/*-- random-fips.c --*/
 void _gcry_rngfips_initialize (int full);
 void _gcry_rngfips_dump_stats (void);
 int  _gcry_rngfips_is_faked (void);
 gcry_error_t _gcry_rngfips_add_bytes (const void *buf, size_t buflen,
                                         int quality);
-void *_gcry_rngfips_get_bytes (size_t nbytes,
-                               enum gcry_random_level level);
-void *_gcry_rngfips_get_bytes_secure (size_t nbytes,
-                                      enum gcry_random_level level);
 void _gcry_rngfips_randomize (void *buffer, size_t length,
                                 enum gcry_random_level level);
 void _gcry_rngfips_create_nonce (void *buffer, size_t length);
index 50357d1..9921c4f 100644 (file)
@@ -1,6 +1,6 @@
 /* random-csprng.c - CSPRNG style random number generator (libgcrypt classic)
  * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007, 2008, 2010  Free Software Foundation, Inc.
+ *               2007, 2008, 2010, 2012  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -189,10 +189,6 @@ static ath_mutex_t pool_lock;
    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;
-
 
 /* We keep some counters in this structure for the sake of the
    _gcry_random_dump_stats () function.  */
@@ -272,11 +268,6 @@ initialize_basics(void)
       if (err)
         log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
 
-      err = ath_mutex_init (&nonce_buffer_lock);
-      if (err)
-        log_fatal ("failed to create the nonce buffer lock: %s\n",
-                   strerror (err) );
-
 #ifdef USE_RANDOM_DAEMON
       _gcry_daemon_initialize_basics ();
 #endif /*USE_RANDOM_DAEMON*/
@@ -1320,89 +1311,3 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins),
   gcry_free (buffer);
   return 0; /* okay */
 }
-
-
-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
-void
-_gcry_rngcsprng_create_nonce (void *buffer, size_t length)
-{
-  static unsigned char nonce_buffer[20+8];
-  static int nonce_buffer_initialized = 0;
-  static volatile pid_t my_pid; /* The volatile is there to make sure the
-                                   compiler does not optimize the code away
-                                   in case the getpid function is badly
-                                   attributed. */
-  volatile pid_t apid;
-  unsigned char *p;
-  size_t n;
-  int err;
-
-  /* Make sure we are initialized. */
-  initialize ();
-
-#ifdef USE_RANDOM_DAEMON
-  if (allow_daemon
-      && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length))
-    return; /* The daemon succeeded. */
-  allow_daemon = 0; /* Daemon failed - switch off. */
-#endif /*USE_RANDOM_DAEMON*/
-
-  /* Acquire the nonce buffer lock. */
-  err = ath_mutex_lock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to acquire the nonce buffer lock: %s\n",
-               strerror (err));
-
-  apid = getpid ();
-  /* The first time initialize our buffer. */
-  if (!nonce_buffer_initialized)
-    {
-      time_t atime = time (NULL);
-      pid_t xpid = apid;
-
-      my_pid = apid;
-
-      if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
-        BUG ();
-
-      /* Initialize the first 20 bytes with a reasonable value so that
-         a failure of gcry_randomize won't affect us too much.  Don't
-         care about the uninitialized remaining bytes. */
-      p = nonce_buffer;
-      memcpy (p, &xpid, sizeof xpid);
-      p += sizeof xpid;
-      memcpy (p, &atime, sizeof atime);
-
-      /* Initialize the never changing private part of 64 bits. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-
-      nonce_buffer_initialized = 1;
-    }
-  else if ( my_pid != apid )
-    {
-      /* We forked. Need to reseed the buffer - doing this for the
-         private part should be sufficient. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-      /* Update the pid so that we won't run into here again and
-         again. */
-      my_pid = apid;
-    }
-
-  /* Create the nonce by hashing the entire buffer, returning the hash
-     and updating the first 20 bytes of the buffer with this hash. */
-  for (p = buffer; length > 0; length -= n, p += n)
-    {
-      _gcry_sha1_hash_buffer (nonce_buffer,
-                              nonce_buffer, sizeof nonce_buffer);
-      n = length > 20? 20 : length;
-      memcpy (p, nonce_buffer, n);
-    }
-
-
-  /* Release the nonce buffer lock. */
-  err = ath_mutex_unlock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to release the nonce buffer lock: %s\n",
-               strerror (err));
-
-}
index 9422e85..26d77f8 100644 (file)
@@ -345,17 +345,4 @@ _gcry_daemon_randomize (const char *socketname,
   return err ? -1 : 0;
 }
 
-
-/* Internal function to fill BUFFER with NBYTES of data usable for a
-   nonce.  Returns 0 on success. */
-int
-_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length)
-{
-  gcry_error_t err;
-
-  err = call_daemon (socketname, buffer, length, 1, 0);
-
-  return err ? -1 : 0;
-}
-
 /* END */
index 40661ab..9a5b166 100644 (file)
@@ -1,5 +1,5 @@
 /* random.c - Random number switch
- * Copyright (C) 2008  Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2006, 2008, 2012  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include "g10lib.h"
 #include "random.h"
 #include "rand-internal.h"
+#include "cipher.h"         /* For _gcry_sha1_hash_buffer().  */
 #include "ath.h"
 
 
@@ -39,6 +43,9 @@
 static void (*progress_cb) (void *,const char*,int,int, int );
 static void *progress_cb_data;
 
+/* This is the lock we use to protect the buffer used by the nonce
+   generation.  */
+static ath_mutex_t nonce_buffer_lock;
 
 
 \f
@@ -75,6 +82,18 @@ _gcry_random_progress (const char *what, int printchar, int current, int total)
 void
 _gcry_random_initialize (int full)
 {
+  static int nonce_initialized;
+  int err;
+
+  if (!nonce_initialized)
+    {
+      nonce_initialized = 1;
+      err = ath_mutex_init (&nonce_buffer_lock);
+      if (err)
+        log_fatal ("failed to create the nonce buffer lock: %s\n",
+                   strerror (err) );
+    }
+
   if (fips_mode ())
     _gcry_rngfips_initialize (full);
   else
@@ -265,10 +284,90 @@ _gcry_fast_random_poll (void)
 void
 gcry_create_nonce (void *buffer, size_t length)
 {
+  static unsigned char nonce_buffer[20+8];
+  static int nonce_buffer_initialized = 0;
+  static volatile pid_t my_pid; /* The volatile is there to make sure the
+                                   compiler does not optimize the code away
+                                   in case the getpid function is badly
+                                   attributed. */
+  volatile pid_t apid;
+  unsigned char *p;
+  size_t n;
+  int err;
+
+  /* First check whether we shall use the FIPS nonce generator.  This
+     is only done in FIPS mode, in all other modes, we use our own
+     nonce generator which is seeded by the RNG actual in use.  */
   if (fips_mode ())
-    _gcry_rngfips_create_nonce (buffer, length);
-  else
-    _gcry_rngcsprng_create_nonce (buffer, length);
+    {
+      _gcry_rngfips_create_nonce (buffer, length);
+      return;
+    }
+
+  /* This is the nonce generator, which formerly lived in
+     random-csprng.c.  It is now used by all RNG types except when in
+     FIPS mode (not that this means it is also used if the FIPS RNG
+     has been selected but we are not in fips mode).  */
+
+  /* Make sure we are initialized. */
+  _gcry_random_initialize (1);
+
+  /* Acquire the nonce buffer lock. */
+  err = ath_mutex_lock (&nonce_buffer_lock);
+  if (err)
+    log_fatal ("failed to acquire the nonce buffer lock: %s\n",
+               strerror (err));
+
+  apid = getpid ();
+  /* The first time initialize our buffer. */
+  if (!nonce_buffer_initialized)
+    {
+      time_t atime = time (NULL);
+      pid_t xpid = apid;
+
+      my_pid = apid;
+
+      if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
+        BUG ();
+
+      /* Initialize the first 20 bytes with a reasonable value so that
+         a failure of gcry_randomize won't affect us too much.  Don't
+         care about the uninitialized remaining bytes. */
+      p = nonce_buffer;
+      memcpy (p, &xpid, sizeof xpid);
+      p += sizeof xpid;
+      memcpy (p, &atime, sizeof atime);
+
+      /* Initialize the never changing private part of 64 bits. */
+      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+
+      nonce_buffer_initialized = 1;
+    }
+  else if ( my_pid != apid )
+    {
+      /* We forked. Need to reseed the buffer - doing this for the
+         private part should be sufficient. */
+      do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+      /* Update the pid so that we won't run into here again and
+         again. */
+      my_pid = apid;
+    }
+
+  /* Create the nonce by hashing the entire buffer, returning the hash
+     and updating the first 20 bytes of the buffer with this hash. */
+  for (p = buffer; length > 0; length -= n, p += n)
+    {
+      _gcry_sha1_hash_buffer (nonce_buffer,
+                              nonce_buffer, sizeof nonce_buffer);
+      n = length > 20? 20 : length;
+      memcpy (p, nonce_buffer, n);
+    }
+
+  /* Release the nonce buffer lock. */
+  err = ath_mutex_unlock (&nonce_buffer_lock);
+  if (err)
+    log_fatal ("failed to release the nonce buffer lock: %s\n",
+               strerror (err));
 }
 
 
index 7a9585c..5f6a42c 100644 (file)
@@ -61,8 +61,6 @@ void _gcry_daemon_initialize_basics (void);
 int _gcry_daemon_randomize (const char *socketname,
                             void *buffer, size_t length,
                             enum gcry_random_level level);
-int _gcry_daemon_create_nonce (const char *socketname,
-                               void *buffer, size_t length);
 #endif /*USE_RANDOM_DAEMON*/
 
 #endif /*G10_RANDOM_H*/