Sfoglia il codice sorgente

qcacld-3.0: Avoid sending RSNXE to legacy APs

Userspace may send RSNXE also in connect request irrespective
of the connecting AP capabilities. This allows the driver to
choose best candidate based on score. But the chosen candidate
may not support the RSNXE features and may not advertise RSNXE
in beacon/probe response. Station is not supposed to include
the RSNX IE in assoc request in such cases as legacy APs
may misbehave due to the new IE. It's observed that few
legacy APs which don't support the RSNXE reject the
connection at EAPOL stage.
So, strip the IE when below conditions are met to avoid
sending the RSNXE to legacy APs,
1. If AP doesn't support/advertise the RSNXE
2. If the connection is legacy than WPA3 mode
3. If no other bits are set than SAE_H2E, SAE_PK, SECURE_LTF,
   SECURE_RTT, PROT_RANGE_NEGOTIOATION in RSNXE capabilities
   field.

This is a continuation to the partial
fix Ia7dee29792718a6514da44b13b36b46586ef25ab (which is reverted
as it's not a complete fix).

Change-Id: Ib857e9358a5414841002966ca14bdbb30d6587c6
CRs-Fixed: 3255353
Srinivas Dasari 2 anni fa
parent
commit
dfba36b6f6
1 ha cambiato i file con 113 aggiunte e 0 eliminazioni
  1. 113 0
      core/mac/src/pe/lim/lim_process_sme_req_messages.c

+ 113 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3661,6 +3661,117 @@ static inline void lim_update_pmksa_to_profile(struct wlan_objmgr_vdev *vdev,
 }
 #endif
 
+static inline bool
+lim_is_rsnxe_cap_set(struct mac_context *mac_ctx,
+		     struct cm_vdev_join_req *req)
+{
+	const uint8_t *rsnxe, *rsnxe_cap;
+	uint8_t cap_len, cap_index;
+	uint32_t cap_mask;
+
+	rsnxe = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSNXE,
+					 req->assoc_ie.ptr,
+					 req->assoc_ie.len);
+	if (!rsnxe)
+		return false;
+
+	rsnxe_cap = wlan_crypto_parse_rsnxe_ie(rsnxe, &cap_len);
+	if (!rsnxe_cap) {
+		mlme_debug("RSNXE caps not present");
+		return false;
+	}
+
+	/*
+	 * Below is the definition of RSNXE capabilities defined
+	 * in (IEEE Std 802.11-2020, 9.4.2.241, Table 9-780).
+	 * The Extended RSN Capabilities field, except its first 4 bits, is a
+	 * bit field indicating the extended RSN capabilities being advertised
+	 * by the STA transmitting the element. The length of the Extended
+	 * RSN Capabilities field is a variable n, in octets, as indicated by
+	 * the first 4 bits in the field.
+	 * Let's consider a uint32_t cap_mask which can accommodate 28(32-4)
+	 * bits to check if those bits are set or not. This is to keep it
+	 * simple as current supported bits are only 11.
+	 * TODO: If spec supports more than this range in future, this needs to
+	 * be an array to hold the complete bitmap/bitmask.
+	 */
+	cap_mask = ~(WLAN_CRYPTO_RSNX_CAP_SAE_H2E |
+		     WLAN_CRYPTO_RSNX_CAP_SAE_PK |
+		     WLAN_CRYPTO_RSNX_CAP_SECURE_LTF |
+		     WLAN_CRYPTO_RSNX_CAP_SECURE_RTT |
+		     WLAN_CRYPTO_RSNX_CAP_PROT_RANGE_NEG);
+
+	/* Check if any other bits are set than cap_mask */
+	for (cap_index = 0; cap_index <= cap_len; cap_index++) {
+		if (rsnxe_cap[cap_index] & (cap_mask & 0xFF))
+			return true;
+		cap_mask >>= 8;
+	}
+
+	return false;
+}
+
+/**
+ * lim_is_akm_wpa_wpa2() - Check if the AKM is legacy than wpa3
+ *
+ * @session: PE session
+ *
+ * This is to check if the AKM is older than WPA3. This helps to determine if
+ * RSNXE needs to be carried or not.
+ *
+ * return true - If AKM is WPA/WPA2 which means it's older than WPA3
+ *        false - If AKM is not older than WPA3
+ */
+static inline bool
+lim_is_akm_wpa_wpa2(struct pe_session *session)
+{
+	int32_t akm;
+
+	akm = wlan_crypto_get_param(session->vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
+	if (akm == -1)
+		return false;
+
+	if (WLAN_CRYPTO_IS_WPA_WPA2(akm))
+		return true;
+
+	return false;
+}
+
+static inline void
+lim_strip_rsnx_ie(struct mac_context *mac_ctx,
+		  struct pe_session *session,
+		  struct cm_vdev_join_req *req)
+{
+	/*
+	 * Userspace may send RSNXE also in connect request irrespective
+	 * of the connecting AP capabilities. This allows the driver to chose
+	 * best candidate based on score. But the chosen candidate may
+	 * not support the RSNXE feature and may not advertise RSNXE
+	 * in beacon/probe response. Station is not supposed to include
+	 * the RSNX IE in assoc request in such cases as legacy APs
+	 * may misbahave due to the new IE. It's observed that few
+	 * legacy APs which don't support the RSNXE reject the
+	 * connection at EAPOL stage.
+	 * So, strip the IE when below conditions are met to avoid
+	 * sending the RSNXE to legacy APs,
+	 * 1. If AP doesn't support/advertise the RSNXE
+	 * 2. If the connection is in a older mode than WPA3 i.e. WPA/WPA2 mode
+	 * 3. If no other bits are set than SAE_H2E, SAE_PK, SECURE_LTF,
+	 * SECURE_RTT, PROT_RANGE_NEGOTIOATION in RSNXE capabilities
+	 * field.
+
+	 */
+	if (!util_scan_entry_rsnxe(req->entry) &&
+	    lim_is_akm_wpa_wpa2(session) &&
+	    !lim_is_rsnxe_cap_set(mac_ctx, req)) {
+		mlme_debug("Strip RSNXE as it's not supported by AP");
+		lim_strip_ie(mac_ctx, req->assoc_ie.ptr,
+			     (uint16_t *)&req->assoc_ie.len,
+			     WLAN_ELEMID_RSNXE, ONE_BYTE,
+			     NULL, 0, NULL, WLAN_MAX_IE_LEN);
+	}
+}
+
 static QDF_STATUS
 lim_fill_rsn_ie(struct mac_context *mac_ctx, struct pe_session *session,
 		struct cm_vdev_join_req *req)
@@ -3742,6 +3853,8 @@ lim_fill_rsn_ie(struct mac_context *mac_ctx, struct pe_session *session,
 		lim_update_pmksa_to_profile(session->vdev, pmksa_peer);
 	}
 
+	lim_strip_rsnx_ie(mac_ctx, session, req);
+
 	return QDF_STATUS_SUCCESS;
 }