Line data Source code
1 : /** @file
2 : * SHA-1 hash.
3 : */
4 :
5 : /*
6 : SHA-1 in C
7 : By Steve Reid <sreid@sea-to-sky.net>
8 : 100% Public Domain
9 :
10 : -----------------
11 : Modified 7/98
12 : By James H. Brown <jbrown@burgoyne.com>
13 : Still 100% Public Domain
14 :
15 : Corrected a problem which generated improper hash values on 16 bit machines
16 : Routine SHA1Update changed from
17 : void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
18 : len)
19 : to
20 : void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
21 : long len)
22 :
23 : The 'len' parameter was declared an int which works fine on 32 bit machines.
24 : However, on 16 bit machines an int is too small for the shifts being done
25 : against
26 : it. This caused the hash function to generate incorrect values if len was
27 : greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
28 :
29 : Since the file IO in main() reads 16K at a time, any file 8K or larger would
30 : be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
31 : "a"s).
32 :
33 : I also changed the declaration of variables i & j in SHA1Update to
34 : unsigned long from unsigned int for the same reason.
35 :
36 : These changes should make no difference to any 32 bit implementations since
37 : an
38 : int and a long are the same size in those environments.
39 :
40 : --
41 : I also corrected a few compiler warnings generated by Borland C.
42 : 1. Added #include <process.h> for exit() prototype
43 : 2. Removed unused variable 'j' in SHA1Final
44 : 3. Changed exit(0) to return(0) at end of main.
45 :
46 : ALL changes I made can be located by searching for comments containing 'JHB'
47 : -----------------
48 : Modified 8/98
49 : By Steve Reid <sreid@sea-to-sky.net>
50 : Still 100% public domain
51 :
52 : 1- Removed #include <process.h> and used return() instead of exit()
53 : 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
54 : 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
55 :
56 : -----------------
57 : Modified 4/01
58 : By Saul Kravitz <Saul.Kravitz@celera.com>
59 : Still 100% PD
60 : Modified to run on Compaq Alpha hardware.
61 :
62 : -----------------
63 : Modified 07/2002
64 : By Ralph Giles <giles@artofcode.com>
65 : Still 100% public domain
66 : modified for use with stdint types, autoconf
67 : code cleanup, removed attribution comments
68 : switched SHA1Final() argument order for consistency
69 : use SHA1_ prefix for public api
70 : move public api to sha1.h
71 : */
72 :
73 : #include <string.h>
74 :
75 : #include "ostypes.h"
76 : #include "sha1.h"
77 :
78 : static uint32_t host_to_be(uint32_t i);
79 : static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
80 :
81 : #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
82 :
83 : /* blk0() and blk() perform the initial expand. */
84 : /* I got the idea of expanding during the round function from SSLeay */
85 : #define blk0(i) (block->l[i] = host_to_be(block->l[i]))
86 : #define blk(i) \
87 : (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
88 : block->l[(i + 2) & 15] ^ block->l[i & 15], \
89 : 1))
90 :
91 : /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
92 : #define R0(v, w, x, y, z, i) \
93 : z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
94 : w = rol(w, 30);
95 : #define R1(v, w, x, y, z, i) \
96 : z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
97 : w = rol(w, 30);
98 : #define R2(v, w, x, y, z, i) \
99 : z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
100 : w = rol(w, 30);
101 : #define R3(v, w, x, y, z, i) \
102 : z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
103 : w = rol(w, 30);
104 : #define R4(v, w, x, y, z, i) \
105 : z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
106 : w = rol(w, 30);
107 :
108 16 : static uint32_t host_to_be(uint32_t i)
109 : {
110 : #define le_to_be(i) ((rol((i), 24) & 0xFF00FF00) | (rol((i), 8) & 0x00FF00FF))
111 : #if defined(__BIG_ENDIAN__) || \
112 : (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
113 : __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
114 : return i;
115 : #elif defined(__LITTLE_ENDIAN__) || \
116 : (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
117 : __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
118 16 : return le_to_be(i);
119 : #else /* fallback to run-time check */
120 : static const union {
121 : uint32_t u;
122 : unsigned char c;
123 : } check = {1};
124 : return check.c ? le_to_be(i) : i;
125 : #endif
126 : #undef le_to_be
127 : }
128 :
129 : static void *(*volatile SHA1_explicit_memset)(void *, int, size_t) = &memset;
130 :
131 112 : static void SHA1_cleanse(void *p, size_t len)
132 : {
133 112 : SHA1_explicit_memset(p, 0, len);
134 : }
135 :
136 : /* Hash a single 512-bit block. This is the core of the algorithm. */
137 16 : static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
138 : {
139 16 : uint32_t a, b, c, d, e;
140 16 : typedef union {
141 : uint8_t c[64];
142 : uint32_t l[16];
143 : } CHAR64LONG16;
144 16 : CHAR64LONG16 *block;
145 :
146 16 : static uint8_t workspace[64];
147 16 : block = (CHAR64LONG16 *)workspace;
148 16 : memcpy(block, buffer, 64);
149 :
150 : /* Copy context->state[] to working vars */
151 16 : a = state[0];
152 16 : b = state[1];
153 16 : c = state[2];
154 16 : d = state[3];
155 16 : e = state[4];
156 :
157 : /* 4 rounds of 20 operations each. Loop unrolled. */
158 : /* clang-format off */
159 16 : 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);
160 16 : 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);
161 16 : 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);
162 16 : 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);
163 16 : 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);
164 16 : 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);
165 16 : 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);
166 16 : 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);
167 16 : 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);
168 16 : 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);
169 16 : 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);
170 16 : 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);
171 16 : 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);
172 16 : 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);
173 16 : 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);
174 16 : 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);
175 16 : 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);
176 16 : 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);
177 16 : 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);
178 16 : 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);
179 : /* clang-format on */
180 :
181 : /* Add the working vars back into context.state[] */
182 16 : state[0] += a;
183 16 : state[1] += b;
184 16 : state[2] += c;
185 16 : state[3] += d;
186 16 : state[4] += e;
187 :
188 : /* Wipe variables */
189 16 : SHA1_cleanse(&a, sizeof(a));
190 16 : SHA1_cleanse(&b, sizeof(b));
191 16 : SHA1_cleanse(&c, sizeof(c));
192 16 : SHA1_cleanse(&d, sizeof(d));
193 16 : SHA1_cleanse(&e, sizeof(e));
194 16 : }
195 :
196 : /* SHA1Init - Initialize new context */
197 8 : void crypto_SHA1_Init(SHA1_CTX *context)
198 : {
199 : /* SHA1 initialization constants */
200 8 : context->state[0] = 0x67452301;
201 8 : context->state[1] = 0xEFCDAB89;
202 8 : context->state[2] = 0x98BADCFE;
203 8 : context->state[3] = 0x10325476;
204 8 : context->state[4] = 0xC3D2E1F0;
205 8 : context->count[0] = context->count[1] = 0;
206 8 : }
207 :
208 : /* Run your data through this. */
209 336 : void crypto_SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len)
210 : {
211 336 : size_t i, j;
212 :
213 336 : j = (context->count[0] >> 3) & 63;
214 336 : if ((context->count[0] += (uint32_t)len << 3) < ((uint32_t)len << 3))
215 0 : context->count[1]++;
216 336 : context->count[1] += (uint32_t)(len >> 29);
217 336 : if ((j + len) > 63) {
218 8 : memcpy(&context->buffer[j], data, (i = 64 - j));
219 8 : SHA1_Transform(context->state, context->buffer);
220 16 : for (; i + 63 < len; i += 64) {
221 0 : SHA1_Transform(context->state, data + i);
222 : }
223 : j = 0;
224 : } else
225 : i = 0;
226 336 : memcpy(&context->buffer[j], &data[i], len - i);
227 336 : }
228 :
229 : /* Add padding and return the message digest. */
230 8 : void crypto_SHA1_Final(SHA1_CTX *context, uint8_t *digest)
231 : {
232 8 : uint32_t i;
233 8 : uint8_t finalcount[8];
234 :
235 72 : for (i = 0; i < 8; i++) {
236 64 : finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
237 64 : ((3 - (i & 3)) * 8)) &
238 : 255); /* Endian independent */
239 : }
240 8 : crypto_SHA1_Update(context, (uint8_t *)"\200", 1);
241 320 : while ((context->count[0] & 504) != 448) {
242 312 : crypto_SHA1_Update(context, (uint8_t *)"\0", 1);
243 : }
244 : /* Should cause a SHA1_Transform() */
245 8 : crypto_SHA1_Update(context, finalcount, 8);
246 168 : for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
247 160 : digest[i] =
248 160 : (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
249 : }
250 :
251 : /* Wipe variables */
252 8 : SHA1_cleanse(context->buffer, 64);
253 8 : SHA1_cleanse(context->state, 20);
254 8 : SHA1_cleanse(context->count, 8);
255 8 : SHA1_cleanse(finalcount, 8); /* SWR */
256 :
257 8 : SHA1_Transform(context->state, context->buffer);
258 8 : }
259 :
260 8 : void crypto_SHA1(const uint8_t *data, size_t len, uint8_t *digest)
261 : {
262 8 : SHA1_CTX ctx;
263 8 : crypto_SHA1_Init(&ctx);
264 8 : crypto_SHA1_Update(&ctx, data, len);
265 8 : crypto_SHA1_Final(&ctx, digest);
266 8 : }
|