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 */
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);
}
+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
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)