From patchwork Mon May 22 19:33:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Otcheretianski X-Patchwork-Id: 1784684 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=ADc09OUX; 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=H9l9LORm; 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 4QQ8jM3J1Pz20Q6 for ; Tue, 23 May 2023 06:50:30 +1000 (AEST) 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=E7FJEJih0CBGuaVI00LKrUMjaumm1jEtBWUEbyZP7/Q=; b=ADc09OUXDAmO+a czV08phPv4cpwYooUV4rTUnpR1nZLyxfnRRxjsHy2IEi/uLKshfe7JlqtAnAXcsqAd/WRYlSwDVp8 975zVSOJepl2r8CwKMCgZgE5Yb0+Pm00DwFjHReXxtgMuJX11HMk1sAVO1kfQhLabPbwQ/015RwIK Ngn5IA8w9Y6zmB8U6KmBQP5nQ+R141A5dEYY2bVMUeRZyPrEzrM9w0JwXAt7rtOB1C8ijYKkyWieK Tm3eTVkWWe85v/3tzs+bD6QGte5PYZMZCWJYa2IrXL5IAAu8d4OA8Rf7VCyDEs4MrphIYai8Dxw97 4KBGa114idT7KE+mqpsQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1CTZ-007y5j-0n; Mon, 22 May 2023 20:49:53 +0000 Received: from mga04.intel.com ([192.55.52.120]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1BJW-007i5r-1W for hostap@lists.infradead.org; Mon, 22 May 2023 19:35:31 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684784126; x=1716320126; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DiTPKQZlx/V9alXFoDNSqBh/aHrvYCqof/HAOmw6pc8=; b=H9l9LORmrpz7SlZkXOmiGQ4xVoohcJ04kD2Aedc2670YDDv+Cq5ut/Th EJn3wP847UKZyylq4YxTQeoV8jAvo43vJ1fPfD/syLemGYeGeV4pG55ON IfIcF8MSjUhK1Vhwsbt5ahrINZRqVuVhmIoUQi14ALcLhZcXZ3av1DxXg zn5+q6oBzPKtsfIZFmABzfuDOwzUdw/5lQmipuE0NUJrcE47cqbKxCnWU kxc7hNk05WGoXs5Dc0bV6aQ54HdILwt70jMMmVyzL/wkE/YJSsUiu1bH1 hCWUvMRn3cy8RP77QCkC8EEZo0bYVw0Ayp6NdzFU++du64UUIc6iHPiOM Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10718"; a="351869300" X-IronPort-AV: E=Sophos;i="6.00,184,1681196400"; d="scan'208";a="351869300" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 12:35:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10718"; a="827809378" X-IronPort-AV: E=Sophos;i="6.00,184,1681196400"; d="scan'208";a="827809378" Received: from ghorst-mobl3.ger.corp.intel.com (HELO aotchere-desk.intel.com) ([10.254.149.56]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 12:35:23 -0700 From: Andrei Otcheretianski To: hostap@lists.infradead.org Cc: Andrei Otcheretianski , Ilan Peer Subject: [PATCH v2 31/44] WPA_AUTH: MLO: Store MLO link information Date: Mon, 22 May 2023 22:33:59 +0300 Message-Id: <20230522193412.658666-32-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230522193412.658666-1-andrei.otcheretianski@intel.com> References: <20230522193412.658666-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-20230522_123526_749240_95138D4C X-CRM114-Status: GOOD ( 20.22 ) 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 [192.55.52.120 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 43558a0e46..6fd9416eed 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3968,15 +3968,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 12b49704b9..f661585611 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" #define STATE_MACHINE_DATA struct wpa_state_machine #define STATE_MACHINE_DEBUG_PREFIX "WPA" @@ -695,6 +696,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; } @@ -788,6 +790,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)); } @@ -3589,6 +3596,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) { @@ -6026,3 +6056,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 8517f6954a..236f2f6001 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]->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 d401550c7a..e0f2d6fa4b 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]; };