All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org,
	Theodore Ts'o <tytso@mit.edu>,
	Dominik Brodowski <linux@dominikbrodowski.net>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Jann Horn <jannh@google.com>
Subject: Re: [PATCH v4] random: use simpler fast key erasure flow on per-cpu keys
Date: Sun, 20 Feb 2022 19:37:38 -0800	[thread overview]
Message-ID: <YhMJAsiHsjCJU1A4@sol.localdomain> (raw)
In-Reply-To: <20220216232142.193220-1-Jason@zx2c4.com>

On Thu, Feb 17, 2022 at 12:21:42AM +0100, Jason A. Donenfeld wrote:
> Rather than the clunky NUMA full ChaCha state system we had prior, this
> commit is closer to the original "fast key erasure RNG" proposal from
> <https://blog.cr.yp.to/20170723-random.html>, by simply treating ChaCha
> keys on a per-cpu basis.
> 
> All entropy is extracted to a base crng key of 32 bytes. This base crng
> has a birthdate and a generation counter. When we go to take bytes from
> the crng, we first check if the birthdate is too old; if it is, we
> reseed per usual. Then we start working on a per-cpu crng.
> 
> This per-cpu crng makes sure that it has the same generation counter as
> the base crng. If it doesn't, it does fast key erasure with the base
> crng key and uses the output as its new per-cpu key, and then updates
> its local generation counter. Then, using this per-cpu state, we do
> ordinary fast key erasure. Half of this first block is used to overwrite
> the per-cpu crng key for the next call -- this is the fast key erasure
> RNG idea -- and the other half, along with the ChaCha state, is returned
> to the caller. If the caller desires more than this remaining half, it
> can generate more ChaCha blocks, unlocked, using the now detached ChaCha
> state that was just returned. Crypto-wise, this is more or less what we
> were doing before, but this simply makes it more explicit and ensures
> that we always have backtrack protection by not playing games with a
> shared block counter.
> 
> The flow looks like this:
> 
> ──extract()──► base_crng.key ◄──memcpy()───┐
>                    │                       │
>                    └──chacha()──────┬─► new_base_key
>                                     └─► crngs[n].key ◄──memcpy()───┐
>                                               │                    │
>                                               └──chacha()───┬─► new_key
>                                                             └─► random_bytes
>                                                                       │
>                                                                       └────►
> 
> There are a few hairy details around early init. Just as was done
> before, prior to having gathered enough entropy, crng_fast_load() and
> crng_slow_load() dump bytes directly into the base crng, and when we go
> to take bytes from the crng, in that case, we're doing fast key erasure
> with the base crng rather than the fast unlocked per-cpu crngs. This is
> fine as that's only the state of affairs during very early boot; once
> the crng initializes we never use these paths again.
> 
> In the process of all this, the APIs into the crng become a bit simpler:
> we have get_random_bytes(buf, len) and get_random_bytes_user(buf, len),
> which both do what you'd expect. All of the details of fast key erasure
> and per-cpu selection happen only in a very short critical section of
> crng_make_state(), which selects the right per-cpu key, does the fast
> key erasure, and returns a local state to the caller's stack. So, we no
> longer have a need for a separate backtrack function, as this happens
> all at once here. The API then allows us to extend backtrack protection
> to batched entropy without really having to do much at all.
> 
> The result is a bit simpler than before and has fewer foot guns. The
> init time state machine also gets a lot simpler as we don't need to wait
> for workqueues to come online and do deferred work. And the multi-core
> performance should be increased significantly, by virtue of having hardly
> any locking on the fast path.
> 
> Cc: Theodore Ts'o <tytso@mit.edu>
> Cc: Dominik Brodowski <linux@dominikbrodowski.net>
> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Reviewed-by: Jann Horn <jannh@google.com>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
> Changes v3->v4:
> - Following Jann's review, base_crng.birth is now written to with
>   WRITE_ONCE.
> 
>  drivers/char/random.c | 388 ++++++++++++++++++++++++------------------
>  1 file changed, 222 insertions(+), 166 deletions(-)

Looks good,

Reviewed-by: Eric Biggers <ebiggers@google.com>

The only oddity I noticed is that some new comments use the net coding style for
multi-line comments, and get reformatted to the standard style later in a later
patch.  It would be preferable to use the standard style from the beginning.

- Eric

  reply	other threads:[~2022-02-21  3:37 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-09  1:19 [PATCH v2 0/9] random: cleanups around per-cpu crng & rdrand Jason A. Donenfeld
2022-02-09  1:19 ` [PATCH v2 1/9] random: use RDSEED instead of RDRAND in entropy extraction Jason A. Donenfeld
2022-02-09  6:18   ` Dominik Brodowski
2022-02-09  1:19 ` [PATCH v2 2/9] random: get rid of secondary crngs Jason A. Donenfeld
2022-02-09  8:22   ` Dominik Brodowski
2022-02-09 10:26     ` Jason A. Donenfeld
2022-02-21  2:38   ` Eric Biggers
2022-02-09  1:19 ` [PATCH v2 3/9] random: inline leaves of rand_initialize() Jason A. Donenfeld
2022-02-09  8:22   ` Dominik Brodowski
2022-02-09 10:27     ` Jason A. Donenfeld
2022-02-09  1:19 ` [PATCH v2 4/9] random: ensure early RDSEED goes through mixer on init Jason A. Donenfeld
2022-02-09  8:23   ` Dominik Brodowski
2022-02-09 10:37     ` Jason A. Donenfeld
2022-02-09  1:19 ` [PATCH v2 5/9] random: do not xor RDRAND when writing into /dev/random Jason A. Donenfeld
2022-02-09  8:28   ` Dominik Brodowski
2022-02-09 10:40     ` Jason A. Donenfeld
2022-02-09  1:19 ` [PATCH v2 6/9] random: absorb fast pool into input pool after fast load Jason A. Donenfeld
2022-02-09  8:29   ` Dominik Brodowski
2022-02-09 10:45     ` Jason A. Donenfeld
2022-02-15 21:13       ` [PATCH v3] " Jason A. Donenfeld
2022-02-21  2:47         ` Eric Biggers
2022-02-21 14:57           ` Jason A. Donenfeld
2022-02-21 14:58             ` [PATCH v4] " Jason A. Donenfeld
2022-02-21 19:08               ` Eric Biggers
2022-02-09  1:19 ` [PATCH v2 7/9] random: use simpler fast key erasure flow on per-cpu keys Jason A. Donenfeld
2022-02-09  8:30   ` Dominik Brodowski
2022-02-09 10:54     ` Jason A. Donenfeld
2022-02-14 18:46   ` [PATCH v3] " Jason A. Donenfeld
2022-02-16 23:21     ` [PATCH v4] " Jason A. Donenfeld
2022-02-21  3:37       ` Eric Biggers [this message]
2022-02-21 14:42         ` Jason A. Donenfeld
2022-02-09  1:19 ` [PATCH v2 8/9] random: use hash function for crng_slow_load() Jason A. Donenfeld
2022-02-09  8:30   ` Dominik Brodowski
2022-02-21  3:40   ` Eric Biggers
2022-02-09  1:19 ` [PATCH v2 9/9] random: remove outdated INT_MAX >> 6 check in urandom_read() Jason A. Donenfeld
2022-02-21  3:56   ` Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YhMJAsiHsjCJU1A4@sol.localdomain \
    --to=ebiggers@kernel.org \
    --cc=Jason@zx2c4.com \
    --cc=bigeasy@linutronix.de \
    --cc=jannh@google.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@dominikbrodowski.net \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.