diff options
Diffstat (limited to 'lib/random32.c')
| -rw-r--r-- | lib/random32.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/lib/random32.c b/lib/random32.c index ca87d86992bd..217d5c4b666d 100644 --- a/lib/random32.c +++ b/lib/random32.c | |||
| @@ -56,23 +56,12 @@ static u32 __random32(struct rnd_state *state) | |||
| 56 | return (state->s1 ^ state->s2 ^ state->s3); | 56 | return (state->s1 ^ state->s2 ^ state->s3); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static void __set_random32(struct rnd_state *state, unsigned long s) | 59 | /* |
| 60 | * Handle minimum values for seeds | ||
| 61 | */ | ||
| 62 | static inline u32 __seed(u32 x, u32 m) | ||
| 60 | { | 63 | { |
| 61 | if (s == 0) | 64 | return (x < m) ? x + m : x; |
| 62 | s = 1; /* default seed is 1 */ | ||
| 63 | |||
| 64 | #define LCG(n) (69069 * n) | ||
| 65 | state->s1 = LCG(s); | ||
| 66 | state->s2 = LCG(state->s1); | ||
| 67 | state->s3 = LCG(state->s2); | ||
| 68 | |||
| 69 | /* "warm it up" */ | ||
| 70 | __random32(state); | ||
| 71 | __random32(state); | ||
| 72 | __random32(state); | ||
| 73 | __random32(state); | ||
| 74 | __random32(state); | ||
| 75 | __random32(state); | ||
| 76 | } | 65 | } |
| 77 | 66 | ||
| 78 | /** | 67 | /** |
| @@ -107,7 +96,7 @@ void srandom32(u32 entropy) | |||
| 107 | */ | 96 | */ |
| 108 | for_each_possible_cpu (i) { | 97 | for_each_possible_cpu (i) { |
| 109 | struct rnd_state *state = &per_cpu(net_rand_state, i); | 98 | struct rnd_state *state = &per_cpu(net_rand_state, i); |
| 110 | __set_random32(state, state->s1 ^ entropy); | 99 | state->s1 = __seed(state->s1 ^ entropy, 1); |
| 111 | } | 100 | } |
| 112 | } | 101 | } |
| 113 | EXPORT_SYMBOL(srandom32); | 102 | EXPORT_SYMBOL(srandom32); |
| @@ -122,7 +111,19 @@ static int __init random32_init(void) | |||
| 122 | 111 | ||
| 123 | for_each_possible_cpu(i) { | 112 | for_each_possible_cpu(i) { |
| 124 | struct rnd_state *state = &per_cpu(net_rand_state,i); | 113 | struct rnd_state *state = &per_cpu(net_rand_state,i); |
| 125 | __set_random32(state, i + jiffies); | 114 | |
| 115 | #define LCG(x) ((x) * 69069) /* super-duper LCG */ | ||
| 116 | state->s1 = __seed(LCG(i + jiffies), 1); | ||
| 117 | state->s2 = __seed(LCG(state->s1), 7); | ||
| 118 | state->s3 = __seed(LCG(state->s2), 15); | ||
| 119 | |||
| 120 | /* "warm it up" */ | ||
| 121 | __random32(state); | ||
| 122 | __random32(state); | ||
| 123 | __random32(state); | ||
| 124 | __random32(state); | ||
| 125 | __random32(state); | ||
| 126 | __random32(state); | ||
| 126 | } | 127 | } |
| 127 | return 0; | 128 | return 0; |
| 128 | } | 129 | } |
| @@ -135,13 +136,18 @@ core_initcall(random32_init); | |||
| 135 | static int __init random32_reseed(void) | 136 | static int __init random32_reseed(void) |
| 136 | { | 137 | { |
| 137 | int i; | 138 | int i; |
| 138 | unsigned long seed; | ||
| 139 | 139 | ||
| 140 | for_each_possible_cpu(i) { | 140 | for_each_possible_cpu(i) { |
| 141 | struct rnd_state *state = &per_cpu(net_rand_state,i); | 141 | struct rnd_state *state = &per_cpu(net_rand_state,i); |
| 142 | u32 seeds[3]; | ||
| 143 | |||
| 144 | get_random_bytes(&seeds, sizeof(seeds)); | ||
| 145 | state->s1 = __seed(seeds[0], 1); | ||
| 146 | state->s2 = __seed(seeds[1], 7); | ||
| 147 | state->s3 = __seed(seeds[2], 15); | ||
| 142 | 148 | ||
| 143 | get_random_bytes(&seed, sizeof(seed)); | 149 | /* mix it in */ |
| 144 | __set_random32(state, seed); | 150 | __random32(state); |
| 145 | } | 151 | } |
| 146 | return 0; | 152 | return 0; |
| 147 | } | 153 | } |
