diff options
author | Werner Koch <[email protected]> | 1998-12-14 20:22:42 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1998-12-14 20:22:42 +0000 |
commit | 7a7a5630aff7f539fd68de6c34d82a0fa240cc8c (patch) | |
tree | c0b8587dd3ef4e434ae03b043a52ad8ec645bc3f /cipher | |
parent | See ChangeLog: Sun Dec 13 14:10:56 CET 1998 Werner Koch (diff) | |
download | gnupg-7a7a5630aff7f539fd68de6c34d82a0fa240cc8c.tar.gz gnupg-7a7a5630aff7f539fd68de6c34d82a0fa240cc8c.zip |
See ChangeLog: Mon Dec 14 21:18:49 CET 1998 Werner Koch
Diffstat (limited to 'cipher')
-rw-r--r-- | cipher/ChangeLog | 10 | ||||
-rw-r--r-- | cipher/dynload.c | 10 | ||||
-rw-r--r-- | cipher/dynload.h | 5 | ||||
-rw-r--r-- | cipher/random.c | 60 | ||||
-rw-r--r-- | cipher/rndlinux.c | 27 | ||||
-rw-r--r-- | cipher/rndunix.c | 64 |
6 files changed, 98 insertions, 78 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 2874426f7..08d27bce6 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,13 @@ +Mon Dec 14 21:18:49 CET 1998 Werner Koch <[email protected]> + + * random.c (read_random_source): Changed the interface to the + random gathering function. + (gather_faked): Use new interface. + * dynload.c (dynload_getfnc_fast_random_poll): Ditto. + (dynload_getfnc_gather_random): Ditto. + * rndlinux.c (gather_random): Ditto. + * rndunix.c (gather_random): Ditto. + Sat Dec 12 18:40:32 CET 1998 Werner Koch <[email protected]> * dynload.c (SYMBOL_VERSION): New to cope with system which needs diff --git a/cipher/dynload.c b/cipher/dynload.c index 563f791f2..abef2da52 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -506,7 +506,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo, int (* -dynload_getfnc_gather_random())(byte*, size_t*, int) +dynload_getfnc_gather_random())(void (*)(const void*, size_t, int), int, + size_t, int) { EXTLIST r; void *sym; @@ -522,7 +523,8 @@ dynload_getfnc_gather_random())(byte*, size_t*, int) while( (sym = (*r->enumfunc)(40, &seq, &class, &vers)) ) { if( vers != 1 || class != 40 ) continue; - return (int (*)(byte*, size_t*, int))sym; + return (int (*)(void (*)(const void*, size_t, int), int, + size_t, int))sym; } } return NULL; @@ -530,7 +532,7 @@ dynload_getfnc_gather_random())(byte*, size_t*, int) void (* -dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int)) +dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int), int) { EXTLIST r; void *sym; @@ -546,7 +548,7 @@ dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int)) while( (sym = (*r->enumfunc)(41, &seq, &class, &vers)) ) { if( vers != 1 || class != 41 ) continue; - return (void (*)( void (*)(const void*, size_t, int)))sym; + return (void (*)( void (*)(const void*, size_t, int), int))sym; } } return NULL; diff --git a/cipher/dynload.h b/cipher/dynload.h index 5e88dc732..d107b5a0a 100644 --- a/cipher/dynload.h +++ b/cipher/dynload.h @@ -54,9 +54,10 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo, unsigned (**get_nbits)( int algo, MPI *pkey ) ); -int (*dynload_getfnc_gather_random(void))(byte*, size_t*, int); +int (*dynload_getfnc_gather_random(void))( void (*)(const void*, size_t, int), + int, size_t, int); void (*dynload_getfnc_fast_random_poll(void) - )( void (*)(const void*, size_t, int)); + )( void (*)(const void*, size_t, int), int ); #endif /*G10_CIPHER_DYNLOAD_H*/ diff --git a/cipher/random.c b/cipher/random.c index 699f76994..c49cc6e08 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -94,8 +94,9 @@ static int faked_rng; static void read_pool( byte *buffer, size_t length, int level ); static void add_randomness( const void *buffer, size_t length, int source ); static void random_poll(void); -static void read_random_source( byte *buffer, size_t length, int level ); -static int gather_faked( byte *buffer, size_t *r_length, int level ); +static void read_random_source( int requester, size_t length, int level); +static int gather_faked( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ); static void @@ -137,7 +138,7 @@ quick_random_gen( int onoff ) { int last; - read_random_source( NULL, 0, 0 ); /* load module */ + read_random_source(0,0,0); /* init */ last = quick_test; if( onoff != -1 ) quick_test = onoff; @@ -236,17 +237,13 @@ read_pool( byte *buffer, size_t length, int level ) /* for level 2 make sure that there is enough random in the pool */ if( level == 2 && pool_balance < length ) { size_t needed; - byte *p; if( pool_balance < 0 ) pool_balance = 0; needed = length - pool_balance; if( needed > POOLSIZE ) BUG(); - p = secure_alloc ? m_alloc_secure( needed ) : m_alloc(needed); - read_random_source( p, needed, 2 ); /* read /dev/random */ - add_randomness( p, needed, 3); - m_free(p); + read_random_source( 3, needed, 2 ); pool_balance += needed; } @@ -321,17 +318,14 @@ add_randomness( const void *buffer, size_t length, int source ) static void random_poll() { - char buf[POOLSIZE/5]; - read_random_source( buf, POOLSIZE/5, 1 ); - add_randomness( buf, POOLSIZE/5, 2); - memset( buf, 0, POOLSIZE/5); + read_random_source( 2, POOLSIZE/5, 1 ); } void fast_random_poll() { - static void (*fnc)( void (*)(const void*, size_t, int)) = NULL; + static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; static int initialized = 0; if( !initialized ) { @@ -341,7 +335,7 @@ fast_random_poll() fnc = dynload_getfnc_fast_random_poll(); } if( fnc ) { - (*fnc)( add_randomness ); + (*fnc)( add_randomness, 1 ); return; } @@ -377,9 +371,10 @@ fast_random_poll() static void -read_random_source( byte *buffer, size_t length, int level ) +read_random_source( int requester, size_t length, int level ) { - static int (*fnc)(byte*, size_t*, int) = NULL; + static int (*fnc)(void (*)(const void*, size_t, int), int, + size_t, int) = NULL; int nbytes; int goodness; @@ -391,24 +386,21 @@ read_random_source( byte *buffer, size_t length, int level ) faked_rng = 1; fnc = gather_faked; } + if( !requester && !length && !level ) + return; /* init only */ } - while( length ) { - nbytes = length; - goodness = (*fnc)( buffer, &nbytes, level ); - if( goodness < 0 ) - log_fatal("No way to gather entropy for the RNG\n"); - buffer +=nbytes; - length -= nbytes; - /* FIXME: how can we handle the goodness */ - } + if( (*fnc)( add_randomness, requester, length, level ) < 0 ) + log_fatal("No way to gather entropy for the RNG\n"); } static int -gather_faked( byte *buffer, size_t *r_length, int level ) +gather_faked( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static int initialized=0; - size_t length = *r_length; + size_t n; + char *buffer, *p; if( !initialized ) { log_info(_("WARNING: using insecure random number generator!!\n")); @@ -423,13 +415,17 @@ gather_faked( byte *buffer, size_t *r_length, int level ) #endif } + p = buffer = m_alloc( length ); + n = length; #ifdef HAVE_RAND - while( length-- ) - *buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); + while( n-- ) + *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); #else - while( length-- ) - *buffer++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); + while( n-- ) + *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); #endif - return 100; /* We really fake it ;-) */ + add_randomness( buffer, length, requester ); + m_free(buffer); + return 0; /* okay */ } diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c index b9376e8fe..66bb34e62 100644 --- a/cipher/rndlinux.c +++ b/cipher/rndlinux.c @@ -45,7 +45,8 @@ #endif static int open_device( const char *name, int minor ); -static int gather_random( byte *buffer, size_t *r_length, int level ); +static int gather_random( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ); #ifdef IS_MODULE static void tty_printf(const char *fmt, ... ) @@ -81,15 +82,15 @@ open_device( const char *name, int minor ) static int -gather_random( byte *buffer, size_t *r_length, int level ) +gather_random( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static int fd_urandom = -1; static int fd_random = -1; int fd; int n; int warn=0; - size_t length = *r_length; - /* note: we will always return the requested length */ + byte buffer[768]; if( level >= 2 ) { if( fd_random == -1 ) @@ -101,7 +102,8 @@ gather_random( byte *buffer, size_t *r_length, int level ) fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 ); fd = fd_urandom; } - do { + + while( length ) { fd_set rfds; struct timeval tv; int rc; @@ -125,20 +127,21 @@ gather_random( byte *buffer, size_t *r_length, int level ) } do { - n = read(fd, buffer, length ); - if( n >= 0 && n > length ) { + int nbytes = length < sizeof(buffer)? length : sizeof(buffer); + n = read(fd, buffer, nbytes ); + if( n >= 0 && n > nbytes ) { g10_log_error("bogus read from random device (n=%d)\n", n ); - n = length; + n = nbytes; } } while( n == -1 && errno == EINTR ); if( n == -1 ) g10_log_fatal("read error on random device: %s\n", strerror(errno)); - assert( n <= length ); - buffer += n; + (*add)( buffer, n, requester ); length -= n; - } while( length ); + } + memset(buffer, 0, sizeof(buffer) ); - return 100; /* always 100% useful at the requested level */ + return 0; /* success */ } diff --git a/cipher/rndunix.c b/cipher/rndunix.c index 92e735689..a4d3bdb56 100644 --- a/cipher/rndunix.c +++ b/cipher/rndunix.c @@ -669,13 +669,13 @@ read_a_msg( int fd, GATHER_MSG *msg ) static int -gather_random( char *buffer, size_t *r_length, int level ) +gather_random( void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static pid_t gatherer_pid = 0; static int pipedes[2]; GATHER_MSG msg; size_t n; - size_t length = *r_length; if( !gatherer_pid ) { /* time to start the gatherer process */ @@ -696,37 +696,45 @@ gather_random( char *buffer, size_t *r_length, int level ) } /* now read from the gatherer */ - if( read_a_msg( pipedes[0], &msg ) ) { - g10_log_error("reading from gatherer pipe failed: %s\n", - strerror(errno)); - return -1; - } + while( length ) { + int goodness; - n = msg.ndata; - if( n > length ) - n = length; - memcpy( buffer, msg.data, n ); + if( read_a_msg( pipedes[0], &msg ) ) { + g10_log_error("reading from gatherer pipe failed: %s\n", + strerror(errno)); + return -1; + } - *r_length = n; - if( level > 1 ) { - if( msg.usefulness > 30 ) - return 100; - else if ( msg.usefulness ) - return msg.usefulness * 100 / 30; - else - return 0; - } - else if( level ) { - if( msg.usefulness > 15 ) - return 100; - else if ( msg.usefulness ) - return msg.usefulness * 100 / 15; + if( level > 1 ) { + if( msg.usefulness > 30 ) + goodness = 100; + else if ( msg.usefulness ) + goodness = msg.usefulness * 100 / 30; + else + goodness = 0; + } + else if( level ) { + if( msg.usefulness > 15 ) + goodness = 100; + else if ( msg.usefulness ) + goodness = msg.usefulness * 100 / 15; + else + goodness = 0; + } else - return 0; + goodness = 100; /* goodness of level 0 is always 100 % */ + + n = msg.ndata; + if( n > length ) + n = length; + (*add)( msg.data, n, requester ); + + /* this is the trick how e cope with the goodness */ + length -= (ulong)n * goodness / 100; } - else - return 100; /* goodness of level 0 is always 100 % */ + + return 0; } |