All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: linux-crypto@vger.kernel.org, Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Stephan Müller" <smueller@chronox.de>,
	"Eric Biggers" <ebiggers@kernel.org>
Subject: [PATCH 09/14] crypto: stdrng - Reimplement "stdrng" using direct DRBG calls
Date: Sun, 18 Oct 2026 13:46:13 -0700	[thread overview]
Message-ID: <20261018204618.104876-10-ebiggers@kernel.org> (raw)
In-Reply-To: <20261018204618.104876-1-ebiggers@kernel.org>

When fips=1, the so-called "stdrng" is always the NIST SP800-90A DRBG.
Simplify the code by making __crypto_stdrng_get_bytes() call into the
DRBG directly instead of going through the unnecessary crypto_rng API.

This required moving the shared DRBG instance (and the function to
delete it) from rng.c to drbg.c.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 crypto/Kconfig                |  1 -
 crypto/crypto_user.c          |  2 +-
 crypto/drbg.c                 | 66 ++++++++++++++++++++++++++
 crypto/rng.c                  | 88 -----------------------------------
 include/crypto/internal/rng.h |  9 ----
 include/crypto/rng.h          | 14 ++++--
 6 files changed, 78 insertions(+), 102 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 5b0806432694f..c41c2f3475d0b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -158,7 +158,6 @@ config CRYPTO_USER
 	tristate "Userspace cryptographic algorithm configuration"
 	depends on NET
 	select CRYPTO_MANAGER
-	select CRYPTO_RNG
 	help
 	  Userspace configuration for cryptographic instantiations such as
 	  cbc(aes).
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index d3ccb507153b2..08e2b4fb9bf73 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -16,9 +16,9 @@
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <crypto/internal/skcipher.h>
-#include <crypto/internal/rng.h>
 #include <crypto/akcipher.h>
 #include <crypto/kpp.h>
+#include <crypto/rng.h>
 
 #include "internal.h"
 
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 9c99b2d510e0a..0f36aa45bfaca 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -638,6 +638,67 @@ void crypto_drbg_free(struct drbg_state *drbg)
 }
 EXPORT_SYMBOL_NS_GPL(crypto_drbg_free, "CRYPTO_INTERNAL");
 
+#ifdef CONFIG_CRYPTO_FIPS
+static DEFINE_MUTEX(crypto_default_rng_lock);
+static struct drbg_state *crypto_default_rng;
+static int crypto_default_rng_refcnt;
+
+static int crypto_get_default_rng(void)
+{
+	struct drbg_state *drbg;
+	int err;
+
+	guard(mutex)(&crypto_default_rng_lock);
+	if (!crypto_default_rng) {
+		drbg = crypto_drbg_alloc();
+		if (IS_ERR(drbg))
+			return PTR_ERR(drbg);
+
+		err = crypto_drbg_seed(drbg, NULL, 0);
+		if (err) {
+			crypto_drbg_free(drbg);
+			return err;
+		}
+		crypto_default_rng = drbg;
+	}
+
+	crypto_default_rng_refcnt++;
+	return 0;
+}
+
+static void crypto_put_default_rng(void)
+{
+	guard(mutex)(&crypto_default_rng_lock);
+	crypto_default_rng_refcnt--;
+}
+
+int __crypto_stdrng_get_bytes(void *buf, unsigned int len)
+{
+	int err;
+
+	err = crypto_get_default_rng();
+	if (err)
+		return err;
+
+	err = crypto_drbg_get_bytes(crypto_default_rng, buf, len, NULL, 0);
+	crypto_put_default_rng();
+	return err;
+}
+EXPORT_SYMBOL_GPL(__crypto_stdrng_get_bytes);
+
+int crypto_del_default_rng(void)
+{
+	guard(mutex)(&crypto_default_rng_lock);
+	if (crypto_default_rng_refcnt)
+		return -EBUSY;
+
+	crypto_drbg_free(crypto_default_rng);
+	crypto_default_rng = NULL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_del_default_rng);
+#endif /* CONFIG_CRYPTO_FIPS */
+
 /*
  * Tests as defined in 11.3.2 in addition to the cipher tests: testing
  * of the error handling.
@@ -812,6 +873,11 @@ static int __init drbg_init(void)
 static void __exit drbg_exit(void)
 {
 	crypto_unregister_rng(&drbg_alg);
+
+	/*
+	 * Note there's no need to call crypto_del_default_rng() from here, as
+	 * it can exist only when this file is built-in.
+	 */
 }
 
 module_init(drbg_init);
diff --git a/crypto/rng.c b/crypto/rng.c
index 828b0d8074738..be4873bec679b 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -23,10 +23,6 @@
 
 #include "internal.h"
 
-static DEFINE_MUTEX(crypto_default_rng_lock);
-static struct crypto_rng *crypto_default_rng;
-static int crypto_default_rng_refcnt;
-
 int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
 {
 	u8 *buf = NULL;
@@ -103,79 +99,6 @@ struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask)
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_rng);
 
-static int crypto_get_default_rng(void)
-{
-	struct crypto_rng *rng;
-	int err;
-
-	mutex_lock(&crypto_default_rng_lock);
-	if (!crypto_default_rng) {
-		rng = crypto_alloc_rng("stdrng", 0, 0);
-		err = PTR_ERR(rng);
-		if (IS_ERR(rng))
-			goto unlock;
-
-		err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
-		if (err) {
-			crypto_free_rng(rng);
-			goto unlock;
-		}
-
-		crypto_default_rng = rng;
-	}
-
-	crypto_default_rng_refcnt++;
-	err = 0;
-
-unlock:
-	mutex_unlock(&crypto_default_rng_lock);
-
-	return err;
-}
-
-static void crypto_put_default_rng(void)
-{
-	mutex_lock(&crypto_default_rng_lock);
-	crypto_default_rng_refcnt--;
-	mutex_unlock(&crypto_default_rng_lock);
-}
-
-int __crypto_stdrng_get_bytes(void *buf, unsigned int len)
-{
-	int err;
-
-	err = crypto_get_default_rng();
-	if (err)
-		return err;
-
-	err = crypto_rng_get_bytes(crypto_default_rng, buf, len);
-	crypto_put_default_rng();
-	return err;
-}
-EXPORT_SYMBOL_GPL(__crypto_stdrng_get_bytes);
-
-#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
-int crypto_del_default_rng(void)
-{
-	int err = -EBUSY;
-
-	mutex_lock(&crypto_default_rng_lock);
-	if (crypto_default_rng_refcnt)
-		goto out;
-
-	crypto_free_rng(crypto_default_rng);
-	crypto_default_rng = NULL;
-
-	err = 0;
-
-out:
-	mutex_unlock(&crypto_default_rng_lock);
-
-	return err;
-}
-EXPORT_SYMBOL_GPL(crypto_del_default_rng);
-#endif
-
 static void rng_default_set_ent(struct crypto_rng *tfm, const u8 *data,
 				unsigned int len)
 {
@@ -230,16 +153,5 @@ void crypto_unregister_rngs(struct rng_alg *algs, int count)
 }
 EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
 
-static void __exit rng_exit(void)
-{
-	int err;
-
-	err = crypto_del_default_rng();
-	if (err)
-		pr_err("Failed delete default RNG: %d\n", err);
-}
-
-module_exit(rng_exit);
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Random Number Generator");
diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h
index e0711b6a597fc..8c9f560d6449c 100644
--- a/include/crypto/internal/rng.h
+++ b/include/crypto/internal/rng.h
@@ -17,15 +17,6 @@ void crypto_unregister_rng(struct rng_alg *alg);
 int crypto_register_rngs(struct rng_alg *algs, int count);
 void crypto_unregister_rngs(struct rng_alg *algs, int count);
 
-#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
-int crypto_del_default_rng(void);
-#else
-static inline int crypto_del_default_rng(void)
-{
-	return 0;
-}
-#endif
-
 static inline void *crypto_rng_ctx(struct crypto_rng *tfm)
 {
 	return crypto_tfm_ctx(&tfm->base);
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
index 07f494b2c8817..463bbdce11c2c 100644
--- a/include/crypto/rng.h
+++ b/include/crypto/rng.h
@@ -66,9 +66,8 @@ int __crypto_stdrng_get_bytes(void *buf, unsigned int len);
  * @buf: output buffer holding the random numbers
  * @len: length of the output buffer
  *
- * This function fills the caller-allocated buffer with random numbers using the
- * normal Linux RNG if fips_enabled=0, or the highest-priority "stdrng"
- * algorithm in the crypto_rng subsystem if fips_enabled=1.
+ * This function fills the given buffer with random numbers using the normal
+ * Linux RNG if fips_enabled=0, or a NIST SP800-90A DRBG if fips_enabled=1.
  *
  * Context: May sleep
  * Return: 0 function was successful; < 0 if an error occurred
@@ -81,6 +80,15 @@ static inline int crypto_stdrng_get_bytes(void *buf, unsigned int len)
 	return get_random_bytes_wait(buf, len);
 }
 
+#ifdef CONFIG_CRYPTO_FIPS
+int crypto_del_default_rng(void);
+#else
+static inline int crypto_del_default_rng(void)
+{
+	return 0;
+}
+#endif
+
 /**
  * DOC: Random number generator API
  *
-- 
2.56.0


  parent reply	other threads:[~2026-10-18 20:49 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18 20:46 [PATCH 00/14] crypto: Remove the unnecessary crypto_rng API Eric Biggers
2026-10-18 20:46 ` [PATCH 01/14] crypto: drbg - Don't use uninitialized stack data Eric Biggers
2026-10-18 20:46 ` [PATCH 02/14] crypto: rng - Remove unnecessary inclusions of internal/rng.h Eric Biggers
2026-10-18 20:46 ` [PATCH 03/14] crypto: jitterentropy - Move health check to first use Eric Biggers
2026-10-18 20:46 ` [PATCH 04/14] crypto: jitterentropy - Add library API Eric Biggers
2026-10-18 20:46 ` [PATCH 05/14] crypto: drbg - Use jitterentropy " Eric Biggers
2026-10-18 20:46 ` [PATCH 06/14] crypto: drbg - Add " Eric Biggers
2026-10-18 20:46 ` [PATCH 07/14] crypto: drbg - Add self-test for " Eric Biggers
2026-10-18 20:46 ` [PATCH 08/14] crypto: algif_rng - Use DRBG and jitterentropy library APIs Eric Biggers
2026-10-18 20:46 ` Eric Biggers [this message]
2026-10-18 20:46 ` [PATCH 10/14] crypto: drbg - Remove crypto_rng support Eric Biggers
2026-10-18 20:46 ` [PATCH 11/14] crypto: jitterentropy " Eric Biggers
2026-10-18 20:46 ` [PATCH 12/14] crypto: jitterentropy - Remove the kconfig prompt Eric Biggers
2026-10-18 20:46 ` [PATCH 13/14] crypto: rng - Remove the rng algorithm type Eric Biggers
2026-10-18 20:46 ` [PATCH 14/14] crypto: stdrng - Make crypto_stdrng_get_bytes() take size_t 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=20261018204618.104876-10-ebiggers@kernel.org \
    --to=ebiggers@kernel.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-crypto@vger.kernel.org \
    --cc=smueller@chronox.de \
    /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.