* [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.