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