mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
See ChangeLog: Fri Feb 11 17:44:40 CET 2000 Werner Koch
This commit is contained in:
parent
3fc9846d2f
commit
1d0f589754
13 changed files with 772 additions and 674 deletions
165
cipher/random.c
165
cipher/random.c
|
@ -36,6 +36,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_GETHRTIME
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
|
@ -91,6 +92,9 @@ static size_t pool_writepos;
|
|||
static int pool_filled;
|
||||
static int pool_balance;
|
||||
static int just_mixed;
|
||||
static int did_initial_extra_seeding;
|
||||
static char *seed_file_name;
|
||||
static int allow_seed_file_update;
|
||||
|
||||
static int secure_alloc;
|
||||
static int quick_test;
|
||||
|
@ -264,6 +268,131 @@ mix_pool(byte *pool)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
set_random_seed_file( const char *name )
|
||||
{
|
||||
if( seed_file_name )
|
||||
BUG();
|
||||
seed_file_name = m_strdup( name );
|
||||
}
|
||||
|
||||
/****************
|
||||
* Read in a seed form the random_seed file
|
||||
* and return true if this was successful
|
||||
*/
|
||||
static int
|
||||
read_seed_file()
|
||||
{
|
||||
int fd;
|
||||
struct stat sb;
|
||||
unsigned char buffer[POOLSIZE];
|
||||
int n;
|
||||
|
||||
if( !seed_file_name )
|
||||
return 0;
|
||||
|
||||
fd = open( seed_file_name, O_RDONLY );
|
||||
if( fd == -1 && errno == ENOENT) {
|
||||
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;
|
||||
}
|
||||
if( fstat( fd, &sb ) ) {
|
||||
log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if( !S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode) ) {
|
||||
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;
|
||||
}
|
||||
if( sb.st_size != POOLSIZE ) {
|
||||
log_info(_("warning: invalid size of random_seed file - not used\n") );
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
add_randomness( buffer, POOLSIZE, 0 );
|
||||
/* add some minor entropy to the pool now (this will also force a mixing) */
|
||||
{ pid_t x = getpid();
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
{ time_t x = time(NULL);
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
{ clock_t x = clock();
|
||||
add_randomness( &x, sizeof(x), 0 );
|
||||
}
|
||||
/* And read a few bytes from our entropy source. By using
|
||||
* a level of 0 this will not block and might not return anything
|
||||
* with some entropy drivers, however the rndlinux driver will use
|
||||
* /dev/urandom and return some stuff - Do not read to much as we
|
||||
* want to be friendly to the scare system entropy resource. */
|
||||
read_random_source( 0, 16, 0 );
|
||||
|
||||
allow_seed_file_update = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
update_random_seed_file()
|
||||
{
|
||||
ulong *sp, *dp;
|
||||
int fd, i;
|
||||
|
||||
if( !seed_file_name || !is_initialized )
|
||||
return;
|
||||
if( !allow_seed_file_update ) {
|
||||
log_info(_("note: random_seed file not updated\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* copy the entropy pool to a scratch pool and mix both of them */
|
||||
for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
|
||||
i < POOLWORDS; i++, dp++, sp++ ) {
|
||||
*dp = *sp + ADD_VALUE;
|
||||
}
|
||||
mix_pool(rndpool); rndstats.mixrnd++;
|
||||
mix_pool(keypool); rndstats.mixkey++;
|
||||
|
||||
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
|
||||
if( fd == -1 ) {
|
||||
log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
|
||||
return;
|
||||
}
|
||||
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) );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_pool( byte *buffer, size_t length, int level )
|
||||
{
|
||||
|
@ -275,6 +404,27 @@ read_pool( byte *buffer, size_t length, int level )
|
|||
POOLSIZE*8-1 );
|
||||
}
|
||||
|
||||
if( !pool_filled ) {
|
||||
if( read_seed_file() )
|
||||
pool_filled = 1;
|
||||
}
|
||||
|
||||
/* For level 2 quality (key generation) we alwas make
|
||||
* sure that the pool has been seeded enough initially */
|
||||
if( level == 2 && !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( 3, needed, 2 );
|
||||
pool_balance += needed;
|
||||
did_initial_extra_seeding=1;
|
||||
}
|
||||
|
||||
/* for level 2 make sure that there is enough random in the pool */
|
||||
if( level == 2 && pool_balance < length ) {
|
||||
size_t needed;
|
||||
|
@ -338,6 +488,12 @@ read_pool( byte *buffer, size_t length, int level )
|
|||
/****************
|
||||
* Add LENGTH bytes of randomness from buffer to the pool.
|
||||
* source may be used to specify the randomness source.
|
||||
* Source is:
|
||||
* 0 - used ony for initialization
|
||||
* 1 - fast random poll function
|
||||
* 2 - normal poll function
|
||||
* 3 - used when level 2 random quality has been requested
|
||||
* to do an extra pool seed.
|
||||
*/
|
||||
static void
|
||||
add_randomness( const void *buffer, size_t length, int source )
|
||||
|
@ -423,6 +579,15 @@ fast_random_poll()
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
/* time and clock are availabe on all systems - so
|
||||
* we better do it just in case one of the above functions
|
||||
* didn't work */
|
||||
{ time_t x = time(NULL);
|
||||
add_randomness( &x, sizeof(x), 1 );
|
||||
}
|
||||
{ clock_t x = clock();
|
||||
add_randomness( &x, sizeof(x), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue