From cf9100c51dec3b332eaba8be54e61fb3bd1c93a3 Mon Sep 17 00:00:00 2001 From: Krupali Dhanvijay Date: Sun, 16 Oct 2022 22:10:30 +0530 Subject: [PATCH] qcacmn: 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: I3c6a49be065e4744e438c2762c103eb3095a2253 CRs-Fixed: 3313882 --- .../crypto/inc/wlan_crypto_global_api.h | 19 +++++++++- .../crypto/src/wlan_crypto_global_api.c | 37 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index 49251a52c4b2..4f1eaf957603 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1068,7 +1069,7 @@ wlan_crypto_selective_clear_sae_single_pmk_entries( struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *conn_bssid); /** - * wlan_crypto_set_sae_single_pmk_bss_cap - Set the peer SAE sinlge pmk + * wlan_crypto_set_sae_single_pmk_bss_cap - Set the peer SAE single pmk * feature supported status * @vdev: Vdev * @bssid: BSSID for which the flag is to be set @@ -1078,6 +1079,16 @@ wlan_crypto_selective_clear_sae_single_pmk_entries( void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid, bool single_pmk_capable_bss); + +/** + * wlan_crypto_set_sae_single_pmk_info - Set the peer SAE single pmk info + * @vdev: Vdev + * @roam_sync_pmksa: pmk info for roamed AP + */ +void +wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *roam_sync_pmksa); + #else static inline void wlan_crypto_selective_clear_sae_single_pmk_entries( @@ -1091,6 +1102,12 @@ void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, bool single_pmk_capable_bss) { } + +static inline void +wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *roam_sync_pmksa) +{ +} #endif #ifdef WLAN_FEATURE_FILS_SK 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 72649ff046a2..6b496baa3dbf 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -4675,6 +4676,42 @@ void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, single_pmk_capable_bss; } } + +void +wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *roam_sync_pmksa) +{ + struct wlan_crypto_params *crypto_params; + struct wlan_crypto_comp_priv *crypto_priv; + int i; + + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return; + } + + crypto_params = &crypto_priv->crypto_params; + + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + if (qdf_is_macaddr_equal(&roam_sync_pmksa->bssid, + &crypto_params->pmksa[i]->bssid) && + roam_sync_pmksa->single_pmk_supported && + roam_sync_pmksa->pmk_len) { + crypto_params->pmksa[i]->single_pmk_supported = + roam_sync_pmksa->single_pmk_supported; + crypto_params->pmksa[i]->pmk_len = + roam_sync_pmksa->pmk_len; + qdf_mem_copy(crypto_params->pmksa[i]->pmk, + roam_sync_pmksa->pmk, + roam_sync_pmksa->pmk_len); + } + } +} #endif void wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev *vdev)