702b861cb05b8df4f54ff38d470b600c0cb500c0
[libeap.git] / src / crypto / sha1-internal.c
1 /*
2  * SHA1 hash implementation and interface functions
3  * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "sha1.h"
19 #include "md5.h"
20 #include "crypto.h"
21
22 struct SHA1Context {
23         u32 state[5];
24         u32 count[2];
25         unsigned char buffer[64];
26 };
27
28 typedef struct SHA1Context SHA1_CTX;
29
30 #ifndef CONFIG_CRYPTO_INTERNAL
31 static void SHA1Init(struct SHA1Context *context);
32 static void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
33 static void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
34 #endif /* CONFIG_CRYPTO_INTERNAL */
35 static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
36
37
38 /**
39  * sha1_vector - SHA-1 hash for data vector
40  * @num_elem: Number of elements in the data vector
41  * @addr: Pointers to the data areas
42  * @len: Lengths of the data blocks
43  * @mac: Buffer for the hash
44  */
45 void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
46                  u8 *mac)
47 {
48         SHA1_CTX ctx;
49         size_t i;
50
51         SHA1Init(&ctx);
52         for (i = 0; i < num_elem; i++)
53                 SHA1Update(&ctx, addr[i], len[i]);
54         SHA1Final(mac, &ctx);
55 }
56
57
58 #ifndef CONFIG_NO_FIPS186_2_PRF
59 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
60 {
61         u8 xkey[64];
62         u32 t[5], _t[5];
63         int i, j, m, k;
64         u8 *xpos = x;
65         u32 carry;
66
67         if (seed_len > sizeof(xkey))
68                 seed_len = sizeof(xkey);
69
70         /* FIPS 186-2 + change notice 1 */
71
72         os_memcpy(xkey, seed, seed_len);
73         os_memset(xkey + seed_len, 0, 64 - seed_len);
74         t[0] = 0x67452301;
75         t[1] = 0xEFCDAB89;
76         t[2] = 0x98BADCFE;
77         t[3] = 0x10325476;
78         t[4] = 0xC3D2E1F0;
79
80         m = xlen / 40;
81         for (j = 0; j < m; j++) {
82                 /* XSEED_j = 0 */
83                 for (i = 0; i < 2; i++) {
84                         /* XVAL = (XKEY + XSEED_j) mod 2^b */
85
86                         /* w_i = G(t, XVAL) */
87                         os_memcpy(_t, t, 20);
88                         SHA1Transform(_t, xkey);
89                         _t[0] = host_to_be32(_t[0]);
90                         _t[1] = host_to_be32(_t[1]);
91                         _t[2] = host_to_be32(_t[2]);
92                         _t[3] = host_to_be32(_t[3]);
93                         _t[4] = host_to_be32(_t[4]);
94                         os_memcpy(xpos, _t, 20);
95
96                         /* XKEY = (1 + XKEY + w_i) mod 2^b */
97                         carry = 1;
98                         for (k = 19; k >= 0; k--) {
99                                 carry += xkey[k] + xpos[k];
100                                 xkey[k] = carry & 0xff;
101                                 carry >>= 8;
102                         }
103
104                         xpos += SHA1_MAC_LEN;
105                 }
106                 /* x_j = w_0|w_1 */
107         }
108
109         return 0;
110 }
111 #endif /* CONFIG_NO_FIPS186_2_PRF */
112
113
114 /* ===== start - public domain SHA1 implementation ===== */
115
116 /*
117 SHA-1 in C
118 By Steve Reid <sreid@sea-to-sky.net>
119 100% Public Domain
120
121 -----------------
122 Modified 7/98 
123 By James H. Brown <jbrown@burgoyne.com>
124 Still 100% Public Domain
125
126 Corrected a problem which generated improper hash values on 16 bit machines
127 Routine SHA1Update changed from
128         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
129 len)
130 to
131         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
132 long len)
133
134 The 'len' parameter was declared an int which works fine on 32 bit machines.
135 However, on 16 bit machines an int is too small for the shifts being done
136 against
137 it.  This caused the hash function to generate incorrect values if len was
138 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
139
140 Since the file IO in main() reads 16K at a time, any file 8K or larger would
141 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
142 "a"s).
143
144 I also changed the declaration of variables i & j in SHA1Update to 
145 unsigned long from unsigned int for the same reason.
146
147 These changes should make no difference to any 32 bit implementations since
148 an
149 int and a long are the same size in those environments.
150
151 --
152 I also corrected a few compiler warnings generated by Borland C.
153 1. Added #include <process.h> for exit() prototype
154 2. Removed unused variable 'j' in SHA1Final
155 3. Changed exit(0) to return(0) at end of main.
156
157 ALL changes I made can be located by searching for comments containing 'JHB'
158 -----------------
159 Modified 8/98
160 By Steve Reid <sreid@sea-to-sky.net>
161 Still 100% public domain
162
163 1- Removed #include <process.h> and used return() instead of exit()
164 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
165 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
166
167 -----------------
168 Modified 4/01
169 By Saul Kravitz <Saul.Kravitz@celera.com>
170 Still 100% PD
171 Modified to run on Compaq Alpha hardware.  
172
173 -----------------
174 Modified 4/01
175 By Jouni Malinen <j@w1.fi>
176 Minor changes to match the coding style used in Dynamics.
177
178 Modified September 24, 2004
179 By Jouni Malinen <j@w1.fi>
180 Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
181
182 */
183
184 /*
185 Test Vectors (from FIPS PUB 180-1)
186 "abc"
187   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
188 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
189   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
190 A million repetitions of "a"
191   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
192 */
193
194 #define SHA1HANDSOFF
195
196 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
197
198 /* blk0() and blk() perform the initial expand. */
199 /* I got the idea of expanding during the round function from SSLeay */
200 #ifndef WORDS_BIGENDIAN
201 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
202         (rol(block->l[i], 8) & 0x00FF00FF))
203 #else
204 #define blk0(i) block->l[i]
205 #endif
206 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
207         block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
208
209 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
210 #define R0(v,w,x,y,z,i) \
211         z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
212         w = rol(w, 30);
213 #define R1(v,w,x,y,z,i) \
214         z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
215         w = rol(w, 30);
216 #define R2(v,w,x,y,z,i) \
217         z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
218 #define R3(v,w,x,y,z,i) \
219         z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
220         w = rol(w, 30);
221 #define R4(v,w,x,y,z,i) \
222         z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
223         w=rol(w, 30);
224
225
226 #ifdef VERBOSE  /* SAK */
227 void SHAPrintContext(SHA1_CTX *context, char *msg)
228 {
229         printf("%s (%d,%d) %x %x %x %x %x\n",
230                msg,
231                context->count[0], context->count[1], 
232                context->state[0],
233                context->state[1],
234                context->state[2],
235                context->state[3],
236                context->state[4]);
237 }
238 #endif
239
240 /* Hash a single 512-bit block. This is the core of the algorithm. */
241
242 static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
243 {
244         u32 a, b, c, d, e;
245         typedef union {
246                 unsigned char c[64];
247                 u32 l[16];
248         } CHAR64LONG16;
249         CHAR64LONG16* block;
250 #ifdef SHA1HANDSOFF
251         u32 workspace[16];
252         block = (CHAR64LONG16 *) workspace;
253         os_memcpy(block, buffer, 64);
254 #else
255         block = (CHAR64LONG16 *) buffer;
256 #endif
257         /* Copy context->state[] to working vars */
258         a = state[0];
259         b = state[1];
260         c = state[2];
261         d = state[3];
262         e = state[4];
263         /* 4 rounds of 20 operations each. Loop unrolled. */
264         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);
265         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);
266         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);
267         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);
268         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);
269         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);
270         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);
271         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);
272         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);
273         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);
274         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);
275         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);
276         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);
277         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);
278         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);
279         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);
280         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);
281         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);
282         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);
283         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);
284         /* Add the working vars back into context.state[] */
285         state[0] += a;
286         state[1] += b;
287         state[2] += c;
288         state[3] += d;
289         state[4] += e;
290         /* Wipe variables */
291         a = b = c = d = e = 0;
292 #ifdef SHA1HANDSOFF
293         os_memset(block, 0, 64);
294 #endif
295 }
296
297
298 /* SHA1Init - Initialize new context */
299
300 void SHA1Init(SHA1_CTX* context)
301 {
302         /* SHA1 initialization constants */
303         context->state[0] = 0x67452301;
304         context->state[1] = 0xEFCDAB89;
305         context->state[2] = 0x98BADCFE;
306         context->state[3] = 0x10325476;
307         context->state[4] = 0xC3D2E1F0;
308         context->count[0] = context->count[1] = 0;
309 }
310
311
312 /* Run your data through this. */
313
314 void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
315 {
316         u32 i, j;
317         const unsigned char *data = _data;
318
319 #ifdef VERBOSE
320         SHAPrintContext(context, "before");
321 #endif
322         j = (context->count[0] >> 3) & 63;
323         if ((context->count[0] += len << 3) < (len << 3))
324                 context->count[1]++;
325         context->count[1] += (len >> 29);
326         if ((j + len) > 63) {
327                 os_memcpy(&context->buffer[j], data, (i = 64-j));
328                 SHA1Transform(context->state, context->buffer);
329                 for ( ; i + 63 < len; i += 64) {
330                         SHA1Transform(context->state, &data[i]);
331                 }
332                 j = 0;
333         }
334         else i = 0;
335         os_memcpy(&context->buffer[j], &data[i], len - i);
336 #ifdef VERBOSE
337         SHAPrintContext(context, "after ");
338 #endif
339 }
340
341
342 /* Add padding and return the message digest. */
343
344 void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
345 {
346         u32 i;
347         unsigned char finalcount[8];
348
349         for (i = 0; i < 8; i++) {
350                 finalcount[i] = (unsigned char)
351                         ((context->count[(i >= 4 ? 0 : 1)] >>
352                           ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
353         }
354         SHA1Update(context, (unsigned char *) "\200", 1);
355         while ((context->count[0] & 504) != 448) {
356                 SHA1Update(context, (unsigned char *) "\0", 1);
357         }
358         SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
359                                               */
360         for (i = 0; i < 20; i++) {
361                 digest[i] = (unsigned char)
362                         ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
363                          255);
364         }
365         /* Wipe variables */
366         i = 0;
367         os_memset(context->buffer, 0, 64);
368         os_memset(context->state, 0, 20);
369         os_memset(context->count, 0, 8);
370         os_memset(finalcount, 0, 8);
371 }
372
373 /* ===== end - public domain SHA1 implementation ===== */