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  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]
Date:   Fri, 27 Dec 2019 11:29:22 +0100
From:   Stephan Mueller <smueller@...onox.de>
To:     Andy Lutomirski <luto@...capital.net>,
        "Theodore Y. Ts'o" <tytso@....edu>
Cc:     Andy Lutomirski <luto@...nel.org>,
        LKML <linux-kernel@...r.kernel.org>,
        Linux API <linux-api@...r.kernel.org>,
        Kees Cook <keescook@...omium.org>,
        "Jason A. Donenfeld" <Jason@...c4.com>,
        "Ahmed S. Darwish" <darwish.07@...il.com>,
        Lennart Poettering <mzxreary@...inter.de>,
        "Eric W. Biederman" <ebiederm@...ssion.com>,
        "Alexander E. Patrakov" <patrakov@...il.com>,
        Michael Kerrisk <mtk.manpages@...il.com>,
        Willy Tarreau <w@....eu>,
        Matthew Garrett <mjg59@...f.ucam.org>,
        Ext4 Developers List <linux-ext4@...r.kernel.org>,
        linux-man <linux-man@...r.kernel.org>
Subject: Re: [PATCH v3 0/8] Rework random blocking

Am Freitag, 27. Dezember 2019, 00:29:20 CET schrieb Andy Lutomirski:

Hi Ted, Andy,

> >> On Dec 26, 2019, at 10:04 PM, Theodore Y. Ts'o <tytso@....edu> wrote:
> >> 
> >> On Thu, Dec 26, 2019 at 01:03:34PM +0100, Stephan Mueller wrote:
> >> Agreed. I was just trying to outline that the removal of the
> >> blocking_pool is a good thing. Even when we decide that random.c should
> >> receive a TRNG, we do not need to re-add a blocking pool, but can easily
> >> use the existing ChaCha20 DRNG (most likely with its own instance).
> > 
> > Well, it depends on what you mean by "TRNG" --- the ChaCha20 DRNG only
> > has a state of 256 bits.  So if you want to only depend on "true
> > entropy" you can't extract more than 256 bits without violating that
> > assumption, at least if you're using a very strict definition of TRNG.


My definition of TRNG is identical to the German AIS 31 and I guess identical 
to your definition of a TRNG.

A TRNG will produce an amount of random data that is equal to the amount of 
"fresh" entropy that was provided by the noise source. I.e. it should be 
identical to the blocking_pool behavior.

This definition is slightly stricter than the SP800-90A definition of "a DRBG 
with prediction resistance" which requires a reseed with entropy equal to the 
security strength of the DRBG, but allows one generate operation which at most 
generates 2^19 random bits.

Such TRNG has two components

1. the noise source / the entropy pool

2. the random number generator

All I try to say is that the random number generator does not need to be a 
special implementation of, say, a blocking_pool, but it can be any type of 
DRNG (ChaCha20, SP800-90A DRBG, ...).

To manage that DRNG, the logic needs to ensure that the maximum entropy 
content assumed to be present in the DRNG is min(entropy_from_noise_source, 
security_strength_DRNG). For the case of the blocking_pool, the security 
strength is 1024 bits which means that at most the blocking_pool can hold up 
to 1024 bits. With a ChaCha20 DRNG, the security strength is 256 bits. 
SP800-90A defines the security strengths of the DRBGs.

That said, for a TRNG, the DRNG part must be seeded with the amount of entropy 
equaling the requested numbers of random bits, but at most with entropy 
equaling the security strength of the DRNG. If the caller wants more random 
data, the request must be chunked to ensure that the DRNG is always reseeded 
before satisfying the chunk of the request.

> > 
> > By getting rid of the blocking pool, and making /dev/random work like
> > getrandom with flags set to 0, we're effectively abandoning any kind
> > of assertion that /dev/random is some kind of TRNG.  This is not
> > insane; this is what the *BSD's have always done.

Correct, and I am not disputing it. And I think that making Linux to behave 
like the BSD's and guaranteeing that the DRNG is fully seeded based on Andy's 
patch set is a good thing.

All I try to say is that there are use cases where a TRNG with the initially 
defined operation is required. This most prominent use case is the German AIS 
31 and the (re)seeding requirements of deterministic RNGs.
> > 
> > But once we do this, and /dev/random takes on the semantics of "block
> > until the CRNG has been initialized, and then it won't block after
> > that", if we change it so that it now has some different semantics,
> > such as "one you extract a 256-bit key, the read from /dev/random will
> > block until we can refill it, which might take seconds, minutes or
> > hours", will be considered a regression, and we can't do that.
> 
> I don’t think Stephan was proposing that. He was proposing a way to
> implement a new interface that blocks.

Thank you, Andy. Yes. I am trying to propose a separate interface.

Our discussion currently produced the following suggestions:

- add a new GRND_TRUERANDOM flag to getrandom(2) which allows access to the 
TRNG. Andy did not like it because he mentioned that it may be misused since 
the syscall is unprivileged. I had some suggestions to overcome this problem, 
but not all of Andy's considerations could be addressed with this suggestion. 
As an idea, my current LRNG system call implementation looks like:

SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
                unsigned int, flags)
{
        if (flags & ~(GRND_NONBLOCK|GRND_RANDOM|GRND_INSECURE|
GRND_TRUERANDOM))
                return -EINVAL;

        /*
         * Requesting insecure and blocking randomness at the same time makes
         * no sense.
         */
        if ((flags &
             (GRND_INSECURE|GRND_RANDOM)) == (GRND_INSECURE|GRND_RANDOM))
                return -EINVAL;

        /* Only allow GRND_TRUERANDOM by itself or with NONBLOCK */
        if ((flags & GRND_TRUERANDOM) &&
            ((flags &~ GRND_TRUERANDOM) != 0) &&
            ((flags &~ (GRND_TRUERANDOM | GRND_NONBLOCK)) != 0))
                return -EINVAL;

        if (count > INT_MAX)
                count = INT_MAX;

        if (flags & GRND_TRUERANDOM)
                return lrng_read_common_block(flags & GRND_NONBLOCK, buf,
                                              count, lrng_trng_get);
        if (flags & GRND_INSECURE)
                return lrng_sdrng_read(NULL, buf, count, NULL);

        return lrng_read_common_block(flags & GRND_NONBLOCK, buf, count,
                                      lrng_sdrng_get_sleep);

}


- Andy mentioned that he likes the approach with having another new char 
device with permissions 440 to provide an interface to the TRNG as more 
appropriate. However, Greg was reluctant to add a new device file.

I personally am indifferent. All I am suggesting is to have a TRNG offered to 
user space.

> > Of course, we can hope that people will be using getrandom() and there
> > will be very few new users of the /dev/random pathname.  But nothing
> > is ever guaranteed..
> > 
> >                       - Ted



Ciao
Stephan


Powered by blists - more mailing lists