|
@@ -7479,6 +7479,7 @@ csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
{
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
struct cm_roam_values_copy src_cfg;
|
|
|
+ uint32_t akm;
|
|
|
|
|
|
wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id,
|
|
|
IS_SINGLE_PMK, &src_cfg);
|
|
@@ -7492,6 +7493,12 @@ csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
|
|
|
+ if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE)) {
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
wlan_crypto_selective_clear_sae_single_pmk_entries(vdev,
|
|
|
(struct qdf_mac_addr *)bss_desc->bssId);
|
|
|
|
|
@@ -7506,6 +7513,7 @@ csr_delete_current_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
struct wlan_crypto_pmksa pmksa;
|
|
|
struct cm_roam_values_copy src_cfg;
|
|
|
+ uint32_t akm;
|
|
|
|
|
|
wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id,
|
|
|
IS_SINGLE_PMK, &src_cfg);
|
|
@@ -7520,6 +7528,12 @@ csr_delete_current_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
|
|
|
+ if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE)) {
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
qdf_copy_macaddr(&pmksa.bssid,
|
|
|
(struct qdf_mac_addr *)bss_desc->bssId);
|
|
|
wlan_crypto_set_del_pmksa(vdev, &pmksa, false);
|
|
@@ -16897,6 +16911,89 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
|
|
|
if (cm_lookup_pmkid_using_bssid(mac_ctx->psoc,
|
|
|
session->vdev_id,
|
|
|
pmkid_cache)) {
|
|
|
+ /*
|
|
|
+ * Consider two APs: AP1, AP2
|
|
|
+ * Both APs configured with EAP 802.1x security mode
|
|
|
+ * and OKC is enabled in both APs by default. Initially
|
|
|
+ * DUT successfully associated with AP1, and generated
|
|
|
+ * PMK1 by performing full EAP and added an entry for
|
|
|
+ * AP1 in pmk table. At this stage, pmk table has only
|
|
|
+ * one entry for PMK1 (1. AP1-->PMK1). Now DUT try to
|
|
|
+ * roam to AP2 using PMK1 (as OKC is enabled) but
|
|
|
+ * session timeout happens on AP2 just before 4 way
|
|
|
+ * handshake completion in FW. At this point of time
|
|
|
+ * DUT not in authenticated state. Due to this DUT
|
|
|
+ * performs full EAP with AP2 and generates PMK2. As
|
|
|
+ * there is no previous entry of AP2 (AP2-->PMK1) in pmk
|
|
|
+ * table. When host gets pmk delete command for BSSID of
|
|
|
+ * AP2, the BSSID match fails. Hence host will not
|
|
|
+ * delete pmk entry of AP1 as well.
|
|
|
+ * At this point of time, the PMK table has two entry
|
|
|
+ * 1. AP1-->PMK1 and 2. AP2 --> PMK2.
|
|
|
+ * Ideally, if OKC is enabled then whenever timeout
|
|
|
+ * occurs in a mobility domain, then the driver should
|
|
|
+ * clear all APs cache entries related to that domain
|
|
|
+ * but as the BSSID doesn't exist yet in the driver
|
|
|
+ * cache there is no way of clearing the cache entries,
|
|
|
+ * without disturbing the legacy roaming.
|
|
|
+ * Now security profile for both APs changed to FT-RSN.
|
|
|
+ * DUT first disassociate with AP2 and successfully
|
|
|
+ * associated with AP2 and perform full EAP and
|
|
|
+ * generates PMK3. DUT first deletes PMK entry for AP2
|
|
|
+ * and then adds a new entry for AP2.
|
|
|
+ * At this point of time pmk table has two entry
|
|
|
+ * AP2--> PMK3 and AP1-->PMK1. Now DUT roamed to AP1
|
|
|
+ * using PMK3 but sends stale entry of AP1 (PMK1) to
|
|
|
+ * fw via RSO command. This override PMK for both APs
|
|
|
+ * with PMK1 (as FW uses mlme session PMK for both APs
|
|
|
+ * in case of FT roaming) and next time when FW try to
|
|
|
+ * roam to AP2 using PMK1, AP2 rejects PMK1 (As AP2 is
|
|
|
+ * expecting PMK3) and initiates full EAP with AP2,
|
|
|
+ * which is wrong.
|
|
|
+ * To address this issue update pmk table entry for
|
|
|
+ * roamed AP1 with PMK3 value comes to host via roam
|
|
|
+ * sync indication event. By this host override stale
|
|
|
+ * entry (if any) with the latest valid pmk for that AP
|
|
|
+ * at a point of time.
|
|
|
+ */
|
|
|
+ if (roam_synch_data->pmk_len) {
|
|
|
+ pmksa = qdf_mem_malloc(sizeof(*pmksa));
|
|
|
+ if (!pmksa) {
|
|
|
+ status = QDF_STATUS_E_NOMEM;
|
|
|
+ qdf_mem_zero(pmkid_cache,
|
|
|
+ sizeof(*pmkid_cache));
|
|
|
+ qdf_mem_free(pmkid_cache);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This pmksa buffer is to update the
|
|
|
+ * crypto table
|
|
|
+ */
|
|
|
+ wlan_vdev_get_bss_peer_mac(vdev, &pmksa->bssid);
|
|
|
+ qdf_mem_copy(pmksa->pmkid,
|
|
|
+ roam_synch_data->pmkid, PMKID_LEN);
|
|
|
+ qdf_mem_copy(pmksa->pmk, roam_synch_data->pmk,
|
|
|
+ roam_synch_data->pmk_len);
|
|
|
+ pmksa->pmk_len = roam_synch_data->pmk_len;
|
|
|
+ status = wlan_crypto_set_del_pmksa(vdev,
|
|
|
+ pmksa, true);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ qdf_mem_zero(pmksa, sizeof(*pmksa));
|
|
|
+ qdf_mem_free(pmksa);
|
|
|
+ pmksa = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* update the pmkid_cache buffer to
|
|
|
+ * update the global session pmk
|
|
|
+ */
|
|
|
+ qdf_mem_copy(pmkid_cache->pmkid,
|
|
|
+ roam_synch_data->pmkid, PMKID_LEN);
|
|
|
+ qdf_mem_copy(pmkid_cache->pmk,
|
|
|
+ roam_synch_data->pmk,
|
|
|
+ roam_synch_data->pmk_len);
|
|
|
+ pmkid_cache->pmk_len = roam_synch_data->pmk_len;
|
|
|
+ }
|
|
|
wlan_cm_set_psk_pmk(mac_ctx->pdev, session_id,
|
|
|
pmkid_cache->pmk,
|
|
|
pmkid_cache->pmk_len);
|