Browse Source

qcacld-3.0: Fill PMKID in association request to SAE AP

After SAE full authentication, driver is not including
PMKID derived as part of the SAE authentication to the
AP in association request frame. This causes interopability
issues with some AP, which expects PMKID in association
request frame.

Fill PMKID in association request to SAE AP.

Change-Id: Ic09d653c74fd5c37486e4fa22b5ca9cd85c04743
CRs-Fixed: 3280164
Pragaspathi Thilagaraj 2 years ago
parent
commit
b0dc5febdb

+ 2 - 0
core/mac/inc/sir_api.h

@@ -5140,6 +5140,7 @@ struct sir_sae_info {
  * @length: message length
  * @vdev_id: vdev id
  * @sae_status: SAE status, 0: Success, Non-zero: Failure.
+ * @pmkid: PMKID derived as part of SAE authentication
  * @peer_mac_addr: peer MAC address
  * @result_code: This carries the reason of the SAE auth failure.
  *               Currently, SAE authentication failure may happen due to
@@ -5152,6 +5153,7 @@ struct sir_sae_msg {
 	uint16_t message_type;
 	uint16_t length;
 	uint16_t vdev_id;
+	uint8_t pmkid[PMKID_LEN];
 	uint8_t sae_status;
 	tSirMacAddr peer_mac_addr;
 	tSirResultCodes result_code;

+ 35 - 2
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -82,6 +82,9 @@ static void lim_process_sae_msg_sta(struct mac_context *mac,
 				    struct pe_session *session,
 				    struct sir_sae_msg *sae_msg)
 {
+	struct wlan_crypto_pmksa *pmksa;
+	uint8_t *rsn_ie_buf;
+
 	switch (session->limMlmState) {
 	case eLIM_MLM_WT_SAE_AUTH_STATE:
 		/* SAE authentication is completed.
@@ -92,15 +95,45 @@ static void lim_process_sae_msg_sta(struct mac_context *mac,
 							eLIM_AUTH_SAE_TIMER);
 		lim_sae_auth_cleanup_retry(mac, session->vdev_id);
 		/* success */
-		if (sae_msg->sae_status == STATUS_SUCCESS)
+		if (sae_msg->sae_status == STATUS_SUCCESS) {
+			uint8_t zero_pmkid[PMKID_LEN] = {0};
+
+			if (!qdf_mem_cmp(sae_msg->pmkid, zero_pmkid,
+					 PMKID_LEN)) {
+				pe_debug("pmkid not received in ext auth");
+				goto restore_auth_state;
+			}
+
+			pmksa = qdf_mem_malloc(sizeof(*pmksa));
+			if (!pmksa)
+				goto restore_auth_state;
+
+			rsn_ie_buf = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2);
+			if (!rsn_ie_buf) {
+				qdf_mem_free(pmksa);
+				goto restore_auth_state;
+			}
+
+			qdf_mem_copy(pmksa->pmkid, sae_msg->pmkid, PMKID_LEN);
+			qdf_mem_copy(pmksa->bssid.bytes, sae_msg->peer_mac_addr,
+				     QDF_MAC_ADDR_SIZE);
+
+			qdf_mem_zero(session->lim_join_req->rsnIE.rsnIEdata,
+				     WLAN_MAX_IE_LEN + 2);
+			lim_update_connect_rsn_ie(session, rsn_ie_buf, pmksa);
+
+			qdf_mem_free(pmksa);
+			qdf_mem_free(rsn_ie_buf);
+restore_auth_state:
 			lim_restore_from_auth_state(mac,
 						    eSIR_SME_SUCCESS,
 						    STATUS_SUCCESS,
 						    session);
-		else
+		} else {
 			lim_restore_from_auth_state(mac, sae_msg->result_code,
 						    sae_msg->sae_status,
 						    session);
+		}
 		break;
 	default:
 		/* SAE msg is received in unexpected state */

+ 22 - 11
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3772,6 +3772,26 @@ lim_strip_rsnx_ie(struct mac_context *mac_ctx,
 	}
 }
 
+void
+lim_update_connect_rsn_ie(struct pe_session *session,
+			  uint8_t *rsn_ie_buf, struct wlan_crypto_pmksa *pmksa)
+{
+	uint8_t *rsn_ie_end;
+	uint16_t rsn_ie_len = 0;
+
+	rsn_ie_end = wlan_crypto_build_rsnie_with_pmksa(session->vdev,
+							rsn_ie_buf, pmksa);
+	if (!rsn_ie_end) {
+		pe_debug("Build RSN IE failed");
+		return;
+	}
+
+	rsn_ie_len = rsn_ie_end - rsn_ie_buf;
+	session->lim_join_req->rsnIE.length = rsn_ie_len;
+	qdf_mem_copy(session->lim_join_req->rsnIE.rsnIEdata,
+		     rsn_ie_buf, rsn_ie_len);
+}
+
 static QDF_STATUS
 lim_fill_rsn_ie(struct mac_context *mac_ctx, struct pe_session *session,
 		struct cm_vdev_join_req *req)
@@ -3779,7 +3799,6 @@ lim_fill_rsn_ie(struct mac_context *mac_ctx, struct pe_session *session,
 	QDF_STATUS status;
 	uint8_t *rsn_ie;
 	uint8_t rsn_ie_len = 0;
-	uint8_t *rsn_ie_end = NULL;
 	struct wlan_crypto_pmksa pmksa, *pmksa_peer;
 	struct bss_description *bss_desc;
 
@@ -3831,17 +3850,9 @@ lim_fill_rsn_ie(struct mac_context *mac_ctx, struct pe_session *session,
 			 session->vdev_id, pmksa.ssid_len, pmksa.ssid,
 			 bss_desc->fils_info_element.is_cache_id_present);
 
-	/* TODO: Add support for Adaptive 11r connection */
-	rsn_ie_end = wlan_crypto_build_rsnie_with_pmksa(session->vdev, rsn_ie,
-							pmksa_peer);
-	if (rsn_ie_end)
-		rsn_ie_len = rsn_ie_end - rsn_ie;
-
-	session->lim_join_req->rsnIE.length = rsn_ie_len;
-	qdf_mem_copy(session->lim_join_req->rsnIE.rsnIEdata,
-		     rsn_ie, rsn_ie_len);
-
+	lim_update_connect_rsn_ie(session, rsn_ie, pmksa_peer);
 	qdf_mem_free(rsn_ie);
+
 	/*
 	 * If a PMK cache is found for the BSSID, then
 	 * update the PMK in CSR session also as this

+ 12 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -1044,6 +1044,18 @@ QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx,
 				 enum csr_cfgdot11mode dot11_mode,
 				 enum QDF_OPMODE device_mode);
 
+/**
+ * lim_update_connect_rsn_ie() - Update the connection RSN IE
+ * @session: PE session
+ * @rsn_ie_buf: RSN IE buffer
+ * @pmksa: PMKSA entry for the connecting AP
+ *
+ * Return: None
+ */
+void
+lim_update_connect_rsn_ie(struct pe_session *session, uint8_t *rsn_ie_buf,
+			  struct wlan_crypto_pmksa *pmksa);
+
 /**
  * lim_send_action_frm_tb_ppdu_cfg() - sets action frame in TB PPDU cfg to FW
  * @mac_ctx: global MAC context

+ 3 - 0
core/sme/src/common/sme_api.c

@@ -14623,6 +14623,9 @@ QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
 		qdf_mem_copy(sae_msg->peer_mac_addr,
 			     peer_mac_addr.bytes,
 			     QDF_MAC_ADDR_SIZE);
+		qdf_mem_zero(sae_msg->pmkid, PMKID_LEN);
+		if (pmkid)
+			qdf_mem_copy(sae_msg->pmkid, pmkid, PMKID_LEN);
 		sme_debug("SAE: sae_status %d vdev_id %d Peer: "
 			  QDF_MAC_ADDR_FMT, sae_msg->sae_status,
 			  sae_msg->vdev_id,