diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 71b6c4366..68bc33303 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2538,6 +2538,10 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, #endif /* CONFIG_IEEE80211R_AP */ #ifdef CONFIG_SAE + if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && + sta->sae->state == SAE_ACCEPTED) + wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); + if (wpa_auth_uses_sae(sta->wpa_sm) && sta->auth_alg == WLAN_AUTH_OPEN) { struct rsn_pmksa_cache_entry *sa; diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 203329eeb..8dde1d0aa 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2035,11 +2035,31 @@ SM_STATE(WPA_PTK, PTKSTART) pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN; RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID); if (sm->pmksa) { + wpa_hexdump(MSG_DEBUG, + "RSN: Message 1/4 PMKID from PMKSA entry", + sm->pmksa->pmkid, PMKID_LEN); os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], sm->pmksa->pmkid, PMKID_LEN); } else if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) { /* No KCK available to derive PMKID */ + wpa_printf(MSG_DEBUG, + "RSN: No KCK available to derive PMKID for message 1/4"); pmkid = NULL; +#ifdef CONFIG_SAE + } else if (wpa_key_mgmt_sae(sm->wpa_key_mgmt)) { + if (sm->pmkid_set) { + wpa_hexdump(MSG_DEBUG, + "RSN: Message 1/4 PMKID from SAE", + sm->pmkid, PMKID_LEN); + os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN], + sm->pmkid, PMKID_LEN); + } else { + /* No PMKID available */ + wpa_printf(MSG_DEBUG, + "RSN: No SAE PMKID available for message 1/4"); + pmkid = NULL; + } +#endif /* CONFIG_SAE */ } else { /* * Calculate PMKID since no PMKSA cache entry was @@ -2048,6 +2068,9 @@ SM_STATE(WPA_PTK, PTKSTART) rsn_pmkid(sm->PMK, sm->pmk_len, sm->wpa_auth->addr, sm->addr, &pmkid[2 + RSN_SELECTOR_LEN], sm->wpa_key_mgmt); + wpa_hexdump(MSG_DEBUG, + "RSN: Message 1/4 PMKID derived from PMK", + &pmkid[2 + RSN_SELECTOR_LEN], PMKID_LEN); } } wpa_send_eapol(sm->wpa_auth, sm, @@ -4040,6 +4063,13 @@ int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, } +void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid) +{ + os_memcpy(sm->pmkid, pmkid, PMKID_LEN); + sm->pmkid_set = 1; +} + + int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *pmk, size_t pmk_len, const u8 *pmkid, int session_timeout, int akmp) diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 1bfacdc7a..6b1887bdc 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -332,6 +332,7 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, struct eapol_state_machine *eapol); int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *pmk, const u8 *pmkid); +void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid); int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *pmk, size_t pmk_len, const u8 *pmkid, int session_timeout, int akmp); diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index befa8007f..609405a26 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -58,6 +58,7 @@ struct wpa_state_machine { u8 alt_replay_counter[WPA_REPLAY_COUNTER_LEN]; u8 PMK[PMK_LEN_MAX]; unsigned int pmk_len; + u8 pmkid[PMKID_LEN]; /* valid if pmkid_set == 1 */ struct wpa_ptk PTK; Boolean PTK_valid; Boolean pairwise_set; @@ -90,6 +91,7 @@ struct wpa_state_machine { unsigned int pmk_r1_name_valid:1; #endif /* CONFIG_IEEE80211R_AP */ unsigned int is_wnmsleep:1; + unsigned int pmkid_set:1; u8 req_replay_counter[WPA_REPLAY_COUNTER_LEN]; int req_replay_counter_used;