public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Nicolai Stange <nstange@suse.de>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	"Jason A. Donenfeld" <Jason@zx2c4.com>
Subject: [PATCH 5.15 23/66] crypto: drbg - make reseeding from get_random_bytes() synchronous
Date: Fri,  3 Jun 2022 19:43:03 +0200	[thread overview]
Message-ID: <20220603173821.330116342@linuxfoundation.org> (raw)
In-Reply-To: <20220603173820.663747061@linuxfoundation.org>

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 crypto/drbg.c         |   61 +++++++++-----------------------------------------
 drivers/char/random.c |    2 -
 include/crypto/drbg.h |    2 -
 3 files changed, 11 insertions(+), 54 deletions(-)

--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1087,12 +1087,10 @@ static inline int drbg_get_random_bytes(
 	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_
 	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;
+		goto out;
 
-	__drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
-
-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_sta
 			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 drb
 	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 @@ free_everything:
  */
 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;
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -163,7 +163,6 @@ int __cold register_random_ready_notifie
 	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_notif
 	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
 	return ret;
 }
-EXPORT_SYMBOL(unregister_random_ready_notifier);
 
 static void __cold process_random_ready_list(void)
 {
--- 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)



  parent reply	other threads:[~2022-06-03 17:55 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-03 17:42 [PATCH 5.15 00/66] 5.15.45-rc1 review Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 01/66] ALSA: usb-audio: Dont get sample rate for MCT Trigger 5 USB-to-HDMI Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 02/66] pinctrl: sunxi: fix f1c100s uart2 function Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 03/66] KVM: arm64: Dont hypercall before EL2 init Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 04/66] percpu_ref_init(): clean ->percpu_count_ref on failure Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 05/66] net: af_key: check encryption module availability consistency Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 06/66] nfc: pn533: Fix buggy cleanup order Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 07/66] net: ftgmac100: Disable hardware checksum on AST2600 Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 08/66] i2c: ismt: Provide a DMA buffer for Interrupt Cause Logging Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 09/66] drivers: i2c: thunderx: Allow driver to work with ACPI defined TWSI controllers Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 10/66] netfilter: nf_tables: disallow non-stateful expression in sets earlier Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 11/66] i2c: ismt: prevent memory corruption in ismt_access() Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 12/66] assoc_array: Fix BUG_ON during garbage collect Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 13/66] pipe: make poll_usage boolean and annotate its access Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 14/66] pipe: Fix missing lock in pipe_resize_ring() Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 15/66] net: ipa: compute proper aggregation limit Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 16/66] drm/i915: Fix -Wstringop-overflow warning in call to intel_read_wm_latency() Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 17/66] exfat: check if cluster num is valid Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 18/66] exfat: fix referencing wrong parent directory information after renaming Greg Kroah-Hartman
2022-06-03 17:42 ` [PATCH 5.15 19/66] lib/crypto: add prompts back to crypto libraries Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 20/66] crypto: drbg - prepare for more fine-grained tracking of seeding state Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 21/66] crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 22/66] crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() Greg Kroah-Hartman
2022-06-03 17:43 ` Greg Kroah-Hartman [this message]
2022-06-03 17:43 ` [PATCH 5.15 24/66] netfilter: nf_tables: sanitize nft_set_desc_concat_parse() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 25/66] netfilter: nf_tables: hold mutex on netns pre_exit path Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 26/66] netfilter: nf_tables: double hook unregistration in netns path Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 27/66] netfilter: conntrack: re-fetch conntrack after insertion Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 28/66] KVM: PPC: Book3S HV: fix incorrect NULL check on list iterator Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 29/66] x86/kvm: Alloc dummy async #PF token outside of raw spinlock Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 30/66] x86, kvm: use correct GFP flags for preemption disabled Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 31/66] KVM: x86: avoid calling x86 emulator without a decoded instruction Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 32/66] KVM: x86: Drop WARNs that assert a triple fault never "escapes" from L2 Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 33/66] KVM: SVM: Use kzalloc for sev ioctl interfaces to prevent kernel data leak Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 34/66] crypto: caam - fix i.MX6SX entropy delay value Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 35/66] crypto: ecrdsa - Fix incorrect use of vli_cmp Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 36/66] zsmalloc: fix races between asynchronous zspage free and page migration Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 37/66] ALSA: usb-audio: Workaround for clock setup on TEAC devices Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 38/66] ALSA: usb-audio: Add missing ep_idx in fixed EP quirks Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 39/66] ALSA: usb-audio: Configure sync endpoints before data Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 40/66] Bluetooth: hci_qca: Use del_timer_sync() before freeing Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 41/66] ARM: dts: s5pv210: Correct interrupt name for bluetooth in Aries Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 42/66] dm integrity: fix error code in dm_integrity_ctr() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 43/66] dm crypt: make printing of the key constant-time Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 44/66] dm stats: add cond_resched when looping over entries Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 45/66] dm verity: set DM_TARGET_IMMUTABLE feature flag Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 46/66] raid5: introduce MD_BROKEN Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 47/66] fs/ntfs3: validate BOOT sectors_per_clusters Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 48/66] HID: multitouch: Add support for Google Whiskers Touchpad Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 49/66] HID: multitouch: add quirks to enable Lenovo X12 trackpoint Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 50/66] x86/sgx: Disconnect backing page references from dirty status Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 51/66] x86/sgx: Mark PCMD page as dirty when modifying contents Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 52/66] x86/sgx: Obtain backing storage page with enclave mutex held Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 53/66] x86/sgx: Fix race between reclaimer and page fault handler Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 54/66] x86/sgx: Ensure no data in PCMD page after truncate Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 55/66] media: i2c: imx412: Fix reset GPIO polarity Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 56/66] media: i2c: imx412: Fix power_off ordering Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 57/66] tpm: Fix buffer access in tpm2_get_tpm_pt() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 58/66] tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 59/66] docs: submitting-patches: Fix crossref to The canonical patch format Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 60/66] NFS: Memory allocation failures are not server fatal errors Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 61/66] NFSD: Fix possible sleep during nfsd4_release_lockowner() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 62/66] bpf: Fix potential array overflow in bpf_trampoline_get_progs() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 63/66] bpf: Enlarge offset check value to INT_MAX in bpf_skb_{load,store}_bytes Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 64/66] bpf: Fix excessive memory allocation in stack_map_alloc() Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 65/66] bpf: Reject writes for PTR_TO_MAP_KEY in check_helper_mem_access Greg Kroah-Hartman
2022-06-03 17:43 ` [PATCH 5.15 66/66] bpf: Check PTR_TO_MEM | MEM_RDONLY " Greg Kroah-Hartman
2022-06-04  0:34 ` [PATCH 5.15 00/66] 5.15.45-rc1 review Fox Chen
2022-06-04 12:37 ` Sudip Mukherjee
2022-06-04 17:11 ` Naresh Kamboju
2022-06-04 21:19 ` Guenter Roeck
2022-06-05  3:37 ` Bagas Sanjaya
2022-06-05  4:15 ` Ron Economos

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=20220603173821.330116342@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=Jason@zx2c4.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nstange@suse.de \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox