From 870930639b22fe54d66ed5898012bf5e5c35bd80 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Fri, 18 Apr 2008 10:02:15 +0000 Subject: [PATCH] Reimplement using RAND_ interface. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@23038 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/hcrypto/rnd_keys.c | 657 +++++++++++-------------------------------------- 1 file changed, 142 insertions(+), 515 deletions(-) rewrite lib/hcrypto/rnd_keys.c (77%) diff --git a/lib/hcrypto/rnd_keys.c b/lib/hcrypto/rnd_keys.c dissimilarity index 77% index 84c023f0a..b6ea40470 100644 --- a/lib/hcrypto/rnd_keys.c +++ b/lib/hcrypto/rnd_keys.c @@ -1,515 +1,142 @@ -/* - * Copyright (c) 1995, 1996, 1997, 1999 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" - -RCSID("$Id$"); -#endif - -#define HC_DEPRECATED - -#ifdef KRB5 -#include -#endif -#include - -#include -#include - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#elif defined(HAVE_SYS_TIME_H) -#include -#else -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_SIGNAL_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#undef __attribute__ -#define __attribute__(X) - -/* - * 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) */ - -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 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 HC_DEPRECATED -DES_rand_data(void *outdata, int size) -{ - unsigned char *data = outdata; - des_not_rand_data (data, size); -} -#endif - -void HC_DEPRECATED -DES_generate_random_block(DES_cblock *block) -{ - DES_rand_data((unsigned char *)block, sizeof(*block)); -} - -#define DES_rand_data_key hc_DES_rand_data_key - -void HC_DEPRECATED -DES_rand_data_key(DES_cblock *key); - -/* - * Generate a "random" DES key. - */ -void HC_DEPRECATED -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 HC_DEPRECATED -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) -{ - 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); -} - -#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 HC_DEPRECATED -DES_set_sequence_number(void *ll) -{ - set_sequence_number(ll); -} - -/* - * Set the generator seed and reset the sequence number to 0. - */ -void HC_DEPRECATED -DES_set_random_generator_seed(DES_cblock *seed) -{ - DES_set_key(seed, &sequence_seed); - zero_long_long(sequence_index); - initialized = 1; -} - -/* - * Generate a sequence of random des keys - * using the random block sequence, fixup - * parity and skip weak keys. - */ -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 */ - DES_set_odd_parity(key); - } while (DES_is_weak_key(key)); - return(0); -} - -/* - * des_init_random_number_generator: - * - * 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. - * - */ -void HC_DEPRECATED -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 HC_DEPRECATED -DES_random_key(DES_cblock *ret) -{ - DES_new_random_key(ret); -} - -#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 - -#ifdef TESTRUN2 -int -main() -{ - 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"); - } -} -#endif +/* + * Copyright (c) 1995, 1996, 1997, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" + +RCSID("$Id$"); +#endif + +#define HC_DEPRECATED + +#ifdef KRB5 +#include +#endif +#include +#include + +#include + +#undef __attribute__ +#define __attribute__(X) + +void HC_DEPRECATED +DES_rand_data(void *outdata, int size) +{ + RAND_bytes(outdata, size); +} + +void HC_DEPRECATED +DES_generate_random_block(DES_cblock *block) +{ + RAND_bytes(block, sizeof(*block)); +} + +#define DES_rand_data_key hc_DES_rand_data_key + +void HC_DEPRECATED +DES_rand_data_key(DES_cblock *key); + +/* + * Generate a random DES key. + */ + +void HC_DEPRECATED +DES_rand_data_key(DES_cblock *key) +{ + DES_new_random_key(key); +} + +void HC_DEPRECATED +DES_set_sequence_number(void *ll) +{ +} + +void HC_DEPRECATED +DES_set_random_generator_seed(DES_cblock *seed) +{ + RAND_seed(seed, sizeof(*seed)); +} + +/** + * 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 +DES_new_random_key(DES_cblock *key) +{ + do { + if (RAND_bytes(key, sizeof(*key)) != 1) + return 1; + DES_set_odd_parity(key); + } while(DES_is_weak_key(key)); + + return(0); +} + +/** + * Seed the random number generator. Deprecated, use @ref page_rand + * + * @param seed a seed to seed that random number generate with. + * + * @ingroup hcrypto_des + */ + +void HC_DEPRECATED +DES_init_random_number_generator(DES_cblock *seed) +{ + RAND_seed(seed, sizeof(*seed)); +} + +/** + * 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 + */ + +void HC_DEPRECATED +DES_random_key(DES_cblock *key) +{ + if (DES_new_random_key(key)) + abort(); +} -- 2.11.4.GIT