summaryrefslogtreecommitdiff
path: root/gl/lib/rand-isaac.c
diff options
context:
space:
mode:
authorPaul R. Eggert <eggert@cs.ucla.edu>2010-07-20 09:50:37 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2010-07-20 09:51:12 -0700
commitc1d8e6e458c2f9deb3013538d6db8da8f7f4e9f1 (patch)
tree8b541824476fa9f641b11ab89d89a3ebf3743aac /gl/lib/rand-isaac.c
parente5444fa2a7a2ad4246e7a5e961d5c4aad2aecbe9 (diff)
downloadcoreutils-c1d8e6e458c2f9deb3013538d6db8da8f7f4e9f1.tar.xz
randread: use /dev/urandom to seed, not just getpid etc
* gl/lib/rand-isaac.c (isaac_seed_start): New arg SEEDED. (isaac_seed): New args FD and BYTES_BOUND. Read from FD if possible. Don't bother with low-quality sources if FD has enough bytes. * gl/lib/rand-isaac.h: New size_t arg for isaac_seed. * gl/lib/randread.c: Include fcntl.h, unistd.h. (NAME_OF_NONCE_DEVICE): New #define. (nonce_device): New static var. (randread_new): Use nonce device if available.
Diffstat (limited to 'gl/lib/rand-isaac.c')
-rw-r--r--gl/lib/rand-isaac.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/gl/lib/rand-isaac.c b/gl/lib/rand-isaac.c
index 377caa605..f73144afe 100644
--- a/gl/lib/rand-isaac.c
+++ b/gl/lib/rand-isaac.c
@@ -209,9 +209,10 @@ isaac_init (struct isaac_state *s, uint32_t const *seed, size_t seedsize)
}
#endif
-/* Initialize *S to a somewhat-random value. */
+/* Initialize *S to a somewhat-random value. The first SEEDED bytes
+ in S->mm are already seeded with random data. */
static void
-isaac_seed_start (struct isaac_state *s)
+isaac_seed_start (struct isaac_state *s, size_t seeded)
{
static uint32_t const iv[8] =
{
@@ -228,11 +229,12 @@ isaac_seed_start (struct isaac_state *s)
mix (iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
#endif
- memset (s->mm, 0, sizeof s->mm);
+ memset ((char *) s->mm + seeded, 0, sizeof s->mm - seeded);
memcpy (s->iv, iv, sizeof s->iv);
/* s->c gets used for a data pointer during the seeding phase */
- s->a = s->b = s->c = 0;
+ s->a = s->b = 0;
+ s->c = seeded;
}
/* Add a buffer of seed material. */
@@ -279,22 +281,37 @@ isaac_seed_finish (struct isaac_state *s)
#define ISAAC_SEED(s,x) isaac_seed_data (s, &(x), sizeof (x))
/* Initialize *S to a somewhat-random value; this starts seeding,
- seeds with somewhat-random data, and finishes seeding. */
+ seeds with somewhat-random data, and finishes seeding. If FD is
+ nonnegative, seed by reading at most BYTES_BOUNDS bytes from it. */
void
-isaac_seed (struct isaac_state *s)
+isaac_seed (struct isaac_state *s, int fd, size_t bytes_bound)
{
- isaac_seed_start (s);
+ /* Get some data from FD if available. */
+ ssize_t seeded = 0;
+ if (0 <= fd)
+ {
+ if (sizeof s->mm < bytes_bound)
+ bytes_bound = sizeof s->mm;
+ seeded = read (fd, s->mm, bytes_bound);
+ if (seeded < 0)
+ seeded = 0;
+ }
- { pid_t t = getpid (); ISAAC_SEED (s, t); }
- { pid_t t = getppid (); ISAAC_SEED (s, t); }
- { uid_t t = getuid (); ISAAC_SEED (s, t); }
- { gid_t t = getgid (); ISAAC_SEED (s, t); }
+ isaac_seed_start (s, seeded);
- {
- struct timeval t;
- gettimeofday (&t, NULL);
- ISAAC_SEED (s, t);
- }
+ if (seeded < sizeof s->mm)
+ {
+ { pid_t t = getpid (); ISAAC_SEED (s, t); }
+ { pid_t t = getppid (); ISAAC_SEED (s, t); }
+ { uid_t t = getuid (); ISAAC_SEED (s, t); }
+ { gid_t t = getgid (); ISAAC_SEED (s, t); }
+
+ {
+ struct timeval t;
+ gettimeofday (&t, NULL);
+ ISAAC_SEED (s, t);
+ }
+ }
isaac_seed_finish (s);
}