--- zzzz-none-000/linux-4.1.52/drivers/char/random.c 2018-05-28 02:26:45.000000000 +0000 +++ bcm63-7530ax-731/linux-4.1.52/drivers/char/random.c 2022-03-02 11:37:12.000000000 +0000 @@ -661,7 +661,9 @@ if (r == &nonblocking_pool) { prandom_reseed_late(); wake_up_interruptible(&urandom_init_wait); +#if !defined(CONFIG_BCM_KF_SUPPRESS_DEBUG) pr_notice("random: %s pool is initialized\n", r->name); +#endif } } @@ -1524,6 +1526,55 @@ .llseek = noop_llseek, }; +/* + * Each time the timer fires, we expect that we got an unpredictable + * jump in the cycle counter. Even if the timer is running on another + * CPU, the timer activity will be touching the stack of the CPU that is + * generating entropy.. + * + * Note that we don't re-arm the timer in the timer itself - we are + * happy to be scheduled away, since that just makes the load more + * complex, but we do not want the timer to keep ticking unless the + * entropy loop is running. + * + * So the re-arming always happens in the entropy loop itself. + */ +static void entropy_timer(unsigned long data) +{ + credit_entropy_bits(&input_pool, 1); +} + +/* + * If we have an actual cycle counter, see if we can + * generate enough entropy with timing noise + */ +static void try_to_generate_entropy(void) +{ + struct { + unsigned long now; + struct timer_list timer; + } stack; + + stack.now = random_get_entropy(); + + /* Slow counter - or none. Don't even bother */ + if (stack.now == random_get_entropy()) + return; + + setup_timer_on_stack(&stack.timer, entropy_timer, 0); + while (!nonblocking_pool.initialized) { + if (!timer_pending(&stack.timer)) + mod_timer(&stack.timer, jiffies+1); + mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now)); + schedule(); + stack.now = random_get_entropy(); + } + + del_timer_sync(&stack.timer); + destroy_timer_on_stack(&stack.timer); + mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now)); +} + SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) { @@ -1539,6 +1590,9 @@ if (unlikely(nonblocking_pool.initialized == 0)) { if (flags & GRND_NONBLOCK) return -EAGAIN; + + try_to_generate_entropy(); + wait_event_interruptible(urandom_init_wait, nonblocking_pool.initialized); if (signal_pending(current))