diff options
-rw-r--r-- | THANKS | 7 | ||||
-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 |
7 files changed, 103 insertions, 80 deletions
@@ -35,6 +35,7 @@ James Troup james@nocrew.org Jean-loup Gailly gzip@prep.ai.mit.edu Jens Bachem bachem@rrz.uni-koeln.de John A. Martin jam@jamux.com +Johnny Teveßen j.tevessen@gmx.de Jörg Schilling schilling@fokus.gmd.de Jun Kuriyama kuriyama@sky.rim.or.jp Karl Fogel kfogel@guanabana.onshore.com @@ -66,6 +67,7 @@ SL Baur steve@xemacs.org Stefan Karrmann S.Karrmann@gmx.net Steffen Ullrich ccrlphr@xensei.com Steffen Zahn zahn@berlin.snafu.de +Susanne Schultz schultz@hsp.de Thiago Jung Bauermann jungmann@usa.net Thomas Roessler roessler@guug.de Tom Spindler dogcow@home.merit.edu @@ -79,8 +81,9 @@ Werner Koch werner.koch@guug.de Wim Vandeputte bunbun@reptile.rug.ac.be nbecker@hns.com -Thanks to the German Unix User Group for providing FTP space and -Martin Hamilton for hosting the mailing list. +Thanks to the German Unix User Group for providing FTP space, +Martin Hamilton for hosting the mailing list and hsp for +hosting gnupg.org. Many thanks to my wife Gerlinde for having so much patience with me while hacking late in the evening. diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 2874426f..08d27bce 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,13 @@ +Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de> + + * 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 <wk@isil.d.shuttle.de> * dynload.c (SYMBOL_VERSION): New to cope with system which needs diff --git a/cipher/dynload.c b/cipher/dynload.c index 563f791f..abef2da5 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 5e88dc73..d107b5a0 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 699f7699..c49cc6e0 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 b9376e8f..66bb34e6 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 92e73568..a4d3bdb5 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; } |