diff options
-rw-r--r-- | drivers/char/random.c | 647 | ||||
-rw-r--r-- | include/trace/events/random.h | 183 |
2 files changed, 587 insertions, 243 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 4fe5609eeb72..429b75bb60e8 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -255,6 +255,7 @@ | |||
255 | #include <linux/fips.h> | 255 | #include <linux/fips.h> |
256 | #include <linux/ptrace.h> | 256 | #include <linux/ptrace.h> |
257 | #include <linux/kmemcheck.h> | 257 | #include <linux/kmemcheck.h> |
258 | #include <linux/workqueue.h> | ||
258 | #include <linux/irq.h> | 259 | #include <linux/irq.h> |
259 | 260 | ||
260 | #include <asm/processor.h> | 261 | #include <asm/processor.h> |
@@ -269,14 +270,28 @@ | |||
269 | /* | 270 | /* |
270 | * Configuration information | 271 | * Configuration information |
271 | */ | 272 | */ |
272 | #define INPUT_POOL_WORDS 128 | 273 | #define INPUT_POOL_SHIFT 12 |
273 | #define OUTPUT_POOL_WORDS 32 | 274 | #define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) |
274 | #define SEC_XFER_SIZE 512 | 275 | #define OUTPUT_POOL_SHIFT 10 |
275 | #define EXTRACT_SIZE 10 | 276 | #define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) |
277 | #define SEC_XFER_SIZE 512 | ||
278 | #define EXTRACT_SIZE 10 | ||
279 | |||
280 | #define DEBUG_RANDOM_BOOT 0 | ||
276 | 281 | ||
277 | #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) | 282 | #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) |
278 | 283 | ||
279 | /* | 284 | /* |
285 | * To allow fractional bits to be tracked, the entropy_count field is | ||
286 | * denominated in units of 1/8th bits. | ||
287 | * | ||
288 | * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in | ||
289 | * credit_entropy_bits() needs to be 64 bits wide. | ||
290 | */ | ||
291 | #define ENTROPY_SHIFT 3 | ||
292 | #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT) | ||
293 | |||
294 | /* | ||
280 | * The minimum number of bits of entropy before we wake up a read on | 295 | * The minimum number of bits of entropy before we wake up a read on |
281 | * /dev/random. Should be enough to do a significant reseed. | 296 | * /dev/random. Should be enough to do a significant reseed. |
282 | */ | 297 | */ |
@@ -287,108 +302,100 @@ static int random_read_wakeup_thresh = 64; | |||
287 | * should wake up processes which are selecting or polling on write | 302 | * should wake up processes which are selecting or polling on write |
288 | * access to /dev/random. | 303 | * access to /dev/random. |
289 | */ | 304 | */ |
290 | static int random_write_wakeup_thresh = 128; | 305 | static int random_write_wakeup_thresh = 28 * OUTPUT_POOL_WORDS; |
291 | 306 | ||
292 | /* | 307 | /* |
293 | * When the input pool goes over trickle_thresh, start dropping most | 308 | * The minimum number of seconds between urandom pool resending. We |
294 | * samples to avoid wasting CPU time and reduce lock contention. | 309 | * do this to limit the amount of entropy that can be drained from the |
310 | * input pool even if there are heavy demands on /dev/urandom. | ||
295 | */ | 311 | */ |
296 | 312 | static int random_min_urandom_seed = 60; | |
297 | static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28; | ||
298 | |||
299 | static DEFINE_PER_CPU(int, trickle_count); | ||
300 | 313 | ||
301 | /* | 314 | /* |
302 | * A pool of size .poolwords is stirred with a primitive polynomial | 315 | * Originally, we used a primitive polynomial of degree .poolwords |
303 | * of degree .poolwords over GF(2). The taps for various sizes are | 316 | * over GF(2). The taps for various sizes are defined below. They |
304 | * defined below. They are chosen to be evenly spaced (minimum RMS | 317 | * were chosen to be evenly spaced except for the last tap, which is 1 |
305 | * distance from evenly spaced; the numbers in the comments are a | 318 | * to get the twisting happening as fast as possible. |
306 | * scaled squared error sum) except for the last tap, which is 1 to | 319 | * |
307 | * get the twisting happening as fast as possible. | 320 | * For the purposes of better mixing, we use the CRC-32 polynomial as |
321 | * well to make a (modified) twisted Generalized Feedback Shift | ||
322 | * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR | ||
323 | * generators. ACM Transactions on Modeling and Computer Simulation | ||
324 | * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted | ||
325 | * GFSR generators II. ACM Transactions on Mdeling and Computer | ||
326 | * Simulation 4:254-266) | ||
327 | * | ||
328 | * Thanks to Colin Plumb for suggesting this. | ||
329 | * | ||
330 | * The mixing operation is much less sensitive than the output hash, | ||
331 | * where we use SHA-1. All that we want of mixing operation is that | ||
332 | * it be a good non-cryptographic hash; i.e. it not produce collisions | ||
333 | * when fed "random" data of the sort we expect to see. As long as | ||
334 | * the pool state differs for different inputs, we have preserved the | ||
335 | * input entropy and done a good job. The fact that an intelligent | ||
336 | * attacker can construct inputs that will produce controlled | ||
337 | * alterations to the pool's state is not important because we don't | ||
338 | * consider such inputs to contribute any randomness. The only | ||
339 | * property we need with respect to them is that the attacker can't | ||
340 | * increase his/her knowledge of the pool's state. Since all | ||
341 | * additions are reversible (knowing the final state and the input, | ||
342 | * you can reconstruct the initial state), if an attacker has any | ||
343 | * uncertainty about the initial state, he/she can only shuffle that | ||
344 | * uncertainty about, but never cause any collisions (which would | ||
345 | * decrease the uncertainty). | ||
346 | * | ||
347 | * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and | ||
348 | * Videau in their paper, "The Linux Pseudorandom Number Generator | ||
349 | * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their | ||
350 | * paper, they point out that we are not using a true Twisted GFSR, | ||
351 | * since Matsumoto & Kurita used a trinomial feedback polynomial (that | ||
352 | * is, with only three taps, instead of the six that we are using). | ||
353 | * As a result, the resulting polynomial is neither primitive nor | ||
354 | * irreducible, and hence does not have a maximal period over | ||
355 | * GF(2**32). They suggest a slight change to the generator | ||
356 | * polynomial which improves the resulting TGFSR polynomial to be | ||
357 | * irreducible, which we have made here. | ||
308 | */ | 358 | */ |
309 | static struct poolinfo { | 359 | static struct poolinfo { |
310 | int poolwords; | 360 | int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits; |
361 | #define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5) | ||
311 | int tap1, tap2, tap3, tap4, tap5; | 362 | int tap1, tap2, tap3, tap4, tap5; |
312 | } poolinfo_table[] = { | 363 | } poolinfo_table[] = { |
313 | /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ | 364 | /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */ |
314 | { 128, 103, 76, 51, 25, 1 }, | 365 | /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */ |
315 | /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ | 366 | { S(128), 104, 76, 51, 25, 1 }, |
316 | { 32, 26, 20, 14, 7, 1 }, | 367 | /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */ |
368 | /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */ | ||
369 | { S(32), 26, 19, 14, 7, 1 }, | ||
317 | #if 0 | 370 | #if 0 |
318 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ | 371 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ |
319 | { 2048, 1638, 1231, 819, 411, 1 }, | 372 | { S(2048), 1638, 1231, 819, 411, 1 }, |
320 | 373 | ||
321 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ | 374 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ |
322 | { 1024, 817, 615, 412, 204, 1 }, | 375 | { S(1024), 817, 615, 412, 204, 1 }, |
323 | 376 | ||
324 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ | 377 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ |
325 | { 1024, 819, 616, 410, 207, 2 }, | 378 | { S(1024), 819, 616, 410, 207, 2 }, |
326 | 379 | ||
327 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ | 380 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ |
328 | { 512, 411, 308, 208, 104, 1 }, | 381 | { S(512), 411, 308, 208, 104, 1 }, |
329 | 382 | ||
330 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ | 383 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ |
331 | { 512, 409, 307, 206, 102, 2 }, | 384 | { S(512), 409, 307, 206, 102, 2 }, |
332 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ | 385 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ |
333 | { 512, 409, 309, 205, 103, 2 }, | 386 | { S(512), 409, 309, 205, 103, 2 }, |
334 | 387 | ||
335 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ | 388 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ |
336 | { 256, 205, 155, 101, 52, 1 }, | 389 | { S(256), 205, 155, 101, 52, 1 }, |
337 | 390 | ||
338 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ | 391 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ |
339 | { 128, 103, 78, 51, 27, 2 }, | 392 | { S(128), 103, 78, 51, 27, 2 }, |
340 | 393 | ||
341 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ | 394 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ |
342 | { 64, 52, 39, 26, 14, 1 }, | 395 | { S(64), 52, 39, 26, 14, 1 }, |
343 | #endif | 396 | #endif |
344 | }; | 397 | }; |
345 | 398 | ||
346 | #define POOLBITS poolwords*32 | ||
347 | #define POOLBYTES poolwords*4 | ||
348 | |||
349 | /* | ||
350 | * For the purposes of better mixing, we use the CRC-32 polynomial as | ||
351 | * well to make a twisted Generalized Feedback Shift Reigster | ||
352 | * | ||
353 | * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM | ||
354 | * Transactions on Modeling and Computer Simulation 2(3):179-194. | ||
355 | * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators | ||
356 | * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266) | ||
357 | * | ||
358 | * Thanks to Colin Plumb for suggesting this. | ||
359 | * | ||
360 | * We have not analyzed the resultant polynomial to prove it primitive; | ||
361 | * in fact it almost certainly isn't. Nonetheless, the irreducible factors | ||
362 | * of a random large-degree polynomial over GF(2) are more than large enough | ||
363 | * that periodicity is not a concern. | ||
364 | * | ||
365 | * The input hash is much less sensitive than the output hash. All | ||
366 | * that we want of it is that it be a good non-cryptographic hash; | ||
367 | * i.e. it not produce collisions when fed "random" data of the sort | ||
368 | * we expect to see. As long as the pool state differs for different | ||
369 | * inputs, we have preserved the input entropy and done a good job. | ||
370 | * The fact that an intelligent attacker can construct inputs that | ||
371 | * will produce controlled alterations to the pool's state is not | ||
372 | * important because we don't consider such inputs to contribute any | ||
373 | * randomness. The only property we need with respect to them is that | ||
374 | * the attacker can't increase his/her knowledge of the pool's state. | ||
375 | * Since all additions are reversible (knowing the final state and the | ||
376 | * input, you can reconstruct the initial state), if an attacker has | ||
377 | * any uncertainty about the initial state, he/she can only shuffle | ||
378 | * that uncertainty about, but never cause any collisions (which would | ||
379 | * decrease the uncertainty). | ||
380 | * | ||
381 | * The chosen system lets the state of the pool be (essentially) the input | ||
382 | * modulo the generator polymnomial. Now, for random primitive polynomials, | ||
383 | * this is a universal class of hash functions, meaning that the chance | ||
384 | * of a collision is limited by the attacker's knowledge of the generator | ||
385 | * polynomail, so if it is chosen at random, an attacker can never force | ||
386 | * a collision. Here, we use a fixed polynomial, but we *can* assume that | ||
387 | * ###--> it is unknown to the processes generating the input entropy. <-### | ||
388 | * Because of this important property, this is a good, collision-resistant | ||
389 | * hash; hash collisions will occur no more often than chance. | ||
390 | */ | ||
391 | |||
392 | /* | 399 | /* |
393 | * Static global variables | 400 | * Static global variables |
394 | */ | 401 | */ |
@@ -396,17 +403,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | |||
396 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 403 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
397 | static struct fasync_struct *fasync; | 404 | static struct fasync_struct *fasync; |
398 | 405 | ||
399 | static bool debug; | ||
400 | module_param(debug, bool, 0644); | ||
401 | #define DEBUG_ENT(fmt, arg...) do { \ | ||
402 | if (debug) \ | ||
403 | printk(KERN_DEBUG "random %04d %04d %04d: " \ | ||
404 | fmt,\ | ||
405 | input_pool.entropy_count,\ | ||
406 | blocking_pool.entropy_count,\ | ||
407 | nonblocking_pool.entropy_count,\ | ||
408 | ## arg); } while (0) | ||
409 | |||
410 | /********************************************************************** | 406 | /********************************************************************** |
411 | * | 407 | * |
412 | * OS independent entropy store. Here are the functions which handle | 408 | * OS independent entropy store. Here are the functions which handle |
@@ -417,23 +413,26 @@ module_param(debug, bool, 0644); | |||
417 | struct entropy_store; | 413 | struct entropy_store; |
418 | struct entropy_store { | 414 | struct entropy_store { |
419 | /* read-only data: */ | 415 | /* read-only data: */ |
420 | struct poolinfo *poolinfo; | 416 | const struct poolinfo *poolinfo; |
421 | __u32 *pool; | 417 | __u32 *pool; |
422 | const char *name; | 418 | const char *name; |
423 | struct entropy_store *pull; | 419 | struct entropy_store *pull; |
424 | int limit; | 420 | struct work_struct push_work; |
425 | 421 | ||
426 | /* read-write data: */ | 422 | /* read-write data: */ |
423 | unsigned long last_pulled; | ||
427 | spinlock_t lock; | 424 | spinlock_t lock; |
428 | unsigned add_ptr; | 425 | unsigned short add_ptr; |
429 | unsigned input_rotate; | 426 | unsigned short input_rotate; |
430 | int entropy_count; | 427 | int entropy_count; |
431 | int entropy_total; | 428 | int entropy_total; |
432 | unsigned int initialized:1; | 429 | unsigned int initialized:1; |
433 | bool last_data_init; | 430 | unsigned int limit:1; |
431 | unsigned int last_data_init:1; | ||
434 | __u8 last_data[EXTRACT_SIZE]; | 432 | __u8 last_data[EXTRACT_SIZE]; |
435 | }; | 433 | }; |
436 | 434 | ||
435 | static void push_to_pool(struct work_struct *work); | ||
437 | static __u32 input_pool_data[INPUT_POOL_WORDS]; | 436 | static __u32 input_pool_data[INPUT_POOL_WORDS]; |
438 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; | 437 | static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; |
439 | static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; | 438 | static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; |
@@ -452,7 +451,9 @@ static struct entropy_store blocking_pool = { | |||
452 | .limit = 1, | 451 | .limit = 1, |
453 | .pull = &input_pool, | 452 | .pull = &input_pool, |
454 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), | 453 | .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), |
455 | .pool = blocking_pool_data | 454 | .pool = blocking_pool_data, |
455 | .push_work = __WORK_INITIALIZER(blocking_pool.push_work, | ||
456 | push_to_pool), | ||
456 | }; | 457 | }; |
457 | 458 | ||
458 | static struct entropy_store nonblocking_pool = { | 459 | static struct entropy_store nonblocking_pool = { |
@@ -460,7 +461,9 @@ static struct entropy_store nonblocking_pool = { | |||
460 | .name = "nonblocking", | 461 | .name = "nonblocking", |
461 | .pull = &input_pool, | 462 | .pull = &input_pool, |
462 | .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), | 463 | .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock), |
463 | .pool = nonblocking_pool_data | 464 | .pool = nonblocking_pool_data, |
465 | .push_work = __WORK_INITIALIZER(nonblocking_pool.push_work, | ||
466 | push_to_pool), | ||
464 | }; | 467 | }; |
465 | 468 | ||
466 | static __u32 const twist_table[8] = { | 469 | static __u32 const twist_table[8] = { |
@@ -498,7 +501,7 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, | |||
498 | 501 | ||
499 | /* mix one byte at a time to simplify size handling and churn faster */ | 502 | /* mix one byte at a time to simplify size handling and churn faster */ |
500 | while (nbytes--) { | 503 | while (nbytes--) { |
501 | w = rol32(*bytes++, input_rotate & 31); | 504 | w = rol32(*bytes++, input_rotate); |
502 | i = (i - 1) & wordmask; | 505 | i = (i - 1) & wordmask; |
503 | 506 | ||
504 | /* XOR in the various taps */ | 507 | /* XOR in the various taps */ |
@@ -518,7 +521,7 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, | |||
518 | * rotation, so that successive passes spread the | 521 | * rotation, so that successive passes spread the |
519 | * input bits across the pool evenly. | 522 | * input bits across the pool evenly. |
520 | */ | 523 | */ |
521 | input_rotate += i ? 7 : 14; | 524 | input_rotate = (input_rotate + (i ? 7 : 14)) & 31; |
522 | } | 525 | } |
523 | 526 | ||
524 | ACCESS_ONCE(r->input_rotate) = input_rotate; | 527 | ACCESS_ONCE(r->input_rotate) = input_rotate; |
@@ -561,65 +564,151 @@ struct fast_pool { | |||
561 | * collector. It's hardcoded for an 128 bit pool and assumes that any | 564 | * collector. It's hardcoded for an 128 bit pool and assumes that any |
562 | * locks that might be needed are taken by the caller. | 565 | * locks that might be needed are taken by the caller. |
563 | */ | 566 | */ |
564 | static void fast_mix(struct fast_pool *f, const void *in, int nbytes) | 567 | static void fast_mix(struct fast_pool *f, __u32 input[4]) |
565 | { | 568 | { |
566 | const char *bytes = in; | ||
567 | __u32 w; | 569 | __u32 w; |
568 | unsigned i = f->count; | ||
569 | unsigned input_rotate = f->rotate; | 570 | unsigned input_rotate = f->rotate; |
570 | 571 | ||
571 | while (nbytes--) { | 572 | w = rol32(input[0], input_rotate) ^ f->pool[0] ^ f->pool[3]; |
572 | w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ | 573 | f->pool[0] = (w >> 3) ^ twist_table[w & 7]; |
573 | f->pool[(i + 1) & 3]; | 574 | input_rotate = (input_rotate + 14) & 31; |
574 | f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; | 575 | w = rol32(input[1], input_rotate) ^ f->pool[1] ^ f->pool[0]; |
575 | input_rotate += (i++ & 3) ? 7 : 14; | 576 | f->pool[1] = (w >> 3) ^ twist_table[w & 7]; |
576 | } | 577 | input_rotate = (input_rotate + 7) & 31; |
577 | f->count = i; | 578 | w = rol32(input[2], input_rotate) ^ f->pool[2] ^ f->pool[1]; |
579 | f->pool[2] = (w >> 3) ^ twist_table[w & 7]; | ||
580 | input_rotate = (input_rotate + 7) & 31; | ||
581 | w = rol32(input[3], input_rotate) ^ f->pool[3] ^ f->pool[2]; | ||
582 | f->pool[3] = (w >> 3) ^ twist_table[w & 7]; | ||
583 | input_rotate = (input_rotate + 7) & 31; | ||
584 | |||
578 | f->rotate = input_rotate; | 585 | f->rotate = input_rotate; |
586 | f->count++; | ||
579 | } | 587 | } |
580 | 588 | ||
581 | /* | 589 | /* |
582 | * Credit (or debit) the entropy store with n bits of entropy | 590 | * Credit (or debit) the entropy store with n bits of entropy. |
591 | * Use credit_entropy_bits_safe() if the value comes from userspace | ||
592 | * or otherwise should be checked for extreme values. | ||
583 | */ | 593 | */ |
584 | static void credit_entropy_bits(struct entropy_store *r, int nbits) | 594 | static void credit_entropy_bits(struct entropy_store *r, int nbits) |
585 | { | 595 | { |
586 | int entropy_count, orig; | 596 | int entropy_count, orig; |
597 | const int pool_size = r->poolinfo->poolfracbits; | ||
598 | int nfrac = nbits << ENTROPY_SHIFT; | ||
587 | 599 | ||
588 | if (!nbits) | 600 | if (!nbits) |
589 | return; | 601 | return; |
590 | 602 | ||
591 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | ||
592 | retry: | 603 | retry: |
593 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 604 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
594 | entropy_count += nbits; | 605 | if (nfrac < 0) { |
606 | /* Debit */ | ||
607 | entropy_count += nfrac; | ||
608 | } else { | ||
609 | /* | ||
610 | * Credit: we have to account for the possibility of | ||
611 | * overwriting already present entropy. Even in the | ||
612 | * ideal case of pure Shannon entropy, new contributions | ||
613 | * approach the full value asymptotically: | ||
614 | * | ||
615 | * entropy <- entropy + (pool_size - entropy) * | ||
616 | * (1 - exp(-add_entropy/pool_size)) | ||
617 | * | ||
618 | * For add_entropy <= pool_size/2 then | ||
619 | * (1 - exp(-add_entropy/pool_size)) >= | ||
620 | * (add_entropy/pool_size)*0.7869... | ||
621 | * so we can approximate the exponential with | ||
622 | * 3/4*add_entropy/pool_size and still be on the | ||
623 | * safe side by adding at most pool_size/2 at a time. | ||
624 | * | ||
625 | * The use of pool_size-2 in the while statement is to | ||
626 | * prevent rounding artifacts from making the loop | ||
627 | * arbitrarily long; this limits the loop to log2(pool_size)*2 | ||
628 | * turns no matter how large nbits is. | ||
629 | */ | ||
630 | int pnfrac = nfrac; | ||
631 | const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2; | ||
632 | /* The +2 corresponds to the /4 in the denominator */ | ||
633 | |||
634 | do { | ||
635 | unsigned int anfrac = min(pnfrac, pool_size/2); | ||
636 | unsigned int add = | ||
637 | ((pool_size - entropy_count)*anfrac*3) >> s; | ||
638 | |||
639 | entropy_count += add; | ||
640 | pnfrac -= anfrac; | ||
641 | } while (unlikely(entropy_count < pool_size-2 && pnfrac)); | ||
642 | } | ||
595 | 643 | ||
596 | if (entropy_count < 0) { | 644 | if (entropy_count < 0) { |
597 | DEBUG_ENT("negative entropy/overflow\n"); | 645 | pr_warn("random: negative entropy/overflow: pool %s count %d\n", |
646 | r->name, entropy_count); | ||
647 | WARN_ON(1); | ||
598 | entropy_count = 0; | 648 | entropy_count = 0; |
599 | } else if (entropy_count > r->poolinfo->POOLBITS) | 649 | } else if (entropy_count > pool_size) |
600 | entropy_count = r->poolinfo->POOLBITS; | 650 | entropy_count = pool_size; |
601 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | 651 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
602 | goto retry; | 652 | goto retry; |
603 | 653 | ||
604 | if (!r->initialized && nbits > 0) { | 654 | r->entropy_total += nbits; |
605 | r->entropy_total += nbits; | 655 | if (!r->initialized && r->entropy_total > 128) { |
606 | if (r->entropy_total > 128) { | 656 | r->initialized = 1; |
607 | r->initialized = 1; | 657 | r->entropy_total = 0; |
608 | if (r == &nonblocking_pool) | 658 | if (r == &nonblocking_pool) { |
609 | prandom_reseed_late(); | 659 | prandom_reseed_late(); |
660 | pr_notice("random: %s pool is initialized\n", r->name); | ||
610 | } | 661 | } |
611 | } | 662 | } |
612 | 663 | ||
613 | trace_credit_entropy_bits(r->name, nbits, entropy_count, | 664 | trace_credit_entropy_bits(r->name, nbits, |
665 | entropy_count >> ENTROPY_SHIFT, | ||
614 | r->entropy_total, _RET_IP_); | 666 | r->entropy_total, _RET_IP_); |
615 | 667 | ||
616 | /* should we wake readers? */ | 668 | if (r == &input_pool) { |
617 | if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { | 669 | int entropy_bytes = entropy_count >> ENTROPY_SHIFT; |
618 | wake_up_interruptible(&random_read_wait); | 670 | |
619 | kill_fasync(&fasync, SIGIO, POLL_IN); | 671 | /* should we wake readers? */ |
672 | if (entropy_bytes >= random_read_wakeup_thresh) { | ||
673 | wake_up_interruptible(&random_read_wait); | ||
674 | kill_fasync(&fasync, SIGIO, POLL_IN); | ||
675 | } | ||
676 | /* If the input pool is getting full, send some | ||
677 | * entropy to the two output pools, flipping back and | ||
678 | * forth between them, until the output pools are 75% | ||
679 | * full. | ||
680 | */ | ||
681 | if (entropy_bytes > random_write_wakeup_thresh && | ||
682 | r->initialized && | ||
683 | r->entropy_total >= 2*random_read_wakeup_thresh) { | ||
684 | static struct entropy_store *last = &blocking_pool; | ||
685 | struct entropy_store *other = &blocking_pool; | ||
686 | |||
687 | if (last == &blocking_pool) | ||
688 | other = &nonblocking_pool; | ||
689 | if (other->entropy_count <= | ||
690 | 3 * other->poolinfo->poolfracbits / 4) | ||
691 | last = other; | ||
692 | if (last->entropy_count <= | ||
693 | 3 * last->poolinfo->poolfracbits / 4) { | ||
694 | schedule_work(&last->push_work); | ||
695 | r->entropy_total = 0; | ||
696 | } | ||
697 | } | ||
620 | } | 698 | } |
621 | } | 699 | } |
622 | 700 | ||
701 | static void credit_entropy_bits_safe(struct entropy_store *r, int nbits) | ||
702 | { | ||
703 | const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); | ||
704 | |||
705 | /* Cap the value to avoid overflows */ | ||
706 | nbits = min(nbits, nbits_max); | ||
707 | nbits = max(nbits, -nbits_max); | ||
708 | |||
709 | credit_entropy_bits(r, nbits); | ||
710 | } | ||
711 | |||
623 | /********************************************************************* | 712 | /********************************************************************* |
624 | * | 713 | * |
625 | * Entropy input management | 714 | * Entropy input management |
@@ -633,6 +722,8 @@ struct timer_rand_state { | |||
633 | unsigned dont_count_entropy:1; | 722 | unsigned dont_count_entropy:1; |
634 | }; | 723 | }; |
635 | 724 | ||
725 | #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; | ||
726 | |||
636 | /* | 727 | /* |
637 | * Add device- or boot-specific data to the input and nonblocking | 728 | * Add device- or boot-specific data to the input and nonblocking |
638 | * pools to help initialize them to unique values. | 729 | * pools to help initialize them to unique values. |
@@ -644,15 +735,22 @@ struct timer_rand_state { | |||
644 | void add_device_randomness(const void *buf, unsigned int size) | 735 | void add_device_randomness(const void *buf, unsigned int size) |
645 | { | 736 | { |
646 | unsigned long time = random_get_entropy() ^ jiffies; | 737 | unsigned long time = random_get_entropy() ^ jiffies; |
738 | unsigned long flags; | ||
647 | 739 | ||
648 | mix_pool_bytes(&input_pool, buf, size, NULL); | 740 | trace_add_device_randomness(size, _RET_IP_); |
649 | mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); | 741 | spin_lock_irqsave(&input_pool.lock, flags); |
650 | mix_pool_bytes(&nonblocking_pool, buf, size, NULL); | 742 | _mix_pool_bytes(&input_pool, buf, size, NULL); |
651 | mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); | 743 | _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); |
744 | spin_unlock_irqrestore(&input_pool.lock, flags); | ||
745 | |||
746 | spin_lock_irqsave(&nonblocking_pool.lock, flags); | ||
747 | _mix_pool_bytes(&nonblocking_pool, buf, size, NULL); | ||
748 | _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); | ||
749 | spin_unlock_irqrestore(&nonblocking_pool.lock, flags); | ||
652 | } | 750 | } |
653 | EXPORT_SYMBOL(add_device_randomness); | 751 | EXPORT_SYMBOL(add_device_randomness); |
654 | 752 | ||
655 | static struct timer_rand_state input_timer_state; | 753 | static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE; |
656 | 754 | ||
657 | /* | 755 | /* |
658 | * This function adds entropy to the entropy "pool" by using timing | 756 | * This function adds entropy to the entropy "pool" by using timing |
@@ -666,6 +764,7 @@ static struct timer_rand_state input_timer_state; | |||
666 | */ | 764 | */ |
667 | static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | 765 | static void add_timer_randomness(struct timer_rand_state *state, unsigned num) |
668 | { | 766 | { |
767 | struct entropy_store *r; | ||
669 | struct { | 768 | struct { |
670 | long jiffies; | 769 | long jiffies; |
671 | unsigned cycles; | 770 | unsigned cycles; |
@@ -674,15 +773,12 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
674 | long delta, delta2, delta3; | 773 | long delta, delta2, delta3; |
675 | 774 | ||
676 | preempt_disable(); | 775 | preempt_disable(); |
677 | /* if over the trickle threshold, use only 1 in 4096 samples */ | ||
678 | if (input_pool.entropy_count > trickle_thresh && | ||
679 | ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff)) | ||
680 | goto out; | ||
681 | 776 | ||
682 | sample.jiffies = jiffies; | 777 | sample.jiffies = jiffies; |
683 | sample.cycles = random_get_entropy(); | 778 | sample.cycles = random_get_entropy(); |
684 | sample.num = num; | 779 | sample.num = num; |
685 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); | 780 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; |
781 | mix_pool_bytes(r, &sample, sizeof(sample), NULL); | ||
686 | 782 | ||
687 | /* | 783 | /* |
688 | * Calculate number of bits of randomness we probably added. | 784 | * Calculate number of bits of randomness we probably added. |
@@ -716,10 +812,8 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
716 | * Round down by 1 bit on general principles, | 812 | * Round down by 1 bit on general principles, |
717 | * and limit entropy entimate to 12 bits. | 813 | * and limit entropy entimate to 12 bits. |
718 | */ | 814 | */ |
719 | credit_entropy_bits(&input_pool, | 815 | credit_entropy_bits(r, min_t(int, fls(delta>>1), 11)); |
720 | min_t(int, fls(delta>>1), 11)); | ||
721 | } | 816 | } |
722 | out: | ||
723 | preempt_enable(); | 817 | preempt_enable(); |
724 | } | 818 | } |
725 | 819 | ||
@@ -732,10 +826,10 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
732 | if (value == last_value) | 826 | if (value == last_value) |
733 | return; | 827 | return; |
734 | 828 | ||
735 | DEBUG_ENT("input event\n"); | ||
736 | last_value = value; | 829 | last_value = value; |
737 | add_timer_randomness(&input_timer_state, | 830 | add_timer_randomness(&input_timer_state, |
738 | (type << 4) ^ code ^ (code >> 4) ^ value); | 831 | (type << 4) ^ code ^ (code >> 4) ^ value); |
832 | trace_add_input_randomness(ENTROPY_BITS(&input_pool)); | ||
739 | } | 833 | } |
740 | EXPORT_SYMBOL_GPL(add_input_randomness); | 834 | EXPORT_SYMBOL_GPL(add_input_randomness); |
741 | 835 | ||
@@ -747,20 +841,21 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
747 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); | 841 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); |
748 | struct pt_regs *regs = get_irq_regs(); | 842 | struct pt_regs *regs = get_irq_regs(); |
749 | unsigned long now = jiffies; | 843 | unsigned long now = jiffies; |
750 | __u32 input[4], cycles = random_get_entropy(); | 844 | cycles_t cycles = random_get_entropy(); |
751 | 845 | __u32 input[4], c_high, j_high; | |
752 | input[0] = cycles ^ jiffies; | 846 | __u64 ip; |
753 | input[1] = irq; | ||
754 | if (regs) { | ||
755 | __u64 ip = instruction_pointer(regs); | ||
756 | input[2] = ip; | ||
757 | input[3] = ip >> 32; | ||
758 | } | ||
759 | 847 | ||
760 | fast_mix(fast_pool, input, sizeof(input)); | 848 | c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; |
849 | j_high = (sizeof(now) > 4) ? now >> 32 : 0; | ||
850 | input[0] = cycles ^ j_high ^ irq; | ||
851 | input[1] = now ^ c_high; | ||
852 | ip = regs ? instruction_pointer(regs) : _RET_IP_; | ||
853 | input[2] = ip; | ||
854 | input[3] = ip >> 32; | ||
761 | 855 | ||
762 | if ((fast_pool->count & 1023) && | 856 | fast_mix(fast_pool, input); |
763 | !time_after(now, fast_pool->last + HZ)) | 857 | |
858 | if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ)) | ||
764 | return; | 859 | return; |
765 | 860 | ||
766 | fast_pool->last = now; | 861 | fast_pool->last = now; |
@@ -789,10 +884,8 @@ void add_disk_randomness(struct gendisk *disk) | |||
789 | if (!disk || !disk->random) | 884 | if (!disk || !disk->random) |
790 | return; | 885 | return; |
791 | /* first major is 1, so we get >= 0x200 here */ | 886 | /* first major is 1, so we get >= 0x200 here */ |
792 | DEBUG_ENT("disk event %d:%d\n", | ||
793 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
794 | |||
795 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); | 887 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
888 | trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool)); | ||
796 | } | 889 | } |
797 | #endif | 890 | #endif |
798 | 891 | ||
@@ -810,30 +903,58 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
810 | * from the primary pool to the secondary extraction pool. We make | 903 | * from the primary pool to the secondary extraction pool. We make |
811 | * sure we pull enough for a 'catastrophic reseed'. | 904 | * sure we pull enough for a 'catastrophic reseed'. |
812 | */ | 905 | */ |
906 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes); | ||
813 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | 907 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
814 | { | 908 | { |
815 | __u32 tmp[OUTPUT_POOL_WORDS]; | 909 | if (r->limit == 0 && random_min_urandom_seed) { |
910 | unsigned long now = jiffies; | ||
816 | 911 | ||
817 | if (r->pull && r->entropy_count < nbytes * 8 && | 912 | if (time_before(now, |
818 | r->entropy_count < r->poolinfo->POOLBITS) { | 913 | r->last_pulled + random_min_urandom_seed * HZ)) |
819 | /* If we're limited, always leave two wakeup worth's BITS */ | 914 | return; |
820 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; | 915 | r->last_pulled = now; |
821 | int bytes = nbytes; | ||
822 | |||
823 | /* pull at least as many as BYTES as wakeup BITS */ | ||
824 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); | ||
825 | /* but never more than the buffer size */ | ||
826 | bytes = min_t(int, bytes, sizeof(tmp)); | ||
827 | |||
828 | DEBUG_ENT("going to reseed %s with %d bits " | ||
829 | "(%zu of %d requested)\n", | ||
830 | r->name, bytes * 8, nbytes * 8, r->entropy_count); | ||
831 | |||
832 | bytes = extract_entropy(r->pull, tmp, bytes, | ||
833 | random_read_wakeup_thresh / 8, rsvd); | ||
834 | mix_pool_bytes(r, tmp, bytes, NULL); | ||
835 | credit_entropy_bits(r, bytes*8); | ||
836 | } | 916 | } |
917 | if (r->pull && | ||
918 | r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) && | ||
919 | r->entropy_count < r->poolinfo->poolfracbits) | ||
920 | _xfer_secondary_pool(r, nbytes); | ||
921 | } | ||
922 | |||
923 | static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | ||
924 | { | ||
925 | __u32 tmp[OUTPUT_POOL_WORDS]; | ||
926 | |||
927 | /* For /dev/random's pool, always leave two wakeup worth's BITS */ | ||
928 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; | ||
929 | int bytes = nbytes; | ||
930 | |||
931 | /* pull at least as many as BYTES as wakeup BITS */ | ||
932 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); | ||
933 | /* but never more than the buffer size */ | ||
934 | bytes = min_t(int, bytes, sizeof(tmp)); | ||
935 | |||
936 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, | ||
937 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); | ||
938 | bytes = extract_entropy(r->pull, tmp, bytes, | ||
939 | random_read_wakeup_thresh / 8, rsvd); | ||
940 | mix_pool_bytes(r, tmp, bytes, NULL); | ||
941 | credit_entropy_bits(r, bytes*8); | ||
942 | } | ||
943 | |||
944 | /* | ||
945 | * Used as a workqueue function so that when the input pool is getting | ||
946 | * full, we can "spill over" some entropy to the output pools. That | ||
947 | * way the output pools can store some of the excess entropy instead | ||
948 | * of letting it go to waste. | ||
949 | */ | ||
950 | static void push_to_pool(struct work_struct *work) | ||
951 | { | ||
952 | struct entropy_store *r = container_of(work, struct entropy_store, | ||
953 | push_work); | ||
954 | BUG_ON(!r); | ||
955 | _xfer_secondary_pool(r, random_read_wakeup_thresh/8); | ||
956 | trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT, | ||
957 | r->pull->entropy_count >> ENTROPY_SHIFT); | ||
837 | } | 958 | } |
838 | 959 | ||
839 | /* | 960 | /* |
@@ -853,50 +974,48 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
853 | { | 974 | { |
854 | unsigned long flags; | 975 | unsigned long flags; |
855 | int wakeup_write = 0; | 976 | int wakeup_write = 0; |
977 | int have_bytes; | ||
978 | int entropy_count, orig; | ||
979 | size_t ibytes; | ||
856 | 980 | ||
857 | /* Hold lock while accounting */ | 981 | /* Hold lock while accounting */ |
858 | spin_lock_irqsave(&r->lock, flags); | 982 | spin_lock_irqsave(&r->lock, flags); |
859 | 983 | ||
860 | BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); | 984 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); |
861 | DEBUG_ENT("trying to extract %zu bits from %s\n", | ||
862 | nbytes * 8, r->name); | ||
863 | 985 | ||
864 | /* Can we pull enough? */ | 986 | /* Can we pull enough? */ |
865 | if (r->entropy_count / 8 < min + reserved) { | ||
866 | nbytes = 0; | ||
867 | } else { | ||
868 | int entropy_count, orig; | ||
869 | retry: | 987 | retry: |
870 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 988 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
989 | have_bytes = entropy_count >> (ENTROPY_SHIFT + 3); | ||
990 | ibytes = nbytes; | ||
991 | if (have_bytes < min + reserved) { | ||
992 | ibytes = 0; | ||
993 | } else { | ||
871 | /* If limited, never pull more than available */ | 994 | /* If limited, never pull more than available */ |
872 | if (r->limit && nbytes + reserved >= entropy_count / 8) | 995 | if (r->limit && ibytes + reserved >= have_bytes) |
873 | nbytes = entropy_count/8 - reserved; | 996 | ibytes = have_bytes - reserved; |
874 | |||
875 | if (entropy_count / 8 >= nbytes + reserved) { | ||
876 | entropy_count -= nbytes*8; | ||
877 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | ||
878 | goto retry; | ||
879 | } else { | ||
880 | entropy_count = reserved; | ||
881 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | ||
882 | goto retry; | ||
883 | } | ||
884 | 997 | ||
885 | if (entropy_count < random_write_wakeup_thresh) | 998 | if (have_bytes >= ibytes + reserved) |
886 | wakeup_write = 1; | 999 | entropy_count -= ibytes << (ENTROPY_SHIFT + 3); |
887 | } | 1000 | else |
1001 | entropy_count = reserved << (ENTROPY_SHIFT + 3); | ||
888 | 1002 | ||
889 | DEBUG_ENT("debiting %zu entropy credits from %s%s\n", | 1003 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
890 | nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); | 1004 | goto retry; |
891 | 1005 | ||
1006 | if ((r->entropy_count >> ENTROPY_SHIFT) | ||
1007 | < random_write_wakeup_thresh) | ||
1008 | wakeup_write = 1; | ||
1009 | } | ||
892 | spin_unlock_irqrestore(&r->lock, flags); | 1010 | spin_unlock_irqrestore(&r->lock, flags); |
893 | 1011 | ||
1012 | trace_debit_entropy(r->name, 8 * ibytes); | ||
894 | if (wakeup_write) { | 1013 | if (wakeup_write) { |
895 | wake_up_interruptible(&random_write_wait); | 1014 | wake_up_interruptible(&random_write_wait); |
896 | kill_fasync(&fasync, SIGIO, POLL_OUT); | 1015 | kill_fasync(&fasync, SIGIO, POLL_OUT); |
897 | } | 1016 | } |
898 | 1017 | ||
899 | return nbytes; | 1018 | return ibytes; |
900 | } | 1019 | } |
901 | 1020 | ||
902 | static void extract_buf(struct entropy_store *r, __u8 *out) | 1021 | static void extract_buf(struct entropy_store *r, __u8 *out) |
@@ -904,7 +1023,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
904 | int i; | 1023 | int i; |
905 | union { | 1024 | union { |
906 | __u32 w[5]; | 1025 | __u32 w[5]; |
907 | unsigned long l[LONGS(EXTRACT_SIZE)]; | 1026 | unsigned long l[LONGS(20)]; |
908 | } hash; | 1027 | } hash; |
909 | __u32 workspace[SHA_WORKSPACE_WORDS]; | 1028 | __u32 workspace[SHA_WORKSPACE_WORDS]; |
910 | __u8 extract[64]; | 1029 | __u8 extract[64]; |
@@ -917,6 +1036,17 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
917 | sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); | 1036 | sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); |
918 | 1037 | ||
919 | /* | 1038 | /* |
1039 | * If we have a architectural hardware random number | ||
1040 | * generator, mix that in, too. | ||
1041 | */ | ||
1042 | for (i = 0; i < LONGS(20); i++) { | ||
1043 | unsigned long v; | ||
1044 | if (!arch_get_random_long(&v)) | ||
1045 | break; | ||
1046 | hash.l[i] ^= v; | ||
1047 | } | ||
1048 | |||
1049 | /* | ||
920 | * We mix the hash back into the pool to prevent backtracking | 1050 | * We mix the hash back into the pool to prevent backtracking |
921 | * attacks (where the attacker knows the state of the pool | 1051 | * attacks (where the attacker knows the state of the pool |
922 | * plus the current outputs, and attempts to find previous | 1052 | * plus the current outputs, and attempts to find previous |
@@ -945,17 +1075,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
945 | hash.w[1] ^= hash.w[4]; | 1075 | hash.w[1] ^= hash.w[4]; |
946 | hash.w[2] ^= rol32(hash.w[2], 16); | 1076 | hash.w[2] ^= rol32(hash.w[2], 16); |
947 | 1077 | ||
948 | /* | ||
949 | * If we have a architectural hardware random number | ||
950 | * generator, mix that in, too. | ||
951 | */ | ||
952 | for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { | ||
953 | unsigned long v; | ||
954 | if (!arch_get_random_long(&v)) | ||
955 | break; | ||
956 | hash.l[i] ^= v; | ||
957 | } | ||
958 | |||
959 | memcpy(out, &hash, EXTRACT_SIZE); | 1078 | memcpy(out, &hash, EXTRACT_SIZE); |
960 | memset(&hash, 0, sizeof(hash)); | 1079 | memset(&hash, 0, sizeof(hash)); |
961 | } | 1080 | } |
@@ -971,10 +1090,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
971 | if (fips_enabled) { | 1090 | if (fips_enabled) { |
972 | spin_lock_irqsave(&r->lock, flags); | 1091 | spin_lock_irqsave(&r->lock, flags); |
973 | if (!r->last_data_init) { | 1092 | if (!r->last_data_init) { |
974 | r->last_data_init = true; | 1093 | r->last_data_init = 1; |
975 | spin_unlock_irqrestore(&r->lock, flags); | 1094 | spin_unlock_irqrestore(&r->lock, flags); |
976 | trace_extract_entropy(r->name, EXTRACT_SIZE, | 1095 | trace_extract_entropy(r->name, EXTRACT_SIZE, |
977 | r->entropy_count, _RET_IP_); | 1096 | ENTROPY_BITS(r), _RET_IP_); |
978 | xfer_secondary_pool(r, EXTRACT_SIZE); | 1097 | xfer_secondary_pool(r, EXTRACT_SIZE); |
979 | extract_buf(r, tmp); | 1098 | extract_buf(r, tmp); |
980 | spin_lock_irqsave(&r->lock, flags); | 1099 | spin_lock_irqsave(&r->lock, flags); |
@@ -983,7 +1102,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
983 | spin_unlock_irqrestore(&r->lock, flags); | 1102 | spin_unlock_irqrestore(&r->lock, flags); |
984 | } | 1103 | } |
985 | 1104 | ||
986 | trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); | 1105 | trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); |
987 | xfer_secondary_pool(r, nbytes); | 1106 | xfer_secondary_pool(r, nbytes); |
988 | nbytes = account(r, nbytes, min, reserved); | 1107 | nbytes = account(r, nbytes, min, reserved); |
989 | 1108 | ||
@@ -1016,7 +1135,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
1016 | ssize_t ret = 0, i; | 1135 | ssize_t ret = 0, i; |
1017 | __u8 tmp[EXTRACT_SIZE]; | 1136 | __u8 tmp[EXTRACT_SIZE]; |
1018 | 1137 | ||
1019 | trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); | 1138 | trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); |
1020 | xfer_secondary_pool(r, nbytes); | 1139 | xfer_secondary_pool(r, nbytes); |
1021 | nbytes = account(r, nbytes, 0, 0); | 1140 | nbytes = account(r, nbytes, 0, 0); |
1022 | 1141 | ||
@@ -1056,6 +1175,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
1056 | */ | 1175 | */ |
1057 | void get_random_bytes(void *buf, int nbytes) | 1176 | void get_random_bytes(void *buf, int nbytes) |
1058 | { | 1177 | { |
1178 | #if DEBUG_RANDOM_BOOT > 0 | ||
1179 | if (unlikely(nonblocking_pool.initialized == 0)) | ||
1180 | printk(KERN_NOTICE "random: %pF get_random_bytes called " | ||
1181 | "with %d bits of entropy available\n", | ||
1182 | (void *) _RET_IP_, | ||
1183 | nonblocking_pool.entropy_total); | ||
1184 | #endif | ||
1185 | trace_get_random_bytes(nbytes, _RET_IP_); | ||
1059 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); | 1186 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); |
1060 | } | 1187 | } |
1061 | EXPORT_SYMBOL(get_random_bytes); | 1188 | EXPORT_SYMBOL(get_random_bytes); |
@@ -1074,7 +1201,7 @@ void get_random_bytes_arch(void *buf, int nbytes) | |||
1074 | { | 1201 | { |
1075 | char *p = buf; | 1202 | char *p = buf; |
1076 | 1203 | ||
1077 | trace_get_random_bytes(nbytes, _RET_IP_); | 1204 | trace_get_random_bytes_arch(nbytes, _RET_IP_); |
1078 | while (nbytes) { | 1205 | while (nbytes) { |
1079 | unsigned long v; | 1206 | unsigned long v; |
1080 | int chunk = min(nbytes, (int)sizeof(unsigned long)); | 1207 | int chunk = min(nbytes, (int)sizeof(unsigned long)); |
@@ -1108,13 +1235,11 @@ static void init_std_data(struct entropy_store *r) | |||
1108 | ktime_t now = ktime_get_real(); | 1235 | ktime_t now = ktime_get_real(); |
1109 | unsigned long rv; | 1236 | unsigned long rv; |
1110 | 1237 | ||
1111 | r->entropy_count = 0; | 1238 | r->last_pulled = jiffies; |
1112 | r->entropy_total = 0; | ||
1113 | r->last_data_init = false; | ||
1114 | mix_pool_bytes(r, &now, sizeof(now), NULL); | 1239 | mix_pool_bytes(r, &now, sizeof(now), NULL); |
1115 | for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { | 1240 | for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { |
1116 | if (!arch_get_random_long(&rv)) | 1241 | if (!arch_get_random_long(&rv)) |
1117 | break; | 1242 | rv = random_get_entropy(); |
1118 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); | 1243 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); |
1119 | } | 1244 | } |
1120 | mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); | 1245 | mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); |
@@ -1137,7 +1262,7 @@ static int rand_initialize(void) | |||
1137 | init_std_data(&nonblocking_pool); | 1262 | init_std_data(&nonblocking_pool); |
1138 | return 0; | 1263 | return 0; |
1139 | } | 1264 | } |
1140 | module_init(rand_initialize); | 1265 | early_initcall(rand_initialize); |
1141 | 1266 | ||
1142 | #ifdef CONFIG_BLOCK | 1267 | #ifdef CONFIG_BLOCK |
1143 | void rand_initialize_disk(struct gendisk *disk) | 1268 | void rand_initialize_disk(struct gendisk *disk) |
@@ -1149,8 +1274,10 @@ void rand_initialize_disk(struct gendisk *disk) | |||
1149 | * source. | 1274 | * source. |
1150 | */ | 1275 | */ |
1151 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | 1276 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); |
1152 | if (state) | 1277 | if (state) { |
1278 | state->last_time = INITIAL_JIFFIES; | ||
1153 | disk->random = state; | 1279 | disk->random = state; |
1280 | } | ||
1154 | } | 1281 | } |
1155 | #endif | 1282 | #endif |
1156 | 1283 | ||
@@ -1167,8 +1294,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1167 | if (n > SEC_XFER_SIZE) | 1294 | if (n > SEC_XFER_SIZE) |
1168 | n = SEC_XFER_SIZE; | 1295 | n = SEC_XFER_SIZE; |
1169 | 1296 | ||
1170 | DEBUG_ENT("reading %zu bits\n", n*8); | ||
1171 | |||
1172 | n = extract_entropy_user(&blocking_pool, buf, n); | 1297 | n = extract_entropy_user(&blocking_pool, buf, n); |
1173 | 1298 | ||
1174 | if (n < 0) { | 1299 | if (n < 0) { |
@@ -1176,8 +1301,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1176 | break; | 1301 | break; |
1177 | } | 1302 | } |
1178 | 1303 | ||
1179 | DEBUG_ENT("read got %zd bits (%zd still needed)\n", | 1304 | trace_random_read(n*8, (nbytes-n)*8, |
1180 | n*8, (nbytes-n)*8); | 1305 | ENTROPY_BITS(&blocking_pool), |
1306 | ENTROPY_BITS(&input_pool)); | ||
1181 | 1307 | ||
1182 | if (n == 0) { | 1308 | if (n == 0) { |
1183 | if (file->f_flags & O_NONBLOCK) { | 1309 | if (file->f_flags & O_NONBLOCK) { |
@@ -1185,13 +1311,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1185 | break; | 1311 | break; |
1186 | } | 1312 | } |
1187 | 1313 | ||
1188 | DEBUG_ENT("sleeping?\n"); | ||
1189 | |||
1190 | wait_event_interruptible(random_read_wait, | 1314 | wait_event_interruptible(random_read_wait, |
1191 | input_pool.entropy_count >= | 1315 | ENTROPY_BITS(&input_pool) >= |
1192 | random_read_wakeup_thresh); | 1316 | random_read_wakeup_thresh); |
1193 | |||
1194 | DEBUG_ENT("awake\n"); | ||
1195 | 1317 | ||
1196 | if (signal_pending(current)) { | 1318 | if (signal_pending(current)) { |
1197 | retval = -ERESTARTSYS; | 1319 | retval = -ERESTARTSYS; |
@@ -1214,7 +1336,18 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1214 | static ssize_t | 1336 | static ssize_t |
1215 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 1337 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
1216 | { | 1338 | { |
1217 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1339 | int ret; |
1340 | |||
1341 | if (unlikely(nonblocking_pool.initialized == 0)) | ||
1342 | printk_once(KERN_NOTICE "random: %s urandom read " | ||
1343 | "with %d bits of entropy available\n", | ||
1344 | current->comm, nonblocking_pool.entropy_total); | ||
1345 | |||
1346 | ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); | ||
1347 | |||
1348 | trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), | ||
1349 | ENTROPY_BITS(&input_pool)); | ||
1350 | return ret; | ||
1218 | } | 1351 | } |
1219 | 1352 | ||
1220 | static unsigned int | 1353 | static unsigned int |
@@ -1225,9 +1358,9 @@ random_poll(struct file *file, poll_table * wait) | |||
1225 | poll_wait(file, &random_read_wait, wait); | 1358 | poll_wait(file, &random_read_wait, wait); |
1226 | poll_wait(file, &random_write_wait, wait); | 1359 | poll_wait(file, &random_write_wait, wait); |
1227 | mask = 0; | 1360 | mask = 0; |
1228 | if (input_pool.entropy_count >= random_read_wakeup_thresh) | 1361 | if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_thresh) |
1229 | mask |= POLLIN | POLLRDNORM; | 1362 | mask |= POLLIN | POLLRDNORM; |
1230 | if (input_pool.entropy_count < random_write_wakeup_thresh) | 1363 | if (ENTROPY_BITS(&input_pool) < random_write_wakeup_thresh) |
1231 | mask |= POLLOUT | POLLWRNORM; | 1364 | mask |= POLLOUT | POLLWRNORM; |
1232 | return mask; | 1365 | return mask; |
1233 | } | 1366 | } |
@@ -1278,7 +1411,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1278 | switch (cmd) { | 1411 | switch (cmd) { |
1279 | case RNDGETENTCNT: | 1412 | case RNDGETENTCNT: |
1280 | /* inherently racy, no point locking */ | 1413 | /* inherently racy, no point locking */ |
1281 | if (put_user(input_pool.entropy_count, p)) | 1414 | ent_count = ENTROPY_BITS(&input_pool); |
1415 | if (put_user(ent_count, p)) | ||
1282 | return -EFAULT; | 1416 | return -EFAULT; |
1283 | return 0; | 1417 | return 0; |
1284 | case RNDADDTOENTCNT: | 1418 | case RNDADDTOENTCNT: |
@@ -1286,7 +1420,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1286 | return -EPERM; | 1420 | return -EPERM; |
1287 | if (get_user(ent_count, p)) | 1421 | if (get_user(ent_count, p)) |
1288 | return -EFAULT; | 1422 | return -EFAULT; |
1289 | credit_entropy_bits(&input_pool, ent_count); | 1423 | credit_entropy_bits_safe(&input_pool, ent_count); |
1290 | return 0; | 1424 | return 0; |
1291 | case RNDADDENTROPY: | 1425 | case RNDADDENTROPY: |
1292 | if (!capable(CAP_SYS_ADMIN)) | 1426 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1301,14 +1435,19 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
1301 | size); | 1435 | size); |
1302 | if (retval < 0) | 1436 | if (retval < 0) |
1303 | return retval; | 1437 | return retval; |
1304 | credit_entropy_bits(&input_pool, ent_count); | 1438 | credit_entropy_bits_safe(&input_pool, ent_count); |
1305 | return 0; | 1439 | return 0; |
1306 | case RNDZAPENTCNT: | 1440 | case RNDZAPENTCNT: |
1307 | case RNDCLEARPOOL: | 1441 | case RNDCLEARPOOL: |
1308 | /* Clear the entropy pool counters. */ | 1442 | /* |
1443 | * Clear the entropy pool counters. We no longer clear | ||
1444 | * the entropy pool, as that's silly. | ||
1445 | */ | ||
1309 | if (!capable(CAP_SYS_ADMIN)) | 1446 | if (!capable(CAP_SYS_ADMIN)) |
1310 | return -EPERM; | 1447 | return -EPERM; |
1311 | rand_initialize(); | 1448 | input_pool.entropy_count = 0; |
1449 | nonblocking_pool.entropy_count = 0; | ||
1450 | blocking_pool.entropy_count = 0; | ||
1312 | return 0; | 1451 | return 0; |
1313 | default: | 1452 | default: |
1314 | return -EINVAL; | 1453 | return -EINVAL; |
@@ -1408,6 +1547,23 @@ static int proc_do_uuid(struct ctl_table *table, int write, | |||
1408 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); | 1547 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); |
1409 | } | 1548 | } |
1410 | 1549 | ||
1550 | /* | ||
1551 | * Return entropy available scaled to integral bits | ||
1552 | */ | ||
1553 | static int proc_do_entropy(ctl_table *table, int write, | ||
1554 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1555 | { | ||
1556 | ctl_table fake_table; | ||
1557 | int entropy_count; | ||
1558 | |||
1559 | entropy_count = *(int *)table->data >> ENTROPY_SHIFT; | ||
1560 | |||
1561 | fake_table.data = &entropy_count; | ||
1562 | fake_table.maxlen = sizeof(entropy_count); | ||
1563 | |||
1564 | return proc_dointvec(&fake_table, write, buffer, lenp, ppos); | ||
1565 | } | ||
1566 | |||
1411 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; | 1567 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; |
1412 | extern struct ctl_table random_table[]; | 1568 | extern struct ctl_table random_table[]; |
1413 | struct ctl_table random_table[] = { | 1569 | struct ctl_table random_table[] = { |
@@ -1422,7 +1578,7 @@ struct ctl_table random_table[] = { | |||
1422 | .procname = "entropy_avail", | 1578 | .procname = "entropy_avail", |
1423 | .maxlen = sizeof(int), | 1579 | .maxlen = sizeof(int), |
1424 | .mode = 0444, | 1580 | .mode = 0444, |
1425 | .proc_handler = proc_dointvec, | 1581 | .proc_handler = proc_do_entropy, |
1426 | .data = &input_pool.entropy_count, | 1582 | .data = &input_pool.entropy_count, |
1427 | }, | 1583 | }, |
1428 | { | 1584 | { |
@@ -1444,6 +1600,13 @@ struct ctl_table random_table[] = { | |||
1444 | .extra2 = &max_write_thresh, | 1600 | .extra2 = &max_write_thresh, |
1445 | }, | 1601 | }, |
1446 | { | 1602 | { |
1603 | .procname = "urandom_min_reseed_secs", | ||
1604 | .data = &random_min_urandom_seed, | ||
1605 | .maxlen = sizeof(int), | ||
1606 | .mode = 0644, | ||
1607 | .proc_handler = proc_dointvec, | ||
1608 | }, | ||
1609 | { | ||
1447 | .procname = "boot_id", | 1610 | .procname = "boot_id", |
1448 | .data = &sysctl_bootid, | 1611 | .data = &sysctl_bootid, |
1449 | .maxlen = 16, | 1612 | .maxlen = 16, |
diff --git a/include/trace/events/random.h b/include/trace/events/random.h index 422df19de732..805af6db41cc 100644 --- a/include/trace/events/random.h +++ b/include/trace/events/random.h | |||
@@ -7,6 +7,25 @@ | |||
7 | #include <linux/writeback.h> | 7 | #include <linux/writeback.h> |
8 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
9 | 9 | ||
10 | TRACE_EVENT(add_device_randomness, | ||
11 | TP_PROTO(int bytes, unsigned long IP), | ||
12 | |||
13 | TP_ARGS(bytes, IP), | ||
14 | |||
15 | TP_STRUCT__entry( | ||
16 | __field( int, bytes ) | ||
17 | __field(unsigned long, IP ) | ||
18 | ), | ||
19 | |||
20 | TP_fast_assign( | ||
21 | __entry->bytes = bytes; | ||
22 | __entry->IP = IP; | ||
23 | ), | ||
24 | |||
25 | TP_printk("bytes %d caller %pF", | ||
26 | __entry->bytes, (void *)__entry->IP) | ||
27 | ); | ||
28 | |||
10 | DECLARE_EVENT_CLASS(random__mix_pool_bytes, | 29 | DECLARE_EVENT_CLASS(random__mix_pool_bytes, |
11 | TP_PROTO(const char *pool_name, int bytes, unsigned long IP), | 30 | TP_PROTO(const char *pool_name, int bytes, unsigned long IP), |
12 | 31 | ||
@@ -68,7 +87,112 @@ TRACE_EVENT(credit_entropy_bits, | |||
68 | (void *)__entry->IP) | 87 | (void *)__entry->IP) |
69 | ); | 88 | ); |
70 | 89 | ||
71 | TRACE_EVENT(get_random_bytes, | 90 | TRACE_EVENT(push_to_pool, |
91 | TP_PROTO(const char *pool_name, int pool_bits, int input_bits), | ||
92 | |||
93 | TP_ARGS(pool_name, pool_bits, input_bits), | ||
94 | |||
95 | TP_STRUCT__entry( | ||
96 | __field( const char *, pool_name ) | ||
97 | __field( int, pool_bits ) | ||
98 | __field( int, input_bits ) | ||
99 | ), | ||
100 | |||
101 | TP_fast_assign( | ||
102 | __entry->pool_name = pool_name; | ||
103 | __entry->pool_bits = pool_bits; | ||
104 | __entry->input_bits = input_bits; | ||
105 | ), | ||
106 | |||
107 | TP_printk("%s: pool_bits %d input_pool_bits %d", | ||
108 | __entry->pool_name, __entry->pool_bits, | ||
109 | __entry->input_bits) | ||
110 | ); | ||
111 | |||
112 | TRACE_EVENT(debit_entropy, | ||
113 | TP_PROTO(const char *pool_name, int debit_bits), | ||
114 | |||
115 | TP_ARGS(pool_name, debit_bits), | ||
116 | |||
117 | TP_STRUCT__entry( | ||
118 | __field( const char *, pool_name ) | ||
119 | __field( int, debit_bits ) | ||
120 | ), | ||
121 | |||
122 | TP_fast_assign( | ||
123 | __entry->pool_name = pool_name; | ||
124 | __entry->debit_bits = debit_bits; | ||
125 | ), | ||
126 | |||
127 | TP_printk("%s: debit_bits %d", __entry->pool_name, | ||
128 | __entry->debit_bits) | ||
129 | ); | ||
130 | |||
131 | TRACE_EVENT(add_input_randomness, | ||
132 | TP_PROTO(int input_bits), | ||
133 | |||
134 | TP_ARGS(input_bits), | ||
135 | |||
136 | TP_STRUCT__entry( | ||
137 | __field( int, input_bits ) | ||
138 | ), | ||
139 | |||
140 | TP_fast_assign( | ||
141 | __entry->input_bits = input_bits; | ||
142 | ), | ||
143 | |||
144 | TP_printk("input_pool_bits %d", __entry->input_bits) | ||
145 | ); | ||
146 | |||
147 | TRACE_EVENT(add_disk_randomness, | ||
148 | TP_PROTO(dev_t dev, int input_bits), | ||
149 | |||
150 | TP_ARGS(dev, input_bits), | ||
151 | |||
152 | TP_STRUCT__entry( | ||
153 | __field( dev_t, dev ) | ||
154 | __field( int, input_bits ) | ||
155 | ), | ||
156 | |||
157 | TP_fast_assign( | ||
158 | __entry->dev = dev; | ||
159 | __entry->input_bits = input_bits; | ||
160 | ), | ||
161 | |||
162 | TP_printk("dev %d,%d input_pool_bits %d", MAJOR(__entry->dev), | ||
163 | MINOR(__entry->dev), __entry->input_bits) | ||
164 | ); | ||
165 | |||
166 | TRACE_EVENT(xfer_secondary_pool, | ||
167 | TP_PROTO(const char *pool_name, int xfer_bits, int request_bits, | ||
168 | int pool_entropy, int input_entropy), | ||
169 | |||
170 | TP_ARGS(pool_name, xfer_bits, request_bits, pool_entropy, | ||
171 | input_entropy), | ||
172 | |||
173 | TP_STRUCT__entry( | ||
174 | __field( const char *, pool_name ) | ||
175 | __field( int, xfer_bits ) | ||
176 | __field( int, request_bits ) | ||
177 | __field( int, pool_entropy ) | ||
178 | __field( int, input_entropy ) | ||
179 | ), | ||
180 | |||
181 | TP_fast_assign( | ||
182 | __entry->pool_name = pool_name; | ||
183 | __entry->xfer_bits = xfer_bits; | ||
184 | __entry->request_bits = request_bits; | ||
185 | __entry->pool_entropy = pool_entropy; | ||
186 | __entry->input_entropy = input_entropy; | ||
187 | ), | ||
188 | |||
189 | TP_printk("pool %s xfer_bits %d request_bits %d pool_entropy %d " | ||
190 | "input_entropy %d", __entry->pool_name, __entry->xfer_bits, | ||
191 | __entry->request_bits, __entry->pool_entropy, | ||
192 | __entry->input_entropy) | ||
193 | ); | ||
194 | |||
195 | DECLARE_EVENT_CLASS(random__get_random_bytes, | ||
72 | TP_PROTO(int nbytes, unsigned long IP), | 196 | TP_PROTO(int nbytes, unsigned long IP), |
73 | 197 | ||
74 | TP_ARGS(nbytes, IP), | 198 | TP_ARGS(nbytes, IP), |
@@ -86,6 +210,18 @@ TRACE_EVENT(get_random_bytes, | |||
86 | TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP) | 210 | TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP) |
87 | ); | 211 | ); |
88 | 212 | ||
213 | DEFINE_EVENT(random__get_random_bytes, get_random_bytes, | ||
214 | TP_PROTO(int nbytes, unsigned long IP), | ||
215 | |||
216 | TP_ARGS(nbytes, IP) | ||
217 | ); | ||
218 | |||
219 | DEFINE_EVENT(random__get_random_bytes, get_random_bytes_arch, | ||
220 | TP_PROTO(int nbytes, unsigned long IP), | ||
221 | |||
222 | TP_ARGS(nbytes, IP) | ||
223 | ); | ||
224 | |||
89 | DECLARE_EVENT_CLASS(random__extract_entropy, | 225 | DECLARE_EVENT_CLASS(random__extract_entropy, |
90 | TP_PROTO(const char *pool_name, int nbytes, int entropy_count, | 226 | TP_PROTO(const char *pool_name, int nbytes, int entropy_count, |
91 | unsigned long IP), | 227 | unsigned long IP), |
@@ -126,7 +262,52 @@ DEFINE_EVENT(random__extract_entropy, extract_entropy_user, | |||
126 | TP_ARGS(pool_name, nbytes, entropy_count, IP) | 262 | TP_ARGS(pool_name, nbytes, entropy_count, IP) |
127 | ); | 263 | ); |
128 | 264 | ||
265 | TRACE_EVENT(random_read, | ||
266 | TP_PROTO(int got_bits, int need_bits, int pool_left, int input_left), | ||
267 | |||
268 | TP_ARGS(got_bits, need_bits, pool_left, input_left), | ||
269 | |||
270 | TP_STRUCT__entry( | ||
271 | __field( int, got_bits ) | ||
272 | __field( int, need_bits ) | ||
273 | __field( int, pool_left ) | ||
274 | __field( int, input_left ) | ||
275 | ), | ||
276 | |||
277 | TP_fast_assign( | ||
278 | __entry->got_bits = got_bits; | ||
279 | __entry->need_bits = need_bits; | ||
280 | __entry->pool_left = pool_left; | ||
281 | __entry->input_left = input_left; | ||
282 | ), | ||
283 | |||
284 | TP_printk("got_bits %d still_needed_bits %d " | ||
285 | "blocking_pool_entropy_left %d input_entropy_left %d", | ||
286 | __entry->got_bits, __entry->got_bits, __entry->pool_left, | ||
287 | __entry->input_left) | ||
288 | ); | ||
289 | |||
290 | TRACE_EVENT(urandom_read, | ||
291 | TP_PROTO(int got_bits, int pool_left, int input_left), | ||
292 | |||
293 | TP_ARGS(got_bits, pool_left, input_left), | ||
294 | |||
295 | TP_STRUCT__entry( | ||
296 | __field( int, got_bits ) | ||
297 | __field( int, pool_left ) | ||
298 | __field( int, input_left ) | ||
299 | ), | ||
300 | |||
301 | TP_fast_assign( | ||
302 | __entry->got_bits = got_bits; | ||
303 | __entry->pool_left = pool_left; | ||
304 | __entry->input_left = input_left; | ||
305 | ), | ||
129 | 306 | ||
307 | TP_printk("got_bits %d nonblocking_pool_entropy_left %d " | ||
308 | "input_entropy_left %d", __entry->got_bits, | ||
309 | __entry->pool_left, __entry->input_left) | ||
310 | ); | ||
130 | 311 | ||
131 | #endif /* _TRACE_RANDOM_H */ | 312 | #endif /* _TRACE_RANDOM_H */ |
132 | 313 | ||