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]

Reply via email to