From c3684c78f7fce374edc24ff8996c8838ca8fbf7d Mon Sep 17 00:00:00 2001 From: Sridhar Selvaraj Date: Mon, 21 Aug 2017 14:32:47 +0530 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_assoc.c | 36 -------- core/hdd/src/wlan_hdd_cfg80211.c | 138 ++++++++++++++++++++++++---- core/sme/inc/csr_api.h | 6 ++ core/sme/inc/sme_api.h | 2 +- core/sme/src/common/sme_api.c | 5 +- core/sme/src/csr/csr_api_roam.c | 100 +++++++++++++++------ core/sme/src/csr/csr_inside_api.h | 2 +- core/sme/src/csr/csr_util.c | 143 ++++++++++++++++++++++++------ 8 files changed, 325 insertions(+), 107 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index a3533b694223..26c85c833092 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/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) || diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 96a2891a2516..f63ab784eb3d 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/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)); diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 0ab9f41fd98d..3a9c577b9bbc 100644 --- a/core/sme/inc/csr_api.h +++ b/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 diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index df863820444e..e0e67f2f0dcb 100644 --- a/core/sme/inc/sme_api.h +++ b/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); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index ad7e4cdda23f..dc473c281ddc 100644 --- a/core/sme/src/common/sme_api.c +++ b/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; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 1e4472b1ea4a..fa0994052ad5 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/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); + pmksa, false); + /* Update new entry */ + csr_update_pmk_cache(pSession, pmksa); - /* 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; - - 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; } diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 8704003329c3..94ab1f52ae51 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/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); diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 0d7a0cf5fd8a..fefec6724a4e 100644 --- a/core/sme/src/csr/csr_util.c +++ b/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); - qdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID, - CSR_RSN_PMKID_SIZE); + if (!fMatchFound) { + sme_debug("no pmkid match found NumPmkidCache = %d", + pSession->NumPmkidCache); + return false; + } - fRC = true; - } while (0); - sme_debug("match: %d pMac->roam.NumPmkidCache: %d", + qdf_mem_copy(pmk_cache->PMKID, + pSession->PmkidCacheInfo[Index].PMKID, + CSR_RSN_PMKID_SIZE); + + 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;