tests: Add tests for mpi_cmp.
[libgcrypt.git] / random / random-csprng.c
index fbc4230..9921c4f 100644 (file)
@@ -1,6 +1,6 @@
 /* random-csprng.c - CSPRNG style random number generator (libgcrypt classic)
  * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007, 2008  Free Software Foundation, Inc.
+ *               2007, 2008, 2010, 2012  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
    up.  Its allocated size is POOLSIZE+BLOCKLEN.  Note that this is
    also an indication on whether the module has been fully
    initialized. */
-static unsigned char *rndpool; 
+static unsigned char *rndpool;
 
 /* KEYPOOL is used as a scratch copy to read out random from RNDPOOL.
    Its allocated size is also POOLSIZE+BLOCKLEN.  */
-static unsigned char *keypool; 
+static unsigned char *keypool;
 
 /* This is the offset into RNDPOOL where the next random bytes are to
    be mixed in.  */
@@ -137,7 +137,7 @@ static int pool_balance;
 
 /* After a mixing operation this variable will be set to true and
    cleared if new entropy has been added or a remix is required for
-   otehr reasons.  */
+   other reasons.  */
 static int just_mixed;
 
 /* The name of the seed file or NULL if no seed file has been defined.
@@ -161,7 +161,7 @@ static int (*slow_gather_fnc)(void (*)(const void*, size_t,
                                        enum random_origins),
                               enum random_origins, size_t, int);
 
-/* This function is set to the actual fast entropy gathering fucntion
+/* This function is set to the actual fast entropy gathering function
    during initialization.  If it is NULL, no such function is
    available. */
 static void (*fast_gather_fnc)(void (*)(const void*, size_t,
@@ -181,7 +181,7 @@ static int quick_test;
 static int faked_rng;
 
 /* This is the lock we use to protect all pool operations.  */
-static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t pool_lock;
 
 /* This is a helper for assert calls.  These calls are used to assert
    that functions are called in a locked state.  It is not meant to be
@@ -189,10 +189,6 @@ static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
    test suite.  */
 static int pool_is_locked;
 
-/* This is the lock we use to protect the buffer used by the nonce
-   generation.  */
-static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
-
 
 /* We keep some counters in this structure for the sake of the
    _gcry_random_dump_stats () function.  */
@@ -221,7 +217,7 @@ static struct
    test this flag in a locked state because a wrong value does not
    harm and the trhead will find out itself that the daemon does not
    work and set it (again) to false.  */
-static int allow_daemon;       
+static int allow_daemon;
 
 /* During initialization, the user may set a non-default socket name
    for accessing the random daemon.  If this value is NULL, the
@@ -234,12 +230,12 @@ static char *daemon_socket_name;
 
 /* ---  Prototypes  --- */
 static void read_pool (byte *buffer, size_t length, int level );
-static void add_randomness (const void *buffer, size_t length, 
+static void add_randomness (const void *buffer, size_t length,
                             enum random_origins origin);
 static void random_poll (void);
 static void do_fast_random_poll (void);
-static int (*getfnc_gather_random (void))(void (*)(const void*, size_t, 
-                                                   enum random_origins), 
+static int (*getfnc_gather_random (void))(void (*)(const void*, size_t,
+                                                   enum random_origins),
                                           enum random_origins, size_t, int);
 static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t,
                                                        enum random_origins),
@@ -271,11 +267,6 @@ initialize_basics(void)
       err = ath_mutex_init (&pool_lock);
       if (err)
         log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
-      
-      err = ath_mutex_init (&nonce_buffer_lock);
-      if (err)
-        log_fatal ("failed to create the nonce buffer lock: %s\n",
-                   strerror (err) );
 
 #ifdef USE_RANDOM_DAEMON
       _gcry_daemon_initialize_basics ();
@@ -283,7 +274,7 @@ initialize_basics(void)
 
       /* Make sure that we are still using the values we have
          traditionally used for the random levels.  */
-      gcry_assert (GCRY_WEAK_RANDOM == 0 
+      gcry_assert (GCRY_WEAK_RANDOM == 0
                    && GCRY_STRONG_RANDOM == 1
                    && GCRY_VERY_STRONG_RANDOM == 2);
     }
@@ -293,7 +284,7 @@ initialize_basics(void)
 static void
 lock_pool (void)
 {
-  int err; 
+  int err;
 
   err = ath_mutex_lock (&pool_lock);
   if (err)
@@ -305,7 +296,7 @@ lock_pool (void)
 static void
 unlock_pool (void)
 {
-  int err; 
+  int err;
 
   pool_is_locked = 0;
   err = ath_mutex_unlock (&pool_lock);
@@ -345,7 +336,7 @@ initialize(void)
           faked_rng = 1;
           slow_gather_fnc = gather_faked;
        }
-      
+
       /* Setup the fast entropy gathering function.  */
       fast_gather_fnc = getfnc_fast_random_poll ();
 
@@ -388,7 +379,7 @@ _gcry_rngcsprng_dump_stats (void)
 
 
 /* This function should be called during initialization and before
-   intialization of this module to place the random pools into secure
+   initialization of this module to place the random pools into secure
    memory.  */
 void
 _gcry_rngcsprng_secure_alloc (void)
@@ -427,7 +418,7 @@ _gcry_rngcsprng_use_daemon (int onoff)
 {
 #ifdef USE_RANDOM_DAEMON
   int last;
-  
+
   /* This is not really thread safe.  However it is expected that this
      function is being called during initialization and at that point
      we are for other reasons not really thread safe.  We do not want
@@ -472,7 +463,7 @@ _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality)
     quality = 100;
   else if (quality < 0)
     quality = 0;
-      
+
   if (!buf)
     return gpg_error (GPG_ERR_INV_ARG);
 
@@ -496,9 +487,9 @@ _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality)
       buflen -= nbytes;
     }
   return 0;
-}   
+}
+
 
-    
 /* Public function to fill the buffer with LENGTH bytes of
    cryptographically strong random bytes.  Level GCRY_WEAK_RANDOM is
    not very strong, GCRY_STRONG_RANDOM is strong enough for most
@@ -564,13 +555,13 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length,
    Mix the pool:
 
    |........blocks*20byte........|20byte|..44byte..|
-   <..44byte..>           <20byte> 
+   <..44byte..>           <20byte>
         |                    |
         |                    +------+
         +---------------------------|----------+
                                     v          v
    |........blocks*20byte........|20byte|..44byte..|
-                                 <.....64bytes.....>   
+                                 <.....64bytes.....>
                                          |
       +----------------------------------+
      Hash
@@ -590,7 +581,7 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length,
    |.............................|20byte|..44byte..|
    <20byte><20byte><..44byte..>
 
-   and so on until we did this for all blocks. 
+   and so on until we did this for all blocks.
 
    To better protect against implementation errors in this code, we
    xor a digest of the entire pool into the pool before mixing.
@@ -627,7 +618,7 @@ mix_pool(unsigned char *pool)
       for (i=0; i < 20; i++)
         pool[i] ^= failsafe_digest[i];
     }
-  
+
   p = pool;
   for (n=1; n < POOLBLOCKS; n++)
     {
@@ -636,10 +627,10 @@ mix_pool(unsigned char *pool)
       p += DIGESTLEN;
       if (p+DIGESTLEN+BLOCKLEN < pend)
         memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
-      else 
+      else
         {
           unsigned char *pp = p + DIGESTLEN;
-          
+
           for (i=DIGESTLEN; i < BLOCKLEN; i++ )
             {
               if ( pp >= pend )
@@ -647,7 +638,7 @@ mix_pool(unsigned char *pool)
               hashbuf[i] = *pp++;
            }
        }
-      
+
       _gcry_rmd160_mixblock ( &md, hashbuf);
       memcpy(p, hashbuf, 20 );
     }
@@ -682,7 +673,9 @@ _gcry_rngcsprng_set_seed_file (const char *name)
 static int
 lock_seed_file (int fd, const char *fname, int for_write)
 {
+#ifdef __GCC__
 #warning Check whether we can lock on Windows.
+#endif
 #if LOCK_SEED_FILE
   struct flock lck;
   struct timeval tv;
@@ -703,7 +696,7 @@ lock_seed_file (int fd, const char *fname, int for_write)
 
       if (backoff > 2) /* Show the first message after ~2.25 seconds. */
         log_info( _("waiting for lock on `%s'...\n"), fname);
-      
+
       tv.tv_sec = backoff;
       tv.tv_usec = 250000;
       select (0, NULL, NULL, NULL, &tv);
@@ -728,7 +721,7 @@ lock_seed_file (int fd, const char *fname, int for_write)
    correlated to some extent.  In the perfect scenario, the attacker
    can control (or at least guess) the PID and clock of the
    application, and drain the system's entropy pool to reduce the "up
-   to 16 bytes" above to 0.  Then the dependencies of the inital
+   to 16 bytes" above to 0.  Then the dependencies of the initial
    states of the pools are completely known.  */
 static int
 read_seed_file (void)
@@ -742,7 +735,7 @@ read_seed_file (void)
 
   if (!seed_file_name)
     return 0;
-  
+
 #ifdef HAVE_DOSISH_SYSTEM
   fd = open( seed_file_name, O_RDONLY | O_BINARY );
 #else
@@ -783,7 +776,7 @@ read_seed_file (void)
       allow_seed_file_update = 1;
       return 0;
     }
-  if (sb.st_size != POOLSIZE ) 
+  if (sb.st_size != POOLSIZE )
     {
       log_info(_("warning: invalid size of random_seed file - not used\n") );
       close(fd);
@@ -793,7 +786,7 @@ read_seed_file (void)
   do
     {
       n = read( fd, buffer, POOLSIZE );
-    } 
+    }
   while (n == -1 && errno == EINTR );
 
   if (n != POOLSIZE)
@@ -802,12 +795,12 @@ read_seed_file (void)
       close(fd);/*NOTREACHED*/
       return 0;
     }
-  
+
   close(fd);
 
   add_randomness( buffer, POOLSIZE, RANDOM_ORIGIN_INIT );
   /* add some minor entropy to the pool now (this will also force a mixing) */
-  {    
+  {
     pid_t x = getpid();
     add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
   }
@@ -815,7 +808,7 @@ read_seed_file (void)
     time_t x = time(NULL);
     add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
   }
-  {    
+  {
     clock_t x = clock();
     add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
   }
@@ -863,7 +856,7 @@ _gcry_rngcsprng_update_seed_file (void)
 
   /* Copy the entropy pool to a scratch pool and mix both of them. */
   for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
-       i < POOLWORDS; i++, dp++, sp++ ) 
+       i < POOLWORDS; i++, dp++, sp++ )
     {
       *dp = *sp + ADD_VALUE;
     }
@@ -894,19 +887,19 @@ _gcry_rngcsprng_update_seed_file (void)
       close (fd);
     }
 #endif /*LOCK_SEED_FILE*/
-  else 
+  else
     {
       do
         {
           i = write (fd, keypool, POOLSIZE );
-        } 
+        }
       while (i == -1 && errno == EINTR);
-      if (i != POOLSIZE) 
+      if (i != POOLSIZE)
         log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno));
       if (close(fd))
         log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno));
     }
-  
+
   unlock_pool ();
 }
 
@@ -926,7 +919,7 @@ read_pool (byte *buffer, size_t length, int level)
      Note that we keep a pid in a static variable as well as in a
      stack based one; the latter is to detect ill behaving thread
      libraries, ignoring the pool mutexes. */
-  static volatile pid_t my_pid = (pid_t)(-1); 
+  static volatile pid_t my_pid = (pid_t)(-1);
   volatile pid_t my_pid2;
 
   gcry_assert (pool_is_locked);
@@ -934,7 +927,7 @@ read_pool (byte *buffer, size_t length, int level)
  retry:
   /* Get our own pid, so that we can detect a fork. */
   my_pid2 = getpid ();
-  if (my_pid == (pid_t)(-1))                                
+  if (my_pid == (pid_t)(-1))
     my_pid = my_pid2;
   if ( my_pid != my_pid2 )
     {
@@ -985,7 +978,7 @@ read_pool (byte *buffer, size_t length, int level)
   if (level == GCRY_VERY_STRONG_RANDOM && pool_balance < length)
     {
       size_t needed;
-      
+
       if (pool_balance < 0)
         pool_balance = 0;
       needed = length - pool_balance;
@@ -1002,7 +995,7 @@ read_pool (byte *buffer, size_t length, int level)
 
   /* Always do a fast random poll (we have to use the unlocked version). */
   do_fast_random_poll();
-  
+
   /* Mix the pid in so that we for sure won't deliver the same random
      after a fork. */
   {
@@ -1035,7 +1028,7 @@ read_pool (byte *buffer, size_t length, int level)
         pool_readpos = 0;
       pool_balance--;
     }
+
   if (pool_balance < 0)
     pool_balance = 0;
 
@@ -1110,13 +1103,13 @@ random_poll()
 
 /* Runtime determination of the slow entropy gathering module.  */
 static int (*
-getfnc_gather_random (void))(void (*)(const void*, size_t, 
-                                      enum random_origins), 
+getfnc_gather_random (void))(void (*)(const void*, size_t,
+                                      enum random_origins),
                              enum random_origins, size_t, int)
 {
-  int (*fnc)(void (*)(const void*, size_t, enum random_origins), 
+  int (*fnc)(void (*)(const void*, size_t, enum random_origins),
              enum random_origins, size_t, int);
-  
+
 #if USE_RNDLINUX
   if ( !access (NAME_OF_DEV_RANDOM, R_OK)
        && !access (NAME_OF_DEV_URANDOM, R_OK))
@@ -1144,6 +1137,11 @@ getfnc_gather_random (void))(void (*)(const void*, size_t,
   return fnc;
 #endif
 
+#if USE_RNDW32CE
+  fnc = _gcry_rndw32ce_gather_random;
+  return fnc;
+#endif
+
   log_fatal (_("no entropy gathering module detected\n"));
 
   return NULL; /*NOTREACHED*/
@@ -1159,6 +1157,9 @@ getfnc_fast_random_poll (void))( void (*)(const void*, size_t,
 #if USE_RNDW32
   return _gcry_rndw32_gather_random_fast;
 #endif
+#if USE_RNDW32CE
+  return _gcry_rndw32ce_gather_random_fast;
+#endif
   return NULL;
 }
 
@@ -1176,13 +1177,13 @@ do_fast_random_poll (void)
 
   /* Continue with the generic functions. */
 #if HAVE_GETHRTIME
-  {    
+  {
     hrtime_t tv;
     tv = gethrtime();
     add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL );
   }
 #elif HAVE_GETTIMEOFDAY
-  {    
+  {
     struct timeval tv;
     if( gettimeofday( &tv, NULL ) )
       BUG();
@@ -1207,7 +1208,7 @@ do_fast_random_poll (void)
 
 #ifdef HAVE_GETRUSAGE
 # ifdef RUSAGE_SELF
-  {    
+  {
     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 work
@@ -1230,7 +1231,7 @@ do_fast_random_poll (void)
     time_t x = time(NULL);
     add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
   }
-  {    
+  {
     clock_t x = clock();
     add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
   }
@@ -1243,7 +1244,7 @@ do_fast_random_poll (void)
 
 /* The fast random pool function as called at some places in
    libgcrypt.  This is merely a wrapper to make sure that this module
-   is initalized and to look the pool.  Note, that this function is a
+   is initialized and to lock the pool.  Note, that this function is a
    NOP unless a random function has been used or _gcry_initialize (1)
    has been used.  We use this hack so that the internal use of this
    function in cipher_open and md_open won't start filling up the
@@ -1282,10 +1283,10 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins),
   static int initialized=0;
   size_t n;
   char *buffer, *p;
-  
+
   (void)add;
   (void)level;
-  
+
   if ( !initialized )
     {
       log_info(_("WARNING: using insecure random number generator!!\n"));
@@ -1310,89 +1311,3 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins),
   gcry_free (buffer);
   return 0; /* okay */
 }
-
-
-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
-void
-_gcry_rngcsprng_create_nonce (void *buffer, size_t length)
-{
-  static unsigned char nonce_buffer[20+8];
-  static int nonce_buffer_initialized = 0;
-  static volatile pid_t my_pid; /* The volatile is there to make sure the
-                                   compiler does not optimize the code away
-                                   in case the getpid function is badly
-                                   attributed. */
-  volatile pid_t apid;
-  unsigned char *p;
-  size_t n;
-  int err;
-
-  /* Make sure we are initialized. */
-  initialize ();
-
-#ifdef USE_RANDOM_DAEMON
-  if (allow_daemon
-      && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length))
-    return; /* The daemon succeeded. */
-  allow_daemon = 0; /* Daemon failed - switch off. */
-#endif /*USE_RANDOM_DAEMON*/
-
-  /* Acquire the nonce buffer lock. */
-  err = ath_mutex_lock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to acquire the nonce buffer lock: %s\n",
-               strerror (err));
-
-  apid = getpid ();
-  /* The first time intialize our buffer. */
-  if (!nonce_buffer_initialized)
-    {
-      time_t atime = time (NULL);
-      pid_t xpid = apid;
-
-      my_pid = apid;
-
-      if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
-        BUG ();
-
-      /* Initialize the first 20 bytes with a reasonable value so that
-         a failure of gcry_randomize won't affect us too much.  Don't
-         care about the uninitialized remaining bytes. */
-      p = nonce_buffer;
-      memcpy (p, &xpid, sizeof xpid);
-      p += sizeof xpid;
-      memcpy (p, &atime, sizeof atime); 
-
-      /* Initialize the never changing private part of 64 bits. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-
-      nonce_buffer_initialized = 1;
-    }
-  else if ( my_pid != apid )
-    {
-      /* We forked. Need to reseed the buffer - doing this for the
-         private part should be sufficient. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-      /* Update the pid so that we won't run into here again and
-         again. */
-      my_pid = apid;
-    }
-
-  /* Create the nonce by hashing the entire buffer, returning the hash
-     and updating the first 20 bytes of the buffer with this hash. */
-  for (p = buffer; length > 0; length -= n, p += n)
-    {
-      _gcry_sha1_hash_buffer (nonce_buffer,
-                              nonce_buffer, sizeof nonce_buffer);
-      n = length > 20? 20 : length;
-      memcpy (p, nonce_buffer, n);
-    }
-
-
-  /* Release the nonce buffer lock. */
-  err = ath_mutex_unlock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to release the nonce buffer lock: %s\n",
-               strerror (err));
-
-}