> Date: Sat, 11 Nov 2017 15:48:12 +0100 > From: Maxime Villard <m...@m00nbsd.net> > > It is based on the SHAKE256 hash function, which can produce a variable > sized output. We use an area of 32 bytes, and regenerate it as many times > as needed. > > The first time, it is generated with: > > area = SHAKE256(entropy-file, rdseed, rdtsc) > > When all of the bytes in the area have been consumed, it is regenerated > this way: > > area = SHAKE256(area, rdseed, rdtsc)
If we _both_ reveal y = H(x) for some initial secret x, and then use y as the new secret, we've just revealed the new secret. Rather, we should carve up the output of SHAKE256 into a new 32-byte secret and an n-byte buffer of outputs for some convenient n: nseed(32) || buffer(480) = SHAKE256(oseed(32) || whatever else) See <https://blog.cr.yp.to/20170723-random.html> for further discussion of this structure (and criticism of the obscenely complicated NIST DRBGs in SP800-90A). It may be simpler to use a Keccak duplex like the draft entropy pool I've been sitting on for a while, which has some theoretically nicer properties[1] though hasn't yet appeared in a NIST standard the way SHAKE256 has. Input from someone who is likely to care about certification more than I do would be appreciated here. Also, where do you update the seed that is then passed to rnd_seed to initialize the real kernel entropy pool? Finally, some minor nits: - Don't call it `rndpool', because that has a specific meaning in NetBSD already, which is something else. Just `struct prng' is fine, if confined to that file. - Define functions with foo(void), not foo(), to get prototype checking from the C compiler. - Newline before function name in definitions; see share/misc/style for more details. - No need for casts between void * and other types. - Use unsigned, not u_int; u_int, u_intN_t, &c., are vestiges of older days. - Avoid externs in .c files. Include the right header file for the declaration of bootinfo. [1] https://keccak.team/files/SpongePRNG.pdf