xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c (revision f3d3f64f12c13ea69171f005888f79bf13e50340)
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