aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-09-22 16:04:19 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-10-10 14:32:21 -0400
commit6e9fa2c8a630e6d0882828012431038abce285b9 (patch)
tree086a393d401c89e2d0f31699199676e9e1fdab85 /drivers
parent655b226470b229552ad95b21323864df9bd9fc74 (diff)
random: adjust the generator polynomials in the mixing function slightly
Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and Videau in their paper, "The Linux Pseudorandom Number Generator Revisited" (see: http://eprint.iacr.org/2012/251.pdf). They suggested a slight change to improve our mixing functions slightly. I also adjusted the comments to better explain what is going on, and to document why the polynomials were changed. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/random.c103
1 files changed, 49 insertions, 54 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 74eeec58e779..7ae7ea65da68 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -322,23 +322,61 @@ static const int trickle_thresh = (INPUT_POOL_WORDS * 28) << ENTROPY_SHIFT;
322static DEFINE_PER_CPU(int, trickle_count); 322static DEFINE_PER_CPU(int, trickle_count);
323 323
324/* 324/*
325 * A pool of size .poolwords is stirred with a primitive polynomial 325 * Originally, we used a primitive polynomial of degree .poolwords
326 * of degree .poolwords over GF(2). The taps for various sizes are 326 * over GF(2). The taps for various sizes are defined below. They
327 * defined below. They are chosen to be evenly spaced (minimum RMS 327 * were chosen to be evenly spaced except for the last tap, which is 1
328 * distance from evenly spaced; the numbers in the comments are a 328 * to get the twisting happening as fast as possible.
329 * scaled squared error sum) except for the last tap, which is 1 to 329 *
330 * get the twisting happening as fast as possible. 330 * For the purposes of better mixing, we use the CRC-32 polynomial as
331 * well to make a (modified) twisted Generalized Feedback Shift
332 * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR
333 * generators. ACM Transactions on Modeling and Computer Simulation
334 * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted
335 * GFSR generators II. ACM Transactions on Mdeling and Computer
336 * Simulation 4:254-266)
337 *
338 * Thanks to Colin Plumb for suggesting this.
339 *
340 * The mixing operation is much less sensitive than the output hash,
341 * where we use SHA-1. All that we want of mixing operation is that
342 * it be a good non-cryptographic hash; i.e. it not produce collisions
343 * when fed "random" data of the sort we expect to see. As long as
344 * the pool state differs for different inputs, we have preserved the
345 * input entropy and done a good job. The fact that an intelligent
346 * attacker can construct inputs that will produce controlled
347 * alterations to the pool's state is not important because we don't
348 * consider such inputs to contribute any randomness. The only
349 * property we need with respect to them is that the attacker can't
350 * increase his/her knowledge of the pool's state. Since all
351 * additions are reversible (knowing the final state and the input,
352 * you can reconstruct the initial state), if an attacker has any
353 * uncertainty about the initial state, he/she can only shuffle that
354 * uncertainty about, but never cause any collisions (which would
355 * decrease the uncertainty).
356 *
357 * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and
358 * Videau in their paper, "The Linux Pseudorandom Number Generator
359 * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their
360 * paper, they point out that we are not using a true Twisted GFSR,
361 * since Matsumoto & Kurita used a trinomial feedback polynomial (that
362 * is, with only three taps, instead of the six that we are using).
363 * As a result, the resulting polynomial is neither primitive nor
364 * irreducible, and hence does not have a maximal period over
365 * GF(2**32). They suggest a slight change to the generator
366 * polynomial which improves the resulting TGFSR polynomial to be
367 * irreducible, which we have made here.
331 */ 368 */
332
333static struct poolinfo { 369static struct poolinfo {
334 int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits; 370 int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits;
335#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5) 371#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5)
336 int tap1, tap2, tap3, tap4, tap5; 372 int tap1, tap2, tap3, tap4, tap5;
337} poolinfo_table[] = { 373} poolinfo_table[] = {
338 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ 374 /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
339 { S(128), 103, 76, 51, 25, 1 }, 375 /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
340 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ 376 { S(128), 104, 76, 51, 25, 1 },
341 { S(32), 26, 20, 14, 7, 1 }, 377 /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */
378 /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */
379 { S(32), 26, 19, 14, 7, 1 },
342#if 0 380#if 0
343 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ 381 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
344 { S(2048), 1638, 1231, 819, 411, 1 }, 382 { S(2048), 1638, 1231, 819, 411, 1 },
@@ -369,49 +407,6 @@ static struct poolinfo {
369}; 407};
370 408
371/* 409/*
372 * For the purposes of better mixing, we use the CRC-32 polynomial as
373 * well to make a twisted Generalized Feedback Shift Reigster
374 *
375 * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM
376 * Transactions on Modeling and Computer Simulation 2(3):179-194.
377 * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators
378 * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266)
379 *
380 * Thanks to Colin Plumb for suggesting this.
381 *
382 * We have not analyzed the resultant polynomial to prove it primitive;
383 * in fact it almost certainly isn't. Nonetheless, the irreducible factors
384 * of a random large-degree polynomial over GF(2) are more than large enough
385 * that periodicity is not a concern.
386 *
387 * The input hash is much less sensitive than the output hash. All
388 * that we want of it is that it be a good non-cryptographic hash;
389 * i.e. it not produce collisions when fed "random" data of the sort
390 * we expect to see. As long as the pool state differs for different
391 * inputs, we have preserved the input entropy and done a good job.
392 * The fact that an intelligent attacker can construct inputs that
393 * will produce controlled alterations to the pool's state is not
394 * important because we don't consider such inputs to contribute any
395 * randomness. The only property we need with respect to them is that
396 * the attacker can't increase his/her knowledge of the pool's state.
397 * Since all additions are reversible (knowing the final state and the
398 * input, you can reconstruct the initial state), if an attacker has
399 * any uncertainty about the initial state, he/she can only shuffle
400 * that uncertainty about, but never cause any collisions (which would
401 * decrease the uncertainty).
402 *
403 * The chosen system lets the state of the pool be (essentially) the input
404 * modulo the generator polymnomial. Now, for random primitive polynomials,
405 * this is a universal class of hash functions, meaning that the chance
406 * of a collision is limited by the attacker's knowledge of the generator
407 * polynomail, so if it is chosen at random, an attacker can never force
408 * a collision. Here, we use a fixed polynomial, but we *can* assume that
409 * ###--> it is unknown to the processes generating the input entropy. <-###
410 * Because of this important property, this is a good, collision-resistant
411 * hash; hash collisions will occur no more often than chance.
412 */
413
414/*
415 * Static global variables 410 * Static global variables
416 */ 411 */
417static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); 412static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);