This is a note to let you know that I've just added the patch titled random: order timer entropy functions below interrupt functions to the 5.18-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: random-order-timer-entropy-functions-below-interrupt-functions.patch and it can be found in the queue-5.18 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Thu May 26 04:17:01 PM CEST 2022 From: "Jason A. Donenfeld" <Jason@xxxxxxxxx> Date: Fri, 6 May 2022 18:27:38 +0200 Subject: random: order timer entropy functions below interrupt functions From: "Jason A. Donenfeld" <Jason@xxxxxxxxx> commit a4b5c26b79ffdfcfb816c198f2fc2b1e7b5b580f upstream. There are no code changes here; this is just a reordering of functions, so that in subsequent commits, the timer entropy functions can call into the interrupt ones. Signed-off-by: Jason A. Donenfeld <Jason@xxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/char/random.c | 238 +++++++++++++++++++++++++------------------------- 1 file changed, 119 insertions(+), 119 deletions(-) --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -854,14 +854,14 @@ static void credit_init_bits(size_t nbit * the above entropy accumulation routines: * * void add_device_randomness(const void *buf, size_t size); - * void add_input_randomness(unsigned int type, unsigned int code, - * unsigned int value); - * void add_disk_randomness(struct gendisk *disk); * void add_hwgenerator_randomness(const void *buffer, size_t count, * size_t entropy); * void add_bootloader_randomness(const void *buf, size_t size); * void add_vmfork_randomness(const void *unique_vm_id, size_t size); * void add_interrupt_randomness(int irq); + * void add_input_randomness(unsigned int type, unsigned int code, + * unsigned int value); + * void add_disk_randomness(struct gendisk *disk); * * add_device_randomness() adds data to the input pool that * is likely to differ between two devices (or possibly even per boot). @@ -871,19 +871,6 @@ static void credit_init_bits(size_t nbit * that might otherwise be identical and have very little entropy * available to them (particularly common in the embedded world). * - * add_input_randomness() uses the input layer interrupt timing, as well - * as the event type information from the hardware. - * - * add_disk_randomness() uses what amounts to the seek time of block - * layer request events, on a per-disk_devt basis, as input to the - * entropy pool. Note that high-speed solid state drives with very low - * seek times do not make for good sources of entropy, as their seek - * times are usually fairly consistent. - * - * The above two routines try to estimate how many bits of entropy - * to credit. They do this by keeping track of the first and second - * order deltas of the event timings. - * * add_hwgenerator_randomness() is for true hardware RNGs, and will credit * entropy as specified by the caller. If the entropy pool is full it will * block until more entropy is needed. @@ -901,6 +888,19 @@ static void credit_init_bits(size_t nbit * as inputs, it feeds the input pool roughly once a second or after 64 * interrupts, crediting 1 bit of entropy for whichever comes first. * + * add_input_randomness() uses the input layer interrupt timing, as well + * as the event type information from the hardware. + * + * add_disk_randomness() uses what amounts to the seek time of block + * layer request events, on a per-disk_devt basis, as input to the + * entropy pool. Note that high-speed solid state drives with very low + * seek times do not make for good sources of entropy, as their seek + * times are usually fairly consistent. + * + * The last two routines try to estimate how many bits of entropy + * to credit. They do this by keeping track of the first and second + * order deltas of the event timings. + * **********************************************************************/ static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); @@ -978,109 +978,6 @@ void add_device_randomness(const void *b } EXPORT_SYMBOL(add_device_randomness); -/* There is one of these per entropy source */ -struct timer_rand_state { - unsigned long last_time; - long last_delta, last_delta2; -}; - -/* - * This function adds entropy to the entropy "pool" by using timing - * delays. It uses the timer_rand_state structure to make an estimate - * of how many bits of entropy this call has added to the pool. - * - * The number "num" is also added to the pool - it should somehow describe - * the type of event which just happened. This is currently 0-255 for - * keyboard scan codes, and 256 upwards for interrupts. - */ -static void add_timer_randomness(struct timer_rand_state *state, unsigned int num) -{ - unsigned long entropy = random_get_entropy(), now = jiffies, flags; - long delta, delta2, delta3; - - spin_lock_irqsave(&input_pool.lock, flags); - _mix_pool_bytes(&entropy, sizeof(entropy)); - _mix_pool_bytes(&num, sizeof(num)); - spin_unlock_irqrestore(&input_pool.lock, flags); - - if (crng_ready()) - return; - - /* - * Calculate number of bits of randomness we probably added. - * We take into account the first, second and third-order deltas - * in order to make our estimate. - */ - delta = now - READ_ONCE(state->last_time); - WRITE_ONCE(state->last_time, now); - - delta2 = delta - READ_ONCE(state->last_delta); - WRITE_ONCE(state->last_delta, delta); - - delta3 = delta2 - READ_ONCE(state->last_delta2); - WRITE_ONCE(state->last_delta2, delta2); - - if (delta < 0) - delta = -delta; - if (delta2 < 0) - delta2 = -delta2; - if (delta3 < 0) - delta3 = -delta3; - if (delta > delta2) - delta = delta2; - if (delta > delta3) - delta = delta3; - - /* - * delta is now minimum absolute delta. - * Round down by 1 bit on general principles, - * and limit entropy estimate to 12 bits. - */ - credit_init_bits(min_t(unsigned int, fls(delta >> 1), 11)); -} - -void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value) -{ - static unsigned char last_value; - static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES }; - - /* Ignore autorepeat and the like. */ - if (value == last_value) - return; - - last_value = value; - add_timer_randomness(&input_timer_state, - (type << 4) ^ code ^ (code >> 4) ^ value); -} -EXPORT_SYMBOL_GPL(add_input_randomness); - -#ifdef CONFIG_BLOCK -void add_disk_randomness(struct gendisk *disk) -{ - if (!disk || !disk->random) - return; - /* First major is 1, so we get >= 0x200 here. */ - add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); -} -EXPORT_SYMBOL_GPL(add_disk_randomness); - -void rand_initialize_disk(struct gendisk *disk) -{ - struct timer_rand_state *state; - - /* - * If kzalloc returns null, we just won't use that entropy - * source. - */ - state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); - if (state) { - state->last_time = INITIAL_JIFFIES; - disk->random = state; - } -} -#endif - /* * Interface for in-kernel drivers of true hardware RNGs. * Those devices may produce endless random bits and will be throttled @@ -1276,6 +1173,109 @@ void add_interrupt_randomness(int irq) } EXPORT_SYMBOL_GPL(add_interrupt_randomness); +/* There is one of these per entropy source */ +struct timer_rand_state { + unsigned long last_time; + long last_delta, last_delta2; +}; + +/* + * This function adds entropy to the entropy "pool" by using timing + * delays. It uses the timer_rand_state structure to make an estimate + * of how many bits of entropy this call has added to the pool. + * + * The number "num" is also added to the pool - it should somehow describe + * the type of event which just happened. This is currently 0-255 for + * keyboard scan codes, and 256 upwards for interrupts. + */ +static void add_timer_randomness(struct timer_rand_state *state, unsigned int num) +{ + unsigned long entropy = random_get_entropy(), now = jiffies, flags; + long delta, delta2, delta3; + + spin_lock_irqsave(&input_pool.lock, flags); + _mix_pool_bytes(&entropy, sizeof(entropy)); + _mix_pool_bytes(&num, sizeof(num)); + spin_unlock_irqrestore(&input_pool.lock, flags); + + if (crng_ready()) + return; + + /* + * Calculate number of bits of randomness we probably added. + * We take into account the first, second and third-order deltas + * in order to make our estimate. + */ + delta = now - READ_ONCE(state->last_time); + WRITE_ONCE(state->last_time, now); + + delta2 = delta - READ_ONCE(state->last_delta); + WRITE_ONCE(state->last_delta, delta); + + delta3 = delta2 - READ_ONCE(state->last_delta2); + WRITE_ONCE(state->last_delta2, delta2); + + if (delta < 0) + delta = -delta; + if (delta2 < 0) + delta2 = -delta2; + if (delta3 < 0) + delta3 = -delta3; + if (delta > delta2) + delta = delta2; + if (delta > delta3) + delta = delta3; + + /* + * delta is now minimum absolute delta. + * Round down by 1 bit on general principles, + * and limit entropy estimate to 12 bits. + */ + credit_init_bits(min_t(unsigned int, fls(delta >> 1), 11)); +} + +void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value) +{ + static unsigned char last_value; + static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES }; + + /* Ignore autorepeat and the like. */ + if (value == last_value) + return; + + last_value = value; + add_timer_randomness(&input_timer_state, + (type << 4) ^ code ^ (code >> 4) ^ value); +} +EXPORT_SYMBOL_GPL(add_input_randomness); + +#ifdef CONFIG_BLOCK +void add_disk_randomness(struct gendisk *disk) +{ + if (!disk || !disk->random) + return; + /* First major is 1, so we get >= 0x200 here. */ + add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); +} +EXPORT_SYMBOL_GPL(add_disk_randomness); + +void rand_initialize_disk(struct gendisk *disk) +{ + struct timer_rand_state *state; + + /* + * If kzalloc returns null, we just won't use that entropy + * source. + */ + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); + if (state) { + state->last_time = INITIAL_JIFFIES; + disk->random = state; + } +} +#endif + /* * 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 Patches currently in stable-queue which might be from Jason@xxxxxxxxx are queue-5.18/random-remove-ratelimiting-for-in-kernel-unseeded-randomness.patch queue-5.18/random-fix-sysctl-documentation-nits.patch queue-5.18/random-help-compiler-out-with-fast_mix-by-using-simpler-arguments.patch queue-5.18/siphash-use-one-source-of-truth-for-siphash-permutations.patch queue-5.18/um-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/random-order-timer-entropy-functions-below-interrupt-functions.patch queue-5.18/random-unify-batched-entropy-implementations.patch queue-5.18/random-make-consistent-use-of-buf-and-len.patch queue-5.18/random-move-randomize_page-into-mm-where-it-belongs.patch queue-5.18/random-use-first-128-bits-of-input-as-fast-init.patch queue-5.18/random-use-proper-return-types-on-get_random_-int-long-_wait.patch queue-5.18/s390-define-get_cycles-macro-for-arch-override.patch queue-5.18/timekeeping-add-raw-clock-fallback-for-random_get_entropy.patch queue-5.18/random-use-static-branch-for-crng_ready.patch queue-5.18/arm-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/mips-use-fallback-for-random_get_entropy-instead-of-just-c0-random.patch queue-5.18/random-avoid-initializing-twice-in-credit-race.patch queue-5.18/random-move-initialization-functions-out-of-hot-pages.patch queue-5.18/random-do-not-pretend-to-handle-premature-next-security-model.patch queue-5.18/random-do-not-use-batches-when-crng_ready.patch queue-5.18/m68k-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/random-move-initialization-out-of-reseeding-hot-path.patch queue-5.18/x86-tsc-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/random-credit-architectural-init-the-exact-amount.patch queue-5.18/random-check-for-signals-after-page-of-pool-writes.patch queue-5.18/random-remove-extern-from-functions-in-header.patch queue-5.18/random-do-not-use-input-pool-from-hard-irqs.patch queue-5.18/random-wire-up-fops-splice_-read-write-_iter.patch queue-5.18/random-insist-on-random_get_entropy-existing-in-order-to-simplify.patch queue-5.18/powerpc-define-get_cycles-macro-for-arch-override.patch queue-5.18/parisc-define-get_cycles-macro-for-arch-override.patch queue-5.18/sparc-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/nios2-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/init-call-time_init-before-rand_initialize.patch queue-5.18/riscv-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/ia64-define-get_cycles-macro-for-arch-override.patch queue-5.18/random-handle-latent-entropy-and-command-line-from-random_init.patch queue-5.18/random-use-proper-jiffies-comparison-macro.patch queue-5.18/alpha-define-get_cycles-macro-for-arch-override.patch queue-5.18/random-convert-to-using-fops-read_iter.patch queue-5.18/xtensa-use-fallback-for-random_get_entropy-instead-of-zero.patch queue-5.18/random-use-symbolic-constants-for-crng_init-states.patch queue-5.18/random-convert-to-using-fops-write_iter.patch