From d17145b342f21558c7efd8026a2efde5a1fa55c2 Mon Sep 17 00:00:00 2001 From: tedu Date: Fri, 19 Dec 2014 02:29:40 +0000 Subject: [PATCH] sha512 produces enough output, we can simplify extraction by not looping. ok deraadt djm --- sys/dev/rnd.c | 69 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index b14470ecece..4ceb97f2af4 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.164 2014/12/18 16:27:30 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.165 2014/12/19 02:29:40 tedu Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -215,6 +215,12 @@ struct timer_rand_state { /* There is one of these per entropy source */ #define QEVSLOW (QEVLEN * 3 / 4) /* yet another 0.75 for 60-minutes hour /-; */ #define QEVSBITS 10 +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) +#define EBUFSIZE KEYSZ + IVSZ + struct rand_event { struct timer_rand_state *re_state; u_int re_nbits; @@ -233,7 +239,8 @@ u_char entropy_input_rotate; void dequeue_randomness(void *); void add_entropy_words(const u_int32_t *, u_int); -void extract_entropy(u_int8_t *, int); +void extract_entropy(u_int8_t *) + __attribute__((__bounded__(__minbytes__,1,EBUFSIZE))); int filt_randomread(struct knote *, long); void filt_randomdetach(struct knote *); @@ -487,40 +494,36 @@ dequeue_randomness(void *v) * requested. */ void -extract_entropy(u_int8_t *buf, int nbytes) +extract_entropy(u_int8_t *buf) { static u_int32_t extract_pool[POOLWORDS]; u_char buffer[SHA512_DIGEST_LENGTH]; SHA2_CTX tmp; - u_int i; - add_timer_randomness(nbytes); +#if SHA512_DIGEST_LENGTH < EBUFSIZE +#error "need more bigger hash output" +#endif - while (nbytes) { - i = MIN(nbytes, sizeof(buffer)); + /* + * INTENTIONALLY not protected by entropylock. Races during + * memcpy() result in acceptable input data; races during + * SHA512Update() would create nasty data dependencies. We + * do not rely on this as a benefit, but if it happens, cool. + */ + memcpy(extract_pool, entropy_pool, + sizeof(extract_pool)); - /* - * INTENTIONALLY not protected by entropylock. Races - * during bcopy() result in acceptable input data; races - * during SHA512Update() would create nasty data dependencies. - */ - bcopy(entropy_pool, extract_pool, - sizeof(extract_pool)); - - /* Hash the pool to get the output */ - SHA512Init(&tmp); - SHA512Update(&tmp, (u_int8_t *)extract_pool, sizeof(extract_pool)); - SHA512Final(buffer, &tmp); - - /* Copy data to destination buffer */ - bcopy(buffer, buf, i); - nbytes -= i; - buf += i; - - /* Modify pool so next hash will produce different results */ - add_timer_randomness(nbytes); - dequeue_randomness(NULL); - } + /* Hash the pool to get the output */ + SHA512Init(&tmp); + SHA512Update(&tmp, (u_int8_t *)extract_pool, sizeof(extract_pool)); + SHA512Final(buffer, &tmp); + + /* Copy data to destination buffer */ + memcpy(buf, buffer, EBUFSIZE); + + /* Modify pool so next hash will produce different results */ + add_timer_randomness(EBUFSIZE); + dequeue_randomness(NULL); /* Wipe data from memory */ explicit_bzero(extract_pool, sizeof(extract_pool)); @@ -537,10 +540,6 @@ struct task arc4_task; void arc4_reinit(void *v); /* timeout to start reinit */ void arc4_init(void *, void *); /* actually do the reinit */ -#define KEYSZ 32 -#define IVSZ 8 -#define BLOCKSZ 64 -#define RSBUFSZ (16*BLOCKSZ) static int rs_initialized; static chacha_ctx rs; /* chacha context for random keystream */ /* keystream blocks (also chacha seed from boot) */ @@ -601,7 +600,7 @@ static void _rs_stir(int do_lock) { struct timespec ts; - u_int8_t buf[KEYSZ + IVSZ], *p; + u_int8_t buf[EBUFSIZE], *p; int i; /* @@ -610,7 +609,7 @@ _rs_stir(int do_lock) * not collect entropy very well during this time, but may have * clock information which is better than nothing. */ - extract_entropy((u_int8_t *)buf, sizeof buf); + extract_entropy(buf); nanotime(&ts); for (p = (u_int8_t *)&ts, i = 0; i < sizeof(ts); i++) -- 2.20.1