18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-PEAP common routines 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2008-2011, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peap_common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint peap_prfplus(int version, const u8 *key, size_t key_len, 161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *label, const u8 *seed, size_t seed_len, 171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *buf, size_t buf_len) 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char counter = 0; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pos, plen; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[SHA1_MAC_LEN]; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t label_len = os_strlen(label); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 extra[2]; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *addr[5]; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[5]; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = hash; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = 0; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[1] = (unsigned char *) label; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[1] = label_len; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[2] = seed; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[2] = seed_len; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == 0) { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PRF+(K, S, LEN) = T1 | T2 | ... | Tn 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T1 = HMAC-SHA1(K, S | 0x01 | 0x00 | 0x00) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T2 = HMAC-SHA1(K, T1 | S | 0x02 | 0x00 | 0x00) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ... 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Tn = HMAC-SHA1(K, Tn-1 | S | n | 0x00 | 0x00) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt extra[0] = 0; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt extra[1] = 0; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[3] = &counter; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[3] = 1; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[4] = extra; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[4] = 2; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PRF (K,S,LEN) = T1 | T2 | T3 | T4 | ... where: 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T1 = HMAC-SHA1(K, S | LEN | 0x01) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T2 = HMAC-SHA1 (K, T1 | S | LEN | 0x02) 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T3 = HMAC-SHA1 (K, T2 | S | LEN | 0x03) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * T4 = HMAC-SHA1 (K, T3 | S | LEN | 0x04) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ... 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt extra[0] = buf_len & 0xff; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[3] = extra; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[3] = 1; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[4] = &counter; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[4] = 1; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 0; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < buf_len) { 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = buf_len - pos; 721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hmac_sha1_vector(key, key_len, 5, addr, len, hash) < 0) 731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen >= SHA1_MAC_LEN) { 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += SHA1_MAC_LEN; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&buf[pos], hash, plen); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = SHA1_MAC_LEN; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 86