[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