[Cryptography] Fast-key-erasure RNG and fork()ing
John-Mark Gurney
jmg at funkthat.com
Thu Jul 5 11:57:19 EDT 2018
Yann Ylavic wrote this message on Fri, Jun 29, 2018 at 00:46 +0200:
> On Wed, Jun 27, 2018 at 8:29 PM, Florian Weimer <fw at deneb.enyo.de> wrote:
> > * Yann Ylavic:
> >
> >> I wonder how I'd best handle fork()ed processes, given that with the
> >> above design the forked key is the one that should produce the next
> >> keystream, and obviously the parent and child processes must not use
> >> the same one.
> >
> > You can use two counters, one in a MAP_SHARED page, and one in a
> > MAP_PRIVATE page. Increment them before and after each access to
> > random data, under a process-private lock, and compare if they are
> > still the same. You have to reseed if the counters diverge.
> >
> > An implementation of this approach is part of this patch (still under
> > review, LGPLv2.1+ license, so be careful if that matters to you):
> >
> > <https://sourceware.org/ml/libc-alpha/2018-06/msg00674.html>
>
> Indeed, nice feature and design.
>
> Actually I'm working on this PRNG ([1]) for the Apache Runtime library
> (APR, Apache license v2), besides the portability (P stands for that
> in A*P*R) and license issues, I didn't intend to go that far and
> "catch" fork()s for now.
>
> The lib provides a wrapper for fork() which pretty much does ([1]):
> crypto_prng_before_fork()
> pid = fork()
> crypto_prng_after_fork(pid == 0) /* act differently for parent and child */
>
> and the user is supposed to call it to fork a new process.
>
> So my question was more about the correct rekeying in _after_fork(),
> so that parent and child process hide their state from each other.
> After some work/out-of-list discussions I think I got it right by
> rekeying appropriately, solely based on the keystream(s) ([3]), and
> getting rid of the SHA256(getpid()) xor stuff.
>
> This PRNG for now is not any-fork() proof, it's meant to run either in
> it's own (hardened) process with a named socket/pipe interface, or in
> a "trusted" environment with wrapped fork()s and no arbitrary code run
> (FWIW).
> The design at least ensures that if the process crashes, there is no
> key/state material to recover the random bytes provided so far.
> It's also fast (faster than getrandom() for instance, I didn't test
> arc4random_buf()), but the comparison is probably not fair...
> Mainly, for a lib which supports quite some platforms, it's
> cryptographically safe (supposedly) and never blocks besides the
> initial 32 bytes entropy gathered from the system. Not all platforms
> provide get/arc4-random() unfortunately, while "/dev/urandom" never
> blocks but doesn't garanty good randoms either (w/o enough entropy,
Entirely depends upon the system... All the BSD's I believe provide
good entropy on /dev/urandom, so you should take this into account
for your portability...
> how could it), not to talk about mostly unusable "/dev/random" for
> modern needs of randoms.
Yeah, another Linux'ism...
Don't forget about getentropy (originally OpenBSD) and related syscalls.
--
John-Mark Gurney Voice: +1 415 225 5579
"All that I will do, has been done, All that I have, has not."
More information about the cryptography
mailing list