aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index ba0d70305384..d33f52cd437b 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -439,7 +439,7 @@ static struct entropy_store nonblocking_pool = {
439}; 439};
440 440
441/* 441/*
442 * This function adds a byte into the entropy "pool". It does not 442 * This function adds bytes into the entropy "pool". It does not
443 * update the entropy estimate. The caller should call 443 * update the entropy estimate. The caller should call
444 * credit_entropy_store if this is appropriate. 444 * credit_entropy_store if this is appropriate.
445 * 445 *
@@ -448,8 +448,8 @@ static struct entropy_store nonblocking_pool = {
448 * it's cheap to do so and helps slightly in the expected case where 448 * it's cheap to do so and helps slightly in the expected case where
449 * the entropy is concentrated in the low-order bits. 449 * the entropy is concentrated in the low-order bits.
450 */ 450 */
451static void __add_entropy_words(struct entropy_store *r, const __u32 *in, 451static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
452 int nwords, __u32 out[16]) 452 int nbytes, __u8 out[64])
453{ 453{
454 static __u32 const twist_table[8] = { 454 static __u32 const twist_table[8] = {
455 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, 455 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
@@ -457,6 +457,7 @@ static void __add_entropy_words(struct entropy_store *r, const __u32 *in,
457 unsigned long i, j, tap1, tap2, tap3, tap4, tap5; 457 unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
458 int input_rotate; 458 int input_rotate;
459 int wordmask = r->poolinfo->poolwords - 1; 459 int wordmask = r->poolinfo->poolwords - 1;
460 const char *bytes = in;
460 __u32 w; 461 __u32 w;
461 unsigned long flags; 462 unsigned long flags;
462 463
@@ -471,8 +472,9 @@ static void __add_entropy_words(struct entropy_store *r, const __u32 *in,
471 input_rotate = r->input_rotate; 472 input_rotate = r->input_rotate;
472 i = r->add_ptr; 473 i = r->add_ptr;
473 474
474 while (nwords--) { 475 /* mix one byte at a time to simplify size handling and churn faster */
475 w = rol32(*in++, input_rotate & 31); 476 while (nbytes--) {
477 w = rol32(*bytes++, input_rotate & 31);
476 i = (i - 1) & wordmask; 478 i = (i - 1) & wordmask;
477 479
478 /* XOR in the various taps */ 480 /* XOR in the various taps */
@@ -500,15 +502,14 @@ static void __add_entropy_words(struct entropy_store *r, const __u32 *in,
500 502
501 if (out) 503 if (out)
502 for (j = 0; j < 16; j++) 504 for (j = 0; j < 16; j++)
503 out[j] = r->pool[(i - j) & wordmask]; 505 ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
504 506
505 spin_unlock_irqrestore(&r->lock, flags); 507 spin_unlock_irqrestore(&r->lock, flags);
506} 508}
507 509
508static inline void add_entropy_words(struct entropy_store *r, const __u32 *in, 510static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes)
509 int nwords)
510{ 511{
511 __add_entropy_words(r, in, nwords, NULL); 512 mix_pool_bytes_extract(r, in, bytes, NULL);
512} 513}
513 514
514/* 515/*
@@ -584,7 +585,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
584 sample.jiffies = jiffies; 585 sample.jiffies = jiffies;
585 sample.cycles = get_cycles(); 586 sample.cycles = get_cycles();
586 sample.num = num; 587 sample.num = num;
587 add_entropy_words(&input_pool, (u32 *)&sample, sizeof(sample)/4); 588 mix_pool_bytes(&input_pool, &sample, sizeof(sample));
588 589
589 /* 590 /*
590 * Calculate number of bits of randomness we probably added. 591 * Calculate number of bits of randomness we probably added.
@@ -700,7 +701,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
700 701
701 bytes = extract_entropy(r->pull, tmp, bytes, 702 bytes = extract_entropy(r->pull, tmp, bytes,
702 random_read_wakeup_thresh / 8, rsvd); 703 random_read_wakeup_thresh / 8, rsvd);
703 add_entropy_words(r, tmp, (bytes + 3) / 4); 704 mix_pool_bytes(r, tmp, bytes);
704 credit_entropy_store(r, bytes*8); 705 credit_entropy_store(r, bytes*8);
705 } 706 }
706} 707}
@@ -758,7 +759,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
758static void extract_buf(struct entropy_store *r, __u8 *out) 759static void extract_buf(struct entropy_store *r, __u8 *out)
759{ 760{
760 int i; 761 int i;
761 __u32 extract[16], hash[5], workspace[SHA_WORKSPACE_WORDS]; 762 __u32 hash[5], workspace[SHA_WORKSPACE_WORDS];
763 __u8 extract[64];
762 764
763 /* Generate a hash across the pool, 16 words (512 bits) at a time */ 765 /* Generate a hash across the pool, 16 words (512 bits) at a time */
764 sha_init(hash); 766 sha_init(hash);
@@ -774,13 +776,13 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
774 * brute-forcing the feedback as hard as brute-forcing the 776 * brute-forcing the feedback as hard as brute-forcing the
775 * hash. 777 * hash.
776 */ 778 */
777 __add_entropy_words(r, hash, 5, extract); 779 mix_pool_bytes_extract(r, hash, sizeof(hash), extract);
778 780
779 /* 781 /*
780 * To avoid duplicates, we atomically extract a portion of the 782 * To avoid duplicates, we atomically extract a portion of the
781 * pool while mixing, and hash one final time. 783 * pool while mixing, and hash one final time.
782 */ 784 */
783 sha_transform(hash, (__u8 *)extract, workspace); 785 sha_transform(hash, extract, workspace);
784 memset(extract, 0, sizeof(extract)); 786 memset(extract, 0, sizeof(extract));
785 memset(workspace, 0, sizeof(workspace)); 787 memset(workspace, 0, sizeof(workspace));
786 788
@@ -887,9 +889,8 @@ static void init_std_data(struct entropy_store *r)
887 spin_unlock_irqrestore(&r->lock, flags); 889 spin_unlock_irqrestore(&r->lock, flags);
888 890
889 now = ktime_get_real(); 891 now = ktime_get_real();
890 add_entropy_words(r, (__u32 *)&now, sizeof(now)/4); 892 mix_pool_bytes(r, &now, sizeof(now));
891 add_entropy_words(r, (__u32 *)utsname(), 893 mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
892 sizeof(*(utsname()))/4);
893} 894}
894 895
895static int rand_initialize(void) 896static int rand_initialize(void)
@@ -1030,7 +1031,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
1030 count -= bytes; 1031 count -= bytes;
1031 p += bytes; 1032 p += bytes;
1032 1033
1033 add_entropy_words(r, buf, (bytes + 3) / 4); 1034 mix_pool_bytes(r, buf, bytes);
1034 cond_resched(); 1035 cond_resched();
1035 } 1036 }
1036 1037