xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c (revision 878d42c770e8f4f39f616b20412de44faeced7b9)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * DOC: contains scan cache filter logic
20  */
21 
22 #include <wlan_scan_utils_api.h>
23 #include "wlan_scan_main.h"
24 #include "wlan_scan_cache_db_i.h"
25 #include <wlan_dfs_utils_api.h>
26 #include "wlan_crypto_global_def.h"
27 #include "wlan_crypto_global_api.h"
28 
29 /**
30  * scm_check_open() - Check if scan entry support open authmode
31  * @filter: scan filter
32  * @db_entry: db entry
33  * @security: matched security.
34  *
35  * Return: true if open security else false
36  */
37 static bool scm_check_open(struct scan_filter *filter,
38 			   struct scan_cache_entry *db_entry,
39 			   struct security_info *security)
40 {
41 	if (db_entry->cap_info.wlan_caps.privacy) {
42 		scm_debug(QDF_MAC_ADDR_FMT" : have privacy set",
43 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
44 		return false;
45 	}
46 
47 	if (filter->ucastcipherset &&
48 	   !(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE))) {
49 		scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in uc %x",
50 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
51 			  filter->ucastcipherset);
52 		return false;
53 	}
54 
55 	if (filter->mcastcipherset &&
56 	   !(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE))) {
57 		scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in mc %x",
58 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
59 			  filter->mcastcipherset);
60 		return false;
61 	}
62 
63 	QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE);
64 	QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE);
65 
66 	return true;
67 }
68 
69 /**
70  * scm_check_wep() - Check if scan entry support WEP authmode
71  * @filter: scan filter
72  * @db_entry: db entry
73  * @security: matched security.
74  *
75  * Return: true if WEP security else false
76  */
77 static bool scm_check_wep(struct scan_filter *filter,
78 			  struct scan_cache_entry *db_entry,
79 			  struct security_info *security)
80 {
81 	/* If privacy bit is not set, consider no match */
82 	if (!db_entry->cap_info.wlan_caps.privacy) {
83 		scm_debug(QDF_MAC_ADDR_FMT" : doesn't have privacy set",
84 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
85 		return false;
86 	}
87 
88 	if (!(db_entry->security_type & SCAN_SECURITY_TYPE_WEP)) {
89 		scm_debug(QDF_MAC_ADDR_FMT" : doesn't support WEP",
90 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
91 		return false;
92 	}
93 
94 	if (!filter->ucastcipherset || !filter->mcastcipherset) {
95 		scm_debug(QDF_MAC_ADDR_FMT" : Filter uc %x or mc %x cipher are 0",
96 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
97 			  filter->ucastcipherset,
98 			  filter->mcastcipherset);
99 		return false;
100 	}
101 
102 	if (!(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
103 	     QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
104 	     QDF_HAS_PARAM(filter->ucastcipherset,
105 			   WLAN_CRYPTO_CIPHER_WEP_104))) {
106 		scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in uc %x",
107 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
108 			  filter->ucastcipherset);
109 		return false;
110 	}
111 
112 	if (!(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
113 	     QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
114 	     QDF_HAS_PARAM(filter->mcastcipherset,
115 			   WLAN_CRYPTO_CIPHER_WEP_104))) {
116 		scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in mc %x",
117 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
118 			  filter->mcastcipherset);
119 		return false;
120 	}
121 
122 	if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP))
123 		QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP);
124 
125 	if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40))
126 		QDF_SET_PARAM(security->ucastcipherset,
127 			      WLAN_CRYPTO_CIPHER_WEP_40);
128 
129 	if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104))
130 		QDF_SET_PARAM(security->ucastcipherset,
131 			      WLAN_CRYPTO_CIPHER_WEP_104);
132 
133 	if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP))
134 		QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP);
135 
136 	if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40))
137 		QDF_SET_PARAM(security->mcastcipherset,
138 			      WLAN_CRYPTO_CIPHER_WEP_40);
139 
140 	if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_104))
141 		QDF_SET_PARAM(security->mcastcipherset,
142 			      WLAN_CRYPTO_CIPHER_WEP_104);
143 
144 	return true;
145 }
146 
147 /**
148  * scm_chk_if_cipher_n_akm_match() - Check if akm and ciphers match
149  * @filter: scan filter
150  * @ap_crypto: aps crypto params
151  *
152  * Return: true if matches
153  */
154 static bool scm_chk_if_cipher_n_akm_match(struct scan_filter *filter,
155 					  struct wlan_crypto_params *ap_crypto)
156 {
157 	/* Check AP's pairwise ciphers.*/
158 	if (!(filter->ucastcipherset & ap_crypto->ucastcipherset))
159 		return false;
160 
161 	/* Check AP's group cipher match.*/
162 	if (!(filter->mcastcipherset & ap_crypto->mcastcipherset))
163 		return false;
164 
165 	/* Check AP's AKM match with filter's AKM.*/
166 	if (!(filter->key_mgmt & ap_crypto->key_mgmt))
167 		return false;
168 
169 	/* Check AP's mgmt cipher match if present.*/
170 	if ((filter->mgmtcipherset && ap_crypto->mgmtcipherset) &&
171 	    !(filter->mgmtcipherset & ap_crypto->mgmtcipherset))
172 		return false;
173 
174 	if (filter->ignore_pmf_cap)
175 		return true;
176 
177 	if (filter->pmf_cap == WLAN_PMF_REQUIRED &&
178 	    !(ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
179 		return false;
180 
181 	if (filter->pmf_cap == WLAN_PMF_DISABLED &&
182 	    (ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED))
183 		return false;
184 
185 	return true;
186 }
187 
188 static bool scm_chk_crypto_params(struct scan_filter *filter,
189 				  struct wlan_crypto_params *ap_crypto,
190 				  bool is_adaptive_11r,
191 				  struct scan_cache_entry *db_entry,
192 				  struct security_info *security)
193 {
194 	if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) {
195 		scm_debug(QDF_MAC_ADDR_FMT": 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",
196 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes), is_adaptive_11r,
197 			  filter->key_mgmt, filter->mcastcipherset,
198 			  filter->ucastcipherset, filter->mgmtcipherset,
199 			  filter->pmf_cap, ap_crypto->key_mgmt,
200 			  ap_crypto->mcastcipherset, ap_crypto->ucastcipherset,
201 			  ap_crypto->mgmtcipherset, ap_crypto->rsn_caps);
202 		return false;
203 	}
204 
205 	security->mcastcipherset =
206 		ap_crypto->mcastcipherset & filter->mcastcipherset;
207 	security->ucastcipherset =
208 		ap_crypto->ucastcipherset & filter->ucastcipherset;
209 	security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt;
210 	security->rsn_caps = ap_crypto->rsn_caps;
211 
212 	return true;
213 }
214 
215 /**
216  * scm_check_rsn() - Check if scan entry support RSN security
217  * @filter: scan filter
218  * @db_entry: db entry
219  * @security: matched security.
220  *
221  * Return: true if RSN security else false
222  */
223 static bool scm_check_rsn(struct scan_filter *filter,
224 			  struct scan_cache_entry *db_entry,
225 			  struct security_info *security)
226 {
227 	bool is_adaptive_11r;
228 	QDF_STATUS status;
229 	struct wlan_crypto_params *ap_crypto;
230 	bool match;
231 
232 	if (!util_scan_entry_rsn(db_entry)) {
233 		scm_debug(QDF_MAC_ADDR_FMT" : doesn't have RSN IE",
234 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
235 		return false;
236 	}
237 
238 	ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
239 	if (!ap_crypto)
240 		return false;
241 	status = wlan_crypto_rsnie_check(ap_crypto,
242 					 util_scan_entry_rsn(db_entry));
243 	if (QDF_IS_STATUS_ERROR(status)) {
244 		scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN IE, status %d",
245 			QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
246 		qdf_mem_free(ap_crypto);
247 		return false;
248 	}
249 
250 	is_adaptive_11r = db_entry->adaptive_11r_ap &&
251 				filter->enable_adaptive_11r;
252 
253 	/* If adaptive 11r is enabled set the FT AKM for AP */
254 	if (is_adaptive_11r) {
255 		if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
256 				  WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
257 			QDF_SET_PARAM(ap_crypto->key_mgmt,
258 				      WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X);
259 		}
260 		if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
261 				  WLAN_CRYPTO_KEY_MGMT_PSK)) {
262 			QDF_SET_PARAM(ap_crypto->key_mgmt,
263 				      WLAN_CRYPTO_KEY_MGMT_FT_PSK);
264 		}
265 		if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
266 				  WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) {
267 			QDF_SET_PARAM(ap_crypto->key_mgmt,
268 				      WLAN_CRYPTO_KEY_MGMT_FT_PSK);
269 		}
270 		if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
271 				  WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) {
272 			QDF_SET_PARAM(ap_crypto->key_mgmt,
273 				      WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X);
274 		}
275 	}
276 
277 	match = scm_chk_crypto_params(filter, ap_crypto, is_adaptive_11r,
278 				      db_entry, security);
279 	qdf_mem_free(ap_crypto);
280 
281 	return match;
282 }
283 
284 /**
285  * scm_check_wpa() - Check if scan entry support WPA security
286  * @filter: scan filter
287  * @db_entry: db entry
288  * @security: matched security.
289  *
290  * Return: true if WPA security else false
291  */
292 static bool scm_check_wpa(struct scan_filter *filter,
293 			  struct scan_cache_entry *db_entry,
294 			  struct security_info *security)
295 {
296 	QDF_STATUS status;
297 	struct wlan_crypto_params *ap_crypto;
298 	bool match;
299 
300 	if (!util_scan_entry_wpa(db_entry)) {
301 		scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WPA IE",
302 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
303 		return false;
304 	}
305 
306 	ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
307 	if (!ap_crypto)
308 		return false;
309 
310 	status = wlan_crypto_wpaie_check(ap_crypto,
311 					 util_scan_entry_wpa(db_entry));
312 	if (QDF_IS_STATUS_ERROR(status)) {
313 		scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
314 			QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
315 		qdf_mem_free(ap_crypto);
316 		return false;
317 	}
318 
319 	match = scm_chk_crypto_params(filter, ap_crypto, false,
320 				      db_entry, security);
321 	qdf_mem_free(ap_crypto);
322 
323 	return match;
324 }
325 
326 /**
327  * scm_check_wapi() - Check if scan entry support WAPI security
328  * @filter: scan filter
329  * @db_entry: db entry
330  * @security: matched security.
331  *
332  * Return: true if WAPI security else false
333  */
334 static bool scm_check_wapi(struct scan_filter *filter,
335 			   struct scan_cache_entry *db_entry,
336 			   struct security_info *security)
337 {
338 	QDF_STATUS status;
339 	struct wlan_crypto_params *ap_crypto;
340 
341 	if (!util_scan_entry_wapi(db_entry)) {
342 		scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WAPI IE",
343 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
344 		return false;
345 	}
346 
347 	ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
348 	if (!ap_crypto)
349 		return false;
350 
351 	status = wlan_crypto_wapiie_check(ap_crypto,
352 					  util_scan_entry_wapi(db_entry));
353 	if (QDF_IS_STATUS_ERROR(status)) {
354 		scm_err(QDF_MAC_ADDR_FMT": failed to parse WAPI IE, status %d",
355 			QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
356 		qdf_mem_free(ap_crypto);
357 		return false;
358 	}
359 
360 	if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) {
361 		scm_debug(QDF_MAC_ADDR_FMT": 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",
362 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes), filter->key_mgmt,
363 			  filter->mcastcipherset, filter->ucastcipherset,
364 			  filter->mgmtcipherset, filter->pmf_cap,
365 			  ap_crypto->key_mgmt, ap_crypto->mcastcipherset,
366 			  ap_crypto->ucastcipherset, ap_crypto->mgmtcipherset,
367 			  ap_crypto->rsn_caps);
368 		qdf_mem_free(ap_crypto);
369 
370 		return false;
371 	}
372 
373 	security->mcastcipherset =
374 		ap_crypto->mcastcipherset & filter->mcastcipherset;
375 	security->ucastcipherset =
376 		ap_crypto->ucastcipherset & filter->ucastcipherset;
377 	security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt;
378 	security->rsn_caps = ap_crypto->rsn_caps;
379 	qdf_mem_free(ap_crypto);
380 
381 	return true;
382 }
383 
384 /**
385  * scm_match_any_security() - Check if any security in filter match
386  * @filter: scan filter
387  * @db_entry: db entry
388  * @security: matched security.
389  *
390  * Return: true if any security else false
391  */
392 static bool scm_match_any_security(struct scan_filter *filter,
393 				   struct scan_cache_entry *db_entry,
394 				   struct security_info *security)
395 {
396 	struct wlan_crypto_params *ap_crypto = {0};
397 	QDF_STATUS status;
398 	bool match = false;
399 
400 	ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
401 	if (!ap_crypto)
402 		return match;
403 
404 	if (util_scan_entry_rsn(db_entry)) {
405 		status = wlan_crypto_rsnie_check(ap_crypto,
406 						 util_scan_entry_rsn(db_entry));
407 		if (QDF_IS_STATUS_ERROR(status)) {
408 			scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN IE, status %d",
409 				QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
410 			goto free;
411 		}
412 		security->mcastcipherset = ap_crypto->mcastcipherset;
413 		security->ucastcipherset = ap_crypto->ucastcipherset;
414 		security->key_mgmt = ap_crypto->key_mgmt;
415 		security->rsn_caps = ap_crypto->rsn_caps;
416 		QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_RSNA);
417 		match = true;
418 		goto free;
419 	}
420 
421 	if (util_scan_entry_wpa(db_entry)) {
422 		status = wlan_crypto_wpaie_check(ap_crypto,
423 						 util_scan_entry_wpa(db_entry));
424 		if (QDF_IS_STATUS_ERROR(status)) {
425 			scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
426 				QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
427 			goto free;
428 		}
429 		security->mcastcipherset = ap_crypto->mcastcipherset;
430 		security->ucastcipherset = ap_crypto->ucastcipherset;
431 		security->key_mgmt = ap_crypto->key_mgmt;
432 		security->rsn_caps = ap_crypto->rsn_caps;
433 		QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WPA);
434 		match = true;
435 		goto free;
436 	}
437 
438 	if (util_scan_entry_wapi(db_entry)) {
439 		status = wlan_crypto_wapiie_check(ap_crypto,
440 						util_scan_entry_wapi(db_entry));
441 		if (QDF_IS_STATUS_ERROR(status)) {
442 			scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
443 				QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
444 				status);
445 			goto free;
446 		}
447 		security->mcastcipherset = ap_crypto->mcastcipherset;
448 		security->ucastcipherset = ap_crypto->ucastcipherset;
449 		security->key_mgmt = ap_crypto->key_mgmt;
450 		security->rsn_caps = ap_crypto->rsn_caps;
451 		QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WAPI);
452 		match = true;
453 		goto free;
454 	}
455 
456 	if (db_entry->cap_info.wlan_caps.privacy) {
457 		QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP);
458 		QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP);
459 		QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_SHARED);
460 		match = true;
461 		goto free;
462 	}
463 
464 	QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE);
465 	QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE);
466 	QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_OPEN);
467 	match = true;
468 
469 free:
470 	qdf_mem_free(ap_crypto);
471 
472 	return match;
473 }
474 
475 /**
476  * scm_is_security_match() - Check if security in filter match
477  * @filter: scan filter
478  * @db_entry: db entry
479  * @security: matched security.
480  *
481  * Return: true if security match else false
482  */
483 static bool scm_is_security_match(struct scan_filter *filter,
484 				  struct scan_cache_entry *db_entry,
485 				  struct security_info *security)
486 {
487 	int i;
488 	bool match = false;
489 
490 	if (!filter->authmodeset)
491 		return scm_match_any_security(filter, db_entry, security);
492 
493 	for (i = 0; i <= WLAN_CRYPTO_AUTH_MAX && !match; i++) {
494 		if (!QDF_HAS_PARAM(filter->authmodeset, i))
495 			continue;
496 
497 		security->authmodeset = 0;
498 		QDF_SET_PARAM(security->authmodeset, i);
499 
500 		switch (i) {
501 		case WLAN_CRYPTO_AUTH_NONE:
502 		case WLAN_CRYPTO_AUTH_OPEN:
503 		case WLAN_CRYPTO_AUTH_AUTO:
504 			match = scm_check_open(filter, db_entry, security);
505 			if (match)
506 				break;
507 		/* If not OPEN, then check WEP match */
508 		/* fallthrough */
509 		case WLAN_CRYPTO_AUTH_SHARED:
510 			match = scm_check_wep(filter, db_entry, security);
511 			break;
512 		case WLAN_CRYPTO_AUTH_8021X:
513 		case WLAN_CRYPTO_AUTH_RSNA:
514 		case WLAN_CRYPTO_AUTH_CCKM:
515 		case WLAN_CRYPTO_AUTH_SAE:
516 		case WLAN_CRYPTO_AUTH_FILS_SK:
517 			/* First check if there is a RSN match */
518 			match = scm_check_rsn(filter, db_entry, security);
519 			break;
520 		case WLAN_CRYPTO_AUTH_WPA:
521 			match = scm_check_wpa(filter, db_entry, security);
522 			break;
523 		case WLAN_CRYPTO_AUTH_WAPI:/* WAPI */
524 			match = scm_check_wapi(filter, db_entry, security);
525 			break;
526 		default:
527 			break;
528 		}
529 	}
530 
531 	return match;
532 }
533 
534 static bool scm_ignore_ssid_check_for_owe(struct scan_filter *filter,
535 					  struct scan_cache_entry *db_entry)
536 {
537 	if (util_scan_entry_is_hidden_ap(db_entry) &&
538 	    QDF_HAS_PARAM(filter->key_mgmt, WLAN_CRYPTO_KEY_MGMT_OWE) &&
539 	    util_is_bssid_match(&filter->bssid_hint, &db_entry->bssid))
540 		return true;
541 
542 	return false;
543 }
544 
545 #ifdef WLAN_FEATURE_FILS_SK
546 /**
547  * scm_is_fils_config_match() - Check if FILS config matches
548  * @filter: scan filter
549  * @db_entry: db entry
550  *
551  * Return: true if FILS config matches else false
552  */
553 static bool scm_is_fils_config_match(struct scan_filter *filter,
554 				     struct scan_cache_entry *db_entry)
555 {
556 	int i;
557 	struct fils_indication_ie *indication_ie;
558 	uint8_t *data;
559 	uint8_t *end_ptr;
560 
561 	if (!filter->fils_scan_filter.realm_check)
562 		return true;
563 
564 	if (!db_entry->ie_list.fils_indication)
565 		return false;
566 
567 	indication_ie =
568 		(struct fils_indication_ie *)db_entry->ie_list.fils_indication;
569 
570 	end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2;
571 	data = indication_ie->variable_data;
572 
573 	if (indication_ie->is_cache_id_present &&
574 	    (data + CACHE_IDENTIFIER_LEN) <= end_ptr)
575 		data += CACHE_IDENTIFIER_LEN;
576 
577 	if (indication_ie->is_hessid_present &&
578 	    (data + HESSID_LEN) <= end_ptr)
579 		data += HESSID_LEN;
580 
581 	for (i = 1; i <= indication_ie->realm_identifiers_cnt &&
582 	     (data + REALM_HASH_LEN) <= end_ptr; i++) {
583 		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
584 				 data, REALM_HASH_LEN))
585 			return true;
586 		/* Max realm count reached */
587 		if (indication_ie->realm_identifiers_cnt == i)
588 			break;
589 
590 		data = data + REALM_HASH_LEN;
591 	}
592 
593 	return false;
594 }
595 
596 #else
597 
598 static inline bool scm_is_fils_config_match(struct scan_filter *filter,
599 					    struct scan_cache_entry *db_entry)
600 {
601 	return true;
602 }
603 #endif
604 
605 static bool scm_check_dot11mode(struct scan_cache_entry *db_entry,
606 				struct scan_filter *filter)
607 {
608 	switch (filter->dot11mode) {
609 	case ALLOW_ALL:
610 		break;
611 	case ALLOW_11N_ONLY:
612 		if (!util_scan_entry_htcap(db_entry)) {
613 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(HT only) didn't match",
614 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
615 			return false;
616 		}
617 		break;
618 	case ALLOW_11AC_ONLY:
619 		if (!util_scan_entry_vhtcap(db_entry)) {
620 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(VHT only) didn't match",
621 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
622 			return false;
623 		}
624 		break;
625 	case ALLOW_11AX_ONLY:
626 		if (!util_scan_entry_hecap(db_entry)) {
627 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(HE only) didn't match",
628 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
629 			return false;
630 		}
631 		break;
632 	default:
633 		scm_debug("Invalid dot11mode filter passed %d",
634 			  filter->dot11mode);
635 	}
636 
637 	return true;
638 }
639 
640 bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
641 		      struct scan_cache_entry *db_entry,
642 		      struct scan_filter *filter,
643 		      struct security_info *security)
644 {
645 	int i;
646 	bool match = false;
647 	struct scan_default_params *def_param;
648 	struct wlan_objmgr_pdev *pdev;
649 
650 	def_param = wlan_scan_psoc_get_def_params(psoc);
651 	if (!def_param)
652 		return false;
653 
654 	if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter))
655 		return false;
656 
657 	if (filter->ignore_6ghz_channel &&
658 	    WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq))
659 		return false;
660 
661 	if (filter->age_threshold && filter->age_threshold <
662 					util_scan_entry_age(db_entry))
663 		return false;
664 
665 	if (db_entry->ssid.length) {
666 		for (i = 0; i < filter->num_of_ssid; i++) {
667 			if (util_is_ssid_match(&filter->ssid_list[i],
668 			   &db_entry->ssid)) {
669 				match = true;
670 				break;
671 			}
672 		}
673 	}
674 	/*
675 	 * In OWE transition mode, ssid is hidden. And supplicant does not issue
676 	 * scan with specific ssid prior to connect as in other hidden ssid
677 	 * cases. Add explicit check to allow OWE when ssid is hidden.
678 	 */
679 	if (!match)
680 		match = scm_ignore_ssid_check_for_owe(filter, db_entry);
681 
682 	if (!match && filter->num_of_ssid)
683 		return false;
684 
685 	match = false;
686 	/* TO do Fill p2p MAC*/
687 	for (i = 0; i < filter->num_of_bssid; i++) {
688 		if (util_is_bssid_match(&filter->bssid_list[i],
689 		   &db_entry->bssid)) {
690 			match = true;
691 			break;
692 		}
693 		/* TODO match p2p mac */
694 	}
695 	if (!match && filter->num_of_bssid)
696 		return false;
697 
698 	pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id,
699 					  WLAN_SCAN_ID);
700 	if (!pdev) {
701 		scm_err("Invalid pdev");
702 		return false;
703 	}
704 
705 	if (filter->ignore_nol_chan &&
706 	    utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) {
707 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
708 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as chan in NOL list",
709 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
710 		return false;
711 	}
712 	wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
713 
714 	match = false;
715 	for (i = 0; i < filter->num_of_channels; i++) {
716 		if (!filter->chan_freq_list[i] ||
717 		    filter->chan_freq_list[i] ==
718 		    db_entry->channel.chan_freq) {
719 			match = true;
720 			break;
721 		}
722 	}
723 
724 	if (!match && filter->num_of_channels)
725 		return false;
726 
727 	if (filter->rrm_measurement_filter)
728 		return true;
729 
730 	if (!filter->ignore_auth_enc_type && !filter->match_security_func &&
731 	    !scm_is_security_match(filter, db_entry, security)) {
732 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as security profile didn't match",
733 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
734 		return false;
735 	}
736 
737 	if (filter->match_security_func &&
738 	    !filter->match_security_func(filter->match_security_func_arg,
739 					 db_entry)) {
740 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as custom security match failed",
741 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
742 		return false;
743 	}
744 
745 	if (filter->ccx_validate_bss &&
746 	    !filter->ccx_validate_bss(filter->ccx_validate_bss_arg,
747 				      db_entry, 0)) {
748 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as CCX validateion failed",
749 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
750 		return false;
751 	}
752 
753 	/* Match realm */
754 	if (!scm_is_fils_config_match(filter, db_entry)) {
755 		scm_debug(QDF_MAC_ADDR_FMT" :Ignore as fils config didn't match",
756 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
757 		return false;
758 	}
759 
760 	if (!util_mdie_match(filter->mobility_domain,
761 	   (struct rsn_mdie *)db_entry->ie_list.mdie)) {
762 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as mdie didn't match",
763 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
764 		return false;
765 	}
766 	return true;
767 }
768