diff options
Diffstat (limited to 'sys/dev/random/yarrow.c')
-rw-r--r-- | sys/dev/random/yarrow.c | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/sys/dev/random/yarrow.c b/sys/dev/random/yarrow.c index 1360d8e..fe4d160 100644 --- a/sys/dev/random/yarrow.c +++ b/sys/dev/random/yarrow.c @@ -38,6 +38,7 @@ #include <sys/libkern.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/select.h> #include <sys/random.h> #include <sys/time.h> #include <sys/types.h> @@ -45,8 +46,8 @@ #include <machine/mutex.h> #include <crypto/blowfish/blowfish.h> -#include <dev/randomdev/hash.h> -#include <dev/randomdev/yarrow.h> +#include <dev/random/hash.h> +#include <dev/random/yarrow.h> /* #define DEBUG */ /* #define DEBUG1 */ /* Very noisy - prints plenty harvesting stats */ @@ -65,11 +66,11 @@ TAILQ_HEAD(harvestqueue, harvest) harvestqueue, initqueue = TAILQ_HEAD_INITIALIZER(harvestqueue); /* These are used to queue harvested packets of entropy. The entropy - * buffer size of 16 is pretty arbitrary. + * buffer size is pretty arbitrary. */ struct harvest { struct timespec time; /* nanotime for clock jitter */ - u_char entropy[16]; /* the harvested entropy */ + u_char entropy[HARVESTSIZE]; /* the harvested entropy */ u_int size, bits, frac; /* stats about the entropy */ enum esource source; /* stats about the entropy */ u_int pool; /* which pool this goes into */ @@ -79,19 +80,18 @@ struct harvest { /* The reseed thread mutex */ static struct mtx random_reseed_mtx; -/* The entropy harvest mutex */ +/* The entropy harvest mutex, as well as the mutex associated + * with the msleep() call during deinit + */ static struct mtx random_harvest_mtx; -/* <0 until the kthread starts, 0 for running */ -static int random_kthread_status = -1; - /* <0 to end the kthread, 0 to let it run */ static int random_kthread_control = 0; static struct proc *random_kthread_proc; static void -random_kthread(void *status) +random_kthread(void *arg /* NOTUSED */) { int pl, src, overthreshhold[2]; struct harvest *event; @@ -101,10 +101,8 @@ random_kthread(void *status) #endif #ifdef DEBUG - printf("At %s, line %d: mtx_owned(&Giant) == %d\n", __FILE__, __LINE__, mtx_owned(&Giant)); - printf("At %s, line %d: mtx_owned(&sched_lock) == %d\n", __FILE__, __LINE__, mtx_owned(&sched_lock)); + printf("At %s, line %d: mtx_owned(&Giant) == %d, mtx_owned(&sched_lock) == %d\n", __FILE__, __LINE__, mtx_owned(&Giant), mtx_owned(&sched_lock)); #endif - random_set_wakeup((int *)status, 0); for (pl = 0; pl < 2; pl++) yarrow_hash_init(&random_state.pool[pl].hash, NULL, 0); @@ -148,9 +146,6 @@ random_kthread(void *status) source->frac %= 1024; free(event, M_TEMP); - /* XXX abuse tsleep() to get at mi_switch() */ - /* tsleep(&harvestqueue, PUSER, "rndprc", 1); */ - } #ifdef DEBUG1 printf("Harvested %d events\n", queuecount); @@ -177,7 +172,7 @@ random_kthread(void *status) } /* Is the thread scheduled for a shutdown? */ - if (random_kthread_control < 0) { + if (random_kthread_control != 0) { if (!TAILQ_EMPTY(&harvestqueue)) { #ifdef DEBUG printf("Random cleaning extraneous events\n"); @@ -192,7 +187,8 @@ random_kthread(void *status) #ifdef DEBUG printf("Random kthread setting terminate\n"); #endif - random_set_wakeup_exit((int *)status, -1, 0); + random_set_wakeup_exit(&random_kthread_control); + /* NOTREACHED */ break; } @@ -223,13 +219,13 @@ random_init(void) mtx_init(&random_harvest_mtx, "random harvest", MTX_DEF); /* Start the hash/reseed thread */ - error = kthread_create(random_kthread, &random_kthread_status, + error = kthread_create(random_kthread, NULL, &random_kthread_proc, RFHIGHPID, "random"); if (error != 0) return error; /* Register the randomness harvesting routine */ - random_init_harvester(random_harvest_internal); + random_init_harvester(random_harvest_internal, read_random_real); #ifdef DEBUG printf("Random initalise finish\n"); @@ -253,9 +249,11 @@ random_deinit(void) #endif /* Command the hash/reseed thread to end and wait for it to finish */ + mtx_enter(&random_harvest_mtx, MTX_DEF); random_kthread_control = -1; - while (random_kthread_status != -1) - tsleep(&random_kthread_status, PUSER, "rndend", hz); + msleep((void *)&random_kthread_control, &random_harvest_mtx, PUSER, + "rndend", 0); + mtx_exit(&random_harvest_mtx, MTX_DEF); #ifdef DEBUG printf("Random deinitalise removing mutexes\n"); @@ -364,10 +362,16 @@ reseed(int fastslow) printf("Reseed finish\n"); #endif + if (!random_state.seeded) { + random_state.seeded = 1; + selwakeup(&random_state.rsel); + wakeup(&random_state); + } + } u_int -read_random(void *buf, u_int count) +read_random_real(void *buf, u_int count) { static u_int64_t genval; static int cur = 0; @@ -430,19 +434,19 @@ write_random(void *buf, u_int count) u_int i; struct timespec timebuf; - /* arbitrarily break the input up into 8-byte chunks */ - for (i = 0; i < count; i += 8) { + /* arbitrarily break the input up into HARVESTSIZE chunks */ + for (i = 0; i < count; i += HARVESTSIZE) { nanotime(&timebuf); - random_harvest_internal(&timebuf, (char *)buf + i, 8, 0, 0, + random_harvest_internal(&timebuf, (char *)buf + i, HARVESTSIZE, 0, 0, RANDOM_WRITE); } /* Maybe the loop iterated at least once */ if (i > count) - i -= 8; + i -= HARVESTSIZE; - /* Get the last bytes even if the input length is not a multiple of 8 */ - count %= 8; + /* Get the last bytes even if the input length is not a multiple of HARVESTSIZE */ + count %= HARVESTSIZE; if (count) { nanotime(&timebuf); random_harvest_internal(&timebuf, (char *)buf + i, count, 0, 0, @@ -486,7 +490,6 @@ random_harvest_internal(struct timespec *timep, void *entropy, u_int count, u_int bits, u_int frac, enum esource origin) { struct harvest *event; - u_int64_t entropy_buf; #if 0 #ifdef DEBUG @@ -501,8 +504,8 @@ random_harvest_internal(struct timespec *timep, void *entropy, u_int count, event->time = *timep; /* the harvested entropy */ - count = count > sizeof(entropy_buf) - ? sizeof(entropy_buf) + count = count > sizeof(event->entropy) + ? sizeof(event->entropy) : count; memcpy(event->entropy, entropy, count); |