qcacld-3.0: Validate FILS ERP key lengths in connect request

If ERP key lengths are greater than maximum valid lengths,
currently the connect request is allowed to go through.
Allow fils connection to go through only if erp keys are
not sent in connect. If erp information is present, validate
the rrk, realm, username length.

Add changes to lookup pmkid based on bssid also in addition to
the existing logic to lookup based on fils cache_id and ssid.

Change-Id: Iebde1f382b7db13553b848a459cb4a783744c2a6
CRs-Fixed: 2732050
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index b0b9366..00c15fe 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -18599,23 +18599,21 @@
 		  req->fils_erp_next_seq_num, req->auth_type,
 		  req->fils_erp_username_len, req->fils_erp_rrk_len,
 		  req->fils_erp_realm_len);
-	if (req->fils_erp_rrk_len || req->fils_erp_realm_len ||
-	    req->fils_erp_username_len ||
-	    req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH ||
+
+	if (req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH ||
 	    req->fils_erp_realm_len > FILS_MAX_REALM_LEN ||
 	    req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) {
 		hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu",
 			req->fils_erp_username_len, req->fils_erp_rrk_len,
 			req->fils_erp_realm_len);
-		return true;
+		return false;
 	}
 
 	if (!req->fils_erp_rrk || !req->fils_erp_realm ||
-	    !req->fils_erp_username) {
-		hdd_err("buffer incorrect, user=%pK rrk=%pK realm=%pK",
+	    !req->fils_erp_username)
+		hdd_err("ERP info is NULL, user=%pK rrk=%pK realm=%pK",
 			req->fils_erp_username, req->fils_erp_rrk,
 			req->fils_erp_realm);
-	}
 
 	return true;
 }
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 8b1c0d8..4374430 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -15447,6 +15447,7 @@
 				  uint8_t vdev_id)
 {
 	uint8_t cache_id[CACHE_ID_LEN] = {0};
+	struct qdf_mac_addr bssid;
 
 	if (!profile->fils_con_info)
 		return QDF_STATUS_SUCCESS;
@@ -15465,12 +15466,16 @@
 			  cache_id[0], cache_id[1]);
 	}
 
+	qdf_mem_copy(bssid.bytes,
+		     csr_join_req->bssDescription.bssId,
+		     QDF_MAC_ADDR_SIZE);
+
 	if ((!profile->fils_con_info->r_rk_length ||
 	     !profile->fils_con_info->key_nai_length) &&
 	    !bss_desc->fils_info_element.is_cache_id_present &&
 	    !csr_lookup_fils_pmkid(mac, vdev_id, cache_id,
 				   csr_join_req->ssId.ssId,
-				   csr_join_req->ssId.length))
+				   csr_join_req->ssId.length, &bssid))
 		return QDF_STATUS_E_FAILURE;
 
 	qdf_mem_copy(&csr_join_req->fils_con_info,
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
index 9be4546..070e489 100644
--- a/core/sme/src/csr/csr_inside_api.h
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -1083,12 +1083,13 @@
  * @cache_id:  FILS cache id
  * @ssid:      SSID pointer
  * @ssid_len:  SSID length
+ * @bssid:     Pointer to the BSSID to lookup
  *
  * Return: True if lookup is successful
  */
 bool csr_lookup_fils_pmkid(struct mac_context *mac, uint8_t vdev_id,
 			   uint8_t *cache_id, uint8_t *ssid,
-			   uint8_t ssid_len);
+			   uint8_t ssid_len, struct qdf_mac_addr *bssid);
 /**
  * csr_is_pmkid_found_for_peer() - check if pmkid sent by peer is present
 				   in PMK cache. Used in SAP mode.
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
index 90dc384..f41e05a 100644
--- a/core/sme/src/csr/csr_util.c
+++ b/core/sme/src/csr/csr_util.c
@@ -2747,9 +2747,10 @@
 
 bool csr_lookup_fils_pmkid(struct mac_context *mac,
 			   uint8_t vdev_id, uint8_t *cache_id,
-			   uint8_t *ssid, uint8_t ssid_len)
+			   uint8_t *ssid, uint8_t ssid_len,
+			   struct qdf_mac_addr *bssid)
 {
-	struct wlan_crypto_pmksa *pmksa;
+	struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa;
 	struct wlan_objmgr_vdev *vdev;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
@@ -2759,8 +2760,10 @@
 		return false;
 	}
 
-	pmksa = wlan_crypto_get_fils_pmksa(vdev, cache_id, ssid, ssid_len);
-	if (!pmksa) {
+	bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, bssid);
+	fils_ssid_pmksa =
+		wlan_crypto_get_fils_pmksa(vdev, cache_id, ssid, ssid_len);
+	if (!fils_ssid_pmksa && !bssid_lookup_pmksa) {
 		sme_err("FILS_PMKSA: Lookup failed");
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
 		return false;