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