SAE: Fix PMKID in EAPOL-Key msg 1/4
Previously, the association that used SAE authentication ended up recalculating the PMKID for EAPOL-Key msg 1/4 using incorrect PMK-to-PMKID derivation instead of using the previously derived PMKID from SAE. The correct PMKID was used only when going through PMKSA caching exchange with a previously derived PMKSA from SAE. Fix this by storing the SAE PMKID into the state machine entry for the initial SAE authentication case when there is no explicit PMKSA entry attached to the station. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
a03f9d17ea
commit
9d94e4bb6b
4 changed files with 37 additions and 0 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue