GC wpa_supplicant 0.4.9
[dragonfly/port-amd64.git] / contrib / hostapd-0.4.9 / sha1.c
blob7e32e31ca1ba898566a8f4e83b046ed152c3fff5
1 /*
2 * SHA1 hash implementation and interface functions
3 * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
19 #include "common.h"
20 #include "sha1.h"
21 #include "md5.h"
22 #include "crypto.h"
25 /**
26 * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104)
27 * @key: Key for HMAC operations
28 * @key_len: Length of the key in bytes
29 * @num_elem: Number of elements in the data vector
30 * @addr: Pointers to the data areas
31 * @len: Lengths of the data blocks
32 * @mac: Buffer for the hash (20 bytes)
34 void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
35 const u8 *addr[], const size_t *len, u8 *mac)
37 unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
38 unsigned char tk[20];
39 int i;
40 const u8 *_addr[6];
41 size_t _len[6];
43 if (num_elem > 5) {
45 * Fixed limit on the number of fragments to avoid having to
46 * allocate memory (which could fail).
48 return;
51 /* if key is longer than 64 bytes reset it to key = SHA1(key) */
52 if (key_len > 64) {
53 sha1_vector(1, &key, &key_len, tk);
54 key = tk;
55 key_len = 20;
58 /* the HMAC_SHA1 transform looks like:
60 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
62 * where K is an n byte key
63 * ipad is the byte 0x36 repeated 64 times
64 * opad is the byte 0x5c repeated 64 times
65 * and text is the data being protected */
67 /* start out by storing key in ipad */
68 memset(k_pad, 0, sizeof(k_pad));
69 memcpy(k_pad, key, key_len);
70 /* XOR key with ipad values */
71 for (i = 0; i < 64; i++)
72 k_pad[i] ^= 0x36;
74 /* perform inner SHA1 */
75 _addr[0] = k_pad;
76 _len[0] = 64;
77 for (i = 0; i < num_elem; i++) {
78 _addr[i + 1] = addr[i];
79 _len[i + 1] = len[i];
81 sha1_vector(1 + num_elem, _addr, _len, mac);
83 memset(k_pad, 0, sizeof(k_pad));
84 memcpy(k_pad, key, key_len);
85 /* XOR key with opad values */
86 for (i = 0; i < 64; i++)
87 k_pad[i] ^= 0x5c;
89 /* perform outer SHA1 */
90 _addr[0] = k_pad;
91 _len[0] = 64;
92 _addr[1] = mac;
93 _len[1] = SHA1_MAC_LEN;
94 sha1_vector(2, _addr, _len, mac);
98 /**
99 * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104)
100 * @key: Key for HMAC operations
101 * @key_len: Length of the key in bytes
102 * @data: Pointers to the data area
103 * @data_len: Length of the data area
104 * @mac: Buffer for the hash (20 bytes)
106 void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
107 u8 *mac)
109 hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
114 * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
115 * @key: Key for PRF
116 * @key_len: Length of the key in bytes
117 * @label: A unique label for each purpose of the PRF
118 * @data: Extra data to bind into the key
119 * @data_len: Length of the data
120 * @buf: Buffer for the generated pseudo-random key
121 * @buf_len: Number of bytes of key to generate
123 * This function is used to derive new, cryptographically separate keys from a
124 * given key (e.g., PMK in IEEE 802.11i).
126 void sha1_prf(const u8 *key, size_t key_len, const char *label,
127 const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
129 u8 zero = 0, counter = 0;
130 size_t pos, plen;
131 u8 hash[SHA1_MAC_LEN];
132 size_t label_len = strlen(label);
133 const unsigned char *addr[4];
134 size_t len[4];
136 addr[0] = (u8 *) label;
137 len[0] = label_len;
138 addr[1] = &zero;
139 len[1] = 1;
140 addr[2] = data;
141 len[2] = data_len;
142 addr[3] = &counter;
143 len[3] = 1;
145 pos = 0;
146 while (pos < buf_len) {
147 plen = buf_len - pos;
148 if (plen >= SHA1_MAC_LEN) {
149 hmac_sha1_vector(key, key_len, 4, addr, len,
150 &buf[pos]);
151 pos += SHA1_MAC_LEN;
152 } else {
153 hmac_sha1_vector(key, key_len, 4, addr, len,
154 hash);
155 memcpy(&buf[pos], hash, plen);
156 break;
158 counter++;
164 * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
165 * @key: Key for PRF
166 * @key_len: Length of the key in bytes
167 * @label: A unique label for each purpose of the PRF
168 * @seed: Seed value to bind into the key
169 * @seed_len: Length of the seed
170 * @buf: Buffer for the generated pseudo-random key
171 * @buf_len: Number of bytes of key to generate
173 * This function is used to derive new, cryptographically separate keys from a
174 * given key for EAP-FAST. T-PRF is defined in
175 * draft-cam-winget-eap-fast-02.txt, Appendix B.
177 void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
178 const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
180 unsigned char counter = 0;
181 size_t pos, plen;
182 u8 hash[SHA1_MAC_LEN];
183 size_t label_len = strlen(label);
184 u8 output_len[2];
185 const unsigned char *addr[5];
186 size_t len[5];
188 addr[0] = hash;
189 len[0] = 0;
190 addr[1] = (unsigned char *) label;
191 len[1] = label_len + 1;
192 addr[2] = seed;
193 len[2] = seed_len;
194 addr[3] = output_len;
195 len[3] = 2;
196 addr[4] = &counter;
197 len[4] = 1;
199 output_len[0] = (buf_len >> 8) & 0xff;
200 output_len[1] = buf_len & 0xff;
201 pos = 0;
202 while (pos < buf_len) {
203 counter++;
204 plen = buf_len - pos;
205 hmac_sha1_vector(key, key_len, 5, addr, len, hash);
206 if (plen >= SHA1_MAC_LEN) {
207 memcpy(&buf[pos], hash, SHA1_MAC_LEN);
208 pos += SHA1_MAC_LEN;
209 } else {
210 memcpy(&buf[pos], hash, plen);
211 break;
213 len[0] = SHA1_MAC_LEN;
219 * tls_prf - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
220 * @secret: Key for PRF
221 * @secret_len: Length of the key in bytes
222 * @label: A unique label for each purpose of the PRF
223 * @seed: Seed value to bind into the key
224 * @seed_len: Length of the seed
225 * @out: Buffer for the generated pseudo-random key
226 * @outlen: Number of bytes of key to generate
228 * This function is used to derive new, cryptographically separate keys from a
229 * given key in TLS. This PRF is defined in RFC 2246, Chapter 5.
231 int tls_prf(const u8 *secret, size_t secret_len, const char *label,
232 const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
234 size_t L_S1, L_S2;
235 const u8 *S1, *S2;
236 u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
237 u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
238 int i, MD5_pos, SHA1_pos;
239 const u8 *MD5_addr[3];
240 size_t MD5_len[3];
241 const unsigned char *SHA1_addr[3];
242 size_t SHA1_len[3];
244 if (secret_len & 1)
245 return -1;
247 MD5_addr[0] = A_MD5;
248 MD5_len[0] = MD5_MAC_LEN;
249 MD5_addr[1] = (unsigned char *) label;
250 MD5_len[1] = strlen(label);
251 MD5_addr[2] = seed;
252 MD5_len[2] = seed_len;
254 SHA1_addr[0] = A_SHA1;
255 SHA1_len[0] = SHA1_MAC_LEN;
256 SHA1_addr[1] = (unsigned char *) label;
257 SHA1_len[1] = strlen(label);
258 SHA1_addr[2] = seed;
259 SHA1_len[2] = seed_len;
261 /* RFC 2246, Chapter 5
262 * A(0) = seed, A(i) = HMAC(secret, A(i-1))
263 * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + ..
264 * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
267 L_S1 = L_S2 = (secret_len + 1) / 2;
268 S1 = secret;
269 S2 = secret + L_S1;
271 hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
272 hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
274 MD5_pos = MD5_MAC_LEN;
275 SHA1_pos = SHA1_MAC_LEN;
276 for (i = 0; i < outlen; i++) {
277 if (MD5_pos == MD5_MAC_LEN) {
278 hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
279 MD5_pos = 0;
280 hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
282 if (SHA1_pos == SHA1_MAC_LEN) {
283 hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
284 P_SHA1);
285 SHA1_pos = 0;
286 hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
289 out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
291 MD5_pos++;
292 SHA1_pos++;
295 return 0;
299 static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
300 size_t ssid_len, int iterations, int count,
301 u8 *digest)
303 unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
304 int i, j;
305 unsigned char count_buf[4];
306 const u8 *addr[2];
307 size_t len[2];
308 size_t passphrase_len = strlen(passphrase);
310 addr[0] = (u8 *) ssid;
311 len[0] = ssid_len;
312 addr[1] = count_buf;
313 len[1] = 4;
315 /* F(P, S, c, i) = U1 xor U2 xor ... Uc
316 * U1 = PRF(P, S || i)
317 * U2 = PRF(P, U1)
318 * Uc = PRF(P, Uc-1)
321 count_buf[0] = (count >> 24) & 0xff;
322 count_buf[1] = (count >> 16) & 0xff;
323 count_buf[2] = (count >> 8) & 0xff;
324 count_buf[3] = count & 0xff;
325 hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
326 memcpy(digest, tmp, SHA1_MAC_LEN);
328 for (i = 1; i < iterations; i++) {
329 hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
330 tmp2);
331 memcpy(tmp, tmp2, SHA1_MAC_LEN);
332 for (j = 0; j < SHA1_MAC_LEN; j++)
333 digest[j] ^= tmp2[j];
339 * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
340 * @passphrase: ASCII passphrase
341 * @ssid: SSID
342 * @ssid_len: SSID length in bytes
343 * @interations: Number of iterations to run
344 * @buf: Buffer for the generated key
345 * @buflen: Length of the buffer in bytes
347 * This function is used to derive PSK for WPA-PSK. For this protocol,
348 * iterations is set to 4096 and buflen to 32. This function is described in
349 * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
351 void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
352 int iterations, u8 *buf, size_t buflen)
354 int count = 0;
355 unsigned char *pos = buf;
356 size_t left = buflen, plen;
357 unsigned char digest[SHA1_MAC_LEN];
359 while (left > 0) {
360 count++;
361 pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
362 digest);
363 plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
364 memcpy(pos, digest, plen);
365 pos += plen;
366 left -= plen;
371 #ifndef EAP_TLS_FUNCS
373 typedef struct {
374 u32 state[5];
375 u32 count[2];
376 unsigned char buffer[64];
377 } SHA1_CTX;
379 static void SHA1Init(SHA1_CTX *context);
380 static void SHA1Update(SHA1_CTX *context, const void *data, u32 len);
381 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
382 static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
386 * sha1_vector - SHA-1 hash for data vector
387 * @num_elem: Number of elements in the data vector
388 * @addr: Pointers to the data areas
389 * @len: Lengths of the data blocks
390 * @mac: Buffer for the hash
392 void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
393 u8 *mac)
395 SHA1_CTX ctx;
396 int i;
398 SHA1Init(&ctx);
399 for (i = 0; i < num_elem; i++)
400 SHA1Update(&ctx, addr[i], len[i]);
401 SHA1Final(mac, &ctx);
406 * sha1_transform - Perform one SHA-1 transform step
407 * @state: SHA-1 state
408 * @data: Input data for the SHA-1 transform
410 * This function is used to implement random number generation specified in
411 * NIST FIPS Publication 186-2 for EAP-SIM. This PRF uses a function that is
412 * similar to SHA-1, but has different message padding and as such, access to
413 * just part of the SHA-1 is needed.
415 void sha1_transform(u8 *state, const u8 data[64])
417 SHA1Transform((u32 *) state, data);
421 /* ===== start - public domain SHA1 implementation ===== */
424 SHA-1 in C
425 By Steve Reid <sreid@sea-to-sky.net>
426 100% Public Domain
428 -----------------
429 Modified 7/98
430 By James H. Brown <jbrown@burgoyne.com>
431 Still 100% Public Domain
433 Corrected a problem which generated improper hash values on 16 bit machines
434 Routine SHA1Update changed from
435 void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
436 len)
438 void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
439 long len)
441 The 'len' parameter was declared an int which works fine on 32 bit machines.
442 However, on 16 bit machines an int is too small for the shifts being done
443 against
444 it. This caused the hash function to generate incorrect values if len was
445 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
447 Since the file IO in main() reads 16K at a time, any file 8K or larger would
448 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
449 "a"s).
451 I also changed the declaration of variables i & j in SHA1Update to
452 unsigned long from unsigned int for the same reason.
454 These changes should make no difference to any 32 bit implementations since
456 int and a long are the same size in those environments.
459 I also corrected a few compiler warnings generated by Borland C.
460 1. Added #include <process.h> for exit() prototype
461 2. Removed unused variable 'j' in SHA1Final
462 3. Changed exit(0) to return(0) at end of main.
464 ALL changes I made can be located by searching for comments containing 'JHB'
465 -----------------
466 Modified 8/98
467 By Steve Reid <sreid@sea-to-sky.net>
468 Still 100% public domain
470 1- Removed #include <process.h> and used return() instead of exit()
471 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
472 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
474 -----------------
475 Modified 4/01
476 By Saul Kravitz <Saul.Kravitz@celera.com>
477 Still 100% PD
478 Modified to run on Compaq Alpha hardware.
480 -----------------
481 Modified 4/01
482 By Jouni Malinen <jkmaline@cc.hut.fi>
483 Minor changes to match the coding style used in Dynamics.
485 Modified September 24, 2004
486 By Jouni Malinen <jkmaline@cc.hut.fi>
487 Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
492 Test Vectors (from FIPS PUB 180-1)
493 "abc"
494 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
495 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
496 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
497 A million repetitions of "a"
498 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
501 #define SHA1HANDSOFF
503 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
505 /* blk0() and blk() perform the initial expand. */
506 /* I got the idea of expanding during the round function from SSLeay */
507 #ifndef WORDS_BIGENDIAN
508 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
509 (rol(block->l[i], 8) & 0x00FF00FF))
510 #else
511 #define blk0(i) block->l[i]
512 #endif
513 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
514 block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
516 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
517 #define R0(v,w,x,y,z,i) \
518 z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
519 w = rol(w, 30);
520 #define R1(v,w,x,y,z,i) \
521 z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
522 w = rol(w, 30);
523 #define R2(v,w,x,y,z,i) \
524 z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
525 #define R3(v,w,x,y,z,i) \
526 z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
527 w = rol(w, 30);
528 #define R4(v,w,x,y,z,i) \
529 z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
530 w=rol(w, 30);
533 #ifdef VERBOSE /* SAK */
534 void SHAPrintContext(SHA1_CTX *context, char *msg)
536 printf("%s (%d,%d) %x %x %x %x %x\n",
537 msg,
538 context->count[0], context->count[1],
539 context->state[0],
540 context->state[1],
541 context->state[2],
542 context->state[3],
543 context->state[4]);
545 #endif
547 /* Hash a single 512-bit block. This is the core of the algorithm. */
549 static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
551 u32 a, b, c, d, e;
552 typedef union {
553 unsigned char c[64];
554 u32 l[16];
555 } CHAR64LONG16;
556 CHAR64LONG16* block;
557 #ifdef SHA1HANDSOFF
558 u32 workspace[16];
559 block = (CHAR64LONG16 *) workspace;
560 memcpy(block, buffer, 64);
561 #else
562 block = (CHAR64LONG16 *) buffer;
563 #endif
564 /* Copy context->state[] to working vars */
565 a = state[0];
566 b = state[1];
567 c = state[2];
568 d = state[3];
569 e = state[4];
570 /* 4 rounds of 20 operations each. Loop unrolled. */
571 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);
572 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);
573 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);
574 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);
575 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);
576 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);
577 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);
578 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);
579 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);
580 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);
581 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);
582 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);
583 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);
584 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);
585 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);
586 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);
587 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);
588 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);
589 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);
590 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);
591 /* Add the working vars back into context.state[] */
592 state[0] += a;
593 state[1] += b;
594 state[2] += c;
595 state[3] += d;
596 state[4] += e;
597 /* Wipe variables */
598 a = b = c = d = e = 0;
599 #ifdef SHA1HANDSOFF
600 memset(block, 0, 64);
601 #endif
605 /* SHA1Init - Initialize new context */
607 static void SHA1Init(SHA1_CTX* context)
609 /* SHA1 initialization constants */
610 context->state[0] = 0x67452301;
611 context->state[1] = 0xEFCDAB89;
612 context->state[2] = 0x98BADCFE;
613 context->state[3] = 0x10325476;
614 context->state[4] = 0xC3D2E1F0;
615 context->count[0] = context->count[1] = 0;
619 /* Run your data through this. */
621 static void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
623 u32 i, j;
624 const unsigned char *data = _data;
626 #ifdef VERBOSE
627 SHAPrintContext(context, "before");
628 #endif
629 j = (context->count[0] >> 3) & 63;
630 if ((context->count[0] += len << 3) < (len << 3))
631 context->count[1]++;
632 context->count[1] += (len >> 29);
633 if ((j + len) > 63) {
634 memcpy(&context->buffer[j], data, (i = 64-j));
635 SHA1Transform(context->state, context->buffer);
636 for ( ; i + 63 < len; i += 64) {
637 SHA1Transform(context->state, &data[i]);
639 j = 0;
641 else i = 0;
642 memcpy(&context->buffer[j], &data[i], len - i);
643 #ifdef VERBOSE
644 SHAPrintContext(context, "after ");
645 #endif
649 /* Add padding and return the message digest. */
651 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
653 u32 i;
654 unsigned char finalcount[8];
656 for (i = 0; i < 8; i++) {
657 finalcount[i] = (unsigned char)
658 ((context->count[(i >= 4 ? 0 : 1)] >>
659 ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
661 SHA1Update(context, (unsigned char *) "\200", 1);
662 while ((context->count[0] & 504) != 448) {
663 SHA1Update(context, (unsigned char *) "\0", 1);
665 SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform()
667 for (i = 0; i < 20; i++) {
668 digest[i] = (unsigned char)
669 ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
670 255);
672 /* Wipe variables */
673 i = 0;
674 memset(context->buffer, 0, 64);
675 memset(context->state, 0, 20);
676 memset(context->count, 0, 8);
677 memset(finalcount, 0, 8);
680 /* ===== end - public domain SHA1 implementation ===== */
682 #endif /* EAP_TLS_FUNCS */
685 #ifdef TEST_MAIN
687 #include "md5.c"
689 static int test_eap_fast(void)
691 /* draft-cam-winget-eap-fast-01.txt */
692 const u8 pac_key[] = {
693 0x0B, 0x97, 0x39, 0x0F, 0x37, 0x51, 0x78, 0x09,
694 0x81, 0x1E, 0xFD, 0x9C, 0x6E, 0x65, 0x94, 0x2B,
695 0x63, 0x2C, 0xE9, 0x53, 0x89, 0x38, 0x08, 0xBA,
696 0x36, 0x0B, 0x03, 0x7C, 0xD1, 0x85, 0xE4, 0x14
698 const u8 seed[] = {
699 0x3F, 0xFB, 0x11, 0xC4, 0x6C, 0xBF, 0xA5, 0x7A,
700 0x54, 0x40, 0xDA, 0xE8, 0x22, 0xD3, 0x11, 0xD3,
701 0xF7, 0x6D, 0xE4, 0x1D, 0xD9, 0x33, 0xE5, 0x93,
702 0x70, 0x97, 0xEB, 0xA9, 0xB3, 0x66, 0xF4, 0x2A,
703 0x00, 0x00, 0x00, 0x02, 0x6A, 0x66, 0x43, 0x2A,
704 0x8D, 0x14, 0x43, 0x2C, 0xEC, 0x58, 0x2D, 0x2F,
705 0xC7, 0x9C, 0x33, 0x64, 0xBA, 0x04, 0xAD, 0x3A,
706 0x52, 0x54, 0xD6, 0xA5, 0x79, 0xAD, 0x1E, 0x00
708 const u8 master_secret[] = {
709 0x4A, 0x1A, 0x51, 0x2C, 0x01, 0x60, 0xBC, 0x02,
710 0x3C, 0xCF, 0xBC, 0x83, 0x3F, 0x03, 0xBC, 0x64,
711 0x88, 0xC1, 0x31, 0x2F, 0x0B, 0xA9, 0xA2, 0x77,
712 0x16, 0xA8, 0xD8, 0xE8, 0xBD, 0xC9, 0xD2, 0x29,
713 0x38, 0x4B, 0x7A, 0x85, 0xBE, 0x16, 0x4D, 0x27,
714 0x33, 0xD5, 0x24, 0x79, 0x87, 0xB1, 0xC5, 0xA2
716 const u8 key_block[] = {
717 0x59, 0x59, 0xBE, 0x8E, 0x41, 0x3A, 0x77, 0x74,
718 0x8B, 0xB2, 0xE5, 0xD3, 0x60, 0xAC, 0x4D, 0x35,
719 0xDF, 0xFB, 0xC8, 0x1E, 0x9C, 0x24, 0x9C, 0x8B,
720 0x0E, 0xC3, 0x1D, 0x72, 0xC8, 0x84, 0x9D, 0x57,
721 0x48, 0x51, 0x2E, 0x45, 0x97, 0x6C, 0x88, 0x70,
722 0xBE, 0x5F, 0x01, 0xD3, 0x64, 0xE7, 0x4C, 0xBB,
723 0x11, 0x24, 0xE3, 0x49, 0xE2, 0x3B, 0xCD, 0xEF,
724 0x7A, 0xB3, 0x05, 0x39, 0x5D, 0x64, 0x8A, 0x44,
725 0x11, 0xB6, 0x69, 0x88, 0x34, 0x2E, 0x8E, 0x29,
726 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
727 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
728 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
729 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
730 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
732 const u8 sks[] = {
733 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
734 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
735 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
736 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
737 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
739 const u8 isk[] = {
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
745 const u8 imck[] = {
746 0x16, 0x15, 0x3C, 0x3F, 0x21, 0x55, 0xEF, 0xD9,
747 0x7F, 0x34, 0xAE, 0xC8, 0x1A, 0x4E, 0x66, 0x80,
748 0x4C, 0xC3, 0x76, 0xF2, 0x8A, 0xA9, 0x6F, 0x96,
749 0xC2, 0x54, 0x5F, 0x8C, 0xAB, 0x65, 0x02, 0xE1,
750 0x18, 0x40, 0x7B, 0x56, 0xBE, 0xEA, 0xA7, 0xC5,
751 0x76, 0x5D, 0x8F, 0x0B, 0xC5, 0x07, 0xC6, 0xB9,
752 0x04, 0xD0, 0x69, 0x56, 0x72, 0x8B, 0x6B, 0xB8,
753 0x15, 0xEC, 0x57, 0x7B
755 const u8 msk[] = {
756 0x4D, 0x83, 0xA9, 0xBE, 0x6F, 0x8A, 0x74, 0xED,
757 0x6A, 0x02, 0x66, 0x0A, 0x63, 0x4D, 0x2C, 0x33,
758 0xC2, 0xDA, 0x60, 0x15, 0xC6, 0x37, 0x04, 0x51,
759 0x90, 0x38, 0x63, 0xDA, 0x54, 0x3E, 0x14, 0xB9,
760 0x27, 0x99, 0x18, 0x1E, 0x07, 0xBF, 0x0F, 0x5A,
761 0x5E, 0x3C, 0x32, 0x93, 0x80, 0x8C, 0x6C, 0x49,
762 0x67, 0xED, 0x24, 0xFE, 0x45, 0x40, 0xA0, 0x59,
763 0x5E, 0x37, 0xC2, 0xE9, 0xD0, 0x5D, 0x0A, 0xE3
765 u8 tlv[] = {
766 0x80, 0x0C, 0x00, 0x38, 0x00, 0x01, 0x01, 0x00,
767 0xD8, 0x6A, 0x8C, 0x68, 0x3C, 0x32, 0x31, 0xA8,
768 0x56, 0x63, 0xB6, 0x40, 0x21, 0xFE, 0x21, 0x14,
769 0x4E, 0xE7, 0x54, 0x20, 0x79, 0x2D, 0x42, 0x62,
770 0xC9, 0xBF, 0x53, 0x7F, 0x54, 0xFD, 0xAC, 0x58,
771 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
772 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
773 0x05, 0xC5, 0x5B, 0xB7
775 const u8 compound_mac[] = {
776 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
777 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
778 0x05, 0xC5, 0x5B, 0xB7
780 u8 buf[512];
781 const u8 *simck, *cmk;
782 int errors = 0;
784 printf("EAP-FAST test cases\n");
786 printf("- T-PRF (SHA1) test case / master_secret\n");
787 sha1_t_prf(pac_key, sizeof(pac_key), "PAC to master secret label hash",
788 seed, sizeof(seed), buf, sizeof(master_secret));
789 if (memcmp(master_secret, buf, sizeof(master_secret)) != 0) {
790 printf("T-PRF test - FAILED!\n");
791 errors++;
794 printf("- PRF (TLS, SHA1/MD5) test case / key_block\n");
795 tls_prf(master_secret, sizeof(master_secret), "key expansion",
796 seed, sizeof(seed), buf, sizeof(key_block));
797 if (memcmp(key_block, buf, sizeof(key_block)) != 0) {
798 printf("PRF test - FAILED!\n");
799 errors++;
802 printf("- T-PRF (SHA1) test case / IMCK\n");
803 sha1_t_prf(sks, sizeof(sks), "Inner Methods Compound Keys",
804 isk, sizeof(isk), buf, sizeof(imck));
805 if (memcmp(imck, buf, sizeof(imck)) != 0) {
806 printf("T-PRF test - FAILED!\n");
807 errors++;
810 simck = imck;
811 cmk = imck + 40;
813 printf("- T-PRF (SHA1) test case / MSK\n");
814 sha1_t_prf(simck, 40, "Session Key Generating Function",
815 "", 0, buf, sizeof(msk));
816 if (memcmp(msk, buf, sizeof(msk)) != 0) {
817 printf("T-PRF test - FAILED!\n");
818 errors++;
821 printf("- Compound MAC test case\n");
822 memset(tlv + sizeof(tlv) - 20, 0, 20);
823 hmac_sha1(cmk, 20, tlv, sizeof(tlv), tlv + sizeof(tlv) - 20);
824 if (memcmp(tlv + sizeof(tlv) - 20, compound_mac, sizeof(compound_mac))
825 != 0) {
826 printf("Compound MAC test - FAILED!\n");
827 errors++;
830 return errors;
834 static u8 key0[] =
836 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
837 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
838 0x0b, 0x0b, 0x0b, 0x0b
840 static u8 data0[] = "Hi There";
841 static u8 prf0[] =
843 0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84,
844 0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54,
845 0xb8, 0x62, 0x17, 0x5e, 0xd9, 0xf0, 0x06, 0x06,
846 0xe1, 0x7d, 0x8d, 0xa3, 0x54, 0x02, 0xff, 0xee,
847 0x75, 0xdf, 0x78, 0xc3, 0xd3, 0x1e, 0x0f, 0x88,
848 0x9f, 0x01, 0x21, 0x20, 0xc0, 0x86, 0x2b, 0xeb,
849 0x67, 0x75, 0x3e, 0x74, 0x39, 0xae, 0x24, 0x2e,
850 0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a
853 static u8 key1[] = "Jefe";
854 static u8 data1[] = "what do ya want for nothing?";
855 static u8 prf1[] =
857 0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad,
858 0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4,
859 0xfe, 0x63, 0x14, 0x46, 0xfa, 0xbd, 0xfa, 0x58,
860 0x24, 0x47, 0x59, 0xae, 0x58, 0xef, 0x90, 0x09,
861 0xa9, 0x9a, 0xbf, 0x4e, 0xac, 0x2c, 0xa5, 0xfa,
862 0x87, 0xe6, 0x92, 0xc4, 0x40, 0xeb, 0x40, 0x02,
863 0x3e, 0x7b, 0xab, 0xb2, 0x06, 0xd6, 0x1d, 0xe7,
864 0xb9, 0x2f, 0x41, 0x52, 0x90, 0x92, 0xb8, 0xfc
868 static u8 key2[] =
870 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
871 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
872 0xaa, 0xaa, 0xaa, 0xaa
874 static u8 data2[] =
876 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
877 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
878 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
879 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
880 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
881 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
882 0xdd, 0xdd
884 static u8 prf2[] =
886 0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f,
887 0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1,
888 0x7a, 0x02, 0x52, 0xca, 0x5d, 0x8d, 0x8d, 0xf1,
889 0x2c, 0xfb, 0x04, 0x73, 0x52, 0x52, 0x49, 0xce,
890 0x9d, 0xd8, 0xd1, 0x77, 0xea, 0xd7, 0x10, 0xbc,
891 0x9b, 0x59, 0x05, 0x47, 0x23, 0x91, 0x07, 0xae,
892 0xf7, 0xb4, 0xab, 0xd4, 0x3d, 0x87, 0xf0, 0xa6,
893 0x8f, 0x1c, 0xbd, 0x9e, 0x2b, 0x6f, 0x76, 0x07
897 struct passphrase_test {
898 char *passphrase;
899 char *ssid;
900 char psk[32];
903 static struct passphrase_test passphrase_tests[] =
906 "password",
907 "IEEE",
909 0xf4, 0x2c, 0x6f, 0xc5, 0x2d, 0xf0, 0xeb, 0xef,
910 0x9e, 0xbb, 0x4b, 0x90, 0xb3, 0x8a, 0x5f, 0x90,
911 0x2e, 0x83, 0xfe, 0x1b, 0x13, 0x5a, 0x70, 0xe2,
912 0x3a, 0xed, 0x76, 0x2e, 0x97, 0x10, 0xa1, 0x2e
916 "ThisIsAPassword",
917 "ThisIsASSID",
919 0x0d, 0xc0, 0xd6, 0xeb, 0x90, 0x55, 0x5e, 0xd6,
920 0x41, 0x97, 0x56, 0xb9, 0xa1, 0x5e, 0xc3, 0xe3,
921 0x20, 0x9b, 0x63, 0xdf, 0x70, 0x7d, 0xd5, 0x08,
922 0xd1, 0x45, 0x81, 0xf8, 0x98, 0x27, 0x21, 0xaf
926 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
927 "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
929 0xbe, 0xcb, 0x93, 0x86, 0x6b, 0xb8, 0xc3, 0x83,
930 0x2c, 0xb7, 0x77, 0xc2, 0xf5, 0x59, 0x80, 0x7c,
931 0x8c, 0x59, 0xaf, 0xcb, 0x6e, 0xae, 0x73, 0x48,
932 0x85, 0x00, 0x13, 0x00, 0xa9, 0x81, 0xcc, 0x62
937 #define NUM_PASSPHRASE_TESTS \
938 (sizeof(passphrase_tests) / sizeof(passphrase_tests[0]))
941 int main(int argc, char *argv[])
943 u8 res[512];
944 int ret = 0, i;
946 printf("PRF-SHA1 test cases:\n");
948 sha1_prf(key0, sizeof(key0), "prefix", data0, sizeof(data0) - 1,
949 res, sizeof(prf0));
950 if (memcmp(res, prf0, sizeof(prf0)) == 0)
951 printf("Test case 0 - OK\n");
952 else {
953 printf("Test case 0 - FAILED!\n");
954 ret++;
957 sha1_prf(key1, sizeof(key1) - 1, "prefix", data1, sizeof(data1) - 1,
958 res, sizeof(prf1));
959 if (memcmp(res, prf1, sizeof(prf1)) == 0)
960 printf("Test case 1 - OK\n");
961 else {
962 printf("Test case 1 - FAILED!\n");
963 ret++;
966 sha1_prf(key2, sizeof(key2), "prefix", data2, sizeof(data2),
967 res, sizeof(prf2));
968 if (memcmp(res, prf2, sizeof(prf2)) == 0)
969 printf("Test case 2 - OK\n");
970 else {
971 printf("Test case 2 - FAILED!\n");
972 ret++;
975 ret += test_eap_fast();
977 printf("PBKDF2-SHA1 Passphrase test cases:\n");
978 for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) {
979 u8 psk[32];
980 struct passphrase_test *test = &passphrase_tests[i];
981 pbkdf2_sha1(test->passphrase,
982 test->ssid, strlen(test->ssid),
983 4096, psk, 32);
984 if (memcmp(psk, test->psk, 32) == 0)
985 printf("Test case %d - OK\n", i);
986 else {
987 printf("Test case %d - FAILED!\n", i);
988 ret++;
992 return ret;
994 #endif /* TEST_MAIN */