Re: Patch: rework kernel random number subsystem
[email protected] (Christos Zoulas) Sat, 22 Oct 2011 16:35:42 +0000 (UTC)
| Newsgroups | gmane.os.netbsd.devel.crypto,gmane.os.netbsd.devel.kernel,gmane.os.netbsd.devel.security |
|---|---|
| Message-ID | <[email protected]> |
In article <[email protected]>, Thor Lancelot Simon <[email protected]> wrote: > >I have placed a patch at http://www.panix.com/~tls/rnd1.diff which >implements many changes to the generation and use of randomness >in the kernel (I previously sent it to these lists directly but >it seems to be too large). > >It is (most of) the first step in a three step process I envision for major >overhaul of this subsystem: > > 1) Provide infrastructure needed to separate entropy > harvesting from random stream generation. Clean up > interfaces between existing kernel components that > deal with random number generation and consumption. > > 2) Replace all direct read access to the entropy pool with > an appropriate random stream generator, keyed from the pool. > Clean up the current mess in which the same source files > implement the entropy pool and the userspace pseudodevices > /dev/random and /dev/urandom. > > 3) Replace the entropy pool itself with a more modern design > such as Fortuna. > >Here are the changes you will find in this patch: > > 1) Two new components are provided, "rngtest" (subr_rngtest.c) > and "nist_ctr_drbg" (crypto/nist_ctr_drbg). The rngtest component > implements the FIPS 140-2 statistical RNG test. It is based on > work by Greg Rose at Qualcomm. The nist_ctr_drbg component > implements the NIST SP800-90 CTR_DRBG, which uses AES in a > modified counter mode to generate a backtracking-resistant random > stream. It is based on work by Henric Jungheim. > > Additionally, an abstration layer "cprng" (subr_cprng.c) is > provided for in-kernel consumers of randomness; see below. > > 2) A generic interface, "rndsink", for stream generators to request > that they be re-keyed with good quality entropy from the pool > as soon as it is available, is provided. > > 3) The arc4random/arc4randbytes implementation in libkern is > adjusted to use the rndsink interface for rekeying, which > helps address the problem of low quality keys at boot time. > > 4) The arc4random/arc4randbytes API is deprecated for in-kernel > use. It is replaced by "cprng_fast". The rnd_extract_data > interface is deprecated for in-kernel use. It is replaced > by "cprng_strong". The current cprng_fast implementation > wraps the existing arc4random implementation. The current > cprng_strong implementation wraps the CTR_DRBG implementation, > allowing as many private instances of the CTR_DRBG as desired. > > Both interfaces are rekeyed from the entropy pool automatically > at intervals justifiable from best current cryptographic practice. > > *When these generators are rekeyed, the 'rngtest' test is run > on their output and the kernel will panic if it fails.* It > is not the long-term intent to panic on a rngtest failure, > but rather to rekey; but this is a good way to detect bugs in > the implementation (see below). > > 5) The AES code in src/crypto/rijndael is no longer an optional > kernel component, as it is required by cprng_strong, which is > not an optional kernel component. > > 6) The entropy pool output is subjected to the rngtest tests at > startup time. Entropy pool _input_ from hardware random > number generators is subjected to the rngtest tests at attach > time, as well as the FIPS continuous-output test, to detect > bad or stuck hardware RNGs. > > 7) The sysctl node kern.urandom is now connected to cprng_strong > rather than the entropy pool (this allows cprng_strong testing > from userspace without replacing the pseudodevice yet). > > 8) The set of printfs triggered by RND_VERBOSE has been expanded. > >WARNING: #7 and #8 reveal some kind of synchronization or locking > bug in this patch. #8 causes the entropy pool to log to > the console whenever it supplies rekeying entropy. #7 > causes 'sysctl kern.urandom' to read from a cprng_strong > instance. > > Performing around 1000 consecutive such sysctl calls will > reveal corruption of the cprng_strong state: it is not > rekeyed (nor should it yet be), but is corrupted in such > a way that it thinks it has been, triggering the rngtest > statistical test, which then fails. > > Score 1 for the test, detecting a bug I can't sort out > yet; score 0 for me for not seeing what happens. Help > with this one (it's easy to reproduce!) much appreciated. > > 9) some API mess in rnd.c/rnd.h is cleaned up, such as exposing > structures with in-kernel void * to userspace in arrays, thus > causing compat32 issues. > > 10) I have made a start at letting the entropy pool supply useful > output *much* earlier in the boot process. There is a lot > more to do here. > >This patch is against last night's sources and builds release successfully >for amd64. Works, too, except the bug noted at WARNING above. I am >aware there are KNF issues and would prefer to fix them later. Help, >comments, criticism much appreciated. 1) + memset(r, 0, sizeof(r)); needs (*r) 2) The code around the above memset has whitespace issues. 3) Why do we have loops that have both a count sentinel and the list pointer sentinel? Shouldn't/couldn't those always be synced? 4) What's the hardcoded 16 in the name compares? 5) sizeof(type) in memcpy() should be sizeof(*dst 6) Isn't it possible to use the list foreach macros instead of open-coding? 7) instead of printfs shouldn't we use aprint? 8) some continuation lines are not knf. 9) cprng_strong_t *cprng_strong_create(const char *const name, int ipl) is not knf christos