1214501Srpaulo/* 2252726Srpaulo * IEEE 802.11 RSN / WPA Authenticator 3252726Srpaulo * Copyright (c) 2004-2011, 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" 14214501Srpaulo#include "common/ieee802_11_defs.h" 15214501Srpaulo#include "crypto/aes_wrap.h" 16214501Srpaulo#include "crypto/crypto.h" 17214501Srpaulo#include "crypto/sha1.h" 18214501Srpaulo#include "crypto/sha256.h" 19252726Srpaulo#include "crypto/random.h" 20214501Srpaulo#include "eapol_auth/eapol_auth_sm.h" 21214501Srpaulo#include "ap_config.h" 22214501Srpaulo#include "ieee802_11.h" 23214501Srpaulo#include "wpa_auth.h" 24214501Srpaulo#include "pmksa_cache_auth.h" 25214501Srpaulo#include "wpa_auth_i.h" 26214501Srpaulo#include "wpa_auth_ie.h" 27214501Srpaulo 28214501Srpaulo#define STATE_MACHINE_DATA struct wpa_state_machine 29214501Srpaulo#define STATE_MACHINE_DEBUG_PREFIX "WPA" 30214501Srpaulo#define STATE_MACHINE_ADDR sm->addr 31214501Srpaulo 32214501Srpaulo 33214501Srpaulostatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx); 34214501Srpaulostatic int wpa_sm_step(struct wpa_state_machine *sm); 35214501Srpaulostatic int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len); 36214501Srpaulostatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx); 37214501Srpaulostatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 38214501Srpaulo struct wpa_group *group); 39214501Srpaulostatic void wpa_request_new_ptk(struct wpa_state_machine *sm); 40214501Srpaulostatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 41214501Srpaulo struct wpa_group *group); 42252726Srpaulostatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 43252726Srpaulo struct wpa_group *group); 44214501Srpaulo 45214501Srpaulostatic const u32 dot11RSNAConfigGroupUpdateCount = 4; 46214501Srpaulostatic const u32 dot11RSNAConfigPairwiseUpdateCount = 4; 47214501Srpaulostatic const u32 eapol_key_timeout_first = 100; /* ms */ 48214501Srpaulostatic const u32 eapol_key_timeout_subseq = 1000; /* ms */ 49252726Srpaulostatic const u32 eapol_key_timeout_first_group = 500; /* ms */ 50214501Srpaulo 51214501Srpaulo/* TODO: make these configurable */ 52214501Srpaulostatic const int dot11RSNAConfigPMKLifetime = 43200; 53214501Srpaulostatic const int dot11RSNAConfigPMKReauthThreshold = 70; 54214501Srpaulostatic const int dot11RSNAConfigSATimeout = 60; 55214501Srpaulo 56214501Srpaulo 57252726Srpaulostatic inline int wpa_auth_mic_failure_report( 58214501Srpaulo struct wpa_authenticator *wpa_auth, const u8 *addr) 59214501Srpaulo{ 60214501Srpaulo if (wpa_auth->cb.mic_failure_report) 61252726Srpaulo return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr); 62252726Srpaulo return 0; 63214501Srpaulo} 64214501Srpaulo 65214501Srpaulo 66214501Srpaulostatic inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth, 67214501Srpaulo const u8 *addr, wpa_eapol_variable var, 68214501Srpaulo int value) 69214501Srpaulo{ 70214501Srpaulo if (wpa_auth->cb.set_eapol) 71214501Srpaulo wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value); 72214501Srpaulo} 73214501Srpaulo 74214501Srpaulo 75214501Srpaulostatic inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth, 76214501Srpaulo const u8 *addr, wpa_eapol_variable var) 77214501Srpaulo{ 78214501Srpaulo if (wpa_auth->cb.get_eapol == NULL) 79214501Srpaulo return -1; 80214501Srpaulo return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var); 81214501Srpaulo} 82214501Srpaulo 83214501Srpaulo 84214501Srpaulostatic inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth, 85214501Srpaulo const u8 *addr, const u8 *prev_psk) 86214501Srpaulo{ 87214501Srpaulo if (wpa_auth->cb.get_psk == NULL) 88214501Srpaulo return NULL; 89214501Srpaulo return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, prev_psk); 90214501Srpaulo} 91214501Srpaulo 92214501Srpaulo 93214501Srpaulostatic inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth, 94214501Srpaulo const u8 *addr, u8 *msk, size_t *len) 95214501Srpaulo{ 96214501Srpaulo if (wpa_auth->cb.get_msk == NULL) 97214501Srpaulo return -1; 98214501Srpaulo return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len); 99214501Srpaulo} 100214501Srpaulo 101214501Srpaulo 102214501Srpaulostatic inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, 103214501Srpaulo int vlan_id, 104214501Srpaulo enum wpa_alg alg, const u8 *addr, int idx, 105214501Srpaulo u8 *key, size_t key_len) 106214501Srpaulo{ 107214501Srpaulo if (wpa_auth->cb.set_key == NULL) 108214501Srpaulo return -1; 109214501Srpaulo return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx, 110214501Srpaulo key, key_len); 111214501Srpaulo} 112214501Srpaulo 113214501Srpaulo 114214501Srpaulostatic inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, 115214501Srpaulo const u8 *addr, int idx, u8 *seq) 116214501Srpaulo{ 117214501Srpaulo if (wpa_auth->cb.get_seqnum == NULL) 118214501Srpaulo return -1; 119214501Srpaulo return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq); 120214501Srpaulo} 121214501Srpaulo 122214501Srpaulo 123214501Srpaulostatic inline int 124214501Srpaulowpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr, 125214501Srpaulo const u8 *data, size_t data_len, int encrypt) 126214501Srpaulo{ 127214501Srpaulo if (wpa_auth->cb.send_eapol == NULL) 128214501Srpaulo return -1; 129214501Srpaulo return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len, 130214501Srpaulo encrypt); 131214501Srpaulo} 132214501Srpaulo 133214501Srpaulo 134214501Srpauloint wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, 135214501Srpaulo int (*cb)(struct wpa_state_machine *sm, void *ctx), 136214501Srpaulo void *cb_ctx) 137214501Srpaulo{ 138214501Srpaulo if (wpa_auth->cb.for_each_sta == NULL) 139214501Srpaulo return 0; 140214501Srpaulo return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx); 141214501Srpaulo} 142214501Srpaulo 143214501Srpaulo 144214501Srpauloint wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, 145214501Srpaulo int (*cb)(struct wpa_authenticator *a, void *ctx), 146214501Srpaulo void *cb_ctx) 147214501Srpaulo{ 148214501Srpaulo if (wpa_auth->cb.for_each_auth == NULL) 149214501Srpaulo return 0; 150214501Srpaulo return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx); 151214501Srpaulo} 152214501Srpaulo 153214501Srpaulo 154214501Srpaulovoid wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr, 155214501Srpaulo logger_level level, const char *txt) 156214501Srpaulo{ 157214501Srpaulo if (wpa_auth->cb.logger == NULL) 158214501Srpaulo return; 159214501Srpaulo wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt); 160214501Srpaulo} 161214501Srpaulo 162214501Srpaulo 163214501Srpaulovoid wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr, 164214501Srpaulo logger_level level, const char *fmt, ...) 165214501Srpaulo{ 166214501Srpaulo char *format; 167214501Srpaulo int maxlen; 168214501Srpaulo va_list ap; 169214501Srpaulo 170214501Srpaulo if (wpa_auth->cb.logger == NULL) 171214501Srpaulo return; 172214501Srpaulo 173214501Srpaulo maxlen = os_strlen(fmt) + 100; 174214501Srpaulo format = os_malloc(maxlen); 175214501Srpaulo if (!format) 176214501Srpaulo return; 177214501Srpaulo 178214501Srpaulo va_start(ap, fmt); 179214501Srpaulo vsnprintf(format, maxlen, fmt, ap); 180214501Srpaulo va_end(ap); 181214501Srpaulo 182214501Srpaulo wpa_auth_logger(wpa_auth, addr, level, format); 183214501Srpaulo 184214501Srpaulo os_free(format); 185214501Srpaulo} 186214501Srpaulo 187214501Srpaulo 188214501Srpaulostatic void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, 189214501Srpaulo const u8 *addr) 190214501Srpaulo{ 191214501Srpaulo if (wpa_auth->cb.disconnect == NULL) 192214501Srpaulo return; 193252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); 194214501Srpaulo wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr, 195214501Srpaulo WLAN_REASON_PREV_AUTH_NOT_VALID); 196214501Srpaulo} 197214501Srpaulo 198214501Srpaulo 199214501Srpaulostatic int wpa_use_aes_cmac(struct wpa_state_machine *sm) 200214501Srpaulo{ 201214501Srpaulo int ret = 0; 202214501Srpaulo#ifdef CONFIG_IEEE80211R 203214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 204214501Srpaulo ret = 1; 205214501Srpaulo#endif /* CONFIG_IEEE80211R */ 206214501Srpaulo#ifdef CONFIG_IEEE80211W 207214501Srpaulo if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt)) 208214501Srpaulo ret = 1; 209214501Srpaulo#endif /* CONFIG_IEEE80211W */ 210214501Srpaulo return ret; 211214501Srpaulo} 212214501Srpaulo 213214501Srpaulo 214214501Srpaulostatic void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx) 215214501Srpaulo{ 216214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 217214501Srpaulo 218252726Srpaulo if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) { 219214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 220214501Srpaulo "initialization."); 221214501Srpaulo } else { 222214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd"); 223252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", 224252726Srpaulo wpa_auth->group->GMK, WPA_GMK_LEN); 225214501Srpaulo } 226214501Srpaulo 227214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 228214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 229214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 230214501Srpaulo } 231214501Srpaulo} 232214501Srpaulo 233214501Srpaulo 234214501Srpaulostatic void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx) 235214501Srpaulo{ 236214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 237214501Srpaulo struct wpa_group *group; 238214501Srpaulo 239214501Srpaulo wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK"); 240214501Srpaulo for (group = wpa_auth->group; group; group = group->next) { 241214501Srpaulo group->GTKReKey = TRUE; 242214501Srpaulo do { 243214501Srpaulo group->changed = FALSE; 244214501Srpaulo wpa_group_sm_step(wpa_auth, group); 245214501Srpaulo } while (group->changed); 246214501Srpaulo } 247214501Srpaulo 248214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 249214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 250214501Srpaulo 0, wpa_rekey_gtk, wpa_auth, NULL); 251214501Srpaulo } 252214501Srpaulo} 253214501Srpaulo 254214501Srpaulo 255214501Srpaulostatic void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx) 256214501Srpaulo{ 257214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 258214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 259214501Srpaulo 260214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK"); 261214501Srpaulo wpa_request_new_ptk(sm); 262214501Srpaulo wpa_sm_step(sm); 263214501Srpaulo} 264214501Srpaulo 265214501Srpaulo 266214501Srpaulostatic int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx) 267214501Srpaulo{ 268214501Srpaulo if (sm->pmksa == ctx) 269214501Srpaulo sm->pmksa = NULL; 270214501Srpaulo return 0; 271214501Srpaulo} 272214501Srpaulo 273214501Srpaulo 274214501Srpaulostatic void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, 275214501Srpaulo void *ctx) 276214501Srpaulo{ 277214501Srpaulo struct wpa_authenticator *wpa_auth = ctx; 278214501Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry); 279214501Srpaulo} 280214501Srpaulo 281214501Srpaulo 282252726Srpaulostatic int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth, 283252726Srpaulo struct wpa_group *group) 284214501Srpaulo{ 285252726Srpaulo u8 buf[ETH_ALEN + 8 + sizeof(group)]; 286252726Srpaulo u8 rkey[32]; 287252726Srpaulo 288252726Srpaulo if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0) 289252726Srpaulo return -1; 290252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GMK", group->GMK, WPA_GMK_LEN); 291252726Srpaulo 292252726Srpaulo /* 293252726Srpaulo * Counter = PRF-256(Random number, "Init Counter", 294252726Srpaulo * Local MAC Address || Time) 295252726Srpaulo */ 296252726Srpaulo os_memcpy(buf, wpa_auth->addr, ETH_ALEN); 297252726Srpaulo wpa_get_ntp_timestamp(buf + ETH_ALEN); 298252726Srpaulo os_memcpy(buf + ETH_ALEN + 8, &group, sizeof(group)); 299252726Srpaulo if (random_get_bytes(rkey, sizeof(rkey)) < 0) 300252726Srpaulo return -1; 301252726Srpaulo 302252726Srpaulo if (sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf), 303252726Srpaulo group->Counter, WPA_NONCE_LEN) < 0) 304252726Srpaulo return -1; 305252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "Key Counter", 306252726Srpaulo group->Counter, WPA_NONCE_LEN); 307252726Srpaulo 308252726Srpaulo return 0; 309214501Srpaulo} 310214501Srpaulo 311214501Srpaulo 312214501Srpaulostatic struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth, 313252726Srpaulo int vlan_id, int delay_init) 314214501Srpaulo{ 315214501Srpaulo struct wpa_group *group; 316214501Srpaulo 317214501Srpaulo group = os_zalloc(sizeof(struct wpa_group)); 318214501Srpaulo if (group == NULL) 319214501Srpaulo return NULL; 320214501Srpaulo 321214501Srpaulo group->GTKAuthenticator = TRUE; 322214501Srpaulo group->vlan_id = vlan_id; 323252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 324214501Srpaulo 325252726Srpaulo if (random_pool_ready() != 1) { 326252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 327252726Srpaulo "for secure operations - update keys later when " 328252726Srpaulo "the first station connects"); 329252726Srpaulo } 330214501Srpaulo 331252726Srpaulo /* 332252726Srpaulo * Set initial GMK/Counter value here. The actual values that will be 333252726Srpaulo * used in negotiations will be set once the first station tries to 334252726Srpaulo * connect. This allows more time for collecting additional randomness 335252726Srpaulo * on embedded devices. 336214501Srpaulo */ 337252726Srpaulo if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) { 338214501Srpaulo wpa_printf(MSG_ERROR, "Failed to get random data for WPA " 339214501Srpaulo "initialization."); 340214501Srpaulo os_free(group); 341214501Srpaulo return NULL; 342214501Srpaulo } 343214501Srpaulo 344214501Srpaulo group->GInit = TRUE; 345252726Srpaulo if (delay_init) { 346252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start " 347252726Srpaulo "until Beacon frames have been configured"); 348252726Srpaulo /* Initialization is completed in wpa_init_keys(). */ 349252726Srpaulo } else { 350252726Srpaulo wpa_group_sm_step(wpa_auth, group); 351252726Srpaulo group->GInit = FALSE; 352252726Srpaulo wpa_group_sm_step(wpa_auth, group); 353252726Srpaulo } 354214501Srpaulo 355214501Srpaulo return group; 356214501Srpaulo} 357214501Srpaulo 358214501Srpaulo 359214501Srpaulo/** 360214501Srpaulo * wpa_init - Initialize WPA authenticator 361214501Srpaulo * @addr: Authenticator address 362214501Srpaulo * @conf: Configuration for WPA authenticator 363214501Srpaulo * @cb: Callback functions for WPA authenticator 364214501Srpaulo * Returns: Pointer to WPA authenticator data or %NULL on failure 365214501Srpaulo */ 366214501Srpaulostruct wpa_authenticator * wpa_init(const u8 *addr, 367214501Srpaulo struct wpa_auth_config *conf, 368214501Srpaulo struct wpa_auth_callbacks *cb) 369214501Srpaulo{ 370214501Srpaulo struct wpa_authenticator *wpa_auth; 371214501Srpaulo 372214501Srpaulo wpa_auth = os_zalloc(sizeof(struct wpa_authenticator)); 373214501Srpaulo if (wpa_auth == NULL) 374214501Srpaulo return NULL; 375214501Srpaulo os_memcpy(wpa_auth->addr, addr, ETH_ALEN); 376214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 377214501Srpaulo os_memcpy(&wpa_auth->cb, cb, sizeof(*cb)); 378214501Srpaulo 379214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 380214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 381214501Srpaulo os_free(wpa_auth); 382214501Srpaulo return NULL; 383214501Srpaulo } 384214501Srpaulo 385252726Srpaulo wpa_auth->group = wpa_group_init(wpa_auth, 0, 1); 386214501Srpaulo if (wpa_auth->group == NULL) { 387214501Srpaulo os_free(wpa_auth->wpa_ie); 388214501Srpaulo os_free(wpa_auth); 389214501Srpaulo return NULL; 390214501Srpaulo } 391214501Srpaulo 392214501Srpaulo wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb, 393214501Srpaulo wpa_auth); 394214501Srpaulo if (wpa_auth->pmksa == NULL) { 395214501Srpaulo wpa_printf(MSG_ERROR, "PMKSA cache initialization failed."); 396214501Srpaulo os_free(wpa_auth->wpa_ie); 397214501Srpaulo os_free(wpa_auth); 398214501Srpaulo return NULL; 399214501Srpaulo } 400214501Srpaulo 401214501Srpaulo#ifdef CONFIG_IEEE80211R 402214501Srpaulo wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init(); 403214501Srpaulo if (wpa_auth->ft_pmk_cache == NULL) { 404214501Srpaulo wpa_printf(MSG_ERROR, "FT PMK cache initialization failed."); 405214501Srpaulo os_free(wpa_auth->wpa_ie); 406214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 407214501Srpaulo os_free(wpa_auth); 408214501Srpaulo return NULL; 409214501Srpaulo } 410214501Srpaulo#endif /* CONFIG_IEEE80211R */ 411214501Srpaulo 412214501Srpaulo if (wpa_auth->conf.wpa_gmk_rekey) { 413214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0, 414214501Srpaulo wpa_rekey_gmk, wpa_auth, NULL); 415214501Srpaulo } 416214501Srpaulo 417214501Srpaulo if (wpa_auth->conf.wpa_group_rekey) { 418214501Srpaulo eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0, 419214501Srpaulo wpa_rekey_gtk, wpa_auth, NULL); 420214501Srpaulo } 421214501Srpaulo 422214501Srpaulo return wpa_auth; 423214501Srpaulo} 424214501Srpaulo 425214501Srpaulo 426252726Srpauloint wpa_init_keys(struct wpa_authenticator *wpa_auth) 427252726Srpaulo{ 428252726Srpaulo struct wpa_group *group = wpa_auth->group; 429252726Srpaulo 430252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial " 431252726Srpaulo "keys"); 432252726Srpaulo wpa_group_sm_step(wpa_auth, group); 433252726Srpaulo group->GInit = FALSE; 434252726Srpaulo wpa_group_sm_step(wpa_auth, group); 435252726Srpaulo return 0; 436252726Srpaulo} 437252726Srpaulo 438252726Srpaulo 439214501Srpaulo/** 440214501Srpaulo * wpa_deinit - Deinitialize WPA authenticator 441214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 442214501Srpaulo */ 443214501Srpaulovoid wpa_deinit(struct wpa_authenticator *wpa_auth) 444214501Srpaulo{ 445214501Srpaulo struct wpa_group *group, *prev; 446214501Srpaulo 447214501Srpaulo eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL); 448214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 449214501Srpaulo 450214501Srpaulo#ifdef CONFIG_PEERKEY 451214501Srpaulo while (wpa_auth->stsl_negotiations) 452214501Srpaulo wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations); 453214501Srpaulo#endif /* CONFIG_PEERKEY */ 454214501Srpaulo 455214501Srpaulo pmksa_cache_auth_deinit(wpa_auth->pmksa); 456214501Srpaulo 457214501Srpaulo#ifdef CONFIG_IEEE80211R 458214501Srpaulo wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache); 459214501Srpaulo wpa_auth->ft_pmk_cache = NULL; 460214501Srpaulo#endif /* CONFIG_IEEE80211R */ 461214501Srpaulo 462214501Srpaulo os_free(wpa_auth->wpa_ie); 463214501Srpaulo 464214501Srpaulo group = wpa_auth->group; 465214501Srpaulo while (group) { 466214501Srpaulo prev = group; 467214501Srpaulo group = group->next; 468214501Srpaulo os_free(prev); 469214501Srpaulo } 470214501Srpaulo 471214501Srpaulo os_free(wpa_auth); 472214501Srpaulo} 473214501Srpaulo 474214501Srpaulo 475214501Srpaulo/** 476214501Srpaulo * wpa_reconfig - Update WPA authenticator configuration 477214501Srpaulo * @wpa_auth: Pointer to WPA authenticator data from wpa_init() 478214501Srpaulo * @conf: Configuration for WPA authenticator 479214501Srpaulo */ 480214501Srpauloint wpa_reconfig(struct wpa_authenticator *wpa_auth, 481214501Srpaulo struct wpa_auth_config *conf) 482214501Srpaulo{ 483214501Srpaulo struct wpa_group *group; 484214501Srpaulo if (wpa_auth == NULL) 485214501Srpaulo return 0; 486214501Srpaulo 487214501Srpaulo os_memcpy(&wpa_auth->conf, conf, sizeof(*conf)); 488214501Srpaulo if (wpa_auth_gen_wpa_ie(wpa_auth)) { 489214501Srpaulo wpa_printf(MSG_ERROR, "Could not generate WPA IE."); 490214501Srpaulo return -1; 491214501Srpaulo } 492214501Srpaulo 493214501Srpaulo /* 494214501Srpaulo * Reinitialize GTK to make sure it is suitable for the new 495214501Srpaulo * configuration. 496214501Srpaulo */ 497214501Srpaulo group = wpa_auth->group; 498252726Srpaulo group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group); 499214501Srpaulo group->GInit = TRUE; 500214501Srpaulo wpa_group_sm_step(wpa_auth, group); 501214501Srpaulo group->GInit = FALSE; 502214501Srpaulo wpa_group_sm_step(wpa_auth, group); 503214501Srpaulo 504214501Srpaulo return 0; 505214501Srpaulo} 506214501Srpaulo 507214501Srpaulo 508214501Srpaulostruct wpa_state_machine * 509214501Srpaulowpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr) 510214501Srpaulo{ 511214501Srpaulo struct wpa_state_machine *sm; 512214501Srpaulo 513214501Srpaulo sm = os_zalloc(sizeof(struct wpa_state_machine)); 514214501Srpaulo if (sm == NULL) 515214501Srpaulo return NULL; 516214501Srpaulo os_memcpy(sm->addr, addr, ETH_ALEN); 517214501Srpaulo 518214501Srpaulo sm->wpa_auth = wpa_auth; 519214501Srpaulo sm->group = wpa_auth->group; 520214501Srpaulo 521214501Srpaulo return sm; 522214501Srpaulo} 523214501Srpaulo 524214501Srpaulo 525214501Srpauloint wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, 526214501Srpaulo struct wpa_state_machine *sm) 527214501Srpaulo{ 528214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 529214501Srpaulo return -1; 530214501Srpaulo 531214501Srpaulo#ifdef CONFIG_IEEE80211R 532214501Srpaulo if (sm->ft_completed) { 533214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 534214501Srpaulo "FT authentication already completed - do not " 535214501Srpaulo "start 4-way handshake"); 536214501Srpaulo return 0; 537214501Srpaulo } 538214501Srpaulo#endif /* CONFIG_IEEE80211R */ 539214501Srpaulo 540214501Srpaulo if (sm->started) { 541214501Srpaulo os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); 542214501Srpaulo sm->ReAuthenticationRequest = TRUE; 543214501Srpaulo return wpa_sm_step(sm); 544214501Srpaulo } 545214501Srpaulo 546214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 547214501Srpaulo "start authentication"); 548214501Srpaulo sm->started = 1; 549214501Srpaulo 550214501Srpaulo sm->Init = TRUE; 551214501Srpaulo if (wpa_sm_step(sm) == 1) 552214501Srpaulo return 1; /* should not really happen */ 553214501Srpaulo sm->Init = FALSE; 554214501Srpaulo sm->AuthenticationRequest = TRUE; 555214501Srpaulo return wpa_sm_step(sm); 556214501Srpaulo} 557214501Srpaulo 558214501Srpaulo 559214501Srpaulovoid wpa_auth_sta_no_wpa(struct wpa_state_machine *sm) 560214501Srpaulo{ 561214501Srpaulo /* WPA/RSN was not used - clear WPA state. This is needed if the STA 562214501Srpaulo * reassociates back to the same AP while the previous entry for the 563214501Srpaulo * STA has not yet been removed. */ 564214501Srpaulo if (sm == NULL) 565214501Srpaulo return; 566214501Srpaulo 567214501Srpaulo sm->wpa_key_mgmt = 0; 568214501Srpaulo} 569214501Srpaulo 570214501Srpaulo 571214501Srpaulostatic void wpa_free_sta_sm(struct wpa_state_machine *sm) 572214501Srpaulo{ 573252726Srpaulo if (sm->GUpdateStationKeys) { 574252726Srpaulo sm->group->GKeyDoneStations--; 575252726Srpaulo sm->GUpdateStationKeys = FALSE; 576252726Srpaulo } 577214501Srpaulo#ifdef CONFIG_IEEE80211R 578214501Srpaulo os_free(sm->assoc_resp_ftie); 579214501Srpaulo#endif /* CONFIG_IEEE80211R */ 580214501Srpaulo os_free(sm->last_rx_eapol_key); 581214501Srpaulo os_free(sm->wpa_ie); 582214501Srpaulo os_free(sm); 583214501Srpaulo} 584214501Srpaulo 585214501Srpaulo 586214501Srpaulovoid wpa_auth_sta_deinit(struct wpa_state_machine *sm) 587214501Srpaulo{ 588214501Srpaulo if (sm == NULL) 589214501Srpaulo return; 590214501Srpaulo 591214501Srpaulo if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) { 592214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 593214501Srpaulo "strict rekeying - force GTK rekey since STA " 594214501Srpaulo "is leaving"); 595214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL); 596214501Srpaulo eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth, 597214501Srpaulo NULL); 598214501Srpaulo } 599214501Srpaulo 600214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 601252726Srpaulo sm->pending_1_of_4_timeout = 0; 602214501Srpaulo eloop_cancel_timeout(wpa_sm_call_step, sm, NULL); 603214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 604214501Srpaulo if (sm->in_step_loop) { 605214501Srpaulo /* Must not free state machine while wpa_sm_step() is running. 606214501Srpaulo * Freeing will be completed in the end of wpa_sm_step(). */ 607214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state " 608214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 609214501Srpaulo sm->pending_deinit = 1; 610214501Srpaulo } else 611214501Srpaulo wpa_free_sta_sm(sm); 612214501Srpaulo} 613214501Srpaulo 614214501Srpaulo 615214501Srpaulostatic void wpa_request_new_ptk(struct wpa_state_machine *sm) 616214501Srpaulo{ 617214501Srpaulo if (sm == NULL) 618214501Srpaulo return; 619214501Srpaulo 620214501Srpaulo sm->PTKRequest = TRUE; 621214501Srpaulo sm->PTK_valid = 0; 622214501Srpaulo} 623214501Srpaulo 624214501Srpaulo 625252726Srpaulostatic int wpa_replay_counter_valid(struct wpa_key_replay_counter *ctr, 626214501Srpaulo const u8 *replay_counter) 627214501Srpaulo{ 628214501Srpaulo int i; 629214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 630252726Srpaulo if (!ctr[i].valid) 631214501Srpaulo break; 632252726Srpaulo if (os_memcmp(replay_counter, ctr[i].counter, 633214501Srpaulo WPA_REPLAY_COUNTER_LEN) == 0) 634214501Srpaulo return 1; 635214501Srpaulo } 636214501Srpaulo return 0; 637214501Srpaulo} 638214501Srpaulo 639214501Srpaulo 640252726Srpaulostatic void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr, 641252726Srpaulo const u8 *replay_counter) 642252726Srpaulo{ 643252726Srpaulo int i; 644252726Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 645252726Srpaulo if (ctr[i].valid && 646252726Srpaulo (replay_counter == NULL || 647252726Srpaulo os_memcmp(replay_counter, ctr[i].counter, 648252726Srpaulo WPA_REPLAY_COUNTER_LEN) == 0)) 649252726Srpaulo ctr[i].valid = FALSE; 650252726Srpaulo } 651252726Srpaulo} 652252726Srpaulo 653252726Srpaulo 654214501Srpaulo#ifdef CONFIG_IEEE80211R 655214501Srpaulostatic int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth, 656214501Srpaulo struct wpa_state_machine *sm, 657214501Srpaulo struct wpa_eapol_ie_parse *kde) 658214501Srpaulo{ 659214501Srpaulo struct wpa_ie_data ie; 660214501Srpaulo struct rsn_mdie *mdie; 661214501Srpaulo 662214501Srpaulo if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 || 663214501Srpaulo ie.num_pmkid != 1 || ie.pmkid == NULL) { 664214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in " 665214501Srpaulo "FT 4-way handshake message 2/4"); 666214501Srpaulo return -1; 667214501Srpaulo } 668214501Srpaulo 669214501Srpaulo os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN); 670214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant", 671214501Srpaulo sm->sup_pmk_r1_name, PMKID_LEN); 672214501Srpaulo 673214501Srpaulo if (!kde->mdie || !kde->ftie) { 674214501Srpaulo wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake " 675214501Srpaulo "message 2/4", kde->mdie ? "FTIE" : "MDIE"); 676214501Srpaulo return -1; 677214501Srpaulo } 678214501Srpaulo 679214501Srpaulo mdie = (struct rsn_mdie *) (kde->mdie + 2); 680214501Srpaulo if (kde->mdie[1] < sizeof(struct rsn_mdie) || 681214501Srpaulo os_memcmp(wpa_auth->conf.mobility_domain, mdie->mobility_domain, 682214501Srpaulo MOBILITY_DOMAIN_ID_LEN) != 0) { 683214501Srpaulo wpa_printf(MSG_DEBUG, "FT: MDIE mismatch"); 684214501Srpaulo return -1; 685214501Srpaulo } 686214501Srpaulo 687214501Srpaulo if (sm->assoc_resp_ftie && 688214501Srpaulo (kde->ftie[1] != sm->assoc_resp_ftie[1] || 689214501Srpaulo os_memcmp(kde->ftie, sm->assoc_resp_ftie, 690214501Srpaulo 2 + sm->assoc_resp_ftie[1]) != 0)) { 691214501Srpaulo wpa_printf(MSG_DEBUG, "FT: FTIE mismatch"); 692214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 2/4", 693214501Srpaulo kde->ftie, kde->ftie_len); 694214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)AssocResp", 695214501Srpaulo sm->assoc_resp_ftie, 2 + sm->assoc_resp_ftie[1]); 696214501Srpaulo return -1; 697214501Srpaulo } 698214501Srpaulo 699214501Srpaulo return 0; 700214501Srpaulo} 701214501Srpaulo#endif /* CONFIG_IEEE80211R */ 702214501Srpaulo 703214501Srpaulo 704252726Srpaulostatic int wpa_receive_error_report(struct wpa_authenticator *wpa_auth, 705252726Srpaulo struct wpa_state_machine *sm, int group) 706252726Srpaulo{ 707252726Srpaulo /* Supplicant reported a Michael MIC error */ 708252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 709252726Srpaulo "received EAPOL-Key Error Request " 710252726Srpaulo "(STA detected Michael MIC failure (group=%d))", 711252726Srpaulo group); 712252726Srpaulo 713252726Srpaulo if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) { 714252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 715252726Srpaulo "ignore Michael MIC failure report since " 716252726Srpaulo "group cipher is not TKIP"); 717252726Srpaulo } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) { 718252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 719252726Srpaulo "ignore Michael MIC failure report since " 720252726Srpaulo "pairwise cipher is not TKIP"); 721252726Srpaulo } else { 722252726Srpaulo if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0) 723252726Srpaulo return 1; /* STA entry was removed */ 724252726Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures++; 725252726Srpaulo wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++; 726252726Srpaulo } 727252726Srpaulo 728252726Srpaulo /* 729252726Srpaulo * Error report is not a request for a new key handshake, but since 730252726Srpaulo * Authenticator may do it, let's change the keys now anyway. 731252726Srpaulo */ 732252726Srpaulo wpa_request_new_ptk(sm); 733252726Srpaulo return 0; 734252726Srpaulo} 735252726Srpaulo 736252726Srpaulo 737214501Srpaulovoid wpa_receive(struct wpa_authenticator *wpa_auth, 738214501Srpaulo struct wpa_state_machine *sm, 739214501Srpaulo u8 *data, size_t data_len) 740214501Srpaulo{ 741214501Srpaulo struct ieee802_1x_hdr *hdr; 742214501Srpaulo struct wpa_eapol_key *key; 743214501Srpaulo u16 key_info, key_data_length; 744214501Srpaulo enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST, 745214501Srpaulo SMK_M1, SMK_M3, SMK_ERROR } msg; 746214501Srpaulo char *msgtxt; 747214501Srpaulo struct wpa_eapol_ie_parse kde; 748214501Srpaulo int ft; 749214501Srpaulo const u8 *eapol_key_ie; 750214501Srpaulo size_t eapol_key_ie_len; 751214501Srpaulo 752214501Srpaulo if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL) 753214501Srpaulo return; 754214501Srpaulo 755214501Srpaulo if (data_len < sizeof(*hdr) + sizeof(*key)) 756214501Srpaulo return; 757214501Srpaulo 758214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 759214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 760214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 761214501Srpaulo key_data_length = WPA_GET_BE16(key->key_data_length); 762252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR 763252726Srpaulo " key_info=0x%x type=%u key_data_length=%u", 764252726Srpaulo MAC2STR(sm->addr), key_info, key->type, key_data_length); 765214501Srpaulo if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) { 766214501Srpaulo wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - " 767214501Srpaulo "key_data overflow (%d > %lu)", 768214501Srpaulo key_data_length, 769214501Srpaulo (unsigned long) (data_len - sizeof(*hdr) - 770214501Srpaulo sizeof(*key))); 771214501Srpaulo return; 772214501Srpaulo } 773214501Srpaulo 774214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 775252726Srpaulo if (key->type == EAPOL_KEY_TYPE_WPA) { 776252726Srpaulo /* 777252726Srpaulo * Some deployed station implementations seem to send 778252726Srpaulo * msg 4/4 with incorrect type value in WPA2 mode. 779252726Srpaulo */ 780252726Srpaulo wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key " 781252726Srpaulo "with unexpected WPA type in RSN mode"); 782252726Srpaulo } else if (key->type != EAPOL_KEY_TYPE_RSN) { 783214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 784214501Srpaulo "unexpected type %d in RSN mode", 785214501Srpaulo key->type); 786214501Srpaulo return; 787214501Srpaulo } 788214501Srpaulo } else { 789214501Srpaulo if (key->type != EAPOL_KEY_TYPE_WPA) { 790214501Srpaulo wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with " 791214501Srpaulo "unexpected type %d in WPA mode", 792214501Srpaulo key->type); 793214501Srpaulo return; 794214501Srpaulo } 795214501Srpaulo } 796214501Srpaulo 797252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Key Nonce", key->key_nonce, 798252726Srpaulo WPA_NONCE_LEN); 799252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Received Replay Counter", 800252726Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 801252726Srpaulo 802214501Srpaulo /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys 803214501Srpaulo * are set */ 804214501Srpaulo 805214501Srpaulo if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) == 806214501Srpaulo (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) { 807214501Srpaulo if (key_info & WPA_KEY_INFO_ERROR) { 808214501Srpaulo msg = SMK_ERROR; 809214501Srpaulo msgtxt = "SMK Error"; 810214501Srpaulo } else { 811214501Srpaulo msg = SMK_M1; 812214501Srpaulo msgtxt = "SMK M1"; 813214501Srpaulo } 814214501Srpaulo } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) { 815214501Srpaulo msg = SMK_M3; 816214501Srpaulo msgtxt = "SMK M3"; 817214501Srpaulo } else if (key_info & WPA_KEY_INFO_REQUEST) { 818214501Srpaulo msg = REQUEST; 819214501Srpaulo msgtxt = "Request"; 820214501Srpaulo } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { 821214501Srpaulo msg = GROUP_2; 822214501Srpaulo msgtxt = "2/2 Group"; 823214501Srpaulo } else if (key_data_length == 0) { 824214501Srpaulo msg = PAIRWISE_4; 825214501Srpaulo msgtxt = "4/4 Pairwise"; 826214501Srpaulo } else { 827214501Srpaulo msg = PAIRWISE_2; 828214501Srpaulo msgtxt = "2/4 Pairwise"; 829214501Srpaulo } 830214501Srpaulo 831214501Srpaulo /* TODO: key_info type validation for PeerKey */ 832214501Srpaulo if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 || 833214501Srpaulo msg == GROUP_2) { 834214501Srpaulo u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK; 835252726Srpaulo if (sm->pairwise == WPA_CIPHER_CCMP || 836252726Srpaulo sm->pairwise == WPA_CIPHER_GCMP) { 837214501Srpaulo if (wpa_use_aes_cmac(sm) && 838214501Srpaulo ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) { 839214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 840214501Srpaulo LOGGER_WARNING, 841214501Srpaulo "advertised support for " 842214501Srpaulo "AES-128-CMAC, but did not " 843214501Srpaulo "use it"); 844214501Srpaulo return; 845214501Srpaulo } 846214501Srpaulo 847214501Srpaulo if (!wpa_use_aes_cmac(sm) && 848214501Srpaulo ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 849214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, 850214501Srpaulo LOGGER_WARNING, 851214501Srpaulo "did not use HMAC-SHA1-AES " 852252726Srpaulo "with CCMP/GCMP"); 853214501Srpaulo return; 854214501Srpaulo } 855214501Srpaulo } 856214501Srpaulo } 857214501Srpaulo 858214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 859214501Srpaulo if (sm->req_replay_counter_used && 860214501Srpaulo os_memcmp(key->replay_counter, sm->req_replay_counter, 861214501Srpaulo WPA_REPLAY_COUNTER_LEN) <= 0) { 862214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING, 863214501Srpaulo "received EAPOL-Key request with " 864214501Srpaulo "replayed counter"); 865214501Srpaulo return; 866214501Srpaulo } 867214501Srpaulo } 868214501Srpaulo 869214501Srpaulo if (!(key_info & WPA_KEY_INFO_REQUEST) && 870252726Srpaulo !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) { 871214501Srpaulo int i; 872252726Srpaulo 873252726Srpaulo if (msg == PAIRWISE_2 && 874252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 875252726Srpaulo key->replay_counter) && 876252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING && 877252726Srpaulo os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0) 878252726Srpaulo { 879252726Srpaulo /* 880252726Srpaulo * Some supplicant implementations (e.g., Windows XP 881252726Srpaulo * WZC) update SNonce for each EAPOL-Key 2/4. This 882252726Srpaulo * breaks the workaround on accepting any of the 883252726Srpaulo * pending requests, so allow the SNonce to be updated 884252726Srpaulo * even if we have already sent out EAPOL-Key 3/4. 885252726Srpaulo */ 886252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 887252726Srpaulo "Process SNonce update from STA " 888252726Srpaulo "based on retransmitted EAPOL-Key " 889252726Srpaulo "1/4"); 890252726Srpaulo sm->update_snonce = 1; 891252726Srpaulo wpa_replay_counter_mark_invalid(sm->prev_key_replay, 892252726Srpaulo key->replay_counter); 893252726Srpaulo goto continue_processing; 894252726Srpaulo } 895252726Srpaulo 896252726Srpaulo if (msg == PAIRWISE_2 && 897252726Srpaulo wpa_replay_counter_valid(sm->prev_key_replay, 898252726Srpaulo key->replay_counter) && 899252726Srpaulo sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) { 900252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 901252726Srpaulo "ignore retransmitted EAPOL-Key %s - " 902252726Srpaulo "SNonce did not change", msgtxt); 903252726Srpaulo } else { 904252726Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 905252726Srpaulo "received EAPOL-Key %s with " 906252726Srpaulo "unexpected replay counter", msgtxt); 907252726Srpaulo } 908214501Srpaulo for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) { 909214501Srpaulo if (!sm->key_replay[i].valid) 910214501Srpaulo break; 911214501Srpaulo wpa_hexdump(MSG_DEBUG, "pending replay counter", 912214501Srpaulo sm->key_replay[i].counter, 913214501Srpaulo WPA_REPLAY_COUNTER_LEN); 914214501Srpaulo } 915214501Srpaulo wpa_hexdump(MSG_DEBUG, "received replay counter", 916214501Srpaulo key->replay_counter, WPA_REPLAY_COUNTER_LEN); 917214501Srpaulo return; 918214501Srpaulo } 919214501Srpaulo 920252726Srpaulocontinue_processing: 921214501Srpaulo switch (msg) { 922214501Srpaulo case PAIRWISE_2: 923214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKSTART && 924252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING && 925252726Srpaulo (!sm->update_snonce || 926252726Srpaulo sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) { 927214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 928214501Srpaulo "received EAPOL-Key msg 2/4 in " 929214501Srpaulo "invalid state (%d) - dropped", 930214501Srpaulo sm->wpa_ptk_state); 931214501Srpaulo return; 932214501Srpaulo } 933252726Srpaulo random_add_randomness(key->key_nonce, WPA_NONCE_LEN); 934252726Srpaulo if (sm->group->reject_4way_hs_for_entropy) { 935252726Srpaulo /* 936252726Srpaulo * The system did not have enough entropy to generate 937252726Srpaulo * strong random numbers. Reject the first 4-way 938252726Srpaulo * handshake(s) and collect some entropy based on the 939252726Srpaulo * information from it. Once enough entropy is 940252726Srpaulo * available, the next atempt will trigger GMK/Key 941252726Srpaulo * Counter update and the station will be allowed to 942252726Srpaulo * continue. 943252726Srpaulo */ 944252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to " 945252726Srpaulo "collect more entropy for random number " 946252726Srpaulo "generation"); 947252726Srpaulo random_mark_pool_ready(); 948252726Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 949252726Srpaulo return; 950252726Srpaulo } 951214501Srpaulo if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length, 952214501Srpaulo &kde) < 0) { 953214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 954214501Srpaulo "received EAPOL-Key msg 2/4 with " 955214501Srpaulo "invalid Key Data contents"); 956214501Srpaulo return; 957214501Srpaulo } 958214501Srpaulo if (kde.rsn_ie) { 959214501Srpaulo eapol_key_ie = kde.rsn_ie; 960214501Srpaulo eapol_key_ie_len = kde.rsn_ie_len; 961214501Srpaulo } else { 962214501Srpaulo eapol_key_ie = kde.wpa_ie; 963214501Srpaulo eapol_key_ie_len = kde.wpa_ie_len; 964214501Srpaulo } 965214501Srpaulo ft = sm->wpa == WPA_VERSION_WPA2 && 966214501Srpaulo wpa_key_mgmt_ft(sm->wpa_key_mgmt); 967214501Srpaulo if (sm->wpa_ie == NULL || 968214501Srpaulo wpa_compare_rsn_ie(ft, 969214501Srpaulo sm->wpa_ie, sm->wpa_ie_len, 970214501Srpaulo eapol_key_ie, eapol_key_ie_len)) { 971214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 972214501Srpaulo "WPA IE from (Re)AssocReq did not " 973214501Srpaulo "match with msg 2/4"); 974214501Srpaulo if (sm->wpa_ie) { 975214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq", 976214501Srpaulo sm->wpa_ie, sm->wpa_ie_len); 977214501Srpaulo } 978214501Srpaulo wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", 979214501Srpaulo eapol_key_ie, eapol_key_ie_len); 980214501Srpaulo /* MLME-DEAUTHENTICATE.request */ 981214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 982214501Srpaulo return; 983214501Srpaulo } 984214501Srpaulo#ifdef CONFIG_IEEE80211R 985214501Srpaulo if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { 986214501Srpaulo wpa_sta_disconnect(wpa_auth, sm->addr); 987214501Srpaulo return; 988214501Srpaulo } 989214501Srpaulo#endif /* CONFIG_IEEE80211R */ 990214501Srpaulo break; 991214501Srpaulo case PAIRWISE_4: 992214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING || 993214501Srpaulo !sm->PTK_valid) { 994214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 995214501Srpaulo "received EAPOL-Key msg 4/4 in " 996214501Srpaulo "invalid state (%d) - dropped", 997214501Srpaulo sm->wpa_ptk_state); 998214501Srpaulo return; 999214501Srpaulo } 1000214501Srpaulo break; 1001214501Srpaulo case GROUP_2: 1002214501Srpaulo if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING 1003214501Srpaulo || !sm->PTK_valid) { 1004214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, 1005214501Srpaulo "received EAPOL-Key msg 2/2 in " 1006214501Srpaulo "invalid state (%d) - dropped", 1007214501Srpaulo sm->wpa_ptk_group_state); 1008214501Srpaulo return; 1009214501Srpaulo } 1010214501Srpaulo break; 1011214501Srpaulo#ifdef CONFIG_PEERKEY 1012214501Srpaulo case SMK_M1: 1013214501Srpaulo case SMK_M3: 1014214501Srpaulo case SMK_ERROR: 1015214501Srpaulo if (!wpa_auth->conf.peerkey) { 1016214501Srpaulo wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but " 1017214501Srpaulo "PeerKey use disabled - ignoring message"); 1018214501Srpaulo return; 1019214501Srpaulo } 1020214501Srpaulo if (!sm->PTK_valid) { 1021214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1022214501Srpaulo "received EAPOL-Key msg SMK in " 1023214501Srpaulo "invalid state - dropped"); 1024214501Srpaulo return; 1025214501Srpaulo } 1026214501Srpaulo break; 1027214501Srpaulo#else /* CONFIG_PEERKEY */ 1028214501Srpaulo case SMK_M1: 1029214501Srpaulo case SMK_M3: 1030214501Srpaulo case SMK_ERROR: 1031214501Srpaulo return; /* STSL disabled - ignore SMK messages */ 1032214501Srpaulo#endif /* CONFIG_PEERKEY */ 1033214501Srpaulo case REQUEST: 1034214501Srpaulo break; 1035214501Srpaulo } 1036214501Srpaulo 1037214501Srpaulo wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 1038214501Srpaulo "received EAPOL-Key frame (%s)", msgtxt); 1039214501Srpaulo 1040214501Srpaulo if (key_info & WPA_KEY_INFO_ACK) { 1041214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1042214501Srpaulo "received invalid EAPOL-Key: Key Ack set"); 1043214501Srpaulo return; 1044214501Srpaulo } 1045214501Srpaulo 1046214501Srpaulo if (!(key_info & WPA_KEY_INFO_MIC)) { 1047214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1048214501Srpaulo "received invalid EAPOL-Key: Key MIC not set"); 1049214501Srpaulo return; 1050214501Srpaulo } 1051214501Srpaulo 1052214501Srpaulo sm->MICVerified = FALSE; 1053252726Srpaulo if (sm->PTK_valid && !sm->update_snonce) { 1054214501Srpaulo if (wpa_verify_key_mic(&sm->PTK, data, data_len)) { 1055214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1056214501Srpaulo "received EAPOL-Key with invalid MIC"); 1057214501Srpaulo return; 1058214501Srpaulo } 1059214501Srpaulo sm->MICVerified = TRUE; 1060214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 1061252726Srpaulo sm->pending_1_of_4_timeout = 0; 1062214501Srpaulo } 1063214501Srpaulo 1064214501Srpaulo if (key_info & WPA_KEY_INFO_REQUEST) { 1065214501Srpaulo if (sm->MICVerified) { 1066214501Srpaulo sm->req_replay_counter_used = 1; 1067214501Srpaulo os_memcpy(sm->req_replay_counter, key->replay_counter, 1068214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1069214501Srpaulo } else { 1070214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1071214501Srpaulo "received EAPOL-Key request with " 1072214501Srpaulo "invalid MIC"); 1073214501Srpaulo return; 1074214501Srpaulo } 1075214501Srpaulo 1076214501Srpaulo /* 1077214501Srpaulo * TODO: should decrypt key data field if encryption was used; 1078214501Srpaulo * even though MAC address KDE is not normally encrypted, 1079214501Srpaulo * supplicant is allowed to encrypt it. 1080214501Srpaulo */ 1081214501Srpaulo if (msg == SMK_ERROR) { 1082214501Srpaulo#ifdef CONFIG_PEERKEY 1083214501Srpaulo wpa_smk_error(wpa_auth, sm, key); 1084214501Srpaulo#endif /* CONFIG_PEERKEY */ 1085214501Srpaulo return; 1086214501Srpaulo } else if (key_info & WPA_KEY_INFO_ERROR) { 1087252726Srpaulo if (wpa_receive_error_report( 1088252726Srpaulo wpa_auth, sm, 1089252726Srpaulo !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0) 1090252726Srpaulo return; /* STA entry was removed */ 1091214501Srpaulo } else if (key_info & WPA_KEY_INFO_KEY_TYPE) { 1092214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1093214501Srpaulo "received EAPOL-Key Request for new " 1094214501Srpaulo "4-Way Handshake"); 1095214501Srpaulo wpa_request_new_ptk(sm); 1096214501Srpaulo#ifdef CONFIG_PEERKEY 1097214501Srpaulo } else if (msg == SMK_M1) { 1098214501Srpaulo wpa_smk_m1(wpa_auth, sm, key); 1099214501Srpaulo#endif /* CONFIG_PEERKEY */ 1100214501Srpaulo } else if (key_data_length > 0 && 1101214501Srpaulo wpa_parse_kde_ies((const u8 *) (key + 1), 1102214501Srpaulo key_data_length, &kde) == 0 && 1103214501Srpaulo kde.mac_addr) { 1104214501Srpaulo } else { 1105214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, 1106214501Srpaulo "received EAPOL-Key Request for GTK " 1107214501Srpaulo "rekeying"); 1108214501Srpaulo eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL); 1109214501Srpaulo wpa_rekey_gtk(wpa_auth, NULL); 1110214501Srpaulo } 1111214501Srpaulo } else { 1112252726Srpaulo /* Do not allow the same key replay counter to be reused. */ 1113252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, 1114252726Srpaulo key->replay_counter); 1115252726Srpaulo 1116252726Srpaulo if (msg == PAIRWISE_2) { 1117252726Srpaulo /* 1118252726Srpaulo * Maintain a copy of the pending EAPOL-Key frames in 1119252726Srpaulo * case the EAPOL-Key frame was retransmitted. This is 1120252726Srpaulo * needed to allow EAPOL-Key msg 2/4 reply to another 1121252726Srpaulo * pending msg 1/4 to update the SNonce to work around 1122252726Srpaulo * unexpected supplicant behavior. 1123252726Srpaulo */ 1124252726Srpaulo os_memcpy(sm->prev_key_replay, sm->key_replay, 1125252726Srpaulo sizeof(sm->key_replay)); 1126252726Srpaulo } else { 1127252726Srpaulo os_memset(sm->prev_key_replay, 0, 1128252726Srpaulo sizeof(sm->prev_key_replay)); 1129252726Srpaulo } 1130252726Srpaulo 1131252726Srpaulo /* 1132252726Srpaulo * Make sure old valid counters are not accepted anymore and 1133252726Srpaulo * do not get copied again. 1134252726Srpaulo */ 1135252726Srpaulo wpa_replay_counter_mark_invalid(sm->key_replay, NULL); 1136214501Srpaulo } 1137214501Srpaulo 1138214501Srpaulo#ifdef CONFIG_PEERKEY 1139214501Srpaulo if (msg == SMK_M3) { 1140214501Srpaulo wpa_smk_m3(wpa_auth, sm, key); 1141214501Srpaulo return; 1142214501Srpaulo } 1143214501Srpaulo#endif /* CONFIG_PEERKEY */ 1144214501Srpaulo 1145214501Srpaulo os_free(sm->last_rx_eapol_key); 1146214501Srpaulo sm->last_rx_eapol_key = os_malloc(data_len); 1147214501Srpaulo if (sm->last_rx_eapol_key == NULL) 1148214501Srpaulo return; 1149214501Srpaulo os_memcpy(sm->last_rx_eapol_key, data, data_len); 1150214501Srpaulo sm->last_rx_eapol_key_len = data_len; 1151214501Srpaulo 1152252726Srpaulo sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE); 1153214501Srpaulo sm->EAPOLKeyReceived = TRUE; 1154214501Srpaulo sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); 1155214501Srpaulo sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); 1156214501Srpaulo os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); 1157214501Srpaulo wpa_sm_step(sm); 1158214501Srpaulo} 1159214501Srpaulo 1160214501Srpaulo 1161252726Srpaulostatic int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr, 1162252726Srpaulo const u8 *gnonce, u8 *gtk, size_t gtk_len) 1163214501Srpaulo{ 1164252726Srpaulo u8 data[ETH_ALEN + WPA_NONCE_LEN + 8 + 16]; 1165252726Srpaulo u8 *pos; 1166252726Srpaulo int ret = 0; 1167214501Srpaulo 1168252726Srpaulo /* GTK = PRF-X(GMK, "Group key expansion", 1169252726Srpaulo * AA || GNonce || Time || random data) 1170252726Srpaulo * The example described in the IEEE 802.11 standard uses only AA and 1171252726Srpaulo * GNonce as inputs here. Add some more entropy since this derivation 1172252726Srpaulo * is done only at the Authenticator and as such, does not need to be 1173252726Srpaulo * exactly same. 1174252726Srpaulo */ 1175214501Srpaulo os_memcpy(data, addr, ETH_ALEN); 1176214501Srpaulo os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN); 1177252726Srpaulo pos = data + ETH_ALEN + WPA_NONCE_LEN; 1178252726Srpaulo wpa_get_ntp_timestamp(pos); 1179252726Srpaulo pos += 8; 1180252726Srpaulo if (random_get_bytes(pos, 16) < 0) 1181252726Srpaulo ret = -1; 1182214501Srpaulo 1183214501Srpaulo#ifdef CONFIG_IEEE80211W 1184252726Srpaulo sha256_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len); 1185214501Srpaulo#else /* CONFIG_IEEE80211W */ 1186252726Srpaulo if (sha1_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len) 1187252726Srpaulo < 0) 1188252726Srpaulo ret = -1; 1189214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1190214501Srpaulo 1191252726Srpaulo return ret; 1192214501Srpaulo} 1193214501Srpaulo 1194214501Srpaulo 1195214501Srpaulostatic void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx) 1196214501Srpaulo{ 1197214501Srpaulo struct wpa_authenticator *wpa_auth = eloop_ctx; 1198214501Srpaulo struct wpa_state_machine *sm = timeout_ctx; 1199214501Srpaulo 1200252726Srpaulo sm->pending_1_of_4_timeout = 0; 1201214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout"); 1202214501Srpaulo sm->TimeoutEvt = TRUE; 1203214501Srpaulo wpa_sm_step(sm); 1204214501Srpaulo} 1205214501Srpaulo 1206214501Srpaulo 1207214501Srpaulovoid __wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1208214501Srpaulo struct wpa_state_machine *sm, int key_info, 1209214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1210214501Srpaulo const u8 *kde, size_t kde_len, 1211214501Srpaulo int keyidx, int encr, int force_version) 1212214501Srpaulo{ 1213214501Srpaulo struct ieee802_1x_hdr *hdr; 1214214501Srpaulo struct wpa_eapol_key *key; 1215214501Srpaulo size_t len; 1216214501Srpaulo int alg; 1217214501Srpaulo int key_data_len, pad_len = 0; 1218214501Srpaulo u8 *buf, *pos; 1219214501Srpaulo int version, pairwise; 1220214501Srpaulo int i; 1221214501Srpaulo 1222214501Srpaulo len = sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key); 1223214501Srpaulo 1224214501Srpaulo if (force_version) 1225214501Srpaulo version = force_version; 1226214501Srpaulo else if (wpa_use_aes_cmac(sm)) 1227214501Srpaulo version = WPA_KEY_INFO_TYPE_AES_128_CMAC; 1228252726Srpaulo else if (sm->pairwise != WPA_CIPHER_TKIP) 1229214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1230214501Srpaulo else 1231214501Srpaulo version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1232214501Srpaulo 1233214501Srpaulo pairwise = key_info & WPA_KEY_INFO_KEY_TYPE; 1234214501Srpaulo 1235214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d " 1236214501Srpaulo "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d " 1237214501Srpaulo "encr=%d)", 1238214501Srpaulo version, 1239214501Srpaulo (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0, 1240214501Srpaulo (key_info & WPA_KEY_INFO_MIC) ? 1 : 0, 1241214501Srpaulo (key_info & WPA_KEY_INFO_ACK) ? 1 : 0, 1242214501Srpaulo (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0, 1243214501Srpaulo pairwise, (unsigned long) kde_len, keyidx, encr); 1244214501Srpaulo 1245214501Srpaulo key_data_len = kde_len; 1246214501Srpaulo 1247214501Srpaulo if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1248214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) { 1249214501Srpaulo pad_len = key_data_len % 8; 1250214501Srpaulo if (pad_len) 1251214501Srpaulo pad_len = 8 - pad_len; 1252214501Srpaulo key_data_len += pad_len + 8; 1253214501Srpaulo } 1254214501Srpaulo 1255214501Srpaulo len += key_data_len; 1256214501Srpaulo 1257214501Srpaulo hdr = os_zalloc(len); 1258214501Srpaulo if (hdr == NULL) 1259214501Srpaulo return; 1260214501Srpaulo hdr->version = wpa_auth->conf.eapol_version; 1261214501Srpaulo hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1262214501Srpaulo hdr->length = host_to_be16(len - sizeof(*hdr)); 1263214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1264214501Srpaulo 1265214501Srpaulo key->type = sm->wpa == WPA_VERSION_WPA2 ? 1266214501Srpaulo EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1267214501Srpaulo key_info |= version; 1268214501Srpaulo if (encr && sm->wpa == WPA_VERSION_WPA2) 1269214501Srpaulo key_info |= WPA_KEY_INFO_ENCR_KEY_DATA; 1270214501Srpaulo if (sm->wpa != WPA_VERSION_WPA2) 1271214501Srpaulo key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT; 1272214501Srpaulo WPA_PUT_BE16(key->key_info, key_info); 1273214501Srpaulo 1274214501Srpaulo alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group; 1275252726Srpaulo WPA_PUT_BE16(key->key_length, wpa_cipher_key_len(alg)); 1276214501Srpaulo if (key_info & WPA_KEY_INFO_SMK_MESSAGE) 1277214501Srpaulo WPA_PUT_BE16(key->key_length, 0); 1278214501Srpaulo 1279214501Srpaulo /* FIX: STSL: what to use as key_replay_counter? */ 1280214501Srpaulo for (i = RSNA_MAX_EAPOL_RETRIES - 1; i > 0; i--) { 1281214501Srpaulo sm->key_replay[i].valid = sm->key_replay[i - 1].valid; 1282214501Srpaulo os_memcpy(sm->key_replay[i].counter, 1283214501Srpaulo sm->key_replay[i - 1].counter, 1284214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1285214501Srpaulo } 1286214501Srpaulo inc_byte_array(sm->key_replay[0].counter, WPA_REPLAY_COUNTER_LEN); 1287214501Srpaulo os_memcpy(key->replay_counter, sm->key_replay[0].counter, 1288214501Srpaulo WPA_REPLAY_COUNTER_LEN); 1289214501Srpaulo sm->key_replay[0].valid = TRUE; 1290214501Srpaulo 1291214501Srpaulo if (nonce) 1292214501Srpaulo os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN); 1293214501Srpaulo 1294214501Srpaulo if (key_rsc) 1295214501Srpaulo os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN); 1296214501Srpaulo 1297214501Srpaulo if (kde && !encr) { 1298214501Srpaulo os_memcpy(key + 1, kde, kde_len); 1299214501Srpaulo WPA_PUT_BE16(key->key_data_length, kde_len); 1300214501Srpaulo } else if (encr && kde) { 1301214501Srpaulo buf = os_zalloc(key_data_len); 1302214501Srpaulo if (buf == NULL) { 1303214501Srpaulo os_free(hdr); 1304214501Srpaulo return; 1305214501Srpaulo } 1306214501Srpaulo pos = buf; 1307214501Srpaulo os_memcpy(pos, kde, kde_len); 1308214501Srpaulo pos += kde_len; 1309214501Srpaulo 1310214501Srpaulo if (pad_len) 1311214501Srpaulo *pos++ = 0xdd; 1312214501Srpaulo 1313214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data", 1314214501Srpaulo buf, key_data_len); 1315214501Srpaulo if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || 1316214501Srpaulo version == WPA_KEY_INFO_TYPE_AES_128_CMAC) { 1317214501Srpaulo if (aes_wrap(sm->PTK.kek, (key_data_len - 8) / 8, buf, 1318214501Srpaulo (u8 *) (key + 1))) { 1319214501Srpaulo os_free(hdr); 1320214501Srpaulo os_free(buf); 1321214501Srpaulo return; 1322214501Srpaulo } 1323214501Srpaulo WPA_PUT_BE16(key->key_data_length, key_data_len); 1324214501Srpaulo } else { 1325214501Srpaulo u8 ek[32]; 1326214501Srpaulo os_memcpy(key->key_iv, 1327214501Srpaulo sm->group->Counter + WPA_NONCE_LEN - 16, 16); 1328214501Srpaulo inc_byte_array(sm->group->Counter, WPA_NONCE_LEN); 1329214501Srpaulo os_memcpy(ek, key->key_iv, 16); 1330214501Srpaulo os_memcpy(ek + 16, sm->PTK.kek, 16); 1331214501Srpaulo os_memcpy(key + 1, buf, key_data_len); 1332214501Srpaulo rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len); 1333214501Srpaulo WPA_PUT_BE16(key->key_data_length, key_data_len); 1334214501Srpaulo } 1335214501Srpaulo os_free(buf); 1336214501Srpaulo } 1337214501Srpaulo 1338214501Srpaulo if (key_info & WPA_KEY_INFO_MIC) { 1339214501Srpaulo if (!sm->PTK_valid) { 1340214501Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 1341214501Srpaulo "PTK not valid when sending EAPOL-Key " 1342214501Srpaulo "frame"); 1343214501Srpaulo os_free(hdr); 1344214501Srpaulo return; 1345214501Srpaulo } 1346214501Srpaulo wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len, 1347214501Srpaulo key->key_mic); 1348214501Srpaulo } 1349214501Srpaulo 1350214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1351214501Srpaulo 1); 1352214501Srpaulo wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len, 1353214501Srpaulo sm->pairwise_set); 1354214501Srpaulo os_free(hdr); 1355214501Srpaulo} 1356214501Srpaulo 1357214501Srpaulo 1358214501Srpaulostatic void wpa_send_eapol(struct wpa_authenticator *wpa_auth, 1359214501Srpaulo struct wpa_state_machine *sm, int key_info, 1360214501Srpaulo const u8 *key_rsc, const u8 *nonce, 1361214501Srpaulo const u8 *kde, size_t kde_len, 1362214501Srpaulo int keyidx, int encr) 1363214501Srpaulo{ 1364214501Srpaulo int timeout_ms; 1365214501Srpaulo int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE; 1366214501Srpaulo int ctr; 1367214501Srpaulo 1368214501Srpaulo if (sm == NULL) 1369214501Srpaulo return; 1370214501Srpaulo 1371214501Srpaulo __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len, 1372214501Srpaulo keyidx, encr, 0); 1373214501Srpaulo 1374214501Srpaulo ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr; 1375252726Srpaulo if (ctr == 1 && wpa_auth->conf.tx_status) 1376252726Srpaulo timeout_ms = pairwise ? eapol_key_timeout_first : 1377252726Srpaulo eapol_key_timeout_first_group; 1378214501Srpaulo else 1379214501Srpaulo timeout_ms = eapol_key_timeout_subseq; 1380252726Srpaulo if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC)) 1381252726Srpaulo sm->pending_1_of_4_timeout = 1; 1382252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry " 1383252726Srpaulo "counter %d)", timeout_ms, ctr); 1384214501Srpaulo eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000, 1385214501Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 1386214501Srpaulo} 1387214501Srpaulo 1388214501Srpaulo 1389214501Srpaulostatic int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len) 1390214501Srpaulo{ 1391214501Srpaulo struct ieee802_1x_hdr *hdr; 1392214501Srpaulo struct wpa_eapol_key *key; 1393214501Srpaulo u16 key_info; 1394214501Srpaulo int ret = 0; 1395214501Srpaulo u8 mic[16]; 1396214501Srpaulo 1397214501Srpaulo if (data_len < sizeof(*hdr) + sizeof(*key)) 1398214501Srpaulo return -1; 1399214501Srpaulo 1400214501Srpaulo hdr = (struct ieee802_1x_hdr *) data; 1401214501Srpaulo key = (struct wpa_eapol_key *) (hdr + 1); 1402214501Srpaulo key_info = WPA_GET_BE16(key->key_info); 1403214501Srpaulo os_memcpy(mic, key->key_mic, 16); 1404214501Srpaulo os_memset(key->key_mic, 0, 16); 1405214501Srpaulo if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK, 1406214501Srpaulo data, data_len, key->key_mic) || 1407214501Srpaulo os_memcmp(mic, key->key_mic, 16) != 0) 1408214501Srpaulo ret = -1; 1409214501Srpaulo os_memcpy(key->key_mic, mic, 16); 1410214501Srpaulo return ret; 1411214501Srpaulo} 1412214501Srpaulo 1413214501Srpaulo 1414214501Srpaulovoid wpa_remove_ptk(struct wpa_state_machine *sm) 1415214501Srpaulo{ 1416214501Srpaulo sm->PTK_valid = FALSE; 1417214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1418252726Srpaulo wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL, 0); 1419214501Srpaulo sm->pairwise_set = FALSE; 1420214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 1421214501Srpaulo} 1422214501Srpaulo 1423214501Srpaulo 1424214501Srpauloint wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event) 1425214501Srpaulo{ 1426214501Srpaulo int remove_ptk = 1; 1427214501Srpaulo 1428214501Srpaulo if (sm == NULL) 1429214501Srpaulo return -1; 1430214501Srpaulo 1431214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1432214501Srpaulo "event %d notification", event); 1433214501Srpaulo 1434214501Srpaulo switch (event) { 1435214501Srpaulo case WPA_AUTH: 1436214501Srpaulo case WPA_ASSOC: 1437214501Srpaulo break; 1438214501Srpaulo case WPA_DEAUTH: 1439214501Srpaulo case WPA_DISASSOC: 1440214501Srpaulo sm->DeauthenticationRequest = TRUE; 1441214501Srpaulo break; 1442214501Srpaulo case WPA_REAUTH: 1443214501Srpaulo case WPA_REAUTH_EAPOL: 1444214501Srpaulo if (!sm->started) { 1445214501Srpaulo /* 1446214501Srpaulo * When using WPS, we may end up here if the STA 1447214501Srpaulo * manages to re-associate without the previous STA 1448214501Srpaulo * entry getting removed. Consequently, we need to make 1449214501Srpaulo * sure that the WPA state machines gets initialized 1450214501Srpaulo * properly at this point. 1451214501Srpaulo */ 1452214501Srpaulo wpa_printf(MSG_DEBUG, "WPA state machine had not been " 1453214501Srpaulo "started - initialize now"); 1454214501Srpaulo sm->started = 1; 1455214501Srpaulo sm->Init = TRUE; 1456214501Srpaulo if (wpa_sm_step(sm) == 1) 1457214501Srpaulo return 1; /* should not really happen */ 1458214501Srpaulo sm->Init = FALSE; 1459214501Srpaulo sm->AuthenticationRequest = TRUE; 1460214501Srpaulo break; 1461214501Srpaulo } 1462214501Srpaulo if (sm->GUpdateStationKeys) { 1463214501Srpaulo /* 1464214501Srpaulo * Reauthentication cancels the pending group key 1465214501Srpaulo * update for this STA. 1466214501Srpaulo */ 1467214501Srpaulo sm->group->GKeyDoneStations--; 1468214501Srpaulo sm->GUpdateStationKeys = FALSE; 1469214501Srpaulo sm->PtkGroupInit = TRUE; 1470214501Srpaulo } 1471214501Srpaulo sm->ReAuthenticationRequest = TRUE; 1472214501Srpaulo break; 1473214501Srpaulo case WPA_ASSOC_FT: 1474214501Srpaulo#ifdef CONFIG_IEEE80211R 1475214501Srpaulo wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration " 1476214501Srpaulo "after association"); 1477214501Srpaulo wpa_ft_install_ptk(sm); 1478214501Srpaulo 1479214501Srpaulo /* Using FT protocol, not WPA auth state machine */ 1480214501Srpaulo sm->ft_completed = 1; 1481214501Srpaulo return 0; 1482214501Srpaulo#else /* CONFIG_IEEE80211R */ 1483214501Srpaulo break; 1484214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1485214501Srpaulo } 1486214501Srpaulo 1487214501Srpaulo#ifdef CONFIG_IEEE80211R 1488214501Srpaulo sm->ft_completed = 0; 1489214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1490214501Srpaulo 1491214501Srpaulo#ifdef CONFIG_IEEE80211W 1492214501Srpaulo if (sm->mgmt_frame_prot && event == WPA_AUTH) 1493214501Srpaulo remove_ptk = 0; 1494214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1495214501Srpaulo 1496214501Srpaulo if (remove_ptk) { 1497214501Srpaulo sm->PTK_valid = FALSE; 1498214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1499214501Srpaulo 1500214501Srpaulo if (event != WPA_REAUTH_EAPOL) 1501214501Srpaulo wpa_remove_ptk(sm); 1502214501Srpaulo } 1503214501Srpaulo 1504214501Srpaulo return wpa_sm_step(sm); 1505214501Srpaulo} 1506214501Srpaulo 1507214501Srpaulo 1508214501SrpauloSM_STATE(WPA_PTK, INITIALIZE) 1509214501Srpaulo{ 1510214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk); 1511214501Srpaulo if (sm->Init) { 1512214501Srpaulo /* Init flag is not cleared here, so avoid busy 1513214501Srpaulo * loop by claiming nothing changed. */ 1514214501Srpaulo sm->changed = FALSE; 1515214501Srpaulo } 1516214501Srpaulo 1517214501Srpaulo sm->keycount = 0; 1518214501Srpaulo if (sm->GUpdateStationKeys) 1519214501Srpaulo sm->group->GKeyDoneStations--; 1520214501Srpaulo sm->GUpdateStationKeys = FALSE; 1521214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 1522214501Srpaulo sm->PInitAKeys = FALSE; 1523214501Srpaulo if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and 1524214501Srpaulo * Local AA > Remote AA)) */) { 1525214501Srpaulo sm->Pair = TRUE; 1526214501Srpaulo } 1527214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0); 1528214501Srpaulo wpa_remove_ptk(sm); 1529214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0); 1530214501Srpaulo sm->TimeoutCtr = 0; 1531214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1532214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 1533214501Srpaulo WPA_EAPOL_authorized, 0); 1534214501Srpaulo } 1535214501Srpaulo} 1536214501Srpaulo 1537214501Srpaulo 1538214501SrpauloSM_STATE(WPA_PTK, DISCONNECT) 1539214501Srpaulo{ 1540214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); 1541214501Srpaulo sm->Disconnect = FALSE; 1542214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 1543214501Srpaulo} 1544214501Srpaulo 1545214501Srpaulo 1546214501SrpauloSM_STATE(WPA_PTK, DISCONNECTED) 1547214501Srpaulo{ 1548214501Srpaulo SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk); 1549214501Srpaulo sm->DeauthenticationRequest = FALSE; 1550214501Srpaulo} 1551214501Srpaulo 1552214501Srpaulo 1553214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION) 1554214501Srpaulo{ 1555214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk); 1556214501Srpaulo os_memset(&sm->PTK, 0, sizeof(sm->PTK)); 1557214501Srpaulo sm->PTK_valid = FALSE; 1558214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto, 1559214501Srpaulo 1); 1560214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1); 1561214501Srpaulo sm->AuthenticationRequest = FALSE; 1562214501Srpaulo} 1563214501Srpaulo 1564214501Srpaulo 1565252726Srpaulostatic void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth, 1566252726Srpaulo struct wpa_group *group) 1567252726Srpaulo{ 1568252726Srpaulo if (group->first_sta_seen) 1569252726Srpaulo return; 1570252726Srpaulo /* 1571252726Srpaulo * System has run bit further than at the time hostapd was started 1572252726Srpaulo * potentially very early during boot up. This provides better chances 1573252726Srpaulo * of collecting more randomness on embedded systems. Re-initialize the 1574252726Srpaulo * GMK and Counter here to improve their strength if there was not 1575252726Srpaulo * enough entropy available immediately after system startup. 1576252726Srpaulo */ 1577252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first " 1578252726Srpaulo "station"); 1579252726Srpaulo if (random_pool_ready() != 1) { 1580252726Srpaulo wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool " 1581252726Srpaulo "to proceed - reject first 4-way handshake"); 1582252726Srpaulo group->reject_4way_hs_for_entropy = TRUE; 1583252726Srpaulo } else { 1584252726Srpaulo group->first_sta_seen = TRUE; 1585252726Srpaulo group->reject_4way_hs_for_entropy = FALSE; 1586252726Srpaulo } 1587252726Srpaulo 1588252726Srpaulo wpa_group_init_gmk_and_counter(wpa_auth, group); 1589252726Srpaulo wpa_gtk_update(wpa_auth, group); 1590252726Srpaulo wpa_group_config_group_keys(wpa_auth, group); 1591252726Srpaulo} 1592252726Srpaulo 1593252726Srpaulo 1594214501SrpauloSM_STATE(WPA_PTK, AUTHENTICATION2) 1595214501Srpaulo{ 1596214501Srpaulo SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk); 1597252726Srpaulo 1598252726Srpaulo wpa_group_ensure_init(sm->wpa_auth, sm->group); 1599252726Srpaulo 1600252726Srpaulo /* 1601252726Srpaulo * Definition of ANonce selection in IEEE Std 802.11i-2004 is somewhat 1602252726Srpaulo * ambiguous. The Authenticator state machine uses a counter that is 1603252726Srpaulo * incremented by one for each 4-way handshake. However, the security 1604252726Srpaulo * analysis of 4-way handshake points out that unpredictable nonces 1605252726Srpaulo * help in preventing precomputation attacks. Instead of the state 1606252726Srpaulo * machine definition, use an unpredictable nonce value here to provide 1607252726Srpaulo * stronger protection against potential precomputation attacks. 1608252726Srpaulo */ 1609252726Srpaulo if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 1610252726Srpaulo wpa_printf(MSG_ERROR, "WPA: Failed to get random data for " 1611252726Srpaulo "ANonce."); 1612252726Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 1613252726Srpaulo return; 1614252726Srpaulo } 1615252726Srpaulo wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, 1616252726Srpaulo WPA_NONCE_LEN); 1617214501Srpaulo sm->ReAuthenticationRequest = FALSE; 1618214501Srpaulo /* IEEE 802.11i does not clear TimeoutCtr here, but this is more 1619214501Srpaulo * logical place than INITIALIZE since AUTHENTICATION2 can be 1620214501Srpaulo * re-entered on ReAuthenticationRequest without going through 1621214501Srpaulo * INITIALIZE. */ 1622214501Srpaulo sm->TimeoutCtr = 0; 1623214501Srpaulo} 1624214501Srpaulo 1625214501Srpaulo 1626214501SrpauloSM_STATE(WPA_PTK, INITPMK) 1627214501Srpaulo{ 1628214501Srpaulo u8 msk[2 * PMK_LEN]; 1629214501Srpaulo size_t len = 2 * PMK_LEN; 1630214501Srpaulo 1631214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk); 1632214501Srpaulo#ifdef CONFIG_IEEE80211R 1633214501Srpaulo sm->xxkey_len = 0; 1634214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1635214501Srpaulo if (sm->pmksa) { 1636214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache"); 1637214501Srpaulo os_memcpy(sm->PMK, sm->pmksa->pmk, PMK_LEN); 1638214501Srpaulo } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) { 1639214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine " 1640214501Srpaulo "(len=%lu)", (unsigned long) len); 1641214501Srpaulo os_memcpy(sm->PMK, msk, PMK_LEN); 1642214501Srpaulo#ifdef CONFIG_IEEE80211R 1643214501Srpaulo if (len >= 2 * PMK_LEN) { 1644214501Srpaulo os_memcpy(sm->xxkey, msk + PMK_LEN, PMK_LEN); 1645214501Srpaulo sm->xxkey_len = PMK_LEN; 1646214501Srpaulo } 1647214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1648214501Srpaulo } else { 1649214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Could not get PMK"); 1650214501Srpaulo } 1651214501Srpaulo 1652214501Srpaulo sm->req_replay_counter_used = 0; 1653214501Srpaulo /* IEEE 802.11i does not set keyRun to FALSE, but not doing this 1654214501Srpaulo * will break reauthentication since EAPOL state machines may not be 1655214501Srpaulo * get into AUTHENTICATING state that clears keyRun before WPA state 1656214501Srpaulo * machine enters AUTHENTICATION2 state and goes immediately to INITPMK 1657214501Srpaulo * state and takes PMK from the previously used AAA Key. This will 1658214501Srpaulo * eventually fail in 4-Way Handshake because Supplicant uses PMK 1659214501Srpaulo * derived from the new AAA Key. Setting keyRun = FALSE here seems to 1660214501Srpaulo * be good workaround for this issue. */ 1661214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0); 1662214501Srpaulo} 1663214501Srpaulo 1664214501Srpaulo 1665214501SrpauloSM_STATE(WPA_PTK, INITPSK) 1666214501Srpaulo{ 1667214501Srpaulo const u8 *psk; 1668214501Srpaulo SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk); 1669214501Srpaulo psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL); 1670214501Srpaulo if (psk) { 1671214501Srpaulo os_memcpy(sm->PMK, psk, PMK_LEN); 1672214501Srpaulo#ifdef CONFIG_IEEE80211R 1673214501Srpaulo os_memcpy(sm->xxkey, psk, PMK_LEN); 1674214501Srpaulo sm->xxkey_len = PMK_LEN; 1675214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1676214501Srpaulo } 1677214501Srpaulo sm->req_replay_counter_used = 0; 1678214501Srpaulo} 1679214501Srpaulo 1680214501Srpaulo 1681214501SrpauloSM_STATE(WPA_PTK, PTKSTART) 1682214501Srpaulo{ 1683214501Srpaulo u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL; 1684214501Srpaulo size_t pmkid_len = 0; 1685214501Srpaulo 1686214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk); 1687214501Srpaulo sm->PTKRequest = FALSE; 1688214501Srpaulo sm->TimeoutEvt = FALSE; 1689214501Srpaulo 1690214501Srpaulo sm->TimeoutCtr++; 1691214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 1692214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 1693214501Srpaulo * immediately following this. */ 1694214501Srpaulo return; 1695214501Srpaulo } 1696214501Srpaulo 1697214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1698214501Srpaulo "sending 1/4 msg of 4-Way Handshake"); 1699214501Srpaulo /* 1700214501Srpaulo * TODO: Could add PMKID even with WPA2-PSK, but only if there is only 1701214501Srpaulo * one possible PSK for this STA. 1702214501Srpaulo */ 1703214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && 1704214501Srpaulo wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt)) { 1705214501Srpaulo pmkid = buf; 1706214501Srpaulo pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 1707214501Srpaulo pmkid[0] = WLAN_EID_VENDOR_SPECIFIC; 1708214501Srpaulo pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN; 1709214501Srpaulo RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID); 1710214501Srpaulo if (sm->pmksa) 1711214501Srpaulo os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], 1712214501Srpaulo sm->pmksa->pmkid, PMKID_LEN); 1713214501Srpaulo else { 1714214501Srpaulo /* 1715214501Srpaulo * Calculate PMKID since no PMKSA cache entry was 1716214501Srpaulo * available with pre-calculated PMKID. 1717214501Srpaulo */ 1718214501Srpaulo rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr, 1719214501Srpaulo sm->addr, &pmkid[2 + RSN_SELECTOR_LEN], 1720214501Srpaulo wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 1721214501Srpaulo } 1722214501Srpaulo } 1723214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 1724214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL, 1725214501Srpaulo sm->ANonce, pmkid, pmkid_len, 0, 0); 1726214501Srpaulo} 1727214501Srpaulo 1728214501Srpaulo 1729214501Srpaulostatic int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk, 1730214501Srpaulo struct wpa_ptk *ptk) 1731214501Srpaulo{ 1732252726Srpaulo size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64; 1733214501Srpaulo#ifdef CONFIG_IEEE80211R 1734214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 1735214501Srpaulo return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len); 1736214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1737214501Srpaulo 1738214501Srpaulo wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion", 1739214501Srpaulo sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce, 1740214501Srpaulo (u8 *) ptk, ptk_len, 1741214501Srpaulo wpa_key_mgmt_sha256(sm->wpa_key_mgmt)); 1742214501Srpaulo 1743214501Srpaulo return 0; 1744214501Srpaulo} 1745214501Srpaulo 1746214501Srpaulo 1747214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING) 1748214501Srpaulo{ 1749214501Srpaulo struct wpa_ptk PTK; 1750214501Srpaulo int ok = 0; 1751214501Srpaulo const u8 *pmk = NULL; 1752214501Srpaulo 1753214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); 1754214501Srpaulo sm->EAPOLKeyReceived = FALSE; 1755252726Srpaulo sm->update_snonce = FALSE; 1756214501Srpaulo 1757214501Srpaulo /* WPA with IEEE 802.1X: use the derived PMK from EAP 1758214501Srpaulo * WPA-PSK: iterate through possible PSKs and select the one matching 1759214501Srpaulo * the packet */ 1760214501Srpaulo for (;;) { 1761214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1762214501Srpaulo pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, pmk); 1763214501Srpaulo if (pmk == NULL) 1764214501Srpaulo break; 1765214501Srpaulo } else 1766214501Srpaulo pmk = sm->PMK; 1767214501Srpaulo 1768214501Srpaulo wpa_derive_ptk(sm, pmk, &PTK); 1769214501Srpaulo 1770214501Srpaulo if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key, 1771214501Srpaulo sm->last_rx_eapol_key_len) == 0) { 1772214501Srpaulo ok = 1; 1773214501Srpaulo break; 1774214501Srpaulo } 1775214501Srpaulo 1776214501Srpaulo if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) 1777214501Srpaulo break; 1778214501Srpaulo } 1779214501Srpaulo 1780214501Srpaulo if (!ok) { 1781214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1782214501Srpaulo "invalid MIC in msg 2/4 of 4-Way Handshake"); 1783214501Srpaulo return; 1784214501Srpaulo } 1785214501Srpaulo 1786214501Srpaulo#ifdef CONFIG_IEEE80211R 1787214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 1788214501Srpaulo /* 1789214501Srpaulo * Verify that PMKR1Name from EAPOL-Key message 2/4 matches 1790214501Srpaulo * with the value we derived. 1791214501Srpaulo */ 1792214501Srpaulo if (os_memcmp(sm->sup_pmk_r1_name, sm->pmk_r1_name, 1793214501Srpaulo WPA_PMK_NAME_LEN) != 0) { 1794214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1795214501Srpaulo "PMKR1Name mismatch in FT 4-way " 1796214501Srpaulo "handshake"); 1797214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from " 1798214501Srpaulo "Supplicant", 1799214501Srpaulo sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN); 1800214501Srpaulo wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", 1801214501Srpaulo sm->pmk_r1_name, WPA_PMK_NAME_LEN); 1802214501Srpaulo return; 1803214501Srpaulo } 1804214501Srpaulo } 1805214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1806214501Srpaulo 1807252726Srpaulo sm->pending_1_of_4_timeout = 0; 1808214501Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm); 1809214501Srpaulo 1810214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 1811214501Srpaulo /* PSK may have changed from the previous choice, so update 1812214501Srpaulo * state machine data based on whatever PSK was selected here. 1813214501Srpaulo */ 1814214501Srpaulo os_memcpy(sm->PMK, pmk, PMK_LEN); 1815214501Srpaulo } 1816214501Srpaulo 1817214501Srpaulo sm->MICVerified = TRUE; 1818214501Srpaulo 1819214501Srpaulo os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); 1820214501Srpaulo sm->PTK_valid = TRUE; 1821214501Srpaulo} 1822214501Srpaulo 1823214501Srpaulo 1824214501SrpauloSM_STATE(WPA_PTK, PTKCALCNEGOTIATING2) 1825214501Srpaulo{ 1826214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk); 1827214501Srpaulo sm->TimeoutCtr = 0; 1828214501Srpaulo} 1829214501Srpaulo 1830214501Srpaulo 1831214501Srpaulo#ifdef CONFIG_IEEE80211W 1832214501Srpaulo 1833214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 1834214501Srpaulo{ 1835214501Srpaulo if (sm->mgmt_frame_prot) { 1836214501Srpaulo return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde); 1837214501Srpaulo } 1838214501Srpaulo 1839214501Srpaulo return 0; 1840214501Srpaulo} 1841214501Srpaulo 1842214501Srpaulo 1843214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 1844214501Srpaulo{ 1845214501Srpaulo struct wpa_igtk_kde igtk; 1846214501Srpaulo struct wpa_group *gsm = sm->group; 1847214501Srpaulo 1848214501Srpaulo if (!sm->mgmt_frame_prot) 1849214501Srpaulo return pos; 1850214501Srpaulo 1851214501Srpaulo igtk.keyid[0] = gsm->GN_igtk; 1852214501Srpaulo igtk.keyid[1] = 0; 1853214501Srpaulo if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE || 1854214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, igtk.pn) < 0) 1855214501Srpaulo os_memset(igtk.pn, 0, sizeof(igtk.pn)); 1856214501Srpaulo os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN); 1857252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 1858252726Srpaulo /* 1859252726Srpaulo * Provide unique random IGTK to each STA to prevent use of 1860252726Srpaulo * IGTK in the BSS. 1861252726Srpaulo */ 1862252726Srpaulo if (random_get_bytes(igtk.igtk, WPA_IGTK_LEN) < 0) 1863252726Srpaulo return pos; 1864252726Srpaulo } 1865214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, 1866214501Srpaulo (const u8 *) &igtk, sizeof(igtk), NULL, 0); 1867214501Srpaulo 1868214501Srpaulo return pos; 1869214501Srpaulo} 1870214501Srpaulo 1871214501Srpaulo#else /* CONFIG_IEEE80211W */ 1872214501Srpaulo 1873214501Srpaulostatic int ieee80211w_kde_len(struct wpa_state_machine *sm) 1874214501Srpaulo{ 1875214501Srpaulo return 0; 1876214501Srpaulo} 1877214501Srpaulo 1878214501Srpaulo 1879214501Srpaulostatic u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos) 1880214501Srpaulo{ 1881214501Srpaulo return pos; 1882214501Srpaulo} 1883214501Srpaulo 1884214501Srpaulo#endif /* CONFIG_IEEE80211W */ 1885214501Srpaulo 1886214501Srpaulo 1887214501SrpauloSM_STATE(WPA_PTK, PTKINITNEGOTIATING) 1888214501Srpaulo{ 1889252726Srpaulo u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32]; 1890214501Srpaulo size_t gtk_len, kde_len; 1891214501Srpaulo struct wpa_group *gsm = sm->group; 1892214501Srpaulo u8 *wpa_ie; 1893214501Srpaulo int wpa_ie_len, secure, keyidx, encr = 0; 1894214501Srpaulo 1895214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); 1896214501Srpaulo sm->TimeoutEvt = FALSE; 1897214501Srpaulo 1898214501Srpaulo sm->TimeoutCtr++; 1899214501Srpaulo if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { 1900214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 1901214501Srpaulo * immediately following this. */ 1902214501Srpaulo return; 1903214501Srpaulo } 1904214501Srpaulo 1905214501Srpaulo /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE], 1906214501Srpaulo GTK[GN], IGTK, [FTIE], [TIE * 2]) 1907214501Srpaulo */ 1908214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 1909214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 1910214501Srpaulo /* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */ 1911214501Srpaulo wpa_ie = sm->wpa_auth->wpa_ie; 1912214501Srpaulo wpa_ie_len = sm->wpa_auth->wpa_ie_len; 1913214501Srpaulo if (sm->wpa == WPA_VERSION_WPA && 1914214501Srpaulo (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) && 1915214501Srpaulo wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) { 1916214501Srpaulo /* WPA-only STA, remove RSN IE */ 1917214501Srpaulo wpa_ie = wpa_ie + wpa_ie[1] + 2; 1918214501Srpaulo wpa_ie_len = wpa_ie[1] + 2; 1919214501Srpaulo } 1920214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1921214501Srpaulo "sending 3/4 msg of 4-Way Handshake"); 1922214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 1923214501Srpaulo /* WPA2 send GTK in the 4-way handshake */ 1924214501Srpaulo secure = 1; 1925214501Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 1926214501Srpaulo gtk_len = gsm->GTK_len; 1927252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 1928252726Srpaulo /* 1929252726Srpaulo * Provide unique random GTK to each STA to prevent use 1930252726Srpaulo * of GTK in the BSS. 1931252726Srpaulo */ 1932252726Srpaulo if (random_get_bytes(dummy_gtk, gtk_len) < 0) 1933252726Srpaulo return; 1934252726Srpaulo gtk = dummy_gtk; 1935252726Srpaulo } 1936214501Srpaulo keyidx = gsm->GN; 1937214501Srpaulo _rsc = rsc; 1938214501Srpaulo encr = 1; 1939214501Srpaulo } else { 1940214501Srpaulo /* WPA does not include GTK in msg 3/4 */ 1941214501Srpaulo secure = 0; 1942214501Srpaulo gtk = NULL; 1943214501Srpaulo gtk_len = 0; 1944214501Srpaulo keyidx = 0; 1945214501Srpaulo _rsc = NULL; 1946252726Srpaulo if (sm->rx_eapol_key_secure) { 1947252726Srpaulo /* 1948252726Srpaulo * It looks like Windows 7 supplicant tries to use 1949252726Srpaulo * Secure bit in msg 2/4 after having reported Michael 1950252726Srpaulo * MIC failure and it then rejects the 4-way handshake 1951252726Srpaulo * if msg 3/4 does not set Secure bit. Work around this 1952252726Srpaulo * by setting the Secure bit here even in the case of 1953252726Srpaulo * WPA if the supplicant used it first. 1954252726Srpaulo */ 1955252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 1956252726Srpaulo "STA used Secure bit in WPA msg 2/4 - " 1957252726Srpaulo "set Secure for 3/4 as workaround"); 1958252726Srpaulo secure = 1; 1959252726Srpaulo } 1960214501Srpaulo } 1961214501Srpaulo 1962214501Srpaulo kde_len = wpa_ie_len + ieee80211w_kde_len(sm); 1963214501Srpaulo if (gtk) 1964214501Srpaulo kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len; 1965214501Srpaulo#ifdef CONFIG_IEEE80211R 1966214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 1967214501Srpaulo kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */ 1968214501Srpaulo kde_len += 300; /* FTIE + 2 * TIE */ 1969214501Srpaulo } 1970214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1971214501Srpaulo kde = os_malloc(kde_len); 1972214501Srpaulo if (kde == NULL) 1973214501Srpaulo return; 1974214501Srpaulo 1975214501Srpaulo pos = kde; 1976214501Srpaulo os_memcpy(pos, wpa_ie, wpa_ie_len); 1977214501Srpaulo pos += wpa_ie_len; 1978214501Srpaulo#ifdef CONFIG_IEEE80211R 1979214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 1980214501Srpaulo int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name); 1981214501Srpaulo if (res < 0) { 1982214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert " 1983214501Srpaulo "PMKR1Name into RSN IE in EAPOL-Key data"); 1984214501Srpaulo os_free(kde); 1985214501Srpaulo return; 1986214501Srpaulo } 1987214501Srpaulo pos += res; 1988214501Srpaulo } 1989214501Srpaulo#endif /* CONFIG_IEEE80211R */ 1990214501Srpaulo if (gtk) { 1991214501Srpaulo u8 hdr[2]; 1992214501Srpaulo hdr[0] = keyidx & 0x03; 1993214501Srpaulo hdr[1] = 0; 1994214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 1995214501Srpaulo gtk, gtk_len); 1996214501Srpaulo } 1997214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 1998214501Srpaulo 1999214501Srpaulo#ifdef CONFIG_IEEE80211R 2000214501Srpaulo if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 2001214501Srpaulo int res; 2002214501Srpaulo struct wpa_auth_config *conf; 2003214501Srpaulo 2004214501Srpaulo conf = &sm->wpa_auth->conf; 2005214501Srpaulo res = wpa_write_ftie(conf, conf->r0_key_holder, 2006214501Srpaulo conf->r0_key_holder_len, 2007214501Srpaulo NULL, NULL, pos, kde + kde_len - pos, 2008214501Srpaulo NULL, 0); 2009214501Srpaulo if (res < 0) { 2010214501Srpaulo wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " 2011214501Srpaulo "into EAPOL-Key Key Data"); 2012214501Srpaulo os_free(kde); 2013214501Srpaulo return; 2014214501Srpaulo } 2015214501Srpaulo pos += res; 2016214501Srpaulo 2017214501Srpaulo /* TIE[ReassociationDeadline] (TU) */ 2018214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2019214501Srpaulo *pos++ = 5; 2020214501Srpaulo *pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE; 2021214501Srpaulo WPA_PUT_LE32(pos, conf->reassociation_deadline); 2022214501Srpaulo pos += 4; 2023214501Srpaulo 2024214501Srpaulo /* TIE[KeyLifetime] (seconds) */ 2025214501Srpaulo *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 2026214501Srpaulo *pos++ = 5; 2027214501Srpaulo *pos++ = WLAN_TIMEOUT_KEY_LIFETIME; 2028214501Srpaulo WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60); 2029214501Srpaulo pos += 4; 2030214501Srpaulo } 2031214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2032214501Srpaulo 2033214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2034214501Srpaulo (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC | 2035214501Srpaulo WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | 2036214501Srpaulo WPA_KEY_INFO_KEY_TYPE, 2037214501Srpaulo _rsc, sm->ANonce, kde, pos - kde, keyidx, encr); 2038214501Srpaulo os_free(kde); 2039214501Srpaulo} 2040214501Srpaulo 2041214501Srpaulo 2042214501SrpauloSM_STATE(WPA_PTK, PTKINITDONE) 2043214501Srpaulo{ 2044214501Srpaulo SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk); 2045214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2046214501Srpaulo if (sm->Pair) { 2047252726Srpaulo enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise); 2048252726Srpaulo int klen = wpa_cipher_key_len(sm->pairwise); 2049214501Srpaulo if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, 2050214501Srpaulo sm->PTK.tk1, klen)) { 2051214501Srpaulo wpa_sta_disconnect(sm->wpa_auth, sm->addr); 2052214501Srpaulo return; 2053214501Srpaulo } 2054214501Srpaulo /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ 2055214501Srpaulo sm->pairwise_set = TRUE; 2056214501Srpaulo 2057214501Srpaulo if (sm->wpa_auth->conf.wpa_ptk_rekey) { 2058214501Srpaulo eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm); 2059214501Srpaulo eloop_register_timeout(sm->wpa_auth->conf. 2060214501Srpaulo wpa_ptk_rekey, 0, wpa_rekey_ptk, 2061214501Srpaulo sm->wpa_auth, sm); 2062214501Srpaulo } 2063214501Srpaulo 2064214501Srpaulo if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { 2065214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2066214501Srpaulo WPA_EAPOL_authorized, 1); 2067214501Srpaulo } 2068214501Srpaulo } 2069214501Srpaulo 2070214501Srpaulo if (0 /* IBSS == TRUE */) { 2071214501Srpaulo sm->keycount++; 2072214501Srpaulo if (sm->keycount == 2) { 2073214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, 2074214501Srpaulo WPA_EAPOL_portValid, 1); 2075214501Srpaulo } 2076214501Srpaulo } else { 2077214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 2078214501Srpaulo 1); 2079214501Srpaulo } 2080214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0); 2081214501Srpaulo wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1); 2082214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2083214501Srpaulo sm->PInitAKeys = TRUE; 2084214501Srpaulo else 2085214501Srpaulo sm->has_GTK = TRUE; 2086214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2087214501Srpaulo "pairwise key handshake completed (%s)", 2088214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2089214501Srpaulo 2090214501Srpaulo#ifdef CONFIG_IEEE80211R 2091214501Srpaulo wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr); 2092214501Srpaulo#endif /* CONFIG_IEEE80211R */ 2093214501Srpaulo} 2094214501Srpaulo 2095214501Srpaulo 2096214501SrpauloSM_STEP(WPA_PTK) 2097214501Srpaulo{ 2098214501Srpaulo struct wpa_authenticator *wpa_auth = sm->wpa_auth; 2099214501Srpaulo 2100214501Srpaulo if (sm->Init) 2101214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2102214501Srpaulo else if (sm->Disconnect 2103252726Srpaulo /* || FIX: dot11RSNAConfigSALifetime timeout */) { 2104252726Srpaulo wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, 2105252726Srpaulo "WPA_PTK: sm->Disconnect"); 2106214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2107252726Srpaulo } 2108214501Srpaulo else if (sm->DeauthenticationRequest) 2109214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2110214501Srpaulo else if (sm->AuthenticationRequest) 2111214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION); 2112214501Srpaulo else if (sm->ReAuthenticationRequest) 2113214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2114214501Srpaulo else if (sm->PTKRequest) 2115214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2116214501Srpaulo else switch (sm->wpa_ptk_state) { 2117214501Srpaulo case WPA_PTK_INITIALIZE: 2118214501Srpaulo break; 2119214501Srpaulo case WPA_PTK_DISCONNECT: 2120214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECTED); 2121214501Srpaulo break; 2122214501Srpaulo case WPA_PTK_DISCONNECTED: 2123214501Srpaulo SM_ENTER(WPA_PTK, INITIALIZE); 2124214501Srpaulo break; 2125214501Srpaulo case WPA_PTK_AUTHENTICATION: 2126214501Srpaulo SM_ENTER(WPA_PTK, AUTHENTICATION2); 2127214501Srpaulo break; 2128214501Srpaulo case WPA_PTK_AUTHENTICATION2: 2129214501Srpaulo if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && 2130214501Srpaulo wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2131214501Srpaulo WPA_EAPOL_keyRun) > 0) 2132214501Srpaulo SM_ENTER(WPA_PTK, INITPMK); 2133214501Srpaulo else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) 2134214501Srpaulo /* FIX: && 802.1X::keyRun */) 2135214501Srpaulo SM_ENTER(WPA_PTK, INITPSK); 2136214501Srpaulo break; 2137214501Srpaulo case WPA_PTK_INITPMK: 2138214501Srpaulo if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr, 2139214501Srpaulo WPA_EAPOL_keyAvailable) > 0) 2140214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2141214501Srpaulo else { 2142214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2143252726Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2144252726Srpaulo "INITPMK - keyAvailable = false"); 2145214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2146214501Srpaulo } 2147214501Srpaulo break; 2148214501Srpaulo case WPA_PTK_INITPSK: 2149214501Srpaulo if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL)) 2150214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2151214501Srpaulo else { 2152214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2153214501Srpaulo "no PSK configured for the STA"); 2154214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2155214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2156214501Srpaulo } 2157214501Srpaulo break; 2158214501Srpaulo case WPA_PTK_PTKSTART: 2159214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2160214501Srpaulo sm->EAPOLKeyPairwise) 2161214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2162214501Srpaulo else if (sm->TimeoutCtr > 2163214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2164214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2165252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2166252726Srpaulo "PTKSTART: Retry limit %d reached", 2167252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2168214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2169214501Srpaulo } else if (sm->TimeoutEvt) 2170214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2171214501Srpaulo break; 2172214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING: 2173214501Srpaulo if (sm->MICVerified) 2174214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2); 2175214501Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2176214501Srpaulo sm->EAPOLKeyPairwise) 2177214501Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2178214501Srpaulo else if (sm->TimeoutEvt) 2179214501Srpaulo SM_ENTER(WPA_PTK, PTKSTART); 2180214501Srpaulo break; 2181214501Srpaulo case WPA_PTK_PTKCALCNEGOTIATING2: 2182214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2183214501Srpaulo break; 2184214501Srpaulo case WPA_PTK_PTKINITNEGOTIATING: 2185252726Srpaulo if (sm->update_snonce) 2186252726Srpaulo SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); 2187252726Srpaulo else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2188252726Srpaulo sm->EAPOLKeyPairwise && sm->MICVerified) 2189214501Srpaulo SM_ENTER(WPA_PTK, PTKINITDONE); 2190214501Srpaulo else if (sm->TimeoutCtr > 2191214501Srpaulo (int) dot11RSNAConfigPairwiseUpdateCount) { 2192214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures++; 2193252726Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2194252726Srpaulo "PTKINITNEGOTIATING: Retry limit %d " 2195252726Srpaulo "reached", 2196252726Srpaulo dot11RSNAConfigPairwiseUpdateCount); 2197214501Srpaulo SM_ENTER(WPA_PTK, DISCONNECT); 2198214501Srpaulo } else if (sm->TimeoutEvt) 2199214501Srpaulo SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); 2200214501Srpaulo break; 2201214501Srpaulo case WPA_PTK_PTKINITDONE: 2202214501Srpaulo break; 2203214501Srpaulo } 2204214501Srpaulo} 2205214501Srpaulo 2206214501Srpaulo 2207214501SrpauloSM_STATE(WPA_PTK_GROUP, IDLE) 2208214501Srpaulo{ 2209214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group); 2210214501Srpaulo if (sm->Init) { 2211214501Srpaulo /* Init flag is not cleared here, so avoid busy 2212214501Srpaulo * loop by claiming nothing changed. */ 2213214501Srpaulo sm->changed = FALSE; 2214214501Srpaulo } 2215214501Srpaulo sm->GTimeoutCtr = 0; 2216214501Srpaulo} 2217214501Srpaulo 2218214501Srpaulo 2219214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING) 2220214501Srpaulo{ 2221214501Srpaulo u8 rsc[WPA_KEY_RSC_LEN]; 2222214501Srpaulo struct wpa_group *gsm = sm->group; 2223214501Srpaulo u8 *kde, *pos, hdr[2]; 2224214501Srpaulo size_t kde_len; 2225252726Srpaulo u8 *gtk, dummy_gtk[32]; 2226214501Srpaulo 2227214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group); 2228214501Srpaulo 2229214501Srpaulo sm->GTimeoutCtr++; 2230214501Srpaulo if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) { 2231214501Srpaulo /* No point in sending the EAPOL-Key - we will disconnect 2232214501Srpaulo * immediately following this. */ 2233214501Srpaulo return; 2234214501Srpaulo } 2235214501Srpaulo 2236214501Srpaulo if (sm->wpa == WPA_VERSION_WPA) 2237214501Srpaulo sm->PInitAKeys = FALSE; 2238214501Srpaulo sm->TimeoutEvt = FALSE; 2239214501Srpaulo /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */ 2240214501Srpaulo os_memset(rsc, 0, WPA_KEY_RSC_LEN); 2241214501Srpaulo if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE) 2242214501Srpaulo wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc); 2243214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2244214501Srpaulo "sending 1/2 msg of Group Key Handshake"); 2245214501Srpaulo 2246252726Srpaulo gtk = gsm->GTK[gsm->GN - 1]; 2247252726Srpaulo if (sm->wpa_auth->conf.disable_gtk) { 2248252726Srpaulo /* 2249252726Srpaulo * Provide unique random GTK to each STA to prevent use 2250252726Srpaulo * of GTK in the BSS. 2251252726Srpaulo */ 2252252726Srpaulo if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0) 2253252726Srpaulo return; 2254252726Srpaulo gtk = dummy_gtk; 2255252726Srpaulo } 2256214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) { 2257214501Srpaulo kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len + 2258214501Srpaulo ieee80211w_kde_len(sm); 2259214501Srpaulo kde = os_malloc(kde_len); 2260214501Srpaulo if (kde == NULL) 2261214501Srpaulo return; 2262214501Srpaulo 2263214501Srpaulo pos = kde; 2264214501Srpaulo hdr[0] = gsm->GN & 0x03; 2265214501Srpaulo hdr[1] = 0; 2266214501Srpaulo pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, 2267252726Srpaulo gtk, gsm->GTK_len); 2268214501Srpaulo pos = ieee80211w_kde_add(sm, pos); 2269214501Srpaulo } else { 2270252726Srpaulo kde = gtk; 2271214501Srpaulo pos = kde + gsm->GTK_len; 2272214501Srpaulo } 2273214501Srpaulo 2274214501Srpaulo wpa_send_eapol(sm->wpa_auth, sm, 2275214501Srpaulo WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC | 2276214501Srpaulo WPA_KEY_INFO_ACK | 2277214501Srpaulo (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0), 2278214501Srpaulo rsc, gsm->GNonce, kde, pos - kde, gsm->GN, 1); 2279214501Srpaulo if (sm->wpa == WPA_VERSION_WPA2) 2280214501Srpaulo os_free(kde); 2281214501Srpaulo} 2282214501Srpaulo 2283214501Srpaulo 2284214501SrpauloSM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED) 2285214501Srpaulo{ 2286214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group); 2287214501Srpaulo sm->EAPOLKeyReceived = FALSE; 2288214501Srpaulo if (sm->GUpdateStationKeys) 2289214501Srpaulo sm->group->GKeyDoneStations--; 2290214501Srpaulo sm->GUpdateStationKeys = FALSE; 2291214501Srpaulo sm->GTimeoutCtr = 0; 2292214501Srpaulo /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */ 2293214501Srpaulo wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO, 2294214501Srpaulo "group key handshake completed (%s)", 2295214501Srpaulo sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN"); 2296214501Srpaulo sm->has_GTK = TRUE; 2297214501Srpaulo} 2298214501Srpaulo 2299214501Srpaulo 2300214501SrpauloSM_STATE(WPA_PTK_GROUP, KEYERROR) 2301214501Srpaulo{ 2302214501Srpaulo SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group); 2303214501Srpaulo if (sm->GUpdateStationKeys) 2304214501Srpaulo sm->group->GKeyDoneStations--; 2305214501Srpaulo sm->GUpdateStationKeys = FALSE; 2306214501Srpaulo sm->Disconnect = TRUE; 2307214501Srpaulo} 2308214501Srpaulo 2309214501Srpaulo 2310214501SrpauloSM_STEP(WPA_PTK_GROUP) 2311214501Srpaulo{ 2312214501Srpaulo if (sm->Init || sm->PtkGroupInit) { 2313214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2314214501Srpaulo sm->PtkGroupInit = FALSE; 2315214501Srpaulo } else switch (sm->wpa_ptk_group_state) { 2316214501Srpaulo case WPA_PTK_GROUP_IDLE: 2317214501Srpaulo if (sm->GUpdateStationKeys || 2318214501Srpaulo (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys)) 2319214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2320214501Srpaulo break; 2321214501Srpaulo case WPA_PTK_GROUP_REKEYNEGOTIATING: 2322214501Srpaulo if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest && 2323214501Srpaulo !sm->EAPOLKeyPairwise && sm->MICVerified) 2324214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED); 2325214501Srpaulo else if (sm->GTimeoutCtr > 2326214501Srpaulo (int) dot11RSNAConfigGroupUpdateCount) 2327214501Srpaulo SM_ENTER(WPA_PTK_GROUP, KEYERROR); 2328214501Srpaulo else if (sm->TimeoutEvt) 2329214501Srpaulo SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING); 2330214501Srpaulo break; 2331214501Srpaulo case WPA_PTK_GROUP_KEYERROR: 2332214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2333214501Srpaulo break; 2334214501Srpaulo case WPA_PTK_GROUP_REKEYESTABLISHED: 2335214501Srpaulo SM_ENTER(WPA_PTK_GROUP, IDLE); 2336214501Srpaulo break; 2337214501Srpaulo } 2338214501Srpaulo} 2339214501Srpaulo 2340214501Srpaulo 2341214501Srpaulostatic int wpa_gtk_update(struct wpa_authenticator *wpa_auth, 2342214501Srpaulo struct wpa_group *group) 2343214501Srpaulo{ 2344214501Srpaulo int ret = 0; 2345214501Srpaulo 2346214501Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2347214501Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2348252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "Group key expansion", 2349252726Srpaulo wpa_auth->addr, group->GNonce, 2350252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2351252726Srpaulo ret = -1; 2352252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "GTK", 2353252726Srpaulo group->GTK[group->GN - 1], group->GTK_len); 2354214501Srpaulo 2355214501Srpaulo#ifdef CONFIG_IEEE80211W 2356214501Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { 2357252726Srpaulo os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); 2358252726Srpaulo inc_byte_array(group->Counter, WPA_NONCE_LEN); 2359252726Srpaulo if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion", 2360252726Srpaulo wpa_auth->addr, group->GNonce, 2361252726Srpaulo group->IGTK[group->GN_igtk - 4], 2362252726Srpaulo WPA_IGTK_LEN) < 0) 2363214501Srpaulo ret = -1; 2364214501Srpaulo wpa_hexdump_key(MSG_DEBUG, "IGTK", 2365214501Srpaulo group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN); 2366214501Srpaulo } 2367214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2368214501Srpaulo 2369214501Srpaulo return ret; 2370214501Srpaulo} 2371214501Srpaulo 2372214501Srpaulo 2373214501Srpaulostatic void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth, 2374214501Srpaulo struct wpa_group *group) 2375214501Srpaulo{ 2376214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2377214501Srpaulo "GTK_INIT (VLAN-ID %d)", group->vlan_id); 2378214501Srpaulo group->changed = FALSE; /* GInit is not cleared here; avoid loop */ 2379214501Srpaulo group->wpa_group_state = WPA_GROUP_GTK_INIT; 2380214501Srpaulo 2381214501Srpaulo /* GTK[0..N] = 0 */ 2382214501Srpaulo os_memset(group->GTK, 0, sizeof(group->GTK)); 2383214501Srpaulo group->GN = 1; 2384214501Srpaulo group->GM = 2; 2385214501Srpaulo#ifdef CONFIG_IEEE80211W 2386214501Srpaulo group->GN_igtk = 4; 2387214501Srpaulo group->GM_igtk = 5; 2388214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2389214501Srpaulo /* GTK[GN] = CalcGTK() */ 2390214501Srpaulo wpa_gtk_update(wpa_auth, group); 2391214501Srpaulo} 2392214501Srpaulo 2393214501Srpaulo 2394214501Srpaulostatic int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx) 2395214501Srpaulo{ 2396252726Srpaulo if (ctx != NULL && ctx != sm->group) 2397252726Srpaulo return 0; 2398252726Srpaulo 2399214501Srpaulo if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) { 2400214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2401214501Srpaulo "Not in PTKINITDONE; skip Group Key update"); 2402252726Srpaulo sm->GUpdateStationKeys = FALSE; 2403214501Srpaulo return 0; 2404214501Srpaulo } 2405214501Srpaulo if (sm->GUpdateStationKeys) { 2406214501Srpaulo /* 2407252726Srpaulo * This should not really happen, so add a debug log entry. 2408252726Srpaulo * Since we clear the GKeyDoneStations before the loop, the 2409252726Srpaulo * station needs to be counted here anyway. 2410214501Srpaulo */ 2411214501Srpaulo wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, 2412252726Srpaulo "GUpdateStationKeys was already set when " 2413252726Srpaulo "marking station for GTK rekeying"); 2414214501Srpaulo } 2415252726Srpaulo 2416252726Srpaulo /* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */ 2417252726Srpaulo if (sm->is_wnmsleep) 2418252726Srpaulo return 0; 2419252726Srpaulo 2420252726Srpaulo sm->group->GKeyDoneStations++; 2421252726Srpaulo sm->GUpdateStationKeys = TRUE; 2422252726Srpaulo 2423214501Srpaulo wpa_sm_step(sm); 2424214501Srpaulo return 0; 2425214501Srpaulo} 2426214501Srpaulo 2427214501Srpaulo 2428252726Srpaulo#ifdef CONFIG_WNM 2429252726Srpaulo/* update GTK when exiting WNM-Sleep Mode */ 2430252726Srpaulovoid wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm) 2431252726Srpaulo{ 2432252726Srpaulo if (sm->is_wnmsleep) 2433252726Srpaulo return; 2434252726Srpaulo 2435252726Srpaulo wpa_group_update_sta(sm, NULL); 2436252726Srpaulo} 2437252726Srpaulo 2438252726Srpaulo 2439252726Srpaulovoid wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag) 2440252726Srpaulo{ 2441252726Srpaulo sm->is_wnmsleep = !!flag; 2442252726Srpaulo} 2443252726Srpaulo 2444252726Srpaulo 2445252726Srpauloint wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2446252726Srpaulo{ 2447252726Srpaulo struct wpa_group *gsm = sm->group; 2448252726Srpaulo u8 *start = pos; 2449252726Srpaulo 2450252726Srpaulo /* 2451252726Srpaulo * GTK subelement: 2452252726Srpaulo * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] | 2453252726Srpaulo * Key[5..32] 2454252726Srpaulo */ 2455252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_GTK; 2456252726Srpaulo *pos++ = 11 + gsm->GTK_len; 2457252726Srpaulo /* Key ID in B0-B1 of Key Info */ 2458252726Srpaulo WPA_PUT_LE16(pos, gsm->GN & 0x03); 2459252726Srpaulo pos += 2; 2460252726Srpaulo *pos++ = gsm->GTK_len; 2461252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0) 2462252726Srpaulo return 0; 2463252726Srpaulo pos += 8; 2464252726Srpaulo os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2465252726Srpaulo pos += gsm->GTK_len; 2466252726Srpaulo 2467252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit", 2468252726Srpaulo gsm->GN); 2469252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit", 2470252726Srpaulo gsm->GTK[gsm->GN - 1], gsm->GTK_len); 2471252726Srpaulo 2472252726Srpaulo return pos - start; 2473252726Srpaulo} 2474252726Srpaulo 2475252726Srpaulo 2476252726Srpaulo#ifdef CONFIG_IEEE80211W 2477252726Srpauloint wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos) 2478252726Srpaulo{ 2479252726Srpaulo struct wpa_group *gsm = sm->group; 2480252726Srpaulo u8 *start = pos; 2481252726Srpaulo 2482252726Srpaulo /* 2483252726Srpaulo * IGTK subelement: 2484252726Srpaulo * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16] 2485252726Srpaulo */ 2486252726Srpaulo *pos++ = WNM_SLEEP_SUBELEM_IGTK; 2487252726Srpaulo *pos++ = 2 + 6 + WPA_IGTK_LEN; 2488252726Srpaulo WPA_PUT_LE16(pos, gsm->GN_igtk); 2489252726Srpaulo pos += 2; 2490252726Srpaulo if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0) 2491252726Srpaulo return 0; 2492252726Srpaulo pos += 6; 2493252726Srpaulo 2494252726Srpaulo os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN); 2495252726Srpaulo pos += WPA_IGTK_LEN; 2496252726Srpaulo 2497252726Srpaulo wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit", 2498252726Srpaulo gsm->GN_igtk); 2499252726Srpaulo wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit", 2500252726Srpaulo gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN); 2501252726Srpaulo 2502252726Srpaulo return pos - start; 2503252726Srpaulo} 2504252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2505252726Srpaulo#endif /* CONFIG_WNM */ 2506252726Srpaulo 2507252726Srpaulo 2508214501Srpaulostatic void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, 2509214501Srpaulo struct wpa_group *group) 2510214501Srpaulo{ 2511214501Srpaulo int tmp; 2512214501Srpaulo 2513214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2514214501Srpaulo "SETKEYS (VLAN-ID %d)", group->vlan_id); 2515214501Srpaulo group->changed = TRUE; 2516214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYS; 2517214501Srpaulo group->GTKReKey = FALSE; 2518214501Srpaulo tmp = group->GM; 2519214501Srpaulo group->GM = group->GN; 2520214501Srpaulo group->GN = tmp; 2521214501Srpaulo#ifdef CONFIG_IEEE80211W 2522214501Srpaulo tmp = group->GM_igtk; 2523214501Srpaulo group->GM_igtk = group->GN_igtk; 2524214501Srpaulo group->GN_igtk = tmp; 2525214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2526214501Srpaulo /* "GKeyDoneStations = GNoStations" is done in more robust way by 2527214501Srpaulo * counting the STAs that are marked with GUpdateStationKeys instead of 2528214501Srpaulo * including all STAs that could be in not-yet-completed state. */ 2529214501Srpaulo wpa_gtk_update(wpa_auth, group); 2530214501Srpaulo 2531252726Srpaulo if (group->GKeyDoneStations) { 2532252726Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected " 2533252726Srpaulo "GKeyDoneStations=%d when starting new GTK rekey", 2534252726Srpaulo group->GKeyDoneStations); 2535252726Srpaulo group->GKeyDoneStations = 0; 2536252726Srpaulo } 2537252726Srpaulo wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, group); 2538214501Srpaulo wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d", 2539214501Srpaulo group->GKeyDoneStations); 2540214501Srpaulo} 2541214501Srpaulo 2542214501Srpaulo 2543252726Srpaulostatic int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, 2544252726Srpaulo struct wpa_group *group) 2545214501Srpaulo{ 2546252726Srpaulo int ret = 0; 2547252726Srpaulo 2548252726Srpaulo if (wpa_auth_set_key(wpa_auth, group->vlan_id, 2549252726Srpaulo wpa_cipher_to_alg(wpa_auth->conf.wpa_group), 2550252726Srpaulo broadcast_ether_addr, group->GN, 2551252726Srpaulo group->GTK[group->GN - 1], group->GTK_len) < 0) 2552252726Srpaulo ret = -1; 2553252726Srpaulo 2554252726Srpaulo#ifdef CONFIG_IEEE80211W 2555252726Srpaulo if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION && 2556252726Srpaulo wpa_auth_set_key(wpa_auth, group->vlan_id, WPA_ALG_IGTK, 2557252726Srpaulo broadcast_ether_addr, group->GN_igtk, 2558252726Srpaulo group->IGTK[group->GN_igtk - 4], 2559252726Srpaulo WPA_IGTK_LEN) < 0) 2560252726Srpaulo ret = -1; 2561252726Srpaulo#endif /* CONFIG_IEEE80211W */ 2562252726Srpaulo 2563252726Srpaulo return ret; 2564252726Srpaulo} 2565252726Srpaulo 2566252726Srpaulo 2567252726Srpaulostatic int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth, 2568252726Srpaulo struct wpa_group *group) 2569252726Srpaulo{ 2570214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " 2571214501Srpaulo "SETKEYSDONE (VLAN-ID %d)", group->vlan_id); 2572214501Srpaulo group->changed = TRUE; 2573214501Srpaulo group->wpa_group_state = WPA_GROUP_SETKEYSDONE; 2574214501Srpaulo 2575252726Srpaulo if (wpa_group_config_group_keys(wpa_auth, group) < 0) 2576252726Srpaulo return -1; 2577252726Srpaulo 2578252726Srpaulo return 0; 2579214501Srpaulo} 2580214501Srpaulo 2581214501Srpaulo 2582214501Srpaulostatic void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, 2583214501Srpaulo struct wpa_group *group) 2584214501Srpaulo{ 2585214501Srpaulo if (group->GInit) { 2586214501Srpaulo wpa_group_gtk_init(wpa_auth, group); 2587214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT && 2588214501Srpaulo group->GTKAuthenticator) { 2589214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2590214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE && 2591214501Srpaulo group->GTKReKey) { 2592214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2593214501Srpaulo } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) { 2594214501Srpaulo if (group->GKeyDoneStations == 0) 2595214501Srpaulo wpa_group_setkeysdone(wpa_auth, group); 2596214501Srpaulo else if (group->GTKReKey) 2597214501Srpaulo wpa_group_setkeys(wpa_auth, group); 2598214501Srpaulo } 2599214501Srpaulo} 2600214501Srpaulo 2601214501Srpaulo 2602214501Srpaulostatic int wpa_sm_step(struct wpa_state_machine *sm) 2603214501Srpaulo{ 2604214501Srpaulo if (sm == NULL) 2605214501Srpaulo return 0; 2606214501Srpaulo 2607214501Srpaulo if (sm->in_step_loop) { 2608214501Srpaulo /* This should not happen, but if it does, make sure we do not 2609214501Srpaulo * end up freeing the state machine too early by exiting the 2610214501Srpaulo * recursive call. */ 2611214501Srpaulo wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively"); 2612214501Srpaulo return 0; 2613214501Srpaulo } 2614214501Srpaulo 2615214501Srpaulo sm->in_step_loop = 1; 2616214501Srpaulo do { 2617214501Srpaulo if (sm->pending_deinit) 2618214501Srpaulo break; 2619214501Srpaulo 2620214501Srpaulo sm->changed = FALSE; 2621214501Srpaulo sm->wpa_auth->group->changed = FALSE; 2622214501Srpaulo 2623214501Srpaulo SM_STEP_RUN(WPA_PTK); 2624214501Srpaulo if (sm->pending_deinit) 2625214501Srpaulo break; 2626214501Srpaulo SM_STEP_RUN(WPA_PTK_GROUP); 2627214501Srpaulo if (sm->pending_deinit) 2628214501Srpaulo break; 2629214501Srpaulo wpa_group_sm_step(sm->wpa_auth, sm->group); 2630214501Srpaulo } while (sm->changed || sm->wpa_auth->group->changed); 2631214501Srpaulo sm->in_step_loop = 0; 2632214501Srpaulo 2633214501Srpaulo if (sm->pending_deinit) { 2634214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state " 2635214501Srpaulo "machine deinit for " MACSTR, MAC2STR(sm->addr)); 2636214501Srpaulo wpa_free_sta_sm(sm); 2637214501Srpaulo return 1; 2638214501Srpaulo } 2639214501Srpaulo return 0; 2640214501Srpaulo} 2641214501Srpaulo 2642214501Srpaulo 2643214501Srpaulostatic void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx) 2644214501Srpaulo{ 2645214501Srpaulo struct wpa_state_machine *sm = eloop_ctx; 2646214501Srpaulo wpa_sm_step(sm); 2647214501Srpaulo} 2648214501Srpaulo 2649214501Srpaulo 2650214501Srpaulovoid wpa_auth_sm_notify(struct wpa_state_machine *sm) 2651214501Srpaulo{ 2652214501Srpaulo if (sm == NULL) 2653214501Srpaulo return; 2654214501Srpaulo eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL); 2655214501Srpaulo} 2656214501Srpaulo 2657214501Srpaulo 2658214501Srpaulovoid wpa_gtk_rekey(struct wpa_authenticator *wpa_auth) 2659214501Srpaulo{ 2660214501Srpaulo int tmp, i; 2661214501Srpaulo struct wpa_group *group; 2662214501Srpaulo 2663214501Srpaulo if (wpa_auth == NULL) 2664214501Srpaulo return; 2665214501Srpaulo 2666214501Srpaulo group = wpa_auth->group; 2667214501Srpaulo 2668214501Srpaulo for (i = 0; i < 2; i++) { 2669214501Srpaulo tmp = group->GM; 2670214501Srpaulo group->GM = group->GN; 2671214501Srpaulo group->GN = tmp; 2672214501Srpaulo#ifdef CONFIG_IEEE80211W 2673214501Srpaulo tmp = group->GM_igtk; 2674214501Srpaulo group->GM_igtk = group->GN_igtk; 2675214501Srpaulo group->GN_igtk = tmp; 2676214501Srpaulo#endif /* CONFIG_IEEE80211W */ 2677214501Srpaulo wpa_gtk_update(wpa_auth, group); 2678252726Srpaulo wpa_group_config_group_keys(wpa_auth, group); 2679214501Srpaulo } 2680214501Srpaulo} 2681214501Srpaulo 2682214501Srpaulo 2683214501Srpaulostatic const char * wpa_bool_txt(int bool) 2684214501Srpaulo{ 2685214501Srpaulo return bool ? "TRUE" : "FALSE"; 2686214501Srpaulo} 2687214501Srpaulo 2688214501Srpaulo 2689214501Srpaulo#define RSN_SUITE "%02x-%02x-%02x-%d" 2690214501Srpaulo#define RSN_SUITE_ARG(s) \ 2691214501Srpaulo((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff 2692214501Srpaulo 2693214501Srpauloint wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen) 2694214501Srpaulo{ 2695214501Srpaulo int len = 0, ret; 2696214501Srpaulo char pmkid_txt[PMKID_LEN * 2 + 1]; 2697252726Srpaulo#ifdef CONFIG_RSN_PREAUTH 2698252726Srpaulo const int preauth = 1; 2699252726Srpaulo#else /* CONFIG_RSN_PREAUTH */ 2700252726Srpaulo const int preauth = 0; 2701252726Srpaulo#endif /* CONFIG_RSN_PREAUTH */ 2702214501Srpaulo 2703214501Srpaulo if (wpa_auth == NULL) 2704214501Srpaulo return len; 2705214501Srpaulo 2706214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 2707214501Srpaulo "dot11RSNAOptionImplemented=TRUE\n" 2708252726Srpaulo "dot11RSNAPreauthenticationImplemented=%s\n" 2709214501Srpaulo "dot11RSNAEnabled=%s\n" 2710214501Srpaulo "dot11RSNAPreauthenticationEnabled=%s\n", 2711252726Srpaulo wpa_bool_txt(preauth), 2712214501Srpaulo wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN), 2713214501Srpaulo wpa_bool_txt(wpa_auth->conf.rsn_preauth)); 2714214501Srpaulo if (ret < 0 || (size_t) ret >= buflen - len) 2715214501Srpaulo return len; 2716214501Srpaulo len += ret; 2717214501Srpaulo 2718214501Srpaulo wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), 2719214501Srpaulo wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN); 2720214501Srpaulo 2721214501Srpaulo ret = os_snprintf( 2722214501Srpaulo buf + len, buflen - len, 2723214501Srpaulo "dot11RSNAConfigVersion=%u\n" 2724214501Srpaulo "dot11RSNAConfigPairwiseKeysSupported=9999\n" 2725214501Srpaulo /* FIX: dot11RSNAConfigGroupCipher */ 2726214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyMethod */ 2727214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyTime */ 2728214501Srpaulo /* FIX: dot11RSNAConfigGroupRekeyPackets */ 2729214501Srpaulo "dot11RSNAConfigGroupRekeyStrict=%u\n" 2730214501Srpaulo "dot11RSNAConfigGroupUpdateCount=%u\n" 2731214501Srpaulo "dot11RSNAConfigPairwiseUpdateCount=%u\n" 2732214501Srpaulo "dot11RSNAConfigGroupCipherSize=%u\n" 2733214501Srpaulo "dot11RSNAConfigPMKLifetime=%u\n" 2734214501Srpaulo "dot11RSNAConfigPMKReauthThreshold=%u\n" 2735214501Srpaulo "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n" 2736214501Srpaulo "dot11RSNAConfigSATimeout=%u\n" 2737214501Srpaulo "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" 2738214501Srpaulo "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" 2739214501Srpaulo "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" 2740214501Srpaulo "dot11RSNAPMKIDUsed=%s\n" 2741214501Srpaulo "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" 2742214501Srpaulo "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" 2743214501Srpaulo "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" 2744214501Srpaulo "dot11RSNATKIPCounterMeasuresInvoked=%u\n" 2745214501Srpaulo "dot11RSNA4WayHandshakeFailures=%u\n" 2746214501Srpaulo "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n", 2747214501Srpaulo RSN_VERSION, 2748214501Srpaulo !!wpa_auth->conf.wpa_strict_rekey, 2749214501Srpaulo dot11RSNAConfigGroupUpdateCount, 2750214501Srpaulo dot11RSNAConfigPairwiseUpdateCount, 2751252726Srpaulo wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8, 2752214501Srpaulo dot11RSNAConfigPMKLifetime, 2753214501Srpaulo dot11RSNAConfigPMKReauthThreshold, 2754214501Srpaulo dot11RSNAConfigSATimeout, 2755214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected), 2756214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected), 2757214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected), 2758214501Srpaulo pmkid_txt, 2759214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested), 2760214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested), 2761214501Srpaulo RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested), 2762214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked, 2763214501Srpaulo wpa_auth->dot11RSNA4WayHandshakeFailures); 2764214501Srpaulo if (ret < 0 || (size_t) ret >= buflen - len) 2765214501Srpaulo return len; 2766214501Srpaulo len += ret; 2767214501Srpaulo 2768214501Srpaulo /* TODO: dot11RSNAConfigPairwiseCiphersTable */ 2769214501Srpaulo /* TODO: dot11RSNAConfigAuthenticationSuitesTable */ 2770214501Srpaulo 2771214501Srpaulo /* Private MIB */ 2772214501Srpaulo ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n", 2773214501Srpaulo wpa_auth->group->wpa_group_state); 2774214501Srpaulo if (ret < 0 || (size_t) ret >= buflen - len) 2775214501Srpaulo return len; 2776214501Srpaulo len += ret; 2777214501Srpaulo 2778214501Srpaulo return len; 2779214501Srpaulo} 2780214501Srpaulo 2781214501Srpaulo 2782214501Srpauloint wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) 2783214501Srpaulo{ 2784214501Srpaulo int len = 0, ret; 2785214501Srpaulo u32 pairwise = 0; 2786214501Srpaulo 2787214501Srpaulo if (sm == NULL) 2788214501Srpaulo return 0; 2789214501Srpaulo 2790214501Srpaulo /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */ 2791214501Srpaulo 2792214501Srpaulo /* dot11RSNAStatsEntry */ 2793214501Srpaulo 2794252726Srpaulo pairwise = wpa_cipher_to_suite(sm->wpa == WPA_VERSION_WPA2 ? 2795252726Srpaulo WPA_PROTO_RSN : WPA_PROTO_WPA, 2796252726Srpaulo sm->pairwise); 2797252726Srpaulo if (pairwise == 0) 2798214501Srpaulo return 0; 2799214501Srpaulo 2800214501Srpaulo ret = os_snprintf( 2801214501Srpaulo buf + len, buflen - len, 2802214501Srpaulo /* TODO: dot11RSNAStatsIndex */ 2803214501Srpaulo "dot11RSNAStatsSTAAddress=" MACSTR "\n" 2804214501Srpaulo "dot11RSNAStatsVersion=1\n" 2805214501Srpaulo "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n" 2806214501Srpaulo /* TODO: dot11RSNAStatsTKIPICVErrors */ 2807214501Srpaulo "dot11RSNAStatsTKIPLocalMICFailures=%u\n" 2808252726Srpaulo "dot11RSNAStatsTKIPRemoteMICFailures=%u\n" 2809214501Srpaulo /* TODO: dot11RSNAStatsCCMPReplays */ 2810214501Srpaulo /* TODO: dot11RSNAStatsCCMPDecryptErrors */ 2811214501Srpaulo /* TODO: dot11RSNAStatsTKIPReplays */, 2812214501Srpaulo MAC2STR(sm->addr), 2813214501Srpaulo RSN_SUITE_ARG(pairwise), 2814214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures, 2815214501Srpaulo sm->dot11RSNAStatsTKIPRemoteMICFailures); 2816214501Srpaulo if (ret < 0 || (size_t) ret >= buflen - len) 2817214501Srpaulo return len; 2818214501Srpaulo len += ret; 2819214501Srpaulo 2820214501Srpaulo /* Private MIB */ 2821214501Srpaulo ret = os_snprintf(buf + len, buflen - len, 2822214501Srpaulo "hostapdWPAPTKState=%d\n" 2823214501Srpaulo "hostapdWPAPTKGroupState=%d\n", 2824214501Srpaulo sm->wpa_ptk_state, 2825214501Srpaulo sm->wpa_ptk_group_state); 2826214501Srpaulo if (ret < 0 || (size_t) ret >= buflen - len) 2827214501Srpaulo return len; 2828214501Srpaulo len += ret; 2829214501Srpaulo 2830214501Srpaulo return len; 2831214501Srpaulo} 2832214501Srpaulo 2833214501Srpaulo 2834214501Srpaulovoid wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) 2835214501Srpaulo{ 2836214501Srpaulo if (wpa_auth) 2837214501Srpaulo wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++; 2838214501Srpaulo} 2839214501Srpaulo 2840214501Srpaulo 2841214501Srpauloint wpa_auth_pairwise_set(struct wpa_state_machine *sm) 2842214501Srpaulo{ 2843214501Srpaulo return sm && sm->pairwise_set; 2844214501Srpaulo} 2845214501Srpaulo 2846214501Srpaulo 2847214501Srpauloint wpa_auth_get_pairwise(struct wpa_state_machine *sm) 2848214501Srpaulo{ 2849214501Srpaulo return sm->pairwise; 2850214501Srpaulo} 2851214501Srpaulo 2852214501Srpaulo 2853214501Srpauloint wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm) 2854214501Srpaulo{ 2855214501Srpaulo if (sm == NULL) 2856214501Srpaulo return -1; 2857214501Srpaulo return sm->wpa_key_mgmt; 2858214501Srpaulo} 2859214501Srpaulo 2860214501Srpaulo 2861214501Srpauloint wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) 2862214501Srpaulo{ 2863214501Srpaulo if (sm == NULL) 2864214501Srpaulo return 0; 2865214501Srpaulo return sm->wpa; 2866214501Srpaulo} 2867214501Srpaulo 2868214501Srpaulo 2869214501Srpauloint wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, 2870214501Srpaulo struct rsn_pmksa_cache_entry *entry) 2871214501Srpaulo{ 2872214501Srpaulo if (sm == NULL || sm->pmksa != entry) 2873214501Srpaulo return -1; 2874214501Srpaulo sm->pmksa = NULL; 2875214501Srpaulo return 0; 2876214501Srpaulo} 2877214501Srpaulo 2878214501Srpaulo 2879214501Srpaulostruct rsn_pmksa_cache_entry * 2880214501Srpaulowpa_auth_sta_get_pmksa(struct wpa_state_machine *sm) 2881214501Srpaulo{ 2882214501Srpaulo return sm ? sm->pmksa : NULL; 2883214501Srpaulo} 2884214501Srpaulo 2885214501Srpaulo 2886214501Srpaulovoid wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm) 2887214501Srpaulo{ 2888214501Srpaulo if (sm) 2889214501Srpaulo sm->dot11RSNAStatsTKIPLocalMICFailures++; 2890214501Srpaulo} 2891214501Srpaulo 2892214501Srpaulo 2893214501Srpauloconst u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len) 2894214501Srpaulo{ 2895214501Srpaulo if (wpa_auth == NULL) 2896214501Srpaulo return NULL; 2897214501Srpaulo *len = wpa_auth->wpa_ie_len; 2898214501Srpaulo return wpa_auth->wpa_ie; 2899214501Srpaulo} 2900214501Srpaulo 2901214501Srpaulo 2902214501Srpauloint wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, 2903214501Srpaulo int session_timeout, struct eapol_state_machine *eapol) 2904214501Srpaulo{ 2905252726Srpaulo if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 || 2906252726Srpaulo sm->wpa_auth->conf.disable_pmksa_caching) 2907214501Srpaulo return -1; 2908214501Srpaulo 2909214501Srpaulo if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, 2910214501Srpaulo sm->wpa_auth->addr, sm->addr, session_timeout, 2911214501Srpaulo eapol, sm->wpa_key_mgmt)) 2912214501Srpaulo return 0; 2913214501Srpaulo 2914214501Srpaulo return -1; 2915214501Srpaulo} 2916214501Srpaulo 2917214501Srpaulo 2918214501Srpauloint wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, 2919214501Srpaulo const u8 *pmk, size_t len, const u8 *sta_addr, 2920214501Srpaulo int session_timeout, 2921214501Srpaulo struct eapol_state_machine *eapol) 2922214501Srpaulo{ 2923214501Srpaulo if (wpa_auth == NULL) 2924214501Srpaulo return -1; 2925214501Srpaulo 2926214501Srpaulo if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr, 2927214501Srpaulo sta_addr, session_timeout, eapol, 2928214501Srpaulo WPA_KEY_MGMT_IEEE8021X)) 2929214501Srpaulo return 0; 2930214501Srpaulo 2931214501Srpaulo return -1; 2932214501Srpaulo} 2933214501Srpaulo 2934214501Srpaulo 2935214501Srpaulostatic struct wpa_group * 2936214501Srpaulowpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) 2937214501Srpaulo{ 2938214501Srpaulo struct wpa_group *group; 2939214501Srpaulo 2940214501Srpaulo if (wpa_auth == NULL || wpa_auth->group == NULL) 2941214501Srpaulo return NULL; 2942214501Srpaulo 2943214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d", 2944214501Srpaulo vlan_id); 2945252726Srpaulo group = wpa_group_init(wpa_auth, vlan_id, 0); 2946214501Srpaulo if (group == NULL) 2947214501Srpaulo return NULL; 2948214501Srpaulo 2949214501Srpaulo group->next = wpa_auth->group->next; 2950214501Srpaulo wpa_auth->group->next = group; 2951214501Srpaulo 2952214501Srpaulo return group; 2953214501Srpaulo} 2954214501Srpaulo 2955214501Srpaulo 2956214501Srpauloint wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id) 2957214501Srpaulo{ 2958214501Srpaulo struct wpa_group *group; 2959214501Srpaulo 2960214501Srpaulo if (sm == NULL || sm->wpa_auth == NULL) 2961214501Srpaulo return 0; 2962214501Srpaulo 2963214501Srpaulo group = sm->wpa_auth->group; 2964214501Srpaulo while (group) { 2965214501Srpaulo if (group->vlan_id == vlan_id) 2966214501Srpaulo break; 2967214501Srpaulo group = group->next; 2968214501Srpaulo } 2969214501Srpaulo 2970214501Srpaulo if (group == NULL) { 2971214501Srpaulo group = wpa_auth_add_group(sm->wpa_auth, vlan_id); 2972214501Srpaulo if (group == NULL) 2973214501Srpaulo return -1; 2974214501Srpaulo } 2975214501Srpaulo 2976214501Srpaulo if (sm->group == group) 2977214501Srpaulo return 0; 2978214501Srpaulo 2979214501Srpaulo wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state " 2980214501Srpaulo "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id); 2981214501Srpaulo 2982214501Srpaulo sm->group = group; 2983214501Srpaulo return 0; 2984214501Srpaulo} 2985252726Srpaulo 2986252726Srpaulo 2987252726Srpaulovoid wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, 2988252726Srpaulo struct wpa_state_machine *sm, int ack) 2989252726Srpaulo{ 2990252726Srpaulo if (wpa_auth == NULL || sm == NULL) 2991252726Srpaulo return; 2992252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR 2993252726Srpaulo " ack=%d", MAC2STR(sm->addr), ack); 2994252726Srpaulo if (sm->pending_1_of_4_timeout && ack) { 2995252726Srpaulo /* 2996252726Srpaulo * Some deployed supplicant implementations update their SNonce 2997252726Srpaulo * for each EAPOL-Key 2/4 message even within the same 4-way 2998252726Srpaulo * handshake and then fail to use the first SNonce when 2999252726Srpaulo * deriving the PTK. This results in unsuccessful 4-way 3000252726Srpaulo * handshake whenever the relatively short initial timeout is 3001252726Srpaulo * reached and EAPOL-Key 1/4 is retransmitted. Try to work 3002252726Srpaulo * around this by increasing the timeout now that we know that 3003252726Srpaulo * the station has received the frame. 3004252726Srpaulo */ 3005252726Srpaulo int timeout_ms = eapol_key_timeout_subseq; 3006252726Srpaulo wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 " 3007252726Srpaulo "timeout by %u ms because of acknowledged frame", 3008252726Srpaulo timeout_ms); 3009252726Srpaulo eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); 3010252726Srpaulo eloop_register_timeout(timeout_ms / 1000, 3011252726Srpaulo (timeout_ms % 1000) * 1000, 3012252726Srpaulo wpa_send_eapol_timeout, wpa_auth, sm); 3013252726Srpaulo } 3014252726Srpaulo} 3015252726Srpaulo 3016252726Srpaulo 3017252726Srpauloint wpa_auth_uses_sae(struct wpa_state_machine *sm) 3018252726Srpaulo{ 3019252726Srpaulo if (sm == NULL) 3020252726Srpaulo return 0; 3021252726Srpaulo return wpa_key_mgmt_sae(sm->wpa_key_mgmt); 3022252726Srpaulo} 3023