xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2017-2020 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 
560 	if (!filter->fils_scan_filter.realm_check)
561 		return true;
562 
563 	if (!db_entry->ie_list.fils_indication)
564 		return false;
565 
566 	indication_ie =
567 		(struct fils_indication_ie *)db_entry->ie_list.fils_indication;
568 
569 	data = indication_ie->variable_data;
570 	if (indication_ie->is_cache_id_present)
571 		data += CACHE_IDENTIFIER_LEN;
572 
573 	if (indication_ie->is_hessid_present)
574 		data += HESSID_LEN;
575 
576 	for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) {
577 		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
578 				 data, REALM_HASH_LEN))
579 			return true;
580 		/* Max realm count reached */
581 		if (indication_ie->realm_identifiers_cnt == i)
582 			break;
583 
584 		data = data + REALM_HASH_LEN;
585 	}
586 
587 	return false;
588 }
589 
590 #else
591 
592 static inline bool scm_is_fils_config_match(struct scan_filter *filter,
593 					    struct scan_cache_entry *db_entry)
594 {
595 	return true;
596 }
597 #endif
598 
599 static bool scm_check_dot11mode(struct scan_cache_entry *db_entry,
600 				struct scan_filter *filter)
601 {
602 	switch (filter->dot11mode) {
603 	case ALLOW_ALL:
604 		break;
605 	case ALLOW_11N_ONLY:
606 		if (!util_scan_entry_htcap(db_entry)) {
607 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(HT only) didn't match",
608 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
609 			return false;
610 		}
611 		break;
612 	case ALLOW_11AC_ONLY:
613 		if (!util_scan_entry_vhtcap(db_entry)) {
614 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(VHT only) didn't match",
615 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
616 			return false;
617 		}
618 		break;
619 	case ALLOW_11AX_ONLY:
620 		if (!util_scan_entry_hecap(db_entry)) {
621 			scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode(HE only) didn't match",
622 				  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
623 			return false;
624 		}
625 		break;
626 	default:
627 		scm_debug("Invalid dot11mode filter passed %d",
628 			  filter->dot11mode);
629 	}
630 
631 	return true;
632 }
633 
634 bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
635 		      struct scan_cache_entry *db_entry,
636 		      struct scan_filter *filter,
637 		      struct security_info *security)
638 {
639 	int i;
640 	bool match = false;
641 	struct scan_default_params *def_param;
642 	struct wlan_objmgr_pdev *pdev;
643 
644 	def_param = wlan_scan_psoc_get_def_params(psoc);
645 	if (!def_param)
646 		return false;
647 
648 	if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter))
649 		return false;
650 
651 	if (filter->ignore_6ghz_channel &&
652 	    WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq))
653 		return false;
654 
655 	if (filter->age_threshold && filter->age_threshold <
656 					util_scan_entry_age(db_entry))
657 		return false;
658 
659 	if (db_entry->ssid.length) {
660 		for (i = 0; i < filter->num_of_ssid; i++) {
661 			if (util_is_ssid_match(&filter->ssid_list[i],
662 			   &db_entry->ssid)) {
663 				match = true;
664 				break;
665 			}
666 		}
667 	}
668 	/*
669 	 * In OWE transition mode, ssid is hidden. And supplicant does not issue
670 	 * scan with specific ssid prior to connect as in other hidden ssid
671 	 * cases. Add explicit check to allow OWE when ssid is hidden.
672 	 */
673 	if (!match)
674 		match = scm_ignore_ssid_check_for_owe(filter, db_entry);
675 
676 	if (!match && filter->num_of_ssid)
677 		return false;
678 
679 	match = false;
680 	/* TO do Fill p2p MAC*/
681 	for (i = 0; i < filter->num_of_bssid; i++) {
682 		if (util_is_bssid_match(&filter->bssid_list[i],
683 		   &db_entry->bssid)) {
684 			match = true;
685 			break;
686 		}
687 		/* TODO match p2p mac */
688 	}
689 	if (!match && filter->num_of_bssid)
690 		return false;
691 
692 	pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id,
693 					  WLAN_SCAN_ID);
694 	if (!pdev) {
695 		scm_err("Invalid pdev");
696 		return false;
697 	}
698 
699 	if (filter->ignore_nol_chan &&
700 	    utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) {
701 		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
702 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as chan in NOL list",
703 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
704 		return false;
705 	}
706 	wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
707 
708 	match = false;
709 	for (i = 0; i < filter->num_of_channels; i++) {
710 		if (!filter->chan_freq_list[i] ||
711 		    filter->chan_freq_list[i] ==
712 		    db_entry->channel.chan_freq) {
713 			match = true;
714 			break;
715 		}
716 	}
717 
718 	if (!match && filter->num_of_channels)
719 		return false;
720 
721 	if (filter->rrm_measurement_filter)
722 		return true;
723 
724 	if (!filter->ignore_auth_enc_type && !filter->match_security_func &&
725 	    !scm_is_security_match(filter, db_entry, security)) {
726 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as security profile didn't match",
727 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
728 		return false;
729 	}
730 
731 	if (filter->match_security_func &&
732 	    !filter->match_security_func(filter->match_security_func_arg,
733 					 db_entry)) {
734 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as custom security match failed",
735 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
736 		return false;
737 	}
738 
739 	if (filter->ccx_validate_bss &&
740 	    !filter->ccx_validate_bss(filter->ccx_validate_bss_arg,
741 				      db_entry, 0)) {
742 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as CCX validateion failed",
743 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
744 		return false;
745 	}
746 
747 	/* Match realm */
748 	if (!scm_is_fils_config_match(filter, db_entry)) {
749 		scm_debug(QDF_MAC_ADDR_FMT" :Ignore as fils config didn't match",
750 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
751 		return false;
752 	}
753 
754 	if (!util_mdie_match(filter->mobility_domain,
755 	   (struct rsn_mdie *)db_entry->ie_list.mdie)) {
756 		scm_debug(QDF_MAC_ADDR_FMT" : Ignore as mdie didn't match",
757 			  QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
758 		return false;
759 	}
760 	return true;
761 }
762