diff --git a/lib/des/rnd_keys.c b/lib/des/rnd_keys.c index d6e93435c..c53fe0849 100644 --- a/lib/des/rnd_keys.c +++ b/lib/des/rnd_keys.c @@ -1,39 +1,14 @@ -#include "des_locl.h" +//#include "des_locl.h" +#ifndef RETSIGTYPE +#include +#define RETSIGTYPE void +#else RCSID("$Id$"); - -#include - -#include -#ifdef HAVE_SYS_IOCTL_H -#include #endif -#include +#include #include -#include -#include -#include - -/* this is for broken Solaris */ -#ifndef HAVE_GETHOSTID - -#include - -static long -gethostid(void) -{ - static int flag=0; - static long hostid; - if(!flag){ - char s[32]; - sysinfo(SI_HW_SERIAL, s, 32); - sscanf(s, "%u", &hostid); - flag=1; - } - return hostid; -} -#endif /* * Create a sequence of random 64 bit blocks. @@ -44,15 +19,114 @@ static des_key_schedule sequence_seed; static u_int32_t sequence_index[2]; /* - * In case the generator does not get inited use this for backup. + * These guys are used for the clocked "non crypto" randomness. + * + * The method used is described on page 424 in + * Applied Cryptography 2 ed. by Bruce Schneier. + */ +static volatile int counter; +static volatile unsigned char *gdata; /* Global data */ +static volatile int igdata; /* Index into global data */ + +static +RETSIGTYPE +sigALRM(int sig) +{ + if (igdata < sizeof(des_cblock)) + gdata[igdata++] ^= counter & 0xff; + +#ifdef VOID_RETSIGTYPE + return; +#else + return (RETSIGTYPE)0; +#endif +} + +/* + * Generate size bytes of "random" data using timed interrupts. + * This is a slooow routine but it's meant to be slow. + * It's not neccessary to be root to run it. + */ +static +void +des_clock_rand(unsigned char *data, int size) +{ + struct itimerval tv, otv; + struct sigaction sa, osa; + int i; + + gdata = data; + igdata = 0; + counter = 0; + + /* Setup signal handler */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sigALRM; + sigaction(SIGALRM, &sa, &osa); + + /* Start timer */ + tv.it_value.tv_sec = 0; + tv.it_value.tv_usec = 10 * 1000; /* 10 ms */ + tv.it_interval = tv.it_value; + setitimer(ITIMER_REAL, &tv, &otv); + + for(i = 0; i < 4; i++) + { + for (igdata = 0; igdata < size;) + counter++; + for (igdata = 0; igdata < size; igdata++) + gdata[igdata] = (gdata[igdata]>>2) | (gdata[igdata]<<6); + } + setitimer(ITIMER_REAL, &otv, 0); + sigaction(SIGALRM, &osa, 0); +} + +#if 0 +/* + * Generate a "random" DES key. + */ +void +des_clock_rand_key(des_cblock *key) +{ + unsigned char data[8]; + des_key_schedule sched; + do { + des_clock_rand(data, sizeof(data)); + des_clock_rand((unsigned char*)key, sizeof(des_cblock)); + des_set_odd_parity(key); + des_key_sched(key, sched); + des_ecb_encrypt(&data, key, sched, DES_ENCRYPT); + memset(&data, 0, sizeof(data)); + memset(&sched, 0, sizeof(sched)); + des_set_odd_parity(key); + } while(des_is_weak_key(key)); +} + +/* + * Generate 8 bytes of "random" data by checksumming the first 2 + * megabytes of /dev/mem. + * It's neccessary to be root to run it. + */ +void +des_mem_rand8(unsigned char *data) +{ +} +#endif + +/* + * In case the generator does not get initialized use this for backup. */ static int initialized; -static des_cblock default_seed = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + static void do_initialize(void) { - des_set_odd_parity(&default_seed); - des_set_random_generator_seed(&default_seed); + des_cblock default_seed; + do { + des_clock_rand((unsigned char*)&default_seed, sizeof(default_seed)); + des_set_odd_parity(&default_seed); + } while (des_is_weak_key(&default_seed)); + des_init_random_number_generator(&default_seed); } #define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0) @@ -117,26 +191,12 @@ void des_init_random_number_generator(des_cblock *seed) { struct timeval now; - static long uniq[2]; + static u_int32_t uniq[2]; des_cblock new_key; gettimeofday(&now, (struct timezone *)0); - if (!uniq[0]) - { - struct hostent *hent; - char hostname[100]; - gethostname(hostname, sizeof(hostname)); - hent = gethostbyname(hostname); - if (hent != NULL) - bcopy(hent->h_addr_list[0], &uniq[0], sizeof(uniq[0])); - else - uniq[0] = gethostid(); -#ifdef MSDOS - uniq[1] = 1; -#else - uniq[1] = getpid(); -#endif - } + if (uniq[0] == 0 && uniq[1] == 0) + des_clock_rand((unsigned char *)uniq, sizeof(uniq)); /* Pick a unique random key from the shared sequence. */ des_set_random_generator_seed(seed); @@ -152,89 +212,6 @@ des_init_random_number_generator(des_cblock *seed) des_set_random_generator_seed(&new_key); } -/* - * Generate 8 bytes of "random" data by checksumming the first 2 - * megabytes of /dev/mem. - */ -void -des_mem_rand8(unsigned char *data) -{ -} - -/* - * These guys are for clocked "non crypto" randomness. - * - * The method used is described on page 424 in - * Applied Cryptography 2 ed. by Bruce Schneier. - */ -static volatile int counter; -static volatile unsigned char *gdata; /* Global data */ -static volatile int igdata; /* Index into global data */ - -static -RETSIGTYPE -sigALRM(int sig) -{ - if (igdata < sizeof(des_cblock)) - gdata[igdata++] ^= counter & 0xff; - -#ifdef VOID_RETSIGTYPE - return; -#else - return (RETSIGTYPE)0; -#endif -} - -/* - * Generate size bytes of "random" data using timed interrupts. - * This is a slooow routine but it's meant to be slow. - * It's not neccessary to be root to run it. - */ -void -des_clock_rand(unsigned char *data, int size) -{ - struct itimerval tv, otv; - struct sigaction sa, osa; - int i; - - gdata = data; - igdata = 0; - counter = 0; - - /* Setup signal handler */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sigALRM; - sigaction(SIGALRM, &sa, &osa); - - /* Start timer */ - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = 50 * 1000; /* 50 ms */ - tv.it_interval = tv.it_value; - setitimer(ITIMER_REAL, &tv, &otv); - - for(i = 0; i < 4; i++) - { - for (igdata = 0; igdata < size;) - counter++; - for (igdata = 0; igdata < size; igdata++) - gdata[igdata] = (gdata[igdata]>>2) | (gdata[igdata]<<6); - } - setitimer(ITIMER_REAL, &otv, 0); - sigaction(SIGALRM, &osa, 0); -} - -/* - * Generate a "random" DES key. - */ -void -des_clock_rand_key(des_cblock *key) -{ - do { - des_clock_rand((unsigned char*)key, sizeof(des_cblock)); - des_set_odd_parity(key); - } while(des_is_weak_key(key)); -} - /* This is for backwards compatibility. */ int des_random_key(unsigned char *ret) @@ -258,3 +235,21 @@ main() } } #endif + +#ifdef TESTRUN2 +int +main() +{ + unsigned char data[8]; + int i; + + while (1) + { + do_initialize(); + des_random_key(data); + for (i = 0; i < 8; i++) + printf("%02x", data[i]); + printf("\n"); + } +} +#endif