FILS: Try to use FILS authentication if PMKSA or ERP entry is available
If a PMKSA cache entry for the target AP is available, try to use FILS with PMKSA caching. If an ERP key for the target AP is available, try to use FILS with EAP-Initiate/Re-auth added as Wrapper Data element. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
2c2c557917
commit
f00b9b8864
4 changed files with 120 additions and 4 deletions
|
@ -3199,3 +3199,91 @@ void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
|
||||||
sm->test_assoc_ie = buf;
|
sm->test_assoc_ie = buf;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
|
||||||
|
struct wpabuf * fils_build_auth(struct wpa_sm *sm)
|
||||||
|
{
|
||||||
|
struct wpabuf *buf = NULL;
|
||||||
|
struct wpabuf *erp_msg;
|
||||||
|
|
||||||
|
erp_msg = eapol_sm_build_erp_reauth_start(sm->eapol);
|
||||||
|
if (!erp_msg && !sm->cur_pmksa) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"FILS: Neither ERP EAP-Initiate/Re-auth nor PMKSA cache entry is available - skip FILS");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "FILS: Try to use FILS (erp=%d pmksa_cache=%d)",
|
||||||
|
erp_msg != NULL, sm->cur_pmksa != NULL);
|
||||||
|
|
||||||
|
if (!sm->assoc_wpa_ie) {
|
||||||
|
wpa_printf(MSG_INFO, "FILS: No own RSN IE set for FILS");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (random_get_bytes(sm->fils_nonce, FILS_NONCE_LEN) < 0 ||
|
||||||
|
random_get_bytes(sm->fils_session, FILS_SESSION_LEN) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Nonce",
|
||||||
|
sm->fils_nonce, FILS_NONCE_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Session",
|
||||||
|
sm->fils_session, FILS_SESSION_LEN);
|
||||||
|
|
||||||
|
buf = wpabuf_alloc(1000 + sm->assoc_wpa_ie_len);
|
||||||
|
if (!buf)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Fields following the Authentication algorithm number field */
|
||||||
|
|
||||||
|
/* Authentication Transaction seq# */
|
||||||
|
wpabuf_put_le16(buf, 1);
|
||||||
|
|
||||||
|
/* Status Code */
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
/* TODO: Finite Cyclic Group when using PK or PFS */
|
||||||
|
/* TODO: Element when using PK or PFS */
|
||||||
|
|
||||||
|
/* RSNE */
|
||||||
|
wpa_hexdump(MSG_DEBUG, "FILS: RSNE in FILS Authentication frame",
|
||||||
|
sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
|
||||||
|
wpabuf_put_data(buf, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
|
||||||
|
|
||||||
|
/* TODO: MDE when using FILS for FT initial association */
|
||||||
|
/* TODO: FTE when using FILS for FT initial association */
|
||||||
|
|
||||||
|
/* FILS Nonce */
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
|
||||||
|
wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN); /* Length */
|
||||||
|
/* Element ID Extension */
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
|
||||||
|
wpabuf_put_data(buf, sm->fils_nonce, FILS_NONCE_LEN);
|
||||||
|
|
||||||
|
/* FILS Session */
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
|
||||||
|
wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
|
||||||
|
/* Element ID Extension */
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
|
||||||
|
wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
|
||||||
|
|
||||||
|
/* FILS Wrapped Data */
|
||||||
|
if (erp_msg) {
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
|
||||||
|
wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
|
||||||
|
/* Element ID Extension */
|
||||||
|
wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
|
||||||
|
wpabuf_put_buf(buf, erp_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG, "RSN: FILS fields for Authentication frame",
|
||||||
|
buf);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
wpabuf_free(erp_msg);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
|
|
|
@ -426,4 +426,6 @@ extern unsigned int tdls_testing;
|
||||||
int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
|
int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
|
||||||
void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf);
|
void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf);
|
||||||
|
|
||||||
|
struct wpabuf * fils_build_auth(struct wpa_sm *sm);
|
||||||
|
|
||||||
#endif /* WPA_H */
|
#endif /* WPA_H */
|
||||||
|
|
|
@ -138,6 +138,11 @@ struct wpa_sm {
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
struct wpabuf *test_assoc_ie;
|
struct wpabuf *test_assoc_ie;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
u8 fils_nonce[FILS_NONCE_LEN];
|
||||||
|
u8 fils_session[FILS_SESSION_LEN];
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -549,6 +549,31 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
|
old_ssid = wpa_s->current_ssid;
|
||||||
|
wpa_s->current_ssid = ssid;
|
||||||
|
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
|
||||||
|
wpa_supplicant_initiate_eapol(wpa_s);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
/* TODO: FILS operations can in some cases be done between different
|
||||||
|
* network_ctx (i.e., same credentials can be used with multiple
|
||||||
|
* networks). */
|
||||||
|
if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
|
||||||
|
wpa_key_mgmt_fils(ssid->key_mgmt)) {
|
||||||
|
if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
|
||||||
|
ssid, 0) == 0)
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"SME: Try to use FILS with PMKSA caching");
|
||||||
|
resp = fils_build_auth(wpa_s->wpa);
|
||||||
|
if (resp) {
|
||||||
|
params.auth_alg = WPA_AUTH_ALG_FILS;
|
||||||
|
params.auth_data = wpabuf_head(resp);
|
||||||
|
params.auth_data_len = wpabuf_len(resp);
|
||||||
|
wpa_s->sme.auth_alg = WPA_AUTH_ALG_FILS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
|
|
||||||
wpa_supplicant_cancel_sched_scan(wpa_s);
|
wpa_supplicant_cancel_sched_scan(wpa_s);
|
||||||
wpa_supplicant_cancel_scan(wpa_s);
|
wpa_supplicant_cancel_scan(wpa_s);
|
||||||
|
|
||||||
|
@ -558,10 +583,6 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
wpa_clear_keys(wpa_s, bss->bssid);
|
wpa_clear_keys(wpa_s, bss->bssid);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
|
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
|
||||||
old_ssid = wpa_s->current_ssid;
|
|
||||||
wpa_s->current_ssid = ssid;
|
|
||||||
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
|
|
||||||
wpa_supplicant_initiate_eapol(wpa_s);
|
|
||||||
if (old_ssid != wpa_s->current_ssid)
|
if (old_ssid != wpa_s->current_ssid)
|
||||||
wpas_notify_network_changed(wpa_s);
|
wpas_notify_network_changed(wpa_s);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue