Skip to content

Commit 8c60e85

Browse files
kerneltoastshreeya-patel98
authored andcommitted
crypto: rng - Only allow the DRBG to register as "stdrng" in FIPS mode
In FIPS mode, the DRBG must take precedence over all stdrng algorithms. The only problem standing in the way of this is that a different stdrng algorithm could get registered and utilized before the DRBG is registered, and since crypto_alloc_rng() only allocates an stdrng algorithm when there's no existing allocation, this means that it's possible for the wrong stdrng algorithm to remain in use indefinitely. This issue is also often impossible to observe from userspace; an RNG other than the DRBG could be used somewhere in the kernel and userspace would be none the wiser. To ensure this can never happen, only allow stdrng instances from the DRBG to be registered when running in FIPS mode. This works since the previous commit forces the DRBG to be built into the kernel when CONFIG_CRYPTO_FIPS is enabled, so the DRBG's presence is guaranteed when fips_enabled is true. Signed-off-by: Sultan Alsawaf <sultan@ciq.com> Signed-off-by: Jonathan Maple <jmaple@ciq.com> Signed-off-by: Shreeya Patel <spatel@ciq.com>
1 parent c6960ca commit 8c60e85

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

crypto/rng.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static ____cacheline_aligned_in_smp DEFINE_RT_MUTEX(crypto_default_rng_lock);
3232
struct crypto_rng *crypto_default_rng;
3333
EXPORT_SYMBOL_GPL(crypto_default_rng);
3434
static unsigned int crypto_default_rng_refcnt;
35+
static bool drbg_registered __ro_after_init;
3536

3637
/*
3738
* Per-CPU RNG instances are only used by crypto_devrandom_rng. The global RNG,
@@ -215,6 +216,19 @@ int crypto_register_rng(struct rng_alg *alg)
215216
if (alg->seedsize > PAGE_SIZE / 8)
216217
return -EINVAL;
217218

219+
/*
220+
* In FIPS mode, the DRBG must take precedence over all other "stdrng"
221+
* algorithms. Therefore, forbid registration of a non-DRBG stdrng in
222+
* FIPS mode. All of the DRBG's driver names are prefixed with "drbg_".
223+
* This also stops new stdrng instances from getting registered after it
224+
* is known that the DRBG is registered, so a new module can't come in
225+
* and pretend to be the DRBG. And when CONFIG_CRYPTO_FIPS is enabled,
226+
* the DRBG is built into the kernel directly; it can't be a module.
227+
*/
228+
if (fips_enabled && !strcmp(base->cra_name, "stdrng") &&
229+
(drbg_registered || strncmp(base->cra_driver_name, "drbg_", 5)))
230+
return -EINVAL;
231+
218232
base->cra_type = &crypto_rng_type;
219233
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
220234
base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
@@ -239,6 +253,18 @@ int crypto_register_rngs(struct rng_alg *algs, int count)
239253
goto err;
240254
}
241255

256+
/*
257+
* Track when the DRBG is registered in FIPS mode. The DRBG calls
258+
* crypto_register_rngs() to register its stdrng instances, and since
259+
* crypto_register_rng() only allows stdrng instances from the DRBG in
260+
* FIPS mode, a successful stdrng registration means it was the DRBG.
261+
* Just check the first alg in the array to see if it's called "stdrng",
262+
* since all of the DRBG's algorithms are named "stdrng". Once
263+
* drbg_registered is set to true, this if-statement is always false.
264+
*/
265+
if (fips_enabled && !strcmp(algs->base.cra_name, "stdrng"))
266+
drbg_registered = true;
267+
242268
return 0;
243269

244270
err:

0 commit comments

Comments
 (0)