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