aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-28 19:53:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-29 20:38:52 -0400
commit50ee7529ec4500c88f8664560770a7a1b65db72b (patch)
tree122866c9cd0b4e2425309dc4696c728682434ee1 /drivers/char/random.c
parent4d856f72c10ecb060868ed10ff1b1453943fc6c8 (diff)
random: try to actively add entropy rather than passively wait for it
For 5.3 we had to revert a nice ext4 IO pattern improvement, because it caused a bootup regression due to lack of entropy at bootup together with arguably broken user space that was asking for secure random numbers when it really didn't need to. See commit 72dbcf721566 (Revert "ext4: make __ext4_get_inode_loc plug"). This aims to solve the issue by actively generating entropy noise using the CPU cycle counter when waiting for the random number generator to initialize. This only works when you have a high-frequency time stamp counter available, but that's the case on all modern x86 CPU's, and on most other modern CPU's too. What we do is to generate jitter entropy from the CPU cycle counter under a somewhat complex load: calling the scheduler while also guaranteeing a certain amount of timing noise by also triggering a timer. I'm sure we can tweak this, and that people will want to look at other alternatives, but there's been a number of papers written on jitter entropy, and this should really be fairly conservative by crediting one bit of entropy for every timer-induced jump in the cycle counter. Not because the timer itself would be all that unpredictable, but because the interaction between the timer and the loop is going to be. Even if (and perhaps particularly if) the timer actually happens on another CPU, the cacheline interaction between the loop that reads the cycle counter and the timer itself firing is going to add perturbations to the cycle counter values that get mixed into the entropy pool. As Thomas pointed out, with a modern out-of-order CPU, even quite simple loops show a fair amount of hard-to-predict timing variability even in the absense of external interrupts. But this tries to take that further by actually having a fairly complex interaction. This is not going to solve the entropy issue for architectures that have no CPU cycle counter, but it's not clear how (and if) that is solvable, and the hardware in question is largely starting to be irrelevant. And by doing this we can at least avoid some of the even more contentious approaches (like making the entropy waiting time out in order to avoid the possibly unbounded waiting). Cc: Ahmed Darwish <darwish.07@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Nicholas Mc Guire <hofrat@opentech.at> Cc: Andy Lutomirski <luto@kernel.org> Cc: Kees Cook <keescook@chromium.org> Cc: Willy Tarreau <w@1wt.eu> Cc: Alexander E. Patrakov <patrakov@gmail.com> Cc: Lennart Poettering <mzxreary@0pointer.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5d5ea4ce1442..2fda6166c1dd 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1731,6 +1731,56 @@ void get_random_bytes(void *buf, int nbytes)
1731} 1731}
1732EXPORT_SYMBOL(get_random_bytes); 1732EXPORT_SYMBOL(get_random_bytes);
1733 1733
1734
1735/*
1736 * Each time the timer fires, we expect that we got an unpredictable
1737 * jump in the cycle counter. Even if the timer is running on another
1738 * CPU, the timer activity will be touching the stack of the CPU that is
1739 * generating entropy..
1740 *
1741 * Note that we don't re-arm the timer in the timer itself - we are
1742 * happy to be scheduled away, since that just makes the load more
1743 * complex, but we do not want the timer to keep ticking unless the
1744 * entropy loop is running.
1745 *
1746 * So the re-arming always happens in the entropy loop itself.
1747 */
1748static void entropy_timer(struct timer_list *t)
1749{
1750 credit_entropy_bits(&input_pool, 1);
1751}
1752
1753/*
1754 * If we have an actual cycle counter, see if we can
1755 * generate enough entropy with timing noise
1756 */
1757static void try_to_generate_entropy(void)
1758{
1759 struct {
1760 unsigned long now;
1761 struct timer_list timer;
1762 } stack;
1763
1764 stack.now = random_get_entropy();
1765
1766 /* Slow counter - or none. Don't even bother */
1767 if (stack.now == random_get_entropy())
1768 return;
1769
1770 timer_setup_on_stack(&stack.timer, entropy_timer, 0);
1771 while (!crng_ready()) {
1772 if (!timer_pending(&stack.timer))
1773 mod_timer(&stack.timer, jiffies+1);
1774 mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
1775 schedule();
1776 stack.now = random_get_entropy();
1777 }
1778
1779 del_timer_sync(&stack.timer);
1780 destroy_timer_on_stack(&stack.timer);
1781 mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
1782}
1783
1734/* 1784/*
1735 * Wait for the urandom pool to be seeded and thus guaranteed to supply 1785 * Wait for the urandom pool to be seeded and thus guaranteed to supply
1736 * cryptographically secure random numbers. This applies to: the /dev/urandom 1786 * cryptographically secure random numbers. This applies to: the /dev/urandom
@@ -1745,7 +1795,17 @@ int wait_for_random_bytes(void)
1745{ 1795{
1746 if (likely(crng_ready())) 1796 if (likely(crng_ready()))
1747 return 0; 1797 return 0;
1748 return wait_event_interruptible(crng_init_wait, crng_ready()); 1798
1799 do {
1800 int ret;
1801 ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
1802 if (ret)
1803 return ret > 0 ? 0 : ret;
1804
1805 try_to_generate_entropy();
1806 } while (!crng_ready());
1807
1808 return 0;
1749} 1809}
1750EXPORT_SYMBOL(wait_for_random_bytes); 1810EXPORT_SYMBOL(wait_for_random_bytes);
1751 1811