Эх сурвалжийг харах

qcacmn: Update pmk for roamed AP to pmk cache table

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: 3168078
abhinav kumar 3 жил өмнө
parent
commit
e7861fb758

+ 16 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -1070,6 +1070,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_bss_cap - Set the peer SAE sinlge 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(
@@ -1083,6 +1093,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

+ 37 - 0
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -4675,6 +4675,43 @@ 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)