lkml.org 
[lkml]   [2022]   [Jun]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 149/240] random: order timer entropy functions below interrupt functions
    Date
    From: "Jason A. Donenfeld" <Jason@zx2c4.com>

    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@zx2c4.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/char/random.c | 238 +++++++++++++++++++++++++-------------------------
    1 file changed, 119 insertions(+), 119 deletions(-)

    --- a/drivers/char/random.c
    +++ b/drivers/char/random.c
    @@ -851,13 +851,13 @@ 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_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).
    @@ -867,19 +867,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.
    @@ -893,6 +880,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);
    @@ -970,109 +970,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
    @@ -1234,6 +1131,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

    \
     
     \ /
      Last update: 2022-06-20 16:02    [W:2.250 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site