1 /*
2 SHA-1 in C
3 By Steve Reid <sreid@sea-to-sky.net>
4 100% Public Domain
5 
6 -----------------
7 Modified 7/98
8 By James H. Brown <jbrown@burgoyne.com>
9 Still 100% Public Domain
10 
11 Corrected a problem which generated improper hash values on 16 bit machines
12 Routine SHA1Update changed from
13         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
14 len)
15 to
16         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
17 long len)
18 
19 The 'len' parameter was declared an int which works fine on 32 bit machines.
20 However, on 16 bit machines an int is too small for the shifts being done
21 against
22 it.  This caused the hash function to generate incorrect values if len was
23 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
24 
25 Since the file IO in main() reads 16K at a time, any file 8K or larger would
26 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
27 "a"s).
28 
29 I also changed the declaration of variables i & j in SHA1Update to
30 unsigned long from unsigned int for the same reason.
31 
32 These changes should make no difference to any 32 bit implementations since
33 an
34 int and a long are the same size in those environments.
35 
36 --
37 I also corrected a few compiler warnings generated by Borland C.
38 1. Added #include <process.h> for exit() prototype
39 2. Removed unused variable 'j' in SHA1Final
40 3. Changed exit(0) to return(0) at end of main.
41 
42 ALL changes I made can be located by searching for comments containing 'JHB'
43 -----------------
44 Modified 8/98
45 By Steve Reid <sreid@sea-to-sky.net>
46 Still 100% public domain
47 
48 1- Removed #include <process.h> and used return() instead of exit()
49 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
50 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
51 
52 -----------------
53 Modified 4/01
54 By Saul Kravitz <Saul.Kravitz@celera.com>
55 Still 100% PD
56 Modified to run on Compaq Alpha hardware.
57 
58 -----------------
59 Modified 4/01
60 By Jouni Malinen <jkmaline@cc.hut.fi>
61 Minor changes to match the coding style used in Dynamics.
62 
63 Modified September 24, 2004
64 By Jouni Malinen <jkmaline@cc.hut.fi>
65 Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
66 
67 */
68 
69 /*
70 Test Vectors (from FIPS PUB 180-1)
71 "abc"
72   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
73 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
74   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
75 A million repetitions of "a"
76   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
77 */
78 
79 
80 
81 /*=========================================================================*/
82 #include "tu01_sha1.h"
83 #include <string.h>
84 
85 #undef SHA1HANDSOFF   /* Copies data before messing with it */
86 
87 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
88 
89 /* blk0() and blk() perform the initial expand. */
90 /* I got the idea of expanding during the round function from SSLeay */
91 #ifndef WORDS_BIGENDIAN
92 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
93         (rol(block->l[i], 8) & 0x00FF00FF))
94 #else
95 #define blk0(i) block->l[i]
96 #endif
97 
98 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
99         block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
100 
101 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
102 #define R0(v,w,x,y,z,i) \
103         z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
104         w = rol(w, 30);
105 #define R1(v,w,x,y,z,i) \
106         z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
107         w = rol(w, 30);
108 #define R2(v,w,x,y,z,i) \
109         z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
110 #define R3(v,w,x,y,z,i) \
111         z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
112         w = rol(w, 30);
113 #define R4(v,w,x,y,z,i) \
114         z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
115         w=rol(w, 30);
116 
117 
118 #ifdef VERBOSE                    /* SAK */
119 #include <stdio.h>
120 
SHAPrintContext(SHA1_CTX * context,char * msg)121 void SHAPrintContext (SHA1_CTX * context, char *msg)
122 {
123    printf ("%s (%d,%d) %x %x %x %x %x\n",
124       msg,
125       context->count[0], context->count[1],
126       context->state[0],
127       context->state[1],
128       context->state[2], context->state[3], context->state[4]);
129 }
130 #endif
131 
132 /* Hash a single 512-bit block. This is the core of the algorithm. */
133 
SHA1Transform(uint32_t state[5],const unsigned char buffer[64])134 static void SHA1Transform (uint32_t state[5], const unsigned char buffer[64])
135 {
136    uint32_t a, b, c, d, e;
137    typedef union
138    {
139       unsigned char c[64];
140       uint32_t l[16];
141    } CHAR64LONG16;
142    CHAR64LONG16 *block;
143 #ifdef SHA1HANDSOFF
144    uint32_t workspace[16];
145    block = (CHAR64LONG16 *) workspace;
146    memcpy (block, buffer, 64);
147 #else
148    block = (CHAR64LONG16 *) buffer;
149 #endif
150    /* Copy context->state[] to working vars */
151    a = state[0];
152    b = state[1];
153    c = state[2];
154    d = state[3];
155    e = state[4];
156    /* 4 rounds of 20 operations each. Loop unrolled. */
157    R0 (a, b, c, d, e, 0);
158    R0 (e, a, b, c, d, 1);
159    R0 (d, e, a, b, c, 2);
160    R0 (c, d, e, a, b, 3);
161    R0 (b, c, d, e, a, 4);
162    R0 (a, b, c, d, e, 5);
163    R0 (e, a, b, c, d, 6);
164    R0 (d, e, a, b, c, 7);
165    R0 (c, d, e, a, b, 8);
166    R0 (b, c, d, e, a, 9);
167    R0 (a, b, c, d, e, 10);
168    R0 (e, a, b, c, d, 11);
169    R0 (d, e, a, b, c, 12);
170    R0 (c, d, e, a, b, 13);
171    R0 (b, c, d, e, a, 14);
172    R0 (a, b, c, d, e, 15);
173    R1 (e, a, b, c, d, 16);
174    R1 (d, e, a, b, c, 17);
175    R1 (c, d, e, a, b, 18);
176    R1 (b, c, d, e, a, 19);
177    R2 (a, b, c, d, e, 20);
178    R2 (e, a, b, c, d, 21);
179    R2 (d, e, a, b, c, 22);
180    R2 (c, d, e, a, b, 23);
181    R2 (b, c, d, e, a, 24);
182    R2 (a, b, c, d, e, 25);
183    R2 (e, a, b, c, d, 26);
184    R2 (d, e, a, b, c, 27);
185    R2 (c, d, e, a, b, 28);
186    R2 (b, c, d, e, a, 29);
187    R2 (a, b, c, d, e, 30);
188    R2 (e, a, b, c, d, 31);
189    R2 (d, e, a, b, c, 32);
190    R2 (c, d, e, a, b, 33);
191    R2 (b, c, d, e, a, 34);
192    R2 (a, b, c, d, e, 35);
193    R2 (e, a, b, c, d, 36);
194    R2 (d, e, a, b, c, 37);
195    R2 (c, d, e, a, b, 38);
196    R2 (b, c, d, e, a, 39);
197    R3 (a, b, c, d, e, 40);
198    R3 (e, a, b, c, d, 41);
199    R3 (d, e, a, b, c, 42);
200    R3 (c, d, e, a, b, 43);
201    R3 (b, c, d, e, a, 44);
202    R3 (a, b, c, d, e, 45);
203    R3 (e, a, b, c, d, 46);
204    R3 (d, e, a, b, c, 47);
205    R3 (c, d, e, a, b, 48);
206    R3 (b, c, d, e, a, 49);
207    R3 (a, b, c, d, e, 50);
208    R3 (e, a, b, c, d, 51);
209    R3 (d, e, a, b, c, 52);
210    R3 (c, d, e, a, b, 53);
211    R3 (b, c, d, e, a, 54);
212    R3 (a, b, c, d, e, 55);
213    R3 (e, a, b, c, d, 56);
214    R3 (d, e, a, b, c, 57);
215    R3 (c, d, e, a, b, 58);
216    R3 (b, c, d, e, a, 59);
217    R4 (a, b, c, d, e, 60);
218    R4 (e, a, b, c, d, 61);
219    R4 (d, e, a, b, c, 62);
220    R4 (c, d, e, a, b, 63);
221    R4 (b, c, d, e, a, 64);
222    R4 (a, b, c, d, e, 65);
223    R4 (e, a, b, c, d, 66);
224    R4 (d, e, a, b, c, 67);
225    R4 (c, d, e, a, b, 68);
226    R4 (b, c, d, e, a, 69);
227    R4 (a, b, c, d, e, 70);
228    R4 (e, a, b, c, d, 71);
229    R4 (d, e, a, b, c, 72);
230    R4 (c, d, e, a, b, 73);
231    R4 (b, c, d, e, a, 74);
232    R4 (a, b, c, d, e, 75);
233    R4 (e, a, b, c, d, 76);
234    R4 (d, e, a, b, c, 77);
235    R4 (c, d, e, a, b, 78);
236    R4 (b, c, d, e, a, 79);
237    /* Add the working vars back into context.state[] */
238    state[0] += a;
239    state[1] += b;
240    state[2] += c;
241    state[3] += d;
242    state[4] += e;
243    /* Wipe variables */
244    a = b = c = d = e = 0;
245 #ifdef SHA1HANDSOFF
246    memset (block, 0, 64);
247 #endif
248 }
249 
250 
251 /* SHA1Init - Initialize new context */
252 
SHA1Init(SHA1_CTX * context)253 void SHA1Init (SHA1_CTX * context)
254 {
255    /* SHA1 initialization constants */
256    context->state[0] = 0x67452301;
257    context->state[1] = 0xEFCDAB89;
258    context->state[2] = 0x98BADCFE;
259    context->state[3] = 0x10325476;
260    context->state[4] = 0xC3D2E1F0;
261    context->count[0] = context->count[1] = 0;
262 }
263 
264 
265 /* Run your data through this. */
266 
SHA1Update(SHA1_CTX * context,const unsigned char data[],uint32_t len)267 void SHA1Update (SHA1_CTX * context, const unsigned char data[], uint32_t len)
268 {
269    uint32_t i, j;
270 
271 #ifdef VERBOSE
272    SHAPrintContext (context, "before");
273 #endif
274    j = (context->count[0] >> 3) & 63;
275    if ((context->count[0] += len << 3) < (len << 3))
276       context->count[1]++;
277    context->count[1] += (len >> 29);
278    if ((j + len) > 63) {
279       memcpy (&context->buffer[j], data, (i = 64 - j));
280       SHA1Transform (context->state, context->buffer);
281       for (; i + 63 < len; i += 64) {
282          SHA1Transform (context->state, &data[i]);
283       }
284       j = 0;
285    } else
286       i = 0;
287    memcpy (&context->buffer[j], &data[i], len - i);
288 #ifdef VERBOSE
289    SHAPrintContext (context, "after ");
290 #endif
291 }
292 
293 
294 /* Add padding and return the message digest. */
295 
SHA1Final(unsigned char digest[20],SHA1_CTX * context)296 void SHA1Final (unsigned char digest[20], SHA1_CTX * context)
297 {
298    uint32_t i;
299    unsigned char finalcount[8];
300 
301    for (i = 0; i < 8; i++) {
302       finalcount[i] = (unsigned char)
303          ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255);
304       /* Endian independent */
305    }
306    SHA1Update (context, (unsigned char *) "\200", 1);
307    while ((context->count[0] & 504) != 448) {
308       SHA1Update (context, (unsigned char *) "\0", 1);
309    }
310    SHA1Update (context, finalcount, 8); /* Should cause a SHA1Transform() */
311    for (i = 0; i < 20; i++) {
312       digest[i] = (unsigned char)
313          ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
314    }
315    /* Wipe variables */
316 /*
317    i = 0;
318    memset (context->buffer, 0, 64);
319    memset (context->state, 0, 20);
320    memset (context->count, 0, 8);
321    memset (finalcount, 0, 8);
322 */
323 }
324 
325 
326 #if 0
327 
328 /*************************************************************/
329 /*
330  *  sha1test.c
331  *
332  *  Description:
333  *      This file will exercise the SHA-1 code performing the three
334  *      tests documented in FIPS PUB 180-1 plus one which calls
335  *      SHA1Input with an exact multiple of 512 bits, plus a few
336  *      error test checks.
337  *
338  *  Portability Issues:
339  *      None.
340  *
341  */
342 
343 #include <stdio.h>
344 #include <stdlib.h>
345 
346 /*
347  *  Define patterns for testing
348  */
349 #define TEST1   "abc"
350 #define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
351 
352 #define TEST2b  "jkijkljklmklmnlmnomnopnopq"
353 #define TEST2   TEST2a TEST2b
354 #define TEST3   "a"
355 #define TEST4a  "01234567012345670123456701234567"
356 #define TEST4b  "01234567012345670123456701234567"
357     /* an exact multiple of 512 bits */
358 #define TEST4   TEST4a TEST4b
359 char *testarray[4] = {
360    TEST1,
361    TEST2,
362    TEST3,
363    TEST4
364 };
365 int repeatcount[4] = { 1, 1, 1000000, 10 };
366 char *resultarray[4] = {
367    "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D",
368    "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1",
369    "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F",
370    "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52"
371 };
372 
373 int main (void)
374 {
375    SHA1_CTX sha;
376    int i, j;
377    unsigned char Message_Digest[20];
378 
379    /* Perform SHA-1 tests */
380    for (j = 0; j < 4; ++j) {
381       printf ("\nTest %d: %d, '%s'\n", j + 1, repeatcount[j], testarray[j]);
382       SHA1Init (&sha);
383 
384       for (i = 0; i < repeatcount[j]; ++i) {
385          SHA1Update (&sha, (const unsigned char *) testarray[j],
386             strlen (testarray[j]));
387       }
388 
389       SHA1Final (Message_Digest, &sha);
390       printf ("\t");
391       for (i = 0; i < 20; ++i) {
392          printf ("%02X ", Message_Digest[i]);
393       }
394       printf ("\n");
395       printf ("Should match:\n");
396       printf ("\t%s\n", resultarray[j]);
397    }
398 
399    /* Test some error returns */
400    SHA1Update (&sha, (const unsigned char *) testarray[1], 1);
401    SHA1Init (&sha);
402    return 0;
403 }
404 #endif
405