diff options
author | Werner Koch <wk@gnupg.org> | 2012-11-30 18:16:34 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2012-12-03 20:47:38 +0100 |
commit | c324644aa14e54fc7051983b38222db32b8ab227 (patch) | |
tree | b237ea9932a3990382ee0487b772293bcc897c2b /random | |
parent | f851b9a932ee64fa5a06000d1ac763ba4349f07d (diff) | |
download | libgcrypt-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.h | 7 | ||||
-rw-r--r-- | random/random-csprng.c | 97 | ||||
-rw-r--r-- | random/random-daemon.c | 13 | ||||
-rw-r--r-- | random/random.c | 107 | ||||
-rw-r--r-- | random/random.h | 2 |
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*/ |