Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stephan Mueller and committed by
Herbert Xu
42ea507f c2719503

+12 -1
+11 -1
crypto/drbg.c
··· 1088 1088 1089 1089 __drbg_seed(drbg, &seedlist, true); 1090 1090 1091 + if (drbg->seeded) 1092 + drbg->reseed_threshold = drbg_max_requests(drbg); 1093 + 1091 1094 mutex_unlock(&drbg->drbg_mutex); 1092 1095 1093 1096 memzero_explicit(entropy, entropylen); ··· 1337 1334 * 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented 1338 1335 * here. The spec is a bit convoluted here, we make it simpler. 1339 1336 */ 1340 - if ((drbg_max_requests(drbg)) < drbg->reseed_ctr) 1337 + if (drbg->reseed_threshold < drbg->reseed_ctr) 1341 1338 drbg->seeded = false; 1342 1339 1343 1340 if (drbg->pr || !drbg->seeded) { ··· 1481 1478 1482 1479 drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); 1483 1480 1481 + /* 1482 + * Require frequent reseeds until the seed source is fully 1483 + * initialized. 1484 + */ 1485 + drbg->reseed_threshold = 50; 1486 + 1484 1487 return err; 1485 1488 } 1486 1489 ··· 1531 1522 drbg->core = &drbg_cores[coreref]; 1532 1523 drbg->pr = pr; 1533 1524 drbg->seeded = false; 1525 + drbg->reseed_threshold = drbg_max_requests(drbg); 1534 1526 1535 1527 ret = drbg_alloc_state(drbg); 1536 1528 if (ret)
+1
include/crypto/drbg.h
··· 111 111 unsigned char *C; 112 112 /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ 113 113 size_t reseed_ctr; 114 + size_t reseed_threshold; 114 115 /* some memory the DRBG can use for its operation */ 115 116 unsigned char *scratchpad; 116 117 void *priv_data; /* Cipher handle */