kern/123177: arc4rand(9) produces the same sequence on each boot
Robert Woolley
freebsd-pr08 at mlists.homeunix.com
Mon Apr 28 20:30:03 UTC 2008
>Number: 123177
>Category: kern
>Synopsis: arc4rand(9) produces the same sequence on each boot
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Apr 28 20:30:03 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Robert Woolley
>Release: 7.0
>Organization:
>Environment:
FreeBSD gumby.homeunix.com 7.0-RELEASE-p1 FreeBSD 7.0-RELEASE-p1 #18: Mon Apr 28 14:53:51 BST 2008 root at gumby.homeunix.com:/usr/obj/usr/src/sys/MUSTARD i386
>Description:
arc4rand(9) is used as a source of secure random numbers in the kernel. As far as I can tell, it's the source of the disposable keys for "geli onetime" partitions. It's seeded the first time it's called using read_random(), which is implemented by yarrow (except on VIA Nehemiah).
The problem is that the first call happens before yarrow is seeded and the yarrow cipher-context is initialized. This results in a given kernel producing the same sequence on each boot, and it wont reseed for 5 minutes or 64KB.
It also appears that the use of an uninitialized cipher-context may be causing dubious memory accesses. The sequence alters if the kernel is modified, despite the relevant data structures being static (i.e. pre-zeroed) or explicitly set-up.
>How-To-Repeat:
In /etc/rc.d/initrandom, add some calls to "sysctl kern.arandom" after the line:
feed_dev_random "${entropy_file}"
and cycle the machine a few times. I'm seeing the same sequence each time. By this point in the boot sequence yarrow must have seeded.
(BTW a few lines up "sysctl -a" is dumped into /dev/random before the entropy file. This does cause a call to arc4rand(), but it's not first. You may wish to remove this.)
>Fix:
The patch does two things:
1. Reseeds arc4rand when root closes /dev/random (just after yarrow is reseeded by the entropy file).
2. Provides a provisional yarrow cipher-context to support early calls to read_random.
Patch attached with submission follows:
diff -ur /usr/src.orig/sys/dev/random/randomdev.c /usr/src/sys/dev/random/randomdev.c
--- /usr/src.orig/sys/dev/random/randomdev.c 2006-11-06 13:41:55.000000000 +0000
+++ /usr/src/sys/dev/random/randomdev.c 2008-04-28 14:34:57.000000000 +0100
@@ -36,6 +36,7 @@
#include <sys/filio.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
+#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -88,8 +89,12 @@
{
if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0)
&& (securelevel_gt(td->td_ucred, 0) == 0)) {
+
(*random_systat.reseed)();
random_systat.seeded = 1;
+
+ /* Reseed any other secure PRNGs */
+ arc4rand(NULL, 0, 1);
}
return (0);
diff -ur /usr/src.orig/sys/dev/random/yarrow.c /usr/src/sys/dev/random/yarrow.c
--- /usr/src.orig/sys/dev/random/yarrow.c 2007-11-29 16:05:38.000000000 +0000
+++ /usr/src/sys/dev/random/yarrow.c 2008-04-28 14:38:49.000000000 +0100
@@ -37,6 +37,8 @@
#include <sys/sysctl.h>
#include <sys/systm.h>
+#include <machine/cpu.h>
+
#include <crypto/rijndael/rijndael-api-fst.h>
#include <crypto/sha2/sha2.h>
@@ -160,6 +162,14 @@
for (i = 0; i < 2; i++)
yarrow_hash_init(&random_state.pool[i].hash);
+ /* Generate a provisional cipher key so that read_random
+ * can be used to seed arc4rand(9) (must be securely reseeded).
+ * We do a second get_cyclecount() later, as some CPUs need
+ * to fall back to nanotime, which doesn't work properly yet.
+ */
+ random_state.counter[0] = get_cyclecount();
+ yarrow_encrypt_init(&random_state.key, random_state.counter);
+
/* Clear the counter */
for (i = 0; i < 4; i++)
random_state.counter[i] = 0;
@@ -274,6 +284,10 @@
int i;
int retval;
+ /* Some entropy may be needed on the first call. */
+ if (gate)
+ random_state.counter[1] = get_cyclecount();
+
/* The reseed task must not be jumped on */
mtx_lock(&random_reseed_mtx);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list