From patchwork Wed Feb 15 23:08:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Otcheretianski X-Patchwork-Id: 1743185 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=DS9RBh5A; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=H+7wuBip; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PHF7807Rsz23h0 for ; Thu, 16 Feb 2023 10:45:08 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=qKdoGxbk+c5D4QJh4UHTW3kAgXw6bjA7eDmHUmaATKY=; b=DS9RBh5AI+5JSg zpqxnL18jg4KHCXOJBDSsPFuyVZR1f9lNK3Fi+s8WCZLYf7z8Q7g4p8zkWMvSWO046xFUdGPYGowG 6ugpkPXfbKzfSKiNdGSIRpAuAZODhCSW4GjKUR/mnMfeOHs74KcpTiPHERFhrPZYvF+fp1Axtbw71 Ua+ZEwsiFbSo2SHP2Aao7TEOvivOruxoPlIjnyff432MJh5foeIHvCXDJqaU0fzdmDLKyjRpYdL9R VViFTh8/+cUnR8hNi48KJS4qQhBtICAEMCH7oVcCcROADzEn+8UUv/y1J3e7NQuSTGpJsYkV/sMfp bJ8wg9j6tZQpeDasdIXA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pSRRb-007wZP-No; Wed, 15 Feb 2023 23:44:12 +0000 Received: from mga03.intel.com ([134.134.136.65]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pSQvC-007ljz-Bl for hostap@lists.infradead.org; Wed, 15 Feb 2023 23:10:44 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676502642; x=1708038642; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cpSUWz+rB6oEKqoPnpLTZmF/R9To+U0xQghpGfAJw9U=; b=H+7wuBipUy7v0vZpJ4O98LRC104xiGOp0TSdoBQiaQuYkgm8Hu9VFKvh b/G4f+1252SFG2hllAFbMBcg8YU36T7aIrmFthcAAjicdMnsNbMI9Vilc TvAGKLDTX23nH51I8mdEXFxz0ZOOiWIYyuKtk+5qFvI8NU/yRh6P6ynBg g1YnK9B3DC7Lh6u6Ayk2dJtBovNISx4yikMfklmyhm+CdAEyQwS8ArtI7 /8wIFct1nP3NDFXI2dfwffoejULGkwu1RoqsElqkiI+Iw0PDNnafrGg+c fE05S8MOOZUl25NJTKpcPpHfOFXnsYjSSI0kmiKbRvf32k2BxJZVH81Cj A==; X-IronPort-AV: E=McAfee;i="6500,9779,10622"; a="333719786" X-IronPort-AV: E=Sophos;i="5.97,300,1669104000"; d="scan'208";a="333719786" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2023 15:10:19 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10622"; a="702344496" X-IronPort-AV: E=Sophos;i="5.97,300,1669104000"; d="scan'208";a="702344496" Received: from zfilgut-mobl.ger.corp.intel.com (HELO aotchere-desk.intel.com) ([10.254.144.126]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2023 15:10:17 -0800 From: Andrei Otcheretianski To: hostap@lists.infradead.org Cc: Andrei Otcheretianski , Ilan Peer Subject: [PATCH 37/50] WPA_AUTH: MLO: Store MLO link information Date: Thu, 16 Feb 2023 01:08:51 +0200 Message-Id: <20230215230904.933291-38-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230215230904.933291-1-andrei.otcheretianski@intel.com> References: <20230215230904.933291-1-andrei.otcheretianski@intel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230215_151042_537130_F4980781 X-CRM114-Status: GOOD ( 20.29 ) X-Spam-Score: -2.7 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Signed-off-by: Ilan Peer Signed-off-by: Andrei Otcheretianski --- src/ap/ieee802_11.c | 28 +++++++++-- src/ap/wpa_auth.c | 111 +++++++++++++++++ [...] Content analysis details: (-2.7 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.65 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.2 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Signed-off-by: Ilan Peer Signed-off-by: Andrei Otcheretianski --- src/ap/ieee802_11.c | 28 +++++++++-- src/ap/wpa_auth.c | 111 +++++++++++++++++++++++++++++++++++++++++ src/ap/wpa_auth.h | 44 ++++++++++++++++ src/ap/wpa_auth_glue.c | 46 +++++++++++++++++ src/ap/wpa_auth_i.h | 16 ++++++ 5 files changed, 240 insertions(+), 5 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 10af54b484..c302f01804 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3929,15 +3929,33 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, wpa_ie -= 2; wpa_ie_len += 2; - if (sta->wpa_sm == NULL) + if (!sta->wpa_sm) { +#ifdef CONFIG_IEEE80211BE + struct mld_info *info = &sta->mld_info; +#endif /* CONFIG_IEEE80211BE */ + sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr, p2p_dev_addr); - if (sta->wpa_sm == NULL) { - wpa_printf(MSG_WARNING, "Failed to initialize WPA " - "state machine"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + + if (!sta->wpa_sm) { + wpa_printf(MSG_WARNING, + "Failed to initialize WPA SM"); + return WLAN_STATUS_UNSPECIFIED_FAILURE; + } + +#ifdef CONFIG_IEEE80211BE + if (info->mld_sta) { + wpa_printf(MSG_DEBUG, "MLD: used for WPA"); + + wpa_auth_set_ml_info(sta->wpa_sm, + hapd->mld_addr, + sta->mld_assoc_link_id, + info); + } +#endif /* CONFIG_IEEE80211BE */ } + wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg); res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, hapd->iface->freq, diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index a9227a4f15..a1e5d9bb52 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -33,6 +33,7 @@ #include "pmksa_cache_auth.h" #include "wpa_auth_i.h" #include "wpa_auth_ie.h" +#include "sta_info.h" static const u8 *wpa_auth_get_aa(struct wpa_state_machine *sm) { @@ -694,6 +695,7 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr, sm->wpa_auth = wpa_auth; sm->group = wpa_auth->group; wpa_group_get(sm->wpa_auth, sm->group); + sm->mld_assoc_link_id = -1; return sm; } @@ -787,6 +789,11 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm) #ifdef CONFIG_DPP2 wpabuf_clear_free(sm->dpp_z); #endif /* CONFIG_DPP2 */ + os_memset(sm->own_mld_addr, 0, sizeof(sm->own_mld_addr)); + os_memset(sm->peer_mld_addr, 0, sizeof(sm->peer_mld_addr)); + sm->mld_assoc_link_id = -1; + os_memset(sm->mld_links, 0, sizeof(sm->mld_links)); + bin_clear_free(sm, sizeof(*sm)); } @@ -3587,6 +3594,29 @@ static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid, } #endif /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_IEEE80211BE + +void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a, + struct wpa_auth_ml_link_rsn_info *info) +{ + info->rsn_ies = a->wpa_ie; + info->rsn_ies_len = a->wpa_ie_len; + + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: RSN info: link_id=%u, rsn_ies_len=%u", + info->link_id, info->rsn_ies_len); +} + + +static void wpa_auth_get_ml_rsn_info(struct wpa_authenticator *wpa_auth, + struct wpa_auth_ml_rsn_info *info) +{ + if (!wpa_auth->cb->get_ml_rsn_info) + return; + + wpa_auth->cb->get_ml_rsn_info(wpa_auth->cb_ctx, info); +} +#endif /* CONFIG_IEEE80211BE */ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) { @@ -6024,3 +6054,84 @@ void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success) eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL); } + + +void wpa_auth_set_ml_info(struct wpa_state_machine *sm, + const u8 *mld_addr, u8 mld_assoc_link_id, + struct mld_info *info) +{ +#ifdef CONFIG_IEEE80211BE + struct wpa_auth_ml_rsn_info ml_rsn_info; + u32 link_id, i; + + if (!info) + return; + + os_memset(sm->mld_links, 0, sizeof(sm->mld_links)); + + wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG, + "MLD: initialization"); + + os_memcpy(sm->own_mld_addr, mld_addr, ETH_ALEN); + os_memcpy(sm->peer_mld_addr, info->common_info.mld_addr, ETH_ALEN); + + sm->mld_assoc_link_id = mld_assoc_link_id; + + os_memset(&ml_rsn_info, 0, sizeof(ml_rsn_info)); + + for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { + struct mld_link_info *link = &info->links[link_id]; + struct mld_link *sm_link = &sm->mld_links[link_id]; + + sm_link->valid = link->valid; + + if (!link->valid) + continue; + + os_memcpy(sm_link->peer_addr, link->peer_addr, ETH_ALEN); + os_memcpy(sm_link->own_addr, link->local_addr, ETH_ALEN); + + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: id=%u, addr=" MACSTR " peer=" MACSTR, + link_id, + MAC2STR(sm_link->own_addr), + MAC2STR(sm_link->peer_addr)); + + if (link_id != mld_assoc_link_id) + sm->n_mld_affiliated_links++; + + ml_rsn_info.links[i++].link_id = link_id; + } + + ml_rsn_info.n_mld_links = i; + + wpa_auth_get_ml_rsn_info(sm->wpa_auth, &ml_rsn_info); + + for (i = 0; i < ml_rsn_info.n_mld_links; i++) { + u8 link_id = ml_rsn_info.links[i].link_id; + struct mld_link *sm_link = &sm->mld_links[link_id]; + const u8 *rsn_ies; + u8 rsn_ies_len; + + rsn_ies = ml_rsn_info.links[i].rsn_ies; + rsn_ies_len = ml_rsn_info.links[i].rsn_ies_len; + + /* This should not really happen */ + if (!rsn_ies || rsn_ies_len < 2 || rsn_ies[0] != WLAN_EID_RSN) { + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: Invalid RSN element"); + continue; + } + + sm_link->rsne = rsn_ies; + sm_link->rsne_len = rsn_ies[1] + 2; + + if (rsn_ies[1] + 2UL + 2UL < rsn_ies_len && + rsn_ies[rsn_ies[1] + 2] == WLAN_EID_RSNX) { + sm_link->rsnxe = rsn_ies + 2 + rsn_ies[1]; + sm_link->rsnxe_len = sm_link->rsnxe[1] + 2; + } + } + +#endif /* CONFIG_IEEE80211BE */ +} diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index eed016accb..fbd9d84f8b 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -15,6 +15,7 @@ #include "common/ieee802_11_defs.h" struct vlan_description; +struct mld_info; #define MAX_OWN_IE_OVERRIDE 256 @@ -288,6 +289,40 @@ typedef enum { WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx } wpa_eapol_variable; +struct wpa_auth_ml_rsn_info { + u8 n_mld_links; + + struct wpa_auth_ml_link_rsn_info { + u8 link_id; + const u8 *rsn_ies; + u8 rsn_ies_len; + } links[MAX_NUM_MLD_LINKS]; +}; + +struct wpa_auth_ml_key_info { + u8 n_mld_links; + bool mgmt_frame_prot; + bool beacon_prot; + + struct wpa_auth_ml_link_key_info { + u8 link_id; + + u8 gtkidx; + u8 gtk_len; + u8 pn[6]; + const u8 *gtk; + + u8 igtkidx; + u8 igtk_len; + const u8 *igtk; + u8 ipn[6]; + + u8 bigtkidx; + const u8 *bigtk; + u8 bipn[6]; + } links[MAX_NUM_MLD_LINKS]; +}; + struct wpa_auth_callbacks { void (*logger)(void *ctx, const u8 *addr, logger_level level, const char *txt); @@ -355,6 +390,9 @@ struct wpa_auth_callbacks { int (*set_ltf_keyseed)(void *ctx, const u8 *addr, const u8 *ltf_keyseed, size_t ltf_keyseed_len); #endif /* CONFIG_PASN */ +#ifdef CONFIG_IEEE80211BE + int (*get_ml_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info); +#endif /* CONFIG_IEEE80211BE */ }; struct wpa_authenticator * wpa_init(const u8 *addr, @@ -593,4 +631,10 @@ void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth, void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success); +void wpa_auth_set_ml_info(struct wpa_state_machine *sm, + const u8 *mld_addr, + u8 mld_assoc_link_id, + struct mld_info *info); +void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a, + struct wpa_auth_ml_link_rsn_info *info); #endif /* WPA_AUTH_H */ diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 9090ba7840..e15013c11b 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1496,6 +1496,49 @@ static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr, } #endif /* CONFIG_PASN */ +#ifdef CONFIG_IEEE80211BE + +static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx, + struct wpa_auth_ml_rsn_info *info) +{ + struct hostapd_data *hapd = ctx; + u8 i, j; + + wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: get RSN info CB: n_mld_links=%u", + info->n_mld_links); + + if (!hapd->conf->mld_ap || !hapd->iface || !hapd->iface->interfaces) + return -1; + + for (i = 0; i < info->n_mld_links; i++) { + u8 link_id = info->links[i].link_id; + + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: get link RSN CB: link_id=%u", + link_id); + + for (j = 0; j < hapd->iface->interfaces->count; j++) { + struct hostapd_iface *iface = + hapd->iface->interfaces->iface[j]; + + if (!iface->bss[0]->conf->mld_ap || + hapd->conf->mld_id != iface->bss[0]->conf->mld_id || + link_id != iface->bss[0]->conf->mld_link_id) + continue; + + wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth, + &info->links[i]); + break; + } + + if (j == hapd->iface->interfaces->count) + wpa_printf(MSG_DEBUG, + "WPA_AUTH: MLD: link=%u not found", link_id); + } + + return 0; +} +#endif /* CONFIG_IEEE80211BE */ int hostapd_setup_wpa(struct hostapd_data *hapd) { @@ -1546,6 +1589,9 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) #ifdef CONFIG_PASN .set_ltf_keyseed = hostapd_set_ltf_keyseed, #endif /* CONFIG_PASN */ +#ifdef CONFIG_IEEE80211BE + .get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info, +#endif /* CONFIG_IEEE80211BE */ }; const u8 *wpa_ie; size_t wpa_ie_len; diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index f3cb9be31f..c3f1c19e9d 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -172,6 +172,22 @@ struct wpa_state_machine { void *eapol_status_cb_ctx1; void *eapol_status_cb_ctx2; #endif /* CONFIG_TESTING_OPTIONS */ + + u8 own_mld_addr[ETH_ALEN]; + u8 peer_mld_addr[ETH_ALEN]; + s8 mld_assoc_link_id; + u8 n_mld_affiliated_links; + + struct mld_link { + bool valid; + u8 peer_addr[ETH_ALEN]; + u8 own_addr[ETH_ALEN]; + + const u8 *rsne; + const u8 *rsnxe; + u8 rsne_len; + u8 rsnxe_len; + } mld_links[MAX_NUM_MLD_LINKS]; };