summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2014-01-19 23:52:55 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2014-01-19 23:52:55 +0000
commitd094ca4ac71873c6b776448d4b66fad524c46c71 (patch)
tree4dc45d4532f5fbd9ff2f5c1b63dde9f326e6088f /sys
parentd9596a93c344a36d94a7bf8b5486408b08d437f8 (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.c53
-rw-r--r--sys/dev/rndvar.h3
-rw-r--r--sys/kern/init_main.c4
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 */