crypto: drbg - reseed often if seedsource is degraded
As required by SP800-90A, the DRBG implements are reseeding threshold. This threshold is at 2**48 (64 bit) and 2**32 bit (32 bit) as implemented in drbg_max_requests. With the recently introduced changes, the DRBG is now always used as a stdrng which is initialized very early in the boot cycle. To ensure that sufficient entropy is present, the Jitter RNG is added to even provide entropy at early boot time. However, the 2nd seed source, the nonblocking pool, is usually degraded at that time. Therefore, the DRBG is seeded with the Jitter RNG (which I believe contains good entropy, which however is questioned by others) and is seeded with a degradded nonblocking pool. This seed is now used for quasi the lifetime of the system (2**48 requests is a lot). The patch now changes the reseed threshold as follows: up until the time the DRBG obtains a seed from a fully iniitialized nonblocking pool, the reseeding threshold is lowered such that the DRBG is forced to reseed itself resonably often. Once it obtains the seed from a fully initialized nonblocking pool, the reseed threshold is set to the value required by SP800-90A. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Родитель
c2719503f5
Коммит
42ea507fae
|
@ -1088,6 +1088,9 @@ static void drbg_async_seed(struct work_struct *work)
|
||||||
|
|
||||||
__drbg_seed(drbg, &seedlist, true);
|
__drbg_seed(drbg, &seedlist, true);
|
||||||
|
|
||||||
|
if (drbg->seeded)
|
||||||
|
drbg->reseed_threshold = drbg_max_requests(drbg);
|
||||||
|
|
||||||
mutex_unlock(&drbg->drbg_mutex);
|
mutex_unlock(&drbg->drbg_mutex);
|
||||||
|
|
||||||
memzero_explicit(entropy, entropylen);
|
memzero_explicit(entropy, entropylen);
|
||||||
|
@ -1334,7 +1337,7 @@ static int drbg_generate(struct drbg_state *drbg,
|
||||||
* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented
|
* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented
|
||||||
* here. The spec is a bit convoluted here, we make it simpler.
|
* here. The spec is a bit convoluted here, we make it simpler.
|
||||||
*/
|
*/
|
||||||
if ((drbg_max_requests(drbg)) < drbg->reseed_ctr)
|
if (drbg->reseed_threshold < drbg->reseed_ctr)
|
||||||
drbg->seeded = false;
|
drbg->seeded = false;
|
||||||
|
|
||||||
if (drbg->pr || !drbg->seeded) {
|
if (drbg->pr || !drbg->seeded) {
|
||||||
|
@ -1478,6 +1481,12 @@ static int drbg_prepare_hrng(struct drbg_state *drbg)
|
||||||
|
|
||||||
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
|
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Require frequent reseeds until the seed source is fully
|
||||||
|
* initialized.
|
||||||
|
*/
|
||||||
|
drbg->reseed_threshold = 50;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1522,6 +1531,7 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
|
||||||
drbg->core = &drbg_cores[coreref];
|
drbg->core = &drbg_cores[coreref];
|
||||||
drbg->pr = pr;
|
drbg->pr = pr;
|
||||||
drbg->seeded = false;
|
drbg->seeded = false;
|
||||||
|
drbg->reseed_threshold = drbg_max_requests(drbg);
|
||||||
|
|
||||||
ret = drbg_alloc_state(drbg);
|
ret = drbg_alloc_state(drbg);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct drbg_state {
|
||||||
unsigned char *C;
|
unsigned char *C;
|
||||||
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
|
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
|
||||||
size_t reseed_ctr;
|
size_t reseed_ctr;
|
||||||
|
size_t reseed_threshold;
|
||||||
/* some memory the DRBG can use for its operation */
|
/* some memory the DRBG can use for its operation */
|
||||||
unsigned char *scratchpad;
|
unsigned char *scratchpad;
|
||||||
void *priv_data; /* Cipher handle */
|
void *priv_data; /* Cipher handle */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче