Developers’ Weblog

Sponsored by
HostEurope Logo

Developers’ Weblog

⚠ This page contains old, outdated, obsolete, … historic or WIP content! No warranties e.g. for correctness!

All 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

RNG for MirBSD and subprojects

2014-11-29 by tg@
Tags: plan

Feel free to ignore those semi-unsorted ramblings of mine, they are unfinished, not binding, notes of plans that may come if I ever learn 影分身の術 (Kage Bunshin no Jutsu) or bilocality…

We currently have arc4random(9) in the kernel and arc4random(3) in userspace. We also have the urandom(4) stuff, but nobody should use them really. OpenBSD simplified theirs, but lost functionality like arc4random_addrandom(3) during that. I complicated ours, to get e.g. arc4random_pushb_fast(3), and for using userspace as additional pools, but that grew complex too, and few applications really add to their state other than using it anyway.

My idea thus far is to begin with those applications. That would be mksh(1) and ntpd(8) only, AFAICT. On the basis of the recently Spritz, an aRC4 successor with great sponge properties, I plan on creating s4random, which could serve their specific needs: an output state Spritz (like arc4random has); an input Spritz (which corresponds to the arc4random_roundhash) tweaked to have, every time Shuffle() is called by the absorption functions, four bytes sent to a BAFH state from Drip(); that 32-bit state is then used to randomly drop from the output state (in addition to a value from the output state itself like arc4random uses) for faster feedback (think state recovery attacks). The output state can then be seeded less often but in larger blocks, taking from the input state as well as arc4random(3) or sysctl(3) KERN_ARND or OpenBSD getentropy() or Linux getrandom() or /dev/urandom, with the usual pushback. It could also need only 16 bytes instead of 128/256 bytes from the kernel on such calls (possibly lowering the a4s_count equivalent for the first two trips). It would also need to work on lesser operating systems, so it can probably have a function to determine seed status (2 = third trip, kernel entropy; 1 = first or second trip, or Win32 CryptGenRandom; 0 = untrusted). Also consider skipping initialisation by hardcoding one at compile time, facilitated through Mirtoconf v2. (Also, reducing the maximum Squeeze() parameter to 64 before random dropping engages, instead of 256, makes sense. The BAFH state also needs feedback from the output state…)

Then, I could simplify MirBSD libc arc4random(3) as all other applications than those mentioned above (and maybe libcrypto, but that’s a special case anyway) don’t need this sort of fast feedback loop. I’ve not yet planned that part out. — Finally, the kernel may or may not adopt Spritz but I’ve got ideas wrt. that, faster feedback loops, less overhead for interrupt handlers, etc. as well. This can wait a bit, as Spritz is still very new, so I’d prefer to not lower the security level accidentally, but it can be prototyped for something eventually ending up in ntpd(8) where it has low impact, and mksh, where the MirJSON and Mirkev code will need it.

OpenSSL’s libcrypto is another case. Just using arc4random(3) now has effectively reduced its state size from about 8184 bit to about 1700 bit of aRC4 state while a Spritz state has about 1476‒1604 bit. Of course, it reads from the kernel, which doesn’t offer more anyway, and people say about security levels, but there’s still always EGD and, more importantly, ~/.rnd (or RANDFILE to be exact). So, an upscaling solution is needed, too, but I can construct one, similar to how arc4random_roundhash is comprised of 32 32-bit BAFH states with appropriate (but slow) mixing. But that’s specific to MirBSD anyway, and can take time.

Meh. Reminds me, I probably should add getentropy() before upgrading OpenSSH to a version doing the sandboxing. And let arc4random(3) use the new MAP_INHERIT_ZERO stuff; at least minherit(2) throws EINVAL as safe fallback but it still requires updating the kernel first. But then it has been there for months already.

MirBSD Logo