1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2024 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 /** 21 * DOC: Public API initialization of crypto service with object manager 22 */ 23 #include <qdf_types.h> 24 #include <wlan_cmn.h> 25 #include <wlan_objmgr_cmn.h> 26 27 #include <wlan_objmgr_global_obj.h> 28 #include <wlan_objmgr_psoc_obj.h> 29 #include <wlan_objmgr_pdev_obj.h> 30 #include <wlan_objmgr_vdev_obj.h> 31 #include <wlan_objmgr_peer_obj.h> 32 33 #include "wlan_crypto_global_def.h" 34 #include "wlan_crypto_global_api.h" 35 #include "wlan_crypto_def_i.h" 36 #include "wlan_crypto_main_i.h" 37 #include "wlan_crypto_obj_mgr_i.h" 38 #ifdef WLAN_CRYPTO_SUPPORT_FILS 39 #include "wlan_crypto_fils_api.h" 40 #endif 41 42 #define CRYPTO_MAX_HASH_IDX 16 43 #define CRYPTO_MAX_HASH_ENTRY 1024 44 45 static qdf_mutex_t crypto_lock; 46 47 extern const struct wlan_crypto_cipher 48 *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; 49 50 static inline int crypto_log2_ceil(unsigned int value) 51 { 52 unsigned int tmp = value; 53 int log2 = -1; 54 55 crypto_info("crypto log value %d ", value); 56 while (tmp) { 57 log2++; 58 tmp >>= 1; 59 } 60 if (1 << log2 != value) 61 log2++; 62 return log2; 63 } 64 65 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 66 static QDF_STATUS wlan_crypto_hash_init(struct crypto_psoc_priv_obj *psoc) 67 { 68 int log2, hash_elems, i; 69 70 log2 = crypto_log2_ceil(CRYPTO_MAX_HASH_IDX); 71 hash_elems = 1 << log2; 72 73 psoc->crypto_key_holder.mask = hash_elems - 1; 74 psoc->crypto_key_holder.idx_bits = log2; 75 76 /* allocate an array of TAILQ mec object lists */ 77 psoc->crypto_key_holder.bins = qdf_mem_malloc( 78 hash_elems * 79 sizeof(TAILQ_HEAD(anonymous_tail_q, 80 crypto_hash_entry))); 81 82 if (!psoc->crypto_key_holder.bins) 83 return QDF_STATUS_E_NOMEM; 84 85 for (i = 0; i < hash_elems; i++) 86 TAILQ_INIT(&psoc->crypto_key_holder.bins[i]); 87 88 qdf_mutex_create(&psoc->crypto_key_lock); 89 90 return QDF_STATUS_SUCCESS; 91 } 92 #endif 93 94 static inline uint32_t crypto_hash_index(struct crypto_psoc_priv_obj *psoc, 95 union crypto_align_mac_addr *mac_addr, 96 uint8_t link_id) 97 { 98 uint32_t index; 99 100 index = 101 mac_addr->align2.bytes_ab ^ 102 mac_addr->align2.bytes_cd ^ 103 mac_addr->align2.bytes_ef; 104 index ^= link_id; 105 index ^= index >> psoc->crypto_key_holder.idx_bits; 106 index &= psoc->crypto_key_holder.mask; 107 return index; 108 } 109 110 static inline int crypto_is_mac_addr_same( 111 union crypto_align_mac_addr *mac_addr1, 112 union crypto_align_mac_addr *mac_addr2) 113 { 114 /* 115 * Intentionally use & rather than &&. 116 * because the operands are binary rather than generic boolean, 117 * the functionality is equivalent. 118 * Using && has the advantage of short-circuited evaluation, 119 * but using & has the advantage of no conditional branching, 120 * which is a more significant benefit. 121 */ 122 return ((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd) 123 & (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef)); 124 } 125 126 struct 127 wlan_crypto_key_entry *crypto_hash_find_by_linkid_and_macaddr( 128 struct crypto_psoc_priv_obj *psoc, 129 uint8_t link_id, 130 uint8_t *mac_addr) 131 { 132 union crypto_align_mac_addr local_mac_addr_aligned, *local_mac_addr; 133 uint32_t index; 134 struct wlan_crypto_key_entry *hash_entry; 135 136 qdf_mem_copy(&local_mac_addr_aligned.raw[0], 137 mac_addr, QDF_MAC_ADDR_SIZE); 138 local_mac_addr = &local_mac_addr_aligned; 139 140 index = crypto_hash_index(psoc, local_mac_addr, link_id); 141 TAILQ_FOREACH(hash_entry, &psoc->crypto_key_holder.bins[index], 142 hash_list_elem) { 143 if (link_id == hash_entry->link_id && 144 crypto_is_mac_addr_same( 145 local_mac_addr, 146 &hash_entry->mac_addr)) { 147 crypto_debug("crypto found entry link id %d mac addr" 148 QDF_MAC_ADDR_FMT, 149 hash_entry->link_id, 150 QDF_MAC_ADDR_REF(mac_addr)); 151 return hash_entry; 152 } 153 } 154 return NULL; 155 } 156 157 static inline void crypto_hash_add(struct crypto_psoc_priv_obj *psoc, 158 struct wlan_crypto_key_entry *hash_entry, 159 uint8_t link_id) 160 { 161 uint32_t index; 162 163 index = crypto_hash_index(psoc, &hash_entry->mac_addr, link_id); 164 crypto_debug("crypto hash add index %d ", index); 165 qdf_mutex_acquire(&psoc->crypto_key_lock); 166 TAILQ_INSERT_TAIL(&psoc->crypto_key_holder.bins[index], hash_entry, 167 hash_list_elem); 168 qdf_mutex_release(&psoc->crypto_key_lock); 169 } 170 171 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 172 QDF_STATUS wlan_crypto_add_key_entry(struct wlan_objmgr_psoc *psoc, 173 struct wlan_crypto_key_entry *new_entry) 174 { 175 struct crypto_psoc_priv_obj *crypto_psoc_obj; 176 uint8_t link_id = new_entry->link_id; 177 struct wlan_crypto_key_entry *crypto_entry = NULL; 178 179 crypto_psoc_obj = 180 wlan_objmgr_psoc_get_comp_private_obj(psoc, 181 WLAN_UMAC_COMP_CRYPTO); 182 if (!crypto_psoc_obj) { 183 crypto_err("crypto_psoc_obj NULL"); 184 return QDF_STATUS_E_FAILURE; 185 } 186 187 if (qdf_unlikely(qdf_atomic_read(&crypto_psoc_obj->crypto_key_cnt) >= 188 CRYPTO_MAX_HASH_ENTRY)) { 189 crypto_err("max crypto hash entry limit reached mac_addr: " 190 QDF_MAC_ADDR_FMT, 191 QDF_MAC_ADDR_REF(new_entry->mac_addr.raw)); 192 return QDF_STATUS_E_NOMEM; 193 } 194 195 crypto_debug("crypto add entry link id %d mac_addr: " QDF_MAC_ADDR_FMT, 196 link_id, QDF_MAC_ADDR_REF(new_entry->mac_addr.raw)); 197 198 qdf_mutex_acquire(&crypto_psoc_obj->crypto_key_lock); 199 crypto_entry = 200 crypto_hash_find_by_linkid_and_macaddr(crypto_psoc_obj, link_id, 201 new_entry->mac_addr.raw); 202 qdf_mutex_release(&crypto_psoc_obj->crypto_key_lock); 203 204 if (qdf_unlikely(crypto_entry)) 205 wlan_crypto_free_key_by_link_id(psoc, 206 (struct qdf_mac_addr *)new_entry->mac_addr.raw, 207 link_id); 208 209 crypto_entry = qdf_mem_malloc(sizeof(*crypto_entry)); 210 if (!crypto_entry) 211 return QDF_STATUS_E_NOMEM; 212 213 *crypto_entry = *new_entry; 214 215 crypto_hash_add(crypto_psoc_obj, crypto_entry, link_id); 216 qdf_atomic_inc(&crypto_psoc_obj->crypto_key_cnt); 217 crypto_entry->is_active = 1; 218 219 return QDF_STATUS_SUCCESS; 220 } 221 #endif 222 223 QDF_STATUS crypto_add_entry(struct crypto_psoc_priv_obj *psoc, 224 uint8_t link_id, 225 uint8_t *mac_addr, 226 struct wlan_crypto_key *crypto_key, 227 uint8_t key_index) 228 { 229 struct wlan_crypto_key_entry *crypto_entry = NULL; 230 231 crypto_debug("crypto add entry link id %d mac_addr: " QDF_MAC_ADDR_FMT, 232 link_id, QDF_MAC_ADDR_REF(mac_addr)); 233 234 if (qdf_unlikely(qdf_atomic_read(&psoc->crypto_key_cnt) >= 235 CRYPTO_MAX_HASH_ENTRY)) { 236 crypto_err("max crypto hash entry limit reached mac_addr: " 237 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 238 return QDF_STATUS_E_NOMEM; 239 } 240 241 qdf_mutex_acquire(&psoc->crypto_key_lock); 242 crypto_entry = crypto_hash_find_by_linkid_and_macaddr(psoc, link_id, 243 mac_addr); 244 qdf_mutex_release(&psoc->crypto_key_lock); 245 246 if (qdf_likely(!crypto_entry)) { 247 crypto_entry = (struct wlan_crypto_key_entry *) 248 qdf_mem_malloc(sizeof(struct wlan_crypto_key_entry)); 249 250 if (qdf_unlikely(!crypto_entry)) 251 return QDF_STATUS_E_NOMEM; 252 253 qdf_copy_macaddr((struct qdf_mac_addr *)&crypto_entry->mac_addr.raw[0], 254 (struct qdf_mac_addr *)mac_addr); 255 crypto_entry->link_id = link_id; 256 crypto_hash_add(psoc, crypto_entry, link_id); 257 qdf_atomic_inc(&psoc->crypto_key_cnt); 258 crypto_entry->is_active = 1; 259 } 260 261 if (key_index < WLAN_CRYPTO_MAXKEYIDX) { 262 crypto_entry->keys.key[key_index] = crypto_key; 263 } else if (is_igtk(key_index)) { 264 crypto_entry->keys.igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX] = 265 crypto_key; 266 crypto_entry->keys.def_igtk_tx_keyid = 267 key_index - WLAN_CRYPTO_MAXKEYIDX; 268 crypto_entry->keys.igtk_key_type = crypto_key->cipher_type; 269 } else { 270 crypto_entry->keys.bigtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX 271 - WLAN_CRYPTO_MAXIGTKKEYIDX] = crypto_key; 272 crypto_entry->keys.def_bigtk_tx_keyid = 273 key_index - WLAN_CRYPTO_MAXKEYIDX 274 - WLAN_CRYPTO_MAXIGTKKEYIDX; 275 } 276 return QDF_STATUS_SUCCESS; 277 } 278 279 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 280 static void crypto_remove_entry(struct crypto_psoc_priv_obj *psoc, 281 struct wlan_crypto_key_entry *crypto_entry, 282 void *ptr) 283 { 284 int i = 0; 285 286 uint32_t index = crypto_hash_index(psoc, &crypto_entry->mac_addr, 287 crypto_entry->link_id); 288 TAILQ_HEAD(, wlan_crypto_key_entry) * free_list = ptr; 289 290 crypto_info("crypto remove entry key index %d link id %d", 291 index, crypto_entry->link_id); 292 293 for (i = 0; i < WLAN_CRYPTO_MAX_VLANKEYIX; i++) { 294 if (crypto_entry->keys.key[i]) { 295 qdf_mem_free(crypto_entry->keys.key[i]); 296 crypto_entry->keys.key[i] = NULL; 297 } 298 } 299 300 for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) { 301 if (crypto_entry->keys.igtk_key[i]) { 302 qdf_mem_free(crypto_entry->keys.igtk_key[i]); 303 crypto_entry->keys.igtk_key[i] = NULL; 304 } 305 } 306 307 for (i = 0; i < WLAN_CRYPTO_MAXBIGTKKEYIDX; i++) { 308 if (crypto_entry->keys.bigtk_key[i]) { 309 qdf_mem_free(crypto_entry->keys.bigtk_key[i]); 310 crypto_entry->keys.bigtk_key[i] = NULL; 311 } 312 } 313 /* Reset All key index as well */ 314 crypto_entry->keys.def_tx_keyid = 0; 315 crypto_entry->keys.def_igtk_tx_keyid = 0; 316 crypto_entry->keys.def_bigtk_tx_keyid = 0; 317 318 TAILQ_REMOVE(&psoc->crypto_key_holder.bins[index], crypto_entry, 319 hash_list_elem); 320 TAILQ_INSERT_TAIL(free_list, crypto_entry, hash_list_elem); 321 } 322 323 static void crypto_free_list(struct crypto_psoc_priv_obj *psoc, void *ptr) 324 { 325 struct wlan_crypto_key_entry *crypto_entry, *hash_entry_next; 326 327 TAILQ_HEAD(, wlan_crypto_key_entry) * free_list = ptr; 328 329 TAILQ_FOREACH_SAFE(crypto_entry, free_list, hash_list_elem, 330 hash_entry_next) { 331 crypto_debug("crypto delete for link_id %d mac_addr " 332 QDF_MAC_ADDR_FMT, crypto_entry->link_id, 333 QDF_MAC_ADDR_REF(crypto_entry->mac_addr.raw)); 334 qdf_mem_free(crypto_entry); 335 if (!qdf_atomic_read(&psoc->crypto_key_cnt)) 336 crypto_debug("Invalid crypto_key_cnt %d", 337 psoc->crypto_key_cnt); 338 else 339 qdf_atomic_dec(&psoc->crypto_key_cnt); 340 } 341 } 342 343 void crypto_flush_entries(struct wlan_objmgr_psoc *psoc) 344 { 345 unsigned int index; 346 struct wlan_crypto_key_entry *hash_entry, *hash_entry_next; 347 struct crypto_psoc_priv_obj *crypto_priv; 348 349 TAILQ_HEAD(, wlan_crypto_key_entry) free_list; 350 TAILQ_INIT(&free_list); 351 352 crypto_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc, 353 WLAN_UMAC_COMP_CRYPTO); 354 355 if (!crypto_priv) 356 return; 357 358 if (!crypto_priv->crypto_key_holder.mask) 359 return; 360 361 if (!crypto_priv->crypto_key_holder.bins) 362 return; 363 364 if (!qdf_atomic_read(&crypto_priv->crypto_key_cnt)) 365 return; 366 367 qdf_mutex_acquire(&crypto_priv->crypto_key_lock); 368 for (index = 0; index <= crypto_priv->crypto_key_holder.mask; index++) { 369 if (!TAILQ_EMPTY(&crypto_priv->crypto_key_holder.bins[index])) { 370 TAILQ_FOREACH_SAFE( 371 hash_entry, 372 &crypto_priv->crypto_key_holder.bins[index], 373 hash_list_elem, hash_entry_next) { 374 crypto_remove_entry(crypto_priv, hash_entry, 375 &free_list); 376 } 377 } 378 } 379 crypto_free_list(crypto_priv, &free_list); 380 qdf_mutex_release(&crypto_priv->crypto_key_lock); 381 } 382 383 /** 384 * wlan_crypto_hash_deinit() - This API deinit hash mechanism 385 * @psoc: pointer to PSOC object 386 * 387 * Return: void 388 */ 389 static void wlan_crypto_hash_deinit(struct wlan_objmgr_psoc *psoc) 390 { 391 struct crypto_psoc_priv_obj *crypto_priv; 392 393 crypto_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc, 394 WLAN_UMAC_COMP_CRYPTO); 395 if (!crypto_priv) { 396 crypto_err("failed to get crypto obj in psoc"); 397 return; 398 } 399 400 crypto_flush_entries(psoc); 401 qdf_mem_free(crypto_priv->crypto_key_holder.bins); 402 crypto_priv->crypto_key_holder.bins = NULL; 403 qdf_mutex_destroy(&crypto_priv->crypto_key_lock); 404 } 405 406 static QDF_STATUS wlan_crypto_psoc_obj_create_handler( 407 struct wlan_objmgr_psoc *psoc, 408 void *arg) 409 { 410 QDF_STATUS status; 411 struct crypto_psoc_priv_obj *crypto_psoc_obj; 412 413 crypto_psoc_obj = qdf_mem_malloc(sizeof(*crypto_psoc_obj)); 414 if (!crypto_psoc_obj) 415 return QDF_STATUS_E_NOMEM; 416 417 status = wlan_objmgr_psoc_component_obj_attach(psoc, 418 WLAN_UMAC_COMP_CRYPTO, 419 (void *)crypto_psoc_obj, 420 QDF_STATUS_SUCCESS); 421 422 if (QDF_IS_STATUS_ERROR(status)) { 423 qdf_mem_free(crypto_psoc_obj); 424 crypto_err("failed to attach crypto psoc priv object"); 425 return status; 426 } 427 428 status = wlan_crypto_hash_init(crypto_psoc_obj); 429 if (QDF_IS_STATUS_ERROR(status)) { 430 wlan_objmgr_psoc_component_obj_detach(psoc, 431 WLAN_UMAC_COMP_CRYPTO, 432 crypto_psoc_obj); 433 qdf_mem_free(crypto_psoc_obj); 434 crypto_err("failed to hash init"); 435 } 436 437 return status; 438 } 439 440 static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler( 441 struct wlan_objmgr_psoc *psoc, 442 void *arg) 443 { 444 QDF_STATUS status; 445 struct crypto_psoc_priv_obj *crypto_psoc_obj; 446 447 wlan_crypto_hash_deinit(psoc); 448 449 crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 450 psoc, 451 WLAN_UMAC_COMP_CRYPTO); 452 if (!crypto_psoc_obj) { 453 crypto_err("failed to get crypto obj in psoc"); 454 return QDF_STATUS_E_FAILURE; 455 } 456 457 status = wlan_objmgr_psoc_component_obj_detach(psoc, 458 WLAN_UMAC_COMP_CRYPTO, 459 crypto_psoc_obj); 460 if (QDF_IS_STATUS_ERROR(status)) 461 crypto_err("failed to detach crypto psoc priv object"); 462 463 qdf_mem_free(crypto_psoc_obj); 464 return status; 465 } 466 #else 467 void crypto_flush_entries(struct wlan_objmgr_psoc *psoc) 468 { 469 } 470 #endif 471 472 static QDF_STATUS wlan_crypto_register_all_ciphers( 473 struct wlan_crypto_params *crypto_param) 474 { 475 476 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) { 477 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP] 478 = wep_register(); 479 } 480 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) { 481 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP] 482 = tkip_register(); 483 } 484 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) { 485 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM] 486 = ccmp_register(); 487 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256] 488 = ccmp256_register(); 489 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM] 490 = gcmp_register(); 491 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256] 492 = gcmp256_register(); 493 } 494 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) { 495 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4] 496 = wapi_register(); 497 } 498 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD)) { 499 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_FILS_AEAD] 500 = fils_register(); 501 } 502 503 return QDF_STATUS_SUCCESS; 504 } 505 506 static QDF_STATUS wlan_crypto_vdev_obj_create_handler( 507 struct wlan_objmgr_vdev *vdev, 508 void *arg) 509 { 510 struct wlan_crypto_comp_priv *crypto_priv; 511 struct wlan_objmgr_pdev *pdev; 512 struct wlan_crypto_params *crypto_param; 513 QDF_STATUS status; 514 515 if (!vdev) 516 return QDF_STATUS_E_INVAL; 517 518 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 519 if (!crypto_priv) 520 return QDF_STATUS_E_NOMEM; 521 522 crypto_param = &(crypto_priv->crypto_params); 523 524 RESET_AUTHMODE(crypto_param); 525 RESET_UCAST_CIPHERS(crypto_param); 526 RESET_MCAST_CIPHERS(crypto_param); 527 RESET_MGMT_CIPHERS(crypto_param); 528 RESET_KEY_MGMT(crypto_param); 529 RESET_CIPHER_CAP(crypto_param); 530 531 pdev = wlan_vdev_get_pdev(vdev); 532 wlan_pdev_obj_lock(pdev); 533 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP)) 534 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP); 535 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP)) 536 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC); 537 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) { 538 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES); 539 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256); 540 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM); 541 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256); 542 } 543 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP)) 544 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP); 545 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI)) 546 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4); 547 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD); 548 wlan_pdev_obj_unlock(pdev); 549 /* update the crypto cipher table based on the fw caps*/ 550 /* update the fw_caps into ciphercaps then attach to objmgr*/ 551 wlan_crypto_register_all_ciphers(crypto_param); 552 553 status = wlan_objmgr_vdev_component_obj_attach(vdev, 554 WLAN_UMAC_COMP_CRYPTO, 555 (void *)crypto_priv, 556 QDF_STATUS_SUCCESS); 557 if (status != QDF_STATUS_SUCCESS) 558 qdf_mem_free(crypto_priv); 559 560 return status; 561 } 562 563 static QDF_STATUS wlan_crypto_peer_obj_create_handler( 564 struct wlan_objmgr_peer *peer, 565 void *arg) 566 { 567 struct wlan_crypto_comp_priv *crypto_priv; 568 struct wlan_crypto_params *crypto_param; 569 QDF_STATUS status; 570 571 if (!peer) 572 return QDF_STATUS_E_INVAL; 573 574 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 575 if (!crypto_priv) 576 return QDF_STATUS_E_NOMEM; 577 578 status = wlan_objmgr_peer_component_obj_attach(peer, 579 WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, 580 QDF_STATUS_SUCCESS); 581 582 if (status == QDF_STATUS_SUCCESS) { 583 crypto_param = &crypto_priv->crypto_params; 584 RESET_AUTHMODE(crypto_param); 585 RESET_UCAST_CIPHERS(crypto_param); 586 RESET_MCAST_CIPHERS(crypto_param); 587 RESET_MGMT_CIPHERS(crypto_param); 588 RESET_KEY_MGMT(crypto_param); 589 RESET_CIPHER_CAP(crypto_param); 590 if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) { 591 wlan_crypto_set_peer_wep_keys( 592 wlan_peer_get_vdev(peer), peer); 593 } 594 } else { 595 crypto_err("peer obj failed status %d", status); 596 qdf_mem_free(crypto_priv); 597 } 598 599 return status; 600 } 601 602 void wlan_crypto_free_key(struct wlan_crypto_keys *crypto_key) 603 { 604 uint8_t i; 605 606 if (!crypto_key) { 607 crypto_err("given key ptr is NULL"); 608 return; 609 } 610 611 for (i = 0; i < WLAN_CRYPTO_MAX_VLANKEYIX; i++) { 612 if (crypto_key->key[i]) { 613 qdf_mem_free(crypto_key->key[i]); 614 crypto_key->key[i] = NULL; 615 } 616 } 617 618 for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) { 619 if (crypto_key->igtk_key[i]) { 620 qdf_mem_free(crypto_key->igtk_key[i]); 621 crypto_key->igtk_key[i] = NULL; 622 } 623 } 624 625 for (i = 0; i < WLAN_CRYPTO_MAXBIGTKKEYIDX; i++) { 626 if (crypto_key->bigtk_key[i]) { 627 qdf_mem_free(crypto_key->bigtk_key[i]); 628 crypto_key->bigtk_key[i] = NULL; 629 } 630 } 631 632 /* Reset All key index as well */ 633 crypto_key->def_tx_keyid = 0; 634 crypto_key->def_igtk_tx_keyid = 0; 635 crypto_key->def_bigtk_tx_keyid = 0; 636 } 637 638 #ifdef CRYPTO_SET_KEY_CONVERGED 639 void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev) 640 { 641 struct wlan_crypto_comp_priv *crypto_priv; 642 643 crypto_priv = wlan_get_vdev_crypto_obj(vdev); 644 if (!crypto_priv) { 645 crypto_err("crypto_priv NULL"); 646 return; 647 } 648 649 wlan_crypto_free_key(&crypto_priv->crypto_key); 650 } 651 #endif 652 653 void wlan_crypto_aquire_lock(void) 654 { 655 qdf_mutex_acquire(&crypto_lock); 656 } 657 658 void wlan_crypto_release_lock(void) 659 { 660 qdf_mutex_release(&crypto_lock); 661 } 662 663 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 664 void wlan_crypto_free_key_by_link_id(struct wlan_objmgr_psoc *psoc, 665 struct qdf_mac_addr *link_addr, 666 uint8_t link_id) 667 { 668 struct wlan_crypto_key_entry *hash_entry; 669 struct crypto_psoc_priv_obj *crypto_psoc_obj; 670 671 TAILQ_HEAD(, wlan_crypto_key_entry) free_list; 672 TAILQ_INIT(&free_list); 673 674 crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 675 psoc, 676 WLAN_UMAC_COMP_CRYPTO); 677 if (!crypto_psoc_obj) { 678 crypto_err("crypto_psoc_obj NULL"); 679 return; 680 } 681 682 if (!crypto_psoc_obj->crypto_key_holder.mask) 683 return; 684 685 if (!crypto_psoc_obj->crypto_key_holder.bins) 686 return; 687 688 if (!qdf_atomic_read(&crypto_psoc_obj->crypto_key_cnt)) 689 return; 690 691 qdf_mutex_acquire(&crypto_psoc_obj->crypto_key_lock); 692 hash_entry = crypto_hash_find_by_linkid_and_macaddr( 693 crypto_psoc_obj, link_id, 694 (uint8_t *)link_addr); 695 if (hash_entry) { 696 crypto_remove_entry(crypto_psoc_obj, hash_entry, &free_list); 697 crypto_free_list(crypto_psoc_obj, &free_list); 698 } 699 700 qdf_mutex_release(&crypto_psoc_obj->crypto_key_lock); 701 } 702 703 #endif 704 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( 705 struct wlan_objmgr_vdev *vdev, 706 void *arg) 707 { 708 struct wlan_crypto_comp_priv *crypto_priv; 709 710 if (!vdev) { 711 crypto_err("Vdev NULL"); 712 return QDF_STATUS_E_INVAL; 713 } 714 715 crypto_priv = (struct wlan_crypto_comp_priv *) 716 wlan_get_vdev_crypto_obj(vdev); 717 718 if (!crypto_priv) { 719 crypto_err("crypto_priv NULL"); 720 return QDF_STATUS_E_INVAL; 721 } 722 723 wlan_objmgr_vdev_component_obj_detach(vdev, 724 WLAN_UMAC_COMP_CRYPTO, 725 (void *)crypto_priv); 726 727 wlan_crypto_pmksa_flush(&crypto_priv->crypto_params); 728 wlan_crypto_free_key(&crypto_priv->crypto_key); 729 qdf_mem_free(crypto_priv); 730 731 return QDF_STATUS_SUCCESS; 732 } 733 734 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 735 struct wlan_objmgr_peer *peer, 736 void *arg) 737 { 738 struct wlan_crypto_comp_priv *crypto_priv; 739 740 if (!peer) { 741 crypto_err("Peer NULL"); 742 return QDF_STATUS_E_INVAL; 743 } 744 crypto_priv = (struct wlan_crypto_comp_priv *) 745 wlan_get_peer_crypto_obj(peer); 746 if (!crypto_priv) { 747 crypto_err("crypto_priv NULL"); 748 return QDF_STATUS_E_INVAL; 749 } 750 751 wlan_objmgr_peer_component_obj_detach(peer, 752 WLAN_UMAC_COMP_CRYPTO, 753 (void *)crypto_priv); 754 wlan_crypto_free_key(&crypto_priv->crypto_key); 755 qdf_mem_free(crypto_priv); 756 757 return QDF_STATUS_SUCCESS; 758 } 759 760 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 761 static int register_psoc_create_handler(void) 762 { 763 QDF_STATUS status = QDF_STATUS_SUCCESS; 764 765 status = wlan_objmgr_register_psoc_create_handler( 766 WLAN_UMAC_COMP_CRYPTO, 767 wlan_crypto_psoc_obj_create_handler, 768 NULL); 769 return status; 770 } 771 772 static int register_psoc_destroy_handler(void) 773 { 774 QDF_STATUS status = QDF_STATUS_SUCCESS; 775 776 status = wlan_objmgr_register_psoc_destroy_handler( 777 WLAN_UMAC_COMP_CRYPTO, 778 wlan_crypto_psoc_obj_destroy_handler, 779 NULL); 780 return status; 781 } 782 783 static int unregister_psoc_create_handler(void) 784 { 785 QDF_STATUS status = QDF_STATUS_SUCCESS; 786 787 status = wlan_objmgr_unregister_psoc_create_handler( 788 WLAN_UMAC_COMP_CRYPTO, 789 wlan_crypto_psoc_obj_create_handler, 790 NULL); 791 return status; 792 } 793 794 static int unregister_psoc_destroy_handler(void) 795 { 796 QDF_STATUS status = QDF_STATUS_SUCCESS; 797 798 status = wlan_objmgr_unregister_psoc_destroy_handler( 799 WLAN_UMAC_COMP_CRYPTO, 800 wlan_crypto_psoc_obj_destroy_handler, 801 NULL); 802 return status; 803 } 804 805 #else 806 static int register_psoc_create_handler(void) 807 { 808 return QDF_STATUS_SUCCESS; 809 } 810 811 static int register_psoc_destroy_handler(void) 812 { 813 return QDF_STATUS_SUCCESS; 814 } 815 816 static int unregister_psoc_create_handler(void) 817 { 818 return QDF_STATUS_SUCCESS; 819 } 820 821 static int unregister_psoc_destroy_handler(void) 822 { 823 return QDF_STATUS_SUCCESS; 824 } 825 826 #endif 827 828 QDF_STATUS __wlan_crypto_init(void) 829 { 830 QDF_STATUS status = QDF_STATUS_SUCCESS; 831 832 /* Initialize crypto global lock*/ 833 qdf_mutex_create(&crypto_lock); 834 835 status = register_psoc_create_handler(); 836 if (QDF_IS_STATUS_ERROR(status)) { 837 crypto_err("psoc creation failure"); 838 return status; 839 } 840 841 status = wlan_objmgr_register_vdev_create_handler( 842 WLAN_UMAC_COMP_CRYPTO, 843 wlan_crypto_vdev_obj_create_handler, NULL); 844 if (status != QDF_STATUS_SUCCESS) 845 goto err_vdev_create; 846 847 status = wlan_objmgr_register_peer_create_handler( 848 WLAN_UMAC_COMP_CRYPTO, 849 wlan_crypto_peer_obj_create_handler, NULL); 850 if (status != QDF_STATUS_SUCCESS) 851 goto err_peer_create; 852 853 status = register_psoc_destroy_handler(); 854 if (QDF_IS_STATUS_ERROR(status)) { 855 crypto_err("psoc destroy failure"); 856 goto err_psoc_delete; 857 } 858 859 status = wlan_objmgr_register_vdev_destroy_handler( 860 WLAN_UMAC_COMP_CRYPTO, 861 wlan_crypto_vdev_obj_destroy_handler, NULL); 862 if (status != QDF_STATUS_SUCCESS) 863 goto err_vdev_delete; 864 865 status = wlan_objmgr_register_peer_destroy_handler( 866 WLAN_UMAC_COMP_CRYPTO, 867 wlan_crypto_peer_obj_destroy_handler, NULL); 868 if (status != QDF_STATUS_SUCCESS) 869 goto err_peer_delete; 870 871 goto register_success; 872 err_peer_delete: 873 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 874 wlan_crypto_vdev_obj_destroy_handler, NULL); 875 err_vdev_delete: 876 unregister_psoc_destroy_handler(); 877 err_psoc_delete: 878 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 879 wlan_crypto_peer_obj_create_handler, NULL); 880 err_peer_create: 881 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 882 wlan_crypto_vdev_obj_create_handler, NULL); 883 err_vdev_create: 884 unregister_psoc_create_handler(); 885 register_success: 886 return status; 887 } 888 889 QDF_STATUS __wlan_crypto_deinit(void) 890 { 891 if (unregister_psoc_create_handler() 892 != QDF_STATUS_SUCCESS) { 893 return QDF_STATUS_E_FAILURE; 894 } 895 896 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 897 wlan_crypto_vdev_obj_create_handler, NULL) 898 != QDF_STATUS_SUCCESS) { 899 return QDF_STATUS_E_FAILURE; 900 } 901 902 if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 903 wlan_crypto_peer_obj_create_handler, NULL) 904 != QDF_STATUS_SUCCESS) { 905 return QDF_STATUS_E_FAILURE; 906 } 907 908 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 909 wlan_crypto_vdev_obj_destroy_handler, NULL) 910 != QDF_STATUS_SUCCESS) { 911 return QDF_STATUS_E_FAILURE; 912 } 913 914 if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 915 wlan_crypto_peer_obj_destroy_handler, NULL) 916 != QDF_STATUS_SUCCESS) { 917 return QDF_STATUS_E_FAILURE; 918 } 919 920 if (unregister_psoc_destroy_handler() 921 != QDF_STATUS_SUCCESS) { 922 return QDF_STATUS_E_FAILURE; 923 } 924 925 /* Destroy crypto global lock */ 926 qdf_mutex_destroy(&crypto_lock); 927 928 return QDF_STATUS_SUCCESS; 929 } 930