diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 21dd3a1aa6..0e9cad88ee 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2335,6 +2335,15 @@ wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, void wlan_mlme_get_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, struct wlan_mlme_sae_single_pmk *pmksa); +/** + * wlan_mlme_clear_sae_single_pmk_info - API to clear mlme_pmkid_info ap caps + * @vdev: vdev object + * @pmk : pmk info to clear + * + * Return : None + */ +void wlan_mlme_clear_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *pmk); #else static inline void wlan_mlme_set_sae_single_pmk_bss_cap(struct wlan_objmgr_psoc *psoc, @@ -2353,7 +2362,14 @@ wlan_mlme_get_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, struct wlan_mlme_sae_single_pmk *pmksa) { } + +static inline +void wlan_mlme_clear_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *pmk) +{ +} #endif + /** * mlme_get_roam_fail_reason_str() - Get fail string from enum * WMI_ROAM_FAIL_REASON_ID diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 1b6f6420b9..b6d55194ae 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -3666,6 +3666,37 @@ void wlan_mlme_get_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, qdf_mem_zero(pmksa->pmk_info.pmk, sizeof(*pmksa->pmk_info.pmk)); pmksa->pmk_info.pmk_len = 0; } + +void wlan_mlme_clear_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *pmk_recv) +{ + struct mlme_legacy_priv *mlme_priv; + struct wlan_mlme_sae_single_pmk sae_single_pmk; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return; + } + + sae_single_pmk = mlme_priv->mlme_roam.sae_single_pmk; + + if (!pmk_recv) { + /* Process flush pmk cmd */ + mlme_legacy_debug("Flush sae_single_pmk info"); + qdf_mem_zero(&sae_single_pmk.pmk_info, + sizeof(sae_single_pmk.pmk_info)); + } else if (pmk_recv->pmk_len != sae_single_pmk.pmk_info.pmk_len) { + mlme_legacy_debug("Invalid pmk len"); + return; + } else if (!qdf_mem_cmp(&sae_single_pmk.pmk_info.pmk, pmk_recv->pmk, + pmk_recv->pmk_len)) { + /* Process delete pmk cmd */ + mlme_legacy_debug("Clear sae_single_pmk info"); + qdf_mem_zero(&sae_single_pmk.pmk_info, + sizeof(sae_single_pmk.pmk_info)); + } +} #endif char *mlme_get_roam_fail_reason_str(uint32_t result) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 27a7273c03..7ef2b59617 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -21432,7 +21432,6 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - mac_handle_t mac_handle; QDF_STATUS result = QDF_STATUS_SUCCESS; int status; tPmkidCacheInfo *pmk_cache; @@ -21470,8 +21469,6 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, if (!pmk_cache) return -ENOMEM; - mac_handle = hdd_ctx->mac_handle; - hdd_fill_pmksa_info(adapter, pmk_cache, pmksa, false); /* @@ -21487,7 +21484,7 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, TRACE_CODE_HDD_CFG80211_SET_PMKSA, adapter->vdev_id, result); - sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, + sme_set_del_pmkid_cache(hdd_ctx->psoc, adapter->vdev_id, pmk_cache, true); qdf_mem_zero(pmk_cache, sizeof(pmk_cache)); @@ -21538,7 +21535,6 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - mac_handle_t mac_handle; int status = 0; tPmkidCacheInfo *pmk_cache; @@ -21569,14 +21565,16 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, if (!pmk_cache) return -ENOMEM; - mac_handle = hdd_ctx->mac_handle; - qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_DEL_PMKSA, adapter->vdev_id, 0); hdd_fill_pmksa_info(adapter, pmk_cache, pmksa, true); + /* clear single_pmk_info information */ + sme_clear_sae_single_pmk_info(hdd_ctx->psoc,adapter->vdev_id, + pmk_cache); + /* Delete the PMKID CSR cache */ if (QDF_STATUS_SUCCESS != wlan_hdd_del_pmksa_cache(adapter, pmk_cache)) { @@ -21588,8 +21586,9 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, status = -EINVAL; } - sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, pmk_cache, + sme_set_del_pmkid_cache(hdd_ctx->psoc, adapter->vdev_id, pmk_cache, false); + qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); qdf_mem_free(pmk_cache); @@ -21637,7 +21636,6 @@ static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - mac_handle_t mac_handle; int errno; QDF_STATUS status; @@ -21658,15 +21656,13 @@ static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, if (errno) return errno; - mac_handle = hdd_ctx->mac_handle; - status = wlan_hdd_flush_pmksa_cache(adapter); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Cannot flush PMKIDCache"); errno = -EINVAL; } - sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, NULL, false); + sme_set_del_pmkid_cache(hdd_ctx->psoc, adapter->vdev_id, NULL, false); hdd_exit(); return errno; } diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index be2e273897..627265d3cf 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2756,17 +2756,33 @@ QDF_STATUS sme_set_vc_mode_config(uint32_t vc_bitmap); /** * sme_set_del_pmkid_cache() - API to update PMKID cache - * @mac_handle: Opaque handle to the global MAC context + * @psoc: psoc common object * @session_id: Session id * @pmk_cache_info: Pointer to PMK cache info * @is_add: boolean that implies whether to add or delete PMKID entry * * Return: QDF_STATUS */ -QDF_STATUS sme_set_del_pmkid_cache(mac_handle_t mac_handle, uint8_t session_id, +QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, tPmkidCacheInfo *pmk_cache_info, bool is_add); +/** + * sme_clear_sae_single_pmk_info() - Clear sae_single_pmk onfo + * @psoc: Psoc object + * @session_id: session id + * @pmk_cache_info: pmk cache info + * + * This function will clear sae_single_pmk info while processing delete pmk + * command from userspace. + * + * Return: None + */ +void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + tPmkidCacheInfo *pmk_cache_info); + /** * sme_send_hlp_ie_info() - API to send HLP IE info to fw * @mac_handle: Opaque handle to the global MAC context diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 9815d10622..cd12dfe60e 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -60,6 +60,7 @@ #include "cfg_ucfg_api.h" #include "wlan_fwol_ucfg_api.h" #include +#include "wlan_crypto_global_api.h" static QDF_STATUS init_sme_cmd_list(struct mac_context *mac); @@ -14166,7 +14167,33 @@ QDF_STATUS sme_fast_reassoc(mac_handle_t mac_handle, #endif -QDF_STATUS sme_set_del_pmkid_cache(mac_handle_t mac_handle, uint8_t session_id, +void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + tPmkidCacheInfo *pmk_cache_info) +{ + struct wlan_crypto_pmksa *pmksa; + struct wlan_objmgr_vdev *vdev; + tPmkidCacheInfo pmk_to_del; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return; + } + pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache_info->BSSID); + if (!pmksa) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return; + } + qdf_mem_copy(&pmk_to_del.pmk, pmksa->pmk, pmksa->pmk_len); + pmk_to_del.pmk_len = pmksa->pmk_len; + csr_clear_sae_single_pmk(psoc, session_id, &pmk_to_del); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); +} + +QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, tPmkidCacheInfo *pmk_cache_info, bool is_add) { @@ -14183,6 +14210,7 @@ QDF_STATUS sme_set_del_pmkid_cache(mac_handle_t mac_handle, uint8_t session_id, if (!pmk_cache_info) { pmk_cache->is_flush_all = true; + csr_clear_sae_single_pmk(psoc, session_id, NULL); goto send_flush_cmd; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 6be0390b9f..1a2641b314 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -14582,7 +14582,7 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId, pSession->pmk_len = pmk_len; if (csr_is_auth_type_ese(mac->roam.roamSession[sessionId]. - connectedProfile.AuthType)) { + connectedProfile.AuthType)) { sme_debug("PMK update is not required for ESE"); return QDF_STATUS_SUCCESS; } @@ -14605,6 +14605,37 @@ static void csr_mem_zero_psk_pmk(struct csr_roam_session *session) } #endif +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, tPmkidCacheInfo *pmk_cache) +{ + struct wlan_objmgr_vdev *vdev; + uint32_t keymgmt; + struct mlme_pmk_info pmk_info; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("vdev is NULL"); + return; + } + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + if (!(keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE))) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return; + } + if (pmk_cache) { + qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len); + pmk_info.pmk_len = pmk_cache->pmk_len; + wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info); + } else { + wlan_mlme_clear_sae_single_pmk_info(vdev, NULL); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); +} +#endif + QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, uint32_t sessionId, tPmkidCacheInfo *pmksa, @@ -14632,12 +14663,17 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, /* Flush the entire cache */ qdf_mem_zero(pSession->PmkidCacheInfo, sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED); + /* flush single_pmk_info information */ + csr_clear_sae_single_pmk(mac->psoc, pSession->vdev_id, NULL); pSession->NumPmkidCache = 0; pSession->curr_cache_idx = 0; csr_mem_zero_psk_pmk(pSession); return QDF_STATUS_SUCCESS; } + /* clear single_pmk_info information */ + csr_clear_sae_single_pmk(mac->psoc, pSession->vdev_id, pmksa); + /* !flush_cache - so look up in the cache */ for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) { cached_pmksa = &pSession->PmkidCacheInfo[Index]; diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 7be00e80c2..00cf03f0ad 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -919,6 +919,26 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, tPmkidCacheInfo *pmksa, bool flush_cache); +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * csr_clear_sae_single_pmk - API to clear single_pmk_info cache + * @psoc: psoc common object + * @vdev_id: session id + * @pmksa: pmk info + * + * Return : None + */ +void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, tPmkidCacheInfo *pmksa); + +#else +static inline void +csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + tPmkidCacheInfo *pmksa) +{ +} +#endif + QDF_STATUS csr_send_ext_change_channel(struct mac_context *mac_ctx, uint32_t channel, uint8_t session_id);