From a44d55b68a8e05a9eb37889a3efc29f71d19529b Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 20 Mar 2019 03:22:08 -0400 Subject: [PATCH] qcacld-3.0: Use converged pmkid cache When WLAN_CONV_CRYPTO_IE_SUPPORT enabled, pmkid should be saved to crypto component by crypto API. Otherwsie RSN ie construction will have no pmkid info to add to rsn ie buf. Change-Id: I8643aca794dcb42323d3d051e7a15a0597167ed6 CRs-Fixed: 2402775 --- core/cds/inc/cds_config.h | 1 - core/hdd/src/wlan_hdd_cfg80211.c | 107 ++++++++++++++++++++++++++++--- core/hdd/src/wlan_hdd_cfg80211.h | 9 +++ core/hdd/src/wlan_hdd_hostapd.c | 4 +- core/hdd/src/wlan_hdd_main.c | 4 +- core/sme/src/csr/csr_api_roam.c | 7 +- core/sme/src/csr/csr_util.c | 34 +++++++++- 7 files changed, 144 insertions(+), 22 deletions(-) diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h index 3d875fa0040b..0294e20cb8f9 100644 --- a/core/cds/inc/cds_config.h +++ b/core/cds/inc/cds_config.h @@ -104,7 +104,6 @@ struct cds_config_info { }; #ifdef WLAN_FEATURE_FILS_SK -#define MAX_PMK_LEN 48 #define FILS_MAX_KEYNAME_NAI_LENGTH 253 #define FILS_MAX_REALM_LEN 255 #define FILS_MAX_RRK_LENGTH 64 diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 471658b6d69e..9bd843f38bf2 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -19787,6 +19787,99 @@ static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, return errno; } +#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT +static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, + tPmkidCacheInfo *pmk_cache) +{ + QDF_STATUS result; + struct wlan_crypto_pmksa *pmksa; + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_FAILURE; + + pmksa = qdf_mem_malloc(sizeof(*pmksa)); + if (!pmksa) { + hdd_objmgr_put_vdev(vdev); + return QDF_STATUS_E_NOMEM; + } + qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID); + qdf_mem_copy(pmksa->pmkid, pmk_cache->PMKID, PMKID_LEN); + qdf_mem_copy(pmksa->pmk, pmk_cache->pmk, pmk_cache->pmk_len); + pmksa->pmk_len = pmk_cache->pmk_len; + + result = wlan_crypto_set_del_pmksa(vdev, pmksa, true); + if (result != QDF_STATUS_SUCCESS) { + qdf_mem_zero(pmksa, sizeof(*pmksa)); + qdf_mem_free(pmksa); + } + hdd_objmgr_put_vdev(vdev); + + return result; +} + +static QDF_STATUS wlan_hdd_del_pmksa_cache(struct hdd_adapter *adapter, + tPmkidCacheInfo *pmk_cache) +{ + QDF_STATUS result; + struct wlan_crypto_pmksa pmksa; + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_FAILURE; + + qdf_copy_macaddr(&pmksa.bssid, &pmk_cache->BSSID); + result = wlan_crypto_set_del_pmksa(adapter->vdev, &pmksa, false); + hdd_objmgr_put_vdev(vdev); + + return result; +} + +QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter) +{ + QDF_STATUS result; + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_FAILURE; + + result = wlan_crypto_set_del_pmksa(adapter->vdev, NULL, false); + hdd_objmgr_put_vdev(vdev); + + return result; +} +#else +static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, + tPmkidCacheInfo *pmk_cache) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + return sme_roam_set_pmkid_cache( + hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache, 1, false); +} + +static QDF_STATUS wlan_hdd_del_pmksa_cache(struct hdd_adapter *adapter, + tPmkidCacheInfo *pmk_cache) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + return sme_roam_del_pmkid_from_cache( + hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache, + false); +} + +QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + return sme_roam_del_pmkid_from_cache( + hdd_ctx->mac_handle, adapter->vdev_id, NULL, true); +} +#endif + #if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) /* @@ -19954,8 +20047,7 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, * 2. pmk * 3. bssid or cache identifier */ - result = sme_roam_set_pmkid_cache(mac_handle, adapter->vdev_id, - &pmk_cache, 1, false); + result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache); qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_PMKSA, @@ -20049,9 +20141,7 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, /* Delete the PMKID CSR cache */ if (QDF_STATUS_SUCCESS != - sme_roam_del_pmkid_from_cache(mac_handle, - adapter->vdev_id, &pmk_cache, - false)) { + wlan_hdd_del_pmksa_cache(adapter, &pmk_cache)) { hdd_err("Failed to delete PMKSA for " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pmksa->bssid)); status = -EINVAL; @@ -20127,9 +20217,7 @@ static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, mac_handle = hdd_ctx->mac_handle; - status = sme_roam_del_pmkid_from_cache(mac_handle, - adapter->vdev_id, - NULL, true); + status = wlan_hdd_flush_pmksa_cache(adapter); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Cannot flush PMKIDCache"); errno = -EINVAL; @@ -21402,8 +21490,7 @@ wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter, QDF_MAC_ADDR_SIZE); qdf_mem_copy(pmk_cache.PMKID, params->pmkid, PMKID_LEN); - result = sme_roam_set_pmkid_cache(mac_handle, adapter->vdev_id, - &pmk_cache, 1, false); + result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache); if (!QDF_IS_STATUS_SUCCESS(result)) hdd_debug("external_auth: Failed to cache PMKID"); } diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index a9e2c6f1ebd9..54e6551aba49 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -597,6 +597,15 @@ void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter, uint32_t kek_len, uint8_t *replay_ctr, bool big_endian); + +/** + * wlan_hdd_flush_pmksa_cache() - flush pmksa cache for adapter + * @adapter: Adapter context + * + * Return: qdf status + */ +QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter); + /* * wlan_hdd_send_mode_change_event() - API to send hw mode change event to * userspace diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index e6ddf263d980..2d04268ff5dc 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5706,9 +5706,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, if (adapter->device_mode == QDF_SAP_MODE) { wlan_hdd_del_station(adapter); mac_handle = hdd_ctx->mac_handle; - status = sme_roam_del_pmkid_from_cache(mac_handle, - adapter->vdev_id, - NULL, true); + status = wlan_hdd_flush_pmksa_cache(adapter); if (QDF_IS_STATUS_ERROR(status)) hdd_debug("Cannot flush PMKIDCache"); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 504ea24d88dd..6d3e5303848e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5467,9 +5467,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, wlan_hdd_cleanup_remain_on_channel_ctx(adapter); hdd_clear_fils_connection_info(adapter); - status = sme_roam_del_pmkid_from_cache(mac_handle, - adapter->vdev_id, - NULL, true); + status = wlan_hdd_flush_pmksa_cache(adapter); if (QDF_IS_STATUS_ERROR(status)) hdd_err("Cannot flush PMKIDCache"); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 6eedad5ebf49..6952d0319372 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21351,12 +21351,10 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, if (csr_lookup_pmkid_using_bssid(mac_ctx, session, &pmkid_cache, &pmkid_index)) { - session->pmk_len = - session->PmkidCacheInfo[pmkid_index].pmk_len; + session->pmk_len = pmkid_cache.pmk_len; qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk)); - qdf_mem_copy(session->psk_pmk, - session->PmkidCacheInfo[pmkid_index].pmk, + qdf_mem_copy(session->psk_pmk, pmkid_cache.pmk, session->pmk_len); sme_debug("pmkid found for " QDF_MAC_ADDR_STR " at %d len %d", QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes), @@ -21365,6 +21363,7 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, sme_debug("PMKID Not found in cache for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes)); } + qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); } else { roam_info->fAuthRequired = true; csr_roam_substate_change(mac_ctx, diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 29c1f4e250bd..47cb971c36ea 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -3221,7 +3221,7 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac, if (!csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index)) return false; - session_pmkid = &session->PmkidCacheInfo[index].PMKID[0]; + session_pmkid = &pmkid_cache.PMKID[0]; for (i = 0; i < pmkid_count; i++) { if (!qdf_mem_cmp(pmkid + (i * PMKID_LEN), session_pmkid, PMKID_LEN)) @@ -3654,6 +3654,35 @@ static bool csr_lookup_pmkid_using_ssid(struct mac_context *mac, } #endif +#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT +bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, + struct csr_roam_session *session, + tPmkidCacheInfo *pmk_cache, + uint32_t *index) +{ + struct wlan_crypto_pmksa *pmksa; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session->vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return false; + } + + pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache->BSSID); + if (!pmksa) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return false; + } + qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, sizeof(pmk_cache->PMKID)); + qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len); + pmk_cache->pmk_len = pmksa->pmk_len; + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + + return true; +} +#else bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, struct csr_roam_session *session, tPmkidCacheInfo *pmk_cache, @@ -3672,12 +3701,15 @@ bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, /* match found */ *index = i; sme_debug("PMKID found at index %d", i); + qdf_mem_copy(pmk_cache, session_pmk, + sizeof(tPmkidCacheInfo)); return true; } } return false; } +#endif #ifndef WLAN_CONV_CRYPTO_IE_SUPPORT /**