diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/random.c | 37 |
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 | */ |
451 | static void __add_entropy_words(struct entropy_store *r, const __u32 *in, | 451 | static 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 | ||
508 | static inline void add_entropy_words(struct entropy_store *r, const __u32 *in, | 510 | static 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, | |||
758 | static void extract_buf(struct entropy_store *r, __u8 *out) | 759 | static 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 | ||
895 | static int rand_initialize(void) | 896 | static 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 | ||