From c6f394b8884b4e518c6b6bb2506d85c5bd080e60 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 11 Jul 2024 22:44:46 +0300 Subject: [PATCH] Indicate if SSID has been verified in STATUS output Add a new "ssid_verified=1" entry into the control interface STATUS command output if the SSID has been verified for the current association. This verification may have been done implicitly (e.g., with SAE H2E and FT protocol binding in the SSID into key derivation or with FILS protecting the SSID element in the (Re)Association Request frame) or explicitly with the recently added SSID protection mechanism during the 4-way handshake. Signed-off-by: Jouni Malinen --- src/rsn_supp/wpa.c | 3 +-- src/rsn_supp/wpa.h | 1 + src/rsn_supp/wpa_i.h | 6 +++++ wpa_supplicant/ctrl_iface.c | 7 ++++++ wpa_supplicant/events.c | 41 +++++++++++++++++++++++++------ wpa_supplicant/wpa_supplicant_i.h | 2 ++ wpa_supplicant/wpas_glue.c | 10 ++++++++ 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 21dfeb5fb..323690a66 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -2560,8 +2560,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, goto failed; } - wpa_msg(sm->ctx->msg_ctx, MSG_INFO, - "RSN: SSID matched expected value"); + wpa_sm_ssid_verified(sm); } if (mlo && !ie.valid_mlo_gtks) { diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index c3ea68906..2bef093e3 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -104,6 +104,7 @@ struct wpa_sm_ctx { #endif /* CONFIG_PASN */ void (*notify_pmksa_cache_entry)(void *ctx, struct rsn_pmksa_cache_entry *entry); + void (*ssid_verified)(void *ctx); }; diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index dc429b8b2..d7e780519 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -518,6 +518,12 @@ wpa_sm_notify_pmksa_cache_entry(struct wpa_sm *sm, sm->ctx->notify_pmksa_cache_entry(sm->ctx->ctx, entry); } +static inline void wpa_sm_ssid_verified(struct wpa_sm *sm) +{ + if (sm->ctx->ssid_verified) + sm->ctx->ssid_verified(sm->ctx->ctx); +} + int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, int ver, const u8 *dest, u16 proto, u8 *msg, size_t msg_len, u8 *key_mic); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 74d61132e..acc6ab524 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2568,6 +2568,13 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_SME */ + if (wpa_s->ssid_verified) { + ret = os_snprintf(pos, end - pos, "ssid_verified=1\n"); + if (os_snprintf_error(end - pos, ret)) + return pos - buf; + pos += ret; + } + #ifdef ANDROID /* * Allow using the STATUS command with default behavior, say for debug, diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index d45e7925d..e8b7eea11 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -432,6 +432,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) #ifdef CONFIG_SME wpa_s->sme.bss_max_idle_period = 0; #endif /* CONFIG_SME */ + + wpa_s->ssid_verified = false; } @@ -3368,6 +3370,15 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, bool bssid_known; wpa_dbg(wpa_s, MSG_DEBUG, "Association info event"); + wpa_s->ssid_verified = false; +#ifdef CONFIG_SAE +#ifdef CONFIG_SME + /* SAE H2E binds the SSID into PT and that verifies the SSID + * implicitly. */ + if (wpa_s->sme.sae.state == SAE_ACCEPTED && wpa_s->sme.sae.h2e) + wpa_s->ssid_verified = true; +#endif /* CONFIG_SME */ +#endif /* CONFIG_SAE */ bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0; if (data->assoc_info.req_ies) wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies, @@ -3469,14 +3480,22 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, #ifdef CONFIG_FILS #ifdef CONFIG_SME - if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS || - wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) && - (!data->assoc_info.resp_frame || - fils_process_assoc_resp(wpa_s->wpa, - data->assoc_info.resp_frame, - data->assoc_info.resp_frame_len) < 0)) { - wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED); - return -1; + if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS || + wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) { + if (!data->assoc_info.resp_frame || + fils_process_assoc_resp(wpa_s->wpa, + data->assoc_info.resp_frame, + data->assoc_info.resp_frame_len) < + 0) { + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_UNSPECIFIED); + return -1; + } + + /* FILS use of an AEAD cipher include the SSID element in + * (Re)Association Request frame in the AAD and since the AP + * accepted that, the SSID was verified. */ + wpa_s->ssid_verified = true; } #endif /* CONFIG_SME */ @@ -3537,6 +3556,9 @@ no_pfs: wpa_s, WLAN_REASON_INVALID_IE); return -1; } + /* SSID is included in PMK-R0 derivation, so it is verified + * implicitly. */ + wpa_s->ssid_verified = true; } p = data->assoc_info.resp_ies; @@ -3598,6 +3620,9 @@ no_pfs: return -1; } wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done"); + /* SSID is included in PMK-R0 derivation, so it is verified + * implicitly. */ + wpa_s->ssid_verified = true; } wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies, diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 7a1286225..13406881d 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1609,6 +1609,8 @@ struct wpa_supplicant { struct wpa_radio_work *nan_usd_listen_work; struct wpa_radio_work *nan_usd_tx_work; #endif /* CONFIG_NAN_USD */ + + bool ssid_verified; }; diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index eea854899..9b68d07c6 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1409,6 +1409,15 @@ wpa_supplicant_notify_pmksa_cache_entry(void *_wpa_s, } +static void wpa_supplicant_ssid_verified(void *_wpa_s) +{ + struct wpa_supplicant *wpa_s = _wpa_s; + + wpa_s->ssid_verified = true; + wpa_msg(wpa_s, MSG_INFO, "RSN: SSID matched expected value"); +} + + int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) { #ifndef CONFIG_NO_WPA @@ -1475,6 +1484,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->set_ltf_keyseed = wpa_supplicant_set_ltf_keyseed; #endif /* CONFIG_PASN */ ctx->notify_pmksa_cache_entry = wpa_supplicant_notify_pmksa_cache_entry; + ctx->ssid_verified = wpa_supplicant_ssid_verified; wpa_s->wpa = wpa_sm_init(ctx); if (wpa_s->wpa == NULL) {