From 72f37fd7014abbc15889a808f0fb9abc2f582403 Mon Sep 17 00:00:00 2001 From: Krupali Dhanvijay Date: Sun, 16 Oct 2022 22:06:11 +0530 Subject: [PATCH] qcacld-3.0: Update pmk for roamed AP to pmk cache table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assume AP1 and AP2 are SPMK APs. For SPMK AP(s), Host should add an entry of an AP in PMK cache table like below in two cases only: Case 1. When DUT successfully associated with SPMK supported AP In this case host update “is_spmk_ap” flag in PMK table by parsing beacon of associated AP after successful connection. Case 2. When DUT successfully roamed to SPMK supported AP In this case host update “is_spmk_ap” flag in PMK table by parsing roam sync indication event. In case of connection with SPMK AP, Host selectively deletes PMK entry for other SPMK supported AP(s) on basis of “is_spmk_ap” flag and maintains only one entry for all SPMK AP(s). And host sends the same single PMK in RSO for further roaming to SPMK AP. Initially, DUT is connected with AP2. Then Disconnection happens with AP2 due to NUD failure. After disconnection, the upper layer sends flush PMK requests for AP1 and AP2. Host deletes old PMK entries for both APs. Now upper layer sends a set PMK request for AP2. Host adds AP2 entry in PMK cache table but host does not set "is_spmk_ap" flag in PMK table for this entry as DUT is not connected to AP2. Now host receives a connect request for AP1 from the upper layer. DUT successfully associated with AP1 by performing full SAE authentication. Host adds an entry for AP1 in the PMK cache table and sets "is_spmk_ap" flag for AP1 but fails to delete the entry for other SPMK AP(s), here AP2, from PMK cache table. This is because of "is_spmk_ap" flag is not set for AP2. At this point of time below is the PMK cache table entry for SPMK AP(s): The Host PMK cache table has two entries for two SPMK APs. BSSID PMK is_spmk_ap flag AP2 PMK2 0 AP1 PMK1 1 Now FW roams to AP2 using PMK1. Host process roam sync indication for AP2 and updates "is_spmk_ap" flag for AP2 in the PMK cache table. As Host has a stale entry for AP2 in the PMK cache table, Host sends AP2’s PMK (here PMK2) in RSO command which firmware will use for further roaming but roaming fails due to invalid PMK, as target SPMK AP expects PMK1 in reassociation request. To handle these scenarios, FW should send PMK info of roamed AP and host override stale entry for roamed AP (if any) with roamed AP's PMK in PMK cache table. Change-Id: I5e46d16a64aa05469ebc389df9b638351d02a1e0 CRs-Fixed: 3313884 --- core/sme/src/csr/csr_api_roam.c | 42 +++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2d5aaeb43567..854b6c35a72e 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21017,17 +21017,21 @@ static bool csr_is_sae_single_pmk_vsie_ap(struct bss_description *bss_des) * @mac_ctx: mac context * @session: Session * @vdev_id: session id + * @psk_pmk: pmk of roamed AP + * @pmk_len: pmk length * * Return: True if same pmk IE is present */ static void csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, struct csr_roam_session *session, - uint8_t vdev_id) + uint8_t vdev_id, uint8_t *psk_pmk, + uint8_t pmk_len) { struct wlan_objmgr_vdev *vdev; struct mlme_pmk_info *pmk_info; tPmkidCacheInfo *pmkid_cache; + struct wlan_crypto_pmksa *roam_sync_pmksa; int32_t keymgmt; bool val, lookup_success; @@ -21052,9 +21056,28 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, if (!val) goto end; - wlan_crypto_set_sae_single_pmk_bss_cap(vdev, - (struct qdf_mac_addr *)session->pConnectBssDesc->bssId, - true); + roam_sync_pmksa = qdf_mem_malloc(sizeof(*roam_sync_pmksa)); + if (roam_sync_pmksa) { + qdf_copy_macaddr(&roam_sync_pmksa->bssid, + (struct qdf_mac_addr *) + &session->pConnectBssDesc->bssId); + roam_sync_pmksa->single_pmk_supported = true; + roam_sync_pmksa->pmk_len = pmk_len; + qdf_mem_copy(roam_sync_pmksa->pmk, psk_pmk, + roam_sync_pmksa->pmk_len); + sme_debug("SPMK received for " QDF_MAC_ADDR_FMT + "pmk_len:%d", QDF_MAC_ADDR_REF( + roam_sync_pmksa->bssid.bytes), + roam_sync_pmksa->pmk_len); + /* update single pmk info for roamed ap to pmk table */ + wlan_crypto_set_sae_single_pmk_info(vdev, + roam_sync_pmksa); + + qdf_mem_zero(roam_sync_pmksa, sizeof(*roam_sync_pmksa)); + qdf_mem_free(roam_sync_pmksa); + } else { + goto end; + } pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); if (!pmkid_cache) @@ -21107,7 +21130,8 @@ end: static inline void csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, struct csr_roam_session *session, - uint8_t vdev_id) + uint8_t vdev_id, uint8_t *psk_pmk, + uint8_t pmk_len) { } #endif @@ -21330,8 +21354,12 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx, mac_ctx->psoc); mac_ctx->sme.set_connection_info_cb(false); - csr_check_and_set_sae_single_pmk_cap(mac_ctx, session, - session_id); + if (roam_synch_data->pmk_len) + csr_check_and_set_sae_single_pmk_cap( + mac_ctx, session, + session_id, + roam_synch_data->pmk, + roam_synch_data->pmk_len); if (ucfg_pkt_capture_get_pktcap_mode(mac_ctx->psoc)) ucfg_pkt_capture_record_channel(vdev);