mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacmn: Use crypto APIs in scan filter
Use crypto APIs in scan filter to match the security. Change-Id: I8b4d6f6085e3bfcdd8af2b4d9243c27e070cda78 CRs-Fixed: 2718079
This commit is contained in:
parent
168fbbffe7
commit
9cf786a2ab
5 changed files with 638 additions and 57 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue