diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index 98b04b2ee8e0..f21d686d2e7c 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -342,6 +342,10 @@ int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer, } qdf_export_symbol(wlan_crypto_get_peer_param); +static +QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, + struct wlan_crypto_pmksa *pmksa); + static QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params, struct wlan_crypto_pmksa *pmksa) @@ -349,6 +353,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params, uint8_t i, first_available_slot = 0; bool slot_found = false; + /* Delete the old entry and then Add new entry */ + wlan_crypto_del_pmksa(crypto_params, pmksa); + /* find the empty slot or slot with same bssid */ for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { if (!crypto_params->pmksa[i]) { @@ -360,10 +367,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params, } if (qdf_is_macaddr_equal(&pmksa->bssid, &crypto_params->pmksa[i]->bssid)) { - /* free the current pmksa and use this slot */ - qdf_mem_zero(crypto_params->pmksa[i], - sizeof(struct wlan_crypto_pmksa)); - qdf_mem_free(crypto_params->pmksa[i]); + /* current pmksa is already freed in del_pmksa, + * so just use this slot + */ crypto_params->pmksa[i] = pmksa; return QDF_STATUS_SUCCESS; } else if (pmksa->ssid_len && @@ -373,10 +379,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params, !qdf_mem_cmp(pmksa->cache_id, crypto_params->pmksa[i]->cache_id, WLAN_CACHE_ID_LEN)){ - /* free the current pmksa and use this slot */ - qdf_mem_zero(crypto_params->pmksa[i], - sizeof(struct wlan_crypto_pmksa)); - qdf_mem_free(crypto_params->pmksa[i]); + /* current pmksa is already freed in del_pmksa, + * so just use this slot + */ crypto_params->pmksa[i] = pmksa; return QDF_STATUS_SUCCESS; } @@ -396,6 +401,8 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, struct wlan_crypto_pmksa *pmksa) { uint8_t i; + bool match_found = false; + u8 del_pmk[MAX_PMK_LEN] = {0}; /* find slot with same bssid */ for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { @@ -403,11 +410,7 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, continue; if (qdf_is_macaddr_equal(&pmksa->bssid, &crypto_params->pmksa[i]->bssid)) { - qdf_mem_zero(crypto_params->pmksa[i], - sizeof(struct wlan_crypto_pmksa)); - qdf_mem_free(crypto_params->pmksa[i]); - crypto_params->pmksa[i] = NULL; - return QDF_STATUS_SUCCESS; + match_found = true; } else if (pmksa->ssid_len && !qdf_mem_cmp(pmksa->ssid, crypto_params->pmksa[i]->ssid, @@ -415,14 +418,33 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, !qdf_mem_cmp(pmksa->cache_id, crypto_params->pmksa[i]->cache_id, WLAN_CACHE_ID_LEN)){ - qdf_mem_zero(crypto_params->pmksa[i], - sizeof(struct wlan_crypto_pmksa)); - qdf_mem_free(crypto_params->pmksa[i]); - crypto_params->pmksa[i] = NULL; + match_found = true; + } + + if (match_found) { + qdf_mem_copy(del_pmk, crypto_params->pmksa[i]->pmk, + crypto_params->pmksa[i]->pmk_len); + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + if (crypto_params->pmksa[i]->pmk_len && + (!qdf_mem_cmp(crypto_params->pmksa[i]->pmk, + del_pmk, + crypto_params->pmksa[i]->pmk_len))) { + qdf_mem_zero(crypto_params->pmksa[i], + sizeof( + struct wlan_crypto_pmksa)); + qdf_mem_free(crypto_params->pmksa[i]); + crypto_params->pmksa[i] = NULL; + } + } return QDF_STATUS_SUCCESS; } } + if (i == WLAN_CRYPTO_MAX_PMKID && !match_found) + crypto_debug("No such pmksa entry exists"); + return QDF_STATUS_SUCCESS; }