Visa Hankala <v...@hankala.org> wrote:

> On Thu, Jul 28, 2022 at 11:00:12AM +1000, Damien Miller wrote:
> > +   rs->rs_count = REKEY_BASE;
> > +   /* rekey interval should not be predictable */
> > +   _rs_random_u32(&rekey_fuzz);
> > +   rs->rs_count += rekey_fuzz % REKEY_BASE;
> 
> The randomization looks good.
> 
> However, might it cause a problem (in the future) that _rs_random_u32()
> calls _rs_stir_if_needed()? rs_count has a largish value so a recursive
> invocation of _rs_stir() should not happen, but anyway.

The question is what _rs_random_u32() will do when it calls 
_rs_stir_if_needed().

There is one potential problem.  lib/libcrypto/arc4random/*.h contains portable
wrappers for _rs_forkdetect(), which actually do things.  memset(rs, 0, 
sizeof(*rs))
will trash the rs state. Let's imagine a "fork" has happened same time that 
bytes
run out.

_rs_stir()
...
    rs->rs_count = REKEY_BASE;
    _rs_random_u32 -> _rs_stir_if_needed -> _rs_forkdetect
      - all rs fields are zero'd with memset
      - _rs_forkdetect returns

    back in _rs_stir_if_needed,
         - if (!rs || rs->rs_count <= len)
           _rs_stir();


So it will recurse once (only once, because a 2nd fork cannot happen).
But this is fragile.

Alternatives are to get the value direct from getentropy -- with KEYSZ + IVSZ + 
4
maybe?  Or fetch a value for this random bias early and track it in rs, but 
don't
damage it in the memset?  Or split _rs_random_u32() so that a sub-function of it
may collect these 4 keystream bytes without the _rs_stir_if_needed/_rs_rekey 
checks?

Reply via email to