SSID verification based on beacon protection

If SSID was not verified during the initial setup of an association, but
beacon protection was negotiated, try verify the SSID based on Beacon
frames that have been received after the first BIGTK has been
configured.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2024-07-11 23:52:30 +03:00 committed by Jouni Malinen
parent 89b164138c
commit 5452a4a302
2 changed files with 90 additions and 0 deletions

View file

@ -125,6 +125,7 @@ const char *const wpa_supplicant_full_license5 =
static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_verify_ssid_beacon(void *eloop_ctx, void *timeout_ctx);
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s);
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
@ -611,6 +612,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
eloop_cancel_timeout(wpas_clear_disabled_interface, wpa_s, NULL);
eloop_cancel_timeout(wpas_verify_ssid_beacon, wpa_s, NULL);
wpas_wps_deinit(wpa_s);
@ -927,6 +929,88 @@ void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
}
static void wpas_verify_ssid_beacon(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_bss *bss;
const u8 *ssid;
size_t ssid_len;
if (!wpa_s->current_ssid || !wpa_s->current_bss)
return;
ssid = wpa_s->current_bss->ssid;
ssid_len = wpa_s->current_bss->ssid_len;
if (wpa_s->current_ssid->ssid_len &&
(wpa_s->current_ssid->ssid_len != ssid_len ||
os_memcmp(wpa_s->current_ssid->ssid, ssid, ssid_len) != 0))
return;
if (wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
!wpa_s->bigtk_set || wpa_s->ssid_verified)
return;
wpa_printf(MSG_DEBUG,
"SSID not yet verified; check if the driver has received a verified Beacon frame");
if (wpa_supplicant_update_scan_results(wpa_s, wpa_s->bssid) < 0)
return;
bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->bssid);
if (!bss)
return;
wpa_printf(MSG_DEBUG, "The current beacon time stamp: 0x%llx",
(long long unsigned int) bss->tsf);
if (bss->tsf > wpa_s->first_beacon_tsf) {
const u8 *ie;
wpa_printf(MSG_DEBUG,
"Verified Beacon frame has been received");
wpa_s->beacons_checked++;
ie = wpa_bss_get_ie_beacon(bss, WLAN_EID_SSID);
if (ie && ie[1] == ssid_len &&
os_memcmp(&ie[2], ssid, ssid_len) == 0) {
wpa_printf(MSG_DEBUG,
"SSID verified based on a Beacon frame and beacon protection");
wpa_s->ssid_verified = true;
return;
}
/* TODO: Multiple BSSID element */
}
if (wpa_s->beacons_checked < 16)
eloop_register_timeout(1, 0, wpas_verify_ssid_beacon,
wpa_s, NULL);
}
static void wpas_verify_ssid_beacon_prot(struct wpa_supplicant *wpa_s)
{
struct wpa_bss *bss;
wpa_printf(MSG_DEBUG,
"SSID not yet verified; try to verify using beacon protection");
/* Fetch the current scan result which is likely based on not yet
* verified payload since the current BIGTK was just received. Any
* newer update in the future with a larger timestamp value is an
* indication that a verified Beacon frame has been received. */
if (wpa_supplicant_update_scan_results(wpa_s, wpa_s->bssid) < 0)
return;
bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->bssid);
if (!bss)
return;
wpa_printf(MSG_DEBUG, "The initial beacon time stamp: 0x%llx",
(long long unsigned int) bss->tsf);
wpa_s->first_beacon_tsf = bss->tsf;
wpa_s->beacons_checked = 0;
eloop_cancel_timeout(wpas_verify_ssid_beacon, wpa_s, NULL);
eloop_register_timeout(1, 0, wpas_verify_ssid_beacon, wpa_s, NULL);
}
/**
* wpa_supplicant_set_state - Set current connection state
* @wpa_s: Pointer to wpa_supplicant data
@ -1100,6 +1184,10 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
if (wpa_s->wpa_state == WPA_COMPLETED)
wpas_dpp_connected(wpa_s);
#endif /* CONFIG_DPP2 */
if (wpa_s->wpa_state == WPA_COMPLETED &&
wpa_s->bigtk_set && !wpa_s->ssid_verified)
wpas_verify_ssid_beacon_prot(wpa_s);
}
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
if (update_fils_connect_params)

View file

@ -1612,6 +1612,8 @@ struct wpa_supplicant {
bool ssid_verified;
bool bigtk_set;
u64 first_beacon_tsf;
unsigned int beacons_checked;
};