Add automatic query of EGD sockets to RAND_poll(). The EGD sockets are
authorLutz Jänicke <jaenicke@openssl.org>
Tue, 9 Jan 2001 16:44:59 +0000 (16:44 +0000)
committerLutz Jänicke <jaenicke@openssl.org>
Tue, 9 Jan 2001 16:44:59 +0000 (16:44 +0000)
only queried when the /dev/[u]random devices did not return enough
entropy. Only the amount of entropy missing to reach the required minimum
is queried, as EGD may be drained.
Queried locations are: /etc/entropy, /var/run/egd-pool

CHANGES
crypto/rand/rand.h
crypto/rand/rand_egd.c
crypto/rand/rand_unix.c
e_os.h

diff --git a/CHANGES b/CHANGES
index b0a1f58..75fdcc5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
      (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
      [Geoff Thorpe]
 
+  *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
+     If an EGD or PRNGD is running and enough entropy is returned, automatic
+     seeding like with /dev/[u]random will be performed.
+     Positions tried are: /etc/entropy, /var/run/egd-pool.
+     [Lutz Jaenicke]
+
   *) Change the Unix RAND_poll() variant to be able to poll several
      random devices and only read data for a small fragment of time
      to avoid hangs.  Also separate out the Unix variant to it's own
index eb9c8c0..1331db9 100644 (file)
@@ -91,6 +91,7 @@ int  RAND_load_file(const char *file,long max_bytes);
 int  RAND_write_file(const char *file);
 const char *RAND_file_name(char *file,int 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);
 void ERR_load_RAND_strings(void);
index 02a0d86..28fb1f2 100644 (file)
  */
 
 #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);
@@ -81,13 +85,13 @@ int RAND_egd_bytes(const char *path,int bytes)
 #  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 #endif
 
-int RAND_egd(const char *path)
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
        {
-       int ret = -1;
+       int ret = 0;
        struct sockaddr_un addr;
        int len, num;
        int fd = -1;
-       unsigned char buf[256];
+       unsigned char egdbuf[2];
 
        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
@@ -98,18 +102,44 @@ int RAND_egd(const char *path)
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd == -1) return (-1);
        if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err;
-       buf[0] = 1;
-       buf[1] = 255;
-       write(fd, buf, 2);
-       if (read(fd, buf, 1) != 1) goto err;
-       if (buf[0] == 0) goto err;
-       num = read(fd, buf, 255);
+
+       while(bytes > 0)
+           {
+           egdbuf[0] = 1;
+           egdbuf[1] = bytes < 255 ? bytes : 255;
+           write(fd, egdbuf, 2);
+           if (read(fd, egdbuf, 1) != 1)
+               {
+               ret=-1;
+               goto err;
+               }
+           if(egdbuf[0] == 0)
+               goto err;
+           num = read(fd, buf + ret, egdbuf[0]);
+           if (num < 1)
+               {
+               ret=-1;
+               goto err;
+               }
+           ret += num;
+           bytes-=num;
+           }
+ err:
+       if (fd != -1) close(fd);
+       return(ret);
+       }
+
+int RAND_egd(const char *path)
+       {
+       int num, ret;
+       unsigned char buf[256];
+
+       num = RAND_query_egd_bytes(path, buf, 255);
        if (num < 1) goto err;
        RAND_seed(buf, num);
        if (RAND_status() == 1)
                ret = num;
  err:
-       if (fd != -1) close(fd);
        return(ret);
        }
 
index 658d35f..b68e2ba 100644 (file)
@@ -125,13 +125,19 @@ int RAND_poll(void)
 {
        unsigned long l;
        pid_t curr_pid = getpid();
-#ifdef DEVRANDOM
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        unsigned char tmpbuf[ENTROPY_NEEDED];
        int n = 0;
+#endif
+#ifdef DEVRANDOM
        static const char *randomfiles[] = { DEVRANDOM, NULL };
        const char **randomfile = NULL;
        int fd;
 #endif
+#ifdef DEVRANDOM_EGD
+       static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
+       const char **egdsocket = NULL;
+#endif
 
 #ifdef DEVRANDOM
        /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
@@ -185,6 +191,24 @@ int RAND_poll(void)
                        close(fd);
                        }
                }
+#endif
+
+#ifdef DEVRANDOM_EGD
+       /* Use an EGD socket to read entropy from an EGD or PRNGD entropy
+        * collecting daemon. */
+
+       for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
+               {
+               int r;
+
+               r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
+                                        ENTROPY_NEEDED-n);
+               if (r > 0)
+                       n += r;
+               }
+#endif
+
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        if (n > 0)
                {
                RAND_add(tmpbuf,sizeof tmpbuf,n);
@@ -201,7 +225,7 @@ int RAND_poll(void)
        l=time(NULL);
        RAND_add(&l,sizeof(l),0);
 
-#ifdef DEVRANDOM
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        return 1;
 #endif
        return 0;
diff --git a/e_os.h b/e_os.h
index d658191..e23e254 100644 (file)
--- a/e_os.h
+++ b/e_os.h
@@ -81,6 +81,12 @@ extern "C" {
  * My default, we will try to read at least one of these files */
 #define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
 #endif
+#ifndef DEVRANDOM_EGD
+/* set this to a comma-seperated list of 'egd' sockets to try out. These
+ * sockets will be tried in the order listed in case accessing the device files
+ * listed in DEVRANDOM did not return enough entropy. */
+#define DEVRANDOM_EGD "/etc/entropy","/var/run/egd-pool"
+#endif
 
 #if defined(__MWERKS__) && defined(macintosh)
 # if macintosh==1