From e61fea6b467bec0702096c795b06195584d32a6c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 2 Sep 2017 01:02:15 +0300 Subject: [PATCH] SAE: Fix PMKSA caching behavior in AP mode Add PMKID into EAPOL-Key 1/4 when using SAE and fix the PMK-from-PMKSA selection in some cases where PSK (from passphrase) could have been used. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth.c | 24 +++++++++++++++++++----- src/ap/wpa_auth_glue.c | 5 +++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 863ae832e..7ae64c9ac 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -852,7 +852,8 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data, os_memset(&PTK, 0, sizeof(PTK)); for (;;) { - if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { + if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) && + !wpa_key_mgmt_sae(sm->wpa_key_mgmt)) { pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, pmk); if (pmk == NULL) @@ -2028,6 +2029,13 @@ SM_STATE(WPA_PTK, INITPSK) sm->xxkey_len = PMK_LEN; #endif /* CONFIG_IEEE80211R_AP */ } +#ifdef CONFIG_SAE + if (wpa_auth_uses_sae(sm) && sm->pmksa) { + wpa_printf(MSG_DEBUG, "SAE: PMK from PMKSA cache"); + os_memcpy(sm->PMK, sm->pmksa->pmk, sm->pmksa->pmk_len); + sm->pmk_len = sm->pmksa->pmk_len; + } +#endif /* CONFIG_SAE */ sm->req_replay_counter_used = 0; } @@ -2056,7 +2064,8 @@ SM_STATE(WPA_PTK, PTKSTART) * one possible PSK for this STA. */ if (sm->wpa == WPA_VERSION_WPA2 && - wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) && + (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) || + wpa_key_mgmt_sae(sm->wpa_key_mgmt)) && sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) { pmkid = buf; pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; @@ -2627,7 +2636,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) * WPA-PSK: iterate through possible PSKs and select the one matching * the packet */ for (;;) { - if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { + if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) && + !wpa_key_mgmt_sae(sm->wpa_key_mgmt)) { pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, pmk); if (pmk == NULL) @@ -3156,9 +3166,13 @@ SM_STEP(WPA_PTK) break; case WPA_PTK_INITPSK: if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, - NULL)) + NULL)) { SM_ENTER(WPA_PTK, PTKSTART); - else { +#ifdef CONFIG_SAE + } else if (wpa_auth_uses_sae(sm) && sm->pmksa) { + SM_ENTER(WPA_PTK, PTKSTART); +#endif /* CONFIG_SAE */ + } else { wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, "no PSK configured for the STA"); wpa_auth->dot11RSNA4WayHandshakeFailures++; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 316f5d50b..5a09fb392 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -250,6 +250,11 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr, return NULL; return sta->sae->pmk; } + if (sta && wpa_auth_uses_sae(sta->wpa_sm)) { + wpa_printf(MSG_DEBUG, + "No PSK for STA trying to use SAE with PMKSA caching"); + return NULL; + } #endif /* CONFIG_SAE */ #ifdef CONFIG_OWE