Skip to content

Commit

Permalink
random32: seeding improvement
Browse files Browse the repository at this point in the history
The rationale is:
   * use u32 consistently
   * no need to do LCG on values from (better) get_random_bytes
   * use more data from get_random_bytes for secondary seeding
   * don't reduce state space on srandom32()
   * enforce state variable initialization restrictions

Note: the second paper has a version of random32() with even longer period
and a version of random64() if needed.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jul 30, 2008
1 parent 4adf0af commit 697f8d0
Showing 1 changed file with 27 additions and 21 deletions.
48 changes: 27 additions & 21 deletions lib/random32.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,12 @@ static u32 __random32(struct rnd_state *state)
return (state->s1 ^ state->s2 ^ state->s3);
}

static void __set_random32(struct rnd_state *state, unsigned long s)
/*
* Handle minimum values for seeds
*/
static inline u32 __seed(u32 x, u32 m)
{
if (s == 0)
s = 1; /* default seed is 1 */

#define LCG(n) (69069 * n)
state->s1 = LCG(s);
state->s2 = LCG(state->s1);
state->s3 = LCG(state->s2);

/* "warm it up" */
__random32(state);
__random32(state);
__random32(state);
__random32(state);
__random32(state);
__random32(state);
return (x < m) ? x + m : x;
}

/**
Expand Down Expand Up @@ -107,7 +96,7 @@ void srandom32(u32 entropy)
*/
for_each_possible_cpu (i) {
struct rnd_state *state = &per_cpu(net_rand_state, i);
__set_random32(state, state->s1 ^ entropy);
state->s1 = __seed(state->s1 ^ entropy, 1);
}
}
EXPORT_SYMBOL(srandom32);
Expand All @@ -122,7 +111,19 @@ static int __init random32_init(void)

for_each_possible_cpu(i) {
struct rnd_state *state = &per_cpu(net_rand_state,i);
__set_random32(state, i + jiffies);

#define LCG(x) ((x) * 69069) /* super-duper LCG */
state->s1 = __seed(LCG(i + jiffies), 1);
state->s2 = __seed(LCG(state->s1), 7);
state->s3 = __seed(LCG(state->s2), 15);

/* "warm it up" */
__random32(state);
__random32(state);
__random32(state);
__random32(state);
__random32(state);
__random32(state);
}
return 0;
}
Expand All @@ -135,13 +136,18 @@ core_initcall(random32_init);
static int __init random32_reseed(void)
{
int i;
unsigned long seed;

for_each_possible_cpu(i) {
struct rnd_state *state = &per_cpu(net_rand_state,i);
u32 seeds[3];

get_random_bytes(&seeds, sizeof(seeds));
state->s1 = __seed(seeds[0], 1);
state->s2 = __seed(seeds[1], 7);
state->s3 = __seed(seeds[2], 15);

get_random_bytes(&seed, sizeof(seed));
__set_random32(state, seed);
/* mix it in */
__random32(state);
}
return 0;
}
Expand Down

0 comments on commit 697f8d0

Please sign in to comment.