random: order timer entropy functions below interrupt functions
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>
This commit is contained in:
parent
e85c0fc1d9
commit
a4b5c26b79
|
@ -855,14 +855,14 @@ static void credit_init_bits(size_t nbits)
|
|||
* 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).
|
||||
|
@ -872,19 +872,6 @@ static void credit_init_bits(size_t nbits)
|
|||
* 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.
|
||||
|
@ -902,6 +889,19 @@ static void credit_init_bits(size_t nbits)
|
|||
* 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);
|
||||
|
@ -1011,109 +1011,6 @@ void add_device_randomness(const void *buf, size_t size)
|
|||
}
|
||||
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
|
||||
|
@ -1309,6 +1206,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
|
||||
|
||||
struct entropy_timer_state {
|
||||
unsigned long entropy;
|
||||
struct timer_list timer;
|
||||
|
|
Loading…
Reference in New Issue