diff mbox series

wpa-supplicant: add patches to support RSNE/RSNXE overriding

Message ID 20260422102935.1299772-1-jiacheng.shi@oss.qualcomm.com
State Changes Requested
Headers show
Series wpa-supplicant: add patches to support RSNE/RSNXE overriding | expand

Commit Message

Jiacheng Shi April 22, 2026, 10:29 a.m. UTC
Fix WFA test case 5.2.3.3 "STAUT forward compatibility to
an AP with various AKMs in RSN IE" failure caused by missing
SNonce_Cookie handling.

During the 2EAPMSG exchange, the STA did not apply the
SNonce_Cookie provided by the AP as required by the test
specification, resulting in sniffer validation failure.
To address this, add full support for RSN/RSNX overriding
for STA mode and explicitly signal SNonce_Cookie–based
override capability.

Change-Id: I443bdc00b1983db1a8a97ffa3f1f4998cd826a86
Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
---
 ...r-specific-element-types-for-RSNE-RS.patch |  34 +
 ...-overriding-elements-into-IE-parsing.patch |  58 ++
 ...ide-element-to-override-RSNE-content.patch |  36 +
 ...ride-element-to-override-RSNXE-conte.patch |  36 +
 ...eature-flags-to-indicate-RSN-overrid.patch |  67 ++
 ...a-capability-flag-for-RSN-overriding.patch |  65 ++
 ...ions-to-access-RSNE-RSNXE-from-BSS-e.patch | 448 +++++++++++
 ...bilities-for-AKM-suites-available-wi.patch |  66 ++
 .../0013-RSNE-RSNXE-overriding-for-STA.patch  | 739 ++++++++++++++++++
 ...-Selection-element-to-indicate-which.patch | 415 ++++++++++
 ...cookie-to-indicate-support-for-RSN-o.patch |  84 ++
 .../wpa-supplicant/wpa-supplicant_2.11.bb     |  11 +
 12 files changed, 2059 insertions(+)
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0006-Add-RSN-overriding-elements-into-IE-parsing.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0013-RSNE-RSNXE-overriding-for-STA.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch
 create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch

Comments

Dmitry Baryshkov April 22, 2026, 11:20 a.m. UTC | #1
On Wed, 22 Apr 2026 at 13:29, Jiacheng Shi
<jiacheng.shi@oss.qualcomm.com> wrote:
>
> Fix WFA test case 5.2.3.3 "STAUT forward compatibility to
> an AP with various AKMs in RSN IE" failure caused by missing
> SNonce_Cookie handling.

I can't really decrypt your commit message. Please remember that you
are speaking to non-WiFi people here.

>
> During the 2EAPMSG exchange, the STA did not apply the
> SNonce_Cookie provided by the AP as required by the test
> specification, resulting in sniffer validation failure.
> To address this, add full support for RSN/RSNX overriding
> for STA mode and explicitly signal SNonce_Cookie–based
> override capability.

Please adjust the line length in your editor. I think it's way too short.

>
> Change-Id: I443bdc00b1983db1a8a97ffa3f1f4998cd826a86

No Gerrit tags, thank you.

> Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
> ---
>  ...r-specific-element-types-for-RSNE-RS.patch |  34 +
>  ...-overriding-elements-into-IE-parsing.patch |  58 ++
>  ...ide-element-to-override-RSNE-content.patch |  36 +
>  ...ride-element-to-override-RSNXE-conte.patch |  36 +
>  ...eature-flags-to-indicate-RSN-overrid.patch |  67 ++
>  ...a-capability-flag-for-RSN-overriding.patch |  65 ++
>  ...ions-to-access-RSNE-RSNXE-from-BSS-e.patch | 448 +++++++++++
>  ...bilities-for-AKM-suites-available-wi.patch |  66 ++
>  .../0013-RSNE-RSNXE-overriding-for-STA.patch  | 739 ++++++++++++++++++
>  ...-Selection-element-to-indicate-which.patch | 415 ++++++++++
>  ...cookie-to-indicate-support-for-RSN-o.patch |  84 ++
>  .../wpa-supplicant/wpa-supplicant_2.11.bb     |  11 +
>  12 files changed, 2059 insertions(+)
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0006-Add-RSN-overriding-elements-into-IE-parsing.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0013-RSNE-RSNXE-overriding-for-STA.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch
>  create mode 100644 meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch
>
diff mbox series

Patch

diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch
new file mode 100644
index 0000000000..10b5f42ca8
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch
@@ -0,0 +1,34 @@ 
+From 6b0ce29d25d662b68dcc599e62d42eab0690b976 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 11 Oct 2023 12:43:11 +0300
+Subject: [PATCH 01/11] Define WFA vendor specific element types for RSNE/RSNXE
+ overriding
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=6b0ce29d25d662b68dcc599e62d42eab0690b976]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/ieee802_11_defs.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
+index 0fe631026..e2c132a40 100644
+--- a/src/common/ieee802_11_defs.h
++++ b/src/common/ieee802_11_defs.h
+@@ -1446,6 +1446,12 @@ struct ieee80211_ampe_ie {
+ #define QM_IE_OUI_TYPE 0x22
+ #define WFA_CAPA_IE_VENDOR_TYPE 0x506f9a23
+ #define WFA_CAPA_OUI_TYPE 0x23
++#define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29
++#define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a
++#define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b
++#define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29
++#define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a
++#define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
+ 
+ #define MULTI_AP_SUB_ELEM_TYPE 0x06
+ #define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0006-Add-RSN-overriding-elements-into-IE-parsing.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0006-Add-RSN-overriding-elements-into-IE-parsing.patch
new file mode 100644
index 0000000000..63a2b3721f
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0006-Add-RSN-overriding-elements-into-IE-parsing.patch
@@ -0,0 +1,58 @@ 
+From c16ac89be235ddb07247e0143abf245bb7760c40 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 11 Oct 2023 12:45:09 +0300
+Subject: [PATCH 02/11] Add RSN overriding elements into IE parsing
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=c16ac89be235ddb07247e0143abf245bb7760c40]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/ieee802_11_common.c | 8 ++++++++
+ src/common/ieee802_11_common.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
+index ba1cb5257..40a38955d 100644
+--- a/src/common/ieee802_11_common.c
++++ b/src/common/ieee802_11_common.c
+@@ -140,6 +140,14 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
+ 			elems->sae_pk = pos + 4;
+ 			elems->sae_pk_len = elen - 4;
+ 			break;
++		case WFA_RSNE_OVERRIDE_OUI_TYPE:
++			elems->rsne_override = pos;
++			elems->rsne_override_len = elen;
++			break;
++		case WFA_RSNE_OVERRIDE_2_OUI_TYPE:
++			elems->rsne_override_2 = pos;
++			elems->rsne_override_2_len = elen;
++			break;
+ 		default:
+ 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
+ 				   "information element ignored "
+diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
+index 9e9684c11..46a86096e 100644
+--- a/src/common/ieee802_11_common.h
++++ b/src/common/ieee802_11_common.h
+@@ -116,6 +116,8 @@ struct ieee802_11_elems {
+ 	const u8 *prior_access_mle;
+ 	const u8 *mbssid_known_bss;
+ 	const u8 *mbssid;
++	const u8 *rsne_override;
++	const u8 *rsne_override_2;
+ 
+ 	u8 ssid_len;
+ 	u8 supp_rates_len;
+@@ -179,6 +181,8 @@ struct ieee802_11_elems {
+ 	size_t prior_access_mle_len;
+ 	u8 mbssid_known_bss_len;
+ 	u8 mbssid_len;
++	size_t rsne_override_len;
++	size_t rsne_override_2_len;
+ 
+ 	struct mb_ies_info mb_ies;
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch
new file mode 100644
index 0000000000..5c6a7413a2
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch
@@ -0,0 +1,36 @@ 
+From 48ca68f6f8ba6769d031fac0523e666de7020f57 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 11 Oct 2023 12:46:23 +0300
+Subject: [PATCH 03/11] Allow RSNE Override element to override RSNE contents
+ during parsing
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=48ca68f6f8ba6769d031fac0523e666de7020f57]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/wpa_common.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
+index 1cfdd9ad7..8eb4a1dab 100644
+--- a/src/common/wpa_common.c
++++ b/src/common/wpa_common.c
+@@ -1890,6 +1890,14 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
+ 		data->has_group = 1;
+ 		data->key_mgmt = WPA_KEY_MGMT_OSEN;
+ 		data->proto = WPA_PROTO_OSEN;
++	} else if (rsn_ie_len >= 2 + 4 + 2 && rsn_ie[1] >= 4 + 2 &&
++		   rsn_ie[1] == rsn_ie_len - 2 &&
++		   (WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE ||
++		    WPA_GET_BE32(&rsn_ie[2]) ==
++		    RSNE_OVERRIDE_2_IE_VENDOR_TYPE) &&
++		   WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) {
++		pos = rsn_ie + 2 + 4 + 2;
++		left = rsn_ie_len - 2 - 4 - 2;
+ 	} else {
+ 		const struct rsn_ie_hdr *hdr;
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch
new file mode 100644
index 0000000000..a7492a3378
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch
@@ -0,0 +1,36 @@ 
+From b8a2d11ae04ec20aa6370af4d21150a2a1a5fc89 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 1 Nov 2023 15:27:31 +0200
+Subject: [PATCH 04/11] Allow RSNXE Override element to override RSNXE contents
+ during parsing
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=b8a2d11ae04ec20aa6370af4d21150a2a1a5fc89]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/ieee802_11_common.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
+index 40a38955d..3ca1ffe7e 100644
+--- a/src/common/ieee802_11_common.c
++++ b/src/common/ieee802_11_common.c
+@@ -3131,8 +3131,12 @@ bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
+ 
+ bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
+ {
+-	return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
+-					 rsnxe ? rsnxe[1] : 0, capab);
++	if (!rsnxe)
++		return false;
++	if (rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC && rsnxe[1] >= 4 + 1)
++		return ieee802_11_rsnx_capab_len(rsnxe + 2 + 4, rsnxe[1] - 4,
++						 capab);
++	return ieee802_11_rsnx_capab_len(rsnxe + 2, rsnxe[1], capab);
+ }
+ 
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch
new file mode 100644
index 0000000000..59f25c3998
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch
@@ -0,0 +1,67 @@ 
+From 6fad7224be2f54ef9db77aa15a5beee441fa6db5 Mon Sep 17 00:00:00 2001
+From: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
+Date: Tue, 28 May 2024 07:45:44 +0530
+Subject: [PATCH 05/11] Add QCA vendor feature flags to indicate RSN override
+ elements support
+
+Add a separate feature flag for STA mode to indicate support for RSN
+override elements.
+
+Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=6fad7224be2f54ef9db77aa15a5beee441fa6db5]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/qca-vendor.h | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
+index 5b58ffb39..2971be74b 100644
+--- a/src/common/qca-vendor.h
++++ b/src/common/qca-vendor.h
+@@ -2180,6 +2180,34 @@ enum qca_wlan_vendor_acs_hw_mode {
+  *	that the device supports enhanced audio experience over WLAN feature.
+  * @QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER: Flag indicates that the device
+  *	in AP mode supports TWT responder mode in HT and VHT modes.
++ *
++ * @QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA: Flag indicates that the device
++ *	supports RSNE/RSNXE overriding in STA mode.
++ *
++ *	For SME offload to the driver case:
++ *	- Supplicant should enable RSNO element use only when the driver
++ *	  indicates this feature flag.
++ *	- The driver should enable RSNO element use with the supplicant selected
++ *	  BSS only when the supplicant sends an RSNO element with an empty
++ *	  payload in the connect request elements buffer in NL80211_CMD_CONNECT.
++ *
++ *	For BSS selection offload to the driver case:
++ *	- Supplicant should enable RSNO element use only when the driver
++ *	  indicates this feature flag.
++ *	- Supplicant should always send RSNO elements in the connect request
++ *	  elements buffer in NL80211_CMD_CONNECT irrespective of whether RSNO
++ *	  elements are supported by the BSS that the supplicant selected
++ *	- The driver should enable RSNO element use only when the supplicant
++ *	  sends an RSNO element with an empty payload in connect request
++ *	  elements in NL80211_CMD_CONNECT.
++ *	- The driver should remove RSNO elements from the connect request
++ *	  elements while preparing the (Re)Association Request frame elements
++ *	  if the driver selects a different BSS which is not advertising RSNO
++ *	  elements.
++ *
++ *	If both SME and BSS selection offload to the driver, BSS selection
++ *	offload to the driver case rules shall be applied.
++ *
+  * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
+  */
+ enum qca_wlan_vendor_features {
+@@ -2208,6 +2236,7 @@ enum qca_wlan_vendor_features {
+ 	QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST = 22,
+ 	QCA_WLAN_VENDOR_FEATURE_ENHANCED_AUDIO_EXPERIENCE_OVER_WLAN = 23,
+ 	QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER = 24,
++	QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA = 25,
+ 	NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
+ };
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch
new file mode 100644
index 0000000000..bd0059139f
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch
@@ -0,0 +1,65 @@ 
+From 341bcb2b5c7d83acd2f8f0237182d54d883603e7 Mon Sep 17 00:00:00 2001
+From: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
+Date: Thu, 13 Jun 2024 12:13:14 +0530
+Subject: [PATCH 06/11] nl80211: Add a capability flag for RSN overriding
+
+Add a new capability flag based on the nl80211 feature advertisement for
+RSN overriding support.
+
+Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=341bcb2b5c7d83acd2f8f0237182d54d883603e7]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/drivers/driver.h              | 2 ++
+ src/drivers/driver_nl80211.c      | 3 +++
+ src/drivers/driver_nl80211_capa.c | 6 ++++++
+ 3 files changed, 11 insertions(+)
+
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 3e7747489..4331782d8 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -2330,6 +2330,8 @@ struct wpa_driver_capa {
+ #define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP	0x0000000000100000ULL
+ /** Driver supports TWT responder in HT and VHT modes */
+ #define WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER	0x0000000000200000ULL
++/** Driver supports RSN override elements */
++#define WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA	0x0000000000400000ULL
+ 	u64 flags2;
+ 
+ #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index e6fbad96d..39f58ff83 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -9899,6 +9899,9 @@ static int nl80211_set_param(void *priv, const char *param)
+ 			WPA_DRIVER_FLAGS2_SEC_LTF_AP;
+ 	}
+ 
++	if (os_strstr(param, "rsn_override_in_driver=1"))
++		drv->capa.flags2 |= WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA;
++
+ 	return 0;
+ }
+ 
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index dc16bd445..240d01d3d 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1443,6 +1443,12 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
+ 		drv->qca_ap_allowed_freqs = 1;
+ 	if (check_feature(QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER, &info))
+ 		drv->capa.flags2 |= WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER;
++	if (check_feature(QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA, &info)) {
++		wpa_printf(MSG_DEBUG,
++			   "The driver supports RSN overriding in STA mode");
++		drv->capa.flags2 |= WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA;
++	}
++
+ 	os_free(info.flags);
+ }
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch
new file mode 100644
index 0000000000..d3d5d85703
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch
@@ -0,0 +1,448 @@ 
+From 5488e120d3d47ba602d89b8365a8d8e5e5aa3e4f Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 11 Oct 2023 12:50:05 +0300
+Subject: [PATCH 07/11] Use helper functions to access RSNE/RSNXE from BSS
+ entries
+
+This is a step towards allowing the contents of RSNE/RSNXE to be
+overridden.
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=5488e120d3d47ba602d89b8365a8d8e5e5aa3e4f]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ wpa_supplicant/bss.c                    | 16 ++++++++++++++++
+ wpa_supplicant/bss.h                    |  7 +++++++
+ wpa_supplicant/ctrl_iface.c             |  8 ++++----
+ wpa_supplicant/dbus/dbus_new_handlers.c |  2 +-
+ wpa_supplicant/dpp_supplicant.c         |  2 +-
+ wpa_supplicant/events.c                 | 24 ++++++++++++------------
+ wpa_supplicant/hs20_supplicant.c        |  2 +-
+ wpa_supplicant/interworking.c           |  6 +++---
+ wpa_supplicant/mbo.c                    |  2 +-
+ wpa_supplicant/pasn_supplicant.c        | 10 +++++-----
+ wpa_supplicant/sme.c                    | 10 +++++-----
+ wpa_supplicant/wpa_supplicant.c         |  8 ++++----
+ wpa_supplicant/wpas_glue.c              |  4 ++--
+ wpa_supplicant/wps_supplicant.c         |  2 +-
+ 14 files changed, 63 insertions(+), 40 deletions(-)
+
+diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
+index e8aaf6fe1..6d702bb2e 100644
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -1866,3 +1866,19 @@ out:
+ 	wpabuf_free(mlbuf);
+ 	return removed_links;
+ }
++
++
++const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
++			    const struct wpa_bss *bss, struct wpa_ssid *ssid,
++			    bool mlo)
++{
++	return wpa_bss_get_ie(bss, WLAN_EID_RSN);
++}
++
++
++const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
++			     const struct wpa_bss *bss, struct wpa_ssid *ssid,
++			     bool mlo)
++{
++	return wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++}
+diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
+index 2079606a9..508129c3d 100644
+--- a/wpa_supplicant/bss.h
++++ b/wpa_supplicant/bss.h
+@@ -226,4 +226,11 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
+ u16 wpa_bss_parse_reconf_ml_element(struct wpa_supplicant *wpa_s,
+ 				    struct wpa_bss *bss);
+ 
++const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
++			    const struct wpa_bss *bss, struct wpa_ssid *ssid,
++			    bool mlo);
++const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
++			     const struct wpa_bss *bss, struct wpa_ssid *ssid,
++			     bool mlo);
++
+ #endif /* BSS_H */
+diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
+index bcbcb258f..d245531cd 100644
+--- a/wpa_supplicant/ctrl_iface.c
++++ b/wpa_supplicant/ctrl_iface.c
+@@ -3119,12 +3119,12 @@ static int wpa_supplicant_ctrl_iface_scan_result(
+ 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+ 	if (ie)
+ 		pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
+-	ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	ie2 = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 	if (ie2) {
+ 		pos = wpa_supplicant_ie_txt(pos, end, mesh ? "RSN" : "WPA2",
+ 					    ie2, 2 + ie2[1]);
+ 	}
+-	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++	rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
+ 	if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
+ 		ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
+ 		if (os_snprintf_error(end - pos, ret))
+@@ -5444,12 +5444,12 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ 		if (ie)
+ 			pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
+ 						    2 + ie[1]);
+-		ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		ie2 = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 		if (ie2)
+ 			pos = wpa_supplicant_ie_txt(pos, end,
+ 						    mesh ? "RSN" : "WPA2", ie2,
+ 						    2 + ie2[1]);
+-		rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++		rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
+ 		if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
+ 			ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
+ 			if (os_snprintf_error(end - pos, ret))
+diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
+index db1213196..960b3069b 100644
+--- a/wpa_supplicant/dbus/dbus_new_handlers.c
++++ b/wpa_supplicant/dbus/dbus_new_handlers.c
+@@ -5635,7 +5635,7 @@ dbus_bool_t wpas_dbus_getter_bss_rsn(
+ 		return FALSE;
+ 
+ 	os_memset(&wpa_data, 0, sizeof(wpa_data));
+-	ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
++	ie = wpa_bss_get_rsne(args->wpa_s, res, NULL, false);
+ 	if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
+ 		dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ 				     "failed to parse RSN IE");
+diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
+index 4044b47dd..94d7ae990 100644
+--- a/wpa_supplicant/dpp_supplicant.c
++++ b/wpa_supplicant/dpp_supplicant.c
+@@ -4500,7 +4500,7 @@ int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ 
+ 	if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
+ 		return 0; /* Not using DPP AKM - continue */
+-	rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 	if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
+ 	    !(ied.key_mgmt & WPA_KEY_MGMT_DPP))
+ 		return 0; /* AP does not support DPP AKM - continue */
+diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
+index 49917f7aa..4e55470bb 100644
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -670,7 +670,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
+ 		 (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
+ #endif /* CONFIG_WEP */
+ 
+-	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsn_ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 	if (is_6ghz_bss && !rsn_ie) {
+ 		if (debug_print)
+ 			wpa_dbg(wpa_s, MSG_DEBUG,
+@@ -1143,7 +1143,7 @@ static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ 	u8 ssid_len;
+ 
+ 	owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+-	if (!owe || !wpa_bss_get_ie(bss, WLAN_EID_RSN))
++	if (!owe || !wpa_bss_get_rsne(wpa_s, bss, NULL, false))
+ 		return;
+ 
+ 	pos = owe + 6;
+@@ -1247,7 +1247,7 @@ static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s,
+ 
+ 		if (bss == orig_bss)
+ 			continue;
+-		ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++		ie = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ 		if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
+ 			continue;
+ 
+@@ -1286,7 +1286,7 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ 
+ 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+ 	wpa = ie && ie[1];
+-	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 	wpa |= ie && ie[1];
+ 	if (ie && wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) == 0 &&
+ 	    (data.key_mgmt & WPA_KEY_MGMT_OSEN))
+@@ -1295,7 +1295,7 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ 	osen = ie != NULL;
+ 
+ #ifdef CONFIG_SAE
+-	ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++	ie = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ 	if (ie && ie[1] >= 1)
+ 		rsnxe_capa = ie[2];
+ #endif /* CONFIG_SAE */
+@@ -1650,7 +1650,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
+ 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+ 	wpa_ie_len = ie ? ie[1] : 0;
+ 
+-	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	ie = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 	rsn_ie_len = ie ? ie[1] : 0;
+ 
+ 	ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
+@@ -2117,7 +2117,7 @@ static void wpa_supplicant_rsn_preauth_scan_results(
+ 		if (ssid == NULL)
+ 			continue;
+ 
+-		rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		rsn = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 		if (rsn == NULL)
+ 			continue;
+ 
+@@ -3267,7 +3267,7 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
+ 	if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
+ 		const u8 *bss_rsn;
+ 
+-		bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		bss_rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 		if (bss_rsn) {
+ 			p = bss_rsn;
+ 			len = 2 + bss_rsn[1];
+@@ -3721,8 +3721,8 @@ static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
+ 
+ 	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_rsn = wpa_bss_get_rsne(wpa_s, wpa_s->current_bss, NULL, false);
++	bss_rsnx = wpa_bss_get_rsnxe(wpa_s, wpa_s->current_bss, NULL, false);
+ 
+ 	if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
+ 				 bss_wpa ? 2 + bss_wpa[1] : 0) ||
+@@ -4110,8 +4110,8 @@ static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s)
+ 			return -1;
+ 		}
+ 
+-		bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+-		bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++		bss_rsn = wpa_bss_get_rsne(wpa_s, bss, NULL, true);
++		bss_rsnx = wpa_bss_get_rsnxe(wpa_s, bss, NULL, true);
+ 
+ 		wpa_mlo.links[i].ap_rsne = bss_rsn ? (u8 *) bss_rsn : NULL;
+ 		wpa_mlo.links[i].ap_rsne_len = bss_rsn ? 2 + bss_rsn[1] : 0;
+diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
+index 6a584651e..3ed8813f1 100644
+--- a/wpa_supplicant/hs20_supplicant.c
++++ b/wpa_supplicant/hs20_supplicant.c
+@@ -1087,7 +1087,7 @@ void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
+ 		prov_anqp = bss->anqp->hs20_osu_providers_list;
+ 		if (prov_anqp == NULL)
+ 			continue;
+-		ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		ie = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 		if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &data) == 0 &&
+ 		    (data.key_mgmt & WPA_KEY_MGMT_OSEN)) {
+ 			osu_ssid2 = bss->ssid;
+diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
+index 6773a243c..e3faca69c 100644
+--- a/wpa_supplicant/interworking.c
++++ b/wpa_supplicant/interworking.c
+@@ -1726,7 +1726,7 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ 		   " for connection",
+ 		   MAC2STR(bss->bssid));
+ 
+-	if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
++	if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false)) {
+ 		/*
+ 		 * We currently support only HS 2.0 networks and those are
+ 		 * required to use WPA2-Enterprise.
+@@ -2459,7 +2459,7 @@ static struct wpa_bss * pick_best_roaming_partner(struct wpa_supplicant *wpa_s,
+ 		cred2 = interworking_credentials_available(wpa_s, bss, NULL);
+ 		if (!cred2)
+ 			continue;
+-		if (!wpa_bss_get_ie(bss, WLAN_EID_RSN))
++		if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false))
+ 			continue;
+ 		prio = roaming_prio(wpa_s, cred2, bss);
+ 		wpa_printf(MSG_DEBUG, "Interworking: roaming_prio=%u for BSS "
+@@ -2511,7 +2511,7 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
+ 		if (!cred)
+ 			continue;
+ 
+-		if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
++		if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false)) {
+ 			/*
+ 			 * We currently support only HS 2.0 networks and those
+ 			 * are required to use WPA2-Enterprise.
+diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
+index 59b15daf6..51f8e0212 100644
+--- a/wpa_supplicant/mbo.c
++++ b/wpa_supplicant/mbo.c
+@@ -115,7 +115,7 @@ void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ 		return;
+ 	if (oce && oce[1] >= 1 && (oce[2] & OCE_IS_STA_CFON))
+ 		return; /* STA-CFON is not required to enable PMF */
+-	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsne = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 	if (!rsne || wpa_parse_wpa_ie(rsne, 2 + rsne[1], &ie) < 0)
+ 		return; /* AP is not using RSN */
+ 
+diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
+index 1bb38f73d..89edad49e 100644
+--- a/wpa_supplicant/pasn_supplicant.c
++++ b/wpa_supplicant/pasn_supplicant.c
+@@ -174,7 +174,7 @@ static int wpas_pasn_get_params_from_bss(struct wpa_supplicant *wpa_s,
+ 		}
+ 	}
+ 
+-	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 	if (!rsne) {
+ 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
+ 		return -1;
+@@ -186,7 +186,7 @@ static int wpas_pasn_get_params_from_bss(struct wpa_supplicant *wpa_s,
+ 		return -1;
+ 	}
+ 
+-	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++	rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
+ 
+ 	ssid_str_len = bss->ssid_len;
+ 	ssid_str = bss->ssid;
+@@ -480,7 +480,7 @@ static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
+ 		return NULL;
+ 	}
+ 
+-	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 	if (!rsne) {
+ 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
+ 		return NULL;
+@@ -544,13 +544,13 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
+ 		goto fail;
+ 	}
+ 
+-	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
+ 	if (!rsne) {
+ 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
+ 		goto fail;
+ 	}
+ 
+-	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++	rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
+ 
+ 	derive_kdk = (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
+ 		ieee802_11_rsnx_capab(rsnxe,
+diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
+index e6538e871..8df60393a 100644
+--- a/wpa_supplicant/sme.c
++++ b/wpa_supplicant/sme.c
+@@ -190,7 +190,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
+ 	if (bss) {
+ 		const u8 *rsnxe;
+ 
+-		rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++		rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ 		if (rsnxe && rsnxe[1] >= 1)
+ 			rsnxe_capa = rsnxe[2];
+ 	}
+@@ -643,7 +643,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
+ 		const u8 *rsn;
+ 		struct wpa_ie_data ied;
+ 
+-		rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 		if (!rsn) {
+ 			wpa_dbg(wpa_s, MSG_DEBUG,
+ 				"SAE enabled, but target BSS does not advertise RSN");
+@@ -683,7 +683,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
+ #endif /* CONFIG_WEP */
+ 
+ 	if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
+-	     wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
++	     wpa_bss_get_rsne(wpa_s, bss, ssid, false)) &&
+ 	    wpa_key_mgmt_wpa(ssid->key_mgmt)) {
+ 		int try_opportunistic;
+ 		const u8 *cache_id = NULL;
+@@ -807,7 +807,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
+ 		wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
+ 			md[0], md[1]);
+ 
+-		omit_rsnxe = !wpa_bss_get_ie(bss, WLAN_EID_RSNX);
++		omit_rsnxe = !wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ 		if (wpa_s->sme.assoc_req_ie_len + 5 <
+ 		    sizeof(wpa_s->sme.assoc_req_ie)) {
+ 			struct rsn_mdie *mdie;
+@@ -836,7 +836,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
+ 
+ 	wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
+ 	if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
+-		const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		const u8 *rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 		struct wpa_ie_data _ie;
+ 		if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
+ 		    _ie.capabilities &
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index 037bfa378..de8785a3c 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -1700,8 +1700,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
+ 
+ 	if (bss) {
+ 		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);
++		bss_rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
++		bss_rsnx = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ 		bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
+ 	} else {
+ 		bss_wpa = bss_rsn = bss_rsnx = bss_osen = NULL;
+@@ -3456,7 +3456,7 @@ static u8 * wpas_populate_assoc_ies(
+ 	}
+ 
+ 	if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
+-		    wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
++		    wpa_bss_get_rsne(wpa_s, bss, ssid, false)) &&
+ 	    wpa_key_mgmt_wpa(ssid->key_mgmt)) {
+ 		int try_opportunistic;
+ 		const u8 *cache_id = NULL;
+@@ -4497,7 +4497,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
+ 
+ 	params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
+ 	if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
+-		const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++		const u8 *rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 		struct wpa_ie_data ie;
+ 		if (!wpas_driver_bss_selection(wpa_s) && rsn &&
+ 		    wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
+diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
+index 5199f950b..9100bee05 100644
+--- a/wpa_supplicant/wpas_glue.c
++++ b/wpa_supplicant/wpas_glue.c
+@@ -425,11 +425,11 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
+ 		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
+ 			ret = -1;
+ 
+-		ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
++		ie = wpa_bss_get_rsne(wpa_s, curr, ssid, false);
+ 		if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
+ 			ret = -1;
+ 
+-		ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
++		ie = wpa_bss_get_rsnxe(wpa_s, curr, ssid, false);
+ 		if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
+ 			ret = -1;
+ 	} else {
+diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
+index 8cd355f6b..7b9cf7f9e 100644
+--- a/wpa_supplicant/wps_supplicant.c
++++ b/wpa_supplicant/wps_supplicant.c
+@@ -226,7 +226,7 @@ static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
+ 
+ 	wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
+ 
+-	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ 	if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
+ 		wpa2 = 1;
+ 		if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch
new file mode 100644
index 0000000000..cbd362ecdd
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch
@@ -0,0 +1,66 @@ 
+From d0b55eb360d34231b095a14d55592ea682895e27 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Thu, 27 Jun 2024 17:33:44 +0300
+Subject: [PATCH 08/11] Make driver capabilities for AKM suites available
+ within wpa_supplicant
+
+In addition, add some of the previously missed AKM suites from the
+default capabilities.
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=d0b55eb360d34231b095a14d55592ea682895e27]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/drivers/driver_nl80211_capa.c | 2 ++
+ wpa_supplicant/wpa_supplicant.c   | 1 +
+ wpa_supplicant/wpa_supplicant_i.h | 1 +
+ 3 files changed, 4 insertions(+)
+
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index 240d01d3d..26c1f4140 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1476,6 +1476,7 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
+ 			WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+ 			WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
+ 			WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
++			WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256 |
+ 			WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
+ 			WPA_DRIVER_CAPA_KEY_MGMT_OWE |
+ 			WPA_DRIVER_CAPA_KEY_MGMT_DPP;
+@@ -1491,6 +1492,7 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
+ 				WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
+ 				WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
+ 				WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
++				WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY |
+ 				WPA_DRIVER_CAPA_KEY_MGMT_SAE;
+ 		else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
+ 			drv->capa.key_mgmt |=
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index de8785a3c..c27977560 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -7363,6 +7363,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
+ 		wpa_s->drv_flags = capa.flags;
+ 		wpa_s->drv_flags2 = capa.flags2;
+ 		wpa_s->drv_enc = capa.enc;
++		wpa_s->drv_key_mgmt = capa.key_mgmt;
+ 		wpa_s->drv_rrm_flags = capa.rrm_flags;
+ 		wpa_s->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
+ 		wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
+diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
+index 110a8648c..e92f6b147 100644
+--- a/wpa_supplicant/wpa_supplicant_i.h
++++ b/wpa_supplicant/wpa_supplicant_i.h
+@@ -920,6 +920,7 @@ struct wpa_supplicant {
+ 	u64 drv_flags;
+ 	u64 drv_flags2;
+ 	unsigned int drv_enc;
++	unsigned int drv_key_mgmt;
+ 	unsigned int drv_rrm_flags;
+ 	unsigned int drv_max_acl_mac_addrs;
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0013-RSNE-RSNXE-overriding-for-STA.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0013-RSNE-RSNXE-overriding-for-STA.patch
new file mode 100644
index 0000000000..9ce776321e
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0013-RSNE-RSNXE-overriding-for-STA.patch
@@ -0,0 +1,739 @@ 
+From 765c48d5adcf8996b2568a7b2ec9d3a9c34ec902 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Wed, 11 Oct 2023 12:50:05 +0300
+Subject: [PATCH 09/11] RSNE/RSNXE overriding for STA
+
+Add support for RSNE/RSNXE Override elements. Use these elements to
+determine AP's extended RSN parameters.
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=765c48d5adcf8996b2568a7b2ec9d3a9c34ec902]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/rsn_supp/wpa.c                 |  92 ++++++++++---
+ src/rsn_supp/wpa_ie.c              |  11 +-
+ wpa_supplicant/bss.c               | 201 ++++++++++++++++++++++++++++-
+ wpa_supplicant/config.c            |   1 +
+ wpa_supplicant/config.h            |  13 ++
+ wpa_supplicant/config_file.c       |   2 +
+ wpa_supplicant/events.c            |  24 +++-
+ wpa_supplicant/sme.c               |  27 +++-
+ wpa_supplicant/wpa_supplicant.c    | 128 ++++++++++++++++++
+ wpa_supplicant/wpa_supplicant.conf |   9 ++
+ wpa_supplicant/wpa_supplicant_i.h  |   5 +
+ 11 files changed, 487 insertions(+), 26 deletions(-)
+
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index f23979cd9..e48982989 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -4550,12 +4550,27 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
+ 		} else {
+ 			wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNE",
+ 					 ie, len);
+-			sm->mlo.links[i].ap_rsne = os_memdup(ie, len);
+-			if (!sm->mlo.links[i].ap_rsne) {
+-				sm->mlo.links[i].ap_rsne_len = 0;
+-				return -1;
++			if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
++				sm->mlo.links[i].ap_rsne = os_malloc(len - 4);
++				if (!sm->mlo.links[i].ap_rsne)
++					return -1;
++				sm->mlo.links[i].ap_rsne[0] = WLAN_EID_RSN;
++				sm->mlo.links[i].ap_rsne[1] = len - 2 - 4;
++				os_memcpy(&sm->mlo.links[i].ap_rsne[2],
++					  ie + 2 + 4, len - 2 - 4);
++				sm->mlo.links[i].ap_rsne_len = len - 4;
++				wpa_hexdump(MSG_DEBUG,
++					    "RSN: Converted RSNE override to RSNE",
++					    sm->mlo.links[i].ap_rsne,
++					    sm->mlo.links[i].ap_rsne_len);
++			} else {
++				sm->mlo.links[i].ap_rsne = os_memdup(ie, len);
++				if (!sm->mlo.links[i].ap_rsne) {
++					sm->mlo.links[i].ap_rsne_len = 0;
++					return -1;
++				}
++				sm->mlo.links[i].ap_rsne_len = len;
+ 			}
+-			sm->mlo.links[i].ap_rsne_len = len;
+ 		}
+ 
+ 		ie = mlo->links[i].ap_rsnxe;
+@@ -4571,12 +4586,27 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
+ 		} else {
+ 			wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNXE", ie,
+ 					 len);
+-			sm->mlo.links[i].ap_rsnxe = os_memdup(ie, len);
+-			if (!sm->mlo.links[i].ap_rsnxe) {
+-				sm->mlo.links[i].ap_rsnxe_len = 0;
+-				return -1;
++			if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
++				sm->mlo.links[i].ap_rsnxe = os_malloc(len - 4);
++				if (!sm->mlo.links[i].ap_rsnxe)
++					return -1;
++				sm->mlo.links[i].ap_rsnxe[0] = WLAN_EID_RSNX;
++				sm->mlo.links[i].ap_rsnxe[1] = len - 2 - 4;
++				os_memcpy(&sm->mlo.links[i].ap_rsnxe[2],
++					  ie + 2 + 4, len - 2 - 4);
++				sm->mlo.links[i].ap_rsnxe_len = len - 4;
++				wpa_hexdump(MSG_DEBUG,
++					    "RSN: Converted RSNXE override to RSNXE",
++					    sm->mlo.links[i].ap_rsnxe,
++					    sm->mlo.links[i].ap_rsnxe_len);
++			} else {
++				sm->mlo.links[i].ap_rsnxe = os_memdup(ie, len);
++				if (!sm->mlo.links[i].ap_rsnxe) {
++					sm->mlo.links[i].ap_rsnxe_len = 0;
++					return -1;
++				}
++				sm->mlo.links[i].ap_rsnxe_len = len;
+ 			}
+-			sm->mlo.links[i].ap_rsnxe_len = len;
+ 		}
+ 	}
+ 
+@@ -5077,11 +5107,24 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
+ 		sm->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)
+-			return -1;
++		if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
++			sm->ap_rsn_ie = os_malloc(len - 4);
++			if (!sm->ap_rsn_ie)
++				return -1;
++			sm->ap_rsn_ie[0] = WLAN_EID_RSN;
++			sm->ap_rsn_ie[1] = len - 2 - 4;
++			os_memcpy(&sm->ap_rsn_ie[2], ie + 2 + 4, len - 2 - 4);
++			sm->ap_rsn_ie_len = len - 4;
++			wpa_hexdump(MSG_DEBUG,
++				    "RSN: Converted RSNE override to RSNE",
++				    sm->ap_rsn_ie, sm->ap_rsn_ie_len);
++		} else {
++			sm->ap_rsn_ie = os_memdup(ie, len);
++			if (sm->ap_rsn_ie == NULL)
++				return -1;
+ 
+-		sm->ap_rsn_ie_len = len;
++			sm->ap_rsn_ie_len = len;
++		}
+ 	}
+ 
+ 	return 0;
+@@ -5110,11 +5153,24 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
+ 		sm->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)
+-			return -1;
++		if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
++			sm->ap_rsnxe = os_malloc(len - 4);
++			if (!sm->ap_rsnxe)
++				return -1;
++			sm->ap_rsnxe[0] = WLAN_EID_RSNX;
++			sm->ap_rsnxe[1] = len - 2 - 4;
++			os_memcpy(&sm->ap_rsnxe[2], ie + 2 + 4, len - 2 - 4);
++			sm->ap_rsnxe_len = len - 4;
++			wpa_hexdump(MSG_DEBUG,
++				    "RSN: Converted RSNXE override to RSNXE",
++				    sm->ap_rsnxe, sm->ap_rsnxe_len);
++		} else {
++			sm->ap_rsnxe = os_memdup(ie, len);
++			if (!sm->ap_rsnxe)
++				return -1;
+ 
+-		sm->ap_rsnxe_len = len;
++			sm->ap_rsnxe_len = len;
++		}
+ 	}
+ 
+ 	return 0;
+diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
+index eeedf8ba5..515f1b027 100644
+--- a/src/rsn_supp/wpa_ie.c
++++ b/src/rsn_supp/wpa_ie.c
+@@ -33,8 +33,15 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
+ 	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
+ 	    wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE)
+ 		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
+-	else
+-		return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
++	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
++	    wpa_ie[1] >= 4 &&
++	    WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE)
++		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
++	if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
++	    wpa_ie[1] >= 4 &&
++	    WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_2_IE_VENDOR_TYPE)
++		return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
++	return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
+ }
+ 
+ 
+diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
+index 6d702bb2e..8dcda7848 100644
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -1657,10 +1657,22 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
+ 
+ 	if (ssid) {
+ 		struct wpa_ie_data ie;
+-
+-		if (!elems.rsn_ie ||
+-		    wpa_parse_wpa_ie(elems.rsn_ie - 2, 2 + elems.rsn_ie_len,
+-				     &ie)) {
++		const u8 *rsne;
++		size_t rsne_len;
++
++		if (elems.rsne_override_2 && wpas_rsn_overriding(wpa_s)) {
++			rsne = elems.rsne_override_2;
++			rsne_len = elems.rsne_override_2_len;
++		} else if (elems.rsne_override &&
++			   wpas_rsn_overriding(wpa_s)) {
++			rsne = elems.rsne_override;
++			rsne_len = elems.rsne_override_len;
++		} else {
++			rsne = elems.rsn_ie;
++			rsne_len = elems.rsn_ie_len;
++		}
++		if (!rsne ||
++		    wpa_parse_wpa_ie(rsne - 2, 2 + rsne_len, &ie)) {
+ 			wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
+ 			goto out;
+ 		}
+@@ -1868,10 +1880,163 @@ out:
+ }
+ 
+ 
++static bool wpa_bss_supported_cipher(struct wpa_supplicant *wpa_s,
++				     int pairwise_cipher)
++{
++	if (!wpa_s->drv_enc)
++		return true;
++
++	if ((pairwise_cipher & WPA_CIPHER_CCMP) &&
++	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP))
++		return true;
++
++	if ((pairwise_cipher & WPA_CIPHER_GCMP) &&
++	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP))
++		return true;
++
++	if ((pairwise_cipher & WPA_CIPHER_CCMP_256) &&
++	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256))
++		return true;
++
++	if ((pairwise_cipher & WPA_CIPHER_GCMP_256) &&
++	    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256))
++		return true;
++
++	return false;
++}
++
++
++static bool wpa_bss_supported_key_mgmt(struct wpa_supplicant *wpa_s,
++				       int key_mgmt)
++{
++	if (!wpa_s->drv_key_mgmt)
++		return true;
++
++	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_PSK) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_PSK) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_PSK_SHA256) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_SAE) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_SAE) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_OWE) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_DPP) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA256) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA384) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256))
++		return true;
++	if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) &&
++	    (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384))
++		return true;
++
++	return false;
++}
++
++
++static bool wpa_bss_supported_rsne(struct wpa_supplicant *wpa_s,
++				   struct wpa_ssid *ssid, const u8 *ie)
++{
++	struct wpa_ie_data data;
++
++	if (wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) < 0)
++		return false;
++
++	/* Check that there is a supported AKM and pairwise cipher based on
++	 * overall capabilities */
++	if (!data.pairwise_cipher || !data.key_mgmt)
++		return false;
++
++	if (wpa_s->drv_capa_known) {
++		if (!wpa_bss_supported_cipher(wpa_s, data.pairwise_cipher) ||
++		    !wpa_bss_supported_key_mgmt(wpa_s, data.key_mgmt))
++			return false;
++	}
++
++	if (ssid) {
++		/* Check that there is a supported AKM and pairwise cipher
++		 * based on the specific network profile. */
++		if ((ssid->pairwise_cipher & data.pairwise_cipher) == 0)
++			return false;
++		if ((ssid->key_mgmt & data.key_mgmt) == 0)
++			return false;
++	}
++
++	return true;
++}
++
++
+ const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
+ 			    const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ 			    bool mlo)
+ {
++	const u8 *ie;
++
++	if (wpas_rsn_overriding(wpa_s)) {
++		if (!ssid)
++			ssid = wpa_s->current_ssid;
++
++		/* MLO cases for RSN overriding are required to use RSNE
++		 * Override 2 element and RSNXE Override element together. */
++		ie = wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
++		if (mlo && ie &&
++		    !wpa_bss_get_vendor_ie(bss,
++					   RSNXE_OVERRIDE_IE_VENDOR_TYPE)) {
++			wpa_printf(MSG_DEBUG, "BSS " MACSTR
++				   " advertises RSNE Override 2 element without RSNXE Override element - ignore RSNE Override 2 element for MLO",
++				   MAC2STR(bss->bssid));
++		} else if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie)) {
++			return ie;
++		}
++
++		if (!mlo) {
++			ie = wpa_bss_get_vendor_ie(
++				bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
++			if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie))
++				return ie;
++		}
++	}
++
+ 	return wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ }
+ 
+@@ -1880,5 +2045,33 @@ const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
+ 			     const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ 			     bool mlo)
+ {
++	const u8 *ie;
++
++	if (wpas_rsn_overriding(wpa_s)) {
++		ie = wpa_bss_get_vendor_ie(bss, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
++		if (ie) {
++			const u8 *tmp;
++
++			tmp = wpa_bss_get_rsne(wpa_s, bss, ssid, mlo);
++			if (!tmp || tmp[0] == WLAN_EID_RSN) {
++				/* An acceptable RSNE override element was not
++				 * found, so need to ignore RSNXE overriding. */
++				return NULL;
++			}
++
++			return ie;
++		}
++
++		/* MLO cases for RSN overriding are required to use RSNE
++		 * Override 2 element and RSNXE Override element together. */
++		if (mlo && wpa_bss_get_vendor_ie(
++			    bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE)) {
++			wpa_printf(MSG_DEBUG, "BSS " MACSTR
++				   " advertises RSNXE Override element without RSNE Override 2 element - ignore RSNXE Override element for MLO",
++				   MAC2STR(bss->bssid));
++			return NULL;
++		}
++	}
++
+ 	return wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ }
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index 24861c68f..b02b694a3 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -5579,6 +5579,7 @@ static const struct global_parse_data global_fields[] = {
+ 	{ INT_RANGE(extended_key_id, 0, 1), 0 },
+ #endif /* CONFIG_WNM */
+ 	{ INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0},
++	{ INT_RANGE(rsn_overriding, 0, 2), 0},
+ #ifdef CONFIG_PASN
+ #ifdef CONFIG_TESTING_OPTIONS
+ 	{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
+diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
+index 8981305c2..d74b5c455 100644
+--- a/wpa_supplicant/config.h
++++ b/wpa_supplicant/config.h
+@@ -1774,6 +1774,19 @@ struct wpa_config {
+ 	 */
+ 	int wowlan_disconnect_on_deinit;
+ 
++	/**
++	 * rsn_overriding - RSN overriding
++	 *
++	 * 0 = Disabled
++	 * 1 = Enabled automatically if the driver indicates support
++	 * 2 = Forced to be enabled even without driver capability indication
++	 */
++	enum rsn_overriding {
++		RSN_OVERRIDING_DISABLED = 0,
++		RSN_OVERRIDING_AUTO = 1,
++		RSN_OVERRIDING_ENABLED = 2,
++	} rsn_overriding;
++
+ #ifdef CONFIG_PASN
+ #ifdef CONFIG_TESTING_OPTIONS
+ 	/*
+diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
+index ad37bcf22..fd8eafe2b 100644
+--- a/wpa_supplicant/config_file.c
++++ b/wpa_supplicant/config_file.c
+@@ -1615,6 +1615,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
+ 	if (config->wowlan_disconnect_on_deinit)
+ 		fprintf(f, "wowlan_disconnect_on_deinit=%d\n",
+ 			config->wowlan_disconnect_on_deinit);
++	if (config->rsn_overriding)
++		fprintf(f, "rsn_overriding=%d\n", config->rsn_overriding);
+ #ifdef CONFIG_TESTING_OPTIONS
+ 	if (config->mld_force_single_link)
+ 		fprintf(f, "mld_force_single_link=1\n");
+diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
+index 4e55470bb..4393c469c 100644
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -1296,7 +1296,9 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ 
+ #ifdef CONFIG_SAE
+ 	ie = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+-	if (ie && ie[1] >= 1)
++	if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4 + 1)
++		rsnxe_capa = ie[4 + 2];
++	else if (ie && ie[1] >= 1)
+ 		rsnxe_capa = ie[2];
+ #endif /* CONFIG_SAE */
+ 
+@@ -3665,9 +3667,29 @@ no_pfs:
+ 			wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
+ 		}
+ 
++		if (wpas_rsn_overriding(wpa_s) &&
++		    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
++		    WPA_GET_BE32(&p[2]) == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
++			rsn_found = 1;
++			wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
++		}
++
++		if (!rsn_found &&
++		    wpas_rsn_overriding(wpa_s) &&
++		    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
++		    WPA_GET_BE32(&p[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
++			rsn_found = 1;
++			wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
++		}
++
+ 		if (p[0] == WLAN_EID_RSNX && p[1] >= 1)
+ 			wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
+ 
++		if (wpas_rsn_overriding(wpa_s) &&
++		    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
++		    WPA_GET_BE32(&p[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE)
++			wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
++
+ 		l -= len;
+ 		p += len;
+ 	}
+diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
+index 8df60393a..292897edd 100644
+--- a/wpa_supplicant/sme.c
++++ b/wpa_supplicant/sme.c
+@@ -191,7 +191,10 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
+ 		const u8 *rsnxe;
+ 
+ 		rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+-		if (rsnxe && rsnxe[1] >= 1)
++		if (rsnxe && rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC &&
++		    rsnxe[1] >= 1 + 4)
++			rsnxe_capa = rsnxe[2 + 4];
++		else if (rsnxe && rsnxe[1] >= 1)
+ 			rsnxe_capa = rsnxe[2];
+ 	}
+ 
+@@ -2464,6 +2467,28 @@ mscs_fail:
+ 		wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
+ 	}
+ 
++	if (wpas_rsn_overriding(wpa_s) &&
++	    wpas_ap_supports_rsn_overriding(wpa_s, wpa_s->current_bss) &&
++	    wpa_s->sme.assoc_req_ie_len + 2 + 4 <=
++	    sizeof(wpa_s->sme.assoc_req_ie)) {
++		u8 *pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
++		u32 type = 0;
++		const u8 *ie;
++
++		ie = wpa_bss_get_rsne(wpa_s, wpa_s->current_bss, ssid,
++				      wpa_s->valid_links);
++		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
++			type = WPA_GET_BE32(&ie[2]);
++
++		if (type) {
++			/* Indicate support for RSN overriding */
++			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++			*pos++ = 4;
++			WPA_PUT_BE32(pos, type);
++			wpa_s->sme.assoc_req_ie_len += 2 + 4;
++		}
++	}
++
+ 	params.bssid = bssid;
+ 	params.ssid = wpa_s->sme.ssid;
+ 	params.ssid_len = wpa_s->sme.ssid_len;
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index c27977560..3203446f1 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -3943,6 +3943,57 @@ mscs_end:
+ 		wpa_ie_len += multi_ap_ie_len;
+ 	}
+ 
++	if (!wpas_driver_bss_selection(wpa_s) &&
++	    wpas_rsn_overriding(wpa_s) &&
++	    wpas_ap_supports_rsn_overriding(wpa_s, bss) &&
++	    wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
++		u8 *pos = wpa_ie + wpa_ie_len;
++		u32 type = 0;
++		const u8 *ie;
++
++		ie = wpa_bss_get_rsne(wpa_s, bss, ssid, wpa_s->valid_links);
++		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
++			type = WPA_GET_BE32(&ie[2]);
++
++		if (type) {
++			/* Indicate support for RSN overriding */
++			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++			*pos++ = 4;
++			WPA_PUT_BE32(pos, type);
++			pos += 4;
++			wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
++				    pos - wpa_ie);
++			wpa_ie_len += 2 + 4;
++		}
++	}
++
++	if (wpas_driver_bss_selection(wpa_s) &&
++	    wpas_rsn_overriding(wpa_s)) {
++		if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
++			u8 *pos = wpa_ie + wpa_ie_len;
++
++			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++			*pos++ = 4;
++			WPA_PUT_BE32(pos, RSNE_OVERRIDE_IE_VENDOR_TYPE);
++			pos += 4;
++			wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
++				    pos - wpa_ie);
++			wpa_ie_len += 2 + 4;
++		}
++
++		if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
++			u8 *pos = wpa_ie + wpa_ie_len;
++
++			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++			*pos++ = 4;
++			WPA_PUT_BE32(pos, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
++			pos += 4;
++			wpa_hexdump(MSG_MSGDUMP, "RSNE Override 2",
++				    wpa_ie, pos - wpa_ie);
++			wpa_ie_len += 2 + 4;
++		}
++	}
++
+ 	params->wpa_ie = wpa_ie;
+ 	params->wpa_ie_len = wpa_ie_len;
+ 	params->auth_alg = algs;
+@@ -8557,6 +8608,28 @@ int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
+ }
+ 
+ 
++static bool wpas_driver_rsn_override(struct wpa_supplicant *wpa_s)
++{
++	return !!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA);
++}
++
++
++bool wpas_rsn_overriding(struct wpa_supplicant *wpa_s)
++{
++	if (wpa_s->conf->rsn_overriding == RSN_OVERRIDING_DISABLED)
++		return false;
++
++	if (wpa_s->conf->rsn_overriding == RSN_OVERRIDING_ENABLED)
++		return true;
++
++	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
++	    wpas_driver_bss_selection(wpa_s))
++		return wpas_driver_rsn_override(wpa_s);
++
++	return true;
++}
++
++
+ #if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
+ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
+ 					      struct wpa_ssid *ssid,
+@@ -9531,3 +9604,58 @@ bool wpas_is_6ghz_supported(struct wpa_supplicant *wpa_s, bool only_enabled)
+ 
+ 	return false;
+ }
++
++
++bool wpas_ap_supports_rsn_overriding(struct wpa_supplicant *wpa_s,
++				     struct wpa_bss *bss)
++{
++	int i;
++
++	if (!bss)
++		return false;
++	if (wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_IE_VENDOR_TYPE) ||
++	    wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
++		return true;
++
++	if (!wpa_s->valid_links)
++		return false;
++
++	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
++		if (!(wpa_s->valid_links & BIT(i)))
++			continue;
++		if (wpa_s->links[i].bss &&
++		    (wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
++					   RSNE_OVERRIDE_IE_VENDOR_TYPE) ||
++		     wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
++					   RSNE_OVERRIDE_2_IE_VENDOR_TYPE)))
++			return true;
++	}
++
++	return false;
++}
++
++
++bool wpas_ap_supports_rsn_overriding_2(struct wpa_supplicant *wpa_s,
++				       struct wpa_bss *bss)
++{
++	int i;
++
++	if (!bss)
++		return false;
++	if (wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
++		return true;
++
++	if (!wpa_s->valid_links)
++		return false;
++
++	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
++		if (!(wpa_s->valid_links & BIT(i)))
++			continue;
++		if (wpa_s->links[i].bss &&
++		    wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
++					  RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
++			return true;
++	}
++
++	return false;
++}
+diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
+index b08f5417a..b721f6504 100644
+--- a/wpa_supplicant/wpa_supplicant.conf
++++ b/wpa_supplicant/wpa_supplicant.conf
+@@ -878,6 +878,15 @@ fast_reauth=1
+ # 1 = auto: Activate Extended Key ID support if the driver supports it
+ #extended_key_id=0
+ 
++# RSN overriding
++# NOTE: The protocol used for this mechanism is still subject to change and as
++# such, this should not yet be enabled for production uses to avoid issues if
++# something were to change.
++# 0 = Disabled (default)
++# 1 = Enabled automatically if the driver indicates support
++# 2 = Forced to be enabled even without driver capability indication
++#rsn_overriding=0
++
+ # network block
+ #
+ # Each network (usually AP's sharing the same SSID) is configured as a separate
+diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
+index e92f6b147..3043bc654 100644
+--- a/wpa_supplicant/wpa_supplicant_i.h
++++ b/wpa_supplicant/wpa_supplicant_i.h
+@@ -1727,6 +1727,7 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
+ void fils_connection_failure(struct wpa_supplicant *wpa_s);
+ void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
+ int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
++bool wpas_rsn_overriding(struct wpa_supplicant *wpa_s);
+ int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
+ void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason,
+ 		      const u8 *bssid);
+@@ -2011,5 +2012,9 @@ bool wpas_is_6ghz_supported(struct wpa_supplicant *wpa_s, bool only_enabled);
+ 
+ bool wpa_is_non_eht_scs_traffic_desc_supported(struct wpa_bss *bss);
+ bool wpas_ap_link_address(struct wpa_supplicant *wpa_s, const u8 *addr);
++bool wpas_ap_supports_rsn_overriding(struct wpa_supplicant *wpa_s,
++				     struct wpa_bss *bss);
++bool wpas_ap_supports_rsn_overriding_2(struct wpa_supplicant *wpa_s,
++				       struct wpa_bss *bss);
+ 
+ #endif /* WPA_SUPPLICANT_I_H */
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch
new file mode 100644
index 0000000000..c28a411d19
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch
@@ -0,0 +1,415 @@ 
+From 62ca121f9625ffe16b2d5764568bf6ccffd7d64e Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Mon, 29 Jul 2024 15:41:59 +0300
+Subject: [PATCH 10/11] RSNO: Use the RSN Selection element to indicate which
+ variant was used
+
+This replaces the use of the RSNE Override and RSNE Override 2 elements
+with empty payload to indicate which RSNE variant was used.
+
+In addition, this adds stricter validation of the RSNE in
+(Re)Association Request frame to allow only the pairwise cipher suites
+and AKMs listed in the indicated RSNE variant to be used.
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=62ca121f9625ffe16b2d5764568bf6ccffd7d64e]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/ieee802_11_common.c  |  9 +++++++
+ src/common/ieee802_11_common.h  |  2 ++
+ src/common/ieee802_11_defs.h    |  2 ++
+ src/common/wpa_common.c         |  6 +++++
+ src/common/wpa_common.h         | 10 +++++++
+ src/rsn_supp/wpa.c              | 38 +++++++++++++++++++++++++-
+ src/rsn_supp/wpa.h              |  8 ++++++
+ src/rsn_supp/wpa_i.h            |  2 ++
+ wpa_supplicant/events.c         | 22 ++++++++++++++-
+ wpa_supplicant/sme.c            | 36 ++++++++++++++++++-------
+ wpa_supplicant/wpa_supplicant.c | 47 +++++++++++++++++++++++----------
+ 11 files changed, 157 insertions(+), 25 deletions(-)
+
+diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
+index 3ca1ffe7e..3e6fba5bd 100644
+--- a/src/common/ieee802_11_common.c
++++ b/src/common/ieee802_11_common.c
+@@ -148,6 +148,15 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
+ 			elems->rsne_override_2 = pos;
+ 			elems->rsne_override_2_len = elen;
+ 			break;
++		case WFA_RSN_SELECTION_OUI_TYPE:
++			if (elen < 4 + 1) {
++				wpa_printf(MSG_DEBUG,
++					   "Too short RSN Selection element ignored");
++				return -1;
++			}
++			elems->rsn_selection = pos + 4;
++			elems->rsn_selection_len = elen - 4;
++			break;
+ 		default:
+ 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
+ 				   "information element ignored "
+diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
+index 46a86096e..d4c691e1b 100644
+--- a/src/common/ieee802_11_common.h
++++ b/src/common/ieee802_11_common.h
+@@ -118,6 +118,7 @@ struct ieee802_11_elems {
+ 	const u8 *mbssid;
+ 	const u8 *rsne_override;
+ 	const u8 *rsne_override_2;
++	const u8 *rsn_selection;
+ 
+ 	u8 ssid_len;
+ 	u8 supp_rates_len;
+@@ -183,6 +184,7 @@ struct ieee802_11_elems {
+ 	u8 mbssid_len;
+ 	size_t rsne_override_len;
+ 	size_t rsne_override_2_len;
++	size_t rsn_selection_len;
+ 
+ 	struct mb_ies_info mb_ies;
+ 
+diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
+index e2c132a40..db9e90355 100644
+--- a/src/common/ieee802_11_defs.h
++++ b/src/common/ieee802_11_defs.h
+@@ -1449,9 +1449,11 @@ struct ieee80211_ampe_ie {
+ #define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29
+ #define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a
+ #define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b
++#define WFA_RSN_SELECTION_OUI_TYPE 0x2c
+ #define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29
+ #define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a
+ #define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
++#define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c
+ 
+ #define MULTI_AP_SUB_ELEM_TYPE 0x06
+ #define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07
+diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
+index 8eb4a1dab..bfaca9128 100644
+--- a/src/common/wpa_common.c
++++ b/src/common/wpa_common.c
+@@ -3629,6 +3629,12 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
+ 		return 0;
+ 	}
+ 
++	if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
++		ie->rsn_selection = p;
++		ie->rsn_selection_len = left;
++		return 0;
++	}
++
+ 	return 2;
+ }
+ 
+diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
+index 1e3136843..c8cdf748d 100644
+--- a/src/common/wpa_common.h
++++ b/src/common/wpa_common.h
+@@ -643,6 +643,14 @@ struct wpa_pasn_params_data {
+ #define WPA_PASN_PUBKEY_COMPRESSED_1 0x03
+ #define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
+ 
++/* WPA3 specification - RSN Selection element */
++enum rsn_selection_variant {
++	RSN_SELECTION_RSNE = 0,
++	RSN_SELECTION_RSNE_OVERRIDE = 1,
++	RSN_SELECTION_RSNE_OVERRIDE_2 = 2,
++};
++
++
+ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
+ 		     int key_mgmt, bool reassoc_resp);
+ void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse);
+@@ -704,6 +712,8 @@ struct wpa_eapol_ie_parse {
+ 	u16 aid;
+ 	const u8 *wmm;
+ 	size_t wmm_len;
++	const u8 *rsn_selection;
++	size_t rsn_selection_len;
+ 	u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */
+ 	const u8 *mlo_gtk[MAX_NUM_MLD_LINKS];
+ 	size_t mlo_gtk_len[MAX_NUM_MLD_LINKS];
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index e48982989..9b13b3a84 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -531,7 +531,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
+ 	size_t mic_len, hdrlen, rlen, extra_len = 0;
+ 	struct wpa_eapol_key *reply;
+ 	u8 *rbuf, *key_mic;
+-	u8 *rsn_ie_buf = NULL;
++	u8 *rsn_ie_buf = NULL, *buf2 = NULL;
+ 	u16 key_info;
+ #ifdef CONFIG_TESTING_OPTIONS
+ 	size_t pad_len = 0;
+@@ -581,6 +581,37 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
+ 	}
+ #endif /* CONFIG_IEEE80211R */
+ 
++	if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
++		u8 *pos;
++
++		buf2 = os_malloc(wpa_ie_len + 2 + 4 + 1);
++		if (!buf2) {
++			os_free(rsn_ie_buf);
++			return -1;
++		}
++		os_memcpy(buf2, wpa_ie, wpa_ie_len);
++		pos = buf2 + wpa_ie_len;
++		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++		*pos++ = 4 + 1;
++		WPA_PUT_BE32(pos, RSN_SELECTION_IE_VENDOR_TYPE);
++		pos += 4;
++		if (sm->rsn_override == RSN_OVERRIDE_RSNE) {
++			*pos++ = RSN_SELECTION_RSNE;
++		} else if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
++			*pos++ = RSN_SELECTION_RSNE_OVERRIDE;
++		} else if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE_2) {
++			*pos++ = RSN_SELECTION_RSNE_OVERRIDE_2;
++		} else {
++			os_free(rsn_ie_buf);
++			os_free(buf2);
++			return -1;
++		}
++
++		wpa_ie = buf2;
++		wpa_ie_len += 2 + 4 + 1;
++
++	}
++
+ 	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
+ 
+ #ifdef CONFIG_TESTING_OPTIONS
+@@ -601,6 +632,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
+ 				  &rlen, (void *) &reply);
+ 	if (rbuf == NULL) {
+ 		os_free(rsn_ie_buf);
++		os_free(buf2);
+ 		return -1;
+ 	}
+ 
+@@ -633,6 +665,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
+ 	WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len + extra_len);
+ 	os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
+ 	os_free(rsn_ie_buf);
++	os_free(buf2);
+ #ifdef CONFIG_TESTING_OPTIONS
+ 	if (sm->test_eapol_m2_elems) {
+ 		os_memcpy(key_mic + mic_len + 2 + wpa_ie_len,
+@@ -4767,6 +4800,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
+ 	case WPA_PARAM_SSID_PROTECTION:
+ 		sm->ssid_protection = value;
+ 		break;
++	case WPA_PARAM_RSN_OVERRIDE:
++		sm->rsn_override = value;
++		break;
+ 	default:
+ 		break;
+ 	}
+diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
+index 2bef093e3..f8346e1ef 100644
+--- a/src/rsn_supp/wpa.h
++++ b/src/rsn_supp/wpa.h
+@@ -137,6 +137,14 @@ enum wpa_sm_conf_params {
+ 	WPA_PARAM_ENCRYPT_EAPOL_M4,
+ 	WPA_PARAM_FT_PREPEND_PMKID,
+ 	WPA_PARAM_SSID_PROTECTION,
++	WPA_PARAM_RSN_OVERRIDE,
++};
++
++enum wpa_rsn_override {
++	RSN_OVERRIDE_NOT_USED,
++	RSN_OVERRIDE_RSNE,
++	RSN_OVERRIDE_RSNE_OVERRIDE,
++	RSN_OVERRIDE_RSNE_OVERRIDE_2,
+ };
+ 
+ struct rsn_supp_config {
+diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
+index d7e780519..6e4797577 100644
+--- a/src/rsn_supp/wpa_i.h
++++ b/src/rsn_supp/wpa_i.h
+@@ -229,6 +229,8 @@ struct wpa_sm {
+ 	bool wmm_enabled;
+ 	bool driver_bss_selection;
+ 	bool ft_prepend_pmkid;
++
++	enum wpa_rsn_override rsn_override;
+ };
+ 
+ 
+diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
+index 4393c469c..93191c7fe 100644
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -3368,9 +3368,10 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
+ 					  union wpa_event_data *data)
+ {
+ 	int l, len, found = 0, found_x = 0, wpa_found, rsn_found;
+-	const u8 *p;
++	const u8 *p, *ie;
+ 	u8 bssid[ETH_ALEN];
+ 	bool bssid_known;
++	enum wpa_rsn_override rsn_override;
+ 
+ 	wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
+ 	wpa_s->ssid_verified = false;
+@@ -3482,6 +3483,25 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
+ 	if (!found_x && data->assoc_info.req_ies)
+ 		wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+ 
++	rsn_override = RSN_OVERRIDE_NOT_USED;
++	ie = get_vendor_ie(data->assoc_info.req_ies,
++			   data->assoc_info.req_ies_len,
++			   RSN_SELECTION_IE_VENDOR_TYPE);
++	if (ie && ie[1] >= 4 + 1) {
++		switch (ie[2 + 4]) {
++		case RSN_SELECTION_RSNE:
++			rsn_override = RSN_OVERRIDE_RSNE;
++			break;
++		case RSN_SELECTION_RSNE_OVERRIDE:
++			rsn_override = RSN_OVERRIDE_RSNE_OVERRIDE;
++			break;
++		case RSN_SELECTION_RSNE_OVERRIDE_2:
++			rsn_override = RSN_OVERRIDE_RSNE_OVERRIDE_2;
++			break;
++		}
++	}
++	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE, rsn_override);
++
+ #ifdef CONFIG_FILS
+ #ifdef CONFIG_SME
+ 	if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
+diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
+index 292897edd..443b0b667 100644
+--- a/wpa_supplicant/sme.c
++++ b/wpa_supplicant/sme.c
+@@ -2467,26 +2467,44 @@ mscs_fail:
+ 		wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
+ 	}
+ 
++	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE,
++			 RSN_OVERRIDE_NOT_USED);
+ 	if (wpas_rsn_overriding(wpa_s) &&
+ 	    wpas_ap_supports_rsn_overriding(wpa_s, wpa_s->current_bss) &&
+ 	    wpa_s->sme.assoc_req_ie_len + 2 + 4 <=
+ 	    sizeof(wpa_s->sme.assoc_req_ie)) {
+ 		u8 *pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
+-		u32 type = 0;
+ 		const u8 *ie;
++		enum rsn_selection_variant variant = RSN_SELECTION_RSNE;
+ 
++		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE,
++				 RSN_OVERRIDE_RSNE);
+ 		ie = wpa_bss_get_rsne(wpa_s, wpa_s->current_bss, ssid,
+ 				      wpa_s->valid_links);
+-		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
+-			type = WPA_GET_BE32(&ie[2]);
++		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4) {
++			u32 type;
+ 
+-		if (type) {
+-			/* Indicate support for RSN overriding */
+-			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
+-			*pos++ = 4;
+-			WPA_PUT_BE32(pos, type);
+-			wpa_s->sme.assoc_req_ie_len += 2 + 4;
++			type = WPA_GET_BE32(&ie[2]);
++			if (type == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
++				variant = RSN_SELECTION_RSNE_OVERRIDE;
++				wpa_sm_set_param(wpa_s->wpa,
++						 WPA_PARAM_RSN_OVERRIDE,
++						 RSN_OVERRIDE_RSNE_OVERRIDE);
++			} else if (type == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
++				variant = RSN_SELECTION_RSNE_OVERRIDE_2;
++				wpa_sm_set_param(wpa_s->wpa,
++						 WPA_PARAM_RSN_OVERRIDE,
++						 RSN_OVERRIDE_RSNE_OVERRIDE_2);
++			}
+ 		}
++
++		/* Indicate which RSNE variant was used */
++		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++		*pos++ = 4 + 1;
++		WPA_PUT_BE32(pos, RSN_SELECTION_IE_VENDOR_TYPE);
++		pos += 4;
++		*pos = variant;
++		wpa_s->sme.assoc_req_ie_len += 2 + 4 + 1;
+ 	}
+ 
+ 	params.bssid = bssid;
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index 3203446f1..81eadbc9b 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -3943,32 +3943,51 @@ mscs_end:
+ 		wpa_ie_len += multi_ap_ie_len;
+ 	}
+ 
++	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE,
++			 RSN_OVERRIDE_NOT_USED);
+ 	if (!wpas_driver_bss_selection(wpa_s) &&
+ 	    wpas_rsn_overriding(wpa_s) &&
+ 	    wpas_ap_supports_rsn_overriding(wpa_s, bss) &&
+-	    wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
+-		u8 *pos = wpa_ie + wpa_ie_len;
+-		u32 type = 0;
++	    wpa_ie_len + 2 + 4 + 1 <= max_wpa_ie_len) {
++		u8 *pos = wpa_ie + wpa_ie_len, *start = pos;
+ 		const u8 *ie;
++		enum rsn_selection_variant variant = RSN_SELECTION_RSNE;
+ 
++		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE,
++				 RSN_OVERRIDE_RSNE);
+ 		ie = wpa_bss_get_rsne(wpa_s, bss, ssid, wpa_s->valid_links);
+-		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
+-			type = WPA_GET_BE32(&ie[2]);
++		if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4) {
++			u32 type;
+ 
+-		if (type) {
+-			/* Indicate support for RSN overriding */
+-			*pos++ = WLAN_EID_VENDOR_SPECIFIC;
+-			*pos++ = 4;
+-			WPA_PUT_BE32(pos, type);
+-			pos += 4;
+-			wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
+-				    pos - wpa_ie);
+-			wpa_ie_len += 2 + 4;
++			type = WPA_GET_BE32(&ie[2]);
++			if (type == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
++				variant = RSN_SELECTION_RSNE_OVERRIDE;
++				wpa_sm_set_param(wpa_s->wpa,
++						 WPA_PARAM_RSN_OVERRIDE,
++						 RSN_OVERRIDE_RSNE_OVERRIDE);
++			} else if (type == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
++				variant = RSN_SELECTION_RSNE_OVERRIDE_2;
++				wpa_sm_set_param(wpa_s->wpa,
++						 WPA_PARAM_RSN_OVERRIDE,
++						 RSN_OVERRIDE_RSNE_OVERRIDE_2);
++			}
+ 		}
++
++		/* Indicate which RSNE variant was used */
++		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
++		*pos++ = 4 + 1;
++		WPA_PUT_BE32(pos, RSN_SELECTION_IE_VENDOR_TYPE);
++		pos += 4;
++		*pos++ = variant;
++		wpa_hexdump(MSG_MSGDUMP, "RSN Selection", start, pos - start);
++		wpa_ie_len += pos - start;
+ 	}
+ 
+ 	if (wpas_driver_bss_selection(wpa_s) &&
+ 	    wpas_rsn_overriding(wpa_s)) {
++		/* TODO: Replace this indication of support for RSN overriding
++		 * to the driver in driver-based BSS selection cases with
++		 * something cleaner. */
+ 		if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
+ 			u8 *pos = wpa_ie + wpa_ie_len;
+ 
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch
new file mode 100644
index 0000000000..9be8757102
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch
@@ -0,0 +1,84 @@ 
+From 6f522baa1b445536b3aa7ea0d3a28475fa91e644 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <quic_jouni@quicinc.com>
+Date: Mon, 29 Jul 2024 16:43:50 +0300
+Subject: [PATCH 11/11] RSNO: Use SNonce cookie to indicate support for RSN
+ overriding
+
+This provides an implicitly protected (SNonce is used as an input to PTK
+derivation) mechanism for a STA to indicate support for RSN overriding
+in a manner that does not cause interopability issues with deployed APs.
+
+In addition, update sm->SNonce on the Authenticator only based on
+message 2/4 since that is the only EAPOL-Key message that is defined to
+provide the actual SNonce value. While clearing of this internal buffer
+on message 4/4 might not cause issues, it is better to keep the actual
+SNonce value here since the SNonce cookie can be used at a later point
+in the sequence.
+
+Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
+
+Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?h=hostap_2_11&id=6f522baa1b445536b3aa7ea0d3a28475fa91e644]
+Signed-off-by: Jiacheng Shi <jiacheng.shi@oss.qualcomm.com>
+---
+ src/common/wpa_common.c | 21 +++++++++++++++++++++
+ src/common/wpa_common.h |  3 +++
+ src/rsn_supp/wpa.c      |  2 ++
+ 3 files changed, 26 insertions(+)
+
+diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
+index bfaca9128..4f58f0737 100644
+--- a/src/common/wpa_common.c
++++ b/src/common/wpa_common.c
+@@ -4274,3 +4274,24 @@ int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len)
+ }
+ 
+ #endif /* CONFIG_PASN */
++
++
++void rsn_set_snonce_cookie(u8 *snonce)
++{
++	u8 *pos;
++
++	pos = snonce + WPA_NONCE_LEN - 6;
++	WPA_PUT_BE24(pos, OUI_WFA);
++	pos += 3;
++	WPA_PUT_BE24(pos, 0x000029);
++}
++
++
++bool rsn_is_snonce_cookie(const u8 *snonce)
++{
++	const u8 *pos;
++
++	pos = snonce + WPA_NONCE_LEN - 6;
++	return WPA_GET_BE24(pos) == OUI_WFA &&
++		WPA_GET_BE24(pos + 3) == 0x000029;
++}
+diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
+index c8cdf748d..4cb5b8c60 100644
+--- a/src/common/wpa_common.h
++++ b/src/common/wpa_common.h
+@@ -797,4 +797,7 @@ int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
+ void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab);
+ int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len);
+ 
++void rsn_set_snonce_cookie(u8 *snonce);
++bool rsn_is_snonce_cookie(const u8 *snonce);
++
+ #endif /* WPA_COMMON_H */
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index 9b13b3a84..0a1d4d07f 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -1023,6 +1023,8 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
+ 				"WPA: Failed to get random data for SNonce");
+ 			goto failed;
+ 		}
++		if (sm->rsn_override != RSN_OVERRIDE_NOT_USED)
++			rsn_set_snonce_cookie(sm->snonce);
+ 		sm->renew_snonce = 0;
+ 		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
+ 			    sm->snonce, WPA_NONCE_LEN);
+-- 
+2.34.1
+
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.11.bb b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.11.bb
index 7c7a8bd9c1..ca1bf2ab42 100644
--- a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.11.bb
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.11.bb
@@ -19,6 +19,17 @@  SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \
            file://0002-defconfig-Update-Opportunistic-Wireless-Encryption-O.patch \
            file://0003-defconfig-Document-IEEE-802.11be-as-a-published-amen.patch \
            file://0004-defconfig-Uncomment-CONFIG_IEEE80211BE-y.patch \
+           file://0005-Define-WFA-vendor-specific-element-types-for-RSNE-RS.patch \
+           file://0006-Add-RSN-overriding-elements-into-IE-parsing.patch \
+           file://0007-Allow-RSNE-Override-element-to-override-RSNE-content.patch \
+           file://0008-Allow-RSNXE-Override-element-to-override-RSNXE-conte.patch \
+           file://0009-Add-QCA-vendor-feature-flags-to-indicate-RSN-overrid.patch \
+           file://0010-nl80211-Add-a-capability-flag-for-RSN-overriding.patch \
+           file://0011-Use-helper-functions-to-access-RSNE-RSNXE-from-BSS-e.patch \
+           file://0012-Make-driver-capabilities-for-AKM-suites-available-wi.patch \
+           file://0013-RSNE-RSNXE-overriding-for-STA.patch \
+           file://0014-RSNO-Use-the-RSN-Selection-element-to-indicate-which.patch \
+           file://0015-RSNO-Use-SNonce-cookie-to-indicate-support-for-RSN-o.patch \
            file://CVE-2025-24912-01.patch \
            file://CVE-2025-24912-02.patch \
            "