svn commit: r258019 - in projects/random_number_generator/sys: conf dev/random modules/random sys vm
Mark Murray
markm at FreeBSD.org
Mon Nov 11 21:28:00 UTC 2013
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 <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/systm.h>
#include <sys/time.h>
@@ -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 <sys/malloc.h>
#include <sys/module.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/systm.h>
#include <machine/md_var.h>
@@ -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 <sys/malloc.h>
#include <sys/queue.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@@ -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 <sys/malloc.h>
#include <sys/module.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/systm.h>
#include <machine/segments.h>
@@ -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 <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/poll.h>
#include <sys/queue.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <sys/unistd.h>
#include <dev/random/randomdev.h>
#include <dev/random/random_adaptors.h>
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 <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
@@ -52,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/random/random_adaptors.h>
#include <dev/random/random_harvestq.h>
#include <dev/random/live_entropy_sources.h>
-#include <dev/random/rwfile.h>
/*
* 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 <arthurmesh at gmail.com>
+ * 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 <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/poll.h>
#include <sys/proc.h>
#include <sys/random.h>
-#include <sys/selinfo.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@@ -88,7 +86,7 @@ static struct cdev *random_dev;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list