Browse Source

qcacld-3.0: Sae single pmk entry gets updated while roaming

While initial connection with SPMK AP1 supplicant generates
PMK1, and DUT updates global mlme single pmk entry and
csr session pmk.

Now DUT roam to non-SPMK AP2 and generates PMK2, Global mlme
single pmk has SPMK AP1 PMK1 and csr_roam_session has non-SPMK
AP2 since FULL SAE happen.

Now Roam back to SPMK AP1, since the Full SAE does not happen
and due to check roam_synch_data->authStatus ==
CSR_ROAM_AUTH_STATUS_AUTHENTICATED in
csr_process_roam_synch_callback(). The lookup and update
csr_roam_session code is not hit and driver don’t update
csr session pmk after roaming to SPMK AP. So after roam sync complete,
csr_check_and_set_sae_single_pmk_cap() updates the global mlme
single pmk with session->psk_pmk. This results DUT uses PMK generated
from a Non-Single PMK supported AP in the ReAssoc Request frame
while Roaming to Single PMK supported AP.

Fix is to allow driver to update session->psk_pmk even in case
Full SAE does not happen.

Change-Id: Ie4f06cfcb066ae245de024b62da586aade783aec
CRs-Fixed: 2761771
Abhinav Kumar 4 years ago
parent
commit
5a5ab2c344
2 changed files with 30 additions and 8 deletions
  1. 4 0
      components/mlme/dispatcher/src/wlan_mlme_api.c
  2. 26 8
      core/sme/src/csr/csr_api_roam.c

+ 4 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -3717,6 +3717,10 @@ void wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev,
 	if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE))
 		is_sae_connection = true;
 
+	mlme_legacy_debug("SAE_SPMK: single_pmk_ap:%d, is_sae_connection:%d, pmk_len:%d",
+			  mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap,
+			  is_sae_connection, sae_single_pmk->pmk_len);
+
 	if (mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap &&
 	    is_sae_connection)
 		mlme_priv->mlme_roam.sae_single_pmk.pmk_info = *sae_single_pmk;

+ 26 - 8
core/sme/src/csr/csr_api_roam.c

@@ -22921,23 +22921,28 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx,
 		 */
 		lookup_success = csr_lookup_pmkid_using_bssid(mac_ctx, session,
 							      pmkid_cache);
-		qdf_mem_free(pmkid_cache);
 		if (lookup_success) {
 			wlan_crypto_selective_clear_sae_single_pmk_entries(vdev,
 					&session->connectedProfile.bssid);
 
 			pmk_info = qdf_mem_malloc(sizeof(*pmk_info));
-			if (!pmk_info)
+			if (!pmk_info) {
+				qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache));
+				qdf_mem_free(pmkid_cache);
 				goto end;
+			}
 
-			qdf_mem_copy(pmk_info->pmk, session->psk_pmk,
+			qdf_mem_copy(pmk_info->pmk, pmkid_cache->pmk,
 				     session->pmk_len);
-			pmk_info->pmk_len = session->pmk_len;
+			pmk_info->pmk_len = pmkid_cache->pmk_len;
 			wlan_mlme_update_sae_single_pmk(vdev, pmk_info);
 
 			qdf_mem_zero(pmk_info, sizeof(*pmk_info));
 			qdf_mem_free(pmk_info);
 		}
+
+		qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache));
+		qdf_mem_free(pmkid_cache);
 	}
 
 end:
@@ -23262,9 +23267,21 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 	 * All other authentications - Host supplicant performs EAPOL
 	 *      with AP after this point and sends new keys to the driver.
 	 *      Driver starts wait_for_key timer for that purpose.
+	 * Allow csr_lookup_pmkid_using_bssid() if akm is SAE/OWE since
+	 * SAE/OWE roaming uses hybrid model and eapol is offloaded to
+	 * supplicant unlike in WPA2 – 802.1x case, after 8 way handshake
+	 * the __wlan_hdd_cfg80211_keymgmt_set_key ->sme_roam_set_psk_pmk()
+	 * will get called after roam synch complete to update the
+	 * session->psk_pmk, but in SAE/OWE roaming this sequence is not
+	 * present and set_pmksa will come before roam synch indication &
+	 * eapol. So the session->psk_pmk will be stale in PMKSA cached
+	 * SAE/OWE roaming case.
 	 */
-	if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
-		sme_debug("LFR3:Don't start waitforkey timer");
+	if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED ||
+	    session->pCurRoamProfile->negotiatedAuthType ==
+	    eCSR_AUTH_TYPE_SAE ||
+	    session->pCurRoamProfile->negotiatedAuthType ==
+	    eCSR_AUTH_TYPE_OWE) {
 		csr_roam_substate_change(mac_ctx,
 				eCSR_ROAM_SUBSTATE_NONE, session_id);
 		/*
@@ -23287,8 +23304,9 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 
 		qdf_copy_macaddr(&pmkid_cache->BSSID,
 				 &session->connectedProfile.bssid);
-		sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_FMT,
-			  QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes));
+		sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_FMT " AKM Type:%d",
+			  QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes),
+			  session->pCurRoamProfile->negotiatedAuthType);
 		if (csr_lookup_pmkid_using_bssid(mac_ctx, session,
 						 pmkid_cache)) {
 			session->pmk_len = pmkid_cache->pmk_len;