lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <66f06ea1-3221-5661-e0de-6eef45ac3664@gmail.com>
Date:   Wed, 5 Aug 2020 08:44:04 -0700
From:   Marc Plumb <lkml.mplumb@...il.com>
To:     Willy Tarreau <w@....eu>
Cc:     tytso@....edu, netdev@...r.kernel.org, aksecurity@...il.com,
        torvalds@...ux-foundation.org, edumazet@...gle.com,
        Jason@...c4.com, luto@...nel.org, keescook@...omium.org,
        tglx@...utronix.de, peterz@...radead.org, stable@...r.kernel.org
Subject: Re: Flaw in "random32: update the net random state on interrupt and
 activity"

Hi Willy,

On 2020-08-04 7:49 p.m., Willy Tarreau wrote:
> Hi Marc,
>
> On Tue, Aug 04, 2020 at 05:52:36PM -0700, Marc Plumb wrote:
>> Seeding two PRNGs with the same entropy causes two problems. The minor one
>> is that you're double counting entropy. The major one is that anyone who can
>> determine the state of one PRNG can determine the state of the other.
>>
>> The net_rand_state PRNG is effectively a 113 bit LFSR, so anyone who can see
>> any 113 bits of output can determine the complete internal state.
>>
>> The output of the net_rand_state PRNG is used to determine how data is sent
>> to the network, so the output is effectively broadcast to anyone watching
>> network traffic. Therefore anyone watching the network traffic can determine
>> the seed data being fed to the net_rand_state PRNG.
> The problem this patch is trying to work around is that the reporter
> (Amit) was able to determine the entire net_rand_state after observing
> a certain number of packets due to this trivial LFSR and the fact that
> its internal state between two reseedings only depends on the number
> of calls to read it.

I thought net_rand_state was assumed to be insecure and that anyone 
could determine the internal state. Isn't this Working as Designed? It's 
a PRNG not a CPRNG. If some aspects of security depends on the sate 
remaining secret then this is fundamentally the wrong tool.

> (please note that regarding this point I'll
> propose a patch to replace that PRNG to stop directly exposing the
> internal state to the network).

I'm glad to hear that. A good option would be SFC32.

> If you look closer at the patch, you'll see that in one interrupt
> the patch only uses any 32 out of the 128 bits of fast_pool to
> update only 32 bits of the net_rand_state. As such, the sequence
> observed on the network also depends on the remaining bits of
> net_rand_state, while the 96 other bits of the fast_pool are not
> exposed there.

The fast pool contains 128 bits of state, not 128 bits of entropy. The 
purpose of the large pool size is to make sure that the entropy is not 
lost due to collisions. The non-linear mixing function (a simplified 
version of a single round of the ChaCha mixing function so the entropy 
diffusion is low) means that the 32 bits leaked are not independent from 
the other 96 bits, and in fact you can reconstruct the entire pool from 
a single reading of 32 bits (as long as there aren't more than 32 bits 
of entropy added during this time -- which isn't the case, see below). 
Please think harder about this part. I think you are misunderstanding 
how this code works.

>> Since this is the same
>> seed data being fed to get_random_bytes, it allows an attacker to determine
>> the state and there output of /dev/random. I sincerely hope that this was
>> not the intended goal. :)
> Not only was this obviously not the goal, but I'd be particularly
> interested in seeing this reality demonstrated, considering that
> the whole 128 bits of fast_pool together count as a single bit of
> entropy, and that as such, even if you were able to figure the
> value of the 32 bits leaked to net_rand_state, you'd still have to
> guess the 96 other bits for each single entropy bit :-/

The code assumes that there is at least 1/64 bit of entropy per sample, 
and at most 2 bits of entropy per sample (which is why it dumps 128 bits 
every 64 samples). If you're extracting 32 bits every sample, which 
means it's leaking 2048 bits in 64 samples (to net_random, how fast it 
leaks to the outside world is a different issue). So the question is if 
an attacker can reconstruct 128 bits of entropy from 2048 bits of 
internal state -- this does not seem obviously impossible, since there 
are no cryptographically vetted operations in this.

The other thing that this misses is that reseeding in dribs and drabs 
makes it much easier to recover the new state. This is is explained well 
in the documentation about catastrophic reseeding in the Fortuna CPRNG. 
This entire approach is flawed. Throwing in single bits of entropy at a 
time doesn't really help since an attacker can brute force a single bit 
at a time. (There is a challenge in deriving the initial fast_pool 
states which this makes more difficult, but there is no real 
crytptographic guarantee about how difficult it is.)

Thanks,

Marc

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ