18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 21f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * IEEE 802.11 RSN / WPA Authenticator 3391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Copyright (c) 2004-2013, 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 "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/state_machine.h" 14cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#include "utils/bitfield.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/aes_wrap.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha256.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pmksa_cache_auth.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_i.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_ie.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct wpa_state_machine 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "WPA" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_ADDR sm->addr 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_sm_step(struct wpa_state_machine *sm); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_request_new_ptk(struct wpa_state_machine *sm); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u32 dot11RSNAConfigGroupUpdateCount = 4; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u32 dot11RSNAConfigPairwiseUpdateCount = 4; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u32 eapol_key_timeout_first = 100; /* ms */ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u32 eapol_key_timeout_subseq = 1000; /* ms */ 501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const u32 eapol_key_timeout_first_group = 500; /* ms */ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: make these configurable */ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const int dot11RSNAConfigPMKLifetime = 43200; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const int dot11RSNAConfigPMKReauthThreshold = 70; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const int dot11RSNAConfigSATimeout = 60; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic inline int wpa_auth_mic_failure_report( 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth, const u8 *addr) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.mic_failure_report) 62d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr); 63d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth, 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, wpa_eapol_variable var, 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int value) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.set_eapol) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth, 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, wpa_eapol_variable var) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.get_eapol == NULL) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth, 86391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *addr, 87391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *p2p_dev_addr, 88391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *prev_psk) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.get_psk == NULL) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 92391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr, 93391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev_psk); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth, 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, u8 *msk, size_t *len) 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.get_msk == NULL) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vlan_id, 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg alg, const u8 *addr, int idx, 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key, size_t key_len) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.set_key == NULL) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx, 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key, key_len); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, int idx, u8 *seq) 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.get_seqnum == NULL) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr, 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len, int encrypt) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.send_eapol == NULL) 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len, 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*cb)(struct wpa_state_machine *sm, void *ctx), 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.for_each_sta == NULL) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*cb)(struct wpa_authenticator *a, void *ctx), 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.for_each_auth == NULL) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr, 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt logger_level level, const char *txt) 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.logger == NULL) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr, 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt logger_level level, const char *fmt, ...) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *format; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int maxlen; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_list ap; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.logger == NULL) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxlen = os_strlen(fmt) + 100; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt format = os_malloc(maxlen); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!format) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_start(ap, fmt); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vsnprintf(format, maxlen, fmt, ap); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_end(ap); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, addr, level, format); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(format); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->cb.disconnect == NULL) 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_use_aes_cmac(struct wpa_state_machine *sm) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 1; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt)) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 1; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 214f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) 215f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ret = 1; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx) 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = eloop_ctx; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) { 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialization."); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd"); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "GMK", 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->group->GMK, WPA_GMK_LEN); 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa_gmk_rekey) { 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_rekey_gmk, wpa_auth, NULL); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = eloop_ctx; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK"); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (group = wpa_auth->group; group; group = group->next) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTKReKey = TRUE; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->changed = FALSE; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_sm_step(wpa_auth, group); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (group->changed); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa_group_rekey) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, wpa_rekey_gtk, wpa_auth, NULL); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx) 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = eloop_ctx; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm = timeout_ctx; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK"); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_request_new_ptk(sm); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_step(sm); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx) 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pmksa == ctx) 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = NULL; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = ctx; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth, 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 291a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 buf[ETH_ALEN + 8 + sizeof(unsigned long)]; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rkey[32]; 293a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned long ptr; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "GMK", group->GMK, WPA_GMK_LEN); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Counter = PRF-256(Random number, "Init Counter", 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Local MAC Address || Time) 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpa_auth->addr, ETH_ALEN); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_get_ntp_timestamp(buf + ETH_ALEN); 305a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ptr = (unsigned long) group; 306a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(buf + ETH_ALEN + 8, &ptr, sizeof(ptr)); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(rkey, sizeof(rkey)) < 0) 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf), 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->Counter, WPA_NONCE_LEN) < 0) 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "Key Counter", 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->Counter, WPA_NONCE_LEN); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth, 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int vlan_id, int delay_init) 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = os_zalloc(sizeof(struct wpa_group)); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTKAuthenticator = TRUE; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->vlan_id = vlan_id; 3314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_pool_ready() != 1) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for secure operations - update keys later when " 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the first station connects"); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set initial GMK/Counter value here. The actual values that will be 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used in negotiations will be set once the first station tries to 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * connect. This allows more time for collecting additional randomness 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * on embedded devices. 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) { 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialization."); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(group); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GInit = TRUE; 3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (delay_init) { 3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start " 3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "until Beacon frames have been configured"); 3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Initialization is completed in wpa_init_keys(). */ 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_group_sm_step(wpa_auth, group); 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group->GInit = FALSE; 3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_group_sm_step(wpa_auth, group); 3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_init - Initialize WPA authenticator 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Authenticator address 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Configuration for WPA authenticator 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb: Callback functions for WPA authenticator 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to WPA authenticator data or %NULL on failure 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_authenticator * wpa_init(const u8 *addr, 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_config *conf, 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_callbacks *cb) 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth = os_zalloc(sizeof(struct wpa_authenticator)); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_auth->addr, addr, ETH_ALEN); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&wpa_auth->cb, cb, sizeof(*cb)); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_gen_wpa_ie(wpa_auth)) { 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth->group = wpa_group_init(wpa_auth, 0, 1); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->group == NULL) { 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth->wpa_ie); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb, 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->pmksa == NULL) { 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "PMKSA cache initialization failed."); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth->wpa_ie); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init(); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->ft_pmk_cache == NULL) { 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FT PMK cache initialization failed."); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth->wpa_ie); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmksa_cache_auth_deinit(wpa_auth->pmksa); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa_gmk_rekey) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_rekey_gmk, wpa_auth, NULL); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.wpa_group_rekey) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_rekey_gtk, wpa_auth, NULL); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 430cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 431cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (WPA_GET_BE32(conf->ip_addr_start)) { 432cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int count = WPA_GET_BE32(conf->ip_addr_end) - 433cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPA_GET_BE32(conf->ip_addr_start) + 1; 434cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (count > 1000) 435cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt count = 1000; 436cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (count > 0) 437cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_auth->ip_pool = bitfield_alloc(count); 438cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 439cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 440cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_init_keys(struct wpa_authenticator *wpa_auth) 4461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_group *group = wpa_auth->group; 4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial " 4501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "keys"); 4511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_group_sm_step(wpa_auth, group); 4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group->GInit = FALSE; 4531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_group_sm_step(wpa_auth, group); 454fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 455fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 4561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 4571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_deinit - Deinitialize WPA authenticator 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_deinit(struct wpa_authenticator *wpa_auth) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group, *prev; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_auth->stsl_negotiations) 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmksa_cache_auth_deinit(wpa_auth->pmksa); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->ft_pmk_cache = NULL; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 483cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 484cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bitfield_free(wpa_auth->ip_pool); 485cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 486cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 487cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth->wpa_ie); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpa_auth->group; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (group) { 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = group; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = group->next; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_auth); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_reconfig - Update WPA authenticator configuration 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Configuration for WPA authenticator 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_reconfig(struct wpa_authenticator *wpa_auth, 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_config *conf) 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_gen_wpa_ie(wpa_auth)) { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reinitialize GTK to make sure it is suitable for the new 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration. 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpa_auth->group; 5244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GInit = TRUE; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_sm_step(wpa_auth, group); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GInit = FALSE; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_sm_step(wpa_auth, group); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_state_machine * 535391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtwpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr, 536391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *p2p_dev_addr) 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 540fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_auth->group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 541fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return NULL; 542fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(struct wpa_state_machine)); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->addr, addr, ETH_ALEN); 547391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) 548391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(sm->p2p_dev_addr, p2p_dev_addr, ETH_ALEN); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_auth = wpa_auth; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group = wpa_auth->group; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm) 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ft_completed) { 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT authentication already completed - do not " 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "start 4-way handshake"); 568717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt /* Go to PTKINITDONE state to allow GTK rekeying */ 569717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt sm->wpa_ptk_state = WPA_PTK_PTKINITDONE; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->started) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ReAuthenticationRequest = TRUE; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_sm_step(sm); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "start authentication"); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->started = 1; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Init = TRUE; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_step(sm) == 1) 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* should not really happen */ 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Init = FALSE; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->AuthenticationRequest = TRUE; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_sm_step(sm); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_sta_no_wpa(struct wpa_state_machine *sm) 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA/RSN was not used - clear WPA state. This is needed if the STA 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reassociates back to the same AP while the previous entry for the 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * STA has not yet been removed. */ 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_key_mgmt = 0; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_free_sta_sm(struct wpa_state_machine *sm) 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (WPA_GET_BE32(sm->ip_addr)) { 609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u32 start; 610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Free assigned IP " 611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "address %u.%u.%u.%u from " MACSTR, 612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->ip_addr[0], sm->ip_addr[1], 613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->ip_addr[2], sm->ip_addr[3], 614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(sm->addr)); 615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt start = WPA_GET_BE32(sm->wpa_auth->conf.ip_addr_start); 616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bitfield_clear(sm->wpa_auth->ip_pool, 617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPA_GET_BE32(sm->ip_addr) - start); 618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) { 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations--; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->assoc_resp_ftie); 626d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpabuf_free(sm->ft_pending_req_ies); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_eapol_key); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->wpa_ie); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_sta_deinit(struct wpa_state_machine *sm) 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) { 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "strict rekeying - force GTK rekey since STA " 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "is leaving"); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth, 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_1_of_4_timeout = 0; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_sm_call_step, sm, NULL); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->in_step_loop) { 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Must not free state machine while wpa_sm_step() is running. 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Freeing will be completed in the end of wpa_sm_step(). */ 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state " 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machine deinit for " MACSTR, MAC2STR(sm->addr)); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_deinit = 1; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_free_sta_sm(sm); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_request_new_ptk(struct wpa_state_machine *sm) 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTKRequest = TRUE; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK_valid = 0; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 673c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_replay_counter_valid(struct wpa_key_replay_counter *ctr, 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *replay_counter) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 678c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!ctr[i].valid) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 680c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (os_memcmp(replay_counter, ctr[i].counter, 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) == 0) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr, 689c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt const u8 *replay_counter) 690c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 691c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int i; 692c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 693c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ctr[i].valid && 694c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (replay_counter == NULL || 695c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(replay_counter, ctr[i].counter, 696c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) == 0)) 697c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt ctr[i].valid = FALSE; 698c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 699c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 700c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 701c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth, 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse *kde) 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data ie; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_mdie *mdie; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 || 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie.num_pmkid != 1 || ie.pmkid == NULL) { 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in " 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FT 4-way handshake message 2/4"); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant", 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sup_pmk_r1_name, PMKID_LEN); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!kde->mdie || !kde->ftie) { 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake " 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message 2/4", kde->mdie ? "FTIE" : "MDIE"); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = (struct rsn_mdie *) (kde->mdie + 2); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (kde->mdie[1] < sizeof(struct rsn_mdie) || 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpa_auth->conf.mobility_domain, mdie->mobility_domain, 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN) != 0) { 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: MDIE mismatch"); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->assoc_resp_ftie && 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (kde->ftie[1] != sm->assoc_resp_ftie[1] || 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(kde->ftie, sm->assoc_resp_ftie, 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + sm->assoc_resp_ftie[1]) != 0)) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: FTIE mismatch"); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 2/4", 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde->ftie, kde->ftie_len); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)AssocResp", 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_resp_ftie, 2 + sm->assoc_resp_ftie[1]); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 752d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int wpa_receive_error_report(struct wpa_authenticator *wpa_auth, 753d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_state_machine *sm, int group) 7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 7551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Supplicant reported a Michael MIC error */ 7561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 7571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "received EAPOL-Key Error Request " 7581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "(STA detected Michael MIC failure (group=%d))", 7591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group); 7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) { 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ignore Michael MIC failure report since " 7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "group cipher is not TKIP"); 7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) { 7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ignore Michael MIC failure report since " 7681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pairwise cipher is not TKIP"); 7691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 770d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0) 771d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; /* STA entry was removed */ 7721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sm->dot11RSNAStatsTKIPRemoteMICFailures++; 7731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++; 7741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 7771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Error report is not a request for a new key handshake, but since 7781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Authenticator may do it, let's change the keys now anyway. 7791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 7801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_request_new_ptk(sm); 781d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 7821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_receive(struct wpa_authenticator *wpa_auth, 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *data, size_t data_len) 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *key; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 key_info, key_data_length; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST, 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SMK_M1, SMK_M3, SMK_ERROR } msg; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *msgtxt; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_ie_parse kde; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ft; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eapol_key_ie; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eapol_key_ie_len; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < sizeof(*hdr) + sizeof(*key)) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) data; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct wpa_eapol_key *) (hdr + 1); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_GET_BE16(key->key_info); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_data_length = WPA_GET_BE16(key->key_data_length); 8101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR 8111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " key_info=0x%x type=%u key_data_length=%u", 8121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sm->addr), key_info, key->type, key_data_length); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) { 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - " 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key_data overflow (%d > %lu)", 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_data_length, 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (data_len - sizeof(*hdr) - 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(*key))); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2) { 823c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (key->type == EAPOL_KEY_TYPE_WPA) { 824c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 825c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Some deployed station implementations seem to send 826c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * msg 4/4 with incorrect type value in WPA2 mode. 827c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 828c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key " 829c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "with unexpected WPA type in RSN mode"); 830c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else if (key->type != EAPOL_KEY_TYPE_RSN) { 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected type %d in RSN mode", 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type != EAPOL_KEY_TYPE_WPA) { 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected type %d in WPA mode", 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Received Key Nonce", key->key_nonce, 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_NONCE_LEN); 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Received Replay Counter", 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->replay_counter, WPA_REPLAY_COUNTER_LEN); 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are set */ 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) == 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) { 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_ERROR) { 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = SMK_ERROR; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "SMK Error"; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = SMK_M1; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "SMK M1"; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) { 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = SMK_M3; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "SMK M3"; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_REQUEST) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = REQUEST; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "Request"; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = GROUP_2; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "2/2 Group"; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_data_length == 0) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = PAIRWISE_4; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "4/4 Pairwise"; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = PAIRWISE_2; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msgtxt = "2/4 Pairwise"; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: key_info type validation for PeerKey */ 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 || 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg == GROUP_2) { 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK; 88361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->pairwise == WPA_CIPHER_CCMP || 88461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->pairwise == WPA_CIPHER_GCMP) { 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_use_aes_cmac(sm) && 886f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN && 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) { 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LOGGER_WARNING, 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "advertised support for " 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AES-128-CMAC, but did not " 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "use it"); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_use_aes_cmac(sm) && 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LOGGER_WARNING, 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "did not use HMAC-SHA1-AES " 90161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "with CCMP/GCMP"); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_REQUEST) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->req_replay_counter_used && 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(key->replay_counter, sm->req_replay_counter, 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN) <= 0) { 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key request with " 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "replayed counter"); 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(key_info & WPA_KEY_INFO_REQUEST) && 919c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) { 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 921c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (msg == PAIRWISE_2 && 923c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_replay_counter_valid(sm->prev_key_replay, 924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt key->replay_counter) && 925c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 926c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0) 927c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt { 928c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 929c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Some supplicant implementations (e.g., Windows XP 930c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * WZC) update SNonce for each EAPOL-Key 2/4. This 931c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * breaks the workaround on accepting any of the 932c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pending requests, so allow the SNonce to be updated 933c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * even if we have already sent out EAPOL-Key 3/4. 934c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 935c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 936c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "Process SNonce update from STA " 937c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "based on retransmitted EAPOL-Key " 938c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "1/4"); 939c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->update_snonce = 1; 940c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_replay_counter_mark_invalid(sm->prev_key_replay, 941c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt key->replay_counter); 942c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt goto continue_processing; 943c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 944c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 945c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (msg == PAIRWISE_2 && 946c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_replay_counter_valid(sm->prev_key_replay, 947c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt key->replay_counter) && 948c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) { 949c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 950c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "ignore retransmitted EAPOL-Key %s - " 951c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "SNonce did not change", msgtxt); 952c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 953c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 954c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "received EAPOL-Key %s with " 955c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "unexpected replay counter", msgtxt); 956c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->key_replay[i].valid) 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "pending replay counter", 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->key_replay[i].counter, 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "received replay counter", 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->replay_counter, WPA_REPLAY_COUNTER_LEN); 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 969c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtcontinue_processing: 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (msg) { 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PAIRWISE_2: 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ptk_state != WPA_PTK_PTKSTART && 973c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING && 974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (!sm->update_snonce || 975c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) { 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key msg 2/4 in " 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid state (%d) - dropped", 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_state); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_add_randomness(key->key_nonce, WPA_NONCE_LEN); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->group->reject_4way_hs_for_entropy) { 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The system did not have enough entropy to generate 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * strong random numbers. Reject the first 4-way 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake(s) and collect some entropy based on the 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information from it. Once enough entropy is 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available, the next atempt will trigger GMK/Key 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Counter update and the station will be allowed to 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * continue. 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to " 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "collect more entropy for random number " 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "generation"); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mark_pool_ready(); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sta_disconnect(wpa_auth, sm->addr); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length, 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &kde) < 0) { 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key msg 2/4 with " 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid Key Data contents"); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (kde.rsn_ie) { 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie = kde.rsn_ie; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie_len = kde.rsn_ie_len; 1010f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (kde.osen) { 1011f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eapol_key_ie = kde.osen; 1012f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eapol_key_ie_len = kde.osen_len; 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie = kde.wpa_ie; 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie_len = kde.wpa_ie_len; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ft = sm->wpa == WPA_VERSION_WPA2 && 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_key_mgmt_ft(sm->wpa_key_mgmt); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ie == NULL || 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_compare_rsn_ie(ft, 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ie, sm->wpa_ie_len, 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie, eapol_key_ie_len)) { 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA IE from (Re)AssocReq did not " 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match with msg 2/4"); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ie) { 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq", 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ie, sm->wpa_ie_len); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_key_ie, eapol_key_ie_len); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* MLME-DEAUTHENTICATE.request */ 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sta_disconnect(wpa_auth, sm->addr); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sta_disconnect(wpa_auth, sm->addr); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 1042cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 1043cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (kde.ip_addr_req && kde.ip_addr_req[0] && 1044cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) { 1045cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int idx; 1046cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: IP address requested in " 1047cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "EAPOL-Key exchange"); 1048cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt idx = bitfield_get_first_zero(wpa_auth->ip_pool); 1049cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (idx >= 0) { 1050cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u32 start = WPA_GET_BE32(wpa_auth->conf. 1051cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ip_addr_start); 1052cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bitfield_set(wpa_auth->ip_pool, idx); 1053cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPA_PUT_BE32(sm->ip_addr, start + idx); 1054cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Assigned IP " 1055cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "address %u.%u.%u.%u to " MACSTR, 1056cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->ip_addr[0], sm->ip_addr[1], 1057cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt sm->ip_addr[2], sm->ip_addr[3], 1058cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(sm->addr)); 1059cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1060cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1061cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PAIRWISE_4: 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING || 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->PTK_valid) { 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key msg 4/4 in " 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid state (%d) - dropped", 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_state); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case GROUP_2: 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt || !sm->PTK_valid) { 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key msg 2/2 in " 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid state (%d) - dropped", 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_group_state); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_M1: 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_M3: 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_ERROR: 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_auth->conf.peerkey) { 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but " 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PeerKey use disabled - ignoring message"); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->PTK_valid) { 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key msg SMK in " 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid state - dropped"); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_PEERKEY */ 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_M1: 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_M3: 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SMK_ERROR: 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* STSL disabled - ignore SMK messages */ 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REQUEST: 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key frame (%s)", msgtxt); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_ACK) { 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received invalid EAPOL-Key: Key Ack set"); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(key_info & WPA_KEY_INFO_MIC)) { 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received invalid EAPOL-Key: Key MIC not set"); 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->MICVerified = FALSE; 1125c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sm->PTK_valid && !sm->update_snonce) { 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_verify_key_mic(&sm->PTK, data, data_len)) { 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key with invalid MIC"); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->MICVerified = TRUE; 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_1_of_4_timeout = 0; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_REQUEST) { 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->MICVerified) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->req_replay_counter_used = 1; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->req_replay_counter, key->replay_counter, 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key request with " 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid MIC"); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: should decrypt key data field if encryption was used; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * even though MAC address KDE is not normally encrypted, 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * supplicant is allowed to encrypt it. 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == SMK_ERROR) { 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_smk_error(wpa_auth, sm, key); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_ERROR) { 1159d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_receive_error_report( 1160d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_auth, sm, 1161d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0) 1162d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; /* STA entry was removed */ 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_info & WPA_KEY_INFO_KEY_TYPE) { 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key Request for new " 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "4-Way Handshake"); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_request_new_ptk(sm); 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg == SMK_M1) { 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_smk_m1(wpa_auth, sm, key); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_data_length > 0 && 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_parse_kde_ies((const u8 *) (key + 1), 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_data_length, &kde) == 0 && 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde.mac_addr) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received EAPOL-Key Request for GTK " 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "rekeying"); 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_rekey_gtk(wpa_auth, NULL); 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1184c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* Do not allow the same key replay counter to be reused. */ 1185c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_replay_counter_mark_invalid(sm->key_replay, 1186c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt key->replay_counter); 1187c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1188c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (msg == PAIRWISE_2) { 1189c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 1190c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Maintain a copy of the pending EAPOL-Key frames in 1191c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * case the EAPOL-Key frame was retransmitted. This is 1192c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * needed to allow EAPOL-Key msg 2/4 reply to another 1193c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pending msg 1/4 to update the SNonce to work around 1194c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * unexpected supplicant behavior. 1195c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 1196c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(sm->prev_key_replay, sm->key_replay, 1197c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sizeof(sm->key_replay)); 1198c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 1199c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(sm->prev_key_replay, 0, 1200c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sizeof(sm->prev_key_replay)); 1201c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1202c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1203c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 1204c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Make sure old valid counters are not accepted anymore and 1205c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * do not get copied again. 1206c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 1207c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_replay_counter_mark_invalid(sm->key_replay, NULL); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == SMK_M3) { 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_smk_m3(wpa_auth, sm, key); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */ 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_eapol_key); 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_eapol_key = os_malloc(data_len); 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_rx_eapol_key == NULL) 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_rx_eapol_key, data, data_len); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_eapol_key_len = data_len; 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE); 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyReceived = TRUE; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_step(sm); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr, 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gnonce, u8 *gtk, size_t gtk_len) 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 data[ETH_ALEN + WPA_NONCE_LEN + 8 + 16]; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* GTK = PRF-X(GMK, "Group key expansion", 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AA || GNonce || Time || random data) 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The example described in the IEEE 802.11 standard uses only AA and 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GNonce as inputs here. Add some more entropy since this derivation 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is done only at the Authenticator and as such, does not need to be 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * exactly same. 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data, addr, ETH_ALEN); 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN); 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = data + ETH_ALEN + WPA_NONCE_LEN; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_get_ntp_timestamp(pos); 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 8; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(pos, 16) < 0) 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sha256_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len); 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_IEEE80211W */ 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha1_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len) 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx) 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = eloop_ctx; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm = timeout_ctx; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_1_of_4_timeout = 0; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout"); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutEvt = TRUE; 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_step(sm); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid __wpa_send_eapol(struct wpa_authenticator *wpa_auth, 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, int key_info, 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key_rsc, const u8 *nonce, 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *kde, size_t kde_len, 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int keyidx, int encr, int force_version) 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *key; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int alg; 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_data_len, pad_len = 0; 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, *pos; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int version, pairwise; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_version) 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = force_version; 1298f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) 1299f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt version = WPA_KEY_INFO_TYPE_AKM_DEFINED; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_use_aes_cmac(sm)) 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = WPA_KEY_INFO_TYPE_AES_128_CMAC; 130261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (sm->pairwise != WPA_CIPHER_TKIP) 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 130751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d " 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d " 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encr=%d)", 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version, 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0, 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_MIC) ? 1 : 0, 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_ACK) ? 1 : 0, 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0, 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise, (unsigned long) kde_len, keyidx, encr); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_data_len = kde_len; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1322f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) { 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pad_len = key_data_len % 8; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pad_len) 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pad_len = 8 - pad_len; 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_data_len += pad_len + 8; 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += key_data_len; 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = os_zalloc(len); 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr == NULL) 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version = wpa_auth->conf.eapol_version; 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = host_to_be16(len - sizeof(*hdr)); 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct wpa_eapol_key *) (hdr + 1); 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type = sm->wpa == WPA_VERSION_WPA2 ? 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= version; 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (encr && sm->wpa == WPA_VERSION_WPA2) 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= WPA_KEY_INFO_ENCR_KEY_DATA; 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa != WPA_VERSION_WPA2) 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(key->key_info, key_info); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group; 13504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt WPA_PUT_BE16(key->key_length, wpa_cipher_key_len(alg)); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_SMK_MESSAGE) 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(key->key_length, 0); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: STSL: what to use as key_replay_counter? */ 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = RSNA_MAX_EAPOL_RETRIES - 1; i > 0; i--) { 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->key_replay[i].valid = sm->key_replay[i - 1].valid; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->key_replay[i].counter, 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->key_replay[i - 1].counter, 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(sm->key_replay[0].counter, WPA_REPLAY_COUNTER_LEN); 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->replay_counter, sm->key_replay[0].counter, 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_REPLAY_COUNTER_LEN); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->key_replay[0].valid = TRUE; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nonce) 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_rsc) 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN); 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (kde && !encr) { 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key + 1, kde, kde_len); 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(key->key_data_length, kde_len); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (encr && kde) { 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(key_data_len); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hdr); 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, kde, kde_len); 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += kde_len; 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pad_len) 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0xdd; 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data", 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, key_data_len); 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1391f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version == WPA_KEY_INFO_TYPE_AES_128_CMAC) { 13939ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (aes_wrap(sm->PTK.kek, 16, 13949ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt (key_data_len - 8) / 8, buf, 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) (key + 1))) { 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hdr); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(key->key_data_length, key_data_len); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ek[32]; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_iv, 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->Counter + WPA_NONCE_LEN - 16, 16); 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(sm->group->Counter, WPA_NONCE_LEN); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ek, key->key_iv, 16); 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ek + 16, sm->PTK.kek, 16); 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key + 1, buf, key_data_len); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len); 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(key->key_data_length, key_data_len); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_info & WPA_KEY_INFO_MIC) { 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->PTK_valid) { 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PTK not valid when sending EAPOL-Key " 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame"); 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hdr); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len, 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_mic); 142551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 142651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (!pairwise && 14277832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 && 142851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt drand48() < 142951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpa_auth->conf.corrupt_gtk_rekey_mic_probability) { 143051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 143151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt "Corrupting group EAPOL-Key Key MIC"); 143251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt key->key_mic[0]++; 143351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt } 143451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len, 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pairwise_set); 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hdr); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_send_eapol(struct wpa_authenticator *wpa_auth, 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, int key_info, 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key_rsc, const u8 *nonce, 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *kde, size_t kde_len, 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int keyidx, int encr) 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timeout_ms; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ctr; 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len, 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx, encr, 0); 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctr == 1 && wpa_auth->conf.tx_status) 14631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout_ms = pairwise ? eapol_key_timeout_first : 14641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eapol_key_timeout_first_group; 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout_ms = eapol_key_timeout_subseq; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC)) 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_1_of_4_timeout = 1; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry " 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "counter %d)", timeout_ms, ctr); 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000, 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_send_eapol_timeout, wpa_auth, sm); 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len) 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_eapol_key *key; 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 key_info; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mic[16]; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < sizeof(*hdr) + sizeof(*key)) 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) data; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct wpa_eapol_key *) (hdr + 1); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_info = WPA_GET_BE16(key->key_info); 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mic, key->key_mic, 16); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(key->key_mic, 0, 16); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK, 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, data_len, key->key_mic) || 1494c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(mic, key->key_mic, 16) != 0) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_mic, mic, 16); 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_remove_ptk(struct wpa_state_machine *sm) 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK_valid = FALSE; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL, 0); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pairwise_set = FALSE; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event) 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int remove_ptk = 1; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "event %d notification", event); 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (event) { 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_AUTH: 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_ASSOC: 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_DEAUTH: 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_DISASSOC: 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->DeauthenticationRequest = TRUE; 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_REAUTH: 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_REAUTH_EAPOL: 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->started) { 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using WPS, we may end up here if the STA 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * manages to re-associate without the previous STA 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entry getting removed. Consequently, we need to make 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sure that the WPA state machines gets initialized 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * properly at this point. 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA state machine had not been " 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "started - initialize now"); 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->started = 1; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Init = TRUE; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_step(sm) == 1) 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* should not really happen */ 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Init = FALSE; 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->AuthenticationRequest = TRUE; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) { 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reauthentication cancels the pending group key 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * update for this STA. 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations--; 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PtkGroupInit = TRUE; 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ReAuthenticationRequest = TRUE; 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_ASSOC_FT: 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration " 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "after association"); 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_install_ptk(sm); 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Using FT protocol, not WPA auth state machine */ 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ft_completed = 1; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_IEEE80211R */ 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ft_completed = 0; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->mgmt_frame_prot && event == WPA_AUTH) 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt remove_ptk = 0; 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (remove_ptk) { 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK_valid = FALSE; 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (event != WPA_REAUTH_EAPOL) 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_remove_ptk(sm); 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_sm_step(sm); 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, INITIALIZE) 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->Init) { 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Init flag is not cleared here, so avoid busy 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * loop by claiming nothing changed. */ 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keycount = 0; 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations--; 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA) 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PInitAKeys = FALSE; 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Local AA > Remote AA)) */) { 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Pair = TRUE; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0); 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_remove_ptk(sm); 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutCtr = 0; 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EAPOL_authorized, 0); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, DISCONNECT) 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Disconnect = FALSE; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sta_disconnect(sm->wpa_auth, sm->addr); 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, DISCONNECTED) 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk); 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->DeauthenticationRequest = FALSE; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, AUTHENTICATION) 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK_valid = FALSE; 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto, 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1); 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1); 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->AuthenticationRequest = FALSE; 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1652c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth, 1653c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_group *group) 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1655c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (group->first_sta_seen) 1656c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return; 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * System has run bit further than at the time hostapd was started 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * potentially very early during boot up. This provides better chances 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of collecting more randomness on embedded systems. Re-initialize the 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GMK and Counter here to improve their strength if there was not 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * enough entropy available immediately after system startup. 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first " 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "station"); 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_pool_ready() != 1) { 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to proceed - reject first 4-way handshake"); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->reject_4way_hs_for_entropy = TRUE; 1670c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 1671c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt group->first_sta_seen = TRUE; 1672c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt group->reject_4way_hs_for_entropy = FALSE; 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1674c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_init_gmk_and_counter(wpa_auth, group); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_gtk_update(wpa_auth, group); 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_config_group_keys(wpa_auth, group); 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, AUTHENTICATION2) 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk); 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1685c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_group_ensure_init(sm->wpa_auth, sm->group); 1686444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt sm->ReAuthenticationRequest = FALSE; 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 168904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Definition of ANonce selection in IEEE Std 802.11i-2004 is somewhat 169004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * ambiguous. The Authenticator state machine uses a counter that is 169104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * incremented by one for each 4-way handshake. However, the security 169204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * analysis of 4-way handshake points out that unpredictable nonces 169304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * help in preventing precomputation attacks. Instead of the state 169404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * machine definition, use an unpredictable nonce value here to provide 169504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * stronger protection against potential precomputation attacks. 169604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 169704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 169804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "WPA: Failed to get random data for " 169904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "ANonce."); 1700444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt sm->Disconnect = TRUE; 170104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 170204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_NONCE_LEN); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11i does not clear TimeoutCtr here, but this is more 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * logical place than INITIALIZE since AUTHENTICATION2 can be 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-entered on ReAuthenticationRequest without going through 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * INITIALIZE. */ 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutCtr = 0; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, INITPMK) 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 msk[2 * PMK_LEN]; 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 2 * PMK_LEN; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk); 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = 0; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pmksa) { 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache"); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->PMK, sm->pmksa->pmk, PMK_LEN); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) { 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine " 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", (unsigned long) len); 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->PMK, msk, PMK_LEN); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 2 * PMK_LEN) { 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->xxkey, msk + PMK_LEN, PMK_LEN); 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = PMK_LEN; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Could not get PMK"); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->req_replay_counter_used = 0; 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11i does not set keyRun to FALSE, but not doing this 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will break reauthentication since EAPOL state machines may not be 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * get into AUTHENTICATING state that clears keyRun before WPA state 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine enters AUTHENTICATION2 state and goes immediately to INITPMK 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state and takes PMK from the previously used AAA Key. This will 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eventually fail in 4-Way Handshake because Supplicant uses PMK 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * derived from the new AAA Key. Setting keyRun = FALSE here seems to 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be good workaround for this issue. */ 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0); 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, INITPSK) 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *psk; 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk); 1756391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, NULL); 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (psk) { 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->PMK, psk, PMK_LEN); 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->xxkey, psk, PMK_LEN); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->xxkey_len = PMK_LEN; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->req_replay_counter_used = 0; 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, PTKSTART) 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL; 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pmkid_len = 0; 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk); 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTKRequest = FALSE; 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutEvt = FALSE; 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutCtr++; 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No point in sending the EAPOL-Key - we will disconnect 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately following this. */ 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "sending 1/4 msg of 4-Way Handshake"); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Could add PMKID even with WPA2-PSK, but only if there is only 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * one possible PSK for this STA. 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2 && 1791f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 1792f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) { 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = buf; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid[0] = WLAN_EID_VENDOR_SPECIFIC; 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN; 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pmksa) 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa->pmkid, PMKID_LEN); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Calculate PMKID since no PMKSA cache entry was 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available with pre-calculated PMKID. 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr, 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->addr, &pmkid[2 + RSN_SELECTOR_LEN], 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_send_eapol(sm->wpa_auth, sm, 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL, 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ANonce, pmkid, pmkid_len, 0, 0); 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk, 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ptk *ptk) 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18209866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt size_t ptk_len = wpa_cipher_key_len(sm->pairwise) + 32; 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len); 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion", 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce, 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) ptk, ptk_len, 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, PTKCALCNEGOTIATING) 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ptk PTK; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok = 0; 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmk = NULL; 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyReceived = FALSE; 1843c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->update_snonce = FALSE; 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA with IEEE 802.1X: use the derived PMK from EAP 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA-PSK: iterate through possible PSKs and select the one matching 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the packet */ 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1850391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, 1851391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sm->p2p_dev_addr, pmk); 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmk == NULL) 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk = sm->PMK; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_derive_ptk(sm, pmk, &PTK); 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key, 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_eapol_key_len) == 0) { 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid MIC in msg 2/4 of 4-Way Handshake"); 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Verify that PMKR1Name from EAPOL-Key message 2/4 matches 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with the value we derived. 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1881c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name, 1882c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt WPA_PMK_NAME_LEN) != 0) { 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PMKR1Name mismatch in FT 4-way " 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake"); 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from " 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Supplicant", 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN); 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmk_r1_name, WPA_PMK_NAME_LEN); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pending_1_of_4_timeout = 0; 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PSK may have changed from the previous choice, so update 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine data based on whatever PSK was selected here. 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->PMK, pmk, PMK_LEN); 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->MICVerified = TRUE; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK_valid = TRUE; 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, PTKCALCNEGOTIATING2) 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutCtr = 0; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->mgmt_frame_prot) { 1925b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len; 1926b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 1927b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN + len; 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_igtk_kde igtk; 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *gsm = sm->group; 193868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 rsc[WPA_KEY_RSC_LEN]; 1939b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->mgmt_frame_prot) 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt igtk.keyid[0] = gsm->GN_igtk; 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt igtk.keyid[1] = 0; 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE || 194768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, rsc) < 0) 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(igtk.pn, 0, sizeof(igtk.pn)); 194968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt else 195068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(igtk.pn, rsc, sizeof(igtk.pn)); 1951b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len); 195261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->wpa_auth->conf.disable_gtk) { 195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Provide unique random IGTK to each STA to prevent use of 195561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * IGTK in the BSS. 195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 1957b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (random_get_bytes(igtk.igtk, len) < 0) 195861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos; 195961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, 1961b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt (const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len, 1962b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt NULL, 0); 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_IEEE80211W */ 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, PTKINITNEGOTIATING) 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 198561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32]; 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t gtk_len, kde_len; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *gsm = sm->group; 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *wpa_ie; 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wpa_ie_len, secure, keyidx, encr = 0; 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutEvt = FALSE; 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutCtr++; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No point in sending the EAPOL-Key - we will disconnect 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately following this. */ 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE], 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GTK[GN], IGTK, [FTIE], [TIE * 2]) 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(rsc, 0, WPA_KEY_RSC_LEN); 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */ 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = sm->wpa_auth->wpa_ie; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = sm->wpa_auth->wpa_ie_len; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA && 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) && 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) { 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA-only STA, remove RSN IE */ 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = wpa_ie + wpa_ie[1] + 2; 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = wpa_ie[1] + 2; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "sending 3/4 msg of 4-Way Handshake"); 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2) { 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA2 send GTK in the 4-way handshake */ 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt secure = 1; 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk = gsm->GTK[gsm->GN - 1]; 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk_len = gsm->GTK_len; 202361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->wpa_auth->conf.disable_gtk) { 202461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 202561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Provide unique random GTK to each STA to prevent use 202661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * of GTK in the BSS. 202761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 202861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (random_get_bytes(dummy_gtk, gtk_len) < 0) 202961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 203061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gtk = dummy_gtk; 203161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx = gsm->GN; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rsc = rsc; 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = 1; 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA does not include GTK in msg 3/4 */ 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt secure = 0; 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk = NULL; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk_len = 0; 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx = 0; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rsc = NULL; 20421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sm->rx_eapol_key_secure) { 20431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 20441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * It looks like Windows 7 supplicant tries to use 20451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Secure bit in msg 2/4 after having reported Michael 20461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * MIC failure and it then rejects the 4-way handshake 20471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * if msg 3/4 does not set Secure bit. Work around this 20481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * by setting the Secure bit here even in the case of 20491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * WPA if the supplicant used it first. 20501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 20511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "STA used Secure bit in WPA msg 2/4 - " 20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "set Secure for 3/4 as workaround"); 20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt secure = 1; 20551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde_len = wpa_ie_len + ieee80211w_kde_len(sm); 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gtk) 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */ 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde_len += 300; /* FTIE + 2 * TIE */ 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2067cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 2068cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (WPA_GET_BE32(sm->ip_addr) > 0) 2069cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4; 2070cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde = os_malloc(kde_len); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (kde == NULL) 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = kde; 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, wpa_ie, wpa_ie_len); 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_ie_len; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name); 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FT: Failed to insert " 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PMKR1Name into RSN IE in EAPOL-Key data"); 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(kde); 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gtk) { 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hdr[2]; 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr[0] = keyidx & 0x03; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr[1] = 0; 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtk, gtk_len); 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ieee80211w_kde_add(sm, pos); 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_auth_config *conf; 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf = &sm->wpa_auth->conf; 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_write_ftie(conf, conf->r0_key_holder, 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->r0_key_holder_len, 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL, pos, kde + kde_len - pos, 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "into EAPOL-Key Key Data"); 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(kde); 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TIE[ReassociationDeadline] (TU) */ 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 5; 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE32(pos, conf->reassociation_deadline); 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TIE[KeyLifetime] (seconds) */ 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 5; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_TIMEOUT_KEY_LIFETIME; 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60); 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2132cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 2133cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (WPA_GET_BE32(sm->ip_addr) > 0) { 2134cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 addr[3 * 4]; 2135cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(addr, sm->ip_addr, 4); 2136cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4); 2137cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4); 2138cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC, 2139cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt addr, sizeof(addr), NULL, 0); 2140cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 2141cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_send_eapol(sm->wpa_auth, sm, 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC | 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_KEY_TYPE, 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rsc, sm->ANonce, kde, pos - kde, keyidx, encr); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(kde); 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK, PTKINITDONE) 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk); 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyReceived = FALSE; 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->Pair) { 21574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise); 21584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int klen = wpa_cipher_key_len(sm->pairwise); 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PTK.tk1, klen)) { 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sta_disconnect(sm->wpa_auth, sm->addr); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pairwise_set = TRUE; 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_auth->conf.wpa_ptk_rekey) { 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sm->wpa_auth->conf. 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ptk_rekey, 0, wpa_rekey_ptk, 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_auth, sm); 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EAPOL_authorized, 1); 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (0 /* IBSS == TRUE */) { 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keycount++; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->keycount == 2) { 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EAPOL_portValid, 1); 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0); 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1); 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA) 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PInitAKeys = TRUE; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->has_GTK = TRUE; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pairwise key handshake completed (%s)", 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr); 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(WPA_PTK) 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_authenticator *wpa_auth = sm->wpa_auth; 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->Init) 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, INITIALIZE); 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->Disconnect 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* || FIX: dot11RSNAConfigSALifetime timeout */) { 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WPA_PTK: sm->Disconnect"); 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECT); 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->DeauthenticationRequest) 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECTED); 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->AuthenticationRequest) 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, AUTHENTICATION); 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->ReAuthenticationRequest) 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, AUTHENTICATION2); 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->PTKRequest) 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKSTART); 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else switch (sm->wpa_ptk_state) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_INITIALIZE: 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_DISCONNECT: 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECTED); 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_DISCONNECTED: 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, INITIALIZE); 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_AUTHENTICATION: 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, AUTHENTICATION2); 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_AUTHENTICATION2: 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EAPOL_keyRun) > 0) 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, INITPMK); 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: && 802.1X::keyRun */) 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, INITPSK); 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_INITPMK: 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EAPOL_keyAvailable) > 0) 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKSTART); 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNA4WayHandshakeFailures++; 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "INITPMK - keyAvailable = false"); 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECT); 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_INITPSK: 2259391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, 2260391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt NULL)) 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKSTART); 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "no PSK configured for the STA"); 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNA4WayHandshakeFailures++; 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECT); 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_PTKSTART: 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyPairwise) 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->TimeoutCtr > 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) dot11RSNAConfigPairwiseUpdateCount) { 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNA4WayHandshakeFailures++; 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PTKSTART: Retry limit %d reached", 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigPairwiseUpdateCount); 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECT); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sm->TimeoutEvt) 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKSTART); 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_PTKCALCNEGOTIATING: 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->MICVerified) 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2); 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyPairwise) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->TimeoutEvt) 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKSTART); 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_PTKCALCNEGOTIATING2: 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_PTKINITNEGOTIATING: 2296c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sm->update_snonce) 2297c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2298c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2299c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->EAPOLKeyPairwise && sm->MICVerified) 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKINITDONE); 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->TimeoutCtr > 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) dot11RSNAConfigPairwiseUpdateCount) { 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNA4WayHandshakeFailures++; 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PTKINITNEGOTIATING: Retry limit %d " 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reached", 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigPairwiseUpdateCount); 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, DISCONNECT); 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sm->TimeoutEvt) 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_PTKINITDONE: 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK_GROUP, IDLE) 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group); 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->Init) { 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Init flag is not cleared here, so avoid busy 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * loop by claiming nothing changed. */ 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GTimeoutCtr = 0; 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING) 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rsc[WPA_KEY_RSC_LEN]; 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *gsm = sm->group; 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *kde, *pos, hdr[2]; 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t kde_len; 233661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *gtk, dummy_gtk[32]; 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group); 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GTimeoutCtr++; 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) { 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No point in sending the EAPOL-Key - we will disconnect 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately following this. */ 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA) 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PInitAKeys = FALSE; 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->TimeoutEvt = FALSE; 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */ 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(rsc, 0, WPA_KEY_RSC_LEN); 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE) 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "sending 1/2 msg of Group Key Handshake"); 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 235761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gtk = gsm->GTK[gsm->GN - 1]; 235861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->wpa_auth->conf.disable_gtk) { 235961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 236061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Provide unique random GTK to each STA to prevent use 236161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * of GTK in the BSS. 236261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 236361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0) 236461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 236561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gtk = dummy_gtk; 236661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2) { 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len + 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee80211w_kde_len(sm); 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kde = os_malloc(kde_len); 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (kde == NULL) 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = kde; 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr[0] = gsm->GN & 0x03; 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr[1] = 0; 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 237861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gtk, gsm->GTK_len); 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ieee80211w_kde_add(sm, pos); 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 238161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt kde = gtk; 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = kde + gsm->GTK_len; 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_send_eapol(sm->wpa_auth, sm, 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC | 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_INFO_ACK | 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0), 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsc, gsm->GNonce, kde, pos - kde, gsm->GN, 1); 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa == WPA_VERSION_WPA2) 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(kde); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED) 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group); 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAPOLKeyReceived = FALSE; 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations--; 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GTimeoutCtr = 0; 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */ 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group key handshake completed (%s)", 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->has_GTK = TRUE; 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(WPA_PTK_GROUP, KEYERROR) 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group); 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations--; 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->Disconnect = TRUE; 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(WPA_PTK_GROUP) 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->Init || sm->PtkGroupInit) { 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, IDLE); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->PtkGroupInit = FALSE; 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else switch (sm->wpa_ptk_group_state) { 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_GROUP_IDLE: 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys || 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys)) 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_GROUP_REKEYNEGOTIATING: 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->EAPOLKeyPairwise && sm->MICVerified) 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED); 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->GTimeoutCtr > 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) dot11RSNAConfigGroupUpdateCount) 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, KEYERROR); 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->TimeoutEvt) 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_GROUP_KEYERROR: 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, IDLE); 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPA_PTK_GROUP_REKEYESTABLISHED: 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(WPA_PTK_GROUP, IDLE); 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(group->Counter, WPA_NONCE_LEN); 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_gmk_to_gtk(group->GMK, "Group key expansion", 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->addr, group->GNonce, 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTK[group->GN - 1], group->GTK_len) < 0) 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "GTK", 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTK[group->GN - 1], group->GTK_len); 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2468b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len; 2469b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(group->Counter, WPA_NONCE_LEN); 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion", 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->addr, group->GNonce, 2474b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt group->IGTK[group->GN_igtk - 4], len) < 0) 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "IGTK", 2477b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt group->IGTK[group->GN_igtk - 4], len); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth, 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GTK_INIT (VLAN-ID %d)", group->vlan_id); 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->changed = FALSE; /* GInit is not cleared here; avoid loop */ 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->wpa_group_state = WPA_GROUP_GTK_INIT; 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* GTK[0..N] = 0 */ 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(group->GTK, 0, sizeof(group->GTK)); 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN = 1; 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM = 2; 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN_igtk = 4; 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM_igtk = 5; 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* GTK[GN] = CalcGTK() */ 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_gtk_update(wpa_auth, group); 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx) 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 250861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ctx != NULL && ctx != sm->group) 250961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 251061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) { 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Not in PTKINITDONE; skip Group Key update"); 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = FALSE; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->GUpdateStationKeys) { 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, so add a debug log entry. 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Since we clear the GKeyDoneStations before the loop, the 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * station needs to be counted here anyway. 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GUpdateStationKeys was already set when " 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "marking station for GTK rekeying"); 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */ 252961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->is_wnmsleep) 253061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 253161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group->GKeyDoneStations++; 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->GUpdateStationKeys = TRUE; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_step(sm); 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2540a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM 2541a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/* update GTK when exiting WNM-Sleep Mode */ 254261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm) 254361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2544fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm == NULL || sm->is_wnmsleep) 254561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 254661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 254761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_group_update_sta(sm, NULL); 254861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 254961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 255061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 255161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag) 255261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2553fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm) 2554fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->is_wnmsleep = !!flag; 255561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 255661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 255761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 255861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos) 255961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 256061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_group *gsm = sm->group; 2561a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 *start = pos; 256261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 256361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 2564a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * GTK subelement: 256561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] | 2566a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Key[5..32] 256761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 2568a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt *pos++ = WNM_SLEEP_SUBELEM_GTK; 2569a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt *pos++ = 11 + gsm->GTK_len; 257061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Key ID in B0-B1 of Key Info */ 2571a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt WPA_PUT_LE16(pos, gsm->GN & 0x03); 2572a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += 2; 2573a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt *pos++ = gsm->GTK_len; 2574a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0) 257561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 2576a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += 8; 2577a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2578a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += gsm->GTK_len; 257961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2580a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit", 2581a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt gsm->GN); 2582a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit", 258361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gsm->GTK[gsm->GN - 1], gsm->GTK_len); 258461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2585a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return pos - start; 258661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 258761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 258861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 258961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211W 259061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos) 259161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 259261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_group *gsm = sm->group; 2593a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 *start = pos; 2594b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 259561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2596a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 2597a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * IGTK subelement: 2598a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16] 2599a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 2600a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt *pos++ = WNM_SLEEP_SUBELEM_IGTK; 2601b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt *pos++ = 2 + 6 + len; 2602a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt WPA_PUT_LE16(pos, gsm->GN_igtk); 2603a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += 2; 2604a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0) 260561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 2606a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += 6; 260761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2608b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], len); 2609b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos += len; 261061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2611a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit", 2612a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt gsm->GN_igtk); 2613a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit", 2614b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt gsm->IGTK[gsm->GN_igtk - 4], len); 261561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2616a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return pos - start; 261761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 261861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2619a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */ 262061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 262161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tmp; 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SETKEYS (VLAN-ID %d)", group->vlan_id); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->changed = TRUE; 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->wpa_group_state = WPA_GROUP_SETKEYS; 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTKReKey = FALSE; 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = group->GM; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM = group->GN; 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN = tmp; 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = group->GM_igtk; 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM_igtk = group->GN_igtk; 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN_igtk = tmp; 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "GKeyDoneStations = GNoStations" is done in more robust way by 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * counting the STAs that are marked with GUpdateStationKeys instead of 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * including all STAs that could be in not-yet-completed state. */ 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_gtk_update(wpa_auth, group); 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group->GKeyDoneStations) { 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected " 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GKeyDoneStations=%d when starting new GTK rekey", 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GKeyDoneStations); 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GKeyDoneStations = 0; 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 265161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, group); 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d", 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GKeyDoneStations); 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_set_key(wpa_auth, group->vlan_id, 26634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_cipher_to_alg(wpa_auth->conf.wpa_group), 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt broadcast_ether_addr, group->GN, 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTK[group->GN - 1], group->GTK_len) < 0) 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2669b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2670b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt enum wpa_alg alg; 2671b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t len; 2672b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 2673b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher); 2674b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 2675b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 2676b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (ret == 0 && 2677b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_auth_set_key(wpa_auth, group->vlan_id, alg, 2678b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt broadcast_ether_addr, group->GN_igtk, 2679b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt group->IGTK[group->GN_igtk - 4], len) < 0) 2680b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt ret = -1; 2681b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx) 2689fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2690fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm->group == ctx) { 2691fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR 2692fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt " for discconnection due to fatal failure", 2693fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MAC2STR(sm->addr)); 2694fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->Disconnect = TRUE; 2695fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2696fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2697fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 2698fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2699fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2700fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2701fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth, 2702fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_group *group) 2703fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2704fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE"); 2705fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt group->changed = TRUE; 2706fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt group->wpa_group_state = WPA_GROUP_FATAL_FAILURE; 2707fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group); 2708fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2709fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2710fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth, 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SETKEYSDONE (VLAN-ID %d)", group->vlan_id); 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->changed = TRUE; 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->wpa_group_state = WPA_GROUP_SETKEYSDONE; 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2719fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_group_config_group_keys(wpa_auth, group) < 0) { 2720fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_group_fatal_failure(wpa_auth, group); 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2722fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group) 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group->GInit) { 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_gtk_init(wpa_auth, group); 2733fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) { 2734fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* Do not allow group operations */ 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT && 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTKAuthenticator) { 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_setkeysdone(wpa_auth, group); 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE && 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GTKReKey) { 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_setkeys(wpa_auth, group); 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) { 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group->GKeyDoneStations == 0) 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_setkeysdone(wpa_auth, group); 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (group->GTKReKey) 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_setkeys(wpa_auth, group); 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_sm_step(struct wpa_state_machine *sm) 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->in_step_loop) { 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This should not happen, but if it does, make sure we do not 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * end up freeing the state machine too early by exiting the 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * recursive call. */ 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively"); 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->in_step_loop = 1; 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pending_deinit) 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_auth->group->changed = FALSE; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(WPA_PTK); 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pending_deinit) 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(WPA_PTK_GROUP); 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pending_deinit) 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_group_sm_step(sm->wpa_auth, sm->group); 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (sm->changed || sm->wpa_auth->group->changed); 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->in_step_loop = 0; 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pending_deinit) { 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state " 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machine deinit for " MACSTR, MAC2STR(sm->addr)); 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_free_sta_sm(sm); 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx) 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm = eloop_ctx; 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_step(sm); 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_sm_notify(struct wpa_state_machine *sm) 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL); 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_gtk_rekey(struct wpa_authenticator *wpa_auth) 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tmp, i; 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpa_auth->group; 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 2; i++) { 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = group->GM; 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM = group->GN; 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN = tmp; 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = group->GM_igtk; 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GM_igtk = group->GN_igtk; 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->GN_igtk = tmp; 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_gtk_update(wpa_auth, group); 28261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_group_config_group_keys(wpa_auth, group); 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_bool_txt(int bool) 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return bool ? "TRUE" : "FALSE"; 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RSN_SUITE "%02x-%02x-%02x-%d" 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RSN_SUITE_ARG(s) \ 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen) 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len = 0, ret; 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char pmkid_txt[PMKID_LEN * 2 + 1]; 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_PREAUTH 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const int preauth = 1; 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_RSN_PREAUTH */ 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const int preauth = 0; 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_PREAUTH */ 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAOptionImplemented=TRUE\n" 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPreauthenticationImplemented=%s\n" 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAEnabled=%s\n" 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPreauthenticationEnabled=%s\n", 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bool_txt(preauth), 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN), 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bool_txt(wpa_auth->conf.rsn_preauth)); 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN); 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf( 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + len, buflen - len, 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigVersion=%u\n" 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPairwiseKeysSupported=9999\n" 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: dot11RSNAConfigGroupCipher */ 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: dot11RSNAConfigGroupRekeyMethod */ 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: dot11RSNAConfigGroupRekeyTime */ 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: dot11RSNAConfigGroupRekeyPackets */ 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigGroupRekeyStrict=%u\n" 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigGroupUpdateCount=%u\n" 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPairwiseUpdateCount=%u\n" 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigGroupCipherSize=%u\n" 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPMKLifetime=%u\n" 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigPMKReauthThreshold=%u\n" 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n" 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigSATimeout=%u\n" 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPMKIDUsed=%s\n" 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNATKIPCounterMeasuresInvoked=%u\n" 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNA4WayHandshakeFailures=%u\n" 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n", 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_VERSION, 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !!wpa_auth->conf.wpa_strict_rekey, 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigGroupUpdateCount, 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigPairwiseUpdateCount, 28994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8, 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigPMKLifetime, 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigPMKReauthThreshold, 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11RSNAConfigSATimeout, 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected), 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected), 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected), 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid_txt, 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested), 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested), 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested), 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNATKIPCounterMeasuresInvoked, 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNA4WayHandshakeFailures); 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAConfigPairwiseCiphersTable */ 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAConfigAuthenticationSuitesTable */ 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Private MIB */ 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n", 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->group->wpa_group_state); 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len = 0, ret; 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 pairwise = 0; 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */ 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dot11RSNAStatsEntry */ 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pairwise = wpa_cipher_to_suite(sm->wpa == WPA_VERSION_WPA2 ? 29434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt WPA_PROTO_RSN : WPA_PROTO_WPA, 29444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->pairwise); 29454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (pairwise == 0) 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf( 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + len, buflen - len, 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAStatsIndex */ 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAStatsSTAAddress=" MACSTR "\n" 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAStatsVersion=1\n" 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n" 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAStatsTKIPICVErrors */ 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAStatsTKIPLocalMICFailures=%u\n" 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot11RSNAStatsTKIPRemoteMICFailures=%u\n" 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAStatsCCMPReplays */ 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAStatsCCMPDecryptErrors */ 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot11RSNAStatsTKIPReplays */, 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sm->addr), 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSN_SUITE_ARG(pairwise), 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAStatsTKIPLocalMICFailures, 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAStatsTKIPRemoteMICFailures); 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Private MIB */ 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hostapdWPAPTKState=%d\n" 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hostapdWPAPTKGroupState=%d\n", 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_state, 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_ptk_group_state); 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth) 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++; 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_pairwise_set(struct wpa_state_machine *sm) 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm && sm->pairwise_set; 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_get_pairwise(struct wpa_state_machine *sm) 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->pairwise; 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm) 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->wpa_key_mgmt; 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->wpa; 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_pmksa_cache_entry *entry) 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->pmksa != entry) 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pmksa = NULL; 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct rsn_pmksa_cache_entry * 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_auth_sta_get_pmksa(struct wpa_state_machine *sm) 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->pmksa : NULL; 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm) 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot11RSNAStatsTKIPLocalMICFailures++; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len) 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = wpa_auth->wpa_ie_len; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_auth->wpa_ie; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int session_timeout, struct eapol_state_machine *eapol) 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3053c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 || 3054c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt sm->wpa_auth->conf.disable_pmksa_caching) 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wpa_auth->addr, sm->addr, session_timeout, 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol, sm->wpa_key_mgmt)) 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmk, size_t len, const u8 *sta_addr, 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int session_timeout, 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *eapol) 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL) 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr, 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta_addr, session_timeout, eapol, 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_KEY_MGMT_IEEE8021X)) 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3083f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtvoid wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, 3084f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt const u8 *sta_addr) 3085f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt{ 3086f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt struct rsn_pmksa_cache_entry *pmksa; 3087f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 3088f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (wpa_auth == NULL || wpa_auth->pmksa == NULL) 3089f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return; 3090f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL); 3091f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (pmksa) { 3092f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Remove PMKSA cache entry for " 3093f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt MACSTR " based on request", MAC2STR(sta_addr)); 3094f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt pmksa_cache_free_entry(wpa_auth->pmksa, pmksa); 3095f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } 3096f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 3097f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 3098f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_group * 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL || wpa_auth->group == NULL) 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d", 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_id); 31091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group = wpa_group_init(wpa_auth, vlan_id, 0); 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->next = wpa_auth->group->next; 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth->group->next = group; 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group; 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id) 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_group *group; 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->wpa_auth == NULL) 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = sm->wpa_auth->group; 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (group) { 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group->vlan_id == vlan_id) 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = group->next; 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpa_auth_add_group(sm->wpa_auth, vlan_id); 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->group == group) 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 3144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 3145fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state " 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id); 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->group = group; 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_state_machine *sm, int ack) 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth == NULL || sm == NULL) 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " ack=%d", MAC2STR(sm->addr), ack); 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pending_1_of_4_timeout && ack) { 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some deployed supplicant implementations update their SNonce 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for each EAPOL-Key 2/4 message even within the same 4-way 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake and then fail to use the first SNonce when 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deriving the PTK. This results in unsuccessful 4-way 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake whenever the relatively short initial timeout is 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reached and EAPOL-Key 1/4 is retransmitted. Try to work 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * around this by increasing the timeout now that we know that 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the station has received the frame. 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timeout_ms = eapol_key_timeout_subseq; 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 " 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "timeout by %u ms because of acknowledged frame", 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout_ms); 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout_ms / 1000, 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (timeout_ms % 1000) * 1000, 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_send_eapol_timeout, wpa_auth, sm); 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3182d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3183d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3184d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint wpa_auth_uses_sae(struct wpa_state_machine *sm) 3185d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 3186d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sm == NULL) 3187d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 3188d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpa_key_mgmt_sae(sm->wpa_key_mgmt); 3189d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 3190fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3191fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3192fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint wpa_auth_uses_ft_sae(struct wpa_state_machine *sm) 3193fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 3194fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm == NULL) 3195fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 3196fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE; 3197fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 3198cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 3199cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 3200cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 3201cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr) 3202cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 3203cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0) 3204cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 3205cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(addr, sm->ip_addr, 4); 3206cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 3207cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 3208cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 3209