summaryrefslogtreecommitdiffstats
path: root/sys/dev/random/randomdev_soft.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/random/randomdev_soft.c')
-rw-r--r--sys/dev/random/randomdev_soft.c156
1 files changed, 107 insertions, 49 deletions
diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c
index 7e537fe..9e5a5fd 100644
--- a/sys/dev/random/randomdev_soft.c
+++ b/sys/dev/random/randomdev_soft.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2009 Mark R V Murray
+ * Copyright (c) 2000-2013 Mark R V Murray
* Copyright (c) 2004 Robert N. M. Watson
* All rights reserved.
*
@@ -26,6 +26,12 @@
*
*/
+#if !defined(YARROW_RNG) && !defined(FORTUNA_RNG)
+#define YARROW_RNG
+#elif defined(YARROW_RNG) && defined(FORTUNA_RNG)
+#error "Must define either YARROW_RNG or FORTUNA_RNG"
+#endif
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -54,30 +60,56 @@ __FBSDID("$FreeBSD$");
#include <dev/random/random_adaptors.h>
#include <dev/random/randomdev.h>
#include <dev/random/randomdev_soft.h>
+#if defined(YARROW_RNG)
+#include <dev/random/yarrow.h>
+#endif
+#if defined(FORTUNA_RNG)
+#include <dev/random/fortuna.h>
+#endif
#define RANDOM_FIFO_MAX 256 /* How many events to queue up */
static void random_kthread(void *);
-static void
-random_harvest_internal(u_int64_t, const void *, u_int,
+static void random_harvest_internal(u_int64_t, const void *, u_int,
u_int, u_int, enum esource);
-static int random_yarrow_poll(int event,struct thread *td);
-static int random_yarrow_block(int flag);
-static void random_yarrow_flush_reseed(void);
+static int randomdev_poll(int event, struct thread *td);
+static int randomdev_block(int flag);
+static void randomdev_flush_reseed(void);
-struct random_adaptor random_yarrow = {
+#if defined(YARROW_RNG)
+static struct random_adaptor random_context = {
.ident = "Software, Yarrow",
- .init = random_yarrow_init,
- .deinit = random_yarrow_deinit,
- .block = random_yarrow_block,
+ .init = randomdev_init,
+ .deinit = randomdev_deinit,
+ .block = randomdev_block,
.read = random_yarrow_read,
- .write = random_yarrow_write,
- .poll = random_yarrow_poll,
- .reseed = random_yarrow_flush_reseed,
- .seeded = 1,
+ .write = randomdev_write,
+ .poll = randomdev_poll,
+ .reseed = randomdev_flush_reseed,
+ .seeded = 0,
+};
+#define RANDOM_MODULE_NAME yarrow
+#define RANDOM_CSPRNG_NAME "yarrow"
+#endif
+
+#if defined(FORTUNA_RNG)
+static struct random_adaptor random_context = {
+ .ident = "Software, Fortuna",
+ .init = randomdev_init,
+ .deinit = randomdev_deinit,
+ .block = randomdev_block,
+ .read = random_fortuna_read,
+ .write = randomdev_write,
+ .poll = randomdev_poll,
+ .reseed = randomdev_flush_reseed,
+ .seeded = 0,
};
+#define RANDOM_MODULE_NAME fortuna
+#define RANDOM_CSPRNG_NAME "fortuna"
-MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers");
+#endif
+
+MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers for " RANDOM_CSPRNG_NAME);
/*
* The harvest mutex protects the consistency of the entropy fifos and
@@ -116,16 +148,20 @@ random_check_boolean(SYSCTL_HANDLER_ARGS)
return sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
}
-/* ARGSUSED */
void
-random_yarrow_init(void)
+randomdev_init(void)
{
int error, i;
struct harvest *np;
struct sysctl_oid *random_sys_o, *random_sys_harvest_o;
enum esource e;
+#if defined(YARROW_RNG)
random_yarrow_init_alg(&random_clist);
+#endif
+#if defined(FORTUNA_RNG)
+ random_fortuna_init_alg(&random_clist);
+#endif
random_sys_o = SYSCTL_ADD_NODE(&random_clist,
SYSCTL_STATIC_CHILDREN(_kern_random),
@@ -135,7 +171,7 @@ random_yarrow_init(void)
SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_sys_o),
OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW,
- &random_yarrow.seeded, 1, random_check_boolean, "I",
+ &random_context.seeded, 1, random_check_boolean, "I",
"Seeded State");
random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist,
@@ -156,13 +192,18 @@ random_yarrow_init(void)
SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_sys_harvest_o),
OID_AUTO, "interrupt", CTLTYPE_INT | CTLFLAG_RW,
- &harvest.interrupt, 1, random_check_boolean, "I",
+ &harvest.interrupt, 0, random_check_boolean, "I",
"Harvest IRQ entropy");
SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_sys_harvest_o),
OID_AUTO, "swi", CTLTYPE_INT | CTLFLAG_RW,
&harvest.swi, 0, random_check_boolean, "I",
"Harvest SWI entropy");
+ SYSCTL_ADD_PROC(&random_clist,
+ SYSCTL_CHILDREN(random_sys_harvest_o),
+ OID_AUTO, "namei", CTLTYPE_INT | CTLFLAG_RW,
+ &harvest.namei, 0, random_check_boolean, "I",
+ "Harvest namei cache entropy");
/* Initialise the harvest fifos */
STAILQ_INIT(&emptyfifo.head);
@@ -180,24 +221,23 @@ random_yarrow_init(void)
/* Start the hash/reseed thread */
error = kproc_create(random_kthread, NULL,
- &random_kthread_proc, RFHIGHPID, 0, "yarrow");
+ &random_kthread_proc, RFHIGHPID, 0, RANDOM_CSPRNG_NAME);
if (error != 0)
panic("Cannot create entropy maintenance thread.");
/* Register the randomness harvesting routine */
- random_yarrow_init_harvester(random_harvest_internal,
- random_yarrow_read);
+ randomdev_init_harvester(random_harvest_internal,
+ random_context.read);
}
-/* ARGSUSED */
void
-random_yarrow_deinit(void)
+randomdev_deinit(void)
{
struct harvest *np;
enum esource e;
/* Deregister the randomness harvesting routine */
- random_yarrow_deinit_harvester();
+ randomdev_deinit_harvester();
/*
* Command the hash/reseed thread to end and wait for it to finish
@@ -219,7 +259,12 @@ random_yarrow_deinit(void)
}
}
+#if defined(YARROW_RNG)
random_yarrow_deinit_alg();
+#endif
+#if defined(FORTUNA_RNG)
+ random_fortuna_deinit_alg();
+#endif
mtx_destroy(&harvest_mtx);
@@ -298,10 +343,7 @@ random_harvest_internal(u_int64_t somecounter, const void *entropy,
{
struct harvest *event;
- KASSERT(origin == RANDOM_START || origin == RANDOM_WRITE ||
- origin == RANDOM_KEYBOARD || origin == RANDOM_MOUSE ||
- origin == RANDOM_NET || origin == RANDOM_INTERRUPT ||
- origin == RANDOM_PURE,
+ KASSERT(origin >= RANDOM_START && origin <= RANDOM_PURE,
("random_harvest_internal: origin %d invalid\n", origin));
/* Lockless read to avoid lock operations if fifo is full. */
@@ -311,12 +353,13 @@ random_harvest_internal(u_int64_t somecounter, const void *entropy,
mtx_lock_spin(&harvest_mtx);
/*
- * Don't make the harvest queues too big - help to prevent low-grade
+ * Don't make the harvest queues too big - help to thwart low-grade
* entropy swamping
*/
if (harvestfifo[origin].count < RANDOM_FIFO_MAX) {
event = STAILQ_FIRST(&emptyfifo.head);
if (event != NULL) {
+ count = MIN(count, HARVESTSIZE);
/* Add the harvested data to the fifo */
STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
harvestfifo[origin].count++;
@@ -326,10 +369,20 @@ random_harvest_internal(u_int64_t somecounter, const void *entropy,
event->frac = frac;
event->source = origin;
- /* XXXX Come back and make this dynamic! */
- count = MIN(count, HARVESTSIZE);
memcpy(event->entropy, entropy, count);
+#if 1
+ {
+ int i;
+ printf("Harvest:%16jX ", event->somecounter);
+ for (i = 0; i < event->size; i++)
+ printf("%02X", event->entropy[i]);
+ for (; i < 16; i++)
+ printf(" ");
+ printf(" %2d 0x%2X.%03X %02X\n", event->size, event->bits, event->frac, event->source);
+ }
+#endif
+
STAILQ_INSERT_TAIL(&harvestfifo[origin].head,
event, next);
}
@@ -338,7 +391,7 @@ random_harvest_internal(u_int64_t somecounter, const void *entropy,
}
void
-random_yarrow_write(void *buf, int count)
+randomdev_write(void *buf, int count)
{
int i;
u_int chunk;
@@ -357,46 +410,46 @@ random_yarrow_write(void *buf, int count)
}
void
-random_yarrow_unblock(void)
+randomdev_unblock(void)
{
- if (!random_yarrow.seeded) {
- random_yarrow.seeded = 1;
- selwakeuppri(&random_yarrow.rsel, PUSER);
- wakeup(&random_yarrow);
+ if (!random_context.seeded) {
+ random_context.seeded = 1;
+ selwakeuppri(&random_context.rsel, PUSER);
+ wakeup(&random_context);
}
(void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE,
ARC4_ENTR_HAVE);
}
static int
-random_yarrow_poll(int events, struct thread *td)
+randomdev_poll(int events, struct thread *td)
{
int revents = 0;
mtx_lock(&random_reseed_mtx);
- if (random_yarrow.seeded)
+ if (random_context.seeded)
revents = events & (POLLIN | POLLRDNORM);
else
- selrecord(td, &random_yarrow.rsel);
+ selrecord(td, &random_context.rsel);
mtx_unlock(&random_reseed_mtx);
return revents;
}
static int
-random_yarrow_block(int flag)
+randomdev_block(int flag)
{
int error = 0;
mtx_lock(&random_reseed_mtx);
/* Blocking logic */
- while (!random_yarrow.seeded && !error) {
+ while (!random_context.seeded && !error) {
if (flag & O_NONBLOCK)
error = EWOULDBLOCK;
else {
printf("Entropy device is blocking.\n");
- error = msleep(&random_yarrow,
+ error = msleep(&random_context,
&random_reseed_mtx,
PUSER | PCATCH, "block", 0);
}
@@ -408,23 +461,28 @@ random_yarrow_block(int flag)
/* Helper routine to perform explicit reseeds */
static void
-random_yarrow_flush_reseed(void)
+randomdev_flush_reseed(void)
{
/* Command a entropy queue flush and wait for it to finish */
random_kthread_control = 1;
while (random_kthread_control)
pause("-", hz / 10);
+#if defined(YARROW_RNG)
random_yarrow_reseed();
+#endif
+#if defined(FORTUNA_RNG)
+ random_fortuna_reseed();
+#endif
}
static int
-yarrow_modevent(module_t mod, int type, void *unused)
+randomdev_modevent(module_t mod, int type, void *unused)
{
switch (type) {
case MOD_LOAD:
- random_adaptor_register("yarrow", &random_yarrow);
+ random_adaptor_register(RANDOM_CSPRNG_NAME, &random_context);
/*
* For statically built kernels that contain both device
* random and options PADLOCK_RNG/RDRAND_RNG/etc..,
@@ -437,11 +495,11 @@ yarrow_modevent(module_t mod, int type, void *unused)
* (by dependency). This event handler is there to delay
* creation of /dev/{u,}random and attachment of this *_rng.ko.
*/
- EVENTHANDLER_INVOKE(random_adaptor_attach, &random_yarrow);
+ EVENTHANDLER_INVOKE(random_adaptor_attach, &random_context);
return (0);
}
return (EINVAL);
}
-RANDOM_ADAPTOR_MODULE(yarrow, yarrow_modevent, 1);
+RANDOM_ADAPTOR_MODULE(RANDOM_MODULE_NAME, randomdev_modevent, 1);
OpenPOWER on IntegriCloud