diff --git a/drivers/char/random.c b/drivers/char/random.c
index 3e0d1a403d85..db521b8ae7a6 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -589,30 +589,14 @@ struct fast_pool {
* This is a fast mixing routine used by the interrupt randomness
* collector. It's hardcoded for an 128 bit pool and assumes that any
* locks that might be needed are taken by the caller.
+ * It's based on the suggestion here: https://eprint.iacr.org/2021/523
*/
-static void fast_mix(struct fast_pool *f)
+static void fast_accumulate(struct fast_pool *f, u32 a, u32 b, u32 c, u32 d)
{
- u32 a = f->pool[0], b = f->pool[1];
- u32 c = f->pool[2], d = f->pool[3];
-
- a += b; c += d;
- b = rol32(b, 6); d = rol32(d, 27);
- d ^= a; b ^= c;
-
- a += b; c += d;
- b = rol32(b, 16); d = rol32(d, 14);
- d ^= a; b ^= c;
-
- a += b; c += d;
- b = rol32(b, 6); d = rol32(d, 27);
- d ^= a; b ^= c;
-
- a += b; c += d;
- b = rol32(b, 16); d = rol32(d, 14);
- d ^= a; b ^= c;
-
- f->pool[0] = a; f->pool[1] = b;
- f->pool[2] = c; f->pool[3] = d;
+ f->pool[0] = ror32(f->pool[0], 7) ^ a;
+ f->pool[1] = ror32(f->pool[1], 7) ^ b;
+ f->pool[2] = ror32(f->pool[2], 7) ^ c;
+ f->pool[3] = ror32(f->pool[3], 7) ^ d;
f->count++;
}
@@ -1233,14 +1217,12 @@ void add_interrupt_randomness(int irq)
cycles = get_reg(fast_pool, regs);
c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
j_high = (sizeof(now) > 4) ? now >> 32 : 0;
- fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
- fast_pool->pool[1] ^= now ^ c_high;
ip = regs ? instruction_pointer(regs) : _RET_IP_;
- fast_pool->pool[2] ^= ip;
- fast_pool->pool[3] ^=
- (sizeof(ip) > 4) ? ip >> 32 : get_reg(fast_pool, regs);
- fast_mix(fast_pool);
+ fast_accumulate(fast_pool,
+ cycles ^ j_high ^ irq, now ^ c_high,
+ ip, (sizeof(ip) > 4) ? ip >> 32 : get_reg(fast_pool, regs));
+
add_interrupt_bench(cycles);
if (unlikely(crng_init == 0)) {