18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - WPA state machine and EAPOL-Key processing 3807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt * Copyright (c) 2003-2015, 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/aes_wrap.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "preauth.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pmksa_cache.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_i.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_ie.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "peerkey.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @kck: Key Confirmation Key (KCK, part of PTK) 30807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt * @kck_len: KCK length in octets 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ver: Version field from Key Info 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @dest: Destination address for the frame 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @proto: Ethertype (usually ETH_P_EAPOL) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: EAPOL-Key message 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg_len: Length of message 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidtvoid wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, size_t kck_len, 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ver, const u8 *dest, u16 proto, 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, size_t msg_len, u8 *key_mic) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len = wpa_mic_len(sm->key_mgmt); 43807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) { 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Association event was not yet received; try to fetch 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BSSID from the driver. 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_get_bssid(sm, sm->bssid) < 0) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to read BSSID for " 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key destination address"); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dest = sm->bssid; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Use BSSID (" MACSTR 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ") as the destination for EAPOL-Key", 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dest)); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_mic && 62807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_mic(kck, kck_len, sm->key_mgmt, ver, msg, msg_len, 63807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic)) { 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, 656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC", 666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ver, sm->key_mgmt); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 69807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, kck_len); 70807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, mic_len); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_ether_send(sm, dest, proto, msg, msg_len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_tx_eapol_key(sm->eapol); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_key_request - Send EAPOL-Key Request 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @error: Indicate whether this is an Michael MIC error report 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pairwise: 1 = error report for pairwise packet, 0 = for group packet 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Send an EAPOL-Key Request to the current authenticator. This function is 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used to request rekeying and it is usually called when a local Michael MIC 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure is detected. 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 91807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len, hdrlen, rlen; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *reply; 93807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *reply192; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_info, ver; 95807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt u8 bssid[ETH_ALEN], *rbuf, *key_mic; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->key_mgmt == WPA_KEY_MGMT_OSEN || 986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_key_mgmt_suite_b(sm->key_mgmt)) 99f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ver = WPA_KEY_INFO_TYPE_AKM_DEFINED; 100f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (wpa_key_mgmt_ft(sm->key_mgmt) || 101f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_key_mgmt_sha256(sm->key_mgmt)) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver = WPA_KEY_INFO_TYPE_AES_128_CMAC; 10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (sm->pairwise_cipher != WPA_CIPHER_TKIP) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_get_bssid(sm, bssid) < 0) { 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to read BSSID for EAPOL-Key request"); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 114807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt mic_len = wpa_mic_len(sm->key_mgmt); 115807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 117807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen, &rlen, (void *) &reply); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rbuf == NULL) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 120807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt reply192 = (struct wpa_eapol_key_192 *) reply; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 122f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reply->type = (sm->proto == WPA_PROTO_RSN || 123f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->proto == WPA_PROTO_OSEN) ? 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_KEY_INFO_REQUEST | ver; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ptk_set) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= WPA_KEY_INFO_MIC; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= WPA_KEY_INFO_ERROR; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= WPA_KEY_INFO_KEY_TYPE; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_info, key_info); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_length, 0); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->replay_counter, sm->request_counter, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) 139807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply192->key_data_length, 0); 140807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 141807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply->key_data_length, 0); 142807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (!(key_info & WPA_KEY_INFO_MIC)) 143807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic = NULL; 144807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 145807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic = reply192->key_mic; /* same offset in reply */ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Sending EAPOL-Key Request (error=%d " 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pairwise=%d ptk_set=%d len=%lu)", 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error, pairwise, sm->ptk_set, (unsigned long) rlen); 151807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid, 152807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt ETH_P_EAPOL, rbuf, rlen, key_mic); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm) 1576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_IEEE80211R 1596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) { 1606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len)) 1616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 1626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RSN: Cannot set low order 256 bits of MSK for key management offload"); 1636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else { 1646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_IEEE80211R */ 1656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len)) 1666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 1676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RSN: Cannot set PMK for key management offload"); 1686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_IEEE80211R 1696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_IEEE80211R */ 1716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_get_pmk(struct wpa_sm *sm, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int abort_cached = 0; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid && !sm->cur_pmksa) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* When using drivers that generate RSN IE, wpa_supplicant may 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not have enough time to get the association information 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * event before receiving this 1/4 message, so try to find a 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * matching PMKSA cache entry here. */ 185c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid, 186c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt NULL); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cur_pmksa) { 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: found matching PMKID from PMKSA cache"); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: no matching PMKID found"); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort_cached = 1; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid && sm->cur_pmksa && 198c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_pmk_from_pmksa(sm); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache", 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk, sm->pmk_len); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_cached(sm->eapol); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, pmk_len; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk_len = PMK_LEN; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-LEAP is an exception from other EAP methods: it 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * uses only 16-byte PMK. 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm->eapol, sm->pmk, 16); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk_len = 16; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2 * PMK_LEN]; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = PMK_LEN; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(buf, 0, sizeof(buf)); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 23061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct rsn_pmksa_cache_entry *sa = NULL; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state " 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machines", sm->pmk, pmk_len); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_len = pmk_len; 2346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_key_mgmt_set_pmk(sm); 235c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (sm->proto == WPA_PROTO_RSN && 2366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt) && 237c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt !wpa_key_mgmt_ft(sm->key_mgmt)) { 23861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sa = pmksa_cache_add(sm->pmksa, 23961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->pmk, pmk_len, 2406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt NULL, 0, 24161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt src_addr, sm->own_addr, 24261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->network_ctx, 24361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->key_mgmt); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->cur_pmksa && pmkid && 246c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL)) 247c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: the new PMK matches with the " 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PMKID"); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort_cached = 0; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!sm->cur_pmksa) 25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->cur_pmksa = sa; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to get master session key from " 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL state machines - key handshake " 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "aborted"); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cur_pmksa) { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Cancelled PMKSA caching " 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attempt"); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cur_pmksa = NULL; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort_cached = 1; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!abort_cached) { 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 273c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && 2746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt) && 275f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN) 276f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send EAPOL-Start to trigger full EAP authentication. */ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: no PMKSA entry found - trigger " 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "full EAP authentication"); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, &buflen, NULL); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL, 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, buflen); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @dst: Destination address for the frame 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Pointer to the EAPOL-Key frame header 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ver: Version bits from EAPOL-Key Key Info 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @nonce: Nonce value for the EAPOL-Key frame 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie: WPA/RSN IE 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie_len: Length of the WPA/RSN IE 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ptk: PTK to use for keyed hash and encryption 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ver, const u8 *nonce, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie, size_t wpa_ie_len, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ptk *ptk) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 318807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len, hdrlen, rlen; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *reply; 320807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *reply192; 321807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt u8 *rbuf, *key_mic; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rsn_ie_buf = NULL; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ie == NULL) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - " 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot generate msg 2/4"); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->key_mgmt)) { 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FTIE from (Re)Association Response. 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN + 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_resp_ies_len); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_ie_buf == NULL) 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len, 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_r1_name); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsn_ie_buf); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len += res; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_resp_ies) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_resp_ies_len); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len += sm->assoc_resp_ies_len; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = rsn_ie_buf; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 363807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt mic_len = wpa_mic_len(sm->key_mgmt); 364807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, 366807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt NULL, hdrlen + wpa_ie_len, 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &rlen, (void *) &reply); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rbuf == NULL) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsn_ie_buf); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 372807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt reply192 = (struct wpa_eapol_key_192 *) reply; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 374f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reply->type = (sm->proto == WPA_PROTO_RSN || 375f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->proto == WPA_PROTO_OSEN) ? 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_info, 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC); 379f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_length, 0); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->key_length, key->key_length, 2); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->replay_counter, key->replay_counter, 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter, 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic = reply192->key_mic; /* same offset for reply and reply192 */ 389807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) { 390807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply192->key_data_length, wpa_ie_len); 391807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(reply192 + 1, wpa_ie, wpa_ie_len); 392807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt } else { 393807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply->key_data_length, wpa_ie_len); 394807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(reply + 1, wpa_ie, wpa_ie_len); 395807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt } 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsn_ie_buf); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4"); 401807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL, 402807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt rbuf, rlen, key_mic); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, 409807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const struct wpa_eapol_key *key, struct wpa_ptk *ptk) 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->key_mgmt)) 413807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt return wpa_derive_ptk_ft(sm, src_addr, key, ptk); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 416807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", 417807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->own_addr, sm->bssid, sm->snonce, 418807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key->key_nonce, ptk, sm->key_mgmt, 419807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->pairwise_cipher); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 42643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u16 ver, const u8 *key_data, 42743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt size_t key_data_len) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse ie; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ptk *ptk; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 432cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 *kde, *kde_buf = NULL; 433cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt size_t kde_len; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_get_network_ctx(sm) == NULL) { 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info " 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found (msg 1 of 4)"); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way " 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ie, 0, sizeof(ie)); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 447f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) { 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RSN: msg 1/4 should contain PMKID for the selected PMK */ 44943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", 45043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data, key_data_len); 45143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) 4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto failed; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.pmkid) { 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: PMKID from " 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Authenticator", ie.pmkid, PMKID_LEN); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == -2) { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to " 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "msg 1/4 - requesting full EAP authentication"); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->renew_snonce) { 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) { 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to get random data for SNonce"); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->renew_snonce = 0; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->snonce, WPA_NONCE_LEN); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Calculate PTK which will be stored as a temporary PTK until it has 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been verified when processing message 3/4. */ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptk = &sm->tptk; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_derive_ptk(sm, src_addr, key, ptk); 4839866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt if (sm->pairwise_cipher == WPA_CIPHER_TKIP) { 48461593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt u8 buf[8]; 4859866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt /* Supplicant: swap tx/rx Mic keys */ 486807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(buf, &ptk->tk[16], 8); 487807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(&ptk->tk[16], &ptk->tk[24], 8); 488807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(&ptk->tk[24], buf, 8); 48961593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(buf, 0, sizeof(buf)); 4909866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt } 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->tptk_set = 1; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 493cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde = sm->assoc_wpa_ie; 494cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde_len = sm->assoc_wpa_ie_len; 495cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 496cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 497cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (sm->p2p) { 498cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1); 499cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (kde_buf) { 500cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 *pos; 501cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE " 502cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "into EAPOL-Key 2/4"); 503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(kde_buf, kde, kde_len); 504cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde = kde_buf; 505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos = kde + kde_len; 506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *pos++ = WLAN_EID_VENDOR_SPECIFIC; 507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *pos++ = RSN_SELECTOR_LEN + 1; 508cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ); 509cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos += RSN_SELECTOR_LEN; 510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *pos++ = 0x01; 511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde_len = pos - kde; 512cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce, 517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde, kde_len, ptk)) 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 520cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_free(kde_buf); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 525cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_free(kde_buf); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx) 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_sm *sm = eloop_ctx; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_preauth_candidate_process(sm); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_key_neg_complete(struct wpa_sm *sm, 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, int secure) 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Key negotiation completed with " 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr), 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_cipher_txt(sm->pairwise_cipher), 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_cipher_txt(sm->group_cipher)); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_cancel_auth_timeout(sm); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_COMPLETED); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (secure) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_mlme_setprotection( 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX, 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_portValid(sm->eapol, TRUE); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(sm->key_mgmt)) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_eap_success(sm->eapol, TRUE); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Start preauthentication after a short wait to avoid a 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * possible race condition between the data receive and key 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration after the 4-Way Handshake. This increases the 5591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * likelihood of the first preauth EAPOL-Start frame getting to 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the target AP. 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Authenticator accepted " 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "opportunistic PMKSA entry - marking it valid"); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cur_pmksa->opportunistic = 0; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->key_mgmt)) { 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Prepare for the next transition */ 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_prepare_auth_request(sm, NULL); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx) 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_sm *sm = eloop_ctx; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying"); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_key_request(sm, 0, 1); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_install_ptk(struct wpa_sm *sm, 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key) 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int keylen, rsclen; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg alg; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key_rsc; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Installing PTK to the driver"); 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sm->pairwise_cipher == WPA_CIPHER_NONE) { 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher " 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Suite: NONE - do not use pairwise keys"); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 6054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 6064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) { 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported pairwise cipher %d", 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pairwise_cipher); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt alg = wpa_cipher_to_alg(sm->pairwise_cipher); 6144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt keylen = wpa_cipher_key_len(sm->pairwise_cipher); 6154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher); 6164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 617f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) { 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_rsc = null_rsc; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_rsc = key->key_rsc; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen, 625807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->ptk.tk, keylen) < 0) { 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to set PTK to the " 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver (alg=%d keylen=%d bssid=" MACSTR ")", 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alg, keylen, MAC2STR(sm->bssid)); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* TK is not needed anymore in supplicant */ 634807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); 6356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ptk_rekey) { 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, NULL); 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_check_group_cipher(struct wpa_sm *sm, 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int group_cipher, 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int keylen, int maxkeylen, 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *key_rsc_len, 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg *alg) 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int klen; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt *alg = wpa_cipher_to_alg(group_cipher); 6554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (*alg == WPA_ALG_NONE) { 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported Group Cipher %d", 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_cipher); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt *key_rsc_len = wpa_cipher_rsc_len(group_cipher); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt klen = wpa_cipher_key_len(group_cipher); 6644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (keylen != klen || maxkeylen < klen) { 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported %s Group Cipher key length %d (%d)", 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_cipher_txt(group_cipher), keylen, maxkeylen); 6684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_gtk_data { 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg alg; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tx, key_rsc_len, keyidx; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 gtk[32]; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int gtk_len; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_install_gtk(struct wpa_sm *sm, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_gtk_data *gd, 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key_rsc) 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *_gtk = gd->gtk; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 gtk_buf[32]; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)", 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->keyidx, gd->tx, gd->gtk_len); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->group_cipher == WPA_CIPHER_TKIP) { 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Swap Tx/Rx keys for Michael MIC */ 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(gtk_buf, gd->gtk, 16); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(gtk_buf + 16, gd->gtk + 24, 8); 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(gtk_buf + 24, gd->gtk + 16, 8); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _gtk = gtk_buf; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pairwise_cipher == WPA_CIPHER_NONE) { 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_set_key(sm, gd->alg, NULL, 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->keyidx, 1, key_rsc, gd->key_rsc_len, 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _gtk, gd->gtk_len) < 0) { 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to set GTK to the driver " 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Group only)"); 70861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(gtk_buf, 0, sizeof(gtk_buf)); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr, 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len, 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _gtk, gd->gtk_len) < 0) { 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to set GTK to " 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the driver (alg=%d keylen=%d keyidx=%d)", 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->alg, gd->gtk_len, gd->keyidx); 71861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(gtk_buf, 0, sizeof(gtk_buf)); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 72161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(gtk_buf, 0, sizeof(gtk_buf)); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm, 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tx) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) { 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore Tx bit for GTK if a pairwise key is used. One AP 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * seemed to set this bit (incorrectly, since Tx is only when 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * doing Group Key only APs) and without this workaround, the 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data connection does not work because wpa_supplicant 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured non-zero keyidx to be used for unicast. */ 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Tx bit set for GTK, but pairwise " 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "keys are used - ignore Tx bit"); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tx; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gtk, size_t gtk_len, 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_info) 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_gtk_data gd; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GTK KDE format: 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7] 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reserved [bits 0-7] 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GTK 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake", 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk, gtk_len); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk)) 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd.keyidx = gtk[0] & 0x3; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm, 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !!(gtk[0] & BIT(2))); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk += 2; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk_len -= 2; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(gd.gtk, gtk, gtk_len); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd.gtk_len = gtk_len; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 776fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED && 777fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, 778fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt gtk_len, gtk_len, 779fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt &gd.key_rsc_len, &gd.alg) || 780fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_supplicant_install_gtk(sm, &gd, key->key_rsc))) { 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Failed to install GTK"); 78361593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 78661593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_key_neg_complete(sm, sm->bssid, 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_SECURE); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee80211w_set_keys(struct wpa_sm *sm, 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie) 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 798b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher)) 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie->igtk) { 802b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_igtk_kde *igtk; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 keyidx; 805b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt len = wpa_cipher_key_len(sm->mgmt_group_cipher); 806b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len) 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt igtk = (const struct wpa_igtk_kde *) ie->igtk; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx = WPA_GET_LE16(igtk->keyid); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d " 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pn %02x%02x%02x%02x%02x%02x", 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx, MAC2STR(igtk->pn)); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", 814b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt igtk->igtk, len); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keyidx > 4095) { 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Invalid IGTK KeyID %d", keyidx); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 820b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), 821b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt broadcast_ether_addr, 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx, 0, igtk->pn, sizeof(igtk->pn), 823b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt igtk->igtk, len) < 0) { 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Failed to configure IGTK to the driver"); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_IEEE80211W */ 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_report_ie_mismatch(struct wpa_sm *sm, 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *reason, const u8 *src_addr, 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie, size_t wpa_ie_len, 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *rsn_ie, size_t rsn_ie_len) 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")", 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason, MAC2STR(src_addr)); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ap_wpa_ie) { 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp", 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_wpa_ie, sm->ap_wpa_ie_len); 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ie) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->ap_wpa_ie) { 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No WPA IE in Beacon/ProbeResp"); 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg", 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie, wpa_ie_len); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ap_rsn_ie) { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp", 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie, sm->ap_rsn_ie_len); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn_ie) { 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->ap_rsn_ie) { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No RSN IE in Beacon/ProbeResp"); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg", 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_ie, rsn_ie_len); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 871d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS); 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ft_validate_mdie(struct wpa_sm *sm, 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie, 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *assoc_resp_mdie) 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_mdie *mdie; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = (struct rsn_mdie *) (ie->mdie + 2); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) || 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(mdie->mobility_domain, sm->mobility_domain, 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN) != 0) { 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did " 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not match with the current mobility domain"); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (assoc_resp_mdie && 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (assoc_resp_mdie[1] != ie->mdie[1] || 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) { 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch"); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4", 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->mdie, 2 + ie->mdie[1]); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response", 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assoc_resp_mdie, 2 + assoc_resp_mdie[1]); 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ft_validate_ftie(struct wpa_sm *sm, 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie, 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *assoc_resp_ftie) 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie->ftie == NULL) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT: No FTIE in EAPOL-Key msg 3/4"); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (assoc_resp_ftie == NULL) 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (assoc_resp_ftie[1] != ie->ftie[1] || 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) { 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch"); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4", 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->ftie, 2 + ie->ftie[1]); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response", 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assoc_resp_ftie, 2 + assoc_resp_ftie[1]); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ft_validate_rsnie(struct wpa_sm *sm, 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie) 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data rsn; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ie->rsn_ie) 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Verify that PMKR1Name from EAPOL-Key message 3/4 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * matches with the value we derived. 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 || 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn.num_pmkid != 1 || rsn.pmkid == NULL) { 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in " 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT 4-way handshake message 3/4"); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 956c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) 957c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt { 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT: PMKR1Name mismatch in " 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT 4-way handshake message 3/4"); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator", 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn.pmkid, WPA_PMK_NAME_LEN); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_r1_name, WPA_PMK_NAME_LEN); 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm, 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie) 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end, *mdie = NULL, *ftie = NULL; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_resp_ies) { 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = sm->assoc_resp_ies; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + sm->assoc_resp_ies_len; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 2 < end) { 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (*pos) { 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_MOBILITY_DOMAIN: 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = pos; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_FAST_BSS_TRANSITION: 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ftie = pos; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 || 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ft_validate_ftie(sm, src_addr, ie, ftie) < 0 || 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ft_validate_rsnie(sm, src_addr, ie) < 0) 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_validate_ie(struct wpa_sm *sm, 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *ie) 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) { 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No WPA/RSN IE for this AP known. " 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Trying to get from scan results"); 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_get_beacon_ie(sm) < 0) { 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Could not find AP from " 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the scan results"); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Found the current AP from " 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "updated scan results"); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie->wpa_ie == NULL && ie->rsn_ie == NULL && 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->ap_wpa_ie || sm->ap_rsn_ie)) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match " 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with IE in Beacon/ProbeResp (no IE?)", 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt src_addr, ie->wpa_ie, ie->wpa_ie_len, 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie, ie->rsn_ie_len); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ie->wpa_ie && sm->ap_wpa_ie && 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ie->wpa_ie_len != sm->ap_wpa_ie_len || 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) || 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ie->rsn_ie && sm->ap_rsn_ie && 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt), 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie, sm->ap_rsn_ie_len, 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie, ie->rsn_ie_len))) { 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match " 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with IE in Beacon/ProbeResp", 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt src_addr, ie->wpa_ie, ie->wpa_ie_len, 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie, ie->rsn_ie_len); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->proto == WPA_PROTO_WPA && 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) { 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_report_ie_mismatch(sm, "Possible downgrade attack " 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "detected - RSN was enabled and RSN IE " 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "was in msg 3/4, but not in " 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Beacon/ProbeResp", 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt src_addr, ie->wpa_ie, ie->wpa_ie_len, 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie->rsn_ie, ie->rsn_ie_len); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->key_mgmt) && 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0) 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @dst: Destination address for the frame 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Pointer to the EAPOL-Key frame header 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ver: Version bits from EAPOL-Key Key Info 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key_info: Key Info 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ptk: PTK to use for keyed hash and encryption 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ver, u16 key_info, 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ptk *ptk) 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1085807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len, hdrlen, rlen; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *reply; 1087807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *reply192; 1088807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt u8 *rbuf, *key_mic; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1090807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt mic_len = wpa_mic_len(sm->key_mgmt); 1091807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 1093807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen, &rlen, (void *) &reply); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rbuf == NULL) 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1096807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt reply192 = (struct wpa_eapol_key_192 *) reply; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reply->type = (sm->proto == WPA_PROTO_RSN || 1099f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->proto == WPA_PROTO_OSEN) ? 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info &= WPA_KEY_INFO_SECURE; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_info, key_info); 1104f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_length, 0); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->key_length, key->key_length, 2); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->replay_counter, key->replay_counter, 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1111807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic = reply192->key_mic; /* same offset for reply and reply192 */ 1112807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) 1113807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply192->key_data_length, 0); 1114807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 1115807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply->key_data_length, 0); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4"); 1118807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL, 1119807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt rbuf, rlen, key_mic); 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 112743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u16 ver, const u8 *key_data, 112843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt size_t key_data_len) 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 113043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u16 key_info, keylen; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse ie; 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE); 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way " 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_GET_BE16(key->key_info); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 113943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len); 114043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) 11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto failed; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: GTK IE in unencrypted key data"); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: IGTK KDE in unencrypted key data"); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1154b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (ie.igtk && 1155b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) && 1156b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN + 1157b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) { 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Invalid IGTK KDE length %lu", 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) ie.igtk_len); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: ANonce from message 1 of 4-Way Handshake " 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "differs from 3 of 4-Way Handshake - drop packet (src=" 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR ")", MAC2STR(sm->bssid)); 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keylen = WPA_GET_BE16(key->key_length); 11774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) { 11784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 11794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "WPA: Invalid %s key length %d (src=" MACSTR 11804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ")", wpa_cipher_txt(sm->pairwise_cipher), keylen, 11814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt MAC2STR(sm->bssid)); 11824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt goto failed; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1185cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 1186cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ie.ip_addr_alloc) { 1187cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4); 1188cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: IP address info", 1189cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr)); 1190cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1191cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 1192cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info, 119421de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt &sm->ptk)) { 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SNonce was successfully used in msg 3/4, so mark it to be renewed 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the next 4-Way Handshake. If msg 3 is received again, the old 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SNonce will still be used to avoid changing PTK. */ 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->renew_snonce = 1; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_INSTALL) { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_install_ptk(sm, key)) 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_SECURE) { 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_mlme_setprotection( 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX, 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_portValid(sm->eapol, TRUE); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE); 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1216fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) { 1217fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_supplicant_key_neg_complete(sm, sm->bssid, 1218fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt key_info & WPA_KEY_INFO_SECURE); 1219fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (ie.gtk && 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_pairwise_gtk(sm, key, 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie.gtk, ie.gtk_len, key_info) < 0) { 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Failed to configure GTK"); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee80211w_set_keys(sm, &ie) < 0) { 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Failed to configure IGTK"); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1233cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ie.gtk) 1234cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_sm_set_rekey_offload(sm); 12351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) { 12376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct rsn_pmksa_cache_entry *sa; 12386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 12396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, 1240807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->ptk.kck, sm->ptk.kck_len, 12416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->bssid, sm->own_addr, 12426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->network_ctx, sm->key_mgmt); 12436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!sm->cur_pmksa) 12446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->cur_pmksa = sa; 12456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 12466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 12474dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt sm->msg_3_of_4_ok = 1; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm, 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *keydata, 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t keydatalen, 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 key_info, 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_gtk_data *gd) 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int maxkeylen; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse ie; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen); 12651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0) 12661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: GTK IE in unencrypted key data"); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.gtk == NULL) { 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No GTK IE in Group Key msg 1/2"); 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxkeylen = gd->gtk_len = ie.gtk_len - 2; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->gtk_len, maxkeylen, 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &gd->key_rsc_len, &gd->alg)) 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake", 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie.gtk, ie.gtk_len); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->keyidx = ie.gtk[0] & 0x3; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm, 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !!(ie.gtk[0] & BIT(2))); 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie.gtk_len - 2 > sizeof(gd->gtk)) { 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Too long GTK in GTK IE (len=%lu)", 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) ie.gtk_len - 2); 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2); 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee80211w_set_keys(sm, &ie) < 0) 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Failed to configure IGTK"); 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm, 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 130743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const u8 *key_data, 130843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt size_t key_data_len, u16 key_info, 130943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u16 ver, struct wpa_gtk_data *gd) 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t maxkeylen; 13126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u16 gtk_len; 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt gtk_len = WPA_GET_BE16(key->key_length); 131543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt maxkeylen = key_data_len; 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxkeylen < 8) { 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Too short maxkeylen (%lu)", 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) maxkeylen); 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxkeylen -= 8; 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (gtk_len > maxkeylen || 13276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_check_group_cipher(sm, sm->group_cipher, 13286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt gtk_len, maxkeylen, 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &gd->key_rsc_len, &gd->alg)) 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt gd->gtk_len = gtk_len; 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >> 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_KEY_INDEX_SHIFT; 1335807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) { 133661593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt u8 ek[32]; 133743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (key_data_len > sizeof(gd->gtk)) { 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: RC4 key data too long (%lu)", 134043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned long) key_data_len); 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 134361593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memcpy(ek, key->key_iv, 16); 1344807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len); 134543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_memcpy(gd->gtk, key_data, key_data_len); 134643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) { 134761593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(ek, 0, sizeof(ek)); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: RC4 failed"); 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 135261593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(ek, 0, sizeof(ek)); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 135443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (maxkeylen % 8) { 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported AES-WRAP len %lu", 135743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned long) maxkeylen); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxkeylen > sizeof(gd->gtk)) { 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: AES-WRAP key data " 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "too long (keydatalen=%lu maxkeylen=%lu)", 136443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned long) key_data_len, 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) maxkeylen); 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1368807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8, 1369807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_data, gd->gtk)) { 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: AES unwrap failed - could not decrypt " 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GTK"); 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported key_info type %d", ver); 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gd->tx = wpa_supplicant_gtk_tx_bit_workaround( 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, !!(key_info & WPA_KEY_INFO_TXRX)); 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_send_2_of_2(struct wpa_sm *sm, 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ver, u16 key_info) 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1390807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len, hdrlen, rlen; 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *reply; 1392807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *reply192; 1393807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt u8 *rbuf, *key_mic; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1395807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt mic_len = wpa_mic_len(sm->key_mgmt); 1396807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 1398807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt hdrlen, &rlen, (void *) &reply); 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rbuf == NULL) 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1401807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt reply192 = (struct wpa_eapol_key_192 *) reply; 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1403f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reply->type = (sm->proto == WPA_PROTO_RSN || 1404f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->proto == WPA_PROTO_OSEN) ? 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info &= WPA_KEY_INFO_KEY_INDEX_MASK; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_info, key_info); 1409f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(reply->key_length, 0); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->key_length, key->key_length, 2); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->replay_counter, key->replay_counter, 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1416807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_mic = reply192->key_mic; /* same offset for reply and reply192 */ 1417807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) 1418807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply192->key_data_length, 0); 1419807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 1420807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_PUT_BE16(reply->key_data_length, 0); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2"); 1423807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, sm->bssid, 1424807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt ETH_P_EAPOL, rbuf, rlen, key_mic); 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *src_addr, 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *key, 143343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const u8 *key_data, 143443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt size_t key_data_len, u16 ver) 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 143643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u16 key_info; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rekey, ret; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_gtk_data gd; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14404dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt if (!sm->msg_3_of_4_ok) { 14414dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 14424dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt "WPA: Group Key Handshake started prior to completion of 4-way handshake"); 14434dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt goto failed; 14444dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt } 14454dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rekey = wpa_sm_get_state(sm) == WPA_COMPLETED; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key " 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver); 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_GET_BE16(key->key_info); 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1454f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) { 145543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data, 145643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data_len, key_info, 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &gd); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 145943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data, 146043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data_len, 146143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_info, ver, &gd); 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) || 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_send_2_of_2(sm, key, ver, key_info)) 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 14726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rekey) { 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying " 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "completed with " MACSTR " [GTK=%s]", 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher)); 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_cancel_auth_timeout(sm); 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_state(sm, WPA_COMPLETED); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_key_neg_complete(sm, sm->bssid, 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_SECURE); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1485cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1486cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_sm_set_rekey_offload(sm); 1487cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 14916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm, 1497807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *key, 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ver, 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1501807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok = 0; 1503807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len = wpa_mic_len(sm->key_mgmt); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1505807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(mic, key->key_mic, mic_len); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->tptk_set) { 1507807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memset(key->key_mic, 0, mic_len); 1508807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt, 1509807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt ver, buf, len, key->key_mic); 1510807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) { 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Invalid EAPOL-Key MIC " 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when using TPTK - ignoring TPTK"); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->tptk_set = 0; 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ptk_set = 1; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk)); 151961593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&sm->tptk, 0, sizeof(sm->tptk)); 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok && sm->ptk_set) { 1524807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memset(key->key_mic, 0, mic_len); 1525807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt, 1526807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt ver, buf, len, key->key_mic); 1527807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) { 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Invalid EAPOL-Key MIC - " 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropping packet"); 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Could not verify EAPOL-Key MIC - " 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropping packet"); 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->rx_replay_counter, key->replay_counter, 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rx_replay_counter_set = 1; 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */ 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm, 155243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_eapol_key *key, u16 ver, 155343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 *key_data, size_t *key_data_len) 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data", 155643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data, *key_data_len); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->ptk_set) { 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: PTK not available, cannot decrypt EAPOL-Key Key " 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Data"); 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Decrypt key data here so that this operation does not need 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to be implemented separately for each message type. */ 1566807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) { 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ek[32]; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ek, key->key_iv, 16); 1569807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len); 157043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) { 157161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(ek, 0, sizeof(ek)); 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: RC4 failed"); 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 157661593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(ek, 0, sizeof(ek)); 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1578f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ver == WPA_KEY_INFO_TYPE_AES_128_CMAC || 15796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->key_mgmt == WPA_KEY_MGMT_OSEN || 15806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_key_mgmt_suite_b(sm->key_mgmt)) { 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf; 158243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (*key_data_len < 8 || *key_data_len % 8) { 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 158443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "WPA: Unsupported AES-WRAP len %u", 158543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned int) *key_data_len); 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 158843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt *key_data_len -= 8; /* AES-WRAP adds 8 bytes */ 158943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt buf = os_malloc(*key_data_len); 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No memory for AES-UNWRAP buffer"); 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1595807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8, 159643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data, buf)) { 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: AES unwrap failed - " 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "could not decrypt EAPOL-Key key data"); 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 160343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_memcpy(key_data, buf, *key_data_len); 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 160543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt WPA_PUT_BE16(key->key_data_length, *key_data_len); 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported key_info type %d", ver); 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data", 161243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data, *key_data_len); 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_aborted_cached(struct wpa_sm *sm) 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->cur_pmksa) { 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Cancelling PMKSA caching attempt"); 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cur_pmksa = NULL; 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_eapol_key_dump(struct wpa_sm *sm, 1632807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const struct wpa_eapol_key *key, 1633807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt unsigned int key_data_len, 1634807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const u8 *mic, unsigned int mic_len) 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 key_info = WPA_GET_BE16(key->key_info); 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)", 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info, key_info & WPA_KEY_INFO_TYPE_MASK, 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >> 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_KEY_INDEX_SHIFT, 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13, 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group", 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_INSTALL ? " Install" : "", 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_ACK ? " Ack" : "", 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_MIC ? " MIC" : "", 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_SECURE ? " Secure" : "", 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_ERROR ? " Error" : "", 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_REQUEST ? " Request" : "", 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : ""); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " key_length=%u key_data_length=%u", 1656807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt WPA_GET_BE16(key->key_length), key_data_len); 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " replay_counter", 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->replay_counter, WPA_REPLAY_COUNTER_LEN); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN); 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16); 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8); 1663807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len); 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_rx_eapol - Process received WPA EAPOL frames 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @src_addr: Source MAC address of the EAPOL packet 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the EAPOL frame 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called for each received EAPOL frame. Other than EAPOL-Key 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * only processing WPA and WPA2 EAPOL-Key frames. 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The received EAPOL-Key packets are validated and valid packets are replied 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to. In addition, key material (PTK, GTK) is configured at the end of a 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successful key handshake. 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr, 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 168743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt size_t plen, data_len, key_data_len; 168843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const struct ieee802_1x_hdr *hdr; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *key; 1690807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt struct wpa_eapol_key_192 *key192; 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 key_info, ver; 169243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 *tmp = NULL; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_peerkey *peerkey = NULL; 169543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 *key_data; 1696807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt size_t mic_len, keyhdrlen; 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ft_completed = 0; 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1702807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt mic_len = wpa_mic_len(sm->key_mgmt); 1703807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); 1704807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt 1705807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (len < sizeof(*hdr) + keyhdrlen) { 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL frame too short to be a WPA " 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key (len %lu, expecting at least %lu)", 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, 1710807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt (unsigned long) sizeof(*hdr) + keyhdrlen); 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 171443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt hdr = (const struct ieee802_1x_hdr *) buf; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len = plen + sizeof(*hdr); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IEEE 802.1X RX: version=%d type=%d length=%lu", 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version, hdr->type, (unsigned long) plen); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->version < EAPOL_VERSION) { 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: backwards compatibility */ 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) { 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL frame (type %u) discarded, " 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not a Key frame", hdr->type); 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 173143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len); 1732807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (plen > len - sizeof(*hdr) || plen < keyhdrlen) { 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL frame payload size %lu " 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid (frame size %lu)", 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen, (unsigned long) len); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 174043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (data_len < len) { 174143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 174243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "WPA: ignoring %lu bytes after the IEEE 802.1X data", 174343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned long) len - data_len); 174443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 174543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 174643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 174743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Make a copy of the frame since we need to modify the buffer during 174843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * MAC validation and Key Data decryption. 174943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 175043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt tmp = os_malloc(data_len); 175143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (tmp == NULL) 175243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt goto out; 175343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_memcpy(tmp, buf, data_len); 175443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr)); 1755807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key192 = (struct wpa_eapol_key_192 *) 1756807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt (tmp + sizeof(struct ieee802_1x_hdr)); 1757807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) 1758807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_data = (u8 *) (key192 + 1); 1759807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 1760807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_data = (u8 *) (key + 1); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN) 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL-Key type (%d) unknown, discarded", 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1771807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (mic_len == 24) 1772807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_data_len = WPA_GET_BE16(key192->key_data_length); 1773807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt else 1774807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt key_data_len = WPA_GET_BE16(key->key_data_length); 1775807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_eapol_key_dump(sm, key, key_data_len, key192->key_mic, mic_len); 1776807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt 1777807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (key_data_len > plen - keyhdrlen) { 177843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key " 177943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "frame - key_data overflow (%u > %u)", 178043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt (unsigned int) key_data_len, 1781807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt (unsigned int) (plen - keyhdrlen)); 178243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt goto out; 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 178443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 178543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt eapol_sm_notify_lower_layer_success(sm->eapol, 0); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_GET_BE16(key->key_info); 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver = key_info & WPA_KEY_INFO_TYPE_MASK; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_AES_128_CMAC && 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */ 1792f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES && 17936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt) && 1794f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->key_mgmt != WPA_KEY_MGMT_OSEN) { 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Unsupported EAPOL-Key descriptor version %d", 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1801f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->key_mgmt == WPA_KEY_MGMT_OSEN && 1802f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) { 1803f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 1804f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "OSEN: Unsupported EAPOL-Key descriptor version %d", 1805f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ver); 1806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt goto out; 1807f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1808f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 18096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_key_mgmt_suite_b(sm->key_mgmt) && 18106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) { 18116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 18126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)", 18136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ver); 18146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto out; 18156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 18166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->key_mgmt)) { 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */ 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) { 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT: AP did not use AES-128-CMAC"); 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_sha256(sm->key_mgmt)) { 1829f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC && 18306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->key_mgmt != WPA_KEY_MGMT_OSEN && 18316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt)) { 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: AP did not use the " 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "negotiated AES-128-CMAC"); 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pairwise_cipher == WPA_CIPHER_CCMP && 18406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt) && 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: CCMP is used, but EAPOL-Key " 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "descriptor version (%d) is not 2", ver); 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->group_cipher != WPA_CIPHER_CCMP && 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(key_info & WPA_KEY_INFO_KEY_TYPE)) { 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Earlier versions of IEEE 802.11i did not explicitly 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * require version 2 descriptor for all EAPOL-Key 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets, so allow group keys to use version 1 if 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * CCMP is not used for them. */ 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Backwards compatibility: allow invalid " 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "version for non-CCMP group keys"); 1854658fb4adb9458c3055c64a43833f1a9e89b4db74Jouni Malinen } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) { 1855658fb4adb9458c3055c64a43833f1a9e89b4db74Jouni Malinen wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 1856658fb4adb9458c3055c64a43833f1a9e89b4db74Jouni Malinen "WPA: Interoperability workaround: allow incorrect (should have been HMAC-SHA1), but stronger (is AES-128-CMAC), descriptor version to be used"); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 1859717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP && 18606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_key_mgmt_suite_b(sm->key_mgmt) && 1861717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 186261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 186361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "WPA: GCMP is used, but EAPOL-Key " 186461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "descriptor version (%d) is not 2", ver); 186561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto out; 186661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0) 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) { 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!peerkey->initiator && peerkey->replay_counter_set && 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(key->replay_counter, peerkey->replay_counter, 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) <= 0) { 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: EAPOL-Key Replay Counter did not " 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "increase (STK) - dropping packet"); 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (peerkey->initiator) { 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 _tmp[WPA_REPLAY_COUNTER_LEN]; 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_tmp, key->replay_counter, 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(_tmp, peerkey->replay_counter, 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) != 0) { 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: EAPOL-Key Replay " 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Counter did not match (STK) - " 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropping packet"); 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) { 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: Ack bit in key_info from STK peer"); 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!peerkey && sm->rx_replay_counter_set && 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(key->replay_counter, sm->rx_replay_counter, 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) <= 0) { 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL-Key Replay Counter did not increase - " 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropping packet"); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE)) 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt && (peerkey == NULL || !peerkey->initiator) 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ) { 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No Ack bit in key_info"); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_REQUEST) { 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL-Key with Request bit - dropped"); 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((key_info & WPA_KEY_INFO_MIC) && !peerkey && 1931807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_supplicant_verify_eapol_key_mic(sm, key192, ver, tmp, data_len)) 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((key_info & WPA_KEY_INFO_MIC) && peerkey && 1936807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt peerkey_verify_eapol_key_mic(sm, peerkey, key192, ver, tmp, 1937807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt data_len)) 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1941f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) && 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 194343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data, 194443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt &key_data_len)) 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_KEY_TYPE) { 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) { 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Ignored EAPOL-Key (Pairwise) with " 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "non-zero key index"); 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peerkey) { 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PeerKey 4-Way Handshake */ 1957c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver, 1958c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt key_data, key_data_len); 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_MIC) { 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3/4 4-Way Handshake */ 196143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_supplicant_process_3_of_4(sm, key, ver, key_data, 196243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data_len); 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1/4 4-Way Handshake */ 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_process_1_of_4(sm, src_addr, key, 196643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ver, key_data, 196743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data_len); 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) { 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PeerKey SMK Handshake */ 197143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt peerkey_rx_eapol_smk(sm, src_addr, key, key_data_len, key_info, 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_MIC) { 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1/2 Group Key Handshake */ 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_process_1_of_2(sm, src_addr, key, 197743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt key_data, key_data_len, 197843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ver); 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: EAPOL-Key (Group) without Mic bit - " 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropped"); 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 1; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 19896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(tmp, data_len); 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u32 wpa_key_mgmt_suite(struct wpa_sm *sm) 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (sm->key_mgmt) { 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_IEEE8021X: 1999f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return ((sm->proto == WPA_PROTO_RSN || 2000f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->proto == WPA_PROTO_OSEN) ? 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_AUTH_KEY_MGMT_UNSPEC_802_1X : 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_AUTH_KEY_MGMT_UNSPEC_802_1X); 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_PSK: 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (sm->proto == WPA_PROTO_RSN ? 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X : 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X); 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_FT_IEEE8021X: 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RSN_AUTH_KEY_MGMT_FT_802_1X; 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_FT_PSK: 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RSN_AUTH_KEY_MGMT_FT_PSK; 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_IEEE8021X_SHA256: 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RSN_AUTH_KEY_MGMT_802_1X_SHA256; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_PSK_SHA256: 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RSN_AUTH_KEY_MGMT_PSK_SHA256; 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2019d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt case WPA_KEY_MGMT_CCKM: 2020d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return (sm->proto == WPA_PROTO_RSN ? 2021d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt RSN_AUTH_KEY_MGMT_CCKM: 2022d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_AUTH_KEY_MGMT_CCKM); 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_KEY_MGMT_WPA_NONE: 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_AUTH_KEY_MGMT_NONE; 20256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case WPA_KEY_MGMT_IEEE8021X_SUITE_B: 20266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B; 2027807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: 2028807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192; 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RSN_SUITE "%02x-%02x-%02x-%d" 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RSN_SUITE_ARG(s) \ 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_get_mib - Dump text list of MIB entries 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the list 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Length of the buffer 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buffer 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used fetch dot11 MIB variables. 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char pmkid_txt[PMKID_LEN * 2 + 1]; 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rsna, ret; 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cur_pmksa) { 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cur_pmksa->pmkid, PMKID_LEN); 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid_txt[0] = '\0'; 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) || 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) && 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->proto == WPA_PROTO_RSN) 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsna = 1; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsna = 0; 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAOptionImplemented=TRUE\n" 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPreauthenticationImplemented=TRUE\n" 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAEnabled=%s\n" 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPreauthenticationEnabled=%s\n" 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigVersion=%d\n" 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPairwiseKeysSupported=5\n" 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigGroupCipherSize=%d\n" 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPMKLifetime=%d\n" 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPMKReauthThreshold=%d\n" 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n" 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigSATimeout=%d\n", 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsna ? "TRUE" : "FALSE", 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsna ? "TRUE" : "FALSE", 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_VERSION, 20824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_cipher_key_len(sm->group_cipher) * 8, 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKLifetime, 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKReauthThreshold, 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigSATimeout); 20866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, ret)) 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ret; 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf( 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + len, buflen - len, 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPMKIDUsed=%s\n" 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n" 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNA4WayHandshakeFailures=%u\n", 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)), 21024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto, 21034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->pairwise_cipher)), 21044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto, 21054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->group_cipher)), 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid_txt, 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)), 21084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto, 21094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->pairwise_cipher)), 21104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto, 21114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->group_cipher)), 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNA4WayHandshakeFailures); 21136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!os_snprintf_error(buflen - len, ret)) 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (int) len; 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, 2122d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt void *ctx, enum pmksa_free_reason reason) 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_sm *sm = ctx; 2125d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int deauth = 0; 2126d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: " 2128d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt MACSTR " reason=%d", MAC2STR(entry->aa), reason); 2129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2130d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sm->cur_pmksa == entry) { 2131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 2132d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "RSN: %s current PMKSA entry", 2133d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt reason == PMKSA_REPLACE ? "replaced" : "removed"); 2134d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pmksa_cache_clear_current(sm); 2135d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2136d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 2137d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * If an entry is simply being replaced, there's no need to 2138d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * deauthenticate because it will be immediately re-added. 2139d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * This happens when EAP authentication is completed again 2140d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * (reauth or failed PMKSA caching attempt). 2141d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 2142d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (reason != PMKSA_REPLACE) 2143d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt deauth = 1; 2144d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2146d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (reason == PMKSA_EXPIRE && 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->pmk_len == entry->pmk_len && 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) { 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 2150d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "RSN: deauthenticating due to expired PMK"); 2151d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pmksa_cache_clear_current(sm); 2152d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt deauth = 1; 2153d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2155d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (deauth) { 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(sm->pmk, 0, sizeof(sm->pmk)); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_init - Initialize WPA state machine 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer for callbacks; this needs to be an allocated buffer 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated WPA state machine data 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate a new WPA state machine and the returned 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * value is passed to all WPA state machine calls. 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx) 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_sm *sm; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&sm->pmksa_candidates); 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->renew_snonce = 1; 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx = ctx; 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKLifetime = 43200; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKReauthThreshold = 70; 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigSATimeout = 60; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pmksa == NULL) { 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->ctx->msg_ctx, MSG_ERROR, 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RSN: PMKSA cache initialization failed"); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_deinit - Deinitialize WPA state machine 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_deinit(struct wpa_sm *sm) 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmksa_cache_deinit(sm->pmksa); 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL); 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->assoc_wpa_ie); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ap_wpa_ie); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ap_rsn_ie); 22116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_sm_drop_sa(sm); 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ctx); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peerkey_deinit(sm); 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->assoc_resp_ies); 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_notify_assoc - Notify WPA state machine about association 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: The BSSID of the new association 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to let WPA state machine know that the connection 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * was established. 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int clear_ptk = 1; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: Association event - clear replay counter"); 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->bssid, bssid, ETH_ALEN); 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN); 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rx_replay_counter_set = 0; 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->renew_snonce = 1; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0) 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_preauth_deinit(sm); 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ft_is_completed(sm)) { 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear portValid to kick EAPOL state machine to re-enter 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AUTHENTICATED state to get the EAPOL port Authorized. 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_portValid(sm->eapol, FALSE); 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_key_neg_complete(sm, sm->bssid, 1); 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Prepare for the next transition */ 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_prepare_auth_request(sm, NULL); 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clear_ptk = 0; 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clear_ptk) { 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this is not part of a Fast BSS Transition. 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK"); 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ptk_set = 0; 226861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&sm->ptk, 0, sizeof(sm->ptk)); 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->tptk_set = 0; 227061593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&sm->tptk, 0, sizeof(sm->tptk)); 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_tdls_assoc(sm); 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */ 2276cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2277cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 2278cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr)); 2279cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to let WPA state machine know that the connection 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * was lost. This will abort any existing pre-authentication session. 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_notify_disassoc(struct wpa_sm *sm) 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22924dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL); 22934dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); 2294fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt peerkey_deinit(sm); 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_preauth_deinit(sm); 2296d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pmksa_cache_clear_current(sm); 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE) 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNA4WayHandshakeFailures++; 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_tdls_disassoc(sm); 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */ 23026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 23036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Keys are not needed in the WPA state machine anymore */ 23046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_sm_drop_sa(sm); 23054dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt 23064dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt sm->msg_3_of_4_ok = 0; 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_pmk - Set PMK 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pmk: The new PMK 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pmk_len: The length of the new PMK in bytes 23156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Configure the PMK for WPA state machine. 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len, 23206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *bssid) 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_len = pmk_len; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->pmk, pmk, pmk_len); 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set XXKey to be PSK for FT key derivation */ 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = pmk_len; 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->xxkey, pmk, pmk_len); 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 23336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 23346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (bssid) { 23356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pmksa_cache_add(sm->pmksa, pmk, pmk_len, NULL, 0, 23366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bssid, sm->own_addr, 23376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->network_ctx, sm->key_mgmt); 23386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be cleared. 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm) 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cur_pmksa) { 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_len = sm->cur_pmksa->pmk_len; 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len); 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_len = PMK_LEN; 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(sm->pmk, 0, PMK_LEN); 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @fast_reauth: Whether fast reauthentication (EAP) is allowed 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth) 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->fast_reauth = fast_reauth; 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @scard_ctx: Context pointer for smartcard related callback functions 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx) 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->scard_ctx = scard_ctx; 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->preauth_eapol) 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx); 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_config - Notification of current configration change 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to current network configuration 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify WPA state machine that configuration has changed. config will be 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stored as a backpointer to network configuration. This can be %NULL to clear 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the stored pointed. 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config) 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm) 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config) { 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->network_ctx = config->network_ctx; 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->peerkey_enabled = config->peerkey_enabled; 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher; 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->proactive_key_caching = config->proactive_key_caching; 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_workaround = config->eap_workaround; 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_conf_ctx = config->eap_conf_ctx; 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->ssid) { 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->ssid, config->ssid, config->ssid_len); 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssid_len = config->ssid_len; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssid_len = 0; 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_rekey = config->wpa_ptk_rekey; 2418cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->p2p = config->p2p; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->network_ctx = NULL; 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->peerkey_enabled = 0; 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowed_pairwise_cipher = 0; 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->proactive_key_caching = 0; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_workaround = 0; 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_conf_ctx = NULL; 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssid_len = 0; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_rekey = 0; 2428cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->p2p = 0; 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_own_addr - Set own MAC address 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Own MAC address 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr) 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->own_addr, addr, ETH_ALEN); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_ifname - Set network interface name 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Interface name 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bridge_ifname: Optional bridge interface name (for pre-auth) 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname, 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *bridge_ifname) 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ifname = ifname; 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->bridge_ifname = bridge_ifname; 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_eapol - Set EAPOL state machine pointer 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init() 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol) 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol = eapol; 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_param - Set WPA state machine parameters 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @param: Parameter field 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @value: Parameter value 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int value) 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (param) { 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RSNA_PMK_LIFETIME: 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (value > 0) 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKLifetime = value; 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RSNA_PMK_REAUTH_THRESHOLD: 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (value > 0 && value <= 100) 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigPMKReauthThreshold = value; 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RSNA_SA_TIMEOUT: 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (value > 0) 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAConfigSATimeout = value; 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_PROTO: 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->proto = value; 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_PAIRWISE: 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pairwise_cipher = value; 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_GROUP: 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group_cipher = value; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_KEY_MGMT: 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->key_mgmt = value; 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_MGMT_GROUP: 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->mgmt_group_cipher = value; 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_RSN_ENABLED: 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rsn_enabled = value; 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PARAM_MFP: 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->mfp = value; 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_get_status - Get WPA state machine 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query WPA state machine for status information. This function fills in 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a text area with current status information. If the buffer (buf) is not 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * large enough, status information will be truncated to fit the buffer. 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen, 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verbose) 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf, *end = buf + buflen; 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pairwise_cipher=%s\n" 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group_cipher=%s\n" 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key_mgmt=%s\n", 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_cipher_txt(sm->pairwise_cipher), 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_cipher_txt(sm->group_cipher), 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_key_mgmt_txt(sm->key_mgmt, sm->proto)); 25636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 2566d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2567d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) { 2568d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ie_data rsn; 2569d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) 2570d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt >= 0 && 2571d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt rsn.capabilities & (WPA_CAPABILITY_MFPR | 2572d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_CAPABILITY_MFPC)) { 2573d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ret = os_snprintf(pos, end - pos, "pmf=%d\n", 2574d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (rsn.capabilities & 2575d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_CAPABILITY_MFPR) ? 2 : 1); 25766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 2577d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return pos - buf; 2578d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pos += ret; 2579d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2580d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2581d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2586f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtint wpa_sm_pmf_enabled(struct wpa_sm *sm) 2587f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt{ 2588f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt struct wpa_ie_data rsn; 2589f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2590f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie) 2591f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return 0; 2592f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2593f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 && 2594f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC)) 2595f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return 1; 2596f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2597f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return 0; 2598f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 2599f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2600f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie: Pointer to buffer for WPA/RSN IE 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie_len: Pointer to the length of the wpa_ie buffer 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie, 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *wpa_ie_len) 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len); 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *wpa_ie_len = res; 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default", 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie, *wpa_ie_len); 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_wpa_ie == NULL) { 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the correct version of the IE even if PMKSA caching is 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * aborted (which would remove PMKID from IE generation). 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie = os_malloc(*wpa_ie_len); 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_wpa_ie == NULL) 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len); 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie_len = *wpa_ie_len; 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ie: Pointer to IE data (starting from id) 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: IE length 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inform WPA state machine about the WPA/RSN IE used in (Re)Association 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. The IE will be used to override the default value generated 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with wpa_sm_set_assoc_wpa_ie_default(). 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len) 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->assoc_wpa_ie); 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie == NULL || len == 0) { 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: clearing own WPA/RSN IE"); 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie = NULL; 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie_len = 0; 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len); 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie = os_malloc(len); 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_wpa_ie == NULL) 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->assoc_wpa_ie, ie, len); 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wpa_ie_len = len; 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ie: Pointer to IE data (starting from id) 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: IE length 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inform WPA state machine about the WPA IE used in Beacon / Probe Response 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * frame. 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len) 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ap_wpa_ie); 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie == NULL || len == 0) { 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: clearing AP WPA IE"); 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_wpa_ie = NULL; 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_wpa_ie_len = 0; 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len); 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_wpa_ie = os_malloc(len); 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ap_wpa_ie == NULL) 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->ap_wpa_ie, ie, len); 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_wpa_ie_len = len; 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ie: Pointer to IE data (starting from id) 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: IE length 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inform WPA state machine about the RSN IE used in Beacon / Probe Response 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * frame. 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len) 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ap_rsn_ie); 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie == NULL || len == 0) { 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: clearing AP RSN IE"); 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie = NULL; 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie_len = 0; 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len); 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie = os_malloc(len); 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ap_rsn_ie == NULL) 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->ap_rsn_ie, ie, len); 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ap_rsn_ie_len = len; 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to WPA state machine data from wpa_sm_init() 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Pointer to data area for parsing results 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parsed data into data. 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data) 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_wpa_ie == NULL) { 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA: No WPA/RSN IE available from association info"); 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data)) 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len) 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pmksa_cache_list(sm->pmksa, buf, len); 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_sm_drop_sa(struct wpa_sm *sm) 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK"); 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ptk_set = 0; 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->tptk_set = 0; 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(sm->pmk, 0, sizeof(sm->pmk)); 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->ptk, 0, sizeof(sm->ptk)); 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->tptk, 0, sizeof(sm->tptk)); 27876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_IEEE80211R 27886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); 27896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0)); 27906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1)); 27916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_IEEE80211R */ 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_sm_has_ptk(struct wpa_sm *sm) 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->ptk_set; 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr) 28041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 28051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN); 28061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 28071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx) 28101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2811f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0); 28121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 281361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 281461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2815a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM 281661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) 281761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 281861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 keyinfo; 281961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 keylen; /* plaintext key len */ 282061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *key_rsc; 282161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 282261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (subelem_id == WNM_SLEEP_SUBELEM_GTK) { 282361593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt struct wpa_gtk_data gd; 282461593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt 282561593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 282661593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt keylen = wpa_cipher_key_len(sm->group_cipher); 282761593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher); 282861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt gd.alg = wpa_cipher_to_alg(sm->group_cipher); 282961593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt if (gd.alg == WPA_ALG_NONE) { 283061593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt wpa_printf(MSG_DEBUG, "Unsupported group cipher suite"); 283161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt return -1; 283261593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt } 283361593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt 283461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt key_rsc = buf + 5; 2835a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt keyinfo = WPA_GET_LE16(buf + 2); 283661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gd.gtk_len = keylen; 283761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (gd.gtk_len != buf[4]) { 283861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d", 283961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gd.gtk_len, buf[4]); 284061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 284161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 284261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gd.keyidx = keyinfo & 0x03; /* B0 - B1 */ 284361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gd.tx = wpa_supplicant_gtk_tx_bit_workaround( 284461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm, !!(keyinfo & WPA_KEY_INFO_TXRX)); 284561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2846a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(gd.gtk, buf + 13, gd.gtk_len); 284761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 284861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", 284961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gd.gtk, gd.gtk_len); 285061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) { 285161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 285261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to install the GTK in " 285361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "WNM mode"); 285461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 285561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 285661593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&gd, 0, sizeof(gd)); 285761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211W 285861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { 285961593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt struct wpa_igtk_kde igd; 286061593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt u16 keyidx; 286161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt 286261593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&igd, 0, sizeof(igd)); 2863b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt keylen = wpa_cipher_key_len(sm->mgmt_group_cipher); 286461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(igd.keyid, buf + 2, 2); 286561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(igd.pn, buf + 4, 6); 286661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 286761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt keyidx = WPA_GET_LE16(igd.keyid); 2868b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt os_memcpy(igd.igtk, buf + 10, keylen); 286961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 287061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)", 2871b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt igd.igtk, keylen); 2872b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), 2873b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt broadcast_ether_addr, 287461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt keyidx, 0, igd.pn, sizeof(igd.pn), 2875b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt igd.igtk, keylen) < 0) { 287661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to install the IGTK in " 287761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "WNM mode"); 287861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&igd, 0, sizeof(igd)); 287961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 288061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 288161593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt os_memset(&igd, 0, sizeof(igd)); 288261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 288361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 288461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Unknown element id"); 288561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 288661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 288761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 288861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 288961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 2890a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */ 2891fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2892fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2893fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_PEERKEY 2894fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr, 2895fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const u8 *buf, size_t len) 2896fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2897fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_peerkey *peerkey; 2898fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2899fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 2900fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0) 2901fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt break; 2902fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2903fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2904fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!peerkey) 2905fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 2906fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2907fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_sm_rx_eapol(sm, src_addr, buf, len); 2908fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2909fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 2910fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2911fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 2912cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2913cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2914cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 2915cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2916cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf) 2917cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 2918cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0) 2919cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 2920cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(buf, sm->p2p_ip_addr, 3 * 4); 2921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 2922cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 2923cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2924cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 29256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 29266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 29276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter) 29286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 29296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (rx_replay_counter == NULL) 29306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 29316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 29326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(sm->rx_replay_counter, rx_replay_counter, 29336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_REPLAY_COUNTER_LEN); 29346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->rx_replay_counter_set = 1; 29356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "Updated key replay counter"); 29366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 29376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 29386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2939807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidtvoid wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm, 2940807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const u8 *ptk_kck, size_t ptk_kck_len, 2941807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const u8 *ptk_kek, size_t ptk_kek_len) 29426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 2943807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) { 2944807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len); 2945807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->ptk.kck_len = ptk_kck_len; 29466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "Updated PTK KCK"); 29476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 2948807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) { 2949807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len); 2950807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt sm->ptk.kek_len = ptk_kek_len; 29516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "Updated PTK KEK"); 29526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 29536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->ptk_set = 1; 29546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 2955