svn commit: r258801 - in projects/random_number_generator/sys: conf dev/random
Mark Murray
markm at FreeBSD.org
Sun Dec 1 17:29:04 UTC 2013
Author: markm
Date: Sun Dec 1 17:29:00 2013
New Revision: 258801
URL: http://svnweb.freebsd.org/changeset/base/258801
Log:
This is now working! Fortuna too!
* Fix use of mutexes (what was I smoking?)
* Tidy up static vraibles; move around a bit (mutexes, sysctl stuff).
* Add debugging code.
Unit tests are now broken; I'll fix those in my Copious Free Time(tm).
Testers and reviewers welcome.
To follow:
* More sysctls for instrumentation and control.
* Final tidy-up pass (I'll throw lint at this too).
Modified:
projects/random_number_generator/sys/conf/NOTES
projects/random_number_generator/sys/conf/files
projects/random_number_generator/sys/dev/random/dummy_rng.c
projects/random_number_generator/sys/dev/random/fortuna.c
projects/random_number_generator/sys/dev/random/fortuna.h
projects/random_number_generator/sys/dev/random/ivy.c
projects/random_number_generator/sys/dev/random/live_entropy_sources.c
projects/random_number_generator/sys/dev/random/live_entropy_sources.h
projects/random_number_generator/sys/dev/random/nehemiah.c
projects/random_number_generator/sys/dev/random/random_adaptors.c
projects/random_number_generator/sys/dev/random/random_adaptors.h
projects/random_number_generator/sys/dev/random/random_harvestq.c
projects/random_number_generator/sys/dev/random/randomdev.c
projects/random_number_generator/sys/dev/random/randomdev.h
projects/random_number_generator/sys/dev/random/randomdev_soft.c
projects/random_number_generator/sys/dev/random/randomdev_soft.h
projects/random_number_generator/sys/dev/random/yarrow.c
projects/random_number_generator/sys/dev/random/yarrow.h
Modified: projects/random_number_generator/sys/conf/NOTES
==============================================================================
--- projects/random_number_generator/sys/conf/NOTES Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/conf/NOTES Sun Dec 1 17:29:00 2013 (r258801)
@@ -2958,6 +2958,6 @@ options BROOKTREE_ALLOC_PAGES=(217*4+1)
options MAXFILES=999
# Random number generator
-options RANDOM_YARROW # Yarrow RNG
-##options RANDOM_FORTUNA # Fortuna RNG - not yet implemented
+options RANDOM_YARROW # Yarrow RNG (Default)
+options RANDOM_FORTUNA # Fortuna RNG
options RANDOM_DEBUG # Debugging messages
Modified: projects/random_number_generator/sys/conf/files
==============================================================================
--- projects/random_number_generator/sys/conf/files Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/conf/files Sun Dec 1 17:29:00 2013 (r258801)
@@ -2049,6 +2049,7 @@ dev/random/live_entropy_sources.c option
dev/random/random_harvestq.c optional random
dev/random/randomdev_soft.c optional random
dev/random/yarrow.c optional random
+dev/random/fortuna.c optional random
dev/random/hash.c optional random
dev/rc/rc.c optional rc
dev/re/if_re.c optional re
Modified: projects/random_number_generator/sys/dev/random/dummy_rng.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/dummy_rng.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/dummy_rng.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -57,9 +57,13 @@ dummy_random(void)
/* ARGSUSED */
static void
-dummy_random_init(struct mtx *mtx __unused)
+dummy_random_init(void)
{
+#ifdef RANDOM_DEBUG
+ printf("random: %s\n", __func__);
+#endif
+
randomdev_init_reader(dummy_random_read_phony);
}
@@ -79,12 +83,12 @@ dummy_random_init(struct mtx *mtx __unus
* Caveat Emptor.
*/
u_int
-dummy_random_read_phony(void *buf, u_int count)
+dummy_random_read_phony(uint8_t *buf, u_int count)
{
/* If no entropy device is loaded, don't spam the console with warnings */
static int warned = 0;
u_long randval;
- int size, i;
+ size_t size, i;
if (!warned) {
log(LOG_WARNING, "random device not loaded/active; using insecure pseudo-random number generator\n");
@@ -94,10 +98,10 @@ dummy_random_read_phony(void *buf, u_int
/* srandom() is called in kern/init_main.c:proc0_post() */
/* Fill buf[] with random(9) output */
- for (i = 0; i < count; i+= (int)sizeof(u_long)) {
+ for (i = 0; i < count; i += sizeof(u_long)) {
randval = random();
size = MIN(count - i, sizeof(u_long));
- memcpy(&((char *)buf)[i], &randval, (size_t)size);
+ memcpy(buf + i, &randval, (size_t)size);
}
return (count);
Modified: projects/random_number_generator/sys/dev/random/fortuna.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/fortuna.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/fortuna.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -69,6 +69,13 @@ __FBSDID("$FreeBSD$");
#include <dev/random/yarrow.h>
#endif /* _KERNEL */
+#if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA)
+#define RANDOM_YARROW
+#elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA)
+#error "Must define either RANDOM_YARROW or RANDOM_FORTUNA"
+#endif
+#if defined(RANDOM_FORTUNA)
+
#define NPOOLS 32
#define MINPOOLSIZE 64
#define DEFPOOLSIZE 256
@@ -106,15 +113,15 @@ static struct fortuna_state {
/* Extras for the OS */
- /* The reseed thread mutex */
- mtx_t *reseed_mtx;
-
#ifdef _KERNEL
/* For use when 'pacing' the reseeds */
sbintime_t lasttime;
#endif
} fortuna_state;
+/* The random_reseed_mtx mutex protects seeding and polling/blocking. */
+static struct mtx random_reseed_mtx;
+
static struct fortuna_start_cache {
uint8_t junk[PAGE_SIZE];
size_t length;
@@ -122,11 +129,12 @@ static struct fortuna_start_cache {
} fortuna_start_cache;
#ifdef _KERNEL
+static struct sysctl_ctx_list random_clist;
RANDOM_CHECK_UINT(minpoolsize, MINPOOLSIZE, MAXPOOLSIZE);
#endif
void
-random_fortuna_init_alg(struct sysctl_ctx_list *clist, mtx_t *lock)
+random_fortuna_init_alg(void)
{
int i;
#ifdef _KERNEL
@@ -142,18 +150,18 @@ random_fortuna_init_alg(struct sysctl_ct
randomdev_hash_init(&fortuna_start_cache.hash);
/* Set up a lock for the reseed process */
- fortuna_state.reseed_mtx = lock;
+ mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF);
#ifdef _KERNEL
/* Fortuna parameters. Do not adjust these unless you have
* have a very good clue about what they do!
*/
- random_fortuna_o = SYSCTL_ADD_NODE(clist,
+ random_fortuna_o = SYSCTL_ADD_NODE(&random_clist,
SYSCTL_STATIC_CHILDREN(_kern_random),
OID_AUTO, "fortuna", CTLFLAG_RW, 0,
"Fortuna Parameters");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_fortuna_o), OID_AUTO,
"minpoolsize", CTLTYPE_UINT|CTLFLAG_RW,
&fortuna_state.minpoolsize, DEFPOOLSIZE,
@@ -192,6 +200,7 @@ random_fortuna_deinit_alg(void)
#ifdef RANDOM_DEBUG
printf("random: %s\n", __func__);
#endif
+ mtx_destroy(&random_reseed_mtx);
memset((void *)(&fortuna_state), 0, sizeof(struct fortuna_state));
}
@@ -203,7 +212,7 @@ random_fortuna_process_event(struct harv
u_int pl;
/* We must be locked for all this as plenty of state gets messed with */
- mtx_lock(fortuna_state.reseed_mtx);
+ mtx_lock(&random_reseed_mtx);
/* Accumulate the event into the appropriate pool
* where each event carries the destination information
@@ -217,7 +226,7 @@ random_fortuna_process_event(struct harv
fortuna_state.pool[pl].length = MIN(fortuna_state.pool[pl].length, MAXPOOLSIZE);
/* Done with state-messing */
- mtx_unlock(fortuna_state.reseed_mtx);
+ mtx_unlock(&random_reseed_mtx);
}
/* F&S - Reseed() */
@@ -233,7 +242,7 @@ reseed(uint8_t *junk, u_int length)
printf("random: %s %d %u\n", __func__, (fortuna_state.counter.whole != 0ULL), length);
#endif
#ifdef _KERNEL
- mtx_assert(fortuna_state.reseed_mtx, MA_OWNED);
+ mtx_assert(&random_reseed_mtx, MA_OWNED);
#endif
/* F&S - temp = H(K|s) */
@@ -313,7 +322,7 @@ random_fortuna_read(uint8_t *buf, u_int
u_int seedlength;
/* We must be locked for all this as plenty of state gets messed with */
- mtx_lock(fortuna_state.reseed_mtx);
+ mtx_lock(&random_reseed_mtx);
/* if buf == NULL and bytecount == 0 then this is the pre-read. */
/* if buf == NULL and bytecount != 0 then this is the post-read; ignore. */
@@ -378,7 +387,7 @@ random_fortuna_read(uint8_t *buf, u_int
else
random_fortuna_genrandom(buf, bytecount);
- mtx_unlock(fortuna_state.reseed_mtx);
+ mtx_unlock(&random_reseed_mtx);
}
/* Internal function to hand external entropy to the PRNG */
@@ -390,7 +399,7 @@ random_fortuna_write(uint8_t *buf, u_int
uintmax_t timestamp;
/* We must be locked for all this as plenty of state gets messed with */
- mtx_lock(fortuna_state.reseed_mtx);
+ mtx_lock(&random_reseed_mtx);
timestamp = get_cyclecount();
randomdev_hash_iterate(&fortuna_start_cache.hash, ×tamp, sizeof(timestamp));
@@ -415,7 +424,7 @@ random_fortuna_write(uint8_t *buf, u_int
reseed(fortuna_start_cache.junk, MIN(PAGE_SIZE, fortuna_start_cache.length));
memset((void *)(fortuna_start_cache.junk), 0, sizeof(fortuna_start_cache.junk));
- mtx_unlock(fortuna_state.reseed_mtx);
+ mtx_unlock(&random_reseed_mtx);
}
void
@@ -431,3 +440,5 @@ random_fortuna_seeded(void)
return (fortuna_state.counter.whole != 0ULL);
}
+
+#endif /* RANDOM_FORTUNA */
Modified: projects/random_number_generator/sys/dev/random/fortuna.h
==============================================================================
--- projects/random_number_generator/sys/dev/random/fortuna.h Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/fortuna.h Sun Dec 1 17:29:00 2013 (r258801)
@@ -33,7 +33,7 @@
typedef struct mtx mtx_t;
#endif
-void random_fortuna_init_alg(struct sysctl_ctx_list *, mtx_t *);
+void random_fortuna_init_alg(void);
void random_fortuna_deinit_alg(void);
void random_fortuna_read(uint8_t *, u_int);
void random_fortuna_write(uint8_t *, u_int);
Modified: projects/random_number_generator/sys/dev/random/ivy.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/ivy.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/ivy.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -133,4 +133,4 @@ rdrand_modevent(module_t mod, int type,
DEV_MODULE(rdrand, rdrand_modevent, NULL);
MODULE_VERSION(rdrand, 1);
-MODULE_DEPEND(rdrand, randomdev, 1, 1, 1);
+MODULE_DEPEND(rdrand, random_adaptors, 1, 1, 1);
Modified: projects/random_number_generator/sys/dev/random/live_entropy_sources.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/live_entropy_sources.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/live_entropy_sources.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/queue.h>
#include <sys/random.h>
#include <sys/sbuf.h>
@@ -169,8 +170,8 @@ live_entropy_sources_feed(void)
sx_sunlock(&les_lock);
}
-static void
-live_entropy_sources_init(void *unused)
+void
+live_entropy_sources_init(void)
{
SYSCTL_PROC(_kern_random, OID_AUTO, live_entropy_sources,
@@ -181,14 +182,9 @@ live_entropy_sources_init(void *unused)
sx_init(&les_lock, "live_entropy_sources");
}
-static void
-live_entropy_sources_deinit(void *unused)
+void
+live_entropy_sources_deinit(void)
{
sx_destroy(&les_lock);
}
-
-SYSINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
- live_entropy_sources_init, NULL);
-SYSUNINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
- live_entropy_sources_deinit, NULL);
Modified: projects/random_number_generator/sys/dev/random/live_entropy_sources.h
==============================================================================
--- projects/random_number_generator/sys/dev/random/live_entropy_sources.h Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/live_entropy_sources.h Sun Dec 1 17:29:00 2013 (r258801)
@@ -50,6 +50,8 @@ struct live_entropy_sources {
extern struct mtx live_mtx;
+void live_entropy_sources_init(void);
+void live_entropy_sources_deinit(void);
void live_entropy_source_register(struct live_entropy_source *);
void live_entropy_source_deregister(struct live_entropy_source *);
void live_entropy_sources_feed(void);
Modified: projects/random_number_generator/sys/dev/random/nehemiah.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/nehemiah.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/nehemiah.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -157,4 +157,4 @@ nehemiah_modevent(module_t mod, int type
DEV_MODULE(nehemiah, nehemiah_modevent, NULL);
MODULE_VERSION(nehemiah, 1);
-MODULE_DEPEND(nehemiah, randomdev, 1, 1, 1);
+MODULE_DEPEND(nehemiah, random_adaptors, 1, 1, 1);
Modified: projects/random_number_generator/sys/dev/random/random_adaptors.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/random_adaptors.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/random_adaptors.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/poll.h>
#include <sys/queue.h>
@@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <dev/random/randomdev.h>
#include <dev/random/random_adaptors.h>
+#include <dev/random/live_entropy_sources.h>
/* The random_adaptors_lock protects random_adaptors_list and friends and random_adaptor.
* We need a sleepable lock for uiomove/block/poll/sbuf/sysctl.
@@ -68,12 +70,6 @@ static struct mtx random_read_rate_mtx;
static int random_adaptor_read_rate_cache;
/* End of data items requiring random_readrate_mtx mutex protection */
-/* The random_reseed_mtx mutex protects seeding and polling/blocking.
- * This is passed into the software entropy hasher/processor.
- */
-static struct mtx random_reseed_mtx;
-/* End of data items requiring random_reseed_mtx mutex protection */
-
static struct selinfo rsel;
/* Utility routine to change active adaptor when the random_adaptors_list
@@ -147,7 +143,7 @@ random_adaptor_choose(void)
#endif
if (random_adaptor_previous != NULL)
(random_adaptor_previous->ra_deinit)();
- (random_adaptor->ra_init)(&random_reseed_mtx);
+ (random_adaptor->ra_init)();
}
}
@@ -200,12 +196,14 @@ random_adaptor_read(struct cdev *dev __u
int c, error;
ssize_t nbytes;
+#ifdef RANDOM_DEBUG_VERBOSE
+ printf("random: %s %ld\n", __func__, uio->uio_resid);
+#endif
+
KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__));
sx_slock(&random_adaptors_lock);
- mtx_lock(&random_reseed_mtx);
-
/* Let the entropy source do any pre-read setup. */
(random_adaptor->ra_read)(NULL, 0);
@@ -218,14 +216,12 @@ random_adaptor_read(struct cdev *dev __u
}
/* Sleep instead of going into a spin-frenzy */
- msleep(&random_adaptor, &random_reseed_mtx, PUSER | PCATCH, "block", hz/10);
+ tsleep(&random_adaptor, PUSER | PCATCH, "block", hz/10);
/* keep tapping away at the pre-read until we seed/unblock. */
(random_adaptor->ra_read)(NULL, 0);
}
- mtx_unlock(&random_reseed_mtx);
-
mtx_lock(&random_read_rate_mtx);
/* The read-rate stuff is a rough indication of the instantaneous read rate,
@@ -284,6 +280,10 @@ random_adaptor_write(struct cdev *dev __
int c, error = 0;
void *random_buf;
+#ifdef RANDOM_DEBUG
+ printf("random: %s %ld\n", __func__, uio->uio_resid);
+#endif
+
KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__));
sx_slock(&random_adaptors_lock);
@@ -291,11 +291,14 @@ random_adaptor_write(struct cdev *dev __
random_buf = (void *)malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK);
while (uio->uio_resid > 0) {
- c = MIN((int)uio->uio_resid, PAGE_SIZE);
+ c = MIN(uio->uio_resid, PAGE_SIZE);
error = uiomove(random_buf, c, uio);
if (error)
break;
(random_adaptor->ra_write)(random_buf, c);
+
+ /* Introduce an annoying delay to stop swamping */
+ tsleep(&random_adaptor, PUSER | PCATCH, "block", hz/10);
}
free(random_buf, M_ENTROPY);
@@ -310,17 +313,21 @@ int
random_adaptor_poll(struct cdev *dev __unused, int events, struct thread *td __unused)
{
+#ifdef RANDOM_DEBUG
+ printf("random: %s\n", __func__);
+#endif
+
KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__));
sx_slock(&random_adaptors_lock);
- mtx_lock(&random_reseed_mtx);
+
if (events & (POLLIN | POLLRDNORM)) {
if (random_adaptor->ra_seeded())
events &= (POLLIN | POLLRDNORM);
else
selrecord(td, &rsel);
}
- mtx_unlock(&random_reseed_mtx);
+
sx_sunlock(&random_adaptors_lock);
return (events);
@@ -331,8 +338,6 @@ void
random_adaptor_unblock(void)
{
- mtx_assert(&random_reseed_mtx, MA_OWNED);
-
selwakeuppri(&rsel, PUSER);
wakeup(&random_adaptor);
printf("random: unblocking device.\n");
@@ -385,46 +390,53 @@ random_sysctl_active_adaptor_handler(SYS
return (error);
}
-/* ARGSUSED */
-static void
-random_adaptors_init(void *unused __unused)
+void
+random_adaptors_init(void)
{
+#ifdef RANDOM_DEBUG
+ printf("random: %s\n", __func__);
+#endif
+
SYSCTL_PROC(_kern_random, OID_AUTO, adaptors,
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, 0, random_sysctl_adaptors_handler, "",
+ NULL, 0, random_sysctl_adaptors_handler, "A",
"Random Number Generator adaptors");
SYSCTL_PROC(_kern_random, OID_AUTO, active_adaptor,
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, 0, random_sysctl_active_adaptor_handler, "",
+ NULL, 0, random_sysctl_active_adaptor_handler, "A",
"Active Random Number Generator Adaptor");
sx_init(&random_adaptors_lock, "random_adaptors");
- mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF);
+ mtx_init(&random_read_rate_mtx, "read rate mutex", NULL, MTX_DEF);
/* The dummy adaptor is not a module by itself, but part of the
* randomdev module.
*/
random_adaptor_register("dummy", &randomdev_dummy);
+
+ live_entropy_sources_init();
}
-SYSINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
- random_adaptors_init, NULL);
-/* ARGSUSED */
-static void
-random_adaptors_deinit(void *unused __unused)
+void
+random_adaptors_deinit(void)
{
+
+#ifdef RANDOM_DEBUG
+ printf("random: %s\n", __func__);
+#endif
+
+ live_entropy_sources_deinit();
+
/* Don't do this! Panic will surely follow! */
/* random_adaptor_deregister("dummy"); */
- mtx_destroy(&random_reseed_mtx);
+ mtx_destroy(&random_read_rate_mtx);
sx_destroy(&random_adaptors_lock);
}
-SYSUNINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
- random_adaptors_deinit, NULL);
/*
* First seed.
@@ -459,9 +471,7 @@ random_adaptors_seed(void *unused __unus
KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__));
sx_slock(&random_adaptors_lock);
- mtx_lock(&random_reseed_mtx);
random_adaptor->ra_reseed();
- mtx_unlock(&random_reseed_mtx);
sx_sunlock(&random_adaptors_lock);
arc4rand(NULL, 0, 1);
Modified: projects/random_number_generator/sys/dev/random/random_adaptors.h
==============================================================================
--- projects/random_number_generator/sys/dev/random/random_adaptors.h Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/random_adaptors.h Sun Dec 1 17:29:00 2013 (r258801)
@@ -31,7 +31,7 @@
MALLOC_DECLARE(M_ENTROPY);
-typedef void random_adaptor_init_func_t(struct mtx *);
+typedef void random_adaptor_init_func_t(void);
typedef void random_adaptor_deinit_func_t(void);
typedef void random_adaptor_read_func_t(uint8_t *, u_int);
typedef void random_adaptor_write_func_t(uint8_t *, u_int);
@@ -58,6 +58,9 @@ struct random_adaptors {
/* Dummy "always-block" pseudo-device */
extern struct random_adaptor randomdev_dummy;
+void random_adaptors_init(void);
+void random_adaptors_deinit(void);
+
void random_adaptor_register(const char *, struct random_adaptor *);
void random_adaptor_deregister(const char *);
Modified: projects/random_number_generator/sys/dev/random/random_harvestq.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/random_harvestq.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/random_harvestq.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -90,7 +90,7 @@ void (*harvest_process_event)(struct har
/* Allow the sysadmin to select the broad category of
* entropy types to harvest.
*/
-static u_int harvest_source_mask = ((1<<RANDOM_ENVIRONMENTAL_END) - 1);
+static u_int harvest_source_mask = ((1U << RANDOM_ENVIRONMENTAL_END) - 1);
/* Pool count is used by anything needing to know how many entropy
* pools are currently being maintained.
@@ -172,7 +172,7 @@ random_harvestq_flush(void)
}
/* ARGSUSED */
-RANDOM_CHECK_UINT(harvestmask, 0, ((1<<RANDOM_ENVIRONMENTAL_END) - 1));
+RANDOM_CHECK_UINT(harvestmask, 0, ((1U << RANDOM_ENVIRONMENTAL_END) - 1));
/* ARGSUSED */
static int
@@ -184,8 +184,8 @@ random_print_harvestmask(SYSCTL_HANDLER_
error = sysctl_wire_old_buffer(req, 0);
if (error == 0) {
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
- for (i = 31; i >= 0; i--)
- sbuf_cat(&sbuf, (harvest_source_mask & (1<<i)) ? "1" : "0");
+ for (i = RANDOM_ENVIRONMENTAL_END - 1; i >= 0; i--)
+ sbuf_cat(&sbuf, (harvest_source_mask & (1U << i)) ? "1" : "0");
error = sbuf_finish(&sbuf);
sbuf_delete(&sbuf);
}
@@ -226,9 +226,10 @@ random_print_harvestmask_symbolic(SYSCTL
error = sysctl_wire_old_buffer(req, 0);
if (error == 0) {
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
- for (i = ENTROPYSOURCE - 1; i >= 0; i--)
- sbuf_cat(&sbuf, (i == ENTROPYSOURCE - 1) ? "" : ",");
- sbuf_cat(&sbuf, (harvest_source_mask & (1<<i)) ? random_source_descr[i] : "");
+ for (i = RANDOM_ENVIRONMENTAL_END - 1; i >= 0; i--) {
+ sbuf_cat(&sbuf, (i == RANDOM_ENVIRONMENTAL_END - 1) ? "" : ",");
+ sbuf_cat(&sbuf, (harvest_source_mask & (1U << i)) ? random_source_descr[i] : "");
+ }
error = sbuf_finish(&sbuf);
sbuf_delete(&sbuf);
}
@@ -257,7 +258,7 @@ random_harvestq_init(void (*event_proces
SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_sys_o),
OID_AUTO, "mask", CTLTYPE_UINT | CTLFLAG_RW,
- &harvest_source_mask, ((1<<RANDOM_ENVIRONMENTAL_END) - 1),
+ &harvest_source_mask, ((1U << RANDOM_ENVIRONMENTAL_END) - 1),
random_check_uint_harvestmask, "IU",
"Entropy harvesting mask");
@@ -374,7 +375,7 @@ random_harvestq_internal(const void *ent
("random_harvest_internal: origin %d invalid\n", origin));
/* Mask out unwanted sources */
- if (!(harvest_source_mask & (1<<origin)))
+ if (!(harvest_source_mask & (1U << origin)))
return;
/* Lockless check to avoid lock operations if queue is empty. */
Modified: projects/random_number_generator/sys/dev/random/randomdev.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/randomdev.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/randomdev.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -135,12 +135,15 @@ randomdev_modevent(module_t mod __unused
switch (type) {
case MOD_LOAD:
+ printf("random: entropy device infrastructure driver\n");
random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw,
RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0644, "random");
make_dev_alias(random_dev, "urandom"); /* compatibility */
+ random_adaptors_init();
break;
case MOD_UNLOAD:
+ random_adaptors_deinit();
destroy_dev(random_dev);
break;
@@ -156,8 +159,15 @@ randomdev_modevent(module_t mod __unused
return (error);
}
-/* Order is SI_ORDER_MIDDLE */
-DEV_MODULE(randomdev, randomdev_modevent, NULL);
+#define EARLY_2_DEV_MODULE(name, evh, arg) \
+static moduledata_t name##_mod = { \
+ #name, \
+ evh, \
+ arg \
+}; \
+DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND)
+
+EARLY_2_DEV_MODULE(randomdev, randomdev_modevent, NULL);
MODULE_VERSION(randomdev, 1);
/* ================
@@ -212,11 +222,11 @@ random_harvest(const void *entropy, u_in
*/
/* Hold the address of the routine which is actually called */
-static u_int (*read_func)(void *, u_int) = dummy_random_read_phony;
+static u_int (*read_func)(uint8_t *, u_int) = dummy_random_read_phony;
/* Initialise the reader when/if it is loaded */
void
-randomdev_init_reader(u_int (*reader)(void *, u_int))
+randomdev_init_reader(u_int (*reader)(uint8_t *, u_int))
{
read_func = reader;
Modified: projects/random_number_generator/sys/dev/random/randomdev.h
==============================================================================
--- projects/random_number_generator/sys/dev/random/randomdev.h Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/randomdev.h Sun Dec 1 17:29:00 2013 (r258801)
@@ -37,12 +37,12 @@ typedef void random_init_func_t(void);
typedef void random_deinit_func_t(void);
void randomdev_init_harvester(void (*)(const void *, u_int, u_int, enum random_entropy_source));
-void randomdev_init_reader(u_int (*)(void *, u_int));
+void randomdev_init_reader(u_int (*)(uint8_t *, u_int));
void randomdev_deinit_harvester(void);
void randomdev_deinit_reader(void);
/* Stub/fake routines for when no entropy processor is loaded */
-extern u_int dummy_random_read_phony(void *, u_int);
+extern u_int dummy_random_read_phony(uint8_t *, u_int);
/* kern.random sysctls */
#ifdef SYSCTL_DECL /* from sysctl.h */
Modified: projects/random_number_generator/sys/dev/random/randomdev_soft.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/randomdev_soft.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/randomdev_soft.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -95,46 +95,16 @@ static struct random_adaptor random_soft
.ra_deinit = randomdev_deinit,
};
-/* List for the dynamic sysctls */
-static struct sysctl_ctx_list random_clist;
-
-/* ARGSUSED */
-static int
-random_check_boolean(SYSCTL_HANDLER_ARGS)
-{
- if (oidp->oid_arg1 != NULL && *(u_int *)(oidp->oid_arg1) != 0)
- *(u_int *)(oidp->oid_arg1) = 1;
- return (sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req));
-}
-
void
-randomdev_init(struct mtx *mtx)
+randomdev_init(void)
{
- struct sysctl_oid *random_sys_o;
-
-#if defined(RANDOM_YARROW)
- random_yarrow_init_alg(&random_clist, mtx);
-#endif
-#if defined(RANDOM_FORTUNA)
- random_fortuna_init_alg(&random_clist, mtx);
-#endif
- random_sys_o = SYSCTL_ADD_NODE(&random_clist,
- 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_RD,
- &random_soft_processor.ra_seeded, 0, random_check_boolean, "I",
- "Seeded State");
-
- /* Register the randomness processing routine */
#if defined(RANDOM_YARROW)
+ random_yarrow_init_alg();
random_harvestq_init(random_yarrow_process_event, 2);
#endif
#if defined(RANDOM_FORTUNA)
+ random_fortuna_init_alg();
random_harvestq_init(random_fortuna_process_event, 32);
#endif
@@ -154,8 +124,6 @@ randomdev_deinit(void)
#if defined(RANDOM_FORTUNA)
random_fortuna_deinit_alg();
#endif
-
- sysctl_ctx_free(&random_clist);
}
/* ARGSUSED */
@@ -166,6 +134,7 @@ randomdev_soft_modevent(module_t mod __u
switch (type) {
case MOD_LOAD:
+ printf("random: SOFT: %s init()\n", RANDOM_CSPRNG_NAME);
random_adaptor_register(RANDOM_CSPRNG_NAME, &random_soft_processor);
break;
@@ -184,21 +153,21 @@ randomdev_soft_modevent(module_t mod __u
return (error);
}
-#define EARLY_DEV_MODULE(name, evh, arg) \
-static moduledata_t name##_mod = { \
- #name, \
- evh, \
- arg \
-}; \
-DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND)
+#define MID_DEV_MODULE(name, evh, arg) \
+static moduledata_t name##_mod = { \
+ #name, \
+ evh, \
+ arg \
+}; \
+DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
#if defined(RANDOM_YARROW)
-EARLY_DEV_MODULE(yarrow, randomdev_soft_modevent, NULL);
+MID_DEV_MODULE(yarrow, randomdev_soft_modevent, NULL);
MODULE_VERSION(yarrow, 1);
-MODULE_DEPEND(yarrow, randomdev, 1, 1, 1);
+MODULE_DEPEND(yarrow, random_adaptors, 1, 1, 1);
#endif
#if defined(RANDOM_FORTUNA)
-EARLY_DEV_MODULE(fortuna, randomdev_soft_modevent, NULL);
+MID_DEV_MODULE(fortuna, randomdev_soft_modevent, NULL);
MODULE_VERSION(fortuna, 1);
-MODULE_DEPEND(fortuna, randomdev, 1, 1, 1);
+MODULE_DEPEND(fortuna, random_adaptors, 1, 1, 1);
#endif
Modified: projects/random_number_generator/sys/dev/random/randomdev_soft.h
==============================================================================
--- projects/random_number_generator/sys/dev/random/randomdev_soft.h Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/randomdev_soft.h Sun Dec 1 17:29:00 2013 (r258801)
@@ -33,9 +33,7 @@
* specific to the entropy processor
*/
-void randomdev_init(struct mtx *);
+void randomdev_init(void);
void randomdev_deinit(void);
-extern struct mtx random_reseed_mtx;
-
#endif
Modified: projects/random_number_generator/sys/dev/random/yarrow.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/yarrow.c Sun Dec 1 17:28:28 2013 (r258800)
+++ projects/random_number_generator/sys/dev/random/yarrow.c Sun Dec 1 17:29:00 2013 (r258801)
@@ -69,6 +69,13 @@ __FBSDID("$FreeBSD$");
#include <dev/random/yarrow.h>
#endif /* _KERNEL */
+#if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA)
+#define RANDOM_YARROW
+#elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA)
+#error "Must define either RANDOM_YARROW or RANDOM_FORTUNA"
+#endif
+#if defined(RANDOM_YARROW)
+
#define TIMEBIN 16 /* max value for Pt/t */
#define FAST 0
@@ -99,17 +106,19 @@ static struct yarrow_state {
u_int thresh; /* pool reseed threshhold */
struct randomdev_hash hash; /* accumulated entropy */
} pool[2]; /* pool[0] is fast, pool[1] is slow */
- mtx_t *reseed_mtx; /* The reseed thread mutex */
int seeded;
+
+ struct start_cache {
+ uint8_t junk[KEYSIZE];
+ struct randomdev_hash hash;
+ } start_cache;
} yarrow_state;
-static struct yarrow_start_cache {
- uint8_t junk[PAGE_SIZE];
- size_t length;
- struct randomdev_hash hash;
-} yarrow_start_cache;
+/* The random_reseed_mtx mutex protects seeding and polling/blocking. */
+static struct mtx random_reseed_mtx;
#ifdef _KERNEL
+static struct sysctl_ctx_list random_clist;
RANDOM_CHECK_UINT(gengateinterval, 4, 64);
RANDOM_CHECK_UINT(bins, 2, 16);
RANDOM_CHECK_UINT(fastthresh, (BLOCKSIZE*8)/4, (BLOCKSIZE*8)); /* Bit counts */
@@ -123,7 +132,7 @@ static void generator_gate(void);
static void reseed(u_int);
void
-random_yarrow_init_alg(struct sysctl_ctx_list *clist, mtx_t *mtx)
+random_yarrow_init_alg(void)
{
int i, j;
#ifdef _KERNEL
@@ -134,12 +143,11 @@ random_yarrow_init_alg(struct sysctl_ctx
printf("random: %s\n", __func__);
#endif
- memset((void *)(yarrow_start_cache.junk), 0, PAGE_SIZE);
- yarrow_start_cache.length = 0U;
- randomdev_hash_init(&yarrow_start_cache.hash);
+ memset((void *)(yarrow_state.start_cache.junk), 0, KEYSIZE);
+ randomdev_hash_init(&yarrow_state.start_cache.hash);
/* Set up the lock for the reseed/gate state */
- yarrow_state.reseed_mtx = mtx;
+ mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF);
/* Start unseeded, therefore blocked. */
yarrow_state.seeded = 0;
@@ -148,40 +156,40 @@ random_yarrow_init_alg(struct sysctl_ctx
/* Yarrow parameters. Do not adjust these unless you have
* have a very good clue about what they do!
*/
- random_yarrow_o = SYSCTL_ADD_NODE(clist,
+ random_yarrow_o = SYSCTL_ADD_NODE(&random_clist,
SYSCTL_STATIC_CHILDREN(_kern_random),
OID_AUTO, "yarrow", CTLFLAG_RW, 0,
"Yarrow Parameters");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
"gengateinterval", CTLTYPE_INT|CTLFLAG_RW,
&yarrow_state.gengateinterval, 10,
random_check_uint_gengateinterval, "I",
"Generation gate interval");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
"bins", CTLTYPE_INT|CTLFLAG_RW,
&yarrow_state.bins, 10,
random_check_uint_bins, "I",
"Execution time tuner");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
"fastthresh", CTLTYPE_INT|CTLFLAG_RW,
&yarrow_state.pool[0].thresh, (3*(BLOCKSIZE*8))/4,
random_check_uint_fastthresh, "I",
"Fast reseed threshold");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
"slowthresh", CTLTYPE_INT|CTLFLAG_RW,
&yarrow_state.pool[1].thresh, (BLOCKSIZE*8),
random_check_uint_slowthresh, "I",
"Slow reseed threshold");
- SYSCTL_ADD_PROC(clist,
+ SYSCTL_ADD_PROC(&random_clist,
SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
"slowoverthresh", CTLTYPE_INT|CTLFLAG_RW,
&yarrow_state.slowoverthresh, 2,
@@ -195,6 +203,9 @@ random_yarrow_init_alg(struct sysctl_ctx
yarrow_state.pool[SLOW].thresh = (BLOCKSIZE*8);
yarrow_state.slowoverthresh = 2;
+ /* Ensure that the first time we read, we are gated. */
+ yarrow_state.outputblocks = yarrow_state.gengateinterval;
+
/* Initialise the fast and slow entropy pools */
for (i = FAST; i <= SLOW; i++) {
randomdev_hash_init(&yarrow_state.pool[i].hash);
@@ -213,7 +224,10 @@ random_yarrow_deinit_alg(void)
#ifdef RANDOM_DEBUG
printf("random: %s\n", __func__);
#endif
+ mtx_destroy(&random_reseed_mtx);
memset((void *)(&yarrow_state), 0, sizeof(struct yarrow_state));
+
+ sysctl_ctx_free(&random_clist);
}
static __inline void
@@ -223,7 +237,7 @@ random_yarrow_post_insert(void)
enum random_entropy_source src;
#ifdef _KERNEL
- mtx_assert(yarrow_state.reseed_mtx, MA_OWNED);
+ mtx_assert(&random_reseed_mtx, MA_OWNED);
#endif
/* Count the over-threshold sources in each pool */
for (pl = 0; pl < 2; pl++) {
@@ -249,7 +263,7 @@ random_yarrow_process_event(struct harve
{
u_int pl;
- mtx_lock(yarrow_state.reseed_mtx);
+ mtx_lock(&random_reseed_mtx);
/* Accumulate the event into the appropriate pool
* where each event carries the destination information.
@@ -262,12 +276,12 @@ random_yarrow_process_event(struct harve
random_yarrow_post_insert();
- mtx_unlock(yarrow_state.reseed_mtx);
+ mtx_unlock(&random_reseed_mtx);
}
-/* Process a block of raw stochastic data */
+/* Process a block of data suspected to be slightly stochastic */
static void
-random_yarrow_process_buffer(uint8_t *buf, u_int length, enum random_entropy_source src, u_int bits)
+random_yarrow_process_buffer(uint8_t *buf, u_int length)
{
static struct harvest_event event;
u_int i, pl;
@@ -277,20 +291,40 @@ random_yarrow_process_buffer(uint8_t *bu
* We lock against pool state modification which can happen
* during accumulation/reseeding and reading/regating
*/
- memset(event.he_entropy + 4, 0, HARVESTSIZE - 4);
- for (i = 0; i < (length + 3)/4; i++) {
+ memset(event.he_entropy + sizeof(uint32_t), 0, HARVESTSIZE - sizeof(uint32_t));
+ for (i = 0; i < length/sizeof(uint32_t); i++) {
event.he_somecounter = get_cyclecount();
- event.he_bits = bits;
- event.he_source = src;
- event.he_destination = harvest_destination[src]++;
- event.he_size = 4;
+ event.he_bits = 0; /* Fake */
+ event.he_source = RANDOM_CACHED;
+ event.he_destination = harvest_destination[RANDOM_CACHED]++;
+ event.he_size = sizeof(uint32_t);
*((uint32_t *)event.he_entropy) = *((uint32_t *)buf + i);
/* Do the actual entropy insertion */
pl = event.he_destination % 2;
randomdev_hash_iterate(&yarrow_state.pool[pl].hash, &event, sizeof(event));
- yarrow_state.pool[pl].source[src].bits += bits;
+#ifdef DONT_DO_THIS_HERE
+ /* Don't do this here - do it in bulk at the end */
+ yarrow_state.pool[pl].source[RANDOM_CACHED].bits += bits;
+#endif
+#ifdef RANDOM_DEBUG_VERBOSE
+ printf("random: %s - ", __func__);
+ printf(" %jX", event.he_somecounter);
+ printf(" %u", event.he_bits);
+ printf(" %u", event.he_source);
+ printf(" %u", event.he_destination);
+ printf(" %u", event.he_size);
+ printf(" %X", *((uint32_t *)(&event.he_entropy)));
+ printf("\n");
+#endif
+
}
+#ifdef RANDOM_DEBUG_VERBOSE
+ printf("random: %s - ", __func__);
+ printf(" bit contribution magical guess is %u\n", length >> 4);
+#endif
+ for (pl = FAST; pl <= SLOW; pl++)
+ yarrow_state.pool[pl].source[RANDOM_CACHED].bits += (length >> 4);
random_yarrow_post_insert();
}
@@ -312,7 +346,9 @@ reseed(u_int fastslow)
KASSERT(yarrow_state.pool[SLOW].thresh > 0, ("random: Yarrow slow threshold = 0"));
#ifdef RANDOM_DEBUG
- printf("random: %s - (%d) %s reseed\n", __func__, yarrow_state.seeded, (fastslow == FAST ? "FAST" : "SLOW"));
+#ifdef RANDOM_DEBUG_VERBOSE
+ printf("random: %s %s\n", __func__, (fastslow == FAST ? "FAST" : "SLOW"));
+#endif
if (!yarrow_state.seeded) {
printf("random: %s - fast - thresh %d,1 - ", __func__, yarrow_state.pool[FAST].thresh);
for (i = RANDOM_START; i < ENTROPYSOURCE; i++)
@@ -325,7 +361,7 @@ reseed(u_int fastslow)
}
#endif
#ifdef _KERNEL
- mtx_assert(yarrow_state.reseed_mtx, MA_OWNED);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list