diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2014-01-19 23:52:55 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2014-01-19 23:52:55 +0000 |
commit | d094ca4ac71873c6b776448d4b66fad524c46c71 (patch) | |
tree | 4dc45d4532f5fbd9ff2f5c1b63dde9f326e6088f /sys | |
parent | d9596a93c344a36d94a7bf8b5486408b08d437f8 (diff) |
Refactor rnd startup so arc4random/arc4random_buf can create a chacha state
on first call, very early on, from boot-supplied entropy, then feed from
that. Later when we have more subsystems ready, the main() can properly
initialize the entropy-driven model. Lots of discussion with mikeb.
ok kettenis markus mikeb
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/rnd.c | 53 | ||||
-rw-r--r-- | sys/dev/rndvar.h | 3 | ||||
-rw-r--r-- | sys/kern/init_main.c | 4 |
3 files changed, 25 insertions, 35 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index 39bfaf1c1e0..6920cd828f0 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.152 2014/01/19 00:39:40 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.153 2014/01/19 23:52:54 deraadt Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -540,7 +540,8 @@ void arc4_init(void *, void *); /* actually do the reinit */ #define RSBUFSZ (16*BLOCKSZ) static int rs_initialized; static chacha_ctx rs; /* chacha context for random keystream */ -static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +/* keystream blocks (also chacha seed from boot) */ +static u_char rs_buf[RSBUFSZ] __attribute__((section(".openbsd.randomdata"))); static size_t rs_have; /* valid bytes at end of rs_buf */ static size_t rs_count; /* bytes till reseed */ @@ -557,14 +558,7 @@ _rs_init(u_char *buf, size_t n) static void _rs_seed(u_char *buf, size_t n) { - if (!rs_initialized) { - rs_initialized = 1; - rnd_states[RND_SRC_TIMER].dont_count_entropy = 1; - rnd_states[RND_SRC_TRUE].dont_count_entropy = 1; - rnd_states[RND_SRC_TRUE].max_entropy = 1; - _rs_init(buf, n); - } else - _rs_rekey(buf, n); + _rs_rekey(buf, n); /* invalidate rs_buf */ rs_have = 0; @@ -605,7 +599,11 @@ _rs_stir(int do_lock) static inline void _rs_stir_if_needed(size_t len) { - if (rs_count <= len || !rs_initialized) + if (!rs_initialized) { + _rs_init(rs_buf, KEYSZ + IVSZ); + rs_count = 1024 * 1024 * 1024; /* until main() runs */ + rs_initialized = 1; + } else if (rs_count <= len) _rs_stir(0); else rs_count -= len; @@ -745,21 +743,6 @@ arc4_reinit(void *v) timeout_add_sec(&arc4_timeout, 10 * 60); } -void -random_init(void) -{ - int off; - - /* - * MI code did not initialize us with a seed, so we are - * hitting the fall-back from kernel main(). Do the best - * we can... We assume there are at 8192 bytes mapped after - * version, because we want to pull some "code" in as well. - */ - for (off = 0; off < 8192 - KEYSZ - IVSZ; off += KEYSZ + IVSZ) - _rs_seed((u_int8_t *)version + off, KEYSZ + IVSZ); -} - /* * Start periodic services inside the random subsystem, which pull * entropy forward, hash it, and re-seed the random stream as needed. @@ -767,14 +750,24 @@ random_init(void) void random_start(void) { - /* - * At this point, the message buffer is mapped, and may contain - * some historical information still. - */ + rnd_states[RND_SRC_TIMER].dont_count_entropy = 1; + rnd_states[RND_SRC_TRUE].dont_count_entropy = 1; + rnd_states[RND_SRC_TRUE].max_entropy = 1; + + /* Provide some data from this kernel */ + add_entropy_words((u_int32_t *)version, + strlen(version) / sizeof(u_int32_t)); + + /* Provide some data from this kernel */ + add_entropy_words((u_int32_t *)cfdata, + 8192 / sizeof(u_int32_t)); + + /* Message buffer may contain data from previous boot */ if (msgbufp->msg_magic == MSG_MAGIC) add_entropy_words((u_int32_t *)msgbufp->msg_bufc, msgbufp->msg_bufs / sizeof(u_int32_t)); + rs_initialized = 1; dequeue_randomness(NULL); arc4_init(NULL, NULL); task_set(&arc4_task, arc4_init, NULL, NULL); diff --git a/sys/dev/rndvar.h b/sys/dev/rndvar.h index 5e631d92dbf..17cc93c7bf4 100644 --- a/sys/dev/rndvar.h +++ b/sys/dev/rndvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rndvar.h,v 1.32 2014/01/19 00:39:40 deraadt Exp $ */ +/* $OpenBSD: rndvar.h,v 1.33 2014/01/19 23:52:54 deraadt Exp $ */ /* * Copyright (c) 1996,2000 Michael Shalayeff. @@ -69,7 +69,6 @@ extern struct rndstats rndstats; #define add_audio_randomness(d) enqueue_randomness(RND_SRC_AUDIO, (int)(d)) #define add_video_randomness(d) enqueue_randomness(RND_SRC_VIDEO, (int)(d)) -void random_init(void); void random_start(void); void enqueue_randomness(int, int); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index dd8180c5ce8..14dff21a4d4 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.201 2014/01/19 13:26:42 deraadt Exp $ */ +/* $OpenBSD: init_main.c,v 1.202 2014/01/19 23:52:54 deraadt Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -218,8 +218,6 @@ main(void *framep) KERNEL_LOCK_INIT(); SCHED_LOCK_INIT(); - random_init(); - uvm_init(); disk_init(); /* must come before autoconfiguration */ tty_init(); /* initialise tty's */ |