From owner-freebsd-bugs@FreeBSD.ORG Mon Apr 28 20:30:03 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AEDD31065674 for ; Mon, 28 Apr 2008 20:30:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 8B8CF8FC18 for ; Mon, 28 Apr 2008 20:30:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m3SKU3fW005565 for ; Mon, 28 Apr 2008 20:30:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m3SKU3gt005559; Mon, 28 Apr 2008 20:30:03 GMT (envelope-from gnats) Resent-Date: Mon, 28 Apr 2008 20:30:03 GMT Resent-Message-Id: <200804282030.m3SKU3gt005559@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Robert Woolley Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 866BA1065672 for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/123177: arc4rand(9) produces the same sequence on each boot X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Apr 2008 20:30:03 -0000 >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@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 #include #include +#include #include #include #include @@ -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 #include +#include + #include #include @@ -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: