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

[PATCH] random: Cleanup SHA interface

Clean up SHA hash function for moving to lib/
Do proper endian conversion
Provide sha_init function
Add kerneldoc
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 9a41cad2
...@@ -671,29 +671,6 @@ void add_disk_randomness(struct gendisk *disk) ...@@ -671,29 +671,6 @@ void add_disk_randomness(struct gendisk *disk)
EXPORT_SYMBOL(add_disk_randomness); EXPORT_SYMBOL(add_disk_randomness);
/******************************************************************
*
* Hash function definition
*
*******************************************************************/
/*
* This chunk of code defines a function
* void sha_transform(__u32 digest[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE],
* __u32 const data[16])
*
* The function hashes the input data to produce a digest in the first
* HASH_BUFFER_SIZE words of the digest[] array, and uses HASH_EXTRA_SIZE
* more words for internal purposes. (This buffer is exported so the
* caller can wipe it once rather than this code doing it each call,
* and tacking it onto the end of the digest[] array is the quick and
* dirty way of doing it.)
*
* For /dev/random purposes, the length of the data being hashed is
* fixed in length, so appending a bit count in the usual way is not
* cryptographically necessary.
*/
#define HASH_BUFFER_SIZE 5 #define HASH_BUFFER_SIZE 5
#define EXTRACT_SIZE 10 #define EXTRACT_SIZE 10
#define HASH_EXTRA_SIZE 80 #define HASH_EXTRA_SIZE 80
...@@ -717,20 +694,32 @@ EXPORT_SYMBOL(add_disk_randomness); ...@@ -717,20 +694,32 @@ EXPORT_SYMBOL(add_disk_randomness);
#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ #define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */
#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ #define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */
static void sha_transform(__u32 digest[85], __u32 const data[16]) /*
* sha_transform: single block SHA1 transform
*
* @digest: 160 bit digest to update
* @data: 512 bytes of data to hash
* @W: 80 words of workspace
*
* This function generates a SHA1 digest for a single. Be warned, it
* does not handle padding and message digest, do not confuse it with
* the full FIPS 180-1 digest algorithm for variable length messages.
*/
static void sha_transform(__u32 digest[5], const char *data, __u32 W[80])
{ {
__u32 A, B, C, D, E; /* Local vars */ __u32 A, B, C, D, E;
__u32 TEMP; __u32 TEMP;
int i; int i;
#define W (digest + HASH_BUFFER_SIZE) /* Expanded data array */
memset(W, 0, sizeof(W));
for (i = 0; i < 16; i++)
W[i] = be32_to_cpu(((const __u32 *)data)[i]);
/* /*
* Do the preliminary expansion of 16 to 80 words. Doing it * Do the preliminary expansion of 16 to 80 words. Doing it
* out-of-line line this is faster than doing it in-line on * out-of-line line this is faster than doing it in-line on
* register-starved machines like the x86, and not really any * register-starved machines like the x86, and not really any
* slower on real processors. * slower on real processors.
*/ */
memcpy(W, data, 16*sizeof(__u32));
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13]; TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13];
W[i+16] = rol32(TEMP, 1); W[i+16] = rol32(TEMP, 1);
...@@ -768,7 +757,6 @@ static void sha_transform(__u32 digest[85], __u32 const data[16]) ...@@ -768,7 +757,6 @@ static void sha_transform(__u32 digest[85], __u32 const data[16])
digest[4] += E; digest[4] += E;
/* W is wiped by the caller */ /* W is wiped by the caller */
#undef W
} }
#undef f1 #undef f1
...@@ -780,6 +768,20 @@ static void sha_transform(__u32 digest[85], __u32 const data[16]) ...@@ -780,6 +768,20 @@ static void sha_transform(__u32 digest[85], __u32 const data[16])
#undef K3 #undef K3
#undef K4 #undef K4
/*
* sha_init: initialize the vectors for a SHA1 digest
*
* @buf: vector to initialize
*/
static void sha_init(__u32 *buf)
{
buf[0] = 0x67452301;
buf[1] = 0xefcdab89;
buf[2] = 0x98badcfe;
buf[3] = 0x10325476;
buf[4] = 0xc3d2e1f0;
}
/********************************************************************* /*********************************************************************
* *
* Entropy extraction routines * Entropy extraction routines
...@@ -870,13 +872,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) ...@@ -870,13 +872,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
int i, x; int i, x;
__u32 data[16], buf[85]; __u32 data[16], buf[85];
/* Hash the pool to get the output */ sha_init(buf);
buf[0] = 0x67452301;
buf[1] = 0xefcdab89;
buf[2] = 0x98badcfe;
buf[3] = 0x10325476;
buf[4] = 0xc3d2e1f0;
/* /*
* As we hash the pool, we mix intermediate values of * As we hash the pool, we mix intermediate values of
* the hash back into the pool. This eliminates * the hash back into the pool. This eliminates
...@@ -886,7 +882,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) ...@@ -886,7 +882,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* function can be inverted. * function can be inverted.
*/ */
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, (__u8 *)r->pool+i, buf + 5);
add_entropy_words(r, &buf[x % 5], 1); add_entropy_words(r, &buf[x % 5], 1);
} }
...@@ -896,7 +892,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) ...@@ -896,7 +892,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* final time. * final time.
*/ */
__add_entropy_words(r, &buf[x % 5], 1, data); __add_entropy_words(r, &buf[x % 5], 1, data);
sha_transform(buf, data); sha_transform(buf, (__u8 *)data, buf + 5);
/* /*
* In case the hash function has some recognizable * In case the hash function has some recognizable
...@@ -1789,7 +1785,7 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, ...@@ -1789,7 +1785,7 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
tmp[0]=saddr; tmp[0]=saddr;
tmp[1]=daddr; tmp[1]=daddr;
tmp[2]=(sport << 16) + dport; tmp[2]=(sport << 16) + dport;
sha_transform(tmp+16, tmp); sha_transform(tmp+16, (__u8 *)tmp, tmp + 16 + 5);
seq = tmp[17] + sseq + (count << COOKIEBITS); seq = tmp[17] + sseq + (count << COOKIEBITS);
memcpy(tmp + 3, syncookie_secret[1], sizeof(syncookie_secret[1])); memcpy(tmp + 3, syncookie_secret[1], sizeof(syncookie_secret[1]));
...@@ -1797,7 +1793,7 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, ...@@ -1797,7 +1793,7 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
tmp[1]=daddr; tmp[1]=daddr;
tmp[2]=(sport << 16) + dport; tmp[2]=(sport << 16) + dport;
tmp[3] = count; /* minute counter */ tmp[3] = count; /* minute counter */
sha_transform(tmp + 16, tmp); sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
/* Add in the second hash and the data */ /* Add in the second hash and the data */
return seq + ((tmp[17] + data) & COOKIEMASK); return seq + ((tmp[17] + data) & COOKIEMASK);
...@@ -1826,7 +1822,7 @@ __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport, ...@@ -1826,7 +1822,7 @@ __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
tmp[0]=saddr; tmp[0]=saddr;
tmp[1]=daddr; tmp[1]=daddr;
tmp[2]=(sport << 16) + dport; tmp[2]=(sport << 16) + dport;
sha_transform(tmp + 16, tmp); sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
cookie -= tmp[17] + sseq; cookie -= tmp[17] + sseq;
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */ /* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
......
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