wpa_auth.c revision 281806
1214501Srpaulo/* 2252726Srpaulo * IEEE 802.11 RSN / WPA Authenticator 3281806Srpaulo * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7214501Srpaulo */ 8214501Srpaulo 9214501Srpaulo#include "utils/includes.h" 10214501Srpaulo 11214501Srpaulo#include "utils/common.h" 12214501Srpaulo#include "utils/eloop.h" 13214501Srpaulo#include "utils/state_machine.h" 14281806Srpaulo#include "utils/bitfield.h" 15214501Srpaulo#include "common/ieee802_11_defs.h" 16214501Srpaulo#include "crypto/aes_wrap.h" 17214501Srpaulo#include "crypto/crypto.h" 18214501Srpaulo#include "crypto/sha1.h" 19214501Srpaulo#include "crypto/sha256.h" 20252726Srpaulo#include "crypto/random.h" 21214501Srpaulo#include "eapol_auth/eapol_auth_sm.h" 22214501Srpaulo#include "ap_config.h" 23214501Srpaulo#include "ieee802_11.h" 24214501Srpaulo#include "wpa_auth.h" 25214501Srpaulo#include "pmksa_cache_auth.h" 26214501Srpaulo#include "wpa_auth_i.h" 27214501Srpaulo#include "wpa_auth_ie.h" 28214501Srpaulo 29214501Srpaulo#define STATE_MACHINE_DATA struct wpa_state_machine 30214501Srpaulo#define STATE_MACHINE_DEBUG_PREFIX "WPA" 31214501Srpaulo#define STATE_MACHINE_ADDR sm->addr 32214501Srpaulo 33214501Srpaulo 34214501Srpaulostatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx); 35214501Srpaulostatic int wpa_sm_step(struct wpa_state_machine *sm); 36281806Srpaulostatic int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data, 37281806Srpaulo size_t data_len); 38214501Srpaulostatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx); 39214501Srpaulostatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 40214501Srpaulo struct wpa_group *group); 41214501Srpaulostatic void wpa_request_new_ptk(struct wpa_state_machine *sm); 42214501Srpaulostatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 43214501Srpaulo struct wpa_group *group); 44252726Srpaulostatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 45252726Srpaulo struct wpa_group *group); 46281806Srpaulostatic int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, 47281806Srpaulo const u8 *pmk, struct wpa_ptk *ptk); 48214501Srpaulo 49214501Srpaulostatic const u32 dot11RSNAConfigGroupUpdateCount = 4; 50214501Srpaulostatic const u32 dot11RSNAConfigPairwiseUpdateCount = 4; 51214501Srpaulostatic const u32 eapol_key_timeout_first = 100; /* ms */ 52214501Srpaulostatic const u32 eapol_key_timeout_subseq = 1000; /* ms */ 53252726Srpaulostatic const u32 eapol_key_timeout_first_group = 500; /* ms */ 54214501Srpaulo 55214501Srpaulo/* TODO: make these configurable */ 56214501Srpaulostatic const int dot11RSNAConfigPMKLifetime = 43200; 57214501Srpaulostatic const int dot11RSNAConfigPMKReauthThreshold = 70; 58214501Srpaulostatic const int dot11RSNAConfigSATimeout = 60; 59214501Srpaulo 60214501Srpaulo 61252726Srpaulostatic inline int wpa_auth_mic_failure_report( 62214501Srpaulo struct wpa_authenticator *wpa_auth, const u8 *addr) 63214501Srpaulo{ 64214501Srpaulo if (wpa_auth->cb.mic_failure_report) 65252726Srpaulo return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr); 66252726Srpaulo return 0; 67214501Srpaulo} 68214501Srpaulo 69214501Srpaulo 70214501Srpaulostatic inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth, 71214501Srpaulo const u8 *addr, wpa_eapol_variable var, 72214501Srpaulo int value) 73214501Srpaulo{ 74214501Srpaulo if (wpa_auth->cb.set_eapol) 75214501Srpaulo wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value); 76214501Srpaulo} 77214501Srpaulo 78214501Srpaulo 79214501Srpaulostatic inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth, 80214501Srpaulo const u8 *addr, wpa_eapol_variable var) 81214501Srpaulo{ 82214501Srpaulo if (wpa_auth->cb.get_eapol == NULL) 83214501Srpaulo return -1; 84214501Srpaulo return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var); 85214501Srpaulo} 86214501Srpaulo 87214501Srpaulo 88214501Srpaulostatic inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth, 89281806Srpaulo const u8 *addr, 90281806Srpaulo const u8 *p2p_dev_addr, 91281806Srpaulo const u8 *prev_psk) 92214501Srpaulo{ 93214501Srpaulo if (wpa_auth->cb.get_psk == NULL) 94214501Srpaulo return NULL; 95281806Srpaulo return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr, 96281806Srpaulo prev_psk); 97214501Srpaulo} 98214501Srpaulo 99214501Srpaulo 100214501Srpaulostatic inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth, 101214501Srpaulo const u8 *addr, u8 *msk, size_t *len) 102214501Srpaulo{ 103214501Srpaulo if (wpa_auth->cb.get_msk == NULL) 104214501Srpaulo return -1; 105214501Srpaulo return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len); 106214501Srpaulo} 107214501Srpaulo 108214501Srpaulo 109214501Srpaulostatic inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, 110214501Srpaulo int vlan_id, 111214501Srpaulo enum wpa_alg alg, const u8 *addr, int idx, 112214501Srpaulo u8 *key, size_t key_len) 113214501Srpaulo{ 114214501Srpaulo if (wpa_auth->cb.set_key == NULL) 115214501Srpaulo return -1; 116214501Srpaulo return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx, 117214501Srpaulo key, key_len); 118214501Srpaulo} 119214501Srpaulo 120214501Srpaulo 121214501Srpaulostatic inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, 122214501Srpaulo const u8 *addr, int idx, u8 *seq) 123214501Srpaulo{ 124214501Srpaulo if (wpa_auth->cb.get_seqnum == NULL) 125214501Srpaulo return -1; 126214501Srpaulo return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq); 127214501Srpaulo} 128214501Srpaulo 129214501Srpaulo 130214501Srpaulostatic inline int 131214501Srpaulowpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr, 132214501Srpaulo const u8 *data, size_t data_len, int encrypt) 133214501Srpaulo{ 134214501Srpaulo if (wpa_auth->cb.send_eapol == NULL) 135214501Srpaulo return -1; 136214501Srpaulo return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len, 137214501Srpaulo encrypt); 138214501Srpaulo} 139214501Srpaulo 140214501Srpaulo 141281806Srpaulo#ifdef CONFIG_MESH 142281806Srpaulostatic inline int wpa_auth_start_ampe(struct wpa_authenticator *wpa_auth, 143281806Srpaulo const u8 *addr) 144281806Srpaulo{ 145281806Srpaulo if (wpa_auth->cb.start_ampe == NULL) 146281806Srpaulo return -1; 147281806Srpaulo return wpa_auth->cb.start_ampe(wpa_auth->cb.ctx, addr); 148281806Srpaulo} 149281806Srpaulo#endif /* CONFIG_MESH */ 150281806Srpaulo 151281806Srpaulo 152214501Srpauloint wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, 153214501Srpaulo int (*cb)(struct wpa_state_machine *sm, void *ctx), 154214501Srpaulo void *cb_ctx) 155214501Srpaulo{ 156214501Srpaulo if (wpa_auth->cb.for_each_sta == NULL) 157214501Srpaulo return 0; 158214501Srpaulo return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx); 159214501Srpaulo} 160214501Srpaulo 161214501Srpaulo 162214501Srpauloint wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, 163214501Srpaulo int (*cb)(struct wpa_authenticator *a, void *ctx), 164214501Srpaulo void *cb_ctx) 165214501Srpaulo{ 166214501Srpaulo if (wpa_auth->cb.for_each_auth == NULL) 167214501Srpaulo return 0; 168214501Srpaulo return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx); 169214501Srpaulo} 170214501Srpaulo 171214501Srpaulo 172214501Srpaulovoid wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr, 173214501Srpaulo logger_level level, const char *txt) 174214501Srpaulo{ 175214501Srpaulo if (wpa_auth->cb.logger == NULL) 176214501Srpaulo return; 177214501Srpaulo wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt); 178214501Srpaulo} 179214501Srpaulo 180214501Srpaulo 181214501Srpaulovoid wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr, 182214501Srpaulo logger_level level, const char *fmt, ...) 183214501Srpaulo{ 184214501Srpaulo char *format; 185214501Srpaulo int maxlen; 186214501Srpaulo va_list ap; 187214501Srpaulo 188214501Srpaulo if (wpa_auth->cb.logger == NULL) 189214501Srpaulo return; 190214501Srpaulo 191214501Srpaulo maxlen = os_strlen(fmt) + 100; 192214501Srpaulo format = os_malloc(maxlen); 193214501Srpaulo if (!format) 194214501Srpaulo return; 195214501Srpaulo 196214501Srpaulo va_start(ap, fmt); 197214501Srpaulo vsnprintf(format, maxlen, fmt, ap); 198214501Srpaulo va_end(ap); 199214501Srpaulo 200214501Srpaulo wpa_auth_logger(wpa_auth, addr, level, format); 201214501Srpaulo 202214501Srpaulo os_free(format); 203214501Srpaulo} 204214501Srpaulo 205214501Srpaulo 206214501Srpaulostatic void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, 207214501Srpaulo const u8 *addr) 208214501Srpaulo{ 209214501Srpaulo if (wpa_auth->cb.disconnect == NULL) 210214501Srpaulo return; 211252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); 212214501Srpaulo wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr, 213214501Srpaulo WLAN_REASON_PREV_AUTH_NOT_VALID); 214214501Srpaulo} 215214501Srpaulo 216214501Srpaulo 217214501Srpaulostatic int wpa_use_aes_cmac(struct wpa_state_machine *sm) 218214501Srpaulo{ 219214501Srpaulo int ret = 0; 220214501Srpaulo#ifdef CONFIG_IEEE80211R 221214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 222214501Srpaulo ret = 1; 223214501Srpaulo#endif /* CONFIG_IEEE80211R */ 224214501Srpaulo#ifdef CONFIG_IEEE80211W 225214501Srpaulo if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt)) 226214501Srpaulo ret = 1; 227214501Srpaulo#endif /* CONFIG_IEEE80211W */ 228281806Srpaulo if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) 229281806Srpaulo ret = 1; 230214501Srpaulo return ret; 231214501Srpaulo} 232214501Srpaulo 233214501Srpaulo 234214501Srpaulostatic void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx) 235214501Srpaulo{ 236214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 237214501Srpaulo 238252726Srpaulo if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) { 239214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 240214501Srpaulo "initialization."); 241214501Srpaulo } else { 242214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd"); 243252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", 244252726Srpaulo wpa_auth->group->GMK, WPA_GMK_LEN); 245214501Srpaulo } 246214501Srpaulo 247214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 248214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 249214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 250214501Srpaulo } 251214501Srpaulo} 252214501Srpaulo 253214501Srpaulo 254214501Srpaulostatic void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx) 255214501Srpaulo{ 256214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 257214501Srpaulo struct wpa_group *group; 258214501Srpaulo 259214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK"); 260214501Srpaulo for (group = wpa_auth->group; group; group = group->next) { 261214501Srpaulo group->GTKReKey = TRUE; 262214501Srpaulo do { 263214501Srpaulo group->changed = FALSE; 264214501Srpaulo wpa_group_sm_step(wpa_auth, group); 265214501Srpaulo } while (group->changed); 266214501Srpaulo } 267214501Srpaulo 268214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 269214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 270214501Srpaulo 0, wpa_rekey_gtk, wpa_auth, NULL); 271214501Srpaulo } 272214501Srpaulo} 273214501Srpaulo 274214501Srpaulo 275214501Srpaulostatic void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx) 276214501Srpaulo{ 277214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 278214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 279214501Srpaulo 280214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK"); 281214501Srpaulo wpa_request_new_ptk(sm); 282214501Srpaulo wpa_sm_step(sm); 283214501Srpaulo} 284214501Srpaulo 285214501Srpaulo 286214501Srpaulostatic int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx) 287214501Srpaulo{ 288214501Srpaulo if (sm->pmksa == ctx) 289214501Srpaulo sm->pmksa = NULL; 290214501Srpaulo return 0; 291214501Srpaulo} 292214501Srpaulo 293214501Srpaulo 294214501Srpaulostatic void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, 295214501Srpaulo void *ctx) 296214501Srpaulo{ 297214501Srpaulo struct wpa_authenticator *wpa_auth = ctx; 298214501Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry); 299214501Srpaulo} 300214501Srpaulo 301214501Srpaulo 302252726Srpaulostatic int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth, 303252726Srpaulo struct wpa_group *group) 304214501Srpaulo{ 305281806Srpaulo u8 buf[ETH_ALEN + 8 + sizeof(unsigned long)]; 306252726Srpaulo u8 rkey[32]; 307281806Srpaulo unsigned long ptr; 308252726Srpaulo 309252726Srpaulo if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0) 310252726Srpaulo return -1; 311252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", group->GMK, WPA_GMK_LEN); 312252726Srpaulo 313252726Srpaulo /* 314252726Srpaulo * Counter = PRF-256(Random number, "Init Counter", 315252726Srpaulo * Local MAC Address || Time) 316252726Srpaulo */ 317252726Srpaulo os_memcpy(buf, wpa_auth->addr, ETH_ALEN); 318252726Srpaulo wpa_get_ntp_timestamp(buf + ETH_ALEN); 319281806Srpaulo ptr = (unsigned long) group; 320281806Srpaulo os_memcpy(buf + ETH_ALEN + 8, &ptr, sizeof(ptr)); 321252726Srpaulo if (random_get_bytes(rkey, sizeof(rkey)) < 0) 322252726Srpaulo return -1; 323252726Srpaulo 324252726Srpaulo if (sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf), 325252726Srpaulo group->Counter, WPA_NONCE_LEN) < 0) 326252726Srpaulo return -1; 327252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "Key Counter", 328252726Srpaulo group->Counter, WPA_NONCE_LEN); 329252726Srpaulo 330252726Srpaulo return 0; 331214501Srpaulo} 332214501Srpaulo 333214501Srpaulo 334214501Srpaulostatic struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth, 335252726Srpaulo int vlan_id, int delay_init) 336214501Srpaulo{ 337214501Srpaulo struct wpa_group *group; 338214501Srpaulo 339214501Srpaulo group = os_zalloc(sizeof(struct wpa_group)); 340214501Srpaulo if (group == NULL) 341214501Srpaulo return NULL; 342214501Srpaulo 343214501Srpaulo group->GTKAuthenticator = TRUE; 344214501Srpaulo group->vlan_id = vlan_id; 345252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 346214501Srpaulo 347252726Srpaulo if (random_pool_ready() != 1) { 348252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 349252726Srpaulo "for secure operations - update keys later when " 350252726Srpaulo "the first station connects"); 351252726Srpaulo } 352214501Srpaulo 353252726Srpaulo /* 354252726Srpaulo * Set initial GMK/Counter value here. The actual values that will be 355252726Srpaulo * used in negotiations will be set once the first station tries to 356252726Srpaulo * connect. This allows more time for collecting additional randomness 357252726Srpaulo * on embedded devices. 358214501Srpaulo */ 359252726Srpaulo if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) { 360214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 361214501Srpaulo "initialization."); 362214501Srpaulo os_free(group); 363214501Srpaulo return NULL; 364214501Srpaulo } 365214501Srpaulo 366214501Srpaulo group->GInit = TRUE; 367252726Srpaulo if (delay_init) { 368252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start " 369252726Srpaulo "until Beacon frames have been configured"); 370252726Srpaulo /* Initialization is completed in wpa_init_keys(). */ 371252726Srpaulo } else { 372252726Srpaulo wpa_group_sm_step(wpa_auth, group); 373252726Srpaulo group->GInit = FALSE; 374252726Srpaulo wpa_group_sm_step(wpa_auth, group); 375252726Srpaulo } 376214501Srpaulo 377214501Srpaulo return group; 378214501Srpaulo} 379214501Srpaulo 380214501Srpaulo 381214501Srpaulo/** 382214501Srpaulo * wpa_init - Initialize WPA authenticator 383214501Srpaulo * @addr: Authenticator address 384214501Srpaulo * @conf: Configuration for WPA authenticator 385214501Srpaulo * @cb: Callback functions for WPA authenticator 386214501Srpaulo * Returns: Pointer to WPA authenticator data or %NULL on failure 387214501Srpaulo */ 388214501Srpaulostruct wpa_authenticator * wpa_init(const u8 *addr, 389214501Srpaulo struct wpa_auth_config *conf, 390214501Srpaulo struct wpa_auth_callbacks *cb) 391214501Srpaulo{ 392214501Srpaulo struct wpa_authenticator *wpa_auth; 393214501Srpaulo 394214501Srpaulo wpa_auth = os_zalloc(sizeof(struct wpa_authenticator)); 395214501Srpaulo if (wpa_auth == NULL) 396214501Srpaulo return NULL; 397214501Srpaulo os_memcpy(wpa_auth->addr, addr, ETH_ALEN); 398214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 399214501Srpaulo os_memcpy(&wpa_auth->cb, cb, sizeof(*cb)); 400214501Srpaulo 401214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 402214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 403214501Srpaulo os_free(wpa_auth); 404214501Srpaulo return NULL; 405214501Srpaulo } 406214501Srpaulo 407252726Srpaulo wpa_auth->group = wpa_group_init(wpa_auth, 0, 1); 408214501Srpaulo if (wpa_auth->group == NULL) { 409214501Srpaulo os_free(wpa_auth->wpa_ie); 410214501Srpaulo os_free(wpa_auth); 411214501Srpaulo return NULL; 412214501Srpaulo } 413214501Srpaulo 414214501Srpaulo wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb, 415214501Srpaulo wpa_auth); 416214501Srpaulo if (wpa_auth->pmksa == NULL) { 417214501Srpaulo wpa_printf(MSG_ERROR, "PMKSA cache initialization failed."); 418281806Srpaulo os_free(wpa_auth->group); 419214501Srpaulo os_free(wpa_auth->wpa_ie); 420214501Srpaulo os_free(wpa_auth); 421214501Srpaulo return NULL; 422214501Srpaulo } 423214501Srpaulo 424214501Srpaulo#ifdef CONFIG_IEEE80211R 425214501Srpaulo wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init(); 426214501Srpaulo if (wpa_auth->ft_pmk_cache == NULL) { 427214501Srpaulo wpa_printf(MSG_ERROR, "FT PMK cache initialization failed."); 428281806Srpaulo os_free(wpa_auth->group); 429214501Srpaulo os_free(wpa_auth->wpa_ie); 430214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 431214501Srpaulo os_free(wpa_auth); 432214501Srpaulo return NULL; 433214501Srpaulo } 434214501Srpaulo#endif /* CONFIG_IEEE80211R */ 435214501Srpaulo 436214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 437214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 438214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 439214501Srpaulo } 440214501Srpaulo 441214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 442214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0, 443214501Srpaulo wpa_rekey_gtk, wpa_auth, NULL); 444214501Srpaulo } 445214501Srpaulo 446281806Srpaulo#ifdef CONFIG_P2P 447281806Srpaulo if (WPA_GET_BE32(conf->ip_addr_start)) { 448281806Srpaulo int count = WPA_GET_BE32(conf->ip_addr_end) - 449281806Srpaulo WPA_GET_BE32(conf->ip_addr_start) + 1; 450281806Srpaulo if (count > 1000) 451281806Srpaulo count = 1000; 452281806Srpaulo if (count > 0) 453281806Srpaulo wpa_auth->ip_pool = bitfield_alloc(count); 454281806Srpaulo } 455281806Srpaulo#endif /* CONFIG_P2P */ 456281806Srpaulo 457214501Srpaulo return wpa_auth; 458214501Srpaulo} 459214501Srpaulo 460214501Srpaulo 461252726Srpauloint wpa_init_keys(struct wpa_authenticator *wpa_auth) 462252726Srpaulo{ 463252726Srpaulo struct wpa_group *group = wpa_auth->group; 464252726Srpaulo 465252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial " 466252726Srpaulo "keys"); 467252726Srpaulo wpa_group_sm_step(wpa_auth, group); 468252726Srpaulo group->GInit = FALSE; 469252726Srpaulo wpa_group_sm_step(wpa_auth, group); 470281806Srpaulo if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 471281806Srpaulo return -1; 472252726Srpaulo return 0; 473252726Srpaulo} 474252726Srpaulo 475252726Srpaulo 476214501Srpaulo/** 477214501Srpaulo * wpa_deinit - Deinitialize WPA authenticator 478214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 479214501Srpaulo */ 480214501Srpaulovoid wpa_deinit(struct wpa_authenticator *wpa_auth) 481214501Srpaulo{ 482214501Srpaulo struct wpa_group *group, *prev; 483214501Srpaulo 484214501Srpaulo eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL); 485214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 486214501Srpaulo 487214501Srpaulo#ifdef CONFIG_PEERKEY 488214501Srpaulo while (wpa_auth->stsl_negotiations) 489214501Srpaulo wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations); 490214501Srpaulo#endif /* CONFIG_PEERKEY */ 491214501Srpaulo 492214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 493214501Srpaulo 494214501Srpaulo#ifdef CONFIG_IEEE80211R 495214501Srpaulo wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache); 496214501Srpaulo wpa_auth->ft_pmk_cache = NULL; 497214501Srpaulo#endif /* CONFIG_IEEE80211R */ 498214501Srpaulo 499281806Srpaulo#ifdef CONFIG_P2P 500281806Srpaulo bitfield_free(wpa_auth->ip_pool); 501281806Srpaulo#endif /* CONFIG_P2P */ 502281806Srpaulo 503281806Srpaulo 504214501Srpaulo os_free(wpa_auth->wpa_ie); 505214501Srpaulo 506214501Srpaulo group = wpa_auth->group; 507214501Srpaulo while (group) { 508214501Srpaulo prev = group; 509214501Srpaulo group = group->next; 510214501Srpaulo os_free(prev); 511214501Srpaulo } 512214501Srpaulo 513214501Srpaulo os_free(wpa_auth); 514214501Srpaulo} 515214501Srpaulo 516214501Srpaulo 517214501Srpaulo/** 518214501Srpaulo * wpa_reconfig - Update WPA authenticator configuration 519214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 520214501Srpaulo * @conf: Configuration for WPA authenticator 521214501Srpaulo */ 522214501Srpauloint wpa_reconfig(struct wpa_authenticator *wpa_auth, 523214501Srpaulo struct wpa_auth_config *conf) 524214501Srpaulo{ 525214501Srpaulo struct wpa_group *group; 526214501Srpaulo if (wpa_auth == NULL) 527214501Srpaulo return 0; 528214501Srpaulo 529214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 530214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 531214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 532214501Srpaulo return -1; 533214501Srpaulo } 534214501Srpaulo 535214501Srpaulo /* 536214501Srpaulo * Reinitialize GTK to make sure it is suitable for the new 537214501Srpaulo * configuration. 538214501Srpaulo */ 539214501Srpaulo group = wpa_auth->group; 540252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 541214501Srpaulo group->GInit = TRUE; 542214501Srpaulo wpa_group_sm_step(wpa_auth, group); 543214501Srpaulo group->GInit = FALSE; 544214501Srpaulo wpa_group_sm_step(wpa_auth, group); 545214501Srpaulo 546214501Srpaulo return 0; 547214501Srpaulo} 548214501Srpaulo 549214501Srpaulo 550214501Srpaulostruct wpa_state_machine * 551281806Srpaulowpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr, 552281806Srpaulo const u8 *p2p_dev_addr) 553214501Srpaulo{ 554214501Srpaulo struct wpa_state_machine *sm; 555214501Srpaulo 556281806Srpaulo if (wpa_auth->group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 557281806Srpaulo return NULL; 558281806Srpaulo 559214501Srpaulo sm = os_zalloc(sizeof(struct wpa_state_machine)); 560214501Srpaulo if (sm == NULL) 561214501Srpaulo return NULL; 562214501Srpaulo os_memcpy(sm->addr, addr, ETH_ALEN); 563281806Srpaulo if (p2p_dev_addr) 564281806Srpaulo os_memcpy(sm->p2p_dev_addr, p2p_dev_addr, ETH_ALEN); 565214501Srpaulo 566214501Srpaulo sm->wpa_auth = wpa_auth; 567214501Srpaulo sm->group = wpa_auth->group; 568214501Srpaulo 569214501Srpaulo return sm; 570214501Srpaulo} 571214501Srpaulo 572214501Srpaulo 573214501Srpauloint wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, 574214501Srpaulo struct wpa_state_machine *sm) 575214501Srpaulo{ 576214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 577214501Srpaulo return -1; 578214501Srpaulo 579214501Srpaulo#ifdef CONFIG_IEEE80211R 580214501Srpaulo if (sm->ft_completed) { 581214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 582214501Srpaulo "FT authentication already completed - do not " 583214501Srpaulo "start 4-way handshake"); 584281806Srpaulo /* Go to PTKINITDONE state to allow GTK rekeying */ 585281806Srpaulo sm->wpa_ptk_state = WPA_PTK_PTKINITDONE; 586214501Srpaulo return 0; 587214501Srpaulo } 588214501Srpaulo#endif /* CONFIG_IEEE80211R */ 589214501Srpaulo 590214501Srpaulo if (sm->started) { 591214501Srpaulo os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); 592214501Srpaulo sm->ReAuthenticationRequest = TRUE; 593214501Srpaulo return wpa_sm_step(sm); 594214501Srpaulo } 595214501Srpaulo 596214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 597214501Srpaulo "start authentication"); 598214501Srpaulo sm->started = 1; 599214501Srpaulo 600214501Srpaulo sm->Init = TRUE; 601214501Srpaulo if (wpa_sm_step(sm) == 1) 602214501Srpaulo return 1; /* should not really happen */ 603214501Srpaulo sm->Init = FALSE; 604214501Srpaulo sm->AuthenticationRequest = TRUE; 605214501Srpaulo return wpa_sm_step(sm); 606214501Srpaulo} 607214501Srpaulo 608214501Srpaulo 609214501Srpaulovoid wpa_auth_sta_no_wpa(struct wpa_state_machine *sm) 610214501Srpaulo{ 611214501Srpaulo /* WPA/RSN was not used - clear WPA state. This is needed if the STA 612214501Srpaulo * reassociates back to the same AP while the previous entry for the 613214501Srpaulo * STA has not yet been removed. */ 614214501Srpaulo if (sm == NULL) 615214501Srpaulo return; 616214501Srpaulo 617214501Srpaulo sm->wpa_key_mgmt = 0; 618214501Srpaulo} 619214501Srpaulo 620214501Srpaulo 621214501Srpaulostatic void wpa_free_sta_sm(struct wpa_state_machine *sm) 622214501Srpaulo{ 623281806Srpaulo#ifdef CONFIG_P2P 624281806Srpaulo if (WPA_GET_BE32(sm->ip_addr)) { 625281806Srpaulo u32 start; 626281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: Free assigned IP " 627281806Srpaulo "address %u.%u.%u.%u from " MACSTR, 628281806Srpaulo sm->ip_addr[0], sm->ip_addr[1], 629281806Srpaulo sm->ip_addr[2], sm->ip_addr[3], 630281806Srpaulo MAC2STR(sm->addr)); 631281806Srpaulo start = WPA_GET_BE32(sm->wpa_auth->conf.ip_addr_start); 632281806Srpaulo bitfield_clear(sm->wpa_auth->ip_pool, 633281806Srpaulo WPA_GET_BE32(sm->ip_addr) - start); 634281806Srpaulo } 635281806Srpaulo#endif /* CONFIG_P2P */ 636252726Srpaulo if (sm->GUpdateStationKeys) { 637252726Srpaulo sm->group->GKeyDoneStations--; 638252726Srpaulo sm->GUpdateStationKeys = FALSE; 639252726Srpaulo } 640214501Srpaulo#ifdef CONFIG_IEEE80211R 641214501Srpaulo os_free(sm->assoc_resp_ftie); 642281806Srpaulo wpabuf_free(sm->ft_pending_req_ies); 643214501Srpaulo#endif /* CONFIG_IEEE80211R */ 644214501Srpaulo os_free(sm->last_rx_eapol_key); 645214501Srpaulo os_free(sm->wpa_ie); 646214501Srpaulo os_free(sm); 647214501Srpaulo} 648214501Srpaulo 649214501Srpaulo 650214501Srpaulovoid wpa_auth_sta_deinit(struct wpa_state_machine *sm) 651214501Srpaulo{ 652214501Srpaulo if (sm == NULL) 653214501Srpaulo return; 654214501Srpaulo 655214501Srpaulo if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) { 656214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 657214501Srpaulo "strict rekeying - force GTK rekey since STA " 658214501Srpaulo "is leaving"); 659214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL); 660214501Srpaulo eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth, 661214501Srpaulo NULL); 662214501Srpaulo } 663214501Srpaulo 664214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 665252726Srpaulo sm->pending_1_of_4_timeout = 0; 666214501Srpaulo eloop_cancel_timeout(wpa_sm_call_step, sm, NULL); 667214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 668214501Srpaulo if (sm->in_step_loop) { 669214501Srpaulo /* Must not free state machine while wpa_sm_step() is running. 670214501Srpaulo * Freeing will be completed in the end of wpa_sm_step(). */ 671214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state " 672214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 673214501Srpaulo sm->pending_deinit = 1; 674214501Srpaulo } else 675214501Srpaulo wpa_free_sta_sm(sm); 676214501Srpaulo} 677214501Srpaulo 678214501Srpaulo 679214501Srpaulostatic void wpa_request_new_ptk(struct wpa_state_machine *sm) 680214501Srpaulo{ 681214501Srpaulo if (sm == NULL) 682214501Srpaulo return; 683214501Srpaulo 684214501Srpaulo sm->PTKRequest = TRUE; 685214501Srpaulo sm->PTK_valid = 0; 686214501Srpaulo} 687214501Srpaulo 688214501Srpaulo 689252726Srpaulostatic int wpa_replay_counter_valid(struct wpa_key_replay_counter *ctr, 690214501Srpaulo const u8 *replay_counter) 691214501Srpaulo{ 692214501Srpaulo int i; 693214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 694252726Srpaulo if (!ctr[i].valid) 695214501Srpaulo break; 696252726Srpaulo if (os_memcmp(replay_counter, ctr[i].counter, 697214501Srpaulo WPA_REPLAY_COUNTER_LEN) == 0) 698214501Srpaulo return 1; 699214501Srpaulo } 700214501Srpaulo return 0; 701214501Srpaulo} 702214501Srpaulo 703214501Srpaulo 704252726Srpaulostatic void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr, 705252726Srpaulo const u8 *replay_counter) 706252726Srpaulo{ 707252726Srpaulo int i; 708252726Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 709252726Srpaulo if (ctr[i].valid && 710252726Srpaulo (replay_counter == NULL || 711252726Srpaulo os_memcmp(replay_counter, ctr[i].counter, 712252726Srpaulo WPA_REPLAY_COUNTER_LEN) == 0)) 713252726Srpaulo ctr[i].valid = FALSE; 714252726Srpaulo } 715252726Srpaulo} 716252726Srpaulo 717252726Srpaulo 718214501Srpaulo#ifdef CONFIG_IEEE80211R 719214501Srpaulostatic int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth, 720214501Srpaulo struct wpa_state_machine *sm, 721214501Srpaulo struct wpa_eapol_ie_parse *kde) 722214501Srpaulo{ 723214501Srpaulo struct wpa_ie_data ie; 724214501Srpaulo struct rsn_mdie *mdie; 725214501Srpaulo 726214501Srpaulo if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 || 727214501Srpaulo ie.num_pmkid != 1 || ie.pmkid == NULL) { 728214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in " 729214501Srpaulo "FT 4-way handshake message 2/4"); 730214501Srpaulo return -1; 731214501Srpaulo } 732214501Srpaulo 733214501Srpaulo os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN); 734214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant", 735214501Srpaulo sm->sup_pmk_r1_name, PMKID_LEN); 736214501Srpaulo 737214501Srpaulo if (!kde->mdie || !kde->ftie) { 738214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake " 739214501Srpaulo "message 2/4", kde->mdie ? "FTIE" : "MDIE"); 740214501Srpaulo return -1; 741214501Srpaulo } 742214501Srpaulo 743214501Srpaulo mdie = (struct rsn_mdie *) (kde->mdie + 2); 744214501Srpaulo if (kde->mdie[1] < sizeof(struct rsn_mdie) || 745214501Srpaulo os_memcmp(wpa_auth->conf.mobility_domain, mdie->mobility_domain, 746214501Srpaulo MOBILITY_DOMAIN_ID_LEN) != 0) { 747214501Srpaulo wpa_printf(MSG_DEBUG, "FT: MDIE mismatch"); 748214501Srpaulo return -1; 749214501Srpaulo } 750214501Srpaulo 751214501Srpaulo if (sm->assoc_resp_ftie && 752214501Srpaulo (kde->ftie[1] != sm->assoc_resp_ftie[1] || 753214501Srpaulo os_memcmp(kde->ftie, sm->assoc_resp_ftie, 754214501Srpaulo 2 + sm->assoc_resp_ftie[1]) != 0)) { 755214501Srpaulo wpa_printf(MSG_DEBUG, "FT: FTIE mismatch"); 756214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 2/4", 757214501Srpaulo kde->ftie, kde->ftie_len); 758214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)AssocResp", 759214501Srpaulo sm->assoc_resp_ftie, 2 + sm->assoc_resp_ftie[1]); 760214501Srpaulo return -1; 761214501Srpaulo } 762214501Srpaulo 763214501Srpaulo return 0; 764214501Srpaulo} 765214501Srpaulo#endif /* CONFIG_IEEE80211R */ 766214501Srpaulo 767214501Srpaulo 768252726Srpaulostatic int wpa_receive_error_report(struct wpa_authenticator *wpa_auth, 769252726Srpaulo struct wpa_state_machine *sm, int group) 770252726Srpaulo{ 771252726Srpaulo /* Supplicant reported a Michael MIC error */ 772252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 773252726Srpaulo "received EAPOL-Key Error Request " 774252726Srpaulo "(STA detected Michael MIC failure (group=%d))", 775252726Srpaulo group); 776252726Srpaulo 777252726Srpaulo if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) { 778252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 779252726Srpaulo "ignore Michael MIC failure report since " 780252726Srpaulo "group cipher is not TKIP"); 781252726Srpaulo } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) { 782252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 783252726Srpaulo "ignore Michael MIC failure report since " 784252726Srpaulo "pairwise cipher is not TKIP"); 785252726Srpaulo } else { 786252726Srpaulo if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0) 787252726Srpaulo return 1; /* STA entry was removed */ 788252726Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures++; 789252726Srpaulo wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++; 790252726Srpaulo } 791252726Srpaulo 792252726Srpaulo /* 793252726Srpaulo * Error report is not a request for a new key handshake, but since 794252726Srpaulo * Authenticator may do it, let's change the keys now anyway. 795252726Srpaulo */ 796252726Srpaulo wpa_request_new_ptk(sm); 797252726Srpaulo return 0; 798252726Srpaulo} 799252726Srpaulo 800252726Srpaulo 801281806Srpaulostatic int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data, 802281806Srpaulo size_t data_len) 803281806Srpaulo{ 804281806Srpaulo struct wpa_ptk PTK; 805281806Srpaulo int ok = 0; 806281806Srpaulo const u8 *pmk = NULL; 807281806Srpaulo 808281806Srpaulo for (;;) { 809281806Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 810281806Srpaulo pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, 811281806Srpaulo sm->p2p_dev_addr, pmk); 812281806Srpaulo if (pmk == NULL) 813281806Srpaulo break; 814281806Srpaulo } else 815281806Srpaulo pmk = sm->PMK; 816281806Srpaulo 817281806Srpaulo wpa_derive_ptk(sm, sm->alt_SNonce, pmk, &PTK); 818281806Srpaulo 819281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, data, data_len) 820281806Srpaulo == 0) { 821281806Srpaulo ok = 1; 822281806Srpaulo break; 823281806Srpaulo } 824281806Srpaulo 825281806Srpaulo if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 826281806Srpaulo break; 827281806Srpaulo } 828281806Srpaulo 829281806Srpaulo if (!ok) { 830281806Srpaulo wpa_printf(MSG_DEBUG, 831281806Srpaulo "WPA: Earlier SNonce did not result in matching MIC"); 832281806Srpaulo return -1; 833281806Srpaulo } 834281806Srpaulo 835281806Srpaulo wpa_printf(MSG_DEBUG, 836281806Srpaulo "WPA: Earlier SNonce resulted in matching MIC"); 837281806Srpaulo sm->alt_snonce_valid = 0; 838281806Srpaulo os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN); 839281806Srpaulo os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 840281806Srpaulo sm->PTK_valid = TRUE; 841281806Srpaulo 842281806Srpaulo return 0; 843281806Srpaulo} 844281806Srpaulo 845281806Srpaulo 846214501Srpaulovoid wpa_receive(struct wpa_authenticator *wpa_auth, 847214501Srpaulo struct wpa_state_machine *sm, 848214501Srpaulo u8 *data, size_t data_len) 849214501Srpaulo{ 850214501Srpaulo struct ieee802_1x_hdr *hdr; 851214501Srpaulo struct wpa_eapol_key *key; 852281806Srpaulo struct wpa_eapol_key_192 *key192; 853214501Srpaulo u16 key_info, key_data_length; 854214501Srpaulo enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST, 855214501Srpaulo SMK_M1, SMK_M3, SMK_ERROR } msg; 856214501Srpaulo char *msgtxt; 857214501Srpaulo struct wpa_eapol_ie_parse kde; 858214501Srpaulo int ft; 859281806Srpaulo const u8 *eapol_key_ie, *key_data; 860281806Srpaulo size_t eapol_key_ie_len, keyhdrlen, mic_len; 861214501Srpaulo 862214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 863214501Srpaulo return; 864214501Srpaulo 865281806Srpaulo mic_len = wpa_mic_len(sm->wpa_key_mgmt); 866281806Srpaulo keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); 867281806Srpaulo 868281806Srpaulo if (data_len < sizeof(*hdr) + keyhdrlen) 869214501Srpaulo return; 870214501Srpaulo 871214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 872214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 873281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 874214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 875281806Srpaulo if (mic_len == 24) { 876281806Srpaulo key_data = (const u8 *) (key192 + 1); 877281806Srpaulo key_data_length = WPA_GET_BE16(key192->key_data_length); 878281806Srpaulo } else { 879281806Srpaulo key_data = (const u8 *) (key + 1); 880281806Srpaulo key_data_length = WPA_GET_BE16(key->key_data_length); 881281806Srpaulo } 882252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR 883252726Srpaulo " key_info=0x%x type=%u key_data_length=%u", 884252726Srpaulo MAC2STR(sm->addr), key_info, key->type, key_data_length); 885281806Srpaulo if (key_data_length > data_len - sizeof(*hdr) - keyhdrlen) { 886214501Srpaulo wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - " 887214501Srpaulo "key_data overflow (%d > %lu)", 888214501Srpaulo key_data_length, 889214501Srpaulo (unsigned long) (data_len - sizeof(*hdr) - 890281806Srpaulo keyhdrlen)); 891214501Srpaulo return; 892214501Srpaulo } 893214501Srpaulo 894214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 895252726Srpaulo if (key->type == EAPOL_KEY_TYPE_WPA) { 896252726Srpaulo /* 897252726Srpaulo * Some deployed station implementations seem to send 898252726Srpaulo * msg 4/4 with incorrect type value in WPA2 mode. 899252726Srpaulo */ 900252726Srpaulo wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key " 901252726Srpaulo "with unexpected WPA type in RSN mode"); 902252726Srpaulo } else if (key->type != EAPOL_KEY_TYPE_RSN) { 903214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 904214501Srpaulo "unexpected type %d in RSN mode", 905214501Srpaulo key->type); 906214501Srpaulo return; 907214501Srpaulo } 908214501Srpaulo } else { 909214501Srpaulo if (key->type != EAPOL_KEY_TYPE_WPA) { 910214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 911214501Srpaulo "unexpected type %d in WPA mode", 912214501Srpaulo key->type); 913214501Srpaulo return; 914214501Srpaulo } 915214501Srpaulo } 916214501Srpaulo 917252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Key Nonce", key->key_nonce, 918252726Srpaulo WPA_NONCE_LEN); 919252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Replay Counter", 920252726Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 921252726Srpaulo 922214501Srpaulo /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys 923214501Srpaulo * are set */ 924214501Srpaulo 925214501Srpaulo if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) == 926214501Srpaulo (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) { 927214501Srpaulo if (key_info & WPA_KEY_INFO_ERROR) { 928214501Srpaulo msg = SMK_ERROR; 929214501Srpaulo msgtxt = "SMK Error"; 930214501Srpaulo } else { 931214501Srpaulo msg = SMK_M1; 932214501Srpaulo msgtxt = "SMK M1"; 933214501Srpaulo } 934214501Srpaulo } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) { 935214501Srpaulo msg = SMK_M3; 936214501Srpaulo msgtxt = "SMK M3"; 937214501Srpaulo } else if (key_info & WPA_KEY_INFO_REQUEST) { 938214501Srpaulo msg = REQUEST; 939214501Srpaulo msgtxt = "Request"; 940214501Srpaulo } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { 941214501Srpaulo msg = GROUP_2; 942214501Srpaulo msgtxt = "2/2 Group"; 943214501Srpaulo } else if (key_data_length == 0) { 944214501Srpaulo msg = PAIRWISE_4; 945214501Srpaulo msgtxt = "4/4 Pairwise"; 946214501Srpaulo } else { 947214501Srpaulo msg = PAIRWISE_2; 948214501Srpaulo msgtxt = "2/4 Pairwise"; 949214501Srpaulo } 950214501Srpaulo 951214501Srpaulo /* TODO: key_info type validation for PeerKey */ 952214501Srpaulo if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 || 953214501Srpaulo msg == GROUP_2) { 954214501Srpaulo u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK; 955252726Srpaulo if (sm->pairwise == WPA_CIPHER_CCMP || 956252726Srpaulo sm->pairwise == WPA_CIPHER_GCMP) { 957214501Srpaulo if (wpa_use_aes_cmac(sm) && 958281806Srpaulo sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN && 959281806Srpaulo !wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) && 960214501Srpaulo ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) { 961214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 962214501Srpaulo LOGGER_WARNING, 963214501Srpaulo "advertised support for " 964214501Srpaulo "AES-128-CMAC, but did not " 965214501Srpaulo "use it"); 966214501Srpaulo return; 967214501Srpaulo } 968214501Srpaulo 969214501Srpaulo if (!wpa_use_aes_cmac(sm) && 970214501Srpaulo ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 971214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 972214501Srpaulo LOGGER_WARNING, 973214501Srpaulo "did not use HMAC-SHA1-AES " 974252726Srpaulo "with CCMP/GCMP"); 975214501Srpaulo return; 976214501Srpaulo } 977214501Srpaulo } 978281806Srpaulo 979281806Srpaulo if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) && 980281806Srpaulo ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) { 981281806Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 982281806Srpaulo "did not use EAPOL-Key descriptor version 0 as required for AKM-defined cases"); 983281806Srpaulo return; 984281806Srpaulo } 985214501Srpaulo } 986214501Srpaulo 987214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 988214501Srpaulo if (sm->req_replay_counter_used && 989214501Srpaulo os_memcmp(key->replay_counter, sm->req_replay_counter, 990214501Srpaulo WPA_REPLAY_COUNTER_LEN) <= 0) { 991214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 992214501Srpaulo "received EAPOL-Key request with " 993214501Srpaulo "replayed counter"); 994214501Srpaulo return; 995214501Srpaulo } 996214501Srpaulo } 997214501Srpaulo 998214501Srpaulo if (!(key_info & WPA_KEY_INFO_REQUEST) && 999252726Srpaulo !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) { 1000214501Srpaulo int i; 1001252726Srpaulo 1002252726Srpaulo if (msg == PAIRWISE_2 && 1003252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 1004252726Srpaulo key->replay_counter) && 1005252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 1006252726Srpaulo os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0) 1007252726Srpaulo { 1008252726Srpaulo /* 1009252726Srpaulo * Some supplicant implementations (e.g., Windows XP 1010252726Srpaulo * WZC) update SNonce for each EAPOL-Key 2/4. This 1011252726Srpaulo * breaks the workaround on accepting any of the 1012252726Srpaulo * pending requests, so allow the SNonce to be updated 1013252726Srpaulo * even if we have already sent out EAPOL-Key 3/4. 1014252726Srpaulo */ 1015252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1016252726Srpaulo "Process SNonce update from STA " 1017252726Srpaulo "based on retransmitted EAPOL-Key " 1018252726Srpaulo "1/4"); 1019252726Srpaulo sm->update_snonce = 1; 1020281806Srpaulo os_memcpy(sm->alt_SNonce, sm->SNonce, WPA_NONCE_LEN); 1021281806Srpaulo sm->alt_snonce_valid = TRUE; 1022281806Srpaulo os_memcpy(sm->alt_replay_counter, 1023281806Srpaulo sm->key_replay[0].counter, 1024281806Srpaulo WPA_REPLAY_COUNTER_LEN); 1025252726Srpaulo goto continue_processing; 1026252726Srpaulo } 1027252726Srpaulo 1028281806Srpaulo if (msg == PAIRWISE_4 && sm->alt_snonce_valid && 1029281806Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 1030281806Srpaulo os_memcmp(key->replay_counter, sm->alt_replay_counter, 1031281806Srpaulo WPA_REPLAY_COUNTER_LEN) == 0) { 1032281806Srpaulo /* 1033281806Srpaulo * Supplicant may still be using the old SNonce since 1034281806Srpaulo * there was two EAPOL-Key 2/4 messages and they had 1035281806Srpaulo * different SNonce values. 1036281806Srpaulo */ 1037281806Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1038281806Srpaulo "Try to process received EAPOL-Key 4/4 based on old Replay Counter and SNonce from an earlier EAPOL-Key 1/4"); 1039281806Srpaulo goto continue_processing; 1040281806Srpaulo } 1041281806Srpaulo 1042252726Srpaulo if (msg == PAIRWISE_2 && 1043252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 1044252726Srpaulo key->replay_counter) && 1045252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) { 1046252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1047252726Srpaulo "ignore retransmitted EAPOL-Key %s - " 1048252726Srpaulo "SNonce did not change", msgtxt); 1049252726Srpaulo } else { 1050252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1051252726Srpaulo "received EAPOL-Key %s with " 1052252726Srpaulo "unexpected replay counter", msgtxt); 1053252726Srpaulo } 1054214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 1055214501Srpaulo if (!sm->key_replay[i].valid) 1056214501Srpaulo break; 1057214501Srpaulo wpa_hexdump(MSG_DEBUG, "pending replay counter", 1058214501Srpaulo sm->key_replay[i].counter, 1059214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1060214501Srpaulo } 1061214501Srpaulo wpa_hexdump(MSG_DEBUG, "received replay counter", 1062214501Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 1063214501Srpaulo return; 1064214501Srpaulo } 1065214501Srpaulo 1066252726Srpaulocontinue_processing: 1067214501Srpaulo switch (msg) { 1068214501Srpaulo case PAIRWISE_2: 1069214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKSTART && 1070252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING && 1071252726Srpaulo (!sm->update_snonce || 1072252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) { 1073214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1074214501Srpaulo "received EAPOL-Key msg 2/4 in " 1075214501Srpaulo "invalid state (%d) - dropped", 1076214501Srpaulo sm->wpa_ptk_state); 1077214501Srpaulo return; 1078214501Srpaulo } 1079252726Srpaulo random_add_randomness(key->key_nonce, WPA_NONCE_LEN); 1080252726Srpaulo if (sm->group->reject_4way_hs_for_entropy) { 1081252726Srpaulo /* 1082252726Srpaulo * The system did not have enough entropy to generate 1083252726Srpaulo * strong random numbers. Reject the first 4-way 1084252726Srpaulo * handshake(s) and collect some entropy based on the 1085252726Srpaulo * information from it. Once enough entropy is 1086252726Srpaulo * available, the next atempt will trigger GMK/Key 1087252726Srpaulo * Counter update and the station will be allowed to 1088252726Srpaulo * continue. 1089252726Srpaulo */ 1090252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to " 1091252726Srpaulo "collect more entropy for random number " 1092252726Srpaulo "generation"); 1093252726Srpaulo random_mark_pool_ready(); 1094252726Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1095252726Srpaulo return; 1096252726Srpaulo } 1097281806Srpaulo if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) { 1098214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1099214501Srpaulo "received EAPOL-Key msg 2/4 with " 1100214501Srpaulo "invalid Key Data contents"); 1101214501Srpaulo return; 1102214501Srpaulo } 1103214501Srpaulo if (kde.rsn_ie) { 1104214501Srpaulo eapol_key_ie = kde.rsn_ie; 1105214501Srpaulo eapol_key_ie_len = kde.rsn_ie_len; 1106281806Srpaulo } else if (kde.osen) { 1107281806Srpaulo eapol_key_ie = kde.osen; 1108281806Srpaulo eapol_key_ie_len = kde.osen_len; 1109214501Srpaulo } else { 1110214501Srpaulo eapol_key_ie = kde.wpa_ie; 1111214501Srpaulo eapol_key_ie_len = kde.wpa_ie_len; 1112214501Srpaulo } 1113214501Srpaulo ft = sm->wpa == WPA_VERSION_WPA2 && 1114214501Srpaulo wpa_key_mgmt_ft(sm->wpa_key_mgmt); 1115214501Srpaulo if (sm->wpa_ie == NULL || 1116214501Srpaulo wpa_compare_rsn_ie(ft, 1117214501Srpaulo sm->wpa_ie, sm->wpa_ie_len, 1118214501Srpaulo eapol_key_ie, eapol_key_ie_len)) { 1119214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1120214501Srpaulo "WPA IE from (Re)AssocReq did not " 1121214501Srpaulo "match with msg 2/4"); 1122214501Srpaulo if (sm->wpa_ie) { 1123214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq", 1124214501Srpaulo sm->wpa_ie, sm->wpa_ie_len); 1125214501Srpaulo } 1126214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", 1127214501Srpaulo eapol_key_ie, eapol_key_ie_len); 1128214501Srpaulo /* MLME-DEAUTHENTICATE.request */ 1129214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1130214501Srpaulo return; 1131214501Srpaulo } 1132214501Srpaulo#ifdef CONFIG_IEEE80211R 1133214501Srpaulo if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { 1134214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1135214501Srpaulo return; 1136214501Srpaulo } 1137214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1138281806Srpaulo#ifdef CONFIG_P2P 1139281806Srpaulo if (kde.ip_addr_req && kde.ip_addr_req[0] && 1140281806Srpaulo wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) { 1141281806Srpaulo int idx; 1142281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: IP address requested in " 1143281806Srpaulo "EAPOL-Key exchange"); 1144281806Srpaulo idx = bitfield_get_first_zero(wpa_auth->ip_pool); 1145281806Srpaulo if (idx >= 0) { 1146281806Srpaulo u32 start = WPA_GET_BE32(wpa_auth->conf. 1147281806Srpaulo ip_addr_start); 1148281806Srpaulo bitfield_set(wpa_auth->ip_pool, idx); 1149281806Srpaulo WPA_PUT_BE32(sm->ip_addr, start + idx); 1150281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: Assigned IP " 1151281806Srpaulo "address %u.%u.%u.%u to " MACSTR, 1152281806Srpaulo sm->ip_addr[0], sm->ip_addr[1], 1153281806Srpaulo sm->ip_addr[2], sm->ip_addr[3], 1154281806Srpaulo MAC2STR(sm->addr)); 1155281806Srpaulo } 1156281806Srpaulo } 1157281806Srpaulo#endif /* CONFIG_P2P */ 1158214501Srpaulo break; 1159214501Srpaulo case PAIRWISE_4: 1160214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING || 1161214501Srpaulo !sm->PTK_valid) { 1162214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1163214501Srpaulo "received EAPOL-Key msg 4/4 in " 1164214501Srpaulo "invalid state (%d) - dropped", 1165214501Srpaulo sm->wpa_ptk_state); 1166214501Srpaulo return; 1167214501Srpaulo } 1168214501Srpaulo break; 1169214501Srpaulo case GROUP_2: 1170214501Srpaulo if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING 1171214501Srpaulo || !sm->PTK_valid) { 1172214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1173214501Srpaulo "received EAPOL-Key msg 2/2 in " 1174214501Srpaulo "invalid state (%d) - dropped", 1175214501Srpaulo sm->wpa_ptk_group_state); 1176214501Srpaulo return; 1177214501Srpaulo } 1178214501Srpaulo break; 1179214501Srpaulo#ifdef CONFIG_PEERKEY 1180214501Srpaulo case SMK_M1: 1181214501Srpaulo case SMK_M3: 1182214501Srpaulo case SMK_ERROR: 1183214501Srpaulo if (!wpa_auth->conf.peerkey) { 1184214501Srpaulo wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but " 1185214501Srpaulo "PeerKey use disabled - ignoring message"); 1186214501Srpaulo return; 1187214501Srpaulo } 1188214501Srpaulo if (!sm->PTK_valid) { 1189214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1190214501Srpaulo "received EAPOL-Key msg SMK in " 1191214501Srpaulo "invalid state - dropped"); 1192214501Srpaulo return; 1193214501Srpaulo } 1194214501Srpaulo break; 1195214501Srpaulo#else /* CONFIG_PEERKEY */ 1196214501Srpaulo case SMK_M1: 1197214501Srpaulo case SMK_M3: 1198214501Srpaulo case SMK_ERROR: 1199214501Srpaulo return; /* STSL disabled - ignore SMK messages */ 1200214501Srpaulo#endif /* CONFIG_PEERKEY */ 1201214501Srpaulo case REQUEST: 1202214501Srpaulo break; 1203214501Srpaulo } 1204214501Srpaulo 1205214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1206214501Srpaulo "received EAPOL-Key frame (%s)", msgtxt); 1207214501Srpaulo 1208214501Srpaulo if (key_info & WPA_KEY_INFO_ACK) { 1209214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1210214501Srpaulo "received invalid EAPOL-Key: Key Ack set"); 1211214501Srpaulo return; 1212214501Srpaulo } 1213214501Srpaulo 1214214501Srpaulo if (!(key_info & WPA_KEY_INFO_MIC)) { 1215214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1216214501Srpaulo "received invalid EAPOL-Key: Key MIC not set"); 1217214501Srpaulo return; 1218214501Srpaulo } 1219214501Srpaulo 1220214501Srpaulo sm->MICVerified = FALSE; 1221252726Srpaulo if (sm->PTK_valid && !sm->update_snonce) { 1222281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data, 1223281806Srpaulo data_len) && 1224281806Srpaulo (msg != PAIRWISE_4 || !sm->alt_snonce_valid || 1225281806Srpaulo wpa_try_alt_snonce(sm, data, data_len))) { 1226214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1227214501Srpaulo "received EAPOL-Key with invalid MIC"); 1228214501Srpaulo return; 1229214501Srpaulo } 1230214501Srpaulo sm->MICVerified = TRUE; 1231214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 1232252726Srpaulo sm->pending_1_of_4_timeout = 0; 1233214501Srpaulo } 1234214501Srpaulo 1235214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 1236214501Srpaulo if (sm->MICVerified) { 1237214501Srpaulo sm->req_replay_counter_used = 1; 1238214501Srpaulo os_memcpy(sm->req_replay_counter, key->replay_counter, 1239214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1240214501Srpaulo } else { 1241214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1242214501Srpaulo "received EAPOL-Key request with " 1243214501Srpaulo "invalid MIC"); 1244214501Srpaulo return; 1245214501Srpaulo } 1246214501Srpaulo 1247214501Srpaulo /* 1248214501Srpaulo * TODO: should decrypt key data field if encryption was used; 1249214501Srpaulo * even though MAC address KDE is not normally encrypted, 1250214501Srpaulo * supplicant is allowed to encrypt it. 1251214501Srpaulo */ 1252214501Srpaulo if (msg == SMK_ERROR) { 1253214501Srpaulo#ifdef CONFIG_PEERKEY 1254281806Srpaulo wpa_smk_error(wpa_auth, sm, key_data, key_data_length); 1255214501Srpaulo#endif /* CONFIG_PEERKEY */ 1256214501Srpaulo return; 1257214501Srpaulo } else if (key_info & WPA_KEY_INFO_ERROR) { 1258252726Srpaulo if (wpa_receive_error_report( 1259252726Srpaulo wpa_auth, sm, 1260252726Srpaulo !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0) 1261252726Srpaulo return; /* STA entry was removed */ 1262214501Srpaulo } else if (key_info & WPA_KEY_INFO_KEY_TYPE) { 1263214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1264214501Srpaulo "received EAPOL-Key Request for new " 1265214501Srpaulo "4-Way Handshake"); 1266214501Srpaulo wpa_request_new_ptk(sm); 1267214501Srpaulo#ifdef CONFIG_PEERKEY 1268214501Srpaulo } else if (msg == SMK_M1) { 1269281806Srpaulo wpa_smk_m1(wpa_auth, sm, key, key_data, 1270281806Srpaulo key_data_length); 1271214501Srpaulo#endif /* CONFIG_PEERKEY */ 1272214501Srpaulo } else if (key_data_length > 0 && 1273281806Srpaulo wpa_parse_kde_ies(key_data, key_data_length, 1274281806Srpaulo &kde) == 0 && 1275214501Srpaulo kde.mac_addr) { 1276214501Srpaulo } else { 1277214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1278214501Srpaulo "received EAPOL-Key Request for GTK " 1279214501Srpaulo "rekeying"); 1280214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 1281214501Srpaulo wpa_rekey_gtk(wpa_auth, NULL); 1282214501Srpaulo } 1283214501Srpaulo } else { 1284252726Srpaulo /* Do not allow the same key replay counter to be reused. */ 1285252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, 1286252726Srpaulo key->replay_counter); 1287252726Srpaulo 1288252726Srpaulo if (msg == PAIRWISE_2) { 1289252726Srpaulo /* 1290252726Srpaulo * Maintain a copy of the pending EAPOL-Key frames in 1291252726Srpaulo * case the EAPOL-Key frame was retransmitted. This is 1292252726Srpaulo * needed to allow EAPOL-Key msg 2/4 reply to another 1293252726Srpaulo * pending msg 1/4 to update the SNonce to work around 1294252726Srpaulo * unexpected supplicant behavior. 1295252726Srpaulo */ 1296252726Srpaulo os_memcpy(sm->prev_key_replay, sm->key_replay, 1297252726Srpaulo sizeof(sm->key_replay)); 1298252726Srpaulo } else { 1299252726Srpaulo os_memset(sm->prev_key_replay, 0, 1300252726Srpaulo sizeof(sm->prev_key_replay)); 1301252726Srpaulo } 1302252726Srpaulo 1303252726Srpaulo /* 1304252726Srpaulo * Make sure old valid counters are not accepted anymore and 1305252726Srpaulo * do not get copied again. 1306252726Srpaulo */ 1307252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, NULL); 1308214501Srpaulo } 1309214501Srpaulo 1310214501Srpaulo#ifdef CONFIG_PEERKEY 1311214501Srpaulo if (msg == SMK_M3) { 1312281806Srpaulo wpa_smk_m3(wpa_auth, sm, key, key_data, key_data_length); 1313214501Srpaulo return; 1314214501Srpaulo } 1315214501Srpaulo#endif /* CONFIG_PEERKEY */ 1316214501Srpaulo 1317214501Srpaulo os_free(sm->last_rx_eapol_key); 1318214501Srpaulo sm->last_rx_eapol_key = os_malloc(data_len); 1319214501Srpaulo if (sm->last_rx_eapol_key == NULL) 1320214501Srpaulo return; 1321214501Srpaulo os_memcpy(sm->last_rx_eapol_key, data, data_len); 1322214501Srpaulo sm->last_rx_eapol_key_len = data_len; 1323214501Srpaulo 1324252726Srpaulo sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE); 1325214501Srpaulo sm->EAPOLKeyReceived = TRUE; 1326214501Srpaulo sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 1327214501Srpaulo sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); 1328214501Srpaulo os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); 1329214501Srpaulo wpa_sm_step(sm); 1330214501Srpaulo} 1331214501Srpaulo 1332214501Srpaulo 1333252726Srpaulostatic int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr, 1334252726Srpaulo const u8 *gnonce, u8 *gtk, size_t gtk_len) 1335214501Srpaulo{ 1336252726Srpaulo u8 data[ETH_ALEN + WPA_NONCE_LEN + 8 + 16]; 1337252726Srpaulo u8 *pos; 1338252726Srpaulo int ret = 0; 1339214501Srpaulo 1340252726Srpaulo /* GTK = PRF-X(GMK, "Group key expansion", 1341252726Srpaulo * AA || GNonce || Time || random data) 1342252726Srpaulo * The example described in the IEEE 802.11 standard uses only AA and 1343252726Srpaulo * GNonce as inputs here. Add some more entropy since this derivation 1344252726Srpaulo * is done only at the Authenticator and as such, does not need to be 1345252726Srpaulo * exactly same. 1346252726Srpaulo */ 1347214501Srpaulo os_memcpy(data, addr, ETH_ALEN); 1348214501Srpaulo os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN); 1349252726Srpaulo pos = data + ETH_ALEN + WPA_NONCE_LEN; 1350252726Srpaulo wpa_get_ntp_timestamp(pos); 1351252726Srpaulo pos += 8; 1352252726Srpaulo if (random_get_bytes(pos, 16) < 0) 1353252726Srpaulo ret = -1; 1354214501Srpaulo 1355214501Srpaulo#ifdef CONFIG_IEEE80211W 1356252726Srpaulo sha256_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len); 1357214501Srpaulo#else /* CONFIG_IEEE80211W */ 1358252726Srpaulo if (sha1_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len) 1359252726Srpaulo < 0) 1360252726Srpaulo ret = -1; 1361214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1362214501Srpaulo 1363252726Srpaulo return ret; 1364214501Srpaulo} 1365214501Srpaulo 1366214501Srpaulo 1367214501Srpaulostatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx) 1368214501Srpaulo{ 1369214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 1370214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 1371214501Srpaulo 1372252726Srpaulo sm->pending_1_of_4_timeout = 0; 1373214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout"); 1374214501Srpaulo sm->TimeoutEvt = TRUE; 1375214501Srpaulo wpa_sm_step(sm); 1376214501Srpaulo} 1377214501Srpaulo 1378214501Srpaulo 1379214501Srpaulovoid __wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1380214501Srpaulo struct wpa_state_machine *sm, int key_info, 1381214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1382214501Srpaulo const u8 *kde, size_t kde_len, 1383214501Srpaulo int keyidx, int encr, int force_version) 1384214501Srpaulo{ 1385214501Srpaulo struct ieee802_1x_hdr *hdr; 1386214501Srpaulo struct wpa_eapol_key *key; 1387281806Srpaulo struct wpa_eapol_key_192 *key192; 1388281806Srpaulo size_t len, mic_len, keyhdrlen; 1389214501Srpaulo int alg; 1390214501Srpaulo int key_data_len, pad_len = 0; 1391214501Srpaulo u8 *buf, *pos; 1392214501Srpaulo int version, pairwise; 1393214501Srpaulo int i; 1394281806Srpaulo u8 *key_data; 1395214501Srpaulo 1396281806Srpaulo mic_len = wpa_mic_len(sm->wpa_key_mgmt); 1397281806Srpaulo keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); 1398214501Srpaulo 1399281806Srpaulo len = sizeof(struct ieee802_1x_hdr) + keyhdrlen; 1400281806Srpaulo 1401214501Srpaulo if (force_version) 1402214501Srpaulo version = force_version; 1403281806Srpaulo else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1404281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) 1405281806Srpaulo version = WPA_KEY_INFO_TYPE_AKM_DEFINED; 1406214501Srpaulo else if (wpa_use_aes_cmac(sm)) 1407214501Srpaulo version = WPA_KEY_INFO_TYPE_AES_128_CMAC; 1408252726Srpaulo else if (sm->pairwise != WPA_CIPHER_TKIP) 1409214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1410214501Srpaulo else 1411214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1412214501Srpaulo 1413281806Srpaulo pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 1414214501Srpaulo 1415214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d " 1416214501Srpaulo "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d " 1417214501Srpaulo "encr=%d)", 1418214501Srpaulo version, 1419214501Srpaulo (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0, 1420214501Srpaulo (key_info & WPA_KEY_INFO_MIC) ? 1 : 0, 1421214501Srpaulo (key_info & WPA_KEY_INFO_ACK) ? 1 : 0, 1422214501Srpaulo (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0, 1423214501Srpaulo pairwise, (unsigned long) kde_len, keyidx, encr); 1424214501Srpaulo 1425214501Srpaulo key_data_len = kde_len; 1426214501Srpaulo 1427214501Srpaulo if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1428281806Srpaulo sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1429281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) || 1430214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) { 1431214501Srpaulo pad_len = key_data_len % 8; 1432214501Srpaulo if (pad_len) 1433214501Srpaulo pad_len = 8 - pad_len; 1434214501Srpaulo key_data_len += pad_len + 8; 1435214501Srpaulo } 1436214501Srpaulo 1437214501Srpaulo len += key_data_len; 1438214501Srpaulo 1439214501Srpaulo hdr = os_zalloc(len); 1440214501Srpaulo if (hdr == NULL) 1441214501Srpaulo return; 1442214501Srpaulo hdr->version = wpa_auth->conf.eapol_version; 1443214501Srpaulo hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1444214501Srpaulo hdr->length = host_to_be16(len - sizeof(*hdr)); 1445214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1446281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 1447281806Srpaulo key_data = ((u8 *) (hdr + 1)) + keyhdrlen; 1448214501Srpaulo 1449214501Srpaulo key->type = sm->wpa == WPA_VERSION_WPA2 ? 1450214501Srpaulo EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1451214501Srpaulo key_info |= version; 1452214501Srpaulo if (encr && sm->wpa == WPA_VERSION_WPA2) 1453214501Srpaulo key_info |= WPA_KEY_INFO_ENCR_KEY_DATA; 1454214501Srpaulo if (sm->wpa != WPA_VERSION_WPA2) 1455214501Srpaulo key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT; 1456214501Srpaulo WPA_PUT_BE16(key->key_info, key_info); 1457214501Srpaulo 1458214501Srpaulo alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group; 1459252726Srpaulo WPA_PUT_BE16(key->key_length, wpa_cipher_key_len(alg)); 1460214501Srpaulo if (key_info & WPA_KEY_INFO_SMK_MESSAGE) 1461214501Srpaulo WPA_PUT_BE16(key->key_length, 0); 1462214501Srpaulo 1463214501Srpaulo /* FIX: STSL: what to use as key_replay_counter? */ 1464214501Srpaulo for (i = RSNA_MAX_EAPOL_RETRIES - 1; i > 0; i--) { 1465214501Srpaulo sm->key_replay[i].valid = sm->key_replay[i - 1].valid; 1466214501Srpaulo os_memcpy(sm->key_replay[i].counter, 1467214501Srpaulo sm->key_replay[i - 1].counter, 1468214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1469214501Srpaulo } 1470214501Srpaulo inc_byte_array(sm->key_replay[0].counter, WPA_REPLAY_COUNTER_LEN); 1471214501Srpaulo os_memcpy(key->replay_counter, sm->key_replay[0].counter, 1472214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1473281806Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", 1474281806Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 1475214501Srpaulo sm->key_replay[0].valid = TRUE; 1476214501Srpaulo 1477214501Srpaulo if (nonce) 1478214501Srpaulo os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN); 1479214501Srpaulo 1480214501Srpaulo if (key_rsc) 1481214501Srpaulo os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN); 1482214501Srpaulo 1483214501Srpaulo if (kde && !encr) { 1484281806Srpaulo os_memcpy(key_data, kde, kde_len); 1485281806Srpaulo if (mic_len == 24) 1486281806Srpaulo WPA_PUT_BE16(key192->key_data_length, kde_len); 1487281806Srpaulo else 1488281806Srpaulo WPA_PUT_BE16(key->key_data_length, kde_len); 1489214501Srpaulo } else if (encr && kde) { 1490214501Srpaulo buf = os_zalloc(key_data_len); 1491214501Srpaulo if (buf == NULL) { 1492214501Srpaulo os_free(hdr); 1493214501Srpaulo return; 1494214501Srpaulo } 1495214501Srpaulo pos = buf; 1496214501Srpaulo os_memcpy(pos, kde, kde_len); 1497214501Srpaulo pos += kde_len; 1498214501Srpaulo 1499214501Srpaulo if (pad_len) 1500214501Srpaulo *pos++ = 0xdd; 1501214501Srpaulo 1502214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data", 1503214501Srpaulo buf, key_data_len); 1504214501Srpaulo if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1505281806Srpaulo sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1506281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) || 1507214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) { 1508281806Srpaulo if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, 1509281806Srpaulo (key_data_len - 8) / 8, buf, key_data)) { 1510214501Srpaulo os_free(hdr); 1511214501Srpaulo os_free(buf); 1512214501Srpaulo return; 1513214501Srpaulo } 1514281806Srpaulo if (mic_len == 24) 1515281806Srpaulo WPA_PUT_BE16(key192->key_data_length, 1516281806Srpaulo key_data_len); 1517281806Srpaulo else 1518281806Srpaulo WPA_PUT_BE16(key->key_data_length, 1519281806Srpaulo key_data_len); 1520281806Srpaulo } else if (sm->PTK.kek_len == 16) { 1521214501Srpaulo u8 ek[32]; 1522214501Srpaulo os_memcpy(key->key_iv, 1523214501Srpaulo sm->group->Counter + WPA_NONCE_LEN - 16, 16); 1524214501Srpaulo inc_byte_array(sm->group->Counter, WPA_NONCE_LEN); 1525214501Srpaulo os_memcpy(ek, key->key_iv, 16); 1526281806Srpaulo os_memcpy(ek + 16, sm->PTK.kek, sm->PTK.kek_len); 1527281806Srpaulo os_memcpy(key_data, buf, key_data_len); 1528281806Srpaulo rc4_skip(ek, 32, 256, key_data, key_data_len); 1529281806Srpaulo if (mic_len == 24) 1530281806Srpaulo WPA_PUT_BE16(key192->key_data_length, 1531281806Srpaulo key_data_len); 1532281806Srpaulo else 1533281806Srpaulo WPA_PUT_BE16(key->key_data_length, 1534281806Srpaulo key_data_len); 1535281806Srpaulo } else { 1536281806Srpaulo os_free(hdr); 1537281806Srpaulo os_free(buf); 1538281806Srpaulo return; 1539214501Srpaulo } 1540214501Srpaulo os_free(buf); 1541214501Srpaulo } 1542214501Srpaulo 1543214501Srpaulo if (key_info & WPA_KEY_INFO_MIC) { 1544281806Srpaulo u8 *key_mic; 1545281806Srpaulo 1546214501Srpaulo if (!sm->PTK_valid) { 1547214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 1548214501Srpaulo "PTK not valid when sending EAPOL-Key " 1549214501Srpaulo "frame"); 1550214501Srpaulo os_free(hdr); 1551214501Srpaulo return; 1552214501Srpaulo } 1553281806Srpaulo 1554281806Srpaulo key_mic = key192->key_mic; /* same offset for key and key192 */ 1555281806Srpaulo wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len, 1556281806Srpaulo sm->wpa_key_mgmt, version, 1557281806Srpaulo (u8 *) hdr, len, key_mic); 1558281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 1559281806Srpaulo if (!pairwise && 1560281806Srpaulo wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 && 1561281806Srpaulo drand48() < 1562281806Srpaulo wpa_auth->conf.corrupt_gtk_rekey_mic_probability) { 1563281806Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1564281806Srpaulo "Corrupting group EAPOL-Key Key MIC"); 1565281806Srpaulo key_mic[0]++; 1566281806Srpaulo } 1567281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 1568214501Srpaulo } 1569214501Srpaulo 1570214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1571214501Srpaulo 1); 1572214501Srpaulo wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len, 1573214501Srpaulo sm->pairwise_set); 1574214501Srpaulo os_free(hdr); 1575214501Srpaulo} 1576214501Srpaulo 1577214501Srpaulo 1578214501Srpaulostatic void wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1579214501Srpaulo struct wpa_state_machine *sm, int key_info, 1580214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1581214501Srpaulo const u8 *kde, size_t kde_len, 1582214501Srpaulo int keyidx, int encr) 1583214501Srpaulo{ 1584214501Srpaulo int timeout_ms; 1585214501Srpaulo int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE; 1586214501Srpaulo int ctr; 1587214501Srpaulo 1588214501Srpaulo if (sm == NULL) 1589214501Srpaulo return; 1590214501Srpaulo 1591214501Srpaulo __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len, 1592214501Srpaulo keyidx, encr, 0); 1593214501Srpaulo 1594214501Srpaulo ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr; 1595252726Srpaulo if (ctr == 1 && wpa_auth->conf.tx_status) 1596252726Srpaulo timeout_ms = pairwise ? eapol_key_timeout_first : 1597252726Srpaulo eapol_key_timeout_first_group; 1598214501Srpaulo else 1599214501Srpaulo timeout_ms = eapol_key_timeout_subseq; 1600252726Srpaulo if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC)) 1601252726Srpaulo sm->pending_1_of_4_timeout = 1; 1602252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry " 1603252726Srpaulo "counter %d)", timeout_ms, ctr); 1604214501Srpaulo eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000, 1605214501Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 1606214501Srpaulo} 1607214501Srpaulo 1608214501Srpaulo 1609281806Srpaulostatic int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data, 1610281806Srpaulo size_t data_len) 1611214501Srpaulo{ 1612214501Srpaulo struct ieee802_1x_hdr *hdr; 1613214501Srpaulo struct wpa_eapol_key *key; 1614281806Srpaulo struct wpa_eapol_key_192 *key192; 1615214501Srpaulo u16 key_info; 1616214501Srpaulo int ret = 0; 1617281806Srpaulo u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; 1618281806Srpaulo size_t mic_len = wpa_mic_len(akmp); 1619214501Srpaulo 1620214501Srpaulo if (data_len < sizeof(*hdr) + sizeof(*key)) 1621214501Srpaulo return -1; 1622214501Srpaulo 1623214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 1624214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1625281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 1626214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 1627281806Srpaulo os_memcpy(mic, key192->key_mic, mic_len); 1628281806Srpaulo os_memset(key192->key_mic, 0, mic_len); 1629281806Srpaulo if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp, 1630281806Srpaulo key_info & WPA_KEY_INFO_TYPE_MASK, 1631281806Srpaulo data, data_len, key192->key_mic) || 1632281806Srpaulo os_memcmp_const(mic, key192->key_mic, mic_len) != 0) 1633214501Srpaulo ret = -1; 1634281806Srpaulo os_memcpy(key192->key_mic, mic, mic_len); 1635214501Srpaulo return ret; 1636214501Srpaulo} 1637214501Srpaulo 1638214501Srpaulo 1639214501Srpaulovoid wpa_remove_ptk(struct wpa_state_machine *sm) 1640214501Srpaulo{ 1641214501Srpaulo sm->PTK_valid = FALSE; 1642214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1643252726Srpaulo wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL, 0); 1644214501Srpaulo sm->pairwise_set = FALSE; 1645214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 1646214501Srpaulo} 1647214501Srpaulo 1648214501Srpaulo 1649214501Srpauloint wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event) 1650214501Srpaulo{ 1651214501Srpaulo int remove_ptk = 1; 1652214501Srpaulo 1653214501Srpaulo if (sm == NULL) 1654214501Srpaulo return -1; 1655214501Srpaulo 1656214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1657214501Srpaulo "event %d notification", event); 1658214501Srpaulo 1659214501Srpaulo switch (event) { 1660214501Srpaulo case WPA_AUTH: 1661281806Srpaulo#ifdef CONFIG_MESH 1662281806Srpaulo /* PTKs are derived through AMPE */ 1663281806Srpaulo if (wpa_auth_start_ampe(sm->wpa_auth, sm->addr)) { 1664281806Srpaulo /* not mesh */ 1665281806Srpaulo break; 1666281806Srpaulo } 1667281806Srpaulo return 0; 1668281806Srpaulo#endif /* CONFIG_MESH */ 1669214501Srpaulo case WPA_ASSOC: 1670214501Srpaulo break; 1671214501Srpaulo case WPA_DEAUTH: 1672214501Srpaulo case WPA_DISASSOC: 1673214501Srpaulo sm->DeauthenticationRequest = TRUE; 1674214501Srpaulo break; 1675214501Srpaulo case WPA_REAUTH: 1676214501Srpaulo case WPA_REAUTH_EAPOL: 1677214501Srpaulo if (!sm->started) { 1678214501Srpaulo /* 1679214501Srpaulo * When using WPS, we may end up here if the STA 1680214501Srpaulo * manages to re-associate without the previous STA 1681214501Srpaulo * entry getting removed. Consequently, we need to make 1682214501Srpaulo * sure that the WPA state machines gets initialized 1683214501Srpaulo * properly at this point. 1684214501Srpaulo */ 1685214501Srpaulo wpa_printf(MSG_DEBUG, "WPA state machine had not been " 1686214501Srpaulo "started - initialize now"); 1687214501Srpaulo sm->started = 1; 1688214501Srpaulo sm->Init = TRUE; 1689214501Srpaulo if (wpa_sm_step(sm) == 1) 1690214501Srpaulo return 1; /* should not really happen */ 1691214501Srpaulo sm->Init = FALSE; 1692214501Srpaulo sm->AuthenticationRequest = TRUE; 1693214501Srpaulo break; 1694214501Srpaulo } 1695214501Srpaulo if (sm->GUpdateStationKeys) { 1696214501Srpaulo /* 1697214501Srpaulo * Reauthentication cancels the pending group key 1698214501Srpaulo * update for this STA. 1699214501Srpaulo */ 1700214501Srpaulo sm->group->GKeyDoneStations--; 1701214501Srpaulo sm->GUpdateStationKeys = FALSE; 1702214501Srpaulo sm->PtkGroupInit = TRUE; 1703214501Srpaulo } 1704214501Srpaulo sm->ReAuthenticationRequest = TRUE; 1705214501Srpaulo break; 1706214501Srpaulo case WPA_ASSOC_FT: 1707214501Srpaulo#ifdef CONFIG_IEEE80211R 1708214501Srpaulo wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration " 1709214501Srpaulo "after association"); 1710214501Srpaulo wpa_ft_install_ptk(sm); 1711214501Srpaulo 1712214501Srpaulo /* Using FT protocol, not WPA auth state machine */ 1713214501Srpaulo sm->ft_completed = 1; 1714214501Srpaulo return 0; 1715214501Srpaulo#else /* CONFIG_IEEE80211R */ 1716214501Srpaulo break; 1717214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1718214501Srpaulo } 1719214501Srpaulo 1720214501Srpaulo#ifdef CONFIG_IEEE80211R 1721214501Srpaulo sm->ft_completed = 0; 1722214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1723214501Srpaulo 1724214501Srpaulo#ifdef CONFIG_IEEE80211W 1725214501Srpaulo if (sm->mgmt_frame_prot && event == WPA_AUTH) 1726214501Srpaulo remove_ptk = 0; 1727214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1728214501Srpaulo 1729214501Srpaulo if (remove_ptk) { 1730214501Srpaulo sm->PTK_valid = FALSE; 1731214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1732214501Srpaulo 1733214501Srpaulo if (event != WPA_REAUTH_EAPOL) 1734214501Srpaulo wpa_remove_ptk(sm); 1735214501Srpaulo } 1736214501Srpaulo 1737214501Srpaulo return wpa_sm_step(sm); 1738214501Srpaulo} 1739214501Srpaulo 1740214501Srpaulo 1741214501SrpauloSM_STATE(WPA_PTK, INITIALIZE) 1742214501Srpaulo{ 1743214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk); 1744214501Srpaulo if (sm->Init) { 1745214501Srpaulo /* Init flag is not cleared here, so avoid busy 1746214501Srpaulo * loop by claiming nothing changed. */ 1747214501Srpaulo sm->changed = FALSE; 1748214501Srpaulo } 1749214501Srpaulo 1750214501Srpaulo sm->keycount = 0; 1751214501Srpaulo if (sm->GUpdateStationKeys) 1752214501Srpaulo sm->group->GKeyDoneStations--; 1753214501Srpaulo sm->GUpdateStationKeys = FALSE; 1754214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 1755214501Srpaulo sm->PInitAKeys = FALSE; 1756214501Srpaulo if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and 1757214501Srpaulo * Local AA > Remote AA)) */) { 1758214501Srpaulo sm->Pair = TRUE; 1759214501Srpaulo } 1760214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0); 1761214501Srpaulo wpa_remove_ptk(sm); 1762214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0); 1763214501Srpaulo sm->TimeoutCtr = 0; 1764214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1765214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 1766214501Srpaulo WPA_EAPOL_authorized, 0); 1767214501Srpaulo } 1768214501Srpaulo} 1769214501Srpaulo 1770214501Srpaulo 1771214501SrpauloSM_STATE(WPA_PTK, DISCONNECT) 1772214501Srpaulo{ 1773214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); 1774214501Srpaulo sm->Disconnect = FALSE; 1775214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 1776214501Srpaulo} 1777214501Srpaulo 1778214501Srpaulo 1779214501SrpauloSM_STATE(WPA_PTK, DISCONNECTED) 1780214501Srpaulo{ 1781214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk); 1782214501Srpaulo sm->DeauthenticationRequest = FALSE; 1783214501Srpaulo} 1784214501Srpaulo 1785214501Srpaulo 1786214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION) 1787214501Srpaulo{ 1788214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk); 1789214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1790214501Srpaulo sm->PTK_valid = FALSE; 1791214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto, 1792214501Srpaulo 1); 1793214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1); 1794214501Srpaulo sm->AuthenticationRequest = FALSE; 1795214501Srpaulo} 1796214501Srpaulo 1797214501Srpaulo 1798252726Srpaulostatic void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth, 1799252726Srpaulo struct wpa_group *group) 1800252726Srpaulo{ 1801252726Srpaulo if (group->first_sta_seen) 1802252726Srpaulo return; 1803252726Srpaulo /* 1804252726Srpaulo * System has run bit further than at the time hostapd was started 1805252726Srpaulo * potentially very early during boot up. This provides better chances 1806252726Srpaulo * of collecting more randomness on embedded systems. Re-initialize the 1807252726Srpaulo * GMK and Counter here to improve their strength if there was not 1808252726Srpaulo * enough entropy available immediately after system startup. 1809252726Srpaulo */ 1810252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first " 1811252726Srpaulo "station"); 1812252726Srpaulo if (random_pool_ready() != 1) { 1813252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 1814252726Srpaulo "to proceed - reject first 4-way handshake"); 1815252726Srpaulo group->reject_4way_hs_for_entropy = TRUE; 1816252726Srpaulo } else { 1817252726Srpaulo group->first_sta_seen = TRUE; 1818252726Srpaulo group->reject_4way_hs_for_entropy = FALSE; 1819252726Srpaulo } 1820252726Srpaulo 1821252726Srpaulo wpa_group_init_gmk_and_counter(wpa_auth, group); 1822252726Srpaulo wpa_gtk_update(wpa_auth, group); 1823252726Srpaulo wpa_group_config_group_keys(wpa_auth, group); 1824252726Srpaulo} 1825252726Srpaulo 1826252726Srpaulo 1827214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION2) 1828214501Srpaulo{ 1829214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk); 1830252726Srpaulo 1831252726Srpaulo wpa_group_ensure_init(sm->wpa_auth, sm->group); 1832281806Srpaulo sm->ReAuthenticationRequest = FALSE; 1833252726Srpaulo 1834252726Srpaulo /* 1835252726Srpaulo * Definition of ANonce selection in IEEE Std 802.11i-2004 is somewhat 1836252726Srpaulo * ambiguous. The Authenticator state machine uses a counter that is 1837252726Srpaulo * incremented by one for each 4-way handshake. However, the security 1838252726Srpaulo * analysis of 4-way handshake points out that unpredictable nonces 1839252726Srpaulo * help in preventing precomputation attacks. Instead of the state 1840252726Srpaulo * machine definition, use an unpredictable nonce value here to provide 1841252726Srpaulo * stronger protection against potential precomputation attacks. 1842252726Srpaulo */ 1843252726Srpaulo if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 1844252726Srpaulo wpa_printf(MSG_ERROR, "WPA: Failed to get random data for " 1845252726Srpaulo "ANonce."); 1846281806Srpaulo sm->Disconnect = TRUE; 1847252726Srpaulo return; 1848252726Srpaulo } 1849252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, 1850252726Srpaulo WPA_NONCE_LEN); 1851214501Srpaulo /* IEEE 802.11i does not clear TimeoutCtr here, but this is more 1852214501Srpaulo * logical place than INITIALIZE since AUTHENTICATION2 can be 1853214501Srpaulo * re-entered on ReAuthenticationRequest without going through 1854214501Srpaulo * INITIALIZE. */ 1855214501Srpaulo sm->TimeoutCtr = 0; 1856214501Srpaulo} 1857214501Srpaulo 1858214501Srpaulo 1859214501SrpauloSM_STATE(WPA_PTK, INITPMK) 1860214501Srpaulo{ 1861214501Srpaulo u8 msk[2 * PMK_LEN]; 1862214501Srpaulo size_t len = 2 * PMK_LEN; 1863214501Srpaulo 1864214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk); 1865214501Srpaulo#ifdef CONFIG_IEEE80211R 1866214501Srpaulo sm->xxkey_len = 0; 1867214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1868214501Srpaulo if (sm->pmksa) { 1869214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache"); 1870214501Srpaulo os_memcpy(sm->PMK, sm->pmksa->pmk, PMK_LEN); 1871214501Srpaulo } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) { 1872214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine " 1873214501Srpaulo "(len=%lu)", (unsigned long) len); 1874214501Srpaulo os_memcpy(sm->PMK, msk, PMK_LEN); 1875214501Srpaulo#ifdef CONFIG_IEEE80211R 1876214501Srpaulo if (len >= 2 * PMK_LEN) { 1877214501Srpaulo os_memcpy(sm->xxkey, msk + PMK_LEN, PMK_LEN); 1878214501Srpaulo sm->xxkey_len = PMK_LEN; 1879214501Srpaulo } 1880214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1881214501Srpaulo } else { 1882281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Could not get PMK, get_msk: %p", 1883281806Srpaulo sm->wpa_auth->cb.get_msk); 1884281806Srpaulo sm->Disconnect = TRUE; 1885281806Srpaulo return; 1886214501Srpaulo } 1887281806Srpaulo os_memset(msk, 0, sizeof(msk)); 1888214501Srpaulo 1889214501Srpaulo sm->req_replay_counter_used = 0; 1890214501Srpaulo /* IEEE 802.11i does not set keyRun to FALSE, but not doing this 1891214501Srpaulo * will break reauthentication since EAPOL state machines may not be 1892214501Srpaulo * get into AUTHENTICATING state that clears keyRun before WPA state 1893214501Srpaulo * machine enters AUTHENTICATION2 state and goes immediately to INITPMK 1894214501Srpaulo * state and takes PMK from the previously used AAA Key. This will 1895214501Srpaulo * eventually fail in 4-Way Handshake because Supplicant uses PMK 1896214501Srpaulo * derived from the new AAA Key. Setting keyRun = FALSE here seems to 1897214501Srpaulo * be good workaround for this issue. */ 1898214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0); 1899214501Srpaulo} 1900214501Srpaulo 1901214501Srpaulo 1902214501SrpauloSM_STATE(WPA_PTK, INITPSK) 1903214501Srpaulo{ 1904214501Srpaulo const u8 *psk; 1905214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk); 1906281806Srpaulo psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, NULL); 1907214501Srpaulo if (psk) { 1908214501Srpaulo os_memcpy(sm->PMK, psk, PMK_LEN); 1909214501Srpaulo#ifdef CONFIG_IEEE80211R 1910214501Srpaulo os_memcpy(sm->xxkey, psk, PMK_LEN); 1911214501Srpaulo sm->xxkey_len = PMK_LEN; 1912214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1913214501Srpaulo } 1914214501Srpaulo sm->req_replay_counter_used = 0; 1915214501Srpaulo} 1916214501Srpaulo 1917214501Srpaulo 1918214501SrpauloSM_STATE(WPA_PTK, PTKSTART) 1919214501Srpaulo{ 1920214501Srpaulo u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL; 1921214501Srpaulo size_t pmkid_len = 0; 1922214501Srpaulo 1923214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk); 1924214501Srpaulo sm->PTKRequest = FALSE; 1925214501Srpaulo sm->TimeoutEvt = FALSE; 1926281806Srpaulo sm->alt_snonce_valid = FALSE; 1927214501Srpaulo 1928214501Srpaulo sm->TimeoutCtr++; 1929214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 1930214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 1931214501Srpaulo * immediately following this. */ 1932214501Srpaulo return; 1933214501Srpaulo } 1934214501Srpaulo 1935214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1936214501Srpaulo "sending 1/4 msg of 4-Way Handshake"); 1937214501Srpaulo /* 1938214501Srpaulo * TODO: Could add PMKID even with WPA2-PSK, but only if there is only 1939214501Srpaulo * one possible PSK for this STA. 1940214501Srpaulo */ 1941214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && 1942281806Srpaulo wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 1943281806Srpaulo sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) { 1944214501Srpaulo pmkid = buf; 1945214501Srpaulo pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 1946214501Srpaulo pmkid[0] = WLAN_EID_VENDOR_SPECIFIC; 1947214501Srpaulo pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN; 1948214501Srpaulo RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID); 1949281806Srpaulo if (sm->pmksa) { 1950214501Srpaulo os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], 1951214501Srpaulo sm->pmksa->pmkid, PMKID_LEN); 1952281806Srpaulo } else if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) { 1953281806Srpaulo /* No KCK available to derive PMKID */ 1954281806Srpaulo pmkid = NULL; 1955281806Srpaulo } else { 1956214501Srpaulo /* 1957214501Srpaulo * Calculate PMKID since no PMKSA cache entry was 1958214501Srpaulo * available with pre-calculated PMKID. 1959214501Srpaulo */ 1960214501Srpaulo rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr, 1961214501Srpaulo sm->addr, &pmkid[2 + RSN_SELECTOR_LEN], 1962214501Srpaulo wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 1963214501Srpaulo } 1964214501Srpaulo } 1965214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 1966214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL, 1967214501Srpaulo sm->ANonce, pmkid, pmkid_len, 0, 0); 1968214501Srpaulo} 1969214501Srpaulo 1970214501Srpaulo 1971281806Srpaulostatic int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, 1972281806Srpaulo const u8 *pmk, struct wpa_ptk *ptk) 1973214501Srpaulo{ 1974214501Srpaulo#ifdef CONFIG_IEEE80211R 1975214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 1976281806Srpaulo return wpa_auth_derive_ptk_ft(sm, pmk, ptk); 1977214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1978214501Srpaulo 1979281806Srpaulo return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion", 1980281806Srpaulo sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, 1981281806Srpaulo ptk, sm->wpa_key_mgmt, sm->pairwise); 1982214501Srpaulo} 1983214501Srpaulo 1984214501Srpaulo 1985214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING) 1986214501Srpaulo{ 1987214501Srpaulo struct wpa_ptk PTK; 1988214501Srpaulo int ok = 0; 1989214501Srpaulo const u8 *pmk = NULL; 1990214501Srpaulo 1991214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); 1992214501Srpaulo sm->EAPOLKeyReceived = FALSE; 1993252726Srpaulo sm->update_snonce = FALSE; 1994214501Srpaulo 1995214501Srpaulo /* WPA with IEEE 802.1X: use the derived PMK from EAP 1996214501Srpaulo * WPA-PSK: iterate through possible PSKs and select the one matching 1997214501Srpaulo * the packet */ 1998214501Srpaulo for (;;) { 1999214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2000281806Srpaulo pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, 2001281806Srpaulo sm->p2p_dev_addr, pmk); 2002214501Srpaulo if (pmk == NULL) 2003214501Srpaulo break; 2004214501Srpaulo } else 2005214501Srpaulo pmk = sm->PMK; 2006214501Srpaulo 2007281806Srpaulo wpa_derive_ptk(sm, sm->SNonce, pmk, &PTK); 2008214501Srpaulo 2009281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, 2010281806Srpaulo sm->last_rx_eapol_key, 2011214501Srpaulo sm->last_rx_eapol_key_len) == 0) { 2012214501Srpaulo ok = 1; 2013214501Srpaulo break; 2014214501Srpaulo } 2015214501Srpaulo 2016214501Srpaulo if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 2017214501Srpaulo break; 2018214501Srpaulo } 2019214501Srpaulo 2020214501Srpaulo if (!ok) { 2021214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2022214501Srpaulo "invalid MIC in msg 2/4 of 4-Way Handshake"); 2023214501Srpaulo return; 2024214501Srpaulo } 2025214501Srpaulo 2026214501Srpaulo#ifdef CONFIG_IEEE80211R 2027214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2028214501Srpaulo /* 2029214501Srpaulo * Verify that PMKR1Name from EAPOL-Key message 2/4 matches 2030214501Srpaulo * with the value we derived. 2031214501Srpaulo */ 2032281806Srpaulo if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name, 2033281806Srpaulo WPA_PMK_NAME_LEN) != 0) { 2034214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2035214501Srpaulo "PMKR1Name mismatch in FT 4-way " 2036214501Srpaulo "handshake"); 2037214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from " 2038214501Srpaulo "Supplicant", 2039214501Srpaulo sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN); 2040214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", 2041214501Srpaulo sm->pmk_r1_name, WPA_PMK_NAME_LEN); 2042214501Srpaulo return; 2043214501Srpaulo } 2044214501Srpaulo } 2045214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2046214501Srpaulo 2047252726Srpaulo sm->pending_1_of_4_timeout = 0; 2048214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 2049214501Srpaulo 2050214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2051214501Srpaulo /* PSK may have changed from the previous choice, so update 2052214501Srpaulo * state machine data based on whatever PSK was selected here. 2053214501Srpaulo */ 2054214501Srpaulo os_memcpy(sm->PMK, pmk, PMK_LEN); 2055214501Srpaulo } 2056214501Srpaulo 2057214501Srpaulo sm->MICVerified = TRUE; 2058214501Srpaulo 2059214501Srpaulo os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 2060214501Srpaulo sm->PTK_valid = TRUE; 2061214501Srpaulo} 2062214501Srpaulo 2063214501Srpaulo 2064214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING2) 2065214501Srpaulo{ 2066214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk); 2067214501Srpaulo sm->TimeoutCtr = 0; 2068214501Srpaulo} 2069214501Srpaulo 2070214501Srpaulo 2071214501Srpaulo#ifdef CONFIG_IEEE80211W 2072214501Srpaulo 2073214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 2074214501Srpaulo{ 2075214501Srpaulo if (sm->mgmt_frame_prot) { 2076281806Srpaulo size_t len; 2077281806Srpaulo len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2078281806Srpaulo return 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN + len; 2079214501Srpaulo } 2080214501Srpaulo 2081214501Srpaulo return 0; 2082214501Srpaulo} 2083214501Srpaulo 2084214501Srpaulo 2085214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 2086214501Srpaulo{ 2087214501Srpaulo struct wpa_igtk_kde igtk; 2088214501Srpaulo struct wpa_group *gsm = sm->group; 2089281806Srpaulo u8 rsc[WPA_KEY_RSC_LEN]; 2090281806Srpaulo size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2091214501Srpaulo 2092214501Srpaulo if (!sm->mgmt_frame_prot) 2093214501Srpaulo return pos; 2094214501Srpaulo 2095214501Srpaulo igtk.keyid[0] = gsm->GN_igtk; 2096214501Srpaulo igtk.keyid[1] = 0; 2097214501Srpaulo if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE || 2098281806Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, rsc) < 0) 2099214501Srpaulo os_memset(igtk.pn, 0, sizeof(igtk.pn)); 2100281806Srpaulo else 2101281806Srpaulo os_memcpy(igtk.pn, rsc, sizeof(igtk.pn)); 2102281806Srpaulo os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len); 2103252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2104252726Srpaulo /* 2105252726Srpaulo * Provide unique random IGTK to each STA to prevent use of 2106252726Srpaulo * IGTK in the BSS. 2107252726Srpaulo */ 2108281806Srpaulo if (random_get_bytes(igtk.igtk, len) < 0) 2109252726Srpaulo return pos; 2110252726Srpaulo } 2111214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, 2112281806Srpaulo (const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len, 2113281806Srpaulo NULL, 0); 2114214501Srpaulo 2115214501Srpaulo return pos; 2116214501Srpaulo} 2117214501Srpaulo 2118214501Srpaulo#else /* CONFIG_IEEE80211W */ 2119214501Srpaulo 2120214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 2121214501Srpaulo{ 2122214501Srpaulo return 0; 2123214501Srpaulo} 2124214501Srpaulo 2125214501Srpaulo 2126214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 2127214501Srpaulo{ 2128214501Srpaulo return pos; 2129214501Srpaulo} 2130214501Srpaulo 2131214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2132214501Srpaulo 2133214501Srpaulo 2134214501SrpauloSM_STATE(WPA_PTK, PTKINITNEGOTIATING) 2135214501Srpaulo{ 2136252726Srpaulo u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32]; 2137214501Srpaulo size_t gtk_len, kde_len; 2138214501Srpaulo struct wpa_group *gsm = sm->group; 2139214501Srpaulo u8 *wpa_ie; 2140214501Srpaulo int wpa_ie_len, secure, keyidx, encr = 0; 2141214501Srpaulo 2142214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); 2143214501Srpaulo sm->TimeoutEvt = FALSE; 2144214501Srpaulo 2145214501Srpaulo sm->TimeoutCtr++; 2146214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 2147214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 2148214501Srpaulo * immediately following this. */ 2149214501Srpaulo return; 2150214501Srpaulo } 2151214501Srpaulo 2152214501Srpaulo /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE], 2153214501Srpaulo GTK[GN], IGTK, [FTIE], [TIE * 2]) 2154214501Srpaulo */ 2155214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 2156214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 2157214501Srpaulo /* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */ 2158214501Srpaulo wpa_ie = sm->wpa_auth->wpa_ie; 2159214501Srpaulo wpa_ie_len = sm->wpa_auth->wpa_ie_len; 2160214501Srpaulo if (sm->wpa == WPA_VERSION_WPA && 2161214501Srpaulo (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) && 2162214501Srpaulo wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) { 2163281806Srpaulo /* WPA-only STA, remove RSN IE and possible MDIE */ 2164214501Srpaulo wpa_ie = wpa_ie + wpa_ie[1] + 2; 2165281806Srpaulo if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN) 2166281806Srpaulo wpa_ie = wpa_ie + wpa_ie[1] + 2; 2167214501Srpaulo wpa_ie_len = wpa_ie[1] + 2; 2168214501Srpaulo } 2169214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2170214501Srpaulo "sending 3/4 msg of 4-Way Handshake"); 2171214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 2172214501Srpaulo /* WPA2 send GTK in the 4-way handshake */ 2173214501Srpaulo secure = 1; 2174214501Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 2175214501Srpaulo gtk_len = gsm->GTK_len; 2176252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2177252726Srpaulo /* 2178252726Srpaulo * Provide unique random GTK to each STA to prevent use 2179252726Srpaulo * of GTK in the BSS. 2180252726Srpaulo */ 2181252726Srpaulo if (random_get_bytes(dummy_gtk, gtk_len) < 0) 2182252726Srpaulo return; 2183252726Srpaulo gtk = dummy_gtk; 2184252726Srpaulo } 2185214501Srpaulo keyidx = gsm->GN; 2186214501Srpaulo _rsc = rsc; 2187214501Srpaulo encr = 1; 2188214501Srpaulo } else { 2189214501Srpaulo /* WPA does not include GTK in msg 3/4 */ 2190214501Srpaulo secure = 0; 2191214501Srpaulo gtk = NULL; 2192214501Srpaulo gtk_len = 0; 2193214501Srpaulo keyidx = 0; 2194214501Srpaulo _rsc = NULL; 2195252726Srpaulo if (sm->rx_eapol_key_secure) { 2196252726Srpaulo /* 2197252726Srpaulo * It looks like Windows 7 supplicant tries to use 2198252726Srpaulo * Secure bit in msg 2/4 after having reported Michael 2199252726Srpaulo * MIC failure and it then rejects the 4-way handshake 2200252726Srpaulo * if msg 3/4 does not set Secure bit. Work around this 2201252726Srpaulo * by setting the Secure bit here even in the case of 2202252726Srpaulo * WPA if the supplicant used it first. 2203252726Srpaulo */ 2204252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2205252726Srpaulo "STA used Secure bit in WPA msg 2/4 - " 2206252726Srpaulo "set Secure for 3/4 as workaround"); 2207252726Srpaulo secure = 1; 2208252726Srpaulo } 2209214501Srpaulo } 2210214501Srpaulo 2211214501Srpaulo kde_len = wpa_ie_len + ieee80211w_kde_len(sm); 2212214501Srpaulo if (gtk) 2213214501Srpaulo kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len; 2214214501Srpaulo#ifdef CONFIG_IEEE80211R 2215214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2216214501Srpaulo kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */ 2217214501Srpaulo kde_len += 300; /* FTIE + 2 * TIE */ 2218214501Srpaulo } 2219214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2220281806Srpaulo#ifdef CONFIG_P2P 2221281806Srpaulo if (WPA_GET_BE32(sm->ip_addr) > 0) 2222281806Srpaulo kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4; 2223281806Srpaulo#endif /* CONFIG_P2P */ 2224214501Srpaulo kde = os_malloc(kde_len); 2225214501Srpaulo if (kde == NULL) 2226214501Srpaulo return; 2227214501Srpaulo 2228214501Srpaulo pos = kde; 2229214501Srpaulo os_memcpy(pos, wpa_ie, wpa_ie_len); 2230214501Srpaulo pos += wpa_ie_len; 2231214501Srpaulo#ifdef CONFIG_IEEE80211R 2232214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2233214501Srpaulo int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name); 2234214501Srpaulo if (res < 0) { 2235214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert " 2236214501Srpaulo "PMKR1Name into RSN IE in EAPOL-Key data"); 2237214501Srpaulo os_free(kde); 2238214501Srpaulo return; 2239214501Srpaulo } 2240214501Srpaulo pos += res; 2241214501Srpaulo } 2242214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2243214501Srpaulo if (gtk) { 2244214501Srpaulo u8 hdr[2]; 2245214501Srpaulo hdr[0] = keyidx & 0x03; 2246214501Srpaulo hdr[1] = 0; 2247214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 2248214501Srpaulo gtk, gtk_len); 2249214501Srpaulo } 2250214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 2251214501Srpaulo 2252214501Srpaulo#ifdef CONFIG_IEEE80211R 2253214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2254214501Srpaulo int res; 2255214501Srpaulo struct wpa_auth_config *conf; 2256214501Srpaulo 2257214501Srpaulo conf = &sm->wpa_auth->conf; 2258214501Srpaulo res = wpa_write_ftie(conf, conf->r0_key_holder, 2259214501Srpaulo conf->r0_key_holder_len, 2260214501Srpaulo NULL, NULL, pos, kde + kde_len - pos, 2261214501Srpaulo NULL, 0); 2262214501Srpaulo if (res < 0) { 2263214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " 2264214501Srpaulo "into EAPOL-Key Key Data"); 2265214501Srpaulo os_free(kde); 2266214501Srpaulo return; 2267214501Srpaulo } 2268214501Srpaulo pos += res; 2269214501Srpaulo 2270214501Srpaulo /* TIE[ReassociationDeadline] (TU) */ 2271214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2272214501Srpaulo *pos++ = 5; 2273214501Srpaulo *pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE; 2274214501Srpaulo WPA_PUT_LE32(pos, conf->reassociation_deadline); 2275214501Srpaulo pos += 4; 2276214501Srpaulo 2277214501Srpaulo /* TIE[KeyLifetime] (seconds) */ 2278214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2279214501Srpaulo *pos++ = 5; 2280214501Srpaulo *pos++ = WLAN_TIMEOUT_KEY_LIFETIME; 2281214501Srpaulo WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60); 2282214501Srpaulo pos += 4; 2283214501Srpaulo } 2284214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2285281806Srpaulo#ifdef CONFIG_P2P 2286281806Srpaulo if (WPA_GET_BE32(sm->ip_addr) > 0) { 2287281806Srpaulo u8 addr[3 * 4]; 2288281806Srpaulo os_memcpy(addr, sm->ip_addr, 4); 2289281806Srpaulo os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4); 2290281806Srpaulo os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4); 2291281806Srpaulo pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC, 2292281806Srpaulo addr, sizeof(addr), NULL, 0); 2293281806Srpaulo } 2294281806Srpaulo#endif /* CONFIG_P2P */ 2295214501Srpaulo 2296214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2297214501Srpaulo (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC | 2298214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | 2299214501Srpaulo WPA_KEY_INFO_KEY_TYPE, 2300214501Srpaulo _rsc, sm->ANonce, kde, pos - kde, keyidx, encr); 2301214501Srpaulo os_free(kde); 2302214501Srpaulo} 2303214501Srpaulo 2304214501Srpaulo 2305214501SrpauloSM_STATE(WPA_PTK, PTKINITDONE) 2306214501Srpaulo{ 2307214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk); 2308214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2309214501Srpaulo if (sm->Pair) { 2310252726Srpaulo enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise); 2311252726Srpaulo int klen = wpa_cipher_key_len(sm->pairwise); 2312214501Srpaulo if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, 2313281806Srpaulo sm->PTK.tk, klen)) { 2314214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 2315214501Srpaulo return; 2316214501Srpaulo } 2317214501Srpaulo /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ 2318214501Srpaulo sm->pairwise_set = TRUE; 2319214501Srpaulo 2320214501Srpaulo if (sm->wpa_auth->conf.wpa_ptk_rekey) { 2321214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 2322214501Srpaulo eloop_register_timeout(sm->wpa_auth->conf. 2323214501Srpaulo wpa_ptk_rekey, 0, wpa_rekey_ptk, 2324214501Srpaulo sm->wpa_auth, sm); 2325214501Srpaulo } 2326214501Srpaulo 2327214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2328214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2329214501Srpaulo WPA_EAPOL_authorized, 1); 2330214501Srpaulo } 2331214501Srpaulo } 2332214501Srpaulo 2333214501Srpaulo if (0 /* IBSS == TRUE */) { 2334214501Srpaulo sm->keycount++; 2335214501Srpaulo if (sm->keycount == 2) { 2336214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2337214501Srpaulo WPA_EAPOL_portValid, 1); 2338214501Srpaulo } 2339214501Srpaulo } else { 2340214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 2341214501Srpaulo 1); 2342214501Srpaulo } 2343214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0); 2344214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1); 2345214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2346214501Srpaulo sm->PInitAKeys = TRUE; 2347214501Srpaulo else 2348214501Srpaulo sm->has_GTK = TRUE; 2349214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2350214501Srpaulo "pairwise key handshake completed (%s)", 2351214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2352214501Srpaulo 2353214501Srpaulo#ifdef CONFIG_IEEE80211R 2354214501Srpaulo wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr); 2355214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2356214501Srpaulo} 2357214501Srpaulo 2358214501Srpaulo 2359214501SrpauloSM_STEP(WPA_PTK) 2360214501Srpaulo{ 2361214501Srpaulo struct wpa_authenticator *wpa_auth = sm->wpa_auth; 2362214501Srpaulo 2363214501Srpaulo if (sm->Init) 2364214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2365214501Srpaulo else if (sm->Disconnect 2366252726Srpaulo /* || FIX: dot11RSNAConfigSALifetime timeout */) { 2367252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 2368252726Srpaulo "WPA_PTK: sm->Disconnect"); 2369214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2370252726Srpaulo } 2371214501Srpaulo else if (sm->DeauthenticationRequest) 2372214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2373214501Srpaulo else if (sm->AuthenticationRequest) 2374214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION); 2375214501Srpaulo else if (sm->ReAuthenticationRequest) 2376214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2377214501Srpaulo else if (sm->PTKRequest) 2378214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2379214501Srpaulo else switch (sm->wpa_ptk_state) { 2380214501Srpaulo case WPA_PTK_INITIALIZE: 2381214501Srpaulo break; 2382214501Srpaulo case WPA_PTK_DISCONNECT: 2383214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2384214501Srpaulo break; 2385214501Srpaulo case WPA_PTK_DISCONNECTED: 2386214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2387214501Srpaulo break; 2388214501Srpaulo case WPA_PTK_AUTHENTICATION: 2389214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2390214501Srpaulo break; 2391214501Srpaulo case WPA_PTK_AUTHENTICATION2: 2392214501Srpaulo if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 2393214501Srpaulo wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2394214501Srpaulo WPA_EAPOL_keyRun) > 0) 2395214501Srpaulo SM_ENTER(WPA_PTK, INITPMK); 2396214501Srpaulo else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) 2397214501Srpaulo /* FIX: && 802.1X::keyRun */) 2398214501Srpaulo SM_ENTER(WPA_PTK, INITPSK); 2399214501Srpaulo break; 2400214501Srpaulo case WPA_PTK_INITPMK: 2401214501Srpaulo if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2402214501Srpaulo WPA_EAPOL_keyAvailable) > 0) 2403214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2404214501Srpaulo else { 2405214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2406252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2407252726Srpaulo "INITPMK - keyAvailable = false"); 2408214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2409214501Srpaulo } 2410214501Srpaulo break; 2411214501Srpaulo case WPA_PTK_INITPSK: 2412281806Srpaulo if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, 2413281806Srpaulo NULL)) 2414214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2415214501Srpaulo else { 2416214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2417214501Srpaulo "no PSK configured for the STA"); 2418214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2419214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2420214501Srpaulo } 2421214501Srpaulo break; 2422214501Srpaulo case WPA_PTK_PTKSTART: 2423214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2424214501Srpaulo sm->EAPOLKeyPairwise) 2425214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2426214501Srpaulo else if (sm->TimeoutCtr > 2427214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2428214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2429252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2430252726Srpaulo "PTKSTART: Retry limit %d reached", 2431252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2432214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2433214501Srpaulo } else if (sm->TimeoutEvt) 2434214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2435214501Srpaulo break; 2436214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING: 2437214501Srpaulo if (sm->MICVerified) 2438214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2); 2439214501Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2440214501Srpaulo sm->EAPOLKeyPairwise) 2441214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2442214501Srpaulo else if (sm->TimeoutEvt) 2443214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2444214501Srpaulo break; 2445214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING2: 2446214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2447214501Srpaulo break; 2448214501Srpaulo case WPA_PTK_PTKINITNEGOTIATING: 2449252726Srpaulo if (sm->update_snonce) 2450252726Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2451252726Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2452252726Srpaulo sm->EAPOLKeyPairwise && sm->MICVerified) 2453214501Srpaulo SM_ENTER(WPA_PTK, PTKINITDONE); 2454214501Srpaulo else if (sm->TimeoutCtr > 2455214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2456214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2457252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2458252726Srpaulo "PTKINITNEGOTIATING: Retry limit %d " 2459252726Srpaulo "reached", 2460252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2461214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2462214501Srpaulo } else if (sm->TimeoutEvt) 2463214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2464214501Srpaulo break; 2465214501Srpaulo case WPA_PTK_PTKINITDONE: 2466214501Srpaulo break; 2467214501Srpaulo } 2468214501Srpaulo} 2469214501Srpaulo 2470214501Srpaulo 2471214501SrpauloSM_STATE(WPA_PTK_GROUP, IDLE) 2472214501Srpaulo{ 2473214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group); 2474214501Srpaulo if (sm->Init) { 2475214501Srpaulo /* Init flag is not cleared here, so avoid busy 2476214501Srpaulo * loop by claiming nothing changed. */ 2477214501Srpaulo sm->changed = FALSE; 2478214501Srpaulo } 2479214501Srpaulo sm->GTimeoutCtr = 0; 2480214501Srpaulo} 2481214501Srpaulo 2482214501Srpaulo 2483214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING) 2484214501Srpaulo{ 2485214501Srpaulo u8 rsc[WPA_KEY_RSC_LEN]; 2486214501Srpaulo struct wpa_group *gsm = sm->group; 2487281806Srpaulo const u8 *kde; 2488281806Srpaulo u8 *kde_buf = NULL, *pos, hdr[2]; 2489214501Srpaulo size_t kde_len; 2490252726Srpaulo u8 *gtk, dummy_gtk[32]; 2491214501Srpaulo 2492214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group); 2493214501Srpaulo 2494214501Srpaulo sm->GTimeoutCtr++; 2495214501Srpaulo if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) { 2496214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 2497214501Srpaulo * immediately following this. */ 2498214501Srpaulo return; 2499214501Srpaulo } 2500214501Srpaulo 2501214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2502214501Srpaulo sm->PInitAKeys = FALSE; 2503214501Srpaulo sm->TimeoutEvt = FALSE; 2504214501Srpaulo /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */ 2505214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 2506214501Srpaulo if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE) 2507214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 2508214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2509214501Srpaulo "sending 1/2 msg of Group Key Handshake"); 2510214501Srpaulo 2511252726Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 2512252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2513252726Srpaulo /* 2514252726Srpaulo * Provide unique random GTK to each STA to prevent use 2515252726Srpaulo * of GTK in the BSS. 2516252726Srpaulo */ 2517252726Srpaulo if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0) 2518252726Srpaulo return; 2519252726Srpaulo gtk = dummy_gtk; 2520252726Srpaulo } 2521214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 2522214501Srpaulo kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len + 2523214501Srpaulo ieee80211w_kde_len(sm); 2524281806Srpaulo kde_buf = os_malloc(kde_len); 2525281806Srpaulo if (kde_buf == NULL) 2526214501Srpaulo return; 2527214501Srpaulo 2528281806Srpaulo kde = pos = kde_buf; 2529214501Srpaulo hdr[0] = gsm->GN & 0x03; 2530214501Srpaulo hdr[1] = 0; 2531214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 2532252726Srpaulo gtk, gsm->GTK_len); 2533214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 2534281806Srpaulo kde_len = pos - kde; 2535214501Srpaulo } else { 2536252726Srpaulo kde = gtk; 2537281806Srpaulo kde_len = gsm->GTK_len; 2538214501Srpaulo } 2539214501Srpaulo 2540214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2541214501Srpaulo WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC | 2542214501Srpaulo WPA_KEY_INFO_ACK | 2543214501Srpaulo (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0), 2544281806Srpaulo rsc, gsm->GNonce, kde, kde_len, gsm->GN, 1); 2545281806Srpaulo 2546281806Srpaulo os_free(kde_buf); 2547214501Srpaulo} 2548214501Srpaulo 2549214501Srpaulo 2550214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED) 2551214501Srpaulo{ 2552214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group); 2553214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2554214501Srpaulo if (sm->GUpdateStationKeys) 2555214501Srpaulo sm->group->GKeyDoneStations--; 2556214501Srpaulo sm->GUpdateStationKeys = FALSE; 2557214501Srpaulo sm->GTimeoutCtr = 0; 2558214501Srpaulo /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */ 2559214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2560214501Srpaulo "group key handshake completed (%s)", 2561214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2562214501Srpaulo sm->has_GTK = TRUE; 2563214501Srpaulo} 2564214501Srpaulo 2565214501Srpaulo 2566214501SrpauloSM_STATE(WPA_PTK_GROUP, KEYERROR) 2567214501Srpaulo{ 2568214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group); 2569214501Srpaulo if (sm->GUpdateStationKeys) 2570214501Srpaulo sm->group->GKeyDoneStations--; 2571214501Srpaulo sm->GUpdateStationKeys = FALSE; 2572214501Srpaulo sm->Disconnect = TRUE; 2573214501Srpaulo} 2574214501Srpaulo 2575214501Srpaulo 2576214501SrpauloSM_STEP(WPA_PTK_GROUP) 2577214501Srpaulo{ 2578214501Srpaulo if (sm->Init || sm->PtkGroupInit) { 2579214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2580214501Srpaulo sm->PtkGroupInit = FALSE; 2581214501Srpaulo } else switch (sm->wpa_ptk_group_state) { 2582214501Srpaulo case WPA_PTK_GROUP_IDLE: 2583214501Srpaulo if (sm->GUpdateStationKeys || 2584214501Srpaulo (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys)) 2585214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2586214501Srpaulo break; 2587214501Srpaulo case WPA_PTK_GROUP_REKEYNEGOTIATING: 2588214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2589214501Srpaulo !sm->EAPOLKeyPairwise && sm->MICVerified) 2590214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED); 2591214501Srpaulo else if (sm->GTimeoutCtr > 2592214501Srpaulo (int) dot11RSNAConfigGroupUpdateCount) 2593214501Srpaulo SM_ENTER(WPA_PTK_GROUP, KEYERROR); 2594214501Srpaulo else if (sm->TimeoutEvt) 2595214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2596214501Srpaulo break; 2597214501Srpaulo case WPA_PTK_GROUP_KEYERROR: 2598214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2599214501Srpaulo break; 2600214501Srpaulo case WPA_PTK_GROUP_REKEYESTABLISHED: 2601214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2602214501Srpaulo break; 2603214501Srpaulo } 2604214501Srpaulo} 2605214501Srpaulo 2606214501Srpaulo 2607214501Srpaulostatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 2608214501Srpaulo struct wpa_group *group) 2609214501Srpaulo{ 2610214501Srpaulo int ret = 0; 2611214501Srpaulo 2612214501Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2613214501Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2614252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "Group key expansion", 2615252726Srpaulo wpa_auth->addr, group->GNonce, 2616252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2617252726Srpaulo ret = -1; 2618252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GTK", 2619252726Srpaulo group->GTK[group->GN - 1], group->GTK_len); 2620214501Srpaulo 2621214501Srpaulo#ifdef CONFIG_IEEE80211W 2622214501Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2623281806Srpaulo size_t len; 2624281806Srpaulo len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 2625252726Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2626252726Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2627252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion", 2628252726Srpaulo wpa_auth->addr, group->GNonce, 2629281806Srpaulo group->IGTK[group->GN_igtk - 4], len) < 0) 2630214501Srpaulo ret = -1; 2631214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "IGTK", 2632281806Srpaulo group->IGTK[group->GN_igtk - 4], len); 2633214501Srpaulo } 2634214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2635214501Srpaulo 2636214501Srpaulo return ret; 2637214501Srpaulo} 2638214501Srpaulo 2639214501Srpaulo 2640214501Srpaulostatic void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth, 2641214501Srpaulo struct wpa_group *group) 2642214501Srpaulo{ 2643214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2644214501Srpaulo "GTK_INIT (VLAN-ID %d)", group->vlan_id); 2645214501Srpaulo group->changed = FALSE; /* GInit is not cleared here; avoid loop */ 2646214501Srpaulo group->wpa_group_state = WPA_GROUP_GTK_INIT; 2647214501Srpaulo 2648214501Srpaulo /* GTK[0..N] = 0 */ 2649214501Srpaulo os_memset(group->GTK, 0, sizeof(group->GTK)); 2650214501Srpaulo group->GN = 1; 2651214501Srpaulo group->GM = 2; 2652214501Srpaulo#ifdef CONFIG_IEEE80211W 2653214501Srpaulo group->GN_igtk = 4; 2654214501Srpaulo group->GM_igtk = 5; 2655214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2656214501Srpaulo /* GTK[GN] = CalcGTK() */ 2657214501Srpaulo wpa_gtk_update(wpa_auth, group); 2658214501Srpaulo} 2659214501Srpaulo 2660214501Srpaulo 2661214501Srpaulostatic int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx) 2662214501Srpaulo{ 2663252726Srpaulo if (ctx != NULL && ctx != sm->group) 2664252726Srpaulo return 0; 2665252726Srpaulo 2666214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) { 2667214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2668214501Srpaulo "Not in PTKINITDONE; skip Group Key update"); 2669252726Srpaulo sm->GUpdateStationKeys = FALSE; 2670214501Srpaulo return 0; 2671214501Srpaulo } 2672214501Srpaulo if (sm->GUpdateStationKeys) { 2673214501Srpaulo /* 2674252726Srpaulo * This should not really happen, so add a debug log entry. 2675252726Srpaulo * Since we clear the GKeyDoneStations before the loop, the 2676252726Srpaulo * station needs to be counted here anyway. 2677214501Srpaulo */ 2678214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2679252726Srpaulo "GUpdateStationKeys was already set when " 2680252726Srpaulo "marking station for GTK rekeying"); 2681214501Srpaulo } 2682252726Srpaulo 2683252726Srpaulo /* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */ 2684252726Srpaulo if (sm->is_wnmsleep) 2685252726Srpaulo return 0; 2686252726Srpaulo 2687252726Srpaulo sm->group->GKeyDoneStations++; 2688252726Srpaulo sm->GUpdateStationKeys = TRUE; 2689252726Srpaulo 2690214501Srpaulo wpa_sm_step(sm); 2691214501Srpaulo return 0; 2692214501Srpaulo} 2693214501Srpaulo 2694214501Srpaulo 2695252726Srpaulo#ifdef CONFIG_WNM 2696252726Srpaulo/* update GTK when exiting WNM-Sleep Mode */ 2697252726Srpaulovoid wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm) 2698252726Srpaulo{ 2699281806Srpaulo if (sm == NULL || sm->is_wnmsleep) 2700252726Srpaulo return; 2701252726Srpaulo 2702252726Srpaulo wpa_group_update_sta(sm, NULL); 2703252726Srpaulo} 2704252726Srpaulo 2705252726Srpaulo 2706252726Srpaulovoid wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag) 2707252726Srpaulo{ 2708281806Srpaulo if (sm) 2709281806Srpaulo sm->is_wnmsleep = !!flag; 2710252726Srpaulo} 2711252726Srpaulo 2712252726Srpaulo 2713252726Srpauloint wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2714252726Srpaulo{ 2715252726Srpaulo struct wpa_group *gsm = sm->group; 2716252726Srpaulo u8 *start = pos; 2717252726Srpaulo 2718252726Srpaulo /* 2719252726Srpaulo * GTK subelement: 2720252726Srpaulo * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] | 2721252726Srpaulo * Key[5..32] 2722252726Srpaulo */ 2723252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_GTK; 2724252726Srpaulo *pos++ = 11 + gsm->GTK_len; 2725252726Srpaulo /* Key ID in B0-B1 of Key Info */ 2726252726Srpaulo WPA_PUT_LE16(pos, gsm->GN & 0x03); 2727252726Srpaulo pos += 2; 2728252726Srpaulo *pos++ = gsm->GTK_len; 2729252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0) 2730252726Srpaulo return 0; 2731252726Srpaulo pos += 8; 2732252726Srpaulo os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2733252726Srpaulo pos += gsm->GTK_len; 2734252726Srpaulo 2735252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit", 2736252726Srpaulo gsm->GN); 2737252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit", 2738252726Srpaulo gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2739252726Srpaulo 2740252726Srpaulo return pos - start; 2741252726Srpaulo} 2742252726Srpaulo 2743252726Srpaulo 2744252726Srpaulo#ifdef CONFIG_IEEE80211W 2745252726Srpauloint wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2746252726Srpaulo{ 2747252726Srpaulo struct wpa_group *gsm = sm->group; 2748252726Srpaulo u8 *start = pos; 2749281806Srpaulo size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2750252726Srpaulo 2751252726Srpaulo /* 2752252726Srpaulo * IGTK subelement: 2753252726Srpaulo * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16] 2754252726Srpaulo */ 2755252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_IGTK; 2756281806Srpaulo *pos++ = 2 + 6 + len; 2757252726Srpaulo WPA_PUT_LE16(pos, gsm->GN_igtk); 2758252726Srpaulo pos += 2; 2759252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0) 2760252726Srpaulo return 0; 2761252726Srpaulo pos += 6; 2762252726Srpaulo 2763281806Srpaulo os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], len); 2764281806Srpaulo pos += len; 2765252726Srpaulo 2766252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit", 2767252726Srpaulo gsm->GN_igtk); 2768252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit", 2769281806Srpaulo gsm->IGTK[gsm->GN_igtk - 4], len); 2770252726Srpaulo 2771252726Srpaulo return pos - start; 2772252726Srpaulo} 2773252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2774252726Srpaulo#endif /* CONFIG_WNM */ 2775252726Srpaulo 2776252726Srpaulo 2777214501Srpaulostatic void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, 2778214501Srpaulo struct wpa_group *group) 2779214501Srpaulo{ 2780214501Srpaulo int tmp; 2781214501Srpaulo 2782214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2783214501Srpaulo "SETKEYS (VLAN-ID %d)", group->vlan_id); 2784214501Srpaulo group->changed = TRUE; 2785214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYS; 2786214501Srpaulo group->GTKReKey = FALSE; 2787214501Srpaulo tmp = group->GM; 2788214501Srpaulo group->GM = group->GN; 2789214501Srpaulo group->GN = tmp; 2790214501Srpaulo#ifdef CONFIG_IEEE80211W 2791214501Srpaulo tmp = group->GM_igtk; 2792214501Srpaulo group->GM_igtk = group->GN_igtk; 2793214501Srpaulo group->GN_igtk = tmp; 2794214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2795214501Srpaulo /* "GKeyDoneStations = GNoStations" is done in more robust way by 2796214501Srpaulo * counting the STAs that are marked with GUpdateStationKeys instead of 2797214501Srpaulo * including all STAs that could be in not-yet-completed state. */ 2798214501Srpaulo wpa_gtk_update(wpa_auth, group); 2799214501Srpaulo 2800252726Srpaulo if (group->GKeyDoneStations) { 2801252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected " 2802252726Srpaulo "GKeyDoneStations=%d when starting new GTK rekey", 2803252726Srpaulo group->GKeyDoneStations); 2804252726Srpaulo group->GKeyDoneStations = 0; 2805252726Srpaulo } 2806252726Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, group); 2807214501Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d", 2808214501Srpaulo group->GKeyDoneStations); 2809214501Srpaulo} 2810214501Srpaulo 2811214501Srpaulo 2812252726Srpaulostatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 2813252726Srpaulo struct wpa_group *group) 2814214501Srpaulo{ 2815252726Srpaulo int ret = 0; 2816252726Srpaulo 2817252726Srpaulo if (wpa_auth_set_key(wpa_auth, group->vlan_id, 2818252726Srpaulo wpa_cipher_to_alg(wpa_auth->conf.wpa_group), 2819252726Srpaulo broadcast_ether_addr, group->GN, 2820252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2821252726Srpaulo ret = -1; 2822252726Srpaulo 2823252726Srpaulo#ifdef CONFIG_IEEE80211W 2824281806Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2825281806Srpaulo enum wpa_alg alg; 2826281806Srpaulo size_t len; 2827281806Srpaulo 2828281806Srpaulo alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher); 2829281806Srpaulo len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 2830281806Srpaulo 2831281806Srpaulo if (ret == 0 && 2832281806Srpaulo wpa_auth_set_key(wpa_auth, group->vlan_id, alg, 2833281806Srpaulo broadcast_ether_addr, group->GN_igtk, 2834281806Srpaulo group->IGTK[group->GN_igtk - 4], len) < 0) 2835281806Srpaulo ret = -1; 2836281806Srpaulo } 2837252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2838252726Srpaulo 2839252726Srpaulo return ret; 2840252726Srpaulo} 2841252726Srpaulo 2842252726Srpaulo 2843281806Srpaulostatic int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx) 2844281806Srpaulo{ 2845281806Srpaulo if (sm->group == ctx) { 2846281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR 2847281806Srpaulo " for discconnection due to fatal failure", 2848281806Srpaulo MAC2STR(sm->addr)); 2849281806Srpaulo sm->Disconnect = TRUE; 2850281806Srpaulo } 2851281806Srpaulo 2852281806Srpaulo return 0; 2853281806Srpaulo} 2854281806Srpaulo 2855281806Srpaulo 2856281806Srpaulostatic void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth, 2857281806Srpaulo struct wpa_group *group) 2858281806Srpaulo{ 2859281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE"); 2860281806Srpaulo group->changed = TRUE; 2861281806Srpaulo group->wpa_group_state = WPA_GROUP_FATAL_FAILURE; 2862281806Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group); 2863281806Srpaulo} 2864281806Srpaulo 2865281806Srpaulo 2866252726Srpaulostatic int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth, 2867252726Srpaulo struct wpa_group *group) 2868252726Srpaulo{ 2869214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2870214501Srpaulo "SETKEYSDONE (VLAN-ID %d)", group->vlan_id); 2871214501Srpaulo group->changed = TRUE; 2872214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYSDONE; 2873214501Srpaulo 2874281806Srpaulo if (wpa_group_config_group_keys(wpa_auth, group) < 0) { 2875281806Srpaulo wpa_group_fatal_failure(wpa_auth, group); 2876252726Srpaulo return -1; 2877281806Srpaulo } 2878252726Srpaulo 2879252726Srpaulo return 0; 2880214501Srpaulo} 2881214501Srpaulo 2882214501Srpaulo 2883214501Srpaulostatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 2884214501Srpaulo struct wpa_group *group) 2885214501Srpaulo{ 2886214501Srpaulo if (group->GInit) { 2887214501Srpaulo wpa_group_gtk_init(wpa_auth, group); 2888281806Srpaulo } else if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) { 2889281806Srpaulo /* Do not allow group operations */ 2890214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT && 2891214501Srpaulo group->GTKAuthenticator) { 2892214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2893214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE && 2894214501Srpaulo group->GTKReKey) { 2895214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2896214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) { 2897214501Srpaulo if (group->GKeyDoneStations == 0) 2898214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2899214501Srpaulo else if (group->GTKReKey) 2900214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2901214501Srpaulo } 2902214501Srpaulo} 2903214501Srpaulo 2904214501Srpaulo 2905214501Srpaulostatic int wpa_sm_step(struct wpa_state_machine *sm) 2906214501Srpaulo{ 2907214501Srpaulo if (sm == NULL) 2908214501Srpaulo return 0; 2909214501Srpaulo 2910214501Srpaulo if (sm->in_step_loop) { 2911214501Srpaulo /* This should not happen, but if it does, make sure we do not 2912214501Srpaulo * end up freeing the state machine too early by exiting the 2913214501Srpaulo * recursive call. */ 2914214501Srpaulo wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively"); 2915214501Srpaulo return 0; 2916214501Srpaulo } 2917214501Srpaulo 2918214501Srpaulo sm->in_step_loop = 1; 2919214501Srpaulo do { 2920214501Srpaulo if (sm->pending_deinit) 2921214501Srpaulo break; 2922214501Srpaulo 2923214501Srpaulo sm->changed = FALSE; 2924214501Srpaulo sm->wpa_auth->group->changed = FALSE; 2925214501Srpaulo 2926214501Srpaulo SM_STEP_RUN(WPA_PTK); 2927214501Srpaulo if (sm->pending_deinit) 2928214501Srpaulo break; 2929214501Srpaulo SM_STEP_RUN(WPA_PTK_GROUP); 2930214501Srpaulo if (sm->pending_deinit) 2931214501Srpaulo break; 2932214501Srpaulo wpa_group_sm_step(sm->wpa_auth, sm->group); 2933214501Srpaulo } while (sm->changed || sm->wpa_auth->group->changed); 2934214501Srpaulo sm->in_step_loop = 0; 2935214501Srpaulo 2936214501Srpaulo if (sm->pending_deinit) { 2937214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state " 2938214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 2939214501Srpaulo wpa_free_sta_sm(sm); 2940214501Srpaulo return 1; 2941214501Srpaulo } 2942214501Srpaulo return 0; 2943214501Srpaulo} 2944214501Srpaulo 2945214501Srpaulo 2946214501Srpaulostatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx) 2947214501Srpaulo{ 2948214501Srpaulo struct wpa_state_machine *sm = eloop_ctx; 2949214501Srpaulo wpa_sm_step(sm); 2950214501Srpaulo} 2951214501Srpaulo 2952214501Srpaulo 2953214501Srpaulovoid wpa_auth_sm_notify(struct wpa_state_machine *sm) 2954214501Srpaulo{ 2955214501Srpaulo if (sm == NULL) 2956214501Srpaulo return; 2957214501Srpaulo eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL); 2958214501Srpaulo} 2959214501Srpaulo 2960214501Srpaulo 2961214501Srpaulovoid wpa_gtk_rekey(struct wpa_authenticator *wpa_auth) 2962214501Srpaulo{ 2963214501Srpaulo int tmp, i; 2964214501Srpaulo struct wpa_group *group; 2965214501Srpaulo 2966214501Srpaulo if (wpa_auth == NULL) 2967214501Srpaulo return; 2968214501Srpaulo 2969214501Srpaulo group = wpa_auth->group; 2970214501Srpaulo 2971214501Srpaulo for (i = 0; i < 2; i++) { 2972214501Srpaulo tmp = group->GM; 2973214501Srpaulo group->GM = group->GN; 2974214501Srpaulo group->GN = tmp; 2975214501Srpaulo#ifdef CONFIG_IEEE80211W 2976214501Srpaulo tmp = group->GM_igtk; 2977214501Srpaulo group->GM_igtk = group->GN_igtk; 2978214501Srpaulo group->GN_igtk = tmp; 2979214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2980214501Srpaulo wpa_gtk_update(wpa_auth, group); 2981252726Srpaulo wpa_group_config_group_keys(wpa_auth, group); 2982214501Srpaulo } 2983214501Srpaulo} 2984214501Srpaulo 2985214501Srpaulo 2986214501Srpaulostatic const char * wpa_bool_txt(int bool) 2987214501Srpaulo{ 2988214501Srpaulo return bool ? "TRUE" : "FALSE"; 2989214501Srpaulo} 2990214501Srpaulo 2991214501Srpaulo 2992214501Srpaulo#define RSN_SUITE "%02x-%02x-%02x-%d" 2993214501Srpaulo#define RSN_SUITE_ARG(s) \ 2994214501Srpaulo((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff 2995214501Srpaulo 2996214501Srpauloint wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen) 2997214501Srpaulo{ 2998214501Srpaulo int len = 0, ret; 2999214501Srpaulo char pmkid_txt[PMKID_LEN * 2 + 1]; 3000252726Srpaulo#ifdef CONFIG_RSN_PREAUTH 3001252726Srpaulo const int preauth = 1; 3002252726Srpaulo#else /* CONFIG_RSN_PREAUTH */ 3003252726Srpaulo const int preauth = 0; 3004252726Srpaulo#endif /* CONFIG_RSN_PREAUTH */ 3005214501Srpaulo 3006214501Srpaulo if (wpa_auth == NULL) 3007214501Srpaulo return len; 3008214501Srpaulo 3009214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 3010214501Srpaulo "dot11RSNAOptionImplemented=TRUE\n" 3011252726Srpaulo "dot11RSNAPreauthenticationImplemented=%s\n" 3012214501Srpaulo "dot11RSNAEnabled=%s\n" 3013214501Srpaulo "dot11RSNAPreauthenticationEnabled=%s\n", 3014252726Srpaulo wpa_bool_txt(preauth), 3015214501Srpaulo wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN), 3016214501Srpaulo wpa_bool_txt(wpa_auth->conf.rsn_preauth)); 3017281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3018214501Srpaulo return len; 3019214501Srpaulo len += ret; 3020214501Srpaulo 3021214501Srpaulo wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), 3022214501Srpaulo wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN); 3023214501Srpaulo 3024214501Srpaulo ret = os_snprintf( 3025214501Srpaulo buf + len, buflen - len, 3026214501Srpaulo "dot11RSNAConfigVersion=%u\n" 3027214501Srpaulo "dot11RSNAConfigPairwiseKeysSupported=9999\n" 3028214501Srpaulo /* FIX: dot11RSNAConfigGroupCipher */ 3029214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyMethod */ 3030214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyTime */ 3031214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyPackets */ 3032214501Srpaulo "dot11RSNAConfigGroupRekeyStrict=%u\n" 3033214501Srpaulo "dot11RSNAConfigGroupUpdateCount=%u\n" 3034214501Srpaulo "dot11RSNAConfigPairwiseUpdateCount=%u\n" 3035214501Srpaulo "dot11RSNAConfigGroupCipherSize=%u\n" 3036214501Srpaulo "dot11RSNAConfigPMKLifetime=%u\n" 3037214501Srpaulo "dot11RSNAConfigPMKReauthThreshold=%u\n" 3038214501Srpaulo "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n" 3039214501Srpaulo "dot11RSNAConfigSATimeout=%u\n" 3040214501Srpaulo "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" 3041214501Srpaulo "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" 3042214501Srpaulo "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" 3043214501Srpaulo "dot11RSNAPMKIDUsed=%s\n" 3044214501Srpaulo "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" 3045214501Srpaulo "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" 3046214501Srpaulo "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" 3047214501Srpaulo "dot11RSNATKIPCounterMeasuresInvoked=%u\n" 3048214501Srpaulo "dot11RSNA4WayHandshakeFailures=%u\n" 3049214501Srpaulo "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n", 3050214501Srpaulo RSN_VERSION, 3051214501Srpaulo !!wpa_auth->conf.wpa_strict_rekey, 3052214501Srpaulo dot11RSNAConfigGroupUpdateCount, 3053214501Srpaulo dot11RSNAConfigPairwiseUpdateCount, 3054252726Srpaulo wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8, 3055214501Srpaulo dot11RSNAConfigPMKLifetime, 3056214501Srpaulo dot11RSNAConfigPMKReauthThreshold, 3057214501Srpaulo dot11RSNAConfigSATimeout, 3058214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected), 3059214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected), 3060214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected), 3061214501Srpaulo pmkid_txt, 3062214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested), 3063214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested), 3064214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested), 3065214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked, 3066214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures); 3067281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3068214501Srpaulo return len; 3069214501Srpaulo len += ret; 3070214501Srpaulo 3071214501Srpaulo /* TODO: dot11RSNAConfigPairwiseCiphersTable */ 3072214501Srpaulo /* TODO: dot11RSNAConfigAuthenticationSuitesTable */ 3073214501Srpaulo 3074214501Srpaulo /* Private MIB */ 3075214501Srpaulo ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n", 3076214501Srpaulo wpa_auth->group->wpa_group_state); 3077281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3078214501Srpaulo return len; 3079214501Srpaulo len += ret; 3080214501Srpaulo 3081214501Srpaulo return len; 3082214501Srpaulo} 3083214501Srpaulo 3084214501Srpaulo 3085214501Srpauloint wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) 3086214501Srpaulo{ 3087214501Srpaulo int len = 0, ret; 3088214501Srpaulo u32 pairwise = 0; 3089214501Srpaulo 3090214501Srpaulo if (sm == NULL) 3091214501Srpaulo return 0; 3092214501Srpaulo 3093214501Srpaulo /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */ 3094214501Srpaulo 3095214501Srpaulo /* dot11RSNAStatsEntry */ 3096214501Srpaulo 3097252726Srpaulo pairwise = wpa_cipher_to_suite(sm->wpa == WPA_VERSION_WPA2 ? 3098252726Srpaulo WPA_PROTO_RSN : WPA_PROTO_WPA, 3099252726Srpaulo sm->pairwise); 3100252726Srpaulo if (pairwise == 0) 3101214501Srpaulo return 0; 3102214501Srpaulo 3103214501Srpaulo ret = os_snprintf( 3104214501Srpaulo buf + len, buflen - len, 3105214501Srpaulo /* TODO: dot11RSNAStatsIndex */ 3106214501Srpaulo "dot11RSNAStatsSTAAddress=" MACSTR "\n" 3107214501Srpaulo "dot11RSNAStatsVersion=1\n" 3108214501Srpaulo "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n" 3109214501Srpaulo /* TODO: dot11RSNAStatsTKIPICVErrors */ 3110214501Srpaulo "dot11RSNAStatsTKIPLocalMICFailures=%u\n" 3111252726Srpaulo "dot11RSNAStatsTKIPRemoteMICFailures=%u\n" 3112214501Srpaulo /* TODO: dot11RSNAStatsCCMPReplays */ 3113214501Srpaulo /* TODO: dot11RSNAStatsCCMPDecryptErrors */ 3114214501Srpaulo /* TODO: dot11RSNAStatsTKIPReplays */, 3115214501Srpaulo MAC2STR(sm->addr), 3116214501Srpaulo RSN_SUITE_ARG(pairwise), 3117214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures, 3118214501Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures); 3119281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3120214501Srpaulo return len; 3121214501Srpaulo len += ret; 3122214501Srpaulo 3123214501Srpaulo /* Private MIB */ 3124214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 3125214501Srpaulo "hostapdWPAPTKState=%d\n" 3126214501Srpaulo "hostapdWPAPTKGroupState=%d\n", 3127214501Srpaulo sm->wpa_ptk_state, 3128214501Srpaulo sm->wpa_ptk_group_state); 3129281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3130214501Srpaulo return len; 3131214501Srpaulo len += ret; 3132214501Srpaulo 3133214501Srpaulo return len; 3134214501Srpaulo} 3135214501Srpaulo 3136214501Srpaulo 3137214501Srpaulovoid wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) 3138214501Srpaulo{ 3139214501Srpaulo if (wpa_auth) 3140214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++; 3141214501Srpaulo} 3142214501Srpaulo 3143214501Srpaulo 3144214501Srpauloint wpa_auth_pairwise_set(struct wpa_state_machine *sm) 3145214501Srpaulo{ 3146214501Srpaulo return sm && sm->pairwise_set; 3147214501Srpaulo} 3148214501Srpaulo 3149214501Srpaulo 3150214501Srpauloint wpa_auth_get_pairwise(struct wpa_state_machine *sm) 3151214501Srpaulo{ 3152214501Srpaulo return sm->pairwise; 3153214501Srpaulo} 3154214501Srpaulo 3155214501Srpaulo 3156214501Srpauloint wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm) 3157214501Srpaulo{ 3158214501Srpaulo if (sm == NULL) 3159214501Srpaulo return -1; 3160214501Srpaulo return sm->wpa_key_mgmt; 3161214501Srpaulo} 3162214501Srpaulo 3163214501Srpaulo 3164214501Srpauloint wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) 3165214501Srpaulo{ 3166214501Srpaulo if (sm == NULL) 3167214501Srpaulo return 0; 3168214501Srpaulo return sm->wpa; 3169214501Srpaulo} 3170214501Srpaulo 3171214501Srpaulo 3172214501Srpauloint wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, 3173214501Srpaulo struct rsn_pmksa_cache_entry *entry) 3174214501Srpaulo{ 3175214501Srpaulo if (sm == NULL || sm->pmksa != entry) 3176214501Srpaulo return -1; 3177214501Srpaulo sm->pmksa = NULL; 3178214501Srpaulo return 0; 3179214501Srpaulo} 3180214501Srpaulo 3181214501Srpaulo 3182214501Srpaulostruct rsn_pmksa_cache_entry * 3183214501Srpaulowpa_auth_sta_get_pmksa(struct wpa_state_machine *sm) 3184214501Srpaulo{ 3185214501Srpaulo return sm ? sm->pmksa : NULL; 3186214501Srpaulo} 3187214501Srpaulo 3188214501Srpaulo 3189214501Srpaulovoid wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm) 3190214501Srpaulo{ 3191214501Srpaulo if (sm) 3192214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures++; 3193214501Srpaulo} 3194214501Srpaulo 3195214501Srpaulo 3196214501Srpauloconst u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len) 3197214501Srpaulo{ 3198214501Srpaulo if (wpa_auth == NULL) 3199214501Srpaulo return NULL; 3200214501Srpaulo *len = wpa_auth->wpa_ie_len; 3201214501Srpaulo return wpa_auth->wpa_ie; 3202214501Srpaulo} 3203214501Srpaulo 3204214501Srpaulo 3205214501Srpauloint wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, 3206214501Srpaulo int session_timeout, struct eapol_state_machine *eapol) 3207214501Srpaulo{ 3208252726Srpaulo if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 || 3209252726Srpaulo sm->wpa_auth->conf.disable_pmksa_caching) 3210214501Srpaulo return -1; 3211214501Srpaulo 3212214501Srpaulo if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, 3213281806Srpaulo sm->PTK.kck, sm->PTK.kck_len, 3214214501Srpaulo sm->wpa_auth->addr, sm->addr, session_timeout, 3215214501Srpaulo eapol, sm->wpa_key_mgmt)) 3216214501Srpaulo return 0; 3217214501Srpaulo 3218214501Srpaulo return -1; 3219214501Srpaulo} 3220214501Srpaulo 3221214501Srpaulo 3222214501Srpauloint wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, 3223214501Srpaulo const u8 *pmk, size_t len, const u8 *sta_addr, 3224214501Srpaulo int session_timeout, 3225214501Srpaulo struct eapol_state_machine *eapol) 3226214501Srpaulo{ 3227214501Srpaulo if (wpa_auth == NULL) 3228214501Srpaulo return -1; 3229214501Srpaulo 3230281806Srpaulo if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, 3231281806Srpaulo NULL, 0, 3232281806Srpaulo wpa_auth->addr, 3233214501Srpaulo sta_addr, session_timeout, eapol, 3234214501Srpaulo WPA_KEY_MGMT_IEEE8021X)) 3235214501Srpaulo return 0; 3236214501Srpaulo 3237214501Srpaulo return -1; 3238214501Srpaulo} 3239214501Srpaulo 3240214501Srpaulo 3241281806Srpauloint wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, 3242281806Srpaulo const u8 *pmk) 3243281806Srpaulo{ 3244281806Srpaulo if (wpa_auth->conf.disable_pmksa_caching) 3245281806Srpaulo return -1; 3246281806Srpaulo 3247281806Srpaulo if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, 3248281806Srpaulo NULL, 0, 3249281806Srpaulo wpa_auth->addr, addr, 0, NULL, 3250281806Srpaulo WPA_KEY_MGMT_SAE)) 3251281806Srpaulo return 0; 3252281806Srpaulo 3253281806Srpaulo return -1; 3254281806Srpaulo} 3255281806Srpaulo 3256281806Srpaulo 3257281806Srpaulovoid wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, 3258281806Srpaulo const u8 *sta_addr) 3259281806Srpaulo{ 3260281806Srpaulo struct rsn_pmksa_cache_entry *pmksa; 3261281806Srpaulo 3262281806Srpaulo if (wpa_auth == NULL || wpa_auth->pmksa == NULL) 3263281806Srpaulo return; 3264281806Srpaulo pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL); 3265281806Srpaulo if (pmksa) { 3266281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Remove PMKSA cache entry for " 3267281806Srpaulo MACSTR " based on request", MAC2STR(sta_addr)); 3268281806Srpaulo pmksa_cache_free_entry(wpa_auth->pmksa, pmksa); 3269281806Srpaulo } 3270281806Srpaulo} 3271281806Srpaulo 3272281806Srpaulo 3273214501Srpaulostatic struct wpa_group * 3274214501Srpaulowpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) 3275214501Srpaulo{ 3276214501Srpaulo struct wpa_group *group; 3277214501Srpaulo 3278214501Srpaulo if (wpa_auth == NULL || wpa_auth->group == NULL) 3279214501Srpaulo return NULL; 3280214501Srpaulo 3281214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d", 3282214501Srpaulo vlan_id); 3283252726Srpaulo group = wpa_group_init(wpa_auth, vlan_id, 0); 3284214501Srpaulo if (group == NULL) 3285214501Srpaulo return NULL; 3286214501Srpaulo 3287214501Srpaulo group->next = wpa_auth->group->next; 3288214501Srpaulo wpa_auth->group->next = group; 3289214501Srpaulo 3290214501Srpaulo return group; 3291214501Srpaulo} 3292214501Srpaulo 3293214501Srpaulo 3294214501Srpauloint wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id) 3295214501Srpaulo{ 3296214501Srpaulo struct wpa_group *group; 3297214501Srpaulo 3298214501Srpaulo if (sm == NULL || sm->wpa_auth == NULL) 3299214501Srpaulo return 0; 3300214501Srpaulo 3301214501Srpaulo group = sm->wpa_auth->group; 3302214501Srpaulo while (group) { 3303214501Srpaulo if (group->vlan_id == vlan_id) 3304214501Srpaulo break; 3305214501Srpaulo group = group->next; 3306214501Srpaulo } 3307214501Srpaulo 3308214501Srpaulo if (group == NULL) { 3309214501Srpaulo group = wpa_auth_add_group(sm->wpa_auth, vlan_id); 3310214501Srpaulo if (group == NULL) 3311214501Srpaulo return -1; 3312214501Srpaulo } 3313214501Srpaulo 3314214501Srpaulo if (sm->group == group) 3315214501Srpaulo return 0; 3316214501Srpaulo 3317281806Srpaulo if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 3318281806Srpaulo return -1; 3319281806Srpaulo 3320214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state " 3321214501Srpaulo "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id); 3322214501Srpaulo 3323214501Srpaulo sm->group = group; 3324214501Srpaulo return 0; 3325214501Srpaulo} 3326252726Srpaulo 3327252726Srpaulo 3328252726Srpaulovoid wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, 3329252726Srpaulo struct wpa_state_machine *sm, int ack) 3330252726Srpaulo{ 3331252726Srpaulo if (wpa_auth == NULL || sm == NULL) 3332252726Srpaulo return; 3333252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR 3334252726Srpaulo " ack=%d", MAC2STR(sm->addr), ack); 3335252726Srpaulo if (sm->pending_1_of_4_timeout && ack) { 3336252726Srpaulo /* 3337252726Srpaulo * Some deployed supplicant implementations update their SNonce 3338252726Srpaulo * for each EAPOL-Key 2/4 message even within the same 4-way 3339252726Srpaulo * handshake and then fail to use the first SNonce when 3340252726Srpaulo * deriving the PTK. This results in unsuccessful 4-way 3341252726Srpaulo * handshake whenever the relatively short initial timeout is 3342252726Srpaulo * reached and EAPOL-Key 1/4 is retransmitted. Try to work 3343252726Srpaulo * around this by increasing the timeout now that we know that 3344252726Srpaulo * the station has received the frame. 3345252726Srpaulo */ 3346252726Srpaulo int timeout_ms = eapol_key_timeout_subseq; 3347252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 " 3348252726Srpaulo "timeout by %u ms because of acknowledged frame", 3349252726Srpaulo timeout_ms); 3350252726Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 3351252726Srpaulo eloop_register_timeout(timeout_ms / 1000, 3352252726Srpaulo (timeout_ms % 1000) * 1000, 3353252726Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 3354252726Srpaulo } 3355252726Srpaulo} 3356252726Srpaulo 3357252726Srpaulo 3358252726Srpauloint wpa_auth_uses_sae(struct wpa_state_machine *sm) 3359252726Srpaulo{ 3360252726Srpaulo if (sm == NULL) 3361252726Srpaulo return 0; 3362252726Srpaulo return wpa_key_mgmt_sae(sm->wpa_key_mgmt); 3363252726Srpaulo} 3364281806Srpaulo 3365281806Srpaulo 3366281806Srpauloint wpa_auth_uses_ft_sae(struct wpa_state_machine *sm) 3367281806Srpaulo{ 3368281806Srpaulo if (sm == NULL) 3369281806Srpaulo return 0; 3370281806Srpaulo return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE; 3371281806Srpaulo} 3372281806Srpaulo 3373281806Srpaulo 3374281806Srpaulo#ifdef CONFIG_P2P 3375281806Srpauloint wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr) 3376281806Srpaulo{ 3377281806Srpaulo if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0) 3378281806Srpaulo return -1; 3379281806Srpaulo os_memcpy(addr, sm->ip_addr, 4); 3380281806Srpaulo return 0; 3381281806Srpaulo} 3382281806Srpaulo#endif /* CONFIG_P2P */ 3383281806Srpaulo 3384281806Srpaulo 3385281806Srpauloint wpa_auth_radius_das_disconnect_pmksa(struct wpa_authenticator *wpa_auth, 3386281806Srpaulo struct radius_das_attrs *attr) 3387281806Srpaulo{ 3388281806Srpaulo return pmksa_cache_auth_radius_das_disconnect(wpa_auth->pmksa, attr); 3389281806Srpaulo} 3390281806Srpaulo 3391281806Srpaulo 3392281806Srpaulovoid wpa_auth_reconfig_group_keys(struct wpa_authenticator *wpa_auth) 3393281806Srpaulo{ 3394281806Srpaulo struct wpa_group *group; 3395281806Srpaulo 3396281806Srpaulo if (!wpa_auth) 3397281806Srpaulo return; 3398281806Srpaulo for (group = wpa_auth->group; group; group = group->next) 3399281806Srpaulo wpa_group_config_group_keys(wpa_auth, group); 3400281806Srpaulo} 3401