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 wlan_objmgr_pdev *pdev, 694 struct scan_filter *filter, 695 struct scan_cache_entry *db_entry) 696 { 697 uint8_t i, band_bitmap, assoc_band_bitmap; 698 enum reg_wifi_band band; 699 struct partner_link_info *partner_link; 700 bool is_disabled; 701 702 if (!db_entry->ie_list.multi_link) 703 return true; 704 if (!filter->band_bitmap) 705 return true; 706 707 /* Apply assoc band filter only for assoc link */ 708 band_bitmap = filter->band_bitmap & 0xf; 709 assoc_band_bitmap = (filter->band_bitmap & 0xf0) >> 4; 710 band = wlan_reg_freq_to_band(db_entry->channel.chan_freq); 711 if ((assoc_band_bitmap && !(band_bitmap & BIT(band) & assoc_band_bitmap)) || 712 (!assoc_band_bitmap && !(band_bitmap & BIT(band)))) { 713 scm_debug("bss freq %d not match band bitmap: 0x%x", 714 db_entry->channel.chan_freq, 715 filter->band_bitmap); 716 return false; 717 } 718 for (i = 0; i < db_entry->ml_info.num_links; i++) { 719 partner_link = &db_entry->ml_info.link_info[i]; 720 band = wlan_reg_freq_to_band(partner_link->freq); 721 722 is_disabled = wlan_reg_is_disable_for_pwrmode( 723 pdev, 724 partner_link->freq, 725 REG_BEST_PWR_MODE); 726 if (is_disabled) { 727 scm_debug("partner link id %d freq %d disabled : "QDF_MAC_ADDR_FMT, 728 partner_link->link_id, 729 partner_link->freq, 730 QDF_MAC_ADDR_REF( 731 partner_link->link_addr.bytes)); 732 continue; 733 } 734 if (band_bitmap & BIT(band)) { 735 scm_debug("partner link id %d freq %d match band bitmap: 0x%x "QDF_MAC_ADDR_FMT, 736 partner_link->link_id, 737 partner_link->freq, 738 filter->band_bitmap, 739 QDF_MAC_ADDR_REF( 740 partner_link->link_addr.bytes)); 741 partner_link->is_valid_link = true; 742 } 743 } 744 745 return true; 746 } 747 #else 748 static bool util_mlo_filter_match(struct wlan_objmgr_pdev *pdev, 749 struct scan_filter *filter, 750 struct scan_cache_entry *db_entry) 751 { 752 return true; 753 } 754 #endif 755 756 #ifdef WLAN_FEATURE_11BE 757 static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry) 758 { 759 struct wlan_ie_ehtops *eht_ops; 760 int8_t orig_width; 761 enum phy_ch_width width; 762 qdf_freq_t center_freq_320m; 763 uint16_t orig_puncture_bitmap; 764 uint16_t new_puncture_bitmap = 0; 765 QDF_STATUS status; 766 767 eht_ops = (struct wlan_ie_ehtops *)util_scan_entry_ehtop(db_entry); 768 if (!eht_ops) 769 return true; 770 if (!QDF_GET_BITS(eht_ops->ehtop_param, 771 EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS)) 772 return true; 773 orig_puncture_bitmap = db_entry->channel.puncture_bitmap; 774 if (!orig_puncture_bitmap) 775 return true; 776 777 orig_width = QDF_GET_BITS(eht_ops->control, 778 EHTOP_INFO_CHAN_WIDTH_IDX, 779 EHTOP_INFO_CHAN_WIDTH_BITS); 780 if (orig_width == WLAN_EHT_CHWIDTH_320) { 781 width = CH_WIDTH_320MHZ; 782 center_freq_320m = db_entry->channel.cfreq1; 783 } else { 784 width = orig_width; 785 center_freq_320m = 0; 786 } 787 788 status = wlan_reg_extract_puncture_by_bw(width, 789 orig_puncture_bitmap, 790 db_entry->channel.chan_freq, 791 center_freq_320m, 792 CH_WIDTH_20MHZ, 793 &new_puncture_bitmap); 794 if (QDF_IS_STATUS_ERROR(status) || new_puncture_bitmap) { 795 scm_debug(QDF_MAC_ADDR_FMT "freq %d width %d 320m center %d puncture: orig %d new %d status %d", 796 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 797 db_entry->channel.chan_freq, width, center_freq_320m, 798 orig_puncture_bitmap, new_puncture_bitmap, status); 799 return false; 800 } else { 801 return true; 802 } 803 } 804 #else 805 static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry) 806 { 807 return true; 808 } 809 #endif 810 811 bool scm_filter_match(struct wlan_objmgr_psoc *psoc, 812 struct scan_cache_entry *db_entry, 813 struct scan_filter *filter, 814 struct security_info *security) 815 { 816 int i; 817 bool match = false; 818 struct scan_default_params *def_param; 819 struct wlan_objmgr_pdev *pdev; 820 821 def_param = wlan_scan_psoc_get_def_params(psoc); 822 if (!def_param) 823 return false; 824 825 if (db_entry->ssid.length) { 826 for (i = 0; i < filter->num_of_ssid; i++) { 827 if (util_is_ssid_match(&filter->ssid_list[i], 828 &db_entry->ssid)) { 829 match = true; 830 break; 831 } 832 } 833 } 834 /* 835 * In OWE transition mode, ssid is hidden. And supplicant does not issue 836 * scan with specific ssid prior to connect as in other hidden ssid 837 * cases. Add explicit check to allow OWE when ssid is hidden. 838 */ 839 if (!match) 840 match = scm_ignore_ssid_check_for_owe(filter, db_entry); 841 842 if (!match && filter->num_of_ssid) 843 return false; 844 845 match = false; 846 for (i = 0; i < filter->num_of_bssid; i++) { 847 if (util_is_bssid_match(&filter->bssid_list[i], 848 &db_entry->bssid)) { 849 match = true; 850 break; 851 } 852 } 853 854 if (!match && filter->num_of_bssid) { 855 /* 856 * Do not print if ssid is not present in filter to avoid 857 * excessive prints 858 */ 859 if (filter->num_of_ssid) 860 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as BSSID not in list (no. of BSSID in list %d)", 861 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 862 filter->num_of_bssid); 863 return false; 864 } 865 866 if (filter->age_threshold && 867 filter->age_threshold < util_scan_entry_age(db_entry)) { 868 /* 869 * Do not print if bssid/ssid is not present in filter to avoid 870 * excessive prints 871 */ 872 if (filter->num_of_bssid || filter->num_of_ssid) 873 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as age %lu ms is greater than threshold %lu ms", 874 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 875 util_scan_entry_age(db_entry), 876 filter->age_threshold); 877 return false; 878 } 879 880 if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter)) { 881 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode %d didn't match phymode %d", 882 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 883 filter->dot11mode, db_entry->phy_mode); 884 return false; 885 } 886 887 if (filter->ignore_6ghz_channel && 888 WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq)) { 889 /* 890 * Do not print if bssid/ssid is not present in filter to avoid 891 * excessive prints 892 */ 893 if (filter->num_of_bssid || filter->num_of_ssid) 894 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as its on 6Ghz freq %d", 895 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 896 db_entry->channel.chan_freq); 897 898 return false; 899 } 900 901 pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id, 902 WLAN_SCAN_ID); 903 if (!pdev) { 904 scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found", 905 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 906 return false; 907 } 908 909 if (filter->ignore_nol_chan && 910 utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) { 911 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 912 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as chan in NOL list", 913 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 914 return false; 915 } 916 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 917 918 match = false; 919 for (i = 0; i < filter->num_of_channels; i++) { 920 if (!filter->chan_freq_list[i] || 921 filter->chan_freq_list[i] == 922 db_entry->channel.chan_freq) { 923 match = true; 924 break; 925 } 926 } 927 928 if (!match && filter->num_of_channels) { 929 /* 930 * Do not print if bssid/ssid is not present in filter to avoid 931 * excessive prints (e.g RRM case where only freq list is 932 * provided to get AP's in specific frequencies) 933 */ 934 if (filter->num_of_bssid || filter->num_of_ssid) 935 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as AP's freq %d is not in freq list", 936 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 937 db_entry->channel.chan_freq); 938 return false; 939 } 940 941 if (filter->rrm_measurement_filter) 942 return true; 943 944 if (!filter->ignore_auth_enc_type && !filter->match_security_func && 945 !scm_is_security_match(filter, db_entry, security)) { 946 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as security profile didn't match", 947 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 948 return false; 949 } 950 951 if (filter->match_security_func && 952 !filter->match_security_func(filter->match_security_func_arg, 953 db_entry)) { 954 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as custom security match failed", 955 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 956 return false; 957 } 958 959 if (filter->ccx_validate_bss && 960 !filter->ccx_validate_bss(filter->ccx_validate_bss_arg, 961 db_entry, 0)) { 962 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as CCX validateion failed", 963 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 964 return false; 965 } 966 967 if (!util_is_bss_type_match(filter->bss_type, db_entry->cap_info)) { 968 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as bss type didn't match cap_info %x bss_type %d", 969 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 970 db_entry->cap_info.value, filter->bss_type); 971 return false; 972 } 973 974 /* Match realm */ 975 if (!scm_is_fils_config_match(filter, db_entry)) { 976 scm_debug(QDF_MAC_ADDR_FMT ":Ignore as fils config didn't match", 977 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 978 return false; 979 } 980 981 if (!util_mdie_match(filter->mobility_domain, 982 (struct rsn_mdie *)db_entry->ie_list.mdie)) { 983 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mdie didn't match", 984 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 985 return false; 986 } 987 988 if (!util_mlo_filter_match(pdev, filter, db_entry)) { 989 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mlo filter didn't match", 990 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 991 return false; 992 } 993 994 if (!util_eht_puncture_valid(db_entry)) 995 return false; 996 997 return true; 998 } 999