Commit 9eb8b950 authored by Niels Möller's avatar Niels Möller

Deleted old generators.

Rev: src/randomness.c:1.25
parent 24b0713a
......@@ -49,278 +49,8 @@
#include "randomness.h.x"
#undef GABA_DEFINE
#include "randomness.c.x"
/* Random */
/* GABA:
(class
(name poor_random)
(super randomness)
(vars
(hash object hash_instance)
(pos . UINT32)
(buffer space UINT8)))
*/
static void
do_poor_random(struct randomness *r, UINT32 length, UINT8 *dst)
{
CAST(poor_random, self, r);
while(length)
{
UINT32 available = self->hash->hash_size - self->pos;
UINT32 to_copy;
if (!available)
{
time_t now = time(NULL); /* To avoid cycles */
HASH_UPDATE(self->hash, sizeof(now), (UINT8 *) &now);
HASH_UPDATE(self->hash, self->hash->hash_size,
self->buffer);
HASH_DIGEST(self->hash, self->buffer);
available = self->hash->hash_size;
self->pos = 0;
}
to_copy = MIN(available, length);
memcpy(dst, self->buffer + self->pos, to_copy);
length -= to_copy;
dst += to_copy;
self->pos += to_copy;
}
}
struct randomness *
make_poor_random(struct hash_algorithm *hash,
struct lsh_string *init)
{
NEW(poor_random, self);
time_t now = time(NULL);
pid_t pid = getpid();
self->super.random = do_poor_random;
self->super.quality = 0;
self->hash = MAKE_HASH(hash);
self->buffer = lsh_space_alloc(hash->hash_size);
HASH_UPDATE(self->hash, sizeof(now), (UINT8 *) &now);
HASH_UPDATE(self->hash, sizeof(pid), (UINT8 *) &pid);
if (init)
{
HASH_UPDATE(self->hash, init->length, init->data);
lsh_string_free(init);
}
HASH_DIGEST(self->hash, self->buffer);
self->pos = 0;
return &self->super;
}
struct randomness *make_bad_random()
{
return make_poor_random(&sha1_algorithm, NULL);
}
/* GABA:
(class
(name device_random)
(super randomness)
(vars
(fd . int)))
*/
static void
do_device_random(struct randomness *r, UINT32 length, UINT8 *dst)
{
CAST(device_random, self, r);
while(length)
{
int n = read(self->fd, dst, length);
if (!n)
fatal("do_device_random: EOF on random source.\n");
if (n<0)
switch(errno)
{
case EINTR:
break;
default:
fatal("Read from random device failed (errno = %i): %z\n",
errno, STRERROR(errno));
}
else
{
length -= n;
dst += n;
}
}
}
/* NOTE: In most cases, blocking while waiting for more entropy to
* arrive is not acceptable. So use /dev/urandom, not /dev/random. The
* alternative is to read a smaller seed from /dev/random at startup,
* and use an internal pseudorandom generator. That
* would be friendlier to other applications, but would not buy as
* more security, as /dev/urandom should degenerate to a fairly strong
* pseudorandom generator when it runs out of entropy. */
struct randomness *
make_device_random(const char *device)
{
int fd = open(device, O_RDONLY);
if (fd < 0)
{
werror("make_device_random: Failed to open '%z' (errno = %i): %z\n",
device, errno, STRERROR(errno));
return NULL;
}
else
{
NEW(device_random, self);
self->super.random = do_device_random;
/* The quality depends on the used device. */
self->super.quality = 2;
self->fd = fd;
return &self->super;
}
}
/* GABA:
(class
(name arcfour_random)
(super randomness_with_poll)
(vars
(e object exception_handler)
; The pool that is used to create the output bytes
(pool . "struct arcfour_ctx")
; Accumulate randomness here before it is added to the main
; pool
(staging_area object hash_instance)
(staging_count . unsigned)))
*/
#define STAGE_THRESHOLD 100
static void
do_arcfour_random(struct randomness *r, UINT32 length, UINT8 *dst)
{
CAST(arcfour_random, self, r);
self->staging_count += RANDOM_POLL_FAST(self->super.poller, self->staging_area);
if (self->staging_count > STAGE_THRESHOLD)
{
/* Pour the collected randomness into the pool */
UINT8 *buf = alloca(self->staging_area->hash_size);
verbose("do_arcfour_random: Pouring staging area into pool.\n");
/* Get some data out of the pool, in order to keep any entropy
* there. */
arcfour_stream(&self->pool, self->staging_area->hash_size, buf);
HASH_UPDATE(self->staging_area, self->staging_area->hash_size, buf);
HASH_DIGEST(self->staging_area, buf);
arcfour_set_key(&self->pool, self->staging_area->hash_size, buf);
self->staging_count = 0;
}
arcfour_stream(&self->pool, length, dst);
}
static void
do_arcfour_random_slow(struct randomness *r, UINT32 length, UINT8 *dst)
{
CAST(arcfour_random, self, r);
unsigned count = RANDOM_POLL_SLOW(self->super.poller, self->staging_area);
debug("arcfour_random: entropy estimate for initialization: %i bits.\n",
count);
if (count < STAGE_THRESHOLD)
{
const struct exception low_entropy =
STATIC_EXCEPTION(EXC_RANDOMNESS_LOW_ENTROPY,
"Could not get enough entropy from the environment.");
EXCEPTION_RAISE(self->e, &low_entropy);
}
else
self->super.super.quality = 1;
{
/* Initialize the pool. */
UINT8 *buf = alloca(self->staging_area->hash_size);
verbose("do_arcfour_random_slow: Initalizing randomness pool.\n");
HASH_DIGEST(self->staging_area, buf);
arcfour_set_key(&self->pool, self->staging_area->hash_size, buf);
self->staging_count = 0;
}
self->super.super.random = do_arcfour_random;
arcfour_stream(&self->pool, length, dst);
}
struct randomness_with_poll *
make_arcfour_random(struct random_poll *poller,
struct hash_algorithm *hash,
struct exception_handler *e)
{
NEW(arcfour_random, self);
self->super.super.random = do_arcfour_random_slow;
self->super.super.quality = 0;
self->super.poller = poller;
self->e = e;
self->staging_area = MAKE_HASH(hash);
self->staging_count = 0;
return &self->super;
}
#if 0
struct randomness *
make_reasonably_random(void)
{
struct randomness *r = make_device_random("/dev/urandom");
if (r)
r->quality = 1;
else
{
werror("Warning: Falling back to an insecure pseudorandom generator.\n");
r = make_poor_random(&sha1_algorithm, NULL);
}
return r;
}
#endif
struct randomness_with_poll *
make_default_random(struct reap *reaper,
struct exception_handler *e)
{
struct random_poll *poller = make_unix_random(reaper);
/* FIXME: Move away from using rc4. */
return make_arcfour_random(poller, &sha1_algorithm, e);
}
#include "randomness.c.x"
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment