]>
Commit | Line | Data |
---|---|---|
1160f6c9 AC |
1 | /* |
2 | * Based on the SHA-1 C implementation by Steve Reid <steve@edmweb.com> | |
3 | * 100% Public Domain | |
4 | * | |
5 | * Test Vectors (from FIPS PUB 180-1) | |
6 | * "abc" | |
7 | * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D | |
8 | * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | |
9 | * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 | |
10 | * A million repetitions of "a" | |
11 | * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F | |
12 | */ | |
13 | ||
0e0d823a SA |
14 | #include "stdinc.h" |
15 | ||
1160f6c9 AC |
16 | #ifdef _WIN32 |
17 | #include <winsock2.h> // for htonl() | |
18 | #else | |
19 | #include <netinet/in.h> // for htonl() | |
20 | #endif | |
21 | ||
22 | #include "sha1.h" | |
23 | ||
24 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | |
25 | ||
26 | // blk0() and blk() perform the initial expand. blk0() deals with host endianess | |
27 | #define blk0(i) (block[i] = htonl(block[i])) | |
28 | #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15]^block[(i+2)&15]^block[i&15],1)) | |
29 | ||
30 | // (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 | |
31 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); | |
32 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); | |
33 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); | |
34 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); | |
35 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); | |
36 | ||
37 | // hash a single 512-bit block. this is the core of the algorithm | |
38 | static uint32_t sha1_transform(SHA1 *sha1, const uint8_t buffer[SHA1_BLOCK_LENGTH]) { | |
39 | uint32_t a, b, c, d, e; | |
40 | uint32_t block[SHA1_BLOCK_LENGTH / 4]; | |
41 | ||
42 | memcpy(&block, buffer, SHA1_BLOCK_LENGTH); | |
43 | ||
44 | // copy sha1->state[] to working variables | |
45 | a = sha1->state[0]; | |
46 | b = sha1->state[1]; | |
47 | c = sha1->state[2]; | |
48 | d = sha1->state[3]; | |
49 | e = sha1->state[4]; | |
50 | ||
51 | // 4 rounds of 20 operations each (loop unrolled) | |
52 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); | |
53 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); | |
54 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); | |
55 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); | |
56 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); | |
57 | ||
58 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); | |
59 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); | |
60 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); | |
61 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); | |
62 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); | |
63 | ||
64 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); | |
65 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); | |
66 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); | |
67 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); | |
68 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); | |
69 | ||
70 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); | |
71 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); | |
72 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); | |
73 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); | |
74 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); | |
75 | ||
76 | // add the working variables back into sha1->state[] | |
77 | sha1->state[0] += a; | |
78 | sha1->state[1] += b; | |
79 | sha1->state[2] += c; | |
80 | sha1->state[3] += d; | |
81 | sha1->state[4] += e; | |
82 | ||
83 | // wipe variables | |
84 | a = b = c = d = e = 0; | |
85 | ||
86 | return a; // return a to avoid dead-store warning from clang static analyzer | |
87 | } | |
88 | ||
89 | void sha1_init(SHA1 *sha1) { | |
90 | sha1->state[0] = 0x67452301; | |
91 | sha1->state[1] = 0xEFCDAB89; | |
92 | sha1->state[2] = 0x98BADCFE; | |
93 | sha1->state[3] = 0x10325476; | |
94 | sha1->state[4] = 0xC3D2E1F0; | |
95 | sha1->count = 0; | |
96 | } | |
97 | ||
98 | void sha1_update(SHA1 *sha1, const uint8_t *data, size_t length) { | |
99 | size_t i, j; | |
100 | ||
101 | j = (size_t)((sha1->count >> 3) & 63); | |
102 | sha1->count += (length << 3); | |
103 | ||
104 | if ((j + length) > 63) { | |
105 | i = 64 - j; | |
106 | ||
107 | memcpy(&sha1->buffer[j], data, i); | |
108 | sha1_transform(sha1, sha1->buffer); | |
109 | ||
110 | for (; i + 63 < length; i += 64) { | |
111 | sha1_transform(sha1, &data[i]); | |
112 | } | |
113 | ||
114 | j = 0; | |
115 | } else { | |
116 | i = 0; | |
117 | } | |
118 | ||
119 | memcpy(&sha1->buffer[j], &data[i], length - i); | |
120 | } | |
121 | ||
122 | void sha1_final(SHA1 *sha1, uint8_t digest[SHA1_DIGEST_LENGTH]) { | |
123 | uint32_t i; | |
124 | uint8_t count[8]; | |
125 | ||
126 | for (i = 0; i < 8; i++) { | |
127 | // this is endian independent | |
128 | count[i] = (uint8_t)((sha1->count >> ((7 - (i & 7)) * 8)) & 255); | |
129 | } | |
130 | ||
131 | sha1_update(sha1, (uint8_t *)"\200", 1); | |
132 | ||
133 | while ((sha1->count & 504) != 448) { | |
134 | sha1_update(sha1, (uint8_t *)"\0", 1); | |
135 | } | |
136 | ||
137 | sha1_update(sha1, count, 8); | |
138 | ||
139 | for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { | |
140 | digest[i] = (uint8_t)((sha1->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); | |
141 | } | |
142 | ||
143 | memset(sha1, 0, sizeof(*sha1)); | |
144 | } |