1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Restructured the RNG source and add support for loadable

random modules.
This commit is contained in:
Werner Koch 1998-11-25 11:52:41 +00:00
parent 710d2e351b
commit 2e494682b6
11 changed files with 1101 additions and 281 deletions

View file

@ -36,7 +36,9 @@
#include "rmd.h"
#include "ttyio.h"
#include "i18n.h"
#include "random.h"
#include "rand-internal.h"
#include "dynload.h"
#if SIZEOF_UNSIGNED_LONG == 8
@ -47,6 +49,20 @@
#error weird size for an unsigned long
#endif
#define BLOCKLEN 64 /* hash this amount of bytes */
#define DIGESTLEN 20 /* into a digest of this length (rmd160) */
/* poolblocks is the number of digests which make up the pool
* and poolsize must be a multiple of the digest length
* to make the AND operations faster, the size should also be
* a multiple of ulong
*/
#define POOLBLOCKS 30
#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
#error Please make sure that poolsize is a multiple of ulong
#endif
#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
static int is_initialized;
#define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0)
@ -60,9 +76,16 @@ static int just_mixed;
static int secure_alloc;
static int quick_test;
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 );
#ifndef HAVE_DEV_RANDOM
static int gather_faked( byte *buffer, size_t *r_length, int level );
#endif
static void
@ -76,6 +99,20 @@ initialize()
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
: m_alloc_clear(POOLSIZE+BLOCKLEN);
is_initialized = 1;
#if USE_RNDLINUX
rndlinux_constructor();
#elif USE_RNDUNIX
rndunix_constructor();
#elif USE_RNDW32
rndw32_constructor();
#elif USE_RNDOS2
rndos2_constructor();
#elif USE_RNDATARI
rndatari_constructor();
#elif USE_RNDMVS
rndmvs_constructor();
#endif
}
void
@ -88,13 +125,13 @@ secure_random_alloc()
int
quick_random_gen( int onoff )
{
int last = quick_test;
int last;
read_random_source( NULL, 0, 0 ); /* load module */
last = quick_test;
if( onoff != -1 )
quick_test = onoff;
#ifdef USE_RAND_DUMMY
last = 1; /* insecure RNG */
#endif
return last;
return faked_rng? 1 : last;
}
@ -250,9 +287,9 @@ 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 randomeness source.
* source may be used to specify the randomness source.
*/
void
static void
add_randomness( const void *buffer, size_t length, int source )
{
if( !is_initialized )
@ -271,3 +308,95 @@ 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);
}
void
fast_random_poll()
{
static void (*fnc)( void (*)(const void*, size_t, int)) = NULL;
static int initialized = 0;
if( !initialized ) {
if( !is_initialized )
initialize();
initialized = 1;
fnc = dynload_getfnc_fast_random_poll();
if( !fnc )
log_info("Ooops: No fast random poll function\n");
}
if( fnc )
(*fnc)( add_randomness );
}
static void
read_random_source( byte *buffer, size_t length, int level )
{
static int (*fnc)(byte*, size_t*, int) = NULL;
int nbytes;
int goodness;
if( !fnc ) {
if( !is_initialized )
initialize();
fnc = dynload_getfnc_gather_random();
if( !fnc ) {
faked_rng = 1;
#ifndef HAVE_DEV_RANDOM
fnc = gather_faked;
#else
BUG();
#endif
}
}
while( length ) {
nbytes = length;
goodness = (*fnc)( buffer, &nbytes, level );
buffer +=nbytes;
length -= nbytes;
/* FIXME: how can we handle the goodness */
}
}
#ifndef HAVE_DEV_RANDOM
static int
gather_faked( byte *buffer, size_t *r_length, int level )
{
static int initialized=0;
size_t length = *r_length;
if( !initialized ) {
log_info(_("WARNING: using insecure random number generator!!\n"));
tty_printf(_("The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
initialized=1;
#ifdef HAVE_RAND
srand(make_timestamp()*getpid());
#else
srandom(make_timestamp()*getpid());
#endif
}
#ifdef HAVE_RAND
while( length-- )
*buffer++ = ((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);
#endif
return 100; /* We really fake it ;-) */
}
#endif /* ! HAVE_DEV_RANDOM */