From nobody@FreeBSD.org  Mon Apr 28 20:20:19 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 866BA1065672
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 28 Apr 2008 20:20:19 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 763348FC19
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 28 Apr 2008 20:20:19 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m3SKJhwq087336
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 28 Apr 2008 20:19:43 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m3SKJhHf087335;
	Mon, 28 Apr 2008 20:19:43 GMT
	(envelope-from nobody)
Message-Id: <200804282019.m3SKJhHf087335@www.freebsd.org>
Date: Mon, 28 Apr 2008 20:19:43 GMT
From: Robert Woolley <freebsd-pr08@mlists.homeunix.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: arc4rand(9) produces the same sequence on each boot
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         123177
>Category:       kern
>Synopsis:       [random] [patch] arc4rand(9) produces the same sequence on each boot
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    secteam
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 28 20:30:03 UTC 2008
>Closed-Date:    Mon Aug 05 11:59:22 UTC 2013
>Last-Modified:  Mon Aug 05 11:59:22 UTC 2013
>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@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:
Responsible-Changed-From-To: freebsd-bugs->secteam 
Responsible-Changed-By: csjp 
Responsible-Changed-When: Wed Apr 30 13:43:28 UTC 2008 
Responsible-Changed-Why:  
Over to secteam for evaluation. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123177 
State-Changed-From-To: open->closed 
State-Changed-By: remko 
State-Changed-When: Mon Aug 5 11:57:48 UTC 2013 
State-Changed-Why:  
Hi, 

My apologies for this taking a long time. We believe that while 
we greatly appreciate your considerations and patch, that we might 
have a patch that suits our wishes better. There is discussion on 
why this had not been implemented yet, but it is on the active 
radar again. 

Thank you for contributing to FreeBSD, it -is- greatly appreciated! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123177 
>Unformatted:
