random: order timer entropy functions below interrupt functions
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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
ce3c4ff381
commit
999b0c9e8a
@@ -856,13 +856,13 @@ static void credit_init_bits(size_t nbits)
|
|||||||
* the above entropy accumulation routines:
|
* the above entropy accumulation routines:
|
||||||
*
|
*
|
||||||
* void add_device_randomness(const void *buf, size_t size);
|
* 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,
|
* void add_hwgenerator_randomness(const void *buffer, size_t count,
|
||||||
* size_t entropy);
|
* size_t entropy);
|
||||||
* void add_bootloader_randomness(const void *buf, size_t size);
|
* void add_bootloader_randomness(const void *buf, size_t size);
|
||||||
* void add_interrupt_randomness(int irq);
|
* 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
|
* add_device_randomness() adds data to the input pool that
|
||||||
* is likely to differ between two devices (or possibly even per boot).
|
* is likely to differ between two devices (or possibly even per boot).
|
||||||
@@ -872,19 +872,6 @@ static void credit_init_bits(size_t nbits)
|
|||||||
* that might otherwise be identical and have very little entropy
|
* that might otherwise be identical and have very little entropy
|
||||||
* available to them (particularly common in the embedded world).
|
* 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
|
* 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
|
* entropy as specified by the caller. If the entropy pool is full it will
|
||||||
* block until more entropy is needed.
|
* block until more entropy is needed.
|
||||||
@@ -898,6 +885,19 @@ static void credit_init_bits(size_t nbits)
|
|||||||
* as inputs, it feeds the input pool roughly once a second or after 64
|
* as inputs, it feeds the input pool roughly once a second or after 64
|
||||||
* interrupts, crediting 1 bit of entropy for whichever comes first.
|
* 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);
|
static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
|
||||||
@@ -975,109 +975,6 @@ void add_device_randomness(const void *buf, size_t size)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(add_device_randomness);
|
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.
|
* Interface for in-kernel drivers of true hardware RNGs.
|
||||||
* Those devices may produce endless random bits and will be throttled
|
* Those devices may produce endless random bits and will be throttled
|
||||||
@@ -1239,6 +1136,109 @@ void add_interrupt_randomness(int irq)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(add_interrupt_randomness);
|
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
|
* 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
|
* jump in the cycle counter. Even if the timer is running on another
|
||||||
|
Reference in New Issue
Block a user