[Cryptography] Fast-key-erasure RNG and fork()ing

John-Mark Gurney jmg at funkthat.com
Mon Jun 25 19:15:53 EDT 2018


Yann Ylavic wrote this message on Mon, Jun 25, 2018 at 00:11 +0200:
> I've implemented a PRNG based on D.J. Bernstein's blog entry [1] and
> implementation from libpqcrypto [2].
> 
> In this design, the initial key is filled from the system's RNG
> (getentropy(), getrandom(), arc4random_buf(), /dev/[u]random, ...) and
> the keystream of AES-256-CTR or Chacha20 (zeroed plaintext/IV)
> produces both the next key (first 32 bytes) and the random stream (a
> buffer of 736 bytes which is cleared on consumption). Once the buffer
> is empty, the process restarts with the new key and so on.
> 
> 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.

The closes platform independant method is pthread_atfork, but I don't
know how well that works across various platforms...  But you can use
that to trigger reseeds...

A great solution is the flag to zero a page on fork...

OpenBSD, and now FreeBSD, has a flag to zero a page when the process
forks...  This way you store the seed in the page, and check to make
sure it's not zero, if it is, then you reseed...  This has the best
protection as you will never leak seed material...

See INHERIT_ZERO in:
https://man.openbsd.org/minherit.2
and:
https://www.freebsd.org/cgi/man.cgi?query=minherit&sektion=2&apropos=0&manpath=freebsd

> I would like to avoid using the system's RNG for each child process,
> so was thinking of:

If your child processes are so short lived that a call to the system
RNG is expensive, then you're likely having a larger overhead of forking
than doing real work...  I'd just reseed from the system RNG, and it
has the advantage that the parent cannot know what the child's data
is...

> - in the child process, mix/xor the key with SHA256(<pid-of-child>)
> and use that as the initial key;
> - in the parent process, renew the key immediatly (i.e. produce the
> next key and random bytes as described above) since PIDs can
> potentially wrap around or come back before the buffer is exhausted
> thus the renewal of the key.

How do you detect that the fork happened?

-- 
  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