diff --git a/qdf/inc/qdf_util.h b/qdf/inc/qdf_util.h index 76c88ae0d443..4025e18ff337 100644 --- a/qdf/inc/qdf_util.h +++ b/qdf/inc/qdf_util.h @@ -92,6 +92,10 @@ typedef __qdf_wait_queue_head_t qdf_wait_queue_head_t; */ #define qdf_target_assert_always(expr) __qdf_target_assert(expr) +#define QDF_SET_PARAM(__param, __val) ((__param) |= (1 << (__val))) +#define QDF_HAS_PARAM(__param, __val) ((__param) & (1 << (__val))) +#define QDF_CLEAR_PARAM(__param, __val) ((__param) &= ((~1) << (__val))) + /** * QDF_MAX - get maximum of two values * @_x: 1st argument diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index 82c8231800d9..b06d9ef950d4 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -527,6 +527,7 @@ struct wlan_rsn_ie_hdr { #define WLAN_RSN_IE_MIN_LEN 2 +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 /** * struct wlan_rsn_ie: rsn ie info * @ver: RSN ver @@ -552,7 +553,7 @@ struct wlan_rsn_ie { uint8_t pmkid[MAX_PMKID][PMKID_LEN]; uint32_t mgmt_cipher_suite; }; - +#endif #define WLAN_WAPI_IE_MIN_LEN 20 /** @@ -569,6 +570,7 @@ struct wlan_wpa_ie_hdr { u8 version[2]; }; +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 /** * struct wlan_wpa_ie: WPA ie info * @ver: WPA ver @@ -588,7 +590,7 @@ struct wlan_wpa_ie { uint32_t auth_suites[WLAN_MAX_CIPHER]; uint16_t cap; }; - +#endif #define WAPI_VERSION 1 #define WLAN_WAPI_OUI 0x721400 @@ -597,6 +599,7 @@ struct wlan_wpa_ie { #define WLAN_WAI_CERT_OR_SMS4 0x01 #define WLAN_WAI_PSK 0x02 +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 /** * struct wlan_wapi_ie: WAPI ie info * @ver: WAPI ver @@ -614,7 +617,7 @@ struct wlan_wapi_ie { uint32_t uc_cipher_suites[WLAN_MAX_CIPHER]; uint32_t mc_cipher_suite; }; - +#endif /** * struct wlan_frame_hdr: generic IEEE 802.11 frames * @i_fc: frame control @@ -1549,6 +1552,7 @@ is_sae_single_pmk_oui(uint8_t *frm) ((SAE_SINGLE_PMK_TYPE << OUI_TYPE_BITS) | SAE_SINGLE_PMK_OUI)); } +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 /** * wlan_parse_rsn_ie() - parse rsn ie * @rsn_ie: rsn ie ptr @@ -1864,6 +1868,7 @@ static inline void wlan_parse_wapi_ie(uint8_t *wapi_ie, if (len >= WLAN_OUI_SIZE) wapi->mc_cipher_suite = LE_READ_4(ie); } +#endif /** * wlan_parse_oce_reduced_wan_metrics_ie() - parse oce wan metrics diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h index 37f26c04a212..e01d3364b97d 100644 --- a/umac/cmn_services/inc/wlan_cmn.h +++ b/umac/cmn_services/inc/wlan_cmn.h @@ -572,6 +572,7 @@ enum wlan_pmf_cap { WLAN_PMF_REQUIRED, }; +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 /** * enum wlan_auth_type - Enumeration of the various Auth types * @WLAN_AUTH_TYPE_OPEN_SYSTEM: Open auth type @@ -670,6 +671,7 @@ enum wlan_enc_type { WLAN_ENCRYPT_TYPE_ANY, WLAN_NUM_OF_ENCRYPT_TYPE = WLAN_ENCRYPT_TYPE_ANY, }; +#endif /** * struct wlan_ssid - SSID info diff --git a/umac/scan/core/src/wlan_scan_filter.c b/umac/scan/core/src/wlan_scan_filter.c index 8a4fb9168519..88fdb8aa1346 100644 --- a/umac/scan/core/src/wlan_scan_filter.c +++ b/umac/scan/core/src/wlan_scan_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +23,514 @@ #include "wlan_scan_main.h" #include "wlan_scan_cache_db_i.h" +#ifdef WLAN_SCAN_SECURITY_FILTER_V1 +#include "wlan_crypto_global_def.h" +#include "wlan_crypto_global_api.h" + +/** + * scm_check_open() - Check if scan entry support open authmode + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if open security else false + */ +static bool scm_check_open(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + if (db_entry->cap_info.wlan_caps.privacy) { + scm_debug("%pM : have privacy set", + db_entry->bssid.bytes); + return false; + } + + if (filter->ucastcipherset && + !(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE))) { + scm_debug("%pM : Filter doesn't have CIPHER none in uc %x", + db_entry->bssid.bytes, filter->ucastcipherset); + return false; + } + + if (filter->mcastcipherset && + !(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE))) { + scm_debug("%pM : Filter doesn't have CIPHER none in mc %x", + db_entry->bssid.bytes, filter->mcastcipherset); + return false; + } + + QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE); + QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE); + + return true; +} + +/** + * scm_check_wep() - Check if scan entry support WEP authmode + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if WEP security else false + */ +static bool scm_check_wep(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + /* If privacy bit is not set, consider no match */ + if (!db_entry->cap_info.wlan_caps.privacy) { + scm_debug("%pM : doesn't have privacy set", + db_entry->bssid.bytes); + return false; + } + + if (!(db_entry->security_type & SCAN_SECURITY_TYPE_WEP)) { + scm_debug("%pM : doesn't support WEP", db_entry->bssid.bytes); + return false; + } + + if (!filter->ucastcipherset || !filter->mcastcipherset) { + scm_debug("%pM : Filter uc %x or mc %x cipher are 0", + db_entry->bssid.bytes, filter->ucastcipherset, + filter->mcastcipherset); + return false; + } + + if (!(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) || + QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) || + QDF_HAS_PARAM(filter->ucastcipherset, + WLAN_CRYPTO_CIPHER_WEP_104))) { + scm_debug("%pM : Filter doesn't have WEP cipher in uc %x", + db_entry->bssid.bytes, filter->ucastcipherset); + return false; + } + + if (!(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP) || + QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) || + QDF_HAS_PARAM(filter->mcastcipherset, + WLAN_CRYPTO_CIPHER_WEP_104))) { + scm_debug("%pM : Filter doesn't have WEP cipher in mc %x", + db_entry->bssid.bytes, filter->mcastcipherset); + return false; + } + + if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP)) + QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP); + + if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40)) + QDF_SET_PARAM(security->ucastcipherset, + WLAN_CRYPTO_CIPHER_WEP_40); + + if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)) + QDF_SET_PARAM(security->ucastcipherset, + WLAN_CRYPTO_CIPHER_WEP_104); + + if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP)) + QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP); + + if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40)) + QDF_SET_PARAM(security->mcastcipherset, + WLAN_CRYPTO_CIPHER_WEP_40); + + if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)) + QDF_SET_PARAM(security->mcastcipherset, + WLAN_CRYPTO_CIPHER_WEP_104); + + return true; +} + +/** + * scm_chk_if_cipher_n_akm_match() - Check if akm and ciphers match + * @filter: scan filter + * @ap_crypto: aps crypto params + * + * Return: true if matches + */ +static bool scm_chk_if_cipher_n_akm_match(struct scan_filter *filter, + struct wlan_crypto_params *ap_crypto) +{ + /* Check AP's pairwise ciphers.*/ + if (!(filter->ucastcipherset & ap_crypto->ucastcipherset)) + return false; + + /* Check AP's group cipher match.*/ + if (!(filter->mcastcipherset & ap_crypto->mcastcipherset)) + return false; + + /* Check AP's AKM match with filter's AKM.*/ + if (!(filter->key_mgmt & ap_crypto->key_mgmt)) + return false; + + /* Check AP's mgmt cipher match if present.*/ + if ((filter->mgmtcipherset && ap_crypto->mgmtcipherset) && + !(filter->mgmtcipherset & ap_crypto->mgmtcipherset)) + return false; + + if (filter->ignore_pmf_cap) + return true; + + if (filter->pmf_cap == WLAN_PMF_REQUIRED && + !(ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) + return false; + + if (filter->pmf_cap == WLAN_PMF_DISABLED && + (ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) + return false; + + return true; +} + +static bool scm_chk_crypto_params(struct scan_filter *filter, + struct wlan_crypto_params *ap_crypto, + bool is_adaptive_11r, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) { + scm_debug("%pM: fail. adaptive 11r %d Self: AKM %x CIPHER: mc %x uc %x mgmt %x pmf %d AP: AKM %x CIPHER: mc %x uc %x mgmt %x, RSN caps %x", + db_entry->bssid.bytes, is_adaptive_11r, + filter->key_mgmt, filter->mcastcipherset, + filter->ucastcipherset, filter->mgmtcipherset, + filter->pmf_cap, ap_crypto->key_mgmt, + ap_crypto->mcastcipherset, ap_crypto->ucastcipherset, + ap_crypto->mgmtcipherset, ap_crypto->rsn_caps); + return false; + } + + security->mcastcipherset = + ap_crypto->mcastcipherset & filter->mcastcipherset; + security->ucastcipherset = + ap_crypto->ucastcipherset & filter->ucastcipherset; + security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt; + + return true; +} + +/** + * scm_check_rsn() - Check if scan entry support RSN security + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if RSN security else false + */ +static bool scm_check_rsn(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + bool is_adaptive_11r; + QDF_STATUS status; + struct wlan_crypto_params *ap_crypto; + bool match; + + if (!util_scan_entry_rsn(db_entry)) { + scm_debug("%pM : doesn't have RSN IE", db_entry->bssid.bytes); + return false; + } + + ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); + if (!ap_crypto) + return false; + status = wlan_crypto_rsnie_check(ap_crypto, + util_scan_entry_rsn(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse RSN IE, status %d", + db_entry->bssid.bytes, status); + qdf_mem_free(ap_crypto); + return false; + } + + is_adaptive_11r = db_entry->adaptive_11r_ap && + filter->enable_adaptive_11r; + + /* If adaptive 11r is enabled set the FT AKM for AP */ + if (is_adaptive_11r) { + if (QDF_HAS_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) { + QDF_SET_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X); + } + if (QDF_HAS_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_PSK)) { + QDF_SET_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_FT_PSK); + } + if (QDF_HAS_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) { + QDF_SET_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_FT_PSK); + } + if (QDF_HAS_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) { + QDF_SET_PARAM(ap_crypto->key_mgmt, + WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X); + } + } + + match = scm_chk_crypto_params(filter, ap_crypto, is_adaptive_11r, + db_entry, security); + qdf_mem_free(ap_crypto); + + return match; +} + +/** + * scm_check_wpa() - Check if scan entry support WPA security + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if WPA security else false + */ +static bool scm_check_wpa(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + QDF_STATUS status; + struct wlan_crypto_params *ap_crypto; + bool match; + + if (!util_scan_entry_wpa(db_entry)) { + scm_debug("%pM : doesn't have WPA IE", + db_entry->bssid.bytes); + return false; + } + + ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); + if (!ap_crypto) + return false; + + status = wlan_crypto_wpaie_check(ap_crypto, + util_scan_entry_wpa(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse WPA IE, status %d", + db_entry->bssid.bytes, status); + qdf_mem_free(ap_crypto); + return false; + } + + match = scm_chk_crypto_params(filter, ap_crypto, false, + db_entry, security); + qdf_mem_free(ap_crypto); + + return match; +} + +/** + * scm_check_wapi() - Check if scan entry support WAPI security + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if WAPI security else false + */ +static bool scm_check_wapi(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + QDF_STATUS status; + struct wlan_crypto_params *ap_crypto; + + if (!util_scan_entry_wapi(db_entry)) { + scm_debug("%pM : doesn't have WAPI IE", + db_entry->bssid.bytes); + return false; + } + + ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); + if (!ap_crypto) + return false; + + status = wlan_crypto_wapiie_check(ap_crypto, + util_scan_entry_wapi(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse WAPI IE, status %d", + db_entry->bssid.bytes, status); + qdf_mem_free(ap_crypto); + return false; + } + + if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) { + scm_debug("%pM: fail. Self: AKM %x CIPHER: mc %x uc %x mgmt %x pmf %d AP: AKM %x CIPHER: mc %x uc %x mgmt %x, RSN caps %x", + db_entry->bssid.bytes, filter->key_mgmt, + filter->mcastcipherset, filter->ucastcipherset, + filter->mgmtcipherset, filter->pmf_cap, + ap_crypto->key_mgmt, ap_crypto->mcastcipherset, + ap_crypto->ucastcipherset, ap_crypto->mgmtcipherset, + ap_crypto->rsn_caps); + qdf_mem_free(ap_crypto); + + return false; + } + + security->mcastcipherset = + ap_crypto->mcastcipherset & filter->mcastcipherset; + security->ucastcipherset = + ap_crypto->ucastcipherset & filter->ucastcipherset; + security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt; + qdf_mem_free(ap_crypto); + + return true; +} + +/** + * scm_match_any_security() - Check if any security in filter match + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if any security else false + */ +static bool scm_match_any_security(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + struct wlan_crypto_params *ap_crypto = {0}; + QDF_STATUS status; + bool match = false; + + ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); + if (!ap_crypto) + return match; + + if (util_scan_entry_rsn(db_entry)) { + status = wlan_crypto_rsnie_check(ap_crypto, + util_scan_entry_rsn(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse RSN IE, status %d", + db_entry->bssid.bytes, status); + goto free; + } + security->mcastcipherset = ap_crypto->mcastcipherset; + security->ucastcipherset = ap_crypto->ucastcipherset; + security->key_mgmt = ap_crypto->key_mgmt; + QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_RSNA); + match = true; + goto free; + } + + if (util_scan_entry_wpa(db_entry)) { + status = wlan_crypto_wpaie_check(ap_crypto, + util_scan_entry_wpa(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse WPA IE, status %d", + db_entry->bssid.bytes, status); + goto free; + } + security->mcastcipherset = ap_crypto->mcastcipherset; + security->ucastcipherset = ap_crypto->ucastcipherset; + security->key_mgmt = ap_crypto->key_mgmt; + QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WPA); + match = true; + goto free; + } + + if (util_scan_entry_wapi(db_entry)) { + status = wlan_crypto_wapiie_check(ap_crypto, + util_scan_entry_wapi(db_entry)); + if (QDF_IS_STATUS_ERROR(status)) { + scm_err("%pM: failed to parse WPA IE, status %d", + db_entry->bssid.bytes, status); + goto free; + } + security->mcastcipherset = ap_crypto->mcastcipherset; + security->ucastcipherset = ap_crypto->ucastcipherset; + security->key_mgmt = ap_crypto->key_mgmt; + QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WAPI); + match = true; + goto free; + } + + if (db_entry->cap_info.wlan_caps.privacy) { + QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP); + QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP); + QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_SHARED); + match = true; + goto free; + } + + QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE); + QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE); + QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_OPEN); + match = true; + +free: + qdf_mem_free(ap_crypto); + + return match; +} + +/** + * scm_is_security_match() - Check if security in filter match + * @filter: scan filter + * @db_entry: db entry + * @security: matched security. + * + * Return: true if security match else false + */ +static bool scm_is_security_match(struct scan_filter *filter, + struct scan_cache_entry *db_entry, + struct security_info *security) +{ + int i; + bool match = false; + + if (!filter->authmodeset) + return scm_match_any_security(filter, db_entry, security); + + for (i = 0; i <= WLAN_CRYPTO_AUTH_MAX && !match; i++) { + if (!QDF_HAS_PARAM(filter->authmodeset, i)) + continue; + + security->authmodeset = 0; + QDF_SET_PARAM(security->authmodeset, i); + + switch (i) { + case WLAN_CRYPTO_AUTH_NONE: + case WLAN_CRYPTO_AUTH_OPEN: + case WLAN_CRYPTO_AUTH_AUTO: + match = scm_check_open(filter, db_entry, security); + if (match) + break; + /* If not OPEN, then check WEP match so fall through */ + case WLAN_CRYPTO_AUTH_SHARED: + match = scm_check_wep(filter, db_entry, security); + break; + case WLAN_CRYPTO_AUTH_8021X: + case WLAN_CRYPTO_AUTH_RSNA: + case WLAN_CRYPTO_AUTH_CCKM: + case WLAN_CRYPTO_AUTH_SAE: + case WLAN_CRYPTO_AUTH_FILS_SK: + /* First check if there is a RSN match */ + match = scm_check_rsn(filter, db_entry, security); + break; + case WLAN_CRYPTO_AUTH_WPA: + match = scm_check_wpa(filter, db_entry, security); + break; + case WLAN_CRYPTO_AUTH_WAPI:/* WAPI */ + match = scm_check_wapi(filter, db_entry, security); + break; + default: + break; + } + } + + return match; +} + +static bool scm_ignore_ssid_check_for_owe(struct scan_filter *filter, + struct scan_cache_entry *db_entry) +{ + if (util_scan_entry_is_hidden_ap(db_entry) && + QDF_HAS_PARAM(filter->key_mgmt, WLAN_CRYPTO_KEY_MGMT_OWE) && + util_is_bssid_match(&filter->bssid_hint, &db_entry->bssid)) + return true; + + return false; +} + +#else + /** * scm_is_open_security() - Check if scan entry support open security * @filter: scan filter @@ -1021,51 +1529,6 @@ static bool scm_is_def_security(struct scan_filter *filter, return true; } -/** - * scm_is_fils_config_match() - Check if FILS config matches - * @filter: scan filter - * @db_entry: db entry - * - * Return: true if FILS config matches else false - */ -static bool scm_is_fils_config_match(struct scan_filter *filter, - struct scan_cache_entry *db_entry) -{ - int i; - struct fils_indication_ie *indication_ie; - uint8_t *data; - - if (!filter->fils_scan_filter.realm_check) - return true; - - if (!db_entry->ie_list.fils_indication) - return false; - - - indication_ie = - (struct fils_indication_ie *) db_entry->ie_list.fils_indication; - - data = indication_ie->variable_data; - if (indication_ie->is_cache_id_present) - data += CACHE_IDENTIFIER_LEN; - - if (indication_ie->is_hessid_present) - data += HESSID_LEN; - - for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) { - if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm, - data, REAM_HASH_LEN)) - return true; - /* Max realm count reached */ - if (indication_ie->realm_identifiers_cnt == i) - break; - else - data = data + REAM_HASH_LEN; - } - - return false; -} - /** * scm_is_security_match() - Check if security in filter match * @filter: scan filter @@ -1133,6 +1596,80 @@ static bool scm_is_security_match(struct scan_filter *filter, return match; } +static bool scm_ignore_ssid_check_for_owe(struct scan_filter *filter, + struct scan_cache_entry *db_entry) +{ + int i; + + if (util_scan_entry_is_hidden_ap(db_entry)) { + for (i = 0; i < filter->num_of_auth; i++) { + if (filter->auth_type[i] == WLAN_AUTH_TYPE_OWE && + util_is_bssid_match(&filter->bssid_hint, + &db_entry->bssid)) { + return true; + } + } + } + + return false; +} +#endif + +#ifdef WLAN_FEATURE_FILS_SK +/** + * scm_is_fils_config_match() - Check if FILS config matches + * @filter: scan filter + * @db_entry: db entry + * + * Return: true if FILS config matches else false + */ +static bool scm_is_fils_config_match(struct scan_filter *filter, + struct scan_cache_entry *db_entry) +{ + int i; + struct fils_indication_ie *indication_ie; + uint8_t *data; + + if (!filter->fils_scan_filter.realm_check) + return true; + + if (!db_entry->ie_list.fils_indication) + return false; + + indication_ie = + (struct fils_indication_ie *)db_entry->ie_list.fils_indication; + + data = indication_ie->variable_data; + if (indication_ie->is_cache_id_present) + data += CACHE_IDENTIFIER_LEN; + + if (indication_ie->is_hessid_present) + data += HESSID_LEN; + + for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) { + if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm, + data, REAM_HASH_LEN)) + return true; + /* Max realm count reached */ + if (indication_ie->realm_identifiers_cnt == i) + break; + + data = data + REAM_HASH_LEN; + } + + return false; +} + +#else + +static inline bool scm_is_fils_config_match(struct scan_filter *filter, + struct scan_cache_entry *db_entry) +{ + return true; +} +#endif + + bool scm_filter_match(struct wlan_objmgr_psoc *psoc, struct scan_cache_entry *db_entry, struct scan_filter *filter, @@ -1168,14 +1705,9 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc, * scan with specific ssid prior to connect as in other hidden ssid * cases. Add explicit check to allow OWE when ssid is hidden. */ - if (!match && util_scan_entry_is_hidden_ap(db_entry)) { - for (i = 0; i < filter->num_of_auth; i++) { - if (filter->auth_type[i] == WLAN_AUTH_TYPE_OWE) { - match = true; - break; - } - } - } + if (!match) + match = scm_ignore_ssid_check_for_owe(filter, db_entry); + if (!match && filter->num_of_ssid) return false; diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 0c212ef68589..0050fde9ba36 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -230,10 +230,29 @@ struct scan_cache_node { struct scan_cache_entry *entry; }; +/** + * struct security_info - Scan cache security info + * @authmodeset: auth mode + * @key_mgmt: key management + * @ucastcipherset: unicast cipher set + * @mcastcipherset: multicast cipher set + * @mgmtcipherset: mgmt cipher set + * @uc_enc: unicast cipher + * @mc_enc: multicast cipher + * @auth_type: key management + */ struct security_info { +#ifdef WLAN_SCAN_SECURITY_FILTER_V1 + uint32_t authmodeset; + uint32_t key_mgmt; + uint32_t ucastcipherset; + uint32_t mcastcipherset; + uint32_t mgmtcipherset; +#else enum wlan_enc_type uc_enc; enum wlan_enc_type mc_enc; enum wlan_auth_type auth_type; +#endif }; /** @@ -435,6 +454,7 @@ struct scan_cache_entry { #define CACHE_IDENTIFIER_LEN 2 #define HESSID_LEN 6 +#ifdef WLAN_FEATURE_FILS_SK /** * struct fils_filter_info: FILS info present in scan filter * @realm_check: whether realm check is required @@ -446,6 +466,7 @@ struct fils_filter_info { uint8_t fils_realm[REAM_HASH_LEN]; uint8_t security_type; }; +#endif /** * struct scan_filter: scan filter @@ -476,6 +497,11 @@ struct fils_filter_info { * @bssid_list: bssid list * @ssid_list: ssid list * @chan_freq_list: channel frequency list, frequency unit: MHz + * @authmodeset: auth mode + * @key_mgmt: key management + * @ucastcipherset: unicast cipher set + * @mcastcipherset: multicast cipher set + * @mgmtcipherset: mgmt cipher set * @auth_type: auth type list * @enc_type: unicast enc type list * @mc_enc_type: multicast cast enc type list @@ -490,9 +516,11 @@ struct scan_filter { uint32_t num_of_bssid; uint32_t num_of_ssid; uint32_t num_of_channels; +#ifndef WLAN_SCAN_SECURITY_FILTER_V1 uint32_t num_of_auth; uint32_t num_of_enc_type; uint32_t num_of_mc_enc_type; +#endif enum wlan_pmf_cap pmf_cap; bool ignore_pmf_cap; enum wlan_bss_type bss_type; @@ -507,10 +535,20 @@ struct scan_filter { struct qdf_mac_addr bssid_list[WLAN_SCAN_FILTER_NUM_BSSID]; struct wlan_ssid ssid_list[WLAN_SCAN_FILTER_NUM_SSID]; uint32_t chan_freq_list[NUM_CHANNELS]; +#ifdef WLAN_SCAN_SECURITY_FILTER_V1 + uint32_t authmodeset; + uint32_t key_mgmt; + uint32_t ucastcipherset; + uint32_t mcastcipherset; + uint32_t mgmtcipherset; +#else enum wlan_auth_type auth_type[WLAN_NUM_OF_SUPPORT_AUTH_TYPE]; enum wlan_enc_type enc_type[WLAN_NUM_OF_ENCRYPT_TYPE]; enum wlan_enc_type mc_enc_type[WLAN_NUM_OF_ENCRYPT_TYPE]; +#endif +#ifdef WLAN_FEATURE_FILS_SK struct fils_filter_info fils_scan_filter; +#endif struct qdf_mac_addr bssid_hint; };