summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--THANKS7
-rw-r--r--cipher/ChangeLog10
-rw-r--r--cipher/dynload.c10
-rw-r--r--cipher/dynload.h5
-rw-r--r--cipher/random.c60
-rw-r--r--cipher/rndlinux.c27
-rw-r--r--cipher/rndunix.c64
7 files changed, 103 insertions, 80 deletions
diff --git a/THANKS b/THANKS
index 61116a64..460b3978 100644
--- a/THANKS
+++ b/THANKS
@@ -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;
}