From patchwork Thu Aug 25 05:53:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Veerendranath Jakkam X-Patchwork-Id: 1670060 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=l4YzdIJa; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=quicinc.com header.i=@quicinc.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=croncKwj; 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 4MCscn2sglz1ygc for ; Thu, 25 Aug 2022 15:55:05 +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=4IVqStDB3b0To2ukWZ0lvsHuBZqloP7S6ijOln0hkwU=; b=l4YzdIJakTjKuN jJ2eb0fBg0TGNg96+Rd6HNfV2E6F7u4dpGkcvnuX42uD7fAamTd5O2WJd9PJeA9ZcMS1qsCKpiAo4 F5/7cbdGmugrcw6oolywS+RA0kuAtU+HQGr9yz58UtlhI6j04AyU/Kixw8Ep+yiSf2SwmjepKTX37 wqkxwhr+sdybaOfQb0cmEtdu0Ek6AaTQnE/DSgBnfUAWJ9UIur0Ubh7ziGOVJCBb4uu66VUn9Lfzc U1CjFul3mgCXV9TkQGtyjQrnpGYbbwxY6ClzCgjYasJatDSIOC6eEItJpuIsft4RtIUxi8HoHQo2D /qsplwCB5h99ASBjvIsw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oR5od-007aeq-1s; Thu, 25 Aug 2022 05:54:07 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oR5o5-007Z28-68 for hostap@lists.infradead.org; Thu, 25 Aug 2022 05:53:37 +0000 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27P2lrvi018229 for ; Thu, 25 Aug 2022 05:53:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=qcppdkim1; bh=ylAR0Sx+kMXGAVkPst8yzapKmpgM8Ppp5Haug1jT7B8=; b=croncKwjXHslsYZbCw0jg+gqpelpQQunBJMSKqGJDAQyHr2Bx0NM6Rrh5EcnaspDKMHZ FL81vjvUgy8PIvEKeYaepMHN54Ns6D1uX7V3nOAcbuwRC6sfdL4suS68ICqJ9TAPX+Cw xvoSOel84N2r0T8uN2tC53BDNSaTyVoSKMhoJ+Xfl1H+6W8E67hGd2/DbURhrNRO7xaN qZcDd54JSki7/7+LCLcXUNCfQERlfUFR1C/baNsHxpx6Hp2nGboo3iGKG5Gc2pehnKc/ FRm3G8MSg87zIMHV6Nfs1i0FsKPozwVQe5s/muPYOPu67aq9eFdkhLABQLzD9dn3O5Lp Bg== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j5w5jgsp9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 25 Aug 2022 05:53:28 +0000 Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27P5rR3o008406 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 25 Aug 2022 05:53:27 GMT Received: from cnss-mw-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Wed, 24 Aug 2022 22:53:26 -0700 From: Veerendranath Jakkam To: CC: Subject: [PATCH 03/12] MLD STA: Add support to fetch per-link beacon WPA/RSN/RSNX IEs into wpa_sm Date: Thu, 25 Aug 2022 11:23:02 +0530 Message-ID: <20220825055311.3327147-4-quic_vjakkam@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220825055311.3327147-1-quic_vjakkam@quicinc.com> References: <20220825055311.3327147-1-quic_vjakkam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: DYwWOcZdynGMg4H2mfSR5nVbqNGJB4tW X-Proofpoint-GUID: DYwWOcZdynGMg4H2mfSR5nVbqNGJB4tW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-25_03,2022-08-22_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 adultscore=0 priorityscore=1501 clxscore=1015 phishscore=0 mlxscore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208250020 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220824_225333_409686_56C5F9D4 X-CRM114-Status: GOOD ( 26.40 ) X-Spam-Score: -0.2 (/) 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: wpa_sm needs per-link beacon RSN and RSNX IEs for MLO KDE validation. Thus, Add required APIs to parse and set AP link WPA/RSN/RSNX IEs to wpa_sm. Signed-off-by: Veerendranath Jakkam --- src/rsn_supp/wpa.c | 103 +++++++++++++----- src/rsn_supp/wpa.h | 22 ++-- src/rsn_supp/wpa_i.h | 8 ++ tests/fuzzing/eapol-key-supp/eap [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [205.220.180.131 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO 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 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 wpa_sm needs per-link beacon RSN and RSNX IEs for MLO KDE validation. Thus, Add required APIs to parse and set AP link WPA/RSN/RSNX IEs to wpa_sm. Signed-off-by: Veerendranath Jakkam --- src/rsn_supp/wpa.c | 103 +++++++++++++----- src/rsn_supp/wpa.h | 22 ++-- src/rsn_supp/wpa_i.h | 8 ++ tests/fuzzing/eapol-key-supp/eapol-key-supp.c | 2 +- wpa_supplicant/events.c | 66 ++++++++--- wpa_supplicant/ibss_rsn.c | 4 +- wpa_supplicant/wpa_supplicant.c | 19 ++-- wpa_supplicant/wpas_glue.c | 103 +++++++++++++++--- 8 files changed, 247 insertions(+), 80 deletions(-) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index a28d49225..f3965ca50 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -3716,6 +3716,7 @@ int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) /** * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp * @sm: Pointer to WPA state machine data from wpa_sm_init() + * @link_id: MLO link ID to set specific link or -1 to set default * @ie: Pointer to IE data (starting from id) * @len: IE length * Returns: 0 on success, -1 on failure @@ -3723,24 +3724,40 @@ int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) * Inform WPA state machine about the WPA IE used in Beacon / Probe Response * frame. */ -int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len) +int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len) { - if (sm == NULL) + u8 **ap_wpa_ie; + size_t *ap_wpa_ie_len; + + if (!sm) return -1; - os_free(sm->ap_wpa_ie); - if (ie == NULL || len == 0) { + if (link_id == -1) { + ap_wpa_ie = &sm->ap_wpa_ie; + ap_wpa_ie_len = &sm->ap_wpa_ie_len; + } else { + if (link_id < 0 || link_id >= MAX_NUM_MLD_LINKS) + return -1; + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, - "WPA: clearing AP WPA IE"); - sm->ap_wpa_ie = NULL; - sm->ap_wpa_ie_len = 0; + "WPA: set AP WPA IE for link ID %d", link_id); + ap_wpa_ie = &sm->links[link_id].ap_wpa_ie; + ap_wpa_ie_len = &sm->links[link_id].ap_wpa_ie_len; + } + + os_free(*ap_wpa_ie); + if (ie == NULL || len == 0) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: clearing AP WPA IE"); + *ap_wpa_ie = NULL; + *ap_wpa_ie_len = 0; } else { wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len); - sm->ap_wpa_ie = os_memdup(ie, len); - if (sm->ap_wpa_ie == NULL) + *ap_wpa_ie = os_memdup(ie, len); + if (*ap_wpa_ie == NULL) return -1; - sm->ap_wpa_ie_len = len; + *ap_wpa_ie_len = len; } return 0; @@ -3750,6 +3767,7 @@ int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len) /** * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp * @sm: Pointer to WPA state machine data from wpa_sm_init() + * @link_id: MLO link ID to set specific link or -1 to set default * @ie: Pointer to IE data (starting from id) * @len: IE length * Returns: 0 on success, -1 on failure @@ -3757,24 +3775,41 @@ int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len) * Inform WPA state machine about the RSN IE used in Beacon / Probe Response * frame. */ -int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len) +int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len) { - if (sm == NULL) + u8 **ap_rsn_ie; + size_t *ap_rsn_ie_len; + + if (!sm) return -1; - os_free(sm->ap_rsn_ie); + if (link_id == -1) { + ap_rsn_ie = &sm->ap_rsn_ie; + ap_rsn_ie_len = &sm->ap_rsn_ie_len; + } else { + if (link_id < 0 || link_id >= MAX_NUM_MLD_LINKS) + return -1; + + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: set AP RSN IE for link ID %d", link_id); + ap_rsn_ie = &sm->links[link_id].ap_rsn_ie; + ap_rsn_ie_len = &sm->links[link_id].ap_rsn_ie_len; + } + + os_free(*ap_rsn_ie); if (ie == NULL || len == 0) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: clearing AP RSN IE"); - sm->ap_rsn_ie = NULL; - sm->ap_rsn_ie_len = 0; + *ap_rsn_ie = NULL; + *ap_rsn_ie_len = 0; } else { wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len); - sm->ap_rsn_ie = os_memdup(ie, len); - if (sm->ap_rsn_ie == NULL) + *ap_rsn_ie = os_memdup(ie, len); + if (*ap_rsn_ie == NULL) return -1; - sm->ap_rsn_ie_len = len; + *ap_rsn_ie_len = len; } return 0; @@ -3784,6 +3819,7 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len) /** * wpa_sm_set_ap_rsnxe - Set AP RSNXE from Beacon/ProbeResp * @sm: Pointer to WPA state machine data from wpa_sm_init() + * @link_id: MLO link ID to set specific link or -1 to set default * @ie: Pointer to IE data (starting from id) * @len: IE length * Returns: 0 on success, -1 on failure @@ -3791,23 +3827,40 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len) * Inform WPA state machine about the RSNXE used in Beacon / Probe Response * frame. */ -int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len) +int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len) { + u8 **ap_rsnxe; + size_t *ap_rsnxe_len; + if (!sm) return -1; - os_free(sm->ap_rsnxe); + if (link_id == -1) { + ap_rsnxe = &sm->ap_rsnxe; + ap_rsnxe_len = &sm->ap_rsnxe_len; + } else { + if (link_id < 0 || link_id >= MAX_NUM_MLD_LINKS) + return -1; + + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: set AP RSNXE IE for link ID %d", link_id); + ap_rsnxe = &sm->links[link_id].ap_rsnxe; + ap_rsnxe_len = &sm->links[link_id].ap_rsnxe_len; + } + + os_free(*ap_rsnxe); if (!ie || len == 0) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: clearing AP RSNXE"); - sm->ap_rsnxe = NULL; - sm->ap_rsnxe_len = 0; + *ap_rsnxe = NULL; + *ap_rsnxe_len = 0; } else { wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len); - sm->ap_rsnxe = os_memdup(ie, len); - if (!sm->ap_rsnxe) + *ap_rsnxe = os_memdup(ie, len); + if (*ap_rsnxe == NULL) return -1; - sm->ap_rsnxe_len = len; + *ap_rsnxe_len = len; } return 0; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index e6eef0c99..a56802b0a 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -93,6 +93,7 @@ struct wpa_sm_ctx { void (*transition_disable)(void *ctx, u8 bitmap); void (*store_ptk)(void *ctx, u8 *addr, int cipher, u32 life_time, const struct wpa_ptk *ptk); + int (*get_link_beacon_ie)(void *ctx, u8 link_id); }; @@ -165,9 +166,12 @@ int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie, int wpa_sm_set_assoc_rsnxe_default(struct wpa_sm *sm, u8 *rsnxe, size_t *rsnxe_len); int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); -int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len); -int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len); -int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); +int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len); +int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len); +int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, int link_id, const u8 *ie, + size_t len); int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen); int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, @@ -299,20 +303,20 @@ static inline int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, return -1; } -static inline int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, - size_t len) +static inline int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, int link_id, + const u8 *ie, size_t len) { return -1; } -static inline int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, - size_t len) +static inline int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, int link_id, + const u8 *ie, size_t len) { return -1; } -static inline int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, - size_t len) +static inline int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, int link_id, + const u8 *ie, size_t len) { return -1; } diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 62b85cb2e..8bf0f28d8 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -224,6 +224,8 @@ struct wpa_sm { struct { u8 addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; + u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; + size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; } links[MAX_NUM_MLD_LINKS]; }; @@ -288,6 +290,12 @@ static inline int wpa_sm_get_beacon_ie(struct wpa_sm *sm) return sm->ctx->get_beacon_ie(sm->ctx->ctx); } +static inline int wpa_sm_get_link_beacon_ie(struct wpa_sm *sm, u8 link_id) +{ + WPA_ASSERT(sm->ctx->get_link_beacon_ie); + return sm->ctx->get_link_beacon_ie(sm->ctx->ctx, link_id); +} + static inline void wpa_sm_cancel_auth_timeout(struct wpa_sm *sm) { WPA_ASSERT(sm->ctx->cancel_auth_timeout); diff --git a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c index 0c7189571..a86efd376 100644 --- a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c +++ b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c @@ -168,7 +168,7 @@ static int supp_get_beacon_ie(void *ctx) ie = wpa->wpa1 ? wpaie : rsne; if (ie[0] == WLAN_EID_RSN) return wpa_sm_set_ap_rsn_ie(wpa->supp, ie, 2 + ie[1]); - return wpa_sm_set_ap_wpa_ie(wpa->supp, ie, 2 + ie[1]); + return wpa_sm_set_ap_wpa_ie(wpa->supp, -1, ie, 2 + ie[1]); } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index db4de316f..5f13d4674 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3223,27 +3223,27 @@ no_pfs: p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 && os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) { wpa_found = 1; - wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len); + wpa_sm_set_ap_wpa_ie(wpa_s->wpa, -1, p, len); } if (!rsn_found && p[0] == WLAN_EID_RSN && p[1] >= 2) { rsn_found = 1; - wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len); + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, -1, p, len); } if (p[0] == WLAN_EID_RSNX && p[1] >= 1) - wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len); + wpa_sm_set_ap_rsnxe(wpa_s->wpa, -1, p, len); l -= len; p += len; } if (!wpa_found && data->assoc_info.beacon_ies) - wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0); + wpa_sm_set_ap_wpa_ie(wpa_s->wpa, -1, NULL, 0); if (!rsn_found && data->assoc_info.beacon_ies) { - wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0); - wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0); + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, -1, NULL, 0); + wpa_sm_set_ap_rsnxe(wpa_s->wpa, -1, NULL, 0); } if (wpa_found || rsn_found) wpa_s->ap_ies_from_associnfo = 1; @@ -3265,26 +3265,23 @@ no_pfs: } -static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s) +static int wpa_supplicant_update_link_ie(struct wpa_supplicant *wpa_s, + int link_id, const struct wpa_bss *bss) { const u8 *bss_wpa = NULL, *bss_rsn = NULL, *bss_rsnx = NULL; - if (!wpa_s->current_bss || !wpa_s->current_ssid) + if (!bss) return -1; - if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt)) - return 0; - - bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss, - WPA_IE_VENDOR_TYPE); - bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN); - bss_rsnx = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSNX); + bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); + bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX); - if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa, + if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, link_id, bss_wpa, bss_wpa ? 2 + bss_wpa[1] : 0) || - wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn, + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, link_id, bss_rsn, bss_rsn ? 2 + bss_rsn[1] : 0) || - wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx, + wpa_sm_set_ap_rsnxe(wpa_s->wpa, link_id, bss_rsnx, bss_rsnx ? 2 + bss_rsnx[1] : 0)) return -1; @@ -3292,6 +3289,39 @@ static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s) } +static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s) +{ + int i; + + if (!wpa_s->current_bss || !wpa_s->current_ssid) + return -1; + + if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt)) + return 0; + + if (wpa_supplicant_update_link_ie(wpa_s, -1, wpa_s->current_bss)) + return -1; + + if (!wpa_s->valid_links) + return 0; + + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + if (!(wpa_s->valid_links & BIT(i))) { + wpa_sm_set_ap_wpa_ie(wpa_s->wpa, i, NULL, 0); + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, i, NULL, 0); + wpa_sm_set_ap_rsnxe(wpa_s->wpa, i, NULL, 0); + continue; + } + + if (wpa_supplicant_update_link_ie(wpa_s, i, + wpa_s->links[i].bss)) + return -1; + } + + return 0; +} + + static void wpas_fst_update_mb_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 874c2bf1d..459d7bd2d 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -117,8 +117,8 @@ static int supp_get_beacon_ie(void *ctx) wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); /* TODO: get correct RSN IE */ - wpa_sm_set_ap_rsnxe(peer->supp, NULL, 0); - return wpa_sm_set_ap_rsn_ie(peer->supp, + wpa_sm_set_ap_rsnxe(peer->supp, -1, NULL, 0); + return wpa_sm_set_ap_rsn_ie(peer->supp, -1, (u8 *) "\x30\x14\x01\x00" "\x00\x0f\xac\x04" "\x01\x00\x00\x0f\xac\x04" diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index ba364324d..b0087328c 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -400,9 +400,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s) void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { -#ifdef CONFIG_WEP int i; -#endif /* CONFIG_WEP */ if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) wpa_s->key_mgmt = WPA_KEY_MGMT_WPS; @@ -410,9 +408,14 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s, wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA; else wpa_s->key_mgmt = WPA_KEY_MGMT_NONE; - wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0); - wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0); - wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0); + wpa_sm_set_ap_wpa_ie(wpa_s->wpa, -1, NULL, 0); + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, -1, NULL, 0); + wpa_sm_set_ap_rsnxe(wpa_s->wpa, -1, NULL, 0); + for (int i = 0; i < MAX_NUM_MLD_LINKS; i++) { + wpa_sm_set_ap_wpa_ie(wpa_s->wpa, i, NULL, 0); + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, i, NULL, 0); + wpa_sm_set_ap_rsnxe(wpa_s->wpa, i, NULL, 0); + } wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0); wpa_s->rsnxe_len = 0; @@ -1505,11 +1508,11 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN))); if (bss || !wpa_s->ap_ies_from_associnfo) { - if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa, + if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, -1, bss_wpa, bss_wpa ? 2 + bss_wpa[1] : 0) || - wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn, + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, -1, bss_rsn, bss_rsn ? 2 + bss_rsn[1] : 0) || - wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx, + wpa_sm_set_ap_rsnxe(wpa_s->wpa, -1, bss_rsnx, bss_rsnx ? 2 + bss_rsnx[1] : 0)) return -1; } diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index ccc72c4d6..2784fb096 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -390,15 +390,21 @@ static void wpa_supplicant_notify_eapol_done(void *ctx) #ifndef CONFIG_NO_WPA -static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) +struct beacon_ies { + const u8 *wpa_ie, *rsn_ie, *rsnxe; + size_t wpa_ie_len, rsn_ie_len, rsnxe_len; +}; + + +static int wpa_get_bssid_beacon_ie(struct wpa_supplicant *wpa_s, + const u8 *bssid, struct beacon_ies *ies) { - int ret = 0; struct wpa_bss *curr = NULL, *bss; struct wpa_ssid *ssid = wpa_s->current_ssid; const u8 *ie; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { - if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0) + if (os_memcmp(bss->bssid, bssid, ETH_ALEN) != 0) continue; if (ssid == NULL || ((bss->ssid_len == ssid->ssid_len && @@ -416,23 +422,42 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) #endif /* CONFIG_OWE */ } - if (curr) { - ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); - if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) - ret = -1; + if (!curr) + return -1; - ie = wpa_bss_get_ie(curr, WLAN_EID_RSN); - if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) - ret = -1; + ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); + ies->wpa_ie = ie; + ies->wpa_ie_len = ie ? 2 + ie[1] : 0; - ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX); - if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) - ret = -1; - } else { - ret = -1; - } + ie = wpa_bss_get_ie(curr, WLAN_EID_RSN); + ies->rsn_ie = ie; + ies->rsn_ie_len = ie ? 2 + ie[1] : 0; - return ret; + ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX); + ies->rsnxe = ie; + ies->rsnxe_len = ie ? 2 + ie[1] : 0; + + return 0; +} + + +static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) +{ + struct beacon_ies ies; + + if (wpa_get_bssid_beacon_ie(wpa_s, wpa_s->bssid, &ies)) + return -1; + + if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, -1, ies.wpa_ie, ies.wpa_ie_len)) + return -1; + + if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, -1, ies.rsn_ie, ies.rsn_ie_len)) + return -1; + + if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, -1, ies.rsnxe, ies.rsnxe_len)) + return -1; + + return 0; } @@ -452,6 +477,49 @@ static int wpa_supplicant_get_beacon_ie(void *ctx) } +static int wpa_get_link_beacon_ie(struct wpa_supplicant *wpa_s, u8 link_id) +{ + struct beacon_ies ies; + + if (!(wpa_s->valid_links & BIT(link_id))) + return -1; + + + if (wpa_get_bssid_beacon_ie(wpa_s, wpa_s->links[link_id].bssid, &ies)) + return -1; + + if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, link_id, ies.wpa_ie, + ies.wpa_ie_len)) + return -1; + + if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, link_id, ies.rsn_ie, + ies.rsn_ie_len)) + return -1; + + if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, link_id, ies.rsnxe, ies.rsnxe_len)) + return -1; + + return 0; +} + + +static int wpa_supplicant_get_link_beacon_ie(void *ctx, u8 link_id) +{ + struct wpa_supplicant *wpa_s = ctx; + if (wpa_get_link_beacon_ie(wpa_s, link_id) == 0) { + return 0; + } + + /* No WPA/RSN IE found in the cached scan results. Try to get updated + * scan results from the driver. */ + if (wpa_supplicant_update_scan_results(wpa_s) < 0) + return -1; + + return wpa_get_link_beacon_ie(wpa_s, link_id); +} + + + static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, const void *data, u16 data_len, size_t *msg_len, void **data_pos) @@ -1412,6 +1480,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->get_bssid = wpa_supplicant_get_bssid; ctx->ether_send = _wpa_ether_send; ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; + ctx->get_link_beacon_ie = wpa_supplicant_get_link_beacon_ie; ctx->alloc_eapol = _wpa_alloc_eapol; ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; ctx->add_pmkid = wpa_supplicant_add_pmkid;