diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 27cf6d64cb6d..92044f91b43c 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -13469,6 +13469,30 @@ enum hdd_external_acs_freq_band {
#define CFG_ENABLE_SCORING_FOR_ROAM_MIN (0)
#define CFG_ENABLE_SCORING_FOR_ROAM_MAX (1)
+/*
+ *
+ * force_rsne_override - force rsnie override from user
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable test mode to force rsne override used in
+ * security enhancement test cases to pass the RSNIE sent by user in
+ * assoc request.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: internal
+ *
+ *
+ */
+#define CFG_FORCE_RSNE_OVERRIDE_NAME "force_rsne_override"
+#define CFG_FORCE_RSNE_OVERRIDE_MIN (0)
+#define CFG_FORCE_RSNE_OVERRIDE_MAX (1)
+#define CFG_FORCE_RSNE_OVERRIDE_DEFAULT (0)
+
/*
*
* gChanSwitchHostapdRateEnabled - Enable/disable hostapd rate when doing SAP
@@ -14824,6 +14848,7 @@ struct hdd_config {
uint32_t oce_wan_score_slots11_to_8;
uint32_t oce_wan_score_slots15_to_12;
bool enable_scoring_for_roam;
+ bool force_rsne_override;
bool is_fils_enabled;
uint16_t wlm_latency_enable;
uint16_t wlm_latency_level;
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 092fa14054b1..631372f790e1 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1711,6 +1711,7 @@ struct hdd_context {
qdf_atomic_t disable_lro_in_concurrency;
qdf_atomic_t disable_lro_in_low_tput;
bool en_tcp_delack_no_lro;
+ bool force_rsne_override;
qdf_wake_lock_t monitor_mode_wakelock;
bool lte_coex_ant_share;
};
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 90fdb969ea81..92b41e82fd87 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -4942,6 +4942,7 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
tDot11fIEWPA dot11WPAIE;
uint8_t *pRsnIe;
uint16_t RSNIeLen;
+ uint32_t parse_status;
/*
* Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
@@ -4963,8 +4964,13 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
pRsnIe = gen_ie + 2;
RSNIeLen = gen_ie_len - 2;
/* Unpack the RSN IE */
- sme_unpack_rsn_ie(halHandle, pRsnIe, RSNIeLen,
+ parse_status = sme_unpack_rsn_ie(halHandle, pRsnIe, RSNIeLen,
&dot11RSNIE, false);
+ if (!DOT11F_SUCCEEDED(parse_status)) {
+ hdd_err("Invalid RSN IE: parse status %d",
+ parse_status);
+ return -EINVAL;
+ }
/* Copy out the encryption and authentication types */
hdd_debug("pairwise cipher suite count: %d",
dot11RSNIE.pwise_cipher_suite_count);
@@ -4999,8 +5005,13 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
pRsnIe = gen_ie + 2 + 4;
RSNIeLen = gen_ie_len - (2 + 4);
/* Unpack the WPA IE */
- dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
+ parse_status = dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
pRsnIe, RSNIeLen, &dot11WPAIE, false);
+ if (!DOT11F_SUCCEEDED(parse_status)) {
+ hdd_err("Invalid WPA IE: parse status %d",
+ parse_status);
+ return -EINVAL;
+ }
/* Copy out the encryption and authentication types */
hdd_debug("WPA unicast cipher suite count: %d",
dot11WPAIE.unicast_cipher_count);
@@ -5026,6 +5037,37 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
return 0;
}
+/**
+ * hdd_set_def_rsne_override() - set default encryption type and auth type
+ * in profile.
+ * @roam_profile: pointer to adapter
+ * @auth_type: pointer to auth type
+ *
+ * Set default value of encryption type and auth type in profile to
+ * search the AP using filter, as in force_rsne_override the RSNIE can be
+ * currupt and we might not get the proper encryption type and auth type
+ * while parsing the RSNIE.
+ *
+ * Return: void
+ */
+static void hdd_set_def_rsne_override(
+ tCsrRoamProfile *roam_profile, eCsrAuthType *auth_type)
+{
+
+ hdd_debug("Set def values in roam profile");
+ roam_profile->MFPCapable = roam_profile->MFPEnabled;
+ roam_profile->EncryptionType.numEntries = 2;
+ roam_profile->mcEncryptionType.numEntries = 2;
+ /* Use the cipher type in the RSN IE */
+ roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES;
+ roam_profile->EncryptionType.encryptionType[1] = eCSR_ENCRYPT_TYPE_TKIP;
+ roam_profile->mcEncryptionType.encryptionType[0] =
+ eCSR_ENCRYPT_TYPE_AES;
+ roam_profile->mcEncryptionType.encryptionType[1] =
+ eCSR_ENCRYPT_TYPE_TKIP;
+ *auth_type = eCSR_AUTH_TYPE_RSN_PSK;
+}
+
/**
* hdd_set_genie_to_csr() - set genie to csr
* @adapter: pointer to adapter
@@ -5041,6 +5083,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
uint32_t status = 0;
eCsrEncryptionType RSNEncryptType;
eCsrEncryptionType mcRSNEncryptType;
+ struct hdd_context *hdd_ctx;
#ifdef WLAN_FEATURE_11W
uint8_t RSNMfpRequired = 0;
uint8_t RSNMfpCapable = 0;
@@ -5057,6 +5100,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
} else {
return 0;
}
+
/* The actual processing may eventually be more extensive than this. */
/* Right now, just consume any PMKIDs that are sent in by the app. */
status = hdd_process_genie(adapter, bssid,
@@ -5067,6 +5111,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
#endif
pWextState->WPARSNIE[1] + 2,
pWextState->WPARSNIE);
+
if (status == 0) {
/*
* Now copy over all the security attributes
@@ -5107,6 +5152,21 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
*RSNAuthType, RSNEncryptType, mcRSNEncryptType);
}
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ if (hdd_ctx->force_rsne_override &&
+ (pWextState->WPARSNIE[0] == DOT11F_EID_RSN)) {
+ hdd_warn("Test mode enabled set def Auth and enc type. RSN IE passed in connect req: ");
+ qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
+ pWextState->roamProfile.pRSNReqIE,
+ pWextState->roamProfile.nRSNReqIELength);
+
+ pWextState->roamProfile.force_rsne_override = true;
+ /* If parsing failed set the def value for the roam profile */
+ if (status)
+ hdd_set_def_rsne_override(&pWextState->roamProfile,
+ RSNAuthType);
+ }
return 0;
}
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 972e2410cbd7..79de8445cefc 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -5266,6 +5266,13 @@ struct reg_table_entry g_registry_table[] = {
CFG_ENABLE_SCORING_FOR_ROAM_MIN,
CFG_ENABLE_SCORING_FOR_ROAM_MAX),
+ REG_VARIABLE(CFG_FORCE_RSNE_OVERRIDE_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, force_rsne_override,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_FORCE_RSNE_OVERRIDE_DEFAULT,
+ CFG_FORCE_RSNE_OVERRIDE_MIN,
+ CFG_FORCE_RSNE_OVERRIDE_MAX),
+
REG_VARIABLE(CFG_MBO_CANDIDATE_RSSI_THRESHOLD_NAME,
WLAN_PARAM_SignedInteger, struct hdd_config,
mbo_candidate_rssi_thres,
@@ -7223,6 +7230,9 @@ void hdd_cfg_print(struct hdd_context *hdd_ctx)
hdd_debug("Name = [%s] value = [%u]",
CFG_OCE_WAN_SCORE_IDX15_TO_12_NAME,
hdd_ctx->config->oce_wan_score_slots15_to_12);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_FORCE_RSNE_OVERRIDE_NAME,
+ hdd_ctx->config->force_rsne_override);
hdd_debug("Name = [%s] value = [0x%x]", CFG_VC_MODE_BITMAP,
hdd_ctx->config->vc_mode_cfg_bitmap);
hdd_debug("Name = [%s] Value = [%u]",
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c029301a97cb..9fae1ad087e1 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -6269,6 +6269,7 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL] = {.type = NLA_U16 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT] = {.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
};
/**
@@ -7176,6 +7177,22 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
}
}
+ if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
+ hdd_ctx->config->force_rsne_override) {
+ uint8_t force_rsne_override;
+
+ force_rsne_override =
+ nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
+ if (force_rsne_override > 1) {
+ hdd_err("Invalid test_mode %d", force_rsne_override);
+ ret_val = -EINVAL;
+ }
+
+ hdd_ctx->force_rsne_override = force_rsne_override;
+ hdd_debug("force_rsne_override - %d",
+ hdd_ctx->force_rsne_override);
+ }
+
return ret_val;
}
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 917c01225df0..9ef879ebaf9e 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -1260,6 +1260,7 @@ typedef struct sSirSmeJoinReq {
#endif
/* Pls make this as last variable in struct */
bool force_24ghz_in_ht20;
+ bool force_rsne_override;
tSirBssDescription bssDescription;
/*
* WARNING: Pls make bssDescription as last variable in struct
diff --git a/core/mac/src/pe/lim/lim_sme_req_utils.c b/core/mac/src/pe/lim/lim_sme_req_utils.c
index 1d66be4f95bc..e2646e6ace71 100644
--- a/core/mac/src/pe/lim/lim_sme_req_utils.c
+++ b/core/mac/src/pe/lim/lim_sme_req_utils.c
@@ -490,7 +490,13 @@ uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
{
uint8_t valid = true;
- if (!lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
+ /*
+ * If force_rsne_override is enabled that mean User has provided the
+ * test RSNIE which need to be send as it is in assoc req and thus RSNIE
+ * validity is not required.
+ */
+ if (!pJoinReq->force_rsne_override &&
+ !lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
pe_err("received SME_JOIN_REQ with invalid RSNIE");
valid = false;
goto end;
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 6f09ed6777a5..99a96b831c8f 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1002,6 +1002,7 @@ typedef struct csr_roam_profile {
uint32_t hlp_ie_len;
struct cds_fils_connection_info *fils_con_info;
#endif
+ bool force_rsne_override;
} tCsrRoamProfile;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index af73b975b06d..041d6360c2b2 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -8053,6 +8053,7 @@ QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
pDstProfile->dfs_regdomain = pSrcProfile->dfs_regdomain;
pDstProfile->chan_switch_hostapd_rate_enabled =
pSrcProfile->chan_switch_hostapd_rate_enabled;
+ pDstProfile->force_rsne_override = pSrcProfile->force_rsne_override;
end:
if (!QDF_IS_STATUS_SUCCESS(status)) {
csr_release_profile(pMac, pDstProfile);
@@ -14972,6 +14973,8 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
csr_retrieve_rsn_ie(pMac, sessionId, pProfile,
pBssDescription, pIes,
(tCsrRSNIe *) (wpaRsnIE));
+ csr_join_req->force_rsne_override =
+ pProfile->force_rsne_override;
}
#ifdef FEATURE_WLAN_WAPI
else if (csr_is_profile_wapi(pProfile)) {
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
index 48de1fd3bb0d..ea8fd058e276 100644
--- a/core/sme/src/csr/csr_util.c
+++ b/core/sme/src/csr/csr_util.c
@@ -4693,6 +4693,22 @@ uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId,
do {
if (!csr_is_profile_rsn(pProfile))
break;
+ /* copy RSNIE from user as it is if test mode is enabled */
+ if (pProfile->force_rsne_override &&
+ pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
+ sme_debug("force_rsne_override, copy RSN IE provided by user");
+ if (pProfile->nRSNReqIELength <=
+ DOT11F_IE_RSN_MAX_LEN) {
+ cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
+ qdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
+ cbRsnIe);
+ } else {
+ sme_warn("csr_retrieve_rsn_ie detect invalid RSN IE length (%d)",
+ pProfile->nRSNReqIELength);
+ }
+ break;
+ }
+
if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
/* If "Legacy Fast Roaming" is enabled ALWAYS rebuild
* the RSN IE from scratch. So it contains the current