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