diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/random/harvest.c | 77 | ||||
-rw-r--r-- | sys/dev/random/hash.c | 2 | ||||
-rw-r--r-- | sys/dev/random/randomdev.c | 46 | ||||
-rw-r--r-- | sys/dev/random/yarrow.c | 65 | ||||
-rw-r--r-- | sys/dev/random/yarrow.h | 10 | ||||
-rw-r--r-- | sys/dev/randomdev/harvest.c | 91 | ||||
-rw-r--r-- | sys/dev/randomdev/hash.c | 119 | ||||
-rw-r--r-- | sys/dev/randomdev/hash.h | 46 | ||||
-rw-r--r-- | sys/dev/randomdev/randomdev.c | 175 | ||||
-rw-r--r-- | sys/dev/randomdev/yarrow.c | 525 | ||||
-rw-r--r-- | sys/dev/randomdev/yarrow.h | 75 |
11 files changed, 139 insertions, 1092 deletions
diff --git a/sys/dev/random/harvest.c b/sys/dev/random/harvest.c index 4bfac55..2f9ac2b 100644 --- a/sys/dev/random/harvest.c +++ b/sys/dev/random/harvest.c @@ -31,30 +31,38 @@ #include <sys/types.h> #include <sys/queue.h> #include <sys/kthread.h> +#include <sys/poll.h> +#include <sys/select.h> #include <sys/random.h> #include <sys/time.h> +#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> + +static u_int read_random_phony(void *, u_int); /* hold the address of the routine which is actually called if * the ramdomdev is loaded */ -static void (*reap)(struct timespec *, void *, u_int, u_int, u_int, u_int) = NULL; +static void (*reap_func)(struct timespec *, void *, u_int, u_int, u_int, u_int) = NULL; +static u_int (*read_func)(void *, u_int) = read_random_phony; /* Initialise the harvester at load time */ void -random_init_harvester(void (*reaper)(struct timespec *, void *, u_int, u_int, u_int, u_int)) +random_init_harvester(void (*reaper)(struct timespec *, void *, u_int, u_int, u_int, u_int), u_int (*reader)(void *, u_int)) { - reap = reaper; + reap_func = reaper; + read_func = reader; } /* Deinitialise the harvester at unload time */ void random_deinit_harvester(void) { - reap = NULL; + reap_func = NULL; + read_func = read_random_phony; } /* Entropy harvesting routine. This is supposed to be fast; do @@ -67,25 +75,60 @@ random_harvest(void *entropy, u_int count, u_int bits, u_int frac, u_int origin) { struct timespec timebuf; - if (reap) { + if (reap_func) { nanotime(&timebuf); - (*reap)(&timebuf, entropy, count, bits, frac, origin); + (*reap_func)(&timebuf, entropy, count, bits, frac, origin); } } -/* Helper routines to enable kthread_exit() to work while the module is - * being (or has been) unloaded. +/* Userland-visible version of read_random */ +u_int +read_random(void *buf, u_int count) +{ + return (*read_func)(buf, count); +} + +/* If the entropy device is not loaded, make a token effort to + * provide _some_ kind of randomness. This should only be used + * inside other RNG's, like arc4random(9). */ -void -random_set_wakeup(int *var, int value) +static u_int +read_random_phony(void *buf, u_int count) { - *var = value; - wakeup(var); + struct timespec timebuf; + u_long randval; + int size, i; + static int initialised = 0; + + /* Try to give random(9) a half decent initialisation + * DO not make the mistake of thinking this is secure!! + */ + if (!initialised) { + nanotime(&timebuf); + srandom((u_long)(timebuf.tv_sec ^ timebuf.tv_nsec)); + } + + /* Fill buf[] with random(9) output */ + for (i = 0; i < count; i+= sizeof(u_long)) { + randval = random(); + size = (count - i) < sizeof(u_long) ? (count - i) : sizeof(u_long); + memcpy(&((char *)buf)[i], &randval, size); + } + + return count; } +/* Helper routine to enable kthread_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 -random_set_wakeup_exit(int *var, int value, int exitval) +random_set_wakeup_exit(void *control) { - random_set_wakeup(var, value); - kthread_exit(exitval); + wakeup(control); + mtx_enter(&Giant, MTX_DEF); + kthread_exit(0); + /* NOTREACHED */ } diff --git a/sys/dev/random/hash.c b/sys/dev/random/hash.c index 432a54b..47bf7c2 100644 --- a/sys/dev/random/hash.c +++ b/sys/dev/random/hash.c @@ -35,7 +35,7 @@ #include <sys/types.h> #include <crypto/blowfish/blowfish.h> -#include <dev/randomdev/hash.h> +#include <dev/random/hash.h> /* initialise the hash by copying in some supplied data */ void diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index d6796ef..eaa47b9 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -36,20 +36,24 @@ #include <sys/malloc.h> #include <sys/module.h> #include <sys/bus.h> +#include <sys/poll.h> #include <sys/proc.h> +#include <sys/select.h> #include <sys/random.h> +#include <sys/vnode.h> #include <machine/bus.h> #include <machine/resource.h> #include <sys/sysctl.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> static d_open_t random_open; static d_read_t random_read; static d_write_t random_write; static d_ioctl_t random_ioctl; +static d_poll_t random_poll; #define CDEV_MAJOR 2 #define RANDOM_MINOR 3 @@ -61,7 +65,7 @@ static struct cdevsw random_cdevsw = { /* read */ random_read, /* write */ random_write, /* ioctl */ random_ioctl, - /* poll */ nopoll, + /* poll */ random_poll, /* mmap */ nommap, /* strategy */ nostrategy, /* name */ "random", @@ -105,13 +109,22 @@ random_read(dev_t dev, struct uio *uio, int flag) int error = 0; void *random_buf; - c = min(uio->uio_resid, PAGE_SIZE); - random_buf = (void *)malloc(c, M_TEMP, M_WAITOK); - while (uio->uio_resid > 0 && error == 0) { - ret = read_random(random_buf, c); - error = uiomove(random_buf, ret, uio); + if (flag & IO_NDELAY && !random_state.seeded) { + error = EWOULDBLOCK; + } + else { + if (random_state.seeded) { + c = min(uio->uio_resid, PAGE_SIZE); + random_buf = (void *)malloc(c, M_TEMP, M_WAITOK); + while (uio->uio_resid > 0 && error == 0) { + ret = read_random_real(random_buf, c); + error = uiomove(random_buf, ret, uio); + } + free(random_buf, M_TEMP); + } + else + error = tsleep(&random_state, 0, "rndblk", 0); } - free(random_buf, M_TEMP); return error; } @@ -141,6 +154,21 @@ random_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } static int +random_poll(dev_t dev, int events, struct proc *p) +{ + int revents; + + revents = 0; + if (events & (POLLIN | POLLRDNORM)) { + if (random_state.seeded) + revents = events & (POLLIN | POLLRDNORM); + else + selrecord(p, &random_state.rsel); + } + return revents; +} + +static int random_modevent(module_t mod, int type, void *data) { int error; 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); diff --git a/sys/dev/random/yarrow.h b/sys/dev/random/yarrow.h index a81fa1f..4bf97fd 100644 --- a/sys/dev/random/yarrow.h +++ b/sys/dev/random/yarrow.h @@ -36,16 +36,18 @@ #define ENTROPYBIN 256 /* buckets to harvest entropy events */ #define TIMEBIN 16 /* max value for Pt/t */ +#define HARVESTSIZE 16 /* max size of each harvested entropy unit */ + #define FAST 0 #define SLOW 1 int random_init(void); void random_deinit(void); -void random_init_harvester(void (*)(struct timespec *, void *, u_int, u_int, u_int, enum esource)); +void random_init_harvester(void (*)(struct timespec *, void *, u_int, u_int, u_int, enum esource), u_int (*)(void *, u_int)); void random_deinit_harvester(void); -void random_set_wakeup(int *, int); -void random_set_wakeup_exit(int *, int, int); +void random_set_wakeup_exit(void *); +u_int read_random_real(void *, u_int); void write_random(void *, u_int); /* This is the beastie that needs protecting. It contains all of the @@ -70,6 +72,8 @@ struct random_state { struct yarrowhash hash; /* accumulated entropy */ } pool[2]; /* pool[0] is fast, pool[1] is slow */ int which; /* toggle - shows the current insertion pool */ + int seeded; /* 0 until first reseed, then 1 */ + struct selinfo rsel; /* For poll(2) */ }; extern struct random_state random_state; diff --git a/sys/dev/randomdev/harvest.c b/sys/dev/randomdev/harvest.c deleted file mode 100644 index 4bfac55..0000000 --- a/sys/dev/randomdev/harvest.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/types.h> -#include <sys/queue.h> -#include <sys/kthread.h> -#include <sys/random.h> -#include <sys/time.h> -#include <crypto/blowfish/blowfish.h> - -#include <dev/randomdev/hash.h> -#include <dev/randomdev/yarrow.h> - -/* hold the address of the routine which is actually called if - * the ramdomdev is loaded - */ -static void (*reap)(struct timespec *, void *, u_int, u_int, u_int, u_int) = NULL; - -/* Initialise the harvester at load time */ -void -random_init_harvester(void (*reaper)(struct timespec *, void *, u_int, u_int, u_int, u_int)) -{ - reap = reaper; -} - -/* Deinitialise the harvester at unload time */ -void -random_deinit_harvester(void) -{ - reap = NULL; -} - -/* Entropy harvesting routine. This is supposed to be fast; do - * not do anything slow in here! - * Implemented as in indirect call to allow non-inclusion of - * the entropy device. - */ -void -random_harvest(void *entropy, u_int count, u_int bits, u_int frac, u_int origin) -{ - struct timespec timebuf; - - if (reap) { - nanotime(&timebuf); - (*reap)(&timebuf, entropy, count, bits, frac, origin); - } -} - -/* Helper routines to enable kthread_exit() to work while the module is - * being (or has been) unloaded. - */ -void -random_set_wakeup(int *var, int value) -{ - *var = value; - wakeup(var); -} - -void -random_set_wakeup_exit(int *var, int value, int exitval) -{ - random_set_wakeup(var, value); - kthread_exit(exitval); -} diff --git a/sys/dev/randomdev/hash.c b/sys/dev/randomdev/hash.c deleted file mode 100644 index 432a54b..0000000 --- a/sys/dev/randomdev/hash.c +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/libkern.h> -#include <sys/random.h> -#include <sys/time.h> -#include <sys/types.h> -#include <crypto/blowfish/blowfish.h> - -#include <dev/randomdev/hash.h> - -/* initialise the hash by copying in some supplied data */ -void -yarrow_hash_init(struct yarrowhash *context, void *data, size_t size) -{ - size_t count; - - count = size > KEYSIZE ? KEYSIZE : size; - memset(context->hash, 0xff, KEYSIZE); - memcpy(context->hash, data, count); -} - -/* Do a Davies-Meyer hash using a block cipher. - * H_0 = I - * H_i = E_M_i(H_i-1) ^ H_i-1 - */ -void -yarrow_hash_iterate(struct yarrowhash *context, void *data, size_t size) -{ - u_char keybuffer[KEYSIZE], temp[KEYSIZE]; - size_t count; - int iteration, last, i; - - iteration = 0; - last = 0; - for (;;) { - if (size <= KEYSIZE) - last = 1; - count = size > KEYSIZE ? KEYSIZE : size; - memcpy(keybuffer, &((u_char *)data)[iteration], count); - memset(&keybuffer[KEYSIZE - count], 0xff, count); - BF_set_key(&context->hashkey, count, - &((u_char *)data)[iteration]); - BF_cbc_encrypt(context->hash, temp, KEYSIZE, &context->hashkey, - context->ivec, BF_ENCRYPT); - for (i = 0; i < KEYSIZE; i++) - context->hash[i] ^= temp[i]; - if (last) - break; - iteration += KEYSIZE; - size -= KEYSIZE; - } -} - -/* Conclude by returning a pointer to the data */ -void -yarrow_hash_finish(struct yarrowhash *context, void *buf) -{ - memcpy(buf, context->hash, sizeof(context->hash)); -} - -/* Initialise the encryption routine by setting up the key schedule */ -void -yarrow_encrypt_init(struct yarrowkey *context, void *data, size_t size) -{ - size_t count; - - count = size > KEYSIZE ? KEYSIZE : size; - BF_set_key(&context->key, size, data); -} - -/* Encrypt the supplied data using the key schedule preset in the context */ -void -yarrow_encrypt(struct yarrowkey *context, void *d_in, void *d_out, size_t size) -{ - size_t count; - int iteration, last; - - last = 0; - for (iteration = 0;; iteration += KEYSIZE) { - if (size <= KEYSIZE) - last = 1; - count = size > KEYSIZE ? KEYSIZE : size; - BF_cbc_encrypt(&((u_char *)d_in)[iteration], - &((u_char *)d_out)[iteration], count, &context->key, - context->ivec, BF_ENCRYPT); - if (last) - break; - size -= KEYSIZE; - } -} diff --git a/sys/dev/randomdev/hash.h b/sys/dev/randomdev/hash.h deleted file mode 100644 index f210f13..0000000 --- a/sys/dev/randomdev/hash.h +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -#define KEYSIZE 32 /* 32 bytes == 256 bits */ - -struct yarrowhash { /* Big! Make static! */ - BF_KEY hashkey; /* Data cycles through here */ - u_char ivec[8]; /* Blowfish Internal */ - u_char hash[KEYSIZE]; /* Repeatedly encrypted */ -}; - -struct yarrowkey { /* Big! Make static! */ - BF_KEY key; /* Key schedule */ - u_char ivec[8]; /* Blowfish Internal */ -}; - -void yarrow_hash_init(struct yarrowhash *, void *, size_t); -void yarrow_hash_iterate(struct yarrowhash *, void *, size_t); -void yarrow_hash_finish(struct yarrowhash *, void *); -void yarrow_encrypt_init(struct yarrowkey *, void *, size_t); -void yarrow_encrypt(struct yarrowkey *context, void *, void *, size_t); diff --git a/sys/dev/randomdev/randomdev.c b/sys/dev/randomdev/randomdev.c deleted file mode 100644 index d6796ef..0000000 --- a/sys/dev/randomdev/randomdev.c +++ /dev/null @@ -1,175 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -#include <sys/param.h> -#include <sys/queue.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/proc.h> -#include <sys/random.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/sysctl.h> -#include <crypto/blowfish/blowfish.h> - -#include <dev/randomdev/hash.h> -#include <dev/randomdev/yarrow.h> - -static d_open_t random_open; -static d_read_t random_read; -static d_write_t random_write; -static d_ioctl_t random_ioctl; - -#define CDEV_MAJOR 2 -#define RANDOM_MINOR 3 -#define URANDOM_MINOR 4 - -static struct cdevsw random_cdevsw = { - /* open */ random_open, - /* close */ (d_close_t *)nullop, - /* read */ random_read, - /* write */ random_write, - /* ioctl */ random_ioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ nostrategy, - /* name */ "random", - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ 0, - /* bmaj */ -1 -}; - -/* For use with make_dev(9)/destroy_dev(9). */ -static dev_t random_dev; -static dev_t urandom_dev; /* XXX Temporary */ - -SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0, "Random Number Generator"); -SYSCTL_NODE(_kern_random, OID_AUTO, yarrow, CTLFLAG_RW, 0, "Yarrow Parameters"); -SYSCTL_INT(_kern_random_yarrow, OID_AUTO, gengateinterval, CTLFLAG_RW, - &random_state.gengateinterval, 10, "Generator Gate Interval"); -SYSCTL_INT(_kern_random_yarrow, OID_AUTO, bins, CTLFLAG_RW, - &random_state.bins, 10, "Execution time tuner"); -SYSCTL_INT(_kern_random_yarrow, OID_AUTO, fastthresh, CTLFLAG_RW, - &random_state.pool[0].thresh, 100, "Fast pool reseed threshhold"); -SYSCTL_INT(_kern_random_yarrow, OID_AUTO, slowthresh, CTLFLAG_RW, - &random_state.pool[1].thresh, 160, "Slow pool reseed threshhold"); -SYSCTL_INT(_kern_random_yarrow, OID_AUTO, slowoverthresh, CTLFLAG_RW, - &random_state.slowoverthresh, 2, "Slow pool over-threshhold reseed"); - -static int -random_open(dev_t dev, int flags, int fmt, struct proc *p) -{ - if ((flags & FWRITE) && (securelevel > 0 || suser(p))) - return EPERM; - else - return 0; -} - -static int -random_read(dev_t dev, struct uio *uio, int flag) -{ - u_int c, ret; - int error = 0; - void *random_buf; - - c = min(uio->uio_resid, PAGE_SIZE); - random_buf = (void *)malloc(c, M_TEMP, M_WAITOK); - while (uio->uio_resid > 0 && error == 0) { - ret = read_random(random_buf, c); - error = uiomove(random_buf, ret, uio); - } - free(random_buf, M_TEMP); - return error; -} - -static int -random_write(dev_t dev, struct uio *uio, int flag) -{ - u_int c; - int error = 0; - void *random_buf; - - random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); - while (uio->uio_resid > 0) { - c = min(uio->uio_resid, PAGE_SIZE); - error = uiomove(random_buf, c, uio); - if (error) - break; - write_random(random_buf, c); - } - free(random_buf, M_TEMP); - return error; -} - -static int -random_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) -{ - return ENOTTY; -} - -static int -random_modevent(module_t mod, int type, void *data) -{ - int error; - - switch(type) { - case MOD_LOAD: - error = random_init(); - if (error != 0) - return error; - if (bootverbose) - printf("random: <entropy source>\n"); - random_dev = make_dev(&random_cdevsw, RANDOM_MINOR, UID_ROOT, - GID_WHEEL, 0666, "random"); - urandom_dev = make_dev(&random_cdevsw, URANDOM_MINOR, UID_ROOT, - GID_WHEEL, 0666, "urandom"); /* XXX Temporary */ - return 0; - - case MOD_UNLOAD: - random_deinit(); - destroy_dev(random_dev); - destroy_dev(urandom_dev); /* XXX Temporary */ - return 0; - - case MOD_SHUTDOWN: - return 0; - - default: - return EOPNOTSUPP; - } -} - -DEV_MODULE(random, random_modevent, NULL); diff --git a/sys/dev/randomdev/yarrow.c b/sys/dev/randomdev/yarrow.c deleted file mode 100644 index 1360d8e..0000000 --- a/sys/dev/randomdev/yarrow.c +++ /dev/null @@ -1,525 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -/* NOTE NOTE NOTE - This is not finished! It will supply numbers, but - * it is not yet cryptographically secure!! - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/kernel.h> -#include <sys/kthread.h> -#include <sys/libkern.h> -#include <sys/malloc.h> -#include <sys/proc.h> -#include <sys/random.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/unistd.h> -#include <machine/mutex.h> -#include <crypto/blowfish/blowfish.h> - -#include <dev/randomdev/hash.h> -#include <dev/randomdev/yarrow.h> - -/* #define DEBUG */ -/* #define DEBUG1 */ /* Very noisy - prints plenty harvesting stats */ - -static void generator_gate(void); -static void reseed(int); -static void random_harvest_internal(struct timespec *, void *, u_int, u_int, u_int, enum esource); - -static void random_kthread(void *); - -/* Structure holding the entropy state */ -struct random_state random_state; - -/* Queue holding harvested entropy */ -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. - */ -struct harvest { - struct timespec time; /* nanotime for clock jitter */ - u_char entropy[16]; /* 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 */ - TAILQ_ENTRY(harvest) harvest; /* link to next */ -}; - -/* The reseed thread mutex */ -static struct mtx random_reseed_mtx; - -/* The entropy harvest mutex */ -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) -{ - int pl, src, overthreshhold[2]; - struct harvest *event; - struct source *source; -#ifdef DEBUG1 - int queuecount; -#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)); -#endif - random_set_wakeup((int *)status, 0); - - for (pl = 0; pl < 2; pl++) - yarrow_hash_init(&random_state.pool[pl].hash, NULL, 0); - - for (;;) { - - if (TAILQ_EMPTY(&harvestqueue)) { - - /* Sleep for a second to give the system a chance */ - mtx_enter(&Giant, MTX_DEF); - tsleep(&harvestqueue, PUSER, "rndslp", hz); - mtx_exit(&Giant, MTX_DEF); - - } - else { - - /* Suck the harvested entropy out of the queue and hash - * it into the fast and slow pools. - */ -#ifdef DEBUG1 - queuecount = 0; -#endif - while (!TAILQ_EMPTY(&harvestqueue)) { -#ifdef DEBUG1 - queuecount++; -#endif - mtx_enter(&random_harvest_mtx, MTX_DEF); - - event = TAILQ_FIRST(&harvestqueue); - TAILQ_REMOVE(&harvestqueue, event, harvest); - - mtx_exit(&random_harvest_mtx, MTX_DEF); - - source = &random_state.pool[event->pool].source[event->source]; - yarrow_hash_iterate(&random_state.pool[event->pool].hash, - event->entropy, sizeof(event->entropy)); - yarrow_hash_iterate(&random_state.pool[event->pool].hash, - &event->time, sizeof(event->time)); - source->frac += event->frac; - source->bits += event->bits + source->frac/1024; - 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); -#endif - - /* Count the over-threshold sources in each pool */ - for (pl = 0; pl < 2; pl++) { - overthreshhold[pl] = 0; - for (src = 0; src < ENTROPYSOURCE; src++) { - if (random_state.pool[pl].source[src].bits - > random_state.pool[pl].thresh) - overthreshhold[pl]++; - } - } - - /* if any fast source over threshhold, reseed */ - if (overthreshhold[FAST]) - reseed(FAST); - - /* if enough slow sources are over threshhold, reseed */ - if (overthreshhold[SLOW] >= random_state.slowoverthresh) - reseed(SLOW); - - } - - /* Is the thread scheduled for a shutdown? */ - if (random_kthread_control < 0) { - if (!TAILQ_EMPTY(&harvestqueue)) { -#ifdef DEBUG - printf("Random cleaning extraneous events\n"); -#endif - mtx_enter(&random_harvest_mtx, MTX_DEF); - TAILQ_FOREACH(event, &harvestqueue, harvest) { - TAILQ_REMOVE(&harvestqueue, event, harvest); - free(event, M_TEMP); - } - mtx_exit(&random_harvest_mtx, MTX_DEF); - } -#ifdef DEBUG - printf("Random kthread setting terminate\n"); -#endif - random_set_wakeup_exit((int *)status, -1, 0); - break; - } - - } - -} - -int -random_init(void) -{ - int error; - -#ifdef DEBUG - printf("Random initialise\n"); -#endif - - random_state.gengateinterval = 10; - random_state.bins = 10; - random_state.pool[0].thresh = 100; - random_state.pool[1].thresh = 160; - random_state.slowoverthresh = 2; - random_state.which = FAST; - - harvestqueue = initqueue; - - /* Initialise the mutexes */ - mtx_init(&random_reseed_mtx, "random reseed", MTX_DEF); - mtx_init(&random_harvest_mtx, "random harvest", MTX_DEF); - - /* Start the hash/reseed thread */ - error = kthread_create(random_kthread, &random_kthread_status, - &random_kthread_proc, RFHIGHPID, "random"); - if (error != 0) - return error; - - /* Register the randomness harvesting routine */ - random_init_harvester(random_harvest_internal); - -#ifdef DEBUG - printf("Random initalise finish\n"); -#endif - - return 0; -} - -void -random_deinit(void) -{ -#ifdef DEBUG - printf("Random deinitalise\n"); -#endif - - /* Deregister the randomness harvesting routine */ - random_deinit_harvester(); - -#ifdef DEBUG - printf("Random deinitalise waiting for thread to terminate\n"); -#endif - - /* Command the hash/reseed thread to end and wait for it to finish */ - random_kthread_control = -1; - while (random_kthread_status != -1) - tsleep(&random_kthread_status, PUSER, "rndend", hz); - -#ifdef DEBUG - printf("Random deinitalise removing mutexes\n"); -#endif - - /* Remove the mutexes */ - mtx_destroy(&random_reseed_mtx); - mtx_destroy(&random_harvest_mtx); - -#ifdef DEBUG - printf("Random deinitalise finish\n"); -#endif -} - -static void -reseed(int fastslow) -{ - /* Interrupt-context stack is a limited resource; make large - * structures static. - */ - static u_char v[TIMEBIN][KEYSIZE]; /* v[i] */ - static struct yarrowhash context; - u_char hash[KEYSIZE]; /* h' */ - u_char temp[KEYSIZE]; - int i, j; - -#ifdef DEBUG - printf("Reseed type %d\n", fastslow); -#endif - - /* The reseed task must not be jumped on */ - mtx_enter(&random_reseed_mtx, MTX_DEF); - - /* 1. Hash the accumulated entropy into v[0] */ - - yarrow_hash_init(&context, NULL, 0); - /* Feed the slow pool hash in if slow */ - if (fastslow == SLOW) - yarrow_hash_iterate(&context, - &random_state.pool[SLOW].hash, sizeof(struct yarrowhash)); - - yarrow_hash_iterate(&context, - &random_state.pool[FAST].hash, sizeof(struct yarrowhash)); - - /* 2. Compute hash values for all v. _Supposed_ to be computationally - * intensive. - */ - - if (random_state.bins > TIMEBIN) - random_state.bins = TIMEBIN; - for (i = 1; i < random_state.bins; i++) { - yarrow_hash_init(&context, NULL, 0); - /* v[i] #= h(v[i-1]) */ - yarrow_hash_iterate(&context, v[i - 1], KEYSIZE); - /* v[i] #= h(v[0]) */ - yarrow_hash_iterate(&context, v[0], KEYSIZE); - /* v[i] #= h(i) */ - yarrow_hash_iterate(&context, &i, sizeof(int)); - /* Return the hashval */ - yarrow_hash_finish(&context, v[i]); - } - - /* 3. Compute a new key; h' is the identity function here; - * it is not being ignored! - */ - - yarrow_hash_init(&context, NULL, 0); - yarrow_hash_iterate(&context, &random_state.key, KEYSIZE); - for (i = 1; i < random_state.bins; i++) - yarrow_hash_iterate(&context, &v[i], KEYSIZE); - yarrow_hash_finish(&context, temp); - yarrow_encrypt_init(&random_state.key, temp, KEYSIZE); - - /* 4. Recompute the counter */ - - random_state.counter = 0; - yarrow_encrypt(&random_state.key, &random_state.counter, temp, - sizeof(random_state.counter)); - memcpy(&random_state.counter, temp, random_state.counter); - - /* 5. Reset entropy estimate accumulators to zero */ - - for (i = 0; i <= fastslow; i++) { - for (j = 0; j < ENTROPYSOURCE; j++) { - if (random_state.pool[i].source[j].bits > - random_state.pool[i].thresh) { - random_state.pool[i].source[j].bits = 0; - random_state.pool[i].source[j].frac = 0; - } - } - } - - /* 6. Wipe memory of intermediate values */ - - memset((void *)v, 0, sizeof(v)); - memset((void *)temp, 0, sizeof(temp)); - memset((void *)hash, 0, sizeof(hash)); - - /* 7. Dump to seed file */ - /* XXX Not done here yet */ - - /* Release the reseed mutex */ - mtx_exit(&random_reseed_mtx, MTX_DEF); - -#ifdef DEBUG - printf("Reseed finish\n"); -#endif - -} - -u_int -read_random(void *buf, u_int count) -{ - static u_int64_t genval; - static int cur = 0; - static int gate = 1; - u_int i; - u_int retval; - - /* The reseed task must not be jumped on */ - mtx_enter(&random_reseed_mtx, MTX_DEF); - - if (gate) { - generator_gate(); - random_state.outputblocks = 0; - gate = 0; - } - if (count >= sizeof(random_state.counter)) { - retval = 0; - for (i = 0; i < count; i += sizeof(random_state.counter)) { - random_state.counter++; - yarrow_encrypt(&random_state.key, &random_state.counter, - &genval, sizeof(random_state.counter)); - memcpy((char *)buf + i, &genval, - sizeof(random_state.counter)); - if (++random_state.outputblocks >= random_state.gengateinterval) { - generator_gate(); - random_state.outputblocks = 0; - } - retval += sizeof(random_state.counter); - } - } - else { - if (!cur) { - random_state.counter++; - yarrow_encrypt(&random_state.key, &random_state.counter, - &genval, sizeof(random_state.counter)); - memcpy(buf, &genval, count); - cur = sizeof(random_state.counter) - count; - if (++random_state.outputblocks >= random_state.gengateinterval) { - generator_gate(); - random_state.outputblocks = 0; - } - retval = count; - } - else { - retval = cur < count ? cur : count; - memcpy(buf, - (char *)&genval + - (sizeof(random_state.counter) - cur), - retval); - cur -= retval; - } - } - mtx_exit(&random_reseed_mtx, MTX_DEF); - return retval; -} - -void -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) { - nanotime(&timebuf); - random_harvest_internal(&timebuf, (char *)buf + i, 8, 0, 0, - RANDOM_WRITE); - } - - /* Maybe the loop iterated at least once */ - if (i > count) - i -= 8; - - /* Get the last bytes even if the input length is not a multiple of 8 */ - count %= 8; - if (count) { - nanotime(&timebuf); - random_harvest_internal(&timebuf, (char *)buf + i, count, 0, 0, - RANDOM_WRITE); - } - - /* Explicit reseed */ - reseed(FAST); -} - -static void -generator_gate(void) -{ - int i; - u_char temp[KEYSIZE]; - -#ifdef DEBUG - printf("Generator gate\n"); -#endif - - for (i = 0; i < KEYSIZE; i += sizeof(random_state.counter)) { - random_state.counter++; - yarrow_encrypt(&random_state.key, &random_state.counter, - &(temp[i]), sizeof(random_state.counter)); - } - - yarrow_encrypt_init(&random_state.key, temp, KEYSIZE); - memset((void *)temp, 0, KEYSIZE); - -#ifdef DEBUG - printf("Generator gate finish\n"); -#endif -} - -/* Entropy harvesting routine. This is supposed to be fast; do - * not do anything slow in here! - */ - -static void -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 - printf("Random harvest\n"); -#endif -#endif - event = malloc(sizeof(struct harvest), M_TEMP, M_NOWAIT); - - if (origin < ENTROPYSOURCE && event != NULL) { - - /* nanotime provides clock jitter */ - event->time = *timep; - - /* the harvested entropy */ - count = count > sizeof(entropy_buf) - ? sizeof(entropy_buf) - : count; - memcpy(event->entropy, entropy, count); - - event->size = count; - event->bits = bits; - event->frac = frac; - event->source = origin; - - /* protect the queue from simultaneous updates */ - mtx_enter(&random_harvest_mtx, MTX_DEF); - - /* toggle the pool for next insertion */ - event->pool = random_state.which; - random_state.which = !random_state.which; - - TAILQ_INSERT_TAIL(&harvestqueue, event, harvest); - - mtx_exit(&random_harvest_mtx, MTX_DEF); - } -} diff --git a/sys/dev/randomdev/yarrow.h b/sys/dev/randomdev/yarrow.h deleted file mode 100644 index a81fa1f..0000000 --- a/sys/dev/randomdev/yarrow.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2000 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$ - */ - -/* #define ENTROPYSOURCE nn entropy sources (actually classes) - * The entropy classes will as follows: - * 0 - Direct write - * 1 - Keyboard - * 2 - Mouse - */ - -#define ENTROPYBIN 256 /* buckets to harvest entropy events */ -#define TIMEBIN 16 /* max value for Pt/t */ - -#define FAST 0 -#define SLOW 1 - -int random_init(void); -void random_deinit(void); -void random_init_harvester(void (*)(struct timespec *, void *, u_int, u_int, u_int, enum esource)); -void random_deinit_harvester(void); -void random_set_wakeup(int *, int); -void random_set_wakeup_exit(int *, int, int); - -void write_random(void *, u_int); - -/* This is the beastie that needs protecting. It contains all of the - * state that we are excited about. - * This is a biiig structure. It may move over to a malloc(9)ed - * replacement. - */ -struct random_state { - u_int64_t counter; /* C */ - struct yarrowkey key; /* K */ - int gengateinterval; /* Pg */ - int bins; /* Pt/t */ - int outputblocks; /* count output blocks for gates */ - u_int slowoverthresh; /* slow pool overthreshhold reseed count */ - struct pool { - struct source { - u_int bits; /* estimated bits of entropy */ - u_int frac; /* fractional bits of entropy - (given as 1024/n) */ - } source[ENTROPYSOURCE]; - u_int thresh; /* pool reseed threshhold */ - struct yarrowhash hash; /* accumulated entropy */ - } pool[2]; /* pool[0] is fast, pool[1] is slow */ - int which; /* toggle - shows the current insertion pool */ -}; - -extern struct random_state random_state; |