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); 48289549Srpaulostatic void wpa_group_free(struct wpa_authenticator *wpa_auth, 49289549Srpaulo struct wpa_group *group); 50289549Srpaulostatic void wpa_group_get(struct wpa_authenticator *wpa_auth, 51289549Srpaulo struct wpa_group *group); 52289549Srpaulostatic void wpa_group_put(struct wpa_authenticator *wpa_auth, 53289549Srpaulo struct wpa_group *group); 54214501Srpaulo 55214501Srpaulostatic const u32 dot11RSNAConfigGroupUpdateCount = 4; 56214501Srpaulostatic const u32 dot11RSNAConfigPairwiseUpdateCount = 4; 57214501Srpaulostatic const u32 eapol_key_timeout_first = 100; /* ms */ 58214501Srpaulostatic const u32 eapol_key_timeout_subseq = 1000; /* ms */ 59252726Srpaulostatic const u32 eapol_key_timeout_first_group = 500; /* ms */ 60214501Srpaulo 61214501Srpaulo/* TODO: make these configurable */ 62214501Srpaulostatic const int dot11RSNAConfigPMKLifetime = 43200; 63214501Srpaulostatic const int dot11RSNAConfigPMKReauthThreshold = 70; 64214501Srpaulostatic const int dot11RSNAConfigSATimeout = 60; 65214501Srpaulo 66214501Srpaulo 67252726Srpaulostatic inline int wpa_auth_mic_failure_report( 68214501Srpaulo struct wpa_authenticator *wpa_auth, const u8 *addr) 69214501Srpaulo{ 70214501Srpaulo if (wpa_auth->cb.mic_failure_report) 71252726Srpaulo return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr); 72252726Srpaulo return 0; 73214501Srpaulo} 74214501Srpaulo 75214501Srpaulo 76289549Srpaulostatic inline void wpa_auth_psk_failure_report( 77289549Srpaulo struct wpa_authenticator *wpa_auth, const u8 *addr) 78289549Srpaulo{ 79289549Srpaulo if (wpa_auth->cb.psk_failure_report) 80289549Srpaulo wpa_auth->cb.psk_failure_report(wpa_auth->cb.ctx, addr); 81289549Srpaulo} 82289549Srpaulo 83289549Srpaulo 84214501Srpaulostatic inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth, 85214501Srpaulo const u8 *addr, wpa_eapol_variable var, 86214501Srpaulo int value) 87214501Srpaulo{ 88214501Srpaulo if (wpa_auth->cb.set_eapol) 89214501Srpaulo wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value); 90214501Srpaulo} 91214501Srpaulo 92214501Srpaulo 93214501Srpaulostatic inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth, 94214501Srpaulo const u8 *addr, wpa_eapol_variable var) 95214501Srpaulo{ 96214501Srpaulo if (wpa_auth->cb.get_eapol == NULL) 97214501Srpaulo return -1; 98214501Srpaulo return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var); 99214501Srpaulo} 100214501Srpaulo 101214501Srpaulo 102214501Srpaulostatic inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth, 103281806Srpaulo const u8 *addr, 104281806Srpaulo const u8 *p2p_dev_addr, 105281806Srpaulo const u8 *prev_psk) 106214501Srpaulo{ 107214501Srpaulo if (wpa_auth->cb.get_psk == NULL) 108214501Srpaulo return NULL; 109281806Srpaulo return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr, 110281806Srpaulo prev_psk); 111214501Srpaulo} 112214501Srpaulo 113214501Srpaulo 114214501Srpaulostatic inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth, 115214501Srpaulo const u8 *addr, u8 *msk, size_t *len) 116214501Srpaulo{ 117214501Srpaulo if (wpa_auth->cb.get_msk == NULL) 118214501Srpaulo return -1; 119214501Srpaulo return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len); 120214501Srpaulo} 121214501Srpaulo 122214501Srpaulo 123214501Srpaulostatic inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, 124214501Srpaulo int vlan_id, 125214501Srpaulo enum wpa_alg alg, const u8 *addr, int idx, 126214501Srpaulo u8 *key, size_t key_len) 127214501Srpaulo{ 128214501Srpaulo if (wpa_auth->cb.set_key == NULL) 129214501Srpaulo return -1; 130214501Srpaulo return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx, 131214501Srpaulo key, key_len); 132214501Srpaulo} 133214501Srpaulo 134214501Srpaulo 135214501Srpaulostatic inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, 136214501Srpaulo const u8 *addr, int idx, u8 *seq) 137214501Srpaulo{ 138214501Srpaulo if (wpa_auth->cb.get_seqnum == NULL) 139214501Srpaulo return -1; 140214501Srpaulo return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq); 141214501Srpaulo} 142214501Srpaulo 143214501Srpaulo 144214501Srpaulostatic inline int 145214501Srpaulowpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr, 146214501Srpaulo const u8 *data, size_t data_len, int encrypt) 147214501Srpaulo{ 148214501Srpaulo if (wpa_auth->cb.send_eapol == NULL) 149214501Srpaulo return -1; 150214501Srpaulo return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len, 151214501Srpaulo encrypt); 152214501Srpaulo} 153214501Srpaulo 154214501Srpaulo 155281806Srpaulo#ifdef CONFIG_MESH 156281806Srpaulostatic inline int wpa_auth_start_ampe(struct wpa_authenticator *wpa_auth, 157281806Srpaulo const u8 *addr) 158281806Srpaulo{ 159281806Srpaulo if (wpa_auth->cb.start_ampe == NULL) 160281806Srpaulo return -1; 161281806Srpaulo return wpa_auth->cb.start_ampe(wpa_auth->cb.ctx, addr); 162281806Srpaulo} 163281806Srpaulo#endif /* CONFIG_MESH */ 164281806Srpaulo 165281806Srpaulo 166214501Srpauloint wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, 167214501Srpaulo int (*cb)(struct wpa_state_machine *sm, void *ctx), 168214501Srpaulo void *cb_ctx) 169214501Srpaulo{ 170214501Srpaulo if (wpa_auth->cb.for_each_sta == NULL) 171214501Srpaulo return 0; 172214501Srpaulo return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx); 173214501Srpaulo} 174214501Srpaulo 175214501Srpaulo 176214501Srpauloint wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, 177214501Srpaulo int (*cb)(struct wpa_authenticator *a, void *ctx), 178214501Srpaulo void *cb_ctx) 179214501Srpaulo{ 180214501Srpaulo if (wpa_auth->cb.for_each_auth == NULL) 181214501Srpaulo return 0; 182214501Srpaulo return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx); 183214501Srpaulo} 184214501Srpaulo 185214501Srpaulo 186214501Srpaulovoid wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr, 187214501Srpaulo logger_level level, const char *txt) 188214501Srpaulo{ 189214501Srpaulo if (wpa_auth->cb.logger == NULL) 190214501Srpaulo return; 191214501Srpaulo wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt); 192214501Srpaulo} 193214501Srpaulo 194214501Srpaulo 195214501Srpaulovoid wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr, 196214501Srpaulo logger_level level, const char *fmt, ...) 197214501Srpaulo{ 198214501Srpaulo char *format; 199214501Srpaulo int maxlen; 200214501Srpaulo va_list ap; 201214501Srpaulo 202214501Srpaulo if (wpa_auth->cb.logger == NULL) 203214501Srpaulo return; 204214501Srpaulo 205214501Srpaulo maxlen = os_strlen(fmt) + 100; 206214501Srpaulo format = os_malloc(maxlen); 207214501Srpaulo if (!format) 208214501Srpaulo return; 209214501Srpaulo 210214501Srpaulo va_start(ap, fmt); 211214501Srpaulo vsnprintf(format, maxlen, fmt, ap); 212214501Srpaulo va_end(ap); 213214501Srpaulo 214214501Srpaulo wpa_auth_logger(wpa_auth, addr, level, format); 215214501Srpaulo 216214501Srpaulo os_free(format); 217214501Srpaulo} 218214501Srpaulo 219214501Srpaulo 220214501Srpaulostatic void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, 221214501Srpaulo const u8 *addr) 222214501Srpaulo{ 223214501Srpaulo if (wpa_auth->cb.disconnect == NULL) 224214501Srpaulo return; 225252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); 226214501Srpaulo wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr, 227214501Srpaulo WLAN_REASON_PREV_AUTH_NOT_VALID); 228214501Srpaulo} 229214501Srpaulo 230214501Srpaulo 231214501Srpaulostatic int wpa_use_aes_cmac(struct wpa_state_machine *sm) 232214501Srpaulo{ 233214501Srpaulo int ret = 0; 234214501Srpaulo#ifdef CONFIG_IEEE80211R 235214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 236214501Srpaulo ret = 1; 237214501Srpaulo#endif /* CONFIG_IEEE80211R */ 238214501Srpaulo#ifdef CONFIG_IEEE80211W 239214501Srpaulo if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt)) 240214501Srpaulo ret = 1; 241214501Srpaulo#endif /* CONFIG_IEEE80211W */ 242281806Srpaulo if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) 243281806Srpaulo ret = 1; 244214501Srpaulo return ret; 245214501Srpaulo} 246214501Srpaulo 247214501Srpaulo 248214501Srpaulostatic void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx) 249214501Srpaulo{ 250214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 251214501Srpaulo 252252726Srpaulo if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) { 253214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 254214501Srpaulo "initialization."); 255214501Srpaulo } else { 256214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd"); 257252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", 258252726Srpaulo wpa_auth->group->GMK, WPA_GMK_LEN); 259214501Srpaulo } 260214501Srpaulo 261214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 262214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 263214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 264214501Srpaulo } 265214501Srpaulo} 266214501Srpaulo 267214501Srpaulo 268214501Srpaulostatic void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx) 269214501Srpaulo{ 270214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 271289549Srpaulo struct wpa_group *group, *next; 272214501Srpaulo 273214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK"); 274289549Srpaulo group = wpa_auth->group; 275289549Srpaulo while (group) { 276289549Srpaulo wpa_group_get(wpa_auth, group); 277289549Srpaulo 278214501Srpaulo group->GTKReKey = TRUE; 279214501Srpaulo do { 280214501Srpaulo group->changed = FALSE; 281214501Srpaulo wpa_group_sm_step(wpa_auth, group); 282214501Srpaulo } while (group->changed); 283289549Srpaulo 284289549Srpaulo next = group->next; 285289549Srpaulo wpa_group_put(wpa_auth, group); 286289549Srpaulo group = next; 287214501Srpaulo } 288214501Srpaulo 289214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 290214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 291214501Srpaulo 0, wpa_rekey_gtk, wpa_auth, NULL); 292214501Srpaulo } 293214501Srpaulo} 294214501Srpaulo 295214501Srpaulo 296214501Srpaulostatic void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx) 297214501Srpaulo{ 298214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 299214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 300214501Srpaulo 301214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK"); 302214501Srpaulo wpa_request_new_ptk(sm); 303214501Srpaulo wpa_sm_step(sm); 304214501Srpaulo} 305214501Srpaulo 306214501Srpaulo 307214501Srpaulostatic int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx) 308214501Srpaulo{ 309214501Srpaulo if (sm->pmksa == ctx) 310214501Srpaulo sm->pmksa = NULL; 311214501Srpaulo return 0; 312214501Srpaulo} 313214501Srpaulo 314214501Srpaulo 315214501Srpaulostatic void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, 316214501Srpaulo void *ctx) 317214501Srpaulo{ 318214501Srpaulo struct wpa_authenticator *wpa_auth = ctx; 319214501Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry); 320214501Srpaulo} 321214501Srpaulo 322214501Srpaulo 323252726Srpaulostatic int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth, 324252726Srpaulo struct wpa_group *group) 325214501Srpaulo{ 326281806Srpaulo u8 buf[ETH_ALEN + 8 + sizeof(unsigned long)]; 327252726Srpaulo u8 rkey[32]; 328281806Srpaulo unsigned long ptr; 329252726Srpaulo 330252726Srpaulo if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0) 331252726Srpaulo return -1; 332252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", group->GMK, WPA_GMK_LEN); 333252726Srpaulo 334252726Srpaulo /* 335252726Srpaulo * Counter = PRF-256(Random number, "Init Counter", 336252726Srpaulo * Local MAC Address || Time) 337252726Srpaulo */ 338252726Srpaulo os_memcpy(buf, wpa_auth->addr, ETH_ALEN); 339252726Srpaulo wpa_get_ntp_timestamp(buf + ETH_ALEN); 340281806Srpaulo ptr = (unsigned long) group; 341281806Srpaulo os_memcpy(buf + ETH_ALEN + 8, &ptr, sizeof(ptr)); 342252726Srpaulo if (random_get_bytes(rkey, sizeof(rkey)) < 0) 343252726Srpaulo return -1; 344252726Srpaulo 345252726Srpaulo if (sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf), 346252726Srpaulo group->Counter, WPA_NONCE_LEN) < 0) 347252726Srpaulo return -1; 348252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "Key Counter", 349252726Srpaulo group->Counter, WPA_NONCE_LEN); 350252726Srpaulo 351252726Srpaulo return 0; 352214501Srpaulo} 353214501Srpaulo 354214501Srpaulo 355214501Srpaulostatic struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth, 356252726Srpaulo int vlan_id, int delay_init) 357214501Srpaulo{ 358214501Srpaulo struct wpa_group *group; 359214501Srpaulo 360214501Srpaulo group = os_zalloc(sizeof(struct wpa_group)); 361214501Srpaulo if (group == NULL) 362214501Srpaulo return NULL; 363214501Srpaulo 364214501Srpaulo group->GTKAuthenticator = TRUE; 365214501Srpaulo group->vlan_id = vlan_id; 366252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 367214501Srpaulo 368252726Srpaulo if (random_pool_ready() != 1) { 369252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 370252726Srpaulo "for secure operations - update keys later when " 371252726Srpaulo "the first station connects"); 372252726Srpaulo } 373214501Srpaulo 374252726Srpaulo /* 375252726Srpaulo * Set initial GMK/Counter value here. The actual values that will be 376252726Srpaulo * used in negotiations will be set once the first station tries to 377252726Srpaulo * connect. This allows more time for collecting additional randomness 378252726Srpaulo * on embedded devices. 379214501Srpaulo */ 380252726Srpaulo if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) { 381214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 382214501Srpaulo "initialization."); 383214501Srpaulo os_free(group); 384214501Srpaulo return NULL; 385214501Srpaulo } 386214501Srpaulo 387214501Srpaulo group->GInit = TRUE; 388252726Srpaulo if (delay_init) { 389252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start " 390252726Srpaulo "until Beacon frames have been configured"); 391252726Srpaulo /* Initialization is completed in wpa_init_keys(). */ 392252726Srpaulo } else { 393252726Srpaulo wpa_group_sm_step(wpa_auth, group); 394252726Srpaulo group->GInit = FALSE; 395252726Srpaulo wpa_group_sm_step(wpa_auth, group); 396252726Srpaulo } 397214501Srpaulo 398214501Srpaulo return group; 399214501Srpaulo} 400214501Srpaulo 401214501Srpaulo 402214501Srpaulo/** 403214501Srpaulo * wpa_init - Initialize WPA authenticator 404214501Srpaulo * @addr: Authenticator address 405214501Srpaulo * @conf: Configuration for WPA authenticator 406214501Srpaulo * @cb: Callback functions for WPA authenticator 407214501Srpaulo * Returns: Pointer to WPA authenticator data or %NULL on failure 408214501Srpaulo */ 409214501Srpaulostruct wpa_authenticator * wpa_init(const u8 *addr, 410214501Srpaulo struct wpa_auth_config *conf, 411214501Srpaulo struct wpa_auth_callbacks *cb) 412214501Srpaulo{ 413214501Srpaulo struct wpa_authenticator *wpa_auth; 414214501Srpaulo 415214501Srpaulo wpa_auth = os_zalloc(sizeof(struct wpa_authenticator)); 416214501Srpaulo if (wpa_auth == NULL) 417214501Srpaulo return NULL; 418214501Srpaulo os_memcpy(wpa_auth->addr, addr, ETH_ALEN); 419214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 420214501Srpaulo os_memcpy(&wpa_auth->cb, cb, sizeof(*cb)); 421214501Srpaulo 422214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 423214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 424214501Srpaulo os_free(wpa_auth); 425214501Srpaulo return NULL; 426214501Srpaulo } 427214501Srpaulo 428252726Srpaulo wpa_auth->group = wpa_group_init(wpa_auth, 0, 1); 429214501Srpaulo if (wpa_auth->group == NULL) { 430214501Srpaulo os_free(wpa_auth->wpa_ie); 431214501Srpaulo os_free(wpa_auth); 432214501Srpaulo return NULL; 433214501Srpaulo } 434214501Srpaulo 435214501Srpaulo wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb, 436214501Srpaulo wpa_auth); 437214501Srpaulo if (wpa_auth->pmksa == NULL) { 438214501Srpaulo wpa_printf(MSG_ERROR, "PMKSA cache initialization failed."); 439281806Srpaulo os_free(wpa_auth->group); 440214501Srpaulo os_free(wpa_auth->wpa_ie); 441214501Srpaulo os_free(wpa_auth); 442214501Srpaulo return NULL; 443214501Srpaulo } 444214501Srpaulo 445214501Srpaulo#ifdef CONFIG_IEEE80211R 446214501Srpaulo wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init(); 447214501Srpaulo if (wpa_auth->ft_pmk_cache == NULL) { 448214501Srpaulo wpa_printf(MSG_ERROR, "FT PMK cache initialization failed."); 449281806Srpaulo os_free(wpa_auth->group); 450214501Srpaulo os_free(wpa_auth->wpa_ie); 451214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 452214501Srpaulo os_free(wpa_auth); 453214501Srpaulo return NULL; 454214501Srpaulo } 455214501Srpaulo#endif /* CONFIG_IEEE80211R */ 456214501Srpaulo 457214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 458214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 459214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 460214501Srpaulo } 461214501Srpaulo 462214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 463214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0, 464214501Srpaulo wpa_rekey_gtk, wpa_auth, NULL); 465214501Srpaulo } 466214501Srpaulo 467281806Srpaulo#ifdef CONFIG_P2P 468281806Srpaulo if (WPA_GET_BE32(conf->ip_addr_start)) { 469281806Srpaulo int count = WPA_GET_BE32(conf->ip_addr_end) - 470281806Srpaulo WPA_GET_BE32(conf->ip_addr_start) + 1; 471281806Srpaulo if (count > 1000) 472281806Srpaulo count = 1000; 473281806Srpaulo if (count > 0) 474281806Srpaulo wpa_auth->ip_pool = bitfield_alloc(count); 475281806Srpaulo } 476281806Srpaulo#endif /* CONFIG_P2P */ 477281806Srpaulo 478214501Srpaulo return wpa_auth; 479214501Srpaulo} 480214501Srpaulo 481214501Srpaulo 482252726Srpauloint wpa_init_keys(struct wpa_authenticator *wpa_auth) 483252726Srpaulo{ 484252726Srpaulo struct wpa_group *group = wpa_auth->group; 485252726Srpaulo 486252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial " 487252726Srpaulo "keys"); 488252726Srpaulo wpa_group_sm_step(wpa_auth, group); 489252726Srpaulo group->GInit = FALSE; 490252726Srpaulo wpa_group_sm_step(wpa_auth, group); 491281806Srpaulo if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 492281806Srpaulo return -1; 493252726Srpaulo return 0; 494252726Srpaulo} 495252726Srpaulo 496252726Srpaulo 497214501Srpaulo/** 498214501Srpaulo * wpa_deinit - Deinitialize WPA authenticator 499214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 500214501Srpaulo */ 501214501Srpaulovoid wpa_deinit(struct wpa_authenticator *wpa_auth) 502214501Srpaulo{ 503214501Srpaulo struct wpa_group *group, *prev; 504214501Srpaulo 505214501Srpaulo eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL); 506214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 507214501Srpaulo 508214501Srpaulo#ifdef CONFIG_PEERKEY 509214501Srpaulo while (wpa_auth->stsl_negotiations) 510214501Srpaulo wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations); 511214501Srpaulo#endif /* CONFIG_PEERKEY */ 512214501Srpaulo 513214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 514214501Srpaulo 515214501Srpaulo#ifdef CONFIG_IEEE80211R 516214501Srpaulo wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache); 517214501Srpaulo wpa_auth->ft_pmk_cache = NULL; 518214501Srpaulo#endif /* CONFIG_IEEE80211R */ 519214501Srpaulo 520281806Srpaulo#ifdef CONFIG_P2P 521281806Srpaulo bitfield_free(wpa_auth->ip_pool); 522281806Srpaulo#endif /* CONFIG_P2P */ 523281806Srpaulo 524281806Srpaulo 525214501Srpaulo os_free(wpa_auth->wpa_ie); 526214501Srpaulo 527214501Srpaulo group = wpa_auth->group; 528214501Srpaulo while (group) { 529214501Srpaulo prev = group; 530214501Srpaulo group = group->next; 531214501Srpaulo os_free(prev); 532214501Srpaulo } 533214501Srpaulo 534214501Srpaulo os_free(wpa_auth); 535214501Srpaulo} 536214501Srpaulo 537214501Srpaulo 538214501Srpaulo/** 539214501Srpaulo * wpa_reconfig - Update WPA authenticator configuration 540214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 541214501Srpaulo * @conf: Configuration for WPA authenticator 542214501Srpaulo */ 543214501Srpauloint wpa_reconfig(struct wpa_authenticator *wpa_auth, 544214501Srpaulo struct wpa_auth_config *conf) 545214501Srpaulo{ 546214501Srpaulo struct wpa_group *group; 547214501Srpaulo if (wpa_auth == NULL) 548214501Srpaulo return 0; 549214501Srpaulo 550214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 551214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 552214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 553214501Srpaulo return -1; 554214501Srpaulo } 555214501Srpaulo 556214501Srpaulo /* 557214501Srpaulo * Reinitialize GTK to make sure it is suitable for the new 558214501Srpaulo * configuration. 559214501Srpaulo */ 560214501Srpaulo group = wpa_auth->group; 561252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 562214501Srpaulo group->GInit = TRUE; 563214501Srpaulo wpa_group_sm_step(wpa_auth, group); 564214501Srpaulo group->GInit = FALSE; 565214501Srpaulo wpa_group_sm_step(wpa_auth, group); 566214501Srpaulo 567214501Srpaulo return 0; 568214501Srpaulo} 569214501Srpaulo 570214501Srpaulo 571214501Srpaulostruct wpa_state_machine * 572281806Srpaulowpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr, 573281806Srpaulo const u8 *p2p_dev_addr) 574214501Srpaulo{ 575214501Srpaulo struct wpa_state_machine *sm; 576214501Srpaulo 577281806Srpaulo if (wpa_auth->group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 578281806Srpaulo return NULL; 579281806Srpaulo 580214501Srpaulo sm = os_zalloc(sizeof(struct wpa_state_machine)); 581214501Srpaulo if (sm == NULL) 582214501Srpaulo return NULL; 583214501Srpaulo os_memcpy(sm->addr, addr, ETH_ALEN); 584281806Srpaulo if (p2p_dev_addr) 585281806Srpaulo os_memcpy(sm->p2p_dev_addr, p2p_dev_addr, ETH_ALEN); 586214501Srpaulo 587214501Srpaulo sm->wpa_auth = wpa_auth; 588214501Srpaulo sm->group = wpa_auth->group; 589289549Srpaulo wpa_group_get(sm->wpa_auth, sm->group); 590214501Srpaulo 591214501Srpaulo return sm; 592214501Srpaulo} 593214501Srpaulo 594214501Srpaulo 595214501Srpauloint wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, 596214501Srpaulo struct wpa_state_machine *sm) 597214501Srpaulo{ 598214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 599214501Srpaulo return -1; 600214501Srpaulo 601214501Srpaulo#ifdef CONFIG_IEEE80211R 602214501Srpaulo if (sm->ft_completed) { 603214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 604214501Srpaulo "FT authentication already completed - do not " 605214501Srpaulo "start 4-way handshake"); 606281806Srpaulo /* Go to PTKINITDONE state to allow GTK rekeying */ 607281806Srpaulo sm->wpa_ptk_state = WPA_PTK_PTKINITDONE; 608214501Srpaulo return 0; 609214501Srpaulo } 610214501Srpaulo#endif /* CONFIG_IEEE80211R */ 611214501Srpaulo 612214501Srpaulo if (sm->started) { 613214501Srpaulo os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); 614214501Srpaulo sm->ReAuthenticationRequest = TRUE; 615214501Srpaulo return wpa_sm_step(sm); 616214501Srpaulo } 617214501Srpaulo 618214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 619214501Srpaulo "start authentication"); 620214501Srpaulo sm->started = 1; 621214501Srpaulo 622214501Srpaulo sm->Init = TRUE; 623214501Srpaulo if (wpa_sm_step(sm) == 1) 624214501Srpaulo return 1; /* should not really happen */ 625214501Srpaulo sm->Init = FALSE; 626214501Srpaulo sm->AuthenticationRequest = TRUE; 627214501Srpaulo return wpa_sm_step(sm); 628214501Srpaulo} 629214501Srpaulo 630214501Srpaulo 631214501Srpaulovoid wpa_auth_sta_no_wpa(struct wpa_state_machine *sm) 632214501Srpaulo{ 633214501Srpaulo /* WPA/RSN was not used - clear WPA state. This is needed if the STA 634214501Srpaulo * reassociates back to the same AP while the previous entry for the 635214501Srpaulo * STA has not yet been removed. */ 636214501Srpaulo if (sm == NULL) 637214501Srpaulo return; 638214501Srpaulo 639214501Srpaulo sm->wpa_key_mgmt = 0; 640214501Srpaulo} 641214501Srpaulo 642214501Srpaulo 643214501Srpaulostatic void wpa_free_sta_sm(struct wpa_state_machine *sm) 644214501Srpaulo{ 645281806Srpaulo#ifdef CONFIG_P2P 646281806Srpaulo if (WPA_GET_BE32(sm->ip_addr)) { 647281806Srpaulo u32 start; 648281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: Free assigned IP " 649281806Srpaulo "address %u.%u.%u.%u from " MACSTR, 650281806Srpaulo sm->ip_addr[0], sm->ip_addr[1], 651281806Srpaulo sm->ip_addr[2], sm->ip_addr[3], 652281806Srpaulo MAC2STR(sm->addr)); 653281806Srpaulo start = WPA_GET_BE32(sm->wpa_auth->conf.ip_addr_start); 654281806Srpaulo bitfield_clear(sm->wpa_auth->ip_pool, 655281806Srpaulo WPA_GET_BE32(sm->ip_addr) - start); 656281806Srpaulo } 657281806Srpaulo#endif /* CONFIG_P2P */ 658252726Srpaulo if (sm->GUpdateStationKeys) { 659252726Srpaulo sm->group->GKeyDoneStations--; 660252726Srpaulo sm->GUpdateStationKeys = FALSE; 661252726Srpaulo } 662214501Srpaulo#ifdef CONFIG_IEEE80211R 663214501Srpaulo os_free(sm->assoc_resp_ftie); 664281806Srpaulo wpabuf_free(sm->ft_pending_req_ies); 665214501Srpaulo#endif /* CONFIG_IEEE80211R */ 666214501Srpaulo os_free(sm->last_rx_eapol_key); 667214501Srpaulo os_free(sm->wpa_ie); 668289549Srpaulo wpa_group_put(sm->wpa_auth, sm->group); 669214501Srpaulo os_free(sm); 670214501Srpaulo} 671214501Srpaulo 672214501Srpaulo 673214501Srpaulovoid wpa_auth_sta_deinit(struct wpa_state_machine *sm) 674214501Srpaulo{ 675214501Srpaulo if (sm == NULL) 676214501Srpaulo return; 677214501Srpaulo 678214501Srpaulo if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) { 679214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 680214501Srpaulo "strict rekeying - force GTK rekey since STA " 681214501Srpaulo "is leaving"); 682214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL); 683214501Srpaulo eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth, 684214501Srpaulo NULL); 685214501Srpaulo } 686214501Srpaulo 687214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 688252726Srpaulo sm->pending_1_of_4_timeout = 0; 689214501Srpaulo eloop_cancel_timeout(wpa_sm_call_step, sm, NULL); 690214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 691214501Srpaulo if (sm->in_step_loop) { 692214501Srpaulo /* Must not free state machine while wpa_sm_step() is running. 693214501Srpaulo * Freeing will be completed in the end of wpa_sm_step(). */ 694214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state " 695214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 696214501Srpaulo sm->pending_deinit = 1; 697214501Srpaulo } else 698214501Srpaulo wpa_free_sta_sm(sm); 699214501Srpaulo} 700214501Srpaulo 701214501Srpaulo 702214501Srpaulostatic void wpa_request_new_ptk(struct wpa_state_machine *sm) 703214501Srpaulo{ 704214501Srpaulo if (sm == NULL) 705214501Srpaulo return; 706214501Srpaulo 707214501Srpaulo sm->PTKRequest = TRUE; 708214501Srpaulo sm->PTK_valid = 0; 709214501Srpaulo} 710214501Srpaulo 711214501Srpaulo 712252726Srpaulostatic int wpa_replay_counter_valid(struct wpa_key_replay_counter *ctr, 713214501Srpaulo const u8 *replay_counter) 714214501Srpaulo{ 715214501Srpaulo int i; 716214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 717252726Srpaulo if (!ctr[i].valid) 718214501Srpaulo break; 719252726Srpaulo if (os_memcmp(replay_counter, ctr[i].counter, 720214501Srpaulo WPA_REPLAY_COUNTER_LEN) == 0) 721214501Srpaulo return 1; 722214501Srpaulo } 723214501Srpaulo return 0; 724214501Srpaulo} 725214501Srpaulo 726214501Srpaulo 727252726Srpaulostatic void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr, 728252726Srpaulo const u8 *replay_counter) 729252726Srpaulo{ 730252726Srpaulo int i; 731252726Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 732252726Srpaulo if (ctr[i].valid && 733252726Srpaulo (replay_counter == NULL || 734252726Srpaulo os_memcmp(replay_counter, ctr[i].counter, 735252726Srpaulo WPA_REPLAY_COUNTER_LEN) == 0)) 736252726Srpaulo ctr[i].valid = FALSE; 737252726Srpaulo } 738252726Srpaulo} 739252726Srpaulo 740252726Srpaulo 741214501Srpaulo#ifdef CONFIG_IEEE80211R 742214501Srpaulostatic int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth, 743214501Srpaulo struct wpa_state_machine *sm, 744214501Srpaulo struct wpa_eapol_ie_parse *kde) 745214501Srpaulo{ 746214501Srpaulo struct wpa_ie_data ie; 747214501Srpaulo struct rsn_mdie *mdie; 748214501Srpaulo 749214501Srpaulo if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 || 750214501Srpaulo ie.num_pmkid != 1 || ie.pmkid == NULL) { 751214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in " 752214501Srpaulo "FT 4-way handshake message 2/4"); 753214501Srpaulo return -1; 754214501Srpaulo } 755214501Srpaulo 756214501Srpaulo os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN); 757214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant", 758214501Srpaulo sm->sup_pmk_r1_name, PMKID_LEN); 759214501Srpaulo 760214501Srpaulo if (!kde->mdie || !kde->ftie) { 761214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake " 762214501Srpaulo "message 2/4", kde->mdie ? "FTIE" : "MDIE"); 763214501Srpaulo return -1; 764214501Srpaulo } 765214501Srpaulo 766214501Srpaulo mdie = (struct rsn_mdie *) (kde->mdie + 2); 767214501Srpaulo if (kde->mdie[1] < sizeof(struct rsn_mdie) || 768214501Srpaulo os_memcmp(wpa_auth->conf.mobility_domain, mdie->mobility_domain, 769214501Srpaulo MOBILITY_DOMAIN_ID_LEN) != 0) { 770214501Srpaulo wpa_printf(MSG_DEBUG, "FT: MDIE mismatch"); 771214501Srpaulo return -1; 772214501Srpaulo } 773214501Srpaulo 774214501Srpaulo if (sm->assoc_resp_ftie && 775214501Srpaulo (kde->ftie[1] != sm->assoc_resp_ftie[1] || 776214501Srpaulo os_memcmp(kde->ftie, sm->assoc_resp_ftie, 777214501Srpaulo 2 + sm->assoc_resp_ftie[1]) != 0)) { 778214501Srpaulo wpa_printf(MSG_DEBUG, "FT: FTIE mismatch"); 779214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 2/4", 780214501Srpaulo kde->ftie, kde->ftie_len); 781214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)AssocResp", 782214501Srpaulo sm->assoc_resp_ftie, 2 + sm->assoc_resp_ftie[1]); 783214501Srpaulo return -1; 784214501Srpaulo } 785214501Srpaulo 786214501Srpaulo return 0; 787214501Srpaulo} 788214501Srpaulo#endif /* CONFIG_IEEE80211R */ 789214501Srpaulo 790214501Srpaulo 791252726Srpaulostatic int wpa_receive_error_report(struct wpa_authenticator *wpa_auth, 792252726Srpaulo struct wpa_state_machine *sm, int group) 793252726Srpaulo{ 794252726Srpaulo /* Supplicant reported a Michael MIC error */ 795252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 796252726Srpaulo "received EAPOL-Key Error Request " 797252726Srpaulo "(STA detected Michael MIC failure (group=%d))", 798252726Srpaulo group); 799252726Srpaulo 800252726Srpaulo if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) { 801252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 802252726Srpaulo "ignore Michael MIC failure report since " 803252726Srpaulo "group cipher is not TKIP"); 804252726Srpaulo } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) { 805252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 806252726Srpaulo "ignore Michael MIC failure report since " 807252726Srpaulo "pairwise cipher is not TKIP"); 808252726Srpaulo } else { 809252726Srpaulo if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0) 810252726Srpaulo return 1; /* STA entry was removed */ 811252726Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures++; 812252726Srpaulo wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++; 813252726Srpaulo } 814252726Srpaulo 815252726Srpaulo /* 816252726Srpaulo * Error report is not a request for a new key handshake, but since 817252726Srpaulo * Authenticator may do it, let's change the keys now anyway. 818252726Srpaulo */ 819252726Srpaulo wpa_request_new_ptk(sm); 820252726Srpaulo return 0; 821252726Srpaulo} 822252726Srpaulo 823252726Srpaulo 824281806Srpaulostatic int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data, 825281806Srpaulo size_t data_len) 826281806Srpaulo{ 827281806Srpaulo struct wpa_ptk PTK; 828281806Srpaulo int ok = 0; 829281806Srpaulo const u8 *pmk = NULL; 830281806Srpaulo 831281806Srpaulo for (;;) { 832281806Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 833281806Srpaulo pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, 834281806Srpaulo sm->p2p_dev_addr, pmk); 835281806Srpaulo if (pmk == NULL) 836281806Srpaulo break; 837281806Srpaulo } else 838281806Srpaulo pmk = sm->PMK; 839281806Srpaulo 840281806Srpaulo wpa_derive_ptk(sm, sm->alt_SNonce, pmk, &PTK); 841281806Srpaulo 842281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, data, data_len) 843281806Srpaulo == 0) { 844281806Srpaulo ok = 1; 845281806Srpaulo break; 846281806Srpaulo } 847281806Srpaulo 848281806Srpaulo if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 849281806Srpaulo break; 850281806Srpaulo } 851281806Srpaulo 852281806Srpaulo if (!ok) { 853281806Srpaulo wpa_printf(MSG_DEBUG, 854281806Srpaulo "WPA: Earlier SNonce did not result in matching MIC"); 855281806Srpaulo return -1; 856281806Srpaulo } 857281806Srpaulo 858281806Srpaulo wpa_printf(MSG_DEBUG, 859281806Srpaulo "WPA: Earlier SNonce resulted in matching MIC"); 860281806Srpaulo sm->alt_snonce_valid = 0; 861281806Srpaulo os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN); 862281806Srpaulo os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 863281806Srpaulo sm->PTK_valid = TRUE; 864281806Srpaulo 865281806Srpaulo return 0; 866281806Srpaulo} 867281806Srpaulo 868281806Srpaulo 869214501Srpaulovoid wpa_receive(struct wpa_authenticator *wpa_auth, 870214501Srpaulo struct wpa_state_machine *sm, 871214501Srpaulo u8 *data, size_t data_len) 872214501Srpaulo{ 873214501Srpaulo struct ieee802_1x_hdr *hdr; 874214501Srpaulo struct wpa_eapol_key *key; 875281806Srpaulo struct wpa_eapol_key_192 *key192; 876214501Srpaulo u16 key_info, key_data_length; 877214501Srpaulo enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST, 878214501Srpaulo SMK_M1, SMK_M3, SMK_ERROR } msg; 879214501Srpaulo char *msgtxt; 880214501Srpaulo struct wpa_eapol_ie_parse kde; 881214501Srpaulo int ft; 882281806Srpaulo const u8 *eapol_key_ie, *key_data; 883281806Srpaulo size_t eapol_key_ie_len, keyhdrlen, mic_len; 884214501Srpaulo 885214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 886214501Srpaulo return; 887214501Srpaulo 888281806Srpaulo mic_len = wpa_mic_len(sm->wpa_key_mgmt); 889281806Srpaulo keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); 890281806Srpaulo 891281806Srpaulo if (data_len < sizeof(*hdr) + keyhdrlen) 892214501Srpaulo return; 893214501Srpaulo 894214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 895214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 896281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 897214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 898281806Srpaulo if (mic_len == 24) { 899281806Srpaulo key_data = (const u8 *) (key192 + 1); 900281806Srpaulo key_data_length = WPA_GET_BE16(key192->key_data_length); 901281806Srpaulo } else { 902281806Srpaulo key_data = (const u8 *) (key + 1); 903281806Srpaulo key_data_length = WPA_GET_BE16(key->key_data_length); 904281806Srpaulo } 905252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR 906252726Srpaulo " key_info=0x%x type=%u key_data_length=%u", 907252726Srpaulo MAC2STR(sm->addr), key_info, key->type, key_data_length); 908281806Srpaulo if (key_data_length > data_len - sizeof(*hdr) - keyhdrlen) { 909214501Srpaulo wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - " 910214501Srpaulo "key_data overflow (%d > %lu)", 911214501Srpaulo key_data_length, 912214501Srpaulo (unsigned long) (data_len - sizeof(*hdr) - 913281806Srpaulo keyhdrlen)); 914214501Srpaulo return; 915214501Srpaulo } 916214501Srpaulo 917214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 918252726Srpaulo if (key->type == EAPOL_KEY_TYPE_WPA) { 919252726Srpaulo /* 920252726Srpaulo * Some deployed station implementations seem to send 921252726Srpaulo * msg 4/4 with incorrect type value in WPA2 mode. 922252726Srpaulo */ 923252726Srpaulo wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key " 924252726Srpaulo "with unexpected WPA type in RSN mode"); 925252726Srpaulo } else if (key->type != EAPOL_KEY_TYPE_RSN) { 926214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 927214501Srpaulo "unexpected type %d in RSN mode", 928214501Srpaulo key->type); 929214501Srpaulo return; 930214501Srpaulo } 931214501Srpaulo } else { 932214501Srpaulo if (key->type != EAPOL_KEY_TYPE_WPA) { 933214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 934214501Srpaulo "unexpected type %d in WPA mode", 935214501Srpaulo key->type); 936214501Srpaulo return; 937214501Srpaulo } 938214501Srpaulo } 939214501Srpaulo 940252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Key Nonce", key->key_nonce, 941252726Srpaulo WPA_NONCE_LEN); 942252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Replay Counter", 943252726Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 944252726Srpaulo 945214501Srpaulo /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys 946214501Srpaulo * are set */ 947214501Srpaulo 948214501Srpaulo if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) == 949214501Srpaulo (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) { 950214501Srpaulo if (key_info & WPA_KEY_INFO_ERROR) { 951214501Srpaulo msg = SMK_ERROR; 952214501Srpaulo msgtxt = "SMK Error"; 953214501Srpaulo } else { 954214501Srpaulo msg = SMK_M1; 955214501Srpaulo msgtxt = "SMK M1"; 956214501Srpaulo } 957214501Srpaulo } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) { 958214501Srpaulo msg = SMK_M3; 959214501Srpaulo msgtxt = "SMK M3"; 960214501Srpaulo } else if (key_info & WPA_KEY_INFO_REQUEST) { 961214501Srpaulo msg = REQUEST; 962214501Srpaulo msgtxt = "Request"; 963214501Srpaulo } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { 964214501Srpaulo msg = GROUP_2; 965214501Srpaulo msgtxt = "2/2 Group"; 966214501Srpaulo } else if (key_data_length == 0) { 967214501Srpaulo msg = PAIRWISE_4; 968214501Srpaulo msgtxt = "4/4 Pairwise"; 969214501Srpaulo } else { 970214501Srpaulo msg = PAIRWISE_2; 971214501Srpaulo msgtxt = "2/4 Pairwise"; 972214501Srpaulo } 973214501Srpaulo 974214501Srpaulo /* TODO: key_info type validation for PeerKey */ 975214501Srpaulo if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 || 976214501Srpaulo msg == GROUP_2) { 977214501Srpaulo u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK; 978252726Srpaulo if (sm->pairwise == WPA_CIPHER_CCMP || 979252726Srpaulo sm->pairwise == WPA_CIPHER_GCMP) { 980214501Srpaulo if (wpa_use_aes_cmac(sm) && 981281806Srpaulo sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN && 982281806Srpaulo !wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) && 983214501Srpaulo ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) { 984214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 985214501Srpaulo LOGGER_WARNING, 986214501Srpaulo "advertised support for " 987214501Srpaulo "AES-128-CMAC, but did not " 988214501Srpaulo "use it"); 989214501Srpaulo return; 990214501Srpaulo } 991214501Srpaulo 992214501Srpaulo if (!wpa_use_aes_cmac(sm) && 993214501Srpaulo ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 994214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 995214501Srpaulo LOGGER_WARNING, 996214501Srpaulo "did not use HMAC-SHA1-AES " 997252726Srpaulo "with CCMP/GCMP"); 998214501Srpaulo return; 999214501Srpaulo } 1000214501Srpaulo } 1001281806Srpaulo 1002281806Srpaulo if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) && 1003281806Srpaulo ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) { 1004281806Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 1005281806Srpaulo "did not use EAPOL-Key descriptor version 0 as required for AKM-defined cases"); 1006281806Srpaulo return; 1007281806Srpaulo } 1008214501Srpaulo } 1009214501Srpaulo 1010214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 1011214501Srpaulo if (sm->req_replay_counter_used && 1012214501Srpaulo os_memcmp(key->replay_counter, sm->req_replay_counter, 1013214501Srpaulo WPA_REPLAY_COUNTER_LEN) <= 0) { 1014214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 1015214501Srpaulo "received EAPOL-Key request with " 1016214501Srpaulo "replayed counter"); 1017214501Srpaulo return; 1018214501Srpaulo } 1019214501Srpaulo } 1020214501Srpaulo 1021214501Srpaulo if (!(key_info & WPA_KEY_INFO_REQUEST) && 1022252726Srpaulo !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) { 1023214501Srpaulo int i; 1024252726Srpaulo 1025252726Srpaulo if (msg == PAIRWISE_2 && 1026252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 1027252726Srpaulo key->replay_counter) && 1028252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 1029252726Srpaulo os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0) 1030252726Srpaulo { 1031252726Srpaulo /* 1032252726Srpaulo * Some supplicant implementations (e.g., Windows XP 1033252726Srpaulo * WZC) update SNonce for each EAPOL-Key 2/4. This 1034252726Srpaulo * breaks the workaround on accepting any of the 1035252726Srpaulo * pending requests, so allow the SNonce to be updated 1036252726Srpaulo * even if we have already sent out EAPOL-Key 3/4. 1037252726Srpaulo */ 1038252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1039252726Srpaulo "Process SNonce update from STA " 1040252726Srpaulo "based on retransmitted EAPOL-Key " 1041252726Srpaulo "1/4"); 1042252726Srpaulo sm->update_snonce = 1; 1043281806Srpaulo os_memcpy(sm->alt_SNonce, sm->SNonce, WPA_NONCE_LEN); 1044281806Srpaulo sm->alt_snonce_valid = TRUE; 1045281806Srpaulo os_memcpy(sm->alt_replay_counter, 1046281806Srpaulo sm->key_replay[0].counter, 1047281806Srpaulo WPA_REPLAY_COUNTER_LEN); 1048252726Srpaulo goto continue_processing; 1049252726Srpaulo } 1050252726Srpaulo 1051281806Srpaulo if (msg == PAIRWISE_4 && sm->alt_snonce_valid && 1052281806Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 1053281806Srpaulo os_memcmp(key->replay_counter, sm->alt_replay_counter, 1054281806Srpaulo WPA_REPLAY_COUNTER_LEN) == 0) { 1055281806Srpaulo /* 1056281806Srpaulo * Supplicant may still be using the old SNonce since 1057281806Srpaulo * there was two EAPOL-Key 2/4 messages and they had 1058281806Srpaulo * different SNonce values. 1059281806Srpaulo */ 1060281806Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1061281806Srpaulo "Try to process received EAPOL-Key 4/4 based on old Replay Counter and SNonce from an earlier EAPOL-Key 1/4"); 1062281806Srpaulo goto continue_processing; 1063281806Srpaulo } 1064281806Srpaulo 1065252726Srpaulo if (msg == PAIRWISE_2 && 1066252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 1067252726Srpaulo key->replay_counter) && 1068252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) { 1069252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1070252726Srpaulo "ignore retransmitted EAPOL-Key %s - " 1071252726Srpaulo "SNonce did not change", msgtxt); 1072252726Srpaulo } else { 1073252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1074252726Srpaulo "received EAPOL-Key %s with " 1075252726Srpaulo "unexpected replay counter", msgtxt); 1076252726Srpaulo } 1077214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 1078214501Srpaulo if (!sm->key_replay[i].valid) 1079214501Srpaulo break; 1080214501Srpaulo wpa_hexdump(MSG_DEBUG, "pending replay counter", 1081214501Srpaulo sm->key_replay[i].counter, 1082214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1083214501Srpaulo } 1084214501Srpaulo wpa_hexdump(MSG_DEBUG, "received replay counter", 1085214501Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 1086214501Srpaulo return; 1087214501Srpaulo } 1088214501Srpaulo 1089252726Srpaulocontinue_processing: 1090214501Srpaulo switch (msg) { 1091214501Srpaulo case PAIRWISE_2: 1092214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKSTART && 1093252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING && 1094252726Srpaulo (!sm->update_snonce || 1095252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) { 1096214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1097214501Srpaulo "received EAPOL-Key msg 2/4 in " 1098214501Srpaulo "invalid state (%d) - dropped", 1099214501Srpaulo sm->wpa_ptk_state); 1100214501Srpaulo return; 1101214501Srpaulo } 1102252726Srpaulo random_add_randomness(key->key_nonce, WPA_NONCE_LEN); 1103252726Srpaulo if (sm->group->reject_4way_hs_for_entropy) { 1104252726Srpaulo /* 1105252726Srpaulo * The system did not have enough entropy to generate 1106252726Srpaulo * strong random numbers. Reject the first 4-way 1107252726Srpaulo * handshake(s) and collect some entropy based on the 1108252726Srpaulo * information from it. Once enough entropy is 1109252726Srpaulo * available, the next atempt will trigger GMK/Key 1110252726Srpaulo * Counter update and the station will be allowed to 1111252726Srpaulo * continue. 1112252726Srpaulo */ 1113252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to " 1114252726Srpaulo "collect more entropy for random number " 1115252726Srpaulo "generation"); 1116252726Srpaulo random_mark_pool_ready(); 1117252726Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1118252726Srpaulo return; 1119252726Srpaulo } 1120281806Srpaulo if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) { 1121214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1122214501Srpaulo "received EAPOL-Key msg 2/4 with " 1123214501Srpaulo "invalid Key Data contents"); 1124214501Srpaulo return; 1125214501Srpaulo } 1126214501Srpaulo if (kde.rsn_ie) { 1127214501Srpaulo eapol_key_ie = kde.rsn_ie; 1128214501Srpaulo eapol_key_ie_len = kde.rsn_ie_len; 1129281806Srpaulo } else if (kde.osen) { 1130281806Srpaulo eapol_key_ie = kde.osen; 1131281806Srpaulo eapol_key_ie_len = kde.osen_len; 1132214501Srpaulo } else { 1133214501Srpaulo eapol_key_ie = kde.wpa_ie; 1134214501Srpaulo eapol_key_ie_len = kde.wpa_ie_len; 1135214501Srpaulo } 1136214501Srpaulo ft = sm->wpa == WPA_VERSION_WPA2 && 1137214501Srpaulo wpa_key_mgmt_ft(sm->wpa_key_mgmt); 1138214501Srpaulo if (sm->wpa_ie == NULL || 1139214501Srpaulo wpa_compare_rsn_ie(ft, 1140214501Srpaulo sm->wpa_ie, sm->wpa_ie_len, 1141214501Srpaulo eapol_key_ie, eapol_key_ie_len)) { 1142214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1143214501Srpaulo "WPA IE from (Re)AssocReq did not " 1144214501Srpaulo "match with msg 2/4"); 1145214501Srpaulo if (sm->wpa_ie) { 1146214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq", 1147214501Srpaulo sm->wpa_ie, sm->wpa_ie_len); 1148214501Srpaulo } 1149214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", 1150214501Srpaulo eapol_key_ie, eapol_key_ie_len); 1151214501Srpaulo /* MLME-DEAUTHENTICATE.request */ 1152214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1153214501Srpaulo return; 1154214501Srpaulo } 1155214501Srpaulo#ifdef CONFIG_IEEE80211R 1156214501Srpaulo if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { 1157214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 1158214501Srpaulo return; 1159214501Srpaulo } 1160214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1161281806Srpaulo#ifdef CONFIG_P2P 1162281806Srpaulo if (kde.ip_addr_req && kde.ip_addr_req[0] && 1163281806Srpaulo wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) { 1164281806Srpaulo int idx; 1165281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: IP address requested in " 1166281806Srpaulo "EAPOL-Key exchange"); 1167281806Srpaulo idx = bitfield_get_first_zero(wpa_auth->ip_pool); 1168281806Srpaulo if (idx >= 0) { 1169281806Srpaulo u32 start = WPA_GET_BE32(wpa_auth->conf. 1170281806Srpaulo ip_addr_start); 1171281806Srpaulo bitfield_set(wpa_auth->ip_pool, idx); 1172281806Srpaulo WPA_PUT_BE32(sm->ip_addr, start + idx); 1173281806Srpaulo wpa_printf(MSG_DEBUG, "P2P: Assigned IP " 1174281806Srpaulo "address %u.%u.%u.%u to " MACSTR, 1175281806Srpaulo sm->ip_addr[0], sm->ip_addr[1], 1176281806Srpaulo sm->ip_addr[2], sm->ip_addr[3], 1177281806Srpaulo MAC2STR(sm->addr)); 1178281806Srpaulo } 1179281806Srpaulo } 1180281806Srpaulo#endif /* CONFIG_P2P */ 1181214501Srpaulo break; 1182214501Srpaulo case PAIRWISE_4: 1183214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING || 1184214501Srpaulo !sm->PTK_valid) { 1185214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1186214501Srpaulo "received EAPOL-Key msg 4/4 in " 1187214501Srpaulo "invalid state (%d) - dropped", 1188214501Srpaulo sm->wpa_ptk_state); 1189214501Srpaulo return; 1190214501Srpaulo } 1191214501Srpaulo break; 1192214501Srpaulo case GROUP_2: 1193214501Srpaulo if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING 1194214501Srpaulo || !sm->PTK_valid) { 1195214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1196214501Srpaulo "received EAPOL-Key msg 2/2 in " 1197214501Srpaulo "invalid state (%d) - dropped", 1198214501Srpaulo sm->wpa_ptk_group_state); 1199214501Srpaulo return; 1200214501Srpaulo } 1201214501Srpaulo break; 1202214501Srpaulo#ifdef CONFIG_PEERKEY 1203214501Srpaulo case SMK_M1: 1204214501Srpaulo case SMK_M3: 1205214501Srpaulo case SMK_ERROR: 1206214501Srpaulo if (!wpa_auth->conf.peerkey) { 1207214501Srpaulo wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but " 1208214501Srpaulo "PeerKey use disabled - ignoring message"); 1209214501Srpaulo return; 1210214501Srpaulo } 1211214501Srpaulo if (!sm->PTK_valid) { 1212214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1213214501Srpaulo "received EAPOL-Key msg SMK in " 1214214501Srpaulo "invalid state - dropped"); 1215214501Srpaulo return; 1216214501Srpaulo } 1217214501Srpaulo break; 1218214501Srpaulo#else /* CONFIG_PEERKEY */ 1219214501Srpaulo case SMK_M1: 1220214501Srpaulo case SMK_M3: 1221214501Srpaulo case SMK_ERROR: 1222214501Srpaulo return; /* STSL disabled - ignore SMK messages */ 1223214501Srpaulo#endif /* CONFIG_PEERKEY */ 1224214501Srpaulo case REQUEST: 1225214501Srpaulo break; 1226214501Srpaulo } 1227214501Srpaulo 1228214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1229214501Srpaulo "received EAPOL-Key frame (%s)", msgtxt); 1230214501Srpaulo 1231214501Srpaulo if (key_info & WPA_KEY_INFO_ACK) { 1232214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1233214501Srpaulo "received invalid EAPOL-Key: Key Ack set"); 1234214501Srpaulo return; 1235214501Srpaulo } 1236214501Srpaulo 1237214501Srpaulo if (!(key_info & WPA_KEY_INFO_MIC)) { 1238214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1239214501Srpaulo "received invalid EAPOL-Key: Key MIC not set"); 1240214501Srpaulo return; 1241214501Srpaulo } 1242214501Srpaulo 1243214501Srpaulo sm->MICVerified = FALSE; 1244252726Srpaulo if (sm->PTK_valid && !sm->update_snonce) { 1245281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data, 1246281806Srpaulo data_len) && 1247281806Srpaulo (msg != PAIRWISE_4 || !sm->alt_snonce_valid || 1248281806Srpaulo wpa_try_alt_snonce(sm, data, data_len))) { 1249214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1250214501Srpaulo "received EAPOL-Key with invalid MIC"); 1251214501Srpaulo return; 1252214501Srpaulo } 1253214501Srpaulo sm->MICVerified = TRUE; 1254214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 1255252726Srpaulo sm->pending_1_of_4_timeout = 0; 1256214501Srpaulo } 1257214501Srpaulo 1258214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 1259214501Srpaulo if (sm->MICVerified) { 1260214501Srpaulo sm->req_replay_counter_used = 1; 1261214501Srpaulo os_memcpy(sm->req_replay_counter, key->replay_counter, 1262214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1263214501Srpaulo } else { 1264214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1265214501Srpaulo "received EAPOL-Key request with " 1266214501Srpaulo "invalid MIC"); 1267214501Srpaulo return; 1268214501Srpaulo } 1269214501Srpaulo 1270214501Srpaulo /* 1271214501Srpaulo * TODO: should decrypt key data field if encryption was used; 1272214501Srpaulo * even though MAC address KDE is not normally encrypted, 1273214501Srpaulo * supplicant is allowed to encrypt it. 1274214501Srpaulo */ 1275214501Srpaulo if (msg == SMK_ERROR) { 1276214501Srpaulo#ifdef CONFIG_PEERKEY 1277281806Srpaulo wpa_smk_error(wpa_auth, sm, key_data, key_data_length); 1278214501Srpaulo#endif /* CONFIG_PEERKEY */ 1279214501Srpaulo return; 1280214501Srpaulo } else if (key_info & WPA_KEY_INFO_ERROR) { 1281252726Srpaulo if (wpa_receive_error_report( 1282252726Srpaulo wpa_auth, sm, 1283252726Srpaulo !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0) 1284252726Srpaulo return; /* STA entry was removed */ 1285214501Srpaulo } else if (key_info & WPA_KEY_INFO_KEY_TYPE) { 1286214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1287214501Srpaulo "received EAPOL-Key Request for new " 1288214501Srpaulo "4-Way Handshake"); 1289214501Srpaulo wpa_request_new_ptk(sm); 1290214501Srpaulo#ifdef CONFIG_PEERKEY 1291214501Srpaulo } else if (msg == SMK_M1) { 1292281806Srpaulo wpa_smk_m1(wpa_auth, sm, key, key_data, 1293281806Srpaulo key_data_length); 1294214501Srpaulo#endif /* CONFIG_PEERKEY */ 1295214501Srpaulo } else if (key_data_length > 0 && 1296281806Srpaulo wpa_parse_kde_ies(key_data, key_data_length, 1297281806Srpaulo &kde) == 0 && 1298214501Srpaulo kde.mac_addr) { 1299214501Srpaulo } else { 1300214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1301214501Srpaulo "received EAPOL-Key Request for GTK " 1302214501Srpaulo "rekeying"); 1303214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 1304214501Srpaulo wpa_rekey_gtk(wpa_auth, NULL); 1305214501Srpaulo } 1306214501Srpaulo } else { 1307252726Srpaulo /* Do not allow the same key replay counter to be reused. */ 1308252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, 1309252726Srpaulo key->replay_counter); 1310252726Srpaulo 1311252726Srpaulo if (msg == PAIRWISE_2) { 1312252726Srpaulo /* 1313252726Srpaulo * Maintain a copy of the pending EAPOL-Key frames in 1314252726Srpaulo * case the EAPOL-Key frame was retransmitted. This is 1315252726Srpaulo * needed to allow EAPOL-Key msg 2/4 reply to another 1316252726Srpaulo * pending msg 1/4 to update the SNonce to work around 1317252726Srpaulo * unexpected supplicant behavior. 1318252726Srpaulo */ 1319252726Srpaulo os_memcpy(sm->prev_key_replay, sm->key_replay, 1320252726Srpaulo sizeof(sm->key_replay)); 1321252726Srpaulo } else { 1322252726Srpaulo os_memset(sm->prev_key_replay, 0, 1323252726Srpaulo sizeof(sm->prev_key_replay)); 1324252726Srpaulo } 1325252726Srpaulo 1326252726Srpaulo /* 1327252726Srpaulo * Make sure old valid counters are not accepted anymore and 1328252726Srpaulo * do not get copied again. 1329252726Srpaulo */ 1330252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, NULL); 1331214501Srpaulo } 1332214501Srpaulo 1333214501Srpaulo#ifdef CONFIG_PEERKEY 1334214501Srpaulo if (msg == SMK_M3) { 1335281806Srpaulo wpa_smk_m3(wpa_auth, sm, key, key_data, key_data_length); 1336214501Srpaulo return; 1337214501Srpaulo } 1338214501Srpaulo#endif /* CONFIG_PEERKEY */ 1339214501Srpaulo 1340214501Srpaulo os_free(sm->last_rx_eapol_key); 1341214501Srpaulo sm->last_rx_eapol_key = os_malloc(data_len); 1342214501Srpaulo if (sm->last_rx_eapol_key == NULL) 1343214501Srpaulo return; 1344214501Srpaulo os_memcpy(sm->last_rx_eapol_key, data, data_len); 1345214501Srpaulo sm->last_rx_eapol_key_len = data_len; 1346214501Srpaulo 1347252726Srpaulo sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE); 1348214501Srpaulo sm->EAPOLKeyReceived = TRUE; 1349214501Srpaulo sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 1350214501Srpaulo sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); 1351214501Srpaulo os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); 1352214501Srpaulo wpa_sm_step(sm); 1353214501Srpaulo} 1354214501Srpaulo 1355214501Srpaulo 1356252726Srpaulostatic int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr, 1357252726Srpaulo const u8 *gnonce, u8 *gtk, size_t gtk_len) 1358214501Srpaulo{ 1359252726Srpaulo u8 data[ETH_ALEN + WPA_NONCE_LEN + 8 + 16]; 1360252726Srpaulo u8 *pos; 1361252726Srpaulo int ret = 0; 1362214501Srpaulo 1363252726Srpaulo /* GTK = PRF-X(GMK, "Group key expansion", 1364252726Srpaulo * AA || GNonce || Time || random data) 1365252726Srpaulo * The example described in the IEEE 802.11 standard uses only AA and 1366252726Srpaulo * GNonce as inputs here. Add some more entropy since this derivation 1367252726Srpaulo * is done only at the Authenticator and as such, does not need to be 1368252726Srpaulo * exactly same. 1369252726Srpaulo */ 1370214501Srpaulo os_memcpy(data, addr, ETH_ALEN); 1371214501Srpaulo os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN); 1372252726Srpaulo pos = data + ETH_ALEN + WPA_NONCE_LEN; 1373252726Srpaulo wpa_get_ntp_timestamp(pos); 1374252726Srpaulo pos += 8; 1375252726Srpaulo if (random_get_bytes(pos, 16) < 0) 1376252726Srpaulo ret = -1; 1377214501Srpaulo 1378214501Srpaulo#ifdef CONFIG_IEEE80211W 1379252726Srpaulo sha256_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len); 1380214501Srpaulo#else /* CONFIG_IEEE80211W */ 1381252726Srpaulo if (sha1_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len) 1382252726Srpaulo < 0) 1383252726Srpaulo ret = -1; 1384214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1385214501Srpaulo 1386252726Srpaulo return ret; 1387214501Srpaulo} 1388214501Srpaulo 1389214501Srpaulo 1390214501Srpaulostatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx) 1391214501Srpaulo{ 1392214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 1393214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 1394214501Srpaulo 1395252726Srpaulo sm->pending_1_of_4_timeout = 0; 1396214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout"); 1397214501Srpaulo sm->TimeoutEvt = TRUE; 1398214501Srpaulo wpa_sm_step(sm); 1399214501Srpaulo} 1400214501Srpaulo 1401214501Srpaulo 1402214501Srpaulovoid __wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1403214501Srpaulo struct wpa_state_machine *sm, int key_info, 1404214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1405214501Srpaulo const u8 *kde, size_t kde_len, 1406214501Srpaulo int keyidx, int encr, int force_version) 1407214501Srpaulo{ 1408214501Srpaulo struct ieee802_1x_hdr *hdr; 1409214501Srpaulo struct wpa_eapol_key *key; 1410281806Srpaulo struct wpa_eapol_key_192 *key192; 1411281806Srpaulo size_t len, mic_len, keyhdrlen; 1412214501Srpaulo int alg; 1413214501Srpaulo int key_data_len, pad_len = 0; 1414214501Srpaulo u8 *buf, *pos; 1415214501Srpaulo int version, pairwise; 1416214501Srpaulo int i; 1417281806Srpaulo u8 *key_data; 1418214501Srpaulo 1419281806Srpaulo mic_len = wpa_mic_len(sm->wpa_key_mgmt); 1420281806Srpaulo keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); 1421214501Srpaulo 1422281806Srpaulo len = sizeof(struct ieee802_1x_hdr) + keyhdrlen; 1423281806Srpaulo 1424214501Srpaulo if (force_version) 1425214501Srpaulo version = force_version; 1426281806Srpaulo else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1427281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) 1428281806Srpaulo version = WPA_KEY_INFO_TYPE_AKM_DEFINED; 1429214501Srpaulo else if (wpa_use_aes_cmac(sm)) 1430214501Srpaulo version = WPA_KEY_INFO_TYPE_AES_128_CMAC; 1431252726Srpaulo else if (sm->pairwise != WPA_CIPHER_TKIP) 1432214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1433214501Srpaulo else 1434214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1435214501Srpaulo 1436281806Srpaulo pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 1437214501Srpaulo 1438214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d " 1439214501Srpaulo "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d " 1440214501Srpaulo "encr=%d)", 1441214501Srpaulo version, 1442214501Srpaulo (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0, 1443214501Srpaulo (key_info & WPA_KEY_INFO_MIC) ? 1 : 0, 1444214501Srpaulo (key_info & WPA_KEY_INFO_ACK) ? 1 : 0, 1445214501Srpaulo (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0, 1446214501Srpaulo pairwise, (unsigned long) kde_len, keyidx, encr); 1447214501Srpaulo 1448214501Srpaulo key_data_len = kde_len; 1449214501Srpaulo 1450214501Srpaulo if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1451281806Srpaulo sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1452281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) || 1453214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) { 1454214501Srpaulo pad_len = key_data_len % 8; 1455214501Srpaulo if (pad_len) 1456214501Srpaulo pad_len = 8 - pad_len; 1457214501Srpaulo key_data_len += pad_len + 8; 1458214501Srpaulo } 1459214501Srpaulo 1460214501Srpaulo len += key_data_len; 1461214501Srpaulo 1462214501Srpaulo hdr = os_zalloc(len); 1463214501Srpaulo if (hdr == NULL) 1464214501Srpaulo return; 1465214501Srpaulo hdr->version = wpa_auth->conf.eapol_version; 1466214501Srpaulo hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1467214501Srpaulo hdr->length = host_to_be16(len - sizeof(*hdr)); 1468214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1469281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 1470281806Srpaulo key_data = ((u8 *) (hdr + 1)) + keyhdrlen; 1471214501Srpaulo 1472214501Srpaulo key->type = sm->wpa == WPA_VERSION_WPA2 ? 1473214501Srpaulo EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1474214501Srpaulo key_info |= version; 1475214501Srpaulo if (encr && sm->wpa == WPA_VERSION_WPA2) 1476214501Srpaulo key_info |= WPA_KEY_INFO_ENCR_KEY_DATA; 1477214501Srpaulo if (sm->wpa != WPA_VERSION_WPA2) 1478214501Srpaulo key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT; 1479214501Srpaulo WPA_PUT_BE16(key->key_info, key_info); 1480214501Srpaulo 1481214501Srpaulo alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group; 1482252726Srpaulo WPA_PUT_BE16(key->key_length, wpa_cipher_key_len(alg)); 1483214501Srpaulo if (key_info & WPA_KEY_INFO_SMK_MESSAGE) 1484214501Srpaulo WPA_PUT_BE16(key->key_length, 0); 1485214501Srpaulo 1486214501Srpaulo /* FIX: STSL: what to use as key_replay_counter? */ 1487214501Srpaulo for (i = RSNA_MAX_EAPOL_RETRIES - 1; i > 0; i--) { 1488214501Srpaulo sm->key_replay[i].valid = sm->key_replay[i - 1].valid; 1489214501Srpaulo os_memcpy(sm->key_replay[i].counter, 1490214501Srpaulo sm->key_replay[i - 1].counter, 1491214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1492214501Srpaulo } 1493214501Srpaulo inc_byte_array(sm->key_replay[0].counter, WPA_REPLAY_COUNTER_LEN); 1494214501Srpaulo os_memcpy(key->replay_counter, sm->key_replay[0].counter, 1495214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1496281806Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", 1497281806Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 1498214501Srpaulo sm->key_replay[0].valid = TRUE; 1499214501Srpaulo 1500214501Srpaulo if (nonce) 1501214501Srpaulo os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN); 1502214501Srpaulo 1503214501Srpaulo if (key_rsc) 1504214501Srpaulo os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN); 1505214501Srpaulo 1506214501Srpaulo if (kde && !encr) { 1507281806Srpaulo os_memcpy(key_data, kde, kde_len); 1508281806Srpaulo if (mic_len == 24) 1509281806Srpaulo WPA_PUT_BE16(key192->key_data_length, kde_len); 1510281806Srpaulo else 1511281806Srpaulo WPA_PUT_BE16(key->key_data_length, kde_len); 1512214501Srpaulo } else if (encr && kde) { 1513214501Srpaulo buf = os_zalloc(key_data_len); 1514214501Srpaulo if (buf == NULL) { 1515214501Srpaulo os_free(hdr); 1516214501Srpaulo return; 1517214501Srpaulo } 1518214501Srpaulo pos = buf; 1519214501Srpaulo os_memcpy(pos, kde, kde_len); 1520214501Srpaulo pos += kde_len; 1521214501Srpaulo 1522214501Srpaulo if (pad_len) 1523214501Srpaulo *pos++ = 0xdd; 1524214501Srpaulo 1525214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data", 1526214501Srpaulo buf, key_data_len); 1527214501Srpaulo if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1528281806Srpaulo sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN || 1529281806Srpaulo wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) || 1530214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) { 1531281806Srpaulo if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, 1532281806Srpaulo (key_data_len - 8) / 8, buf, key_data)) { 1533214501Srpaulo os_free(hdr); 1534214501Srpaulo os_free(buf); 1535214501Srpaulo return; 1536214501Srpaulo } 1537281806Srpaulo if (mic_len == 24) 1538281806Srpaulo WPA_PUT_BE16(key192->key_data_length, 1539281806Srpaulo key_data_len); 1540281806Srpaulo else 1541281806Srpaulo WPA_PUT_BE16(key->key_data_length, 1542281806Srpaulo key_data_len); 1543289549Srpaulo#ifndef CONFIG_NO_RC4 1544281806Srpaulo } else if (sm->PTK.kek_len == 16) { 1545214501Srpaulo u8 ek[32]; 1546214501Srpaulo os_memcpy(key->key_iv, 1547214501Srpaulo sm->group->Counter + WPA_NONCE_LEN - 16, 16); 1548214501Srpaulo inc_byte_array(sm->group->Counter, WPA_NONCE_LEN); 1549214501Srpaulo os_memcpy(ek, key->key_iv, 16); 1550281806Srpaulo os_memcpy(ek + 16, sm->PTK.kek, sm->PTK.kek_len); 1551281806Srpaulo os_memcpy(key_data, buf, key_data_len); 1552281806Srpaulo rc4_skip(ek, 32, 256, key_data, key_data_len); 1553281806Srpaulo if (mic_len == 24) 1554281806Srpaulo WPA_PUT_BE16(key192->key_data_length, 1555281806Srpaulo key_data_len); 1556281806Srpaulo else 1557281806Srpaulo WPA_PUT_BE16(key->key_data_length, 1558281806Srpaulo key_data_len); 1559289549Srpaulo#endif /* CONFIG_NO_RC4 */ 1560281806Srpaulo } else { 1561281806Srpaulo os_free(hdr); 1562281806Srpaulo os_free(buf); 1563281806Srpaulo return; 1564214501Srpaulo } 1565214501Srpaulo os_free(buf); 1566214501Srpaulo } 1567214501Srpaulo 1568214501Srpaulo if (key_info & WPA_KEY_INFO_MIC) { 1569281806Srpaulo u8 *key_mic; 1570281806Srpaulo 1571214501Srpaulo if (!sm->PTK_valid) { 1572214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 1573214501Srpaulo "PTK not valid when sending EAPOL-Key " 1574214501Srpaulo "frame"); 1575214501Srpaulo os_free(hdr); 1576214501Srpaulo return; 1577214501Srpaulo } 1578281806Srpaulo 1579281806Srpaulo key_mic = key192->key_mic; /* same offset for key and key192 */ 1580281806Srpaulo wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len, 1581281806Srpaulo sm->wpa_key_mgmt, version, 1582281806Srpaulo (u8 *) hdr, len, key_mic); 1583281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 1584281806Srpaulo if (!pairwise && 1585281806Srpaulo wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 && 1586281806Srpaulo drand48() < 1587281806Srpaulo wpa_auth->conf.corrupt_gtk_rekey_mic_probability) { 1588281806Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1589281806Srpaulo "Corrupting group EAPOL-Key Key MIC"); 1590281806Srpaulo key_mic[0]++; 1591281806Srpaulo } 1592281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 1593214501Srpaulo } 1594214501Srpaulo 1595214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1596214501Srpaulo 1); 1597214501Srpaulo wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len, 1598214501Srpaulo sm->pairwise_set); 1599214501Srpaulo os_free(hdr); 1600214501Srpaulo} 1601214501Srpaulo 1602214501Srpaulo 1603214501Srpaulostatic void wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1604214501Srpaulo struct wpa_state_machine *sm, int key_info, 1605214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1606214501Srpaulo const u8 *kde, size_t kde_len, 1607214501Srpaulo int keyidx, int encr) 1608214501Srpaulo{ 1609214501Srpaulo int timeout_ms; 1610214501Srpaulo int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE; 1611214501Srpaulo int ctr; 1612214501Srpaulo 1613214501Srpaulo if (sm == NULL) 1614214501Srpaulo return; 1615214501Srpaulo 1616214501Srpaulo __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len, 1617214501Srpaulo keyidx, encr, 0); 1618214501Srpaulo 1619214501Srpaulo ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr; 1620252726Srpaulo if (ctr == 1 && wpa_auth->conf.tx_status) 1621252726Srpaulo timeout_ms = pairwise ? eapol_key_timeout_first : 1622252726Srpaulo eapol_key_timeout_first_group; 1623214501Srpaulo else 1624214501Srpaulo timeout_ms = eapol_key_timeout_subseq; 1625252726Srpaulo if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC)) 1626252726Srpaulo sm->pending_1_of_4_timeout = 1; 1627252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry " 1628252726Srpaulo "counter %d)", timeout_ms, ctr); 1629214501Srpaulo eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000, 1630214501Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 1631214501Srpaulo} 1632214501Srpaulo 1633214501Srpaulo 1634281806Srpaulostatic int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data, 1635281806Srpaulo size_t data_len) 1636214501Srpaulo{ 1637214501Srpaulo struct ieee802_1x_hdr *hdr; 1638214501Srpaulo struct wpa_eapol_key *key; 1639281806Srpaulo struct wpa_eapol_key_192 *key192; 1640214501Srpaulo u16 key_info; 1641214501Srpaulo int ret = 0; 1642281806Srpaulo u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; 1643281806Srpaulo size_t mic_len = wpa_mic_len(akmp); 1644214501Srpaulo 1645214501Srpaulo if (data_len < sizeof(*hdr) + sizeof(*key)) 1646214501Srpaulo return -1; 1647214501Srpaulo 1648214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 1649214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1650281806Srpaulo key192 = (struct wpa_eapol_key_192 *) (hdr + 1); 1651214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 1652281806Srpaulo os_memcpy(mic, key192->key_mic, mic_len); 1653281806Srpaulo os_memset(key192->key_mic, 0, mic_len); 1654281806Srpaulo if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp, 1655281806Srpaulo key_info & WPA_KEY_INFO_TYPE_MASK, 1656281806Srpaulo data, data_len, key192->key_mic) || 1657281806Srpaulo os_memcmp_const(mic, key192->key_mic, mic_len) != 0) 1658214501Srpaulo ret = -1; 1659281806Srpaulo os_memcpy(key192->key_mic, mic, mic_len); 1660214501Srpaulo return ret; 1661214501Srpaulo} 1662214501Srpaulo 1663214501Srpaulo 1664214501Srpaulovoid wpa_remove_ptk(struct wpa_state_machine *sm) 1665214501Srpaulo{ 1666214501Srpaulo sm->PTK_valid = FALSE; 1667214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1668252726Srpaulo wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL, 0); 1669214501Srpaulo sm->pairwise_set = FALSE; 1670214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 1671214501Srpaulo} 1672214501Srpaulo 1673214501Srpaulo 1674289549Srpauloint wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event) 1675214501Srpaulo{ 1676214501Srpaulo int remove_ptk = 1; 1677214501Srpaulo 1678214501Srpaulo if (sm == NULL) 1679214501Srpaulo return -1; 1680214501Srpaulo 1681214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1682214501Srpaulo "event %d notification", event); 1683214501Srpaulo 1684214501Srpaulo switch (event) { 1685214501Srpaulo case WPA_AUTH: 1686281806Srpaulo#ifdef CONFIG_MESH 1687281806Srpaulo /* PTKs are derived through AMPE */ 1688281806Srpaulo if (wpa_auth_start_ampe(sm->wpa_auth, sm->addr)) { 1689281806Srpaulo /* not mesh */ 1690281806Srpaulo break; 1691281806Srpaulo } 1692281806Srpaulo return 0; 1693281806Srpaulo#endif /* CONFIG_MESH */ 1694214501Srpaulo case WPA_ASSOC: 1695214501Srpaulo break; 1696214501Srpaulo case WPA_DEAUTH: 1697214501Srpaulo case WPA_DISASSOC: 1698214501Srpaulo sm->DeauthenticationRequest = TRUE; 1699214501Srpaulo break; 1700214501Srpaulo case WPA_REAUTH: 1701214501Srpaulo case WPA_REAUTH_EAPOL: 1702214501Srpaulo if (!sm->started) { 1703214501Srpaulo /* 1704214501Srpaulo * When using WPS, we may end up here if the STA 1705214501Srpaulo * manages to re-associate without the previous STA 1706214501Srpaulo * entry getting removed. Consequently, we need to make 1707214501Srpaulo * sure that the WPA state machines gets initialized 1708214501Srpaulo * properly at this point. 1709214501Srpaulo */ 1710214501Srpaulo wpa_printf(MSG_DEBUG, "WPA state machine had not been " 1711214501Srpaulo "started - initialize now"); 1712214501Srpaulo sm->started = 1; 1713214501Srpaulo sm->Init = TRUE; 1714214501Srpaulo if (wpa_sm_step(sm) == 1) 1715214501Srpaulo return 1; /* should not really happen */ 1716214501Srpaulo sm->Init = FALSE; 1717214501Srpaulo sm->AuthenticationRequest = TRUE; 1718214501Srpaulo break; 1719214501Srpaulo } 1720214501Srpaulo if (sm->GUpdateStationKeys) { 1721214501Srpaulo /* 1722214501Srpaulo * Reauthentication cancels the pending group key 1723214501Srpaulo * update for this STA. 1724214501Srpaulo */ 1725214501Srpaulo sm->group->GKeyDoneStations--; 1726214501Srpaulo sm->GUpdateStationKeys = FALSE; 1727214501Srpaulo sm->PtkGroupInit = TRUE; 1728214501Srpaulo } 1729214501Srpaulo sm->ReAuthenticationRequest = TRUE; 1730214501Srpaulo break; 1731214501Srpaulo case WPA_ASSOC_FT: 1732214501Srpaulo#ifdef CONFIG_IEEE80211R 1733214501Srpaulo wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration " 1734214501Srpaulo "after association"); 1735214501Srpaulo wpa_ft_install_ptk(sm); 1736214501Srpaulo 1737214501Srpaulo /* Using FT protocol, not WPA auth state machine */ 1738214501Srpaulo sm->ft_completed = 1; 1739214501Srpaulo return 0; 1740214501Srpaulo#else /* CONFIG_IEEE80211R */ 1741214501Srpaulo break; 1742214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1743214501Srpaulo } 1744214501Srpaulo 1745214501Srpaulo#ifdef CONFIG_IEEE80211R 1746214501Srpaulo sm->ft_completed = 0; 1747214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1748214501Srpaulo 1749214501Srpaulo#ifdef CONFIG_IEEE80211W 1750214501Srpaulo if (sm->mgmt_frame_prot && event == WPA_AUTH) 1751214501Srpaulo remove_ptk = 0; 1752214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1753214501Srpaulo 1754214501Srpaulo if (remove_ptk) { 1755214501Srpaulo sm->PTK_valid = FALSE; 1756214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1757214501Srpaulo 1758214501Srpaulo if (event != WPA_REAUTH_EAPOL) 1759214501Srpaulo wpa_remove_ptk(sm); 1760214501Srpaulo } 1761214501Srpaulo 1762289549Srpaulo if (sm->in_step_loop) { 1763289549Srpaulo /* 1764289549Srpaulo * wpa_sm_step() is already running - avoid recursive call to 1765289549Srpaulo * it by making the existing loop process the new update. 1766289549Srpaulo */ 1767289549Srpaulo sm->changed = TRUE; 1768289549Srpaulo return 0; 1769289549Srpaulo } 1770214501Srpaulo return wpa_sm_step(sm); 1771214501Srpaulo} 1772214501Srpaulo 1773214501Srpaulo 1774214501SrpauloSM_STATE(WPA_PTK, INITIALIZE) 1775214501Srpaulo{ 1776214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk); 1777214501Srpaulo if (sm->Init) { 1778214501Srpaulo /* Init flag is not cleared here, so avoid busy 1779214501Srpaulo * loop by claiming nothing changed. */ 1780214501Srpaulo sm->changed = FALSE; 1781214501Srpaulo } 1782214501Srpaulo 1783214501Srpaulo sm->keycount = 0; 1784214501Srpaulo if (sm->GUpdateStationKeys) 1785214501Srpaulo sm->group->GKeyDoneStations--; 1786214501Srpaulo sm->GUpdateStationKeys = FALSE; 1787214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 1788214501Srpaulo sm->PInitAKeys = FALSE; 1789214501Srpaulo if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and 1790214501Srpaulo * Local AA > Remote AA)) */) { 1791214501Srpaulo sm->Pair = TRUE; 1792214501Srpaulo } 1793214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0); 1794214501Srpaulo wpa_remove_ptk(sm); 1795214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0); 1796214501Srpaulo sm->TimeoutCtr = 0; 1797214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1798214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 1799214501Srpaulo WPA_EAPOL_authorized, 0); 1800214501Srpaulo } 1801214501Srpaulo} 1802214501Srpaulo 1803214501Srpaulo 1804214501SrpauloSM_STATE(WPA_PTK, DISCONNECT) 1805214501Srpaulo{ 1806214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); 1807214501Srpaulo sm->Disconnect = FALSE; 1808214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 1809214501Srpaulo} 1810214501Srpaulo 1811214501Srpaulo 1812214501SrpauloSM_STATE(WPA_PTK, DISCONNECTED) 1813214501Srpaulo{ 1814214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk); 1815214501Srpaulo sm->DeauthenticationRequest = FALSE; 1816214501Srpaulo} 1817214501Srpaulo 1818214501Srpaulo 1819214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION) 1820214501Srpaulo{ 1821214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk); 1822214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1823214501Srpaulo sm->PTK_valid = FALSE; 1824214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto, 1825214501Srpaulo 1); 1826214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1); 1827214501Srpaulo sm->AuthenticationRequest = FALSE; 1828214501Srpaulo} 1829214501Srpaulo 1830214501Srpaulo 1831252726Srpaulostatic void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth, 1832252726Srpaulo struct wpa_group *group) 1833252726Srpaulo{ 1834252726Srpaulo if (group->first_sta_seen) 1835252726Srpaulo return; 1836252726Srpaulo /* 1837252726Srpaulo * System has run bit further than at the time hostapd was started 1838252726Srpaulo * potentially very early during boot up. This provides better chances 1839252726Srpaulo * of collecting more randomness on embedded systems. Re-initialize the 1840252726Srpaulo * GMK and Counter here to improve their strength if there was not 1841252726Srpaulo * enough entropy available immediately after system startup. 1842252726Srpaulo */ 1843252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first " 1844252726Srpaulo "station"); 1845252726Srpaulo if (random_pool_ready() != 1) { 1846252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 1847252726Srpaulo "to proceed - reject first 4-way handshake"); 1848252726Srpaulo group->reject_4way_hs_for_entropy = TRUE; 1849252726Srpaulo } else { 1850252726Srpaulo group->first_sta_seen = TRUE; 1851252726Srpaulo group->reject_4way_hs_for_entropy = FALSE; 1852252726Srpaulo } 1853252726Srpaulo 1854289549Srpaulo if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0 || 1855289549Srpaulo wpa_gtk_update(wpa_auth, group) < 0 || 1856289549Srpaulo wpa_group_config_group_keys(wpa_auth, group) < 0) { 1857289549Srpaulo wpa_printf(MSG_INFO, "WPA: GMK/GTK setup failed"); 1858289549Srpaulo group->first_sta_seen = FALSE; 1859289549Srpaulo group->reject_4way_hs_for_entropy = TRUE; 1860289549Srpaulo } 1861252726Srpaulo} 1862252726Srpaulo 1863252726Srpaulo 1864214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION2) 1865214501Srpaulo{ 1866214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk); 1867252726Srpaulo 1868252726Srpaulo wpa_group_ensure_init(sm->wpa_auth, sm->group); 1869281806Srpaulo sm->ReAuthenticationRequest = FALSE; 1870252726Srpaulo 1871252726Srpaulo /* 1872252726Srpaulo * Definition of ANonce selection in IEEE Std 802.11i-2004 is somewhat 1873252726Srpaulo * ambiguous. The Authenticator state machine uses a counter that is 1874252726Srpaulo * incremented by one for each 4-way handshake. However, the security 1875252726Srpaulo * analysis of 4-way handshake points out that unpredictable nonces 1876252726Srpaulo * help in preventing precomputation attacks. Instead of the state 1877252726Srpaulo * machine definition, use an unpredictable nonce value here to provide 1878252726Srpaulo * stronger protection against potential precomputation attacks. 1879252726Srpaulo */ 1880252726Srpaulo if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 1881252726Srpaulo wpa_printf(MSG_ERROR, "WPA: Failed to get random data for " 1882252726Srpaulo "ANonce."); 1883281806Srpaulo sm->Disconnect = TRUE; 1884252726Srpaulo return; 1885252726Srpaulo } 1886252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, 1887252726Srpaulo WPA_NONCE_LEN); 1888214501Srpaulo /* IEEE 802.11i does not clear TimeoutCtr here, but this is more 1889214501Srpaulo * logical place than INITIALIZE since AUTHENTICATION2 can be 1890214501Srpaulo * re-entered on ReAuthenticationRequest without going through 1891214501Srpaulo * INITIALIZE. */ 1892214501Srpaulo sm->TimeoutCtr = 0; 1893214501Srpaulo} 1894214501Srpaulo 1895214501Srpaulo 1896324698Sgordonstatic int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) 1897324698Sgordon{ 1898324698Sgordon if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 1899324698Sgordon wpa_printf(MSG_ERROR, 1900324698Sgordon "WPA: Failed to get random data for ANonce"); 1901324698Sgordon sm->Disconnect = TRUE; 1902324698Sgordon return -1; 1903324698Sgordon } 1904324698Sgordon wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, 1905324698Sgordon WPA_NONCE_LEN); 1906324698Sgordon sm->TimeoutCtr = 0; 1907324698Sgordon return 0; 1908324698Sgordon} 1909324698Sgordon 1910324698Sgordon 1911214501SrpauloSM_STATE(WPA_PTK, INITPMK) 1912214501Srpaulo{ 1913214501Srpaulo u8 msk[2 * PMK_LEN]; 1914214501Srpaulo size_t len = 2 * PMK_LEN; 1915214501Srpaulo 1916214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk); 1917214501Srpaulo#ifdef CONFIG_IEEE80211R 1918214501Srpaulo sm->xxkey_len = 0; 1919214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1920214501Srpaulo if (sm->pmksa) { 1921214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache"); 1922214501Srpaulo os_memcpy(sm->PMK, sm->pmksa->pmk, PMK_LEN); 1923214501Srpaulo } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) { 1924214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine " 1925214501Srpaulo "(len=%lu)", (unsigned long) len); 1926214501Srpaulo os_memcpy(sm->PMK, msk, PMK_LEN); 1927214501Srpaulo#ifdef CONFIG_IEEE80211R 1928214501Srpaulo if (len >= 2 * PMK_LEN) { 1929214501Srpaulo os_memcpy(sm->xxkey, msk + PMK_LEN, PMK_LEN); 1930214501Srpaulo sm->xxkey_len = PMK_LEN; 1931214501Srpaulo } 1932214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1933214501Srpaulo } else { 1934281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Could not get PMK, get_msk: %p", 1935281806Srpaulo sm->wpa_auth->cb.get_msk); 1936281806Srpaulo sm->Disconnect = TRUE; 1937281806Srpaulo return; 1938214501Srpaulo } 1939281806Srpaulo os_memset(msk, 0, sizeof(msk)); 1940214501Srpaulo 1941214501Srpaulo sm->req_replay_counter_used = 0; 1942214501Srpaulo /* IEEE 802.11i does not set keyRun to FALSE, but not doing this 1943214501Srpaulo * will break reauthentication since EAPOL state machines may not be 1944214501Srpaulo * get into AUTHENTICATING state that clears keyRun before WPA state 1945214501Srpaulo * machine enters AUTHENTICATION2 state and goes immediately to INITPMK 1946214501Srpaulo * state and takes PMK from the previously used AAA Key. This will 1947214501Srpaulo * eventually fail in 4-Way Handshake because Supplicant uses PMK 1948214501Srpaulo * derived from the new AAA Key. Setting keyRun = FALSE here seems to 1949214501Srpaulo * be good workaround for this issue. */ 1950214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0); 1951214501Srpaulo} 1952214501Srpaulo 1953214501Srpaulo 1954214501SrpauloSM_STATE(WPA_PTK, INITPSK) 1955214501Srpaulo{ 1956214501Srpaulo const u8 *psk; 1957214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk); 1958281806Srpaulo psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, NULL); 1959214501Srpaulo if (psk) { 1960214501Srpaulo os_memcpy(sm->PMK, psk, PMK_LEN); 1961214501Srpaulo#ifdef CONFIG_IEEE80211R 1962214501Srpaulo os_memcpy(sm->xxkey, psk, PMK_LEN); 1963214501Srpaulo sm->xxkey_len = PMK_LEN; 1964214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1965214501Srpaulo } 1966214501Srpaulo sm->req_replay_counter_used = 0; 1967214501Srpaulo} 1968214501Srpaulo 1969214501Srpaulo 1970214501SrpauloSM_STATE(WPA_PTK, PTKSTART) 1971214501Srpaulo{ 1972214501Srpaulo u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL; 1973214501Srpaulo size_t pmkid_len = 0; 1974214501Srpaulo 1975214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk); 1976214501Srpaulo sm->PTKRequest = FALSE; 1977214501Srpaulo sm->TimeoutEvt = FALSE; 1978281806Srpaulo sm->alt_snonce_valid = FALSE; 1979214501Srpaulo 1980214501Srpaulo sm->TimeoutCtr++; 1981214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 1982214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 1983214501Srpaulo * immediately following this. */ 1984214501Srpaulo return; 1985214501Srpaulo } 1986214501Srpaulo 1987214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1988214501Srpaulo "sending 1/4 msg of 4-Way Handshake"); 1989214501Srpaulo /* 1990214501Srpaulo * TODO: Could add PMKID even with WPA2-PSK, but only if there is only 1991214501Srpaulo * one possible PSK for this STA. 1992214501Srpaulo */ 1993214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && 1994281806Srpaulo wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 1995281806Srpaulo sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) { 1996214501Srpaulo pmkid = buf; 1997214501Srpaulo pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 1998214501Srpaulo pmkid[0] = WLAN_EID_VENDOR_SPECIFIC; 1999214501Srpaulo pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN; 2000214501Srpaulo RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID); 2001281806Srpaulo if (sm->pmksa) { 2002214501Srpaulo os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], 2003214501Srpaulo sm->pmksa->pmkid, PMKID_LEN); 2004281806Srpaulo } else if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) { 2005281806Srpaulo /* No KCK available to derive PMKID */ 2006281806Srpaulo pmkid = NULL; 2007281806Srpaulo } else { 2008214501Srpaulo /* 2009214501Srpaulo * Calculate PMKID since no PMKSA cache entry was 2010214501Srpaulo * available with pre-calculated PMKID. 2011214501Srpaulo */ 2012214501Srpaulo rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr, 2013214501Srpaulo sm->addr, &pmkid[2 + RSN_SELECTOR_LEN], 2014214501Srpaulo wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 2015214501Srpaulo } 2016214501Srpaulo } 2017214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2018214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL, 2019214501Srpaulo sm->ANonce, pmkid, pmkid_len, 0, 0); 2020214501Srpaulo} 2021214501Srpaulo 2022214501Srpaulo 2023281806Srpaulostatic int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, 2024281806Srpaulo const u8 *pmk, struct wpa_ptk *ptk) 2025214501Srpaulo{ 2026214501Srpaulo#ifdef CONFIG_IEEE80211R 2027214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 2028281806Srpaulo return wpa_auth_derive_ptk_ft(sm, pmk, ptk); 2029214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2030214501Srpaulo 2031281806Srpaulo return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion", 2032281806Srpaulo sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, 2033281806Srpaulo ptk, sm->wpa_key_mgmt, sm->pairwise); 2034214501Srpaulo} 2035214501Srpaulo 2036214501Srpaulo 2037214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING) 2038214501Srpaulo{ 2039214501Srpaulo struct wpa_ptk PTK; 2040289549Srpaulo int ok = 0, psk_found = 0; 2041214501Srpaulo const u8 *pmk = NULL; 2042214501Srpaulo 2043214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); 2044214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2045252726Srpaulo sm->update_snonce = FALSE; 2046214501Srpaulo 2047214501Srpaulo /* WPA with IEEE 802.1X: use the derived PMK from EAP 2048214501Srpaulo * WPA-PSK: iterate through possible PSKs and select the one matching 2049214501Srpaulo * the packet */ 2050214501Srpaulo for (;;) { 2051214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2052281806Srpaulo pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, 2053281806Srpaulo sm->p2p_dev_addr, pmk); 2054214501Srpaulo if (pmk == NULL) 2055214501Srpaulo break; 2056289549Srpaulo psk_found = 1; 2057214501Srpaulo } else 2058214501Srpaulo pmk = sm->PMK; 2059214501Srpaulo 2060281806Srpaulo wpa_derive_ptk(sm, sm->SNonce, pmk, &PTK); 2061214501Srpaulo 2062281806Srpaulo if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, 2063281806Srpaulo sm->last_rx_eapol_key, 2064214501Srpaulo sm->last_rx_eapol_key_len) == 0) { 2065214501Srpaulo ok = 1; 2066214501Srpaulo break; 2067214501Srpaulo } 2068214501Srpaulo 2069214501Srpaulo if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 2070214501Srpaulo break; 2071214501Srpaulo } 2072214501Srpaulo 2073214501Srpaulo if (!ok) { 2074214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2075214501Srpaulo "invalid MIC in msg 2/4 of 4-Way Handshake"); 2076289549Srpaulo if (psk_found) 2077289549Srpaulo wpa_auth_psk_failure_report(sm->wpa_auth, sm->addr); 2078214501Srpaulo return; 2079214501Srpaulo } 2080214501Srpaulo 2081214501Srpaulo#ifdef CONFIG_IEEE80211R 2082214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2083214501Srpaulo /* 2084214501Srpaulo * Verify that PMKR1Name from EAPOL-Key message 2/4 matches 2085214501Srpaulo * with the value we derived. 2086214501Srpaulo */ 2087281806Srpaulo if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name, 2088281806Srpaulo WPA_PMK_NAME_LEN) != 0) { 2089214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2090214501Srpaulo "PMKR1Name mismatch in FT 4-way " 2091214501Srpaulo "handshake"); 2092214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from " 2093214501Srpaulo "Supplicant", 2094214501Srpaulo sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN); 2095214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", 2096214501Srpaulo sm->pmk_r1_name, WPA_PMK_NAME_LEN); 2097214501Srpaulo return; 2098214501Srpaulo } 2099214501Srpaulo } 2100214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2101214501Srpaulo 2102252726Srpaulo sm->pending_1_of_4_timeout = 0; 2103214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 2104214501Srpaulo 2105214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2106214501Srpaulo /* PSK may have changed from the previous choice, so update 2107214501Srpaulo * state machine data based on whatever PSK was selected here. 2108214501Srpaulo */ 2109214501Srpaulo os_memcpy(sm->PMK, pmk, PMK_LEN); 2110214501Srpaulo } 2111214501Srpaulo 2112214501Srpaulo sm->MICVerified = TRUE; 2113214501Srpaulo 2114214501Srpaulo os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 2115214501Srpaulo sm->PTK_valid = TRUE; 2116214501Srpaulo} 2117214501Srpaulo 2118214501Srpaulo 2119214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING2) 2120214501Srpaulo{ 2121214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk); 2122214501Srpaulo sm->TimeoutCtr = 0; 2123214501Srpaulo} 2124214501Srpaulo 2125214501Srpaulo 2126214501Srpaulo#ifdef CONFIG_IEEE80211W 2127214501Srpaulo 2128214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 2129214501Srpaulo{ 2130214501Srpaulo if (sm->mgmt_frame_prot) { 2131281806Srpaulo size_t len; 2132281806Srpaulo len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2133281806Srpaulo return 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN + len; 2134214501Srpaulo } 2135214501Srpaulo 2136214501Srpaulo return 0; 2137214501Srpaulo} 2138214501Srpaulo 2139214501Srpaulo 2140214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 2141214501Srpaulo{ 2142214501Srpaulo struct wpa_igtk_kde igtk; 2143214501Srpaulo struct wpa_group *gsm = sm->group; 2144281806Srpaulo u8 rsc[WPA_KEY_RSC_LEN]; 2145281806Srpaulo size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2146214501Srpaulo 2147214501Srpaulo if (!sm->mgmt_frame_prot) 2148214501Srpaulo return pos; 2149214501Srpaulo 2150214501Srpaulo igtk.keyid[0] = gsm->GN_igtk; 2151214501Srpaulo igtk.keyid[1] = 0; 2152214501Srpaulo if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE || 2153281806Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, rsc) < 0) 2154214501Srpaulo os_memset(igtk.pn, 0, sizeof(igtk.pn)); 2155281806Srpaulo else 2156281806Srpaulo os_memcpy(igtk.pn, rsc, sizeof(igtk.pn)); 2157281806Srpaulo os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len); 2158252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2159252726Srpaulo /* 2160252726Srpaulo * Provide unique random IGTK to each STA to prevent use of 2161252726Srpaulo * IGTK in the BSS. 2162252726Srpaulo */ 2163281806Srpaulo if (random_get_bytes(igtk.igtk, len) < 0) 2164252726Srpaulo return pos; 2165252726Srpaulo } 2166214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, 2167281806Srpaulo (const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len, 2168281806Srpaulo NULL, 0); 2169214501Srpaulo 2170214501Srpaulo return pos; 2171214501Srpaulo} 2172214501Srpaulo 2173214501Srpaulo#else /* CONFIG_IEEE80211W */ 2174214501Srpaulo 2175214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 2176214501Srpaulo{ 2177214501Srpaulo return 0; 2178214501Srpaulo} 2179214501Srpaulo 2180214501Srpaulo 2181214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 2182214501Srpaulo{ 2183214501Srpaulo return pos; 2184214501Srpaulo} 2185214501Srpaulo 2186214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2187214501Srpaulo 2188214501Srpaulo 2189214501SrpauloSM_STATE(WPA_PTK, PTKINITNEGOTIATING) 2190214501Srpaulo{ 2191252726Srpaulo u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32]; 2192214501Srpaulo size_t gtk_len, kde_len; 2193214501Srpaulo struct wpa_group *gsm = sm->group; 2194214501Srpaulo u8 *wpa_ie; 2195214501Srpaulo int wpa_ie_len, secure, keyidx, encr = 0; 2196214501Srpaulo 2197214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); 2198214501Srpaulo sm->TimeoutEvt = FALSE; 2199214501Srpaulo 2200214501Srpaulo sm->TimeoutCtr++; 2201214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 2202214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 2203214501Srpaulo * immediately following this. */ 2204214501Srpaulo return; 2205214501Srpaulo } 2206214501Srpaulo 2207214501Srpaulo /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE], 2208214501Srpaulo GTK[GN], IGTK, [FTIE], [TIE * 2]) 2209214501Srpaulo */ 2210214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 2211214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 2212214501Srpaulo /* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */ 2213214501Srpaulo wpa_ie = sm->wpa_auth->wpa_ie; 2214214501Srpaulo wpa_ie_len = sm->wpa_auth->wpa_ie_len; 2215214501Srpaulo if (sm->wpa == WPA_VERSION_WPA && 2216214501Srpaulo (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) && 2217214501Srpaulo wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) { 2218281806Srpaulo /* WPA-only STA, remove RSN IE and possible MDIE */ 2219214501Srpaulo wpa_ie = wpa_ie + wpa_ie[1] + 2; 2220281806Srpaulo if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN) 2221281806Srpaulo wpa_ie = wpa_ie + wpa_ie[1] + 2; 2222214501Srpaulo wpa_ie_len = wpa_ie[1] + 2; 2223214501Srpaulo } 2224214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2225214501Srpaulo "sending 3/4 msg of 4-Way Handshake"); 2226214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 2227214501Srpaulo /* WPA2 send GTK in the 4-way handshake */ 2228214501Srpaulo secure = 1; 2229214501Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 2230214501Srpaulo gtk_len = gsm->GTK_len; 2231252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2232252726Srpaulo /* 2233252726Srpaulo * Provide unique random GTK to each STA to prevent use 2234252726Srpaulo * of GTK in the BSS. 2235252726Srpaulo */ 2236252726Srpaulo if (random_get_bytes(dummy_gtk, gtk_len) < 0) 2237252726Srpaulo return; 2238252726Srpaulo gtk = dummy_gtk; 2239252726Srpaulo } 2240214501Srpaulo keyidx = gsm->GN; 2241214501Srpaulo _rsc = rsc; 2242214501Srpaulo encr = 1; 2243214501Srpaulo } else { 2244214501Srpaulo /* WPA does not include GTK in msg 3/4 */ 2245214501Srpaulo secure = 0; 2246214501Srpaulo gtk = NULL; 2247214501Srpaulo gtk_len = 0; 2248214501Srpaulo keyidx = 0; 2249214501Srpaulo _rsc = NULL; 2250252726Srpaulo if (sm->rx_eapol_key_secure) { 2251252726Srpaulo /* 2252252726Srpaulo * It looks like Windows 7 supplicant tries to use 2253252726Srpaulo * Secure bit in msg 2/4 after having reported Michael 2254252726Srpaulo * MIC failure and it then rejects the 4-way handshake 2255252726Srpaulo * if msg 3/4 does not set Secure bit. Work around this 2256252726Srpaulo * by setting the Secure bit here even in the case of 2257252726Srpaulo * WPA if the supplicant used it first. 2258252726Srpaulo */ 2259252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2260252726Srpaulo "STA used Secure bit in WPA msg 2/4 - " 2261252726Srpaulo "set Secure for 3/4 as workaround"); 2262252726Srpaulo secure = 1; 2263252726Srpaulo } 2264214501Srpaulo } 2265214501Srpaulo 2266214501Srpaulo kde_len = wpa_ie_len + ieee80211w_kde_len(sm); 2267214501Srpaulo if (gtk) 2268214501Srpaulo kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len; 2269214501Srpaulo#ifdef CONFIG_IEEE80211R 2270214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2271214501Srpaulo kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */ 2272214501Srpaulo kde_len += 300; /* FTIE + 2 * TIE */ 2273214501Srpaulo } 2274214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2275281806Srpaulo#ifdef CONFIG_P2P 2276281806Srpaulo if (WPA_GET_BE32(sm->ip_addr) > 0) 2277281806Srpaulo kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4; 2278281806Srpaulo#endif /* CONFIG_P2P */ 2279214501Srpaulo kde = os_malloc(kde_len); 2280214501Srpaulo if (kde == NULL) 2281214501Srpaulo return; 2282214501Srpaulo 2283214501Srpaulo pos = kde; 2284214501Srpaulo os_memcpy(pos, wpa_ie, wpa_ie_len); 2285214501Srpaulo pos += wpa_ie_len; 2286214501Srpaulo#ifdef CONFIG_IEEE80211R 2287214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2288214501Srpaulo int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name); 2289214501Srpaulo if (res < 0) { 2290214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert " 2291214501Srpaulo "PMKR1Name into RSN IE in EAPOL-Key data"); 2292214501Srpaulo os_free(kde); 2293214501Srpaulo return; 2294214501Srpaulo } 2295214501Srpaulo pos += res; 2296214501Srpaulo } 2297214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2298214501Srpaulo if (gtk) { 2299214501Srpaulo u8 hdr[2]; 2300214501Srpaulo hdr[0] = keyidx & 0x03; 2301214501Srpaulo hdr[1] = 0; 2302214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 2303214501Srpaulo gtk, gtk_len); 2304214501Srpaulo } 2305214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 2306214501Srpaulo 2307214501Srpaulo#ifdef CONFIG_IEEE80211R 2308214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2309214501Srpaulo int res; 2310214501Srpaulo struct wpa_auth_config *conf; 2311214501Srpaulo 2312214501Srpaulo conf = &sm->wpa_auth->conf; 2313214501Srpaulo res = wpa_write_ftie(conf, conf->r0_key_holder, 2314214501Srpaulo conf->r0_key_holder_len, 2315214501Srpaulo NULL, NULL, pos, kde + kde_len - pos, 2316214501Srpaulo NULL, 0); 2317214501Srpaulo if (res < 0) { 2318214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " 2319214501Srpaulo "into EAPOL-Key Key Data"); 2320214501Srpaulo os_free(kde); 2321214501Srpaulo return; 2322214501Srpaulo } 2323214501Srpaulo pos += res; 2324214501Srpaulo 2325214501Srpaulo /* TIE[ReassociationDeadline] (TU) */ 2326214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2327214501Srpaulo *pos++ = 5; 2328214501Srpaulo *pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE; 2329214501Srpaulo WPA_PUT_LE32(pos, conf->reassociation_deadline); 2330214501Srpaulo pos += 4; 2331214501Srpaulo 2332214501Srpaulo /* TIE[KeyLifetime] (seconds) */ 2333214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2334214501Srpaulo *pos++ = 5; 2335214501Srpaulo *pos++ = WLAN_TIMEOUT_KEY_LIFETIME; 2336214501Srpaulo WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60); 2337214501Srpaulo pos += 4; 2338214501Srpaulo } 2339214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2340281806Srpaulo#ifdef CONFIG_P2P 2341281806Srpaulo if (WPA_GET_BE32(sm->ip_addr) > 0) { 2342281806Srpaulo u8 addr[3 * 4]; 2343281806Srpaulo os_memcpy(addr, sm->ip_addr, 4); 2344281806Srpaulo os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4); 2345281806Srpaulo os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4); 2346281806Srpaulo pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC, 2347281806Srpaulo addr, sizeof(addr), NULL, 0); 2348281806Srpaulo } 2349281806Srpaulo#endif /* CONFIG_P2P */ 2350214501Srpaulo 2351214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2352214501Srpaulo (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC | 2353214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | 2354214501Srpaulo WPA_KEY_INFO_KEY_TYPE, 2355214501Srpaulo _rsc, sm->ANonce, kde, pos - kde, keyidx, encr); 2356214501Srpaulo os_free(kde); 2357214501Srpaulo} 2358214501Srpaulo 2359214501Srpaulo 2360214501SrpauloSM_STATE(WPA_PTK, PTKINITDONE) 2361214501Srpaulo{ 2362214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk); 2363214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2364214501Srpaulo if (sm->Pair) { 2365252726Srpaulo enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise); 2366252726Srpaulo int klen = wpa_cipher_key_len(sm->pairwise); 2367214501Srpaulo if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, 2368281806Srpaulo sm->PTK.tk, klen)) { 2369214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 2370214501Srpaulo return; 2371214501Srpaulo } 2372214501Srpaulo /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ 2373214501Srpaulo sm->pairwise_set = TRUE; 2374214501Srpaulo 2375214501Srpaulo if (sm->wpa_auth->conf.wpa_ptk_rekey) { 2376214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 2377214501Srpaulo eloop_register_timeout(sm->wpa_auth->conf. 2378214501Srpaulo wpa_ptk_rekey, 0, wpa_rekey_ptk, 2379214501Srpaulo sm->wpa_auth, sm); 2380214501Srpaulo } 2381214501Srpaulo 2382214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2383214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2384214501Srpaulo WPA_EAPOL_authorized, 1); 2385214501Srpaulo } 2386214501Srpaulo } 2387214501Srpaulo 2388214501Srpaulo if (0 /* IBSS == TRUE */) { 2389214501Srpaulo sm->keycount++; 2390214501Srpaulo if (sm->keycount == 2) { 2391214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2392214501Srpaulo WPA_EAPOL_portValid, 1); 2393214501Srpaulo } 2394214501Srpaulo } else { 2395214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 2396214501Srpaulo 1); 2397214501Srpaulo } 2398214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0); 2399214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1); 2400214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2401214501Srpaulo sm->PInitAKeys = TRUE; 2402214501Srpaulo else 2403214501Srpaulo sm->has_GTK = TRUE; 2404214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2405214501Srpaulo "pairwise key handshake completed (%s)", 2406214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2407214501Srpaulo 2408214501Srpaulo#ifdef CONFIG_IEEE80211R 2409214501Srpaulo wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr); 2410214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2411214501Srpaulo} 2412214501Srpaulo 2413214501Srpaulo 2414214501SrpauloSM_STEP(WPA_PTK) 2415214501Srpaulo{ 2416214501Srpaulo struct wpa_authenticator *wpa_auth = sm->wpa_auth; 2417214501Srpaulo 2418214501Srpaulo if (sm->Init) 2419214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2420214501Srpaulo else if (sm->Disconnect 2421252726Srpaulo /* || FIX: dot11RSNAConfigSALifetime timeout */) { 2422252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 2423252726Srpaulo "WPA_PTK: sm->Disconnect"); 2424214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2425252726Srpaulo } 2426214501Srpaulo else if (sm->DeauthenticationRequest) 2427214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2428214501Srpaulo else if (sm->AuthenticationRequest) 2429214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION); 2430214501Srpaulo else if (sm->ReAuthenticationRequest) 2431214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2432324698Sgordon else if (sm->PTKRequest) { 2433324698Sgordon if (wpa_auth_sm_ptk_update(sm) < 0) 2434324698Sgordon SM_ENTER(WPA_PTK, DISCONNECTED); 2435324698Sgordon else 2436324698Sgordon SM_ENTER(WPA_PTK, PTKSTART); 2437324698Sgordon } else switch (sm->wpa_ptk_state) { 2438214501Srpaulo case WPA_PTK_INITIALIZE: 2439214501Srpaulo break; 2440214501Srpaulo case WPA_PTK_DISCONNECT: 2441214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2442214501Srpaulo break; 2443214501Srpaulo case WPA_PTK_DISCONNECTED: 2444214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2445214501Srpaulo break; 2446214501Srpaulo case WPA_PTK_AUTHENTICATION: 2447214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2448214501Srpaulo break; 2449214501Srpaulo case WPA_PTK_AUTHENTICATION2: 2450214501Srpaulo if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 2451214501Srpaulo wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2452214501Srpaulo WPA_EAPOL_keyRun) > 0) 2453214501Srpaulo SM_ENTER(WPA_PTK, INITPMK); 2454214501Srpaulo else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) 2455214501Srpaulo /* FIX: && 802.1X::keyRun */) 2456214501Srpaulo SM_ENTER(WPA_PTK, INITPSK); 2457214501Srpaulo break; 2458214501Srpaulo case WPA_PTK_INITPMK: 2459214501Srpaulo if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2460214501Srpaulo WPA_EAPOL_keyAvailable) > 0) 2461214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2462214501Srpaulo else { 2463214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2464252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2465252726Srpaulo "INITPMK - keyAvailable = false"); 2466214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2467214501Srpaulo } 2468214501Srpaulo break; 2469214501Srpaulo case WPA_PTK_INITPSK: 2470281806Srpaulo if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, 2471281806Srpaulo NULL)) 2472214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2473214501Srpaulo else { 2474214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2475214501Srpaulo "no PSK configured for the STA"); 2476214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2477214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2478214501Srpaulo } 2479214501Srpaulo break; 2480214501Srpaulo case WPA_PTK_PTKSTART: 2481214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2482214501Srpaulo sm->EAPOLKeyPairwise) 2483214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2484214501Srpaulo else if (sm->TimeoutCtr > 2485214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2486214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2487252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2488252726Srpaulo "PTKSTART: Retry limit %d reached", 2489252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2490214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2491214501Srpaulo } else if (sm->TimeoutEvt) 2492214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2493214501Srpaulo break; 2494214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING: 2495214501Srpaulo if (sm->MICVerified) 2496214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2); 2497214501Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2498214501Srpaulo sm->EAPOLKeyPairwise) 2499214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2500214501Srpaulo else if (sm->TimeoutEvt) 2501214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2502214501Srpaulo break; 2503214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING2: 2504214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2505214501Srpaulo break; 2506214501Srpaulo case WPA_PTK_PTKINITNEGOTIATING: 2507252726Srpaulo if (sm->update_snonce) 2508252726Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2509252726Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2510252726Srpaulo sm->EAPOLKeyPairwise && sm->MICVerified) 2511214501Srpaulo SM_ENTER(WPA_PTK, PTKINITDONE); 2512214501Srpaulo else if (sm->TimeoutCtr > 2513214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2514214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2515252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2516252726Srpaulo "PTKINITNEGOTIATING: Retry limit %d " 2517252726Srpaulo "reached", 2518252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2519214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2520214501Srpaulo } else if (sm->TimeoutEvt) 2521214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2522214501Srpaulo break; 2523214501Srpaulo case WPA_PTK_PTKINITDONE: 2524214501Srpaulo break; 2525214501Srpaulo } 2526214501Srpaulo} 2527214501Srpaulo 2528214501Srpaulo 2529214501SrpauloSM_STATE(WPA_PTK_GROUP, IDLE) 2530214501Srpaulo{ 2531214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group); 2532214501Srpaulo if (sm->Init) { 2533214501Srpaulo /* Init flag is not cleared here, so avoid busy 2534214501Srpaulo * loop by claiming nothing changed. */ 2535214501Srpaulo sm->changed = FALSE; 2536214501Srpaulo } 2537214501Srpaulo sm->GTimeoutCtr = 0; 2538214501Srpaulo} 2539214501Srpaulo 2540214501Srpaulo 2541214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING) 2542214501Srpaulo{ 2543214501Srpaulo u8 rsc[WPA_KEY_RSC_LEN]; 2544214501Srpaulo struct wpa_group *gsm = sm->group; 2545281806Srpaulo const u8 *kde; 2546281806Srpaulo u8 *kde_buf = NULL, *pos, hdr[2]; 2547214501Srpaulo size_t kde_len; 2548252726Srpaulo u8 *gtk, dummy_gtk[32]; 2549214501Srpaulo 2550214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group); 2551214501Srpaulo 2552214501Srpaulo sm->GTimeoutCtr++; 2553214501Srpaulo if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) { 2554214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 2555214501Srpaulo * immediately following this. */ 2556214501Srpaulo return; 2557214501Srpaulo } 2558214501Srpaulo 2559214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2560214501Srpaulo sm->PInitAKeys = FALSE; 2561214501Srpaulo sm->TimeoutEvt = FALSE; 2562214501Srpaulo /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */ 2563214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 2564214501Srpaulo if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE) 2565214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 2566214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2567214501Srpaulo "sending 1/2 msg of Group Key Handshake"); 2568214501Srpaulo 2569252726Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 2570252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2571252726Srpaulo /* 2572252726Srpaulo * Provide unique random GTK to each STA to prevent use 2573252726Srpaulo * of GTK in the BSS. 2574252726Srpaulo */ 2575252726Srpaulo if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0) 2576252726Srpaulo return; 2577252726Srpaulo gtk = dummy_gtk; 2578252726Srpaulo } 2579214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 2580214501Srpaulo kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len + 2581214501Srpaulo ieee80211w_kde_len(sm); 2582281806Srpaulo kde_buf = os_malloc(kde_len); 2583281806Srpaulo if (kde_buf == NULL) 2584214501Srpaulo return; 2585214501Srpaulo 2586281806Srpaulo kde = pos = kde_buf; 2587214501Srpaulo hdr[0] = gsm->GN & 0x03; 2588214501Srpaulo hdr[1] = 0; 2589214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 2590252726Srpaulo gtk, gsm->GTK_len); 2591214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 2592281806Srpaulo kde_len = pos - kde; 2593214501Srpaulo } else { 2594252726Srpaulo kde = gtk; 2595281806Srpaulo kde_len = gsm->GTK_len; 2596214501Srpaulo } 2597214501Srpaulo 2598214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2599214501Srpaulo WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC | 2600214501Srpaulo WPA_KEY_INFO_ACK | 2601214501Srpaulo (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0), 2602281806Srpaulo rsc, gsm->GNonce, kde, kde_len, gsm->GN, 1); 2603281806Srpaulo 2604281806Srpaulo os_free(kde_buf); 2605214501Srpaulo} 2606214501Srpaulo 2607214501Srpaulo 2608214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED) 2609214501Srpaulo{ 2610214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group); 2611214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2612214501Srpaulo if (sm->GUpdateStationKeys) 2613214501Srpaulo sm->group->GKeyDoneStations--; 2614214501Srpaulo sm->GUpdateStationKeys = FALSE; 2615214501Srpaulo sm->GTimeoutCtr = 0; 2616214501Srpaulo /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */ 2617214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2618214501Srpaulo "group key handshake completed (%s)", 2619214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2620214501Srpaulo sm->has_GTK = TRUE; 2621214501Srpaulo} 2622214501Srpaulo 2623214501Srpaulo 2624214501SrpauloSM_STATE(WPA_PTK_GROUP, KEYERROR) 2625214501Srpaulo{ 2626214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group); 2627214501Srpaulo if (sm->GUpdateStationKeys) 2628214501Srpaulo sm->group->GKeyDoneStations--; 2629214501Srpaulo sm->GUpdateStationKeys = FALSE; 2630214501Srpaulo sm->Disconnect = TRUE; 2631214501Srpaulo} 2632214501Srpaulo 2633214501Srpaulo 2634214501SrpauloSM_STEP(WPA_PTK_GROUP) 2635214501Srpaulo{ 2636214501Srpaulo if (sm->Init || sm->PtkGroupInit) { 2637214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2638214501Srpaulo sm->PtkGroupInit = FALSE; 2639214501Srpaulo } else switch (sm->wpa_ptk_group_state) { 2640214501Srpaulo case WPA_PTK_GROUP_IDLE: 2641214501Srpaulo if (sm->GUpdateStationKeys || 2642214501Srpaulo (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys)) 2643214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2644214501Srpaulo break; 2645214501Srpaulo case WPA_PTK_GROUP_REKEYNEGOTIATING: 2646214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2647214501Srpaulo !sm->EAPOLKeyPairwise && sm->MICVerified) 2648214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED); 2649214501Srpaulo else if (sm->GTimeoutCtr > 2650214501Srpaulo (int) dot11RSNAConfigGroupUpdateCount) 2651214501Srpaulo SM_ENTER(WPA_PTK_GROUP, KEYERROR); 2652214501Srpaulo else if (sm->TimeoutEvt) 2653214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2654214501Srpaulo break; 2655214501Srpaulo case WPA_PTK_GROUP_KEYERROR: 2656214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2657214501Srpaulo break; 2658214501Srpaulo case WPA_PTK_GROUP_REKEYESTABLISHED: 2659214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2660214501Srpaulo break; 2661214501Srpaulo } 2662214501Srpaulo} 2663214501Srpaulo 2664214501Srpaulo 2665214501Srpaulostatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 2666214501Srpaulo struct wpa_group *group) 2667214501Srpaulo{ 2668214501Srpaulo int ret = 0; 2669214501Srpaulo 2670214501Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2671214501Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2672252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "Group key expansion", 2673252726Srpaulo wpa_auth->addr, group->GNonce, 2674252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2675252726Srpaulo ret = -1; 2676252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GTK", 2677252726Srpaulo group->GTK[group->GN - 1], group->GTK_len); 2678214501Srpaulo 2679214501Srpaulo#ifdef CONFIG_IEEE80211W 2680214501Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2681281806Srpaulo size_t len; 2682281806Srpaulo len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 2683252726Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2684252726Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2685252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion", 2686252726Srpaulo wpa_auth->addr, group->GNonce, 2687281806Srpaulo group->IGTK[group->GN_igtk - 4], len) < 0) 2688214501Srpaulo ret = -1; 2689214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "IGTK", 2690281806Srpaulo group->IGTK[group->GN_igtk - 4], len); 2691214501Srpaulo } 2692214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2693214501Srpaulo 2694214501Srpaulo return ret; 2695214501Srpaulo} 2696214501Srpaulo 2697214501Srpaulo 2698214501Srpaulostatic void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth, 2699214501Srpaulo struct wpa_group *group) 2700214501Srpaulo{ 2701214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2702214501Srpaulo "GTK_INIT (VLAN-ID %d)", group->vlan_id); 2703214501Srpaulo group->changed = FALSE; /* GInit is not cleared here; avoid loop */ 2704214501Srpaulo group->wpa_group_state = WPA_GROUP_GTK_INIT; 2705214501Srpaulo 2706214501Srpaulo /* GTK[0..N] = 0 */ 2707214501Srpaulo os_memset(group->GTK, 0, sizeof(group->GTK)); 2708214501Srpaulo group->GN = 1; 2709214501Srpaulo group->GM = 2; 2710214501Srpaulo#ifdef CONFIG_IEEE80211W 2711214501Srpaulo group->GN_igtk = 4; 2712214501Srpaulo group->GM_igtk = 5; 2713214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2714214501Srpaulo /* GTK[GN] = CalcGTK() */ 2715214501Srpaulo wpa_gtk_update(wpa_auth, group); 2716214501Srpaulo} 2717214501Srpaulo 2718214501Srpaulo 2719214501Srpaulostatic int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx) 2720214501Srpaulo{ 2721252726Srpaulo if (ctx != NULL && ctx != sm->group) 2722252726Srpaulo return 0; 2723252726Srpaulo 2724214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) { 2725214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2726214501Srpaulo "Not in PTKINITDONE; skip Group Key update"); 2727252726Srpaulo sm->GUpdateStationKeys = FALSE; 2728214501Srpaulo return 0; 2729214501Srpaulo } 2730214501Srpaulo if (sm->GUpdateStationKeys) { 2731214501Srpaulo /* 2732252726Srpaulo * This should not really happen, so add a debug log entry. 2733252726Srpaulo * Since we clear the GKeyDoneStations before the loop, the 2734252726Srpaulo * station needs to be counted here anyway. 2735214501Srpaulo */ 2736214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2737252726Srpaulo "GUpdateStationKeys was already set when " 2738252726Srpaulo "marking station for GTK rekeying"); 2739214501Srpaulo } 2740252726Srpaulo 2741252726Srpaulo /* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */ 2742252726Srpaulo if (sm->is_wnmsleep) 2743252726Srpaulo return 0; 2744252726Srpaulo 2745252726Srpaulo sm->group->GKeyDoneStations++; 2746252726Srpaulo sm->GUpdateStationKeys = TRUE; 2747252726Srpaulo 2748214501Srpaulo wpa_sm_step(sm); 2749214501Srpaulo return 0; 2750214501Srpaulo} 2751214501Srpaulo 2752214501Srpaulo 2753252726Srpaulo#ifdef CONFIG_WNM 2754252726Srpaulo/* update GTK when exiting WNM-Sleep Mode */ 2755252726Srpaulovoid wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm) 2756252726Srpaulo{ 2757281806Srpaulo if (sm == NULL || sm->is_wnmsleep) 2758252726Srpaulo return; 2759252726Srpaulo 2760252726Srpaulo wpa_group_update_sta(sm, NULL); 2761252726Srpaulo} 2762252726Srpaulo 2763252726Srpaulo 2764252726Srpaulovoid wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag) 2765252726Srpaulo{ 2766281806Srpaulo if (sm) 2767281806Srpaulo sm->is_wnmsleep = !!flag; 2768252726Srpaulo} 2769252726Srpaulo 2770252726Srpaulo 2771252726Srpauloint wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2772252726Srpaulo{ 2773252726Srpaulo struct wpa_group *gsm = sm->group; 2774252726Srpaulo u8 *start = pos; 2775252726Srpaulo 2776252726Srpaulo /* 2777252726Srpaulo * GTK subelement: 2778252726Srpaulo * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] | 2779252726Srpaulo * Key[5..32] 2780252726Srpaulo */ 2781252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_GTK; 2782252726Srpaulo *pos++ = 11 + gsm->GTK_len; 2783252726Srpaulo /* Key ID in B0-B1 of Key Info */ 2784252726Srpaulo WPA_PUT_LE16(pos, gsm->GN & 0x03); 2785252726Srpaulo pos += 2; 2786252726Srpaulo *pos++ = gsm->GTK_len; 2787252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0) 2788252726Srpaulo return 0; 2789252726Srpaulo pos += 8; 2790252726Srpaulo os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2791252726Srpaulo pos += gsm->GTK_len; 2792252726Srpaulo 2793252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit", 2794252726Srpaulo gsm->GN); 2795252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit", 2796252726Srpaulo gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2797252726Srpaulo 2798252726Srpaulo return pos - start; 2799252726Srpaulo} 2800252726Srpaulo 2801252726Srpaulo 2802252726Srpaulo#ifdef CONFIG_IEEE80211W 2803252726Srpauloint wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2804252726Srpaulo{ 2805252726Srpaulo struct wpa_group *gsm = sm->group; 2806252726Srpaulo u8 *start = pos; 2807281806Srpaulo size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher); 2808252726Srpaulo 2809252726Srpaulo /* 2810252726Srpaulo * IGTK subelement: 2811252726Srpaulo * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16] 2812252726Srpaulo */ 2813252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_IGTK; 2814281806Srpaulo *pos++ = 2 + 6 + len; 2815252726Srpaulo WPA_PUT_LE16(pos, gsm->GN_igtk); 2816252726Srpaulo pos += 2; 2817252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0) 2818252726Srpaulo return 0; 2819252726Srpaulo pos += 6; 2820252726Srpaulo 2821281806Srpaulo os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], len); 2822281806Srpaulo pos += len; 2823252726Srpaulo 2824252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit", 2825252726Srpaulo gsm->GN_igtk); 2826252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit", 2827281806Srpaulo gsm->IGTK[gsm->GN_igtk - 4], len); 2828252726Srpaulo 2829252726Srpaulo return pos - start; 2830252726Srpaulo} 2831252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2832252726Srpaulo#endif /* CONFIG_WNM */ 2833252726Srpaulo 2834252726Srpaulo 2835214501Srpaulostatic void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, 2836214501Srpaulo struct wpa_group *group) 2837214501Srpaulo{ 2838214501Srpaulo int tmp; 2839214501Srpaulo 2840214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2841214501Srpaulo "SETKEYS (VLAN-ID %d)", group->vlan_id); 2842214501Srpaulo group->changed = TRUE; 2843214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYS; 2844214501Srpaulo group->GTKReKey = FALSE; 2845214501Srpaulo tmp = group->GM; 2846214501Srpaulo group->GM = group->GN; 2847214501Srpaulo group->GN = tmp; 2848214501Srpaulo#ifdef CONFIG_IEEE80211W 2849214501Srpaulo tmp = group->GM_igtk; 2850214501Srpaulo group->GM_igtk = group->GN_igtk; 2851214501Srpaulo group->GN_igtk = tmp; 2852214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2853214501Srpaulo /* "GKeyDoneStations = GNoStations" is done in more robust way by 2854214501Srpaulo * counting the STAs that are marked with GUpdateStationKeys instead of 2855214501Srpaulo * including all STAs that could be in not-yet-completed state. */ 2856214501Srpaulo wpa_gtk_update(wpa_auth, group); 2857214501Srpaulo 2858252726Srpaulo if (group->GKeyDoneStations) { 2859252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected " 2860252726Srpaulo "GKeyDoneStations=%d when starting new GTK rekey", 2861252726Srpaulo group->GKeyDoneStations); 2862252726Srpaulo group->GKeyDoneStations = 0; 2863252726Srpaulo } 2864252726Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, group); 2865214501Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d", 2866214501Srpaulo group->GKeyDoneStations); 2867214501Srpaulo} 2868214501Srpaulo 2869214501Srpaulo 2870252726Srpaulostatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 2871252726Srpaulo struct wpa_group *group) 2872214501Srpaulo{ 2873252726Srpaulo int ret = 0; 2874252726Srpaulo 2875252726Srpaulo if (wpa_auth_set_key(wpa_auth, group->vlan_id, 2876252726Srpaulo wpa_cipher_to_alg(wpa_auth->conf.wpa_group), 2877252726Srpaulo broadcast_ether_addr, group->GN, 2878252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2879252726Srpaulo ret = -1; 2880252726Srpaulo 2881252726Srpaulo#ifdef CONFIG_IEEE80211W 2882281806Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2883281806Srpaulo enum wpa_alg alg; 2884281806Srpaulo size_t len; 2885281806Srpaulo 2886281806Srpaulo alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher); 2887281806Srpaulo len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); 2888281806Srpaulo 2889281806Srpaulo if (ret == 0 && 2890281806Srpaulo wpa_auth_set_key(wpa_auth, group->vlan_id, alg, 2891281806Srpaulo broadcast_ether_addr, group->GN_igtk, 2892281806Srpaulo group->IGTK[group->GN_igtk - 4], len) < 0) 2893281806Srpaulo ret = -1; 2894281806Srpaulo } 2895252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2896252726Srpaulo 2897252726Srpaulo return ret; 2898252726Srpaulo} 2899252726Srpaulo 2900252726Srpaulo 2901281806Srpaulostatic int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx) 2902281806Srpaulo{ 2903281806Srpaulo if (sm->group == ctx) { 2904281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR 2905281806Srpaulo " for discconnection due to fatal failure", 2906281806Srpaulo MAC2STR(sm->addr)); 2907281806Srpaulo sm->Disconnect = TRUE; 2908281806Srpaulo } 2909281806Srpaulo 2910281806Srpaulo return 0; 2911281806Srpaulo} 2912281806Srpaulo 2913281806Srpaulo 2914281806Srpaulostatic void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth, 2915281806Srpaulo struct wpa_group *group) 2916281806Srpaulo{ 2917281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE"); 2918281806Srpaulo group->changed = TRUE; 2919281806Srpaulo group->wpa_group_state = WPA_GROUP_FATAL_FAILURE; 2920281806Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group); 2921281806Srpaulo} 2922281806Srpaulo 2923281806Srpaulo 2924252726Srpaulostatic int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth, 2925252726Srpaulo struct wpa_group *group) 2926252726Srpaulo{ 2927214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2928214501Srpaulo "SETKEYSDONE (VLAN-ID %d)", group->vlan_id); 2929214501Srpaulo group->changed = TRUE; 2930214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYSDONE; 2931214501Srpaulo 2932281806Srpaulo if (wpa_group_config_group_keys(wpa_auth, group) < 0) { 2933281806Srpaulo wpa_group_fatal_failure(wpa_auth, group); 2934252726Srpaulo return -1; 2935281806Srpaulo } 2936252726Srpaulo 2937252726Srpaulo return 0; 2938214501Srpaulo} 2939214501Srpaulo 2940214501Srpaulo 2941214501Srpaulostatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 2942214501Srpaulo struct wpa_group *group) 2943214501Srpaulo{ 2944214501Srpaulo if (group->GInit) { 2945214501Srpaulo wpa_group_gtk_init(wpa_auth, group); 2946281806Srpaulo } else if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) { 2947281806Srpaulo /* Do not allow group operations */ 2948214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT && 2949214501Srpaulo group->GTKAuthenticator) { 2950214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2951214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE && 2952214501Srpaulo group->GTKReKey) { 2953214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2954214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) { 2955214501Srpaulo if (group->GKeyDoneStations == 0) 2956214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2957214501Srpaulo else if (group->GTKReKey) 2958214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2959214501Srpaulo } 2960214501Srpaulo} 2961214501Srpaulo 2962214501Srpaulo 2963214501Srpaulostatic int wpa_sm_step(struct wpa_state_machine *sm) 2964214501Srpaulo{ 2965214501Srpaulo if (sm == NULL) 2966214501Srpaulo return 0; 2967214501Srpaulo 2968214501Srpaulo if (sm->in_step_loop) { 2969214501Srpaulo /* This should not happen, but if it does, make sure we do not 2970214501Srpaulo * end up freeing the state machine too early by exiting the 2971214501Srpaulo * recursive call. */ 2972214501Srpaulo wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively"); 2973214501Srpaulo return 0; 2974214501Srpaulo } 2975214501Srpaulo 2976214501Srpaulo sm->in_step_loop = 1; 2977214501Srpaulo do { 2978214501Srpaulo if (sm->pending_deinit) 2979214501Srpaulo break; 2980214501Srpaulo 2981214501Srpaulo sm->changed = FALSE; 2982214501Srpaulo sm->wpa_auth->group->changed = FALSE; 2983214501Srpaulo 2984214501Srpaulo SM_STEP_RUN(WPA_PTK); 2985214501Srpaulo if (sm->pending_deinit) 2986214501Srpaulo break; 2987214501Srpaulo SM_STEP_RUN(WPA_PTK_GROUP); 2988214501Srpaulo if (sm->pending_deinit) 2989214501Srpaulo break; 2990214501Srpaulo wpa_group_sm_step(sm->wpa_auth, sm->group); 2991214501Srpaulo } while (sm->changed || sm->wpa_auth->group->changed); 2992214501Srpaulo sm->in_step_loop = 0; 2993214501Srpaulo 2994214501Srpaulo if (sm->pending_deinit) { 2995214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state " 2996214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 2997214501Srpaulo wpa_free_sta_sm(sm); 2998214501Srpaulo return 1; 2999214501Srpaulo } 3000214501Srpaulo return 0; 3001214501Srpaulo} 3002214501Srpaulo 3003214501Srpaulo 3004214501Srpaulostatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx) 3005214501Srpaulo{ 3006214501Srpaulo struct wpa_state_machine *sm = eloop_ctx; 3007214501Srpaulo wpa_sm_step(sm); 3008214501Srpaulo} 3009214501Srpaulo 3010214501Srpaulo 3011214501Srpaulovoid wpa_auth_sm_notify(struct wpa_state_machine *sm) 3012214501Srpaulo{ 3013214501Srpaulo if (sm == NULL) 3014214501Srpaulo return; 3015214501Srpaulo eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL); 3016214501Srpaulo} 3017214501Srpaulo 3018214501Srpaulo 3019214501Srpaulovoid wpa_gtk_rekey(struct wpa_authenticator *wpa_auth) 3020214501Srpaulo{ 3021214501Srpaulo int tmp, i; 3022214501Srpaulo struct wpa_group *group; 3023214501Srpaulo 3024214501Srpaulo if (wpa_auth == NULL) 3025214501Srpaulo return; 3026214501Srpaulo 3027214501Srpaulo group = wpa_auth->group; 3028214501Srpaulo 3029214501Srpaulo for (i = 0; i < 2; i++) { 3030214501Srpaulo tmp = group->GM; 3031214501Srpaulo group->GM = group->GN; 3032214501Srpaulo group->GN = tmp; 3033214501Srpaulo#ifdef CONFIG_IEEE80211W 3034214501Srpaulo tmp = group->GM_igtk; 3035214501Srpaulo group->GM_igtk = group->GN_igtk; 3036214501Srpaulo group->GN_igtk = tmp; 3037214501Srpaulo#endif /* CONFIG_IEEE80211W */ 3038214501Srpaulo wpa_gtk_update(wpa_auth, group); 3039252726Srpaulo wpa_group_config_group_keys(wpa_auth, group); 3040214501Srpaulo } 3041214501Srpaulo} 3042214501Srpaulo 3043214501Srpaulo 3044289549Srpaulostatic const char * wpa_bool_txt(int val) 3045214501Srpaulo{ 3046289549Srpaulo return val ? "TRUE" : "FALSE"; 3047214501Srpaulo} 3048214501Srpaulo 3049214501Srpaulo 3050214501Srpaulo#define RSN_SUITE "%02x-%02x-%02x-%d" 3051214501Srpaulo#define RSN_SUITE_ARG(s) \ 3052214501Srpaulo((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff 3053214501Srpaulo 3054214501Srpauloint wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen) 3055214501Srpaulo{ 3056214501Srpaulo int len = 0, ret; 3057214501Srpaulo char pmkid_txt[PMKID_LEN * 2 + 1]; 3058252726Srpaulo#ifdef CONFIG_RSN_PREAUTH 3059252726Srpaulo const int preauth = 1; 3060252726Srpaulo#else /* CONFIG_RSN_PREAUTH */ 3061252726Srpaulo const int preauth = 0; 3062252726Srpaulo#endif /* CONFIG_RSN_PREAUTH */ 3063214501Srpaulo 3064214501Srpaulo if (wpa_auth == NULL) 3065214501Srpaulo return len; 3066214501Srpaulo 3067214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 3068214501Srpaulo "dot11RSNAOptionImplemented=TRUE\n" 3069252726Srpaulo "dot11RSNAPreauthenticationImplemented=%s\n" 3070214501Srpaulo "dot11RSNAEnabled=%s\n" 3071214501Srpaulo "dot11RSNAPreauthenticationEnabled=%s\n", 3072252726Srpaulo wpa_bool_txt(preauth), 3073214501Srpaulo wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN), 3074214501Srpaulo wpa_bool_txt(wpa_auth->conf.rsn_preauth)); 3075281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3076214501Srpaulo return len; 3077214501Srpaulo len += ret; 3078214501Srpaulo 3079214501Srpaulo wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), 3080214501Srpaulo wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN); 3081214501Srpaulo 3082214501Srpaulo ret = os_snprintf( 3083214501Srpaulo buf + len, buflen - len, 3084214501Srpaulo "dot11RSNAConfigVersion=%u\n" 3085214501Srpaulo "dot11RSNAConfigPairwiseKeysSupported=9999\n" 3086214501Srpaulo /* FIX: dot11RSNAConfigGroupCipher */ 3087214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyMethod */ 3088214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyTime */ 3089214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyPackets */ 3090214501Srpaulo "dot11RSNAConfigGroupRekeyStrict=%u\n" 3091214501Srpaulo "dot11RSNAConfigGroupUpdateCount=%u\n" 3092214501Srpaulo "dot11RSNAConfigPairwiseUpdateCount=%u\n" 3093214501Srpaulo "dot11RSNAConfigGroupCipherSize=%u\n" 3094214501Srpaulo "dot11RSNAConfigPMKLifetime=%u\n" 3095214501Srpaulo "dot11RSNAConfigPMKReauthThreshold=%u\n" 3096214501Srpaulo "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n" 3097214501Srpaulo "dot11RSNAConfigSATimeout=%u\n" 3098214501Srpaulo "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" 3099214501Srpaulo "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" 3100214501Srpaulo "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" 3101214501Srpaulo "dot11RSNAPMKIDUsed=%s\n" 3102214501Srpaulo "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" 3103214501Srpaulo "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" 3104214501Srpaulo "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" 3105214501Srpaulo "dot11RSNATKIPCounterMeasuresInvoked=%u\n" 3106214501Srpaulo "dot11RSNA4WayHandshakeFailures=%u\n" 3107214501Srpaulo "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n", 3108214501Srpaulo RSN_VERSION, 3109214501Srpaulo !!wpa_auth->conf.wpa_strict_rekey, 3110214501Srpaulo dot11RSNAConfigGroupUpdateCount, 3111214501Srpaulo dot11RSNAConfigPairwiseUpdateCount, 3112252726Srpaulo wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8, 3113214501Srpaulo dot11RSNAConfigPMKLifetime, 3114214501Srpaulo dot11RSNAConfigPMKReauthThreshold, 3115214501Srpaulo dot11RSNAConfigSATimeout, 3116214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected), 3117214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected), 3118214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected), 3119214501Srpaulo pmkid_txt, 3120214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested), 3121214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested), 3122214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested), 3123214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked, 3124214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures); 3125281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3126214501Srpaulo return len; 3127214501Srpaulo len += ret; 3128214501Srpaulo 3129214501Srpaulo /* TODO: dot11RSNAConfigPairwiseCiphersTable */ 3130214501Srpaulo /* TODO: dot11RSNAConfigAuthenticationSuitesTable */ 3131214501Srpaulo 3132214501Srpaulo /* Private MIB */ 3133214501Srpaulo ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n", 3134214501Srpaulo wpa_auth->group->wpa_group_state); 3135281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3136214501Srpaulo return len; 3137214501Srpaulo len += ret; 3138214501Srpaulo 3139214501Srpaulo return len; 3140214501Srpaulo} 3141214501Srpaulo 3142214501Srpaulo 3143214501Srpauloint wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) 3144214501Srpaulo{ 3145214501Srpaulo int len = 0, ret; 3146214501Srpaulo u32 pairwise = 0; 3147214501Srpaulo 3148214501Srpaulo if (sm == NULL) 3149214501Srpaulo return 0; 3150214501Srpaulo 3151214501Srpaulo /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */ 3152214501Srpaulo 3153214501Srpaulo /* dot11RSNAStatsEntry */ 3154214501Srpaulo 3155252726Srpaulo pairwise = wpa_cipher_to_suite(sm->wpa == WPA_VERSION_WPA2 ? 3156252726Srpaulo WPA_PROTO_RSN : WPA_PROTO_WPA, 3157252726Srpaulo sm->pairwise); 3158252726Srpaulo if (pairwise == 0) 3159214501Srpaulo return 0; 3160214501Srpaulo 3161214501Srpaulo ret = os_snprintf( 3162214501Srpaulo buf + len, buflen - len, 3163214501Srpaulo /* TODO: dot11RSNAStatsIndex */ 3164214501Srpaulo "dot11RSNAStatsSTAAddress=" MACSTR "\n" 3165214501Srpaulo "dot11RSNAStatsVersion=1\n" 3166214501Srpaulo "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n" 3167214501Srpaulo /* TODO: dot11RSNAStatsTKIPICVErrors */ 3168214501Srpaulo "dot11RSNAStatsTKIPLocalMICFailures=%u\n" 3169252726Srpaulo "dot11RSNAStatsTKIPRemoteMICFailures=%u\n" 3170214501Srpaulo /* TODO: dot11RSNAStatsCCMPReplays */ 3171214501Srpaulo /* TODO: dot11RSNAStatsCCMPDecryptErrors */ 3172214501Srpaulo /* TODO: dot11RSNAStatsTKIPReplays */, 3173214501Srpaulo MAC2STR(sm->addr), 3174214501Srpaulo RSN_SUITE_ARG(pairwise), 3175214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures, 3176214501Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures); 3177281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3178214501Srpaulo return len; 3179214501Srpaulo len += ret; 3180214501Srpaulo 3181214501Srpaulo /* Private MIB */ 3182214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 3183214501Srpaulo "hostapdWPAPTKState=%d\n" 3184214501Srpaulo "hostapdWPAPTKGroupState=%d\n", 3185214501Srpaulo sm->wpa_ptk_state, 3186214501Srpaulo sm->wpa_ptk_group_state); 3187281806Srpaulo if (os_snprintf_error(buflen - len, ret)) 3188214501Srpaulo return len; 3189214501Srpaulo len += ret; 3190214501Srpaulo 3191214501Srpaulo return len; 3192214501Srpaulo} 3193214501Srpaulo 3194214501Srpaulo 3195214501Srpaulovoid wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) 3196214501Srpaulo{ 3197214501Srpaulo if (wpa_auth) 3198214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++; 3199214501Srpaulo} 3200214501Srpaulo 3201214501Srpaulo 3202214501Srpauloint wpa_auth_pairwise_set(struct wpa_state_machine *sm) 3203214501Srpaulo{ 3204214501Srpaulo return sm && sm->pairwise_set; 3205214501Srpaulo} 3206214501Srpaulo 3207214501Srpaulo 3208214501Srpauloint wpa_auth_get_pairwise(struct wpa_state_machine *sm) 3209214501Srpaulo{ 3210214501Srpaulo return sm->pairwise; 3211214501Srpaulo} 3212214501Srpaulo 3213214501Srpaulo 3214214501Srpauloint wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm) 3215214501Srpaulo{ 3216214501Srpaulo if (sm == NULL) 3217214501Srpaulo return -1; 3218214501Srpaulo return sm->wpa_key_mgmt; 3219214501Srpaulo} 3220214501Srpaulo 3221214501Srpaulo 3222214501Srpauloint wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) 3223214501Srpaulo{ 3224214501Srpaulo if (sm == NULL) 3225214501Srpaulo return 0; 3226214501Srpaulo return sm->wpa; 3227214501Srpaulo} 3228214501Srpaulo 3229214501Srpaulo 3230324698Sgordonint wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm) 3231324698Sgordon{ 3232324698Sgordon if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 3233324698Sgordon return 0; 3234324698Sgordon return sm->tk_already_set; 3235324698Sgordon} 3236324698Sgordon 3237324698Sgordon 3238214501Srpauloint wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, 3239214501Srpaulo struct rsn_pmksa_cache_entry *entry) 3240214501Srpaulo{ 3241214501Srpaulo if (sm == NULL || sm->pmksa != entry) 3242214501Srpaulo return -1; 3243214501Srpaulo sm->pmksa = NULL; 3244214501Srpaulo return 0; 3245214501Srpaulo} 3246214501Srpaulo 3247214501Srpaulo 3248214501Srpaulostruct rsn_pmksa_cache_entry * 3249214501Srpaulowpa_auth_sta_get_pmksa(struct wpa_state_machine *sm) 3250214501Srpaulo{ 3251214501Srpaulo return sm ? sm->pmksa : NULL; 3252214501Srpaulo} 3253214501Srpaulo 3254214501Srpaulo 3255214501Srpaulovoid wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm) 3256214501Srpaulo{ 3257214501Srpaulo if (sm) 3258214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures++; 3259214501Srpaulo} 3260214501Srpaulo 3261214501Srpaulo 3262214501Srpauloconst u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len) 3263214501Srpaulo{ 3264214501Srpaulo if (wpa_auth == NULL) 3265214501Srpaulo return NULL; 3266214501Srpaulo *len = wpa_auth->wpa_ie_len; 3267214501Srpaulo return wpa_auth->wpa_ie; 3268214501Srpaulo} 3269214501Srpaulo 3270214501Srpaulo 3271214501Srpauloint wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, 3272214501Srpaulo int session_timeout, struct eapol_state_machine *eapol) 3273214501Srpaulo{ 3274252726Srpaulo if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 || 3275252726Srpaulo sm->wpa_auth->conf.disable_pmksa_caching) 3276214501Srpaulo return -1; 3277214501Srpaulo 3278214501Srpaulo if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, 3279281806Srpaulo sm->PTK.kck, sm->PTK.kck_len, 3280214501Srpaulo sm->wpa_auth->addr, sm->addr, session_timeout, 3281214501Srpaulo eapol, sm->wpa_key_mgmt)) 3282214501Srpaulo return 0; 3283214501Srpaulo 3284214501Srpaulo return -1; 3285214501Srpaulo} 3286214501Srpaulo 3287214501Srpaulo 3288214501Srpauloint wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, 3289214501Srpaulo const u8 *pmk, size_t len, const u8 *sta_addr, 3290214501Srpaulo int session_timeout, 3291214501Srpaulo struct eapol_state_machine *eapol) 3292214501Srpaulo{ 3293214501Srpaulo if (wpa_auth == NULL) 3294214501Srpaulo return -1; 3295214501Srpaulo 3296281806Srpaulo if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, 3297281806Srpaulo NULL, 0, 3298281806Srpaulo wpa_auth->addr, 3299214501Srpaulo sta_addr, session_timeout, eapol, 3300214501Srpaulo WPA_KEY_MGMT_IEEE8021X)) 3301214501Srpaulo return 0; 3302214501Srpaulo 3303214501Srpaulo return -1; 3304214501Srpaulo} 3305214501Srpaulo 3306214501Srpaulo 3307281806Srpauloint wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, 3308281806Srpaulo const u8 *pmk) 3309281806Srpaulo{ 3310281806Srpaulo if (wpa_auth->conf.disable_pmksa_caching) 3311281806Srpaulo return -1; 3312281806Srpaulo 3313281806Srpaulo if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, 3314281806Srpaulo NULL, 0, 3315281806Srpaulo wpa_auth->addr, addr, 0, NULL, 3316281806Srpaulo WPA_KEY_MGMT_SAE)) 3317281806Srpaulo return 0; 3318281806Srpaulo 3319281806Srpaulo return -1; 3320281806Srpaulo} 3321281806Srpaulo 3322281806Srpaulo 3323281806Srpaulovoid wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, 3324281806Srpaulo const u8 *sta_addr) 3325281806Srpaulo{ 3326281806Srpaulo struct rsn_pmksa_cache_entry *pmksa; 3327281806Srpaulo 3328281806Srpaulo if (wpa_auth == NULL || wpa_auth->pmksa == NULL) 3329281806Srpaulo return; 3330281806Srpaulo pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL); 3331281806Srpaulo if (pmksa) { 3332281806Srpaulo wpa_printf(MSG_DEBUG, "WPA: Remove PMKSA cache entry for " 3333281806Srpaulo MACSTR " based on request", MAC2STR(sta_addr)); 3334281806Srpaulo pmksa_cache_free_entry(wpa_auth->pmksa, pmksa); 3335281806Srpaulo } 3336281806Srpaulo} 3337281806Srpaulo 3338281806Srpaulo 3339289549Srpaulo/* 3340289549Srpaulo * Remove and free the group from wpa_authenticator. This is triggered by a 3341289549Srpaulo * callback to make sure nobody is currently iterating the group list while it 3342289549Srpaulo * gets modified. 3343289549Srpaulo */ 3344289549Srpaulostatic void wpa_group_free(struct wpa_authenticator *wpa_auth, 3345289549Srpaulo struct wpa_group *group) 3346289549Srpaulo{ 3347289549Srpaulo struct wpa_group *prev = wpa_auth->group; 3348289549Srpaulo 3349289549Srpaulo wpa_printf(MSG_DEBUG, "WPA: Remove group state machine for VLAN-ID %d", 3350289549Srpaulo group->vlan_id); 3351289549Srpaulo 3352289549Srpaulo while (prev) { 3353289549Srpaulo if (prev->next == group) { 3354289549Srpaulo /* This never frees the special first group as needed */ 3355289549Srpaulo prev->next = group->next; 3356289549Srpaulo os_free(group); 3357289549Srpaulo break; 3358289549Srpaulo } 3359289549Srpaulo prev = prev->next; 3360289549Srpaulo } 3361289549Srpaulo 3362289549Srpaulo} 3363289549Srpaulo 3364289549Srpaulo 3365289549Srpaulo/* Increase the reference counter for group */ 3366289549Srpaulostatic void wpa_group_get(struct wpa_authenticator *wpa_auth, 3367289549Srpaulo struct wpa_group *group) 3368289549Srpaulo{ 3369289549Srpaulo /* Skip the special first group */ 3370289549Srpaulo if (wpa_auth->group == group) 3371289549Srpaulo return; 3372289549Srpaulo 3373289549Srpaulo group->references++; 3374289549Srpaulo} 3375289549Srpaulo 3376289549Srpaulo 3377289549Srpaulo/* Decrease the reference counter and maybe free the group */ 3378289549Srpaulostatic void wpa_group_put(struct wpa_authenticator *wpa_auth, 3379289549Srpaulo struct wpa_group *group) 3380289549Srpaulo{ 3381289549Srpaulo /* Skip the special first group */ 3382289549Srpaulo if (wpa_auth->group == group) 3383289549Srpaulo return; 3384289549Srpaulo 3385289549Srpaulo group->references--; 3386289549Srpaulo if (group->references) 3387289549Srpaulo return; 3388289549Srpaulo wpa_group_free(wpa_auth, group); 3389289549Srpaulo} 3390289549Srpaulo 3391289549Srpaulo 3392289549Srpaulo/* 3393289549Srpaulo * Add a group that has its references counter set to zero. Caller needs to 3394289549Srpaulo * call wpa_group_get() on the return value to mark the entry in use. 3395289549Srpaulo */ 3396214501Srpaulostatic struct wpa_group * 3397214501Srpaulowpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) 3398214501Srpaulo{ 3399214501Srpaulo struct wpa_group *group; 3400214501Srpaulo 3401214501Srpaulo if (wpa_auth == NULL || wpa_auth->group == NULL) 3402214501Srpaulo return NULL; 3403214501Srpaulo 3404214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d", 3405214501Srpaulo vlan_id); 3406252726Srpaulo group = wpa_group_init(wpa_auth, vlan_id, 0); 3407214501Srpaulo if (group == NULL) 3408214501Srpaulo return NULL; 3409214501Srpaulo 3410214501Srpaulo group->next = wpa_auth->group->next; 3411214501Srpaulo wpa_auth->group->next = group; 3412214501Srpaulo 3413214501Srpaulo return group; 3414214501Srpaulo} 3415214501Srpaulo 3416214501Srpaulo 3417214501Srpauloint wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id) 3418214501Srpaulo{ 3419214501Srpaulo struct wpa_group *group; 3420214501Srpaulo 3421214501Srpaulo if (sm == NULL || sm->wpa_auth == NULL) 3422214501Srpaulo return 0; 3423214501Srpaulo 3424214501Srpaulo group = sm->wpa_auth->group; 3425214501Srpaulo while (group) { 3426214501Srpaulo if (group->vlan_id == vlan_id) 3427214501Srpaulo break; 3428214501Srpaulo group = group->next; 3429214501Srpaulo } 3430214501Srpaulo 3431214501Srpaulo if (group == NULL) { 3432214501Srpaulo group = wpa_auth_add_group(sm->wpa_auth, vlan_id); 3433214501Srpaulo if (group == NULL) 3434214501Srpaulo return -1; 3435214501Srpaulo } 3436214501Srpaulo 3437214501Srpaulo if (sm->group == group) 3438214501Srpaulo return 0; 3439214501Srpaulo 3440281806Srpaulo if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) 3441281806Srpaulo return -1; 3442281806Srpaulo 3443214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state " 3444214501Srpaulo "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id); 3445214501Srpaulo 3446289549Srpaulo wpa_group_get(sm->wpa_auth, group); 3447289549Srpaulo wpa_group_put(sm->wpa_auth, sm->group); 3448214501Srpaulo sm->group = group; 3449289549Srpaulo 3450214501Srpaulo return 0; 3451214501Srpaulo} 3452252726Srpaulo 3453252726Srpaulo 3454252726Srpaulovoid wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, 3455252726Srpaulo struct wpa_state_machine *sm, int ack) 3456252726Srpaulo{ 3457252726Srpaulo if (wpa_auth == NULL || sm == NULL) 3458252726Srpaulo return; 3459252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR 3460252726Srpaulo " ack=%d", MAC2STR(sm->addr), ack); 3461252726Srpaulo if (sm->pending_1_of_4_timeout && ack) { 3462252726Srpaulo /* 3463252726Srpaulo * Some deployed supplicant implementations update their SNonce 3464252726Srpaulo * for each EAPOL-Key 2/4 message even within the same 4-way 3465252726Srpaulo * handshake and then fail to use the first SNonce when 3466252726Srpaulo * deriving the PTK. This results in unsuccessful 4-way 3467252726Srpaulo * handshake whenever the relatively short initial timeout is 3468252726Srpaulo * reached and EAPOL-Key 1/4 is retransmitted. Try to work 3469252726Srpaulo * around this by increasing the timeout now that we know that 3470252726Srpaulo * the station has received the frame. 3471252726Srpaulo */ 3472252726Srpaulo int timeout_ms = eapol_key_timeout_subseq; 3473252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 " 3474252726Srpaulo "timeout by %u ms because of acknowledged frame", 3475252726Srpaulo timeout_ms); 3476252726Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 3477252726Srpaulo eloop_register_timeout(timeout_ms / 1000, 3478252726Srpaulo (timeout_ms % 1000) * 1000, 3479252726Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 3480252726Srpaulo } 3481252726Srpaulo} 3482252726Srpaulo 3483252726Srpaulo 3484252726Srpauloint wpa_auth_uses_sae(struct wpa_state_machine *sm) 3485252726Srpaulo{ 3486252726Srpaulo if (sm == NULL) 3487252726Srpaulo return 0; 3488252726Srpaulo return wpa_key_mgmt_sae(sm->wpa_key_mgmt); 3489252726Srpaulo} 3490281806Srpaulo 3491281806Srpaulo 3492281806Srpauloint wpa_auth_uses_ft_sae(struct wpa_state_machine *sm) 3493281806Srpaulo{ 3494281806Srpaulo if (sm == NULL) 3495281806Srpaulo return 0; 3496281806Srpaulo return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE; 3497281806Srpaulo} 3498281806Srpaulo 3499281806Srpaulo 3500281806Srpaulo#ifdef CONFIG_P2P 3501281806Srpauloint wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr) 3502281806Srpaulo{ 3503281806Srpaulo if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0) 3504281806Srpaulo return -1; 3505281806Srpaulo os_memcpy(addr, sm->ip_addr, 4); 3506281806Srpaulo return 0; 3507281806Srpaulo} 3508281806Srpaulo#endif /* CONFIG_P2P */ 3509281806Srpaulo 3510281806Srpaulo 3511281806Srpauloint wpa_auth_radius_das_disconnect_pmksa(struct wpa_authenticator *wpa_auth, 3512281806Srpaulo struct radius_das_attrs *attr) 3513281806Srpaulo{ 3514281806Srpaulo return pmksa_cache_auth_radius_das_disconnect(wpa_auth->pmksa, attr); 3515281806Srpaulo} 3516281806Srpaulo 3517281806Srpaulo 3518281806Srpaulovoid wpa_auth_reconfig_group_keys(struct wpa_authenticator *wpa_auth) 3519281806Srpaulo{ 3520281806Srpaulo struct wpa_group *group; 3521281806Srpaulo 3522281806Srpaulo if (!wpa_auth) 3523281806Srpaulo return; 3524281806Srpaulo for (group = wpa_auth->group; group; group = group->next) 3525281806Srpaulo wpa_group_config_group_keys(wpa_auth, group); 3526281806Srpaulo} 3527