1 /* Slightly modified for vsearch by Torbjorn Rognes */
2
3 /*
4 SHA-1 in C
5 By Steve Reid <sreid@sea-to-sky.net>
6 100% Public Domain
7
8 -----------------
9 Modified 7/98
10 By James H. Brown <jbrown@burgoyne.com>
11 Still 100% Public Domain
12
13 Corrected a problem which generated improper hash values on 16 bit machines
14 Routine SHA1Update changed from
15 void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
16 len)
17 to
18 void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
19 long len)
20
21 The 'len' parameter was declared an int which works fine on 32 bit machines.
22 However, on 16 bit machines an int is too small for the shifts being done
23 against
24 it. This caused the hash function to generate incorrect values if len was
25 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
26
27 Since the file IO in main() reads 16K at a time, any file 8K or larger would
28 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
29 "a"s).
30
31 I also changed the declaration of variables i & j in SHA1Update to
32 unsigned long from unsigned int for the same reason.
33
34 These changes should make no difference to any 32 bit implementations since
35 an
36 int and a long are the same size in those environments.
37
38 --
39 I also corrected a few compiler warnings generated by Borland C.
40 1. Added #include <process.h> for exit() prototype
41 2. Removed unused variable 'j' in SHA1Final
42 3. Changed exit(0) to return(0) at end of main.
43
44 ALL changes I made can be located by searching for comments containing 'JHB'
45 -----------------
46 Modified 8/98
47 By Steve Reid <sreid@sea-to-sky.net>
48 Still 100% public domain
49
50 1- Removed #include <process.h> and used return() instead of exit()
51 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
52 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
53
54 -----------------
55 Modified 4/01
56 By Saul Kravitz <Saul.Kravitz@celera.com>
57 Still 100% PD
58 Modified to run on Compaq Alpha hardware.
59
60 -----------------
61 Modified 07/2002
62 By Ralph Giles <giles@ghostscript.com>
63 Still 100% public domain
64 modified for use with stdint types, autoconf
65 code cleanup, removed attribution comments
66 switched SHA1Final() argument order for consistency
67 use SHA1_ prefix for public api
68 move public api to sha1.h
69 */
70
71 /*
72 Test Vectors (from FIPS PUB 180-1)
73 "abc"
74 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
75 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
76 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
77 A million repetitions of "a"
78 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
79 */
80
81 /* #define SHA1HANDSOFF */
82
83 #ifdef HAVE_CONFIG_H
84 #include "config.h"
85 #endif
86
87 #include <stdio.h>
88 #include <string.h>
89
90 #include <stdint.h>
91 #include "sha1.h"
92
93 void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
94
95 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
96
97 /* blk0() and blk() perform the initial expand. */
98 /* I got the idea of expanding during the round function from SSLeay */
99 /* FIXME: can we do this in an endian-proof way? */
100 #ifdef WORDS_BIGENDIAN
101 #define blk0(i) block->l[i]
102 #else
103 #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
104 |(rol(block->l[i],8)&0x00FF00FF))
105 #endif
106 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
107 ^block->l[(i+2)&15]^block->l[i&15],1))
108
109 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
110 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
111 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
112 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
113 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
114 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
115
116
117 #ifdef VERBOSE /* SAK */
SHAPrintContext(SHA1_CTX * context,char * msg)118 void SHAPrintContext(SHA1_CTX *context, char *msg){
119 printf("%s (%d,%d) %x %x %x %x %x\n",
120 msg,
121 context->count[0], context->count[1],
122 context->state[0],
123 context->state[1],
124 context->state[2],
125 context->state[3],
126 context->state[4]);
127 }
128 #endif /* VERBOSE */
129
130 /* Hash a single 512-bit block. This is the core of the algorithm. */
SHA1_Transform(uint32_t state[5],const uint8_t buffer[64])131 void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
132 {
133 uint32_t a, b, c, d, e;
134 typedef union {
135 uint8_t c[64];
136 uint32_t l[16];
137 } CHAR64LONG16;
138 CHAR64LONG16* block;
139
140 #ifdef SHA1HANDSOFF
141 static uint8_t workspace[64];
142 block = (CHAR64LONG16*)workspace;
143 memcpy(block, buffer, 64);
144 #else
145 block = (CHAR64LONG16*)buffer;
146 #endif
147
148 /* Copy context->state[] to working vars */
149 a = state[0];
150 b = state[1];
151 c = state[2];
152 d = state[3];
153 e = state[4];
154
155 /* 4 rounds of 20 operations each. Loop unrolled. */
156 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);
157 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);
158 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);
159 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);
160 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);
161 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);
162 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);
163 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);
164 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);
165 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);
166 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);
167 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);
168 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);
169 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);
170 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);
171 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);
172 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);
173 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);
174 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);
175 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);
176
177 /* Add the working vars back into context.state[] */
178 state[0] += a;
179 state[1] += b;
180 state[2] += c;
181 state[3] += d;
182 state[4] += e;
183
184 /* Wipe variables */
185 a = b = c = d = e = 0;
186 }
187
188
189 /* SHA1Init - Initialize new context */
SHA1_Init(SHA1_CTX * context)190 void SHA1_Init(SHA1_CTX* context)
191 {
192 /* SHA1 initialization constants */
193 context->state[0] = 0x67452301;
194 context->state[1] = 0xEFCDAB89;
195 context->state[2] = 0x98BADCFE;
196 context->state[3] = 0x10325476;
197 context->state[4] = 0xC3D2E1F0;
198 context->count[0] = context->count[1] = 0;
199 }
200
201
202 /* Run your data through this. */
SHA1_Update(SHA1_CTX * context,const uint8_t * data,const size_t len)203 void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
204 {
205 size_t i, j;
206
207 #ifdef VERBOSE
208 SHAPrintContext(context, "before");
209 #endif
210
211 j = (context->count[0] >> 3) & 63;
212 if ((context->count[0] += len << 3) < (len << 3)) { context->count[1]++;
213
214 }
215 context->count[1] += (len >> 29);
216 if ((j + len) > 63) {
217 memcpy(&context->buffer[j], data, (i = 64-j));
218 SHA1_Transform(context->state, context->buffer);
219 for ( ; i + 63 < len; i += 64) {
220 SHA1_Transform(context->state, data + i);
221 }
222 j = 0;
223 }
224 else { i = 0;
225
226 }
227 memcpy(&context->buffer[j], &data[i], len - i);
228
229 #ifdef VERBOSE
230 SHAPrintContext(context, "after ");
231 #endif
232 }
233
234
235 /* Add padding and return the message digest. */
SHA1_Final(SHA1_CTX * context,uint8_t digest[SHA1_DIGEST_SIZE])236 void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
237 {
238 uint32_t i;
239 uint8_t finalcount[8];
240
241 for (i = 0; i < 8; i++) {
242 finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
243 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
244 }
245 SHA1_Update(context, (uint8_t *)"\200", 1);
246 while ((context->count[0] & 504) != 448) {
247 SHA1_Update(context, (uint8_t *)"\0", 1);
248 }
249 SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
250 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
251 digest[i] = (uint8_t)
252 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
253 }
254
255 /* Wipe variables */
256 i = 0;
257 memset(context->buffer, 0, 64);
258 memset(context->state, 0, 20);
259 memset(context->count, 0, 8);
260 memset(finalcount, 0, 8); /* SWR */
261
262 #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
263 SHA1_Transform(context->state, context->buffer);
264 #endif
265 }
266
267 /*************************************************************/
268
269 #if 0
270 int main(int argc, char** argv)
271 {
272 int i, j;
273 SHA1_CTX context;
274 unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384];
275 FILE* file;
276
277 if (argc > 2) {
278 puts("Public domain SHA-1 implementation - by Steve Reid <sreid@sea-to-sky.net>");
279 puts("Modified for 16 bit environments 7/98 - by James H. Brown <jbrown@burgoyne.com>"); /* JHB */
280 puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
281 return(0);
282 }
283 if (argc < 2) {
284 file = stdin;
285 }
286 else {
287 if (!(file = fopen(argv[1], "rb"))) {
288 fputs("Unable to open file.", stderr);
289 return(-1);
290 }
291 }
292 SHA1_Init(&context);
293 while (!feof(file)) { /* note: what if ferror(file) */
294 i = fread(buffer, 1, 16384, file);
295 SHA1_Update(&context, buffer, i);
296 }
297 SHA1_Final(&context, digest);
298 fclose(file);
299 for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
300 for (j = 0; j < 4; j++) {
301 printf("%02X", digest[i*4+j]);
302 }
303 putchar(' ');
304 }
305 putchar('\n');
306 return(0); /* JHB */
307 }
308 #endif
309
310 /* self test */
311
312 #ifdef TEST
313
314 static char *test_data[] = {
315 "abc",
316 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
317 "A million repetitions of 'a'"};
318 static char *test_results[] = {
319 "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
320 "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
321 "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
322
323
digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE],char * output)324 void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
325 {
326 int i,j;
327 char *c = output;
328
329 for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
330 for (j = 0; j < 4; j++) {
331 sprintf(c,"%02X", digest[i*4+j]);
332 c += 2;
333 }
334 sprintf(c, " ");
335 c += 1;
336 }
337 *(c - 1) = '\0';
338 }
339
main(int argc,char ** argv)340 int main(int argc, char** argv)
341 {
342 int k;
343 SHA1_CTX context;
344 uint8_t digest[20];
345 char output[80];
346
347 fprintf(stdout, "verifying SHA-1 implementation... ");
348
349 for (k = 0; k < 2; k++){
350 SHA1_Init(&context);
351 SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
352 SHA1_Final(&context, digest);
353 digest_to_hex(digest, output);
354
355 if (strcmp(output, test_results[k])) {
356 fprintf(stdout, "FAIL\n");
357 fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
358 fprintf(stderr,"\t%s returned\n", output);
359 fprintf(stderr,"\t%s is correct\n", test_results[k]);
360 return (1);
361 }
362 }
363 /* million 'a' vector we feed separately */
364 SHA1_Init(&context);
365 for (k = 0; k < 1000000; k++)
366 SHA1_Update(&context, (uint8_t*)"a", 1);
367 SHA1_Final(&context, digest);
368 digest_to_hex(digest, output);
369 if (strcmp(output, test_results[2])) {
370 fprintf(stdout, "FAIL\n");
371 fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
372 fprintf(stderr,"\t%s returned\n", output);
373 fprintf(stderr,"\t%s is correct\n", test_results[2]);
374 return (1);
375 }
376
377 /* success */
378 fprintf(stdout, "ok\n");
379 return(0);
380 }
381 #endif /* TEST */
382