diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 276ad2a6064b..2d0bc1d8df5a 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -22247,10 +22247,12 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, qdf_mem_free(pmksa); } - if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len) + if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len) { sme_roam_set_psk_pmk(mac_handle, adapter->vdev_id, pmk_cache->pmk, pmk_cache->pmk_len, false); + sme_set_pmk_cache_ft(mac_handle, adapter->vdev_id, pmk_cache); + } hdd_objmgr_put_vdev(vdev); return result; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 2ed97dd66622..1c1e5a32fdd8 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -634,6 +634,18 @@ void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id, QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId, uint8_t *psk_pmk, size_t pmk_len, bool update_to_fw); + +/** + * sme_set_pmk_cache_ft() - a wrapper function to request CSR to save MDID + * This is a synchronous call. + * @mac_handle: Global structure + * @session_id: SME session id + * @pmk_cache: pointer to pmk cache structure tPmkidCacheInfo + * + * Return: QDF_STATUS -status whether MDID is set or not + */ +QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id, + tPmkidCacheInfo *pmk_cache); #else static inline void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id, @@ -661,6 +673,13 @@ QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId, { return QDF_STATUS_SUCCESS; } + +static inline +QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id, + tPmkidCacheInfo *pmk_cache) +{ + return QDF_STATUS_SUCCESS; +} #endif /** diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index e2c5d189e38a..12ff17071f20 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -3904,6 +3904,20 @@ QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId, } return status; } + +QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id, + tPmkidCacheInfo *pmk_cache) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + status = csr_set_pmk_cache_ft(mac, session_id, pmk_cache); + sme_release_global_lock(&mac->sme); + } + return status; +} #endif QDF_STATUS sme_roam_get_wpa_rsn_req_ie(mac_handle_t mac_handle, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index b89fedb141f5..92b277719816 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -7061,8 +7061,8 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, session->connectedProfile.mdid.mdie_present; if (akm_type == eCSR_AUTH_TYPE_FT_SAE && mdie_present) { sme_debug("Update the MDID in PMK cache for FT-SAE case"); - csr_update_pmk_cache_ft(mac_ctx, - session_id, session); + csr_update_pmk_cache_ft(mac_ctx, session_id, + NULL, NULL); } len = join_rsp->assocReqLength + @@ -13867,7 +13867,6 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId, bool update_to_fw) { struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - enum csr_akm_type akm_type; if (!pSession) { sme_err("session %d not found", sessionId); @@ -13882,22 +13881,53 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId, return QDF_STATUS_SUCCESS; } - akm_type = pSession->connectedProfile.AuthType; - if ((akm_type == eCSR_AUTH_TYPE_FT_RSN || - akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA256 || - akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA384 || - akm_type == eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384) && - pSession->connectedProfile.mdid.mdie_present) { - sme_debug("Auth type: %d update the MDID in cache", akm_type); - csr_update_pmk_cache_ft(mac, sessionId, pSession); - } - if (update_to_fw) csr_roam_update_cfg(mac, sessionId, REASON_ROAM_PSK_PMK_CHANGED); return QDF_STATUS_SUCCESS; } + +QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint32_t session_id, + tPmkidCacheInfo *pmk_cache) +{ + struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id); + enum csr_akm_type akm_type; + + if (!CSR_IS_SESSION_VALID(mac, session_id)) { + sme_err("session %d not found", session_id); + return QDF_STATUS_E_INVAL; + } + + akm_type = session->connectedProfile.AuthType; + if ((akm_type == eCSR_AUTH_TYPE_FT_RSN || + akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA256 || + akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA384 || + akm_type == eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384) && + session->connectedProfile.mdid.mdie_present) { + sme_debug("Auth type: %d update the MDID in cache", akm_type); + csr_update_pmk_cache_ft(mac, session_id, pmk_cache, NULL); + } else { + tCsrScanResultInfo *scan_res; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + scan_res = qdf_mem_malloc(sizeof(tCsrScanResultInfo)); + if (!scan_res) + return QDF_STATUS_E_NOMEM; + + status = csr_scan_get_result_for_bssid(mac, &pmk_cache->BSSID, + scan_res); + if (QDF_IS_STATUS_SUCCESS(status) && + scan_res->BssDescriptor.mdiePresent) { + sme_debug("Update MDID in cache from scan_res"); + csr_update_pmk_cache_ft(mac, session_id, + pmk_cache, scan_res); + } + qdf_mem_free(scan_res); + scan_res = NULL; + } + return QDF_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD @@ -14015,12 +14045,14 @@ csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac, #endif void csr_update_pmk_cache_ft(struct mac_context *mac, uint32_t vdev_id, - struct csr_roam_session *session) + tPmkidCacheInfo *pmk_cache, + tCsrScanResultInfo *scan_res) { QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_vdev *vdev; struct wlan_crypto_pmksa pmksa; enum QDF_OPMODE vdev_mode; + struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); if (!session) { sme_err("session not found"); @@ -14043,23 +14075,19 @@ void csr_update_pmk_cache_ft(struct mac_context *mac, uint32_t vdev_id, } /* - * In FT connection fetch the MDID from Session and send it to crypto - * so that it will update the crypto PMKSA table with the MDID for the - * matching BSSID or SSID PMKSA entry. And delete the old/stale PMK - * cache entries for the same mobility domain as of the newly added - * entry to avoid multiple PMK cache entries for the same MDID. + * In FT connection fetch the MDID from Session or scan result whichever + * is available and send it to crypto so that it will update the crypto + * PMKSA table with the MDID for the matching BSSID or SSID PMKSA entry. + * And delete the old/stale PMK cache entries for the same mobility + * domain as of the newly added entry to avoid multiple PMK cache + * entries for the same MDID. */ - qdf_copy_macaddr(&pmksa.bssid, &session->connectedProfile.bssid); - sme_debug("copied the BSSID from session to PMKSA"); - if (session->connectedProfile.SSID.length) { - qdf_mem_copy(&pmksa.ssid, &session->connectedProfile.SSID.ssId, - session->connectedProfile.SSID.length); - qdf_mem_copy( - &pmksa.cache_id, - &session->pConnectBssDesc->fils_info_element.cache_id, - CACHE_ID_LEN); - pmksa.ssid_len = session->connectedProfile.SSID.length; - sme_debug("copied the SSID from session to PMKSA"); + if (pmk_cache && pmk_cache->ssid_len) { + pmksa.ssid_len = pmk_cache->ssid_len; + qdf_mem_copy(&pmksa.ssid, &pmk_cache->ssid, pmksa.ssid_len); + qdf_mem_copy(&pmksa.cache_id, + &pmk_cache->cache_id, CACHE_ID_LEN); + sme_debug("copied the SSID from pmk_cache to PMKSA"); } if (session->connectedProfile.mdid.mdie_present) { @@ -14067,6 +14095,19 @@ void csr_update_pmk_cache_ft(struct mac_context *mac, uint32_t vdev_id, pmksa.mdid.mobility_domain = session->connectedProfile.mdid.mobility_domain; sme_debug("copied the MDID from session to PMKSA"); + qdf_copy_macaddr(&pmksa.bssid, + &session->connectedProfile.bssid); + + status = wlan_crypto_update_pmk_cache_ft(vdev, &pmksa); + if (status == QDF_STATUS_SUCCESS) + sme_debug("Updated the crypto cache table"); + } else if (scan_res && scan_res->BssDescriptor.mdiePresent) { + pmksa.mdid.mdie_present = 1; + pmksa.mdid.mobility_domain = + (scan_res->BssDescriptor.mdie[0] | + (scan_res->BssDescriptor.mdie[1] << 8)); + sme_debug("copied the MDID from scan_res to PMKSA"); + qdf_copy_macaddr(&pmksa.bssid, &pmk_cache->BSSID); status = wlan_crypto_update_pmk_cache_ft(vdev, &pmksa); if (status == QDF_STATUS_SUCCESS) diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 7a88dea6390b..4afb98021c8f 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -729,6 +729,18 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId, uint8_t *psk_pmk, size_t pmk_len, bool update_to_fw); +/** + * csr_set_pmk_cache_ft() - store MDID in PMK cache + * + * @mac - pointer to global structure for MAC + * @session_id - Sme session id + * @pmk_cache: pointer to a structure of PMK + * + * Return QDF_STATUS - usually it succeed unless session_id is not found + */ +QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint32_t session_id, + tPmkidCacheInfo *pmk_cache); + QDF_STATUS csr_roam_set_key_mgmt_offload(struct mac_context *mac_ctx, uint32_t session_id, struct pmkid_mode_bits *pmkid_modes); @@ -880,13 +892,16 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, /** * csr_update_pmk_cache_ft - API to update MDID in PMKSA cache entry - * @session_id: session ID - * @session: sme session pointer + * @mac: Pointer to global structure for MAC + * @vdev_id: session ID + * @pmk_cache: pointer to pmk cache + * @scan_res: pointer to tCsrScanResultInfo * * Return: None */ -void csr_update_pmk_cache_ft(struct mac_context *mac, uint32_t session_id, - struct csr_roam_session *session); +void csr_update_pmk_cache_ft(struct mac_context *mac, uint32_t vdev_id, + tPmkidCacheInfo *pmk_cache, + tCsrScanResultInfo *scan_res); #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) /**