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 <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2024-07-11 22:44:46 +03:00 committed by Jouni Malinen
parent b745cd33ef
commit c6f394b888
7 changed files with 60 additions and 10 deletions

View file

@ -2560,8 +2560,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
goto failed; goto failed;
} }
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, wpa_sm_ssid_verified(sm);
"RSN: SSID matched expected value");
} }
if (mlo && !ie.valid_mlo_gtks) { if (mlo && !ie.valid_mlo_gtks) {

View file

@ -104,6 +104,7 @@ struct wpa_sm_ctx {
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
void (*notify_pmksa_cache_entry)(void *ctx, void (*notify_pmksa_cache_entry)(void *ctx,
struct rsn_pmksa_cache_entry *entry); struct rsn_pmksa_cache_entry *entry);
void (*ssid_verified)(void *ctx);
}; };

View file

@ -518,6 +518,12 @@ wpa_sm_notify_pmksa_cache_entry(struct wpa_sm *sm,
sm->ctx->notify_pmksa_cache_entry(sm->ctx->ctx, entry); 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 wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
int ver, const u8 *dest, u16 proto, int ver, const u8 *dest, u16 proto,
u8 *msg, size_t msg_len, u8 *key_mic); u8 *msg, size_t msg_len, u8 *key_mic);

View file

@ -2568,6 +2568,13 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
} }
#endif /* CONFIG_SME */ #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 #ifdef ANDROID
/* /*
* Allow using the STATUS command with default behavior, say for debug, * Allow using the STATUS command with default behavior, say for debug,

View file

@ -432,6 +432,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_SME #ifdef CONFIG_SME
wpa_s->sme.bss_max_idle_period = 0; wpa_s->sme.bss_max_idle_period = 0;
#endif /* CONFIG_SME */ #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; bool bssid_known;
wpa_dbg(wpa_s, MSG_DEBUG, "Association info event"); 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; bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
if (data->assoc_info.req_ies) if (data->assoc_info.req_ies)
wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies, wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
@ -3469,15 +3480,23 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
#ifdef CONFIG_SME #ifdef CONFIG_SME
if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS || if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) && wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) {
(!data->assoc_info.resp_frame || if (!data->assoc_info.resp_frame ||
fils_process_assoc_resp(wpa_s->wpa, fils_process_assoc_resp(wpa_s->wpa,
data->assoc_info.resp_frame, data->assoc_info.resp_frame,
data->assoc_info.resp_frame_len) < 0)) { data->assoc_info.resp_frame_len) <
wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED); 0) {
wpa_supplicant_deauthenticate(wpa_s,
WLAN_REASON_UNSPECIFIED);
return -1; 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 */ #endif /* CONFIG_SME */
/* Additional processing for FILS when SME is in driver */ /* Additional processing for FILS when SME is in driver */
@ -3537,6 +3556,9 @@ no_pfs:
wpa_s, WLAN_REASON_INVALID_IE); wpa_s, WLAN_REASON_INVALID_IE);
return -1; 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; p = data->assoc_info.resp_ies;
@ -3598,6 +3620,9 @@ no_pfs:
return -1; return -1;
} }
wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done"); 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, wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,

View file

@ -1609,6 +1609,8 @@ struct wpa_supplicant {
struct wpa_radio_work *nan_usd_listen_work; struct wpa_radio_work *nan_usd_listen_work;
struct wpa_radio_work *nan_usd_tx_work; struct wpa_radio_work *nan_usd_tx_work;
#endif /* CONFIG_NAN_USD */ #endif /* CONFIG_NAN_USD */
bool ssid_verified;
}; };

View file

@ -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) int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
{ {
#ifndef CONFIG_NO_WPA #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; ctx->set_ltf_keyseed = wpa_supplicant_set_ltf_keyseed;
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
ctx->notify_pmksa_cache_entry = wpa_supplicant_notify_pmksa_cache_entry; 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); wpa_s->wpa = wpa_sm_init(ctx);
if (wpa_s->wpa == NULL) { if (wpa_s->wpa == NULL) {