[PATCH 14/20] WPA: Verify Security Profile element in protected delivery

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Jun 10 06:12:07 PDT 2026


From: Ilan Peer <ilan.peer at intel.com>

Based on Draft P802.11bn (D1.4), the non-AP MLD needs to verify that the
Security Profile element delivered via the protected channel matches
the one advertised by the AP in Beacon or Probe Response frames:

- If the (Re)Association Request frame is encrypted, the verification
  is performed against the element (if present) in the (Re)Association
  Response frame.

- If the (Re)Association Request frame is not encrypted, the
  verification is performed against the element (if present) in
  message 3 of the 4-way handshake.

If this verification fails, deauthenticate.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/rsn_supp/wpa.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 0d8531f823..e0b9241583 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -2215,6 +2215,59 @@ static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
 #endif /* CONFIG_IEEE80211R */
 
 
+/*
+ * wpa_supplicant_validate_security_profile - Verify Security Profile element
+ * @sm: WPA state machine
+ * @src_addr: Source MAC address (for debug/disconnect)
+ * @payload: Pointer to the Security Profile element payload (after the
+ *	Element ID Extension octet), or %NULL if not present
+ * @payload_len: Length of @payload in octets
+ * Returns: 0 on success, -1 on mismatch
+ *
+ * Verify that the Security Profile element advertised by the AP in the Beacon
+ * or Probe Response frame is the same as the one delivered through the
+ * protected channel (encrypted (Re)Association Response or message 3 of the
+ * 4-way handshake).
+ */
+static int wpa_supplicant_validate_security_profile(struct wpa_sm *sm,
+						    const u8 *src_addr,
+						    const u8 *payload,
+						    size_t payload_len)
+{
+	const u8 *ap_payload = NULL;
+	size_t ap_payload_len = 0;
+
+	if (sm->ap_security_profile && sm->ap_security_profile_len) {
+		ap_payload = sm->ap_security_profile;
+		ap_payload_len = sm->ap_security_profile_len;
+	}
+
+	if (!payload && !ap_payload)
+		return 0;
+
+	if (!payload || !ap_payload ||
+	    payload_len != ap_payload_len ||
+	    os_memcmp(payload, ap_payload, payload_len) != 0) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"RSN: Security Profile element mismatch between Beacon/ProbeResp and protected delivery");
+
+		wpa_hexdump(MSG_INFO,
+			    "Security Profile element in Beacon/ProbeResp",
+			    ap_payload, ap_payload_len);
+
+		wpa_hexdump(MSG_INFO,
+			    "Security Profile element in protected delivery",
+			    payload, payload_len);
+
+		wpa_sm_deauthenticate(sm,
+				      WLAN_STATUS_REJECTED_INVALID_SECURITY_PROFILE);
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
 				      const unsigned char *src_addr,
 				      struct wpa_eapol_ie_parse *ie)
@@ -2351,6 +2404,20 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
 		return -1;
 #endif /* CONFIG_IEEE80211R */
 
+	if (sm->proto == WPA_PROTO_RSN) {
+		const u8 *secp = NULL;
+		size_t secp_len = 0;
+
+		if (ie->security_profile) {
+			secp = ie->security_profile;
+			secp_len = ie->security_profile_len;
+		}
+		if (wpa_supplicant_validate_security_profile(sm, src_addr,
+							     secp,
+							     secp_len) < 0)
+			return -1;
+	}
+
 	return 0;
 }
 
@@ -7897,6 +7964,12 @@ int process_encrypted_assoc_resp(struct wpa_sm *sm, int valid_links,
 			return -1;
 	}
 
+	if (wpa_supplicant_validate_security_profile(sm, sm->bssid,
+						     elems.security_profile,
+						     elems.security_profile_len)
+	    < 0)
+		return -1;
+
 	/* TODO: Check for RSNE/RSNXE mismatch for per-STA profile for MLO */
 
 	/* Key Delivery element */
-- 
2.53.0




More information about the Hostap mailing list