/**************** * Return a pointer to a randomized buffer of level 0 and LENGTH bits * caller must free the buffer. * Note: The returned value is rounded up to bytes. */ byte * get_random_bits( size_t nbits, int level, int secure ) { byte *buf, *p; size_t nbytes = (nbits+7)/8; if( quick_test && level > 1 ) level = 1; MASK_LEVEL(level); if( level == 1 ) { rndstats.getbytes1 += nbytes; rndstats.ngetbytes1++; } else if( level >= 2 ) { rndstats.getbytes2 += nbytes; rndstats.ngetbytes2++; } buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes ); for( p = buf; nbytes > 0; ) { size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes; read_pool( p, n, level ); nbytes -= n; p += n; } return buf; }
/* * Return a pointer to a randomized buffer of LEVEL and NBYTES length. * Caller must free the buffer. */ static byte * get_random_bytes ( size_t nbytes, int level, int secure) { byte *buf, *p; int err; /* First a hack toavoid the strong random using our regression test suite. */ if (quick_test && level > 1) level = 1; /* Make sure the requested level is in range. */ MASK_LEVEL(level); /* Lock the pool. */ err = ath_mutex_lock (&pool_lock); if (err) log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); pool_is_locked = 1; /* Keep some statistics. */ if (level >= 2) { rndstats.getbytes2 += nbytes; rndstats.ngetbytes2++; } else { rndstats.getbytes1 += nbytes; rndstats.ngetbytes1++; } /* Allocate the return buffer. */ buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes ) : gcry_xmalloc( nbytes ); /* Fill that buffer with random. */ for (p = buf; nbytes > 0; ) { size_t n; n = nbytes > POOLSIZE? POOLSIZE : nbytes; read_pool( p, n, level ); nbytes -= n; p += n; } /* 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)); /* Return the buffer. */ return buf; }
/* Public function to fill the buffer with LENGTH bytes of cryptographically strong random bytes. level 0 is not very strong, 1 is strong enough for most usage, 2 is good for key generation stuff but may be very slow. */ void gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) { byte *p; int err; /* Make sure we are initialized. */ if (!is_initialized) initialize (); /* Handle our hack used for regression tests of Libgcrypt. */ if( quick_test && level > 1 ) level = 1; /* Make sure the level is okay. */ MASK_LEVEL(level); /* 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; /* Update the statistics. */ if (level >= 2) { rndstats.getbytes2 += length; rndstats.ngetbytes2++; } else { rndstats.getbytes1 += length; rndstats.ngetbytes1++; } /* Read the random into the provided buffer. */ for (p = buffer; length > 0;) { size_t n; n = length > POOLSIZE? POOLSIZE : length; read_pool (p, n, level); length -= n; p += n; } /* 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)); }
int initpool(void) { field_view *v; for (v = views_pool; v->name != NULL; v++) add_view(v); read_pool(); 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 usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but may be very slow. */ void _gcry_rngcsprng_randomize (void *buffer, size_t length, enum gcry_random_level level) { unsigned char *p; /* Make sure we are initialized. */ initialize (); /* Handle our hack used for regression tests of Libgcrypt. */ if ( quick_test && 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. */ allow_daemon = 0; /* Daemon failed - switch off. */ #endif /*USE_RANDOM_DAEMON*/ /* Acquire the pool lock. */ lock_pool (); /* Update the statistics. */ if (level >= GCRY_VERY_STRONG_RANDOM) { rndstats.getbytes2 += length; rndstats.ngetbytes2++; } else { rndstats.getbytes1 += length; rndstats.ngetbytes1++; } /* Read the random into the provided buffer. */ for (p = buffer; length > 0;) { size_t n; n = length > POOLSIZE? POOLSIZE : length; read_pool (p, n, level); length -= n; p += n; } /* Release the pool lock. */ unlock_pool (); }