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];
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
00048
00049
00050 return;
00051 }
00052
00053
00054 if (key_len > 64) {
00055 sha1_vector(1, &key, &key_len, tk);
00056 key = tk;
00057 key_len = 20;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 memset(k_pad, 0, sizeof(k_pad));
00071 memcpy(k_pad, key, key_len);
00072
00073 for (i = 0; i < 64; i++)
00074 k_pad[i] ^= 0x36;
00075
00076
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
00088 for (i = 0; i < 64; i++)
00089 k_pad[i] ^= 0x5c;
00090
00091
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
00268
00269
00270
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
00322
00323
00324
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
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 #define SHA1HANDSOFF
00511
00512 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
00513
00514
00515
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
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
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
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
00574 a = state[0];
00575 b = state[1];
00576 c = state[2];
00577 d = state[3];
00578 e = state[4];
00579
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
00601 state[0] += a;
00602 state[1] += b;
00603 state[2] += c;
00604 state[3] += d;
00605 state[4] += e;
00606
00607 a = b = c = d = e = 0;
00608 #ifdef SHA1HANDSOFF
00609 memset(block, 0, 64);
00610 #endif
00611 }
00612
00613
00614
00615
00616 static void SHA1Init(SHA1_CTX* context)
00617 {
00618
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
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
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);
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);
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
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
00690
00691 #endif
00692
00693
00694 #ifdef TEST_MAIN
00695
00696 #include "md5.c"
00697
00698 static int test_eap_fast(void)
00699 {
00700
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
01004