1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 /* 20 * DOC: contains scan cache filter logic 21 */ 22 23 #include <wlan_scan_utils_api.h> 24 #include "wlan_scan_main.h" 25 #include "wlan_scan_cache_db_i.h" 26 #include <wlan_dfs_utils_api.h> 27 #include "wlan_crypto_global_def.h" 28 #include "wlan_crypto_global_api.h" 29 #include "wlan_reg_services_api.h" 30 31 /** 32 * scm_check_open() - Check if scan entry support open authmode 33 * @filter: scan filter 34 * @db_entry: db entry 35 * @security: matched security. 36 * 37 * Return: true if open security else false 38 */ 39 static bool scm_check_open(struct scan_filter *filter, 40 struct scan_cache_entry *db_entry, 41 struct security_info *security) 42 { 43 if (db_entry->cap_info.wlan_caps.privacy) { 44 scm_debug(QDF_MAC_ADDR_FMT" : have privacy set", 45 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 46 return false; 47 } 48 49 if (filter->ucastcipherset && 50 !(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE))) { 51 scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in uc %x", 52 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 53 filter->ucastcipherset); 54 return false; 55 } 56 57 if (filter->mcastcipherset && 58 !(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE))) { 59 scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in mc %x", 60 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 61 filter->mcastcipherset); 62 return false; 63 } 64 65 QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE); 66 QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE); 67 68 return true; 69 } 70 71 /** 72 * scm_check_wep() - Check if scan entry support WEP authmode 73 * @filter: scan filter 74 * @db_entry: db entry 75 * @security: matched security. 76 * 77 * Return: true if WEP security else false 78 */ 79 static bool scm_check_wep(struct scan_filter *filter, 80 struct scan_cache_entry *db_entry, 81 struct security_info *security) 82 { 83 /* If privacy bit is not set, consider no match */ 84 if (!db_entry->cap_info.wlan_caps.privacy) { 85 scm_debug(QDF_MAC_ADDR_FMT" : doesn't have privacy set", 86 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 87 return false; 88 } 89 90 if (!(db_entry->security_type & SCAN_SECURITY_TYPE_WEP)) { 91 scm_debug(QDF_MAC_ADDR_FMT" : doesn't support WEP", 92 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 93 return false; 94 } 95 96 if (!filter->ucastcipherset || !filter->mcastcipherset) { 97 scm_debug(QDF_MAC_ADDR_FMT" : Filter uc %x or mc %x cipher are 0", 98 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 99 filter->ucastcipherset, 100 filter->mcastcipherset); 101 return false; 102 } 103 104 if (!(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) || 105 QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) || 106 QDF_HAS_PARAM(filter->ucastcipherset, 107 WLAN_CRYPTO_CIPHER_WEP_104))) { 108 scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in uc %x", 109 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 110 filter->ucastcipherset); 111 return false; 112 } 113 114 if (!(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP) || 115 QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) || 116 QDF_HAS_PARAM(filter->mcastcipherset, 117 WLAN_CRYPTO_CIPHER_WEP_104))) { 118 scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in mc %x", 119 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 120 filter->mcastcipherset); 121 return false; 122 } 123 124 if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP)) 125 QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP); 126 127 if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40)) 128 QDF_SET_PARAM(security->ucastcipherset, 129 WLAN_CRYPTO_CIPHER_WEP_40); 130 131 if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)) 132 QDF_SET_PARAM(security->ucastcipherset, 133 WLAN_CRYPTO_CIPHER_WEP_104); 134 135 if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP)) 136 QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP); 137 138 if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40)) 139 QDF_SET_PARAM(security->mcastcipherset, 140 WLAN_CRYPTO_CIPHER_WEP_40); 141 142 if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)) 143 QDF_SET_PARAM(security->mcastcipherset, 144 WLAN_CRYPTO_CIPHER_WEP_104); 145 146 return true; 147 } 148 149 /** 150 * scm_chk_if_cipher_n_akm_match() - Check if akm and ciphers match 151 * @filter: scan filter 152 * @ap_crypto: aps crypto params 153 * 154 * Return: true if matches 155 */ 156 static bool scm_chk_if_cipher_n_akm_match(struct scan_filter *filter, 157 struct wlan_crypto_params *ap_crypto) 158 { 159 /* Check AP's pairwise ciphers.*/ 160 if (!(filter->ucastcipherset & ap_crypto->ucastcipherset)) 161 return false; 162 163 /* Check AP's group cipher match.*/ 164 if (!(filter->mcastcipherset & ap_crypto->mcastcipherset)) 165 return false; 166 167 /* Check AP's AKM match with filter's AKM.*/ 168 if (!(filter->key_mgmt & ap_crypto->key_mgmt)) 169 return false; 170 171 /* Check AP's mgmt cipher match if present.*/ 172 if ((filter->mgmtcipherset && ap_crypto->mgmtcipherset) && 173 !(filter->mgmtcipherset & ap_crypto->mgmtcipherset)) 174 return false; 175 176 if (filter->ignore_pmf_cap) 177 return true; 178 179 if (filter->pmf_cap == WLAN_PMF_REQUIRED && 180 !(ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) 181 return false; 182 183 if (filter->pmf_cap == WLAN_PMF_DISABLED && 184 (ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) 185 return false; 186 187 return true; 188 } 189 190 static bool scm_chk_crypto_params(struct scan_filter *filter, 191 struct wlan_crypto_params *ap_crypto, 192 bool is_adaptive_11r, 193 struct scan_cache_entry *db_entry, 194 struct security_info *security) 195 { 196 if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) { 197 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", 198 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), is_adaptive_11r, 199 filter->key_mgmt, filter->mcastcipherset, 200 filter->ucastcipherset, filter->mgmtcipherset, 201 filter->pmf_cap, ap_crypto->key_mgmt, 202 ap_crypto->mcastcipherset, ap_crypto->ucastcipherset, 203 ap_crypto->mgmtcipherset, ap_crypto->rsn_caps); 204 return false; 205 } 206 207 security->mcastcipherset = 208 ap_crypto->mcastcipherset & filter->mcastcipherset; 209 security->ucastcipherset = 210 ap_crypto->ucastcipherset & filter->ucastcipherset; 211 security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt; 212 security->rsn_caps = ap_crypto->rsn_caps; 213 214 return true; 215 } 216 217 #ifdef WLAN_ADAPTIVE_11R 218 /** 219 * scm_check_and_update_adaptive_11r_key_mgmt_support() - check and update 220 * first rsn security which is present in RSN IE of Beacon/Probe response to 221 * corresponding FT AKM. 222 * @ap_crypto: crypto param structure 223 * 224 * Return: none 225 */ 226 static void scm_check_and_update_adaptive_11r_key_mgmt_support( 227 struct wlan_crypto_params *ap_crypto) 228 { 229 uint32_t i, first_key_mgmt = WLAN_CRYPTO_KEY_MGMT_MAX; 230 231 /* 232 * Supplicant compares AKM(s) in RSN IE of Beacon/Probe response and 233 * AKM on EAPOL M3 frame received by AP. In the case of multi AKM, 234 * previously Host converts all adaptive 11r AKM(s), if any, present 235 * in RSN IE of Beacon/Probe response to corresponding FT AKM but the 236 * AP(s) which support adaptive 11r (ADAPTIVE_11R_OUI: 0x964000) only 237 * converts first AKM to corresponding FT AKM and sends EAPOL M3 frame 238 * to DUT. This results in failure in a 4-way handshake in supplicant 239 * due to RSN IE miss-match between RSNIE sent by host and RSNIE 240 * present in EAPOL M3 frame. Now like AP, the host is converting only 241 * the first AKM to corresponding FT AKM to avoid RSNIE mismatch in 242 * supplicant. 243 */ 244 for (i = 0; i < WLAN_CRYPTO_KEY_MGMT_MAX; i++) { 245 if (ap_crypto->akm_list[i].key_mgmt == 246 WLAN_CRYPTO_KEY_MGMT_IEEE8021X || 247 ap_crypto->akm_list[i].key_mgmt == 248 WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256) { 249 first_key_mgmt = WLAN_CRYPTO_KEY_MGMT_IEEE8021X; 250 break; 251 } 252 253 if (ap_crypto->akm_list[i].key_mgmt == 254 WLAN_CRYPTO_KEY_MGMT_PSK || 255 ap_crypto->akm_list[i].key_mgmt == 256 WLAN_CRYPTO_KEY_MGMT_PSK_SHA256) { 257 first_key_mgmt = WLAN_CRYPTO_KEY_MGMT_PSK; 258 break; 259 } 260 } 261 262 if (first_key_mgmt == WLAN_CRYPTO_KEY_MGMT_MAX) { 263 scm_debug("No adaptive 11r's AKM present in RSN IE"); 264 return; 265 } 266 267 scm_debug("First AKM:%d present in RSN IE of bcn/Probe rsp at index:%d", 268 first_key_mgmt, i); 269 270 if (first_key_mgmt == WLAN_CRYPTO_KEY_MGMT_IEEE8021X) 271 QDF_SET_PARAM(ap_crypto->key_mgmt, 272 WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X); 273 274 if (first_key_mgmt == WLAN_CRYPTO_KEY_MGMT_PSK) 275 QDF_SET_PARAM(ap_crypto->key_mgmt, WLAN_CRYPTO_KEY_MGMT_FT_PSK); 276 } 277 #else 278 static inline void scm_check_and_update_adaptive_11r_key_mgmt_support( 279 struct wlan_crypto_params *ap_crypto) 280 { 281 } 282 #endif 283 284 /** 285 * scm_check_rsn() - Check if scan entry support RSN security 286 * @filter: scan filter 287 * @db_entry: db entry 288 * @security: matched security. 289 * 290 * Return: true if RSN security else false 291 */ 292 static bool scm_check_rsn(struct scan_filter *filter, 293 struct scan_cache_entry *db_entry, 294 struct security_info *security) 295 { 296 bool is_adaptive_11r; 297 QDF_STATUS status; 298 struct wlan_crypto_params *ap_crypto; 299 bool match; 300 301 if (!util_scan_entry_rsn(db_entry)) { 302 scm_debug(QDF_MAC_ADDR_FMT" : doesn't have RSN IE", 303 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 304 return false; 305 } 306 307 ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); 308 if (!ap_crypto) 309 return false; 310 status = wlan_crypto_rsnie_check(ap_crypto, 311 util_scan_entry_rsn(db_entry)); 312 if (QDF_IS_STATUS_ERROR(status)) { 313 scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN 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 is_adaptive_11r = db_entry->adaptive_11r_ap && 320 filter->enable_adaptive_11r; 321 322 /* If adaptive 11r is enabled set the FT AKM for AP */ 323 if (is_adaptive_11r) 324 scm_check_and_update_adaptive_11r_key_mgmt_support(ap_crypto); 325 326 scm_debug("ap_crypto->key_mgmt:%d, filter->key_mgmt:%d", 327 ap_crypto->key_mgmt, filter->key_mgmt); 328 match = scm_chk_crypto_params(filter, ap_crypto, is_adaptive_11r, 329 db_entry, security); 330 qdf_mem_free(ap_crypto); 331 332 return match; 333 } 334 335 /** 336 * scm_check_wpa() - Check if scan entry support WPA security 337 * @filter: scan filter 338 * @db_entry: db entry 339 * @security: matched security. 340 * 341 * Return: true if WPA security else false 342 */ 343 static bool scm_check_wpa(struct scan_filter *filter, 344 struct scan_cache_entry *db_entry, 345 struct security_info *security) 346 { 347 QDF_STATUS status; 348 struct wlan_crypto_params *ap_crypto; 349 bool match; 350 351 if (!util_scan_entry_wpa(db_entry)) { 352 scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WPA IE", 353 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 354 return false; 355 } 356 357 ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); 358 if (!ap_crypto) 359 return false; 360 361 status = wlan_crypto_wpaie_check(ap_crypto, 362 util_scan_entry_wpa(db_entry)); 363 if (QDF_IS_STATUS_ERROR(status)) { 364 scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d", 365 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status); 366 qdf_mem_free(ap_crypto); 367 return false; 368 } 369 370 match = scm_chk_crypto_params(filter, ap_crypto, false, 371 db_entry, security); 372 qdf_mem_free(ap_crypto); 373 374 return match; 375 } 376 377 /** 378 * scm_check_wapi() - Check if scan entry support WAPI security 379 * @filter: scan filter 380 * @db_entry: db entry 381 * @security: matched security. 382 * 383 * Return: true if WAPI security else false 384 */ 385 static bool scm_check_wapi(struct scan_filter *filter, 386 struct scan_cache_entry *db_entry, 387 struct security_info *security) 388 { 389 QDF_STATUS status; 390 struct wlan_crypto_params *ap_crypto; 391 392 if (!util_scan_entry_wapi(db_entry)) { 393 scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WAPI IE", 394 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 395 return false; 396 } 397 398 ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); 399 if (!ap_crypto) 400 return false; 401 402 status = wlan_crypto_wapiie_check(ap_crypto, 403 util_scan_entry_wapi(db_entry)); 404 if (QDF_IS_STATUS_ERROR(status)) { 405 scm_err(QDF_MAC_ADDR_FMT": failed to parse WAPI IE, status %d", 406 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status); 407 qdf_mem_free(ap_crypto); 408 return false; 409 } 410 411 if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) { 412 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", 413 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), filter->key_mgmt, 414 filter->mcastcipherset, filter->ucastcipherset, 415 filter->mgmtcipherset, filter->pmf_cap, 416 ap_crypto->key_mgmt, ap_crypto->mcastcipherset, 417 ap_crypto->ucastcipherset, ap_crypto->mgmtcipherset, 418 ap_crypto->rsn_caps); 419 qdf_mem_free(ap_crypto); 420 421 return false; 422 } 423 424 security->mcastcipherset = 425 ap_crypto->mcastcipherset & filter->mcastcipherset; 426 security->ucastcipherset = 427 ap_crypto->ucastcipherset & filter->ucastcipherset; 428 security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt; 429 security->rsn_caps = ap_crypto->rsn_caps; 430 qdf_mem_free(ap_crypto); 431 432 return true; 433 } 434 435 /** 436 * scm_match_any_security() - Check if any security in filter match 437 * @filter: scan filter 438 * @db_entry: db entry 439 * @security: matched security. 440 * 441 * Return: true if any security else false 442 */ 443 static bool scm_match_any_security(struct scan_filter *filter, 444 struct scan_cache_entry *db_entry, 445 struct security_info *security) 446 { 447 struct wlan_crypto_params *ap_crypto = {0}; 448 QDF_STATUS status; 449 bool match = false; 450 451 ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto)); 452 if (!ap_crypto) 453 return match; 454 455 if (util_scan_entry_rsn(db_entry)) { 456 status = wlan_crypto_rsnie_check(ap_crypto, 457 util_scan_entry_rsn(db_entry)); 458 if (QDF_IS_STATUS_ERROR(status)) { 459 scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN IE, status %d", 460 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status); 461 goto free; 462 } 463 security->mcastcipherset = ap_crypto->mcastcipherset; 464 security->ucastcipherset = ap_crypto->ucastcipherset; 465 security->key_mgmt = ap_crypto->key_mgmt; 466 security->rsn_caps = ap_crypto->rsn_caps; 467 QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_RSNA); 468 match = true; 469 goto free; 470 } 471 472 if (util_scan_entry_wpa(db_entry)) { 473 status = wlan_crypto_wpaie_check(ap_crypto, 474 util_scan_entry_wpa(db_entry)); 475 if (QDF_IS_STATUS_ERROR(status)) { 476 scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d", 477 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status); 478 goto free; 479 } 480 security->mcastcipherset = ap_crypto->mcastcipherset; 481 security->ucastcipherset = ap_crypto->ucastcipherset; 482 security->key_mgmt = ap_crypto->key_mgmt; 483 security->rsn_caps = ap_crypto->rsn_caps; 484 QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WPA); 485 match = true; 486 goto free; 487 } 488 489 if (util_scan_entry_wapi(db_entry)) { 490 status = wlan_crypto_wapiie_check(ap_crypto, 491 util_scan_entry_wapi(db_entry)); 492 if (QDF_IS_STATUS_ERROR(status)) { 493 scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d", 494 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 495 status); 496 goto free; 497 } 498 security->mcastcipherset = ap_crypto->mcastcipherset; 499 security->ucastcipherset = ap_crypto->ucastcipherset; 500 security->key_mgmt = ap_crypto->key_mgmt; 501 security->rsn_caps = ap_crypto->rsn_caps; 502 QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WAPI); 503 match = true; 504 goto free; 505 } 506 507 if (db_entry->cap_info.wlan_caps.privacy) { 508 QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP); 509 QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP); 510 QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_SHARED); 511 match = true; 512 goto free; 513 } 514 515 QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE); 516 QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE); 517 QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_OPEN); 518 match = true; 519 520 free: 521 qdf_mem_free(ap_crypto); 522 523 return match; 524 } 525 526 /** 527 * scm_is_security_match() - Check if security in filter match 528 * @filter: scan filter 529 * @db_entry: db entry 530 * @security: matched security. 531 * 532 * Return: true if security match else false 533 */ 534 static bool scm_is_security_match(struct scan_filter *filter, 535 struct scan_cache_entry *db_entry, 536 struct security_info *security) 537 { 538 int i; 539 bool match = false; 540 541 if (!filter->authmodeset) 542 return scm_match_any_security(filter, db_entry, security); 543 544 for (i = 0; i < WLAN_CRYPTO_AUTH_MAX && !match; i++) { 545 if (!QDF_HAS_PARAM(filter->authmodeset, i)) 546 continue; 547 548 security->authmodeset = 0; 549 QDF_SET_PARAM(security->authmodeset, i); 550 551 switch (i) { 552 case WLAN_CRYPTO_AUTH_NONE: 553 case WLAN_CRYPTO_AUTH_OPEN: 554 case WLAN_CRYPTO_AUTH_AUTO: 555 match = scm_check_open(filter, db_entry, security); 556 if (match) 557 break; 558 /* If not OPEN, then check WEP match */ 559 fallthrough; 560 case WLAN_CRYPTO_AUTH_SHARED: 561 match = scm_check_wep(filter, db_entry, security); 562 break; 563 case WLAN_CRYPTO_AUTH_8021X: 564 case WLAN_CRYPTO_AUTH_RSNA: 565 case WLAN_CRYPTO_AUTH_CCKM: 566 case WLAN_CRYPTO_AUTH_SAE: 567 case WLAN_CRYPTO_AUTH_FILS_SK: 568 /* First check if there is a RSN match */ 569 match = scm_check_rsn(filter, db_entry, security); 570 break; 571 case WLAN_CRYPTO_AUTH_WPA: 572 match = scm_check_wpa(filter, db_entry, security); 573 break; 574 case WLAN_CRYPTO_AUTH_WAPI:/* WAPI */ 575 match = scm_check_wapi(filter, db_entry, security); 576 break; 577 default: 578 break; 579 } 580 } 581 582 return match; 583 } 584 585 static bool scm_ignore_ssid_check_for_owe(struct scan_filter *filter, 586 struct scan_cache_entry *db_entry) 587 { 588 bool is_hidden; 589 590 is_hidden = util_scan_entry_is_hidden_ap(db_entry); 591 if (is_hidden && 592 QDF_HAS_PARAM(filter->key_mgmt, WLAN_CRYPTO_KEY_MGMT_OWE) && 593 util_is_bssid_match(&filter->bssid_hint, &db_entry->bssid)) 594 return true; 595 596 /* Dump only for hidden SSID as non-hidden are anyway rejected */ 597 if (is_hidden) 598 scm_debug(QDF_MAC_ADDR_FMT ": Ignore hidden AP as key_mgmt 0x%x is not OWE or bssid hint: " 599 QDF_MAC_ADDR_FMT " does not match", 600 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 601 filter->key_mgmt, 602 QDF_MAC_ADDR_REF(filter->bssid_hint.bytes)); 603 return false; 604 } 605 606 #ifdef WLAN_FEATURE_FILS_SK 607 /** 608 * scm_is_fils_config_match() - Check if FILS config matches 609 * @filter: scan filter 610 * @db_entry: db entry 611 * 612 * Return: true if FILS config matches else false 613 */ 614 static bool scm_is_fils_config_match(struct scan_filter *filter, 615 struct scan_cache_entry *db_entry) 616 { 617 int i; 618 struct fils_indication_ie *indication_ie; 619 uint8_t *data; 620 uint8_t *end_ptr; 621 622 if (!filter->fils_scan_filter.realm_check) 623 return true; 624 625 if (!db_entry->ie_list.fils_indication) 626 return false; 627 628 indication_ie = 629 (struct fils_indication_ie *)db_entry->ie_list.fils_indication; 630 631 end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2; 632 data = indication_ie->variable_data; 633 634 if (indication_ie->is_cache_id_present && 635 (data + CACHE_IDENTIFIER_LEN) <= end_ptr) 636 data += CACHE_IDENTIFIER_LEN; 637 638 if (indication_ie->is_hessid_present && 639 (data + HESSID_LEN) <= end_ptr) 640 data += HESSID_LEN; 641 642 for (i = 1; i <= indication_ie->realm_identifiers_cnt && 643 (data + REALM_HASH_LEN) <= end_ptr; i++) { 644 if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm, 645 data, REALM_HASH_LEN)) 646 return true; 647 /* Max realm count reached */ 648 if (indication_ie->realm_identifiers_cnt == i) 649 break; 650 651 data = data + REALM_HASH_LEN; 652 } 653 654 return false; 655 } 656 657 #else 658 659 static inline bool scm_is_fils_config_match(struct scan_filter *filter, 660 struct scan_cache_entry *db_entry) 661 { 662 return true; 663 } 664 #endif 665 666 static bool scm_check_dot11mode(struct scan_cache_entry *db_entry, 667 struct scan_filter *filter) 668 { 669 switch (filter->dot11mode) { 670 case ALLOW_ALL: 671 break; 672 case ALLOW_11N_ONLY: 673 if (!util_scan_entry_htcap(db_entry)) 674 return false; 675 break; 676 case ALLOW_11AC_ONLY: 677 if (!util_scan_entry_vhtcap(db_entry)) 678 return false; 679 break; 680 case ALLOW_11AX_ONLY: 681 if (!util_scan_entry_hecap(db_entry)) 682 return false; 683 break; 684 default: 685 scm_debug("Invalid dot11mode filter passed %d", 686 filter->dot11mode); 687 } 688 689 return true; 690 } 691 692 #ifdef WLAN_FEATURE_11BE_MLO 693 static bool util_mlo_filter_match(struct scan_filter *filter, 694 struct scan_cache_entry *db_entry) 695 { 696 uint8_t i, band_bitmap, assoc_band_bitmap; 697 enum reg_wifi_band band; 698 struct partner_link_info *partner_link; 699 700 if (!db_entry->ie_list.multi_link) 701 return true; 702 if (!filter->band_bitmap) 703 return true; 704 705 /* Apply assoc band filter only for assoc link */ 706 band_bitmap = filter->band_bitmap & 0xf; 707 assoc_band_bitmap = (filter->band_bitmap & 0xf0) >> 4; 708 band = wlan_reg_freq_to_band(db_entry->channel.chan_freq); 709 if ((assoc_band_bitmap && !(band_bitmap & BIT(band) & assoc_band_bitmap)) || 710 (!assoc_band_bitmap && !(band_bitmap & BIT(band)))) { 711 scm_debug("bss freq %d not match band bitmap: 0x%x", 712 db_entry->channel.chan_freq, 713 filter->band_bitmap); 714 return false; 715 } 716 for (i = 0; i < db_entry->ml_info.num_links; i++) { 717 partner_link = &db_entry->ml_info.link_info[i]; 718 band = wlan_reg_freq_to_band(partner_link->freq); 719 if (band_bitmap & BIT(band)) { 720 scm_debug("partner freq %d match band bitmap: 0x%x", 721 partner_link->freq, 722 filter->band_bitmap); 723 partner_link->is_valid_link = true; 724 } 725 } 726 727 return true; 728 } 729 #else 730 static bool util_mlo_filter_match(struct scan_filter *filter, 731 struct scan_cache_entry *db_entry) 732 { 733 return true; 734 } 735 #endif 736 737 #ifdef WLAN_FEATURE_11BE 738 static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry) 739 { 740 struct wlan_ie_ehtops *eht_ops; 741 int8_t orig_width; 742 enum phy_ch_width width; 743 qdf_freq_t center_freq_320m; 744 uint16_t orig_puncture_bitmap; 745 uint16_t new_puncture_bitmap = 0; 746 QDF_STATUS status; 747 748 eht_ops = (struct wlan_ie_ehtops *)util_scan_entry_ehtop(db_entry); 749 if (!eht_ops) 750 return true; 751 if (!QDF_GET_BITS(eht_ops->ehtop_param, 752 EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS)) 753 return true; 754 orig_puncture_bitmap = db_entry->channel.puncture_bitmap; 755 if (!orig_puncture_bitmap) 756 return true; 757 758 orig_width = QDF_GET_BITS(eht_ops->control, 759 EHTOP_INFO_CHAN_WIDTH_IDX, 760 EHTOP_INFO_CHAN_WIDTH_BITS); 761 if (orig_width == WLAN_EHT_CHWIDTH_320) { 762 width = CH_WIDTH_320MHZ; 763 center_freq_320m = db_entry->channel.cfreq1; 764 } else { 765 width = orig_width; 766 center_freq_320m = 0; 767 } 768 769 status = wlan_reg_extract_puncture_by_bw(width, 770 orig_puncture_bitmap, 771 db_entry->channel.chan_freq, 772 center_freq_320m, 773 CH_WIDTH_20MHZ, 774 &new_puncture_bitmap); 775 if (QDF_IS_STATUS_ERROR(status) || new_puncture_bitmap) { 776 scm_debug(QDF_MAC_ADDR_FMT "freq %d width %d 320m center %d puncture: orig %d new %d status %d", 777 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 778 db_entry->channel.chan_freq, width, center_freq_320m, 779 orig_puncture_bitmap, new_puncture_bitmap, status); 780 return false; 781 } else { 782 return true; 783 } 784 } 785 #else 786 static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry) 787 { 788 return true; 789 } 790 #endif 791 792 bool scm_filter_match(struct wlan_objmgr_psoc *psoc, 793 struct scan_cache_entry *db_entry, 794 struct scan_filter *filter, 795 struct security_info *security) 796 { 797 int i; 798 bool match = false; 799 struct scan_default_params *def_param; 800 struct wlan_objmgr_pdev *pdev; 801 802 def_param = wlan_scan_psoc_get_def_params(psoc); 803 if (!def_param) 804 return false; 805 806 if (db_entry->ssid.length) { 807 for (i = 0; i < filter->num_of_ssid; i++) { 808 if (util_is_ssid_match(&filter->ssid_list[i], 809 &db_entry->ssid)) { 810 match = true; 811 break; 812 } 813 } 814 } 815 /* 816 * In OWE transition mode, ssid is hidden. And supplicant does not issue 817 * scan with specific ssid prior to connect as in other hidden ssid 818 * cases. Add explicit check to allow OWE when ssid is hidden. 819 */ 820 if (!match) 821 match = scm_ignore_ssid_check_for_owe(filter, db_entry); 822 823 if (!match && filter->num_of_ssid) 824 return false; 825 826 match = false; 827 for (i = 0; i < filter->num_of_bssid; i++) { 828 if (util_is_bssid_match(&filter->bssid_list[i], 829 &db_entry->bssid)) { 830 match = true; 831 break; 832 } 833 } 834 835 if (!match && filter->num_of_bssid) { 836 /* 837 * Do not print if ssid is not present in filter to avoid 838 * excessive prints 839 */ 840 if (filter->num_of_ssid) 841 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as BSSID not in list (no. of BSSID in list %d)", 842 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 843 filter->num_of_bssid); 844 return false; 845 } 846 847 if (filter->age_threshold && 848 filter->age_threshold < util_scan_entry_age(db_entry)) { 849 /* 850 * Do not print if bssid/ssid is not present in filter to avoid 851 * excessive prints 852 */ 853 if (filter->num_of_bssid || filter->num_of_ssid) 854 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as age %lu ms is greater than threshold %lu ms", 855 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 856 util_scan_entry_age(db_entry), 857 filter->age_threshold); 858 return false; 859 } 860 861 if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter)) { 862 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode %d didn't match phymode %d", 863 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 864 filter->dot11mode, db_entry->phy_mode); 865 return false; 866 } 867 868 if (filter->ignore_6ghz_channel && 869 WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq)) { 870 /* 871 * Do not print if bssid/ssid is not present in filter to avoid 872 * excessive prints 873 */ 874 if (filter->num_of_bssid || filter->num_of_ssid) 875 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as its on 6Ghz freq %d", 876 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 877 db_entry->channel.chan_freq); 878 879 return false; 880 } 881 882 pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id, 883 WLAN_SCAN_ID); 884 if (!pdev) { 885 scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found", 886 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 887 return false; 888 } 889 890 if (filter->ignore_nol_chan && 891 utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) { 892 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 893 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as chan in NOL list", 894 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 895 return false; 896 } 897 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 898 899 match = false; 900 for (i = 0; i < filter->num_of_channels; i++) { 901 if (!filter->chan_freq_list[i] || 902 filter->chan_freq_list[i] == 903 db_entry->channel.chan_freq) { 904 match = true; 905 break; 906 } 907 } 908 909 if (!match && filter->num_of_channels) { 910 /* 911 * Do not print if bssid/ssid is not present in filter to avoid 912 * excessive prints (e.g RRM case where only freq list is 913 * provided to get AP's in specific frequencies) 914 */ 915 if (filter->num_of_bssid || filter->num_of_ssid) 916 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as AP's freq %d is not in freq list", 917 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 918 db_entry->channel.chan_freq); 919 return false; 920 } 921 922 if (filter->rrm_measurement_filter) 923 return true; 924 925 if (!filter->ignore_auth_enc_type && !filter->match_security_func && 926 !scm_is_security_match(filter, db_entry, security)) { 927 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as security profile didn't match", 928 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 929 return false; 930 } 931 932 if (filter->match_security_func && 933 !filter->match_security_func(filter->match_security_func_arg, 934 db_entry)) { 935 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as custom security match failed", 936 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 937 return false; 938 } 939 940 if (filter->ccx_validate_bss && 941 !filter->ccx_validate_bss(filter->ccx_validate_bss_arg, 942 db_entry, 0)) { 943 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as CCX validateion failed", 944 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 945 return false; 946 } 947 948 if (!util_is_bss_type_match(filter->bss_type, db_entry->cap_info)) { 949 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as bss type didn't match cap_info %x bss_type %d", 950 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 951 db_entry->cap_info.value, filter->bss_type); 952 return false; 953 } 954 955 /* Match realm */ 956 if (!scm_is_fils_config_match(filter, db_entry)) { 957 scm_debug(QDF_MAC_ADDR_FMT ":Ignore as fils config didn't match", 958 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 959 return false; 960 } 961 962 if (!util_mdie_match(filter->mobility_domain, 963 (struct rsn_mdie *)db_entry->ie_list.mdie)) { 964 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mdie didn't match", 965 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 966 return false; 967 } 968 969 if (!util_mlo_filter_match(filter, db_entry)) { 970 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mlo filter didn't match", 971 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 972 return false; 973 } 974 975 if (!util_eht_puncture_valid(db_entry)) 976 return false; 977 978 return true; 979 } 980