summaryrefslogtreecommitdiff
path: root/random
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2012-11-30 18:16:34 +0100
committerWerner Koch <wk@gnupg.org>2012-12-03 20:47:38 +0100
commitc324644aa14e54fc7051983b38222db32b8ab227 (patch)
treeb237ea9932a3990382ee0487b772293bcc897c2b /random
parentf851b9a932ee64fa5a06000d1ac763ba4349f07d (diff)
downloadlibgcrypt-c324644aa14e54fc7051983b38222db32b8ab227.tar.gz
Move nonce creation from csprng backend to random main module.
* 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.
Diffstat (limited to 'random')
-rw-r--r--random/rand-internal.h7
-rw-r--r--random/random-csprng.c97
-rw-r--r--random/random-daemon.c13
-rw-r--r--random/random.c107
-rw-r--r--random/random.h2
5 files changed, 105 insertions, 121 deletions
diff --git a/random/rand-internal.h b/random/rand-internal.h
index a04a2d41..a72d88c1 100644
--- a/random/rand-internal.h
+++ b/random/rand-internal.h
@@ -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);
diff --git a/random/random-csprng.c b/random/random-csprng.c
index 50357d17..9921c4fd 100644
--- a/random/random-csprng.c
+++ b/random/random-csprng.c
@@ -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));
-
-}
diff --git a/random/random-daemon.c b/random/random-daemon.c
index 9422e853..26d77f8c 100644
--- a/random/random-daemon.c
+++ b/random/random-daemon.c
@@ -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 */
diff --git a/random/random.c b/random/random.c
index 40661ab0..9a5b166c 100644
--- a/random/random.c
+++ b/random/random.c
@@ -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.
*
@@ -26,10 +26,14 @@
#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;
@@ -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));
}
diff --git a/random/random.h b/random/random.h
index 7a9585cd..5f6a42c1 100644
--- a/random/random.h
+++ b/random/random.h
@@ -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*/