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