1
0
Fork 0
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:
Werner Koch 2000-02-11 16:48:22 +00:00
parent 3fc9846d2f
commit 1d0f589754
13 changed files with 772 additions and 674 deletions

View file

@ -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 );
}
}