diff options
-rw-r--r-- | sys/boot/forth/loader.conf | 11 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/conf/files.amd64 | 2 | ||||
-rw-r--r-- | sys/conf/files.i386 | 2 | ||||
-rw-r--r-- | sys/dev/random/ivy.c | 15 | ||||
-rw-r--r-- | sys/dev/random/live_entropy_sources.c | 37 | ||||
-rw-r--r-- | sys/dev/random/live_entropy_sources.h | 2 | ||||
-rw-r--r-- | sys/dev/random/random_harvestq.c | 57 | ||||
-rw-r--r-- | sys/dev/random/randomdev_soft.c | 2 | ||||
-rw-r--r-- | sys/dev/random/rwfile.c | 91 | ||||
-rw-r--r-- | sys/dev/random/rwfile.h | 30 | ||||
-rw-r--r-- | sys/kern/init_main.c | 2 | ||||
-rw-r--r-- | sys/sys/eventhandler.h | 4 | ||||
-rw-r--r-- | sys/sys/random.h | 3 |
14 files changed, 244 insertions, 15 deletions
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 76f40c4..0757b5f 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -39,6 +39,17 @@ bitmap_type="splash_image_data" # and place it on the module_path ############################################################## +### Random number generator configuration ################### +############################################################## + +entropy_cache_load="NO" # Set this to YES to load entropy at boot time +entropy_cache_name="/boot/entropy" # Set this to the name of the file +entropy_cache_type="/boot/entropy" +#kern.random.sys.seeded="0" # Set this to 1 to start /dev/random + # without waiting for a (re)seed. + + +############################################################## ### Loader settings ######################################## ############################################################## diff --git a/sys/conf/files b/sys/conf/files index 39fddd9..f3e298c 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2051,6 +2051,7 @@ dev/random/randomdev.c optional random 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 diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 7ac5d72..1914c48 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -259,6 +259,8 @@ dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvram/nvram.c optional nvram isa +dev/random/ivy.c optional rdrand_rng +dev/random/nehemiah.c optional padlock_rng dev/qlxge/qls_dbg.c optional qlxge pci dev/qlxge/qls_dump.c optional qlxge pci dev/qlxge/qls_hw.c optional qlxge pci diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 55017dc..e259659 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -257,6 +257,8 @@ dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvram/nvram.c optional nvram isa dev/pcf/pcf_isa.c optional pcf +dev/random/ivy.c optional rdrand_rng +dev/random/nehemiah.c optional padlock_rng dev/sbni/if_sbni.c optional sbni dev/sbni/if_sbni_isa.c optional sbni isa dev/sbni/if_sbni_pci.c optional sbni pci diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c index f9a9832..8ca291e 100644 --- a/sys/dev/random/ivy.c +++ b/sys/dev/random/ivy.c @@ -57,6 +57,15 @@ struct random_hardware_source random_ivy = { .read = random_ivy_read }; +#if 1 +static inline int +ivy_rng_store(uint64_t *tmp) +{ + *tmp = 0xF001FACE; + + return (sizeof(uint64_t)); +} +#else static inline int ivy_rng_store(uint64_t *tmp) { @@ -82,6 +91,7 @@ ivy_rng_store(uint64_t *tmp) return (0); #endif } +#endif static int random_ivy_read(void *buf, int c) @@ -114,6 +124,10 @@ rdrand_modevent(module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: +#if 1 + live_entropy_source_register(&random_ivy); + printf("%s: CRAP RDRAND is present\n", random_ivy.ident); +#else if (cpu_feature2 & CPUID2_RDRAND) live_entropy_source_register(&random_ivy); else @@ -122,6 +136,7 @@ rdrand_modevent(module_t mod, int type, void *unused) #endif printf("%s: RDRAND is not present\n", random_ivy.ident); +#endif break; case MOD_UNLOAD: diff --git a/sys/dev/random/live_entropy_sources.c b/sys/dev/random/live_entropy_sources.c index 7d5ee9b..d9af30b 100644 --- a/sys/dev/random/live_entropy_sources.c +++ b/sys/dev/random/live_entropy_sources.c @@ -52,7 +52,11 @@ __FBSDID("$FreeBSD$"); LIST_HEAD(les_head, live_entropy_sources); static struct les_head sources = LIST_HEAD_INITIALIZER(sources); -#define LES_THRESHOLD 10 +/* + * The harvest mutex protects the consistency of the entropy fifos and + * empty fifo and other associated structures. + */ +struct mtx live_mtx; void live_entropy_source_register(struct random_hardware_source *rsource) @@ -64,27 +68,27 @@ live_entropy_source_register(struct random_hardware_source *rsource) les = malloc(sizeof(struct live_entropy_sources), M_ENTROPY, M_WAITOK); les->rsource = rsource; - mtx_lock_spin(&harvest_mtx); + mtx_lock(&live_mtx); LIST_INSERT_HEAD(&sources, les, entries); - mtx_unlock_spin(&harvest_mtx); + mtx_unlock(&live_mtx); } void live_entropy_source_deregister(struct random_hardware_source *rsource) { - struct live_entropy_sources *les; + struct live_entropy_sources *les = NULL; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); - mtx_lock_spin(&harvest_mtx); - LIST_FOREACH(les, &sources, entries) { + mtx_lock(&live_mtx); + LIST_FOREACH(les, &sources, entries) if (les->rsource == rsource) { LIST_REMOVE(les, entries); - free(les, M_ENTROPY); break; } - } - mtx_unlock_spin(&harvest_mtx); + mtx_unlock(&live_mtx); + if (les != NULL) + free(les, M_ENTROPY); } static int @@ -95,7 +99,7 @@ live_entropy_source_handler(SYSCTL_HANDLER_ARGS) count = error = 0; - mtx_lock_spin(&harvest_mtx); + mtx_lock(&live_mtx); if (LIST_EMPTY(&sources)) error = SYSCTL_OUT(req, "", 0); @@ -112,7 +116,7 @@ live_entropy_source_handler(SYSCTL_HANDLER_ARGS) } } - mtx_unlock_spin(&harvest_mtx); + mtx_unlock(&live_mtx); return (error); } @@ -125,6 +129,8 @@ live_entropy_sources_init(void *unused) CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, live_entropy_source_handler, "", "List of Active Live Entropy Sources"); + + mtx_init(&live_mtx, "live entropy source mutex", NULL, MTX_DEF); } /* @@ -135,7 +141,7 @@ live_entropy_sources_init(void *unused) * * BEWARE!!! * This function runs inside the RNG thread! Don't do anything silly! - * The harvest_mtx mutex is held; you may count on that. + * Remember that we are NOT holding harvest_mtx on entry! */ void live_entropy_sources_feed(int rounds, event_proc_f entropy_processor) @@ -145,6 +151,8 @@ live_entropy_sources_feed(int rounds, event_proc_f entropy_processor) struct live_entropy_sources *les; int i, n; + mtx_lock(&live_mtx); + /* * Walk over all of live entropy sources, and feed their output * to the system-wide RNG. @@ -168,15 +176,18 @@ live_entropy_sources_feed(int rounds, event_proc_f entropy_processor) /* Do the actual entropy insertion */ entropy_processor(&event); - } } + + mtx_unlock(&live_mtx); } static void live_entropy_sources_deinit(void *unused) { + + mtx_destroy(&live_mtx); } SYSINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST, diff --git a/sys/dev/random/live_entropy_sources.h b/sys/dev/random/live_entropy_sources.h index ae74cc9..febb24a 100644 --- a/sys/dev/random/live_entropy_sources.h +++ b/sys/dev/random/live_entropy_sources.h @@ -40,6 +40,8 @@ struct live_entropy_sources { struct random_hardware_source *rsource; /* associated random adaptor */ }; +extern struct mtx live_mtx; + void live_entropy_source_register(struct random_hardware_source *); void live_entropy_source_deregister(struct random_hardware_source *); void live_entropy_sources_feed(int, event_proc_f); 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, diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c index 8f8b849..352d0ae 100644 --- a/sys/dev/random/randomdev_soft.c +++ b/sys/dev/random/randomdev_soft.c @@ -99,6 +99,8 @@ static struct random_adaptor random_context = { #define RANDOM_CSPRNG_NAME "fortuna" #endif +TUNABLE_INT("kern.random.sys.seeded", &random_context.seeded); + /* List for the dynamic sysctls */ static struct sysctl_ctx_list random_clist; diff --git a/sys/dev/random/rwfile.c b/sys/dev/random/rwfile.c new file mode 100644 index 0000000..2c563c8 --- /dev/null +++ b/sys/dev/random/rwfile.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2013 Mark R V Murray + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/namei.h> +#include <sys/fcntl.h> +#include <sys/vnode.h> + +#include <dev/random/rwfile.h> + +int +randomdev_read_file(const char *filename, void *buf) +{ + struct nameidata nd; + struct thread* td = curthread; + int error; + ssize_t resid; + int flags; + + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td); + flags = FREAD; + error = vn_open(&nd, &flags, 0, NULL); + if (error == 0) { + NDFREE(&nd, NDF_ONLY_PNBUF); + if (nd.ni_vp->v_type != VREG) + error = ENOEXEC; + else + error = vn_rdwr(UIO_READ, nd.ni_vp, buf, PAGE_SIZE, 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td); + + VOP_UNLOCK(nd.ni_vp, 0); + vn_close(nd.ni_vp, FREAD, td->td_ucred, td); + } + + return (error); +} + +int +randomdev_write_file(const char *filename, void *buf) +{ + struct nameidata nd; + struct thread* td = curthread; + int error; + ssize_t resid; + int flags; + + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td); + flags = FWRITE | O_CREAT | O_TRUNC; + error = vn_open(&nd, &flags, 0, NULL); + if (error == 0) { + NDFREE(&nd, NDF_ONLY_PNBUF); + if (nd.ni_vp->v_type != VREG) + error = ENOEXEC; + else + error = vn_rdwr(UIO_WRITE, nd.ni_vp, buf, PAGE_SIZE, 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td); + + VOP_UNLOCK(nd.ni_vp, 0); + vn_close(nd.ni_vp, FREAD, td->td_ucred, td); + } + + return (error); +} diff --git a/sys/dev/random/rwfile.h b/sys/dev/random/rwfile.h new file mode 100644 index 0000000..b1fcff8 --- /dev/null +++ b/sys/dev/random/rwfile.h @@ -0,0 +1,30 @@ +/*- + * Copyright (c) 2013 Mark R V Murray + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +int randomdev_read_file(const char *filename, void *buf); +int randomdev_write_file(const char *filename, void *buf); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index ed343b6..b366f69 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -847,6 +847,8 @@ kick_init(const void *udata __unused) { struct thread *td; + EVENTHANDLER_INVOKE(multiuser); + td = FIRST_THREAD_IN_PROC(initproc); thread_lock(td); TD_SET_CAN_RUN(td); diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index f1d06b5..ee19073 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -192,6 +192,10 @@ EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); typedef void (*mountroot_handler_t)(void *); EVENTHANDLER_DECLARE(mountroot, mountroot_handler_t); +/* Going multiuser (starting pid 1) event */ +typedef void (*multiuser_handler_t)(void *); +EVENTHANDLER_DECLARE(multiuser, multiuser_handler_t); + /* File system mount events */ struct mount; struct vnode; diff --git a/sys/sys/random.h b/sys/sys/random.h index efaa587..1ccad3a 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -39,7 +39,7 @@ int read_random(void *, int); */ enum esource { RANDOM_START = 0, - RANDOM_WRITE = 0, + RANDOM_CACHED = 0, RANDOM_KEYBOARD, RANDOM_MOUSE, RANDOM_NET_TUN, @@ -54,7 +54,6 @@ enum esource { RANDOM_PURE_HIFN, RANDOM_PURE_RDRAND, RANDOM_PURE_NEHEMIAH, - RANDOM_PURE, ENTROPYSOURCE }; void random_harvest(void *, u_int, u_int, enum esource); |