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