sha1.c

Go to the documentation of this file.
00001 
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 
00020 #include "common.h"
00021 #include "sha1.h"
00022 #include "md5.h"
00023 #include "crypto.h"
00024 
00025 
00036 void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
00037                       const u8 *addr[], const size_t *len, u8 *mac)
00038 {
00039         unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
00040         unsigned char tk[20];
00041         int i;
00042         const u8 *_addr[6];
00043         size_t _len[6];
00044 
00045         if (num_elem > 5) {
00046                 /*
00047                  * Fixed limit on the number of fragments to avoid having to
00048                  * allocate memory (which could fail).
00049                  */
00050                 return;
00051         }
00052 
00053         /* if key is longer than 64 bytes reset it to key = SHA1(key) */
00054         if (key_len > 64) {
00055                 sha1_vector(1, &key, &key_len, tk);
00056                 key = tk;
00057                 key_len = 20;
00058         }
00059 
00060         /* the HMAC_SHA1 transform looks like:
00061          *
00062          * SHA1(K XOR opad, SHA1(K XOR ipad, text))
00063          *
00064          * where K is an n byte key
00065          * ipad is the byte 0x36 repeated 64 times
00066          * opad is the byte 0x5c repeated 64 times
00067          * and text is the data being protected */
00068 
00069         /* start out by storing key in ipad */
00070         memset(k_pad, 0, sizeof(k_pad));
00071         memcpy(k_pad, key, key_len);
00072         /* XOR key with ipad values */
00073         for (i = 0; i < 64; i++)
00074                 k_pad[i] ^= 0x36;
00075 
00076         /* perform inner SHA1 */
00077         _addr[0] = k_pad;
00078         _len[0] = 64;
00079         for (i = 0; i < num_elem; i++) {
00080                 _addr[i + 1] = addr[i];
00081                 _len[i + 1] = len[i];
00082         }
00083         sha1_vector(1 + num_elem, _addr, _len, mac);
00084 
00085         memset(k_pad, 0, sizeof(k_pad));
00086         memcpy(k_pad, key, key_len);
00087         /* XOR key with opad values */
00088         for (i = 0; i < 64; i++)
00089                 k_pad[i] ^= 0x5c;
00090 
00091         /* perform outer SHA1 */
00092         _addr[0] = k_pad;
00093         _len[0] = 64;
00094         _addr[1] = mac;
00095         _len[1] = SHA1_MAC_LEN;
00096         sha1_vector(2, _addr, _len, mac);
00097 }
00098 
00099 
00109 void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
00110                u8 *mac)
00111 {
00112         hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
00113 }
00114 
00115 
00130 void sha1_prf(const u8 *key, size_t key_len, const char *label,
00131               const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
00132 {
00133         u8 zero = 0, counter = 0;
00134         size_t pos, plen;
00135         u8 hash[SHA1_MAC_LEN];
00136         size_t label_len = strlen(label);
00137         const unsigned char *addr[4];
00138         size_t len[4];
00139 
00140         addr[0] = (u8 *) label;
00141         len[0] = label_len;
00142         addr[1] = &zero;
00143         len[1] = 1;
00144         addr[2] = data;
00145         len[2] = data_len;
00146         addr[3] = &counter;
00147         len[3] = 1;
00148 
00149         pos = 0;
00150         while (pos < buf_len) {
00151                 plen = buf_len - pos;
00152                 if (plen >= SHA1_MAC_LEN) {
00153                         hmac_sha1_vector(key, key_len, 4, addr, len,
00154                                          &buf[pos]);
00155                         pos += SHA1_MAC_LEN;
00156                 } else {
00157                         hmac_sha1_vector(key, key_len, 4, addr, len,
00158                                          hash);
00159                         memcpy(&buf[pos], hash, plen);
00160                         break;
00161                 }
00162                 counter++;
00163         }
00164 }
00165 
00166 
00182 void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
00183                 const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
00184 {
00185         unsigned char counter = 0;
00186         size_t pos, plen;
00187         u8 hash[SHA1_MAC_LEN];
00188         size_t label_len = strlen(label);
00189         u8 output_len[2];
00190         const unsigned char *addr[5];
00191         size_t len[5];
00192 
00193         addr[0] = hash;
00194         len[0] = 0;
00195         addr[1] = (unsigned char *) label;
00196         len[1] = label_len + 1;
00197         addr[2] = seed;
00198         len[2] = seed_len;
00199         addr[3] = output_len;
00200         len[3] = 2;
00201         addr[4] = &counter;
00202         len[4] = 1;
00203 
00204         output_len[0] = (buf_len >> 8) & 0xff;
00205         output_len[1] = buf_len & 0xff;
00206         pos = 0;
00207         while (pos < buf_len) {
00208                 counter++;
00209                 plen = buf_len - pos;
00210                 hmac_sha1_vector(key, key_len, 5, addr, len, hash);
00211                 if (plen >= SHA1_MAC_LEN) {
00212                         memcpy(&buf[pos], hash, SHA1_MAC_LEN);
00213                         pos += SHA1_MAC_LEN;
00214                 } else {
00215                         memcpy(&buf[pos], hash, plen);
00216                         break;
00217                 }
00218                 len[0] = SHA1_MAC_LEN;
00219         }
00220 }
00221 
00222 
00237 int tls_prf(const u8 *secret, size_t secret_len, const char *label,
00238             const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
00239 {
00240         size_t L_S1, L_S2;
00241         const u8 *S1, *S2;
00242         u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
00243         u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
00244         int i, MD5_pos, SHA1_pos;
00245         const u8 *MD5_addr[3];
00246         size_t MD5_len[3];
00247         const unsigned char *SHA1_addr[3];
00248         size_t SHA1_len[3];
00249 
00250         if (secret_len & 1)
00251                 return -1;
00252 
00253         MD5_addr[0] = A_MD5;
00254         MD5_len[0] = MD5_MAC_LEN;
00255         MD5_addr[1] = (unsigned char *) label;
00256         MD5_len[1] = strlen(label);
00257         MD5_addr[2] = seed;
00258         MD5_len[2] = seed_len;
00259 
00260         SHA1_addr[0] = A_SHA1;
00261         SHA1_len[0] = SHA1_MAC_LEN;
00262         SHA1_addr[1] = (unsigned char *) label;
00263         SHA1_len[1] = strlen(label);
00264         SHA1_addr[2] = seed;
00265         SHA1_len[2] = seed_len;
00266 
00267         /* RFC 2246, Chapter 5
00268          * A(0) = seed, A(i) = HMAC(secret, A(i-1))
00269          * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + ..
00270          * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
00271          */
00272 
00273         L_S1 = L_S2 = (secret_len + 1) / 2;
00274         S1 = secret;
00275         S2 = secret + L_S1;
00276 
00277         hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
00278         hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
00279 
00280         MD5_pos = MD5_MAC_LEN;
00281         SHA1_pos = SHA1_MAC_LEN;
00282         for (i = 0; i < outlen; i++) {
00283                 if (MD5_pos == MD5_MAC_LEN) {
00284                         hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
00285                         MD5_pos = 0;
00286                         hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
00287                 }
00288                 if (SHA1_pos == SHA1_MAC_LEN) {
00289                         hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
00290                                          P_SHA1);
00291                         SHA1_pos = 0;
00292                         hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
00293                 }
00294 
00295                 out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
00296 
00297                 MD5_pos++;
00298                 SHA1_pos++;
00299         }
00300 
00301         return 0;
00302 }
00303 
00304 
00305 static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
00306                           size_t ssid_len, int iterations, int count,
00307                           u8 *digest)
00308 {
00309         unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
00310         int i, j;
00311         unsigned char count_buf[4];
00312         const u8 *addr[2];
00313         size_t len[2];
00314         size_t passphrase_len = strlen(passphrase);
00315 
00316         addr[0] = (u8 *) ssid;
00317         len[0] = ssid_len;
00318         addr[1] = count_buf;
00319         len[1] = 4;
00320 
00321         /* F(P, S, c, i) = U1 xor U2 xor ... Uc
00322          * U1 = PRF(P, S || i)
00323          * U2 = PRF(P, U1)
00324          * Uc = PRF(P, Uc-1)
00325          */
00326 
00327         count_buf[0] = (count >> 24) & 0xff;
00328         count_buf[1] = (count >> 16) & 0xff;
00329         count_buf[2] = (count >> 8) & 0xff;
00330         count_buf[3] = count & 0xff;
00331         hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
00332         memcpy(digest, tmp, SHA1_MAC_LEN);
00333 
00334         for (i = 1; i < iterations; i++) {
00335                 hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
00336                           tmp2);
00337                 memcpy(tmp, tmp2, SHA1_MAC_LEN);
00338                 for (j = 0; j < SHA1_MAC_LEN; j++)
00339                         digest[j] ^= tmp2[j];
00340         }
00341 }
00342 
00343 
00358 void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
00359                  int iterations, u8 *buf, size_t buflen)
00360 {
00361         int count = 0;
00362         unsigned char *pos = buf;
00363         size_t left = buflen, plen;
00364         unsigned char digest[SHA1_MAC_LEN];
00365 
00366         while (left > 0) {
00367                 count++;
00368                 pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
00369                               digest);
00370                 plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
00371                 memcpy(pos, digest, plen);
00372                 pos += plen;
00373                 left -= plen;
00374         }
00375 }
00376 
00377 
00378 #ifndef EAP_TLS_FUNCS
00379 
00380 typedef struct {
00381         u32 state[5];
00382         u32 count[2];
00383         unsigned char buffer[64];
00384 } SHA1_CTX;
00385 
00386 static void SHA1Init(SHA1_CTX *context);
00387 static void SHA1Update(SHA1_CTX *context, const void *data, u32 len);
00388 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
00389 static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
00390 
00391 
00400 void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
00401                  u8 *mac)
00402 {
00403         SHA1_CTX ctx;
00404         int i;
00405 
00406         SHA1Init(&ctx);
00407         for (i = 0; i < num_elem; i++)
00408                 SHA1Update(&ctx, addr[i], len[i]);
00409         SHA1Final(mac, &ctx);
00410 }
00411 
00412 
00424 void sha1_transform(u8 *state, const u8 data[64])
00425 {
00426         SHA1Transform((u32 *) state, data);
00427 }
00428 
00429 
00430 /* ===== start - public domain SHA1 implementation ===== */
00431 
00432 /*
00433 SHA-1 in C
00434 By Steve Reid <[email protected]>
00435 100% Public Domain
00436 
00437 -----------------
00438 Modified 7/98 
00439 By James H. Brown <[email protected]>
00440 Still 100% Public Domain
00441 
00442 Corrected a problem which generated improper hash values on 16 bit machines
00443 Routine SHA1Update changed from
00444         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
00445 len)
00446 to
00447         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
00448 long len)
00449 
00450 The 'len' parameter was declared an int which works fine on 32 bit machines.
00451 However, on 16 bit machines an int is too small for the shifts being done
00452 against
00453 it.  This caused the hash function to generate incorrect values if len was
00454 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
00455 
00456 Since the file IO in main() reads 16K at a time, any file 8K or larger would
00457 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
00458 "a"s).
00459 
00460 I also changed the declaration of variables i & j in SHA1Update to 
00461 unsigned long from unsigned int for the same reason.
00462 
00463 These changes should make no difference to any 32 bit implementations since
00464 an
00465 int and a long are the same size in those environments.
00466 
00467 --
00468 I also corrected a few compiler warnings generated by Borland C.
00469 1. Added #include <process.h> for exit() prototype
00470 2. Removed unused variable 'j' in SHA1Final
00471 3. Changed exit(0) to return(0) at end of main.
00472 
00473 ALL changes I made can be located by searching for comments containing 'JHB'
00474 -----------------
00475 Modified 8/98
00476 By Steve Reid <[email protected]>
00477 Still 100% public domain
00478 
00479 1- Removed #include <process.h> and used return() instead of exit()
00480 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
00481 3- Changed email address from [email protected] to [email protected]
00482 
00483 -----------------
00484 Modified 4/01
00485 By Saul Kravitz <[email protected]>
00486 Still 100% PD
00487 Modified to run on Compaq Alpha hardware.  
00488 
00489 -----------------
00490 Modified 4/01
00491 By Jouni Malinen <[email protected]>
00492 Minor changes to match the coding style used in Dynamics.
00493 
00494 Modified September 24, 2004
00495 By Jouni Malinen <[email protected]>
00496 Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
00497 
00498 */
00499 
00500 /*
00501 Test Vectors (from FIPS PUB 180-1)
00502 "abc"
00503   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
00504 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
00505   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
00506 A million repetitions of "a"
00507   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
00508 */
00509 
00510 #define SHA1HANDSOFF
00511 
00512 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
00513 
00514 /* blk0() and blk() perform the initial expand. */
00515 /* I got the idea of expanding during the round function from SSLeay */
00516 #ifndef WORDS_BIGENDIAN
00517 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
00518         (rol(block->l[i], 8) & 0x00FF00FF))
00519 #else
00520 #define blk0(i) block->l[i]
00521 #endif
00522 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
00523         block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
00524 
00525 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
00526 #define R0(v,w,x,y,z,i) \
00527         z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
00528         w = rol(w, 30);
00529 #define R1(v,w,x,y,z,i) \
00530         z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
00531         w = rol(w, 30);
00532 #define R2(v,w,x,y,z,i) \
00533         z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
00534 #define R3(v,w,x,y,z,i) \
00535         z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
00536         w = rol(w, 30);
00537 #define R4(v,w,x,y,z,i) \
00538         z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
00539         w=rol(w, 30);
00540 
00541 
00542 #ifdef VERBOSE  /* SAK */
00543 void SHAPrintContext(SHA1_CTX *context, char *msg)
00544 {
00545         printf("%s (%d,%d) %x %x %x %x %x\n",
00546                msg,
00547                context->count[0], context->count[1], 
00548                context->state[0],
00549                context->state[1],
00550                context->state[2],
00551                context->state[3],
00552                context->state[4]);
00553 }
00554 #endif
00555 
00556 /* Hash a single 512-bit block. This is the core of the algorithm. */
00557 
00558 static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
00559 {
00560         u32 a, b, c, d, e;
00561         typedef union {
00562                 unsigned char c[64];
00563                 u32 l[16];
00564         } CHAR64LONG16;
00565         CHAR64LONG16* block;
00566 #ifdef SHA1HANDSOFF
00567         u32 workspace[16];
00568         block = (CHAR64LONG16 *) workspace;
00569         memcpy(block, buffer, 64);
00570 #else
00571         block = (CHAR64LONG16 *) buffer;
00572 #endif
00573         /* Copy context->state[] to working vars */
00574         a = state[0];
00575         b = state[1];
00576         c = state[2];
00577         d = state[3];
00578         e = state[4];
00579         /* 4 rounds of 20 operations each. Loop unrolled. */
00580         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);
00581         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);
00582         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);
00583         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);
00584         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);
00585         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);
00586         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);
00587         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);
00588         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);
00589         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);
00590         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);
00591         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);
00592         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);
00593         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);
00594         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);
00595         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);
00596         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);
00597         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);
00598         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);
00599         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);
00600         /* Add the working vars back into context.state[] */
00601         state[0] += a;
00602         state[1] += b;
00603         state[2] += c;
00604         state[3] += d;
00605         state[4] += e;
00606         /* Wipe variables */
00607         a = b = c = d = e = 0;
00608 #ifdef SHA1HANDSOFF
00609         memset(block, 0, 64);
00610 #endif
00611 }
00612 
00613 
00614 /* SHA1Init - Initialize new context */
00615 
00616 static void SHA1Init(SHA1_CTX* context)
00617 {
00618         /* SHA1 initialization constants */
00619         context->state[0] = 0x67452301;
00620         context->state[1] = 0xEFCDAB89;
00621         context->state[2] = 0x98BADCFE;
00622         context->state[3] = 0x10325476;
00623         context->state[4] = 0xC3D2E1F0;
00624         context->count[0] = context->count[1] = 0;
00625 }
00626 
00627 
00628 /* Run your data through this. */
00629 
00630 static void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
00631 {
00632         u32 i, j;
00633         const unsigned char *data = _data;
00634 
00635 #ifdef VERBOSE
00636         SHAPrintContext(context, "before");
00637 #endif
00638         j = (context->count[0] >> 3) & 63;
00639         if ((context->count[0] += len << 3) < (len << 3))
00640                 context->count[1]++;
00641         context->count[1] += (len >> 29);
00642         if ((j + len) > 63) {
00643                 memcpy(&context->buffer[j], data, (i = 64-j));
00644                 SHA1Transform(context->state, context->buffer);
00645                 for ( ; i + 63 < len; i += 64) {
00646                         SHA1Transform(context->state, &data[i]);
00647                 }
00648                 j = 0;
00649         }
00650         else i = 0;
00651         memcpy(&context->buffer[j], &data[i], len - i);
00652 #ifdef VERBOSE
00653         SHAPrintContext(context, "after ");
00654 #endif
00655 }
00656 
00657 
00658 /* Add padding and return the message digest. */
00659 
00660 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
00661 {
00662         u32 i;
00663         unsigned char finalcount[8];
00664 
00665         for (i = 0; i < 8; i++) {
00666                 finalcount[i] = (unsigned char)
00667                         ((context->count[(i >= 4 ? 0 : 1)] >>
00668                           ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
00669         }
00670         SHA1Update(context, (unsigned char *) "\200", 1);
00671         while ((context->count[0] & 504) != 448) {
00672                 SHA1Update(context, (unsigned char *) "\0", 1);
00673         }
00674         SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
00675                                               */
00676         for (i = 0; i < 20; i++) {
00677                 digest[i] = (unsigned char)
00678                         ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
00679                          255);
00680         }
00681         /* Wipe variables */
00682         i = 0;
00683         memset(context->buffer, 0, 64);
00684         memset(context->state, 0, 20);
00685         memset(context->count, 0, 8);
00686         memset(finalcount, 0, 8);
00687 }
00688 
00689 /* ===== end - public domain SHA1 implementation ===== */
00690 
00691 #endif /* EAP_TLS_FUNCS */
00692 
00693 
00694 #ifdef TEST_MAIN
00695 
00696 #include "md5.c"
00697 
00698 static int test_eap_fast(void)
00699 {
00700         /* draft-cam-winget-eap-fast-01.txt */
00701         const u8 pac_key[] = {
00702                 0x0B, 0x97, 0x39, 0x0F, 0x37, 0x51, 0x78, 0x09,
00703                 0x81, 0x1E, 0xFD, 0x9C, 0x6E, 0x65, 0x94, 0x2B,
00704                 0x63, 0x2C, 0xE9, 0x53, 0x89, 0x38, 0x08, 0xBA,
00705                 0x36, 0x0B, 0x03, 0x7C, 0xD1, 0x85, 0xE4, 0x14
00706         };
00707         const u8 seed[] = {
00708                 0x3F, 0xFB, 0x11, 0xC4, 0x6C, 0xBF, 0xA5, 0x7A,
00709                 0x54, 0x40, 0xDA, 0xE8, 0x22, 0xD3, 0x11, 0xD3,
00710                 0xF7, 0x6D, 0xE4, 0x1D, 0xD9, 0x33, 0xE5, 0x93,
00711                 0x70, 0x97, 0xEB, 0xA9, 0xB3, 0x66, 0xF4, 0x2A,
00712                 0x00, 0x00, 0x00, 0x02, 0x6A, 0x66, 0x43, 0x2A,
00713                 0x8D, 0x14, 0x43, 0x2C, 0xEC, 0x58, 0x2D, 0x2F,
00714                 0xC7, 0x9C, 0x33, 0x64, 0xBA, 0x04, 0xAD, 0x3A,
00715                 0x52, 0x54, 0xD6, 0xA5, 0x79, 0xAD, 0x1E, 0x00
00716         };
00717         const u8 master_secret[] = {
00718                 0x4A, 0x1A, 0x51, 0x2C, 0x01, 0x60, 0xBC, 0x02,
00719                 0x3C, 0xCF, 0xBC, 0x83, 0x3F, 0x03, 0xBC, 0x64,
00720                 0x88, 0xC1, 0x31, 0x2F, 0x0B, 0xA9, 0xA2, 0x77,
00721                 0x16, 0xA8, 0xD8, 0xE8, 0xBD, 0xC9, 0xD2, 0x29,
00722                 0x38, 0x4B, 0x7A, 0x85, 0xBE, 0x16, 0x4D, 0x27,
00723                 0x33, 0xD5, 0x24, 0x79, 0x87, 0xB1, 0xC5, 0xA2  
00724         };
00725         const u8 key_block[] = {
00726                 0x59, 0x59, 0xBE, 0x8E, 0x41, 0x3A, 0x77, 0x74,
00727                 0x8B, 0xB2, 0xE5, 0xD3, 0x60, 0xAC, 0x4D, 0x35,
00728                 0xDF, 0xFB, 0xC8, 0x1E, 0x9C, 0x24, 0x9C, 0x8B,
00729                 0x0E, 0xC3, 0x1D, 0x72, 0xC8, 0x84, 0x9D, 0x57,
00730                 0x48, 0x51, 0x2E, 0x45, 0x97, 0x6C, 0x88, 0x70,
00731                 0xBE, 0x5F, 0x01, 0xD3, 0x64, 0xE7, 0x4C, 0xBB,
00732                 0x11, 0x24, 0xE3, 0x49, 0xE2, 0x3B, 0xCD, 0xEF,
00733                 0x7A, 0xB3, 0x05, 0x39, 0x5D, 0x64, 0x8A, 0x44,
00734                 0x11, 0xB6, 0x69, 0x88, 0x34, 0x2E, 0x8E, 0x29,
00735                 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
00736                 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
00737                 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
00738                 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
00739                 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
00740         };
00741         const u8 sks[] = {
00742                 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
00743                 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
00744                 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
00745                 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
00746                 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
00747         };
00748         const u8 isk[] = {
00749                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00750                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00751                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00752                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00753         };
00754         const u8 imck[] = {
00755                 0x16, 0x15, 0x3C, 0x3F, 0x21, 0x55, 0xEF, 0xD9,
00756                 0x7F, 0x34, 0xAE, 0xC8, 0x1A, 0x4E, 0x66, 0x80,
00757                 0x4C, 0xC3, 0x76, 0xF2, 0x8A, 0xA9, 0x6F, 0x96,
00758                 0xC2, 0x54, 0x5F, 0x8C, 0xAB, 0x65, 0x02, 0xE1,
00759                 0x18, 0x40, 0x7B, 0x56, 0xBE, 0xEA, 0xA7, 0xC5,
00760                 0x76, 0x5D, 0x8F, 0x0B, 0xC5, 0x07, 0xC6, 0xB9,
00761                 0x04, 0xD0, 0x69, 0x56, 0x72, 0x8B, 0x6B, 0xB8,
00762                 0x15, 0xEC, 0x57, 0x7B
00763         };
00764         const u8 msk[] = {
00765                 0x4D, 0x83, 0xA9, 0xBE, 0x6F, 0x8A, 0x74, 0xED,
00766                 0x6A, 0x02, 0x66, 0x0A, 0x63, 0x4D, 0x2C, 0x33,
00767                 0xC2, 0xDA, 0x60, 0x15, 0xC6, 0x37, 0x04, 0x51,
00768                 0x90, 0x38, 0x63, 0xDA, 0x54, 0x3E, 0x14, 0xB9,
00769                 0x27, 0x99, 0x18, 0x1E, 0x07, 0xBF, 0x0F, 0x5A,
00770                 0x5E, 0x3C, 0x32, 0x93, 0x80, 0x8C, 0x6C, 0x49,
00771                 0x67, 0xED, 0x24, 0xFE, 0x45, 0x40, 0xA0, 0x59,
00772                 0x5E, 0x37, 0xC2, 0xE9, 0xD0, 0x5D, 0x0A, 0xE3
00773         };
00774         u8 tlv[] = {
00775                 0x80, 0x0C, 0x00, 0x38, 0x00, 0x01, 0x01, 0x00,
00776                 0xD8, 0x6A, 0x8C, 0x68, 0x3C, 0x32, 0x31, 0xA8,
00777                 0x56, 0x63, 0xB6, 0x40, 0x21, 0xFE, 0x21, 0x14,
00778                 0x4E, 0xE7, 0x54, 0x20, 0x79, 0x2D, 0x42, 0x62,
00779                 0xC9, 0xBF, 0x53, 0x7F, 0x54, 0xFD, 0xAC, 0x58,
00780                 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
00781                 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
00782                 0x05, 0xC5, 0x5B, 0xB7
00783         };
00784         const u8 compound_mac[] = {
00785                 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
00786                 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
00787                 0x05, 0xC5, 0x5B, 0xB7
00788         };
00789         u8 buf[512];
00790         const u8 *simck, *cmk;
00791         int errors = 0;
00792 
00793         printf("EAP-FAST test cases\n");
00794 
00795         printf("- T-PRF (SHA1) test case / master_secret\n");
00796         sha1_t_prf(pac_key, sizeof(pac_key), "PAC to master secret label hash",
00797                    seed, sizeof(seed), buf, sizeof(master_secret));
00798         if (memcmp(master_secret, buf, sizeof(master_secret)) != 0) {
00799                 printf("T-PRF test - FAILED!\n");
00800                 errors++;
00801         }
00802 
00803         printf("- PRF (TLS, SHA1/MD5) test case / key_block\n");
00804         tls_prf(master_secret, sizeof(master_secret), "key expansion",
00805                 seed, sizeof(seed), buf, sizeof(key_block));
00806         if (memcmp(key_block, buf, sizeof(key_block)) != 0) {
00807                 printf("PRF test - FAILED!\n");
00808                 errors++;
00809         }
00810 
00811         printf("- T-PRF (SHA1) test case / IMCK\n");
00812         sha1_t_prf(sks, sizeof(sks), "Inner Methods Compound Keys",
00813                    isk, sizeof(isk), buf, sizeof(imck));
00814         if (memcmp(imck, buf, sizeof(imck)) != 0) {
00815                 printf("T-PRF test - FAILED!\n");
00816                 errors++;
00817         }
00818 
00819         simck = imck;
00820         cmk = imck + 40;
00821 
00822         printf("- T-PRF (SHA1) test case / MSK\n");
00823         sha1_t_prf(simck, 40, "Session Key Generating Function",
00824                    "", 0, buf, sizeof(msk));
00825         if (memcmp(msk, buf, sizeof(msk)) != 0) {
00826                 printf("T-PRF test - FAILED!\n");
00827                 errors++;
00828         }
00829 
00830         printf("- Compound MAC test case\n");
00831         memset(tlv + sizeof(tlv) - 20, 0, 20);
00832         hmac_sha1(cmk, 20, tlv, sizeof(tlv), tlv + sizeof(tlv) - 20);
00833         if (memcmp(tlv + sizeof(tlv) - 20, compound_mac, sizeof(compound_mac))
00834             != 0) {
00835                 printf("Compound MAC test - FAILED!\n");
00836                 errors++;
00837         }
00838 
00839         return errors;
00840 }
00841 
00842 
00843 static u8 key0[] =
00844 {
00845         0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
00846         0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
00847         0x0b, 0x0b, 0x0b, 0x0b
00848 };
00849 static u8 data0[] = "Hi There";
00850 static u8 prf0[] =
00851 {
00852         0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84,
00853         0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54,
00854         0xb8, 0x62, 0x17, 0x5e, 0xd9, 0xf0, 0x06, 0x06,
00855         0xe1, 0x7d, 0x8d, 0xa3, 0x54, 0x02, 0xff, 0xee,
00856         0x75, 0xdf, 0x78, 0xc3, 0xd3, 0x1e, 0x0f, 0x88,
00857         0x9f, 0x01, 0x21, 0x20, 0xc0, 0x86, 0x2b, 0xeb,
00858         0x67, 0x75, 0x3e, 0x74, 0x39, 0xae, 0x24, 0x2e,
00859         0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a
00860 };
00861 
00862 static u8 key1[] = "Jefe";
00863 static u8 data1[] = "what do ya want for nothing?";
00864 static u8 prf1[] =
00865 {
00866         0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad,
00867         0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4,
00868         0xfe, 0x63, 0x14, 0x46, 0xfa, 0xbd, 0xfa, 0x58,
00869         0x24, 0x47, 0x59, 0xae, 0x58, 0xef, 0x90, 0x09,
00870         0xa9, 0x9a, 0xbf, 0x4e, 0xac, 0x2c, 0xa5, 0xfa,
00871         0x87, 0xe6, 0x92, 0xc4, 0x40, 0xeb, 0x40, 0x02,
00872         0x3e, 0x7b, 0xab, 0xb2, 0x06, 0xd6, 0x1d, 0xe7,
00873         0xb9, 0x2f, 0x41, 0x52, 0x90, 0x92, 0xb8, 0xfc
00874 };
00875 
00876 
00877 static u8 key2[] =
00878 {
00879         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
00880         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
00881         0xaa, 0xaa, 0xaa, 0xaa
00882 };
00883 static u8 data2[] =
00884 {
00885         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00886         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00887         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00888         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00889         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00890         0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
00891         0xdd, 0xdd
00892 };
00893 static u8 prf2[] =
00894 {
00895         0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f,
00896         0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1,
00897         0x7a, 0x02, 0x52, 0xca, 0x5d, 0x8d, 0x8d, 0xf1,
00898         0x2c, 0xfb, 0x04, 0x73, 0x52, 0x52, 0x49, 0xce,
00899         0x9d, 0xd8, 0xd1, 0x77, 0xea, 0xd7, 0x10, 0xbc,
00900         0x9b, 0x59, 0x05, 0x47, 0x23, 0x91, 0x07, 0xae,
00901         0xf7, 0xb4, 0xab, 0xd4, 0x3d, 0x87, 0xf0, 0xa6,
00902         0x8f, 0x1c, 0xbd, 0x9e, 0x2b, 0x6f, 0x76, 0x07
00903 };
00904 
00905 
00906 struct passphrase_test {
00907         char *passphrase;
00908         char *ssid;
00909         char psk[32];
00910 };
00911 
00912 static struct passphrase_test passphrase_tests[] =
00913 {
00914         {
00915                 "password",
00916                 "IEEE",
00917                 {
00918                         0xf4, 0x2c, 0x6f, 0xc5, 0x2d, 0xf0, 0xeb, 0xef,
00919                         0x9e, 0xbb, 0x4b, 0x90, 0xb3, 0x8a, 0x5f, 0x90,
00920                         0x2e, 0x83, 0xfe, 0x1b, 0x13, 0x5a, 0x70, 0xe2,
00921                         0x3a, 0xed, 0x76, 0x2e, 0x97, 0x10, 0xa1, 0x2e
00922                 }
00923         },
00924         {
00925                 "ThisIsAPassword",
00926                 "ThisIsASSID",
00927                 {
00928                         0x0d, 0xc0, 0xd6, 0xeb, 0x90, 0x55, 0x5e, 0xd6,
00929                         0x41, 0x97, 0x56, 0xb9, 0xa1, 0x5e, 0xc3, 0xe3,
00930                         0x20, 0x9b, 0x63, 0xdf, 0x70, 0x7d, 0xd5, 0x08,
00931                         0xd1, 0x45, 0x81, 0xf8, 0x98, 0x27, 0x21, 0xaf
00932                 }
00933         },
00934         {
00935                 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
00936                 "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
00937                 {
00938                         0xbe, 0xcb, 0x93, 0x86, 0x6b, 0xb8, 0xc3, 0x83,
00939                         0x2c, 0xb7, 0x77, 0xc2, 0xf5, 0x59, 0x80, 0x7c,
00940                         0x8c, 0x59, 0xaf, 0xcb, 0x6e, 0xae, 0x73, 0x48,
00941                         0x85, 0x00, 0x13, 0x00, 0xa9, 0x81, 0xcc, 0x62
00942                 }
00943         },
00944 };
00945 
00946 #define NUM_PASSPHRASE_TESTS \
00947 (sizeof(passphrase_tests) / sizeof(passphrase_tests[0]))
00948 
00949 
00950 int main(int argc, char *argv[])
00951 {
00952         u8 res[512];
00953         int ret = 0, i;
00954 
00955         printf("PRF-SHA1 test cases:\n");
00956 
00957         sha1_prf(key0, sizeof(key0), "prefix", data0, sizeof(data0) - 1,
00958                  res, sizeof(prf0));
00959         if (memcmp(res, prf0, sizeof(prf0)) == 0)
00960                 printf("Test case 0 - OK\n");
00961         else {
00962                 printf("Test case 0 - FAILED!\n");
00963                 ret++;
00964         }
00965 
00966         sha1_prf(key1, sizeof(key1) - 1, "prefix", data1, sizeof(data1) - 1,
00967                  res, sizeof(prf1));
00968         if (memcmp(res, prf1, sizeof(prf1)) == 0)
00969                 printf("Test case 1 - OK\n");
00970         else {
00971                 printf("Test case 1 - FAILED!\n");
00972                 ret++;
00973         }
00974 
00975         sha1_prf(key2, sizeof(key2), "prefix", data2, sizeof(data2),
00976                  res, sizeof(prf2));
00977         if (memcmp(res, prf2, sizeof(prf2)) == 0)
00978                 printf("Test case 2 - OK\n");
00979         else {
00980                 printf("Test case 2 - FAILED!\n");
00981                 ret++;
00982         }
00983 
00984         ret += test_eap_fast();
00985 
00986         printf("PBKDF2-SHA1 Passphrase test cases:\n");
00987         for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) {
00988                 u8 psk[32];
00989                 struct passphrase_test *test = &passphrase_tests[i];
00990                 pbkdf2_sha1(test->passphrase,
00991                             test->ssid, strlen(test->ssid),
00992                             4096, psk, 32);
00993                 if (memcmp(psk, test->psk, 32) == 0)
00994                         printf("Test case %d - OK\n", i);
00995                 else {
00996                         printf("Test case %d - FAILED!\n", i);
00997                         ret++;
00998                 }
00999         }
01000 
01001         return ret;
01002 }
01003 #endif /* TEST_MAIN */
01004 

Generated on Sat May 6 21:13:38 2006 for wpa_supplicant by  doxygen 1.4.2