Speed and security of /dev/urandom

John-Mark Gurney jmg at funkthat.com
Sat Jul 19 19:03:56 UTC 2014


Steven Chamberlain wrote this message on Fri, Jul 18, 2014 at 00:41 +0100:
> 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?

Wow, am I really seeing this right, that kern.arc4rand doesn't use the
same interface that /dev/random/ uses?  And there isn't a sysctl interface
to /dev/random?

This really needs to b e fixed...

> 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?

We should move arc4random to just using the same interface as /dev/random,
or, if you're talking about arc4random(3), we should just convert
arc4random(3) to using the sysctl...

Though this introduces a standard problem... People are using an
implementation (arc4random) instead of a generic give me x interface,
though it looks like there isn't a way to directly seed the arc4random
pool, so hopefully people are expecting to use this to get reproducable
random numbers (for testing)...

> * 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

Yes, if there is an error from the sysctl or something, the process
should abort or something similar...

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

I assume you mean convert arc4random(3) to use the sysctl, or?

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

Per other person's comment, this shouldn't matter if you have a good
PRNG...

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

So, my suggestions:
1)	Convert arc4random(9) in the kernel to use the random pool as
	/dev/random uses.  I vaguely remeber there being an issue w/
	arc4random(9) being used early in boot before /dev/random is
	initalized which would complicate this change...
2)	Convert arc4random(3) to use the sysctl, and if the sysctl fails,
	kill the process.

There are also some other improvements that can be made to the
/dev/random frame work, but those are more code cleanup, not security
related changes...

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."


More information about the freebsd-security mailing list