From 5a5ab2c344bb9b830fab9756ac1e4da457d8658b Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 9 Sep 2020 17:46:02 +0530 Subject: [PATCH] qcacld-3.0: Sae single pmk entry gets updated while roaming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While initial connection with SPMK AP1 supplicant generates PMK1, and DUT updates global mlme single pmk entry and csr session pmk. Now DUT roam to non-SPMK AP2 and generates PMK2, Global mlme single pmk has SPMK AP1 PMK1 and csr_roam_session has non-SPMK AP2 since FULL SAE happen. Now Roam back to SPMK AP1, since the Full SAE does not happen and due to check roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED in csr_process_roam_synch_callback(). The lookup and update csr_roam_session code is not hit and driver don’t update csr session pmk after roaming to SPMK AP. So after roam sync complete, csr_check_and_set_sae_single_pmk_cap() updates the global mlme single pmk with session->psk_pmk. This results DUT uses PMK generated from a Non-Single PMK supported AP in the ReAssoc Request frame while Roaming to Single PMK supported AP. Fix is to allow driver to update session->psk_pmk even in case Full SAE does not happen. Change-Id: Ie4f06cfcb066ae245de024b62da586aade783aec CRs-Fixed: 2761771 --- .../mlme/dispatcher/src/wlan_mlme_api.c | 4 +++ core/sme/src/csr/csr_api_roam.c | 34 ++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 1a0bef556e0d..78bd169974d0 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -3717,6 +3717,10 @@ void wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) is_sae_connection = true; + mlme_legacy_debug("SAE_SPMK: single_pmk_ap:%d, is_sae_connection:%d, pmk_len:%d", + mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap, + is_sae_connection, sae_single_pmk->pmk_len); + if (mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap && is_sae_connection) mlme_priv->mlme_roam.sae_single_pmk.pmk_info = *sae_single_pmk; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2024897b5969..a4f1f58d0594 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -22921,23 +22921,28 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, */ lookup_success = csr_lookup_pmkid_using_bssid(mac_ctx, session, pmkid_cache); - qdf_mem_free(pmkid_cache); if (lookup_success) { wlan_crypto_selective_clear_sae_single_pmk_entries(vdev, &session->connectedProfile.bssid); pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); - if (!pmk_info) + if (!pmk_info) { + qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); + qdf_mem_free(pmkid_cache); goto end; + } - qdf_mem_copy(pmk_info->pmk, session->psk_pmk, + qdf_mem_copy(pmk_info->pmk, pmkid_cache->pmk, session->pmk_len); - pmk_info->pmk_len = session->pmk_len; + pmk_info->pmk_len = pmkid_cache->pmk_len; wlan_mlme_update_sae_single_pmk(vdev, pmk_info); qdf_mem_zero(pmk_info, sizeof(*pmk_info)); qdf_mem_free(pmk_info); } + + qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); + qdf_mem_free(pmkid_cache); } end: @@ -23262,9 +23267,21 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx, * All other authentications - Host supplicant performs EAPOL * with AP after this point and sends new keys to the driver. * Driver starts wait_for_key timer for that purpose. + * Allow csr_lookup_pmkid_using_bssid() if akm is SAE/OWE since + * SAE/OWE roaming uses hybrid model and eapol is offloaded to + * supplicant unlike in WPA2 – 802.1x case, after 8 way handshake + * the __wlan_hdd_cfg80211_keymgmt_set_key ->sme_roam_set_psk_pmk() + * will get called after roam synch complete to update the + * session->psk_pmk, but in SAE/OWE roaming this sequence is not + * present and set_pmksa will come before roam synch indication & + * eapol. So the session->psk_pmk will be stale in PMKSA cached + * SAE/OWE roaming case. */ - if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED) { - sme_debug("LFR3:Don't start waitforkey timer"); + if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED || + session->pCurRoamProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_SAE || + session->pCurRoamProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_OWE) { csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, session_id); /* @@ -23287,8 +23304,9 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx, qdf_copy_macaddr(&pmkid_cache->BSSID, &session->connectedProfile.bssid); - sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_FMT, - QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes)); + sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_FMT " AKM Type:%d", + QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes), + session->pCurRoamProfile->negotiatedAuthType); if (csr_lookup_pmkid_using_bssid(mac_ctx, session, pmkid_cache)) { session->pmk_len = pmkid_cache->pmk_len;