Module Name:    src
Committed By:   tls
Date:           Thu Mar 28 18:06:49 UTC 2013

Modified Files:
        src/sys/kern: subr_cprng.c

Log Message:
Re-fix 'fix' for SA-2013-003.  Because the original fix evaluated a flag
backwards, in low-entropy conditions there was a time interval in which
/dev/urandom could still output bits on an unacceptably short key.  Output
from /dev/random was *NOT* impacted.

Eliminate the flag in question -- it's safest to always fill the requested
key buffer with output from the entropy-pool, even if we let the caller
know we couldn't provide bytes with the full entropy it requested.

Advisory will be updated soon with a full worst-case analysis of the
/dev/urandom output path in the presence of either variant of the
SA-2013-003 bug.  Fortunately, because a large amount of other input
is mixed in before users can obtain any output, it doesn't look as dangerous
in practice as I'd feared it might be.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/kern/subr_cprng.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_cprng.c
diff -u src/sys/kern/subr_cprng.c:1.15 src/sys/kern/subr_cprng.c:1.16
--- src/sys/kern/subr_cprng.c:1.15	Sat Jan 26 16:05:34 2013
+++ src/sys/kern/subr_cprng.c	Thu Mar 28 18:06:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_cprng.c,v 1.15 2013/01/26 16:05:34 tls Exp $ */
+/*	$NetBSD: subr_cprng.c,v 1.16 2013/03/28 18:06:48 tls Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
 
 #include <sys/cprng.h>
 
-__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.15 2013/01/26 16:05:34 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.16 2013/03/28 18:06:48 tls Exp $");
 
 void
 cprng_init(void)
@@ -157,11 +157,11 @@ cprng_strong_reseed(void *const arg)
 }
 
 static size_t
-cprng_entropy_try(uint8_t *key, size_t keylen, int hard)
+cprng_entropy_try(uint8_t *key, size_t keylen)
 {
 	int r;
 	r = rnd_extract_data(key, keylen, RND_EXTRACT_GOOD);
-	if (r != keylen && !hard) {
+	if (r != keylen) {	/* Always fill in, for safety */
 		rnd_extract_data(key + r, keylen - r, RND_EXTRACT_ANY);
 	}
 	return r;
@@ -196,7 +196,7 @@ cprng_strong_create(const char *const na
 
 	selinit(&c->selq);
 
-	r = cprng_entropy_try(key, sizeof(key), c->flags & CPRNG_INIT_ANY);
+	r = cprng_entropy_try(key, sizeof(key));
 	if (r != sizeof(key)) {
 		if (c->flags & CPRNG_INIT_ANY) {
 #ifdef DEBUG
@@ -251,7 +251,7 @@ rekeyany:
 		if (c->flags & CPRNG_REKEY_ANY) {
 			uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
 
-			if (cprng_entropy_try(key, sizeof(key), 0) !=
+			if (cprng_entropy_try(key, sizeof(key)) !=
 			    sizeof(key)) {
  				printf("cprng %s: WARNING "
 				       "pseudorandom rekeying.\n", c->name);

Reply via email to