Commit c9eabcc8 authored by Matt Mackall's avatar Matt Mackall Committed by Linus Torvalds

[PATCH] random: Clean up hash buffering

Clean up buffer usage for SHA and reseed.  This makes the code more readable
and reduces worst-case stack usage.
Signed-off-by: default avatarMatt Mackall <mpm@selenic.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 66764b54
...@@ -255,6 +255,7 @@ ...@@ -255,6 +255,7 @@
#define INPUT_POOL_WORDS 128 #define INPUT_POOL_WORDS 128
#define OUTPUT_POOL_WORDS 32 #define OUTPUT_POOL_WORDS 32
#define BATCH_ENTROPY_SIZE 256 #define BATCH_ENTROPY_SIZE 256
#define SEC_XFER_SIZE 512
/* /*
* The minimum number of bits of entropy before we wake up a read on * The minimum number of bits of entropy before we wake up a read on
...@@ -813,6 +814,7 @@ EXPORT_SYMBOL(add_disk_randomness); ...@@ -813,6 +814,7 @@ EXPORT_SYMBOL(add_disk_randomness);
*/ */
#define HASH_BUFFER_SIZE 5 #define HASH_BUFFER_SIZE 5
#define EXTRACT_SIZE 10
#define HASH_EXTRA_SIZE 80 #define HASH_EXTRA_SIZE 80
/* Various size/speed tradeoffs are available. Choose 0..3. */ /* Various size/speed tradeoffs are available. Choose 0..3. */
...@@ -1048,9 +1050,6 @@ static void sha_transform(__u32 digest[85], __u32 const data[16]) ...@@ -1048,9 +1050,6 @@ static void sha_transform(__u32 digest[85], __u32 const data[16])
* *
*********************************************************************/ *********************************************************************/
#define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE)
#define SEC_XFER_SIZE (TMP_BUF_SIZE*4)
static ssize_t extract_entropy(struct entropy_store *r, void * buf, static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int min, int rsvd); size_t nbytes, int min, int rsvd);
...@@ -1059,13 +1058,14 @@ static ssize_t extract_entropy(struct entropy_store *r, void * buf, ...@@ -1059,13 +1058,14 @@ static ssize_t extract_entropy(struct entropy_store *r, void * buf,
* from the primary pool to the secondary extraction pool. We make * from the primary pool to the secondary extraction pool. We make
* sure we pull enough for a 'catastrophic reseed'. * sure we pull enough for a 'catastrophic reseed'.
*/ */
static void xfer_secondary_pool(struct entropy_store *r, static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
size_t nbytes, __u32 *tmp)
{ {
__u32 tmp[OUTPUT_POOL_WORDS];
if (r->pull && r->entropy_count < nbytes * 8 && if (r->pull && r->entropy_count < nbytes * 8 &&
r->entropy_count < r->poolinfo->POOLBITS) { r->entropy_count < r->poolinfo->POOLBITS) {
int bytes = max_t(int, random_read_wakeup_thresh / 8, int bytes = max_t(int, random_read_wakeup_thresh / 8,
min_t(int, nbytes, TMP_BUF_SIZE)); min_t(int, nbytes, sizeof(tmp)));
int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
DEBUG_ENT("going to reseed %s with %d bits " DEBUG_ENT("going to reseed %s with %d bits "
...@@ -1129,10 +1129,10 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, ...@@ -1129,10 +1129,10 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
return nbytes; return nbytes;
} }
static void extract_buf(struct entropy_store *r, __u32 *buf) static void extract_buf(struct entropy_store *r, __u8 *out)
{ {
int i, x; int i, x;
__u32 data[16]; __u32 data[16], buf[85];
/* Hash the pool to get the output */ /* Hash the pool to get the output */
buf[0] = 0x67452301; buf[0] = 0x67452301;
...@@ -1151,7 +1151,7 @@ static void extract_buf(struct entropy_store *r, __u32 *buf) ...@@ -1151,7 +1151,7 @@ static void extract_buf(struct entropy_store *r, __u32 *buf)
*/ */
for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) { for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
sha_transform(buf, r->pool+i); sha_transform(buf, r->pool+i);
add_entropy_words(r, &buf[x%HASH_BUFFER_SIZE], 1); add_entropy_words(r, &buf[x % 5], 1);
} }
/* /*
...@@ -1159,7 +1159,7 @@ static void extract_buf(struct entropy_store *r, __u32 *buf) ...@@ -1159,7 +1159,7 @@ static void extract_buf(struct entropy_store *r, __u32 *buf)
* portion of the pool while mixing, and hash one * portion of the pool while mixing, and hash one
* final time. * final time.
*/ */
__add_entropy_words(r, &buf[x%HASH_BUFFER_SIZE], 1, data); __add_entropy_words(r, &buf[x % 5], 1, data);
sha_transform(buf, data); sha_transform(buf, data);
/* /*
...@@ -1170,21 +1170,23 @@ static void extract_buf(struct entropy_store *r, __u32 *buf) ...@@ -1170,21 +1170,23 @@ static void extract_buf(struct entropy_store *r, __u32 *buf)
buf[0] ^= buf[3]; buf[0] ^= buf[3];
buf[1] ^= buf[4]; buf[1] ^= buf[4];
buf[0] ^= rol32(buf[3], 16); buf[0] ^= rol32(buf[3], 16);
memcpy(out, buf, EXTRACT_SIZE);
memset(buf, 0, sizeof(buf));
} }
static ssize_t extract_entropy(struct entropy_store *r, void * buf, static ssize_t extract_entropy(struct entropy_store *r, void * buf,
size_t nbytes, int min, int reserved) size_t nbytes, int min, int reserved)
{ {
ssize_t ret = 0, i; ssize_t ret = 0, i;
__u32 tmp[TMP_BUF_SIZE]; __u8 tmp[EXTRACT_SIZE];
xfer_secondary_pool(r, nbytes, tmp); xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, min, reserved); nbytes = account(r, nbytes, min, reserved);
while (nbytes) { while (nbytes) {
extract_buf(r, tmp); extract_buf(r, tmp);
i = min(nbytes, HASH_BUFFER_SIZE * sizeof(__u32) / 2); i = min_t(int, nbytes, EXTRACT_SIZE);
memcpy(buf, (__u8 const *)tmp, i); memcpy(buf, tmp, i);
nbytes -= i; nbytes -= i;
buf += i; buf += i;
ret += i; ret += i;
...@@ -1200,9 +1202,9 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, ...@@ -1200,9 +1202,9 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
size_t nbytes) size_t nbytes)
{ {
ssize_t ret = 0, i; ssize_t ret = 0, i;
__u32 tmp[TMP_BUF_SIZE]; __u8 tmp[EXTRACT_SIZE];
xfer_secondary_pool(r, nbytes, tmp); xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, 0, 0); nbytes = account(r, nbytes, 0, 0);
while (nbytes) { while (nbytes) {
...@@ -1216,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, ...@@ -1216,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
} }
extract_buf(r, tmp); extract_buf(r, tmp);
i = min(nbytes, HASH_BUFFER_SIZE * sizeof(__u32) / 2); i = min_t(int, nbytes, EXTRACT_SIZE);
if (copy_to_user(buf, tmp, i)) { if (copy_to_user(buf, tmp, i)) {
ret = -EFAULT; ret = -EFAULT;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment