From owner-svn-src-projects@FreeBSD.ORG Mon Nov 11 21:28:00 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id CC9546BF; Mon, 11 Nov 2013 21:28:00 +0000 (UTC) (envelope-from markm@FreeBSD.org) 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 B84D128D8; Mon, 11 Nov 2013 21:28:00 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rABLS0kP024478; Mon, 11 Nov 2013 21:28:00 GMT (envelope-from markm@svn.freebsd.org) Received: (from markm@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rABLRwJ6024454; Mon, 11 Nov 2013 21:27:58 GMT (envelope-from markm@svn.freebsd.org) Message-Id: <201311112127.rABLRwJ6024454@svn.freebsd.org> From: Mark Murray Date: Mon, 11 Nov 2013 21:27:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r258019 - in projects/random_number_generator/sys: conf dev/random modules/random sys vm 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.14 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: Mon, 11 Nov 2013 21:28:00 -0000 Author: markm Date: Mon Nov 11 21:27:57 2013 New Revision: 258019 URL: http://svnweb.freebsd.org/changeset/base/258019 Log: More fixing from code review. RWatson partially to blame^Wthank here. * Rename structure elements with a prefix so they are more easily recognised * Give (some/most) static/fileScope variables file_local names for uniqueness. * Remove the much-dislikes RWFILE mode. Now we'll need to add back some form of file writing. * Self-apply a cluebat and fix up locking. I haven't exhaustively checked this, but its better than it was before. Thanks Robert! * Add uma_(zalloc|zfree)_arg harvesting. This is wonderfully high-rate, but needs a hammering to make sure we aren't breaking things. Not quite finished in that it can't be disabled yet. Deleted: projects/random_number_generator/sys/dev/random/rwfile.c projects/random_number_generator/sys/dev/random/rwfile.h Modified: projects/random_number_generator/sys/conf/NOTES projects/random_number_generator/sys/conf/files projects/random_number_generator/sys/conf/options projects/random_number_generator/sys/dev/random/dummy_rng.c 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/random_harvestq.h 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/yarrow.c projects/random_number_generator/sys/dev/random/yarrow.h projects/random_number_generator/sys/modules/random/Makefile projects/random_number_generator/sys/sys/random.h projects/random_number_generator/sys/vm/uma_core.c Modified: projects/random_number_generator/sys/conf/NOTES ============================================================================== --- projects/random_number_generator/sys/conf/NOTES Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/conf/NOTES Mon Nov 11 21:27:57 2013 (r258019) @@ -2964,4 +2964,3 @@ options MAXFILES=999 options RANDOM_YARROW # Yarrow RNG ##options RANDOM_FORTUNA # Fortuna RNG - not yet implemented options RANDOM_DEBUG # Debugging messages -options RANDOM_RWFILE # Read and write entropy cache Modified: projects/random_number_generator/sys/conf/files ============================================================================== --- projects/random_number_generator/sys/conf/files Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/conf/files Mon Nov 11 21:27:57 2013 (r258019) @@ -2048,7 +2048,6 @@ dev/random/random_harvestq.c optional ra dev/random/randomdev_soft.c optional random dev/random/yarrow.c optional random dev/random/hash.c optional random -dev/random/rwfile.c optional random dev/rc/rc.c optional rc dev/re/if_re.c optional re dev/rndtest/rndtest.c optional rndtest Modified: projects/random_number_generator/sys/conf/options ============================================================================== --- projects/random_number_generator/sys/conf/options Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/conf/options Mon Nov 11 21:27:57 2013 (r258019) @@ -912,4 +912,3 @@ RCTL opt_global.h RANDOM_YARROW opt_random.h RANDOM_FORTUNA opt_random.h RANDOM_DEBUG opt_random.h -RANDOM_RWFILE opt_random.h Modified: projects/random_number_generator/sys/dev/random/dummy_rng.c ============================================================================== --- projects/random_number_generator/sys/dev/random/dummy_rng.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/dummy_rng.c Mon Nov 11 21:27:57 2013 (r258019) @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -95,14 +94,14 @@ dummy_random_deinit(void) mtx_destroy(&dummy_random_mtx); } -struct random_adaptor dummy_random = { - .ident = "Dummy entropy device", - .init = dummy_random_init, - .deinit = dummy_random_deinit, - .block = dummy_random_block, - .poll = dummy_random_poll, - .read = (random_read_func_t *)random_null_func, - .reseed = (random_reseed_func_t *)random_null_func, - .seeded = 0, /* This device can never be seeded */ - .priority = 1, /* Bottom priority, so goes to last position */ +struct random_adaptor randomdev_dummy = { + .ra_ident = "Dummy entropy device", + .ra_init = dummy_random_init, + .ra_deinit = dummy_random_deinit, + .ra_block = dummy_random_block, + .ra_poll = dummy_random_poll, + .ra_read = (random_adaptor_read_func_t *)random_null_func, + .ra_reseed = (random_adaptor_reseed_func_t *)random_null_func, + .ra_seeded = 0, /* This device can never be seeded */ + .ra_priority = 1, /* Bottom priority, so goes to last position */ }; Modified: projects/random_number_generator/sys/dev/random/ivy.c ============================================================================== --- projects/random_number_generator/sys/dev/random/ivy.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/ivy.c Mon Nov 11 21:27:57 2013 (r258019) @@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -57,9 +56,9 @@ __FBSDID("$FreeBSD$"); static int random_ivy_read(void *, int); static struct live_entropy_source random_ivy = { - .ident = "Hardware, Intel IvyBridge+ RNG", - .source = RANDOM_PURE_RDRAND, - .read = random_ivy_read + .les_ident = "Hardware, Intel IvyBridge+ RNG", + .les_source = RANDOM_PURE_RDRAND, + .les_read = random_ivy_read }; static inline int Modified: projects/random_number_generator/sys/dev/random/live_entropy_sources.c ============================================================================== --- projects/random_number_generator/sys/dev/random/live_entropy_sources.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/live_entropy_sources.c Mon Nov 11 21:27:57 2013 (r258019) @@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -50,44 +49,44 @@ __FBSDID("$FreeBSD$"); #include "live_entropy_sources.h" LIST_HEAD(les_head, live_entropy_sources); -static struct les_head sources = LIST_HEAD_INITIALIZER(sources); +static struct les_head les_sources = LIST_HEAD_INITIALIZER(les_sources); /* - * The live_lock protects the consistency of the "struct les_head sources" + * The live_lock protects the consistency of the "struct les_head les_sources" */ static struct sx les_lock; /* need a sleepable lock */ void live_entropy_source_register(struct live_entropy_source *rsource) { - struct live_entropy_sources *les; + struct live_entropy_sources *lles; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); - les = malloc(sizeof(struct live_entropy_sources), M_ENTROPY, M_WAITOK); - les->rsource = rsource; + lles = malloc(sizeof(struct live_entropy_sources), M_ENTROPY, M_WAITOK); + lles->lles_rsource = rsource; sx_xlock(&les_lock); - LIST_INSERT_HEAD(&sources, les, entries); + LIST_INSERT_HEAD(&les_sources, lles, lles_entries); sx_xunlock(&les_lock); } void live_entropy_source_deregister(struct live_entropy_source *rsource) { - struct live_entropy_sources *les = NULL; + struct live_entropy_sources *lles = NULL; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); sx_xlock(&les_lock); - LIST_FOREACH(les, &sources, entries) - if (les->rsource == rsource) { - LIST_REMOVE(les, entries); + LIST_FOREACH(lles, &les_sources, lles_entries) + if (lles->lles_rsource == rsource) { + LIST_REMOVE(lles, lles_entries); break; } sx_xunlock(&les_lock); - if (les != NULL) - free(les, M_ENTROPY); + if (lles != NULL) + free(lles, M_ENTROPY); } static int @@ -95,16 +94,16 @@ live_entropy_source_handler(SYSCTL_HANDL { /* XXX: FIX!! Fixed array size */ char buf[128]; - struct live_entropy_sources *les; + struct live_entropy_sources *lles; int count; sx_slock(&les_lock); buf[0] = '\0'; count = 0; - LIST_FOREACH(les, &sources, entries) { + LIST_FOREACH(lles, &les_sources, lles_entries) { strcat(buf, (count++ ? "," : "")); - strcat(buf, les->rsource->ident); + strcat(buf, lles->lles_rsource->les_ident); } sx_sunlock(&les_lock); @@ -129,9 +128,9 @@ live_entropy_source_handler(SYSCTL_HANDL void live_entropy_sources_feed(void) { - static struct harvest event; + static struct harvest_event event; static u_int dest = 0; - struct live_entropy_sources *les; + struct live_entropy_sources *lles; int i, n; sx_slock(&les_lock); @@ -140,7 +139,7 @@ live_entropy_sources_feed(void) * Walk over all of live entropy sources, and feed their output * to the system-wide RNG. */ - LIST_FOREACH(les, &sources, entries) { + LIST_FOREACH(lles, &les_sources, lles_entries) { /* XXX: FIX!! "2" is the number of pools in Yarrow */ for (i = 0; i < 2; i++) { @@ -149,12 +148,12 @@ live_entropy_sources_feed(void) * source. */ /* XXX: FIX!! Whine loudly if this didn't work. */ - n = les->rsource->read(event.entropy, HARVESTSIZE); - event.somecounter = get_cyclecount(); - event.size = n; - event.bits = (n*8)/2; - event.source = les->rsource->source; - event.destination = dest++; + n = lles->lles_rsource->les_read(event.he_entropy, HARVESTSIZE); + event.he_somecounter = get_cyclecount(); + event.he_size = n; + event.he_bits = (n*8)/2; + event.he_source = lles->lles_rsource->les_source; + event.he_destination = dest++; /* Do the actual entropy insertion */ harvest_process_event(&event); Modified: projects/random_number_generator/sys/dev/random/live_entropy_sources.h ============================================================================== --- projects/random_number_generator/sys/dev/random/live_entropy_sources.h Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/live_entropy_sources.h Mon Nov 11 21:27:57 2013 (r258019) @@ -36,14 +36,14 @@ * an acceptable amount of time. */ struct live_entropy_source { - const char *ident; - enum esource source; - random_read_func_t *read; + const char *les_ident; + enum random_entropy_source les_source; + random_adaptor_read_func_t *les_read; }; struct live_entropy_sources { - LIST_ENTRY(live_entropy_sources) entries; /* list of providers */ - struct live_entropy_source *rsource; /* associated random adaptor */ + LIST_ENTRY(live_entropy_sources) lles_entries; /* list of providers */ + struct live_entropy_source *lles_rsource; /* associated random adaptor */ }; extern struct mtx live_mtx; Modified: projects/random_number_generator/sys/dev/random/nehemiah.c ============================================================================== --- projects/random_number_generator/sys/dev/random/nehemiah.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/nehemiah.c Mon Nov 11 21:27:57 2013 (r258019) @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -55,9 +54,9 @@ static void random_nehemiah_deinit(void) static int random_nehemiah_read(void *, int); static struct live_entropy_source random_nehemiah = { - .ident = "Hardware, VIA Nehemiah Padlock RNG", - .source = RANDOM_PURE_NEHEMIAH, - .read = random_nehemiah_read + .les_ident = "Hardware, VIA Nehemiah Padlock RNG", + .les_source = RANDOM_PURE_NEHEMIAH, + .les_read = random_nehemiah_read }; /* XXX: FIX? TODO? now that the Davies-Meyer hash is gone and we only use Modified: projects/random_number_generator/sys/dev/random/random_adaptors.c ============================================================================== --- projects/random_number_generator/sys/dev/random/random_adaptors.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/random_adaptors.c Mon Nov 11 21:27:57 2013 (r258019) @@ -35,82 +35,143 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include -#include #include #include +#include #include #include #include LIST_HEAD(adaptors_head, random_adaptors); -static struct adaptors_head adaptors = LIST_HEAD_INITIALIZER(adaptors); -static struct sx adaptors_lock; /* need a sleepable lock */ +static struct adaptors_head random_adaptors_list = LIST_HEAD_INITIALIZER(random_adaptors_list); +static struct sx random_adaptors_lock; /* need a sleepable lock */ -/* List for the dynamic sysctls */ -static struct sysctl_ctx_list random_clist; - -struct random_adaptor *random_adaptor = NULL; +/* Contains a pointer to the currently active adaptor */ +static struct random_adaptor *random_adaptor = NULL; MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data structures"); +static void random_adaptor_choose(void); + void -random_adaptor_register(const char *name, struct random_adaptor *rsp) +random_adaptor_register(const char *name, struct random_adaptor *ra) { - struct random_adaptors *rpp; + struct random_adaptors *rra; - KASSERT(name != NULL && rsp != NULL, ("invalid input to %s", __func__)); + KASSERT(name != NULL && ra != NULL, ("invalid input to %s", __func__)); - rpp = malloc(sizeof(struct random_adaptors), M_ENTROPY, M_WAITOK); - rpp->name = name; - rpp->rsp = rsp; + rra = malloc(sizeof(struct random_adaptors), M_ENTROPY, M_WAITOK); + rra->rra_name = name; + rra->rra_ra = ra; - sx_xlock(&adaptors_lock); - LIST_INSERT_HEAD(&adaptors, rpp, entries); - sx_xunlock(&adaptors_lock); + sx_xlock(&random_adaptors_lock); + + LIST_INSERT_HEAD(&random_adaptors_list, rra, rra_entries); random_adaptor_choose(); + + sx_xunlock(&random_adaptors_lock); + + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); } void random_adaptor_deregister(const char *name) { - struct random_adaptors *rpp; + struct random_adaptors *rra; KASSERT(name != NULL, ("invalid input to %s", __func__)); + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); + + sx_xlock(&random_adaptors_lock); - sx_xlock(&adaptors_lock); - LIST_FOREACH(rpp, &adaptors, entries) - if (strcmp(rpp->name, name) == 0) { - LIST_REMOVE(rpp, entries); + LIST_FOREACH(rra, &random_adaptors_list, rra_entries) + if (strcmp(rra->rra_name, name) == 0) { + LIST_REMOVE(rra, rra_entries); break; } - sx_xunlock(&adaptors_lock); - if (rpp != NULL) - free(rpp, M_ENTROPY); random_adaptor_choose(); + /* It is conceivable that there is no active random adaptor here, + * e.g. at shutdown. + */ + + sx_xunlock(&random_adaptors_lock); + + if (rra != NULL) + free(rra, M_ENTROPY); +} + +int +random_adaptor_block(int flag) +{ + int ret; + + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); + sx_slock(&random_adaptors_lock); + ret = random_adaptor->ra_block(flag); + sx_sunlock(&random_adaptors_lock); + return ret; } -static struct random_adaptor * -random_adaptor_get(const char *name) +int +random_adaptor_read(struct uio *uio, int flag) { - struct random_adaptors *rpp; - struct random_adaptor *rsp; + int c, error = 0; + void *random_buf; - rsp = NULL; + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); - sx_slock(&adaptors_lock); + sx_slock(&random_adaptors_lock); - LIST_FOREACH(rpp, &adaptors, entries) - if (strcmp(rpp->name, name) == 0) - rsp = rpp->rsp; + /* Blocking logic */ + if (random_adaptor->ra_seeded) + error = (random_adaptor->ra_block)(flag); - sx_sunlock(&adaptors_lock); + /* The actual read */ + if (!error) { - return (rsp); + random_buf = (void *)malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); + + while (uio->uio_resid > 0 && !error) { + c = MIN(uio->uio_resid, PAGE_SIZE); + c = (random_adaptor->ra_read)(random_buf, c); + error = uiomove(random_buf, c, uio); + } + /* Finished reading; let the source know so it can do some + * optional housekeeping */ + (random_adaptor->ra_read)(NULL, 0); + + free(random_buf, M_ENTROPY); + + } + + sx_sunlock(&random_adaptors_lock); + + return (error); +} + +int +random_adaptor_poll(int events, struct thread *td) +{ + int revents = 0; + + sx_slock(&random_adaptors_lock); + + if (events & (POLLIN | POLLRDNORM)) { + if (random_adaptor->ra_seeded) + revents = events & (POLLIN | POLLRDNORM); + else + revents = (random_adaptor->ra_poll)(events, td); + } + + sx_sunlock(&random_adaptors_lock); + + return (revents); } /* @@ -118,29 +179,40 @@ random_adaptor_get(const char *name) * one or the highest priority one, whichever comes first. Panic on failure * as the fallback must be the "dummy" adaptor. */ -void +static void random_adaptor_choose(void) { char rngs[128], *token, *cp; - struct random_adaptors *rppi; + struct random_adaptors *rra, *rrai; struct random_adaptor *random_adaptor_previous; u_int primax; + /* We are going to be messing with random_adaptor. + * Exclusive lock is mandatory. + */ + sx_assert(&random_adaptors_lock, SA_XLOCKED); + random_adaptor_previous = random_adaptor; random_adaptor = NULL; if (TUNABLE_STR_FETCH("kern.random.active_adaptor", rngs, sizeof(rngs))) { cp = rngs; - while ((token = strsep(&cp, ",")) != NULL) - if ((random_adaptor = random_adaptor_get(token)) != NULL) { + while ((token = strsep(&cp, ",")) != NULL) { + LIST_FOREACH(rra, &random_adaptors_list, rra_entries) + if (strcmp(rra->rra_name, token) == 0) { + random_adaptor = rra->rra_ra; + break; + } + if (random_adaptor != NULL) { printf("random: selecting requested adaptor <%s>\n", - random_adaptor->ident); + random_adaptor->ra_ident); break; } else printf("random: requested adaptor <%s> not available\n", token); + } } primax = 0U; @@ -149,17 +221,15 @@ random_adaptor_choose(void) * Fall back to the highest priority item on the available * RNG list. */ - sx_slock(&adaptors_lock); - LIST_FOREACH(rppi, &adaptors, entries) { - if (rppi->rsp->priority >= primax) { - random_adaptor = rppi->rsp; - primax = rppi->rsp->priority; + LIST_FOREACH(rrai, &random_adaptors_list, rra_entries) { + if (rrai->rra_ra->ra_priority >= primax) { + random_adaptor = rrai->rra_ra; + primax = rrai->rra_ra->ra_priority; } } - sx_sunlock(&adaptors_lock); if (random_adaptor != NULL) printf("random: selecting highest priority adaptor <%s>\n", - random_adaptor->ident); + random_adaptor->ra_ident); } KASSERT(random_adaptor != NULL, ("adaptor not found")); @@ -167,8 +237,8 @@ random_adaptor_choose(void) /* If we are changing adaptors, deinit the old and init the new. */ if (random_adaptor != random_adaptor_previous) { if (random_adaptor_previous != NULL) - (random_adaptor_previous->deinit)(); - (random_adaptor->init)(); + (random_adaptor_previous->ra_deinit)(); + (random_adaptor->ra_init)(); } } @@ -177,25 +247,26 @@ random_sysctl_adaptors_handler(SYSCTL_HA { /* XXX: FIX!! Fixed array size, but see below, this may be OK */ char buf[128], *pbuf; - struct random_adaptors *rpp; + struct random_adaptors *rra; int count, snp; size_t lbuf; - sx_slock(&adaptors_lock); - buf[0] = '\0'; pbuf = buf; lbuf = 256; count = 0; - LIST_FOREACH(rpp, &adaptors, entries) { + + sx_slock(&random_adaptors_lock); + + LIST_FOREACH(rra, &random_adaptors_list, rra_entries) { snp = snprintf(pbuf, lbuf, "%s%s(%d)", - (count++ ? "," : ""), rpp->name, rpp->rsp->priority); + (count++ ? "," : ""), rra->rra_name, rra->rra_ra->ra_priority); KASSERT(snp > 0, ("buffer overflow")); lbuf -= (size_t)snp; pbuf += snp; } - sx_sunlock(&adaptors_lock); + sx_sunlock(&random_adaptors_lock); return (SYSCTL_OUT(req, buf, strlen(buf))); } @@ -203,30 +274,28 @@ random_sysctl_adaptors_handler(SYSCTL_HA static int random_sysctl_active_adaptor_handler(SYSCTL_HANDLER_ARGS) { - struct random_adaptor *rsp; - struct random_adaptors *rpp; - const char *name; - int error; + /* XXX: FIX!! Fixed array size, but see below, this may be OK */ + char buf[32]; + struct random_adaptors *rra; + const char *name; + + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); name = NULL; - rsp = random_adaptor; + buf[0] = '\0'; - if (rsp != NULL) { - sx_slock(&adaptors_lock); + sx_slock(&random_adaptors_lock); - LIST_FOREACH(rpp, &adaptors, entries) - if (rpp->rsp == rsp) - name = rpp->name; + LIST_FOREACH(rra, &random_adaptors_list, rra_entries) + if (rra->rra_ra == random_adaptor) { + strncpy(buf, rra->rra_name, sizeof(buf)); + break; + } - sx_sunlock(&adaptors_lock); - } - if (rsp == NULL || name == NULL) - error = SYSCTL_OUT(req, "", 0); - else - error = SYSCTL_OUT(req, name, strlen(name)); + sx_sunlock(&random_adaptors_lock); - return (error); + return (SYSCTL_OUT(req, buf, strlen(buf))); } /* ARGSUSED */ @@ -244,12 +313,12 @@ random_adaptors_init(void *unused __unus NULL, 0, random_sysctl_active_adaptor_handler, "", "Active Random Number Generator Adaptor"); - sx_init(&adaptors_lock, "random_adaptors"); + sx_init(&random_adaptors_lock, "random_adaptors"); /* This dummy "thing" is not a module by itself, but part of the * randomdev module. */ - random_adaptor_register("dummy", &dummy_random); + random_adaptor_register("dummy", &randomdev_dummy); } /* ARGSUSED */ @@ -259,8 +328,7 @@ random_adaptors_deinit(void *unused __un /* Don't do this! Panic will follow. */ /* random_adaptor_deregister("dummy"); */ - sx_destroy(&adaptors_lock); - sysctl_ctx_free(&random_clist); + sx_destroy(&random_adaptors_lock); } /* XXX: FIX!! Move this to where its not so well hidden, like randomdev[_soft].c, maybe. */ @@ -289,8 +357,14 @@ static void random_adaptors_seed(void *unused __unused) { - if (random_adaptor != NULL) - (*random_adaptor->reseed)(); + KASSERT(random_adaptor != NULL, ("No active random adaptor in %s", __func__)); + + sx_slock(&random_adaptors_lock); + + random_adaptor->ra_reseed(); + + sx_sunlock(&random_adaptors_lock); + arc4rand(NULL, 0, 1); } SYSINIT(random_seed, SI_SUB_INTRINSIC_POST, SI_ORDER_LAST, Modified: projects/random_number_generator/sys/dev/random/random_adaptors.h ============================================================================== --- projects/random_number_generator/sys/dev/random/random_adaptors.h Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/random_adaptors.h Mon Nov 11 21:27:57 2013 (r258019) @@ -31,29 +31,41 @@ MALLOC_DECLARE(M_ENTROPY); +typedef void random_adaptor_init_func_t(void); +typedef void random_adaptor_deinit_func_t(void); + +typedef int random_adaptor_block_func_t(int); +typedef int random_adaptor_read_func_t(void *, int); +typedef int random_adaptor_poll_func_t(int, struct thread *); + +typedef void random_adaptor_reseed_func_t(void); + struct random_adaptor { - struct selinfo rsel; - const char *ident; - int seeded; - u_int priority; - random_init_func_t *init; - random_deinit_func_t *deinit; - random_block_func_t *block; - random_read_func_t *read; - random_poll_func_t *poll; - random_reseed_func_t *reseed; + const char *ra_ident; + int ra_seeded; + u_int ra_priority; + random_adaptor_init_func_t *ra_init; + random_adaptor_deinit_func_t *ra_deinit; + random_adaptor_block_func_t *ra_block; + random_adaptor_read_func_t *ra_read; + random_adaptor_poll_func_t *ra_poll; + random_adaptor_reseed_func_t *ra_reseed; }; struct random_adaptors { - LIST_ENTRY(random_adaptors) entries; /* list of providers */ - const char *name; /* name of random adaptor */ - struct random_adaptor *rsp; + LIST_ENTRY(random_adaptors) rra_entries; /* list of providers */ + const char *rra_name; /* name of random adaptor */ + struct random_adaptor *rra_ra; }; +/* Dummy "always-block" pseudo-device */ +extern struct random_adaptor randomdev_dummy; + void random_adaptor_register(const char *, struct random_adaptor *); void random_adaptor_deregister(const char *); -void random_adaptor_choose(void); -extern struct random_adaptor *random_adaptor; +int random_adaptor_block(int); +int random_adaptor_read(struct uio *, int); +int random_adaptor_poll(int, struct thread *); #endif /* SYS_DEV_RANDOM_RANDOM_ADAPTORS_H_INCLUDED */ Modified: projects/random_number_generator/sys/dev/random/random_harvestq.c ============================================================================== --- projects/random_number_generator/sys/dev/random/random_harvestq.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/random_harvestq.c Mon Nov 11 21:27:57 2013 (r258019) @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -52,7 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include /* * How many events to queue up. We create this many items in @@ -63,14 +61,14 @@ __FBSDID("$FreeBSD$"); #define RANDOM_FIFO_MAX 1024 /* - * The harvest mutex protects the consistency of the entropy fifos and + * The harvest mutex protects the consistency of the entropy Fifos and * empty fifo and other associated structures. */ struct mtx harvest_mtx; /* Lockable FIFO queue holding entropy buffers */ struct entropyfifo { - STAILQ_HEAD(harvestlist, harvest) head; + STAILQ_HEAD(harvestlist, harvest_event) head; }; /* Empty entropy buffers */ @@ -80,98 +78,20 @@ static struct entropyfifo emptyfifo; static struct entropyfifo harvestfifo; /* Function called to process one harvested stochastic event */ -void (*harvest_process_event)(struct harvest *); +void (*harvest_process_event)(struct harvest_event *); /* <0 to end the kthread, 0 to let it run, 1 to flush the harvest queues */ int random_kthread_control = 0; static struct proc *random_kthread_proc; -#ifdef RANDOM_RWFILE -static struct entropy_cache { - const char *filename; - int already_read; -} entropy_files[] = { - { "/entropy", 0 }, - { "/var/db/entropy-file", 0 }, - { "/var/db/entropy/saved-entropy.1", 0 }, - { "/var/db/entropy/saved-entropy.2", 0 }, - { "/var/db/entropy/saved-entropy.3", 0 }, - { "/var/db/entropy/saved-entropy.4", 0 }, - { "/var/db/entropy/saved-entropy.5", 0 }, - { "/var/db/entropy/saved-entropy.6", 0 }, - { "/var/db/entropy/saved-entropy.7", 0 }, - { "/var/db/entropy/saved-entropy.8", 0 }, - { NULL, 0 } -}; - -/* Deal with entropy cached externally if this is present. - * Lots of policy may eventually arrive in this function. - * Called after any volume is mounted; this way we can keep - * looking for files in (say) /var/db/entropy/... - * - * We keep a cache of files read so we don't keep re-reading them. - * - * Optionally (a compile-time option) overwrite these files. - */ -static void -random_harvestq_cache(void *arg1 __unused, struct mount *arg2 __unused, - struct vnode *arg3 __unused, struct thread *arg4 __unused) -{ - static int caches_read = 0; - struct entropy_cache *entropy_file; - int error; - size_t i; - uint8_t *data; - - /* Read and attempt to overwrite the entropy cache files. - * If the file exists, can be read and then overwritten, - * then use it. Ignore it otherwise, but print out what is - * going on. - */ - data = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); - for (entropy_file = entropy_files; entropy_file->filename; entropy_file++) { - if (entropy_file->already_read) - break; - error = randomdev_read_file(entropy_file->filename, data, PAGE_SIZE); - if (error == 0) { - printf("random: entropy cache '%s' provides %ld bytes\n", entropy_file->filename, (long)PAGE_SIZE); -#ifdef RANDOM_RWFILE_WRITE_OK /* Not defined so writes disabled for now */ - error = randomdev_write_file(entropy_file->filename, zero_region, PAGE_SIZE); - if (error == 0) { - printf("random: entropy cache '%s' successfully overwritten\n", entropy_file->filename); -#endif - for (i = 0; i < PAGE_SIZE; i += 16) - random_harvestq_internal(data + i, 16, 16, RANDOM_CACHED); - entropy_file->already_read = 1; - caches_read++; -#ifdef RANDOM_RWFILE_WRITE_OK /* Not defined so writes disabled for now */ - } - else - printf("random: entropy cache '%s' not overwritten and therefore not used; error = %d\n", entropy_file->filename, error); -#endif - } - else - if (bootverbose) - printf("random: entropy cache '%s' not present or unreadable; error = %d\n", entropy_file->filename, error); - } - bzero(data, PAGE_SIZE); - free(data, M_ENTROPY); - - if (bootverbose) - printf("random: total entropy cache files read so far = %d\n", caches_read); -} -/* Invoke the above every time a FS is mounted; this way we can keep going after cached entropy */ -EVENTHANDLER_DEFINE(vfs_mounted, random_harvestq_cache, NULL, 0); -#endif /* RANDOM_RWFILE */ - static void random_kthread(void *arg __unused) { - STAILQ_HEAD(, harvest) local_queue; - struct harvest *event = NULL; + struct entropyfifo local_queue; + struct harvest_event *event = NULL; - STAILQ_INIT(&local_queue); + STAILQ_INIT(&local_queue.head); /* Process until told to stop */ mtx_lock_spin(&harvest_mtx); @@ -182,18 +102,18 @@ random_kthread(void *arg __unused) * Drain entropy source records into a thread-local * queue for processing while not holding the mutex. */ - STAILQ_CONCAT(&local_queue, &harvestfifo.head); + STAILQ_CONCAT(&local_queue.head, &harvestfifo.head); /* * Deal with events, if any. * Then transfer the used events back into the empty fifo. */ - if (!STAILQ_EMPTY(&local_queue)) { + if (!STAILQ_EMPTY(&local_queue.head)) { mtx_unlock_spin(&harvest_mtx); - STAILQ_FOREACH(event, &local_queue, next) + STAILQ_FOREACH(event, &local_queue.head, he_next) harvest_process_event(event); mtx_lock_spin(&harvest_mtx); - STAILQ_CONCAT(&emptyfifo.head, &local_queue); + STAILQ_CONCAT(&emptyfifo.head, &local_queue.head); } /* @@ -223,20 +143,20 @@ random_kthread(void *arg __unused) } void -random_harvestq_init(void (*event_processor)(struct harvest *)) +random_harvestq_init(void (*event_processor)(struct harvest_event *)) { uint8_t *keyfile, *data; int error, i; size_t size, j; - struct harvest *np; + struct harvest_event *np; /* Initialise the harvest fifos */ /* Contains the currently unused event structs. */ STAILQ_INIT(&emptyfifo.head); for (i = 0; i < RANDOM_FIFO_MAX; i++) { - np = malloc(sizeof(struct harvest), M_ENTROPY, M_WAITOK); - STAILQ_INSERT_TAIL(&emptyfifo.head, np, next); + np = malloc(sizeof(struct harvest_event), M_ENTROPY, M_WAITOK); + STAILQ_INSERT_TAIL(&emptyfifo.head, np, he_next); } /* Will contain the queued-up events. */ @@ -276,17 +196,17 @@ random_harvestq_init(void (*event_proces void random_harvestq_deinit(void) { - struct harvest *np; + struct harvest_event *np; /* Destroy the harvest fifos */ while (!STAILQ_EMPTY(&emptyfifo.head)) { np = STAILQ_FIRST(&emptyfifo.head); - STAILQ_REMOVE_HEAD(&emptyfifo.head, next); + STAILQ_REMOVE_HEAD(&emptyfifo.head, he_next); free(np, M_ENTROPY); } while (!STAILQ_EMPTY(&harvestfifo.head)) { np = STAILQ_FIRST(&harvestfifo.head); - STAILQ_REMOVE_HEAD(&harvestfifo.head, next); + STAILQ_REMOVE_HEAD(&harvestfifo.head, he_next); free(np, M_ENTROPY); } @@ -309,10 +229,10 @@ random_harvestq_deinit(void) */ void random_harvestq_internal(const void *entropy, u_int count, u_int bits, - enum esource origin) + enum random_entropy_source origin) { static u_int destination[ENTROPYSOURCE]; - struct harvest *event; + struct harvest_event *event; KASSERT(origin >= RANDOM_START && origin < ENTROPYSOURCE, ("random_harvest_internal: origin %d invalid\n", origin)); @@ -326,17 +246,17 @@ random_harvestq_internal(const void *ent event = STAILQ_FIRST(&emptyfifo.head); if (event != NULL) { /* Add the harvested data to the fifo */ - STAILQ_REMOVE_HEAD(&emptyfifo.head, next); - event->somecounter = get_cyclecount(); - event->size = count; - event->bits = bits; - event->source = origin; - event->destination = destination[origin]++; - memcpy(event->entropy, entropy, + STAILQ_REMOVE_HEAD(&emptyfifo.head, he_next); + event->he_somecounter = get_cyclecount(); + event->he_size = count; + event->he_bits = bits; + event->he_source = origin; + event->he_destination = destination[origin]++; + memcpy(event->he_entropy, entropy, MIN(count, HARVESTSIZE)); STAILQ_INSERT_TAIL(&harvestfifo.head, - event, next); + event, he_next); } mtx_unlock_spin(&harvest_mtx); Modified: projects/random_number_generator/sys/dev/random/random_harvestq.h ============================================================================== --- projects/random_number_generator/sys/dev/random/random_harvestq.h Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/random_harvestq.h Mon Nov 11 21:27:57 2013 (r258019) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 Arthur Mesh + * Copyright (c) 2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,23 +35,24 @@ /* These are used to queue harvested packets of entropy. The entropy * buffer size is pretty arbitrary. */ -struct harvest { - uintmax_t somecounter; /* fast counter for clock jitter */ - uint8_t entropy[HARVESTSIZE]; /* the harvested entropy */ - u_int size, bits; /* stats about the entropy */ - u_int destination; /* destination pool of this entropy */ - enum esource source; /* origin of the entropy */ - STAILQ_ENTRY(harvest) next; /* next item on the list */ +struct harvest_event { + uintmax_t he_somecounter; /* fast counter for clock jitter */ + uint8_t he_entropy[HARVESTSIZE];/* some harvested entropy */ + u_int he_size; /* harvested entropy byte count */ + u_int he_bits; /* stats about the entropy */ + u_int he_destination; /* destination pool of this entropy */ + enum random_entropy_source he_source; /* origin of the entropy */ + STAILQ_ENTRY(harvest_event) he_next; /* next item on the list */ }; -void random_harvestq_init(void (*)(struct harvest *)); +void random_harvestq_init(void (*)(struct harvest_event *)); void random_harvestq_deinit(void); -void random_harvestq_internal(const void *, u_int, u_int, enum esource); +void random_harvestq_internal(const void *, u_int, u_int, enum random_entropy_source); -/* This is in randomdev.c as it needs to be fixed in the kernel */ +/* This is in randomdev.c as it needs to be permanently in the kernel */ void randomdev_set_wakeup_exit(void *); -extern void (*harvest_process_event)(struct harvest *); +extern void (*harvest_process_event)(struct harvest_event *); extern int random_kthread_control; extern struct mtx harvest_mtx; Modified: projects/random_number_generator/sys/dev/random/randomdev.c ============================================================================== --- projects/random_number_generator/sys/dev/random/randomdev.c Mon Nov 11 21:19:18 2013 (r258018) +++ projects/random_number_generator/sys/dev/random/randomdev.c Mon Nov 11 21:27:57 2013 (r258019) @@ -49,10 +49,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include -#include #include #include #include @@ -88,7 +86,7 @@ static struct cdev *random_dev; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***