1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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 /* 632 * Don't validate the realm, if AP advertises realm count as 0 633 * in the FILS indication element 634 */ 635 if (!indication_ie->realm_identifiers_cnt) 636 return true; 637 638 end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2; 639 data = indication_ie->variable_data; 640 641 if (indication_ie->is_cache_id_present && 642 (data + CACHE_IDENTIFIER_LEN) <= end_ptr) 643 data += CACHE_IDENTIFIER_LEN; 644 645 if (indication_ie->is_hessid_present && 646 (data + HESSID_LEN) <= end_ptr) 647 data += HESSID_LEN; 648 649 for (i = 1; i <= indication_ie->realm_identifiers_cnt && 650 (data + REALM_HASH_LEN) <= end_ptr; i++) { 651 if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm, 652 data, REALM_HASH_LEN)) 653 return true; 654 /* Max realm count reached */ 655 if (indication_ie->realm_identifiers_cnt == i) 656 break; 657 658 data = data + REALM_HASH_LEN; 659 } 660 661 return false; 662 } 663 664 #else 665 666 static inline bool scm_is_fils_config_match(struct scan_filter *filter, 667 struct scan_cache_entry *db_entry) 668 { 669 return true; 670 } 671 #endif 672 673 static bool scm_check_dot11mode(struct scan_cache_entry *db_entry, 674 struct scan_filter *filter) 675 { 676 switch (filter->dot11mode) { 677 case ALLOW_ALL: 678 break; 679 case ALLOW_11N_ONLY: 680 if (!util_scan_entry_htcap(db_entry)) 681 return false; 682 break; 683 case ALLOW_11AC_ONLY: 684 if (!util_scan_entry_vhtcap(db_entry)) 685 return false; 686 break; 687 case ALLOW_11AX_ONLY: 688 if (!util_scan_entry_hecap(db_entry)) 689 return false; 690 break; 691 case ALLOW_11BE_ONLY: 692 if (!util_scan_entry_ehtcap(db_entry)) 693 return false; 694 break; 695 default: 696 scm_debug("Invalid dot11mode filter passed %d", 697 filter->dot11mode); 698 } 699 700 return true; 701 } 702 703 #ifdef WLAN_FEATURE_11BE_MLO 704 static bool util_mlo_filter_match(struct wlan_objmgr_pdev *pdev, 705 struct scan_filter *filter, 706 struct scan_cache_entry *db_entry) 707 { 708 uint8_t i, band_bitmap, assoc_band_bitmap; 709 enum reg_wifi_band band; 710 struct partner_link_info *partner_link; 711 bool is_disabled; 712 713 if (!db_entry->ie_list.multi_link_bv) 714 return true; 715 if (!filter->band_bitmap) 716 return true; 717 718 /* Apply assoc band filter only for assoc link */ 719 band_bitmap = filter->band_bitmap & 0xf; 720 assoc_band_bitmap = (filter->band_bitmap & 0xf0) >> 4; 721 band = wlan_reg_freq_to_band(db_entry->channel.chan_freq); 722 if ((assoc_band_bitmap && !(band_bitmap & BIT(band) & assoc_band_bitmap)) || 723 (!assoc_band_bitmap && !(band_bitmap & BIT(band)))) { 724 scm_debug("bss freq %d not match band bitmap: 0x%x", 725 db_entry->channel.chan_freq, 726 filter->band_bitmap); 727 return false; 728 } 729 for (i = 0; i < db_entry->ml_info.num_links; i++) { 730 partner_link = &db_entry->ml_info.link_info[i]; 731 band = wlan_reg_freq_to_band(partner_link->freq); 732 733 is_disabled = wlan_reg_is_disable_for_pwrmode( 734 pdev, 735 partner_link->freq, 736 REG_BEST_PWR_MODE); 737 if (is_disabled) { 738 scm_debug("partner link id %d freq %d disabled : "QDF_MAC_ADDR_FMT, 739 partner_link->link_id, 740 partner_link->freq, 741 QDF_MAC_ADDR_REF( 742 partner_link->link_addr.bytes)); 743 continue; 744 } 745 if (band_bitmap & BIT(band)) { 746 scm_debug("partner link id %d freq %d match band bitmap: 0x%x "QDF_MAC_ADDR_FMT, 747 partner_link->link_id, 748 partner_link->freq, 749 filter->band_bitmap, 750 QDF_MAC_ADDR_REF( 751 partner_link->link_addr.bytes)); 752 partner_link->is_valid_link = true; 753 } 754 } 755 756 return true; 757 } 758 #else 759 static bool util_mlo_filter_match(struct wlan_objmgr_pdev *pdev, 760 struct scan_filter *filter, 761 struct scan_cache_entry *db_entry) 762 { 763 return true; 764 } 765 #endif 766 767 #ifdef WLAN_FEATURE_11BE 768 /** 769 * util_eht_puncture_valid(): The function finds the puncturing pattern from the 770 * IE. If the primary channel is in the punctured list then the channel cannot 771 * be used, and this function returns false/invalid. 772 * @pdev: pdev device. 773 * @db_entry: scan cache entry which will indicate EHT ops. 774 * 775 * Return - false if the primary channel is punctured and true if otherwise. 776 */ 777 static bool util_eht_puncture_valid(struct wlan_objmgr_pdev *pdev, 778 struct scan_cache_entry *db_entry) 779 { 780 struct wlan_ie_ehtops *eht_ops; 781 int8_t orig_width; 782 enum phy_ch_width width; 783 qdf_freq_t center_freq_320m; 784 uint16_t orig_puncture_bitmap; 785 uint16_t new_puncture_bitmap = 0; 786 QDF_STATUS status; 787 uint32_t cfreq1; 788 uint8_t band_mask = BIT(REG_BAND_6G); 789 790 eht_ops = (struct wlan_ie_ehtops *)util_scan_entry_ehtop(db_entry); 791 if (!eht_ops) 792 return true; 793 if (!QDF_GET_BITS(eht_ops->ehtop_param, 794 EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS)) 795 return true; 796 if (QDF_GET_BITS(eht_ops->ehtop_param, 797 EHTOP_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX, 798 EHTOP_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS)) { 799 orig_puncture_bitmap = 800 QDF_GET_BITS(eht_ops->disabled_sub_chan_bitmap[0], 801 0, 8); 802 orig_puncture_bitmap |= 803 QDF_GET_BITS(eht_ops->disabled_sub_chan_bitmap[1], 804 0, 8) << 8; 805 } else { 806 orig_puncture_bitmap = 0; 807 } 808 if (!orig_puncture_bitmap) 809 return true; 810 811 orig_width = QDF_GET_BITS(eht_ops->control, 812 EHTOP_INFO_CHAN_WIDTH_IDX, 813 EHTOP_INFO_CHAN_WIDTH_BITS); 814 /* Check if CCFS bits are present */ 815 if (QDF_GET_BITS(eht_ops->ehtop_param, 816 EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS)) 817 cfreq1 = wlan_reg_chan_band_to_freq(pdev, eht_ops->ccfs1, 818 band_mask); 819 else 820 cfreq1 = 0; 821 822 if (orig_width == WLAN_EHT_CHWIDTH_320) { 823 width = CH_WIDTH_320MHZ; 824 center_freq_320m = cfreq1; 825 } else { 826 width = orig_width; 827 center_freq_320m = 0; 828 } 829 830 /* Find if the primary channel is punctured */ 831 status = wlan_reg_extract_puncture_by_bw(width, 832 orig_puncture_bitmap, 833 db_entry->channel.chan_freq, 834 center_freq_320m, 835 CH_WIDTH_20MHZ, 836 &new_puncture_bitmap); 837 if (QDF_IS_STATUS_ERROR(status) || new_puncture_bitmap) { 838 scm_debug(QDF_MAC_ADDR_FMT "freq %d width %d 320m center %d puncture: orig %d new %d status %d", 839 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 840 db_entry->channel.chan_freq, width, center_freq_320m, 841 orig_puncture_bitmap, new_puncture_bitmap, status); 842 return false; 843 } else { 844 return true; 845 } 846 } 847 #else 848 static bool util_eht_puncture_valid(struct wlan_objmgr_pdev *pdev, 849 struct scan_cache_entry *db_entry) 850 { 851 return true; 852 } 853 #endif 854 855 bool scm_filter_match(struct wlan_objmgr_psoc *psoc, 856 struct scan_cache_entry *db_entry, 857 struct scan_filter *filter, 858 struct security_info *security) 859 { 860 int i; 861 bool match = false; 862 struct scan_default_params *def_param; 863 struct wlan_objmgr_pdev *pdev; 864 865 def_param = wlan_scan_psoc_get_def_params(psoc); 866 if (!def_param) 867 return false; 868 869 if (db_entry->ssid.length) { 870 for (i = 0; i < filter->num_of_ssid; i++) { 871 if (util_is_ssid_match(&filter->ssid_list[i], 872 &db_entry->ssid)) { 873 match = true; 874 break; 875 } 876 } 877 } 878 /* 879 * In OWE transition mode, ssid is hidden. And supplicant does not issue 880 * scan with specific ssid prior to connect as in other hidden ssid 881 * cases. Add explicit check to allow OWE when ssid is hidden. 882 */ 883 if (!match) 884 match = scm_ignore_ssid_check_for_owe(filter, db_entry); 885 886 if (!match && filter->num_of_ssid) 887 return false; 888 889 match = false; 890 for (i = 0; i < filter->num_of_bssid; i++) { 891 if (util_is_bssid_match(&filter->bssid_list[i], 892 &db_entry->bssid)) { 893 match = true; 894 break; 895 } 896 } 897 898 if (!match && filter->num_of_bssid) { 899 /* 900 * Do not print if ssid is not present in filter to avoid 901 * excessive prints 902 */ 903 if (filter->num_of_ssid) 904 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as BSSID not in list (no. of BSSID in list %d)", 905 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 906 filter->num_of_bssid); 907 return false; 908 } 909 910 if (filter->age_threshold && 911 filter->age_threshold < util_scan_entry_age(db_entry)) { 912 /* 913 * Do not print if bssid/ssid is not present in filter to avoid 914 * excessive prints 915 */ 916 if (filter->num_of_bssid || filter->num_of_ssid) 917 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as age %lu ms is greater than threshold %lu ms", 918 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 919 util_scan_entry_age(db_entry), 920 filter->age_threshold); 921 return false; 922 } 923 924 if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter)) { 925 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode %d didn't match phymode %d", 926 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 927 filter->dot11mode, db_entry->phy_mode); 928 return false; 929 } 930 931 if (filter->ignore_6ghz_channel && 932 WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq)) { 933 /* 934 * Do not print if bssid/ssid is not present in filter to avoid 935 * excessive prints 936 */ 937 if (filter->num_of_bssid || filter->num_of_ssid) 938 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as its on 6Ghz freq %d", 939 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 940 db_entry->channel.chan_freq); 941 942 return false; 943 } 944 945 pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id, 946 WLAN_SCAN_ID); 947 if (!pdev) { 948 scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found", 949 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 950 return false; 951 } 952 953 if (filter->ignore_nol_chan && 954 utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) { 955 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 956 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as chan in NOL list", 957 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 958 return false; 959 } 960 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 961 962 match = false; 963 for (i = 0; i < filter->num_of_channels; i++) { 964 if (!filter->chan_freq_list[i] || 965 filter->chan_freq_list[i] == 966 db_entry->channel.chan_freq) { 967 match = true; 968 break; 969 } 970 } 971 972 if (!match && filter->num_of_channels) { 973 /* 974 * Do not print if bssid/ssid is not present in filter to avoid 975 * excessive prints (e.g RRM case where only freq list is 976 * provided to get AP's in specific frequencies) 977 */ 978 if (filter->num_of_bssid || filter->num_of_ssid) 979 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as AP's freq %d is not in freq list", 980 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 981 db_entry->channel.chan_freq); 982 return false; 983 } 984 985 if (filter->rrm_measurement_filter) 986 return true; 987 988 if (!filter->ignore_auth_enc_type && !filter->match_security_func && 989 !scm_is_security_match(filter, db_entry, security)) { 990 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as security profile didn't match", 991 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 992 return false; 993 } 994 995 if (filter->match_security_func && 996 !filter->match_security_func(filter->match_security_func_arg, 997 db_entry)) { 998 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as custom security match failed", 999 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1000 return false; 1001 } 1002 1003 if (filter->ccx_validate_bss && 1004 !filter->ccx_validate_bss(filter->ccx_validate_bss_arg, 1005 db_entry, 0)) { 1006 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as CCX validateion failed", 1007 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1008 return false; 1009 } 1010 1011 if (!util_is_bss_type_match(filter->bss_type, db_entry->cap_info)) { 1012 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as bss type didn't match cap_info %x bss_type %d", 1013 QDF_MAC_ADDR_REF(db_entry->bssid.bytes), 1014 db_entry->cap_info.value, filter->bss_type); 1015 return false; 1016 } 1017 1018 /* Match realm */ 1019 if (!scm_is_fils_config_match(filter, db_entry)) { 1020 scm_debug(QDF_MAC_ADDR_FMT ":Ignore as fils config didn't match", 1021 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1022 return false; 1023 } 1024 1025 if (!util_mdie_match(filter->mobility_domain, 1026 (struct rsn_mdie *)db_entry->ie_list.mdie)) { 1027 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mdie didn't match", 1028 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1029 return false; 1030 } 1031 1032 if (!util_mlo_filter_match(pdev, filter, db_entry)) { 1033 scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mlo filter didn't match", 1034 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1035 return false; 1036 } 1037 1038 pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id, 1039 WLAN_SCAN_ID); 1040 if (!pdev) { 1041 scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found", 1042 QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); 1043 return false; 1044 } 1045 if (!util_eht_puncture_valid(pdev, db_entry)) { 1046 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1047 return false; 1048 } 1049 wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); 1050 1051 return true; 1052 } 1053