mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	random32: seeding improvement
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>
This commit is contained in:
		
							parent
							
								
									4adf0af681
								
							
						
					
					
						commit
						697f8d0348
					
				
					 1 changed files with 27 additions and 21 deletions
				
			
		| 
						 | 
					@ -56,23 +56,12 @@ static u32 __random32(struct rnd_state *state)
 | 
				
			||||||
	return (state->s1 ^ state->s2 ^ state->s3);
 | 
						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)
 | 
						return (x < m) ? x + m : x;
 | 
				
			||||||
		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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -107,7 +96,7 @@ void srandom32(u32 entropy)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	for_each_possible_cpu (i) {
 | 
						for_each_possible_cpu (i) {
 | 
				
			||||||
		struct rnd_state *state = &per_cpu(net_rand_state, 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);
 | 
					EXPORT_SYMBOL(srandom32);
 | 
				
			||||||
| 
						 | 
					@ -122,7 +111,19 @@ static int __init random32_init(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for_each_possible_cpu(i) {
 | 
						for_each_possible_cpu(i) {
 | 
				
			||||||
		struct rnd_state *state = &per_cpu(net_rand_state,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;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -135,13 +136,18 @@ core_initcall(random32_init);
 | 
				
			||||||
static int __init random32_reseed(void)
 | 
					static int __init random32_reseed(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned long seed;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for_each_possible_cpu(i) {
 | 
						for_each_possible_cpu(i) {
 | 
				
			||||||
		struct rnd_state *state = &per_cpu(net_rand_state,i);
 | 
							struct rnd_state *state = &per_cpu(net_rand_state,i);
 | 
				
			||||||
 | 
							u32 seeds[3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		get_random_bytes(&seed, sizeof(seed));
 | 
							get_random_bytes(&seeds, sizeof(seeds));
 | 
				
			||||||
		__set_random32(state, seed);
 | 
							state->s1 = __seed(seeds[0], 1);
 | 
				
			||||||
 | 
							state->s2 = __seed(seeds[1], 7);
 | 
				
			||||||
 | 
							state->s3 = __seed(seeds[2], 15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* mix it in */
 | 
				
			||||||
 | 
							__random32(state);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue