Deleted Added
full compact
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 ---