[PATCH v4 08/13] MLD STA: Add support for validating MLO KDEs for 4WHS EAPOL frames

Veerendranath Jakkam quic_vjakkam at quicinc.com
Thu Nov 3 01:08:51 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 | 171 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 1 deletion(-)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 0e6e4d1c1..95f9e930a 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -773,6 +773,13 @@ static u8 *wpa_mlo_link_kde(struct wpa_sm *sm, u8 *pos)
 	return pos;
 }
 
+
+static bool is_valid_ap_mld_mac_kde(struct wpa_sm *sm, const u8 *mac_kde)
+{
+	return mac_kde && !os_memcmp(mac_kde, sm->mlo.ap_mld_addr, ETH_ALEN);
+}
+
+
 static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
 					  const unsigned char *src_addr,
 					  const struct wpa_eapol_key *key,
@@ -828,6 +835,12 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
 		}
 	}
 
+	if (sm->mlo.valid_links && !is_valid_ap_mld_mac_kde(sm, ie.mac_addr)) {
+		wpa_printf(MSG_INFO,
+			  "RSN: Discard EAPOL-Key msg 1/4 with invalid AP MLD 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 "
@@ -2131,6 +2144,133 @@ 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)
+{
+	size_t rsne_len = 0, rsnxe_len = 0;
+	const u8 *rsne = NULL, *rsnxe = NULL;
+
+	if (!link_kde) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN: MLO Link KDE is not found for link ID %d",
+			link_id);
+		return -1;
+	}
+
+	if (os_memcmp(sm->mlo.links[link_id].bssid,
+		      &link_kde[RSN_MLO_LINK_KDE_LINK_MAC_INDEX], ETH_ALEN)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN: MLO Link %u MAC address not matching with assoc response",
+			link_id);
+		return -1;
+	}
+
+	if (link_kde[0] & RSN_MLO_LINK_KDE_LI_RSNE_INFO) {
+		rsne = link_kde + RSN_MLO_LINK_KDE_FIXED_LENGTH;
+		if (link_kde_len < (RSN_MLO_LINK_KDE_FIXED_LENGTH + 2) ||
+		    link_kde_len <
+		    (RSN_MLO_LINK_KDE_FIXED_LENGTH + 2 + rsne[1]))
+			return -1;
+
+		rsne_len = rsne[1] + 2;
+	}
+
+	if (!rsne) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN: RSNE not present in MLO Link %u KDE",
+			link_id);
+		return -1;
+	}
+
+	if (link_kde[0] & RSN_MLO_LINK_KDE_LI_RSNXE_INFO) {
+		rsnxe = link_kde + RSN_MLO_LINK_KDE_FIXED_LENGTH + rsne_len;
+		if (link_kde_len <
+		    (RSN_MLO_LINK_KDE_FIXED_LENGTH + rsne_len + 2) ||
+		    link_kde_len <
+		    (RSN_MLO_LINK_KDE_FIXED_LENGTH + rsne_len + 2 + rsnxe[1]))
+			return -1;
+
+		rsnxe_len = rsnxe[1] + 2;
+	}
+
+	if (wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
+			       sm->mlo.links[link_id].ap_rsne,
+			       sm->mlo.links[link_id].ap_rsne_len,
+			       rsne, rsne_len)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN 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->mlo.links[link_id].ap_rsne,
+			    sm->mlo.links[link_id].ap_rsne_len);
+		wpa_hexdump(MSG_INFO, "RSNE in EAPOL-Key msg 3/4",
+			    rsne, rsne_len);
+		return -1;
+	}
+
+	if ((sm->mlo.links[link_id].ap_rsnxe && !rsnxe) ||
+	    (!sm->mlo.links[link_id].ap_rsnxe && rsnxe) ||
+	    (sm->mlo.links[link_id].ap_rsnxe && rsnxe &&
+	     (sm->mlo.links[link_id].ap_rsnxe_len != rsnxe_len ||
+	      os_memcmp(sm->mlo.links[link_id].ap_rsnxe, rsnxe,
+			sm->mlo.links[link_id].ap_rsnxe_len) != 0))) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+			"RSN 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->mlo.links[link_id].ap_rsnxe,
+			    sm->mlo.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_ieee80211w_kdes(struct wpa_sm *sm,
+					    u8 link_id,
+					    struct wpa_eapol_ie_parse *ie)
+{
+	if (!ie->mlo_igtk[link_id]) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN: IGTK not found for link ID %u", link_id);
+		return -1;
+	}
+
+	if (ie->mlo_igtk_len[link_id] != RSN_MLO_IGTK_KDE_PREFIX_LENGTH +
+	    (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 (!sm->beacon_prot)
+		return 0;
+
+	if (!ie->mlo_bigtk[link_id]) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+			"RSN: BIGTK not found for link ID %u", link_id);
+		return -1;
+	}
+
+	if (ie->mlo_bigtk_len[link_id] != RSN_MLO_BIGTK_KDE_PREFIX_LENGTH +
+	    (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+			"WPA MLO: Invalid BIGTK KDE length %lu for link ID %u",
+			(unsigned long) ie->mlo_bigtk_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,
@@ -2138,7 +2278,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 res;
+	int res, i;
 
 	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
 	wpa_dbg(sm->ctx->msg_ctx, MSG_INFO, "RSN MLO: RX message 3 of 4-Way "
@@ -2165,6 +2305,35 @@ static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 		goto failed;
 	}
 
+	if (!is_valid_ap_mld_mac_kde(sm, ie.mac_addr)) {
+		wpa_printf(MSG_DEBUG, "RSN: Invalid AP MLD MAC address KDE");
+		goto failed;
+	}
+
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(sm->mlo.req_links & BIT(i)))
+			continue;
+
+		if (wpa_supplicant_validate_link_kde(sm, i, ie.mlo_link[i],
+						     ie.mlo_link_len[i]) < 0)
+			goto failed;
+
+		if (!(sm->mlo.valid_links & BIT(i)))
+			continue;
+
+		if (!ie.mlo_gtk[i]) {
+			wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+				"RSN: GTK not found for link ID %u", i);
+			goto failed;
+		}
+
+		if (!wpa_sm_pmf_enabled(sm))
+			continue;
+
+		if (wpa_validate_mlo_ieee80211w_kdes(sm, i, &ie) < 0)
+			goto failed;
+	}
+
 #ifdef CONFIG_IEEE80211R
 	if (wpa_key_mgmt_ft(sm->key_mgmt) &&
 	    wpa_supplicant_validate_ie_ft(sm, sm->bssid, &ie) < 0)
-- 
2.25.1




More information about the Hostap mailing list