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

qcacmn: Fix the FILS params set

Host updates proper FILS param set i.e. username, auth_type and
is_fils_connection in the FILS response.

Change-Id: I0c30325bc7d620aa286aae0dd299dec9b26219ff
CRs-Fixed: 2865060
Abhishek Ambure 4 жил өмнө
parent
commit
35135ea9a1

+ 1 - 0
os_if/linux/mlme/src/osif_cm_connect_rsp.c

@@ -427,6 +427,7 @@ static void osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss,
 		osif_cm_save_gtk(vdev, rsp);
 	}
 
+	osif_debug("Connect resp status  %d", conn_rsp_params.status);
 	cfg80211_connect_done(dev, &conn_rsp_params, GFP_KERNEL);
 	if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len)
 		osif_cm_set_hlp_data(dev, vdev, rsp);

+ 74 - 34
os_if/linux/mlme/src/osif_cm_req.c

@@ -27,6 +27,9 @@
 #include "wlan_nl_to_crypto_params.h"
 #include <wlan_cfg80211.h>
 #include "osif_cm_util.h"
+#ifdef WLAN_FEATURE_FILS_SK
+#include <wlan_mlme_ucfg_api.h>
+#endif
 
 static void osif_cm_free_wep_key_params(struct wlan_cm_connect_req *connect_req)
 {
@@ -169,18 +172,6 @@ QDF_STATUS osif_cm_set_crypto_params(struct wlan_cm_connect_req *connect_req,
 }
 
 #ifdef WLAN_FEATURE_FILS_SK
-static bool osif_cm_is_fils_auth_type(enum nl80211_auth_type auth_type)
-{
-	switch (auth_type) {
-	case NL80211_AUTHTYPE_FILS_SK:
-	case NL80211_AUTHTYPE_FILS_SK_PFS:
-	case NL80211_AUTHTYPE_FILS_PK:
-		return true;
-	default:
-		return false;
-	}
-}
-
 static bool osif_cm_is_akm_suite_fils(uint32_t key_mgmt)
 {
 	switch (key_mgmt) {
@@ -194,12 +185,11 @@ static bool osif_cm_is_akm_suite_fils(uint32_t key_mgmt)
 	}
 }
 
-static bool osif_cm_is_conn_type_fils(const struct cfg80211_connect_params *req)
+static bool osif_cm_is_conn_type_fils(struct wlan_cm_connect_req *connect_req,
+				      const struct cfg80211_connect_params *req)
 {
 	int num_akm_suites = req->crypto.n_akm_suites;
 	uint32_t key_mgmt = req->crypto.akm_suites[0];
-	bool is_fils_auth_type =
-		osif_cm_is_fils_auth_type(req->auth_type);
 
 	if (num_akm_suites <= 0)
 		return false;
@@ -207,7 +197,7 @@ static bool osif_cm_is_conn_type_fils(const struct cfg80211_connect_params *req)
 	/*
 	 * Auth type will be either be OPEN or FILS type for a FILS connection
 	 */
-	if (!is_fils_auth_type &&
+	if (connect_req->fils_info.auth_type == FILS_PK_MAX &&
 	    req->auth_type != NL80211_AUTHTYPE_OPEN_SYSTEM)
 		return false;
 
@@ -235,52 +225,102 @@ osif_cm_get_fils_auth_type(enum nl80211_auth_type auth)
 }
 
 static QDF_STATUS
-osif_cm_set_fils_info(struct wlan_cm_connect_req *connect_req,
+osif_cm_set_fils_info(struct wlan_objmgr_vdev *vdev,
+		      struct wlan_cm_connect_req *connect_req,
 		      const struct cfg80211_connect_params *req)
 {
+	bool value = 0;
+	QDF_STATUS status;
+	uint8_t *buf;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return -QDF_STATUS_E_INVAL;
+
+	connect_req->fils_info.auth_type =
+		osif_cm_get_fils_auth_type(req->auth_type);
 	connect_req->fils_info.is_fils_connection =
-					osif_cm_is_conn_type_fils(req);
-	connect_req->fils_info.username_len = req->fils_erp_username_len;
+					osif_cm_is_conn_type_fils(connect_req,
+								  req);
+	osif_debug("auth type %d is fils %d",
+		   connect_req->fils_info.auth_type,
+		   connect_req->fils_info.is_fils_connection);
+	if (!connect_req->fils_info.is_fils_connection)
+		return QDF_STATUS_SUCCESS;
 
-	if (connect_req->fils_info.username_len >
-					WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH) {
-		osif_err("Invalid fils username len");
+	status = ucfg_mlme_get_fils_enabled_info(psoc, &value);
+	if (QDF_IS_STATUS_ERROR(status) || !value) {
+		osif_err("get_fils_enabled status: %d fils_enabled: %d",
+			 status, value);
 		return QDF_STATUS_E_INVAL;
 	}
-	qdf_mem_zero(connect_req->fils_info.username,
-		     WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH);
-	qdf_mem_copy(connect_req->fils_info.username, req->fils_erp_username,
-		     connect_req->fils_info.username_len);
 
-	connect_req->fils_info.realm_len = req->fils_erp_username_len;
+	/*
+	 * The initial connection for FILS may happen with an OPEN
+	 * auth type. Hence we need to allow the connection to go
+	 * through in that case as well.
+	 */
+	if (req->auth_type != NL80211_AUTHTYPE_FILS_SK) {
+		osif_debug("set is fils false for initial connection");
+		connect_req->fils_info.is_fils_connection = false;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	connect_req->fils_info.realm_len = req->fils_erp_realm_len;
 
 	if (connect_req->fils_info.realm_len > WLAN_CM_FILS_MAX_REALM_LEN) {
-		osif_err("Invalid fils realm len");
+		osif_err("Invalid fils realm len %d",
+			 connect_req->fils_info.realm_len);
 		return QDF_STATUS_E_INVAL;
 	}
 	qdf_mem_zero(connect_req->fils_info.realm, WLAN_CM_FILS_MAX_REALM_LEN);
 	qdf_mem_copy(connect_req->fils_info.realm, req->fils_erp_realm,
 		     connect_req->fils_info.realm_len);
 
-	connect_req->fils_info.next_seq_num = req->fils_erp_next_seq_num;
+	connect_req->fils_info.next_seq_num = req->fils_erp_next_seq_num + 1;
 
 	connect_req->fils_info.rrk_len = req->fils_erp_rrk_len;
 
 	if (connect_req->fils_info.rrk_len > WLAN_CM_FILS_MAX_RRK_LENGTH) {
-		osif_err("Invalid fils rrk len");
+		osif_err("Invalid fils rrk len %d",
+			 connect_req->fils_info.rrk_len);
 		return QDF_STATUS_E_INVAL;
 	}
 	qdf_mem_zero(connect_req->fils_info.rrk, WLAN_CM_FILS_MAX_RRK_LENGTH);
 	qdf_mem_copy(connect_req->fils_info.rrk, req->fils_erp_rrk,
 		     connect_req->fils_info.rrk_len);
-	connect_req->fils_info.auth_type =
-		osif_cm_get_fils_auth_type(req->auth_type);
+
+	connect_req->fils_info.username_len = req->fils_erp_username_len +
+					sizeof(char) + req->fils_erp_realm_len;
+	osif_debug("usrname len %d = usrname recv len %d + realm len %d + 1",
+		   connect_req->fils_info.username_len,
+		   req->fils_erp_username_len, req->fils_erp_realm_len);
+
+	if (connect_req->fils_info.username_len >
+					WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH) {
+		osif_err("Invalid fils username len %d",
+			 connect_req->fils_info.username_len);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!req->fils_erp_username_len) {
+		osif_info("FILS_PMKSA: No ERP username, return success");
+		return QDF_STATUS_SUCCESS;
+	}
+	buf = connect_req->fils_info.username;
+	qdf_mem_zero(connect_req->fils_info.username,
+		     WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH);
+	qdf_mem_copy(buf, req->fils_erp_username, req->fils_erp_username_len);
+	buf += req->fils_erp_username_len;
+	*buf++ = '@';
+	qdf_mem_copy(buf, req->fils_erp_realm, req->fils_erp_realm_len);
 
 	return QDF_STATUS_SUCCESS;
 }
 #else
 static inline
-QDF_STATUS osif_cm_set_fils_info(struct wlan_cm_connect_req *connect_req,
+QDF_STATUS osif_cm_set_fils_info(struct wlan_objmgr_vdev *vdev,
+				 struct wlan_cm_connect_req *connect_req,
 				 const struct cfg80211_connect_params *req)
 {
 	return QDF_STATUS_SUCCESS;
@@ -476,7 +516,7 @@ int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
 	qdf_mem_copy(connect_req->assoc_ie.ptr, req->ie,
 		     connect_req->assoc_ie.len);
 
-	status = osif_cm_set_fils_info(connect_req, req);
+	status = osif_cm_set_fils_info(vdev, connect_req, req);
 	if (QDF_IS_STATUS_ERROR(status))
 		goto connect_start_fail;
 

+ 9 - 6
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -1391,18 +1391,21 @@ static inline void cm_set_fils_connection(struct cnx_mgr *cm_ctx,
 {
 	int32_t key_mgmt;
 
-	/* return if already set */
-	if (resp->is_fils_connection)
+	/*
+	 * Check and set only in case of failure and when
+	 * resp->is_fils_connection is not alredy set, else return.
+	 */
+	if (QDF_IS_STATUS_SUCCESS(resp->connect_status) ||
+	    resp->is_fils_connection)
 		return;
+
 	key_mgmt = wlan_crypto_get_param(cm_ctx->vdev,
 					 WLAN_CRYPTO_PARAM_KEY_MGMT);
 
-	if (!(key_mgmt & (1 << WLAN_CRYPTO_KEY_MGMT_FILS_SHA256 |
+	if (key_mgmt & (1 << WLAN_CRYPTO_KEY_MGMT_FILS_SHA256 |
 			  1 << WLAN_CRYPTO_KEY_MGMT_FILS_SHA384 |
 			  1 << WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256 |
-			  1 << WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384)))
-		resp->is_fils_connection = false;
-	else
+			  1 << WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384))
 		resp->is_fils_connection = true;
 }
 #else

+ 3 - 3
umac/scan/core/src/wlan_scan_filter.c

@@ -571,15 +571,15 @@ static bool scm_is_fils_config_match(struct scan_filter *filter,
 	data = indication_ie->variable_data;
 
 	if (indication_ie->is_cache_id_present &&
-	    (data + CACHE_IDENTIFIER_LEN) < end_ptr)
+	    (data + CACHE_IDENTIFIER_LEN) <= end_ptr)
 		data += CACHE_IDENTIFIER_LEN;
 
 	if (indication_ie->is_hessid_present &&
-	    (data + HESSID_LEN) < end_ptr)
+	    (data + HESSID_LEN) <= end_ptr)
 		data += HESSID_LEN;
 
 	for (i = 1; i <= indication_ie->realm_identifiers_cnt &&
-	     (data + REALM_HASH_LEN) < end_ptr; i++) {
+	     (data + REALM_HASH_LEN) <= end_ptr; i++) {
 		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
 				 data, REALM_HASH_LEN))
 			return true;