All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH stable 5.15.y 0/5] missing random.c-related stable patches
@ 2022-06-02 20:23 Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 1/5] lib/crypto: add prompts back to crypto libraries Jason A. Donenfeld
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

Hi Greg,

I forgot two things when doing the 5.15 backport. The first is a patch
from Justin fixing a bug in some of the lib/crypto Kconfig changes,
which Pablo (CC'd) pointed out was missed. The second is that the
backport of 5acd35487dc9 ("random: replace custom notifier chain with
standard one") isn't quite right without Nicolai's patches there too,
since the drbg module is removable.

I'll continue to monitor all the channels I possibly can for chatter
about problems, but so far this is all I've run into.

Jason

Cc: Pablo Greco <pgreco@centosproject.org>

Justin M. Forbes (1):
  lib/crypto: add prompts back to crypto libraries

Nicolai Stange (4):
  crypto: drbg - prepare for more fine-grained tracking of seeding state
  crypto: drbg - track whether DRBG was seeded with
    !rng_is_initialized()
  crypto: drbg - move dynamic ->reseed_threshold adjustments to
    __drbg_seed()
  crypto: drbg - make reseeding from get_random_bytes() synchronous

 crypto/Kconfig        |   2 -
 crypto/drbg.c         | 110 +++++++++++++++++-------------------------
 drivers/char/random.c |   2 -
 include/crypto/drbg.h |  10 ++--
 lib/Kconfig           |   2 +
 lib/crypto/Kconfig    |  17 +++++--
 6 files changed, 65 insertions(+), 78 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH stable 5.15.y 1/5] lib/crypto: add prompts back to crypto libraries
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
@ 2022-06-02 20:23 ` Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 2/5] crypto: drbg - prepare for more fine-grained tracking of seeding state Jason A. Donenfeld
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

From: "Justin M. Forbes" <jforbes@fedoraproject.org>

commit e56e18985596617ae426ed5997fb2e737cffb58b upstream.

Commit 6048fdcc5f269 ("lib/crypto: blake2s: include as built-in") took
away a number of prompt texts from other crypto libraries. This makes
values flip from built-in to module when oldconfig runs, and causes
problems when these crypto libs need to be built in for thingslike
BIG_KEYS.

Fixes: 6048fdcc5f269 ("lib/crypto: blake2s: include as built-in")
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: linux-crypto@vger.kernel.org
Signed-off-by: Justin M. Forbes <jforbes@fedoraproject.org>
[Jason: - moved menu into submenu of lib/ instead of root menu
        - fixed chacha sub-dependencies for CONFIG_CRYPTO]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 crypto/Kconfig     |  2 --
 lib/Kconfig        |  2 ++
 lib/crypto/Kconfig | 17 ++++++++++++-----
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 55718de56137..a346b6f74bb3 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1924,5 +1924,3 @@ source "crypto/asymmetric_keys/Kconfig"
 source "certs/Kconfig"
 
 endif	# if CRYPTO
-
-source "lib/crypto/Kconfig"
diff --git a/lib/Kconfig b/lib/Kconfig
index fa4b10322efc..e052f843afed 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -121,6 +121,8 @@ config INDIRECT_IOMEM_FALLBACK
 	  mmio accesses when the IO memory address is not a registered
 	  emulated region.
 
+source "lib/crypto/Kconfig"
+
 config CRC_CCITT
 	tristate "CRC-CCITT functions"
 	help
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 8620f38e117c..e8e525650cf2 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
+menu "Crypto library routines"
+
 config CRYPTO_LIB_AES
 	tristate
 
@@ -31,7 +33,7 @@ config CRYPTO_ARCH_HAVE_LIB_CHACHA
 
 config CRYPTO_LIB_CHACHA_GENERIC
 	tristate
-	select CRYPTO_ALGAPI
+	select XOR_BLOCKS
 	help
 	  This symbol can be depended upon by arch implementations of the
 	  ChaCha library interface that require the generic code as a
@@ -40,7 +42,8 @@ config CRYPTO_LIB_CHACHA_GENERIC
 	  of CRYPTO_LIB_CHACHA.
 
 config CRYPTO_LIB_CHACHA
-	tristate
+	tristate "ChaCha library interface"
+	depends on CRYPTO
 	depends on CRYPTO_ARCH_HAVE_LIB_CHACHA || !CRYPTO_ARCH_HAVE_LIB_CHACHA
 	select CRYPTO_LIB_CHACHA_GENERIC if CRYPTO_ARCH_HAVE_LIB_CHACHA=n
 	help
@@ -65,7 +68,7 @@ config CRYPTO_LIB_CURVE25519_GENERIC
 	  of CRYPTO_LIB_CURVE25519.
 
 config CRYPTO_LIB_CURVE25519
-	tristate
+	tristate "Curve25519 scalar multiplication library"
 	depends on CRYPTO_ARCH_HAVE_LIB_CURVE25519 || !CRYPTO_ARCH_HAVE_LIB_CURVE25519
 	select CRYPTO_LIB_CURVE25519_GENERIC if CRYPTO_ARCH_HAVE_LIB_CURVE25519=n
 	help
@@ -100,7 +103,7 @@ config CRYPTO_LIB_POLY1305_GENERIC
 	  of CRYPTO_LIB_POLY1305.
 
 config CRYPTO_LIB_POLY1305
-	tristate
+	tristate "Poly1305 library interface"
 	depends on CRYPTO_ARCH_HAVE_LIB_POLY1305 || !CRYPTO_ARCH_HAVE_LIB_POLY1305
 	select CRYPTO_LIB_POLY1305_GENERIC if CRYPTO_ARCH_HAVE_LIB_POLY1305=n
 	help
@@ -109,14 +112,18 @@ config CRYPTO_LIB_POLY1305
 	  is available and enabled.
 
 config CRYPTO_LIB_CHACHA20POLY1305
-	tristate
+	tristate "ChaCha20-Poly1305 AEAD support (8-byte nonce library version)"
 	depends on CRYPTO_ARCH_HAVE_LIB_CHACHA || !CRYPTO_ARCH_HAVE_LIB_CHACHA
 	depends on CRYPTO_ARCH_HAVE_LIB_POLY1305 || !CRYPTO_ARCH_HAVE_LIB_POLY1305
+	depends on CRYPTO
 	select CRYPTO_LIB_CHACHA
 	select CRYPTO_LIB_POLY1305
+	select CRYPTO_ALGAPI
 
 config CRYPTO_LIB_SHA256
 	tristate
 
 config CRYPTO_LIB_SM4
 	tristate
+
+endmenu
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH stable 5.15.y 2/5] crypto: drbg - prepare for more fine-grained tracking of seeding state
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 1/5] lib/crypto: add prompts back to crypto libraries Jason A. Donenfeld
@ 2022-06-02 20:23 ` Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 3/5] crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() Jason A. Donenfeld
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

From: Nicolai Stange <nstange@suse.de>

commit ce8ce31b2c5c8b18667784b8c515650c65d57b4e upstream.

There are two different randomness sources the DRBGs are getting seeded
from, namely the jitterentropy source (if enabled) and get_random_bytes().
At initial DRBG seeding time during boot, the latter might not have
collected sufficient entropy for seeding itself yet and thus, the DRBG
implementation schedules a reseed work from a random_ready_callback once
that has happened. This is particularly important for the !->pr DRBG
instances, for which (almost) no further reseeds are getting triggered
during their lifetime.

Because collecting data from the jitterentropy source is a rather expensive
operation, the aforementioned asynchronously scheduled reseed work
restricts itself to get_random_bytes() only. That is, it in some sense
amends the initial DRBG seed derived from jitterentropy output at full
(estimated) entropy with fresh randomness obtained from get_random_bytes()
once that has been seeded with sufficient entropy itself.

With the advent of rng_is_initialized(), there is no real need for doing
the reseed operation from an asynchronously scheduled work anymore and a
subsequent patch will make it synchronous by moving it next to related
logic already present in drbg_generate().

However, for tracking whether a full reseed including the jitterentropy
source is required or a "partial" reseed involving only get_random_bytes()
would be sufficient already, the boolean struct drbg_state's ->seeded
member must become a tristate value.

Prepare for this by introducing the new enum drbg_seed_state and change
struct drbg_state's ->seeded member's type from bool to that type.

For facilitating review, enum drbg_seed_state is made to only contain
two members corresponding to the former ->seeded values of false and true
resp. at this point: DRBG_SEED_STATE_UNSEEDED and DRBG_SEED_STATE_FULL. A
third one for tracking the intermediate state of "seeded from jitterentropy
only" will be introduced with a subsequent patch.

There is no change in behaviour at this point.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Reviewed-by: Stephan Müller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 crypto/drbg.c         | 19 ++++++++++---------
 include/crypto/drbg.h |  7 ++++++-
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 03c9ef768c22..35358119fcfb 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1043,7 +1043,7 @@ static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
 	if (ret)
 		return ret;
 
-	drbg->seeded = true;
+	drbg->seeded = DRBG_SEED_STATE_FULL;
 	/* 10.1.1.2 / 10.1.1.3 step 5 */
 	drbg->reseed_ctr = 1;
 
@@ -1088,14 +1088,14 @@ static void drbg_async_seed(struct work_struct *work)
 	if (ret)
 		goto unlock;
 
-	/* Set seeded to false so that if __drbg_seed fails the
-	 * next generate call will trigger a reseed.
+	/* Reset ->seeded so that if __drbg_seed fails the next
+	 * generate call will trigger a reseed.
 	 */
-	drbg->seeded = false;
+	drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
 
 	__drbg_seed(drbg, &seedlist, true);
 
-	if (drbg->seeded)
+	if (drbg->seeded == DRBG_SEED_STATE_FULL)
 		drbg->reseed_threshold = drbg_max_requests(drbg);
 
 unlock:
@@ -1386,13 +1386,14 @@ static int drbg_generate(struct drbg_state *drbg,
 	 * here. The spec is a bit convoluted here, we make it simpler.
 	 */
 	if (drbg->reseed_threshold < drbg->reseed_ctr)
-		drbg->seeded = false;
+		drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
 
-	if (drbg->pr || !drbg->seeded) {
+	if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) {
 		pr_devel("DRBG: reseeding before generation (prediction "
 			 "resistance: %s, state %s)\n",
 			 drbg->pr ? "true" : "false",
-			 drbg->seeded ? "seeded" : "unseeded");
+			 (drbg->seeded ==  DRBG_SEED_STATE_FULL ?
+			  "seeded" : "unseeded"));
 		/* 9.3.1 steps 7.1 through 7.3 */
 		len = drbg_seed(drbg, addtl, true);
 		if (len)
@@ -1577,7 +1578,7 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
 	if (!drbg->core) {
 		drbg->core = &drbg_cores[coreref];
 		drbg->pr = pr;
-		drbg->seeded = false;
+		drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
 		drbg->reseed_threshold = drbg_max_requests(drbg);
 
 		ret = drbg_alloc_state(drbg);
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 88e4d145f7cd..2db72121d568 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -105,6 +105,11 @@ struct drbg_test_data {
 	struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */
 };
 
+enum drbg_seed_state {
+	DRBG_SEED_STATE_UNSEEDED,
+	DRBG_SEED_STATE_FULL,
+};
+
 struct drbg_state {
 	struct mutex drbg_mutex;	/* lock around DRBG */
 	unsigned char *V;	/* internal state 10.1.1.1 1a) */
@@ -127,7 +132,7 @@ struct drbg_state {
 	struct crypto_wait ctr_wait;		/* CTR mode async wait obj */
 	struct scatterlist sg_in, sg_out;	/* CTR mode SGLs */
 
-	bool seeded;		/* DRBG fully seeded? */
+	enum drbg_seed_state seeded;		/* DRBG fully seeded? */
 	bool pr;		/* Prediction resistance enabled? */
 	bool fips_primed;	/* Continuous test primed? */
 	unsigned char *prev;	/* FIPS 140-2 continuous test value */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH stable 5.15.y 3/5] crypto: drbg - track whether DRBG was seeded with !rng_is_initialized()
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 1/5] lib/crypto: add prompts back to crypto libraries Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 2/5] crypto: drbg - prepare for more fine-grained tracking of seeding state Jason A. Donenfeld
@ 2022-06-02 20:23 ` Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 4/5] crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() Jason A. Donenfeld
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

From: Nicolai Stange <nstange@suse.de>

commit 2bcd25443868aa8863779a6ebc6c9319633025d2 upstream.

Currently, the DRBG implementation schedules asynchronous works from
random_ready_callbacks for reseeding the DRBG instances with output from
get_random_bytes() once the latter has sufficient entropy available.

However, as the get_random_bytes() initialization state can get queried by
means of rng_is_initialized() now, there is no real need for this
asynchronous reseeding logic anymore and it's better to keep things simple
by doing it synchronously when needed instead, i.e. from drbg_generate()
once rng_is_initialized() has flipped to true.

Of course, for this to work, drbg_generate() would need some means by which
it can tell whether or not rng_is_initialized() has flipped to true since
the last seeding from get_random_bytes(). Or equivalently, whether or not
the last seed from get_random_bytes() has happened when
rng_is_initialized() was still evaluating to false.

As it currently stands, enum drbg_seed_state allows for the representation
of two different DRBG seeding states: DRBG_SEED_STATE_UNSEEDED and
DRBG_SEED_STATE_FULL. The former makes drbg_generate() to invoke a full
reseeding operation involving both, the rather expensive jitterentropy as
well as the get_random_bytes() randomness sources. The DRBG_SEED_STATE_FULL
state on the other hand implies that no reseeding at all is required for a
!->pr DRBG variant.

Introduce the new DRBG_SEED_STATE_PARTIAL state to enum drbg_seed_state for
representing the condition that a DRBG was being seeded when
rng_is_initialized() had still been false. In particular, this new state
implies that
- the given DRBG instance has been fully seeded from the jitterentropy
  source (if enabled)
- and drbg_generate() is supposed to reseed from get_random_bytes()
  *only* once rng_is_initialized() turns to true.

Up to now, the __drbg_seed() helper used to set the given DRBG instance's
->seeded state to constant DRBG_SEED_STATE_FULL. Introduce a new argument
allowing for the specification of the to be written ->seeded value instead.
Make the first of its two callers, drbg_seed(), determine the appropriate
value based on rng_is_initialized(). The remaining caller,
drbg_async_seed(), is known to get invoked only once rng_is_initialized()
is true, hence let it pass constant DRBG_SEED_STATE_FULL for the new
argument to __drbg_seed().

There is no change in behaviour, except for that the pr_devel() in
drbg_generate() would now report "unseeded" for ->pr DRBG instances which
had last been seeded when rng_is_initialized() was still evaluating to
false.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Reviewed-by: Stephan Müller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 crypto/drbg.c         | 12 ++++++++----
 include/crypto/drbg.h |  1 +
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 35358119fcfb..bc5a533c0960 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1036,14 +1036,14 @@ static const struct drbg_state_ops drbg_hash_ops = {
  ******************************************************************/
 
 static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
-			      int reseed)
+			      int reseed, enum drbg_seed_state new_seed_state)
 {
 	int ret = drbg->d_ops->update(drbg, seed, reseed);
 
 	if (ret)
 		return ret;
 
-	drbg->seeded = DRBG_SEED_STATE_FULL;
+	drbg->seeded = new_seed_state;
 	/* 10.1.1.2 / 10.1.1.3 step 5 */
 	drbg->reseed_ctr = 1;
 
@@ -1093,7 +1093,7 @@ static void drbg_async_seed(struct work_struct *work)
 	 */
 	drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
 
-	__drbg_seed(drbg, &seedlist, true);
+	__drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
 
 	if (drbg->seeded == DRBG_SEED_STATE_FULL)
 		drbg->reseed_threshold = drbg_max_requests(drbg);
@@ -1123,6 +1123,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
 	unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
 	struct drbg_string data1;
 	LIST_HEAD(seedlist);
+	enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
 
 	/* 9.1 / 9.2 / 9.3.1 step 3 */
 	if (pers && pers->len > (drbg_max_addtl(drbg))) {
@@ -1150,6 +1151,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
 		BUG_ON((entropylen * 2) > sizeof(entropy));
 
 		/* Get seed from in-kernel /dev/urandom */
+		if (!rng_is_initialized())
+			new_seed_state = DRBG_SEED_STATE_PARTIAL;
+
 		ret = drbg_get_random_bytes(drbg, entropy, entropylen);
 		if (ret)
 			goto out;
@@ -1206,7 +1210,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
 		memset(drbg->C, 0, drbg_statelen(drbg));
 	}
 
-	ret = __drbg_seed(drbg, &seedlist, reseed);
+	ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
 
 out:
 	memzero_explicit(entropy, entropylen * 2);
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 2db72121d568..01caab5e65de 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -107,6 +107,7 @@ struct drbg_test_data {
 
 enum drbg_seed_state {
 	DRBG_SEED_STATE_UNSEEDED,
+	DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */
 	DRBG_SEED_STATE_FULL,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH stable 5.15.y 4/5] crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed()
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
                   ` (2 preceding siblings ...)
  2022-06-02 20:23 ` [PATCH stable 5.15.y 3/5] crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() Jason A. Donenfeld
@ 2022-06-02 20:23 ` Jason A. Donenfeld
  2022-06-02 20:23 ` [PATCH stable 5.15.y 5/5] crypto: drbg - make reseeding from get_random_bytes() synchronous Jason A. Donenfeld
  2022-06-03 14:48 ` [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Greg KH
  5 siblings, 0 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

From: Nicolai Stange <nstange@suse.de>

commit 262d83a4290c331cd4f617a457408bdb82fbb738 upstream.

Since commit 42ea507fae1a ("crypto: drbg - reseed often if seedsource is
degraded"), the maximum seed lifetime represented by ->reseed_threshold
gets temporarily lowered if the get_random_bytes() source cannot provide
sufficient entropy yet, as is common during boot, and restored back to
the original value again once that has changed.

More specifically, if the add_random_ready_callback() invoked from
drbg_prepare_hrng() in the course of DRBG instantiation does not return
-EALREADY, that is, if get_random_bytes() has not been fully initialized
at this point yet, drbg_prepare_hrng() will lower ->reseed_threshold
to a value of 50. The drbg_async_seed() scheduled from said
random_ready_callback will eventually restore the original value.

A future patch will replace the random_ready_callback based notification
mechanism and thus, there will be no add_random_ready_callback() return
value anymore which could get compared to -EALREADY.

However, there's __drbg_seed() which gets invoked in the course of both,
the DRBG instantiation as well as the eventual reseeding from
get_random_bytes() in aforementioned drbg_async_seed(), if any. Moreover,
it knows about the get_random_bytes() initialization state by the time the
seed data had been obtained from it: the new_seed_state argument introduced
with the previous patch would get set to DRBG_SEED_STATE_PARTIAL in case
get_random_bytes() had not been fully initialized yet and to
DRBG_SEED_STATE_FULL otherwise. Thus, __drbg_seed() provides a convenient
alternative for managing that ->reseed_threshold lowering and restoring at
a central place.

Move all ->reseed_threshold adjustment code from drbg_prepare_hrng() and
drbg_async_seed() respectively to __drbg_seed(). Make __drbg_seed()
lower the ->reseed_threshold to 50 in case its new_seed_state argument
equals DRBG_SEED_STATE_PARTIAL and let it restore the original value
otherwise.

There is no change in behaviour.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Reviewed-by: Stephan Müller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 crypto/drbg.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index bc5a533c0960..84b489fd4251 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1047,6 +1047,27 @@ static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
 	/* 10.1.1.2 / 10.1.1.3 step 5 */
 	drbg->reseed_ctr = 1;
 
+	switch (drbg->seeded) {
+	case DRBG_SEED_STATE_UNSEEDED:
+		/* Impossible, but handle it to silence compiler warnings. */
+		fallthrough;
+	case DRBG_SEED_STATE_PARTIAL:
+		/*
+		 * Require frequent reseeds until the seed source is
+		 * fully initialized.
+		 */
+		drbg->reseed_threshold = 50;
+		break;
+
+	case DRBG_SEED_STATE_FULL:
+		/*
+		 * Seed source has become fully initialized, frequent
+		 * reseeds no longer required.
+		 */
+		drbg->reseed_threshold = drbg_max_requests(drbg);
+		break;
+	}
+
 	return ret;
 }
 
@@ -1095,9 +1116,6 @@ static void drbg_async_seed(struct work_struct *work)
 
 	__drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
 
-	if (drbg->seeded == DRBG_SEED_STATE_FULL)
-		drbg->reseed_threshold = drbg_max_requests(drbg);
-
 unlock:
 	mutex_unlock(&drbg->drbg_mutex);
 
@@ -1533,12 +1551,6 @@ static int drbg_prepare_hrng(struct drbg_state *drbg)
 		return err;
 	}
 
-	/*
-	 * Require frequent reseeds until the seed source is fully
-	 * initialized.
-	 */
-	drbg->reseed_threshold = 50;
-
 	return err;
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH stable 5.15.y 5/5] crypto: drbg - make reseeding from get_random_bytes() synchronous
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
                   ` (3 preceding siblings ...)
  2022-06-02 20:23 ` [PATCH stable 5.15.y 4/5] crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() Jason A. Donenfeld
@ 2022-06-02 20:23 ` Jason A. Donenfeld
  2022-06-03 14:48 ` [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Greg KH
  5 siblings, 0 replies; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-02 20:23 UTC (permalink / raw)
  To: stable, gregkh

From: Nicolai Stange <nstange@suse.de>

commit 074bcd4000e0d812bc253f86fedc40f81ed59ccc upstream.

get_random_bytes() usually hasn't full entropy available by the time DRBG
instances are first getting seeded from it during boot. Thus, the DRBG
implementation registers random_ready_callbacks which would in turn
schedule some work for reseeding the DRBGs once get_random_bytes() has
sufficient entropy available.

For reference, the relevant history around handling DRBG (re)seeding in
the context of a not yet fully seeded get_random_bytes() is:

  commit 16b369a91d0d ("random: Blocking API for accessing
                        nonblocking_pool")
  commit 4c7879907edd ("crypto: drbg - add async seeding operation")

  commit 205a525c3342 ("random: Add callback API for random pool
                        readiness")
  commit 57225e679788 ("crypto: drbg - Use callback API for random
                        readiness")
  commit c2719503f5e1 ("random: Remove kernel blocking API")

However, some time later, the initialization state of get_random_bytes()
has been made queryable via rng_is_initialized() introduced with commit
9a47249d444d ("random: Make crng state queryable"). This primitive now
allows for streamlining the DRBG reseeding from get_random_bytes() by
replacing that aforementioned asynchronous work scheduling from
random_ready_callbacks with some simpler, synchronous code in
drbg_generate() next to the related logic already present therein. Apart
from improving overall code readability, this change will also enable DRBG
users to rely on wait_for_random_bytes() for ensuring that the initial
seeding has completed, if desired.

The previous patches already laid the grounds by making drbg_seed() to
record at each DRBG instance whether it was being seeded at a time when
rng_is_initialized() still had been false as indicated by
->seeded == DRBG_SEED_STATE_PARTIAL.

All that remains to be done now is to make drbg_generate() check for this
condition, determine whether rng_is_initialized() has flipped to true in
the meanwhile and invoke a reseed from get_random_bytes() if so.

Make this move:
- rename the former drbg_async_seed() work handler, i.e. the one in charge
  of reseeding a DRBG instance from get_random_bytes(), to
  "drbg_seed_from_random()",
- change its signature as appropriate, i.e. make it take a struct
  drbg_state rather than a work_struct and change its return type from
  "void" to "int" in order to allow for passing error information from
  e.g. its __drbg_seed() invocation onwards to callers,
- make drbg_generate() invoke this drbg_seed_from_random() once it
  encounters a DRBG instance with ->seeded == DRBG_SEED_STATE_PARTIAL by
  the time rng_is_initialized() has flipped to true and
- prune everything related to the former, random_ready_callback based
  mechanism.

As drbg_seed_from_random() is now getting invoked from drbg_generate() with
the ->drbg_mutex being held, it must not attempt to recursively grab it
once again. Remove the corresponding mutex operations from what is now
drbg_seed_from_random(). Furthermore, as drbg_seed_from_random() can now
report errors directly to its caller, there's no need for it to temporarily
switch the DRBG's ->seeded state to DRBG_SEED_STATE_UNSEEDED so that a
failure of the subsequently invoked __drbg_seed() will get signaled to
drbg_generate(). Don't do it then.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[Jason: for stable, undid the modifications for the backport of 5acd3548.]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 crypto/drbg.c         | 61 ++++++++-----------------------------------
 drivers/char/random.c |  2 --
 include/crypto/drbg.h |  2 --
 3 files changed, 11 insertions(+), 54 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 84b489fd4251..761104e93d44 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1087,12 +1087,10 @@ static inline int drbg_get_random_bytes(struct drbg_state *drbg,
 	return 0;
 }
 
-static void drbg_async_seed(struct work_struct *work)
+static int drbg_seed_from_random(struct drbg_state *drbg)
 {
 	struct drbg_string data;
 	LIST_HEAD(seedlist);
-	struct drbg_state *drbg = container_of(work, struct drbg_state,
-					       seed_work);
 	unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
 	unsigned char entropy[32];
 	int ret;
@@ -1103,23 +1101,15 @@ static void drbg_async_seed(struct work_struct *work)
 	drbg_string_fill(&data, entropy, entropylen);
 	list_add_tail(&data.list, &seedlist);
 
-	mutex_lock(&drbg->drbg_mutex);
-
 	ret = drbg_get_random_bytes(drbg, entropy, entropylen);
 	if (ret)
-		goto unlock;
-
-	/* Reset ->seeded so that if __drbg_seed fails the next
-	 * generate call will trigger a reseed.
-	 */
-	drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
-
-	__drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
+		goto out;
 
-unlock:
-	mutex_unlock(&drbg->drbg_mutex);
+	ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
 
+out:
 	memzero_explicit(entropy, entropylen);
+	return ret;
 }
 
 /*
@@ -1422,6 +1412,11 @@ static int drbg_generate(struct drbg_state *drbg,
 			goto err;
 		/* 9.3.1 step 7.4 */
 		addtl = NULL;
+	} else if (rng_is_initialized() &&
+		   drbg->seeded == DRBG_SEED_STATE_PARTIAL) {
+		len = drbg_seed_from_random(drbg);
+		if (len)
+			goto err;
 	}
 
 	if (addtl && 0 < addtl->len)
@@ -1514,44 +1509,15 @@ static int drbg_generate_long(struct drbg_state *drbg,
 	return 0;
 }
 
-static int drbg_schedule_async_seed(struct notifier_block *nb, unsigned long action, void *data)
-{
-	struct drbg_state *drbg = container_of(nb, struct drbg_state,
-					       random_ready);
-
-	schedule_work(&drbg->seed_work);
-	return 0;
-}
-
 static int drbg_prepare_hrng(struct drbg_state *drbg)
 {
-	int err;
-
 	/* We do not need an HRNG in test mode. */
 	if (list_empty(&drbg->test_data.list))
 		return 0;
 
 	drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
 
-	INIT_WORK(&drbg->seed_work, drbg_async_seed);
-
-	drbg->random_ready.notifier_call = drbg_schedule_async_seed;
-	err = register_random_ready_notifier(&drbg->random_ready);
-
-	switch (err) {
-	case 0:
-		break;
-
-	case -EALREADY:
-		err = 0;
-		fallthrough;
-
-	default:
-		drbg->random_ready.notifier_call = NULL;
-		return err;
-	}
-
-	return err;
+	return 0;
 }
 
 /*
@@ -1645,11 +1611,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
  */
 static int drbg_uninstantiate(struct drbg_state *drbg)
 {
-	if (drbg->random_ready.notifier_call) {
-		unregister_random_ready_notifier(&drbg->random_ready);
-		cancel_work_sync(&drbg->seed_work);
-	}
-
 	if (!IS_ERR_OR_NULL(drbg->jent))
 		crypto_free_rng(drbg->jent);
 	drbg->jent = NULL;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index ca17a658c214..e2f1fce8dc97 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -163,7 +163,6 @@ int __cold register_random_ready_notifier(struct notifier_block *nb)
 	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
 	return ret;
 }
-EXPORT_SYMBOL(register_random_ready_notifier);
 
 /*
  * Delete a previously registered readiness callback function.
@@ -178,7 +177,6 @@ int __cold unregister_random_ready_notifier(struct notifier_block *nb)
 	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
 	return ret;
 }
-EXPORT_SYMBOL(unregister_random_ready_notifier);
 
 static void __cold process_random_ready_list(void)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 01caab5e65de..a6c3b8e7deb6 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -137,12 +137,10 @@ struct drbg_state {
 	bool pr;		/* Prediction resistance enabled? */
 	bool fips_primed;	/* Continuous test primed? */
 	unsigned char *prev;	/* FIPS 140-2 continuous test value */
-	struct work_struct seed_work;	/* asynchronous seeding support */
 	struct crypto_rng *jent;
 	const struct drbg_state_ops *d_ops;
 	const struct drbg_core *core;
 	struct drbg_string test_data;
-	struct notifier_block random_ready;
 };
 
 static inline __u8 drbg_statelen(struct drbg_state *drbg)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH stable 5.15.y 0/5] missing random.c-related stable patches
  2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
                   ` (4 preceding siblings ...)
  2022-06-02 20:23 ` [PATCH stable 5.15.y 5/5] crypto: drbg - make reseeding from get_random_bytes() synchronous Jason A. Donenfeld
@ 2022-06-03 14:48 ` Greg KH
  2022-06-03 15:14   ` Jason A. Donenfeld
  5 siblings, 1 reply; 9+ messages in thread
From: Greg KH @ 2022-06-03 14:48 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: stable

On Thu, Jun 02, 2022 at 10:23:22PM +0200, Jason A. Donenfeld wrote:
> Hi Greg,
> 
> I forgot two things when doing the 5.15 backport. The first is a patch
> from Justin fixing a bug in some of the lib/crypto Kconfig changes,
> which Pablo (CC'd) pointed out was missed. The second is that the
> backport of 5acd35487dc9 ("random: replace custom notifier chain with
> standard one") isn't quite right without Nicolai's patches there too,
> since the drbg module is removable.
> 
> I'll continue to monitor all the channels I possibly can for chatter
> about problems, but so far this is all I've run into.

All now queued up, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH stable 5.15.y 0/5] missing random.c-related stable patches
  2022-06-03 14:48 ` [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Greg KH
@ 2022-06-03 15:14   ` Jason A. Donenfeld
  2022-06-03 15:23     ` Greg KH
  0 siblings, 1 reply; 9+ messages in thread
From: Jason A. Donenfeld @ 2022-06-03 15:14 UTC (permalink / raw)
  To: Greg KH; +Cc: stable

On Fri, Jun 03, 2022 at 04:48:13PM +0200, Greg KH wrote:
> On Thu, Jun 02, 2022 at 10:23:22PM +0200, Jason A. Donenfeld wrote:
> > Hi Greg,
> > 
> > I forgot two things when doing the 5.15 backport. The first is a patch
> > from Justin fixing a bug in some of the lib/crypto Kconfig changes,
> > which Pablo (CC'd) pointed out was missed. The second is that the
> > backport of 5acd35487dc9 ("random: replace custom notifier chain with
> > standard one") isn't quite right without Nicolai's patches there too,
> > since the drbg module is removable.
> > 
> > I'll continue to monitor all the channels I possibly can for chatter
> > about problems, but so far this is all I've run into.
> 
> All now queued up, thanks.

Thanks. Note that the 5.10 patchset I posted is identical to this one,
except I made sure patch 1/5 applies. Just cherry picking the 5.15 has a
trivial conflict to fix up.

Jason

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH stable 5.15.y 0/5] missing random.c-related stable patches
  2022-06-03 15:14   ` Jason A. Donenfeld
@ 2022-06-03 15:23     ` Greg KH
  0 siblings, 0 replies; 9+ messages in thread
From: Greg KH @ 2022-06-03 15:23 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: stable

On Fri, Jun 03, 2022 at 05:14:48PM +0200, Jason A. Donenfeld wrote:
> On Fri, Jun 03, 2022 at 04:48:13PM +0200, Greg KH wrote:
> > On Thu, Jun 02, 2022 at 10:23:22PM +0200, Jason A. Donenfeld wrote:
> > > Hi Greg,
> > > 
> > > I forgot two things when doing the 5.15 backport. The first is a patch
> > > from Justin fixing a bug in some of the lib/crypto Kconfig changes,
> > > which Pablo (CC'd) pointed out was missed. The second is that the
> > > backport of 5acd35487dc9 ("random: replace custom notifier chain with
> > > standard one") isn't quite right without Nicolai's patches there too,
> > > since the drbg module is removable.
> > > 
> > > I'll continue to monitor all the channels I possibly can for chatter
> > > about problems, but so far this is all I've run into.
> > 
> > All now queued up, thanks.
> 
> Thanks. Note that the 5.10 patchset I posted is identical to this one,
> except I made sure patch 1/5 applies. Just cherry picking the 5.15 has a
> trivial conflict to fix up.

I took the 5.10 series as-you-sent-them so all should be good.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-06-03 15:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 20:23 [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Jason A. Donenfeld
2022-06-02 20:23 ` [PATCH stable 5.15.y 1/5] lib/crypto: add prompts back to crypto libraries Jason A. Donenfeld
2022-06-02 20:23 ` [PATCH stable 5.15.y 2/5] crypto: drbg - prepare for more fine-grained tracking of seeding state Jason A. Donenfeld
2022-06-02 20:23 ` [PATCH stable 5.15.y 3/5] crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() Jason A. Donenfeld
2022-06-02 20:23 ` [PATCH stable 5.15.y 4/5] crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() Jason A. Donenfeld
2022-06-02 20:23 ` [PATCH stable 5.15.y 5/5] crypto: drbg - make reseeding from get_random_bytes() synchronous Jason A. Donenfeld
2022-06-03 14:48 ` [PATCH stable 5.15.y 0/5] missing random.c-related stable patches Greg KH
2022-06-03 15:14   ` Jason A. Donenfeld
2022-06-03 15:23     ` Greg KH

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.