1/*
2SHA-1 in C
3By Steve Reid <sreid@sea-to-sky.net>
4100% Public Domain
5
6-----------------
7Modified 7/98
8By James H. Brown <jbrown@burgoyne.com>
9Still 100% Public Domain
10
11Corrected a problem which generated improper hash values on 16 bit machines
12Routine SHA1Update changed from
13    void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned int
14len)
15to
16    void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned
17long len)
18
19The 'len' parameter was declared an int which works fine on 32 bit machines.
20However, on 16 bit machines an int is too small for the shifts being done
21against
22it.  This caused the hash function to generate incorrect values if len was
23greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
24
25Since the file IO in main() reads 16K at a time, any file 8K or larger would
26be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
27"a"s).
28
29I also changed the declaration of variables i & j in SHA1Update to
30unsigned long from unsigned int for the same reason.
31
32These changes should make no difference to any 32 bit implementations since
33an
34int and a long are the same size in those environments.
35
36--
37I also corrected a few compiler warnings generated by Borland C.
381. Added #include <process.h> for exit() prototype
392. Removed unused variable 'j' in SHA1Final
403. Changed exit(0) to return(0) at end of main.
41
42ALL changes I made can be located by searching for comments containing 'JHB'
43-----------------
44Modified 8/98
45By Steve Reid <sreid@sea-to-sky.net>
46Still 100% public domain
47
481- Removed #include <process.h> and used return() instead of exit()
492- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
503- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
51
52-----------------
53Modified 4/01
54By Saul Kravitz <Saul.Kravitz@celera.com>
55Still 100% PD
56Modified to run on Compaq Alpha hardware.
57
58-----------------
59Modified 07/2002
60By Ralph Giles <giles@ghostscript.com>
61Still 100% public domain
62modified for use with stdint types, autoconf
63code cleanup, removed attribution comments
64switched SHA1Final() argument order for consistency
65use SHA1_ prefix for public api
66move public api to sha1.h
67*/
68
69/*
7011/2016 adapted for CivetWeb:
71  include sha1.h in sha1.c,
72  rename to sha1.inl
73  remove unused #ifdef sections
74  make endian independent
75  align buffer to 4 bytes
76  remove unused variable assignments
77*/
78
79/*
80Test Vectors (from FIPS PUB 180-1)
81"abc"
82  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
83"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
85A million repetitions of "a"
86  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
87*/
88
89#include <stdint.h>
90#include <string.h>
91
92typedef struct {
93	uint32_t state[5];
94	uint32_t count[2];
95	uint8_t buffer[64];
96} SHA_CTX;
97
98#define SHA1_DIGEST_SIZE 20
99
100#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
101
102/* blk0() and blk() perform the initial expand. */
103/* I got the idea of expanding during the round function from SSLeay */
104
105
106typedef union {
107	uint8_t c[64];
108	uint32_t l[16];
109} CHAR64LONG16;
110
111
112static uint32_t
113blk0(CHAR64LONG16 *block, int i)
114{
115	static const uint32_t n = 1u;
116	if ((*((uint8_t *)(&n))) == 1) {
117		/* little endian / intel byte order */
118		block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00)
119		              | (rol(block->l[i], 8) & 0x00FF00FF);
120	}
121	return block->l[i];
122}
123
124#define blk(block, i)                                                          \
125	((block)->l[(i)&15] =                                                      \
126	     rol((block)->l[((i) + 13) & 15] ^ (block)->l[((i) + 8) & 15]          \
127	             ^ (block)->l[((i) + 2) & 15] ^ (block)->l[(i)&15],            \
128	         1))
129
130/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
131#define R0(v, w, x, y, z, i)                                                   \
132	z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5);        \
133	w = rol(w, 30);
134#define R1(v, w, x, y, z, i)                                                   \
135	z += ((w & (x ^ y)) ^ y) + blk(block, i) + 0x5A827999 + rol(v, 5);         \
136	w = rol(w, 30);
137#define R2(v, w, x, y, z, i)                                                   \
138	z += (w ^ x ^ y) + blk(block, i) + 0x6ED9EBA1 + rol(v, 5);                 \
139	w = rol(w, 30);
140#define R3(v, w, x, y, z, i)                                                   \
141	z += (((w | x) & y) | (w & x)) + blk(block, i) + 0x8F1BBCDC + rol(v, 5);   \
142	w = rol(w, 30);
143#define R4(v, w, x, y, z, i)                                                   \
144	z += (w ^ x ^ y) + blk(block, i) + 0xCA62C1D6 + rol(v, 5);                 \
145	w = rol(w, 30);
146
147
148/* Hash a single 512-bit block. This is the core of the algorithm. */
149static void
150SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
151{
152	uint32_t a, b, c, d, e;
153
154	/* Must use an aligned, read/write buffer */
155	CHAR64LONG16 block[1];
156	memcpy(block, buffer, sizeof(block));
157
158	/* Copy context->state[] to working vars */
159	a = state[0];
160	b = state[1];
161	c = state[2];
162	d = state[3];
163	e = state[4];
164
165	/* 4 rounds of 20 operations each. Loop unrolled. */
166	R0(a, b, c, d, e, 0);
167	R0(e, a, b, c, d, 1);
168	R0(d, e, a, b, c, 2);
169	R0(c, d, e, a, b, 3);
170	R0(b, c, d, e, a, 4);
171	R0(a, b, c, d, e, 5);
172	R0(e, a, b, c, d, 6);
173	R0(d, e, a, b, c, 7);
174	R0(c, d, e, a, b, 8);
175	R0(b, c, d, e, a, 9);
176	R0(a, b, c, d, e, 10);
177	R0(e, a, b, c, d, 11);
178	R0(d, e, a, b, c, 12);
179	R0(c, d, e, a, b, 13);
180	R0(b, c, d, e, a, 14);
181	R0(a, b, c, d, e, 15);
182	R1(e, a, b, c, d, 16);
183	R1(d, e, a, b, c, 17);
184	R1(c, d, e, a, b, 18);
185	R1(b, c, d, e, a, 19);
186	R2(a, b, c, d, e, 20);
187	R2(e, a, b, c, d, 21);
188	R2(d, e, a, b, c, 22);
189	R2(c, d, e, a, b, 23);
190	R2(b, c, d, e, a, 24);
191	R2(a, b, c, d, e, 25);
192	R2(e, a, b, c, d, 26);
193	R2(d, e, a, b, c, 27);
194	R2(c, d, e, a, b, 28);
195	R2(b, c, d, e, a, 29);
196	R2(a, b, c, d, e, 30);
197	R2(e, a, b, c, d, 31);
198	R2(d, e, a, b, c, 32);
199	R2(c, d, e, a, b, 33);
200	R2(b, c, d, e, a, 34);
201	R2(a, b, c, d, e, 35);
202	R2(e, a, b, c, d, 36);
203	R2(d, e, a, b, c, 37);
204	R2(c, d, e, a, b, 38);
205	R2(b, c, d, e, a, 39);
206	R3(a, b, c, d, e, 40);
207	R3(e, a, b, c, d, 41);
208	R3(d, e, a, b, c, 42);
209	R3(c, d, e, a, b, 43);
210	R3(b, c, d, e, a, 44);
211	R3(a, b, c, d, e, 45);
212	R3(e, a, b, c, d, 46);
213	R3(d, e, a, b, c, 47);
214	R3(c, d, e, a, b, 48);
215	R3(b, c, d, e, a, 49);
216	R3(a, b, c, d, e, 50);
217	R3(e, a, b, c, d, 51);
218	R3(d, e, a, b, c, 52);
219	R3(c, d, e, a, b, 53);
220	R3(b, c, d, e, a, 54);
221	R3(a, b, c, d, e, 55);
222	R3(e, a, b, c, d, 56);
223	R3(d, e, a, b, c, 57);
224	R3(c, d, e, a, b, 58);
225	R3(b, c, d, e, a, 59);
226	R4(a, b, c, d, e, 60);
227	R4(e, a, b, c, d, 61);
228	R4(d, e, a, b, c, 62);
229	R4(c, d, e, a, b, 63);
230	R4(b, c, d, e, a, 64);
231	R4(a, b, c, d, e, 65);
232	R4(e, a, b, c, d, 66);
233	R4(d, e, a, b, c, 67);
234	R4(c, d, e, a, b, 68);
235	R4(b, c, d, e, a, 69);
236	R4(a, b, c, d, e, 70);
237	R4(e, a, b, c, d, 71);
238	R4(d, e, a, b, c, 72);
239	R4(c, d, e, a, b, 73);
240	R4(b, c, d, e, a, 74);
241	R4(a, b, c, d, e, 75);
242	R4(e, a, b, c, d, 76);
243	R4(d, e, a, b, c, 77);
244	R4(c, d, e, a, b, 78);
245	R4(b, c, d, e, a, 79);
246
247	/* Add the working vars back into context.state[] */
248	state[0] += a;
249	state[1] += b;
250	state[2] += c;
251	state[3] += d;
252	state[4] += e;
253}
254
255
256/* SHA1Init - Initialize new context */
257SHA_API void
258SHA1_Init(SHA_CTX *context)
259{
260	/* SHA1 initialization constants */
261	context->state[0] = 0x67452301;
262	context->state[1] = 0xEFCDAB89;
263	context->state[2] = 0x98BADCFE;
264	context->state[3] = 0x10325476;
265	context->state[4] = 0xC3D2E1F0;
266	context->count[0] = context->count[1] = 0;
267}
268
269
270SHA_API void
271SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len)
272{
273	uint32_t i, j;
274
275	j = context->count[0];
276	if ((context->count[0] += (len << 3)) < j) {
277		context->count[1]++;
278	}
279	context->count[1] += (len >> 29);
280	j = (j >> 3) & 63;
281	if ((j + len) > 63) {
282		i = 64 - j;
283		memcpy(&context->buffer[j], data, i);
284		SHA1_Transform(context->state, context->buffer);
285		for (; i + 63 < len; i += 64) {
286			SHA1_Transform(context->state, &data[i]);
287		}
288		j = 0;
289	} else {
290		i = 0;
291	}
292	memcpy(&context->buffer[j], &data[i], len - i);
293}
294
295
296/* Add padding and return the message digest. */
297SHA_API void
298SHA1_Final(unsigned char *digest, SHA_CTX *context)
299{
300	uint32_t i;
301	uint8_t finalcount[8];
302
303	for (i = 0; i < 8; i++) {
304		finalcount[i] =
305		    (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8))
306		              & 255); /* Endian independent */
307	}
308	SHA1_Update(context, (uint8_t *)"\x80", 1);
309	while ((context->count[0] & 504) != 448) {
310		SHA1_Update(context, (uint8_t *)"\x00", 1);
311	}
312	SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
313	for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
314		digest[i] =
315		    (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
316	}
317
318	/* Wipe variables */
319	memset(context, '\0', sizeof(*context));
320}
321
322
323/* End of sha1.inl */
324