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