randomdev_soft.c (253845) | randomdev_soft.c (254147) |
---|---|
1/*- 2 * Copyright (c) 2000-2009 Mark R V Murray 3 * Copyright (c) 2004 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2000-2009 Mark R V Murray 3 * Copyright (c) 2004 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/random/randomdev_soft.c 253845 2013-07-31 17:21:18Z obrien $"); | 30__FBSDID("$FreeBSD: head/sys/dev/random/randomdev_soft.c 254147 2013-08-09 15:31:50Z obrien $"); |
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/conf.h> 36#include <sys/fcntl.h> 37#include <sys/kernel.h> 38#include <sys/kthread.h> 39#include <sys/lock.h> 40#include <sys/malloc.h> | 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/conf.h> 36#include <sys/fcntl.h> 37#include <sys/kernel.h> 38#include <sys/kthread.h> 39#include <sys/lock.h> 40#include <sys/malloc.h> |
41#include <sys/module.h> |
|
41#include <sys/mutex.h> 42#include <sys/poll.h> 43#include <sys/proc.h> 44#include <sys/random.h> 45#include <sys/selinfo.h> 46#include <sys/sysctl.h> 47#include <sys/uio.h> 48#include <sys/unistd.h> 49 50#include <machine/bus.h> 51#include <machine/cpu.h> 52 | 42#include <sys/mutex.h> 43#include <sys/poll.h> 44#include <sys/proc.h> 45#include <sys/random.h> 46#include <sys/selinfo.h> 47#include <sys/sysctl.h> 48#include <sys/uio.h> 49#include <sys/unistd.h> 50 51#include <machine/bus.h> 52#include <machine/cpu.h> 53 |
54#include <dev/random/random_adaptors.h> |
|
53#include <dev/random/randomdev.h> 54#include <dev/random/randomdev_soft.h> 55 56#define RANDOM_FIFO_MAX 256 /* How many events to queue up */ 57 58static void random_kthread(void *); 59static void 60random_harvest_internal(u_int64_t, const void *, u_int, 61 u_int, u_int, enum esource); 62static int random_yarrow_poll(int event,struct thread *td); 63static int random_yarrow_block(int flag); 64static void random_yarrow_flush_reseed(void); 65 | 55#include <dev/random/randomdev.h> 56#include <dev/random/randomdev_soft.h> 57 58#define RANDOM_FIFO_MAX 256 /* How many events to queue up */ 59 60static void random_kthread(void *); 61static void 62random_harvest_internal(u_int64_t, const void *, u_int, 63 u_int, u_int, enum esource); 64static int random_yarrow_poll(int event,struct thread *td); 65static int random_yarrow_block(int flag); 66static void random_yarrow_flush_reseed(void); 67 |
66struct random_systat random_yarrow = { | 68struct random_adaptor random_yarrow = { |
67 .ident = "Software, Yarrow", 68 .init = random_yarrow_init, 69 .deinit = random_yarrow_deinit, 70 .block = random_yarrow_block, 71 .read = random_yarrow_read, 72 .write = random_yarrow_write, 73 .poll = random_yarrow_poll, 74 .reseed = random_yarrow_flush_reseed, --- 23 unchanged lines hidden (view full) --- 98static struct entropyfifo harvestfifo[ENTROPYSOURCE]; 99 100/* <0 to end the kthread, 0 to let it run, 1 to flush the harvest queues */ 101static int random_kthread_control = 0; 102 103static struct proc *random_kthread_proc; 104 105/* List for the dynamic sysctls */ | 69 .ident = "Software, Yarrow", 70 .init = random_yarrow_init, 71 .deinit = random_yarrow_deinit, 72 .block = random_yarrow_block, 73 .read = random_yarrow_read, 74 .write = random_yarrow_write, 75 .poll = random_yarrow_poll, 76 .reseed = random_yarrow_flush_reseed, --- 23 unchanged lines hidden (view full) --- 100static struct entropyfifo harvestfifo[ENTROPYSOURCE]; 101 102/* <0 to end the kthread, 0 to let it run, 1 to flush the harvest queues */ 103static int random_kthread_control = 0; 104 105static struct proc *random_kthread_proc; 106 107/* List for the dynamic sysctls */ |
106struct sysctl_ctx_list random_clist; | 108static struct sysctl_ctx_list random_clist; |
107 108/* ARGSUSED */ 109static int 110random_check_boolean(SYSCTL_HANDLER_ARGS) 111{ 112 if (oidp->oid_arg1 != NULL && *(u_int *)(oidp->oid_arg1) != 0) 113 *(u_int *)(oidp->oid_arg1) = 1; 114 return sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); 115} 116 117/* ARGSUSED */ 118void 119random_yarrow_init(void) 120{ 121 int error, i; 122 struct harvest *np; | 109 110/* ARGSUSED */ 111static int 112random_check_boolean(SYSCTL_HANDLER_ARGS) 113{ 114 if (oidp->oid_arg1 != NULL && *(u_int *)(oidp->oid_arg1) != 0) 115 *(u_int *)(oidp->oid_arg1) = 1; 116 return sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); 117} 118 119/* ARGSUSED */ 120void 121random_yarrow_init(void) 122{ 123 int error, i; 124 struct harvest *np; |
123 struct sysctl_oid *random_o, *random_sys_o, *random_sys_harvest_o; | 125 struct sysctl_oid *random_sys_o, *random_sys_harvest_o; |
124 enum esource e; 125 | 126 enum esource e; 127 |
126 random_o = SYSCTL_ADD_NODE(&random_clist, 127 SYSCTL_STATIC_CHILDREN(_kern), 128 OID_AUTO, "random", CTLFLAG_RW, 0, 129 "Software Random Number Generator"); | 128 random_yarrow_init_alg(&random_clist); |
130 | 129 |
131 random_yarrow_init_alg(&random_clist, random_o); 132 | |
133 random_sys_o = SYSCTL_ADD_NODE(&random_clist, | 130 random_sys_o = SYSCTL_ADD_NODE(&random_clist, |
134 SYSCTL_CHILDREN(random_o), | 131 SYSCTL_STATIC_CHILDREN(_kern_random), |
135 OID_AUTO, "sys", CTLFLAG_RW, 0, 136 "Entropy Device Parameters"); 137 138 SYSCTL_ADD_PROC(&random_clist, 139 SYSCTL_CHILDREN(random_sys_o), 140 OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW, | 132 OID_AUTO, "sys", CTLFLAG_RW, 0, 133 "Entropy Device Parameters"); 134 135 SYSCTL_ADD_PROC(&random_clist, 136 SYSCTL_CHILDREN(random_sys_o), 137 OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW, |
141 &random_systat->seeded, 1, random_check_boolean, "I", | 138 &random_yarrow.seeded, 1, random_check_boolean, "I", |
142 "Seeded State"); 143 144 random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist, 145 SYSCTL_CHILDREN(random_sys_o), 146 OID_AUTO, "harvest", CTLFLAG_RW, 0, 147 "Entropy Sources"); 148 149 SYSCTL_ADD_PROC(&random_clist, --- 207 unchanged lines hidden (view full) --- 357 random_harvest_internal(get_cyclecount(), (char *)buf + i, 358 chunk, 0, 0, RANDOM_WRITE); 359 } 360} 361 362void 363random_yarrow_unblock(void) 364{ | 139 "Seeded State"); 140 141 random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist, 142 SYSCTL_CHILDREN(random_sys_o), 143 OID_AUTO, "harvest", CTLFLAG_RW, 0, 144 "Entropy Sources"); 145 146 SYSCTL_ADD_PROC(&random_clist, --- 207 unchanged lines hidden (view full) --- 354 random_harvest_internal(get_cyclecount(), (char *)buf + i, 355 chunk, 0, 0, RANDOM_WRITE); 356 } 357} 358 359void 360random_yarrow_unblock(void) 361{ |
365 if (!random_systat->seeded) { 366 random_systat->seeded = 1; 367 selwakeuppri(&random_systat->rsel, PUSER); 368 wakeup(random_systat); | 362 if (!random_yarrow.seeded) { 363 random_yarrow.seeded = 1; 364 selwakeuppri(&random_yarrow.rsel, PUSER); 365 wakeup(&random_yarrow); |
369 } 370 (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, 371 ARC4_ENTR_HAVE); 372} 373 374static int 375random_yarrow_poll(int events, struct thread *td) 376{ 377 int revents = 0; 378 mtx_lock(&random_reseed_mtx); 379 | 366 } 367 (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, 368 ARC4_ENTR_HAVE); 369} 370 371static int 372random_yarrow_poll(int events, struct thread *td) 373{ 374 int revents = 0; 375 mtx_lock(&random_reseed_mtx); 376 |
380 if (random_systat->seeded) | 377 if (random_yarrow.seeded) |
381 revents = events & (POLLIN | POLLRDNORM); 382 else | 378 revents = events & (POLLIN | POLLRDNORM); 379 else |
383 selrecord(td, &random_systat->rsel); | 380 selrecord(td, &random_yarrow.rsel); |
384 385 mtx_unlock(&random_reseed_mtx); 386 return revents; 387} 388 389static int 390random_yarrow_block(int flag) 391{ 392 int error = 0; 393 394 mtx_lock(&random_reseed_mtx); 395 396 /* Blocking logic */ | 381 382 mtx_unlock(&random_reseed_mtx); 383 return revents; 384} 385 386static int 387random_yarrow_block(int flag) 388{ 389 int error = 0; 390 391 mtx_lock(&random_reseed_mtx); 392 393 /* Blocking logic */ |
397 while (!random_systat->seeded && !error) { | 394 while (!random_yarrow.seeded && !error) { |
398 if (flag & O_NONBLOCK) 399 error = EWOULDBLOCK; 400 else { 401 printf("Entropy device is blocking.\n"); | 395 if (flag & O_NONBLOCK) 396 error = EWOULDBLOCK; 397 else { 398 printf("Entropy device is blocking.\n"); |
402 error = msleep(random_systat, | 399 error = msleep(&random_yarrow, |
403 &random_reseed_mtx, 404 PUSER | PCATCH, "block", 0); 405 } 406 } 407 mtx_unlock(&random_reseed_mtx); 408 409 return error; 410} --- 4 unchanged lines hidden (view full) --- 415{ 416 /* Command a entropy queue flush and wait for it to finish */ 417 random_kthread_control = 1; 418 while (random_kthread_control) 419 pause("-", hz / 10); 420 421 random_yarrow_reseed(); 422} | 400 &random_reseed_mtx, 401 PUSER | PCATCH, "block", 0); 402 } 403 } 404 mtx_unlock(&random_reseed_mtx); 405 406 return error; 407} --- 4 unchanged lines hidden (view full) --- 412{ 413 /* Command a entropy queue flush and wait for it to finish */ 414 random_kthread_control = 1; 415 while (random_kthread_control) 416 pause("-", hz / 10); 417 418 random_yarrow_reseed(); 419} |
420 421static int 422yarrow_modevent(module_t mod, int type, void *unused) 423{ 424 425 switch (type) { 426 case MOD_LOAD: 427 random_adaptor_register("yarrow", &random_yarrow); 428 /* 429 * For statically built kernels that contain both device 430 * random and options PADLOCK_RNG/RDRAND_RNG/etc.., 431 * this event handler will do nothing, since the random 432 * driver-specific handlers are loaded after these HW 433 * consumers, and hence hasn't yet registered for this event. 434 * 435 * In case where both the random driver and RNG's are built 436 * as seperate modules, random.ko is loaded prior to *_rng.ko's 437 * (by dependency). This event handler is there to delay 438 * creation of /dev/{u,}random and attachment of this *_rng.ko. 439 */ 440 EVENTHANDLER_INVOKE(random_adaptor_attach, &random_yarrow); 441 return (0); 442 } 443 444 return (EINVAL); 445} 446 447RANDOM_ADAPTOR_MODULE(yarrow, yarrow_modevent, 1); |
|