diff options
Diffstat (limited to 'lib/sha1.c')
-rw-r--r-- | lib/sha1.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/sha1.c b/lib/sha1.c new file mode 100644 index 000000000000..2f7f1148dfde --- /dev/null +++ b/lib/sha1.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * SHA transform algorithm, originally taken from code written by | ||
3 | * Peter Gutmann, and placed in the public domain. | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/cryptohash.h> | ||
9 | |||
10 | /* The SHA f()-functions. */ | ||
11 | |||
12 | #define f1(x,y,z) (z ^ (x & (y ^ z))) /* x ? y : z */ | ||
13 | #define f2(x,y,z) (x ^ y ^ z) /* XOR */ | ||
14 | #define f3(x,y,z) ((x & y) + (z & (x ^ y))) /* majority */ | ||
15 | |||
16 | /* The SHA Mysterious Constants */ | ||
17 | |||
18 | #define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */ | ||
19 | #define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */ | ||
20 | #define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ | ||
21 | #define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ | ||
22 | |||
23 | /* | ||
24 | * sha_transform: single block SHA1 transform | ||
25 | * | ||
26 | * @digest: 160 bit digest to update | ||
27 | * @data: 512 bits of data to hash | ||
28 | * @W: 80 words of workspace (see note) | ||
29 | * | ||
30 | * This function generates a SHA1 digest for a single 512-bit block. | ||
31 | * Be warned, it does not handle padding and message digest, do not | ||
32 | * confuse it with the full FIPS 180-1 digest algorithm for variable | ||
33 | * length messages. | ||
34 | * | ||
35 | * Note: If the hash is security sensitive, the caller should be sure | ||
36 | * to clear the workspace. This is left to the caller to avoid | ||
37 | * unnecessary clears between chained hashing operations. | ||
38 | */ | ||
39 | void sha_transform(__u32 *digest, const char *in, __u32 *W) | ||
40 | { | ||
41 | __u32 a, b, c, d, e, t, i; | ||
42 | |||
43 | for (i = 0; i < 16; i++) | ||
44 | W[i] = be32_to_cpu(((const __u32 *)in)[i]); | ||
45 | |||
46 | for (i = 0; i < 64; i++) | ||
47 | W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1); | ||
48 | |||
49 | a = digest[0]; | ||
50 | b = digest[1]; | ||
51 | c = digest[2]; | ||
52 | d = digest[3]; | ||
53 | e = digest[4]; | ||
54 | |||
55 | for (i = 0; i < 20; i++) { | ||
56 | t = f1(b, c, d) + K1 + rol32(a, 5) + e + W[i]; | ||
57 | e = d; d = c; c = rol32(b, 30); b = a; a = t; | ||
58 | } | ||
59 | |||
60 | for (; i < 40; i ++) { | ||
61 | t = f2(b, c, d) + K2 + rol32(a, 5) + e + W[i]; | ||
62 | e = d; d = c; c = rol32(b, 30); b = a; a = t; | ||
63 | } | ||
64 | |||
65 | for (; i < 60; i ++) { | ||
66 | t = f3(b, c, d) + K3 + rol32(a, 5) + e + W[i]; | ||
67 | e = d; d = c; c = rol32(b, 30); b = a; a = t; | ||
68 | } | ||
69 | |||
70 | for (; i < 80; i ++) { | ||
71 | t = f2(b, c, d) + K4 + rol32(a, 5) + e + W[i]; | ||
72 | e = d; d = c; c = rol32(b, 30); b = a; a = t; | ||
73 | } | ||
74 | |||
75 | digest[0] += a; | ||
76 | digest[1] += b; | ||
77 | digest[2] += c; | ||
78 | digest[3] += d; | ||
79 | digest[4] += e; | ||
80 | } | ||
81 | EXPORT_SYMBOL(sha_transform); | ||
82 | |||
83 | /* | ||
84 | * sha_init: initialize the vectors for a SHA1 digest | ||
85 | * | ||
86 | * @buf: vector to initialize | ||
87 | */ | ||
88 | void sha_init(__u32 *buf) | ||
89 | { | ||
90 | buf[0] = 0x67452301; | ||
91 | buf[1] = 0xefcdab89; | ||
92 | buf[2] = 0x98badcfe; | ||
93 | buf[3] = 0x10325476; | ||
94 | buf[4] = 0xc3d2e1f0; | ||
95 | } | ||
96 | |||