[PATCH 09/12] MLD STA: Add support for validating MLO KDEs for 4WHS EAPOL frames

Veerendranath Jakkam quic_vjakkam at quicinc.com
Wed Aug 24 22:53:08 PDT 2022


Validate new KDEs defined for MLO connection in EAPOL 1/4 and 3/4 and
reject the Four-Way handshake frames if any of the new KDE data is not
matching expected key data.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
---
 src/rsn_supp/wpa.c | 147 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 96adc4817..9a4e0ebee 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -785,6 +785,14 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
 		}
 	}
 
+	if (sm->valid_links &&
+	    (!ie.mac_addr || ie.mac_addr_len < ETH_ALEN ||
+	     os_memcmp(ie.mac_addr, sm->ap_mld_addr, ETH_ALEN))) {
+		wpa_printf(MSG_INFO,
+			  "RSN MLO: Discard EAPOL-Key msg 1/4 with invalid MAC address KDE");
+		return;
+	}
+
 	res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
 	if (res == -2) {
 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
@@ -2092,6 +2100,131 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
 }
 
 
+static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm,
+					    u8 link_id,
+					    const u8 *link_kde,
+					    size_t link_kde_len)
+{
+	struct wpa_mlo_link_hdr *link_kde_hdr;
+	size_t rsn_ie_len = 0, rsnxe_len = 0;
+	const u8 *rsn_ie = NULL, *rsnxe = NULL;
+
+	if (!link_kde || link_kde_len < sizeof(*link_kde_hdr)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"WPA MLO: Invalid link KDE for link ID %d",
+			link_id);
+		return -1;
+	}
+
+	link_kde_hdr = (struct wpa_mlo_link_hdr *) link_kde;
+
+	if (os_memcmp(sm->links[link_id].bssid, link_kde_hdr->mac, ETH_ALEN)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"WPA MLO: Link MAC address not matching with assoc response");
+		return -1;
+	}
+
+	if (link_kde_hdr->rsne_present) {
+		rsn_ie = link_kde + sizeof(*link_kde_hdr);
+		if (link_kde_len < (sizeof(*link_kde_hdr) + 2) ||
+		    link_kde_len < (sizeof(*link_kde_hdr) + 2 + rsn_ie[1]))
+			return -1;
+
+		rsn_ie_len = rsn_ie[1] + 2;
+	}
+
+	if (link_kde_hdr->rsnxe_present) {
+		rsnxe = link_kde + sizeof(*link_kde_hdr) + rsn_ie_len;
+		if (link_kde_len < (sizeof(*link_kde_hdr) + rsn_ie_len + 2) ||
+		    link_kde_len < (sizeof(*link_kde_hdr) + rsn_ie_len + 2 +
+				    rsnxe[1]))
+			return -1;
+
+		rsnxe_len = rsnxe[1] + 2;
+	}
+
+	if (sm->links[link_id].ap_rsn_ie == NULL) {
+		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+			"WPA MLO: No RSN IE AP link ID %u known. "
+			"Trying to get from scan results", link_id);
+		if (wpa_sm_get_link_beacon_ie(sm, link_id) < 0) {
+			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+				"WPA MLO: Could not find AP from "
+				"the scan results");
+			return -1;
+		}
+		wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
+			"WPA MLO: Found the current AP from updated scan results");
+	}
+
+	if (rsn_ie == NULL && sm->links[link_id].ap_rsn_ie) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"WPA MLO: IE in 3/4 msg does not match with IE in Beacon/ProbeResp (no IE?) for link ID %u",
+			link_id);
+		return -1;
+	}
+
+	if (rsn_ie && sm->links[link_id].ap_rsn_ie &&
+	    wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
+			       sm->links[link_id].ap_rsn_ie,
+			       sm->links[link_id].ap_rsn_ie_len,
+			       rsn_ie, rsn_ie_len)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"WPA MLO: IE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
+			link_id);
+		wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp",
+			    sm->links[link_id].ap_rsnxe,
+			    sm->links[link_id].ap_rsnxe_len);
+		wpa_hexdump(MSG_INFO, "RSNE in EAPOL-Key msg 3/4",
+			    rsn_ie, rsn_ie_len);
+		return -1;
+	}
+
+	if ((sm->links[link_id].ap_rsnxe && !rsnxe) ||
+	    (!sm->links[link_id].ap_rsnxe && rsnxe) ||
+	    (sm->links[link_id].ap_rsnxe && rsnxe &&
+	     (sm->links[link_id].ap_rsnxe_len != rsnxe_len ||
+	      os_memcmp(sm->links[link_id].ap_rsnxe, rsnxe,
+			sm->links[link_id].ap_rsnxe_len) != 0))) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"WPA MLO: RSNXE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4 for link ID %u",
+			link_id);
+		wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp",
+			    sm->links[link_id].ap_rsnxe,
+			    sm->links[link_id].ap_rsnxe_len);
+		wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4",
+			    rsnxe, rsnxe_len);
+		wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int wpa_validate_mlo_kdes(struct wpa_sm *sm,
+				 u8 link_id, struct wpa_eapol_ie_parse *ie)
+{
+	if (ie->mlo_igtk[link_id] &&
+	    sm->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED &&
+	    wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
+	    ie->mlo_igtk_len[link_id] != sizeof(struct wpa_mlo_igtk_hdr) +
+	    (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+			"WPA MLO: Invalid IGTK KDE length %lu for link ID %u",
+			(unsigned long) ie->mlo_igtk_len, link_id);
+		return -1;
+	}
+
+	if (wpa_supplicant_validate_link_kde(sm, link_id,
+					     ie->mlo_link[link_id],
+					     ie->mlo_link_len[link_id]))
+		return -1;
+
+	return 0;
+}
+
+
 static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 					      const struct wpa_eapol_key *key,
 					      u16 ver, const u8 *key_data,
@@ -2099,6 +2232,7 @@ static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 {
 	u16 key_info, keylen;
 	struct wpa_eapol_ie_parse ie;
+	int i;
 
 	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
 	wpa_dbg(sm->ctx->msg_ctx, MSG_INFO, "WPA MLO: RX message 3 of 4-Way "
@@ -2121,6 +2255,19 @@ static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 		goto failed;
 	}
 
+	if (!ie.mac_addr || ie.mac_addr_len < ETH_ALEN ||
+	    os_memcmp(ie.mac_addr, sm->ap_mld_addr, ETH_ALEN)) {
+		wpa_printf(MSG_DEBUG, "RSN MLO: Invalid MAC address KDE");
+		goto failed;
+	}
+
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(sm->valid_links & BIT(i)))
+			continue;
+
+		if (wpa_validate_mlo_kdes(sm, i, &ie))
+			goto failed;
+	}
 
 #ifdef CONFIG_IEEE80211R
 	if (wpa_key_mgmt_ft(sm->key_mgmt) &&
-- 
2.25.1




More information about the Hostap mailing list