diff options
Diffstat (limited to 'libgcrypt-1.4.6/random/random-csprng.c')
-rw-r--r-- | libgcrypt-1.4.6/random/random-csprng.c | 926 |
1 files changed, 463 insertions, 463 deletions
diff --git a/libgcrypt-1.4.6/random/random-csprng.c b/libgcrypt-1.4.6/random/random-csprng.c index aca977e..6ab868a 100644 --- a/libgcrypt-1.4.6/random/random-csprng.c +++ b/libgcrypt-1.4.6/random/random-csprng.c @@ -158,15 +158,15 @@ static int secure_alloc; 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); + 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); + enum random_origins), + enum random_origins); /* Option flag useful for debugging and the test suite. If set @@ -235,22 +235,22 @@ static char *daemon_socket_name; /* --- 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); + 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); + 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); + enum random_origins), + enum random_origins); static void read_random_source (enum random_origins origin, - size_t length, int level); + 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 ); + enum random_origins, size_t length, int level ); - + /* --- Functions --- */ @@ -266,27 +266,27 @@ initialize_basics(void) int err; if (!initialized) - { - initialized = 1; - err = ath_mutex_init (&pool_lock); - 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) ); + { + initialized = 1; + err = ath_mutex_init (&pool_lock); + 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 (); + _gcry_daemon_initialize_basics (); #endif /*USE_RANDOM_DAEMON*/ - /* Make sure that we are still using the values we have - traditionally used for the random levels. */ - gcry_assert (GCRY_WEAK_RANDOM == 0 - && GCRY_STRONG_RANDOM == 1 - && GCRY_VERY_STRONG_RANDOM == 2); - } + /* Make sure that we are still using the values we have + traditionally used for the random levels. */ + gcry_assert (GCRY_WEAK_RANDOM == 0 + && GCRY_STRONG_RANDOM == 1 + && GCRY_VERY_STRONG_RANDOM == 2); + } } /* Take the pool lock. */ @@ -297,7 +297,7 @@ lock_pool (void) err = ath_mutex_lock (&pool_lock); if (err) - log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); + log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); pool_is_locked = 1; } @@ -310,7 +310,7 @@ unlock_pool (void) pool_is_locked = 0; err = ath_mutex_unlock (&pool_lock); if (err) - log_fatal ("failed to release the pool lock: %s\n", strerror (err)); + log_fatal ("failed to release the pool lock: %s\n", strerror (err)); } @@ -319,37 +319,37 @@ static void initialize(void) { /* Although the basic initialization should have happened already, - we call it here to make sure that all prerequisites are met. */ + we call it here to make sure that all prerequisites are met. */ initialize_basics (); /* Now we can look the pool and complete the initialization if - necessary. */ + necessary. */ 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)); - - /* 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; + { + /* 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)); + + /* 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 (); + + /* Setup the fast entropy gathering function. */ + fast_gather_fnc = getfnc_fast_random_poll (); - } + } unlock_pool (); } @@ -364,9 +364,9 @@ void _gcry_rngcsprng_initialize (int full) { if (!full) - initialize_basics (); + initialize_basics (); else - initialize (); + initialize (); } @@ -374,16 +374,16 @@ void _gcry_rngcsprng_dump_stats (void) { /* In theory we would need to lock the stats here. However this - function is usually called during cleanup and then we _might_ run - into problems. */ + function is usually called during cleanup and then we _might_ run + into problems. */ log_info ("random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n" - " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu%s\n", - POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls, - rndstats.naddbytes, rndstats.addbytes, - rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, - rndstats.ngetbytes2, rndstats.getbytes2, - _gcry_rndhw_failed_p()? " (hwrng failed)":""); + " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu%s\n", + POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls, + rndstats.naddbytes, rndstats.addbytes, + rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, + rndstats.ngetbytes2, rndstats.getbytes2, + _gcry_rndhw_failed_p()? " (hwrng failed)":""); } @@ -411,7 +411,7 @@ _gcry_rngcsprng_set_daemon_socket (const char *socketname) { #ifdef USE_RANDOM_DAEMON if (daemon_socket_name) - BUG (); + BUG (); daemon_socket_name = gcry_xstrdup (socketname); #else /*!USE_RANDOM_DAEMON*/ @@ -429,13 +429,13 @@ _gcry_rngcsprng_use_daemon (int onoff) int last; /* This is not really thread safe. However it is expected that this - function is being called during initialization and at that point - we are for other reasons not really thread safe. We do not want - to lock it because we might eventually decide that this function - may even be called prior to gcry_check_version. */ + function is being called during initialization and at that point + we are for other reasons not really thread safe. We do not want + to lock it because we might eventually decide that this function + may even be called prior to gcry_check_version. */ last = allow_daemon; if (onoff != -1) - allow_daemon = onoff; + allow_daemon = onoff; return last; #else /*!USE_RANDOM_DAEMON*/ @@ -451,7 +451,7 @@ int _gcry_rngcsprng_is_faked (void) { /* We need to initialize due to the runtime determination of - available entropy gather modules. */ + available entropy gather modules. */ initialize(); return (faked_rng || quick_test); } @@ -467,38 +467,38 @@ _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality) const char *bufptr; if (quality == -1) - quality = 35; + quality = 35; else if (quality > 100) - quality = 100; + quality = 100; else if (quality < 0) - quality = 0; - + quality = 0; + if (!buf) - return gpg_error (GPG_ERR_INV_ARG); + return gpg_error (GPG_ERR_INV_ARG); if (!buflen || quality < 10) - return 0; /* Take a shortcut. */ + return 0; /* Take a shortcut. */ /* Because we don't increment the entropy estimation with FASTPOLL, - we don't need to take lock that estimation while adding from an - external source. This limited entropy estimation also means that - we can't take QUALITY into account. */ + we don't need to take lock that estimation while adding from an + external source. This limited entropy estimation also means that + we can't take QUALITY into account. */ initialize_basics (); bufptr = buf; while (buflen) - { - nbytes = buflen > POOLSIZE? POOLSIZE : buflen; - lock_pool (); - if (rndpool) - add_randomness (bufptr, nbytes, RANDOM_ORIGIN_EXTERNAL); - unlock_pool (); - bufptr += nbytes; - buflen -= nbytes; - } + { + nbytes = buflen > POOLSIZE? POOLSIZE : buflen; + lock_pool (); + if (rndpool) + add_randomness (bufptr, nbytes, RANDOM_ORIGIN_EXTERNAL); + unlock_pool (); + bufptr += nbytes; + buflen -= nbytes; + } return 0; } - + /* Public function to fill the buffer with LENGTH bytes of cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is not very strong, GCRY_STRONG_RANDOM is strong enough for most @@ -506,7 +506,7 @@ _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality) may be very slow. */ void _gcry_rngcsprng_randomize (void *buffer, size_t length, - enum gcry_random_level level) + enum gcry_random_level level) { unsigned char *p; @@ -515,15 +515,15 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, /* Handle our hack used for regression tests of Libgcrypt. */ if ( quick_test && level > GCRY_STRONG_RANDOM ) - level = GCRY_STRONG_RANDOM; + level = GCRY_STRONG_RANDOM; /* Make sure the level is okay. */ level &= 3; #ifdef USE_RANDOM_DAEMON if (allow_daemon - && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level)) - return; /* The daemon succeeded. */ + && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level)) + return; /* The daemon succeeded. */ allow_daemon = 0; /* Daemon failed - switch off. */ #endif /*USE_RANDOM_DAEMON*/ @@ -532,26 +532,26 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, /* Update the statistics. */ if (level >= GCRY_VERY_STRONG_RANDOM) - { - rndstats.getbytes2 += length; - rndstats.ngetbytes2++; - } + { + rndstats.getbytes2 += length; + rndstats.ngetbytes2++; + } else - { - rndstats.getbytes1 += length; - rndstats.ngetbytes1++; - } + { + rndstats.getbytes1 += length; + rndstats.ngetbytes1++; + } /* Read the random into the provided buffer. */ for (p = buffer; length > 0;) - { - size_t n; + { + size_t n; - n = length > POOLSIZE? POOLSIZE : length; - read_pool (p, n, level); - length -= n; - p += n; - } + n = length > POOLSIZE? POOLSIZE : length; + read_pool (p, n, level); + length -= n; + p += n; + } /* Release the pool lock. */ unlock_pool (); @@ -565,28 +565,28 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, |........blocks*20byte........|20byte|..44byte..| <..44byte..> <20byte> - | | - | +------+ - +---------------------------|----------+ - v v + | | + | +------+ + +---------------------------|----------+ + v v |........blocks*20byte........|20byte|..44byte..| - <.....64bytes.....> - | - +----------------------------------+ - Hash - v + <.....64bytes.....> + | + +----------------------------------+ + Hash + v |.............................|20byte|..44byte..| <20byte><20byte><..44byte..> - | | - | +---------------------+ - +-----------------------------+ | - v v + | | + | +---------------------+ + +-----------------------------+ | + v v |.............................|20byte|..44byte..| - <.....64byte......> - | - +-------------------------+ - Hash - v + <.....64byte......> + | + +-------------------------+ + Hash + v |.............................|20byte|..44byte..| <20byte><20byte><..44byte..> @@ -623,46 +623,46 @@ mix_pool(unsigned char *pool) memcpy(pool, hashbuf, 20 ); if (failsafe_digest_valid && pool == rndpool) - { - for (i=0; i < 20; i++) - pool[i] ^= failsafe_digest[i]; - } + { + for (i=0; i < 20; i++) + pool[i] ^= failsafe_digest[i]; + } p = pool; for (n=1; n < POOLBLOCKS; n++) - { - memcpy (hashbuf, p, DIGESTLEN); - - p += DIGESTLEN; - if (p+DIGESTLEN+BLOCKLEN < pend) - memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); - else - { - unsigned char *pp = p + DIGESTLEN; - - for (i=DIGESTLEN; i < BLOCKLEN; i++ ) - { - if ( pp >= pend ) - pp = pool; - hashbuf[i] = *pp++; - } + { + memcpy (hashbuf, p, DIGESTLEN); + + p += DIGESTLEN; + if (p+DIGESTLEN+BLOCKLEN < pend) + memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + else + { + unsigned char *pp = p + DIGESTLEN; + + for (i=DIGESTLEN; i < BLOCKLEN; i++ ) + { + if ( pp >= pend ) + pp = pool; + hashbuf[i] = *pp++; + } + } + + _gcry_rmd160_mixblock ( &md, hashbuf); + memcpy(p, hashbuf, 20 ); } - - _gcry_rmd160_mixblock ( &md, hashbuf); - memcpy(p, hashbuf, 20 ); - } - - /* Our hash implementation does only leave small parts (64 bytes) - of the pool on the stack, so it is okay not to require secure - memory here. Before we use this pool, it will be copied to the - help buffer anyway. */ - if ( pool == rndpool) - { - _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE); - failsafe_digest_valid = 1; - } - - _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */ + + /* Our hash implementation does only leave small parts (64 bytes) + of the pool on the stack, so it is okay not to require secure + memory here. Before we use this pool, it will be copied to the + help buffer anyway. */ + if ( pool == rndpool) + { + _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE); + failsafe_digest_valid = 1; + } + + _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */ } @@ -670,7 +670,7 @@ void _gcry_rngcsprng_set_seed_file (const char *name) { if (seed_file_name) - BUG (); + BUG (); seed_file_name = gcry_xstrdup (name); } @@ -693,22 +693,22 @@ lock_seed_file (int fd, const char *fname, int for_write) lck.l_whence = SEEK_SET; while (fcntl (fd, F_SETLK, &lck) == -1) - { - if (errno != EAGAIN && errno != EACCES) - { - log_info (_("can't lock `%s': %s\n"), fname, strerror (errno)); - return -1; - } - - if (backoff > 2) /* Show the first message after ~2.25 seconds. */ - log_info( _("waiting for lock on `%s'...\n"), fname); - - tv.tv_sec = backoff; - tv.tv_usec = 250000; - select (0, NULL, NULL, NULL, &tv); - if (backoff < 10) - backoff++ ; - } + { + if (errno != EAGAIN && errno != EACCES) + { + log_info (_("can't lock `%s': %s\n"), fname, strerror (errno)); + return -1; + } + + if (backoff > 2) /* Show the first message after ~2.25 seconds. */ + log_info( _("waiting for lock on `%s'...\n"), fname); + + tv.tv_sec = backoff; + tv.tv_usec = 250000; + select (0, NULL, NULL, NULL, &tv); + if (backoff < 10) + backoff++ ; + } #endif /*LOCK_SEED_FILE*/ return 0; } @@ -740,7 +740,7 @@ read_seed_file (void) gcry_assert (pool_is_locked); if (!seed_file_name) - return 0; + return 0; #ifdef HAVE_DOSISH_SYSTEM fd = open( seed_file_name, O_RDONLY | O_BINARY ); @@ -748,75 +748,75 @@ read_seed_file (void) fd = open( seed_file_name, O_RDONLY ); #endif if( fd == -1 && errno == ENOENT) - { - allow_seed_file_update = 1; - return 0; - } + { + allow_seed_file_update = 1; + return 0; + } if (fd == -1 ) - { - log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) ); - return 0; - } + { + log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) ); + return 0; + } if (lock_seed_file (fd, seed_file_name, 0)) - { - close (fd); - return 0; - } + { + close (fd); + return 0; + } if (fstat( fd, &sb ) ) - { - log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) ); - close(fd); - return 0; - } + { + log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) ); + close(fd); + return 0; + } if (!S_ISREG(sb.st_mode) ) - { - log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name ); - close(fd); - return 0; - } + { + log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name ); + close(fd); + return 0; + } if (!sb.st_size ) - { - log_info(_("note: random_seed file is empty\n") ); - close(fd); - allow_seed_file_update = 1; - return 0; - } + { + log_info(_("note: random_seed file is empty\n") ); + close(fd); + allow_seed_file_update = 1; + return 0; + } if (sb.st_size != POOLSIZE ) - { - log_info(_("warning: invalid size of random_seed file - not used\n") ); - close(fd); - return 0; - } + { + log_info(_("warning: invalid size of random_seed file - not used\n") ); + close(fd); + return 0; + } do - { - n = read( fd, buffer, POOLSIZE ); - } + { + n = read( fd, buffer, POOLSIZE ); + } while (n == -1 && errno == EINTR ); if (n != POOLSIZE) - { - log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); - close(fd);/*NOTREACHED*/ - return 0; - } + { + log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); + close(fd);/*NOTREACHED*/ + return 0; + } close(fd); add_randomness( buffer, POOLSIZE, RANDOM_ORIGIN_INIT ); /* add some minor entropy to the pool now (this will also force a mixing) */ { - pid_t x = getpid(); - add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); + pid_t x = getpid(); + add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); } { - time_t x = time(NULL); - add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); + time_t x = time(NULL); + add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); } { - clock_t x = clock(); - add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); + clock_t x = clock(); + add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT ); } /* And read a few bytes from our entropy source. By using a level @@ -838,73 +838,73 @@ _gcry_rngcsprng_update_seed_file (void) int fd, i; /* We do only a basic initialization so that we can lock the pool. - This is required to cope with the case that this function is - called by some cleanup code at a point where the RNG has never - been initialized. */ + This is required to cope with the case that this function is + called by some cleanup code at a point where the RNG has never + been initialized. */ initialize_basics (); lock_pool (); if ( !seed_file_name || !rndpool || !pool_filled ) - { - unlock_pool (); - return; - } + { + unlock_pool (); + return; + } if ( !allow_seed_file_update ) - { - unlock_pool (); - log_info(_("note: random_seed file not updated\n")); - return; - } + { + unlock_pool (); + log_info(_("note: random_seed file not updated\n")); + return; + } /* At this point we know that there is something in the pool and - thus we can conclude that the pool has been fully initialized. */ + thus we can conclude that the pool has been fully initialized. */ /* Copy the entropy pool to a scratch pool and mix both of them. */ for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; - i < POOLWORDS; i++, dp++, sp++ ) - { - *dp = *sp + ADD_VALUE; - } + i < POOLWORDS; i++, dp++, sp++ ) + { + *dp = *sp + ADD_VALUE; + } mix_pool(rndpool); rndstats.mixrnd++; mix_pool(keypool); rndstats.mixkey++; #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, - S_IRUSR|S_IWUSR ); + S_IRUSR|S_IWUSR ); #else # if LOCK_SEED_FILE - fd = open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR ); + fd = open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR ); # else - fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); + fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); # endif #endif if (fd == -1 ) - log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) ); + log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) ); else if (lock_seed_file (fd, seed_file_name, 1)) - { - close (fd); - } + { + close (fd); + } #if LOCK_SEED_FILE else if (ftruncate (fd, 0)) - { - log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno)); - close (fd); - } + { + log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno)); + close (fd); + } #endif /*LOCK_SEED_FILE*/ else - { - do - { - i = write (fd, keypool, POOLSIZE ); - } - while (i == -1 && errno == EINTR); - if (i != POOLSIZE) - log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno)); - if (close(fd)) - log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno)); - } + { + do + { + i = write (fd, keypool, POOLSIZE ); + } + while (i == -1 && errno == EINTR); + if (i != POOLSIZE) + log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno)); + if (close(fd)) + log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno)); + } unlock_pool (); } @@ -921,10 +921,10 @@ read_pool (byte *buffer, size_t length, int level) int i; unsigned long *sp, *dp; /* The volatile is there to make sure the compiler does not optimize - the code away in case the getpid function is badly attributed. - Note that we keep a pid in a static variable as well as in a - stack based one; the latter is to detect ill behaving thread - libraries, ignoring the pool mutexes. */ + the code away in case the getpid function is badly attributed. + Note that we keep a pid in a static variable as well as in a + stack based one; the latter is to detect ill behaving thread + libraries, ignoring the pool mutexes. */ static volatile pid_t my_pid = (pid_t)(-1); volatile pid_t my_pid2; @@ -934,127 +934,127 @@ read_pool (byte *buffer, size_t length, int level) /* Get our own pid, so that we can detect a fork. */ my_pid2 = getpid (); if (my_pid == (pid_t)(-1)) - my_pid = my_pid2; + my_pid = my_pid2; if ( my_pid != my_pid2 ) - { - /* We detected a plain fork; i.e. we are now the child. Update - the static pid and add some randomness. */ - pid_t x; - - my_pid = my_pid2; - x = my_pid; - add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT); - just_mixed = 0; /* Make sure it will get mixed. */ - } + { + /* We detected a plain fork; i.e. we are now the child. Update + the static pid and add some randomness. */ + pid_t x; + + my_pid = my_pid2; + x = my_pid; + add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT); + just_mixed = 0; /* Make sure it will get mixed. */ + } gcry_assert (pool_is_locked); /* Our code does not allow to extract more than POOLSIZE. Better - check it here. */ + check it here. */ if (length > POOLSIZE) - { - log_bug("too many random bits requested\n"); - } + { + log_bug("too many random bits requested\n"); + } if (!pool_filled) - { - if (read_seed_file() ) - pool_filled = 1; - } + { + if (read_seed_file() ) + pool_filled = 1; + } /* For level 2 quality (key generation) we always make sure that the - pool has been seeded enough initially. */ + pool has been seeded enough initially. */ if (level == GCRY_VERY_STRONG_RANDOM && !did_initial_extra_seeding) - { - size_t needed; - - pool_balance = 0; - needed = length - pool_balance; - if (needed < POOLSIZE/2) - needed = POOLSIZE/2; - else if( needed > POOLSIZE ) - BUG (); - read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed, - GCRY_VERY_STRONG_RANDOM); - pool_balance += needed; - did_initial_extra_seeding = 1; - } + { + size_t needed; + + pool_balance = 0; + needed = length - pool_balance; + if (needed < POOLSIZE/2) + needed = POOLSIZE/2; + else if( needed > POOLSIZE ) + BUG (); + read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed, + GCRY_VERY_STRONG_RANDOM); + pool_balance += needed; + did_initial_extra_seeding = 1; + } /* For level 2 make sure that there is enough random in the pool. */ if (level == GCRY_VERY_STRONG_RANDOM && pool_balance < length) - { - size_t needed; - - if (pool_balance < 0) - pool_balance = 0; - needed = length - pool_balance; - if (needed > POOLSIZE) - BUG (); - read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed, - GCRY_VERY_STRONG_RANDOM); - pool_balance += needed; - } + { + size_t needed; + + if (pool_balance < 0) + pool_balance = 0; + needed = length - pool_balance; + if (needed > POOLSIZE) + BUG (); + read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed, + GCRY_VERY_STRONG_RANDOM); + pool_balance += needed; + } /* Make sure the pool is filled. */ while (!pool_filled) - random_poll(); + random_poll(); /* Always do a fast random poll (we have to use the unlocked version). */ do_fast_random_poll(); /* Mix the pid in so that we for sure won't deliver the same random - after a fork. */ + after a fork. */ { - pid_t apid = my_pid; - add_randomness (&apid, sizeof (apid), RANDOM_ORIGIN_INIT); + pid_t apid = my_pid; + add_randomness (&apid, sizeof (apid), RANDOM_ORIGIN_INIT); } /* Mix the pool (if add_randomness() didn't it). */ if (!just_mixed) - { - mix_pool(rndpool); - rndstats.mixrnd++; - } + { + mix_pool(rndpool); + rndstats.mixrnd++; + } /* Create a new pool. */ for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; - i < POOLWORDS; i++, dp++, sp++ ) - *dp = *sp + ADD_VALUE; + i < POOLWORDS; i++, dp++, sp++ ) + *dp = *sp + ADD_VALUE; /* Mix both pools. */ mix_pool(rndpool); rndstats.mixrnd++; mix_pool(keypool); rndstats.mixkey++; /* Read the requested data. We use a read pointer to read from a - different position each time. */ + different position each time. */ while (length--) - { - *buffer++ = keypool[pool_readpos++]; - if (pool_readpos >= POOLSIZE) - pool_readpos = 0; - pool_balance--; - } + { + *buffer++ = keypool[pool_readpos++]; + if (pool_readpos >= POOLSIZE) + pool_readpos = 0; + pool_balance--; + } if (pool_balance < 0) - pool_balance = 0; + pool_balance = 0; /* Clear the keypool. */ memset (keypool, 0, POOLSIZE); /* We need to detect whether a fork has happened. A fork might have - an identical pool and thus the child and the parent could emit - the very same random number. This test here is to detect forks - in a multi-threaded process. It does not work with all thread - implementations in particular not with pthreads. However it is - good enough for GNU Pth. */ + an identical pool and thus the child and the parent could emit + the very same random number. This test here is to detect forks + in a multi-threaded process. It does not work with all thread + implementations in particular not with pthreads. However it is + good enough for GNU Pth. */ if ( getpid () != my_pid2 ) - { - pid_t x = getpid(); - add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT); - just_mixed = 0; /* Make sure it will get mixed. */ - my_pid = x; /* Also update the static pid. */ - goto retry; - } + { + pid_t x = getpid(); + add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT); + just_mixed = 0; /* Make sure it will get mixed. */ + my_pid = x; /* Also update the static pid. */ + goto retry; + } } @@ -1073,28 +1073,28 @@ add_randomness (const void *buffer, size_t length, enum random_origins origin) rndstats.addbytes += length; rndstats.naddbytes++; while (length-- ) - { - rndpool[pool_writepos++] ^= *p++; - count++; - if (pool_writepos >= POOLSIZE ) - { - /* It is possible that we are invoked before the pool is - filled using an unreliable origin of entropy, for example - the fast random poll. To avoid flagging the pool as - filled in this case, we track the initial filling state - separately. See also the remarks about the seed file. */ - if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled) - { - pool_filled_counter += count; - count = 0; - if (pool_filled_counter >= POOLSIZE) - pool_filled = 1; - } - pool_writepos = 0; - mix_pool(rndpool); rndstats.mixrnd++; - just_mixed = !length; + { + rndpool[pool_writepos++] ^= *p++; + count++; + if (pool_writepos >= POOLSIZE ) + { + /* It is possible that we are invoked before the pool is + filled using an unreliable origin of entropy, for example + the fast random poll. To avoid flagging the pool as + filled in this case, we track the initial filling state + separately. See also the remarks about the seed file. */ + if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled) + { + pool_filled_counter += count; + count = 0; + if (pool_filled_counter >= POOLSIZE) + pool_filled = 1; + } + pool_writepos = 0; + mix_pool(rndpool); rndstats.mixrnd++; + just_mixed = !length; + } } - } } @@ -1110,27 +1110,27 @@ random_poll() /* Runtime determination of the slow entropy gathering module. */ static int (* getfnc_gather_random (void))(void (*)(const void*, size_t, - enum random_origins), - enum random_origins, size_t, int) + enum random_origins), + enum random_origins, size_t, int) { int (*fnc)(void (*)(const void*, size_t, enum random_origins), - enum random_origins, size_t, int); + enum random_origins, size_t, int); #if USE_RNDLINUX if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { - fnc = _gcry_rndlinux_gather_random; - return fnc; - } + && !access (NAME_OF_DEV_URANDOM, R_OK)) + { + fnc = _gcry_rndlinux_gather_random; + return fnc; + } #endif #if USE_RNDEGD if ( _gcry_rndegd_connect_socket (1) != -1 ) - { - fnc = _gcry_rndegd_gather_random; - return fnc; - } + { + fnc = _gcry_rndegd_gather_random; + return fnc; + } #endif #if USE_RNDUNIX @@ -1152,8 +1152,8 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, (Currently a compile time method is used.) */ static void (* getfnc_fast_random_poll (void))( void (*)(const void*, size_t, - enum random_origins), - enum random_origins) + enum random_origins), + enum random_origins) { #if USE_RNDW32 return _gcry_rndw32_gather_random_fast; @@ -1171,27 +1171,27 @@ do_fast_random_poll (void) rndstats.fastpolls++; if (fast_gather_fnc) - fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL); + fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL); /* Continue with the generic functions. */ #if HAVE_GETHRTIME { - hrtime_t tv; - tv = gethrtime(); - add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL ); + hrtime_t tv; + tv = gethrtime(); + add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL ); } #elif HAVE_GETTIMEOFDAY { - struct timeval tv; - if( gettimeofday( &tv, NULL ) ) - BUG(); - add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL ); - add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), RANDOM_ORIGIN_FASTPOLL ); + struct timeval tv; + if( gettimeofday( &tv, NULL ) ) + BUG(); + add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL ); + add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), RANDOM_ORIGIN_FASTPOLL ); } #elif HAVE_CLOCK_GETTIME { struct timespec tv; if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) - BUG(); + BUG(); add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL ); add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), RANDOM_ORIGIN_FASTPOLL ); } @@ -1207,14 +1207,14 @@ do_fast_random_poll (void) #ifdef HAVE_GETRUSAGE # ifdef RUSAGE_SELF { - struct rusage buf; - /* QNX/Neutrino does return ENOSYS - so we just ignore it and add - whatever is in buf. In a chroot environment it might not work - at all (i.e. because /proc/ is not accessible), so we better - ignore all error codes and hope for the best. */ - getrusage (RUSAGE_SELF, &buf ); - add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL ); - memset( &buf, 0, sizeof buf ); + struct rusage buf; + /* QNX/Neutrino does return ENOSYS - so we just ignore it and add + whatever is in buf. In a chroot environment it might not work + at all (i.e. because /proc/ is not accessible), so we better + ignore all error codes and hope for the best. */ + getrusage (RUSAGE_SELF, &buf ); + add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL ); + memset( &buf, 0, sizeof buf ); } # else /*!RUSAGE_SELF*/ # ifdef __GCC__ @@ -1224,18 +1224,18 @@ do_fast_random_poll (void) #endif /*HAVE_GETRUSAGE*/ /* Time and clock are availabe on all systems - so we better do it - just in case one of the above functions didn't work. */ + just in case one of the above functions didn't work. */ { - time_t x = time(NULL); - add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL ); + time_t x = time(NULL); + add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL ); } { - clock_t x = clock(); - add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL ); + clock_t x = clock(); + add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL ); } /* If the system features a fast hardware RNG, read some bytes from - there. */ + there. */ _gcry_rndhw_poll_fast (add_randomness, RANDOM_ORIGIN_FASTPOLL); } @@ -1254,10 +1254,10 @@ _gcry_rngcsprng_fast_poll (void) lock_pool (); if (rndpool) - { - /* Yes, we are fully initialized. */ - do_fast_random_poll (); - } + { + /* Yes, we are fully initialized. */ + do_fast_random_poll (); + } unlock_pool (); } @@ -1267,16 +1267,16 @@ static void read_random_source (enum random_origins orgin, size_t length, int level ) { if ( !slow_gather_fnc ) - log_fatal ("Slow entropy gathering module not yet initialized\n"); + log_fatal ("Slow entropy gathering module not yet initialized\n"); if ( slow_gather_fnc (add_randomness, orgin, length, level) < 0) - log_fatal ("No way to gather entropy for the RNG\n"); + log_fatal ("No way to gather entropy for the RNG\n"); } static int gather_faked (void (*add)(const void*, size_t, enum random_origins), - enum random_origins origin, size_t length, int level ) + enum random_origins origin, size_t length, int level ) { static int initialized=0; size_t n; @@ -1286,24 +1286,24 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins), (void)level; if ( !initialized ) - { - log_info(_("WARNING: using insecure random number generator!!\n")); - initialized=1; + { + log_info(_("WARNING: using insecure random number generator!!\n")); + initialized=1; #ifdef HAVE_RAND - srand( time(NULL)*getpid()); + srand( time(NULL)*getpid()); #else - srandom( time(NULL)*getpid()); + srandom( time(NULL)*getpid()); #endif - } + } p = buffer = gcry_xmalloc( length ); n = length; #ifdef HAVE_RAND while ( n-- ) - *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); + *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); #else while ( n-- ) - *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); + *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); #endif add_randomness ( buffer, length, origin ); gcry_free (buffer); @@ -1318,9 +1318,9 @@ _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. */ + 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; @@ -1331,67 +1331,67 @@ _gcry_rngcsprng_create_nonce (void *buffer, size_t length) #ifdef USE_RANDOM_DAEMON if (allow_daemon - && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length)) - return; /* The daemon succeeded. */ + && !_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)); + log_fatal ("failed to acquire the nonce buffer lock: %s\n", + strerror (err)); apid = getpid (); /* The first time intialize our buffer. */ if (!nonce_buffer_initialized) - { - time_t atime = time (NULL); - pid_t xpid = apid; + { + time_t atime = time (NULL); + pid_t xpid = apid; - my_pid = apid; + my_pid = apid; - if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) - BUG (); + 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 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); + /* Initialize the never changing private part of 64 bits. */ + gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); - nonce_buffer_initialized = 1; - } + 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; - } + { + /* 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. */ + 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); - } + { + _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)); + log_fatal ("failed to release the nonce buffer lock: %s\n", + strerror (err)); } |