diff options
Diffstat (limited to 'source4/heimdal/lib/hcrypto/rnd_keys.c')
-rw-r--r-- | source4/heimdal/lib/hcrypto/rnd_keys.c | 471 |
1 files changed, 52 insertions, 419 deletions
diff --git a/source4/heimdal/lib/hcrypto/rnd_keys.c b/source4/heimdal/lib/hcrypto/rnd_keys.c index a035b890b8..0fd64af3b5 100644 --- a/source4/heimdal/lib/hcrypto/rnd_keys.c +++ b/source4/heimdal/lib/hcrypto/rnd_keys.c @@ -34,476 +34,109 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id: rnd_keys.c 23093 2008-04-27 18:49:51Z lha $"); #endif +#define HC_DEPRECATED + #ifdef KRB5 #include <krb5-types.h> #endif #include <des.h> +#include <rand.h> #include <stdlib.h> -#include <string.h> - -#ifdef TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#elif defined(HAVE_SYS_TIME_H) -#include <sys/time.h> -#else -#include <time.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_IO_H -#include <io.h> -#endif - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -/* - * Generate "random" data by checksumming a file. - * - * Returns -1 if there were any problems with permissions or I/O - * errors. - */ -static -int -sumFile (const char *name, int len, void *res) -{ - uint32_t sum[2] = { 0, 0 }; - uint32_t buf[1024*2]; - int fd, i; - - fd = open (name, 0); - if (fd < 0) - return -1; - - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - for (i = 0; i < (n/sizeof(buf[0])); i++) - { - sum[0] += buf[i]; - i++; - sum[1] += buf[i]; - } - len -= n; - } - close (fd); - memcpy (res, &sum, sizeof(sum)); - return 0; -} - -#if 0 -static -int -md5sumFile (const char *name, int len, int32_t sum[4]) -{ - int32_t buf[1024*2]; - int fd, cnt; - struct md5 md5; - - fd = open (name, 0); - if (fd < 0) - return -1; - - md5_init(&md5); - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - md5_update(&md5, buf, n); - len -= n; - } - md5_finito(&md5, (unsigned char *)sum); - close (fd); - return 0; -} -#endif - -/* - * Create a sequence of random 64 bit blocks. - * The sequence is indexed with a long long and - * based on an initial des key used as a seed. - */ -static DES_key_schedule sequence_seed; -static uint32_t sequence_index[2]; - -/* - * Random number generator based on ideas from truerand in cryptolib - * as 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 int gsize; -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) -/* Visual C++ 4.0 (Windows95/NT) */ +#undef __attribute__ +#define __attribute__(X) -static -RETSIGTYPE -sigALRM(int sig) -{ - if (igdata < gsize) - gdata[igdata++] ^= counter & 0xff; - -#ifndef HAVE_SIGACTION - signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */ -#endif - SIGRETURN(0); -} - -#endif - -#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) -#ifndef srandom -#define srandom srand -#endif -#ifndef random -#define random rand -#endif -#endif - -#if !defined(HAVE_SETITIMER) || defined(WIN32) || defined(__EMX__) || defined(__OS2__) || defined(__CYGWIN32__) -static void -des_not_rand_data(unsigned char *data, int size) -{ - int i; - - srandom (time (NULL)); - - for(i = 0; i < size; ++i) - data[i] ^= random() % 0x100; -} -#endif - -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) - -#ifndef HAVE_SETITIMER -static void -pacemaker(struct timeval *tv) -{ - fd_set fds; - pid_t pid; - pid = getppid(); - while(1){ - FD_ZERO(&fds); - FD_SET(0, &fds); - select(1, &fds, NULL, NULL, tv); - kill(pid, SIGALRM); - } -} -#endif - -#ifdef HAVE_SIGACTION -/* XXX ugly hack, should perhaps use function from roken */ -static RETSIGTYPE -(*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int) -{ - struct sigaction sa, osa; - sa.sa_handler = f; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(sig, &sa, &osa); - return osa.sa_handler; -} -#define signal(S, F) fake_signal((S), (F)) -#endif - -/* - * Generate size bytes of "random" data using timed interrupts. - * It takes about 40ms/byte random data. - * It's not neccessary to be root to run it. - */ -void +void HC_DEPRECATED DES_rand_data(void *outdata, int size) { - unsigned char *data = outdata; - struct itimerval tv, otv; - RETSIGTYPE (*osa)(int); - int i, j; -#ifndef HAVE_SETITIMER - RETSIGTYPE (*ochld)(int); - pid_t pid; -#endif - const char *rnd_devices[] = {"/dev/random", - "/dev/srandom", - "/dev/urandom", - "/dev/arandom", - NULL}; - const char **p; - - for(p = rnd_devices; *p; p++) { - int fd = open(*p, O_RDONLY | O_NDELAY); - - if(fd >= 0 && read(fd, data, size) == size) { - close(fd); - return; - } - close(fd); - } - - /* Paranoia? Initialize data from /dev/mem if we can read it. */ - if (size >= 8) - sumFile("/dev/mem", (1024*1024*2), data); - - gdata = data; - gsize = size; - igdata = 0; - - osa = signal(SIGALRM, sigALRM); - - /* Start timer */ - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = 10 * 1000; /* 10 ms */ - tv.it_interval = tv.it_value; -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &tv, &otv); -#else - ochld = signal(SIGCHLD, SIG_IGN); - pid = fork(); - if(pid == -1){ - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); - des_not_rand_data(data, size); - return; - } - if(pid == 0) - pacemaker(&tv.it_interval); -#endif - - for(i = 0; i < 4; i++) { - for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */ - counter++; - for (j = 0; j < size; j++) /* Only use 2 bits each lap */ - gdata[j] = (gdata[j]>>2) | (gdata[j]<<6); - } -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &otv, 0); -#else - kill(pid, SIGKILL); - while(waitpid(pid, NULL, 0) != pid); - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); -#endif - signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL); -} -#else -void -DES_rand_data(unsigned char *p, int s) -{ - des_not_rand_data (p, s); + RAND_bytes(outdata, size); } -#endif -void +void HC_DEPRECATED DES_generate_random_block(DES_cblock *block) { - DES_rand_data((unsigned char *)block, sizeof(*block)); + RAND_bytes(block, sizeof(*block)); } #define DES_rand_data_key hc_DES_rand_data_key -void +void HC_DEPRECATED DES_rand_data_key(DES_cblock *key); /* - * Generate a "random" DES key. + * Generate a random DES key. */ -void -DES_rand_data_key(DES_cblock *key) -{ - unsigned char data[8]; - DES_key_schedule sched; - do { - DES_rand_data(data, sizeof(data)); - DES_rand_data((unsigned char*)key, sizeof(DES_cblock)); - DES_set_odd_parity(key); - DES_set_key(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 "random" data by checksumming /dev/mem - * - * It's neccessary to be root to run it. Returns -1 if there were any - * problems with permissions. - */ - -#define DES_mem_rand8 hc_DES_mem_rand8 - -int -DES_mem_rand8(unsigned char *data); - -int -DES_mem_rand8(unsigned char *data) -{ - return 1; -} - -/* - * In case the generator does not get initialized use this as fallback. - */ -static int initialized; - -static void -do_initialize(void) +void HC_DEPRECATED +DES_rand_data_key(DES_cblock *key) { - DES_cblock default_seed; - do { - DES_generate_random_block(&default_seed); - DES_set_odd_parity(&default_seed); - } while (DES_is_weak_key(&default_seed)); - DES_init_random_number_generator(&default_seed); + DES_new_random_key(key); } -#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0) - -#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0) - -#define set_sequence_number(ll) \ -memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); - -/* - * Set the sequnce number to this value (a long long). - */ -void +void HC_DEPRECATED DES_set_sequence_number(void *ll) { - set_sequence_number(ll); } -/* - * Set the generator seed and reset the sequence number to 0. - */ -void +void HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *seed) { - DES_set_key(seed, &sequence_seed); - zero_long_long(sequence_index); - initialized = 1; + RAND_seed(seed, sizeof(*seed)); } -/* - * Generate a sequence of random des keys - * using the random block sequence, fixup - * parity and skip weak keys. +/** + * Generate a random des key using a random block, fixup parity and + * skip weak keys. + * + * @param key is set to a random key. + * + * @return 0 on success, non zero on random number generator failure. + * + * @ingroup hcrypto_des */ -int + +int HC_DEPRECATED DES_new_random_key(DES_cblock *key) { - if (!initialized) - do_initialize(); - do { - DES_ecb_encrypt((DES_cblock *) sequence_index, - key, - &sequence_seed, - DES_ENCRYPT); - incr_long_long(sequence_index); - /* random key must have odd parity and not be weak */ + if (RAND_bytes(key, sizeof(*key)) != 1) + return 1; DES_set_odd_parity(key); - } while (DES_is_weak_key(key)); + } while(DES_is_weak_key(key)); + return(0); } -/* - * des_init_random_number_generator: +/** + * Seed the random number generator. Deprecated, use @ref page_rand * - * Initialize the sequence of random 64 bit blocks. The input seed - * can be a secret key since it should be well hidden and is also not - * kept. + * @param seed a seed to seed that random number generate with. * + * @ingroup hcrypto_des */ -void -DES_init_random_number_generator(DES_cblock *seed) -{ - struct timeval now; - DES_cblock uniq; - DES_cblock new_key; - gettimeofday(&now, (struct timezone *)0); - DES_generate_random_block(&uniq); - - /* Pick a unique random key from the shared sequence. */ - DES_set_random_generator_seed(seed); - set_sequence_number((unsigned char *)&uniq); - DES_new_random_key(&new_key); - - /* Select a new nonshared sequence, */ - DES_set_random_generator_seed(&new_key); - - /* and use the current time to pick a key for the new sequence. */ - set_sequence_number((unsigned char *)&now); - DES_new_random_key(&new_key); - DES_set_random_generator_seed(&new_key); -} - -/* This is for backwards compatibility. */ -void -DES_random_key(DES_cblock *ret) +void HC_DEPRECATED +DES_init_random_number_generator(DES_cblock *seed) { - DES_new_random_key(ret); + RAND_seed(seed, sizeof(*seed)); } -#ifdef TESTRUN -int -main() -{ - unsigned char data[8]; - int i; - - while (1) - { - if (sumFile("/dev/mem", (1024*1024*8), data) != 0) - { perror("sumFile"); exit(1); } - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } -} -#endif +/** + * Generate a random key, deprecated since it doesn't return an error + * code, use DES_new_random_key(). + * + * @param key is set to a random key. + * + * @ingroup hcrypto_des + */ -#ifdef TESTRUN2 -int -main() +void HC_DEPRECATED +DES_random_key(DES_cblock *key) { - DES_cblock data; - int i; - - while (1) - { - do_initialize(); - DES_random_key(data); - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } + if (DES_new_random_key(key)) + abort(); } -#endif |