瀏覽代碼

qcacld-3.0: Support for PMKSA caching

Add support for PMK and PMKID cache based on either bssid or
ssid + cache identifier.

Change-Id: I23c50472e4c2032b953ccf264fc4cadb2ea573ca
CRs-Fixed: 2028113
Sridhar Selvaraj 7 年之前
父節點
當前提交
c3684c78f7

+ 0 - 36
core/hdd/src/wlan_hdd_assoc.c

@@ -5447,14 +5447,10 @@ static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
 				 uint16_t gen_ie_len, uint8_t *gen_ie)
 {
 	tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
-	QDF_STATUS result;
 	tDot11fIERSN dot11RSNIE;
 	tDot11fIEWPA dot11WPAIE;
-	uint32_t i;
 	uint8_t *pRsnIe;
 	uint16_t RSNIeLen;
-	tPmkidCacheInfo PMKIDCache[4];  /* Local transfer memory */
-	bool updatePMKCache = false;
 
 	/*
 	 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
@@ -5500,38 +5496,6 @@ static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
 		*pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
 		*pMfpCapable = csr_is_mfpc_capable(&dot11RSNIE);
 #endif
-		/* Set the PMKSA ID Cache for this interface */
-		for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
-			if (is_zero_ether_addr(bssid)) {
-				hdd_warn("MAC address is all zeroes");
-				break;
-			}
-			updatePMKCache = true;
-			/*
-			 * For right now, I assume setASSOCIATE() has passed
-			 * in the bssid.
-			 */
-			qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
-				     bssid, QDF_MAC_ADDR_SIZE);
-			qdf_mem_copy(PMKIDCache[i].PMKID,
-				     dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
-		}
-
-		if (updatePMKCache) {
-			/*
-			 * Calling csr_roam_set_pmkid_cache to configure the
-			 * PMKIDs into the cache.
-			 */
-			hdd_debug("Calling sme_roam_set_pmkid_cache with cache entry %d.",
-				 i);
-			/* Finally set the PMKSA ID Cache in CSR */
-			result =
-				sme_roam_set_pmkid_cache(halHandle,
-							 pAdapter->sessionId,
-							 PMKIDCache,
-							 dot11RSNIE.pmkid_count,
-							 false);
-		}
 	} else if (gen_ie[0] == DOT11F_EID_WPA) {
 		/* Validity checks */
 		if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||

+ 121 - 17
core/hdd/src/wlan_hdd_cfg80211.c

@@ -17253,6 +17253,102 @@ static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
 	return ret;
 }
 
+#ifdef CFG80211_FILS_SK_OFFLOAD_SUPPORT
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+	if (!pmksa->bssid) {
+		hdd_err("bssid (%p) is NULL",
+		       pmksa->bssid);
+	} else if (!pmksa->ssid || !pmksa->cache_id) {
+		hdd_err("either ssid (%p) or cache_id (%p) are NULL",
+		       pmksa->ssid, pmksa->cache_id);
+		return false;
+	}
+	return true;
+}
+
+/*
+ * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @pmk_cache: pmksa from supplicant
+ * @pmk_cache: pmk needs to be updated
+ *
+ * Return: None
+ */
+static void hdd_fill_pmksa_info(tPmkidCacheInfo *pmk_cache,
+				  struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+	if (pmksa->bssid) {
+		hdd_debug("%s PMKSA for " MAC_ADDRESS_STR,
+			is_delete ? "Delete" : "Set",
+			MAC_ADDR_ARRAY(pmksa->bssid));
+		qdf_mem_copy(pmk_cache->BSSID.bytes,
+				pmksa->bssid, QDF_MAC_ADDR_SIZE);
+	} else {
+		qdf_mem_copy(pmk_cache->ssid, pmksa->ssid,
+				SIR_MAC_MAX_SSID_LENGTH);
+		qdf_mem_copy(pmk_cache->cache_id,
+			pmksa->cache_id, CACHE_ID_LEN);
+		pmk_cache->ssid_len = pmksa->ssid_len;
+		hdd_debug("%s PMKSA for ssid %*.*s cache_id %x %x",
+			is_delete ? "Delete" : "Set",
+			pmk_cache->ssid_len, pmk_cache->ssid_len,
+			pmksa->ssid, pmksa->cache_id[0], pmksa->cache_id[1]);
+	}
+
+	if (is_delete)
+		return;
+
+	qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+	if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
+		qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
+		pmk_cache->pmk_len = pmksa->pmk_len;
+	} else
+		hdd_info("pmk len is %zu", pmksa->pmk_len);
+}
+#else
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+	if (!pmksa->bssid) {
+		hdd_err("both bssid is NULL %p", pmksa->bssid);
+		return false;
+	}
+	return true;
+}
+
+/*
+ * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @pmk_cache: pmksa from supplicant
+ * @pmk_cache: pmk needs to be updated
+ *
+ * Return: None
+ */
+static void hdd_fill_pmksa_info(tPmkidCacheInfo *pmk_cache,
+				  struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+	hdd_debug("%s PMKSA for " MAC_ADDRESS_STR, is_delete ? "Delete" : "Set",
+	MAC_ADDR_ARRAY(pmksa->bssid));
+	qdf_mem_copy(pmk_cache->BSSID.bytes,
+				pmksa->bssid, QDF_MAC_ADDR_SIZE);
+
+	if (is_delete)
+		return;
+
+	qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+}
+#endif
+
 /**
  * __wlan_hdd_cfg80211_set_pmksa() - set pmksa
  * @wiphy: Pointer to wiphy
@@ -17270,7 +17366,7 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
 	tHalHandle halHandle;
 	QDF_STATUS result = QDF_STATUS_SUCCESS;
 	int status;
-	tPmkidCacheInfo pmk_id;
+	tPmkidCacheInfo pmk_cache;
 
 	ENTER();
 
@@ -17289,14 +17385,14 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 
-	if (!pmksa->bssid || !pmksa->pmkid) {
-		hdd_err("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL",
-		       pmksa->bssid, pmksa->pmkid);
+	if (!pmksa->pmkid) {
+		hdd_err("pmksa->pmkid(%p) is NULL",
+		       pmksa->pmkid);
 		return -EINVAL;
 	}
 
-	hdd_debug("set PMKSA for " MAC_ADDRESS_STR,
-		MAC_ADDR_ARRAY(pmksa->bssid));
+	if (!wlan_hdd_is_pmksa_valid(pmksa))
+		return -EINVAL;
 
 	status = wlan_hdd_validate_context(pHddCtx);
 
@@ -17305,12 +17401,19 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
 
 	halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
 
-	qdf_mem_copy(pmk_id.BSSID.bytes, pmksa->bssid, QDF_MAC_ADDR_SIZE);
-	qdf_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+	qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
 
-	/* Add to the PMKSA ID Cache in CSR */
+	hdd_fill_pmksa_info(&pmk_cache, pmksa, false);
+
+	/*
+	 * Add to the PMKSA Cache in CSR
+	 * PMKSA cache will be having following
+	 * 1. pmkid id
+	 * 2. pmk
+	 * 3. bssid or cache identifier
+	 */
 	result = sme_roam_set_pmkid_cache(halHandle, pAdapter->sessionId,
-					  &pmk_id, 1, false);
+					  &pmk_cache, 1, false);
 
 	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
 			 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
@@ -17357,6 +17460,7 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
 	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 	tHalHandle halHandle;
 	int status = 0;
+	tPmkidCacheInfo pmk_cache;
 
 	ENTER();
 
@@ -17375,13 +17479,8 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 
-	if (!pmksa->bssid) {
-		hdd_err("pmksa->bssid is NULL");
+	if (!wlan_hdd_is_pmksa_valid(pmksa))
 		return -EINVAL;
-	}
-
-	hdd_debug("Deleting PMKSA for " MAC_ADDRESS_STR,
-	       MAC_ADDR_ARRAY(pmksa->bssid));
 
 	status = wlan_hdd_validate_context(pHddCtx);
 
@@ -17393,10 +17492,15 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
 	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
 			 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
 			 pAdapter->sessionId, 0));
+
+	qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
+	hdd_fill_pmksa_info(&pmk_cache, pmksa, true);
+
 	/* Delete the PMKID CSR cache */
 	if (QDF_STATUS_SUCCESS !=
 	    sme_roam_del_pmkid_from_cache(halHandle,
-					  pAdapter->sessionId, pmksa->bssid,
+					  pAdapter->sessionId, &pmk_cache,
 					  false)) {
 		hdd_err("Failed to delete PMKSA for " MAC_ADDRESS_STR,
 		       MAC_ADDR_ARRAY(pmksa->bssid));

+ 6 - 0
core/sme/inc/csr_api.h

@@ -219,6 +219,7 @@ typedef enum {
 } eIniChanBondState;
 
 #define CSR_RSN_PMKID_SIZE          16
+#define CSR_RSN_MAX_PMK_LEN         48
 #define CSR_MAX_PMKID_ALLOWED       32
 #define CSR_WEP40_KEY_LEN           5
 #define CSR_WEP104_KEY_LEN          13
@@ -868,6 +869,11 @@ typedef struct tagPmkidCandidateInfo {
 typedef struct tagPmkidCacheInfo {
 	struct qdf_mac_addr BSSID;
 	uint8_t PMKID[CSR_RSN_PMKID_SIZE];
+	uint8_t pmk[CSR_RSN_MAX_PMK_LEN];
+	uint8_t pmk_len;
+	uint8_t ssid_len;
+	uint8_t ssid[SIR_MAC_MAX_SSID_LENGTH];
+	uint8_t cache_id[CACHE_ID_LEN];
 } tPmkidCacheInfo;
 
 #ifdef FEATURE_WLAN_WAPI

+ 1 - 1
core/sme/inc/sme_api.h

@@ -715,7 +715,7 @@ QDF_STATUS sme_del_periodic_tx_ptrn(tHalHandle hHal, tSirDelPeriodicTxPtrn
 QDF_STATUS sme_send_rate_update_ind(tHalHandle hHal,
 		tSirRateUpdateInd *rateUpdateParams);
 QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
-		const uint8_t *pBSSId, bool flush_cache);
+		tPmkidCacheInfo *pmksa, bool flush_cache);
 void sme_get_command_q_status(tHalHandle hHal);
 
 QDF_STATUS sme_enable_rmc(tHalHandle hHal, uint32_t sessionId);

+ 3 - 2
core/sme/src/common/sme_api.c

@@ -4008,7 +4008,8 @@ QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
 }
 
 QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
-					 const uint8_t *pBSSId, bool flush_cache)
+					 tPmkidCacheInfo *pmksa,
+					 bool flush_cache)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
@@ -4020,7 +4021,7 @@ QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
 	if (QDF_IS_STATUS_SUCCESS(status)) {
 		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
 			status = csr_roam_del_pmkid_from_cache(pMac, sessionId,
-							       pBSSId, flush_cache);
+						       pmksa, flush_cache);
 		} else {
 			status = QDF_STATUS_E_INVAL;
 		}

+ 75 - 25
core/sme/src/csr/csr_api_roam.c

@@ -13667,6 +13667,59 @@ csr_roam_diag_set_pmkid(tCsrRoamSession *pSession)
 }
 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
 
+/**
+ * csr_update_pmk_cache - API to update PMK cache
+ * @pSession: pointer to session
+ * @pmksa: pointer to PMKSA struct
+ *
+ * Return : None
+ */
+static void csr_update_pmk_cache(tCsrRoamSession *session,
+			tPmkidCacheInfo *pmksa)
+{
+	uint16_t cache_idx = session->curr_cache_idx;
+
+	/* Add entry to the cache */
+	if (!pmksa->ssid_len) {
+		qdf_copy_macaddr(
+		    &session->PmkidCacheInfo[cache_idx].BSSID,
+		    &pmksa->BSSID);
+		session->PmkidCacheInfo[cache_idx].ssid_len = 0;
+	} else {
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].ssid,
+			pmksa->ssid, pmksa->ssid_len);
+		session->PmkidCacheInfo[cache_idx].ssid_len =
+			pmksa->ssid_len;
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].cache_id,
+			pmksa->cache_id, CACHE_ID_LEN);
+
+	}
+	qdf_mem_copy(
+	    session->PmkidCacheInfo[cache_idx].PMKID,
+	    pmksa->PMKID, CSR_RSN_PMKID_SIZE);
+
+	if (pmksa->pmk_len)
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].pmk,
+				pmksa->pmk, pmksa->pmk_len);
+
+	session->PmkidCacheInfo[cache_idx].pmk_len = pmksa->pmk_len;
+
+	/* Increment the CSR local cache index */
+	if (cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
+		session->curr_cache_idx++;
+	else {
+		sme_debug("max value reached, setting current index as 0");
+		session->curr_cache_idx = 0;
+	}
+
+	session->NumPmkidCache++;
+	if (session->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) {
+		sme_debug("setting num pmkid cache to %d",
+			CSR_MAX_PMKID_ALLOWED);
+		session->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+	}
+}
+
 QDF_STATUS
 csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
 			 tPmkidCacheInfo *pPMKIDCache, uint32_t numItems,
@@ -13705,38 +13758,24 @@ csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
 
 		/* Delete the entry if present */
 		csr_roam_del_pmkid_from_cache(pMac, sessionId,
-				pmksa->BSSID.bytes, false);
-
-		/* Add entry to the cache */
-		qdf_copy_macaddr(
-		    &pSession->PmkidCacheInfo[pSession->curr_cache_idx].BSSID,
-		    &pmksa->BSSID);
-		qdf_mem_copy(
-		    pSession->PmkidCacheInfo[pSession->curr_cache_idx].PMKID,
-		    pmksa->PMKID, CSR_RSN_PMKID_SIZE);
-
-		/* Increment the CSR local cache index */
-		if (pSession->curr_cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
-			pSession->curr_cache_idx++;
-		else
-			pSession->curr_cache_idx = 0;
+				pmksa, false);
+		/* Update new entry */
+		csr_update_pmk_cache(pSession, pmksa);
 
-		pSession->NumPmkidCache++;
-		if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED)
-			pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
 	}
 	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
 					 uint32_t sessionId,
-					 const uint8_t *pBSSId,
+					 tPmkidCacheInfo *pmksa,
 					 bool flush_cache)
 {
 	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
 	bool fMatchFound = false;
 	uint32_t Index;
 	uint32_t curr_idx;
+	tPmkidCacheInfo *cached_pmksa;
 	uint32_t i;
 
 	if (!pSession) {
@@ -13761,20 +13800,28 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
 
 	/* !flush_cache - so look up in the cache */
 	for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
-		if (!qdf_mem_cmp(pSession->PmkidCacheInfo[Index].BSSID.bytes,
-				    pBSSId, QDF_MAC_ADDR_SIZE)) {
+		cached_pmksa = &pSession->PmkidCacheInfo[Index];
+		if ((!cached_pmksa->ssid_len) &&
+			qdf_is_macaddr_equal(&cached_pmksa->BSSID,
+				&pmksa->BSSID))
 			fMatchFound = 1;
 
+		else if (cached_pmksa->ssid_len &&
+			(!qdf_mem_cmp(cached_pmksa->ssid,
+			pmksa->ssid, pmksa->ssid_len)) &&
+			(!qdf_mem_cmp(cached_pmksa->cache_id,
+				pmksa->cache_id, CACHE_ID_LEN)))
+			fMatchFound = 1;
+
+		if (fMatchFound)
 			/* Clear this - the matched entry */
-			qdf_mem_zero(&pSession->PmkidCacheInfo[Index],
+			qdf_mem_zero(cached_pmksa,
 				     sizeof(tPmkidCacheInfo));
 			break;
-		}
 	}
 
 	if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) {
-		sme_debug("No such PMKSA entry exists"
-			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pBSSId));
+		sme_debug("No such PMKSA entry exists");
 		return QDF_STATUS_SUCCESS;
 	}
 
@@ -13805,6 +13852,9 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
 
 	/* Decrement the count since an entry has been deleted */
 	pSession->NumPmkidCache--;
+	sme_debug("PMKID at index=%d deleted, current index=%d cache count=%d",
+		Index, pSession->curr_cache_idx, pSession->NumPmkidCache);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 1 - 1
core/sme/src/csr/csr_inside_api.h

@@ -1024,7 +1024,7 @@ QDF_STATUS csr_scan_create_entry_in_scan_cache(tpAniSirGlobal pMac,
 QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac);
 QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
 					 uint32_t sessionId,
-					 const uint8_t *pBSSId,
+					 tPmkidCacheInfo *pmksa,
 					 bool flush_cache);
 
 bool csr_elected_country_info(tpAniSirGlobal pMac);

+ 118 - 25
core/sme/src/csr/csr_util.c

@@ -3588,8 +3588,91 @@ static bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType,
 	return fRSNMatch;
 }
 
+/**
+ * csr_lookup_pmkid_using_ssid() - lookup pmkid using ssid and cache_id
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+static bool csr_lookup_pmkid_using_ssid(tpAniSirGlobal mac,
+					tCsrRoamSession *session,
+					tPmkidCacheInfo *pmk_cache,
+					uint32_t *index)
+{
+	uint32_t i;
+	tPmkidCacheInfo *session_pmk;
+
+	for (i = 0; i < session->NumPmkidCache; i++) {
+		session_pmk = &session->PmkidCacheInfo[i];
+		sme_debug("match PMKID ssid %*.*s cache id %x %x ssid_len %d to ssid %s cache_id %x %x",
+			pmk_cache->ssid_len, pmk_cache->ssid_len,
+			pmk_cache->ssid, pmk_cache->cache_id[0],
+			pmk_cache->cache_id[1], pmk_cache->ssid_len,
+			session_pmk->ssid,
+			session_pmk->cache_id[0], session_pmk->cache_id[1]);
+
+		if ((!qdf_mem_cmp(pmk_cache->ssid, session_pmk->ssid,
+				  pmk_cache->ssid_len)) &&
+		    (!qdf_mem_cmp(session_pmk->cache_id,
+				  pmk_cache->cache_id, CACHE_ID_LEN))) {
+			/* match found */
+			*index = i;
+			sme_debug("PMKID found at index %d", i);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+static bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+					tCsrRoamSession *session,
+					tPmkidCacheInfo *pmk_cache,
+					uint32_t *index)
+{
+	uint32_t i;
+	tPmkidCacheInfo *session_pmk;
+
+	for (i = 0; i < session->NumPmkidCache; i++) {
+		session_pmk = &session->PmkidCacheInfo[i];
+		sme_debug("Matching BSSID: " MAC_ADDRESS_STR " to cached BSSID:"
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pmk_cache->BSSID.bytes),
+			MAC_ADDR_ARRAY(session_pmk->BSSID.bytes));
+		if (qdf_is_macaddr_equal(&pmk_cache->BSSID,
+					 &session_pmk->BSSID)) {
+			/* match found */
+			*index = i;
+			sme_debug("PMKID found at index %d", i);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * csr_lookup_pmkid() - lookup pmkid using bssid or ssid + cache_id
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
 static bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId,
-			     uint8_t *pBSSId, uint8_t *pPMKId)
+				tPmkidCacheInfo *pmk_cache)
 {
 	bool fRC = false, fMatchFound = false;
 	uint32_t Index;
@@ -3600,29 +3683,34 @@ static bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId,
 		return false;
 	}
 
-	sme_debug("match PMKID " MAC_ADDRESS_STR " to ",
-		  MAC_ADDR_ARRAY(pBSSId));
-	do {
-		for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
-			if (!qdf_mem_cmp
-			   (pBSSId, pSession->PmkidCacheInfo[Index].BSSID.bytes,
-			    sizeof(struct qdf_mac_addr))) {
-				/* match found */
-				fMatchFound = true;
-				sme_debug("PMKID found");
-				break;
-			}
-		}
+	if (pmk_cache->ssid_len) {
+		/* Try to find based on cache_id and ssid first */
+		fMatchFound = csr_lookup_pmkid_using_ssid(pMac, pSession,
+							  pmk_cache, &Index);
+	}
 
-		if (!fMatchFound)
-			break;
+	/* If not able to find using cache id or ssid_len is not present */
+	if (!fMatchFound)
+		fMatchFound = csr_lookup_pmkid_using_bssid(pMac,
+						pSession, pmk_cache, &Index);
+
+	if (!fMatchFound) {
+		sme_debug("no pmkid match found NumPmkidCache = %d",
+			pSession->NumPmkidCache);
+		return false;
+	}
 
-		qdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID,
-			     CSR_RSN_PMKID_SIZE);
+	qdf_mem_copy(pmk_cache->PMKID,
+		     pSession->PmkidCacheInfo[Index].PMKID,
+		     CSR_RSN_PMKID_SIZE);
 
-		fRC = true;
-	} while (0);
-	sme_debug("match: %d pMac->roam.NumPmkidCache: %d",
+	qdf_mem_copy(pmk_cache->pmk,
+		     pSession->PmkidCacheInfo[Index].pmk,
+		     pSession->PmkidCacheInfo[Index].pmk_len);
+	pmk_cache->pmk_len = pSession->PmkidCacheInfo[Index].pmk_len;
+
+	fRC = true;
+	sme_debug("match = %d NumPmkidCache = %d",
 		fRC, pSession->NumPmkidCache);
 
 	return fRC;
@@ -3642,7 +3730,7 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
 	tCsrRSNAuthIe *pAuthSuite;
 	tCsrRSNCapabilities RSNCapabilities;
 	tCsrRSNPMKIe *pPMK;
-	uint8_t PMKId[CSR_RSN_PMKID_SIZE];
+	tPmkidCacheInfo pmkid_cache;
 #ifdef WLAN_FEATURE_11W
 	uint8_t *pGroupMgmtCipherSuite;
 #endif
@@ -3715,16 +3803,21 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
 		pPMK = (tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1]))
 				+ sizeof(uint16_t));
 
+		qdf_mem_copy(pmkid_cache.BSSID.bytes,
+				pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
 		/* Don't include the PMK SA IDs for CCKM associations. */
 		if (
 #ifdef FEATURE_WLAN_ESE
 			(eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
 #endif
-			csr_lookup_pmkid(pMac, sessionId, pSirBssDesc->bssId,
-					 &(PMKId[0]))) {
+			csr_lookup_pmkid(pMac, sessionId, &pmkid_cache)) {
 			pPMK->cPMKIDs = 1;
 
-			qdf_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId,
+			qdf_trace_hex_dump(QDF_MODULE_ID_PE,
+				   QDF_TRACE_LEVEL_INFO,
+				   pmkid_cache.pmk, pmkid_cache.pmk_len);
+			qdf_mem_copy(pPMK->PMKIDList[0].PMKID,
+				     pmkid_cache.PMKID,
 				     CSR_RSN_PMKID_SIZE);
 		} else
 			pPMK->cPMKIDs = 0;