18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-FAST common helper functions (RFC 4851) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2008, 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 "crypto/tls.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_defs.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_tlv_common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_fast_common.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len) 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct pac_tlv_hdr hdr; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr.type = host_to_be16(type); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr.len = host_to_be16(len); 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, &hdr, sizeof(hdr)); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 len) 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_fast_put_tlv_hdr(buf, type, len); 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, data, len); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *data) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_fast_put_tlv_hdr(buf, type, wpabuf_len(data)); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, data); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *e; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Encapsulate EAP packet in EAP-Payload TLV */ 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV"); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e == NULL) { 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for TLV encapsulation"); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_fast_put_tlv_buf(e, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return e; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *client_random, u8 *master_secret) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TLS_RANDOM_LEN 32 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TLS_MASTER_SECRET_LEN 48 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 seed[2 * TLS_RANDOM_LEN]; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random", 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client_random, TLS_RANDOM_LEN); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random", 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt server_random, TLS_RANDOM_LEN); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4851, Section 5.1: 82293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash", 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * server_random + client_random, 48) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed, server_random, TLS_RANDOM_LEN); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sha1_t_prf(pac_key, EAP_FAST_PAC_KEY_LEN, 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PAC to master secret label hash", 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret", 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt master_secret, TLS_MASTER_SECRET_LEN); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 96849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtu8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, size_t len) 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 98af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *out; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 100af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt out = os_malloc(len); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 104849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (tls_connection_get_eap_fast_key(ssl_ctx, conn, out, len)) { 105af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(out); 106af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return NULL; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1131b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidtint eap_fast_derive_eap_msk(const u8 *simck, u8 *msk) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4851, Section 5.4: EAP Master Session Key Generation 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MSK = T-PRF(S-IMCK[j], "Session Key Generating Function", 64) 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1201b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, 1211b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt "Session Key Generating Function", (u8 *) "", 0, 1221b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt msk, EAP_FAST_KEY_LEN) < 0) 1231b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return -1; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msk, EAP_FAST_KEY_LEN); 1261b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return 0; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1301b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidtint eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4851, Section 5.4: EAP Master Session Key Genreration 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EMSK = T-PRF(S-IMCK[j], 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * "Extended Session Key Generating Function", 64) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1381b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, 1391b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt "Extended Session Key Generating Function", (u8 *) "", 0, 1401b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt emsk, EAP_EMSK_LEN) < 0) 1411b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return -1; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt emsk, EAP_EMSK_LEN); 1441b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return 0; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, 1490c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt int tlv_type, u8 *pos, size_t len) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (tlv_type) { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_EAP_PAYLOAD_TLV: 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP-Payload TLV", 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, len); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->eap_payload_tlv) { 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Payload TLV in the message"); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->eap_payload_tlv = pos; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->eap_payload_tlv_len = len; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_RESULT_TLV: 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV", pos, len); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->result) { 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Result TLV in the message"); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result = EAP_TLV_RESULT_FAILURE; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Result TLV"); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result = EAP_TLV_RESULT_FAILURE; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result = WPA_GET_BE16(pos); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->result != EAP_TLV_RESULT_SUCCESS && 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result != EAP_TLV_RESULT_FAILURE) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Result %d", 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result = EAP_TLV_RESULT_FAILURE; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s", 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->result == EAP_TLV_RESULT_SUCCESS ? 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Success" : "Failure"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_INTERMEDIATE_RESULT_TLV: 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate Result TLV", 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, len); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Intermediate-Result TLV"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->iresult) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Intermediate-Result TLV in the message"); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = WPA_GET_BE16(pos); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->iresult != EAP_TLV_RESULT_SUCCESS && 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult != EAP_TLV_RESULT_FAILURE) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Intermediate " 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Result %d", tlv->iresult); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Intermediate Result: %s", 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult == EAP_TLV_RESULT_SUCCESS ? 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Success" : "Failure"); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_CRYPTO_BINDING_TLV: 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV", 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, len); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->crypto_binding) { 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Crypto-Binding TLV in the message"); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->crypto_binding_len = sizeof(struct eap_tlv_hdr) + len; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) { 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Crypto-Binding TLV"); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->crypto_binding = (struct eap_tlv_crypto_binding_tlv *) 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (pos - sizeof(struct eap_tlv_hdr)); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_REQUEST_ACTION_TLV: 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Request-Action TLV", 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, len); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->request_action) { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request-Action TLV in the message"); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request-Action TLV"); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->request_action = WPA_GET_BE16(pos); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: Request-Action: %d", 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->request_action); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TLV_PAC_TLV: 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV", pos, len); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlv->pac) { 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PAC TLV in the message"); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->iresult = EAP_TLV_RESULT_FAILURE; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->pac = pos; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv->pac_len = len; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Unknown TLV */ 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 271