A lot of cleanups as well as minor API changes.
[libgcrypt.git] / cipher / random.c
index ea69f4c..c9c95cc 100644 (file)
@@ -43,7 +43,7 @@
 #include <sys/times.h>
 #endif
 #ifdef HAVE_GETTIMEOFDAY
-#include <sys/times.h>
+#include <sys/time.h>
 #endif
 #ifdef HAVE_GETRUSAGE
 #include <sys/resource.h>
@@ -96,8 +96,8 @@
 static int is_initialized;
 static int allow_daemon; /* If true, try to use the daemon first. */
 #define MASK_LEVEL(a) do { (a) &= 3; } while(0)
-static char *rndpool;  /* allocated size is POOLSIZE+BLOCKLEN */
-static char *keypool;  /* allocated size is POOLSIZE+BLOCKLEN */
+static unsigned char *rndpool; /* Allocated size is POOLSIZE+BLOCKLEN.  */
+static unsigned char *keypool; /* Allocated size is POOLSIZE+BLOCKLEN.  */
 static size_t pool_readpos;
 static size_t pool_writepos;
 static int pool_filled;
@@ -105,6 +105,7 @@ static int pool_balance;
 static int just_mixed;
 static int did_initial_extra_seeding;
 static char *seed_file_name;
+static char *daemon_socket_name;
 static int allow_seed_file_update;
 
 static int secure_alloc;
@@ -251,6 +252,15 @@ _gcry_quick_random_gen( int onoff )
 }
 
 
+void
+_gcry_set_random_daemon_socket (const char *socketname)
+{
+  if (daemon_socket_name)
+    BUG ();
+
+  daemon_socket_name = gcry_xstrdup (socketname);
+}
+
 /* With ONOFF set to 1, enable the use of the daemon.  With ONOFF set
    to 0, disable the use of the daemon.  With ONOF set to -1, return
    whether the daemon has been enabled. */
@@ -258,11 +268,12 @@ int
 _gcry_use_random_daemon (int onoff)
 {
   int last;
-
+  
   /* FIXME: This is not really thread safe. */
   last = allow_daemon;
   if (onoff != -1)
     allow_daemon = onoff;
+
   return last;
 }
 
@@ -293,8 +304,11 @@ get_random_bytes ( size_t nbytes, int level, int secure)
   /* Make sure the requested level is in range. */
   MASK_LEVEL(level);
 
-  if (allow_daemon && (p=_gcry_daemon_get_random_bytes (nbytes, level,secure)))
+  if (allow_daemon &&
+      (p=_gcry_daemon_get_random_bytes (daemon_socket_name,
+                                        nbytes, level,secure)))
     return p; /* The daemon succeeded. */
+  allow_daemon = 0; /* Daemon failed - switch off. */
 
   /* Lock the pool. */
   err = ath_mutex_lock (&pool_lock);
@@ -390,9 +404,9 @@ gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level )
    1 is strong enough for most usage, 2 is good for key generation
    stuff but may be very slow.  */
 void
-gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level)
+gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
 {
-  byte *p;
+  unsigned char *p;
   int err;
 
   /* Make sure we are initialized. */
@@ -406,8 +420,10 @@ gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level)
   /* Make sure the level is okay. */
   MASK_LEVEL(level);
 
-  if (allow_daemon && !_gcry_daemon_randomize (buffer, length, level))
+  if (allow_daemon
+      && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level))
     return; /* The daemon succeeded. */
+  allow_daemon = 0; /* Daemon failed - switch off. */
 
   /* Acquire the pool lock. */
   err = ath_mutex_lock (&pool_lock);
@@ -484,16 +500,16 @@ gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level)
    To better protect against implementation errors in this code, we
    xor a digest of the entire pool into the pool before mixing.
 
-   Note, that this function muts only be called with a locked pool.
+   Note: this function must only be called with a locked pool.
  */
 static void
-mix_pool(byte *pool)
+mix_pool(unsigned char *pool)
 {
   static unsigned char failsafe_digest[DIGESTLEN];
   static int failsafe_digest_valid;
 
-  char *hashbuf = pool + POOLSIZE;
-  char *p, *pend;
+  unsigned char *hashbuf = pool + POOLSIZE;
+  unsigned char *p, *pend;
   int i, n;
   RMD160_CONTEXT md;
 
@@ -504,14 +520,14 @@ mix_pool(byte *pool)
   assert (pool_is_locked);
   _gcry_rmd160_init( &md );
 
-  /* loop over the pool */
+  /* Loop over the pool.  */
   pend = pool + POOLSIZE;
   memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
   memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
   _gcry_rmd160_mixblock( &md, hashbuf);
   memcpy(pool, hashbuf, 20 );
 
-  if (failsafe_digest_valid && (char *)pool == rndpool)
+  if (failsafe_digest_valid && pool == rndpool)
     {
       for (i=0; i < 20; i++)
         pool[i] ^= failsafe_digest[i];
@@ -527,7 +543,7 @@ mix_pool(byte *pool)
         memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
       else 
         {
-          char *pp = p + DIGESTLEN;
+          unsigned char *pp = p + DIGESTLEN;
           
           for (i=DIGESTLEN; i < BLOCKLEN; i++ )
             {
@@ -537,7 +553,7 @@ mix_pool(byte *pool)
            }
        }
       
-      _gcry_rmd160_mixblock( &md, hashbuf);
+      _gcry_rmd160_mixblock ( &md, hashbuf);
       memcpy(p, hashbuf, 20 );
     }
 
@@ -545,7 +561,7 @@ mix_pool(byte *pool)
        of the pool on the stack, so it is okay not to require secure
        memory here.  Before we use this pool, it will be copied to the
        help buffer anyway. */
-    if ( (char*)pool == rndpool)
+    if ( pool == rndpool)
       {
         _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE);
         failsafe_digest_valid = 1;
@@ -1170,6 +1186,9 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
     size_t n;
     char *buffer, *p;
 
+    (void)add;
+    (void)level;
+
     if( !initialized ) {
        log_info(_("WARNING: using insecure random number generator!!\n"));
        /* we can't use tty_printf here - do we need this function at
@@ -1205,7 +1224,7 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
 
 /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
 void
-gcry_create_nonce (unsigned char *buffer, size_t length)
+gcry_create_nonce (void *buffer, size_t length)
 {
   static unsigned char nonce_buffer[20+8];
   static int nonce_buffer_initialized = 0;
@@ -1213,6 +1232,7 @@ gcry_create_nonce (unsigned char *buffer, size_t length)
                                    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;
@@ -1221,8 +1241,10 @@ gcry_create_nonce (unsigned char *buffer, size_t length)
   if (!is_initialized)
     initialize ();
 
-  if (allow_daemon && !_gcry_daemon_create_nonce (buffer, length))
+  if (allow_daemon
+      && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length))
     return; /* The daemon succeeded. */
+  allow_daemon = 0; /* Daemon failed - switch off. */
 
   /* Acquire the nonce buffer lock. */
   err = ath_mutex_lock (&nonce_buffer_lock);
@@ -1230,11 +1252,12 @@ gcry_create_nonce (unsigned char *buffer, size_t length)
     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)
     {
-      pid_t apid = getpid ();
       time_t atime = time (NULL);
+      pid_t xpid = apid;
 
       my_pid = apid;
 
@@ -1245,8 +1268,8 @@ gcry_create_nonce (unsigned char *buffer, size_t length)
          a failure of gcry_randomize won't affect us too much.  Don't
          care about the uninitialized remaining bytes. */
       p = nonce_buffer;
-      memcpy (p, &apid, sizeof apid);
-      p += sizeof apid;
+      memcpy (p, &xpid, sizeof xpid);
+      p += sizeof xpid;
       memcpy (p, &atime, sizeof atime); 
 
       /* Initialize the never changing private part of 64 bits. */
@@ -1254,11 +1277,14 @@ gcry_create_nonce (unsigned char *buffer, size_t length)
 
       nonce_buffer_initialized = 1;
     }
-  else if ( my_pid != getpid () )
+  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