aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2013-11-11 06:20:34 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-11 14:32:14 -0500
commit4af712e8df998475736f3e2727701bd31e3751a9 (patch)
tree315b7092cf6ee0aeb3a180a09f8d628984cd9ddf /lib
parent6d31920246a9fc80be4f16acd27c0bbe8d7b8494 (diff)
random32: add prandom_reseed_late() and call when nonblocking pool becomes initialized
The Tausworthe PRNG is initialized at late_initcall time. At that time the entropy pool serving get_random_bytes is not filled sufficiently. This patch adds an additional reseeding step as soon as the nonblocking pool gets marked as initialized. On some machines it might be possible that late_initcall gets called after the pool has been initialized. In this situation we won't reseed again. (A call to prandom_seed_late blocks later invocations of early reseed attempts.) Joint work with Daniel Borkmann. Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/random32.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/random32.c b/lib/random32.c
index 12215df701e8..9f2f2fb03dfe 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -200,9 +200,18 @@ static void prandom_start_seed_timer(void)
200 * Generate better values after random number generator 200 * Generate better values after random number generator
201 * is fully initialized. 201 * is fully initialized.
202 */ 202 */
203static int __init prandom_reseed(void) 203static void __prandom_reseed(bool late)
204{ 204{
205 int i; 205 int i;
206 unsigned long flags;
207 static bool latch = false;
208 static DEFINE_SPINLOCK(lock);
209
210 /* only allow initial seeding (late == false) once */
211 spin_lock_irqsave(&lock, flags);
212 if (latch && !late)
213 goto out;
214 latch = true;
206 215
207 for_each_possible_cpu(i) { 216 for_each_possible_cpu(i) {
208 struct rnd_state *state = &per_cpu(net_rand_state,i); 217 struct rnd_state *state = &per_cpu(net_rand_state,i);
@@ -216,6 +225,18 @@ static int __init prandom_reseed(void)
216 /* mix it in */ 225 /* mix it in */
217 prandom_u32_state(state); 226 prandom_u32_state(state);
218 } 227 }
228out:
229 spin_unlock_irqrestore(&lock, flags);
230}
231
232void prandom_reseed_late(void)
233{
234 __prandom_reseed(true);
235}
236
237static int __init prandom_reseed(void)
238{
239 __prandom_reseed(false);
219 prandom_start_seed_timer(); 240 prandom_start_seed_timer();
220 return 0; 241 return 0;
221} 242}