Index: head/sys/dev/random/ivy.c =================================================================== --- head/sys/dev/random/ivy.c (revision 274251) +++ head/sys/dev/random/ivy.c (revision 274252) @@ -1,135 +1,135 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation * Copyright (c) 2013 David E. O'Brien * Copyright (c) 2012 Konstantin Belousov * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RETRY_COUNT 10 static u_int random_ivy_read(void *, u_int); static struct live_entropy_source random_ivy = { .les_ident = "Intel Secure Key RNG", .les_source = RANDOM_PURE_RDRAND, .les_read = random_ivy_read }; static inline int ivy_rng_store(u_long *buf) { #ifdef __GNUCLIKE_ASM u_long rndval; int retry; retry = RETRY_COUNT; __asm __volatile( "1:\n\t" "rdrand %1\n\t" /* read randomness into tmp */ "jc 2f\n\t" /* CF is set on success, exit retry loop */ "dec %0\n\t" /* otherwise, retry-- */ "jne 1b\n\t" /* and loop if retries are not exhausted */ "2:" : "+r" (retry), "=r" (rndval) : : "cc"); *buf = rndval; return (retry); #else /* __GNUCLIKE_ASM */ return (0); #endif } /* It is required that buf length is a multiple of sizeof(u_long). */ static u_int random_ivy_read(void *buf, u_int c) { u_long *b, rndval; u_int count; KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); b = buf; for (count = c; count > 0; count -= sizeof(*b)) { if (ivy_rng_store(&rndval) == 0) break; *b++ = rndval; } return (c - count); } static int rdrand_modevent(module_t mod, int type, void *unused) { int error = 0; switch (type) { case MOD_LOAD: if (cpu_feature2 & CPUID2_RDRAND) { live_entropy_source_register(&random_ivy); printf("random: live provider: \"%s\"\n", random_ivy.les_ident); } break; case MOD_UNLOAD: if (cpu_feature2 & CPUID2_RDRAND) live_entropy_source_deregister(&random_ivy); break; case MOD_SHUTDOWN: break; default: error = EOPNOTSUPP; break; } return (error); } DEV_MODULE(rdrand, rdrand_modevent, NULL); MODULE_VERSION(rdrand, 1); -MODULE_DEPEND(rdrand, random_adaptors, 1, 1, 1); +MODULE_DEPEND(rdrand, randomdev, 1, 1, 1); Index: head/sys/dev/random/nehemiah.c =================================================================== --- head/sys/dev/random/nehemiah.c (revision 274251) +++ head/sys/dev/random/nehemiah.c (revision 274252) @@ -1,160 +1,160 @@ /*- * Copyright (c) 2013 Mark R V Murray * Copyright (c) 2013 David E. O'Brien * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void random_nehemiah_init(void); static void random_nehemiah_deinit(void); static u_int random_nehemiah_read(void *, u_int); static struct live_entropy_source random_nehemiah = { .les_ident = "VIA Nehemiah Padlock RNG", .les_source = RANDOM_PURE_NEHEMIAH, .les_read = random_nehemiah_read }; /* XXX: FIX? Now that the Davies-Meyer hash is gone and we only use * the 'xstore' instruction, do we still need to preserve the * FPU state with fpu_kern_(enter|leave)() ? */ static struct fpu_kern_ctx *fpu_ctx_save; /* This H/W source never stores more than 8 bytes in one go */ /* ARGSUSED */ static __inline size_t VIA_RNG_store(void *buf) { uint32_t retval = 0; uint32_t rate = 0; #ifdef __GNUCLIKE_ASM __asm __volatile( "movl $0,%%edx\n\t" "xstore" : "=a" (retval), "+d" (rate), "+D" (buf) : : "memory" ); #endif if (rate == 0) return (retval&0x1f); return (0); } static void random_nehemiah_init(void) { fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL); } static void random_nehemiah_deinit(void) { fpu_kern_free_ctx(fpu_ctx_save); } /* It is specifically allowed that buf is a multiple of sizeof(long) */ static u_int random_nehemiah_read(void *buf, u_int c) { uint8_t *b; size_t count, ret; uint64_t tmp; if ((fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL) == 0)) { b = buf; for (count = c; count > 0; count -= ret) { ret = MIN(VIA_RNG_store(&tmp), count); memcpy(b, &tmp, ret); b += ret; } fpu_kern_leave(curthread, fpu_ctx_save); } else c = 0; return (c); } static int nehemiah_modevent(module_t mod, int type, void *unused) { int error = 0; switch (type) { case MOD_LOAD: if (via_feature_rng & VIA_HAS_RNG) { live_entropy_source_register(&random_nehemiah); printf("random: live provider: \"%s\"\n", random_nehemiah.les_ident); random_nehemiah_init(); } break; case MOD_UNLOAD: if (via_feature_rng & VIA_HAS_RNG) random_nehemiah_deinit(); live_entropy_source_deregister(&random_nehemiah); break; case MOD_SHUTDOWN: break; default: error = EOPNOTSUPP; break; } return (error); } DEV_MODULE(nehemiah, nehemiah_modevent, NULL); MODULE_VERSION(nehemiah, 1); -MODULE_DEPEND(nehemiah, random_adaptors, 1, 1, 1); +MODULE_DEPEND(nehemiah, randomdev, 1, 1, 1); Index: head/sys/dev/random/randomdev.c =================================================================== --- head/sys/dev/random/randomdev.c (revision 274251) +++ head/sys/dev/random/randomdev.c (revision 274252) @@ -1,252 +1,244 @@ /*- * Copyright (c) 2000-2013 Mark R V Murray * Copyright (c) 2013 Arthur Mesh * 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. * */ /* * NOTE NOTE NOTE * * This file is compiled into the kernel unconditionally. Any random(4) * infrastructure that needs to be in the kernel by default goes here! * * Except ... * * The adaptor code all goes into random_adaptor.c, which is also compiled * the kernel by default. The module in that file is initialised before * this one. * * Other modules must be initialised after the above two, and are * software random processors which plug into random_adaptor.c. * */ #include __FBSDID("$FreeBSD$"); #include "opt_random.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RANDOM_MINOR 0 static d_ioctl_t randomdev_ioctl; static struct cdevsw random_cdevsw = { .d_name = "random", .d_version = D_VERSION, .d_read = random_adaptor_read, .d_write = random_adaptor_write, .d_poll = random_adaptor_poll, .d_ioctl = randomdev_ioctl, }; /* For use with make_dev(9)/destroy_dev(9). */ static struct cdev *random_dev; /* Set up the sysctl root node for the entropy device */ SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0, "Random Number Generator"); MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data structures"); /* ARGSUSED */ static int randomdev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr __unused, int flags __unused, struct thread *td __unused) { int error = 0; switch (cmd) { /* Really handled in upper layer */ case FIOASYNC: case FIONBIO: break; default: error = ENOTTY; } return (error); } /* Helper routine to enable kproc_exit() to work while the module is * being (or has been) unloaded. * This routine is in this file because it is always linked into the kernel, * and will thus never be unloaded. This is critical for unloadable modules * that have threads. */ void randomdev_set_wakeup_exit(void *control) { wakeup(control); kproc_exit(0); /* NOTREACHED */ } /* ARGSUSED */ static int randomdev_modevent(module_t mod __unused, int type, void *data __unused) { int error = 0; switch (type) { case MOD_LOAD: printf("random: entropy device infrastructure driver\n"); random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0644, "random"); make_dev_alias(random_dev, "urandom"); /* compatibility */ random_adaptors_init(); break; case MOD_UNLOAD: random_adaptors_deinit(); destroy_dev(random_dev); break; case MOD_SHUTDOWN: break; default: error = EOPNOTSUPP; break; } return (error); } -#define EARLY_2_DEV_MODULE(name, evh, arg) \ -static moduledata_t name##_mod = { \ - #name, \ - evh, \ - arg \ -}; \ -DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND) - -EARLY_2_DEV_MODULE(randomdev, randomdev_modevent, NULL); +DEV_MODULE_ORDERED(randomdev, randomdev_modevent, NULL, SI_ORDER_SECOND); MODULE_VERSION(randomdev, 1); /* ================ * Harvesting stubs * ================ */ /* Internal stub/fake routine for when no entropy processor is loaded. * If the entropy device is not loaded, don't act on harvesting calls * and just return. */ /* ARGSUSED */ static void random_harvest_phony(const void *entropy __unused, u_int count __unused, u_int bits __unused, enum random_entropy_source origin __unused) { } /* Hold the address of the routine which is actually called */ static void (*reap_func)(const void *, u_int, u_int, enum random_entropy_source) = random_harvest_phony; /* Initialise the harvester when/if it is loaded */ void randomdev_init_harvester(void (*reaper)(const void *, u_int, u_int, enum random_entropy_source)) { reap_func = reaper; } /* Deinitialise the harvester when/if it is unloaded */ void randomdev_deinit_harvester(void) { reap_func = random_harvest_phony; } /* Entropy harvesting routine. * Implemented as in indirect call to allow non-inclusion of * the entropy device. */ void random_harvest(const void *entropy, u_int count, u_int bits, enum random_entropy_source origin) { (*reap_func)(entropy, count, bits, origin); } /* ================================ * Internal reading stubs and fakes * ================================ */ /* Hold the address of the routine which is actually called */ static u_int (*read_func)(uint8_t *, u_int) = dummy_random_read_phony; /* Initialise the reader when/if it is loaded */ void randomdev_init_reader(u_int (*reader)(uint8_t *, u_int)) { read_func = reader; } /* Deinitialise the reader when/if it is unloaded */ void randomdev_deinit_reader(void) { read_func = dummy_random_read_phony; } /* Kernel API version of read_random(). * Implemented as in indirect call to allow non-inclusion of * the entropy device. */ int read_random(void *buf, int count) { return ((int)(*read_func)(buf, (u_int)count)); } Index: head/sys/dev/random/randomdev_soft.c =================================================================== --- head/sys/dev/random/randomdev_soft.c (revision 274251) +++ head/sys/dev/random/randomdev_soft.c (revision 274252) @@ -1,173 +1,165 @@ /*- * Copyright (c) 2000-2014 Mark R V Murray * Copyright (c) 2004 Robert N. M. Watson * 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. * */ /* * This is the loadable infrastructure base file for software CSPRNG * drivers such as Yarrow or Fortuna. * * It is anticipated that one instance of this file will be used * for _each_ invocation of a CSPRNG, but with different #defines * set. See below. * */ #include "opt_random.h" #if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA) #define RANDOM_YARROW #elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA) #error "Must define either RANDOM_YARROW or RANDOM_FORTUNA" #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(RANDOM_YARROW) #include #endif #if defined(RANDOM_FORTUNA) #include #endif static struct random_adaptor random_soft_processor = { #if defined(RANDOM_YARROW) #define RANDOM_CSPRNG_NAME "yarrow" .ra_ident = "Yarrow", .ra_priority = 90, /* High priority, so top of the list. Fortuna may still win. */ .ra_read = random_yarrow_read, .ra_write = random_yarrow_write, .ra_reseed = random_yarrow_reseed, .ra_seeded = random_yarrow_seeded, #endif #if defined(RANDOM_FORTUNA) #define RANDOM_CSPRNG_NAME "fortuna" .ra_ident = "Fortuna", .ra_priority = 100, /* High priority, so top of the list. Beat Yarrow. */ .ra_read = random_fortuna_read, .ra_write = random_fortuna_write, .ra_reseed = random_fortuna_reseed, .ra_seeded = random_fortuna_seeded, #endif .ra_init = randomdev_init, .ra_deinit = randomdev_deinit, }; void randomdev_init(void) { #if defined(RANDOM_YARROW) random_yarrow_init_alg(); random_harvestq_init(random_yarrow_process_event, 2); #endif #if defined(RANDOM_FORTUNA) random_fortuna_init_alg(); random_harvestq_init(random_fortuna_process_event, 32); #endif /* Register the randomness harvesting routine */ randomdev_init_harvester(random_harvestq_internal); } void randomdev_deinit(void) { /* Deregister the randomness harvesting routine */ randomdev_deinit_harvester(); #if defined(RANDOM_YARROW) random_yarrow_deinit_alg(); #endif #if defined(RANDOM_FORTUNA) random_fortuna_deinit_alg(); #endif } /* ARGSUSED */ static int randomdev_soft_modevent(module_t mod __unused, int type, void *unused __unused) { int error = 0; switch (type) { case MOD_LOAD: printf("random: SOFT: %s init()\n", RANDOM_CSPRNG_NAME); random_adaptor_register(RANDOM_CSPRNG_NAME, &random_soft_processor); break; case MOD_UNLOAD: random_adaptor_deregister(RANDOM_CSPRNG_NAME); break; case MOD_SHUTDOWN: break; default: error = EOPNOTSUPP; break; } return (error); } -#define MID_DEV_MODULE(name, evh, arg) \ -static moduledata_t name##_mod = { \ - #name, \ - evh, \ - arg \ -}; \ -DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) - #if defined(RANDOM_YARROW) -MID_DEV_MODULE(yarrow, randomdev_soft_modevent, NULL); +DEV_MODULE(yarrow, randomdev_soft_modevent, NULL); MODULE_VERSION(yarrow, 1); -MODULE_DEPEND(yarrow, random_adaptors, 1, 1, 1); +MODULE_DEPEND(yarrow, randomdev, 1, 1, 1); #endif #if defined(RANDOM_FORTUNA) -MID_DEV_MODULE(fortuna, randomdev_soft_modevent, NULL); +DEV_MODULE(fortuna, randomdev_soft_modevent, NULL); MODULE_VERSION(fortuna, 1); -MODULE_DEPEND(fortuna, random_adaptors, 1, 1, 1); +MODULE_DEPEND(fortuna, randomdev, 1, 1, 1); #endif Index: head/sys/modules/random/Makefile =================================================================== --- head/sys/modules/random/Makefile (revision 274251) +++ head/sys/modules/random/Makefile (revision 274252) @@ -1,16 +1,15 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../../dev/random .PATH: ${.CURDIR}/../../crypto/rijndael .PATH: ${.CURDIR}/../../crypto/sha2 KMOD= random SRCS= randomdev_soft.c -SRCS+= yarrow.c hash.c -SRCS+= random_harvestq.c live_entropy_sources.c +SRCS+= yarrow.c fortuna.c hash.c SRCS+= rijndael-alg-fst.c rijndael-api-fst.c sha2.c sha256c.c SRCS+= bus_if.h device_if.h vnode_if.h opt_cpu.h opt_random.h CFLAGS+= -I${.CURDIR}/../.. .include