Speed and security of /dev/urandom

Steven Chamberlain steven at pyro.eu.org
Fri Jul 18 20:06:39 UTC 2014


On 18/07/14 20:01, Leif Pedersen wrote:
> I believe one of Steven's points was (I'm fairly sure I understood him
> correctly) that neglecting to reseed after fork() has led to problems.

Yes, it's one of many things that has gone wrong in the past.

It's been pointed out to me that OpenBSD solved that particular issue
with MAP_INHERIT_ZERO:  the state of the arc4random PRNG is zeroed out
on forking, and it knows to reseed then.

FreeBSD since r227520 (2011-11-15), calls getpid() on every
arc4random_buf call, to see if the pid has changed since it seeded, and
thus reseed.  It was shown recently (in the context of LibreSSL
Portable) that this may not work in a contrived corner-case, so there
they added an atfork handler, but again might not always be called.

*If* getpid involves a syscall on every arc4random_buf call, that is
going to already going to limit its performance?  Would it really be any
slower to just return random bytes from the kernel, with the KERN_ARND
sysctl?  The overhead of currently having to initially and periodically
seed RC4, discard the early keystream, and apply that cipher thereafter,
would be gone.  The risk of the problem described above, or of
weaknesses in RC4, or implementation issues with arc4random's PRNG
seeding are also gone.

And if FreeBSD's kernel CSPRNG wasn't trusted already, the arc4random
PRNG is badly seeded and untrusted anyway.  arc4random wasn't doing
anything to supplement with entropy gathered from userland (which seems
to be the belt-and-braces approach taken by OpenSSL).

I don't suppose there's a risk of exhausting entropy by reading too much
via the sysctl, or else an unprivileged user could do that already.
Yarrow should already handle this.

I very much welcome critique here, I think that's a necessary part of
design and evolution of security code.  I think we should periodically
look at what we have to make sure it still holds up to scrutiny, even if
it 'aint broke (as far as we know).  Please point out any wrong
assumptions you think I've made, even if it seems obvious.

> will have exactly the
> same initial state if there is no provision to reseed the PRNG.

There is arc4random_stir, but an application could easily forget to do
that.  Users of libevent for example, which uses arc4random, doesn't
expose an API function to do an explicit stir if the application forks.

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


More information about the freebsd-security mailing list