summaryrefslogtreecommitdiffstats
path: root/sys/dev/random/random_harvestq.c
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2013-10-06 22:45:02 +0000
committermarkm <markm@FreeBSD.org>2013-10-06 22:45:02 +0000
commit6492773aa9ae924eadd5d93c57be51d3f002671d (patch)
tree741539b4dd2e73c69952feb52d1ba5c5c7da3966 /sys/dev/random/random_harvestq.c
parent2a88d99d1be9d4f05cfe3b0a6e5ed6fb5cdf6b02 (diff)
downloadFreeBSD-src-6492773aa9ae924eadd5d93c57be51d3f002671d.zip
FreeBSD-src-6492773aa9ae924eadd5d93c57be51d3f002671d.tar.gz
Snapshot.
Looking pretty good; this mostly works now. New code includes: * Read cached entropy at startup, both from files and from loader(8) preloaded entropy. Failures are soft, but announced. Untested. * Use EVENTHANDLER to do above just before we go multiuser. Untested.
Diffstat (limited to 'sys/dev/random/random_harvestq.c')
-rw-r--r--sys/dev/random/random_harvestq.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
index 4e9d711..04c59b1 100644
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -33,8 +33,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
+#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@@ -43,10 +45,13 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/unistd.h>
+#include <machine/cpu.h>
+
#include <dev/random/randomdev.h>
#include <dev/random/randomdev_soft.h>
#include <dev/random/random_harvestq.h>
#include <dev/random/live_entropy_sources.h>
+#include <dev/random/rwfile.h>
#define RANDOM_FIFO_MAX 1024 /* How many events to queue up */
@@ -73,6 +78,56 @@ int random_kthread_control = 0;
static struct proc *random_kthread_proc;
+static const char *entropy_files[] = {
+ "/entropy",
+ "/var/db/entropy",
+ "/boot/entropy", /* Yeah, Yeah. I know this is loaded by
+ * loader(8), but not always, and it doesn't
+ * hurt to do this again.
+ */
+ NULL
+};
+
+/* Deal with entropy cached externally if this is present.
+ */
+static void
+random_harvestq_cache(void *arg __unused)
+{
+ const char **entropy_file;
+ uint8_t *keyfile, *data;
+ size_t size, i;
+ int error;
+
+ /* Get stuff that may have been preloaded by loader(8) */
+ keyfile = preload_search_by_type("/boot/entropy");
+ if (keyfile != NULL) {
+ data = preload_fetch_addr(keyfile);
+ size = preload_fetch_size(keyfile);
+ if (data != NULL && size != 0) {
+ for (i = 0U; i < size; i += 16)
+ random_harvestq_internal(get_cyclecount(), data + i, 16, (16*8)/4, RANDOM_CACHED);
+ printf("random: read %zu bytes from preloaded cache\n", size);
+ bzero(data, size);
+ }
+ else
+ printf("random: no preloaded entropy cache available\n");
+ }
+ data = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK);
+ for (entropy_file = entropy_files; *entropy_file; entropy_file++) {
+ error = randomdev_read_file(*entropy_file, data);
+ if (error == 0) {
+ for (i = 0U; i < PAGE_SIZE; i += 16)
+ random_harvestq_internal(get_cyclecount(), data + i, 16, (16*8)/4, RANDOM_CACHED);
+ printf("random: read %d bytes from '%s'\n", PAGE_SIZE, *entropy_file);
+ }
+ else
+ printf("random: entropy cache '%s' not present or unreadable; error = %d\n", *entropy_file, error);
+ }
+ bzero(data, PAGE_SIZE);
+ free(data, M_ENTROPY);
+}
+EVENTHANDLER_DEFINE(multiuser, random_harvestq_cache, NULL, 0);
+
static void
random_kthread(void *arg)
{
@@ -118,7 +173,9 @@ random_kthread(void *arg)
* Do only one round of the hardware sources for now.
* Later we'll need to make it rate-adaptive.
*/
+ mtx_unlock_spin(&harvest_mtx);
live_entropy_sources_feed(1, entropy_processor);
+ mtx_lock_spin(&harvest_mtx);
/*
* If a queue flush was commanded, it has now happened,
OpenPOWER on IntegriCloud