s4:heimdal: import lorikeet-heimdal-200908052208 (commit 370a73a74199a5a55188340906e1...
[samba.git] / source4 / heimdal / lib / hcrypto / rand-fortuna.c
index 1d47ed49cc3521649cfef5c7c789a45659e2405b..c39c71390121c01545b427f099f10ee817cc134b 100644 (file)
  * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.8 2006/10/04 00:29:46 momjian Exp $
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
-
-RCSID("$Id: rand-fortuna.c 21196 2007-06-20 05:08:58Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -118,6 +114,7 @@ struct fortuna_state
     unsigned           pool0_bytes;
     unsigned           rnd_pos;
     int                        tricks_done;
+    pid_t              pid;
 };
 typedef struct fortuna_state FState;
 
@@ -175,6 +172,7 @@ init_state(FState * st)
     memset(st, 0, sizeof(*st));
     for (i = 0; i < NUM_POOLS; i++)
        md_init(&st->pool[i]);
+    st->pid = getpid();
 }
 
 /*
@@ -276,6 +274,9 @@ reseed(FState * st)
     /* add old key into mix too */
     md_update(&key_md, st->key, BLOCK);
 
+    /* add pid to make output diverse after fork() */
+    md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid));
+
     /* now we have new key */
     md_result(&key_md, st->key);
 
@@ -384,6 +385,7 @@ extract_data(FState * st, unsigned count, unsigned char *dst)
 {
     unsigned   n;
     unsigned   block_nr = 0;
+    pid_t      pid = getpid();
 
     /* Should we reseed? */
     if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
@@ -394,6 +396,12 @@ extract_data(FState * st, unsigned count, unsigned char *dst)
     if (!st->tricks_done)
        startup_tricks(st);
 
+    /* If we forked, force a reseed again */
+    if (pid != st->pid) {
+       st->pid = pid;
+       reseed(st);
+    }
+
     while (count > 0)
     {
        /* produce bytes */
@@ -462,7 +470,7 @@ fortuna_reseed(void)
        entropy_p = 1;
     }
 #endif
-    /* 
+    /*
      * Only to get egd entropy if /dev/random or arc4rand failed since
      * it can be horribly slow to generate new bits.
      */
@@ -493,6 +501,7 @@ fortuna_reseed(void)
        fd = open("/etc/shadow", O_RDONLY, 0);
        if (fd >= 0) {
            ssize_t n;
+           rk_cloexec(fd);
            /* add_entropy will hash the buf */
            while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0)
                add_entropy(&main_state, u.shad, sizeof(u.shad));
@@ -543,7 +552,7 @@ fortuna_seed(const void *indata, int size)
        have_entropy = 1;
 }
 
-static int 
+static int
 fortuna_bytes(unsigned char *outdata, int size)
 {
     if (!fortuna_init())