mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-02-13 10:52:09 +02:00
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.
This commit is contained in:
committed by
Paul Eggert
parent
e5444fa2a7
commit
c1d8e6e458
@@ -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);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef RAND_ISAAC_H
|
||||
# define RAND_ISAAC_H
|
||||
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
|
||||
/* Size of the state tables to use. ISAAC_LOG should be at least 3,
|
||||
@@ -37,7 +38,7 @@ struct isaac_state
|
||||
uint32_t a, b, c; /* Extra index variables */
|
||||
};
|
||||
|
||||
void isaac_seed (struct isaac_state *);
|
||||
void isaac_seed (struct isaac_state *, int, size_t);
|
||||
void isaac_refill (struct isaac_state *, uint32_t[ISAAC_WORDS]);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <exitfail.h>
|
||||
#include <fcntl.h>
|
||||
#include <quotearg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
@@ -60,6 +62,10 @@
|
||||
# define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef NAME_OF_NONCE_DEVICE
|
||||
#define NAME_OF_NONCE_DEVICE "/dev/urandom"
|
||||
#endif
|
||||
|
||||
/* The maximum buffer size used for reads of random data. Using the
|
||||
value 2 * ISAAC_BYTES makes this the largest power of two that
|
||||
would not otherwise cause struct randread_source to grow. */
|
||||
@@ -164,8 +170,11 @@ randread_new (char const *name, size_t bytes_bound)
|
||||
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
|
||||
else
|
||||
{
|
||||
int nonce_device = open (NAME_OF_NONCE_DEVICE, O_RDONLY | O_BINARY);
|
||||
s->buf.isaac.buffered = 0;
|
||||
isaac_seed (&s->buf.isaac.state);
|
||||
isaac_seed (&s->buf.isaac.state, nonce_device, bytes_bound);
|
||||
if (0 <= nonce_device)
|
||||
close (nonce_device);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
Reference in New Issue
Block a user