FILS: Fix PTK rekeying
The PMK and PMKID information from FILS ERP and FILS PMKSA caching needs to be stored within struct wpa_state_machine for PTK to work. Without this, PTK derivation would fail and attempt to go through rekeying would result in disconnection. Furthermore, wpa_rekey_ptk() timer needs to be started at the completion of FILS association since the place where it was done for non-FILS cases at the end of 4-way handshake is not reached when FILS authentication is used. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
c8931afe24
commit
a40bd06e9b
4 changed files with 51 additions and 6 deletions
|
@ -1821,6 +1821,8 @@ prepare_auth_resp_fils(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
sta->fils_erp_pmkid_set = 0;
|
||||
wpa_auth_add_fils_pmk_pmkid(sta->wpa_sm, pmk, pmk_len,
|
||||
sta->fils_erp_pmkid);
|
||||
if (!hapd->conf->disable_pmksa_caching &&
|
||||
wpa_auth_pmksa_add2(
|
||||
hapd->wpa_auth, sta->addr,
|
||||
|
|
|
@ -1236,6 +1236,7 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
|
|||
sta->eapol_sm->portValid = TRUE;
|
||||
if (sta->eapol_sm->eap)
|
||||
eap_sm_notify_cached(sta->eapol_sm->eap);
|
||||
wpa_auth_set_ptk_rekey_timer(sta->wpa_sm);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
|
|
@ -320,6 +320,19 @@ static void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
|
|||
}
|
||||
|
||||
|
||||
void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm)
|
||||
{
|
||||
if (sm && sm->wpa_auth->conf.wpa_ptk_rekey) {
|
||||
wpa_printf(MSG_DEBUG, "WPA: Start PTK rekeying timer for "
|
||||
MACSTR " (%d seconds)", MAC2STR(sm->addr),
|
||||
sm->wpa_auth->conf.wpa_ptk_rekey);
|
||||
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
eloop_register_timeout(sm->wpa_auth->conf.wpa_ptk_rekey, 0,
|
||||
wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx)
|
||||
{
|
||||
if (sm->pmksa == ctx)
|
||||
|
@ -2124,6 +2137,21 @@ SM_STATE(WPA_PTK, PTKSTART)
|
|||
wpa_printf(MSG_DEBUG,
|
||||
"RSN: No KCK available to derive PMKID for message 1/4");
|
||||
pmkid = NULL;
|
||||
#ifdef CONFIG_FILS
|
||||
} else if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
|
||||
if (sm->pmkid_set) {
|
||||
wpa_hexdump(MSG_DEBUG,
|
||||
"RSN: Message 1/4 PMKID from FILS/ERP",
|
||||
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 FILS/ERP PMKID available for message 1/4");
|
||||
pmkid = NULL;
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
#ifdef CONFIG_SAE
|
||||
} else if (wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
|
||||
if (sm->pmkid_set) {
|
||||
|
@ -2790,6 +2818,12 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
|||
pmk_len = sm->pmk_len;
|
||||
}
|
||||
|
||||
if ((!pmk || !pmk_len) && sm->pmksa) {
|
||||
wpa_printf(MSG_DEBUG, "WPA: Use PMK from PMKSA cache");
|
||||
pmk = sm->pmksa->pmk;
|
||||
pmk_len = sm->pmksa->pmk_len;
|
||||
}
|
||||
|
||||
if (wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK) < 0)
|
||||
break;
|
||||
|
||||
|
@ -3287,12 +3321,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
|
|||
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
|
||||
sm->pairwise_set = TRUE;
|
||||
|
||||
if (sm->wpa_auth->conf.wpa_ptk_rekey) {
|
||||
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
eloop_register_timeout(sm->wpa_auth->conf.
|
||||
wpa_ptk_rekey, 0, wpa_rekey_ptk,
|
||||
sm->wpa_auth, sm);
|
||||
}
|
||||
wpa_auth_set_ptk_rekey_timer(sm);
|
||||
|
||||
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
|
||||
sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
|
||||
|
@ -4840,6 +4869,16 @@ void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
|
|||
*fils_kek_len = sm->PTK.kek_len;
|
||||
}
|
||||
|
||||
|
||||
void wpa_auth_add_fils_pmk_pmkid(struct wpa_state_machine *sm, const u8 *pmk,
|
||||
size_t pmk_len, const u8 *pmkid)
|
||||
{
|
||||
os_memcpy(sm->PMK, pmk, pmk_len);
|
||||
sm->pmk_len = pmk_len;
|
||||
os_memcpy(sm->pmkid, pmkid, PMKID_LEN);
|
||||
sm->pmkid_set = 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
|
||||
|
|
|
@ -470,6 +470,8 @@ int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
|
|||
void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
|
||||
u8 *fils_anonce, u8 *fils_snonce,
|
||||
u8 *fils_kek, size_t *fils_kek_len);
|
||||
void wpa_auth_add_fils_pmk_pmkid(struct wpa_state_machine *sm, const u8 *pmk,
|
||||
size_t pmk_len, const u8 *pmkid);
|
||||
u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm,
|
||||
u8 *pos, size_t max_len,
|
||||
const u8 *req_ies, size_t req_ies_len);
|
||||
|
@ -486,5 +488,6 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
|
|||
void (*cb)(void *ctx1, void *ctx2),
|
||||
void *ctx1, void *ctx2);
|
||||
int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
|
||||
void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
|
||||
|
||||
#endif /* WPA_AUTH_H */
|
||||
|
|
Loading…
Reference in a new issue