Cumulative patch from commit 077232f603dbbef3ac06b33cc793d346be8c5af8

077232f60 OCE: Add OCE capability attribute only when associating to an OCE AP
2ac433340 OCE: Send scan parameters when OCE_STA functionality is enabled
d6801b054 nl80211: Support OCE features (driver capability and scan params)
938dd97a8 driver: Add OCE scan parameters
830eacf9d Sync with mac80211-next.git include/uapi/linux/nl80211.h
2543b19e4 random: Remove write-only variable random_entropy_file_read
b5ebe5dd5 hostapd: Send an event before throwing a station on re-authentication
57151ae98 atheros: Fix atheros_send_mgmt() dependency on CONFIG_FILS
410e2dd1d OWE: Fix build error in AP code without CONFIG_IEEE80211W=y
560e30bf3 Parse sae_password option when CONFIG_SAE is enabled
b898b6558 nl80211: Do not ignore disconnect event in case of !drv->associated
20f612d99 DPP: Set group id through DPP_AUTH_INIT or dpp_configurator_params
495aebd39 Add new QCA vendor command and attributes to enhance NAN
28c7f77a8 Correct the documentation of NAN vendor command
b3f24b06e mka: Fix confidentiality offset issue in macsec_qca driver interface
bed30e8d3 mka: Fix sci port mask issue in macsec_qca driver interface
1bac151ea Change the ADDBA buffer size attribute type to U16 from U8
d35003e50 Vendor attribute to get max blacklist BSSIDs capability
8bfbb295d nl80211: Fix sending of WDS STA event to the correct BSS context
af835d75b FILS: Fix FILS connect failures after ERP key invalidation
1ff860577 mka: Support GCM-AES-256
47abe29aa hostapd: SET ht_capab support for disabling 40 MHz bandwidth
567df5501 Re-configure WEP keys on hostapd interface re-enable
1e1245bc8 Fix QoS Mapping ext capab bit setting
373c79694 OpenSSL: Fix compile with OpenSSL 1.1.0 and deprecated APIs
c6e1a9a0b Clarify the TODO comment regarding PMKID KDE in EAPOL-Key msg 1/4
3e34cfdff WPA: Ignore unauthenticated encrypted EAPOL-Key data
c06cd3e0a HS 2.0: Fix hs20-osu-client handling of HomeSP/HomeOIList/<X+>/HomeOI
ecec4878b Provide more details of WPA3 modes in wpa_supplicant.conf
e7d73c378 Provide more details of WPA3 modes in hostapd.conf
cbdf5a49c Define test config vendor attribute to override MU EDCA

Bug: 113905758
Test: Device boots up and connects to wifi networks.
Test: Able to turn on/off softap.
Test: Regression test passed (Bug: 114246387)
Change-Id: I81d5922c7af382322cc78a5a2dc51a2aec9ff234
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index d14203f..899c4c2 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -540,6 +540,7 @@
 	size_t pass_len = 0;
 	u8 psk[PMK_LEN];
 	int psk_set = 0;
+	char *group_id = NULL;
 
 	if (!cmd)
 		return;
@@ -575,6 +576,20 @@
 		psk_set = 1;
 	}
 
+	pos = os_strstr(cmd, " group_id=");
+	if (pos) {
+		size_t group_id_len;
+
+		pos += 10;
+		end = os_strchr(pos, ' ');
+		group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
+		group_id = os_malloc(group_id_len + 1);
+		if (!group_id)
+			goto fail;
+		os_memcpy(group_id, pos, group_id_len);
+		group_id[group_id_len] = '\0';
+	}
+
 	if (os_strstr(cmd, " conf=sta-")) {
 		conf_sta = os_zalloc(sizeof(struct dpp_configuration));
 		if (!conf_sta)
@@ -602,6 +617,10 @@
 		} else {
 			goto fail;
 		}
+		if (os_strstr(cmd, " group_id=")) {
+			conf_sta->group_id = group_id;
+			group_id = NULL;
+		}
 	}
 
 	if (os_strstr(cmd, " conf=ap-")) {
@@ -631,6 +650,10 @@
 		} else {
 			goto fail;
 		}
+		if (os_strstr(cmd, " group_id=")) {
+			conf_ap->group_id = group_id;
+			group_id = NULL;
+		}
 	}
 
 	pos = os_strstr(cmd, " expiry=");
@@ -660,12 +683,14 @@
 	auth->conf_sta = conf_sta;
 	auth->conf_ap = conf_ap;
 	auth->conf = conf;
+	os_free(group_id);
 	return;
 
 fail:
 	wpa_printf(MSG_DEBUG, "DPP: Failed to set configurator parameters");
 	dpp_configuration_free(conf_sta);
 	dpp_configuration_free(conf_ap);
+	os_free(group_id);
 }
 
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c94007c..29fb7ec 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3972,10 +3972,12 @@
 
 #ifdef CONFIG_FILS
 	/* Update ERP next sequence number */
-	if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS)
+	if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
 		eapol_sm_update_erp_next_seq_num(
 			wpa_s->eapol,
 			data->assoc_reject.fils_erp_next_seq_num);
+		fils_connection_failure(wpa_s);
+	}
 #endif /* CONFIG_FILS */
 
 	wpas_connection_failed(wpa_s, bssid);
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 129d205..5adf61e 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -38,6 +38,19 @@
 }
 
 
+const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr)
+{
+	const u8 *mbo;
+	u8 ie_len = mbo_ie[1];
+
+	if (ie_len < MBO_IE_HEADER - 2)
+		return NULL;
+	mbo = mbo_ie + MBO_IE_HEADER;
+
+	return get_ie(mbo, 2 + ie_len - MBO_IE_HEADER, attr);
+}
+
+
 const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr)
 {
 	const u8 *mbo, *end;
@@ -149,7 +162,8 @@
 }
 
 
-int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len)
+int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len,
+		int add_oce_capa)
 {
 	struct wpabuf *mbo;
 	int res;
@@ -175,7 +189,7 @@
 	wpabuf_put_u8(mbo, wpa_s->conf->mbo_cell_capa);
 
 	/* Add OCE capability indication attribute if OCE is enabled */
-	if (wpa_s->enable_oce & OCE_STA) {
+	if ((wpa_s->enable_oce & OCE_STA) && add_oce_capa) {
 		wpabuf_put_u8(mbo, OCE_ATTR_ID_CAPA_IND);
 		wpabuf_put_u8(mbo, 1);
 		wpabuf_put_u8(mbo, OCE_RELEASE);
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 104b258..56d53fb 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -455,6 +455,33 @@
 #endif /* CONFIG_INTERWORKING */
 
 
+#ifdef CONFIG_MBO
+static void wpas_fils_req_param_add_max_channel(struct wpa_supplicant *wpa_s,
+						struct wpabuf **ie)
+{
+	if (wpabuf_resize(ie, 5)) {
+		wpa_printf(MSG_DEBUG,
+			   "Failed to allocate space for FILS Request Parameters element");
+		return;
+	}
+
+	/* FILS Request Parameters element */
+	wpabuf_put_u8(*ie, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(*ie, 3); /* FILS Request attribute length */
+	wpabuf_put_u8(*ie, WLAN_EID_EXT_FILS_REQ_PARAMS);
+	/* Parameter control bitmap */
+	wpabuf_put_u8(*ie, 0);
+	/* Max Channel Time field - contains the value of MaxChannelTime
+	 * parameter of the MLME-SCAN.request primitive represented in units of
+	 * TUs, as an unsigned integer. A Max Channel Time field value of 255
+	 * is used to indicate any duration of more than 254 TUs, or an
+	 * unspecified or unknown duration. (IEEE Std 802.11ai-2016, 9.4.2.178)
+	 */
+	wpabuf_put_u8(*ie, 255);
+}
+#endif /* CONFIG_MBO */
+
+
 void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
 {
 	struct wpabuf *default_ies = NULL;
@@ -476,6 +503,8 @@
 		wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
 
 #ifdef CONFIG_MBO
+	if (wpa_s->enable_oce & OCE_STA)
+		wpas_fils_req_param_add_max_channel(wpa_s, &default_ies);
 	/* Send MBO and OCE capabilities */
 	if (wpabuf_resize(&default_ies, 12) == 0)
 		wpas_mbo_scan_ie(wpa_s, default_ies);
@@ -517,6 +546,11 @@
 		wpas_add_interworking_elements(wpa_s, extra_ie);
 #endif /* CONFIG_INTERWORKING */
 
+#ifdef CONFIG_MBO
+	if (wpa_s->enable_oce & OCE_STA)
+		wpas_fils_req_param_add_max_channel(wpa_s, &extra_ie);
+#endif /* CONFIG_MBO */
+
 #ifdef CONFIG_WPS
 	wps = wpas_wps_in_use(wpa_s, &req_type);
 
@@ -1077,6 +1111,11 @@
 		}
 	}
 
+#ifdef CONFIG_MBO
+	if (wpa_s->enable_oce & OCE_STA)
+		params.oce_scan = 1;
+#endif /* CONFIG_MBO */
+
 	params.filter_ssids = wpa_supplicant_build_filter_ssids(
 		wpa_s->conf, &params.num_filter_ssids);
 	if (extra_ie) {
@@ -1486,6 +1525,11 @@
 		int_array_concat(&params.freqs, wpa_s->conf->freq_list);
 	}
 
+#ifdef CONFIG_MBO
+	if (wpa_s->enable_oce & OCE_STA)
+		params.oce_scan = 1;
+#endif /* CONFIG_MBO */
+
 	scan_params = &params;
 
 scan:
@@ -2401,6 +2445,7 @@
 	params->low_priority = src->low_priority;
 	params->duration = src->duration;
 	params->duration_mandatory = src->duration_mandatory;
+	params->oce_scan = src->oce_scan;
 
 	if (src->sched_scan_plans_num > 0) {
 		params->sched_scan_plans =
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index d57195f..708a347 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -240,6 +240,9 @@
 	u8 ext_capab[18];
 	int ext_capab_len;
 	int skip_auth;
+#ifdef CONFIG_MBO
+	const u8 *mbo_ie;
+#endif /* CONFIG_MBO */
 
 	if (bss == NULL) {
 		wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for "
@@ -539,13 +542,16 @@
 	}
 
 #ifdef CONFIG_MBO
-	if (wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
+	mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
+	if (mbo_ie) {
 		int len;
 
 		len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
 				  wpa_s->sme.assoc_req_ie_len,
 				  sizeof(wpa_s->sme.assoc_req_ie) -
-				  wpa_s->sme.assoc_req_ie_len);
+				  wpa_s->sme.assoc_req_ie_len,
+				  !!mbo_attr_from_mbo_ie(mbo_ie,
+							 OCE_ATTR_ID_CAPA_IND));
 		if (len >= 0)
 			wpa_s->sme.assoc_req_ie_len += len;
 	}
@@ -591,6 +597,9 @@
 	    wpa_key_mgmt_fils(ssid->key_mgmt)) {
 		const u8 *indic;
 		u16 fils_info;
+		const u8 *realm, *username, *rrk;
+		size_t realm_len, username_len, rrk_len;
+		u16 next_seq_num;
 
 		/*
 		 * Check FILS Indication element (FILS Information field) bits
@@ -620,6 +629,19 @@
 			goto no_fils;
 		}
 
+		if (wpa_s->last_con_fail_realm &&
+		    eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
+					  &username, &username_len,
+					  &realm, &realm_len, &next_seq_num,
+					  &rrk, &rrk_len) == 0 &&
+		    realm && realm_len == wpa_s->last_con_fail_realm_len &&
+		    os_memcmp(realm, wpa_s->last_con_fail_realm,
+			      realm_len) == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "SME: FILS authentication for this realm failed last time - try to regenerate ERP key hierarchy");
+			goto no_fils;
+		}
+
 		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
 					    ssid, 0,
 					    wpa_bss_get_fils_cache_id(bss),
@@ -1195,6 +1217,12 @@
 			ie_txt ? ie_txt : "");
 		os_free(ie_txt);
 
+#ifdef CONFIG_FILS
+		if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
+		    wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS)
+			fils_connection_failure(wpa_s);
+#endif /* CONFIG_FILS */
+
 		if (data->auth.status_code !=
 		    WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
 		    wpa_s->sme.auth_alg == data->auth.auth_type ||
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index c2529e6..fc13a57 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -281,6 +281,9 @@
 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
 	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
 	wpa_blacklist_del(wpa_s, wpa_s->bssid);
+	os_free(wpa_s->last_con_fail_realm);
+	wpa_s->last_con_fail_realm = NULL;
+	wpa_s->last_con_fail_realm_len = 0;
 }
 
 
@@ -505,6 +508,10 @@
 	os_free(wpa_s->confanother);
 	wpa_s->confanother = NULL;
 
+	os_free(wpa_s->last_con_fail_realm);
+	wpa_s->last_con_fail_realm = NULL;
+	wpa_s->last_con_fail_realm_len = 0;
+
 	wpa_sm_set_eapol(wpa_s->wpa, NULL);
 	eapol_sm_deinit(wpa_s->eapol);
 	wpa_s->eapol = NULL;
@@ -1657,7 +1664,7 @@
 		break;
 	case 4: /* Bits 32-39 */
 #ifdef CONFIG_INTERWORKING
-		if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
+		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)
 			*pos |= 0x01; /* Bit 32 - QoS Map */
 #endif /* CONFIG_INTERWORKING */
 		break;
@@ -2438,6 +2445,9 @@
 	size_t max_wpa_ie_len = 500;
 	size_t wpa_ie_len;
 	int algs = WPA_AUTH_ALG_OPEN;
+#ifdef CONFIG_MBO
+	const u8 *mbo_ie;
+#endif
 #ifdef CONFIG_FILS
 	const u8 *realm, *username, *rrk;
 	size_t realm_len, username_len, rrk_len;
@@ -2546,7 +2556,10 @@
 	    ssid->eap.erp && wpa_key_mgmt_fils(wpa_s->key_mgmt) &&
 	    eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap, &username,
 				  &username_len, &realm, &realm_len,
-				  &next_seq_num, &rrk, &rrk_len) == 0) {
+				  &next_seq_num, &rrk, &rrk_len) == 0 &&
+	    (!wpa_s->last_con_fail_realm ||
+	     wpa_s->last_con_fail_realm_len != realm_len ||
+	     os_memcmp(wpa_s->last_con_fail_realm, realm, realm_len) != 0)) {
 		algs = WPA_AUTH_ALG_FILS;
 		params->fils_erp_username = username;
 		params->fils_erp_username_len = username_len;
@@ -2690,11 +2703,14 @@
 #endif /* CONFIG_FST */
 
 #ifdef CONFIG_MBO
-	if (bss && wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
+	mbo_ie = bss ? wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE) : NULL;
+	if (mbo_ie) {
 		int len;
 
 		len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
-				  max_wpa_ie_len - wpa_ie_len);
+				  max_wpa_ie_len - wpa_ie_len,
+				  !!mbo_attr_from_mbo_ie(mbo_ie,
+							 OCE_ATTR_ID_CAPA_IND));
 		if (len >= 0)
 			wpa_ie_len += len;
 	}
@@ -6507,6 +6523,35 @@
 }
 
 
+#ifdef CONFIG_FILS
+void fils_connection_failure(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	const u8 *realm, *username, *rrk;
+	size_t realm_len, username_len, rrk_len;
+	u16 next_seq_num;
+
+	if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt) ||
+	    eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
+				  &username, &username_len,
+				  &realm, &realm_len, &next_seq_num,
+				  &rrk, &rrk_len) != 0 ||
+	    !realm)
+		return;
+
+	wpa_hexdump_ascii(MSG_DEBUG,
+			  "FILS: Store last connection failure realm",
+			  realm, realm_len);
+	os_free(wpa_s->last_con_fail_realm);
+	wpa_s->last_con_fail_realm = os_malloc(realm_len);
+	if (wpa_s->last_con_fail_realm) {
+		wpa_s->last_con_fail_realm_len = realm_len;
+		os_memcpy(wpa_s->last_con_fail_realm, realm, realm_len);
+	}
+}
+#endif /* CONFIG_FILS */
+
+
 int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
 {
 	return wpa_s->conf->ap_scan == 2 ||
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index f4cf91d..4f59160 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -865,6 +865,7 @@
 # proto: list of accepted protocols
 # WPA = WPA/IEEE 802.11i/D3.0
 # RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
+# Note that RSN is used also for WPA3.
 # If not set, this defaults to: WPA RSN
 #
 # key_mgmt: list of accepted authenticated key management protocols
@@ -883,7 +884,7 @@
 # WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms
 # SAE = Simultaneous authentication of equals; pre-shared key/password -based
 #	authentication with stronger security than WPA-PSK especially when using
-#	not that strong password
+#	not that strong password; a.k.a. WPA3-Personal
 # FT-SAE = SAE with FT
 # WPA-EAP-SUITE-B = Suite B 128-bit level
 # WPA-EAP-SUITE-B-192 = Suite B 192-bit level
@@ -892,6 +893,8 @@
 # FILS-SHA384 = Fast Initial Link Setup with SHA384
 # FT-FILS-SHA256 = FT and Fast Initial Link Setup with SHA256
 # FT-FILS-SHA384 = FT and Fast Initial Link Setup with SHA384
+# OWE = Opportunistic Wireless Encryption (a.k.a. Enhanced Open)
+# DPP = Device Provisioning Protocol
 # If not set, this defaults to: WPA-PSK WPA-EAP
 #
 # ieee80211w: whether management frame protection is enabled
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 45e3eb9..d367ba0 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -532,6 +532,8 @@
 	struct wpa_bss *current_bss;
 	int ap_ies_from_associnfo;
 	unsigned int assoc_freq;
+	u8 *last_con_fail_realm;
+	size_t last_con_fail_realm_len;
 
 	/* Selected configuration (based on Beacon/ProbeResp WPA IE) */
 	int pairwise_cipher;
@@ -1318,6 +1320,7 @@
 void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
 void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
+void fils_connection_failure(struct wpa_supplicant *wpa_s);
 int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
 int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
 void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);
@@ -1358,7 +1361,9 @@
 
 
 /* MBO functions */
-int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len);
+int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len,
+		int add_oce_capa);
+const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr);
 const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr);
 int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s,
 				  const char *non_pref_chan);