* random.c: Fix prototype of the fast random gatherer. Noted by Joe
[gnupg.git] / cipher / random.c
index d7ebf57..4dd8d54 100644 (file)
@@ -1,5 +1,6 @@
 /* random.c  - random number generator
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -15,7 +16,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 
 #include <errno.h>
 #include <string.h>
 #include <time.h>
+#ifndef _WIN32
 #include <sys/time.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
-#ifdef HAVE_GETHRTIME
-  #include <sys/times.h>
+#ifdef HAVE_GETHRTIME
+#include <sys/times.h>
 #endif
 #ifdef HAVE_GETTIMEOFDAY
-  #include <sys/times.h>
+#include <sys/times.h>
+#endif
+#ifdef HAVE_TIMES
+#include <sys/times.h>
 #endif
 #ifdef HAVE_GETRUSAGE
-  #include <sys/resource.h>
+#include <sys/resource.h>
 #endif
-#ifdef __MINGW32__
-  #include <process.h>
+#ifdef _WIN32
+#include <process.h>
 #endif
 #include "util.h"
 #include "rmd.h"
 #include "algorithms.h"
 
 #ifndef RAND_MAX   /* for SunOS */
-  #define RAND_MAX 32767
+#define RAND_MAX 32767
 #endif
 
 
 #if SIZEOF_UNSIGNED_LONG == 8
-  #define ADD_VALUE 0xa5a5a5a5a5a5a5a5
+#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
 #elif SIZEOF_UNSIGNED_LONG == 4
-  #define ADD_VALUE 0xa5a5a5a5
+#define ADD_VALUE 0xa5a5a5a5
 #else
-  #error weird size for an unsigned long
+#error weird size for an unsigned long
 #endif
 
 #define BLOCKLEN  64   /* hash this amount of bytes */
@@ -81,7 +88,7 @@
 #define POOLBLOCKS 30
 #define POOLSIZE (POOLBLOCKS*DIGESTLEN)
 #if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
-  #error Please make sure that poolsize is a multiple of ulong
+#error Please make sure that poolsize is a multiple of ulong
 #endif
 #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
 
@@ -129,25 +136,54 @@ static int (*
 getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
                         size_t, int)
 {
-#ifdef USE_RNDLINUX
+#ifdef USE_ALL_RANDOM_MODULES
+  static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int);
+  
+  if (fnc)
+    return fnc;
+# ifdef USE_RNDLINUX
+  if ( !access (NAME_OF_DEV_RANDOM, R_OK)
+       && !access (NAME_OF_DEV_URANDOM, R_OK))
+    {
+      fnc = rndlinux_gather_random;
+      return fnc;
+    }
+# endif
+# ifdef USE_RNDEGD
+  if ( rndegd_connect_socket (1) != -1 )
+    {
+      fnc = rndegd_gather_random;
+      return fnc;
+    }
+# endif
+# ifdef USE_RNDUNIX
+  fnc = rndunix_gather_random;
+  return fnc;
+# endif
+
+  log_fatal (_("no entropy gathering module detected\n"));
+
+#else
+# ifdef USE_RNDLINUX
   return rndlinux_gather_random;
-#endif
-#ifdef USE_RNDUNIX
+# endif
+# ifdef USE_RNDUNIX
   return rndunix_gather_random;
-#endif
-#ifdef USE_RNDEGD
+# endif
+# ifdef USE_RNDEGD
   return rndegd_gather_random;
-#endif
-#ifdef USE_RNDW32
+# endif
+# ifdef USE_RNDW32
   return rndw32_gather_random;
-#endif
-#ifdef USE_RNDRISCOS
+# endif
+# ifdef USE_RNDRISCOS
   return rndriscos_gather_random;
+# endif
 #endif
   return NULL;
 }
 
-static void (*
+static int (*
 getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
 {
 #ifdef USE_RNDW32
@@ -176,7 +212,7 @@ burn_stack (int bytes)
 {
     char buf[128];
     
-    memset (buf, 0, sizeof buf);
+    wipememory(buf,sizeof buf);
     bytes -= sizeof buf;
     if (bytes > 0)
         burn_stack (bytes);
@@ -282,9 +318,9 @@ mix_pool(byte *pool)
     RMD160_CONTEXT md;
 
     rmd160_init( &md );
- #if DIGESTLEN != 20
-    #error must have a digest length of 20 for ripe-md-160
- #endif
+#if DIGESTLEN != 20
+#error must have a digest length of 20 for ripe-md-160
+#endif
     /* loop over the pool */
     pend = pool + POOLSIZE;
     memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
@@ -338,11 +374,11 @@ read_seed_file(void)
     if( !seed_file_name )
        return 0;
 
-  #ifdef HAVE_DOSISH_SYSTEM
+#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
     fd = open( seed_file_name, O_RDONLY | O_BINARY );
-  #else
+#else
     fd = open( seed_file_name, O_RDONLY );
-  #endif
+#endif
     if( fd == -1 && errno == ENOENT) {
        allow_seed_file_update = 1;
        return 0;
@@ -428,12 +464,12 @@ update_random_seed_file()
     mix_pool(rndpool); rndstats.mixrnd++;
     mix_pool(keypool); rndstats.mixkey++;
 
-  #ifdef HAVE_DOSISH_SYSTEM
+#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
     fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
                                                        S_IRUSR|S_IWUSR );
-  #else
+#else
     fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
-  #endif
+#endif
     if( fd == -1 ) {
        log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
        return;
@@ -535,7 +571,7 @@ read_pool( byte *buffer, size_t length, int level )
        if( pool_balance < 0 )
            pool_balance = 0;
        /* and clear the keypool */
-       memset( keypool, 0, POOLSIZE );
+       wipememory(keypool, POOLSIZE);
     }
 }
 
@@ -584,7 +620,7 @@ random_poll()
 void
 fast_random_poll()
 {
-    static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
+    static int (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
     static int initialized = 0;
 
     rndstats.fastpolls++;
@@ -600,41 +636,40 @@ fast_random_poll()
     }
 
     /* fall back to the generic function */
-  #if defined(HAVE_GETHRTIME) && !defined(HAVE_BROKEN_GETHRTIME)
+#if defined(HAVE_GETHRTIME) && !defined(HAVE_BROKEN_GETHRTIME)
     {  hrtime_t tv;
         /* On some Solaris and HPUX system gethrtime raises an SIGILL, but we 
          * checked this with configure */
        tv = gethrtime();
        add_randomness( &tv, sizeof(tv), 1 );
     }
-  #elif defined (HAVE_GETTIMEOFDAY)
+#elif defined (HAVE_GETTIMEOFDAY)
     {  struct timeval tv;
        if( gettimeofday( &tv, NULL ) )
            BUG();
        add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
        add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
     }
-  #elif defined (HAVE_CLOCK_GETTIME)
+#elif defined (HAVE_CLOCK_GETTIME)
     {  struct timespec tv;
        if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
            BUG();
        add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
        add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
     }
-  #else /* use times */
-    #ifndef HAVE_DOSISH_SYSTEM
+#elif defined (HAVE_TIMES)
     {  struct tms buf;
-       times( &buf );
+        if( times( &buf ) == -1 )
+           BUG();
        add_randomness( &buf, sizeof buf, 1 );
     }
-    #endif
-  #endif
-  #ifdef HAVE_GETRUSAGE
-    #ifndef RUSAGE_SELF
-      #ifdef __GCC__
-       #warning There is no RUSAGE_SELF on this system
-      #endif
-    #else
+#endif
+#ifdef HAVE_GETRUSAGE
+#ifndef RUSAGE_SELF
+#ifdef __GCC__
+#warning There is no RUSAGE_SELF on this system
+#endif
+#else
     {  struct rusage buf;
         /* QNX/Neutrino does return ENOSYS - so we just ignore it and
          * add whatever is in buf.  In a chroot environment it might not
@@ -644,10 +679,10 @@ fast_random_poll()
         getrusage( RUSAGE_SELF, &buf );
         
        add_randomness( &buf, sizeof buf, 1 );
-       memset( &buf, 0, sizeof buf );
+       wipememory( &buf, sizeof buf );
     }
-    #endif
-  #endif
+#endif
+#endif
     /* time and clock are available on all systems - so
      * we better do it just in case one of the above functions
      * didn't work */
@@ -696,25 +731,23 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
                   "it run - it is in no way a strong RNG!\n\n"
                   "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
        initialized=1;
-      #ifdef HAVE_RAND
+#ifdef HAVE_RAND
        srand(make_timestamp()*getpid());
-      #else
+#else
        srandom(make_timestamp()*getpid());
-      #endif
+#endif
     }
 
     p = buffer = m_alloc( length );
     n = length;
-  #ifdef HAVE_RAND
+#ifdef HAVE_RAND
     while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
-  #else
+#else
     while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
-  #endif
+#endif
     add_randomness( buffer, length, requester );
     m_free(buffer);
     return 0; /* okay */
 }
-
-