aboutsummaryrefslogtreecommitdiffstats
diff options
authorEric Biggers <ebiggers@kernel.org>2026-04-19 23:34:15 -0700
committerHerbert Xu <herbert@gondor.apana.org.au>2026-05-07 16:10:01 +0800
commitad8883374f34809f04d6839b9e7efe0afa5e92cd (patch)
treec1077677c72345e18c2c8586b127aef1e2f4367e
parent810ba022870bfdf7b7ac0e04db98b2891e80f59e (diff)
downloadlinux-next-history-ad8883374f34809f04d6839b9e7efe0afa5e92cd.tar.gz
crypto: drbg - Separate "reseed" case in drbg_kcapi_seed()
Clearly separate the code for the "reseed" and "instantiate" cases, since what they need to do is quite different. Note that the mutex guard makes the mutex start being held during the call to drbg_uninstantiate(), which is fine. Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/drbg.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 763c14e3786c6..a9d586107ebed 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -577,11 +577,13 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm,
static const u8 initial_key[DRBG_STATE_LEN]; /* all zeroes */
struct drbg_state *drbg = crypto_rng_ctx(tfm);
int ret;
- bool reseed = true;
pr_devel("DRBG: Initializing DRBG with prediction resistance %s\n",
str_enabled_disabled(pr));
- mutex_lock(&drbg->drbg_mutex);
+ guard(mutex)(&drbg->drbg_mutex);
+
+ if (drbg->instantiated)
+ return drbg_seed(drbg, pers, pers_len, /* reseed= */ true);
/* 9.1 step 1 is implicit with the selected DRBG type */
@@ -592,32 +594,24 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm,
/* 9.1 step 4 is implicit in DRBG_SEC_STRENGTH */
- if (!drbg->instantiated) {
- drbg->instantiated = true;
- drbg->pr = pr;
- drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
- drbg->last_seed_time = 0;
- drbg->reseed_threshold = DRBG_MAX_REQUESTS;
- memset(drbg->V, 1, DRBG_STATE_LEN);
- hmac_sha512_preparekey(&drbg->key, initial_key, DRBG_STATE_LEN);
-
- ret = drbg_prepare_hrng(drbg);
- if (ret)
- goto free_everything;
-
- reseed = false;
- }
-
- ret = drbg_seed(drbg, pers, pers_len, reseed);
+ drbg->instantiated = true;
+ drbg->pr = pr;
+ drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
+ drbg->last_seed_time = 0;
+ drbg->reseed_threshold = DRBG_MAX_REQUESTS;
+ memset(drbg->V, 1, DRBG_STATE_LEN);
+ hmac_sha512_preparekey(&drbg->key, initial_key, DRBG_STATE_LEN);
- if (ret && !reseed)
+ ret = drbg_prepare_hrng(drbg);
+ if (ret)
+ goto free_everything;
+ ret = drbg_seed(drbg, pers, pers_len, /* reseed= */ false);
+ if (ret)
goto free_everything;
- mutex_unlock(&drbg->drbg_mutex);
return ret;
free_everything:
- mutex_unlock(&drbg->drbg_mutex);
drbg_uninstantiate(drbg);
return ret;
}