From owner-svn-src-projects@FreeBSD.ORG Sun Dec 1 17:29:04 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B46EC121; Sun, 1 Dec 2013 17:29:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 9F3FE1108; Sun, 1 Dec 2013 17:29:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rB1HT4Et029959; Sun, 1 Dec 2013 17:29:04 GMT (envelope-from markm@svn.freebsd.org) Received: (from markm@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rB1HT13E029926; Sun, 1 Dec 2013 17:29:01 GMT (envelope-from markm@svn.freebsd.org) Message-Id: <201312011729.rB1HT13E029926@svn.freebsd.org> From: Mark Murray Date: Sun, 1 Dec 2013 17:29:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r258801 - in projects/random_number_generator/sys: conf dev/random X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Dec 2013 17:29:04 -0000 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 #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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include /* 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<= 0; i--) - sbuf_cat(&sbuf, (harvest_source_mask & (1<= 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<= 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<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 #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 ***