Stop explicitly using nanotime(9) and use the new get_cyclecounter(9)
call instead. This makes a pretty dramatic difference to the amount of work that the harvester needs to do - it is much friendlier on the system. (80386 and 80486 class machines will notice little, as the new get_cyclecounter() call is a wrapper round nanotime(9) for them).
This commit is contained in:
parent
89c2809e65
commit
e73a42f8fb
@ -35,7 +35,9 @@
|
||||
#include <sys/poll.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <crypto/blowfish/blowfish.h>
|
||||
|
||||
#include <dev/random/hash.h>
|
||||
@ -44,14 +46,14 @@
|
||||
static u_int read_random_phony(void *, u_int);
|
||||
|
||||
/* hold the address of the routine which is actually called if
|
||||
* the ramdomdev is loaded
|
||||
* the randomdev is loaded
|
||||
*/
|
||||
static void (*reap_func)(struct timespec *, void *, u_int, u_int, u_int, u_int) = NULL;
|
||||
static void (*reap_func)(u_int64_t, 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), u_int (*reader)(void *, u_int))
|
||||
random_init_harvester(void (*reaper)(u_int64_t, void *, u_int, u_int, u_int, u_int), u_int (*reader)(void *, u_int))
|
||||
{
|
||||
reap_func = reaper;
|
||||
read_func = reader;
|
||||
@ -73,12 +75,8 @@ random_deinit_harvester(void)
|
||||
void
|
||||
random_harvest(void *entropy, u_int count, u_int bits, u_int frac, u_int origin)
|
||||
{
|
||||
struct timespec timebuf;
|
||||
|
||||
if (reap_func) {
|
||||
nanotime(&timebuf);
|
||||
(*reap_func)(&timebuf, entropy, count, bits, frac, origin);
|
||||
}
|
||||
if (reap_func)
|
||||
(*reap_func)(get_cyclecount(), entropy, count, bits, frac, origin);
|
||||
}
|
||||
|
||||
/* Userland-visible version of read_random */
|
||||
@ -95,18 +93,15 @@ read_random(void *buf, u_int count)
|
||||
static u_int
|
||||
read_random_phony(void *buf, u_int count)
|
||||
{
|
||||
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!!
|
||||
* DO NOT make the mistake of thinking this is secure!!
|
||||
*/
|
||||
if (!initialised) {
|
||||
nanotime(&timebuf);
|
||||
srandom((u_long)(timebuf.tv_sec ^ timebuf.tv_nsec));
|
||||
}
|
||||
if (!initialised)
|
||||
srandom((u_long)get_cyclecount());
|
||||
|
||||
/* Fill buf[] with random(9) output */
|
||||
for (i = 0; i < count; i+= sizeof(u_long)) {
|
||||
|
@ -31,8 +31,8 @@
|
||||
#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/random/hash.h>
|
||||
|
@ -40,9 +40,11 @@
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <crypto/blowfish/blowfish.h>
|
||||
|
||||
#include <dev/random/hash.h>
|
||||
@ -53,7 +55,7 @@
|
||||
|
||||
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_harvest_internal(u_int64_t, void *, u_int, u_int, u_int, enum esource);
|
||||
|
||||
static void random_kthread(void *);
|
||||
|
||||
@ -68,7 +70,7 @@ TAILQ_HEAD(harvestqueue, harvest) harvestqueue,
|
||||
* buffer size is pretty arbitrary.
|
||||
*/
|
||||
struct harvest {
|
||||
struct timespec time; /* nanotime for clock jitter */
|
||||
u_int64_t somecounter; /* fast counter for clock jitter */
|
||||
u_char entropy[HARVESTSIZE]; /* the harvested entropy */
|
||||
u_int size, bits, frac; /* stats about the entropy */
|
||||
enum esource source; /* stats about the entropy */
|
||||
@ -139,7 +141,7 @@ random_kthread(void *arg /* NOTUSED */)
|
||||
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));
|
||||
&event->somecounter, sizeof(event->somecounter));
|
||||
source->frac += event->frac;
|
||||
source->bits += event->bits + source->frac/1024;
|
||||
source->frac %= 1024;
|
||||
@ -431,25 +433,27 @@ void
|
||||
write_random(void *buf, u_int count)
|
||||
{
|
||||
u_int i;
|
||||
struct timespec timebuf;
|
||||
|
||||
/* arbitrarily break the input up into HARVESTSIZE chunks */
|
||||
/* Break the input up into HARVESTSIZE chunks.
|
||||
* The writer has too much control here, so "estimate" the
|
||||
* the entropy as zero.
|
||||
*/
|
||||
for (i = 0; i < count; i += HARVESTSIZE) {
|
||||
nanotime(&timebuf);
|
||||
random_harvest_internal(&timebuf, (char *)buf + i, HARVESTSIZE, 0, 0,
|
||||
RANDOM_WRITE);
|
||||
random_harvest_internal(get_cyclecount(), (char *)buf + i,
|
||||
HARVESTSIZE, 0, 0, RANDOM_WRITE);
|
||||
}
|
||||
|
||||
/* Maybe the loop iterated at least once */
|
||||
if (i > count)
|
||||
i -= HARVESTSIZE;
|
||||
|
||||
/* Get the last bytes even if the input length is not a multiple of HARVESTSIZE */
|
||||
/* 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,
|
||||
RANDOM_WRITE);
|
||||
random_harvest_internal(get_cyclecount(), (char *)buf + i, count,
|
||||
0, 0, RANDOM_WRITE);
|
||||
}
|
||||
|
||||
/* Explicit reseed */
|
||||
@ -485,22 +489,20 @@ generator_gate(void)
|
||||
*/
|
||||
|
||||
static void
|
||||
random_harvest_internal(struct timespec *timep, void *entropy, u_int count,
|
||||
random_harvest_internal(u_int64_t somecounter, void *entropy, u_int count,
|
||||
u_int bits, u_int frac, enum esource origin)
|
||||
{
|
||||
struct harvest *event;
|
||||
|
||||
#if 0
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG1
|
||||
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;
|
||||
/* fast counter provides clock jitter */
|
||||
event->somecounter = somecounter;
|
||||
|
||||
/* the harvested entropy */
|
||||
count = count > sizeof(event->entropy)
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
int random_init(void);
|
||||
void random_deinit(void);
|
||||
void random_init_harvester(void (*)(struct timespec *, void *, u_int, u_int, u_int, enum esource), u_int (*)(void *, u_int));
|
||||
void random_init_harvester(void (*)(u_int64_t, void *, u_int, u_int, u_int, enum esource), u_int (*)(void *, u_int));
|
||||
void random_deinit_harvester(void);
|
||||
void random_set_wakeup_exit(void *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user