Linux was the first operating system to expose a kernel-powered CSPRNG to userland, thanks to Theodore Ts’o, who committed added one in Linux 1.3.30, in September 1995. This was done in collaboration with Colin Plumb, who designed the random number generator in the original PGP code base, and Dale Worley. It relied on gathering random signals (interrupts, timers, latencies, inputs, …), and mixing them via MD5.
In August 1996, David Mazieres added the
/dev/arnd device, based on
arc4random function was added in December 1996
to OpenBSD’s libc. It has several advantages over
/dev/urandom: it can’t fail, it’s available in chroots,
is thread-safe, it has better performances since it’s only asking the kernel
for entropy to (re)seed its keystream, … making it easy to use for developers.
Following OpenBSD’s example, Linux got a new syscall to gather entropy, in July 2014, by Theodore Ts’o, again.
Three years later, in July 2016, he also changed the implementation of the Linux kernel’s implementation to ChaCha20 too, and it landed in Linux 4.8 in October 2016.
The 30th of July 2017, a fun bug was fixed, in Theo de Raadt’s words:
A few optimizations later, a security requirement has been removed.
The issue was that compilers are trying to be clever, (rightly) assuming
const static object will always be zero, even when placed in a
.openbsd.randomdata segment, resulting in useless stack cookies and
Amusingly, the issue has been introduced the 1st of September 2016, and was unnoticed for almost one year!
arc4random in userland is available on various platforms,
even when not being natively implemented, thanks to
FreeBSD, Linux, … have all moved to a
ChaCha20-based CSPRNG. Even Tor is now
using some of its code, for
OpenBSD took inspiration from Linux two decades ago, but nowadays, it’s the other way around, OpenBSD is driving the CSRPNG game!
As for the gory details of OpenBSD’s PRNG, there is a long comment on top of its implementation, but it boils down to being seeded with various timings (keyboard input, interrupts delays, …), all mixed from time to time with a CRC into the entropy pool, which is used (mostly) to (re)seed a ChaCha20 stream cipher, from which entropy is finally presented to the user.