Greetings, after getting tired of supporting diferent SSL/SSH environments for Solaris 2.6, 7 and 8, and getting too anxious while reading that Solaris 9 was to provide a /dev/[u]random device and that openssl 0.9.7 (with support for polling prngd) was on the way.
i got this patch backporting (sorta - for sure not as elegant as Lutz code on 0.9.7 but i didn't wanted to make too many changes on the 0.9.6 code so the patch looks clear) the prngd support that comes with openssl 0.9.7 over the openssl-0.9.6c code (appended at the end and available from ftp://ftp.sajinet.com.pe/pub/misc/crypto/openssl/openssl-0.9.6c-egd.patch) now that SUN has decided to support a /dev/[u]random device on Solaris 8 http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsrdb%2F27606&zone_32=%2Fdev%2Frandom with patches 112438-01 (SunOS 5.8) and 112439-01 (SunOS 5.8_x86) and that the openssl-0.9.6d is on beta, could support for a prng on Solaris be a good idea on the source? regards, Carlo PS. following patch can also be applied to openssl-0.9.6d-beta1 with no much fuzz --------------- CUT HERE FOR PATCH --------------------- diff -ur openssl-0.9.6c/CHANGES openssl-0.9.6c-egd/CHANGES --- openssl-0.9.6c/CHANGES Thu Dec 20 20:20:51 2001 +++ openssl-0.9.6c-egd/CHANGES Mon Mar 25 02:38:37 2002 @@ -2,6 +2,16 @@ OpenSSL CHANGES _______________ + Additional Changes [25 mar 2002] + + +) Add automatic query of EGD sockets in RAND_poll() for the unix variant. + If /dev/[u]random devices are not available or do not return enough + entropy, EGD style sockets (served by EGD or PRNGD) will automatically + be queried. + The location defined on DEVRANDOM_EGD (on default /var/run/egd-pool) + will be queried until enough entropy is collected + [Carlo Arenas, raw functionality backported from 0.9.7 Lutz Jaenicke] + Changes between 0.9.6b and 0.9.6c [21 dec 2001] *) Fix BN_rand_range bug pointed out by Dominikus Scherkl diff -ur openssl-0.9.6c/crypto/rand/rand.h openssl-0.9.6c-egd/crypto/rand/rand.h --- openssl-0.9.6c/crypto/rand/rand.h Mon Dec 17 14:24:16 2001 +++ openssl-0.9.6c-egd/crypto/rand/rand.h Mon Mar 25 02:06:10 2002 @@ -91,6 +91,7 @@ int RAND_write_file(const char *file); const char *RAND_file_name(char *file,size_t num); int RAND_status(void); +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); int RAND_egd(const char *path); int RAND_egd_bytes(const char *path,int bytes); int RAND_poll(void); diff -ur openssl-0.9.6c/crypto/rand/rand_egd.c openssl-0.9.6c-egd/crypto/rand/rand_egd.c --- openssl-0.9.6c/crypto/rand/rand_egd.c Wed Mar 21 09:10:47 2001 +++ openssl-0.9.6c-egd/crypto/rand/rand_egd.c Mon Mar 25 03:41:36 2002 @@ -60,6 +60,11 @@ */ #if defined(WIN32) || defined(VMS) || defined(__VMS) +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) + { + return(-1); + } + int RAND_egd(const char *path) { return(-1); @@ -83,10 +88,154 @@ }; #endif /* NO_SYS_UN_H */ #include <string.h> +#include <errno.h> #ifndef offsetof # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif + +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) + { + int ret = 0; + struct sockaddr_un addr; + int len, num, numbytes; + int fd = -1; + int success; + unsigned char egdbuf[2], tempbuf[255], *retrievebuf; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlen(path) > sizeof(addr.sun_path)) + return (-1); + strcpy(addr.sun_path,path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(path); + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) return (-1); + success = 0; + while (!success) + { + if (connect(fd, (struct sockaddr *)&addr, len) == 0) + success = 1; + else + { + switch (errno) + { +#ifdef EINTR + case EINTR: +#endif +#ifdef EAGAIN + case EAGAIN: +#endif +#ifdef EINPROGRESS + case EINPROGRESS: +#endif +#ifdef EALREADY + case EALREADY: +#endif + /* No error, try again */ + break; +#ifdef EISCONN + case EISCONN: + success = 1; + break; +#endif + default: + goto err; /* failure */ + } + } + } + + while(bytes > 0) + { + egdbuf[0] = 1; + egdbuf[1] = bytes < 255 ? bytes : 255; + numbytes = 0; + while (numbytes != 2) + { + num = write(fd, egdbuf + numbytes, 2 - numbytes); + if (num >= 0) + numbytes += num; + else + { + switch (errno) + { +#ifdef EINTR + case EINTR: +#endif +#ifdef EAGAIN + case EAGAIN: +#endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + numbytes = 0; + while (numbytes != 1) + { + num = read(fd, egdbuf, 1); + if (num >= 0) + numbytes += num; + else + { + switch (errno) + { +#ifdef EINTR + case EINTR: +#endif +#ifdef EAGAIN + case EAGAIN: +#endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + if(egdbuf[0] == 0) + goto err; + if (buf) + retrievebuf = buf + ret; + else + retrievebuf = tempbuf; + numbytes = 0; + while (numbytes != egdbuf[0]) + { + num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); + if (num >= 0) + numbytes += num; + else + { + switch (errno) + { +#ifdef EINTR + case EINTR: +#endif +#ifdef EAGAIN + case EAGAIN: +#endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + ret += egdbuf[0]; + bytes -= egdbuf[0]; + if (!buf) + RAND_seed(tempbuf, egdbuf[0]); + } + err: + if (fd != -1) close(fd); + return(ret); + } int RAND_egd(const char *path) { diff -ur openssl-0.9.6c/crypto/rand/rand_win.c openssl-0.9.6c-egd/crypto/rand/rand_win.c --- openssl-0.9.6c/crypto/rand/rand_win.c Thu Mar 22 03:39:03 2001 +++ openssl-0.9.6c-egd/crypto/rand/rand_win.c Mon Mar 25 03:44:33 2002 @@ -697,6 +697,11 @@ FILE *fh; #endif +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + unsigned char tmpbuf[ENTROPY_NEEDED]; + int n; +#endif + #ifdef DEVRANDOM /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD * have this. Use /dev/urandom if you can as /dev/random may block @@ -704,12 +709,28 @@ if ((fh = fopen(DEVRANDOM, "r")) != NULL) { - unsigned char tmpbuf[ENTROPY_NEEDED]; - int n; setvbuf(fh, NULL, _IONBF, 0); n=fread((unsigned char *)tmpbuf,1,ENTROPY_NEEDED,fh); fclose(fh); + } +#endif + +#ifdef DEVRANDOM_EGD + /* Use and EGD socket to read entropy from an EGD or PRNGD entropy + * collecting daemon */ + + if ( n < ENTROPY_NEEDED ) + { + /* if we have no enough entropy yet, poll the egd socket */ + + n = RAND_query_egd_bytes(DEVRANDOM_EGD, (unsigned char *)tmpbuf, +ENTROPY_NEEDED); + } +#endif + +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + if (n > 0) + { RAND_add(tmpbuf,sizeof tmpbuf,n); memset(tmpbuf,0,n); } @@ -724,7 +745,7 @@ l=time(NULL); RAND_add(&l,sizeof(l),0); -#ifdef DEVRANDOM +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) return 1; #else return 0; diff -ur openssl-0.9.6c/crypto/rand/randtest.c openssl-0.9.6c-egd/crypto/rand/randtest.c --- openssl-0.9.6c/crypto/rand/randtest.c Sun Jan 16 10:58:17 2000 +++ openssl-0.9.6c-egd/crypto/rand/randtest.c Mon Mar 25 03:51:50 2002 @@ -73,7 +73,13 @@ /*double d; */ long d; - RAND_pseudo_bytes(buf,2500); + i = RAND_pseudo_bytes(buf,2500); + if (i < 0) + { + printf ("init failed, the rand method is not properly installed\n"); + err++; + goto err; + } n1=0; for (i=0; i<16; i++) n2[i]=0; @@ -201,6 +207,7 @@ err++; } printf("test 4 done\n"); + err: err=((err)?1:0); exit(err); return(err); diff -ur openssl-0.9.6c/e_os.h openssl-0.9.6c-egd/e_os.h --- openssl-0.9.6c/e_os.h Thu Nov 8 09:36:49 2001 +++ openssl-0.9.6c-egd/e_os.h Mon Mar 25 03:33:05 2002 @@ -81,6 +81,10 @@ * My default, we will try to read this file */ #define DEVRANDOM "/dev/urandom" #endif +#ifndef DEVRANDOM_EGD +/* set this to your 'egd' socket to try out. */ +#define DEVRANDOM_EGD "/var/run/egd-pool" +#endif #if defined(__MWERKS__) && defined(macintosh) # if macintosh==1 ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
