diff options
author | obrien <obrien@FreeBSD.org> | 2013-07-29 20:26:27 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2013-07-29 20:26:27 +0000 |
commit | 721ce839c7c49ecca90b66a4523be0e6e29c057e (patch) | |
tree | 7321ee5c53e41f64a4e3a37d1e501321672bb5af /sys/dev/random/randomdev_soft.c | |
parent | f6b004c36a12554e599bc79d3f4efc2047574d1b (diff) | |
download | FreeBSD-src-721ce839c7c49ecca90b66a4523be0e6e29c057e.zip FreeBSD-src-721ce839c7c49ecca90b66a4523be0e6e29c057e.tar.gz |
Decouple yarrow from random(4) device.
* Make Yarrow an optional kernel component -- enabled by "YARROW_RNG" option.
The files sha2.c, hash.c, randomdev_soft.c and yarrow.c comprise yarrow.
* random(4) device doesn't really depend on rijndael-*. Yarrow, however, does.
* Add random_adaptors.[ch] which is basically a store of random_adaptor's.
random_adaptor is basically an adapter that plugs in to random(4).
random_adaptor can only be plugged in to random(4) very early in bootup.
Unplugging random_adaptor from random(4) is not supported, and is probably a
bad idea anyway, due to potential loss of entropy pools.
We currently have 3 random_adaptors:
+ yarrow
+ rdrand (ivy.c)
+ nehemeiah
* Remove platform dependent logic from probe.c, and move it into
corresponding registration routines of each random_adaptor provider.
probe.c doesn't do anything other than picking a specific random_adaptor
from a list of registered ones.
* If the kernel doesn't have any random_adaptor adapters present then the
creation of /dev/random is postponed until next random_adaptor is kldload'ed.
* Fix randomdev_soft.c to refer to its own random_adaptor, instead of a
system wide one.
Submitted by: arthurmesh@gmail.com, obrien
Obtained from: Juniper Networks
Reviewed by: obrien
Diffstat (limited to 'sys/dev/random/randomdev_soft.c')
-rw-r--r-- | sys/dev/random/randomdev_soft.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c index ac48214..e2a3925 100644 --- a/sys/dev/random/randomdev_soft.c +++ b/sys/dev/random/randomdev_soft.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kthread.h> #include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> #include <sys/mutex.h> #include <sys/poll.h> #include <sys/proc.h> @@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <machine/cpu.h> +#include <dev/random/random_adaptors.h> #include <dev/random/randomdev.h> #include <dev/random/randomdev_soft.h> @@ -63,7 +65,7 @@ static int random_yarrow_poll(int event,struct thread *td); static int random_yarrow_block(int flag); static void random_yarrow_flush_reseed(void); -struct random_systat random_yarrow = { +struct random_adaptor random_yarrow = { .ident = "Software, Yarrow", .init = random_yarrow_init, .deinit = random_yarrow_deinit, @@ -103,7 +105,7 @@ static int random_kthread_control = 0; static struct proc *random_kthread_proc; /* List for the dynamic sysctls */ -struct sysctl_ctx_list random_clist; +static struct sysctl_ctx_list random_clist; /* ARGSUSED */ static int @@ -120,25 +122,20 @@ random_yarrow_init(void) { int error, i; struct harvest *np; - struct sysctl_oid *random_o, *random_sys_o, *random_sys_harvest_o; + struct sysctl_oid *random_sys_o, *random_sys_harvest_o; enum esource e; - random_o = SYSCTL_ADD_NODE(&random_clist, - SYSCTL_STATIC_CHILDREN(_kern), - OID_AUTO, "random", CTLFLAG_RW, 0, - "Software Random Number Generator"); - - random_yarrow_init_alg(&random_clist, random_o); + random_yarrow_init_alg(&random_clist); random_sys_o = SYSCTL_ADD_NODE(&random_clist, - SYSCTL_CHILDREN(random_o), + SYSCTL_STATIC_CHILDREN(_kern_random), OID_AUTO, "sys", CTLFLAG_RW, 0, "Entropy Device Parameters"); SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_o), OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW, - &random_systat->seeded, 1, random_check_boolean, "I", + &random_yarrow.seeded, 1, random_check_boolean, "I", "Seeded State"); random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist, @@ -362,10 +359,10 @@ random_yarrow_write(void *buf, int count) void random_yarrow_unblock(void) { - if (!random_systat->seeded) { - random_systat->seeded = 1; - selwakeuppri(&random_systat->rsel, PUSER); - wakeup(random_systat); + if (!random_yarrow.seeded) { + random_yarrow.seeded = 1; + selwakeuppri(&random_yarrow.rsel, PUSER); + wakeup(&random_yarrow); } (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, ARC4_ENTR_HAVE); @@ -377,10 +374,10 @@ random_yarrow_poll(int events, struct thread *td) int revents = 0; mtx_lock(&random_reseed_mtx); - if (random_systat->seeded) + if (random_yarrow.seeded) revents = events & (POLLIN | POLLRDNORM); else - selrecord(td, &random_systat->rsel); + selrecord(td, &random_yarrow.rsel); mtx_unlock(&random_reseed_mtx); return revents; @@ -394,12 +391,12 @@ random_yarrow_block(int flag) mtx_lock(&random_reseed_mtx); /* Blocking logic */ - while (!random_systat->seeded && !error) { + while (!random_yarrow.seeded && !error) { if (flag & O_NONBLOCK) error = EWOULDBLOCK; else { printf("Entropy device is blocking.\n"); - error = msleep(random_systat, + error = msleep(&random_yarrow, &random_reseed_mtx, PUSER | PCATCH, "block", 0); } @@ -420,3 +417,30 @@ random_yarrow_flush_reseed(void) random_yarrow_reseed(); } + +static int +yarrow_modevent(module_t mod, int type, void *unused) +{ + + switch (type) { + case MOD_LOAD: + random_adaptor_register("yarrow", &random_yarrow); + /* + * For statically built kernels that contain both random.ko and + * *_rng.ko, this event handler will do nothing, since + * random.ko is loaded after *_rng.ko's, and hence hasn't yet + * registered for this event. + * + * In case where both random.ko and *_rng.ko are built as + * modules, random.ko is loaded prior to *_rng.ko's (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); + return (0); + } + + return (EINVAL); +} + +RANDOM_ADAPTOR_MODULE(yarrow, yarrow_modevent, 1); |