Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jul 2014 00:41:54 +0100
From:      Steven Chamberlain <steven@pyro.eu.org>
To:        freebsd-security@freebsd.org
Subject:   Speed and security of /dev/urandom
Message-ID:  <53C85F42.1000704@pyro.eu.org>

next in thread | raw e-mail | index | archive | help
Hi,

FreeBSD is as far as I know, quite unique in using Yarrow to provide a
nice, fast CSPRNG for /dev/urandom

But OpenSSL, LibreSSL, OpenSSH, and various reimplementations of
arc4random(), don't directly use it.  They typically take only ~128 bits
from /dev/urandom or through other means, to seed a stream cipher, then
return the output of that.  I understand why Linux, even OpenBSD must do
that.  Good-quality random bits from the kernel are scarce, so they
*must* be stretched somehow.

But isn't that essentially what Yarrow does already in FreeBSD?

Is there a good reason arc4random_buf() can't take bytes directly from
/dev/urandom or sysctl KERN_ARND?  Therefore no longer needing to seed
first, periodically reseed, or use any stream cipher?

There are a few reasons I mention it now:

* arc4random relies on the stream cipher being cryptographically strong
between reseeds, or else you could guess previous/later output.  FreeBSD
still uses RC4 for arc4random, and that seems increasingly risky;
OpenBSD moved recently to ChaCha-20, but who knows if even that will
prove to be safe in the longer term?

* after seeding, some arc4random implementations completely forget to
reseed after the process forks - the same 'random' stream of bytes could
occur twice, with security implications

* LibreSSL tried to detect forking, and to reseed automatically, but
Andrew Ayer showed a corner-case where that still didn't work as
expected (CVE-2014-2970)

* some arc4random implementations might not be thread-safe

* (re)seeding can fail sometimes (fd's exhausted reading /dev/urandom,
or that is missing in a chroot;  even a sysctl might return an error
code);  OpenSSL and LibreSSL each have 'scary' ways to try to gather
entropy in userland as a fallback, especially for Linux;  FreeBSD and
OpenBSD may have better expectations that the sysctl will work, and
maybe raise SIGKILL otherwise

So I wonder, could a simplified arc4random for FreeBSD use Yarrow
directly, to avoid making any of these sorts of mistakes we've seen?

(There's also the benefit that having many readers from a single
pseudorandom stream, adds an additional kind of randomness to its output).

This is obviously a complex issue, and some of it will be subjective.
But I welcome your comments.  Thanks!

Regards,
-- 
Steven Chamberlain
steven@pyro.eu.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53C85F42.1000704>