summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hcrypto/rnd_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hcrypto/rnd_keys.c')
-rw-r--r--source4/heimdal/lib/hcrypto/rnd_keys.c471
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