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