2022-01-21 21:17:30

by Sandy Harris

[permalink] [raw]
Subject: random(4) question

I see this in the current random.c

/* Note that EXTRACT_SIZE is half of hash size here, because above
* we've dumped the full length back into mixer. By reducing the
* amount that we emit, we retain a level of forward secrecy.
*/
memcpy(out, hash, EXTRACT_SIZE);

Like the previous version based on SHA1, this produces an output half
the hash size which is likely a fine idea since we do not want to
expose the full hash output to an enemy. Unlike the older code,
though, this does expose some hash output.

The older code split the 160-bit hash in half and XORed the halves
together to get an 80-bit output. Should we do that here for 256-bit
output?

Dan Bernstein has something called "SURF: Simple Unpredictable Random
Function." that takes 384 bits in & gives 256 out.
https://cr.yp.to/papers.html#surf
I'm not sure that would work for us since it needs a 1024-bit key and
has 32 rounds, but it seems worth considering.


2022-01-21 21:19:04

by Jason A. Donenfeld

[permalink] [raw]
Subject: Re: random(4) question

We copy out half not because we don't trust the hash function but so
that we don't export part of what we're feeding back into the mixer.

2022-01-21 22:21:37

by Theodore Ts'o

[permalink] [raw]
Subject: Re: random(4) question

On Thu, Jan 20, 2022 at 06:39:31PM +0800, Sandy Harris wrote:
>
> Like the previous version based on SHA1, this produces an output half
> the hash size which is likely a fine idea since we do not want to
> expose the full hash output to an enemy. Unlike the older code,
> though, this does expose some hash output.

Well, as the comment says, we do this because we want to prevent
backtracking attacks --- where the attacker knows the state of the
pool plus the current outputs, and is trying to go back in time to
figure out previous outputs. Whether we XOR the halves together or
just reveal half the bits, either will achieve this goal.

Note that we're actually no longer directly exposing this output to
the enemy, since extract_buf is now only being use to extract entropy
from the input pool into the CRNG. And if the attacker can intercept
the values being used to reseed the CRNG, we've got bigger problems. :-)

Given how extrat_buf is being used today, assuming that we are
confident in the cryptosecurity of the CHACHA20 algorithm, it's
probably a bit of overkill as it is. However, it's not like this is
on the hot path from a performance perspective, and a bit of
over-engineering is not a bad thing.

Cheers,

- Ted