Converted all m_free to xfree etc.
[gnupg.git] / cipher / random.c
index 2c958d9..1ae2e80 100644 (file)
@@ -1,5 +1,6 @@
 /* random.c  - random number generator
 /* random.c  - random number generator
- *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  *
  * 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
  *
  * 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>
 #include <errno.h>
 #include <string.h>
 #include <time.h>
+#ifndef _WIN32
 #include <sys/time.h>
 #include <sys/time.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 #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
 #endif
 #ifdef HAVE_GETTIMEOFDAY
-  #include <sys/times.h>
+#include <sys/times.h>
+#endif
+#ifdef HAVE_TIMES
+#include <sys/times.h>
 #endif
 #ifdef HAVE_GETRUSAGE
 #endif
 #ifdef HAVE_GETRUSAGE
-  #include <sys/resource.h>
+#include <sys/resource.h>
 #endif
 #endif
-#ifdef __MINGW32__
-  #include <process.h>
+#ifdef _WIN32
+#include <process.h>
 #endif
 #include "util.h"
 #include "rmd.h"
 #endif
 #include "util.h"
 #include "rmd.h"
 #include "i18n.h"
 #include "random.h"
 #include "rand-internal.h"
 #include "i18n.h"
 #include "random.h"
 #include "rand-internal.h"
-#include "dynload.h"
-
+#include "algorithms.h"
 
 #ifndef RAND_MAX   /* for SunOS */
 
 #ifndef RAND_MAX   /* for SunOS */
-  #define RAND_MAX 32767
+#define RAND_MAX 32767
 #endif
 
 
 #if SIZEOF_UNSIGNED_LONG == 8
 #endif
 
 
 #if SIZEOF_UNSIGNED_LONG == 8
-  #define ADD_VALUE 0xa5a5a5a5a5a5a5a5
+#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
 #elif SIZEOF_UNSIGNED_LONG == 4
 #elif SIZEOF_UNSIGNED_LONG == 4
-  #define ADD_VALUE 0xa5a5a5a5
+#define ADD_VALUE 0xa5a5a5a5
 #else
 #else
-  #error weird size for an unsigned long
+#error weird size for an unsigned long
 #endif
 
 #define BLOCKLEN  64   /* hash this amount of bytes */
 #endif
 
 #define BLOCKLEN  64   /* hash this amount of bytes */
@@ -82,7 +88,7 @@
 #define POOLBLOCKS 30
 #define POOLSIZE (POOLBLOCKS*DIGESTLEN)
 #if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
 #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)
 
 #endif
 #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
 
@@ -125,18 +131,80 @@ static struct {
     ulong naddbytes;
 } rndstats;
 
     ulong naddbytes;
 } rndstats;
 
+
+static int (*
+getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
+                        size_t, int)
+{
+#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
+  return rndunix_gather_random;
+# endif
+# ifdef USE_RNDEGD
+  return rndegd_gather_random;
+# endif
+# ifdef USE_RNDW32
+  return rndw32_gather_random;
+# endif
+# ifdef USE_RNDRISCOS
+  return rndriscos_gather_random;
+# endif
+#endif
+  return NULL;
+}
+
+static int (*
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
+{
+#ifdef USE_RNDW32
+  return rndw32_gather_random_fast;
+#endif
+  return NULL;
+}
+
+
+
 static void
 initialize(void)
 {
     /* The data buffer is allocated somewhat larger, so that
      * we can use this extra space (which is allocated in secure memory)
      * as a temporary hash buffer */
 static void
 initialize(void)
 {
     /* The data buffer is allocated somewhat larger, so that
      * we can use this extra space (which is allocated in secure memory)
      * as a temporary hash buffer */
-    rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-                          : m_alloc_clear(POOLSIZE+BLOCKLEN);
-    keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-                          : m_alloc_clear(POOLSIZE+BLOCKLEN);
+    rndpool = secure_alloc ? xmalloc_secure_clear(POOLSIZE+BLOCKLEN)
+                          : xmalloc_clear(POOLSIZE+BLOCKLEN);
+    keypool = secure_alloc ? xmalloc_secure_clear(POOLSIZE+BLOCKLEN)
+                          : xmalloc_clear(POOLSIZE+BLOCKLEN);
     is_initialized = 1;
     is_initialized = 1;
-    cipher_modules_constructor();
 }
 
 static void
 }
 
 static void
@@ -144,7 +212,7 @@ burn_stack (int bytes)
 {
     char buf[128];
     
 {
     char buf[128];
     
-    memset (buf, 0, sizeof buf);
+    wipememory(buf,sizeof buf);
     bytes -= sizeof buf;
     if (bytes > 0)
         burn_stack (bytes);
     bytes -= sizeof buf;
     if (bytes > 0)
         burn_stack (bytes);
@@ -163,7 +231,7 @@ random_dump_stats()
 }
 
 void
 }
 
 void
-secure_random_alloc()
+secure_randoxmalloc()
 {
     secure_alloc = 1;
 }
 {
     secure_alloc = 1;
 }
@@ -192,7 +260,7 @@ randomize_buffer( byte *buffer, size_t length, int level )
 {
     char *p = get_random_bits( length*8, level, 1 );
     memcpy( buffer, p, length );
 {
     char *p = get_random_bits( length*8, level, 1 );
     memcpy( buffer, p, length );
-    m_free(p);
+    xfree(p);
 }
 
 
 }
 
 
@@ -227,7 +295,7 @@ get_random_bits( size_t nbits, int level, int secure )
        rndstats.ngetbytes2++;
     }
 
        rndstats.ngetbytes2++;
     }
 
-    buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes );
+    buf = secure && secure_alloc ? xmalloc_secure( nbytes ) : xmalloc( nbytes );
     for( p = buf; nbytes > 0; ) {
        size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
        read_pool( p, n, level );
     for( p = buf; nbytes > 0; ) {
        size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
        read_pool( p, n, level );
@@ -250,9 +318,9 @@ mix_pool(byte *pool)
     RMD160_CONTEXT md;
 
     rmd160_init( &md );
     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 );
     /* loop over the pool */
     pend = pool + POOLSIZE;
     memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
@@ -288,7 +356,7 @@ set_random_seed_file( const char *name )
 {
     if( seed_file_name )
        BUG();
 {
     if( seed_file_name )
        BUG();
-    seed_file_name = m_strdup( name );
+    seed_file_name = xstrdup( name );
 }
 
 /****************
 }
 
 /****************
@@ -306,11 +374,11 @@ read_seed_file(void)
     if( !seed_file_name )
        return 0;
 
     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 );
     fd = open( seed_file_name, O_RDONLY | O_BINARY );
-  #else
+#else
     fd = open( seed_file_name, O_RDONLY );
     fd = open( seed_file_name, O_RDONLY );
-  #endif
+#endif
     if( fd == -1 && errno == ENOENT) {
        allow_seed_file_update = 1;
        return 0;
     if( fd == -1 && errno == ENOENT) {
        allow_seed_file_update = 1;
        return 0;
@@ -396,12 +464,12 @@ update_random_seed_file()
     mix_pool(rndpool); rndstats.mixrnd++;
     mix_pool(keypool); rndstats.mixkey++;
 
     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 );
     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 );
     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;
     if( fd == -1 ) {
        log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
        return;
@@ -503,7 +571,7 @@ read_pool( byte *buffer, size_t length, int level )
        if( pool_balance < 0 )
            pool_balance = 0;
        /* and clear the keypool */
        if( pool_balance < 0 )
            pool_balance = 0;
        /* and clear the keypool */
-       memset( keypool, 0, POOLSIZE );
+       wipememory(keypool, POOLSIZE);
     }
 }
 
     }
 }
 
@@ -552,7 +620,7 @@ random_poll()
 void
 fast_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++;
     static int initialized = 0;
 
     rndstats.fastpolls++;
@@ -560,7 +628,7 @@ fast_random_poll()
        if( !is_initialized )
            initialize();
        initialized = 1;
        if( !is_initialized )
            initialize();
        initialized = 1;
-       fnc = dynload_getfnc_fast_random_poll();
+       fnc = getfnc_fast_random_poll();
     }
     if( fnc ) {
        (*fnc)( add_randomness, 1 );
     }
     if( fnc ) {
        (*fnc)( add_randomness, 1 );
@@ -568,41 +636,40 @@ fast_random_poll()
     }
 
     /* fall back to the generic function */
     }
 
     /* 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 );
     }
     {  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 );
     }
     {  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 );
     }
     {  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;
     {  struct tms buf;
-       times( &buf );
+        if( times( &buf ) == -1 )
+           BUG();
        add_randomness( &buf, sizeof buf, 1 );
     }
        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
     {  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
@@ -612,10 +679,10 @@ fast_random_poll()
         getrusage( RUSAGE_SELF, &buf );
         
        add_randomness( &buf, sizeof buf, 1 );
         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 */
     /* time and clock are available on all systems - so
      * we better do it just in case one of the above functions
      * didn't work */
@@ -637,7 +704,7 @@ read_random_source( int requester, size_t length, int level )
     if( !fnc ) {
        if( !is_initialized )
            initialize();
     if( !fnc ) {
        if( !is_initialized )
            initialize();
-       fnc = dynload_getfnc_gather_random();
+       fnc = getfnc_gather_random();
        if( !fnc ) {
            faked_rng = 1;
            fnc = gather_faked;
        if( !fnc ) {
            faked_rng = 1;
            fnc = gather_faked;
@@ -664,24 +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;
                   "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());
        srand(make_timestamp()*getpid());
-      #else
+#else
        srandom(make_timestamp()*getpid());
        srandom(make_timestamp()*getpid());
-      #endif
+#endif
     }
 
     }
 
-    p = buffer = m_alloc( length );
+    p = buffer = xmalloc( length );
     n = length;
     n = length;
-  #ifdef HAVE_RAND
+#ifdef HAVE_RAND
     while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
     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);
     while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
-  #endif
+#endif
     add_randomness( buffer, length, requester );
     add_randomness( buffer, length, requester );
-    m_free(buffer);
+    xfree(buffer);
     return 0; /* okay */
 }
     return 0; /* okay */
 }
-