DJGPP changes. Contributed by Doug Kaufman <dkaufman@rahul.net>
[openssl.git] / crypto / rand / rand_unix.c
index 5a78009e9aa4b9e9bf7cfef164007971ea1b2834..bf9a0e993aef99c2332a1266ffa88d4525a134f1 100644 (file)
  * Hudson (tjh@cryptsoft.com).
  *
  */
+#include <stdio.h>
 
+#define USE_SOCKETS
+#include "e_os.h"
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 
-#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2))
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) 
 
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/times.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <time.h>
 
+#ifdef __OpenBSD__
+int RAND_poll(void)
+{
+       u_int32_t rnd = 0, i;
+       unsigned char buf[ENTROPY_NEEDED];
+
+       for (i = 0; i < sizeof(buf); i++) {
+               if (i % 4 == 0)
+                       rnd = arc4random();
+               buf[i] = rnd;
+               rnd >>= 8;
+       }
+       RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+       memset(buf, 0, sizeof(buf));
+
+       return 1;
+}
+#else
 int RAND_poll(void)
 {
        unsigned long l;
@@ -131,9 +153,9 @@ int RAND_poll(void)
        int n = 0;
 #endif
 #ifdef DEVRANDOM
-       static const char *randomfiles[] = { DEVRANDOM, NULL };
-       const char **randomfile = NULL;
-       int fd;
+       static const char *randomfiles[] = { "DEVRANDOM" };
+       struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
+       int fd,i;
 #endif
 #ifdef DEVRANDOM_EGD
        static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -141,26 +163,42 @@ int RAND_poll(void)
 #endif
 
 #ifdef DEVRANDOM
+       memset(randomstats,0,sizeof(randomstats));
        /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
         * have this. Use /dev/urandom if you can as /dev/random may block
         * if it runs out of random entries.  */
 
-       for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++)
+       for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
                {
-               if ((fd = open(*randomfile, O_RDONLY|O_NONBLOCK
+               if ((fd = open(randomfiles[i], O_RDONLY
+#ifdef O_NONBLOCK
+                       |O_NONBLOCK
+#endif
+#ifdef O_BINARY
+                       |O_BINARY
+#endif
 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
                   our controlling tty */
                        |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
-                       |O_NOFOLLOW
 #endif
                        )) >= 0)
                        {
                        struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
                                                              each file. */
-                       int r;
+                       int r,j;
                        fd_set fset;
+                       struct stat *st=&randomstats[i];
+
+                       /* Avoid using same input... Used to be O_NOFOLLOW
+                        * above, but it's not universally appropriate... */
+                       if (fstat(fd,st) != 0)  { close(fd); continue; }
+                       for (j=0;j<i;j++)
+                               {
+                               if (randomstats[j].st_ino==st->st_ino &&
+                                   randomstats[j].st_dev==st->st_dev)
+                                       break;
+                               }
+                       if (j<i)                { close(fd); continue; }
 
                        do
                                {
@@ -212,19 +250,19 @@ int RAND_poll(void)
 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        if (n > 0)
                {
-               RAND_add(tmpbuf,sizeof tmpbuf,n);
-               memset(tmpbuf,0,n);
+               RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
+               OPENSSL_cleanse(tmpbuf,n);
                }
 #endif
 
        /* put in some default random data, we need more than just this */
        l=curr_pid;
-       RAND_add(&l,sizeof(l),0);
+       RAND_add(&l,sizeof(l),0.0);
        l=getuid();
-       RAND_add(&l,sizeof(l),0);
+       RAND_add(&l,sizeof(l),0.0);
 
        l=time(NULL);
-       RAND_add(&l,sizeof(l),0);
+       RAND_add(&l,sizeof(l),0.0);
 
 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        return 1;
@@ -234,3 +272,11 @@ int RAND_poll(void)
 }
 
 #endif
+#endif
+
+#if defined(OPENSSL_SYS_VXWORKS)
+int RAND_poll(void)
+{
+    return 0;
+}
+#endif