From ec0035c9b8e0690f3bc21f3de089c39eae660916 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 Jul 2007 08:00:08 +0000 Subject: r23678: Update to current lorikeet-heimdal (-r 767), which should fix the panics on hosts without /dev/random. Andrew Bartlett (This used to be commit 14a4ddb131993fec72316f7e8e371638749e6f1f) --- source4/heimdal/lib/hcrypto/pkcs12.c | 7 +- source4/heimdal/lib/hcrypto/rand-egd.c | 4 +- source4/heimdal/lib/hcrypto/rand-fortuna.c | 38 +++++- source4/heimdal/lib/hcrypto/rand-timer.c | 206 +++++++++++++++++++++++++++++ source4/heimdal/lib/hcrypto/rand.c | 8 +- source4/heimdal/lib/hcrypto/randi.h | 5 +- source4/heimdal/lib/hcrypto/rsa-imath.c | 3 +- 7 files changed, 257 insertions(+), 14 deletions(-) create mode 100644 source4/heimdal/lib/hcrypto/rand-timer.c (limited to 'source4/heimdal/lib/hcrypto') diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index dcfbdfad42..b43fe571d6 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: pkcs12.c 20661 2007-05-10 21:57:58Z lha $"); +RCSID("$Id: pkcs12.c 21155 2007-06-18 21:59:44Z lha $"); #include #include @@ -93,8 +93,11 @@ PKCS12_key_gen(const void *key, size_t keylen, while (1) { BIGNUM *bnB, *bnOne; - if (!EVP_DigestInit_ex(&ctx, md, NULL)) + if (!EVP_DigestInit_ex(&ctx, md, NULL)) { + free(I); + free(v); return 0; + } for (i = 0; i < vlen; i++) EVP_DigestUpdate(&ctx, &idc, 1); EVP_DigestUpdate(&ctx, I, size_I); diff --git a/source4/heimdal/lib/hcrypto/rand-egd.c b/source4/heimdal/lib/hcrypto/rand-egd.c index d1b024b535..497a3ab5f8 100644 --- a/source4/heimdal/lib/hcrypto/rand-egd.c +++ b/source4/heimdal/lib/hcrypto/rand-egd.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rand-egd.c 20093 2007-01-31 12:44:28Z lha $"); +RCSID("$Id: rand-egd.c 21156 2007-06-18 22:00:59Z lha $"); #include #ifdef HAVE_SYS_UN_H @@ -255,7 +255,7 @@ RAND_egd_bytes(const char *filename, int size) RAND_seed(data, size); - memset(data, 0, sizeof(data)); + memset(data, 0, size); free(data); return 1; diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c index 6cc4267c13..1d47ed49cc 100644 --- a/source4/heimdal/lib/hcrypto/rand-fortuna.c +++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c @@ -33,7 +33,7 @@ #include #endif -RCSID("$Id: rand-fortuna.c 20029 2007-01-21 09:55:42Z lha $"); +RCSID("$Id: rand-fortuna.c 21196 2007-06-20 05:08:58Z lha $"); #include #include @@ -427,6 +427,8 @@ extract_data(FState * st, unsigned count, unsigned char *dst) static FState main_state; static int init_done; static int have_entropy; +#define FORTUNA_RESEED_BYTE 10000 +static unsigned resend_bytes; /* * Try our best to do an inital seed @@ -472,6 +474,35 @@ fortuna_reseed(void) memset(buf, 0, sizeof(buf)); } } + /* + * Fall back to gattering data from timer and secret files, this + * is really the last resort. + */ + if (!entropy_p) { + /* to save stackspace */ + union { + unsigned char buf[INIT_BYTES]; + unsigned char shad[1001]; + } u; + int fd; + + /* add timer info */ + if ((*hc_rand_timer_method.bytes)(u.buf, sizeof(u.buf)) == 1) + add_entropy(&main_state, u.buf, sizeof(u.buf)); + /* add /etc/shadow */ + fd = open("/etc/shadow", O_RDONLY, 0); + if (fd >= 0) { + ssize_t n; + /* add_entropy will hash the buf */ + while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0) + add_entropy(&main_state, u.shad, sizeof(u.shad)); + close(fd); + } + + memset(&u, 0, sizeof(u)); + + entropy_p = 1; /* sure about this ? */ + } { pid_t pid = getpid(); add_entropy(&main_state, (void *)&pid, sizeof(pid)); @@ -517,6 +548,11 @@ fortuna_bytes(unsigned char *outdata, int size) { if (!fortuna_init()) return 0; + resend_bytes += size; + if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) { + resend_bytes = 0; + fortuna_reseed(); + } extract_data(&main_state, size, outdata); return 1; } diff --git a/source4/heimdal/lib/hcrypto/rand-timer.c b/source4/heimdal/lib/hcrypto/rand-timer.c new file mode 100644 index 0000000000..67a77b01fc --- /dev/null +++ b/source4/heimdal/lib/hcrypto/rand-timer.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1999, 2007 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 +#endif + +RCSID("$Id$"); + +#include +#include +#include + +#include + +#include "randi.h" + +#ifndef WIN32 /* don't bother with this on windows */ + +static volatile int counter; +static volatile unsigned char *gdata; /* Global data */ +static volatile int igdata; /* Index into global data */ +static int gsize; + +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); +} + +#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 + +#endif /* WIN32*/ + +/* + * + */ + +static void +timer_seed(const void *indata, int size) +{ +} + +static int +timer_bytes(unsigned char *outdata, int size) +{ +#ifdef WIN32 + return 0; +#else /* WIN32 */ + struct itimerval tv, otv; + RETSIGTYPE (*osa)(int); + int i, j; +#ifndef HAVE_SETITIMER + RETSIGTYPE (*ochld)(int); + pid_t pid; +#endif + + gdata = outdata; + 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); + + return 1; +#endif +} + +static void +timer_cleanup(void) +{ +} + +static void +timer_add(const void *indata, int size, double entropi) +{ +} + +static int +timer_pseudorand(unsigned char *outdata, int size) +{ + return timer_bytes(outdata, size); +} + +static int +timer_status(void) +{ +#ifdef WIN32 + return 0; +#else + return 1; +#endif +} + +const RAND_METHOD hc_rand_timer_method = { + timer_seed, + timer_bytes, + timer_cleanup, + timer_add, + timer_pseudorand, + timer_status +}; + +const RAND_METHOD * +RAND_timer_method(void) +{ + return &hc_rand_timer_method; +} diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 29f2d46dba..248fdde620 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rand.c 20126 2007-02-01 22:08:41Z lha $"); +RCSID("$Id: rand.c 21198 2007-06-20 05:10:41Z lha $"); #include #include @@ -56,11 +56,7 @@ init_method(void) { if (selected_meth != NULL) return; - - if ((*hc_rand_unix_method.status)() == 1) - selected_meth = &hc_rand_unix_method; - else - selected_meth = &hc_rand_fortuna_method; + selected_meth = &hc_rand_fortuna_method; } void diff --git a/source4/heimdal/lib/hcrypto/randi.h b/source4/heimdal/lib/hcrypto/randi.h index b9b9b5309c..6ae75f262b 100644 --- a/source4/heimdal/lib/hcrypto/randi.h +++ b/source4/heimdal/lib/hcrypto/randi.h @@ -32,7 +32,7 @@ */ /* - * $Id: randi.h 20027 2007-01-21 09:54:00Z lha $ + * $Id: randi.h 21101 2007-06-18 03:53:46Z lha $ */ #ifndef _HEIM_RANDI_H @@ -41,5 +41,8 @@ extern const RAND_METHOD hc_rand_fortuna_method; extern const RAND_METHOD hc_rand_unix_method; extern const RAND_METHOD hc_rand_egd_method; +extern const RAND_METHOD hc_rand_timer_method; + +const RAND_METHOD * RAND_timer_method(void); #endif /* _HEIM_RANDI_H */ diff --git a/source4/heimdal/lib/hcrypto/rsa-imath.c b/source4/heimdal/lib/hcrypto/rsa-imath.c index e05ead1e66..74093ff7ba 100644 --- a/source4/heimdal/lib/hcrypto/rsa-imath.c +++ b/source4/heimdal/lib/hcrypto/rsa-imath.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rsa-imath.c 19750 2007-01-06 13:45:25Z lha $"); +RCSID("$Id: rsa-imath.c 21154 2007-06-18 21:58:12Z lha $"); #include #include @@ -180,7 +180,6 @@ imath_rsa_public_encrypt(int flen, const unsigned char* from, } padlen = size - flen - 3; - assert(padlen >= 8); *p++ = 2; if (RAND_bytes(p, padlen) != 1) { -- cgit