xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c (revision 87a8e4458319c60b618522e263ed900e36aab528)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19  /**
20  * DOC: Public APIs for crypto service
21  */
22 #include <qdf_types.h>
23 #include <wlan_cmn.h>
24 #include <wlan_objmgr_cmn.h>
25 #include <wlan_objmgr_global_obj.h>
26 #include <wlan_objmgr_psoc_obj.h>
27 #include <wlan_objmgr_pdev_obj.h>
28 #include <wlan_objmgr_vdev_obj.h>
29 #include <wlan_objmgr_peer_obj.h>
30 
31 #include "wlan_crypto_global_def.h"
32 #include "wlan_crypto_global_api.h"
33 #include "wlan_crypto_def_i.h"
34 #include "wlan_crypto_param_handling_i.h"
35 #include "wlan_crypto_obj_mgr_i.h"
36 
37 #include <qdf_module.h>
38 
39 
40 const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
41 
42 /**
43  * wlan_crypto_vdev_get_crypto_params - called by mlme to get crypto params
44  * @vdev:vdev
45  *
46  * This function gets called by mlme to get crypto params
47  *
48  * Return: wlan_crypto_params or NULL in case of failure
49  */
50 static struct wlan_crypto_params *wlan_crypto_vdev_get_comp_params(
51 				struct wlan_objmgr_vdev *vdev,
52 				struct wlan_crypto_comp_priv **crypto_priv){
53 	*crypto_priv = (struct wlan_crypto_comp_priv *)
54 					wlan_get_vdev_crypto_obj(vdev);
55 	if (*crypto_priv == NULL) {
56 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
57 		return NULL;
58 	}
59 
60 	return &((*crypto_priv)->crypto_params);
61 }
62 
63 /**
64  * wlan_crypto_peer_get_crypto_params - called by mlme to get crypto params
65  * @peer:peer
66  *
67  * This function gets called by mlme to get crypto params
68  *
69  * Return: wlan_crypto_params or NULL in case of failure
70  */
71 static struct wlan_crypto_params *wlan_crypto_peer_get_comp_params(
72 				struct wlan_objmgr_peer *peer,
73 				struct wlan_crypto_comp_priv **crypto_priv){
74 
75 	*crypto_priv = (struct wlan_crypto_comp_priv *)
76 					wlan_get_peer_crypto_obj(peer);
77 	if (*crypto_priv == NULL) {
78 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
79 		return NULL;
80 	}
81 
82 	return &((*crypto_priv)->crypto_params);
83 }
84 
85 static QDF_STATUS wlan_crypto_set_igtk_key(struct wlan_crypto_key *key)
86 {
87 	return QDF_STATUS_SUCCESS;
88 }
89 
90 /**
91  * wlan_crypto_set_param - called by ucfg to set crypto param
92  * @crypto_params: crypto_params
93  * @param: param to be set.
94  * @value: value
95  *
96  * This function gets called from ucfg to set param
97  *
98  * Return: QDF_STATUS_SUCCESS - in case of success
99  */
100 static QDF_STATUS wlan_crypto_set_param(struct wlan_crypto_params *crypto_params,
101 					wlan_crypto_param_type param,
102 					uint32_t value){
103 	QDF_STATUS status = QDF_STATUS_E_INVAL;
104 
105 	switch (param) {
106 	case WLAN_CRYPTO_PARAM_AUTH_MODE:
107 		status = wlan_crypto_set_authmode(crypto_params, value);
108 		break;
109 	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
110 		status = wlan_crypto_set_ucastciphers(crypto_params, value);
111 		break;
112 	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
113 		status = wlan_crypto_set_mcastcipher(crypto_params, value);
114 		break;
115 	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
116 		status = wlan_crypto_set_mgmtcipher(crypto_params, value);
117 		break;
118 	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
119 		status = wlan_crypto_set_cipher_cap(crypto_params, value);
120 		break;
121 	case WLAN_CRYPTO_PARAM_RSN_CAP:
122 		status = wlan_crypto_set_rsn_cap(crypto_params,	value);
123 		break;
124 	case WLAN_CRYPTO_PARAM_KEY_MGMT:
125 		status = wlan_crypto_set_key_mgmt(crypto_params, value);
126 		break;
127 	default:
128 		status = QDF_STATUS_E_INVAL;
129 	}
130 	return status;
131 }
132 
133 /**
134  * wlan_crypto_set_vdev_param - called by ucfg to set crypto param
135  * @vdev: vdev
136  * @param: param to be set.
137  * @value: value
138  *
139  * This function gets called from ucfg to set param
140  *
141  * Return: QDF_STATUS_SUCCESS - in case of success
142  */
143 QDF_STATUS wlan_crypto_set_vdev_param(struct wlan_objmgr_vdev *vdev,
144 					wlan_crypto_param_type param,
145 					uint32_t value){
146 	QDF_STATUS status = QDF_STATUS_E_INVAL;
147 	struct wlan_crypto_comp_priv *crypto_priv;
148 	struct wlan_crypto_params *crypto_params;
149 
150 	crypto_priv = (struct wlan_crypto_comp_priv *)
151 					wlan_get_vdev_crypto_obj(vdev);
152 
153 	if (crypto_priv == NULL) {
154 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
155 		return QDF_STATUS_E_INVAL;
156 	}
157 
158 	crypto_params = &(crypto_priv->crypto_params);
159 
160 	status = wlan_crypto_set_param(crypto_params, param, value);
161 
162 	return status;
163 }
164 
165 /**
166  * wlan_crypto_set_param - called by ucfg to set crypto param
167  *
168  * @peer: peer
169  * @param: param to be set.
170  * @value: value
171  *
172  * This function gets called from ucfg to set param
173  *
174  * Return: QDF_STATUS_SUCCESS - in case of success
175  */
176 QDF_STATUS wlan_crypto_set_peer_param(struct wlan_objmgr_peer *peer,
177 				wlan_crypto_param_type param,
178 				uint32_t value){
179 	QDF_STATUS status = QDF_STATUS_E_INVAL;
180 	struct wlan_crypto_comp_priv *crypto_priv;
181 	struct wlan_crypto_params *crypto_params;
182 
183 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
184 							&crypto_priv);
185 
186 	if (crypto_priv == NULL) {
187 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
188 		return QDF_STATUS_E_INVAL;
189 	}
190 
191 	crypto_params = &(crypto_priv->crypto_params);
192 
193 	status = wlan_crypto_set_param(crypto_params, param, value);
194 
195 	return status;
196 }
197 
198 /**
199  * wlan_crypto_get_param_value - called by crypto APIs to get value for param
200  * @param: Crypto param type
201  * @crypto_params: Crypto params struct
202  *
203  * This function gets called from in-within crypto layer
204  *
205  * Return: value or -1 for failure
206  */
207 static int32_t wlan_crypto_get_param_value(wlan_crypto_param_type param,
208 				struct wlan_crypto_params *crypto_params)
209 {
210 	int32_t value = -1;
211 
212 	switch (param) {
213 	case WLAN_CRYPTO_PARAM_AUTH_MODE:
214 		value = wlan_crypto_get_authmode(crypto_params);
215 		break;
216 	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
217 		value = wlan_crypto_get_ucastciphers(crypto_params);
218 		break;
219 	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
220 		value = wlan_crypto_get_mcastcipher(crypto_params);
221 		break;
222 	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
223 		value = wlan_crypto_get_mgmtciphers(crypto_params);
224 		break;
225 	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
226 		value = wlan_crypto_get_cipher_cap(crypto_params);
227 		break;
228 	case WLAN_CRYPTO_PARAM_RSN_CAP:
229 		value = wlan_crypto_get_rsn_cap(crypto_params);
230 		break;
231 	case WLAN_CRYPTO_PARAM_KEY_MGMT:
232 		value = wlan_crypto_get_key_mgmt(crypto_params);
233 		break;
234 	default:
235 		value = QDF_STATUS_E_INVAL;
236 	}
237 
238 	return value;
239 }
240 
241 /**
242  * wlan_crypto_get_param - called to get value for param from vdev
243  * @vdev:  vdev
244  * @param: Crypto param type
245  *
246  * This function gets called to get value for param from vdev
247  *
248  * Return: value or -1 for failure
249  */
250 int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev,
251 			      wlan_crypto_param_type param)
252 {
253 	int32_t value = -1;
254 	struct wlan_crypto_comp_priv *crypto_priv;
255 	struct wlan_crypto_params *crypto_params;
256 	crypto_priv = (struct wlan_crypto_comp_priv *)
257 				wlan_get_vdev_crypto_obj(vdev);
258 
259 	if (crypto_priv == NULL) {
260 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
261 		return QDF_STATUS_E_INVAL;
262 	}
263 
264 	crypto_params = &(crypto_priv->crypto_params);
265 	value = wlan_crypto_get_param_value(param, crypto_params);
266 
267 	return value;
268 }
269 /**
270  * wlan_crypto_get_peer_param - called to get value for param from peer
271  * @peer:  peer
272  * @param: Crypto param type
273  *
274  * This function gets called to get value for param from peer
275  *
276  * Return: value or -1 for failure
277  */
278 int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer,
279 				   wlan_crypto_param_type param)
280 {
281 	int32_t value = -1;
282 	struct wlan_crypto_comp_priv *crypto_priv;
283 	struct wlan_crypto_params *crypto_params;
284 
285 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
286 							&crypto_priv);
287 
288 	if (crypto_params == NULL) {
289 		qdf_print("%s[%d] crypto_params NULL", __func__, __LINE__);
290 		return QDF_STATUS_E_INVAL;
291 	}
292 	value = wlan_crypto_get_param_value(param, crypto_params);
293 
294 	return value;
295 }
296 qdf_export_symbol(wlan_crypto_get_peer_param);
297 /**
298  * wlan_crypto_is_htallowed - called to check is HT allowed for cipher
299  * @vdev:  vdev
300  * @peer:  peer
301  *
302  * This function gets called to check is HT allowed for cipher.
303  * HT is not allowed for wep and tkip.
304  *
305  * Return: 0 - not allowed or 1 - allowed
306  */
307 uint8_t wlan_crypto_is_htallowed(struct wlan_objmgr_vdev *vdev,
308 				 struct wlan_objmgr_peer *peer)
309 {
310 	int32_t ucast_cipher;
311 
312 	if (!(vdev || peer)) {
313 		qdf_print("%s[%d] Invalid params", __func__, __LINE__);
314 		return 0;
315 	}
316 
317 	if (vdev)
318 		ucast_cipher = wlan_crypto_get_param(vdev,
319 				WLAN_CRYPTO_PARAM_UCAST_CIPHER);
320 	else
321 		ucast_cipher = wlan_crypto_get_peer_param(peer,
322 				WLAN_CRYPTO_PARAM_UCAST_CIPHER);
323 
324 	return (ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_WEP)) ||
325 		((ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_TKIP)) &&
326 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM)) &&
327 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM)) &&
328 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM_256)) &&
329 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM_256)));
330 }
331 qdf_export_symbol(wlan_crypto_is_htallowed);
332 
333 /**
334  * wlan_crypto_setkey - called by ucfg to setkey
335  * @vdev: vdev
336  * @req_key: req_key with cipher type, key macaddress
337  *
338  * This function gets called from ucfg to sey key
339  *
340  * Return: QDF_STATUS_SUCCESS - in case of success
341  */
342 QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
343 				struct wlan_crypto_req_key *req_key){
344 
345 	QDF_STATUS status = QDF_STATUS_E_INVAL;
346 	struct wlan_crypto_comp_priv *crypto_priv;
347 	struct wlan_crypto_params *crypto_params;
348 	struct wlan_objmgr_psoc *psoc;
349 	struct wlan_objmgr_peer *peer;
350 	struct wlan_crypto_key *key = NULL;
351 	const struct wlan_crypto_cipher *cipher;
352 	uint8_t macaddr[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
353 	bool isbcast;
354 	enum QDF_OPMODE vdev_mode;
355 	uint8_t igtk_idx = 0;
356 
357 	if (!vdev || !req_key || req_key->keylen > (sizeof(req_key->keydata))) {
358 		qdf_print("%s[%d] Invalid params vdev%pK, req_key%pK",
359 			  __func__, __LINE__, vdev, req_key);
360 		return QDF_STATUS_E_INVAL;
361 	}
362 
363 	isbcast = qdf_is_macaddr_group(
364 				(struct qdf_mac_addr *)req_key->macaddr);
365 	if ((req_key->keylen == 0) && !IS_FILS_CIPHER(req_key->type)) {
366 		/* zero length keys, only set default key id if flags are set*/
367 		if ((req_key->flags & WLAN_CRYPTO_KEY_DEFAULT)
368 			&& (req_key->keyix != WLAN_CRYPTO_KEYIX_NONE)
369 			&& (!IS_MGMT_CIPHER(req_key->type))) {
370 			wlan_crypto_default_key(vdev,
371 				req_key->macaddr,
372 				req_key->keyix,
373 				!isbcast);
374 			return QDF_STATUS_SUCCESS;
375 		}
376 		qdf_print("%s[%d] req_key len zero", __func__, __LINE__);
377 		return QDF_STATUS_E_INVAL;
378 	}
379 
380 	cipher = wlan_crypto_cipher_ops[req_key->type];
381 
382 	if (!cipher && !IS_MGMT_CIPHER(req_key->type)) {
383 		qdf_print("%s[%d] cipher invalid", __func__, __LINE__);
384 		return QDF_STATUS_E_INVAL;
385 	}
386 
387 	if (cipher && (!IS_FILS_CIPHER(req_key->type)) &&
388 	    (!IS_MGMT_CIPHER(req_key->type)) &&
389 	    ((req_key->keylen != (cipher->keylen / CRYPTO_NBBY)) &&
390 	    (req_key->type != WLAN_CRYPTO_CIPHER_WEP))) {
391 		qdf_print("%s[%d] cipher invalid", __func__, __LINE__);
392 		return QDF_STATUS_E_INVAL;
393 	} else if ((req_key->type == WLAN_CRYPTO_CIPHER_WEP) &&
394 		!((req_key->keylen == WLAN_CRYPTO_KEY_WEP40_LEN)
395 		|| (req_key->keylen == WLAN_CRYPTO_KEY_WEP104_LEN)
396 		|| (req_key->keylen == WLAN_CRYPTO_KEY_WEP128_LEN))) {
397 		qdf_print("%s[%d] wep key len invalid", __func__, __LINE__);
398 		return QDF_STATUS_E_INVAL;
399 	}
400 
401 	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE) {
402 		if (req_key->flags != (WLAN_CRYPTO_KEY_XMIT
403 						| WLAN_CRYPTO_KEY_RECV)) {
404 			req_key->flags |= (WLAN_CRYPTO_KEY_XMIT
405 						| WLAN_CRYPTO_KEY_RECV);
406 		}
407 	} else {
408 		if ((req_key->keyix >= WLAN_CRYPTO_MAXKEYIDX)
409 			&& (!IS_MGMT_CIPHER(req_key->type))) {
410 			return QDF_STATUS_E_INVAL;
411 		}
412 
413 		req_key->flags |= (WLAN_CRYPTO_KEY_XMIT
414 					| WLAN_CRYPTO_KEY_RECV);
415 		if (isbcast)
416 			req_key->flags |= WLAN_CRYPTO_KEY_GROUP;
417 	}
418 
419 	vdev_mode = wlan_vdev_mlme_get_opmode(vdev);
420 
421 	wlan_vdev_obj_lock(vdev);
422 	qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
423 	psoc = wlan_vdev_get_psoc(vdev);
424 	if (!psoc) {
425 		wlan_vdev_obj_unlock(vdev);
426 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
427 		return QDF_STATUS_E_INVAL;
428 	}
429 	wlan_vdev_obj_unlock(vdev);
430 
431 	if (req_key->type == WLAN_CRYPTO_CIPHER_WEP) {
432 		if (wlan_crypto_vdev_has_auth_mode(vdev,
433 					(1 << WLAN_CRYPTO_AUTH_8021X))) {
434 			req_key->flags |= WLAN_CRYPTO_KEY_DEFAULT;
435 		}
436 	}
437 
438 	if (isbcast) {
439 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
440 								&crypto_priv);
441 		if (crypto_priv == NULL) {
442 			qdf_print("%s[%d] crypto_priv NULL",
443 				  __func__, __LINE__);
444 			return QDF_STATUS_E_INVAL;
445 		}
446 
447 		if (IS_MGMT_CIPHER(req_key->type)) {
448 			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
449 			if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
450 				qdf_print("%s[%d] igtk key invalid keyid %d ",
451 					  __func__, __LINE__, igtk_idx);
452 				return QDF_STATUS_E_INVAL;
453 			}
454 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
455 			if (key == NULL) {
456 				qdf_print("%s[%d] igtk key alloc failed",
457 					  __func__, __LINE__);
458 				return QDF_STATUS_E_NOMEM;
459 			}
460 
461 			if (crypto_priv->igtk_key[igtk_idx])
462 				qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
463 
464 			crypto_priv->igtk_key[igtk_idx] = key;
465 			crypto_priv->igtk_key_type = req_key->type;
466 			crypto_priv->def_igtk_tx_keyid = igtk_idx;
467 		} else {
468 			if (IS_FILS_CIPHER(req_key->type)) {
469 				qdf_err("FILS key is not for BroadCast pkt");
470 				return QDF_STATUS_E_INVAL;
471 			}
472 			if (!HAS_MCAST_CIPHER(crypto_params, req_key->type)
473 				&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP)) {
474 				return QDF_STATUS_E_INVAL;
475 			}
476 			if (!crypto_priv->key[req_key->keyix]) {
477 				crypto_priv->key[req_key->keyix]
478 					= qdf_mem_malloc(
479 						sizeof(struct wlan_crypto_key));
480 				if (!crypto_priv->key[req_key->keyix])
481 					return QDF_STATUS_E_NOMEM;
482 			}
483 			key = crypto_priv->key[req_key->keyix];
484 		}
485 		if (vdev_mode == QDF_STA_MODE) {
486 			peer = wlan_vdev_get_bsspeer(vdev);
487 			if (!(peer && (QDF_STATUS_SUCCESS
488 				== wlan_objmgr_peer_try_get_ref(peer,
489 							WLAN_CRYPTO_ID)))) {
490 				qdf_print("%s[%d] peer %pK failed",
491 					  __func__, __LINE__, peer);
492 				if (IS_MGMT_CIPHER(req_key->type)) {
493 					crypto_priv->igtk_key[igtk_idx] = NULL;
494 					crypto_priv->igtk_key_type
495 						= WLAN_CRYPTO_CIPHER_NONE;
496 				} else
497 					crypto_priv->key[req_key->keyix] = NULL;
498 				if (key)
499 					qdf_mem_free(key);
500 				return QDF_STATUS_E_INVAL;
501 			}
502 			qdf_mem_copy(macaddr, wlan_peer_get_macaddr(peer),
503 						WLAN_ALEN);
504 			wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
505 		}
506 	} else {
507 		uint8_t pdev_id;
508 
509 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
510 				wlan_vdev_get_pdev(vdev));
511 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
512 					psoc,
513 					pdev_id,
514 					macaddr,
515 					req_key->macaddr,
516 					WLAN_CRYPTO_ID);
517 
518 		if (peer == NULL) {
519 			qdf_print("%s[%d] peer NULL", __func__, __LINE__);
520 			return QDF_STATUS_E_INVAL;
521 		}
522 
523 		qdf_mem_copy(macaddr, req_key->macaddr, WLAN_ALEN);
524 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
525 								&crypto_priv);
526 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
527 
528 		if (crypto_priv == NULL) {
529 			qdf_print("%s[%d] crypto_priv NULL",
530 				  __func__, __LINE__);
531 			return QDF_STATUS_E_INVAL;
532 		}
533 		if (IS_MGMT_CIPHER(req_key->type)) {
534 			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
535 			if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
536 				qdf_print("%s[%d] igtk key invalid keyid %d ",
537 					  __func__, __LINE__, igtk_idx);
538 				return QDF_STATUS_E_INVAL;
539 			}
540 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
541 			if (key == NULL) {
542 				qdf_print("%s[%d] igtk key alloc failed",
543 					  __func__, __LINE__);
544 				return QDF_STATUS_E_NOMEM;
545 			}
546 			if (crypto_priv->igtk_key[igtk_idx])
547 				qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
548 
549 			crypto_priv->igtk_key[igtk_idx] = key;
550 			crypto_priv->igtk_key_type = req_key->type;
551 			crypto_priv->def_igtk_tx_keyid = igtk_idx;
552 		} else {
553 			uint16_t kid = req_key->keyix;
554 			if (kid == WLAN_CRYPTO_KEYIX_NONE)
555 				kid = 0;
556 			if (kid >= WLAN_CRYPTO_MAXKEYIDX) {
557 				qdf_print("%s[%d] invalid keyid %d ",
558 					  __func__, __LINE__, kid);
559 				return QDF_STATUS_E_INVAL;
560 			}
561 			if (!crypto_priv->key[kid]) {
562 				crypto_priv->key[kid]
563 					= qdf_mem_malloc(
564 						sizeof(struct wlan_crypto_key));
565 				if (!crypto_priv->key[kid])
566 					return QDF_STATUS_E_NOMEM;
567 			}
568 			key = crypto_priv->key[kid];
569 		}
570 	}
571 
572 	/* alloc key might not required as it is already there */
573 	key->cipher_table = (void *)cipher;
574 	key->keylen = req_key->keylen;
575 	key->flags = req_key->flags;
576 
577 	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE)
578 		key->keyix = 0;
579 	else
580 		key->keyix = req_key->keyix;
581 
582 	if (req_key->flags & WLAN_CRYPTO_KEY_DEFAULT
583 		&& (!IS_MGMT_CIPHER(req_key->type)))  {
584 		crypto_priv->def_tx_keyid = key->keyix;
585 		key->flags |= WLAN_CRYPTO_KEY_DEFAULT;
586 	}
587 	if ((req_key->type == WLAN_CRYPTO_CIPHER_WAPI_SMS4)
588 		|| (req_key->type == WLAN_CRYPTO_CIPHER_WAPI_GCM4)) {
589 		uint8_t iv_AP[16] = {	0x5c, 0x36, 0x5c, 0x36,
590 					0x5c, 0x36, 0x5c, 0x36,
591 					0x5c, 0x36, 0x5c, 0x36,
592 					0x5c, 0x36, 0x5c, 0x37};
593 		uint8_t iv_STA[16] = {	0x5c, 0x36, 0x5c, 0x36,
594 					0x5c, 0x36, 0x5c, 0x36,
595 					0x5c, 0x36, 0x5c, 0x36,
596 					0x5c, 0x36, 0x5c, 0x36};
597 
598 		/* During Tx PN should be increment and
599 		 * send but as per our implementation we increment only after
600 		 * Tx complete. So First packet PN check will be failed.
601 		 * To compensate increment the PN here by 2
602 		 */
603 		if (vdev_mode == QDF_SAP_MODE) {
604 			iv_AP[15] += 2;
605 			qdf_mem_copy(key->recviv, iv_STA,
606 						WLAN_CRYPTO_WAPI_IV_SIZE);
607 			qdf_mem_copy(key->txiv, iv_AP,
608 						WLAN_CRYPTO_WAPI_IV_SIZE);
609 		} else {
610 			iv_STA[15] += 2;
611 			qdf_mem_copy(key->recviv, iv_AP,
612 						WLAN_CRYPTO_WAPI_IV_SIZE);
613 			qdf_mem_copy(key->txiv, iv_STA,
614 						WLAN_CRYPTO_WAPI_IV_SIZE);
615 		}
616 	} else {
617 		uint8_t i = 0;
618 		qdf_mem_copy((uint8_t *)(&key->keytsc),
619 			(uint8_t *)(&req_key->keytsc), sizeof(key->keytsc));
620 		for (i = 0; i < WLAN_CRYPTO_TID_SIZE; i++) {
621 			qdf_mem_copy((uint8_t *)(&key->keyrsc[i]),
622 					(uint8_t *)(&req_key->keyrsc),
623 					sizeof(key->keyrsc[0]));
624 		}
625 	}
626 
627 	qdf_mem_copy(key->keyval, req_key->keydata, sizeof(key->keyval));
628 	key->valid = 1;
629 	if ((IS_MGMT_CIPHER(req_key->type))) {
630 		if (HAS_CIPHER_CAP(crypto_params,
631 					WLAN_CRYPTO_CAP_PMF_OFFLOAD)) {
632 			if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
633 				WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev,
634 						key, macaddr, req_key->type);
635 			}
636 		}
637 		wlan_crypto_set_mgmtcipher(crypto_params, req_key->type);
638 		status = wlan_crypto_set_igtk_key(key);
639 		return status;
640 	} else if (IS_FILS_CIPHER(req_key->type)) {
641 		/* Take request key object to FILS setkey */
642 		key->private = req_key;
643 	} else {
644 		if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
645 			WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev, key,
646 							macaddr, req_key->type);
647 		}
648 	}
649 	status = cipher->setkey(key);
650 
651 	if ((req_key->flags & WLAN_CRYPTO_KEY_DEFAULT) &&
652 	    (req_key->keyix != WLAN_CRYPTO_KEYIX_NONE) &&
653 	    (!IS_MGMT_CIPHER(req_key->type))) {
654 		/* default xmit key */
655 		wlan_crypto_default_key(vdev,
656 					req_key->macaddr,
657 					req_key->keyix,
658 					!isbcast);
659 		}
660 
661 	return status;
662 }
663 
664 /**
665  * wlan_crypto_get_keytype - get keytype
666  * @key: key
667  *
668  * This function gets keytype from key
669  *
670  * Return: keytype
671  */
672 wlan_crypto_cipher_type wlan_crypto_get_key_type(
673 						struct wlan_crypto_key *key){
674 	if (key && key->cipher_table) {
675 		return ((struct wlan_crypto_cipher *)
676 						(key->cipher_table))->cipher;
677 	}
678 	return WLAN_CRYPTO_CIPHER_NONE;
679 }
680 qdf_export_symbol(wlan_crypto_get_key_type);
681 /**
682  * wlan_crypto_vdev_getkey - get key from vdev
683  * @vdev: vdev
684  * @keyix: keyix
685  *
686  * This function gets key from vdev
687  *
688  * Return: key or NULL
689  */
690 struct wlan_crypto_key *wlan_crypto_vdev_getkey(struct wlan_objmgr_vdev *vdev,
691 						uint16_t keyix){
692 	struct wlan_crypto_comp_priv *crypto_priv;
693 	struct wlan_crypto_params *crypto_params;
694 	struct wlan_crypto_key *key = NULL;
695 
696 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
697 
698 	if (crypto_priv == NULL) {
699 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
700 		return NULL;
701 	}
702 
703 	if (keyix == WLAN_CRYPTO_KEYIX_NONE || keyix >= WLAN_CRYPTO_MAXKEYIDX)
704 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
705 	else
706 		key = crypto_priv->key[keyix];
707 
708 	if (key && key->valid)
709 		return key;
710 
711 	return NULL;
712 }
713 qdf_export_symbol(wlan_crypto_vdev_getkey);
714 
715 /**
716  * wlan_crypto_peer_getkey - get key from peer
717  * @peer: peer
718  * @keyix: keyix
719  *
720  * This function gets key from peer
721  *
722  * Return: key or NULL
723  */
724 struct wlan_crypto_key *wlan_crypto_peer_getkey(struct wlan_objmgr_peer *peer,
725 						uint16_t keyix){
726 	struct wlan_crypto_comp_priv *crypto_priv;
727 	struct wlan_crypto_params *crypto_params;
728 	struct wlan_crypto_key *key = NULL;
729 
730 	crypto_params = wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
731 
732 	if (crypto_priv == NULL) {
733 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
734 		return NULL;
735 	}
736 
737 	if (keyix == WLAN_CRYPTO_KEYIX_NONE || keyix >= WLAN_CRYPTO_MAXKEYIDX)
738 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
739 	else
740 		key = crypto_priv->key[keyix];
741 
742 	if (key && key->valid)
743 		return key;
744 
745 	return NULL;
746 }
747 qdf_export_symbol(wlan_crypto_peer_getkey);
748 
749 /**
750  * wlan_crypto_getkey - called by ucfg to get key
751  * @vdev: vdev
752  * @req_key: key value will be copied in this req_key
753  * @mac_address: mac address of the peer for unicast key
754  *			       or broadcast address if group key is requested.
755  *
756  * This function gets called from ucfg to get key
757  *
758  * Return: QDF_STATUS_SUCCESS - in case of success
759  */
760 QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
761 				struct wlan_crypto_req_key *req_key,
762 				uint8_t *mac_addr){
763 	struct wlan_crypto_cipher *cipher_table;
764 	struct wlan_crypto_key *key;
765 	struct wlan_objmgr_psoc *psoc;
766 	uint8_t macaddr[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
767 
768 	if ((req_key->keyix != WLAN_CRYPTO_KEYIX_NONE) &&
769 		(req_key->keyix >= WLAN_CRYPTO_MAXKEYIDX)) {
770 		qdf_print("%s[%d] invalid keyix %d", __func__, __LINE__,
771 			  req_key->keyix);
772 		return QDF_STATUS_E_INVAL;
773 	}
774 
775 	wlan_vdev_obj_lock(vdev);
776 	qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
777 	psoc = wlan_vdev_get_psoc(vdev);
778 	if (!psoc) {
779 		wlan_vdev_obj_unlock(vdev);
780 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
781 		return QDF_STATUS_E_INVAL;
782 	}
783 	wlan_vdev_obj_unlock(vdev);
784 
785 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
786 		key = wlan_crypto_vdev_getkey(vdev, req_key->keyix);
787 		if (!key)
788 			return QDF_STATUS_E_INVAL;
789 	} else {
790 		struct wlan_objmgr_peer *peer;
791 		uint8_t pdev_id;
792 
793 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
794 				wlan_vdev_get_pdev(vdev));
795 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
796 					psoc,
797 					pdev_id,
798 					macaddr,
799 					mac_addr,
800 					WLAN_CRYPTO_ID);
801 		if (peer == NULL) {
802 			QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
803 				"%s[%d] peer NULL", __func__, __LINE__);
804 			return QDF_STATUS_E_NOENT;
805 		}
806 		key = wlan_crypto_peer_getkey(peer, req_key->keyix);
807 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
808 		if (!key)
809 			return QDF_STATUS_E_INVAL;
810 	}
811 
812 	if (key->valid) {
813 		qdf_mem_copy(req_key->keydata,
814 				key->keyval, key->keylen);
815 		qdf_mem_copy((uint8_t *)(&req_key->keytsc),
816 				(uint8_t *)(&key->keytsc),
817 				sizeof(req_key->keytsc));
818 		qdf_mem_copy((uint8_t *)(&req_key->keyrsc),
819 				(uint8_t *)(&key->keyrsc[0]),
820 				sizeof(req_key->keyrsc));
821 		req_key->keylen = key->keylen;
822 		req_key->flags = key->flags;
823 		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
824 
825 		if (!cipher_table)
826 			return QDF_STATUS_SUCCESS;
827 
828 		req_key->type = cipher_table->cipher;
829 		if (req_key->type == WLAN_CRYPTO_CIPHER_WAPI_SMS4) {
830 			qdf_mem_copy((uint8_t *)(&req_key->txiv),
831 					(uint8_t *)(key->txiv),
832 					sizeof(req_key->txiv));
833 			qdf_mem_copy((uint8_t *)(&req_key->recviv),
834 					(uint8_t *)(key->recviv),
835 					sizeof(req_key->recviv));
836 		}
837 	}
838 
839 	return QDF_STATUS_SUCCESS;
840 }
841 
842 /**
843  * wlan_crypto_delkey - called by ucfg to delete key
844  * @vdev: vdev
845  * @mac_address: mac address of the peer for unicast key
846  *                or broadcast address if group key is deleted.
847  * @key_idx: key index to be deleted
848  *
849  * This function gets called from ucfg to delete key
850  *
851  * Return: QDF_STATUS_SUCCESS - in case of success
852  */
853 QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
854 				uint8_t *macaddr,
855 				uint8_t key_idx){
856 	struct wlan_crypto_comp_priv *crypto_priv;
857 	struct wlan_crypto_params *crypto_params;
858 	struct wlan_crypto_key *key;
859 	struct wlan_crypto_cipher *cipher_table;
860 	struct wlan_objmgr_psoc *psoc;
861 	uint8_t bssid_mac[WLAN_ALEN];
862 
863 	if (!vdev || !macaddr ||
864 		(key_idx >=
865 			(WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))) {
866 			QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
867 				  "%s[%d] Invalid params vdev %pK, macaddr %pK, keyidx %d",
868 				  __func__, __LINE__, vdev,
869 				  macaddr, key_idx);
870 		return QDF_STATUS_E_INVAL;
871 	}
872 
873 	wlan_vdev_obj_lock(vdev);
874 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
875 	psoc = wlan_vdev_get_psoc(vdev);
876 	if (!psoc) {
877 		wlan_vdev_obj_unlock(vdev);
878 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
879 		return QDF_STATUS_E_INVAL;
880 	}
881 	wlan_vdev_obj_unlock(vdev);
882 
883 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
884 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
885 								&crypto_priv);
886 		if (crypto_priv == NULL) {
887 			qdf_print("%s[%d] crypto_priv NULL",
888 				  __func__, __LINE__);
889 			return QDF_STATUS_E_INVAL;
890 		}
891 	} else {
892 		struct wlan_objmgr_peer *peer;
893 		uint8_t pdev_id;
894 
895 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
896 				wlan_vdev_get_pdev(vdev));
897 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
898 				psoc, pdev_id,
899 				bssid_mac,
900 				macaddr,
901 				WLAN_CRYPTO_ID);
902 		if (peer == NULL) {
903 			return QDF_STATUS_E_INVAL;
904 		}
905 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
906 								&crypto_priv);
907 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
908 		if (crypto_priv == NULL) {
909 			qdf_print("%s[%d] crypto_priv NULL",
910 				  __func__, __LINE__);
911 			return QDF_STATUS_E_INVAL;
912 		}
913 	}
914 
915 	if (key_idx >= WLAN_CRYPTO_MAXKEYIDX) {
916 		uint8_t igtk_idx = key_idx - WLAN_CRYPTO_MAXKEYIDX;
917 		if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
918 			qdf_print("%s[%d] Igtk key invalid keyid %d",
919 				  __func__, __LINE__, igtk_idx);
920 			return QDF_STATUS_E_INVAL;
921 		}
922 		key = crypto_priv->igtk_key[igtk_idx];
923 		crypto_priv->igtk_key[igtk_idx] = NULL;
924 		if (key)
925 			key->valid = 0;
926 	} else {
927 		key = crypto_priv->key[key_idx];
928 		crypto_priv->key[key_idx] = NULL;
929 	}
930 
931 	if (!key)
932 		return QDF_STATUS_E_INVAL;
933 
934 	if (key->valid) {
935 		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
936 
937 		if (WLAN_CRYPTO_TX_OPS_DELKEY(psoc)) {
938 			WLAN_CRYPTO_TX_OPS_DELKEY(psoc)(vdev, key,
939 						macaddr, cipher_table->cipher);
940 		}
941 	}
942 	qdf_mem_free(key);
943 
944 	return QDF_STATUS_SUCCESS;
945 }
946 
947 /**
948  * wlan_crypto_default_key - called by ucfg to set default tx key
949  * @vdev: vdev
950  * @mac_address: mac address of the peer for unicast key
951  *            or broadcast address if group key need to made default.
952  * @key_idx: key index to be made as default key
953  * @unicast: is key was unicast or group key.
954  *
955  * This function gets called from ucfg to set default key
956  *
957  * Return: QDF_STATUS_SUCCESS - in case of success
958  */
959 QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev,
960 					uint8_t *macaddr,
961 					uint8_t key_idx,
962 					bool unicast){
963 	struct wlan_crypto_comp_priv *crypto_priv;
964 	struct wlan_crypto_params *crypto_params;
965 	struct wlan_crypto_key *key;
966 	struct wlan_objmgr_psoc *psoc;
967 	uint8_t bssid_mac[WLAN_ALEN];
968 
969 	if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) {
970 		qdf_print("%s[%d] Invalid params vdev %pK, macaddr %pK keyidx %d",
971 			  __func__, __LINE__,
972 			  vdev, macaddr, key_idx);
973 		return QDF_STATUS_E_INVAL;
974 	}
975 
976 	wlan_vdev_obj_lock(vdev);
977 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
978 	psoc = wlan_vdev_get_psoc(vdev);
979 	if (!psoc) {
980 		wlan_vdev_obj_unlock(vdev);
981 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
982 		return QDF_STATUS_E_INVAL;
983 	}
984 	wlan_vdev_obj_unlock(vdev);
985 
986 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
987 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
988 								&crypto_priv);
989 		if (crypto_priv == NULL) {
990 			qdf_print("%s[%d] crypto_priv NULL",
991 				  __func__, __LINE__);
992 			return QDF_STATUS_E_INVAL;
993 		}
994 
995 		key = crypto_priv->key[key_idx];
996 		if (!key)
997 			return QDF_STATUS_E_INVAL;
998 	} else {
999 		struct wlan_objmgr_peer *peer;
1000 		uint8_t pdev_id;
1001 
1002 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1003 				wlan_vdev_get_pdev(vdev));
1004 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1005 				psoc, pdev_id,
1006 				bssid_mac,
1007 				macaddr,
1008 				WLAN_CRYPTO_ID);
1009 
1010 		if (peer == NULL) {
1011 			qdf_print("%s[%d] peer NULL", __func__, __LINE__);
1012 			return QDF_STATUS_E_INVAL;
1013 		}
1014 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1015 								&crypto_priv);
1016 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1017 		if (crypto_priv == NULL) {
1018 			qdf_print("%s[%d] crypto_priv NULL",
1019 				  __func__, __LINE__);
1020 			return QDF_STATUS_E_INVAL;
1021 		}
1022 
1023 		key = crypto_priv->key[key_idx];
1024 		if (!key)
1025 			return QDF_STATUS_E_INVAL;
1026 	}
1027 	if (!key->valid)
1028 		return QDF_STATUS_E_INVAL;
1029 
1030 	if (WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)) {
1031 		WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)(vdev, key_idx,
1032 						macaddr);
1033 	}
1034 	crypto_priv->def_tx_keyid = key_idx;
1035 
1036 	return QDF_STATUS_SUCCESS;
1037 }
1038 
1039 /**
1040  * wlan_crypto_encap - called by mgmt for encap the frame based on cipher
1041  * @vdev: vdev
1042  * @wbuf: wbuf
1043  * @macaddr: macaddr
1044  * @encapdone: is encapdone already or not.
1045  *
1046  * This function gets called from mgmt txrx to encap frame.
1047  *
1048  * Return: QDF_STATUS_SUCCESS - in case of success
1049  */
1050 QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
1051 				qdf_nbuf_t wbuf,
1052 				uint8_t *mac_addr,
1053 				uint8_t encapdone){
1054 	struct wlan_crypto_comp_priv *crypto_priv;
1055 	struct wlan_crypto_params *crypto_params;
1056 	struct wlan_crypto_key *key;
1057 	QDF_STATUS status;
1058 	struct wlan_crypto_cipher *cipher_table;
1059 	struct wlan_objmgr_psoc *psoc;
1060 	struct wlan_objmgr_peer *peer;
1061 	uint8_t bssid_mac[WLAN_ALEN];
1062 	uint8_t pdev_id;
1063 	uint8_t hdrlen;
1064 	enum QDF_OPMODE opmode;
1065 
1066 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1067 	wlan_vdev_obj_lock(vdev);
1068 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
1069 	psoc = wlan_vdev_get_psoc(vdev);
1070 	if (!psoc) {
1071 		wlan_vdev_obj_unlock(vdev);
1072 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
1073 		return QDF_STATUS_E_INVAL;
1074 	}
1075 	wlan_vdev_obj_unlock(vdev);
1076 
1077 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
1078 	/* FILS Encap required only for (Re-)Assoc response */
1079 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_CRYPTO_ID);
1080 
1081 	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)) &&
1082 	    peer && !wlan_crypto_get_peer_fils_aead(peer)) {
1083 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1084 		return QDF_STATUS_E_INVAL;
1085 	}
1086 
1087 	if (peer)
1088 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1089 
1090 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)mac_addr)) {
1091 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1092 								&crypto_priv);
1093 		if (crypto_priv == NULL) {
1094 			qdf_print("%s[%d] crypto_priv NULL",
1095 				  __func__, __LINE__);
1096 			return QDF_STATUS_E_INVAL;
1097 		}
1098 
1099 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
1100 		if (!key)
1101 			return QDF_STATUS_E_INVAL;
1102 
1103 	} else {
1104 		struct wlan_objmgr_peer *peer;
1105 		uint8_t pdev_id;
1106 
1107 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1108 				wlan_vdev_get_pdev(vdev));
1109 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(psoc, pdev_id,
1110 							  bssid_mac, mac_addr,
1111 							  WLAN_CRYPTO_ID);
1112 
1113 		if (peer == NULL) {
1114 			qdf_print("%s[%d] crypto_priv NULL",
1115 				  __func__, __LINE__);
1116 			return QDF_STATUS_E_INVAL;
1117 		}
1118 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1119 								&crypto_priv);
1120 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1121 
1122 		if (crypto_priv == NULL) {
1123 			qdf_print("%s[%d] crypto_priv NULL",
1124 				  __func__, __LINE__);
1125 			return QDF_STATUS_E_INVAL;
1126 		}
1127 
1128 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
1129 		if (!key)
1130 			return QDF_STATUS_E_INVAL;
1131 	}
1132 	if (opmode == QDF_MONITOR_MODE)
1133 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1134 	else
1135 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1136 					    (uint8_t *)qdf_nbuf_data(wbuf));
1137 
1138 	/* if tkip, is counter measures enabled, then drop the frame */
1139 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1140 	status = cipher_table->encap(key, wbuf, encapdone,
1141 				     hdrlen);
1142 
1143 	return status;
1144 }
1145 qdf_export_symbol(wlan_crypto_encap);
1146 
1147 /**
1148  * wlan_crypto_decap - called by mgmt for decap the frame based on cipher
1149  * @vdev: vdev
1150  * @wbuf: wbuf
1151  * @macaddr: macaddr
1152  * @tid: tid of the frame
1153  *
1154  * This function gets called from mgmt txrx to decap frame.
1155  *
1156  * Return: QDF_STATUS_SUCCESS - in case of success
1157  */
1158 QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
1159 				qdf_nbuf_t wbuf,
1160 				uint8_t *mac_addr,
1161 				uint8_t tid){
1162 	struct wlan_crypto_comp_priv *crypto_priv;
1163 	struct wlan_crypto_params *crypto_params;
1164 	struct wlan_crypto_key *key;
1165 	QDF_STATUS status;
1166 	struct wlan_crypto_cipher *cipher_table;
1167 	struct wlan_objmgr_psoc *psoc;
1168 	struct wlan_objmgr_peer *peer;
1169 	uint8_t bssid_mac[WLAN_ALEN];
1170 	uint8_t keyid;
1171 	uint8_t pdev_id;
1172 	uint8_t hdrlen;
1173 	enum QDF_OPMODE opmode;
1174 
1175 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1176 	wlan_vdev_obj_lock(vdev);
1177 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
1178 	psoc = wlan_vdev_get_psoc(vdev);
1179 	if (!psoc) {
1180 		wlan_vdev_obj_unlock(vdev);
1181 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
1182 		return QDF_STATUS_E_INVAL;
1183 	}
1184 	wlan_vdev_obj_unlock(vdev);
1185 
1186 	if (opmode == QDF_MONITOR_MODE)
1187 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1188 	else
1189 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1190 					    (uint8_t *)qdf_nbuf_data(wbuf));
1191 
1192 	keyid = wlan_crypto_get_keyid((uint8_t *)qdf_nbuf_data(wbuf), hdrlen);
1193 
1194 	if (keyid >= WLAN_CRYPTO_MAXKEYIDX)
1195 		return QDF_STATUS_E_INVAL;
1196 
1197 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
1198 	/* FILS Decap required only for (Re-)Assoc request */
1199 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_CRYPTO_ID);
1200 
1201 	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)) &&
1202 	    peer && !wlan_crypto_get_peer_fils_aead(peer)) {
1203 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1204 		return QDF_STATUS_E_INVAL;
1205 	}
1206 
1207 	if (peer)
1208 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1209 
1210 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)mac_addr)) {
1211 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1212 								&crypto_priv);
1213 		if (crypto_priv == NULL) {
1214 			qdf_print("%s[%d] crypto_priv NULL",
1215 				  __func__, __LINE__);
1216 			return QDF_STATUS_E_INVAL;
1217 		}
1218 
1219 		key = crypto_priv->key[keyid];
1220 		if (!key)
1221 			return QDF_STATUS_E_INVAL;
1222 
1223 	} else {
1224 		struct wlan_objmgr_peer *peer;
1225 		uint8_t pdev_id;
1226 
1227 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1228 				wlan_vdev_get_pdev(vdev));
1229 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1230 					psoc, pdev_id, bssid_mac,
1231 					mac_addr, WLAN_CRYPTO_ID);
1232 		if (peer == NULL) {
1233 			qdf_print("%s[%d] peer NULL", __func__, __LINE__);
1234 			return QDF_STATUS_E_INVAL;
1235 		}
1236 
1237 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1238 								&crypto_priv);
1239 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1240 
1241 		if (crypto_priv == NULL) {
1242 			qdf_print("%s[%d] crypto_priv NULL",
1243 				  __func__, __LINE__);
1244 			return QDF_STATUS_E_INVAL;
1245 		}
1246 
1247 		key = crypto_priv->key[keyid];
1248 		if (!key)
1249 			return QDF_STATUS_E_INVAL;
1250 	}
1251 	/* if tkip, is counter measures enabled, then drop the frame */
1252 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1253 	status = cipher_table->decap(key, wbuf, tid, hdrlen);
1254 
1255 	return status;
1256 }
1257 qdf_export_symbol(wlan_crypto_decap);
1258 /**
1259  * wlan_crypto_enmic - called by mgmt for adding mic in frame based on cipher
1260  * @vdev: vdev
1261  * @wbuf: wbuf
1262  * @macaddr: macaddr
1263  * @encapdone: is encapdone already or not.
1264  *
1265  * This function gets called from mgmt txrx to adding mic to the frame.
1266  *
1267  * Return: QDF_STATUS_SUCCESS - in case of success
1268  */
1269 QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
1270 				qdf_nbuf_t wbuf,
1271 				uint8_t *mac_addr,
1272 				uint8_t encapdone){
1273 	struct wlan_crypto_comp_priv *crypto_priv;
1274 	struct wlan_crypto_params *crypto_params;
1275 	struct wlan_crypto_key *key;
1276 	QDF_STATUS status;
1277 	struct wlan_crypto_cipher *cipher_table;
1278 	struct wlan_objmgr_psoc *psoc;
1279 	uint8_t bssid_mac[WLAN_ALEN];
1280 	uint8_t hdrlen;
1281 	enum QDF_OPMODE opmode;
1282 
1283 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1284 
1285 
1286 	wlan_vdev_obj_lock(vdev);
1287 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
1288 	psoc = wlan_vdev_get_psoc(vdev);
1289 	if (!psoc) {
1290 		wlan_vdev_obj_unlock(vdev);
1291 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
1292 		return QDF_STATUS_E_INVAL;
1293 	}
1294 	wlan_vdev_obj_unlock(vdev);
1295 
1296 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
1297 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1298 								&crypto_priv);
1299 		if (crypto_priv == NULL) {
1300 			qdf_print("%s[%d] crypto_priv NULL",
1301 				  __func__, __LINE__);
1302 			return QDF_STATUS_E_INVAL;
1303 		}
1304 
1305 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
1306 		if (!key)
1307 			return QDF_STATUS_E_INVAL;
1308 
1309 	} else {
1310 		struct wlan_objmgr_peer *peer;
1311 		uint8_t pdev_id;
1312 
1313 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1314 				wlan_vdev_get_pdev(vdev));
1315 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1316 					psoc, pdev_id, bssid_mac,
1317 					mac_addr, WLAN_CRYPTO_ID);
1318 		if (peer == NULL) {
1319 			qdf_print("%s[%d] crypto_priv NULL",
1320 				  __func__, __LINE__);
1321 			return QDF_STATUS_E_INVAL;
1322 		}
1323 
1324 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1325 								&crypto_priv);
1326 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1327 
1328 		if (crypto_priv == NULL) {
1329 			qdf_print("%s[%d] crypto_priv NULL",
1330 				  __func__, __LINE__);
1331 			return QDF_STATUS_E_INVAL;
1332 		}
1333 
1334 		key = crypto_priv->key[crypto_priv->def_tx_keyid];
1335 		if (!key)
1336 			return QDF_STATUS_E_INVAL;
1337 	}
1338 	if (opmode == QDF_MONITOR_MODE)
1339 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1340 	else
1341 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1342 					    (uint8_t *)qdf_nbuf_data(wbuf));
1343 
1344 	/* if tkip, is counter measures enabled, then drop the frame */
1345 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1346 	status = cipher_table->enmic(key, wbuf, encapdone, hdrlen);
1347 
1348 	return status;
1349 }
1350 
1351 /**
1352  * wlan_crypto_demic - called by mgmt for remove and check mic for
1353  *			                        the frame based on cipher
1354  * @vdev: vdev
1355  * @wbuf: wbuf
1356  * @macaddr: macaddr
1357  * @tid: tid of the frame
1358  * @keyid: keyid in the received frame
1359  * This function gets called from mgmt txrx to decap frame.
1360  *
1361  * Return: QDF_STATUS_SUCCESS - in case of success
1362  */
1363 QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
1364 			     qdf_nbuf_t wbuf,
1365 			     uint8_t *mac_addr,
1366 			     uint8_t tid,
1367 			     uint8_t keyid){
1368 	struct wlan_crypto_comp_priv *crypto_priv;
1369 	struct wlan_crypto_params *crypto_params;
1370 	struct wlan_crypto_key *key;
1371 	QDF_STATUS status;
1372 	struct wlan_crypto_cipher *cipher_table;
1373 	struct wlan_objmgr_psoc *psoc;
1374 	uint8_t bssid_mac[WLAN_ALEN];
1375 	uint8_t hdrlen;
1376 	enum QDF_OPMODE opmode;
1377 
1378 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1379 
1380 	if (opmode == QDF_MONITOR_MODE)
1381 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1382 	else
1383 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1384 					    (uint8_t *)qdf_nbuf_data(wbuf));
1385 
1386 	wlan_vdev_obj_lock(vdev);
1387 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
1388 	psoc = wlan_vdev_get_psoc(vdev);
1389 	if (!psoc) {
1390 		wlan_vdev_obj_unlock(vdev);
1391 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
1392 		return QDF_STATUS_E_INVAL;
1393 	}
1394 	wlan_vdev_obj_unlock(vdev);
1395 
1396 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
1397 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1398 								&crypto_priv);
1399 		if (crypto_priv == NULL) {
1400 			qdf_print("%s[%d] crypto_priv NULL",
1401 				  __func__, __LINE__);
1402 			return QDF_STATUS_E_INVAL;
1403 		}
1404 
1405 		key = crypto_priv->key[keyid];
1406 		if (!key)
1407 			return QDF_STATUS_E_INVAL;
1408 
1409 	} else {
1410 		struct wlan_objmgr_peer *peer;
1411 		uint8_t pdev_id;
1412 
1413 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1414 				wlan_vdev_get_pdev(vdev));
1415 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1416 					psoc, pdev_id, bssid_mac,
1417 					mac_addr, WLAN_CRYPTO_ID);
1418 		if (peer == NULL) {
1419 			qdf_print("%s[%d] peer NULL", __func__, __LINE__);
1420 			return QDF_STATUS_E_INVAL;
1421 		}
1422 
1423 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1424 								&crypto_priv);
1425 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1426 
1427 		if (crypto_priv == NULL) {
1428 			qdf_print("%s[%d] crypto_priv NULL",
1429 				  __func__, __LINE__);
1430 			return QDF_STATUS_E_INVAL;
1431 		}
1432 
1433 		key = crypto_priv->key[keyid];
1434 		if (!key)
1435 			return QDF_STATUS_E_INVAL;
1436 	}
1437 	/* if tkip, is counter measures enabled, then drop the frame */
1438 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1439 	status = cipher_table->demic(key, wbuf, tid, hdrlen);
1440 
1441 	return status;
1442 }
1443 
1444 /**
1445  * wlan_crypto_vdev_is_pmf_enabled - called to check is pmf enabled in vdev
1446  * @vdev: vdev
1447  *
1448  * This function gets called to check is pmf enabled or not in vdev.
1449  *
1450  * Return: true or false
1451  */
1452 bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev)
1453 {
1454 
1455 	struct wlan_crypto_comp_priv *crypto_priv;
1456 	struct wlan_crypto_params *vdev_crypto_params;
1457 
1458 	if (!vdev)
1459 		return false;
1460 	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1461 							&crypto_priv);
1462 	if (crypto_priv == NULL) {
1463 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
1464 		return QDF_STATUS_E_INVAL;
1465 	}
1466 
1467 	if ((vdev_crypto_params->rsn_caps &
1468 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)
1469 		|| (vdev_crypto_params->rsn_caps &
1470 					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
1471 		return true;
1472 	}
1473 
1474 	return false;
1475 }
1476 /**
1477  * wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
1478  * @vdev: vdev
1479  * @peer: peer
1480  *
1481  * This function gets called by mgmt txrx to check is pmf enabled or not.
1482  *
1483  * Return: true or false
1484  */
1485 bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev,
1486 				struct wlan_objmgr_peer *peer){
1487 
1488 	struct wlan_crypto_comp_priv *crypto_priv;
1489 	struct wlan_crypto_params *vdev_crypto_params;
1490 	struct wlan_crypto_params *peer_crypto_params;
1491 
1492 	if (!vdev || !peer)
1493 		return false;
1494 	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1495 							&crypto_priv);
1496 	if (crypto_priv == NULL) {
1497 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
1498 		return QDF_STATUS_E_INVAL;
1499 	}
1500 
1501 	peer_crypto_params = wlan_crypto_peer_get_comp_params(peer,
1502 							&crypto_priv);
1503 	if (crypto_priv == NULL) {
1504 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
1505 		return QDF_STATUS_E_INVAL;
1506 	}
1507 	if (((vdev_crypto_params->rsn_caps &
1508 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) &&
1509 		(peer_crypto_params->rsn_caps &
1510 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
1511 		|| (vdev_crypto_params->rsn_caps &
1512 					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
1513 		return true;
1514 	}
1515 
1516 	return false;
1517 }
1518 
1519 static void wlan_crypto_gmac_pn_swap(uint8_t *a, uint8_t *b)
1520 {
1521 	a[0] = b[5];
1522 	a[1] = b[4];
1523 	a[2] = b[3];
1524 	a[3] = b[2];
1525 	a[4] = b[1];
1526 	a[5] = b[0];
1527 }
1528 
1529 /**
1530  * wlan_crypto_add_mmie - called by mgmt txrx to add mmie in frame
1531  * @vdev: vdev
1532  * @bfrm:  frame starting pointer
1533  * @len:  length of the frame
1534  *
1535  * This function gets called by mgmt txrx to add mmie in frame
1536  *
1537  * Return: end of frame or NULL in case failure
1538  */
1539 uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
1540 				uint8_t *bfrm,
1541 				uint32_t len) {
1542 	struct wlan_crypto_key *key;
1543 	struct wlan_crypto_mmie *mmie;
1544 	uint8_t *pn, *aad, *buf, *efrm, nounce[12];
1545 	struct ieee80211_hdr *hdr;
1546 	uint32_t i, hdrlen, mic_len, aad_len;
1547 	uint8_t mic[16];
1548 	struct wlan_crypto_comp_priv *crypto_priv;
1549 	struct wlan_crypto_params *crypto_params;
1550 	int32_t ret = -1;
1551 
1552 	if (!bfrm) {
1553 		qdf_print("%s[%d] frame is NULL", __func__, __LINE__);
1554 		return NULL;
1555 	}
1556 
1557 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1558 							&crypto_priv);
1559 	if (crypto_priv == NULL) {
1560 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
1561 		return NULL;
1562 	}
1563 
1564 	if (crypto_priv->def_igtk_tx_keyid >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
1565 		qdf_print("%s[%d] igtk key invalid keyid %d ",
1566 			  __func__, __LINE__, crypto_priv->def_igtk_tx_keyid);
1567 		return NULL;
1568 	}
1569 
1570 	key = crypto_priv->igtk_key[crypto_priv->def_igtk_tx_keyid];
1571 	if (!key) {
1572 		qdf_print("%s[%d] No igtk key present", __func__, __LINE__);
1573 		return NULL;
1574 	}
1575 	mic_len = (crypto_priv->igtk_key_type
1576 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
1577 
1578 	efrm = bfrm + len;
1579 	aad_len = 20;
1580 	hdrlen = sizeof(struct ieee80211_hdr);
1581 	len += sizeof(struct wlan_crypto_mmie);
1582 
1583 	mmie = (struct wlan_crypto_mmie *) efrm;
1584 	qdf_mem_zero((unsigned char *)mmie, sizeof(*mmie));
1585 	mmie->element_id = WLAN_ELEMID_MMIE;
1586 	mmie->length = sizeof(*mmie) - 2;
1587 	mmie->key_id = qdf_cpu_to_le16(key->keyix);
1588 
1589 	mic_len = (crypto_priv->igtk_key_type
1590 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
1591 	if (mic_len == 8) {
1592 		mmie->length -= 8;
1593 		len -= 8;
1594 	}
1595 	/* PN = PN + 1 */
1596 	pn = (uint8_t *)&key->keytsc;
1597 
1598 	for (i = 0; i <= 5; i++) {
1599 		pn[i]++;
1600 		if (pn[i])
1601 			break;
1602 	}
1603 
1604 	/* Copy IPN */
1605 	qdf_mem_copy(mmie->sequence_number, pn, 6);
1606 
1607 	hdr = (struct ieee80211_hdr *) bfrm;
1608 
1609 	buf = qdf_mem_malloc(len - hdrlen + 20);
1610 	if (!buf) {
1611 		qdf_print("%s[%d] malloc failed", __func__, __LINE__);
1612 		return NULL;
1613 	}
1614 	qdf_mem_zero(buf, len - hdrlen + 20);
1615 	aad = buf;
1616 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
1617 
1618 	/* FC type/subtype */
1619 	aad[0] = hdr->frame_control[0];
1620 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
1621 	aad[1] = (hdr->frame_control[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
1622 						| WLAN_FC1_MOREDATA));
1623 	/* A1 || A2 || A3 */
1624 	qdf_mem_copy(aad + 2, hdr->addr1, WLAN_ALEN);
1625 	qdf_mem_copy(aad + 8, hdr->addr2, WLAN_ALEN);
1626 	qdf_mem_copy(aad + 14, hdr->addr3, WLAN_ALEN);
1627 	qdf_mem_zero(mic, 16);
1628 
1629 	/*
1630 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
1631 	 */
1632 
1633 	qdf_mem_copy(buf + aad_len, bfrm + hdrlen, len - hdrlen);
1634 	if (crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
1635 
1636 		ret = omac1_aes_128(key->keyval, buf,
1637 					len + aad_len - hdrlen, mic);
1638 		qdf_mem_copy(mmie->mic, mic, 8);
1639 
1640 	} else if (crypto_priv->igtk_key_type
1641 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
1642 
1643 		ret = omac1_aes_256(key->keyval, buf,
1644 					len + aad_len - hdrlen, mmie->mic);
1645 	} else if ((crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_GMAC)
1646 			|| (crypto_priv->igtk_key_type
1647 					== WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
1648 
1649 		qdf_mem_copy(nounce, hdr->addr2, WLAN_ALEN);
1650 		wlan_crypto_gmac_pn_swap(nounce + 6, pn);
1651 		ret = wlan_crypto_aes_gmac(key->keyval, key->keylen, nounce,
1652 					sizeof(nounce), buf,
1653 					len + aad_len - hdrlen, mmie->mic);
1654 	}
1655 	qdf_mem_free(buf);
1656 	if (ret < 0) {
1657 		qdf_print("%s[%d] add mmie failed", __func__, __LINE__);
1658 		return NULL;
1659 	}
1660 
1661 	return bfrm + len;
1662 }
1663 
1664 /**
1665  * wlan_crypto_is_mmie_valid - called by mgmt txrx to check mmie of the frame
1666  * @vdev: vdev
1667  * @frm:  frame starting pointer
1668  * @efrm: end of frame pointer
1669  *
1670  * This function gets called by mgmt txrx to check mmie of the frame
1671  *
1672  * Return: true or false
1673  */
1674 bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
1675 					uint8_t *frm,
1676 					uint8_t *efrm){
1677 	struct wlan_crypto_mmie   *mmie = NULL;
1678 	uint8_t *ipn, *aad, *buf, mic[16], nounce[12];
1679 	struct wlan_crypto_key *key;
1680 	struct ieee80211_hdr *hdr;
1681 	uint16_t mic_len, hdrlen, len;
1682 	struct wlan_crypto_comp_priv *crypto_priv;
1683 	struct wlan_crypto_params *crypto_params;
1684 	uint8_t aad_len = 20;
1685 	int32_t ret = -1;
1686 
1687 	/* check if frame is illegal length */
1688 	if (!frm || !efrm || (efrm < frm)
1689 			|| ((efrm - frm) < sizeof(struct ieee80211_hdr))) {
1690 		qdf_print("%s[%d] Invalid params", __func__, __LINE__);
1691 		return false;
1692 	}
1693 	len = efrm - frm;
1694 	crypto_priv = (struct wlan_crypto_comp_priv *)
1695 				wlan_get_vdev_crypto_obj(vdev);
1696 	if (crypto_priv == NULL) {
1697 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
1698 		return false;
1699 	}
1700 
1701 	crypto_params = &(crypto_priv->crypto_params);
1702 
1703 
1704 	mic_len = (crypto_priv->igtk_key_type
1705 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
1706 	hdrlen = sizeof(struct ieee80211_hdr);
1707 
1708 	if (mic_len == 8)
1709 		mmie = (struct wlan_crypto_mmie *)(efrm - sizeof(*mmie) + 8);
1710 	else
1711 		mmie = (struct wlan_crypto_mmie *)(efrm - sizeof(*mmie));
1712 
1713 
1714 	/* check Elem ID*/
1715 	if ((mmie == NULL) || (mmie->element_id != WLAN_ELEMID_MMIE)) {
1716 		qdf_print("%s[%d] IE is not MMIE", __func__, __LINE__);
1717 		return false;
1718 	}
1719 
1720 	if (mmie->key_id >= (WLAN_CRYPTO_MAXKEYIDX +
1721 				WLAN_CRYPTO_MAXIGTKKEYIDX) ||
1722 				(mmie->key_id < WLAN_CRYPTO_MAXKEYIDX)) {
1723 		qdf_print("%s[%d] keyid not valid", __func__, __LINE__);
1724 		return false;
1725 	}
1726 
1727 	key = crypto_priv->igtk_key[mmie->key_id - WLAN_CRYPTO_MAXKEYIDX];
1728 	if (!key) {
1729 		qdf_print("%s[%d] No igtk key present", __func__, __LINE__);
1730 		return false;
1731 	}
1732 
1733 	/* validate ipn */
1734 	ipn = mmie->sequence_number;
1735 	if (qdf_mem_cmp(ipn, key->keyrsc, 6) <= 0) {
1736 		qdf_print("%s[%d] replay error", __func__, __LINE__);
1737 		return false;
1738 	}
1739 
1740 	buf = qdf_mem_malloc(len - hdrlen + 20);
1741 	if (!buf) {
1742 		qdf_print("%s[%d] malloc failed", __func__, __LINE__);
1743 		return false;
1744 	}
1745 	aad = buf;
1746 
1747 	/* construct AAD */
1748 	hdr = (struct ieee80211_hdr *)frm;
1749 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
1750 
1751 	/* FC type/subtype */
1752 	aad[0] = hdr->frame_control[0];
1753 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
1754 	aad[1] = (hdr->frame_control[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
1755 						| WLAN_FC1_MOREDATA));
1756 	/* A1 || A2 || A3 */
1757 	qdf_mem_copy(aad + 2, hdr->addr1, 3 * WLAN_ALEN);
1758 
1759 	/*
1760 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
1761 	 */
1762 	qdf_mem_copy(buf + 20, frm + hdrlen, len - hdrlen);
1763 	qdf_mem_zero(buf + (len - hdrlen + 20 - mic_len), mic_len);
1764 	qdf_mem_zero(mic, 16);
1765 	if (crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
1766 		ret = omac1_aes_128(key->keyval, buf,
1767 					len - hdrlen + aad_len, mic);
1768 	} else if (crypto_priv->igtk_key_type
1769 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
1770 		ret = omac1_aes_256(key->keyval, buf,
1771 					len + aad_len - hdrlen, mic);
1772 	} else if ((crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_GMAC)
1773 			|| (crypto_priv->igtk_key_type
1774 					== WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
1775 		qdf_mem_copy(nounce, hdr->addr2, WLAN_ALEN);
1776 		wlan_crypto_gmac_pn_swap(nounce + 6, ipn);
1777 		ret = wlan_crypto_aes_gmac(key->keyval, key->keylen, nounce,
1778 					sizeof(nounce), buf,
1779 					len + aad_len - hdrlen, mic);
1780 	}
1781 
1782 	qdf_mem_free(buf);
1783 
1784 	if (ret < 0) {
1785 		qdf_print("%s[%d] genarate mmie failed", __func__, __LINE__);
1786 		return false;
1787 	}
1788 
1789 	if (qdf_mem_cmp(mic, mmie->mic, mic_len) != 0) {
1790 		qdf_print("%s[%d] mmie mismatch", __func__, __LINE__);
1791 		/* MMIE MIC mismatch */
1792 		return false;
1793 	}
1794 
1795 	/* Update the receive sequence number */
1796 	qdf_mem_copy(key->keyrsc, ipn, 6);
1797 	qdf_print("%s[%d] mmie matched", __func__, __LINE__);
1798 
1799 	return true;
1800 }
1801 
1802 
1803 static int32_t wlan_crypto_wpa_cipher_to_suite(uint32_t cipher)
1804 {
1805 	int32_t status = -1;
1806 
1807 	switch (cipher) {
1808 	case WLAN_CRYPTO_CIPHER_TKIP:
1809 		return WPA_CIPHER_SUITE_TKIP;
1810 	case WLAN_CRYPTO_CIPHER_AES_CCM:
1811 		return WPA_CIPHER_SUITE_CCMP;
1812 	case WLAN_CRYPTO_CIPHER_NONE:
1813 		return WPA_CIPHER_SUITE_NONE;
1814 	}
1815 
1816 	return status;
1817 }
1818 
1819 static int32_t wlan_crypto_rsn_cipher_to_suite(uint32_t cipher)
1820 {
1821 	int32_t status = -1;
1822 
1823 	switch (cipher) {
1824 	case WLAN_CRYPTO_CIPHER_TKIP:
1825 		return RSN_CIPHER_SUITE_TKIP;
1826 	case WLAN_CRYPTO_CIPHER_AES_CCM:
1827 		return RSN_CIPHER_SUITE_CCMP;
1828 	case WLAN_CRYPTO_CIPHER_AES_CCM_256:
1829 		return RSN_CIPHER_SUITE_CCMP_256;
1830 	case WLAN_CRYPTO_CIPHER_AES_GCM:
1831 		return RSN_CIPHER_SUITE_GCMP;
1832 	case WLAN_CRYPTO_CIPHER_AES_GCM_256:
1833 		return RSN_CIPHER_SUITE_GCMP_256;
1834 	case WLAN_CRYPTO_CIPHER_AES_CMAC:
1835 		return RSN_CIPHER_SUITE_AES_CMAC;
1836 	case WLAN_CRYPTO_CIPHER_AES_CMAC_256:
1837 		return RSN_CIPHER_SUITE_BIP_CMAC_256;
1838 	case WLAN_CRYPTO_CIPHER_AES_GMAC:
1839 		return RSN_CIPHER_SUITE_BIP_GMAC_128;
1840 	case WLAN_CRYPTO_CIPHER_AES_GMAC_256:
1841 		return RSN_CIPHER_SUITE_BIP_GMAC_256;
1842 	case WLAN_CRYPTO_CIPHER_NONE:
1843 		return RSN_CIPHER_SUITE_NONE;
1844 	}
1845 
1846 	return status;
1847 }
1848 
1849 /*
1850  * Convert an RSN key management/authentication algorithm
1851  * to an internal code.
1852  */
1853 static int32_t
1854 wlan_crypto_rsn_keymgmt_to_suite(uint32_t keymgmt)
1855 {
1856 	int32_t status = -1;
1857 
1858 	switch (keymgmt) {
1859 	case WLAN_CRYPTO_KEY_MGMT_NONE:
1860 		return RSN_AUTH_KEY_MGMT_NONE;
1861 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
1862 		return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
1863 	case WLAN_CRYPTO_KEY_MGMT_PSK:
1864 		return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
1865 	case WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X:
1866 		return RSN_AUTH_KEY_MGMT_FT_802_1X;
1867 	case WLAN_CRYPTO_KEY_MGMT_FT_PSK:
1868 		return RSN_AUTH_KEY_MGMT_FT_PSK;
1869 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256:
1870 		return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
1871 	case WLAN_CRYPTO_KEY_MGMT_PSK_SHA256:
1872 		return RSN_AUTH_KEY_MGMT_PSK_SHA256;
1873 	case WLAN_CRYPTO_KEY_MGMT_SAE:
1874 		return RSN_AUTH_KEY_MGMT_SAE;
1875 	case WLAN_CRYPTO_KEY_MGMT_FT_SAE:
1876 		return RSN_AUTH_KEY_MGMT_FT_SAE;
1877 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B:
1878 		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
1879 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192:
1880 		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
1881 	case WLAN_CRYPTO_KEY_MGMT_CCKM:
1882 		return RSN_AUTH_KEY_MGMT_CCKM;
1883 	case WLAN_CRYPTO_KEY_MGMT_OSEN:
1884 		return RSN_AUTH_KEY_MGMT_OSEN;
1885 	case WLAN_CRYPTO_KEY_MGMT_FILS_SHA256:
1886 		return RSN_AUTH_KEY_MGMT_FILS_SHA256;
1887 	case WLAN_CRYPTO_KEY_MGMT_FILS_SHA384:
1888 		return RSN_AUTH_KEY_MGMT_FILS_SHA384;
1889 	case WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256:
1890 		return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
1891 	case WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384:
1892 		return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
1893 	case WLAN_CRYPTO_KEY_MGMT_OWE:
1894 		return RSN_AUTH_KEY_MGMT_OWE;
1895 	case WLAN_CRYPTO_KEY_MGMT_DPP:
1896 		return RSN_AUTH_KEY_MGMT_DPP;
1897 	}
1898 
1899 	return status;
1900 }
1901 
1902 /*
1903  * Convert an RSN key management/authentication algorithm
1904  * to an internal code.
1905  */
1906 static int32_t
1907 wlan_crypto_wpa_keymgmt_to_suite(uint32_t keymgmt)
1908 {
1909 	int32_t status = -1;
1910 
1911 	switch (keymgmt) {
1912 	case WLAN_CRYPTO_KEY_MGMT_NONE:
1913 		return WPA_AUTH_KEY_MGMT_NONE;
1914 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
1915 		return WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
1916 	case WLAN_CRYPTO_KEY_MGMT_PSK:
1917 		return WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
1918 	case WLAN_CRYPTO_KEY_MGMT_CCKM:
1919 		return WPA_AUTH_KEY_MGMT_CCKM;
1920 	}
1921 
1922 	return status;
1923 }
1924 /**
1925  * Convert a WPA cipher selector OUI to an internal
1926  * cipher algorithm.  Where appropriate we also
1927  * record any key length.
1928  */
1929 static int32_t wlan_crypto_wpa_suite_to_cipher(uint8_t *sel)
1930 {
1931 	uint32_t w = LE_READ_4(sel);
1932 	int32_t status = -1;
1933 
1934 	switch (w) {
1935 	case WPA_CIPHER_SUITE_TKIP:
1936 		return WLAN_CRYPTO_CIPHER_TKIP;
1937 	case WPA_CIPHER_SUITE_CCMP:
1938 		return WLAN_CRYPTO_CIPHER_AES_CCM;
1939 	case WPA_CIPHER_SUITE_NONE:
1940 		return WLAN_CRYPTO_CIPHER_NONE;
1941 	}
1942 
1943 	return status;
1944 }
1945 
1946 /*
1947  * Convert a WPA key management/authentication algorithm
1948  * to an internal code.
1949  */
1950 static int32_t wlan_crypto_wpa_suite_to_keymgmt(uint8_t *sel)
1951 {
1952 	uint32_t w = LE_READ_4(sel);
1953 	int32_t status = -1;
1954 
1955 	switch (w) {
1956 	case WPA_AUTH_KEY_MGMT_UNSPEC_802_1X:
1957 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
1958 	case WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X:
1959 		return WLAN_CRYPTO_KEY_MGMT_PSK;
1960 	case WPA_AUTH_KEY_MGMT_CCKM:
1961 		return WLAN_CRYPTO_KEY_MGMT_CCKM;
1962 	case WPA_AUTH_KEY_MGMT_NONE:
1963 		return WLAN_CRYPTO_KEY_MGMT_NONE;
1964 	}
1965 	return status;
1966 }
1967 
1968 /*
1969  * Convert a RSN cipher selector OUI to an internal
1970  * cipher algorithm.  Where appropriate we also
1971  * record any key length.
1972  */
1973 static int32_t wlan_crypto_rsn_suite_to_cipher(uint8_t *sel)
1974 {
1975 	uint32_t w = LE_READ_4(sel);
1976 	int32_t status = -1;
1977 
1978 	switch (w) {
1979 	case RSN_CIPHER_SUITE_TKIP:
1980 		return WLAN_CRYPTO_CIPHER_TKIP;
1981 	case RSN_CIPHER_SUITE_CCMP:
1982 		return WLAN_CRYPTO_CIPHER_AES_CCM;
1983 	case RSN_CIPHER_SUITE_CCMP_256:
1984 		return WLAN_CRYPTO_CIPHER_AES_CCM_256;
1985 	case RSN_CIPHER_SUITE_GCMP:
1986 		return WLAN_CRYPTO_CIPHER_AES_GCM;
1987 	case RSN_CIPHER_SUITE_GCMP_256:
1988 		return WLAN_CRYPTO_CIPHER_AES_GCM_256;
1989 	case RSN_CIPHER_SUITE_AES_CMAC:
1990 		return WLAN_CRYPTO_CIPHER_AES_CMAC;
1991 	case RSN_CIPHER_SUITE_BIP_CMAC_256:
1992 		return WLAN_CRYPTO_CIPHER_AES_CMAC_256;
1993 	case RSN_CIPHER_SUITE_BIP_GMAC_128:
1994 		return WLAN_CRYPTO_CIPHER_AES_GMAC;
1995 	case RSN_CIPHER_SUITE_BIP_GMAC_256:
1996 		return WLAN_CRYPTO_CIPHER_AES_GMAC_256;
1997 	case RSN_CIPHER_SUITE_NONE:
1998 		return WLAN_CRYPTO_CIPHER_NONE;
1999 	}
2000 
2001 	return status;
2002 }
2003 /*
2004  * Convert an RSN key management/authentication algorithm
2005  * to an internal code.
2006  */
2007 static int32_t wlan_crypto_rsn_suite_to_keymgmt(uint8_t *sel)
2008 {
2009 	uint32_t w = LE_READ_4(sel);
2010 	int32_t status = -1;
2011 
2012 	switch (w) {
2013 	case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
2014 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
2015 	case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
2016 		return WLAN_CRYPTO_KEY_MGMT_PSK;
2017 	case RSN_AUTH_KEY_MGMT_FT_802_1X:
2018 		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X;
2019 	case RSN_AUTH_KEY_MGMT_FT_PSK:
2020 		return WLAN_CRYPTO_KEY_MGMT_FT_PSK;
2021 	case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
2022 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256;
2023 	case RSN_AUTH_KEY_MGMT_PSK_SHA256:
2024 		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA256;
2025 	case RSN_AUTH_KEY_MGMT_SAE:
2026 		return WLAN_CRYPTO_KEY_MGMT_SAE;
2027 	case RSN_AUTH_KEY_MGMT_FT_SAE:
2028 		return WLAN_CRYPTO_KEY_MGMT_FT_SAE;
2029 	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
2030 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B;
2031 	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
2032 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192;
2033 	case RSN_AUTH_KEY_MGMT_CCKM:
2034 		return WLAN_CRYPTO_KEY_MGMT_CCKM;
2035 	case RSN_AUTH_KEY_MGMT_OSEN:
2036 		return WLAN_CRYPTO_KEY_MGMT_OSEN;
2037 	case RSN_AUTH_KEY_MGMT_FILS_SHA256:
2038 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA256;
2039 	case RSN_AUTH_KEY_MGMT_FILS_SHA384:
2040 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA384;
2041 	case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
2042 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256;
2043 	case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
2044 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384;
2045 	case RSN_AUTH_KEY_MGMT_OWE:
2046 		return WLAN_CRYPTO_KEY_MGMT_OWE;
2047 	case RSN_AUTH_KEY_MGMT_DPP:
2048 		return WLAN_CRYPTO_KEY_MGMT_DPP;
2049 	}
2050 
2051 	return status;
2052 }
2053 
2054 /**
2055  * wlan_crypto_wpaie_check - called by mlme to check the wpaie
2056  * @crypto params: crypto params
2057  * @iebuf: ie buffer
2058  *
2059  * This function gets called by mlme to check the contents of wpa is
2060  * matching with given crypto params
2061  *
2062  * Return: QDF_STATUS_SUCCESS - in case of success
2063  */
2064 QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params,
2065 					uint8_t *frm){
2066 	uint8_t len = frm[1];
2067 	int32_t w;
2068 	int n;
2069 
2070 	/*
2071 	 * Check the length once for fixed parts: OUI, type,
2072 	 * version, mcast cipher, and 2 selector counts.
2073 	 * Other, variable-length data, must be checked separately.
2074 	 */
2075 	RESET_AUTHMODE(crypto_params);
2076 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WPA);
2077 
2078 	if (len < 14)
2079 		return QDF_STATUS_E_INVAL;
2080 
2081 	frm += 6, len -= 4;
2082 
2083 	w = LE_READ_2(frm);
2084 	if (w != WPA_VERSION)
2085 		return QDF_STATUS_E_INVAL;
2086 
2087 	frm += 2, len -= 2;
2088 
2089 	/* multicast/group cipher */
2090 	RESET_MCAST_CIPHERS(crypto_params);
2091 	w = wlan_crypto_wpa_suite_to_cipher(frm);
2092 	if (w < 0)
2093 		return QDF_STATUS_E_INVAL;
2094 	SET_MCAST_CIPHER(crypto_params, w);
2095 	frm += 4, len -= 4;
2096 
2097 	/* unicast ciphers */
2098 	n = LE_READ_2(frm);
2099 	frm += 2, len -= 2;
2100 	if (len < n*4+2)
2101 		return QDF_STATUS_E_INVAL;
2102 
2103 	RESET_UCAST_CIPHERS(crypto_params);
2104 	for (; n > 0; n--) {
2105 		w = wlan_crypto_wpa_suite_to_cipher(frm);
2106 		if (w < 0)
2107 			return QDF_STATUS_E_INVAL;
2108 		SET_UCAST_CIPHER(crypto_params, w);
2109 		frm += 4, len -= 4;
2110 	}
2111 
2112 	if (!crypto_params->ucastcipherset)
2113 		return QDF_STATUS_E_INVAL;
2114 
2115 	/* key management algorithms */
2116 	n = LE_READ_2(frm);
2117 	frm += 2, len -= 2;
2118 	if (len < n*4)
2119 		return QDF_STATUS_E_INVAL;
2120 
2121 	w = 0;
2122 	RESET_KEY_MGMT(crypto_params);
2123 	for (; n > 0; n--) {
2124 		w = wlan_crypto_wpa_suite_to_keymgmt(frm);
2125 		if (w < 0)
2126 			return QDF_STATUS_E_INVAL;
2127 		SET_KEY_MGMT(crypto_params, w);
2128 		frm += 4, len -= 4;
2129 	}
2130 
2131 	/* optional capabilities */
2132 	if (len >= 2) {
2133 		crypto_params->rsn_caps = LE_READ_2(frm);
2134 		frm += 2, len -= 2;
2135 	}
2136 
2137 	return 0;
2138 }
2139 
2140 /**
2141  * wlan_crypto_rsnie_check - called by mlme to check the rsnie
2142  * @crypto params: crypto params
2143  * @iebuf: ie buffer
2144  *
2145  * This function gets called by mlme to check the contents of wpa is
2146  * matching with given crypto params
2147  *
2148  * Return: QDF_STATUS_SUCCESS - in case of success
2149  */
2150 QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *crypto_params,
2151 					uint8_t *frm){
2152 	uint8_t len = frm[1];
2153 	int32_t w;
2154 	int n;
2155 
2156 	/* Check the length once for fixed parts: OUI, type & version */
2157 	if (len < 2)
2158 		return QDF_STATUS_E_INVAL;
2159 
2160 	/* initialize crypto params */
2161 	qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
2162 
2163 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_RSNA);
2164 
2165 	frm += 2;
2166 	/* NB: iswapoui already validated the OUI and type */
2167 	w = LE_READ_2(frm);
2168 	if (w != RSN_VERSION)
2169 		return QDF_STATUS_E_INVAL;
2170 
2171 	frm += 2, len -= 2;
2172 
2173 	if (!len) {
2174 		/* set defaults */
2175 		/* default group cipher CCMP-128 */
2176 		SET_MCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2177 		/* default ucast cipher CCMP-128 */
2178 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2179 		/* default key mgmt 8021x */
2180 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2181 		return QDF_STATUS_SUCCESS;
2182 	} else if (len < 4) {
2183 		return QDF_STATUS_E_INVAL;
2184 	}
2185 
2186 	/* multicast/group cipher */
2187 	w = wlan_crypto_rsn_suite_to_cipher(frm);
2188 	if (w < 0)
2189 		return QDF_STATUS_E_INVAL;
2190 	else {
2191 		SET_MCAST_CIPHER(crypto_params, w);
2192 		frm += 4, len -= 4;
2193 	}
2194 
2195 	if (crypto_params->mcastcipherset == 0)
2196 		return QDF_STATUS_E_INVAL;
2197 
2198 	if (!len) {
2199 		/* default ucast cipher CCMP-128 */
2200 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2201 		/* default key mgmt 8021x */
2202 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2203 		return QDF_STATUS_SUCCESS;
2204 	} else if (len < 2) {
2205 		return QDF_STATUS_E_INVAL;
2206 	}
2207 
2208 	/* unicast ciphers */
2209 	n = LE_READ_2(frm);
2210 	frm += 2, len -= 2;
2211 	if (n) {
2212 		if (len < n * 4)
2213 			return QDF_STATUS_E_INVAL;
2214 
2215 		for (; n > 0; n--) {
2216 			w = wlan_crypto_rsn_suite_to_cipher(frm);
2217 			if (w < 0)
2218 				return QDF_STATUS_E_INVAL;
2219 			SET_UCAST_CIPHER(crypto_params, w);
2220 			frm += 4, len -= 4;
2221 		}
2222 	} else {
2223 		/* default ucast cipher CCMP-128 */
2224 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2225 	}
2226 
2227 	if (crypto_params->ucastcipherset == 0)
2228 		return QDF_STATUS_E_INVAL;
2229 
2230 	if (!len) {
2231 		/* default key mgmt 8021x */
2232 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2233 		return QDF_STATUS_SUCCESS;
2234 	} else if (len < 2) {
2235 		return QDF_STATUS_E_INVAL;
2236 	}
2237 
2238 	/* key management algorithms */
2239 	n = LE_READ_2(frm);
2240 	frm += 2, len -= 2;
2241 
2242 	if (n) {
2243 		if (len < n * 4)
2244 			return QDF_STATUS_E_INVAL;
2245 
2246 		for (; n > 0; n--) {
2247 			w = wlan_crypto_rsn_suite_to_keymgmt(frm);
2248 			if (w < 0)
2249 				return QDF_STATUS_E_INVAL;
2250 			SET_KEY_MGMT(crypto_params, w);
2251 			frm += 4, len -= 4;
2252 		}
2253 	} else {
2254 		/* default key mgmt 8021x */
2255 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2256 	}
2257 
2258 	if (crypto_params->key_mgmt == 0)
2259 		return QDF_STATUS_E_INVAL;
2260 
2261 	/* optional capabilities */
2262 	if (len >= 2) {
2263 		crypto_params->rsn_caps = LE_READ_2(frm);
2264 		frm += 2, len -= 2;
2265 	} else if (len && len < 2) {
2266 		return QDF_STATUS_E_INVAL;
2267 	}
2268 
2269 
2270 	/* PMKID */
2271 	if (len >= 2) {
2272 		n = LE_READ_2(frm);
2273 		frm += 2, len -= 2;
2274 		if (n && len) {
2275 			if (len >= n * PMKID_LEN)
2276 				frm += (n * PMKID_LEN), len -= (n * PMKID_LEN);
2277 			else
2278 				return QDF_STATUS_E_INVAL;
2279 		} else if (n && !len) {
2280 			return QDF_STATUS_E_INVAL;
2281 		}
2282 		/*TODO: Save pmkid in params for further reference */
2283 	}
2284 
2285 	/* BIP */
2286 	if (!len &&
2287 	    (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) {
2288 		/* when no BIP mentioned and MFP capable use CMAC as default*/
2289 		SET_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC);
2290 		return QDF_STATUS_SUCCESS;
2291 	} else if (len >= 4) {
2292 		w = wlan_crypto_rsn_suite_to_cipher(frm);
2293 		frm += 4, len -= 4;
2294 		SET_MGMT_CIPHER(crypto_params, w);
2295 	}
2296 
2297 	return QDF_STATUS_SUCCESS;
2298 }
2299 
2300 /**
2301  * wlan_crypto_build_wpaie - called by mlme to build wpaie
2302  * @vdev: vdev
2303  * @iebuf: ie buffer
2304  *
2305  * This function gets called by mlme to build wpaie from given vdev
2306  *
2307  * Return: end of buffer
2308  */
2309 uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev,
2310 					uint8_t *iebuf){
2311 	uint8_t *frm = iebuf;
2312 	uint8_t *selcnt;
2313 	struct wlan_crypto_comp_priv *crypto_priv;
2314 	struct wlan_crypto_params *crypto_params;
2315 
2316 	if (!frm)
2317 		return NULL;
2318 
2319 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
2320 
2321 	if (!crypto_params)
2322 		return NULL;
2323 
2324 	*frm++ = WLAN_ELEMID_VENDOR;
2325 	*frm++ = 0;
2326 	WLAN_CRYPTO_ADDSELECTOR(frm, WPA_TYPE_OUI);
2327 	WLAN_CRYPTO_ADDSHORT(frm, WPA_VERSION);
2328 
2329 
2330 	/* multicast cipher */
2331 	if (MCIPHER_IS_TKIP(crypto_params)) {
2332 		WLAN_CRYPTO_ADDSELECTOR(frm,
2333 					wlan_crypto_wpa_cipher_to_suite(
2334 						WLAN_CRYPTO_CIPHER_TKIP));
2335 	} else if (MCIPHER_IS_CCMP128(crypto_params)) {
2336 		WLAN_CRYPTO_ADDSELECTOR(frm,
2337 					wlan_crypto_wpa_cipher_to_suite(
2338 						WLAN_CRYPTO_CIPHER_AES_CCM));
2339 	}
2340 	/* unicast cipher list */
2341 	selcnt = frm;
2342 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2343 	/* do not use CCMP unicast cipher in WPA mode */
2344 	if (UCIPHER_IS_TKIP(crypto_params)) {
2345 		selcnt[0]++;
2346 		WLAN_CRYPTO_ADDSELECTOR(frm,
2347 			 wlan_crypto_wpa_cipher_to_suite(
2348 						WLAN_CRYPTO_CIPHER_TKIP));
2349 	}
2350 	if (UCIPHER_IS_CCMP128(crypto_params)) {
2351 		selcnt[0]++;
2352 		WLAN_CRYPTO_ADDSELECTOR(frm,
2353 			wlan_crypto_wpa_cipher_to_suite(
2354 						WLAN_CRYPTO_CIPHER_AES_CCM));
2355 	}
2356 
2357 	/* authenticator selector list */
2358 	selcnt = frm;
2359 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2360 
2361 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
2362 		selcnt[0]++;
2363 		WLAN_CRYPTO_ADDSELECTOR(frm,
2364 			wlan_crypto_wpa_keymgmt_to_suite(
2365 					WLAN_CRYPTO_KEY_MGMT_IEEE8021X));
2366 	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
2367 		selcnt[0]++;
2368 		WLAN_CRYPTO_ADDSELECTOR(frm,
2369 			wlan_crypto_wpa_keymgmt_to_suite(
2370 						WLAN_CRYPTO_KEY_MGMT_PSK));
2371 	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
2372 		selcnt[0]++;
2373 		WLAN_CRYPTO_ADDSELECTOR(frm,
2374 			wlan_crypto_wpa_keymgmt_to_suite(
2375 						WLAN_CRYPTO_KEY_MGMT_CCKM));
2376 	} else {
2377 		selcnt[0]++;
2378 		WLAN_CRYPTO_ADDSELECTOR(frm,
2379 			wlan_crypto_wpa_keymgmt_to_suite(
2380 						WLAN_CRYPTO_KEY_MGMT_NONE));
2381 	}
2382 	/* calculate element length */
2383 	iebuf[1] = frm - iebuf - 2;
2384 
2385 	return frm;
2386 }
2387 
2388 /**
2389  * wlan_crypto_build_rsnie - called by mlme to build rsnie
2390  * @vdev: vdev
2391  * @iebuf: ie buffer
2392  *
2393  * This function gets called by mlme to build rsnie from given vdev
2394  *
2395  * Return: end of buffer
2396  */
2397 uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
2398 				 uint8_t *iebuf){
2399 	uint8_t *frm = iebuf;
2400 	uint8_t *selcnt;
2401 	struct wlan_crypto_comp_priv *crypto_priv;
2402 	struct wlan_crypto_params *crypto_params;
2403 
2404 	if (!frm) {
2405 		return NULL;
2406 	}
2407 
2408 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
2409 
2410 	if (!crypto_params) {
2411 		return NULL;
2412 	}
2413 
2414 	*frm++ = WLAN_ELEMID_RSN;
2415 	*frm++ = 0;
2416 	WLAN_CRYPTO_ADDSHORT(frm, RSN_VERSION);
2417 
2418 
2419 	/* multicast cipher */
2420 	if (MCIPHER_IS_TKIP(crypto_params)) {
2421 		WLAN_CRYPTO_ADDSELECTOR(frm,
2422 					wlan_crypto_rsn_cipher_to_suite(
2423 					WLAN_CRYPTO_CIPHER_TKIP));
2424 	} else if (MCIPHER_IS_CCMP128(crypto_params)) {
2425 		WLAN_CRYPTO_ADDSELECTOR(frm,
2426 					wlan_crypto_rsn_cipher_to_suite(
2427 					WLAN_CRYPTO_CIPHER_AES_CCM));
2428 	} else if (MCIPHER_IS_CCMP256(crypto_params)) {
2429 		WLAN_CRYPTO_ADDSELECTOR(frm,
2430 					wlan_crypto_rsn_cipher_to_suite(
2431 					WLAN_CRYPTO_CIPHER_AES_CCM_256));
2432 	} else if (MCIPHER_IS_GCMP128(crypto_params)) {
2433 		WLAN_CRYPTO_ADDSELECTOR(frm,
2434 					wlan_crypto_rsn_cipher_to_suite(
2435 					WLAN_CRYPTO_CIPHER_AES_GCM));
2436 	} else if (MCIPHER_IS_GCMP256(crypto_params)) {
2437 		WLAN_CRYPTO_ADDSELECTOR(frm,
2438 					wlan_crypto_rsn_cipher_to_suite(
2439 					WLAN_CRYPTO_CIPHER_AES_GCM_256));
2440 	}
2441 
2442 	/* unicast cipher list */
2443 	selcnt = frm;
2444 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2445 	/* do not use CCMP unicast cipher in WPA mode */
2446 	if (UCIPHER_IS_TKIP(crypto_params)) {
2447 		selcnt[0]++;
2448 		WLAN_CRYPTO_ADDSELECTOR(frm,
2449 					wlan_crypto_rsn_cipher_to_suite(
2450 						WLAN_CRYPTO_CIPHER_TKIP));
2451 	}
2452 	if (UCIPHER_IS_CCMP128(crypto_params)) {
2453 		selcnt[0]++;
2454 		WLAN_CRYPTO_ADDSELECTOR(frm,
2455 					wlan_crypto_rsn_cipher_to_suite(
2456 						WLAN_CRYPTO_CIPHER_AES_CCM));
2457 	}
2458 	if (UCIPHER_IS_CCMP256(crypto_params)) {
2459 		selcnt[0]++;
2460 		WLAN_CRYPTO_ADDSELECTOR(frm,
2461 			wlan_crypto_rsn_cipher_to_suite(
2462 					WLAN_CRYPTO_CIPHER_AES_CCM_256));
2463 	}
2464 
2465 	if (UCIPHER_IS_GCMP128(crypto_params)) {
2466 		selcnt[0]++;
2467 		WLAN_CRYPTO_ADDSELECTOR(frm,
2468 			 wlan_crypto_rsn_cipher_to_suite(
2469 					WLAN_CRYPTO_CIPHER_AES_GCM));
2470 	}
2471 	if (UCIPHER_IS_GCMP256(crypto_params)) {
2472 		selcnt[0]++;
2473 		WLAN_CRYPTO_ADDSELECTOR(frm,
2474 			wlan_crypto_rsn_cipher_to_suite(
2475 					WLAN_CRYPTO_CIPHER_AES_GCM_256));
2476 	}
2477 
2478 
2479 	/* authenticator selector list */
2480 	selcnt = frm;
2481 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2482 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
2483 		selcnt[0]++;
2484 		WLAN_CRYPTO_ADDSELECTOR(frm,
2485 			wlan_crypto_rsn_keymgmt_to_suite(
2486 					WLAN_CRYPTO_KEY_MGMT_CCKM));
2487 	} else {
2488 		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
2489 			selcnt[0]++;
2490 			WLAN_CRYPTO_ADDSELECTOR(frm,
2491 				wlan_crypto_rsn_keymgmt_to_suite(
2492 					WLAN_CRYPTO_KEY_MGMT_PSK));
2493 		}
2494 		if (HAS_KEY_MGMT(crypto_params,
2495 					WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
2496 			selcnt[0]++;
2497 			WLAN_CRYPTO_ADDSELECTOR(frm,
2498 				wlan_crypto_rsn_keymgmt_to_suite(
2499 					WLAN_CRYPTO_KEY_MGMT_IEEE8021X));
2500 		}
2501 		if (HAS_KEY_MGMT(crypto_params,
2502 					WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X)) {
2503 			selcnt[0]++;
2504 			WLAN_CRYPTO_ADDSELECTOR(frm,
2505 				wlan_crypto_rsn_keymgmt_to_suite(
2506 					WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X));
2507 		}
2508 		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_PSK)) {
2509 			selcnt[0]++;
2510 			WLAN_CRYPTO_ADDSELECTOR(frm,
2511 				wlan_crypto_rsn_keymgmt_to_suite(
2512 					WLAN_CRYPTO_KEY_MGMT_FT_PSK));
2513 		}
2514 		if (HAS_KEY_MGMT(crypto_params,
2515 				WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) {
2516 			selcnt[0]++;
2517 			WLAN_CRYPTO_ADDSELECTOR(frm,
2518 				wlan_crypto_rsn_keymgmt_to_suite(
2519 					WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256));
2520 		}
2521 		if (HAS_KEY_MGMT(crypto_params,
2522 					WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) {
2523 			selcnt[0]++;
2524 			WLAN_CRYPTO_ADDSELECTOR(frm,
2525 				wlan_crypto_rsn_keymgmt_to_suite(
2526 					WLAN_CRYPTO_KEY_MGMT_PSK_SHA256));
2527 		}
2528 		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_OSEN)) {
2529 			selcnt[0]++;
2530 			WLAN_CRYPTO_ADDSELECTOR(frm,
2531 				wlan_crypto_rsn_keymgmt_to_suite(
2532 					WLAN_CRYPTO_KEY_MGMT_OSEN));
2533 		}
2534 	}
2535 
2536 	WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
2537 	/* optional capabilities */
2538 	if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) {
2539 		/* PMK list */
2540 		WLAN_CRYPTO_ADDSHORT(frm, 0);
2541 		if (HAS_MGMT_CIPHER(crypto_params,
2542 						WLAN_CRYPTO_CIPHER_AES_CMAC)) {
2543 			WLAN_CRYPTO_ADDSELECTOR(frm,
2544 				 wlan_crypto_rsn_cipher_to_suite(
2545 						WLAN_CRYPTO_CIPHER_AES_CMAC));
2546 		}
2547 		if (HAS_MGMT_CIPHER(crypto_params,
2548 						WLAN_CRYPTO_CIPHER_AES_GMAC)) {
2549 			WLAN_CRYPTO_ADDSELECTOR(frm,
2550 				 wlan_crypto_rsn_cipher_to_suite(
2551 						WLAN_CRYPTO_CIPHER_AES_GMAC));
2552 		}
2553 		if (HAS_MGMT_CIPHER(crypto_params,
2554 					 WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
2555 			WLAN_CRYPTO_ADDSELECTOR(frm,
2556 				 wlan_crypto_rsn_cipher_to_suite(
2557 					WLAN_CRYPTO_CIPHER_AES_CMAC_256));
2558 		}
2559 
2560 		if (HAS_MGMT_CIPHER(crypto_params,
2561 					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
2562 			WLAN_CRYPTO_ADDSELECTOR(frm,
2563 				 wlan_crypto_rsn_cipher_to_suite(
2564 					WLAN_CRYPTO_CIPHER_AES_GMAC_256));
2565 		}
2566 	}
2567 
2568 	/* calculate element length */
2569 	iebuf[1] = frm - iebuf - 2;
2570 
2571 	return frm;
2572 }
2573 
2574 bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
2575 				struct wlan_crypto_params *crypto_params){
2576 	struct wlan_crypto_params *my_crypto_params;
2577 	my_crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
2578 
2579 	if (!my_crypto_params)
2580 		return false;
2581 	/*
2582 	 * Check peer's pairwise ciphers.
2583 	 * At least one must match with our unicast cipher
2584 	 */
2585 	if (!UCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
2586 		return false;
2587 	/*
2588 	 * Check peer's group cipher is our enabled multicast cipher.
2589 	 */
2590 	if (!MCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
2591 		return false;
2592 	/*
2593 	 * Check peer's key management class set (PSK or UNSPEC)
2594 	 */
2595 	if (!KEY_MGMTSET_MATCH(crypto_params, my_crypto_params))
2596 		return false;
2597 
2598 	return true;
2599 }
2600 
2601 /*
2602  * Convert an WAPI CIPHER suite to to an internal code.
2603  */
2604 static int32_t wlan_crypto_wapi_suite_to_cipher(uint8_t *sel)
2605 {
2606 	uint32_t w = LE_READ_4(sel);
2607 	int32_t status = -1;
2608 
2609 	switch (w) {
2610 	case (WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER)):
2611 		return WLAN_CRYPTO_CIPHER_WAPI_SMS4;
2612 	}
2613 
2614 	return status;
2615 }
2616 
2617 /*
2618  * Convert an WAPI key management/authentication algorithm
2619  * to an internal code.
2620  */
2621 static int32_t wlan_crypto_wapi_keymgmt(u_int8_t *sel)
2622 {
2623 	uint32_t w = LE_READ_4(sel);
2624 	int32_t status = -1;
2625 
2626 	switch (w) {
2627 	case (WLAN_WAPI_SEL(WLAN_WAI_PSK)):
2628 		return WLAN_CRYPTO_KEY_MGMT_WAPI_PSK;
2629 	case (WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4)):
2630 		return WLAN_CRYPTO_KEY_MGMT_WAPI_CERT;
2631 	}
2632 
2633 	return status;
2634 }
2635 /**
2636  * wlan_crypto_wapiie_check - called by mlme to check the wapiie
2637  * @crypto params: crypto params
2638  * @iebuf: ie buffer
2639  *
2640  * This function gets called by mlme to check the contents of wapi is
2641  * matching with given crypto params
2642  *
2643  * Return: QDF_STATUS_SUCCESS - in case of success
2644  */
2645 QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
2646 					uint8_t *frm)
2647 {
2648 	uint8_t len = frm[1];
2649 	int32_t w;
2650 	int n;
2651 
2652 	/*
2653 	 * Check the length once for fixed parts: OUI, type,
2654 	 * version, mcast cipher, and 2 selector counts.
2655 	 * Other, variable-length data, must be checked separately.
2656 	 */
2657 	RESET_AUTHMODE(crypto_params);
2658 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WAPI);
2659 
2660 	if (len < WLAN_CRYPTO_WAPI_IE_LEN)
2661 		return QDF_STATUS_E_INVAL;
2662 
2663 
2664 	frm += 2;
2665 
2666 	w = LE_READ_2(frm);
2667 	frm += 2, len -= 2;
2668 	if (w != WAPI_VERSION)
2669 		return QDF_STATUS_E_INVAL;
2670 
2671 	n = LE_READ_2(frm);
2672 	frm += 2, len -= 2;
2673 	if (len < n*4+2)
2674 		return QDF_STATUS_E_INVAL;
2675 
2676 	RESET_KEY_MGMT(crypto_params);
2677 	for (; n > 0; n--) {
2678 		w = wlan_crypto_wapi_keymgmt(frm);
2679 		if (w < 0)
2680 			return QDF_STATUS_E_INVAL;
2681 
2682 		SET_KEY_MGMT(crypto_params, w);
2683 		frm += 4, len -= 4;
2684 	}
2685 
2686 	/* unicast ciphers */
2687 	n = LE_READ_2(frm);
2688 	frm += 2, len -= 2;
2689 	if (len < n*4+2)
2690 		return QDF_STATUS_E_INVAL;
2691 
2692 	RESET_UCAST_CIPHERS(crypto_params);
2693 	for (; n > 0; n--) {
2694 		w = wlan_crypto_wapi_suite_to_cipher(frm);
2695 		if (w < 0)
2696 			return QDF_STATUS_E_INVAL;
2697 		SET_UCAST_CIPHER(crypto_params, w);
2698 		frm += 4, len -= 4;
2699 	}
2700 
2701 	if (!crypto_params->ucastcipherset)
2702 		return QDF_STATUS_E_INVAL;
2703 
2704 	/* multicast/group cipher */
2705 	RESET_MCAST_CIPHERS(crypto_params);
2706 	w = wlan_crypto_wapi_suite_to_cipher(frm);
2707 
2708 	if (w < 0)
2709 		return QDF_STATUS_E_INVAL;
2710 
2711 	SET_MCAST_CIPHER(crypto_params, w);
2712 	frm += 4, len -= 4;
2713 
2714 	return QDF_STATUS_SUCCESS;
2715 }
2716 
2717 /**
2718  * wlan_crypto_build_wapiie - called by mlme to build wapi ie
2719  * @vdev: vdev
2720  * @iebuf: ie buffer
2721  *
2722  * This function gets called by mlme to build wapi ie from given vdev
2723  *
2724  * Return: end of buffer
2725  */
2726 uint8_t *wlan_crypto_build_wapiie(struct wlan_objmgr_vdev *vdev,
2727 				uint8_t *iebuf)
2728 {
2729 	uint8_t *frm;
2730 	uint8_t *selcnt;
2731 	struct wlan_crypto_comp_priv *crypto_priv;
2732 	struct wlan_crypto_params *crypto_params;
2733 
2734 	frm = iebuf;
2735 	if (!frm) {
2736 		qdf_print("%s[%d] ie buffer NULL", __func__, __LINE__);
2737 		return NULL;
2738 	}
2739 
2740 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
2741 
2742 	if (!crypto_params) {
2743 		qdf_print("%s[%d] crypto_params NULL", __func__, __LINE__);
2744 		return NULL;
2745 	}
2746 
2747 	*frm++ = WLAN_ELEMID_WAPI;
2748 	*frm++ = 0;
2749 
2750 	WLAN_CRYPTO_ADDSHORT(frm, WAPI_VERSION);
2751 
2752 	/* authenticator selector list */
2753 	selcnt = frm;
2754 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2755 
2756 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK)) {
2757 		selcnt[0]++;
2758 		WLAN_CRYPTO_ADDSELECTOR(frm,
2759 				WLAN_WAPI_SEL(WLAN_WAI_PSK));
2760 	}
2761 
2762 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT)) {
2763 		selcnt[0]++;
2764 		WLAN_CRYPTO_ADDSELECTOR(frm,
2765 				WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4));
2766 	}
2767 
2768 	/* unicast cipher list */
2769 	selcnt = frm;
2770 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2771 
2772 	if (UCIPHER_IS_SMS4(crypto_params)) {
2773 		selcnt[0]++;
2774 		WLAN_CRYPTO_ADDSELECTOR(frm,
2775 				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
2776 	}
2777 
2778 	WLAN_CRYPTO_ADDSELECTOR(frm,
2779 				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
2780 
2781 	/* optional capabilities */
2782 	WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
2783 
2784 	/* calculate element length */
2785 	iebuf[1] = frm - iebuf - 2;
2786 
2787 	return frm;
2788 
2789 }
2790 
2791 /**
2792  * wlan_crypto_pn_check - called by data patch for PN check
2793  * @vdev: vdev
2794  * @wbuf: wbuf
2795  *
2796  * This function gets called by data patch for PN check
2797  *
2798  * Return: QDF_STATUS
2799  */
2800 QDF_STATUS wlan_crypto_pn_check(struct wlan_objmgr_vdev *vdev,
2801 				qdf_nbuf_t wbuf){
2802 	/* Need to check is there real requirement for this function
2803 	 * as PN check is already handled in decap function.
2804 	 */
2805 	return QDF_STATUS_SUCCESS;
2806 }
2807 
2808 /**
2809  * wlan_crypto_vdev_get_crypto_params - called by mlme to get crypto params
2810  * @vdev:vdev
2811  *
2812  * This function gets called by mlme to get crypto params
2813  *
2814  * Return: wlan_crypto_params or NULL in case of failure
2815  */
2816 struct wlan_crypto_params *wlan_crypto_vdev_get_crypto_params(
2817 						struct wlan_objmgr_vdev *vdev){
2818 	struct wlan_crypto_comp_priv *crypto_priv;
2819 
2820 	return wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
2821 }
2822 
2823 /**
2824  * wlan_crypto_peer_get_crypto_params - called by mlme to get crypto params
2825  * @peer:peer
2826  *
2827  * This function gets called by mlme to get crypto params
2828  *
2829  * Return: wlan_crypto_params or NULL in case of failure
2830  */
2831 struct wlan_crypto_params *wlan_crypto_peer_get_crypto_params(
2832 						struct wlan_objmgr_peer *peer){
2833 	struct wlan_crypto_comp_priv *crypto_priv;
2834 
2835 	return wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
2836 }
2837 
2838 
2839 QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev,
2840 					struct wlan_objmgr_peer *peer)
2841 {
2842 	struct wlan_crypto_comp_priv *crypto_priv;
2843 	struct wlan_crypto_comp_priv *sta_crypto_priv;
2844 	struct wlan_crypto_params *crypto_params;
2845 	struct wlan_crypto_key *key;
2846 	struct wlan_crypto_key *sta_key;
2847 	struct wlan_crypto_cipher *cipher_table;
2848 	struct wlan_objmgr_psoc *psoc;
2849 	uint8_t *mac_addr;
2850 	int i;
2851 	enum QDF_OPMODE opmode;
2852 
2853 	if (!vdev)
2854 		return QDF_STATUS_E_NULL_VALUE;
2855 
2856 	if (!peer) {
2857 		qdf_print("%s[%d] peer NULL", __func__, __LINE__);
2858 		return QDF_STATUS_E_INVAL;
2859 	}
2860 
2861 	opmode = wlan_vdev_mlme_get_opmode(vdev);
2862 	psoc = wlan_vdev_get_psoc(vdev);
2863 
2864 	if (!psoc) {
2865 		qdf_print("%s[%d] psoc NULL", __func__, __LINE__);
2866 		return QDF_STATUS_E_NULL_VALUE;
2867 	}
2868 
2869 	wlan_peer_obj_lock(peer);
2870 	mac_addr = wlan_peer_get_macaddr(peer);
2871 	wlan_peer_obj_unlock(peer);
2872 
2873 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
2874 							&crypto_priv);
2875 	if (crypto_priv == NULL) {
2876 		qdf_print("%s[%d] crypto_priv NULL", __func__, __LINE__);
2877 		return QDF_STATUS_E_NULL_VALUE;
2878 	}
2879 
2880 	/* push only valid static WEP keys from vap */
2881 	if (AUTH_IS_8021X(crypto_params))
2882 		return QDF_STATUS_E_INVAL;
2883 
2884 	if (opmode == QDF_STA_MODE) {
2885 		peer = wlan_vdev_get_bsspeer(vdev);
2886 		if (!peer) {
2887 			qdf_print("%s[%d] peer NULL", __func__, __LINE__);
2888 			return QDF_STATUS_E_INVAL;
2889 		}
2890 	}
2891 
2892 	wlan_crypto_peer_get_comp_params(peer, &sta_crypto_priv);
2893 	if (sta_crypto_priv == NULL) {
2894 		qdf_print("%s[%d] sta priv is null", __func__, __LINE__);
2895 		return QDF_STATUS_E_INVAL;
2896 	}
2897 
2898 	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
2899 		if (crypto_priv->key[i]) {
2900 			key = crypto_priv->key[i];
2901 			if (!key || !key->valid)
2902 				continue;
2903 
2904 			cipher_table = (struct wlan_crypto_cipher *)
2905 							key->cipher_table;
2906 
2907 			if (cipher_table->cipher == WLAN_CRYPTO_CIPHER_WEP) {
2908 				sta_key = qdf_mem_malloc(
2909 						sizeof(struct wlan_crypto_key));
2910 				if (!sta_key) {
2911 					qdf_print("%s[%d] key alloc failed",
2912 						  __func__, __LINE__);
2913 					return QDF_STATUS_E_NOMEM;
2914 				}
2915 				sta_crypto_priv->key[i] = sta_key;
2916 				qdf_mem_copy(sta_key, key,
2917 						sizeof(struct wlan_crypto_key));
2918 
2919 				sta_key->flags &= ~WLAN_CRYPTO_KEY_DEFAULT;
2920 
2921 				if (crypto_priv->def_tx_keyid == i) {
2922 					sta_key->flags
2923 						|= WLAN_CRYPTO_KEY_DEFAULT;
2924 					sta_crypto_priv->def_tx_keyid =
2925 						crypto_priv->def_tx_keyid;
2926 				}
2927 				/* setting the broadcast/multicast key for sta*/
2928 				if (opmode == QDF_STA_MODE ||
2929 						opmode == QDF_IBSS_MODE){
2930 					if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
2931 						WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(
2932 							vdev, sta_key, mac_addr,
2933 							cipher_table->cipher);
2934 					}
2935 				}
2936 
2937 				/* setting unicast key */
2938 				sta_key->flags &= ~WLAN_CRYPTO_KEY_GROUP;
2939 				if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
2940 					WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev,
2941 						sta_key, mac_addr,
2942 						cipher_table->cipher);
2943 				}
2944 			}
2945 		}
2946 	}
2947 
2948 	return QDF_STATUS_SUCCESS;
2949 }
2950 
2951 /**
2952  * wlan_crypto_register_crypto_rx_ops - set crypto_rx_ops
2953  * @crypto_rx_ops: crypto_rx_ops
2954  *
2955  * This function gets called by object manger to register crypto rx ops.
2956  *
2957  * Return: QDF_STATUS
2958  */
2959 QDF_STATUS wlan_crypto_register_crypto_rx_ops(
2960 			struct wlan_lmac_if_crypto_rx_ops *crypto_rx_ops){
2961 	crypto_rx_ops->crypto_encap      = wlan_crypto_encap;
2962 	crypto_rx_ops->crypto_decap      = wlan_crypto_decap;
2963 	crypto_rx_ops->crypto_enmic      = wlan_crypto_enmic;
2964 	crypto_rx_ops->crypto_demic      = wlan_crypto_demic;
2965 	crypto_rx_ops->set_peer_wep_keys = wlan_crypto_set_peer_wep_keys;
2966 
2967 	return QDF_STATUS_SUCCESS;
2968 }
2969 
2970 /**
2971  * wlan_crypto_get_crypto_rx_ops - get crypto_rx_ops from psoc
2972  * @psoc: psoc
2973  *
2974  * This function gets called by umac to get the crypto_rx_ops
2975  *
2976  * Return: crypto_rx_ops
2977  */
2978 struct wlan_lmac_if_crypto_rx_ops *wlan_crypto_get_crypto_rx_ops(
2979 					struct wlan_objmgr_psoc *psoc)
2980 {
2981 
2982 	return &(psoc->soc_cb.rx_ops.crypto_rx_ops);
2983 }
2984 qdf_export_symbol(wlan_crypto_get_crypto_rx_ops);
2985 
2986 /**
2987  * wlan_crypto_vdev_has_auth_mode - check authmode for vdev
2988  * @vdev: vdev
2989  * @authvalue: authvalue to be checked
2990  *
2991  * This function check is authvalue passed is set in vdev or not
2992  *
2993  * Return: true or false
2994  */
2995 bool wlan_crypto_vdev_has_auth_mode(struct wlan_objmgr_vdev *vdev,
2996 					wlan_crypto_auth_mode authvalue)
2997 {
2998 	return wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE)
2999 			& authvalue;
3000 }
3001 qdf_export_symbol(wlan_crypto_vdev_has_auth_mode);
3002 
3003 /**
3004  * wlan_crypto_peer_has_auth_mode - check authmode for peer
3005  * @peer: peer
3006  * @authvalue: authvalue to be checked
3007  *
3008  * This function check is authvalue passed is set in peer or not
3009  *
3010  * Return: true or false
3011  */
3012 bool wlan_crypto_peer_has_auth_mode(struct wlan_objmgr_peer *peer,
3013 					wlan_crypto_auth_mode authvalue)
3014 {
3015 	return wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_AUTH_MODE)
3016 			& authvalue;
3017 }
3018 qdf_export_symbol(wlan_crypto_peer_has_auth_mode);
3019 
3020 /**
3021  * wlan_crypto_vdev_has_ucastcipher - check ucastcipher for vdev
3022  * @vdev: vdev
3023  * @ucastcipher: ucastcipher to be checked
3024  *
3025  * This function check is ucastcipher passed is set in vdev or not
3026  *
3027  * Return: true or false
3028  */
3029 bool wlan_crypto_vdev_has_ucastcipher(struct wlan_objmgr_vdev *vdev,
3030 					wlan_crypto_cipher_type ucastcipher)
3031 {
3032 	return wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER)
3033 			& ucastcipher;
3034 }
3035 qdf_export_symbol(wlan_crypto_vdev_has_ucastcipher);
3036 
3037 /**
3038  * wlan_crypto_peer_has_ucastcipher - check ucastcipher for peer
3039  * @peer: peer
3040  * @ucastcipher: ucastcipher to be checked
3041  *
3042  * This function check is ucastcipher passed is set in peer or not
3043  *
3044  * Return: true or false
3045  */
3046 bool wlan_crypto_peer_has_ucastcipher(struct wlan_objmgr_peer *peer,
3047 					wlan_crypto_cipher_type ucastcipher)
3048 {
3049 	return wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER)
3050 			& ucastcipher;
3051 }
3052 qdf_export_symbol(wlan_crypto_peer_has_ucastcipher);
3053 
3054 /**
3055  * wlan_crypto_vdev_has_mcastcipher - check mcastcipher for vdev
3056  * @vdev: vdev
3057  * @mcastcipher: mcastcipher to be checked
3058  *
3059  * This function check is mcastcipher passed is set in vdev or not
3060  *
3061  * Return: true or false
3062  */
3063 bool wlan_crypto_vdev_has_mcastcipher(struct wlan_objmgr_vdev *vdev,
3064 					wlan_crypto_cipher_type mcastcipher)
3065 {
3066 	return wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER)
3067 			& mcastcipher;
3068 }
3069 qdf_export_symbol(wlan_crypto_vdev_has_mcastcipher);
3070 
3071 /**
3072  * wlan_crypto_peer_has_mcastcipher - check mcastcipher for peer
3073  * @peer: peer
3074  * @mcastcipher: mcastcipher to be checked
3075  *
3076  * This function check is mcastcipher passed is set in peer or not
3077  *
3078  * Return: true or false
3079  */
3080 bool wlan_crypto_peer_has_mcastcipher(struct wlan_objmgr_peer *peer,
3081 					wlan_crypto_cipher_type mcastcipher)
3082 {
3083 	return wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER)
3084 			& mcastcipher;
3085 }
3086 qdf_export_symbol(wlan_crypto_peer_has_mcastcipher);
3087 
3088 uint8_t wlan_crypto_get_peer_fils_aead(struct wlan_objmgr_peer *peer)
3089 {
3090 	struct wlan_crypto_comp_priv *crypto_priv = NULL;
3091 
3092 	if (!peer) {
3093 		qdf_err("Invalid Input");
3094 		return 0;
3095 	}
3096 
3097 	crypto_priv = wlan_get_peer_crypto_obj(peer);
3098 	if (!crypto_priv) {
3099 		qdf_err("crypto_priv NULL");
3100 		return 0;
3101 	}
3102 
3103 	return crypto_priv->fils_aead_set;
3104 }
3105 
3106 void
3107 wlan_crypto_set_peer_fils_aead(struct wlan_objmgr_peer *peer, uint8_t value)
3108 {
3109 	struct wlan_crypto_comp_priv *crypto_priv = NULL;
3110 
3111 	if (!peer) {
3112 		qdf_err("Invalid Input");
3113 		return;
3114 	}
3115 
3116 	crypto_priv = wlan_get_peer_crypto_obj(peer);
3117 	if (!crypto_priv) {
3118 		qdf_err("crypto_priv NULL");
3119 		return;
3120 	}
3121 
3122 	crypto_priv->fils_aead_set = value;
3123 }
3124 
3125 /**
3126  * wlan_crypto_get_key_header - get header length
3127  * @key: key
3128  *
3129  * This function gets header length based on keytype
3130  *
3131  * Return: header length
3132  */
3133 uint8_t wlan_crypto_get_key_header(struct wlan_crypto_key *key)
3134 {
3135 	struct wlan_crypto_cipher *cipher_table;
3136 
3137 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3138 	if (cipher_table)
3139 		return cipher_table->header;
3140 	else
3141 		return 0;
3142 }
3143 
3144 qdf_export_symbol(wlan_crypto_get_key_header);
3145 
3146 /**
3147  * wlan_crypto_get_key_trailer - get cipher trailer length
3148  * @key: key
3149  *
3150  * This function gets cipher trailer length based on keytype
3151  *
3152  * Return: cipher trailer length
3153  */
3154 uint8_t wlan_crypto_get_key_trailer(struct wlan_crypto_key *key)
3155 {
3156 	struct wlan_crypto_cipher *cipher_table;
3157 
3158 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3159 	if (cipher_table)
3160 		return cipher_table->trailer;
3161 	else
3162 		return 0;
3163 }
3164 
3165 qdf_export_symbol(wlan_crypto_get_key_trailer);
3166 
3167 /**
3168  * wlan_crypto_get_key_miclen - get cipher miclen length
3169  * @key: key
3170  *
3171  * This function gets cipher miclen length based on keytype
3172  *
3173  * Return: cipher miclen length
3174  */
3175 uint8_t wlan_crypto_get_key_miclen(struct wlan_crypto_key *key)
3176 {
3177 	struct wlan_crypto_cipher *cipher_table;
3178 
3179 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3180 	if (cipher_table)
3181 		return cipher_table->miclen;
3182 	else
3183 		return 0;
3184 }
3185 
3186 qdf_export_symbol(wlan_crypto_get_key_miclen);
3187 
3188 /**
3189  * wlan_crypto_get_keyid - get keyid from frame
3190  * @data: frame
3191  *
3192  * This function parse frame and returns keyid
3193  *
3194  * Return: keyid
3195  */
3196 uint16_t wlan_crypto_get_keyid(uint8_t *data, int hdrlen)
3197 {
3198 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data;
3199 	uint8_t *iv;
3200 	uint8_t stype = WLAN_FC0_GET_STYPE(hdr->frame_control[0]);
3201 
3202 	/*
3203 	 * In FILS SK (Re)Association request/response frame has
3204 	 * to be decrypted
3205 	 */
3206 	if ((stype == WLAN_FC0_STYPE_ASSOC_REQ) ||
3207 	    (stype == WLAN_FC0_STYPE_REASSOC_REQ) ||
3208 	    (stype == WLAN_FC0_STYPE_ASSOC_RESP) ||
3209 	    (stype == WLAN_FC0_STYPE_REASSOC_RESP)) {
3210 		return 0;
3211 	}
3212 
3213 	if (hdr->frame_control[1] & WLAN_FC1_ISWEP) {
3214 		iv = data + hdrlen;
3215 		/*
3216 		 * iv[3] is the Key ID octet in the CCMP/TKIP/WEP headers
3217 		 * Bits 6–7 of the Key ID octet are for the Key ID subfield
3218 		 */
3219 		return ((iv[3] >> 6) & 0x3);
3220 	} else {
3221 		return WLAN_CRYPTO_KEYIX_NONE;
3222 	}
3223 }
3224 
3225 qdf_export_symbol(wlan_crypto_get_keyid);
3226 
3227 /**
3228  * crypto_plumb_peer_keys - called during radio reset
3229  * @vdev: vdev
3230  * @object: peer
3231  * @arg: psoc
3232  *
3233  * Restore unicast and persta hardware keys
3234  *
3235  * Return: void
3236  */
3237 static void crypto_plumb_peer_keys(struct wlan_objmgr_vdev *vdev,
3238 				   void *object, void *arg) {
3239 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)object;
3240 	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)arg;
3241 	struct wlan_crypto_comp_priv *crypto_priv;
3242 	struct wlan_crypto_params *crypto_params;
3243 	struct wlan_crypto_key *key = NULL;
3244 	int i;
3245 
3246 	if ((NULL == peer) || (NULL == vdev) || (NULL == psoc)) {
3247 		QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
3248 			  "%s[%d] Peer or vdev or psoc objects are null!",
3249 			  __func__, __LINE__);
3250 		return;
3251 	}
3252 
3253 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
3254 							 &crypto_priv);
3255 
3256 	if (!crypto_priv) {
3257 		QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
3258 			  "%s[%d] crypto_priv NULL",
3259 			  __func__, __LINE__);
3260 		return;
3261 	}
3262 
3263 	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
3264 		key = crypto_priv->key[i];
3265 		if (key && key->valid) {
3266 			if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
3267 				WLAN_CRYPTO_TX_OPS_SETKEY(psoc)
3268 					(
3269 					 vdev,
3270 					 key,
3271 					 wlan_peer_get_macaddr(peer),
3272 					 wlan_crypto_get_key_type(key)
3273 					);
3274 			}
3275 		}
3276 	}
3277 }
3278 
3279 /**
3280  * wlan_crypto_restore_keys - called during radio reset
3281  * @vdev: vdev
3282  *
3283  * Clear and restore keycache, needed for some DA chipsets which put
3284  * random values in keycache when phy reset is triggered
3285  *
3286  * Return: void
3287  */
3288 void wlan_crypto_restore_keys(struct wlan_objmgr_vdev *vdev)
3289 {
3290 	int i;
3291 	struct wlan_crypto_comp_priv *crypto_priv;
3292 	struct wlan_crypto_params *crypto_params;
3293 	struct wlan_crypto_key *key;
3294 	uint8_t macaddr[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3295 	struct wlan_objmgr_pdev *pdev = NULL;
3296 	struct wlan_objmgr_psoc *psoc = NULL;
3297 
3298 	pdev = wlan_vdev_get_pdev(vdev);
3299 	psoc = wlan_vdev_get_psoc(vdev);
3300 	if (NULL == pdev) {
3301 		QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
3302 			  "%s[%d] pdev is NULL",
3303 			  __func__, __LINE__);
3304 		return;
3305 	}
3306 	if (NULL == psoc) {
3307 		QDF_TRACE(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_ERROR,
3308 			  "%s[%d] psoc is NULL",
3309 			  __func__, __LINE__);
3310 		return;
3311 	}
3312 
3313 	/* TBD: QWRAP key restore*/
3314 	/* crypto is on */
3315 	if (wlan_vdev_mlme_feat_cap_get(vdev, WLAN_VDEV_F_PRIVACY)) {
3316 		/* restore static shared keys */
3317 		for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
3318 			crypto_params = wlan_crypto_vdev_get_comp_params
3319 				(
3320 				 vdev,
3321 				 &crypto_priv
3322 				);
3323 			if (!crypto_priv) {
3324 				QDF_TRACE(QDF_MODULE_ID_CRYPTO,
3325 					  QDF_TRACE_LEVEL_ERROR,
3326 					  "%s[%d] crypto_priv is NULL",
3327 					  __func__, __LINE__);
3328 				return;
3329 			}
3330 			key = crypto_priv->key[i];
3331 			if (key && key->valid) {
3332 				if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
3333 					WLAN_CRYPTO_TX_OPS_SETKEY(psoc)
3334 						(
3335 						 vdev,
3336 						 key,
3337 						 macaddr,
3338 						 wlan_crypto_get_key_type(key)
3339 						 );
3340 				}
3341 			}
3342 		}
3343 
3344 		wlan_objmgr_iterate_peerobj_list(vdev,
3345 						 crypto_plumb_peer_keys,
3346 						 psoc,
3347 						 WLAN_CRYPTO_ID);
3348 	}
3349 }
3350