aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/random32.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/lib/random32.c b/lib/random32.c
index fa5da61ce7ad..c9b6bf3afe0c 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -40,6 +40,10 @@
40 40
41#ifdef CONFIG_RANDOM32_SELFTEST 41#ifdef CONFIG_RANDOM32_SELFTEST
42static void __init prandom_state_selftest(void); 42static void __init prandom_state_selftest(void);
43#else
44static inline void prandom_state_selftest(void)
45{
46}
43#endif 47#endif
44 48
45static DEFINE_PER_CPU(struct rnd_state, net_rand_state); 49static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
@@ -53,8 +57,7 @@ static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
53 */ 57 */
54u32 prandom_u32_state(struct rnd_state *state) 58u32 prandom_u32_state(struct rnd_state *state)
55{ 59{
56#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) 60#define TAUSWORTHE(s, a, b, c, d) ((s & c) << d) ^ (((s << a) ^ s) >> b)
57
58 state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U); 61 state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U);
59 state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U); 62 state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U);
60 state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U); 63 state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U);
@@ -147,21 +150,25 @@ static void prandom_warmup(struct rnd_state *state)
147 prandom_u32_state(state); 150 prandom_u32_state(state);
148} 151}
149 152
150static void prandom_seed_very_weak(struct rnd_state *state, u32 seed) 153static u32 __extract_hwseed(void)
151{ 154{
152 /* Note: This sort of seeding is ONLY used in test cases and 155 u32 val = 0;
153 * during boot at the time from core_initcall until late_initcall 156
154 * as we don't have a stronger entropy source available yet. 157 (void)(arch_get_random_seed_int(&val) ||
155 * After late_initcall, we reseed entire state, we have to (!), 158 arch_get_random_int(&val));
156 * otherwise an attacker just needs to search 32 bit space to 159
157 * probe for our internal 128 bit state if he knows a couple 160 return val;
158 * of prandom32 outputs! 161}
159 */ 162
160#define LCG(x) ((x) * 69069U) /* super-duper LCG */ 163static void prandom_seed_early(struct rnd_state *state, u32 seed,
161 state->s1 = __seed(LCG(seed), 2U); 164 bool mix_with_hwseed)
162 state->s2 = __seed(LCG(state->s1), 8U); 165{
163 state->s3 = __seed(LCG(state->s2), 16U); 166#define LCG(x) ((x) * 69069U) /* super-duper LCG */
164 state->s4 = __seed(LCG(state->s3), 128U); 167#define HWSEED() (mix_with_hwseed ? __extract_hwseed() : 0)
168 state->s1 = __seed(HWSEED() ^ LCG(seed), 2U);
169 state->s2 = __seed(HWSEED() ^ LCG(state->s1), 8U);
170 state->s3 = __seed(HWSEED() ^ LCG(state->s2), 16U);
171 state->s4 = __seed(HWSEED() ^ LCG(state->s3), 128U);
165} 172}
166 173
167/** 174/**
@@ -194,14 +201,13 @@ static int __init prandom_init(void)
194{ 201{
195 int i; 202 int i;
196 203
197#ifdef CONFIG_RANDOM32_SELFTEST
198 prandom_state_selftest(); 204 prandom_state_selftest();
199#endif
200 205
201 for_each_possible_cpu(i) { 206 for_each_possible_cpu(i) {
202 struct rnd_state *state = &per_cpu(net_rand_state,i); 207 struct rnd_state *state = &per_cpu(net_rand_state,i);
208 u32 weak_seed = (i + jiffies) ^ random_get_entropy();
203 209
204 prandom_seed_very_weak(state, (i + jiffies) ^ random_get_entropy()); 210 prandom_seed_early(state, weak_seed, true);
205 prandom_warmup(state); 211 prandom_warmup(state);
206 } 212 }
207 213
@@ -210,6 +216,7 @@ static int __init prandom_init(void)
210core_initcall(prandom_init); 216core_initcall(prandom_init);
211 217
212static void __prandom_timer(unsigned long dontcare); 218static void __prandom_timer(unsigned long dontcare);
219
213static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0); 220static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0);
214 221
215static void __prandom_timer(unsigned long dontcare) 222static void __prandom_timer(unsigned long dontcare)
@@ -419,7 +426,7 @@ static void __init prandom_state_selftest(void)
419 for (i = 0; i < ARRAY_SIZE(test1); i++) { 426 for (i = 0; i < ARRAY_SIZE(test1); i++) {
420 struct rnd_state state; 427 struct rnd_state state;
421 428
422 prandom_seed_very_weak(&state, test1[i].seed); 429 prandom_seed_early(&state, test1[i].seed, false);
423 prandom_warmup(&state); 430 prandom_warmup(&state);
424 431
425 if (test1[i].result != prandom_u32_state(&state)) 432 if (test1[i].result != prandom_u32_state(&state))
@@ -434,7 +441,7 @@ static void __init prandom_state_selftest(void)
434 for (i = 0; i < ARRAY_SIZE(test2); i++) { 441 for (i = 0; i < ARRAY_SIZE(test2); i++) {
435 struct rnd_state state; 442 struct rnd_state state;
436 443
437 prandom_seed_very_weak(&state, test2[i].seed); 444 prandom_seed_early(&state, test2[i].seed, false);
438 prandom_warmup(&state); 445 prandom_warmup(&state);
439 446
440 for (j = 0; j < test2[i].iteration - 1; j++) 447 for (j = 0; j < test2[i].iteration - 1; j++)