diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ec3f7f8522..7f6aa72b18 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ec3f7f8522f875a5461aecf913123892b70232de +Subproject commit 7f6aa72b18c5451e95c08f81283dac5ac69044f8 diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 1bb30d6b22..7f28cd2ef4 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -1367,6 +1367,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) } +static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) +{ + if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { + wpa_printf(MSG_ERROR, + "WPA: Failed to get random data for ANonce"); + sm->Disconnect = TRUE; + return -1; + } + wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, + WPA_NONCE_LEN); + sm->TimeoutCtr = 0; + return 0; +} + + SM_STATE(WPA_PTK, INITPMK) { u8 msk[2 * PMK_LEN]; @@ -1846,9 +1861,12 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, AUTHENTICATION); else if (sm->ReAuthenticationRequest) SM_ENTER(WPA_PTK, AUTHENTICATION2); - else if (sm->PTKRequest) - SM_ENTER(WPA_PTK, PTKSTART); - else switch (sm->wpa_ptk_state) { + else if (sm->PTKRequest) { + if (wpa_auth_sm_ptk_update(sm) < 0) + SM_ENTER(WPA_PTK, DISCONNECTED); + else + SM_ENTER(WPA_PTK, PTKSTART); + } else switch (sm->wpa_ptk_state) { case WPA_PTK_INITIALIZE: break; case WPA_PTK_DISCONNECT: diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 821cb36494..0ffda0d8aa 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -625,6 +625,14 @@ int wpa_cipher_to_alg(int cipher) return WIFI_WPA_ALG_NONE; } +int wpa_cipher_valid_pairwise(int cipher) +{ + return cipher == WPA_CIPHER_GCMP_256 || + cipher == WPA_CIPHER_CCMP || + cipher == WPA_CIPHER_GCMP || + cipher == WPA_CIPHER_TKIP; +} + u32 wpa_cipher_to_suite(int proto, int cipher) { if (cipher & WPA_CIPHER_CCMP) diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 46ffecf015..4d67fe46a4 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -178,8 +178,21 @@ struct wpa_ptk { u8 rx_mic_key[8]; } auth; } u; + int installed; /* 1 if key has already been installed to driver */ } STRUCT_PACKED; +struct wpa_gtk { + u8 gtk[WPA_GTK_MAX_LEN]; + size_t gtk_len; +}; + +#ifdef CONFIG_IEEE80211W +struct wpa_igtk { + u8 igtk[WPA_IGTK_MAX_LEN]; + size_t igtk_len; +}; +#endif /* CONFIG_IEEE80211W */ + struct wpa_gtk_data { enum wpa_alg alg; int tx, key_rsc_len, keyidx; @@ -326,10 +339,14 @@ int wpa_cipher_key_len(int cipher); int wpa_cipher_to_alg(int cipher); +int wpa_cipher_valid_pairwise(int cipher); + u32 wpa_cipher_to_suite(int proto, int cipher); int wpa_cipher_put_suites(u8 *pos, int ciphers); +int wpa_cipher_valid_mgmt_group(int cipher); + int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_common.c b/components/wpa_supplicant/src/esp_supplicant/esp_common.c index 0ea50a1bfa..98c584b783 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_common.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_common.c @@ -19,6 +19,8 @@ #include "common/ieee802_11_common.h" #include "esp_rrm.h" #include "esp_wnm.h" +#include "rsn_supp/wpa.h" + struct wpa_supplicant g_wpa_supp; @@ -226,24 +228,42 @@ static void supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_bas } } +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel, u64 current_tsf) { - if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) { - return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); - } else if (type == WLAN_FC_STYPE_ACTION) { - return handle_action_frm(frame, len, sender, rssi, channel); + int ret = 0; + + switch (type) { +#if defined(CONFIG_WPA_11KV_SUPPORT) + case WLAN_FC_STYPE_BEACON: + case WLAN_FC_STYPE_PROBE_RESP: + ret = esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); + break; +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ + case WLAN_FC_STYPE_ASSOC_RESP: + case WLAN_FC_STYPE_REASSOC_RESP: + wpa_sm_notify_assoc(&gWpaSm, sender); + break; +#if defined(CONFIG_WPA_11KV_SUPPORT) + case WLAN_FC_STYPE_ACTION: + ret = handle_action_frm(frame, len, sender, rssi, channel); + break; +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ + default: + ret = -1; + break; } - return -1; + return ret; } - int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) { struct wpa_supplicant *wpa_s = &g_wpa_supp; int ret; +#if defined(CONFIG_WPA_11KV_SUPPORT) s_supplicant_api_lock = xSemaphoreCreateRecursiveMutex(); if (!s_supplicant_api_lock) { wpa_printf(MSG_ERROR, "%s: failed to create Supplicant API lock", __func__); @@ -274,9 +294,14 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &supplicant_sta_disconn_handler, NULL); +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ wpa_s->type = 0; wpa_s->subtype = 0; - esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); + wpa_s->type |= (1 << WLAN_FC_STYPE_ASSOC_RESP) | (1 << WLAN_FC_STYPE_REASSOC_RESP) | (1 << WLAN_FC_STYPE_AUTH); + if (esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype) != ESP_OK) { + ret = -1; + goto err; + } wpa_cb->wpa_sta_rx_mgmt = ieee80211_handle_rx_frm; return 0; err: @@ -288,6 +313,7 @@ void esp_supplicant_common_deinit(void) { struct wpa_supplicant *wpa_s = &g_wpa_supp; +#if defined(CONFIG_WPA_11KV_SUPPORT) esp_scan_deinit(wpa_s); wpas_rrm_reset(wpa_s); wpas_clear_beacon_rep_data(wpa_s); @@ -295,10 +321,12 @@ void esp_supplicant_common_deinit(void) &supplicant_sta_conn_handler); esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &supplicant_sta_disconn_handler); +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ if (wpa_s->type) { wpa_s->type = 0; esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); } +#if defined(CONFIG_WPA_11KV_SUPPORT) if (!s_supplicant_task_hdl && esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) { if (s_supplicant_evt_queue) { vQueueDelete(s_supplicant_evt_queue); @@ -310,8 +338,10 @@ void esp_supplicant_common_deinit(void) } wpa_printf(MSG_ERROR, "failed to send task delete event"); } +#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */ } +#if defined(CONFIG_WPA_11KV_SUPPORT) bool esp_rrm_is_rrm_supported_connection(void) { struct wpa_supplicant *wpa_s = &g_wpa_supp; diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h b/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h index 94a0db559f..6c644835e4 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_common_i.h @@ -39,8 +39,6 @@ enum SIG_SUPPLICANT { int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data); void esp_set_rm_enabled_ie(void); void esp_get_tx_power(uint8_t *tx_power); -int esp_supplicant_common_init(struct wpa_funcs *wpa_cb); -void esp_supplicant_common_deinit(void); #else #include "esp_rrm.h" @@ -49,5 +47,7 @@ void esp_supplicant_common_deinit(void); static inline void esp_set_rm_enabled_ie(void) {} #endif +int esp_supplicant_common_init(struct wpa_funcs *wpa_cb); +void esp_supplicant_common_deinit(void); void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool add_mdie); #endif diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h index 8c5b46487d..de9a34ec95 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h @@ -182,11 +182,11 @@ typedef struct { uint32_t arg_size; } wifi_ipc_config_t; -#define WPA_IGTK_LEN 16 +#define WPA_IGTK_MAX_LEN 32 typedef struct { uint8_t keyid[2]; uint8_t pn[6]; - uint8_t igtk[WPA_IGTK_LEN]; + uint8_t igtk[WPA_IGTK_MAX_LEN]; } wifi_wpa_igtk_t; typedef struct { diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index 6b848b7972..b942674dc9 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -212,24 +212,13 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) case WIFI_REASON_CONNECTION_FAIL: case WIFI_REASON_HANDSHAKE_TIMEOUT: esp_wpa3_free_sae_data(); - wpa_sta_clear_curr_pmksa(); + wpa_sm_notify_disassoc(&gWpaSm); break; default: break; } } -#ifndef CONFIG_WPA_11KV_SUPPORT -static inline int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) -{ - wpa_cb->wpa_sta_rx_mgmt = NULL; - return 0; -} -static inline void esp_supplicant_common_deinit(void) -{ -} -#endif - int esp_supplicant_init(void) { int ret = ESP_OK; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 2d80140c66..8722863345 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -682,31 +682,33 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, enum key_flag key_flag) int keylen; enum wpa_alg alg; + if (sm->ptk.installed) { + wpa_printf(MSG_DEBUG, "WPA: Do not re-install same PTK to the driver"); + return 0; + } #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.\n"); #endif - switch (sm->pairwise_cipher) { - case WPA_CIPHER_CCMP: - alg = WIFI_WPA_ALG_CCMP; - keylen = 16; - break; - case WPA_CIPHER_TKIP: - alg = WIFI_WPA_ALG_TKIP; - keylen = 32; - break; - case WPA_CIPHER_NONE: + if (sm->pairwise_cipher == WPA_CIPHER_NONE) { + wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: NONE - do not use pairwise keys"); + return 0; + } + + if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) { + wpa_printf(MSG_DEBUG, "WPA: Unsupported pairwise cipher %d", sm->pairwise_cipher); + return -1; + } + + alg = wpa_cipher_to_alg(sm->pairwise_cipher); + keylen = wpa_cipher_key_len(sm->pairwise_cipher); + + if (alg == WIFI_WPA_ALG_NONE) { #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: " "NONE - do not use pairwise keys"); #endif return 0; - default: - #ifdef DEBUG_PRINT - wpa_printf(MSG_DEBUG, "WPA: Unsupported pairwise cipher %d", - sm->pairwise_cipher); - #endif - return -1; } if (wpa_sm_set_key(&(sm->install_ptk), alg, sm->bssid, 0, 1, (sm->install_ptk).seq, WPA_KEY_RSC_LEN, @@ -719,6 +721,8 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, enum key_flag key_flag) return -1; } + sm->ptk.installed = 1; + if (sm->wpa_ptk_rekey) { eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk, @@ -832,7 +836,9 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); /* Detect possible key reinstallation */ - if (wpa_supplicant_gtk_in_use(sm, &(sm->gd))) { + if ((sm->gtk.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) || + wpa_supplicant_gtk_in_use(sm, &(sm->gd))) { wpa_printf(MSG_DEBUG, "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", gd->keyidx, gd->tx, gd->gtk_len); @@ -875,6 +881,8 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, #endif return -1; } + sm->gtk.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); return 0; } @@ -975,6 +983,47 @@ int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, #endif /* CONFIG_NO_WPA2 */ } + +#ifdef CONFIG_IEEE80211W +static int wpa_supplicant_install_igtk(struct wpa_sm *sm, + const wifi_wpa_igtk_t *igtk) +{ + size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); + u16 keyidx = WPA_GET_LE16(igtk->keyid); + + /* Detect possible key reinstallation */ + if (sm->igtk.igtk_len == len && + os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { + wpa_printf(MSG_DEBUG, + "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", + keyidx); + return 0; + } + + wpa_printf(MSG_DEBUG, + "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", + keyidx, MAC2STR(igtk->pn)); + wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); + if (keyidx > 4095) { + wpa_printf(MSG_WARNING, + "WPA: Invalid IGTK KeyID %d", keyidx); + return -1; + } + if (esp_wifi_set_igtk_internal(WIFI_IF_STA, igtk) < 0) { + wpa_printf(MSG_WARNING, + "WPA: Failed to configure IGTK to the driver"); + return -1; + } + + sm->igtk.igtk_len = len; + os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + + return 0; +} +#endif /* CONFIG_IEEE80211W */ + + + #ifdef DEBUG_PRINT void wpa_report_ie_mismatch(struct wpa_sm *sm, const char *reason, const u8 *src_addr, @@ -1027,28 +1076,26 @@ int ieee80211w_set_keys(struct wpa_sm *sm, struct wpa_eapol_ie_parse *ie) { #ifdef CONFIG_IEEE80211W - if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) { - return -1; - } + size_t len; - if (ie->igtk) { - const wifi_wpa_igtk_t *igtk; - uint16_t keyidx; + if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher)) + return 0; - if (ie->igtk_len != sizeof(*igtk)) { - return -1; - } - igtk = (const wifi_wpa_igtk_t*)ie->igtk; - keyidx = WPA_GET_LE16(igtk->keyid); - if (keyidx > 4095) { - return -1; - } - return esp_wifi_set_igtk_internal(WIFI_IF_STA, igtk); - } - return 0; -#else - return 0; + if (ie->igtk) { + const wifi_wpa_igtk_t *igtk; +#define WPA_IGTK_KDE_PREFIX_LEN (2 + 6) + len = wpa_cipher_key_len(sm->mgmt_group_cipher); + if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len) { + return -1; + } + + igtk = (const wifi_wpa_igtk_t*)ie->igtk; + if (wpa_supplicant_install_igtk(sm, igtk) < 0) { + return -1; + } + } #endif + return 0; } int wpa_supplicant_validate_ie(struct wpa_sm *sm, @@ -2180,9 +2227,66 @@ void wpa_sm_deinit(void) os_free(sm->ap_rsnxe); sm->ap_rsnxe = NULL; os_free(sm->assoc_rsnxe); + wpa_sm_drop_sa(sm); sm->assoc_rsnxe = NULL; } +/** + * wpa_sm_notify_assoc - Notify WPA state machine about association + * @sm: Pointer to WPA state machine data from wpa_sm_init() + * @bssid: The BSSID of the new association + * + * This function is called to let WPA state machine know that the connection + * was established. + */ +void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) +{ + int clear_keys = 1; + + if (sm == NULL) + return; + + wpa_printf(MSG_DEBUG, + "WPA: Association event - clear replay counter"); + os_memcpy(sm->bssid, bssid, ETH_ALEN); + os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN); + sm->rx_replay_counter_set = 0; + sm->renew_snonce = 1; + + if (clear_keys) { + /* + * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if + * this is not part of a Fast BSS Transition. + */ + wpa_printf(MSG_DEBUG, "WPA: Clear old PTK"); + sm->ptk_set = 0; + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + sm->tptk_set = 0; + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); + } +} + + +/** + * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation + * @sm: Pointer to WPA state machine data from wpa_sm_init() + * + * This function is called to let WPA state machine know that the connection + * was lost. This will abort any existing pre-authentication session. + */ +void wpa_sm_notify_disassoc(struct wpa_sm *sm) +{ + eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); + pmksa_cache_clear_current(sm); + + /* Keys are not needed in the WPA state machine anymore */ + wpa_sm_drop_sa(sm); + + os_memset(sm->bssid, 0, ETH_ALEN); +} + void wpa_set_profile(u32 wpa_proto, u8 auth_mode) { @@ -2590,4 +2694,15 @@ int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) return 0; } +void wpa_sm_drop_sa(struct wpa_sm *sm) +{ + wpa_printf(MSG_DEBUG, "WPA: Clear old PMK and PTK"); + sm->ptk_set = 0; + sm->tptk_set = 0; + sm->pmk_len = 0; + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); +} #endif // ESP_SUPPLICANT diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.h b/components/wpa_supplicant/src/rsn_supp/wpa.h index 66fcad53ad..63fa01c95e 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa.h @@ -33,6 +33,7 @@ #define WPA_SM_STATE(_sm) ((_sm)->wpa_state) struct wpa_sm; +extern struct wpa_sm gWpaSm; int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); bool wpa_sta_is_cur_pmksa_set(void); @@ -140,8 +141,14 @@ int wpa_sm_set_ap_rsnxe(const u8 *ie, size_t len); int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); +void wpa_sm_drop_sa(struct wpa_sm *sm); + struct wpa_sm * get_wpa_sm(void); void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm); +void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid); + +void wpa_sm_notify_disassoc(struct wpa_sm *sm); + #endif /* WPA_H */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index aa295404e1..d7b1714295 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -40,6 +40,11 @@ struct wpa_sm { u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + struct wpa_gtk gtk; +#ifdef CONFIG_IEEE80211W + struct wpa_igtk igtk; +#endif /* CONFIG_IEEE80211W */ + struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */ u8 ssid[32];