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.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index d125a4b792d0..e52f64cbef04 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -767,37 +767,35 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
767 int i; 767 int i;
768 __u32 extract[16], hash[5], workspace[SHA_WORKSPACE_WORDS]; 768 __u32 extract[16], hash[5], workspace[SHA_WORKSPACE_WORDS];
769 769
770 /* Generate a hash across the pool, 16 words (512 bits) at a time */
770 sha_init(hash); 771 sha_init(hash);
772 for (i = 0; i < r->poolinfo->poolwords; i += 16)
773 sha_transform(hash, (__u8 *)(r->pool + i), workspace);
774
771 /* 775 /*
772 * As we hash the pool, we mix intermediate values of 776 * We mix the hash back into the pool to prevent backtracking
773 * the hash back into the pool. This eliminates 777 * attacks (where the attacker knows the state of the pool
774 * backtracking attacks (where the attacker knows 778 * plus the current outputs, and attempts to find previous
775 * the state of the pool plus the current outputs, and 779 * ouputs), unless the hash function can be inverted. By
776 * attempts to find previous ouputs), unless the hash 780 * mixing at least a SHA1 worth of hash data back, we make
777 * function can be inverted. 781 * brute-forcing the feedback as hard as brute-forcing the
782 * hash.
778 */ 783 */
779 for (i = 0; i < r->poolinfo->poolwords; i += 16) { 784 __add_entropy_words(r, hash, 5, extract);
780 /* hash blocks of 16 words = 512 bits */
781 sha_transform(hash, (__u8 *)(r->pool + i), workspace);
782 /* feed back portion of the resulting hash */
783 add_entropy_words(r, &hash[i % 5], 1);
784 }
785 785
786 /* 786 /*
787 * To avoid duplicates, we atomically extract a 787 * To avoid duplicates, we atomically extract a portion of the
788 * portion of the pool while mixing, and hash one 788 * pool while mixing, and hash one final time.
789 * final time.
790 */ 789 */
791 __add_entropy_words(r, &hash[i % 5], 1, extract);
792 sha_transform(hash, (__u8 *)extract, workspace); 790 sha_transform(hash, (__u8 *)extract, workspace);
793 memset(extract, 0, sizeof(extract)); 791 memset(extract, 0, sizeof(extract));
794 memset(workspace, 0, sizeof(workspace)); 792 memset(workspace, 0, sizeof(workspace));
795 793
796 /* 794 /*
797 * In case the hash function has some recognizable 795 * In case the hash function has some recognizable output
798 * output pattern, we fold it in half. 796 * pattern, we fold it in half. Thus, we always feed back
797 * twice as much data as we output.
799 */ 798 */
800
801 hash[0] ^= hash[3]; 799 hash[0] ^= hash[3];
802 hash[1] ^= hash[4]; 800 hash[1] ^= hash[4];
803 hash[2] ^= rol32(hash[2], 16); 801 hash[2] ^= rol32(hash[2], 16);