random: order timer entropy functions below interrupt functions
authorJason A. Donenfeld <Jason@zx2c4.com>
Fri, 6 May 2022 16:27:38 +0000 (18:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 May 2022 07:29:15 +0000 (09:29 +0200)
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

index 5be537f..b5c5899 100644 (file)
@@ -856,13 +856,13 @@ 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_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.
@@ -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
  * 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);
@@ -975,109 +975,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
@@ -1239,6 +1136,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