فهرست منبع

qcacmn: Delete older PMK of all APs which have the same PMK

Currently when supplicant sends set_pmkid_cache (Either after
initial connection or after session timeout with AP) to host to
set the new pmkid derived after the EAP is done. Host deletes
PMK entry only if bssid/ssid matches.
For OKC, the PMK derived from the initially associated AP will
be used for deriving PMKID for all APs. In case of connection with OKC
supported APs, If STA receive session timeout from AP, HOST should
delete older PMK of all APs which have the same PMK. Else While
roaming HOST could send older PMK to OKC supported AP and this
results PMK flush in FW and leads to full EAP.

Change-Id: I83e8d4c0c8b3ad503aa5894ffdc4a14bc3aeec7a
CRs-Fixed: 2679749
Vulupala Shashank Reddy 5 سال پیش
والد
کامیت
f3d1f2a4be
1فایلهای تغییر یافته به همراه39 افزوده شده و 17 حذف شده
  1. 39 17
      umac/cmn_services/crypto/src/wlan_crypto_global_api.c

+ 39 - 17
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -342,6 +342,10 @@ int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer,
 }
 qdf_export_symbol(wlan_crypto_get_peer_param);
 
+static
+QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
+				 struct wlan_crypto_pmksa *pmksa);
+
 static
 QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
 				 struct wlan_crypto_pmksa *pmksa)
@@ -349,6 +353,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
 	uint8_t i, first_available_slot = 0;
 	bool slot_found = false;
 
+	/* Delete the old entry and then Add new entry */
+	wlan_crypto_del_pmksa(crypto_params, pmksa);
+
 	/* find the empty slot or slot with same bssid */
 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
 		if (!crypto_params->pmksa[i]) {
@@ -360,10 +367,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
 		}
 		if (qdf_is_macaddr_equal(&pmksa->bssid,
 					 &crypto_params->pmksa[i]->bssid)) {
-			/* free the current pmksa and use this slot */
-			qdf_mem_zero(crypto_params->pmksa[i],
-				     sizeof(struct wlan_crypto_pmksa));
-			qdf_mem_free(crypto_params->pmksa[i]);
+			/* current pmksa is already freed in del_pmksa,
+			 * so just use this slot
+			 */
 			crypto_params->pmksa[i] = pmksa;
 			return QDF_STATUS_SUCCESS;
 		} else if (pmksa->ssid_len &&
@@ -373,10 +379,9 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
 			    !qdf_mem_cmp(pmksa->cache_id,
 					 crypto_params->pmksa[i]->cache_id,
 					 WLAN_CACHE_ID_LEN)){
-			/* free the current pmksa and use this slot */
-			qdf_mem_zero(crypto_params->pmksa[i],
-				     sizeof(struct wlan_crypto_pmksa));
-			qdf_mem_free(crypto_params->pmksa[i]);
+			/* current pmksa is already freed in del_pmksa,
+			 * so just use this slot
+			 */
 			crypto_params->pmksa[i] = pmksa;
 			return QDF_STATUS_SUCCESS;
 		}
@@ -396,6 +401,8 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
 				 struct wlan_crypto_pmksa *pmksa)
 {
 	uint8_t i;
+	bool match_found = false;
+	u8 del_pmk[MAX_PMK_LEN] = {0};
 
 	/* find slot with same bssid */
 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
@@ -403,11 +410,7 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
 			continue;
 		if (qdf_is_macaddr_equal(&pmksa->bssid,
 					 &crypto_params->pmksa[i]->bssid)) {
-			qdf_mem_zero(crypto_params->pmksa[i],
-				     sizeof(struct wlan_crypto_pmksa));
-			qdf_mem_free(crypto_params->pmksa[i]);
-			crypto_params->pmksa[i] = NULL;
-			return QDF_STATUS_SUCCESS;
+			match_found = true;
 		} else if (pmksa->ssid_len &&
 			   !qdf_mem_cmp(pmksa->ssid,
 					crypto_params->pmksa[i]->ssid,
@@ -415,14 +418,33 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
 			   !qdf_mem_cmp(pmksa->cache_id,
 					crypto_params->pmksa[i]->cache_id,
 					WLAN_CACHE_ID_LEN)){
-			qdf_mem_zero(crypto_params->pmksa[i],
-				     sizeof(struct wlan_crypto_pmksa));
-			qdf_mem_free(crypto_params->pmksa[i]);
-			crypto_params->pmksa[i] = NULL;
+			match_found = true;
+		}
+
+		if (match_found) {
+			qdf_mem_copy(del_pmk, crypto_params->pmksa[i]->pmk,
+				     crypto_params->pmksa[i]->pmk_len);
+			for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
+				if (!crypto_params->pmksa[i])
+					continue;
+				if (crypto_params->pmksa[i]->pmk_len &&
+				    (!qdf_mem_cmp(crypto_params->pmksa[i]->pmk,
+				    del_pmk,
+				    crypto_params->pmksa[i]->pmk_len))) {
+					qdf_mem_zero(crypto_params->pmksa[i],
+						     sizeof(
+						     struct wlan_crypto_pmksa));
+					qdf_mem_free(crypto_params->pmksa[i]);
+					crypto_params->pmksa[i] = NULL;
+				}
+			}
 			return QDF_STATUS_SUCCESS;
 		}
 	}
 
+	if (i == WLAN_CRYPTO_MAX_PMKID && !match_found)
+		crypto_debug("No such pmksa entry exists");
+
 	return QDF_STATUS_SUCCESS;
 }