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:
parent
710d2e351b
commit
2e494682b6
11 changed files with 1101 additions and 281 deletions
143
cipher/random.c
143
cipher/random.c
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue