yarrow.c (67882) | yarrow.c (69168) |
---|---|
1/*- 2 * Copyright (c) 2000 Mark R V Murray 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2000 Mark R V Murray 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/dev/random/yarrow.c 67882 2000-10-29 13:57:19Z phk $ | 26 * $FreeBSD: head/sys/dev/random/yarrow.c 69168 2000-11-25 17:09:01Z markm $ |
27 */ 28 29/* NOTE NOTE NOTE - This is not finished! It will supply numbers, but 30 * it is not yet cryptographically secure!! 31 */ 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/queue.h> 36#include <sys/kernel.h> 37#include <sys/kthread.h> 38#include <sys/libkern.h> 39#include <sys/malloc.h> 40#include <sys/mutex.h> 41#include <sys/select.h> 42#include <sys/random.h> | 27 */ 28 29/* NOTE NOTE NOTE - This is not finished! It will supply numbers, but 30 * it is not yet cryptographically secure!! 31 */ 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/queue.h> 36#include <sys/kernel.h> 37#include <sys/kthread.h> 38#include <sys/libkern.h> 39#include <sys/malloc.h> 40#include <sys/mutex.h> 41#include <sys/select.h> 42#include <sys/random.h> |
43#include <sys/time.h> | |
44#include <sys/types.h> 45#include <sys/unistd.h> | 43#include <sys/types.h> 44#include <sys/unistd.h> |
45 46#include <machine/cpu.h> 47 |
|
46#include <crypto/blowfish/blowfish.h> 47 48#include <dev/random/hash.h> 49#include <dev/random/yarrow.h> 50 51/* #define DEBUG */ 52/* #define DEBUG1 */ /* Very noisy - prints plenty harvesting stats */ 53 54static void generator_gate(void); 55static void reseed(int); | 48#include <crypto/blowfish/blowfish.h> 49 50#include <dev/random/hash.h> 51#include <dev/random/yarrow.h> 52 53/* #define DEBUG */ 54/* #define DEBUG1 */ /* Very noisy - prints plenty harvesting stats */ 55 56static void generator_gate(void); 57static void reseed(int); |
56static void random_harvest_internal(struct timespec *, void *, u_int, u_int, u_int, enum esource); | 58static void random_harvest_internal(u_int64_t, void *, u_int, u_int, u_int, enum esource); |
57 58static void random_kthread(void *); 59 60/* Structure holding the entropy state */ 61struct random_state random_state; 62 63/* Queue holding harvested entropy */ 64TAILQ_HEAD(harvestqueue, harvest) harvestqueue, 65 initqueue = TAILQ_HEAD_INITIALIZER(harvestqueue); 66 67/* These are used to queue harvested packets of entropy. The entropy 68 * buffer size is pretty arbitrary. 69 */ 70struct harvest { | 59 60static void random_kthread(void *); 61 62/* Structure holding the entropy state */ 63struct random_state random_state; 64 65/* Queue holding harvested entropy */ 66TAILQ_HEAD(harvestqueue, harvest) harvestqueue, 67 initqueue = TAILQ_HEAD_INITIALIZER(harvestqueue); 68 69/* These are used to queue harvested packets of entropy. The entropy 70 * buffer size is pretty arbitrary. 71 */ 72struct harvest { |
71 struct timespec time; /* nanotime for clock jitter */ | 73 u_int64_t somecounter; /* fast counter for clock jitter */ |
72 u_char entropy[HARVESTSIZE]; /* the harvested entropy */ 73 u_int size, bits, frac; /* stats about the entropy */ 74 enum esource source; /* stats about the entropy */ 75 u_int pool; /* which pool this goes into */ 76 TAILQ_ENTRY(harvest) harvest; /* link to next */ 77}; 78 79/* The reseed thread mutex */ --- 54 unchanged lines hidden (view full) --- 134 TAILQ_REMOVE(&harvestqueue, event, harvest); 135 136 mtx_exit(&random_harvest_mtx, MTX_DEF); 137 138 source = &random_state.pool[event->pool].source[event->source]; 139 yarrow_hash_iterate(&random_state.pool[event->pool].hash, 140 event->entropy, sizeof(event->entropy)); 141 yarrow_hash_iterate(&random_state.pool[event->pool].hash, | 74 u_char entropy[HARVESTSIZE]; /* the harvested entropy */ 75 u_int size, bits, frac; /* stats about the entropy */ 76 enum esource source; /* stats about the entropy */ 77 u_int pool; /* which pool this goes into */ 78 TAILQ_ENTRY(harvest) harvest; /* link to next */ 79}; 80 81/* The reseed thread mutex */ --- 54 unchanged lines hidden (view full) --- 136 TAILQ_REMOVE(&harvestqueue, event, harvest); 137 138 mtx_exit(&random_harvest_mtx, MTX_DEF); 139 140 source = &random_state.pool[event->pool].source[event->source]; 141 yarrow_hash_iterate(&random_state.pool[event->pool].hash, 142 event->entropy, sizeof(event->entropy)); 143 yarrow_hash_iterate(&random_state.pool[event->pool].hash, |
142 &event->time, sizeof(event->time)); | 144 &event->somecounter, sizeof(event->somecounter)); |
143 source->frac += event->frac; 144 source->bits += event->bits + source->frac/1024; 145 source->frac %= 1024; 146 free(event, M_TEMP); 147 148 } 149#ifdef DEBUG1 150 printf("Harvested %d events\n", queuecount); --- 275 unchanged lines hidden (view full) --- 426 mtx_exit(&random_reseed_mtx, MTX_DEF); 427 return retval; 428} 429 430void 431write_random(void *buf, u_int count) 432{ 433 u_int i; | 145 source->frac += event->frac; 146 source->bits += event->bits + source->frac/1024; 147 source->frac %= 1024; 148 free(event, M_TEMP); 149 150 } 151#ifdef DEBUG1 152 printf("Harvested %d events\n", queuecount); --- 275 unchanged lines hidden (view full) --- 428 mtx_exit(&random_reseed_mtx, MTX_DEF); 429 return retval; 430} 431 432void 433write_random(void *buf, u_int count) 434{ 435 u_int i; |
434 struct timespec timebuf; | |
435 | 436 |
436 /* arbitrarily break the input up into HARVESTSIZE chunks */ | 437 /* Break the input up into HARVESTSIZE chunks. 438 * The writer has too much control here, so "estimate" the 439 * the entropy as zero. 440 */ |
437 for (i = 0; i < count; i += HARVESTSIZE) { | 441 for (i = 0; i < count; i += HARVESTSIZE) { |
438 nanotime(&timebuf); 439 random_harvest_internal(&timebuf, (char *)buf + i, HARVESTSIZE, 0, 0, 440 RANDOM_WRITE); | 442 random_harvest_internal(get_cyclecount(), (char *)buf + i, 443 HARVESTSIZE, 0, 0, RANDOM_WRITE); |
441 } 442 443 /* Maybe the loop iterated at least once */ 444 if (i > count) 445 i -= HARVESTSIZE; 446 | 444 } 445 446 /* Maybe the loop iterated at least once */ 447 if (i > count) 448 i -= HARVESTSIZE; 449 |
447 /* Get the last bytes even if the input length is not a multiple of HARVESTSIZE */ | 450 /* Get the last bytes even if the input length is not 451 * a multiple of HARVESTSIZE. 452 */ |
448 count %= HARVESTSIZE; 449 if (count) { | 453 count %= HARVESTSIZE; 454 if (count) { |
450 nanotime(&timebuf); 451 random_harvest_internal(&timebuf, (char *)buf + i, count, 0, 0, 452 RANDOM_WRITE); | 455 random_harvest_internal(get_cyclecount(), (char *)buf + i, count, 456 0, 0, RANDOM_WRITE); |
453 } 454 455 /* Explicit reseed */ 456 reseed(FAST); 457} 458 459static void 460generator_gate(void) --- 19 unchanged lines hidden (view full) --- 480#endif 481} 482 483/* Entropy harvesting routine. This is supposed to be fast; do 484 * not do anything slow in here! 485 */ 486 487static void | 457 } 458 459 /* Explicit reseed */ 460 reseed(FAST); 461} 462 463static void 464generator_gate(void) --- 19 unchanged lines hidden (view full) --- 484#endif 485} 486 487/* Entropy harvesting routine. This is supposed to be fast; do 488 * not do anything slow in here! 489 */ 490 491static void |
488random_harvest_internal(struct timespec *timep, void *entropy, u_int count, | 492random_harvest_internal(u_int64_t somecounter, void *entropy, u_int count, |
489 u_int bits, u_int frac, enum esource origin) 490{ 491 struct harvest *event; 492 | 493 u_int bits, u_int frac, enum esource origin) 494{ 495 struct harvest *event; 496 |
493#if 0 494#ifdef DEBUG | 497#ifdef DEBUG1 |
495 printf("Random harvest\n"); 496#endif | 498 printf("Random harvest\n"); 499#endif |
497#endif | |
498 event = malloc(sizeof(struct harvest), M_TEMP, M_NOWAIT); 499 500 if (origin < ENTROPYSOURCE && event != NULL) { 501 | 500 event = malloc(sizeof(struct harvest), M_TEMP, M_NOWAIT); 501 502 if (origin < ENTROPYSOURCE && event != NULL) { 503 |
502 /* nanotime provides clock jitter */ 503 event->time = *timep; | 504 /* fast counter provides clock jitter */ 505 event->somecounter = somecounter; |
504 505 /* the harvested entropy */ 506 count = count > sizeof(event->entropy) 507 ? sizeof(event->entropy) 508 : count; 509 memcpy(event->entropy, entropy, count); 510 511 event->size = count; --- 16 unchanged lines hidden --- | 506 507 /* the harvested entropy */ 508 count = count > sizeof(event->entropy) 509 ? sizeof(event->entropy) 510 : count; 511 memcpy(event->entropy, entropy, count); 512 513 event->size = count; --- 16 unchanged lines hidden --- |