If we are removing RDRAND, what about adding some cheaper mixing? Something along these lines? The current code's mixing is triggered only once in 2^32 iterations, depends only on crng->state[], always changes the same state word, and introduces no new entropy. Make it happen more often, depend on a randomly initialised counter as well as state[], make a data-dependent choice of word to change, and use random_get_entropy(). --- drivers/char/random.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 605969ed0f96..d2be079f004d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -985,6 +985,10 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) } } +#define CC_SHIFT 8 +#define CC_MASK ((1<<CC_SHIFT)-1) +static u32 cc_count = 0 ; + static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA_BLOCK_SIZE]) { @@ -998,8 +1002,22 @@ static void _extract_crng(struct crng_state *crng, if (arch_get_random_long(&v)) crng->state[14] ^= v; chacha20_block(&crng->state[0], out); - if (crng->state[12] == 0) - crng->state[13]++; + if (cc_count == 0) + cc_count = crng->state[9] ^ random_get_entropy() ; + switch ((crng->state[12] ^ cc_count) & CC_MASK) { + case 0: + cc_count = crng->state[10] ^ (cc_count>>CC_SHIFT); + break ; + case 31: case 97: case 253: + crng->state[crng->state[13]&7]++; + break ; + case 61: case 127: + crng->state[crng->state[11]&7] += random_get_entropy(); + break ; + default: + break ; + } + cc_count++ ; spin_unlock_irqrestore(&crng->lock, flags); } -- Signed-off-by: Sandy Harris <sandyinchina@xxxxxxxxx>