diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2020-05-15 13:48:58 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2020-05-15 13:48:58 +0000 |
commit | 3120927ed34a496efea79fa0856e4dbfe9601ba0 (patch) | |
tree | 0d0b9a1d463754792349ad217025049072804faf /sys/dev | |
parent | 64a361b7e4a8d4f1fa1e5c62566d90709446bf3d (diff) |
The main comment block from 1996 has become highly inaccurate and
misleading, so rewrite it.
The interesting parts are bootblock-seeding from file + hwrng,
arc4random() being available incredibly early, and seperate timeouts
to pull entropy data forward into a stir of the chacha state (one for
entropy ring crc whitening into a buffer, the 2nd for buffer folding
into the chacha)
Now that it is better documented, I can try to improve each component.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/rnd.c | 81 |
1 files changed, 17 insertions, 64 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index 6e8e2bfd0ed..b5f9bed65fe 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.205 2020/05/15 13:39:02 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.206 2020/05/15 13:48:57 deraadt Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -41,72 +41,25 @@ */ /* - * Computers are very predictable devices. Hence it is extremely hard - * to produce truly random numbers on a computer --- as opposed to - * pseudo-random numbers, which can be easily generated by using an - * algorithm. Unfortunately, it is very easy for attackers to guess - * the sequence of pseudo-random number generators, and for some - * applications this is not acceptable. Instead, we must try to - * gather "environmental noise" from the computer's environment, which - * must be hard for outside attackers to observe and use to - * generate random numbers. In a Unix environment, this is best done - * from inside the kernel. + * The bootblocks pre-fill the kernel .openbsd.randomdata section with seed + * material (on-disk from previous boot, hopefully mixed with a hardware rng). + * The first arc4random(9) call initializes this seed material as a chacha + * state. Calls can be done early in kernel bootstrap code -- early use is + * encouraged. * - * Sources of randomness from the environment include inter-keyboard - * timings, inter-interrupt timings from some interrupts, and other - * events which are both (a) non-deterministic and (b) hard for an - * outside observer to measure. Randomness from these sources is - * added to the "rnd states" queue; this is used as much of the - * source material which is mixed on occasion using a CRC-like function - * into the "entropy pool". This is not cryptographically strong, but - * it is adequate assuming the randomness is not chosen maliciously, - * and it is very fast because the interrupt-time event is only to add - * a small random token to the "rnd states" queue. + * After the kernel timeout subsystem is initialized, random_start() prepares + * the entropy collection mechanism enqueue_randomness() and timeout-driven + * mixing into the chacha state. The first submissions come from device + * probes, later on interrupt-time submissions are more common. Entropy + * data (and timing information) is XOR spread over the entropy input ring + * rnd_event_space[] for later integration. * - * When random bytes are desired, they are obtained by pulling from - * the entropy pool and running a SHA512 hash. The SHA512 hash avoids - * exposing the internal state of the entropy pool. Even if it is - * possible to analyze SHA512 in some clever way, as long as the amount - * of data returned from the generator is less than the inherent - * entropy in the pool, the output data is totally unpredictable. For - * this reason, the routine decreases its internal estimate of how many - * bits of "true randomness" are contained in the entropy pool as it - * outputs random numbers. + * Based upon timeouts, data in the entropy input ring rnd_event_space[] is + * drawn down, CRC bit-distributed and mixed into entropy_pool[]. * - * If this estimate goes to zero, the SHA512 hash will continue to generate - * output since there is no true risk because the SHA512 output is not - * exported outside this subsystem. It is next used as input to seed a - * ChaCha20 stream cipher, which is re-seeded from time to time. This - * design provides very high amounts of output data from a potentially - * small entropy base, at high enough speeds to encourage use of random - * numbers in nearly any situation. Before OpenBSD 5.5, the RC4 stream - * cipher (also known as ARC4) was used instead of ChaCha20. - * - * The output of this single ChaCha20 engine is then shared amongst many - * consumers in the kernel and userland via a few interfaces: - * arc4random_buf(), arc4random(), arc4random_uniform(), randomread() - * for the set of /dev/random nodes and the system call getentropy(), - * which provides seeds for process-context pseudorandom generators. - * - * Acknowledgements: - * ================= - * - * Ideas for constructing this random number generator were derived - * from Pretty Good Privacy's random number generator, and from private - * discussions with Phil Karn. Colin Plumb provided a faster random - * number generator, which speeds up the mixing function of the entropy - * pool, taken from PGPfone. Dale Worley has also contributed many - * useful ideas and suggestions to improve this driver. - * - * Any flaws in the design are solely my responsibility, and should - * not be attributed to the Phil, Colin, or any of the authors of PGP. - * - * Further background information on this topic may be obtained from - * RFC 1750, "Randomness Recommendations for Security", by Donald - * Eastlake, Steve Crocker, and Jeff Schiller. - * - * Using a RC4 stream cipher as 2nd stage after the MD5 (now SHA512) output - * is the result of work by David Mazieres. + * From time to time, entropy_pool[] is SHA512-whitened, mixed with time + * information again, XOR'd with the inner and outer states of the existing + * chacha state, to create a new chacha state. */ #include <sys/param.h> |