xref: /wlan-driver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: Public APIs for crypto service
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #include <qdf_types.h>
25*5113495bSYour Name #include <wlan_cmn.h>
26*5113495bSYour Name #include <wlan_objmgr_cmn.h>
27*5113495bSYour Name #include <wlan_objmgr_global_obj.h>
28*5113495bSYour Name #include <wlan_objmgr_psoc_obj.h>
29*5113495bSYour Name #include <wlan_objmgr_pdev_obj.h>
30*5113495bSYour Name #include <wlan_objmgr_vdev_obj.h>
31*5113495bSYour Name #include <wlan_objmgr_peer_obj.h>
32*5113495bSYour Name #include <wlan_utility.h>
33*5113495bSYour Name #include <wlan_cp_stats_utils_api.h>
34*5113495bSYour Name 
35*5113495bSYour Name #include "wlan_crypto_global_def.h"
36*5113495bSYour Name #include "wlan_crypto_global_api.h"
37*5113495bSYour Name #include "wlan_crypto_def_i.h"
38*5113495bSYour Name #include "wlan_crypto_param_handling_i.h"
39*5113495bSYour Name #include "wlan_crypto_obj_mgr_i.h"
40*5113495bSYour Name #include "wlan_crypto_main.h"
41*5113495bSYour Name #include <qdf_module.h>
42*5113495bSYour Name 
43*5113495bSYour Name const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
44*5113495bSYour Name 
45*5113495bSYour Name #define WPA_ADD_CIPHER_TO_SUITE(frm, cipher) \
46*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm,\
47*5113495bSYour Name 				wlan_crypto_wpa_cipher_to_suite(cipher))
48*5113495bSYour Name 
49*5113495bSYour Name #define RSN_ADD_CIPHER_TO_SUITE(frm, cipher) \
50*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm,\
51*5113495bSYour Name 				wlan_crypto_rsn_cipher_to_suite(cipher))
52*5113495bSYour Name 
53*5113495bSYour Name #define WPA_ADD_KEYMGMT_TO_SUITE(frm, keymgmt)\
54*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm,\
55*5113495bSYour Name 				wlan_crypto_wpa_keymgmt_to_suite(keymgmt))
56*5113495bSYour Name 
57*5113495bSYour Name #define RSN_ADD_KEYMGMT_TO_SUITE(frm, keymgmt)\
58*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm,\
59*5113495bSYour Name 				wlan_crypto_rsn_keymgmt_to_suite(keymgmt))
60*5113495bSYour Name 
is_valid_keyix(uint16_t keyix)61*5113495bSYour Name bool is_valid_keyix(uint16_t keyix)
62*5113495bSYour Name {
63*5113495bSYour Name 	if (keyix >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX
64*5113495bSYour Name 			+ WLAN_CRYPTO_MAXBIGTKKEYIDX))
65*5113495bSYour Name 		return 0;
66*5113495bSYour Name 	else
67*5113495bSYour Name 		return 1;
68*5113495bSYour Name }
69*5113495bSYour Name 
is_igtk(uint16_t keyix)70*5113495bSYour Name bool is_igtk(uint16_t keyix)
71*5113495bSYour Name {
72*5113495bSYour Name 	if (keyix < WLAN_CRYPTO_MAXKEYIDX)
73*5113495bSYour Name 		return 0;
74*5113495bSYour Name 	else if (keyix - WLAN_CRYPTO_MAXKEYIDX >= WLAN_CRYPTO_MAXIGTKKEYIDX)
75*5113495bSYour Name 		return 0;
76*5113495bSYour Name 	else
77*5113495bSYour Name 		return 1;
78*5113495bSYour Name }
79*5113495bSYour Name 
is_bigtk(uint16_t keyix)80*5113495bSYour Name bool is_bigtk(uint16_t keyix)
81*5113495bSYour Name {
82*5113495bSYour Name 	if (keyix < (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))
83*5113495bSYour Name 		return 0;
84*5113495bSYour Name 	if (keyix - WLAN_CRYPTO_MAXKEYIDX - WLAN_CRYPTO_MAXIGTKKEYIDX
85*5113495bSYour Name 						>= WLAN_CRYPTO_MAXBIGTKKEYIDX)
86*5113495bSYour Name 		return 0;
87*5113495bSYour Name 	else
88*5113495bSYour Name 		return 1;
89*5113495bSYour Name }
90*5113495bSYour Name 
is_gtk(uint16_t keyix)91*5113495bSYour Name bool is_gtk(uint16_t keyix)
92*5113495bSYour Name {
93*5113495bSYour Name 	if (keyix == 1 || keyix == 2)
94*5113495bSYour Name 		return 1;
95*5113495bSYour Name 	else
96*5113495bSYour Name 		return 0;
97*5113495bSYour Name }
98*5113495bSYour Name 
99*5113495bSYour Name /**
100*5113495bSYour Name  * wlan_crypto_vdev_get_comp_params() - called by mlme to get crypto params
101*5113495bSYour Name  * @vdev: vdev
102*5113495bSYour Name  * @crypto_priv: location to store pointer to the crypto private data
103*5113495bSYour Name  *
104*5113495bSYour Name  * This function gets called by mlme to get crypto params
105*5113495bSYour Name  *
106*5113495bSYour Name  * Return: wlan_crypto_params or NULL in case of failure
107*5113495bSYour Name  */
wlan_crypto_vdev_get_comp_params(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_comp_priv ** crypto_priv)108*5113495bSYour Name static struct wlan_crypto_params *wlan_crypto_vdev_get_comp_params(
109*5113495bSYour Name 				struct wlan_objmgr_vdev *vdev,
110*5113495bSYour Name 				struct wlan_crypto_comp_priv **crypto_priv)
111*5113495bSYour Name {
112*5113495bSYour Name 	*crypto_priv = (struct wlan_crypto_comp_priv *)
113*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
114*5113495bSYour Name 	if (!(*crypto_priv)) {
115*5113495bSYour Name 		crypto_err("crypto_priv NULL");
116*5113495bSYour Name 		return NULL;
117*5113495bSYour Name 	}
118*5113495bSYour Name 
119*5113495bSYour Name 	return &((*crypto_priv)->crypto_params);
120*5113495bSYour Name }
121*5113495bSYour Name 
122*5113495bSYour Name /**
123*5113495bSYour Name  * wlan_crypto_peer_get_comp_params() - called by mlme to get crypto params
124*5113495bSYour Name  * @peer: peer
125*5113495bSYour Name  * @crypto_priv: location to store pointer to the crypto private data
126*5113495bSYour Name  *
127*5113495bSYour Name  * This function gets called by mlme to get crypto params
128*5113495bSYour Name  *
129*5113495bSYour Name  * Return: wlan_crypto_params or NULL in case of failure
130*5113495bSYour Name  */
wlan_crypto_peer_get_comp_params(struct wlan_objmgr_peer * peer,struct wlan_crypto_comp_priv ** crypto_priv)131*5113495bSYour Name static struct wlan_crypto_params *wlan_crypto_peer_get_comp_params(
132*5113495bSYour Name 				struct wlan_objmgr_peer *peer,
133*5113495bSYour Name 				struct wlan_crypto_comp_priv **crypto_priv)
134*5113495bSYour Name {
135*5113495bSYour Name 
136*5113495bSYour Name 	*crypto_priv = (struct wlan_crypto_comp_priv *)
137*5113495bSYour Name 					wlan_get_peer_crypto_obj(peer);
138*5113495bSYour Name 	if (!*crypto_priv) {
139*5113495bSYour Name 		crypto_err("crypto_priv NULL");
140*5113495bSYour Name 		return NULL;
141*5113495bSYour Name 	}
142*5113495bSYour Name 
143*5113495bSYour Name 	return &((*crypto_priv)->crypto_params);
144*5113495bSYour Name }
145*5113495bSYour Name 
wlan_crypto_set_igtk_key(struct wlan_crypto_key * key)146*5113495bSYour Name static QDF_STATUS wlan_crypto_set_igtk_key(struct wlan_crypto_key *key)
147*5113495bSYour Name {
148*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
149*5113495bSYour Name }
150*5113495bSYour Name 
151*5113495bSYour Name /**
152*5113495bSYour Name  * wlan_crypto_set_param() - called by ucfg to set crypto param
153*5113495bSYour Name  * @crypto_params: crypto_params
154*5113495bSYour Name  * @param: param to be set.
155*5113495bSYour Name  * @value: value
156*5113495bSYour Name  *
157*5113495bSYour Name  * This function gets called from ucfg to set param
158*5113495bSYour Name  *
159*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - in case of success
160*5113495bSYour Name  */
wlan_crypto_set_param(struct wlan_crypto_params * crypto_params,wlan_crypto_param_type param,uint32_t value)161*5113495bSYour Name static QDF_STATUS wlan_crypto_set_param(struct wlan_crypto_params *crypto_params,
162*5113495bSYour Name 					wlan_crypto_param_type param,
163*5113495bSYour Name 					uint32_t value)
164*5113495bSYour Name {
165*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
166*5113495bSYour Name 
167*5113495bSYour Name 	crypto_debug("param %d, value %d", param, value);
168*5113495bSYour Name 	switch (param) {
169*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_AUTH_MODE:
170*5113495bSYour Name 		status = wlan_crypto_set_authmode(crypto_params, value);
171*5113495bSYour Name 		break;
172*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
173*5113495bSYour Name 		status = wlan_crypto_set_ucastciphers(crypto_params, value);
174*5113495bSYour Name 		break;
175*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
176*5113495bSYour Name 		status = wlan_crypto_set_mcastcipher(crypto_params, value);
177*5113495bSYour Name 		break;
178*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
179*5113495bSYour Name 		status = wlan_crypto_set_mgmtcipher(crypto_params, value);
180*5113495bSYour Name 		break;
181*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
182*5113495bSYour Name 		status = wlan_crypto_set_cipher_cap(crypto_params, value);
183*5113495bSYour Name 		break;
184*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_RSN_CAP:
185*5113495bSYour Name 		status = wlan_crypto_set_rsn_cap(crypto_params,	value);
186*5113495bSYour Name 		break;
187*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_RSNX_CAP:
188*5113495bSYour Name 		status = wlan_crypto_set_rsnx_cap(crypto_params, value);
189*5113495bSYour Name 		break;
190*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_KEY_MGMT:
191*5113495bSYour Name 		status = wlan_crypto_set_key_mgmt(crypto_params, value);
192*5113495bSYour Name 		break;
193*5113495bSYour Name 	default:
194*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
195*5113495bSYour Name 	}
196*5113495bSYour Name 	return status;
197*5113495bSYour Name }
198*5113495bSYour Name 
wlan_crypto_set_vdev_param(struct wlan_objmgr_vdev * vdev,wlan_crypto_param_type param,uint32_t value)199*5113495bSYour Name QDF_STATUS wlan_crypto_set_vdev_param(struct wlan_objmgr_vdev *vdev,
200*5113495bSYour Name 					wlan_crypto_param_type param,
201*5113495bSYour Name 					uint32_t value)
202*5113495bSYour Name {
203*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
204*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
205*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
206*5113495bSYour Name 
207*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
208*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
209*5113495bSYour Name 
210*5113495bSYour Name 	if (!crypto_priv) {
211*5113495bSYour Name 		crypto_err("crypto_priv NULL");
212*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
213*5113495bSYour Name 	}
214*5113495bSYour Name 
215*5113495bSYour Name 	crypto_params = &(crypto_priv->crypto_params);
216*5113495bSYour Name 
217*5113495bSYour Name 	status = wlan_crypto_set_param(crypto_params, param, value);
218*5113495bSYour Name 
219*5113495bSYour Name 	return status;
220*5113495bSYour Name }
221*5113495bSYour Name 
wlan_crypto_set_peer_param(struct wlan_objmgr_peer * peer,wlan_crypto_param_type param,uint32_t value)222*5113495bSYour Name QDF_STATUS wlan_crypto_set_peer_param(struct wlan_objmgr_peer *peer,
223*5113495bSYour Name 				wlan_crypto_param_type param,
224*5113495bSYour Name 				uint32_t value)
225*5113495bSYour Name {
226*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
227*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
228*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
229*5113495bSYour Name 
230*5113495bSYour Name 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
231*5113495bSYour Name 							&crypto_priv);
232*5113495bSYour Name 
233*5113495bSYour Name 	if (!crypto_priv) {
234*5113495bSYour Name 		crypto_err("crypto_priv NULL");
235*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
236*5113495bSYour Name 	}
237*5113495bSYour Name 
238*5113495bSYour Name 	crypto_params = &(crypto_priv->crypto_params);
239*5113495bSYour Name 
240*5113495bSYour Name 	status = wlan_crypto_set_param(crypto_params, param, value);
241*5113495bSYour Name 
242*5113495bSYour Name 	return status;
243*5113495bSYour Name }
244*5113495bSYour Name 
245*5113495bSYour Name /**
246*5113495bSYour Name  * wlan_crypto_get_param_value() - called by crypto APIs to get value for param
247*5113495bSYour Name  * @param: Crypto param type
248*5113495bSYour Name  * @crypto_params: Crypto params struct
249*5113495bSYour Name  *
250*5113495bSYour Name  * This function gets called from in-within crypto layer
251*5113495bSYour Name  *
252*5113495bSYour Name  * Return: value or -1 for failure
253*5113495bSYour Name  */
wlan_crypto_get_param_value(wlan_crypto_param_type param,struct wlan_crypto_params * crypto_params)254*5113495bSYour Name static int32_t wlan_crypto_get_param_value(wlan_crypto_param_type param,
255*5113495bSYour Name 				struct wlan_crypto_params *crypto_params)
256*5113495bSYour Name {
257*5113495bSYour Name 	int32_t value;
258*5113495bSYour Name 
259*5113495bSYour Name 	switch (param) {
260*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_AUTH_MODE:
261*5113495bSYour Name 		value = wlan_crypto_get_authmode(crypto_params);
262*5113495bSYour Name 		break;
263*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
264*5113495bSYour Name 		value = wlan_crypto_get_ucastciphers(crypto_params);
265*5113495bSYour Name 		break;
266*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
267*5113495bSYour Name 		value = wlan_crypto_get_mcastcipher(crypto_params);
268*5113495bSYour Name 		break;
269*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
270*5113495bSYour Name 		value = wlan_crypto_get_mgmtciphers(crypto_params);
271*5113495bSYour Name 		break;
272*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
273*5113495bSYour Name 		value = wlan_crypto_get_cipher_cap(crypto_params);
274*5113495bSYour Name 		break;
275*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_RSN_CAP:
276*5113495bSYour Name 		value = wlan_crypto_get_rsn_cap(crypto_params);
277*5113495bSYour Name 		break;
278*5113495bSYour Name 	case WLAN_CRYPTO_PARAM_KEY_MGMT:
279*5113495bSYour Name 		value = wlan_crypto_get_key_mgmt(crypto_params);
280*5113495bSYour Name 		break;
281*5113495bSYour Name 	default:
282*5113495bSYour Name 		value = -1;
283*5113495bSYour Name 	}
284*5113495bSYour Name 
285*5113495bSYour Name 	return value;
286*5113495bSYour Name }
287*5113495bSYour Name 
wlan_crypto_get_param(struct wlan_objmgr_vdev * vdev,wlan_crypto_param_type param)288*5113495bSYour Name int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev,
289*5113495bSYour Name 			      wlan_crypto_param_type param)
290*5113495bSYour Name {
291*5113495bSYour Name 	int32_t value = -1;
292*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
293*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
294*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
295*5113495bSYour Name 				wlan_get_vdev_crypto_obj(vdev);
296*5113495bSYour Name 
297*5113495bSYour Name 	if (!crypto_priv) {
298*5113495bSYour Name 		crypto_err("crypto_priv NULL");
299*5113495bSYour Name 		return value;
300*5113495bSYour Name 	}
301*5113495bSYour Name 
302*5113495bSYour Name 	crypto_params = &(crypto_priv->crypto_params);
303*5113495bSYour Name 	value = wlan_crypto_get_param_value(param, crypto_params);
304*5113495bSYour Name 
305*5113495bSYour Name 	return value;
306*5113495bSYour Name }
307*5113495bSYour Name 
wlan_crypto_get_peer_param(struct wlan_objmgr_peer * peer,wlan_crypto_param_type param)308*5113495bSYour Name int32_t wlan_crypto_get_peer_param(struct wlan_objmgr_peer *peer,
309*5113495bSYour Name 				   wlan_crypto_param_type param)
310*5113495bSYour Name {
311*5113495bSYour Name 	int32_t value = -1;
312*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
313*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
314*5113495bSYour Name 
315*5113495bSYour Name 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
316*5113495bSYour Name 							&crypto_priv);
317*5113495bSYour Name 
318*5113495bSYour Name 	if (!crypto_params) {
319*5113495bSYour Name 		crypto_err("crypto_params NULL");
320*5113495bSYour Name 		return value;
321*5113495bSYour Name 	}
322*5113495bSYour Name 	value = wlan_crypto_get_param_value(param, crypto_params);
323*5113495bSYour Name 
324*5113495bSYour Name 	return value;
325*5113495bSYour Name }
326*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_peer_param);
327*5113495bSYour Name 
328*5113495bSYour Name static
329*5113495bSYour Name QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
330*5113495bSYour Name 				 struct wlan_crypto_pmksa *pmksa);
331*5113495bSYour Name 
332*5113495bSYour Name static
wlan_crypto_set_pmksa(struct wlan_crypto_params * crypto_params,struct wlan_crypto_pmksa * pmksa)333*5113495bSYour Name QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
334*5113495bSYour Name 				 struct wlan_crypto_pmksa *pmksa)
335*5113495bSYour Name {
336*5113495bSYour Name 	uint8_t i, first_available_slot = 0;
337*5113495bSYour Name 	bool slot_found = false;
338*5113495bSYour Name 
339*5113495bSYour Name 	/* Delete the old entry and then Add new entry */
340*5113495bSYour Name 	wlan_crypto_del_pmksa(crypto_params, pmksa);
341*5113495bSYour Name 
342*5113495bSYour Name 	/* find the empty slot as duplicate is already deleted */
343*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
344*5113495bSYour Name 		if (!crypto_params->pmksa[i]) {
345*5113495bSYour Name 			slot_found = true;
346*5113495bSYour Name 			first_available_slot = i;
347*5113495bSYour Name 			break;
348*5113495bSYour Name 		}
349*5113495bSYour Name 	}
350*5113495bSYour Name 
351*5113495bSYour Name 	if (i == WLAN_CRYPTO_MAX_PMKID && !slot_found) {
352*5113495bSYour Name 		crypto_err("no entry available for pmksa");
353*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
354*5113495bSYour Name 	}
355*5113495bSYour Name 	crypto_params->pmksa[first_available_slot] = pmksa;
356*5113495bSYour Name 	crypto_debug("PMKSA: Added the PMKSA entry at index=%d",
357*5113495bSYour Name 		     first_available_slot);
358*5113495bSYour Name 
359*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
360*5113495bSYour Name }
361*5113495bSYour Name 
362*5113495bSYour Name static
wlan_crypto_del_pmksa(struct wlan_crypto_params * crypto_params,struct wlan_crypto_pmksa * pmksa)363*5113495bSYour Name QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
364*5113495bSYour Name 				 struct wlan_crypto_pmksa *pmksa)
365*5113495bSYour Name {
366*5113495bSYour Name 	uint8_t i, j, valid_entries_in_table = 0;
367*5113495bSYour Name 	bool match_found = false;
368*5113495bSYour Name 	u8 del_pmk[MAX_PMK_LEN] = {0};
369*5113495bSYour Name 
370*5113495bSYour Name 	/* find slot with same bssid */
371*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
372*5113495bSYour Name 		if (!crypto_params->pmksa[i])
373*5113495bSYour Name 			continue;
374*5113495bSYour Name 
375*5113495bSYour Name 		valid_entries_in_table++;
376*5113495bSYour Name 
377*5113495bSYour Name 		if (!pmksa->ssid_len &&
378*5113495bSYour Name 		    !qdf_is_macaddr_zero(&pmksa->bssid) &&
379*5113495bSYour Name 		    qdf_is_macaddr_equal(&pmksa->bssid,
380*5113495bSYour Name 					 &crypto_params->pmksa[i]->bssid)) {
381*5113495bSYour Name 			match_found = true;
382*5113495bSYour Name 		} else if (pmksa->ssid_len &&
383*5113495bSYour Name 			   !qdf_mem_cmp(pmksa->ssid,
384*5113495bSYour Name 					crypto_params->pmksa[i]->ssid,
385*5113495bSYour Name 					pmksa->ssid_len) &&
386*5113495bSYour Name 			   !qdf_mem_cmp(pmksa->cache_id,
387*5113495bSYour Name 					crypto_params->pmksa[i]->cache_id,
388*5113495bSYour Name 					WLAN_CACHE_ID_LEN)) {
389*5113495bSYour Name 			match_found = true;
390*5113495bSYour Name 		}
391*5113495bSYour Name 
392*5113495bSYour Name 		if (match_found) {
393*5113495bSYour Name 			qdf_mem_copy(del_pmk, crypto_params->pmksa[i]->pmk,
394*5113495bSYour Name 				     crypto_params->pmksa[i]->pmk_len);
395*5113495bSYour Name 			/* Free matching entry */
396*5113495bSYour Name 			qdf_mem_zero(crypto_params->pmksa[i],
397*5113495bSYour Name 				     sizeof(struct wlan_crypto_pmksa));
398*5113495bSYour Name 			qdf_mem_free(crypto_params->pmksa[i]);
399*5113495bSYour Name 			crypto_params->pmksa[i] = NULL;
400*5113495bSYour Name 			crypto_debug("PMKSA: Deleted PMKSA entry at index=%d",
401*5113495bSYour Name 				     i);
402*5113495bSYour Name 
403*5113495bSYour Name 			/* Find and remove the entries matching the pmk */
404*5113495bSYour Name 			for (j = 0; j < WLAN_CRYPTO_MAX_PMKID; j++) {
405*5113495bSYour Name 				if (!crypto_params->pmksa[j])
406*5113495bSYour Name 					continue;
407*5113495bSYour Name 				if (crypto_params->pmksa[j]->pmk_len &&
408*5113495bSYour Name 				    (!qdf_mem_cmp(crypto_params->pmksa[j]->pmk,
409*5113495bSYour Name 				     del_pmk,
410*5113495bSYour Name 				     crypto_params->pmksa[j]->pmk_len))) {
411*5113495bSYour Name 					qdf_mem_zero(crypto_params->pmksa[j],
412*5113495bSYour Name 					sizeof(struct wlan_crypto_pmksa));
413*5113495bSYour Name 					qdf_mem_free(crypto_params->pmksa[j]);
414*5113495bSYour Name 					crypto_params->pmksa[j] = NULL;
415*5113495bSYour Name 					crypto_debug("PMKSA: Deleted PMKSA at idx=%d",
416*5113495bSYour Name 						     j);
417*5113495bSYour Name 				}
418*5113495bSYour Name 			}
419*5113495bSYour Name 			/* reset stored pmk */
420*5113495bSYour Name 			qdf_mem_zero(del_pmk, MAX_PMK_LEN);
421*5113495bSYour Name 
422*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
423*5113495bSYour Name 		}
424*5113495bSYour Name 	}
425*5113495bSYour Name 
426*5113495bSYour Name 	if (i == WLAN_CRYPTO_MAX_PMKID && !match_found)
427*5113495bSYour Name 		crypto_debug("No such pmksa entry exists: valid entries:%d",
428*5113495bSYour Name 			     valid_entries_in_table);
429*5113495bSYour Name 
430*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
431*5113495bSYour Name }
432*5113495bSYour Name 
wlan_crypto_pmksa_flush(struct wlan_crypto_params * crypto_params)433*5113495bSYour Name QDF_STATUS wlan_crypto_pmksa_flush(struct wlan_crypto_params *crypto_params)
434*5113495bSYour Name {
435*5113495bSYour Name 	uint8_t i;
436*5113495bSYour Name 
437*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
438*5113495bSYour Name 		if (!crypto_params->pmksa[i])
439*5113495bSYour Name 			continue;
440*5113495bSYour Name 		qdf_mem_zero(crypto_params->pmksa[i],
441*5113495bSYour Name 			     sizeof(struct wlan_crypto_pmksa));
442*5113495bSYour Name 		qdf_mem_free(crypto_params->pmksa[i]);
443*5113495bSYour Name 		crypto_params->pmksa[i] = NULL;
444*5113495bSYour Name 	}
445*5113495bSYour Name 
446*5113495bSYour Name 	crypto_debug("Flushed the pmksa table");
447*5113495bSYour Name 
448*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
449*5113495bSYour Name }
450*5113495bSYour Name 
wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * pmksa,bool set)451*5113495bSYour Name QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev,
452*5113495bSYour Name 				     struct wlan_crypto_pmksa *pmksa,
453*5113495bSYour Name 				     bool set)
454*5113495bSYour Name {
455*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
456*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
457*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
458*5113495bSYour Name 	struct wlan_crypto_pmksa *pmkid_cache = NULL;
459*5113495bSYour Name 	enum QDF_OPMODE op_mode;
460*5113495bSYour Name 
461*5113495bSYour Name 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
462*5113495bSYour Name 
463*5113495bSYour Name 	if (op_mode != QDF_STA_MODE && op_mode != QDF_SAP_MODE)
464*5113495bSYour Name 		return QDF_STATUS_E_NOSUPPORT;
465*5113495bSYour Name 
466*5113495bSYour Name 	if (!pmksa && set) {
467*5113495bSYour Name 		crypto_err("pmksa is NULL for set operation");
468*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
469*5113495bSYour Name 	}
470*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
471*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
472*5113495bSYour Name 
473*5113495bSYour Name 	if (!crypto_priv) {
474*5113495bSYour Name 		crypto_err("crypto_priv NULL");
475*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
476*5113495bSYour Name 	}
477*5113495bSYour Name 
478*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
479*5113495bSYour Name 	if (set) {
480*5113495bSYour Name 		pmkid_cache = wlan_crypto_get_pmksa(vdev, &pmksa->bssid);
481*5113495bSYour Name 		if (pmkid_cache && (pmksa->pmk_len &&
482*5113495bSYour Name 				    pmksa->pmk_len == pmkid_cache->pmk_len &&
483*5113495bSYour Name 				    !qdf_mem_cmp(pmkid_cache->pmk, pmksa->pmk,
484*5113495bSYour Name 						 pmksa->pmk_len))) {
485*5113495bSYour Name 			crypto_debug("PMKSA entry found with same PMK");
486*5113495bSYour Name 			pmkid_cache = NULL;
487*5113495bSYour Name 			return QDF_STATUS_E_EXISTS;
488*5113495bSYour Name 		}
489*5113495bSYour Name 
490*5113495bSYour Name 		status = wlan_crypto_set_pmksa(crypto_params, pmksa);
491*5113495bSYour Name 		/* Set pmksa */
492*5113495bSYour Name 	} else {
493*5113495bSYour Name 		/* del pmksa */
494*5113495bSYour Name 		if (!pmksa)
495*5113495bSYour Name 			status = wlan_crypto_pmksa_flush(crypto_params);
496*5113495bSYour Name 		else
497*5113495bSYour Name 			status = wlan_crypto_del_pmksa(crypto_params, pmksa);
498*5113495bSYour Name 	}
499*5113495bSYour Name 
500*5113495bSYour Name 	return status;
501*5113495bSYour Name }
502*5113495bSYour Name 
wlan_crypto_update_pmk_cache_ft(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * pmksa)503*5113495bSYour Name QDF_STATUS wlan_crypto_update_pmk_cache_ft(struct wlan_objmgr_vdev *vdev,
504*5113495bSYour Name 					   struct wlan_crypto_pmksa *pmksa)
505*5113495bSYour Name {
506*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
507*5113495bSYour Name 	struct wlan_crypto_pmksa *cached_pmksa;
508*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
509*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
510*5113495bSYour Name 	uint8_t mdie_present, i;
511*5113495bSYour Name 	uint16_t mobility_domain;
512*5113495bSYour Name 
513*5113495bSYour Name 	if (!pmksa) {
514*5113495bSYour Name 		crypto_err("pmksa is NULL for set operation");
515*5113495bSYour Name 		return status;
516*5113495bSYour Name 	}
517*5113495bSYour Name 
518*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
519*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
520*5113495bSYour Name 	if (!crypto_priv) {
521*5113495bSYour Name 		crypto_err("crypto_priv NULL");
522*5113495bSYour Name 		return status;
523*5113495bSYour Name 	}
524*5113495bSYour Name 
525*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
526*5113495bSYour Name 
527*5113495bSYour Name 	if (pmksa->mdid.mdie_present) {
528*5113495bSYour Name 		for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
529*5113495bSYour Name 			if (!crypto_params->pmksa[i])
530*5113495bSYour Name 				continue;
531*5113495bSYour Name 			cached_pmksa = crypto_params->pmksa[i];
532*5113495bSYour Name 			mdie_present = cached_pmksa->mdid.mdie_present;
533*5113495bSYour Name 			mobility_domain = cached_pmksa->mdid.mobility_domain;
534*5113495bSYour Name 
535*5113495bSYour Name 			/* In FT connection when STA connects to AP1 then PMK1
536*5113495bSYour Name 			 * gets cached. And if STA disconnects from AP1 and
537*5113495bSYour Name 			 * connects to AP2 then PMK2 gets cached. This will
538*5113495bSYour Name 			 * result in having multiple PMK cache entries for the
539*5113495bSYour Name 			 * same MDID. So delete the old/stale PMK cache entries
540*5113495bSYour Name 			 * for the same mobility domain as of the newly added
541*5113495bSYour Name 			 * entry. And Update the MDID for the matching BSSID or
542*5113495bSYour Name 			 * SSID PMKSA entry.
543*5113495bSYour Name 			 */
544*5113495bSYour Name 			if (qdf_is_macaddr_equal
545*5113495bSYour Name 				(&cached_pmksa->bssid, &pmksa->bssid)) {
546*5113495bSYour Name 				cached_pmksa->mdid.mdie_present = 1;
547*5113495bSYour Name 				cached_pmksa->mdid.mobility_domain =
548*5113495bSYour Name 						pmksa->mdid.mobility_domain;
549*5113495bSYour Name 				crypto_debug("Updated the MDID at index=%d", i);
550*5113495bSYour Name 				status = QDF_STATUS_SUCCESS;
551*5113495bSYour Name 			} else if (pmksa->ssid_len &&
552*5113495bSYour Name 				   !qdf_mem_cmp(pmksa->ssid,
553*5113495bSYour Name 						cached_pmksa->ssid,
554*5113495bSYour Name 						pmksa->ssid_len) &&
555*5113495bSYour Name 				   !qdf_mem_cmp(pmksa->cache_id,
556*5113495bSYour Name 						cached_pmksa->cache_id,
557*5113495bSYour Name 						WLAN_CACHE_ID_LEN)) {
558*5113495bSYour Name 				cached_pmksa->mdid.mdie_present = 1;
559*5113495bSYour Name 				cached_pmksa->mdid.mobility_domain =
560*5113495bSYour Name 						pmksa->mdid.mobility_domain;
561*5113495bSYour Name 				crypto_debug("Updated the MDID at index=%d", i);
562*5113495bSYour Name 				status = QDF_STATUS_SUCCESS;
563*5113495bSYour Name 			} else if (mdie_present &&
564*5113495bSYour Name 				   (pmksa->mdid.mobility_domain ==
565*5113495bSYour Name 				    mobility_domain)) {
566*5113495bSYour Name 				qdf_mem_zero(crypto_params->pmksa[i],
567*5113495bSYour Name 					     sizeof(struct wlan_crypto_pmksa));
568*5113495bSYour Name 				qdf_mem_free(crypto_params->pmksa[i]);
569*5113495bSYour Name 				crypto_params->pmksa[i] = NULL;
570*5113495bSYour Name 				crypto_debug("Deleted PMKSA at index=%d", i);
571*5113495bSYour Name 				status = QDF_STATUS_SUCCESS;
572*5113495bSYour Name 			}
573*5113495bSYour Name 		}
574*5113495bSYour Name 	}
575*5113495bSYour Name 	return status;
576*5113495bSYour Name }
577*5113495bSYour Name 
578*5113495bSYour Name struct wlan_crypto_pmksa *
wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * pmksa)579*5113495bSYour Name wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev,
580*5113495bSYour Name 			   struct wlan_crypto_pmksa *pmksa)
581*5113495bSYour Name {
582*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
583*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
584*5113495bSYour Name 	uint8_t i;
585*5113495bSYour Name 
586*5113495bSYour Name 	if (!pmksa) {
587*5113495bSYour Name 		crypto_err("pmksa is NULL");
588*5113495bSYour Name 		return NULL;
589*5113495bSYour Name 	}
590*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
591*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
592*5113495bSYour Name 
593*5113495bSYour Name 	if (!crypto_priv) {
594*5113495bSYour Name 		crypto_err("crypto_priv NULL");
595*5113495bSYour Name 		return NULL;
596*5113495bSYour Name 	}
597*5113495bSYour Name 
598*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
599*5113495bSYour Name 
600*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
601*5113495bSYour Name 		if (!crypto_params->pmksa[i])
602*5113495bSYour Name 			continue;
603*5113495bSYour Name 
604*5113495bSYour Name 		if (pmksa->ssid_len &&
605*5113495bSYour Name 		    !qdf_mem_cmp(pmksa->ssid,
606*5113495bSYour Name 				 crypto_params->pmksa[i]->ssid,
607*5113495bSYour Name 				 pmksa->ssid_len) &&
608*5113495bSYour Name 		    !qdf_mem_cmp(pmksa->cache_id,
609*5113495bSYour Name 				 crypto_params->pmksa[i]->cache_id,
610*5113495bSYour Name 				 WLAN_CACHE_ID_LEN)) {
611*5113495bSYour Name 			return crypto_params->pmksa[i];
612*5113495bSYour Name 		} else if (!pmksa->ssid_len &&
613*5113495bSYour Name 			   !qdf_is_macaddr_zero(&pmksa->bssid) &&
614*5113495bSYour Name 			   qdf_is_macaddr_equal(&pmksa->bssid,
615*5113495bSYour Name 					 &crypto_params->pmksa[i]->bssid)) {
616*5113495bSYour Name 			return crypto_params->pmksa[i];
617*5113495bSYour Name 		}
618*5113495bSYour Name 	}
619*5113495bSYour Name 
620*5113495bSYour Name 	return NULL;
621*5113495bSYour Name }
622*5113495bSYour Name 
623*5113495bSYour Name struct wlan_crypto_pmksa *
wlan_crypto_get_pmksa(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bssid)624*5113495bSYour Name wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid)
625*5113495bSYour Name {
626*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
627*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
628*5113495bSYour Name 	uint8_t i;
629*5113495bSYour Name 
630*5113495bSYour Name 	if (!bssid) {
631*5113495bSYour Name 		crypto_err("bssid is NULL");
632*5113495bSYour Name 		return NULL;
633*5113495bSYour Name 	}
634*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
635*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
636*5113495bSYour Name 
637*5113495bSYour Name 	if (!crypto_priv) {
638*5113495bSYour Name 		crypto_err("crypto_priv NULL");
639*5113495bSYour Name 		return NULL;
640*5113495bSYour Name 	}
641*5113495bSYour Name 
642*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
643*5113495bSYour Name 
644*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
645*5113495bSYour Name 		if (!crypto_params->pmksa[i])
646*5113495bSYour Name 			continue;
647*5113495bSYour Name 		if (qdf_is_macaddr_equal(bssid,
648*5113495bSYour Name 					 &crypto_params->pmksa[i]->bssid)) {
649*5113495bSYour Name 			crypto_debug("PMKSA: Entry found at index %d", i);
650*5113495bSYour Name 			return crypto_params->pmksa[i];
651*5113495bSYour Name 		}
652*5113495bSYour Name 	}
653*5113495bSYour Name 
654*5113495bSYour Name 	return NULL;
655*5113495bSYour Name }
656*5113495bSYour Name 
657*5113495bSYour Name struct wlan_crypto_pmksa *
wlan_crypto_get_fils_pmksa(struct wlan_objmgr_vdev * vdev,uint8_t * cache_id,uint8_t * ssid,uint8_t ssid_len)658*5113495bSYour Name wlan_crypto_get_fils_pmksa(struct wlan_objmgr_vdev *vdev,
659*5113495bSYour Name 			   uint8_t *cache_id, uint8_t *ssid,
660*5113495bSYour Name 			   uint8_t ssid_len)
661*5113495bSYour Name {
662*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
663*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
664*5113495bSYour Name 	uint8_t i;
665*5113495bSYour Name 
666*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
667*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
668*5113495bSYour Name 
669*5113495bSYour Name 	if (!crypto_priv) {
670*5113495bSYour Name 		crypto_err("crypto_priv NULL");
671*5113495bSYour Name 		return NULL;
672*5113495bSYour Name 	}
673*5113495bSYour Name 
674*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
675*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
676*5113495bSYour Name 		if (!crypto_params->pmksa[i])
677*5113495bSYour Name 			continue;
678*5113495bSYour Name 
679*5113495bSYour Name 		if (!qdf_mem_cmp(cache_id,
680*5113495bSYour Name 				 crypto_params->pmksa[i]->cache_id,
681*5113495bSYour Name 				 WLAN_CACHE_ID_LEN) &&
682*5113495bSYour Name 		    !qdf_mem_cmp(ssid, crypto_params->pmksa[i]->ssid,
683*5113495bSYour Name 				 ssid_len) &&
684*5113495bSYour Name 		    ssid_len == crypto_params->pmksa[i]->ssid_len)
685*5113495bSYour Name 			return crypto_params->pmksa[i];
686*5113495bSYour Name 	}
687*5113495bSYour Name 
688*5113495bSYour Name 	return NULL;
689*5113495bSYour Name }
690*5113495bSYour Name 
wlan_crypto_is_htallowed(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)691*5113495bSYour Name uint8_t wlan_crypto_is_htallowed(struct wlan_objmgr_vdev *vdev,
692*5113495bSYour Name 				 struct wlan_objmgr_peer *peer)
693*5113495bSYour Name {
694*5113495bSYour Name 	int32_t ucast_cipher;
695*5113495bSYour Name 
696*5113495bSYour Name 	if (!(vdev || peer)) {
697*5113495bSYour Name 		crypto_err("Invalid params");
698*5113495bSYour Name 		return 0;
699*5113495bSYour Name 	}
700*5113495bSYour Name 
701*5113495bSYour Name 	if (vdev)
702*5113495bSYour Name 		ucast_cipher = wlan_crypto_get_param(vdev,
703*5113495bSYour Name 				WLAN_CRYPTO_PARAM_UCAST_CIPHER);
704*5113495bSYour Name 	else
705*5113495bSYour Name 		ucast_cipher = wlan_crypto_get_peer_param(peer,
706*5113495bSYour Name 				WLAN_CRYPTO_PARAM_UCAST_CIPHER);
707*5113495bSYour Name 
708*5113495bSYour Name 	if (ucast_cipher == -1) {
709*5113495bSYour Name 		crypto_err("Invalid params");
710*5113495bSYour Name 		return 0;
711*5113495bSYour Name 	}
712*5113495bSYour Name 
713*5113495bSYour Name 	return (ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_WEP)) ||
714*5113495bSYour Name 		((ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_TKIP)) &&
715*5113495bSYour Name 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM)) &&
716*5113495bSYour Name 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM)) &&
717*5113495bSYour Name 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM_256)) &&
718*5113495bSYour Name 		!(ucast_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_CCM_256)));
719*5113495bSYour Name }
720*5113495bSYour Name qdf_export_symbol(wlan_crypto_is_htallowed);
721*5113495bSYour Name 
722*5113495bSYour Name /**
723*5113495bSYour Name  * wlan_crypto_store_def_keyix - store default keyix
724*5113495bSYour Name  * @vdev: vdev
725*5113495bSYour Name  * @object: Peer object
726*5113495bSYour Name  * @arg: Argument passed by caller
727*5113495bSYour Name  *
728*5113495bSYour Name  * This function gets called from wlan_crypto_setkey
729*5113495bSYour Name  *
730*5113495bSYour Name  * Return: None
731*5113495bSYour Name  */
wlan_crypto_store_def_keyix(struct wlan_objmgr_vdev * vdev,void * object,void * arg)732*5113495bSYour Name static void wlan_crypto_store_def_keyix(struct wlan_objmgr_vdev *vdev,
733*5113495bSYour Name 					void *object, void *arg)
734*5113495bSYour Name {
735*5113495bSYour Name 	struct wlan_objmgr_peer *peer = object;
736*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
737*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
738*5113495bSYour Name 
739*5113495bSYour Name 	uint16_t kid = *(uint16_t *)arg;
740*5113495bSYour Name 
741*5113495bSYour Name 	crypto_params = wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
742*5113495bSYour Name 	if (!crypto_priv) {
743*5113495bSYour Name 		crypto_err("crypto_priv NULL");
744*5113495bSYour Name 		return;
745*5113495bSYour Name 	}
746*5113495bSYour Name 	crypto_priv->crypto_key.def_tx_keyid = kid;
747*5113495bSYour Name }
748*5113495bSYour Name 
749*5113495bSYour Name /**
750*5113495bSYour Name  * wlan_crypto_setkey - called by ucfg to setkey
751*5113495bSYour Name  * @vdev: vdev
752*5113495bSYour Name  * @req_key: req_key with cipher type, key macaddress
753*5113495bSYour Name  *
754*5113495bSYour Name  * This function gets called from ucfg to sey key
755*5113495bSYour Name  *
756*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - in case of success
757*5113495bSYour Name  */
wlan_crypto_setkey(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_req_key * req_key)758*5113495bSYour Name QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
759*5113495bSYour Name 				struct wlan_crypto_req_key *req_key)
760*5113495bSYour Name {
761*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
762*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
763*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
764*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
765*5113495bSYour Name 	struct wlan_objmgr_peer *peer = NULL;
766*5113495bSYour Name 	struct wlan_crypto_key *key = NULL;
767*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
768*5113495bSYour Name 	const struct wlan_crypto_cipher *cipher;
769*5113495bSYour Name 	uint8_t macaddr[QDF_MAC_ADDR_SIZE] =
770*5113495bSYour Name 			{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
771*5113495bSYour Name 	bool isbcast;
772*5113495bSYour Name 	enum QDF_OPMODE vdev_mode;
773*5113495bSYour Name 	uint8_t igtk_idx = 0;
774*5113495bSYour Name 	uint8_t bigtk_idx = 0;
775*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
776*5113495bSYour Name 
777*5113495bSYour Name 	if (!vdev || !req_key || req_key->keylen > (sizeof(req_key->keydata))) {
778*5113495bSYour Name 		crypto_err("Invalid params vdev%pK, req_key%pK", vdev, req_key);
779*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
780*5113495bSYour Name 	}
781*5113495bSYour Name 
782*5113495bSYour Name 	isbcast = qdf_is_macaddr_group(
783*5113495bSYour Name 				(struct qdf_mac_addr *)req_key->macaddr);
784*5113495bSYour Name 	if ((req_key->keylen == 0) && !IS_FILS_CIPHER(req_key->type)) {
785*5113495bSYour Name 		/* zero length keys, only set default key id if flags are set*/
786*5113495bSYour Name 		if ((req_key->flags & WLAN_CRYPTO_KEY_DEFAULT)
787*5113495bSYour Name 			&& (req_key->keyix != WLAN_CRYPTO_KEYIX_NONE)
788*5113495bSYour Name 			&& (!IS_MGMT_CIPHER(req_key->type))) {
789*5113495bSYour Name 			wlan_crypto_default_key(vdev,
790*5113495bSYour Name 				req_key->macaddr,
791*5113495bSYour Name 				req_key->keyix,
792*5113495bSYour Name 				!isbcast);
793*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
794*5113495bSYour Name 		}
795*5113495bSYour Name 		crypto_err("req_key len zero");
796*5113495bSYour Name 		return QDF_STATUS_CRYPTO_INVALID_KEYLEN;
797*5113495bSYour Name 	}
798*5113495bSYour Name 
799*5113495bSYour Name 	cipher = wlan_crypto_cipher_ops[req_key->type];
800*5113495bSYour Name 
801*5113495bSYour Name 	if (!cipher && !IS_MGMT_CIPHER(req_key->type)) {
802*5113495bSYour Name 		crypto_err("cipher invalid");
803*5113495bSYour Name 		return QDF_STATUS_CRYPTO_INVALID_CIPHERTYPE;
804*5113495bSYour Name 	}
805*5113495bSYour Name 
806*5113495bSYour Name 	if (cipher && (!IS_FILS_CIPHER(req_key->type)) &&
807*5113495bSYour Name 	    (!IS_MGMT_CIPHER(req_key->type)) &&
808*5113495bSYour Name 	    ((req_key->keylen != (cipher->keylen / CRYPTO_NBBY)) &&
809*5113495bSYour Name 	    (req_key->type != WLAN_CRYPTO_CIPHER_WEP))) {
810*5113495bSYour Name 		crypto_err("cipher invalid");
811*5113495bSYour Name 		return QDF_STATUS_CRYPTO_INVALID_CIPHERTYPE;
812*5113495bSYour Name 	} else if ((req_key->type == WLAN_CRYPTO_CIPHER_WEP) &&
813*5113495bSYour Name 		!((req_key->keylen == WLAN_CRYPTO_KEY_WEP40_LEN)
814*5113495bSYour Name 		|| (req_key->keylen == WLAN_CRYPTO_KEY_WEP104_LEN)
815*5113495bSYour Name 		|| (req_key->keylen == WLAN_CRYPTO_KEY_WEP128_LEN))) {
816*5113495bSYour Name 		crypto_err("wep key len invalid. keylen: %d", req_key->keylen);
817*5113495bSYour Name 		return QDF_STATUS_CRYPTO_INVALID_KEYLEN;
818*5113495bSYour Name 	}
819*5113495bSYour Name 
820*5113495bSYour Name 	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE) {
821*5113495bSYour Name 		if (req_key->flags != (WLAN_CRYPTO_KEY_XMIT
822*5113495bSYour Name 						| WLAN_CRYPTO_KEY_RECV)) {
823*5113495bSYour Name 			req_key->flags |= (WLAN_CRYPTO_KEY_XMIT
824*5113495bSYour Name 						| WLAN_CRYPTO_KEY_RECV);
825*5113495bSYour Name 		}
826*5113495bSYour Name 	} else {
827*5113495bSYour Name 		if ((req_key->keyix >= WLAN_CRYPTO_MAX_VLANKEYIX)
828*5113495bSYour Name 			&& (!IS_MGMT_CIPHER(req_key->type))) {
829*5113495bSYour Name 			return QDF_STATUS_CRYPTO_INVALID_KEYID;
830*5113495bSYour Name 		}
831*5113495bSYour Name 
832*5113495bSYour Name 		req_key->flags |= (WLAN_CRYPTO_KEY_XMIT
833*5113495bSYour Name 					| WLAN_CRYPTO_KEY_RECV);
834*5113495bSYour Name 		if (isbcast)
835*5113495bSYour Name 			req_key->flags |= WLAN_CRYPTO_KEY_GROUP;
836*5113495bSYour Name 	}
837*5113495bSYour Name 
838*5113495bSYour Name 	vdev_mode = wlan_vdev_mlme_get_opmode(vdev);
839*5113495bSYour Name 
840*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
841*5113495bSYour Name 	qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(vdev),
842*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
843*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
844*5113495bSYour Name 	if (!psoc) {
845*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
846*5113495bSYour Name 		crypto_err("psoc NULL");
847*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
848*5113495bSYour Name 	}
849*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
850*5113495bSYour Name 
851*5113495bSYour Name 	if (req_key->type == WLAN_CRYPTO_CIPHER_WEP) {
852*5113495bSYour Name 		if (wlan_crypto_vdev_has_auth_mode(vdev,
853*5113495bSYour Name 					(1 << WLAN_CRYPTO_AUTH_8021X))) {
854*5113495bSYour Name 			req_key->flags |= WLAN_CRYPTO_KEY_DEFAULT;
855*5113495bSYour Name 		}
856*5113495bSYour Name 	}
857*5113495bSYour Name 
858*5113495bSYour Name 	if (isbcast) {
859*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
860*5113495bSYour Name 								&crypto_priv);
861*5113495bSYour Name 		if (!crypto_priv) {
862*5113495bSYour Name 			crypto_err("crypto_priv NULL");
863*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
864*5113495bSYour Name 		}
865*5113495bSYour Name 
866*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
867*5113495bSYour Name 
868*5113495bSYour Name 		if (IS_MGMT_CIPHER(req_key->type)) {
869*5113495bSYour Name 			struct wlan_crypto_key *crypto_key = NULL;
870*5113495bSYour Name 
871*5113495bSYour Name 			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
872*5113495bSYour Name 			bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
873*5113495bSYour Name 			if (!is_igtk(req_key->keyix) &&
874*5113495bSYour Name 			    !(is_bigtk(req_key->keyix))) {
875*5113495bSYour Name 				crypto_err("igtk/bigtk key invalid keyid %d",
876*5113495bSYour Name 					   req_key->keyix);
877*5113495bSYour Name 				return QDF_STATUS_CRYPTO_INVALID_KEYID;
878*5113495bSYour Name 			}
879*5113495bSYour Name 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
880*5113495bSYour Name 			if (!key)
881*5113495bSYour Name 				return QDF_STATUS_E_NOMEM;
882*5113495bSYour Name 
883*5113495bSYour Name 
884*5113495bSYour Name 			if (is_igtk(req_key->keyix)) {
885*5113495bSYour Name 				crypto_key = priv_key->igtk_key[igtk_idx];
886*5113495bSYour Name 				if (crypto_key)
887*5113495bSYour Name 					qdf_mem_free(crypto_key);
888*5113495bSYour Name 
889*5113495bSYour Name 				priv_key->igtk_key[igtk_idx] = key;
890*5113495bSYour Name 				priv_key->igtk_key_type = req_key->type;
891*5113495bSYour Name 				priv_key->def_igtk_tx_keyid = igtk_idx;
892*5113495bSYour Name 				bigtk_idx = 0;
893*5113495bSYour Name 			} else {
894*5113495bSYour Name 				crypto_key = priv_key->bigtk_key[bigtk_idx];
895*5113495bSYour Name 				if (crypto_key)
896*5113495bSYour Name 					qdf_mem_free(crypto_key);
897*5113495bSYour Name 
898*5113495bSYour Name 				priv_key->bigtk_key[bigtk_idx] = key;
899*5113495bSYour Name 				priv_key->def_bigtk_tx_keyid = bigtk_idx;
900*5113495bSYour Name 				igtk_idx = 0;
901*5113495bSYour Name 			}
902*5113495bSYour Name 		} else {
903*5113495bSYour Name 			if (IS_FILS_CIPHER(req_key->type)) {
904*5113495bSYour Name 				crypto_err("FILS key is not for BroadCast pkt");
905*5113495bSYour Name 				return QDF_STATUS_CRYPTO_INVALID_CIPHERTYPE;
906*5113495bSYour Name 			}
907*5113495bSYour Name 			if (!HAS_MCAST_CIPHER(crypto_params, req_key->type)
908*5113495bSYour Name 				&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP)) {
909*5113495bSYour Name 				return QDF_STATUS_CRYPTO_INVALID_CIPHERTYPE;
910*5113495bSYour Name 			}
911*5113495bSYour Name 			if (!priv_key->key[req_key->keyix]) {
912*5113495bSYour Name 				priv_key->key[req_key->keyix]
913*5113495bSYour Name 					= qdf_mem_malloc(
914*5113495bSYour Name 						sizeof(struct wlan_crypto_key));
915*5113495bSYour Name 				if (!priv_key->key[req_key->keyix])
916*5113495bSYour Name 					return QDF_STATUS_E_NOMEM;
917*5113495bSYour Name 			}
918*5113495bSYour Name 			key = priv_key->key[req_key->keyix];
919*5113495bSYour Name 			priv_key->def_tx_keyid = req_key->keyix;
920*5113495bSYour Name 		}
921*5113495bSYour Name 		if (vdev_mode == QDF_STA_MODE) {
922*5113495bSYour Name 			peer = wlan_objmgr_vdev_try_get_bsspeer(vdev,
923*5113495bSYour Name 								WLAN_CRYPTO_ID);
924*5113495bSYour Name 			if (!peer) {
925*5113495bSYour Name 				crypto_err("peer NULL");
926*5113495bSYour Name 				if (IS_MGMT_CIPHER(req_key->type)) {
927*5113495bSYour Name 					priv_key->igtk_key[igtk_idx] = NULL;
928*5113495bSYour Name 					priv_key->bigtk_key[bigtk_idx]
929*5113495bSYour Name 						= NULL;
930*5113495bSYour Name 					priv_key->igtk_key_type
931*5113495bSYour Name 						= WLAN_CRYPTO_CIPHER_NONE;
932*5113495bSYour Name 				} else
933*5113495bSYour Name 					priv_key->key[req_key->keyix] = NULL;
934*5113495bSYour Name 				if (key)
935*5113495bSYour Name 					qdf_mem_free(key);
936*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
937*5113495bSYour Name 			}
938*5113495bSYour Name 			qdf_mem_copy(macaddr, wlan_peer_get_macaddr(peer),
939*5113495bSYour Name 				    QDF_MAC_ADDR_SIZE);
940*5113495bSYour Name 			wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
941*5113495bSYour Name 			peer = NULL;
942*5113495bSYour Name 		}
943*5113495bSYour Name 	} else {
944*5113495bSYour Name 		uint8_t pdev_id;
945*5113495bSYour Name 
946*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
947*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
948*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
949*5113495bSYour Name 					psoc,
950*5113495bSYour Name 					pdev_id,
951*5113495bSYour Name 					macaddr,
952*5113495bSYour Name 					req_key->macaddr,
953*5113495bSYour Name 					WLAN_CRYPTO_ID);
954*5113495bSYour Name 
955*5113495bSYour Name 		if (!peer) {
956*5113495bSYour Name 			crypto_err("peer NULL");
957*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
958*5113495bSYour Name 		}
959*5113495bSYour Name 
960*5113495bSYour Name 		qdf_mem_copy(macaddr, req_key->macaddr, QDF_MAC_ADDR_SIZE);
961*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
962*5113495bSYour Name 								&crypto_priv);
963*5113495bSYour Name 
964*5113495bSYour Name 		if (!crypto_priv) {
965*5113495bSYour Name 			crypto_err("crypto_priv NULL");
966*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
967*5113495bSYour Name 			goto err;
968*5113495bSYour Name 		}
969*5113495bSYour Name 
970*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
971*5113495bSYour Name 
972*5113495bSYour Name 		if (IS_MGMT_CIPHER(req_key->type)) {
973*5113495bSYour Name 			struct wlan_crypto_key *crypto_key = NULL;
974*5113495bSYour Name 
975*5113495bSYour Name 			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
976*5113495bSYour Name 			bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
977*5113495bSYour Name 
978*5113495bSYour Name 			if (!is_igtk(req_key->keyix) &&
979*5113495bSYour Name 			    !(is_bigtk(req_key->keyix))) {
980*5113495bSYour Name 				crypto_err("igtk/bigtk key invalid keyid %d",
981*5113495bSYour Name 					   req_key->keyix);
982*5113495bSYour Name 				status = QDF_STATUS_CRYPTO_INVALID_KEYID;
983*5113495bSYour Name 				goto err;
984*5113495bSYour Name 			}
985*5113495bSYour Name 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
986*5113495bSYour Name 			if (!key) {
987*5113495bSYour Name 				status = QDF_STATUS_E_NOMEM;
988*5113495bSYour Name 				goto err;
989*5113495bSYour Name 			}
990*5113495bSYour Name 
991*5113495bSYour Name 			if (is_igtk(req_key->keyix)) {
992*5113495bSYour Name 				crypto_key = priv_key->igtk_key[igtk_idx];
993*5113495bSYour Name 				if (crypto_key)
994*5113495bSYour Name 					qdf_mem_free(crypto_key);
995*5113495bSYour Name 
996*5113495bSYour Name 				priv_key->igtk_key[igtk_idx] = key;
997*5113495bSYour Name 				priv_key->igtk_key_type = req_key->type;
998*5113495bSYour Name 				priv_key->def_igtk_tx_keyid = igtk_idx;
999*5113495bSYour Name 			} else {
1000*5113495bSYour Name 				crypto_key = priv_key->bigtk_key[bigtk_idx];
1001*5113495bSYour Name 				if (crypto_key)
1002*5113495bSYour Name 					qdf_mem_free(crypto_key);
1003*5113495bSYour Name 
1004*5113495bSYour Name 				priv_key->bigtk_key[bigtk_idx] = key;
1005*5113495bSYour Name 				priv_key->def_bigtk_tx_keyid = bigtk_idx;
1006*5113495bSYour Name 			}
1007*5113495bSYour Name 		} else {
1008*5113495bSYour Name 			uint16_t kid = req_key->keyix;
1009*5113495bSYour Name 			if (kid == WLAN_CRYPTO_KEYIX_NONE)
1010*5113495bSYour Name 				kid = 0;
1011*5113495bSYour Name 			if (kid >= WLAN_CRYPTO_MAX_VLANKEYIX) {
1012*5113495bSYour Name 				crypto_err("invalid keyid %d", kid);
1013*5113495bSYour Name 				status = QDF_STATUS_CRYPTO_INVALID_KEYID;
1014*5113495bSYour Name 				goto err;
1015*5113495bSYour Name 			}
1016*5113495bSYour Name 			if (!priv_key->key[kid]) {
1017*5113495bSYour Name 				priv_key->key[kid]
1018*5113495bSYour Name 					= qdf_mem_malloc(
1019*5113495bSYour Name 						sizeof(struct wlan_crypto_key));
1020*5113495bSYour Name 				if (!priv_key->key[kid]) {
1021*5113495bSYour Name 					status = QDF_STATUS_E_NOMEM;
1022*5113495bSYour Name 					goto err;
1023*5113495bSYour Name 				}
1024*5113495bSYour Name 			}
1025*5113495bSYour Name 			key = priv_key->key[kid];
1026*5113495bSYour Name 		}
1027*5113495bSYour Name 	}
1028*5113495bSYour Name 
1029*5113495bSYour Name 	/* alloc key might not required as it is already there */
1030*5113495bSYour Name 	key->cipher_table = (void *)cipher;
1031*5113495bSYour Name 	key->keylen = req_key->keylen;
1032*5113495bSYour Name 	key->flags = req_key->flags;
1033*5113495bSYour Name 
1034*5113495bSYour Name 	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE)
1035*5113495bSYour Name 		key->keyix = 0;
1036*5113495bSYour Name 	else
1037*5113495bSYour Name 		key->keyix = req_key->keyix;
1038*5113495bSYour Name 
1039*5113495bSYour Name 	if (req_key->flags & WLAN_CRYPTO_KEY_DEFAULT
1040*5113495bSYour Name 		&& (!IS_MGMT_CIPHER(req_key->type)))  {
1041*5113495bSYour Name 		crypto_priv->crypto_key.def_tx_keyid = key->keyix;
1042*5113495bSYour Name 		key->flags |= WLAN_CRYPTO_KEY_DEFAULT;
1043*5113495bSYour Name 	}
1044*5113495bSYour Name 	if ((req_key->type == WLAN_CRYPTO_CIPHER_WAPI_SMS4)
1045*5113495bSYour Name 		|| (req_key->type == WLAN_CRYPTO_CIPHER_WAPI_GCM4)) {
1046*5113495bSYour Name 		uint8_t iv_AP[16] = {	0x5c, 0x36, 0x5c, 0x36,
1047*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x36,
1048*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x36,
1049*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x37};
1050*5113495bSYour Name 		uint8_t iv_STA[16] = {	0x5c, 0x36, 0x5c, 0x36,
1051*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x36,
1052*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x36,
1053*5113495bSYour Name 					0x5c, 0x36, 0x5c, 0x36};
1054*5113495bSYour Name 
1055*5113495bSYour Name 		/* During Tx PN should be increment and
1056*5113495bSYour Name 		 * send but as per our implementation we increment only after
1057*5113495bSYour Name 		 * Tx complete. So First packet PN check will be failed.
1058*5113495bSYour Name 		 * To compensate increment the PN here by 2
1059*5113495bSYour Name 		 */
1060*5113495bSYour Name 		if (vdev_mode == QDF_SAP_MODE) {
1061*5113495bSYour Name 			iv_AP[15] += 2;
1062*5113495bSYour Name 			qdf_mem_copy(key->recviv, iv_STA,
1063*5113495bSYour Name 						WLAN_CRYPTO_WAPI_IV_SIZE);
1064*5113495bSYour Name 			qdf_mem_copy(key->txiv, iv_AP,
1065*5113495bSYour Name 						WLAN_CRYPTO_WAPI_IV_SIZE);
1066*5113495bSYour Name 		} else {
1067*5113495bSYour Name 			iv_STA[15] += 2;
1068*5113495bSYour Name 			qdf_mem_copy(key->recviv, iv_AP,
1069*5113495bSYour Name 						WLAN_CRYPTO_WAPI_IV_SIZE);
1070*5113495bSYour Name 			qdf_mem_copy(key->txiv, iv_STA,
1071*5113495bSYour Name 						WLAN_CRYPTO_WAPI_IV_SIZE);
1072*5113495bSYour Name 		}
1073*5113495bSYour Name 	} else {
1074*5113495bSYour Name 		uint8_t i = 0;
1075*5113495bSYour Name 		qdf_mem_copy((uint8_t *)(&key->keytsc),
1076*5113495bSYour Name 			(uint8_t *)(&req_key->keytsc), sizeof(key->keytsc));
1077*5113495bSYour Name 		for (i = 0; i < WLAN_CRYPTO_TID_SIZE; i++) {
1078*5113495bSYour Name 			qdf_mem_copy((uint8_t *)(&key->keyrsc[i]),
1079*5113495bSYour Name 					(uint8_t *)(&req_key->keyrsc),
1080*5113495bSYour Name 					sizeof(key->keyrsc[0]));
1081*5113495bSYour Name 		}
1082*5113495bSYour Name 	}
1083*5113495bSYour Name 
1084*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1085*5113495bSYour Name 	if (!tx_ops) {
1086*5113495bSYour Name 		crypto_err("tx_ops is NULL");
1087*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
1088*5113495bSYour Name 		goto err;
1089*5113495bSYour Name 	}
1090*5113495bSYour Name 
1091*5113495bSYour Name 	qdf_mem_copy(key->keyval, req_key->keydata, sizeof(key->keyval));
1092*5113495bSYour Name 	key->valid = 1;
1093*5113495bSYour Name 	if ((IS_MGMT_CIPHER(req_key->type))) {
1094*5113495bSYour Name 		uint32_t mgmt_cipher = 0;
1095*5113495bSYour Name 
1096*5113495bSYour Name 		if (HAS_CIPHER_CAP(crypto_params,
1097*5113495bSYour Name 					WLAN_CRYPTO_CAP_PMF_OFFLOAD) ||
1098*5113495bSYour Name 					is_bigtk(req_key->keyix)) {
1099*5113495bSYour Name 			if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
1100*5113495bSYour Name 				WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)(vdev,
1101*5113495bSYour Name 						key, macaddr, req_key->type);
1102*5113495bSYour Name 			}
1103*5113495bSYour Name 		}
1104*5113495bSYour Name 		QDF_SET_PARAM(mgmt_cipher, req_key->type);
1105*5113495bSYour Name 		wlan_crypto_set_mgmtcipher(crypto_params, mgmt_cipher);
1106*5113495bSYour Name 		status = wlan_crypto_set_igtk_key(key);
1107*5113495bSYour Name 	} else if (IS_FILS_CIPHER(req_key->type)) {
1108*5113495bSYour Name 		/* Take request key object to FILS setkey */
1109*5113495bSYour Name 		key->private = req_key;
1110*5113495bSYour Name 	} else {
1111*5113495bSYour Name 		if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
1112*5113495bSYour Name 			if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)(vdev, key,
1113*5113495bSYour Name 							      macaddr,
1114*5113495bSYour Name 							      req_key->type)) {
1115*5113495bSYour Name 				status = QDF_STATUS_E_INVAL;
1116*5113495bSYour Name 				goto err;
1117*5113495bSYour Name 			}
1118*5113495bSYour Name 		}
1119*5113495bSYour Name 	}
1120*5113495bSYour Name 	if (cipher)
1121*5113495bSYour Name 		status = cipher->setkey(key);
1122*5113495bSYour Name 
1123*5113495bSYour Name 	if ((req_key->flags & WLAN_CRYPTO_KEY_DEFAULT) &&
1124*5113495bSYour Name 	    (req_key->keyix != WLAN_CRYPTO_KEYIX_NONE) &&
1125*5113495bSYour Name 	    (!IS_MGMT_CIPHER(req_key->type)) && isbcast) {
1126*5113495bSYour Name 		/* default xmit key */
1127*5113495bSYour Name 		wlan_crypto_default_key(vdev,
1128*5113495bSYour Name 					req_key->macaddr,
1129*5113495bSYour Name 					req_key->keyix,
1130*5113495bSYour Name 					!isbcast);
1131*5113495bSYour Name 		/*Iterate through the peer list on this vdev
1132*5113495bSYour Name 		 *and store the keyix in the peer's crypto_priv
1133*5113495bSYour Name 		 */
1134*5113495bSYour Name 		wlan_objmgr_iterate_peerobj_list(vdev,
1135*5113495bSYour Name 						 wlan_crypto_store_def_keyix,
1136*5113495bSYour Name 						 (void *)&req_key->keyix,
1137*5113495bSYour Name 						 WLAN_CRYPTO_ID);
1138*5113495bSYour Name 
1139*5113495bSYour Name 		}
1140*5113495bSYour Name err:
1141*5113495bSYour Name 	if (peer)
1142*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1143*5113495bSYour Name 	return status;
1144*5113495bSYour Name }
1145*5113495bSYour Name 
1146*5113495bSYour Name /**
1147*5113495bSYour Name  * wlan_crypto_get_key_type - get keytype
1148*5113495bSYour Name  * @key: key
1149*5113495bSYour Name  *
1150*5113495bSYour Name  * This function gets keytype from key
1151*5113495bSYour Name  *
1152*5113495bSYour Name  * Return: keytype
1153*5113495bSYour Name  */
wlan_crypto_get_key_type(struct wlan_crypto_key * key)1154*5113495bSYour Name wlan_crypto_cipher_type wlan_crypto_get_key_type(struct wlan_crypto_key *key)
1155*5113495bSYour Name {
1156*5113495bSYour Name 	if (key && key->cipher_table) {
1157*5113495bSYour Name 		return ((struct wlan_crypto_cipher *)
1158*5113495bSYour Name 						(key->cipher_table))->cipher;
1159*5113495bSYour Name 	}
1160*5113495bSYour Name 	return WLAN_CRYPTO_CIPHER_NONE;
1161*5113495bSYour Name }
1162*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_key_type);
1163*5113495bSYour Name 
wlan_crypto_vdev_getkey(struct wlan_objmgr_vdev * vdev,uint16_t keyix)1164*5113495bSYour Name struct wlan_crypto_key *wlan_crypto_vdev_getkey(struct wlan_objmgr_vdev *vdev,
1165*5113495bSYour Name 						uint16_t keyix)
1166*5113495bSYour Name {
1167*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1168*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1169*5113495bSYour Name 	struct wlan_crypto_key *key = NULL;
1170*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
1171*5113495bSYour Name 
1172*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
1173*5113495bSYour Name 
1174*5113495bSYour Name 	if (!crypto_priv) {
1175*5113495bSYour Name 		crypto_err("crypto_priv NULL");
1176*5113495bSYour Name 		return NULL;
1177*5113495bSYour Name 	}
1178*5113495bSYour Name 
1179*5113495bSYour Name 	priv_key = &crypto_priv->crypto_key;
1180*5113495bSYour Name 
1181*5113495bSYour Name 	/* for keyix 4,5 we return the igtk keys for keyix more than 5
1182*5113495bSYour Name 	 * we return the default key, for all other keyix we return the
1183*5113495bSYour Name 	 * key accordingly.
1184*5113495bSYour Name 	 */
1185*5113495bSYour Name 	if ((keyix == WLAN_CRYPTO_KEYIX_NONE) ||
1186*5113495bSYour Name 	    !is_valid_keyix(keyix))
1187*5113495bSYour Name 		key = priv_key->key[crypto_priv->crypto_key.def_tx_keyid];
1188*5113495bSYour Name 	else if (is_bigtk(keyix))
1189*5113495bSYour Name 		key = priv_key->bigtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX
1190*5113495bSYour Name 						- WLAN_CRYPTO_MAXIGTKKEYIDX];
1191*5113495bSYour Name 	else if (is_igtk(keyix))
1192*5113495bSYour Name 		key = priv_key->igtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX];
1193*5113495bSYour Name 	else
1194*5113495bSYour Name 		key = priv_key->key[keyix];
1195*5113495bSYour Name 
1196*5113495bSYour Name 	if (key && key->valid)
1197*5113495bSYour Name 		return key;
1198*5113495bSYour Name 
1199*5113495bSYour Name 	return NULL;
1200*5113495bSYour Name }
1201*5113495bSYour Name qdf_export_symbol(wlan_crypto_vdev_getkey);
1202*5113495bSYour Name 
wlan_crypto_peer_getkey(struct wlan_objmgr_peer * peer,uint16_t keyix)1203*5113495bSYour Name struct wlan_crypto_key *wlan_crypto_peer_getkey(struct wlan_objmgr_peer *peer,
1204*5113495bSYour Name 						uint16_t keyix)
1205*5113495bSYour Name {
1206*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1207*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1208*5113495bSYour Name 	struct wlan_crypto_key *key = NULL;
1209*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
1210*5113495bSYour Name 
1211*5113495bSYour Name 	crypto_params = wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
1212*5113495bSYour Name 
1213*5113495bSYour Name 	if (!crypto_priv) {
1214*5113495bSYour Name 		crypto_err("crypto_priv NULL");
1215*5113495bSYour Name 		return NULL;
1216*5113495bSYour Name 	}
1217*5113495bSYour Name 
1218*5113495bSYour Name 	priv_key = &crypto_priv->crypto_key;
1219*5113495bSYour Name 
1220*5113495bSYour Name 	/* for keyix 4,5 we return the igtk keys for keyix more than 5
1221*5113495bSYour Name 	 * we return the default key, for all other keyix we return the
1222*5113495bSYour Name 	 * key accordingly.
1223*5113495bSYour Name 	 */
1224*5113495bSYour Name 	if (keyix == WLAN_CRYPTO_KEYIX_NONE ||
1225*5113495bSYour Name 	    !is_valid_keyix(keyix))
1226*5113495bSYour Name 		key = priv_key->key[crypto_priv->crypto_key.def_tx_keyid];
1227*5113495bSYour Name 	else if (is_bigtk(keyix))
1228*5113495bSYour Name 		key = priv_key->bigtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX
1229*5113495bSYour Name 						- WLAN_CRYPTO_MAXIGTKKEYIDX];
1230*5113495bSYour Name 	else if (is_igtk(keyix))
1231*5113495bSYour Name 		key = priv_key->igtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX];
1232*5113495bSYour Name 	else
1233*5113495bSYour Name 		key = priv_key->key[keyix];
1234*5113495bSYour Name 
1235*5113495bSYour Name 	if (key && key->valid)
1236*5113495bSYour Name 		return key;
1237*5113495bSYour Name 
1238*5113495bSYour Name 	return NULL;
1239*5113495bSYour Name }
1240*5113495bSYour Name qdf_export_symbol(wlan_crypto_peer_getkey);
1241*5113495bSYour Name 
wlan_crypto_getkey(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_req_key * req_key,uint8_t * mac_addr)1242*5113495bSYour Name QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
1243*5113495bSYour Name 				struct wlan_crypto_req_key *req_key,
1244*5113495bSYour Name 				uint8_t *mac_addr)
1245*5113495bSYour Name {
1246*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1247*5113495bSYour Name 	struct wlan_crypto_key *key;
1248*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1249*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
1250*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
1251*5113495bSYour Name 	uint8_t macaddr[QDF_MAC_ADDR_SIZE] =
1252*5113495bSYour Name 			{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1253*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1254*5113495bSYour Name 	struct wlan_objmgr_peer *peer = NULL;
1255*5113495bSYour Name 	uint8_t pdev_id;
1256*5113495bSYour Name 	uint16_t get_pn_enable;
1257*5113495bSYour Name 	bool is_bcast;
1258*5113495bSYour Name 	uint8_t *pn_mac_addr;
1259*5113495bSYour Name 
1260*5113495bSYour Name 	if (!req_key) {
1261*5113495bSYour Name 		crypto_err("req_key NULL");
1262*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1263*5113495bSYour Name 	}
1264*5113495bSYour Name 
1265*5113495bSYour Name 	get_pn_enable = req_key->flags & WLAN_CRYPTO_KEY_GET_PN;
1266*5113495bSYour Name 
1267*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1268*5113495bSYour Name 	qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(vdev),
1269*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1270*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1271*5113495bSYour Name 	if (!psoc) {
1272*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1273*5113495bSYour Name 		crypto_err("psoc NULL");
1274*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1275*5113495bSYour Name 	}
1276*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1277*5113495bSYour Name 
1278*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1279*5113495bSYour Name 	if (!tx_ops) {
1280*5113495bSYour Name 		crypto_err("tx_ops is NULL");
1281*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1282*5113495bSYour Name 	}
1283*5113495bSYour Name 
1284*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1285*5113495bSYour Name 	if (!rx_ops) {
1286*5113495bSYour Name 		crypto_err("rx_ops is NULL");
1287*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1288*5113495bSYour Name 	}
1289*5113495bSYour Name 	is_bcast = qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr);
1290*5113495bSYour Name 
1291*5113495bSYour Name 	if (is_bcast) {
1292*5113495bSYour Name 		key = wlan_crypto_vdev_getkey(vdev, req_key->keyix);
1293*5113495bSYour Name 		if (!key)
1294*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1295*5113495bSYour Name 	} else {
1296*5113495bSYour Name 
1297*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1298*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
1299*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1300*5113495bSYour Name 					psoc,
1301*5113495bSYour Name 					pdev_id,
1302*5113495bSYour Name 					macaddr,
1303*5113495bSYour Name 					mac_addr,
1304*5113495bSYour Name 					WLAN_CRYPTO_ID);
1305*5113495bSYour Name 		if (!peer) {
1306*5113495bSYour Name 			crypto_err("peer NULL");
1307*5113495bSYour Name 			return QDF_STATUS_E_NOENT;
1308*5113495bSYour Name 		}
1309*5113495bSYour Name 		key = wlan_crypto_peer_getkey(peer, req_key->keyix);
1310*5113495bSYour Name 
1311*5113495bSYour Name 		if (!key) {
1312*5113495bSYour Name 			crypto_err("Key is NULL");
1313*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
1314*5113495bSYour Name 			goto err;
1315*5113495bSYour Name 		}
1316*5113495bSYour Name 	}
1317*5113495bSYour Name 
1318*5113495bSYour Name 	if (key->valid) {
1319*5113495bSYour Name 		qdf_mem_copy(req_key->keydata,
1320*5113495bSYour Name 				key->keyval, key->keylen);
1321*5113495bSYour Name 		req_key->keylen = key->keylen;
1322*5113495bSYour Name 		req_key->keyix = key->keyix;
1323*5113495bSYour Name 		req_key->flags = key->flags;
1324*5113495bSYour Name 
1325*5113495bSYour Name 		if (is_igtk(req_key->keyix) || is_bigtk(req_key->keyix)) {
1326*5113495bSYour Name 			req_key->type = key->cipher_type;
1327*5113495bSYour Name 		} else {
1328*5113495bSYour Name 			cipher_table = key->cipher_table;
1329*5113495bSYour Name 
1330*5113495bSYour Name 			if (!cipher_table) {
1331*5113495bSYour Name 				status = QDF_STATUS_SUCCESS;
1332*5113495bSYour Name 				goto err;
1333*5113495bSYour Name 			}
1334*5113495bSYour Name 
1335*5113495bSYour Name 			req_key->type = cipher_table->cipher;
1336*5113495bSYour Name 		}
1337*5113495bSYour Name 
1338*5113495bSYour Name 		if (req_key->type == WLAN_CRYPTO_CIPHER_WAPI_SMS4) {
1339*5113495bSYour Name 			qdf_mem_copy((uint8_t *)(&req_key->txiv),
1340*5113495bSYour Name 					(uint8_t *)(key->txiv),
1341*5113495bSYour Name 					sizeof(req_key->txiv));
1342*5113495bSYour Name 			qdf_mem_copy((uint8_t *)(&req_key->recviv),
1343*5113495bSYour Name 					(uint8_t *)(key->recviv),
1344*5113495bSYour Name 					sizeof(req_key->recviv));
1345*5113495bSYour Name 		}
1346*5113495bSYour Name 
1347*5113495bSYour Name 		if (get_pn_enable) {
1348*5113495bSYour Name 			pn_mac_addr = ((is_gtk(req_key->keyix) ||
1349*5113495bSYour Name 					is_bigtk(req_key->keyix)) && is_bcast) ?
1350*5113495bSYour Name 					macaddr : mac_addr;
1351*5113495bSYour Name 
1352*5113495bSYour Name 			if (WLAN_CRYPTO_TX_OPS_GETPN(tx_ops))
1353*5113495bSYour Name 				WLAN_CRYPTO_TX_OPS_GETPN(tx_ops)(vdev,
1354*5113495bSYour Name 								 pn_mac_addr,
1355*5113495bSYour Name 								 req_key->keyix,
1356*5113495bSYour Name 								 req_key->type);
1357*5113495bSYour Name 			if (WLAN_CRYPTO_RX_OPS_GET_RXPN(&rx_ops->crypto_rx_ops))
1358*5113495bSYour Name 				WLAN_CRYPTO_RX_OPS_GET_RXPN(&rx_ops->crypto_rx_ops)(
1359*5113495bSYour Name 						vdev, mac_addr, req_key->keyix);
1360*5113495bSYour Name 
1361*5113495bSYour Name 			qdf_mem_copy((uint8_t *)(&req_key->keytsc),
1362*5113495bSYour Name 				     (uint8_t *)(&key->keytsc),
1363*5113495bSYour Name 				     sizeof(req_key->keytsc));
1364*5113495bSYour Name 			qdf_mem_copy((uint8_t *)(&req_key->keyrsc),
1365*5113495bSYour Name 				     (uint8_t *)(&key->keyrsc[0]),
1366*5113495bSYour Name 				     sizeof(req_key->keyrsc));
1367*5113495bSYour Name 		}
1368*5113495bSYour Name 
1369*5113495bSYour Name 	}
1370*5113495bSYour Name 	status = QDF_STATUS_SUCCESS;
1371*5113495bSYour Name 
1372*5113495bSYour Name err:
1373*5113495bSYour Name 	if (peer)
1374*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1375*5113495bSYour Name 
1376*5113495bSYour Name 	return status;
1377*5113495bSYour Name }
1378*5113495bSYour Name 
wlan_crypto_delkey(struct wlan_objmgr_vdev * vdev,uint8_t * macaddr,uint8_t key_idx)1379*5113495bSYour Name QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
1380*5113495bSYour Name 				uint8_t *macaddr,
1381*5113495bSYour Name 				uint8_t key_idx)
1382*5113495bSYour Name {
1383*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1384*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1385*5113495bSYour Name 	struct wlan_crypto_key *key;
1386*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1387*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1388*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
1389*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1390*5113495bSYour Name 	struct wlan_objmgr_peer *peer = NULL;
1391*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1392*5113495bSYour Name 
1393*5113495bSYour Name 	if (!vdev || !macaddr ||
1394*5113495bSYour Name 		!is_valid_keyix(key_idx)) {
1395*5113495bSYour Name 		crypto_err("Invalid param vdev %pK macaddr %pK keyidx %d",
1396*5113495bSYour Name 			   vdev, macaddr, key_idx);
1397*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1398*5113495bSYour Name 	}
1399*5113495bSYour Name 
1400*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1401*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1402*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1403*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1404*5113495bSYour Name 	if (!psoc) {
1405*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1406*5113495bSYour Name 		crypto_err("psoc NULL");
1407*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1408*5113495bSYour Name 	}
1409*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1410*5113495bSYour Name 
1411*5113495bSYour Name 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
1412*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1413*5113495bSYour Name 								&crypto_priv);
1414*5113495bSYour Name 		if (!crypto_priv) {
1415*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1416*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1417*5113495bSYour Name 		}
1418*5113495bSYour Name 	} else {
1419*5113495bSYour Name 		uint8_t pdev_id;
1420*5113495bSYour Name 
1421*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1422*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
1423*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1424*5113495bSYour Name 				psoc, pdev_id,
1425*5113495bSYour Name 				bssid_mac,
1426*5113495bSYour Name 				macaddr,
1427*5113495bSYour Name 				WLAN_CRYPTO_ID);
1428*5113495bSYour Name 		if (!peer) {
1429*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1430*5113495bSYour Name 		}
1431*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1432*5113495bSYour Name 								&crypto_priv);
1433*5113495bSYour Name 		if (!crypto_priv) {
1434*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1435*5113495bSYour Name 			ret = QDF_STATUS_E_INVAL;
1436*5113495bSYour Name 			goto ret_rel_ref;
1437*5113495bSYour Name 		}
1438*5113495bSYour Name 	}
1439*5113495bSYour Name 
1440*5113495bSYour Name 	if (key_idx >= WLAN_CRYPTO_MAXKEYIDX) {
1441*5113495bSYour Name 		uint8_t igtk_idx = key_idx - WLAN_CRYPTO_MAXKEYIDX;
1442*5113495bSYour Name 		uint8_t bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
1443*5113495bSYour Name 
1444*5113495bSYour Name 		if (!is_igtk(key_idx) && !(is_bigtk(key_idx))) {
1445*5113495bSYour Name 			crypto_err("igtk/bigtk key invalid keyid %d", key_idx);
1446*5113495bSYour Name 			ret = QDF_STATUS_E_INVAL;
1447*5113495bSYour Name 			goto ret_rel_ref;
1448*5113495bSYour Name 		}
1449*5113495bSYour Name 		if (is_igtk(key_idx)) {
1450*5113495bSYour Name 			key = crypto_priv->crypto_key.igtk_key[igtk_idx];
1451*5113495bSYour Name 			crypto_priv->crypto_key.igtk_key[igtk_idx] = NULL;
1452*5113495bSYour Name 		} else {
1453*5113495bSYour Name 			key = crypto_priv->crypto_key.bigtk_key[bigtk_idx];
1454*5113495bSYour Name 			crypto_priv->crypto_key.bigtk_key[bigtk_idx] = NULL;
1455*5113495bSYour Name 		}
1456*5113495bSYour Name 		if (key)
1457*5113495bSYour Name 			key->valid = 0;
1458*5113495bSYour Name 	} else {
1459*5113495bSYour Name 		key = crypto_priv->crypto_key.key[key_idx];
1460*5113495bSYour Name 		crypto_priv->crypto_key.key[key_idx] = NULL;
1461*5113495bSYour Name 	}
1462*5113495bSYour Name 
1463*5113495bSYour Name 	if (!key) {
1464*5113495bSYour Name 		ret = QDF_STATUS_E_INVAL;
1465*5113495bSYour Name 		goto ret_rel_ref;
1466*5113495bSYour Name 	}
1467*5113495bSYour Name 
1468*5113495bSYour Name 	if (key->valid) {
1469*5113495bSYour Name 		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1470*5113495bSYour Name 		qdf_mem_zero(key->keyval, sizeof(key->keyval));
1471*5113495bSYour Name 
1472*5113495bSYour Name 		tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1473*5113495bSYour Name 		if (!tx_ops) {
1474*5113495bSYour Name 			crypto_err("tx_ops is NULL");
1475*5113495bSYour Name 			ret = QDF_STATUS_E_INVAL;
1476*5113495bSYour Name 			goto ret_rel_ref;
1477*5113495bSYour Name 		}
1478*5113495bSYour Name 
1479*5113495bSYour Name 		if (!IS_FILS_CIPHER(cipher_table->cipher) &&
1480*5113495bSYour Name 		    WLAN_CRYPTO_TX_OPS_DELKEY(tx_ops)) {
1481*5113495bSYour Name 			WLAN_CRYPTO_TX_OPS_DELKEY(tx_ops)(vdev, key, macaddr,
1482*5113495bSYour Name 							  cipher_table->cipher);
1483*5113495bSYour Name 		} else if (IS_FILS_CIPHER(cipher_table->cipher)) {
1484*5113495bSYour Name 			if (key->private)
1485*5113495bSYour Name 				qdf_mem_free(key->private);
1486*5113495bSYour Name 		}
1487*5113495bSYour Name 	}
1488*5113495bSYour Name 
1489*5113495bSYour Name 	/* Zero-out local key variables */
1490*5113495bSYour Name 	qdf_mem_zero(key, sizeof(struct wlan_crypto_key));
1491*5113495bSYour Name 	qdf_mem_free(key);
1492*5113495bSYour Name 	key = NULL;
1493*5113495bSYour Name 
1494*5113495bSYour Name ret_rel_ref:
1495*5113495bSYour Name 	if (peer)
1496*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1497*5113495bSYour Name 
1498*5113495bSYour Name 	return ret;
1499*5113495bSYour Name }
1500*5113495bSYour Name 
1501*5113495bSYour Name #ifdef CRYPTO_SET_KEY_CONVERGED
wlan_crypto_set_default_key(struct wlan_objmgr_vdev * vdev,uint8_t key_idx,uint8_t * macaddr)1502*5113495bSYour Name static QDF_STATUS wlan_crypto_set_default_key(struct wlan_objmgr_vdev *vdev,
1503*5113495bSYour Name 					      uint8_t key_idx, uint8_t *macaddr)
1504*5113495bSYour Name {
1505*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1506*5113495bSYour Name }
1507*5113495bSYour Name #else
wlan_crypto_set_default_key(struct wlan_objmgr_vdev * vdev,uint8_t key_idx,uint8_t * macaddr)1508*5113495bSYour Name static QDF_STATUS wlan_crypto_set_default_key(struct wlan_objmgr_vdev *vdev,
1509*5113495bSYour Name 					      uint8_t key_idx, uint8_t *macaddr)
1510*5113495bSYour Name {
1511*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1512*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
1513*5113495bSYour Name 
1514*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1515*5113495bSYour Name 	if (!psoc) {
1516*5113495bSYour Name 		crypto_err("psoc is NULL");
1517*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1518*5113495bSYour Name 	}
1519*5113495bSYour Name 
1520*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1521*5113495bSYour Name 	if (!tx_ops) {
1522*5113495bSYour Name 		crypto_err("tx_ops is NULL");
1523*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1524*5113495bSYour Name 	}
1525*5113495bSYour Name 
1526*5113495bSYour Name 	if (WLAN_CRYPTO_TX_OPS_DEFAULTKEY(tx_ops))
1527*5113495bSYour Name 		WLAN_CRYPTO_TX_OPS_DEFAULTKEY(tx_ops)(vdev, key_idx, macaddr);
1528*5113495bSYour Name 
1529*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1530*5113495bSYour Name }
1531*5113495bSYour Name #endif
1532*5113495bSYour Name 
wlan_crypto_default_key(struct wlan_objmgr_vdev * vdev,uint8_t * macaddr,uint8_t key_idx,bool unicast)1533*5113495bSYour Name QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev,
1534*5113495bSYour Name 					uint8_t *macaddr,
1535*5113495bSYour Name 					uint8_t key_idx,
1536*5113495bSYour Name 					bool unicast)
1537*5113495bSYour Name {
1538*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1539*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1540*5113495bSYour Name 	struct wlan_crypto_key *key;
1541*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1542*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1543*5113495bSYour Name 
1544*5113495bSYour Name 	if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) {
1545*5113495bSYour Name 		crypto_err("Invalid param vdev %pK macaddr %pK keyidx %d",
1546*5113495bSYour Name 			   vdev, macaddr, key_idx);
1547*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1548*5113495bSYour Name 	}
1549*5113495bSYour Name 
1550*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1551*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1552*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1553*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1554*5113495bSYour Name 	if (!psoc) {
1555*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1556*5113495bSYour Name 		crypto_err("psoc NULL");
1557*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1558*5113495bSYour Name 	}
1559*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1560*5113495bSYour Name 
1561*5113495bSYour Name 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
1562*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1563*5113495bSYour Name 								&crypto_priv);
1564*5113495bSYour Name 		if (!crypto_priv) {
1565*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1566*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1567*5113495bSYour Name 		}
1568*5113495bSYour Name 
1569*5113495bSYour Name 		key = crypto_priv->crypto_key.key[key_idx];
1570*5113495bSYour Name 		if (!key)
1571*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1572*5113495bSYour Name 	} else {
1573*5113495bSYour Name 		struct wlan_objmgr_peer *peer;
1574*5113495bSYour Name 		uint8_t pdev_id;
1575*5113495bSYour Name 
1576*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1577*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
1578*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1579*5113495bSYour Name 				psoc, pdev_id,
1580*5113495bSYour Name 				bssid_mac,
1581*5113495bSYour Name 				macaddr,
1582*5113495bSYour Name 				WLAN_CRYPTO_ID);
1583*5113495bSYour Name 
1584*5113495bSYour Name 		if (!peer) {
1585*5113495bSYour Name 			crypto_err("peer NULL");
1586*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1587*5113495bSYour Name 		}
1588*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1589*5113495bSYour Name 								&crypto_priv);
1590*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1591*5113495bSYour Name 		if (!crypto_priv) {
1592*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1593*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1594*5113495bSYour Name 		}
1595*5113495bSYour Name 
1596*5113495bSYour Name 		key = crypto_priv->crypto_key.key[key_idx];
1597*5113495bSYour Name 		if (!key)
1598*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1599*5113495bSYour Name 	}
1600*5113495bSYour Name 	if (!key->valid)
1601*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1602*5113495bSYour Name 
1603*5113495bSYour Name 	if (wlan_crypto_set_default_key(vdev, key_idx, macaddr) !=
1604*5113495bSYour Name 			QDF_STATUS_SUCCESS)
1605*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1606*5113495bSYour Name 	crypto_priv->crypto_key.def_tx_keyid = key_idx;
1607*5113495bSYour Name 
1608*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1609*5113495bSYour Name }
1610*5113495bSYour Name 
wlan_crypto_encap(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf,uint8_t * mac_addr,uint8_t encapdone)1611*5113495bSYour Name QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
1612*5113495bSYour Name 				qdf_nbuf_t wbuf,
1613*5113495bSYour Name 				uint8_t *mac_addr,
1614*5113495bSYour Name 				uint8_t encapdone)
1615*5113495bSYour Name {
1616*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1617*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1618*5113495bSYour Name 	struct wlan_crypto_key *key;
1619*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
1620*5113495bSYour Name 	QDF_STATUS status;
1621*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1622*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1623*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1624*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1625*5113495bSYour Name 	uint8_t pdev_id;
1626*5113495bSYour Name 	uint8_t hdrlen;
1627*5113495bSYour Name 	enum QDF_OPMODE opmode;
1628*5113495bSYour Name 
1629*5113495bSYour Name 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1630*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1631*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1632*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1633*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1634*5113495bSYour Name 	if (!psoc) {
1635*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1636*5113495bSYour Name 		crypto_err("psoc NULL");
1637*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1638*5113495bSYour Name 	}
1639*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1640*5113495bSYour Name 
1641*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
1642*5113495bSYour Name 	/* FILS Encap required only for (Re-)Assoc response */
1643*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_CRYPTO_ID);
1644*5113495bSYour Name 
1645*5113495bSYour Name 	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)) &&
1646*5113495bSYour Name 	    peer && !wlan_crypto_get_peer_fils_aead(peer)) {
1647*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1648*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1649*5113495bSYour Name 	}
1650*5113495bSYour Name 
1651*5113495bSYour Name 	if (peer)
1652*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1653*5113495bSYour Name 	peer = NULL;
1654*5113495bSYour Name 
1655*5113495bSYour Name 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)mac_addr)) {
1656*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1657*5113495bSYour Name 								&crypto_priv);
1658*5113495bSYour Name 		if (!crypto_priv) {
1659*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1660*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1661*5113495bSYour Name 		}
1662*5113495bSYour Name 
1663*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
1664*5113495bSYour Name 
1665*5113495bSYour Name 		key = priv_key->key[priv_key->def_tx_keyid];
1666*5113495bSYour Name 		if (!key)
1667*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1668*5113495bSYour Name 
1669*5113495bSYour Name 	} else {
1670*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(psoc, pdev_id,
1671*5113495bSYour Name 							  bssid_mac, mac_addr,
1672*5113495bSYour Name 							  WLAN_CRYPTO_ID);
1673*5113495bSYour Name 		if (!peer) {
1674*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1675*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1676*5113495bSYour Name 		}
1677*5113495bSYour Name 
1678*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1679*5113495bSYour Name 								&crypto_priv);
1680*5113495bSYour Name 
1681*5113495bSYour Name 		if (!crypto_priv) {
1682*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1683*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
1684*5113495bSYour Name 			goto err;
1685*5113495bSYour Name 		}
1686*5113495bSYour Name 
1687*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
1688*5113495bSYour Name 
1689*5113495bSYour Name 		key = priv_key->key[priv_key->def_tx_keyid];
1690*5113495bSYour Name 		if (!key) {
1691*5113495bSYour Name 			crypto_err("Key is NULL");
1692*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
1693*5113495bSYour Name 			goto err;
1694*5113495bSYour Name 		}
1695*5113495bSYour Name 	}
1696*5113495bSYour Name 	if (opmode == QDF_MONITOR_MODE)
1697*5113495bSYour Name 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1698*5113495bSYour Name 	else
1699*5113495bSYour Name 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1700*5113495bSYour Name 					    (uint8_t *)qdf_nbuf_data(wbuf));
1701*5113495bSYour Name 
1702*5113495bSYour Name 	if (!key->valid || !key->cipher_table) {
1703*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
1704*5113495bSYour Name 		goto err;
1705*5113495bSYour Name 	}
1706*5113495bSYour Name 
1707*5113495bSYour Name 	/* if tkip, is counter measures enabled, then drop the frame */
1708*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1709*5113495bSYour Name 	status = cipher_table->encap(key, wbuf, encapdone,
1710*5113495bSYour Name 				     hdrlen);
1711*5113495bSYour Name 
1712*5113495bSYour Name err:
1713*5113495bSYour Name 	if (peer)
1714*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1715*5113495bSYour Name 
1716*5113495bSYour Name 	return status;
1717*5113495bSYour Name }
1718*5113495bSYour Name qdf_export_symbol(wlan_crypto_encap);
1719*5113495bSYour Name 
wlan_crypto_decap(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf,uint8_t * mac_addr,uint8_t tid)1720*5113495bSYour Name QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
1721*5113495bSYour Name 				qdf_nbuf_t wbuf,
1722*5113495bSYour Name 				uint8_t *mac_addr,
1723*5113495bSYour Name 				uint8_t tid)
1724*5113495bSYour Name {
1725*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1726*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1727*5113495bSYour Name 	struct wlan_crypto_key *key;
1728*5113495bSYour Name 	QDF_STATUS status;
1729*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1730*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1731*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1732*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1733*5113495bSYour Name 	uint8_t keyid;
1734*5113495bSYour Name 	uint8_t pdev_id;
1735*5113495bSYour Name 	uint8_t hdrlen;
1736*5113495bSYour Name 	enum QDF_OPMODE opmode;
1737*5113495bSYour Name 
1738*5113495bSYour Name 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1739*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1740*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1741*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1742*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1743*5113495bSYour Name 	if (!psoc) {
1744*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1745*5113495bSYour Name 		crypto_err("psoc NULL");
1746*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1747*5113495bSYour Name 	}
1748*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1749*5113495bSYour Name 
1750*5113495bSYour Name 	if (opmode == QDF_MONITOR_MODE)
1751*5113495bSYour Name 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1752*5113495bSYour Name 	else
1753*5113495bSYour Name 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1754*5113495bSYour Name 					    (uint8_t *)qdf_nbuf_data(wbuf));
1755*5113495bSYour Name 
1756*5113495bSYour Name 	keyid = wlan_crypto_get_keyid((uint8_t *)qdf_nbuf_data(wbuf), hdrlen);
1757*5113495bSYour Name 
1758*5113495bSYour Name 	if (keyid >= WLAN_CRYPTO_MAXKEYIDX)
1759*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1760*5113495bSYour Name 
1761*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
1762*5113495bSYour Name 	/* FILS Decap required only for (Re-)Assoc request */
1763*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_CRYPTO_ID);
1764*5113495bSYour Name 
1765*5113495bSYour Name 	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)) &&
1766*5113495bSYour Name 	    peer && !wlan_crypto_get_peer_fils_aead(peer)) {
1767*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1768*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1769*5113495bSYour Name 	}
1770*5113495bSYour Name 
1771*5113495bSYour Name 	if (peer)
1772*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1773*5113495bSYour Name 	peer = NULL;
1774*5113495bSYour Name 
1775*5113495bSYour Name 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)mac_addr)) {
1776*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1777*5113495bSYour Name 								&crypto_priv);
1778*5113495bSYour Name 		if (!crypto_priv) {
1779*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1780*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1781*5113495bSYour Name 		}
1782*5113495bSYour Name 
1783*5113495bSYour Name 		key = crypto_priv->crypto_key.key[keyid];
1784*5113495bSYour Name 		if (!key)
1785*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1786*5113495bSYour Name 	} else {
1787*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1788*5113495bSYour Name 					psoc, pdev_id, bssid_mac,
1789*5113495bSYour Name 					mac_addr, WLAN_CRYPTO_ID);
1790*5113495bSYour Name 		if (!peer) {
1791*5113495bSYour Name 			crypto_err("peer NULL");
1792*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1793*5113495bSYour Name 		}
1794*5113495bSYour Name 
1795*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1796*5113495bSYour Name 								&crypto_priv);
1797*5113495bSYour Name 
1798*5113495bSYour Name 		if (!crypto_priv) {
1799*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1800*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
1801*5113495bSYour Name 			goto err;
1802*5113495bSYour Name 		}
1803*5113495bSYour Name 
1804*5113495bSYour Name 		key = crypto_priv->crypto_key.key[keyid];
1805*5113495bSYour Name 		if (!key) {
1806*5113495bSYour Name 			crypto_err("Key is NULL");
1807*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
1808*5113495bSYour Name 			goto err;
1809*5113495bSYour Name 		}
1810*5113495bSYour Name 	}
1811*5113495bSYour Name 
1812*5113495bSYour Name 	if (!key->valid || !key->cipher_table) {
1813*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
1814*5113495bSYour Name 		goto err;
1815*5113495bSYour Name 	}
1816*5113495bSYour Name 
1817*5113495bSYour Name 	/* if tkip, is counter measures enabled, then drop the frame */
1818*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1819*5113495bSYour Name 	status = cipher_table->decap(key, wbuf, tid, hdrlen);
1820*5113495bSYour Name 
1821*5113495bSYour Name err:
1822*5113495bSYour Name 	if (peer)
1823*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1824*5113495bSYour Name 
1825*5113495bSYour Name 	return status;
1826*5113495bSYour Name }
1827*5113495bSYour Name qdf_export_symbol(wlan_crypto_decap);
1828*5113495bSYour Name 
wlan_crypto_enmic(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf,uint8_t * mac_addr,uint8_t encapdone)1829*5113495bSYour Name QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
1830*5113495bSYour Name 				qdf_nbuf_t wbuf,
1831*5113495bSYour Name 				uint8_t *mac_addr,
1832*5113495bSYour Name 				uint8_t encapdone)
1833*5113495bSYour Name {
1834*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1835*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1836*5113495bSYour Name 	struct wlan_crypto_key *key;
1837*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
1838*5113495bSYour Name 	QDF_STATUS status;
1839*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1840*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1841*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1842*5113495bSYour Name 	uint8_t hdrlen;
1843*5113495bSYour Name 	enum QDF_OPMODE opmode;
1844*5113495bSYour Name 
1845*5113495bSYour Name 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1846*5113495bSYour Name 
1847*5113495bSYour Name 
1848*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1849*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1850*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1851*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1852*5113495bSYour Name 	if (!psoc) {
1853*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1854*5113495bSYour Name 		crypto_err("psoc NULL");
1855*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1856*5113495bSYour Name 	}
1857*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1858*5113495bSYour Name 
1859*5113495bSYour Name 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
1860*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1861*5113495bSYour Name 								&crypto_priv);
1862*5113495bSYour Name 		if (!crypto_priv) {
1863*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1864*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1865*5113495bSYour Name 		}
1866*5113495bSYour Name 
1867*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
1868*5113495bSYour Name 
1869*5113495bSYour Name 		key = priv_key->key[crypto_priv->crypto_key.def_tx_keyid];
1870*5113495bSYour Name 		if (!key)
1871*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1872*5113495bSYour Name 
1873*5113495bSYour Name 	} else {
1874*5113495bSYour Name 		struct wlan_objmgr_peer *peer;
1875*5113495bSYour Name 		uint8_t pdev_id;
1876*5113495bSYour Name 
1877*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1878*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
1879*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1880*5113495bSYour Name 					psoc, pdev_id, bssid_mac,
1881*5113495bSYour Name 					mac_addr, WLAN_CRYPTO_ID);
1882*5113495bSYour Name 		if (!peer) {
1883*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1884*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1885*5113495bSYour Name 		}
1886*5113495bSYour Name 
1887*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1888*5113495bSYour Name 								&crypto_priv);
1889*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1890*5113495bSYour Name 
1891*5113495bSYour Name 		if (!crypto_priv) {
1892*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1893*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1894*5113495bSYour Name 		}
1895*5113495bSYour Name 
1896*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
1897*5113495bSYour Name 
1898*5113495bSYour Name 		key = priv_key->key[crypto_priv->crypto_key.def_tx_keyid];
1899*5113495bSYour Name 		if (!key)
1900*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1901*5113495bSYour Name 	}
1902*5113495bSYour Name 	if (opmode == QDF_MONITOR_MODE)
1903*5113495bSYour Name 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1904*5113495bSYour Name 	else
1905*5113495bSYour Name 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1906*5113495bSYour Name 					    (uint8_t *)qdf_nbuf_data(wbuf));
1907*5113495bSYour Name 
1908*5113495bSYour Name 	/* if tkip, is counter measures enabled, then drop the frame */
1909*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1910*5113495bSYour Name 	status = cipher_table->enmic(key, wbuf, encapdone, hdrlen);
1911*5113495bSYour Name 
1912*5113495bSYour Name 	return status;
1913*5113495bSYour Name }
1914*5113495bSYour Name 
wlan_crypto_demic(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf,uint8_t * mac_addr,uint8_t tid,uint8_t keyid)1915*5113495bSYour Name QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
1916*5113495bSYour Name 			     qdf_nbuf_t wbuf,
1917*5113495bSYour Name 			     uint8_t *mac_addr,
1918*5113495bSYour Name 			     uint8_t tid,
1919*5113495bSYour Name 			     uint8_t keyid)
1920*5113495bSYour Name {
1921*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
1922*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
1923*5113495bSYour Name 	struct wlan_crypto_key *key;
1924*5113495bSYour Name 	QDF_STATUS status;
1925*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
1926*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1927*5113495bSYour Name 	uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
1928*5113495bSYour Name 	uint8_t hdrlen;
1929*5113495bSYour Name 	enum QDF_OPMODE opmode;
1930*5113495bSYour Name 
1931*5113495bSYour Name 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1932*5113495bSYour Name 
1933*5113495bSYour Name 	if (opmode == QDF_MONITOR_MODE)
1934*5113495bSYour Name 		hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
1935*5113495bSYour Name 	else
1936*5113495bSYour Name 		hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
1937*5113495bSYour Name 					    (uint8_t *)qdf_nbuf_data(wbuf));
1938*5113495bSYour Name 
1939*5113495bSYour Name 	wlan_vdev_obj_lock(vdev);
1940*5113495bSYour Name 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev),
1941*5113495bSYour Name 		    QDF_MAC_ADDR_SIZE);
1942*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
1943*5113495bSYour Name 	if (!psoc) {
1944*5113495bSYour Name 		wlan_vdev_obj_unlock(vdev);
1945*5113495bSYour Name 		crypto_err("psoc NULL");
1946*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1947*5113495bSYour Name 	}
1948*5113495bSYour Name 	wlan_vdev_obj_unlock(vdev);
1949*5113495bSYour Name 
1950*5113495bSYour Name 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
1951*5113495bSYour Name 		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
1952*5113495bSYour Name 								&crypto_priv);
1953*5113495bSYour Name 		if (!crypto_priv) {
1954*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1955*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1956*5113495bSYour Name 		}
1957*5113495bSYour Name 
1958*5113495bSYour Name 		key = crypto_priv->crypto_key.key[keyid];
1959*5113495bSYour Name 		if (!key)
1960*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1961*5113495bSYour Name 
1962*5113495bSYour Name 	} else {
1963*5113495bSYour Name 		struct wlan_objmgr_peer *peer;
1964*5113495bSYour Name 		uint8_t pdev_id;
1965*5113495bSYour Name 
1966*5113495bSYour Name 		pdev_id = wlan_objmgr_pdev_get_pdev_id(
1967*5113495bSYour Name 				wlan_vdev_get_pdev(vdev));
1968*5113495bSYour Name 		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
1969*5113495bSYour Name 					psoc, pdev_id, bssid_mac,
1970*5113495bSYour Name 					mac_addr, WLAN_CRYPTO_ID);
1971*5113495bSYour Name 		if (!peer) {
1972*5113495bSYour Name 			crypto_err("peer NULL");
1973*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1974*5113495bSYour Name 		}
1975*5113495bSYour Name 
1976*5113495bSYour Name 		crypto_params = wlan_crypto_peer_get_comp_params(peer,
1977*5113495bSYour Name 								&crypto_priv);
1978*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
1979*5113495bSYour Name 
1980*5113495bSYour Name 		if (!crypto_priv) {
1981*5113495bSYour Name 			crypto_err("crypto_priv NULL");
1982*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1983*5113495bSYour Name 		}
1984*5113495bSYour Name 
1985*5113495bSYour Name 		key = crypto_priv->crypto_key.key[keyid];
1986*5113495bSYour Name 		if (!key)
1987*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1988*5113495bSYour Name 	}
1989*5113495bSYour Name 	/* if tkip, is counter measures enabled, then drop the frame */
1990*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
1991*5113495bSYour Name 	status = cipher_table->demic(key, wbuf, tid, hdrlen);
1992*5113495bSYour Name 
1993*5113495bSYour Name 	return status;
1994*5113495bSYour Name }
1995*5113495bSYour Name 
wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev * vdev)1996*5113495bSYour Name bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev)
1997*5113495bSYour Name {
1998*5113495bSYour Name 
1999*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2000*5113495bSYour Name 	struct wlan_crypto_params *vdev_crypto_params;
2001*5113495bSYour Name 
2002*5113495bSYour Name 	if (!vdev)
2003*5113495bSYour Name 		return false;
2004*5113495bSYour Name 	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
2005*5113495bSYour Name 							&crypto_priv);
2006*5113495bSYour Name 	if (!crypto_priv) {
2007*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2008*5113495bSYour Name 		return false;
2009*5113495bSYour Name 	}
2010*5113495bSYour Name 
2011*5113495bSYour Name 	if ((vdev_crypto_params->rsn_caps &
2012*5113495bSYour Name 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)
2013*5113495bSYour Name 		|| (vdev_crypto_params->rsn_caps &
2014*5113495bSYour Name 					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
2015*5113495bSYour Name 		return true;
2016*5113495bSYour Name 	}
2017*5113495bSYour Name 
2018*5113495bSYour Name 	return false;
2019*5113495bSYour Name }
2020*5113495bSYour Name 
wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev * vdev)2021*5113495bSYour Name bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev)
2022*5113495bSYour Name {
2023*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2024*5113495bSYour Name 	struct wlan_crypto_params *vdev_crypto_params;
2025*5113495bSYour Name 
2026*5113495bSYour Name 	if (!vdev)
2027*5113495bSYour Name 		return false;
2028*5113495bSYour Name 
2029*5113495bSYour Name 	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
2030*5113495bSYour Name 							      &crypto_priv);
2031*5113495bSYour Name 	if (!crypto_priv) {
2032*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2033*5113495bSYour Name 		return false;
2034*5113495bSYour Name 	}
2035*5113495bSYour Name 
2036*5113495bSYour Name 	if (vdev_crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)
2037*5113495bSYour Name 		return true;
2038*5113495bSYour Name 
2039*5113495bSYour Name 	return false;
2040*5113495bSYour Name }
2041*5113495bSYour Name 
wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)2042*5113495bSYour Name bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev,
2043*5113495bSYour Name 				struct wlan_objmgr_peer *peer)
2044*5113495bSYour Name {
2045*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2046*5113495bSYour Name 	struct wlan_crypto_params *vdev_crypto_params;
2047*5113495bSYour Name 	struct wlan_crypto_params *peer_crypto_params;
2048*5113495bSYour Name 
2049*5113495bSYour Name 	if (!vdev || !peer)
2050*5113495bSYour Name 		return false;
2051*5113495bSYour Name 	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
2052*5113495bSYour Name 							&crypto_priv);
2053*5113495bSYour Name 	if (!crypto_priv) {
2054*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2055*5113495bSYour Name 		return false;
2056*5113495bSYour Name 	}
2057*5113495bSYour Name 
2058*5113495bSYour Name 	peer_crypto_params = wlan_crypto_peer_get_comp_params(peer,
2059*5113495bSYour Name 							&crypto_priv);
2060*5113495bSYour Name 	if (!crypto_priv) {
2061*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2062*5113495bSYour Name 		return false;
2063*5113495bSYour Name 	}
2064*5113495bSYour Name 	if (((vdev_crypto_params->rsn_caps &
2065*5113495bSYour Name 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) &&
2066*5113495bSYour Name 		(peer_crypto_params->rsn_caps &
2067*5113495bSYour Name 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
2068*5113495bSYour Name 		|| (vdev_crypto_params->rsn_caps &
2069*5113495bSYour Name 					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
2070*5113495bSYour Name 		return true;
2071*5113495bSYour Name 	}
2072*5113495bSYour Name 
2073*5113495bSYour Name 	return false;
2074*5113495bSYour Name }
2075*5113495bSYour Name 
wlan_crypto_is_key_valid(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer,uint16_t keyidx)2076*5113495bSYour Name bool wlan_crypto_is_key_valid(struct wlan_objmgr_vdev *vdev,
2077*5113495bSYour Name 			      struct wlan_objmgr_peer *peer,
2078*5113495bSYour Name 			      uint16_t keyidx)
2079*5113495bSYour Name {
2080*5113495bSYour Name 	struct wlan_crypto_key *key = NULL;
2081*5113495bSYour Name 
2082*5113495bSYour Name 	if (!vdev && !peer)
2083*5113495bSYour Name 		return false;
2084*5113495bSYour Name 
2085*5113495bSYour Name 	if (peer)
2086*5113495bSYour Name 		key = wlan_crypto_peer_getkey(peer, keyidx);
2087*5113495bSYour Name 	else if (vdev)
2088*5113495bSYour Name 		key = wlan_crypto_vdev_getkey(vdev, keyidx);
2089*5113495bSYour Name 
2090*5113495bSYour Name 	if ((key) && key->valid)
2091*5113495bSYour Name 		return true;
2092*5113495bSYour Name 
2093*5113495bSYour Name 	return false;
2094*5113495bSYour Name }
2095*5113495bSYour Name 
wlan_crypto_gmac_pn_swap(uint8_t * a,uint8_t * b)2096*5113495bSYour Name static void wlan_crypto_gmac_pn_swap(uint8_t *a, uint8_t *b)
2097*5113495bSYour Name {
2098*5113495bSYour Name 	a[0] = b[5];
2099*5113495bSYour Name 	a[1] = b[4];
2100*5113495bSYour Name 	a[2] = b[3];
2101*5113495bSYour Name 	a[3] = b[2];
2102*5113495bSYour Name 	a[4] = b[1];
2103*5113495bSYour Name 	a[5] = b[0];
2104*5113495bSYour Name }
2105*5113495bSYour Name 
wlan_crypto_add_mmie(struct wlan_objmgr_vdev * vdev,uint8_t * bfrm,uint32_t len)2106*5113495bSYour Name uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
2107*5113495bSYour Name 				uint8_t *bfrm,
2108*5113495bSYour Name 				uint32_t len)
2109*5113495bSYour Name {
2110*5113495bSYour Name 	struct wlan_crypto_key *key;
2111*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
2112*5113495bSYour Name 	struct wlan_crypto_mmie *mmie;
2113*5113495bSYour Name 	uint8_t *pn, *aad, *buf, *efrm, nonce[12];
2114*5113495bSYour Name 	struct wlan_frame_hdr *hdr;
2115*5113495bSYour Name 	uint32_t i, hdrlen, mic_len, aad_len;
2116*5113495bSYour Name 	uint8_t mic[16];
2117*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2118*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
2119*5113495bSYour Name 	int32_t ret = -1;
2120*5113495bSYour Name 
2121*5113495bSYour Name 	if (!bfrm) {
2122*5113495bSYour Name 		crypto_err("frame is NULL");
2123*5113495bSYour Name 		return NULL;
2124*5113495bSYour Name 	}
2125*5113495bSYour Name 
2126*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
2127*5113495bSYour Name 							&crypto_priv);
2128*5113495bSYour Name 	if (!crypto_priv) {
2129*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2130*5113495bSYour Name 		return NULL;
2131*5113495bSYour Name 	}
2132*5113495bSYour Name 
2133*5113495bSYour Name 	priv_key = &crypto_priv->crypto_key;
2134*5113495bSYour Name 
2135*5113495bSYour Name 	if (priv_key->def_igtk_tx_keyid >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
2136*5113495bSYour Name 		crypto_err("igtk key invalid keyid %d",
2137*5113495bSYour Name 			   priv_key->def_igtk_tx_keyid);
2138*5113495bSYour Name 		return NULL;
2139*5113495bSYour Name 	}
2140*5113495bSYour Name 
2141*5113495bSYour Name 	key = priv_key->igtk_key[priv_key->def_igtk_tx_keyid];
2142*5113495bSYour Name 	if (!key) {
2143*5113495bSYour Name 		crypto_err("No igtk key present");
2144*5113495bSYour Name 		return NULL;
2145*5113495bSYour Name 	}
2146*5113495bSYour Name 	mic_len = (priv_key->igtk_key_type
2147*5113495bSYour Name 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
2148*5113495bSYour Name 
2149*5113495bSYour Name 	efrm = bfrm + len;
2150*5113495bSYour Name 	aad_len = 20;
2151*5113495bSYour Name 	hdrlen = sizeof(struct wlan_frame_hdr);
2152*5113495bSYour Name 	len += sizeof(struct wlan_crypto_mmie);
2153*5113495bSYour Name 
2154*5113495bSYour Name 	mmie = (struct wlan_crypto_mmie *) efrm;
2155*5113495bSYour Name 	qdf_mem_zero((unsigned char *)mmie, sizeof(*mmie));
2156*5113495bSYour Name 	mmie->element_id = WLAN_ELEMID_MMIE;
2157*5113495bSYour Name 	mmie->length = sizeof(*mmie) - 2;
2158*5113495bSYour Name 	mmie->key_id = qdf_cpu_to_le16(key->keyix);
2159*5113495bSYour Name 
2160*5113495bSYour Name 	mic_len = (priv_key->igtk_key_type
2161*5113495bSYour Name 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
2162*5113495bSYour Name 	if (mic_len == 8) {
2163*5113495bSYour Name 		mmie->length -= 8;
2164*5113495bSYour Name 		len -= 8;
2165*5113495bSYour Name 	}
2166*5113495bSYour Name 	/* PN = PN + 1 */
2167*5113495bSYour Name 	pn = (uint8_t *)&key->keytsc;
2168*5113495bSYour Name 
2169*5113495bSYour Name 	for (i = 0; i <= 5; i++) {
2170*5113495bSYour Name 		pn[i]++;
2171*5113495bSYour Name 		if (pn[i])
2172*5113495bSYour Name 			break;
2173*5113495bSYour Name 	}
2174*5113495bSYour Name 
2175*5113495bSYour Name 	/* Copy IPN */
2176*5113495bSYour Name 	qdf_mem_copy(mmie->sequence_number, pn, 6);
2177*5113495bSYour Name 
2178*5113495bSYour Name 	hdr = (struct wlan_frame_hdr *) bfrm;
2179*5113495bSYour Name 
2180*5113495bSYour Name 	buf = qdf_mem_malloc(len - hdrlen + 20);
2181*5113495bSYour Name 	if (!buf)
2182*5113495bSYour Name 		return NULL;
2183*5113495bSYour Name 
2184*5113495bSYour Name 	qdf_mem_zero(buf, len - hdrlen + 20);
2185*5113495bSYour Name 	aad = buf;
2186*5113495bSYour Name 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
2187*5113495bSYour Name 
2188*5113495bSYour Name 	/* FC type/subtype */
2189*5113495bSYour Name 	aad[0] = hdr->i_fc[0];
2190*5113495bSYour Name 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
2191*5113495bSYour Name 	aad[1] = (hdr->i_fc[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
2192*5113495bSYour Name 						| WLAN_FC1_MOREDATA));
2193*5113495bSYour Name 	/* A1 || A2 || A3 */
2194*5113495bSYour Name 	qdf_mem_copy(aad + 2, hdr->i_addr1, QDF_MAC_ADDR_SIZE);
2195*5113495bSYour Name 	qdf_mem_copy(aad + 8, hdr->i_addr2, QDF_MAC_ADDR_SIZE);
2196*5113495bSYour Name 	qdf_mem_copy(aad + 14, hdr->i_addr3, QDF_MAC_ADDR_SIZE);
2197*5113495bSYour Name 	qdf_mem_zero(mic, 16);
2198*5113495bSYour Name 
2199*5113495bSYour Name 	/*
2200*5113495bSYour Name 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
2201*5113495bSYour Name 	 */
2202*5113495bSYour Name 
2203*5113495bSYour Name 	qdf_mem_copy(buf + aad_len, bfrm + hdrlen, len - hdrlen);
2204*5113495bSYour Name 	if (priv_key->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
2205*5113495bSYour Name 
2206*5113495bSYour Name 		ret = omac1_aes_128(key->keyval, buf,
2207*5113495bSYour Name 					len + aad_len - hdrlen, mic);
2208*5113495bSYour Name 		qdf_mem_copy(mmie->mic, mic, 8);
2209*5113495bSYour Name 
2210*5113495bSYour Name 	} else if (priv_key->igtk_key_type
2211*5113495bSYour Name 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
2212*5113495bSYour Name 
2213*5113495bSYour Name 		ret = omac1_aes_256(key->keyval, buf,
2214*5113495bSYour Name 					len + aad_len - hdrlen, mmie->mic);
2215*5113495bSYour Name 	} else if ((priv_key->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_GMAC) ||
2216*5113495bSYour Name 			(priv_key->igtk_key_type
2217*5113495bSYour Name 					== WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
2218*5113495bSYour Name 
2219*5113495bSYour Name 		qdf_mem_copy(nonce, hdr->i_addr2, QDF_MAC_ADDR_SIZE);
2220*5113495bSYour Name 		wlan_crypto_gmac_pn_swap(nonce + 6, pn);
2221*5113495bSYour Name 		ret = wlan_crypto_aes_gmac(key->keyval, key->keylen, nonce,
2222*5113495bSYour Name 					sizeof(nonce), buf,
2223*5113495bSYour Name 					len + aad_len - hdrlen, mmie->mic);
2224*5113495bSYour Name 	}
2225*5113495bSYour Name 	qdf_mem_free(buf);
2226*5113495bSYour Name 	if (ret < 0) {
2227*5113495bSYour Name 		crypto_err("add mmie failed");
2228*5113495bSYour Name 		return NULL;
2229*5113495bSYour Name 	}
2230*5113495bSYour Name 
2231*5113495bSYour Name 	return bfrm + len;
2232*5113495bSYour Name }
2233*5113495bSYour Name 
2234*5113495bSYour Name #define MAX_MIC_LEN 16
wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev * vdev,uint8_t * frm,uint8_t * efrm)2235*5113495bSYour Name bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
2236*5113495bSYour Name 					uint8_t *frm,
2237*5113495bSYour Name 					uint8_t *efrm)
2238*5113495bSYour Name {
2239*5113495bSYour Name 	struct wlan_crypto_mmie   *mmie = NULL;
2240*5113495bSYour Name 	uint8_t *ipn, *aad, *buf, *mic, nonce[12];
2241*5113495bSYour Name 	struct wlan_crypto_key *key;
2242*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
2243*5113495bSYour Name 	struct wlan_frame_hdr *hdr;
2244*5113495bSYour Name 	uint16_t mic_len, hdrlen, len;
2245*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2246*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
2247*5113495bSYour Name 	uint8_t aad_len = 20;
2248*5113495bSYour Name 	int32_t ret = -1;
2249*5113495bSYour Name 
2250*5113495bSYour Name 	/* check if frame is illegal length */
2251*5113495bSYour Name 	if (!frm || !efrm || (efrm < frm)
2252*5113495bSYour Name 			|| ((efrm - frm) < sizeof(struct wlan_frame_hdr))) {
2253*5113495bSYour Name 		crypto_err("Invalid params");
2254*5113495bSYour Name 		return false;
2255*5113495bSYour Name 	}
2256*5113495bSYour Name 	len = efrm - frm;
2257*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
2258*5113495bSYour Name 				wlan_get_vdev_crypto_obj(vdev);
2259*5113495bSYour Name 	if (!crypto_priv) {
2260*5113495bSYour Name 		crypto_err("crypto_priv NULL");
2261*5113495bSYour Name 		return false;
2262*5113495bSYour Name 	}
2263*5113495bSYour Name 
2264*5113495bSYour Name 	priv_key = &crypto_priv->crypto_key;
2265*5113495bSYour Name 
2266*5113495bSYour Name 	crypto_params = &(crypto_priv->crypto_params);
2267*5113495bSYour Name 
2268*5113495bSYour Name 
2269*5113495bSYour Name 	mic_len = (priv_key->igtk_key_type
2270*5113495bSYour Name 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
2271*5113495bSYour Name 	hdrlen = sizeof(struct wlan_frame_hdr);
2272*5113495bSYour Name 
2273*5113495bSYour Name 	if (mic_len == 8)
2274*5113495bSYour Name 		mmie = (struct wlan_crypto_mmie *)(efrm - sizeof(*mmie) + 8);
2275*5113495bSYour Name 	else
2276*5113495bSYour Name 		mmie = (struct wlan_crypto_mmie *)(efrm - sizeof(*mmie));
2277*5113495bSYour Name 
2278*5113495bSYour Name 
2279*5113495bSYour Name 	/* check Elem ID*/
2280*5113495bSYour Name 	if ((!mmie) || (mmie->element_id != WLAN_ELEMID_MMIE)) {
2281*5113495bSYour Name 		crypto_err("IE is not MMIE");
2282*5113495bSYour Name 		return false;
2283*5113495bSYour Name 	}
2284*5113495bSYour Name 
2285*5113495bSYour Name 	if (mmie->key_id >= (WLAN_CRYPTO_MAXKEYIDX +
2286*5113495bSYour Name 				WLAN_CRYPTO_MAXIGTKKEYIDX) ||
2287*5113495bSYour Name 				(mmie->key_id < WLAN_CRYPTO_MAXKEYIDX)) {
2288*5113495bSYour Name 		crypto_err("keyid not valid");
2289*5113495bSYour Name 		return false;
2290*5113495bSYour Name 	}
2291*5113495bSYour Name 
2292*5113495bSYour Name 	key = priv_key->igtk_key[mmie->key_id - WLAN_CRYPTO_MAXKEYIDX];
2293*5113495bSYour Name 	if (!key) {
2294*5113495bSYour Name 		crypto_err("No igtk key present");
2295*5113495bSYour Name 		return false;
2296*5113495bSYour Name 	}
2297*5113495bSYour Name 
2298*5113495bSYour Name 	/* validate ipn */
2299*5113495bSYour Name 	ipn = mmie->sequence_number;
2300*5113495bSYour Name 	if (qdf_mem_cmp(ipn, key->keyrsc, 6) <= 0) {
2301*5113495bSYour Name 		uint8_t *su = (uint8_t *)key->keyrsc;
2302*5113495bSYour Name 		uint8_t *end = ipn + 6;
2303*5113495bSYour Name 		struct wlan_objmgr_peer *peer = wlan_vdev_get_selfpeer(vdev);
2304*5113495bSYour Name 
2305*5113495bSYour Name 		crypto_err("replay error :");
2306*5113495bSYour Name 		while (ipn < end) {
2307*5113495bSYour Name 			crypto_err("expected pn = %x received pn = %x",
2308*5113495bSYour Name 				   *ipn++, *su++);
2309*5113495bSYour Name 		}
2310*5113495bSYour Name 		wlan_cp_stats_vdev_mcast_rx_pnerr(vdev);
2311*5113495bSYour Name 		wlan_cp_stats_peer_rx_pnerr(peer);
2312*5113495bSYour Name 		return false;
2313*5113495bSYour Name 	}
2314*5113495bSYour Name 
2315*5113495bSYour Name 	buf = qdf_mem_malloc(len - hdrlen + 20);
2316*5113495bSYour Name 	if (!buf)
2317*5113495bSYour Name 		return false;
2318*5113495bSYour Name 
2319*5113495bSYour Name 	aad = buf;
2320*5113495bSYour Name 
2321*5113495bSYour Name 	/* construct AAD */
2322*5113495bSYour Name 	hdr = (struct wlan_frame_hdr *)frm;
2323*5113495bSYour Name 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
2324*5113495bSYour Name 
2325*5113495bSYour Name 	/* FC type/subtype */
2326*5113495bSYour Name 	aad[0] = hdr->i_fc[0];
2327*5113495bSYour Name 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
2328*5113495bSYour Name 	aad[1] = (hdr->i_fc[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
2329*5113495bSYour Name 						| WLAN_FC1_MOREDATA));
2330*5113495bSYour Name 	/* A1 || A2 || A3 */
2331*5113495bSYour Name 	qdf_mem_copy(aad + 2, hdr->i_addr1, 3 * QDF_MAC_ADDR_SIZE);
2332*5113495bSYour Name 
2333*5113495bSYour Name 	/*
2334*5113495bSYour Name 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
2335*5113495bSYour Name 	 */
2336*5113495bSYour Name 	qdf_mem_copy(buf + 20, frm + hdrlen, len - hdrlen);
2337*5113495bSYour Name 	qdf_mem_zero(buf + (len - hdrlen + 20 - mic_len), mic_len);
2338*5113495bSYour Name 	mic = qdf_mem_malloc(MAX_MIC_LEN);
2339*5113495bSYour Name 	if (!mic) {
2340*5113495bSYour Name 		qdf_mem_free(buf);
2341*5113495bSYour Name 		return false;
2342*5113495bSYour Name 	}
2343*5113495bSYour Name 	if (priv_key->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
2344*5113495bSYour Name 		ret = omac1_aes_128(key->keyval, buf,
2345*5113495bSYour Name 					len - hdrlen + aad_len, mic);
2346*5113495bSYour Name 	} else if (priv_key->igtk_key_type
2347*5113495bSYour Name 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
2348*5113495bSYour Name 		ret = omac1_aes_256(key->keyval, buf,
2349*5113495bSYour Name 					len + aad_len - hdrlen, mic);
2350*5113495bSYour Name 	} else if ((priv_key->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_GMAC) ||
2351*5113495bSYour Name 			(priv_key->igtk_key_type
2352*5113495bSYour Name 					== WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
2353*5113495bSYour Name 		qdf_mem_copy(nonce, hdr->i_addr2, QDF_MAC_ADDR_SIZE);
2354*5113495bSYour Name 		wlan_crypto_gmac_pn_swap(nonce + 6, ipn);
2355*5113495bSYour Name 		ret = wlan_crypto_aes_gmac(key->keyval, key->keylen, nonce,
2356*5113495bSYour Name 					sizeof(nonce), buf,
2357*5113495bSYour Name 					len + aad_len - hdrlen, mic);
2358*5113495bSYour Name 	}
2359*5113495bSYour Name 
2360*5113495bSYour Name 	qdf_mem_free(buf);
2361*5113495bSYour Name 
2362*5113495bSYour Name 	if (ret < 0) {
2363*5113495bSYour Name 		qdf_mem_free(mic);
2364*5113495bSYour Name 		crypto_err("generate mmie failed");
2365*5113495bSYour Name 		return false;
2366*5113495bSYour Name 	}
2367*5113495bSYour Name 
2368*5113495bSYour Name 	if (qdf_mem_cmp(mic, mmie->mic, mic_len) != 0) {
2369*5113495bSYour Name 		qdf_mem_free(mic);
2370*5113495bSYour Name 		crypto_err("mmie mismatch");
2371*5113495bSYour Name 		/* MMIE MIC mismatch */
2372*5113495bSYour Name 		return false;
2373*5113495bSYour Name 	}
2374*5113495bSYour Name 
2375*5113495bSYour Name 	qdf_mem_free(mic);
2376*5113495bSYour Name 	/* Update the receive sequence number */
2377*5113495bSYour Name 	qdf_mem_copy(key->keyrsc, ipn, 6);
2378*5113495bSYour Name 	crypto_debug("mmie matched");
2379*5113495bSYour Name 
2380*5113495bSYour Name 	return true;
2381*5113495bSYour Name }
2382*5113495bSYour Name 
2383*5113495bSYour Name 
wlan_crypto_wpa_cipher_to_suite(uint32_t cipher)2384*5113495bSYour Name static int32_t wlan_crypto_wpa_cipher_to_suite(uint32_t cipher)
2385*5113495bSYour Name {
2386*5113495bSYour Name 	int32_t status = -1;
2387*5113495bSYour Name 
2388*5113495bSYour Name 	switch (cipher) {
2389*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_TKIP:
2390*5113495bSYour Name 		return WPA_CIPHER_SUITE_TKIP;
2391*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CCM:
2392*5113495bSYour Name 		return WPA_CIPHER_SUITE_CCMP;
2393*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_NONE:
2394*5113495bSYour Name 		return WPA_CIPHER_SUITE_NONE;
2395*5113495bSYour Name 	}
2396*5113495bSYour Name 
2397*5113495bSYour Name 	return status;
2398*5113495bSYour Name }
2399*5113495bSYour Name 
wlan_crypto_rsn_cipher_to_suite(uint32_t cipher)2400*5113495bSYour Name static int32_t wlan_crypto_rsn_cipher_to_suite(uint32_t cipher)
2401*5113495bSYour Name {
2402*5113495bSYour Name 	int32_t status = -1;
2403*5113495bSYour Name 
2404*5113495bSYour Name 	switch (cipher) {
2405*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_TKIP:
2406*5113495bSYour Name 		return RSN_CIPHER_SUITE_TKIP;
2407*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CCM:
2408*5113495bSYour Name 		return RSN_CIPHER_SUITE_CCMP;
2409*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CCM_256:
2410*5113495bSYour Name 		return RSN_CIPHER_SUITE_CCMP_256;
2411*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GCM:
2412*5113495bSYour Name 		return RSN_CIPHER_SUITE_GCMP;
2413*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GCM_256:
2414*5113495bSYour Name 		return RSN_CIPHER_SUITE_GCMP_256;
2415*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CMAC:
2416*5113495bSYour Name 		return RSN_CIPHER_SUITE_AES_CMAC;
2417*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CMAC_256:
2418*5113495bSYour Name 		return RSN_CIPHER_SUITE_BIP_CMAC_256;
2419*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GMAC:
2420*5113495bSYour Name 		return RSN_CIPHER_SUITE_BIP_GMAC_128;
2421*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GMAC_256:
2422*5113495bSYour Name 		return RSN_CIPHER_SUITE_BIP_GMAC_256;
2423*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_NONE:
2424*5113495bSYour Name 		return RSN_CIPHER_SUITE_NONE;
2425*5113495bSYour Name 	}
2426*5113495bSYour Name 
2427*5113495bSYour Name 	return status;
2428*5113495bSYour Name }
2429*5113495bSYour Name 
2430*5113495bSYour Name /*
2431*5113495bSYour Name  * Convert an RSN key management/authentication algorithm
2432*5113495bSYour Name  * to an internal code.
2433*5113495bSYour Name  */
2434*5113495bSYour Name static int32_t
wlan_crypto_rsn_keymgmt_to_suite(uint32_t keymgmt)2435*5113495bSYour Name wlan_crypto_rsn_keymgmt_to_suite(uint32_t keymgmt)
2436*5113495bSYour Name {
2437*5113495bSYour Name 	int32_t status = -1;
2438*5113495bSYour Name 
2439*5113495bSYour Name 	switch (keymgmt) {
2440*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_NONE:
2441*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_NONE;
2442*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
2443*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
2444*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_PSK:
2445*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
2446*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X:
2447*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_802_1X;
2448*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_PSK:
2449*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_PSK;
2450*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256:
2451*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2452*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_PSK_SHA256:
2453*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2454*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_SAE:
2455*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_SAE;
2456*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_SAE:
2457*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_SAE;
2458*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B:
2459*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
2460*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192:
2461*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
2462*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_CCKM:
2463*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_CCKM;
2464*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_OSEN:
2465*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_OSEN;
2466*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FILS_SHA256:
2467*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FILS_SHA256;
2468*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FILS_SHA384:
2469*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FILS_SHA384;
2470*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256:
2471*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
2472*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384:
2473*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
2474*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_OWE:
2475*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_OWE;
2476*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_DPP:
2477*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_DPP;
2478*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384:
2479*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384;
2480*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY:
2481*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
2482*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY:
2483*5113495bSYour Name 		return RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
2484*5113495bSYour Name 	}
2485*5113495bSYour Name 
2486*5113495bSYour Name 	return status;
2487*5113495bSYour Name }
2488*5113495bSYour Name 
2489*5113495bSYour Name /*
2490*5113495bSYour Name  * Convert an RSN key management/authentication algorithm
2491*5113495bSYour Name  * to an internal code.
2492*5113495bSYour Name  */
2493*5113495bSYour Name static int32_t
wlan_crypto_wpa_keymgmt_to_suite(uint32_t keymgmt)2494*5113495bSYour Name wlan_crypto_wpa_keymgmt_to_suite(uint32_t keymgmt)
2495*5113495bSYour Name {
2496*5113495bSYour Name 	int32_t status = -1;
2497*5113495bSYour Name 
2498*5113495bSYour Name 	switch (keymgmt) {
2499*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_NONE:
2500*5113495bSYour Name 		return WPA_AUTH_KEY_MGMT_NONE;
2501*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
2502*5113495bSYour Name 		return WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
2503*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_PSK:
2504*5113495bSYour Name 		return WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
2505*5113495bSYour Name 	case WLAN_CRYPTO_KEY_MGMT_CCKM:
2506*5113495bSYour Name 		return WPA_AUTH_KEY_MGMT_CCKM;
2507*5113495bSYour Name 	}
2508*5113495bSYour Name 
2509*5113495bSYour Name 	return status;
2510*5113495bSYour Name }
2511*5113495bSYour Name 
2512*5113495bSYour Name /*
2513*5113495bSYour Name  * Convert a WPA cipher selector OUI to an internal
2514*5113495bSYour Name  * cipher algorithm.  Where appropriate we also
2515*5113495bSYour Name  * record any key length.
2516*5113495bSYour Name  */
wlan_crypto_wpa_suite_to_cipher(const uint8_t * sel)2517*5113495bSYour Name static int32_t wlan_crypto_wpa_suite_to_cipher(const uint8_t *sel)
2518*5113495bSYour Name {
2519*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
2520*5113495bSYour Name 	int32_t status = -1;
2521*5113495bSYour Name 
2522*5113495bSYour Name 	switch (w) {
2523*5113495bSYour Name 	case WPA_CIPHER_SUITE_TKIP:
2524*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_TKIP;
2525*5113495bSYour Name 	case WPA_CIPHER_SUITE_CCMP:
2526*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CCM;
2527*5113495bSYour Name 	case WPA_CIPHER_SUITE_NONE:
2528*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_NONE;
2529*5113495bSYour Name 	}
2530*5113495bSYour Name 
2531*5113495bSYour Name 	return status;
2532*5113495bSYour Name }
2533*5113495bSYour Name 
2534*5113495bSYour Name /*
2535*5113495bSYour Name  * Convert a WPA key management/authentication algorithm
2536*5113495bSYour Name  * to an internal code.
2537*5113495bSYour Name  */
wlan_crypto_wpa_suite_to_keymgmt(const uint8_t * sel)2538*5113495bSYour Name static int32_t wlan_crypto_wpa_suite_to_keymgmt(const uint8_t *sel)
2539*5113495bSYour Name {
2540*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
2541*5113495bSYour Name 	int32_t status = -1;
2542*5113495bSYour Name 
2543*5113495bSYour Name 	switch (w) {
2544*5113495bSYour Name 	case WPA_AUTH_KEY_MGMT_UNSPEC_802_1X:
2545*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
2546*5113495bSYour Name 	case WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X:
2547*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK;
2548*5113495bSYour Name 	case WPA_AUTH_KEY_MGMT_CCKM:
2549*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_CCKM;
2550*5113495bSYour Name 	case WPA_AUTH_KEY_MGMT_NONE:
2551*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_NONE;
2552*5113495bSYour Name 	}
2553*5113495bSYour Name 	return status;
2554*5113495bSYour Name }
2555*5113495bSYour Name 
2556*5113495bSYour Name /*
2557*5113495bSYour Name  * Convert a RSN cipher selector OUI to an internal
2558*5113495bSYour Name  * cipher algorithm.  Where appropriate we also
2559*5113495bSYour Name  * record any key length.
2560*5113495bSYour Name  */
wlan_crypto_rsn_suite_to_cipher(const uint8_t * sel)2561*5113495bSYour Name static int32_t wlan_crypto_rsn_suite_to_cipher(const uint8_t *sel)
2562*5113495bSYour Name {
2563*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
2564*5113495bSYour Name 	int32_t status = -1;
2565*5113495bSYour Name 
2566*5113495bSYour Name 	switch (w) {
2567*5113495bSYour Name 	case RSN_CIPHER_SUITE_TKIP:
2568*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_TKIP;
2569*5113495bSYour Name 	case RSN_CIPHER_SUITE_CCMP:
2570*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CCM;
2571*5113495bSYour Name 	case RSN_CIPHER_SUITE_CCMP_256:
2572*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CCM_256;
2573*5113495bSYour Name 	case RSN_CIPHER_SUITE_GCMP:
2574*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GCM;
2575*5113495bSYour Name 	case RSN_CIPHER_SUITE_GCMP_256:
2576*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GCM_256;
2577*5113495bSYour Name 	case RSN_CIPHER_SUITE_AES_CMAC:
2578*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CMAC;
2579*5113495bSYour Name 	case RSN_CIPHER_SUITE_BIP_CMAC_256:
2580*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_CMAC_256;
2581*5113495bSYour Name 	case RSN_CIPHER_SUITE_BIP_GMAC_128:
2582*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GMAC;
2583*5113495bSYour Name 	case RSN_CIPHER_SUITE_BIP_GMAC_256:
2584*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_AES_GMAC_256;
2585*5113495bSYour Name 	case RSN_CIPHER_SUITE_NONE:
2586*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_NONE;
2587*5113495bSYour Name 	}
2588*5113495bSYour Name 
2589*5113495bSYour Name 	return status;
2590*5113495bSYour Name }
2591*5113495bSYour Name /*
2592*5113495bSYour Name  * Convert an RSN key management/authentication algorithm
2593*5113495bSYour Name  * to an internal code.
2594*5113495bSYour Name  */
wlan_crypto_rsn_suite_to_keymgmt(const uint8_t * sel)2595*5113495bSYour Name static int32_t wlan_crypto_rsn_suite_to_keymgmt(const uint8_t *sel)
2596*5113495bSYour Name {
2597*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
2598*5113495bSYour Name 	int32_t status = -1;
2599*5113495bSYour Name 
2600*5113495bSYour Name 	switch (w) {
2601*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
2602*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
2603*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
2604*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK;
2605*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_802_1X:
2606*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X;
2607*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_PSK:
2608*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_PSK;
2609*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
2610*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256;
2611*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_PSK_SHA256:
2612*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA256;
2613*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_SAE:
2614*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_SAE;
2615*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_SAE:
2616*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_SAE;
2617*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
2618*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B;
2619*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
2620*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192;
2621*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_CCKM:
2622*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_CCKM;
2623*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_OSEN:
2624*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_OSEN;
2625*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FILS_SHA256:
2626*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA256;
2627*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FILS_SHA384:
2628*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA384;
2629*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
2630*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256;
2631*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
2632*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384;
2633*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_OWE:
2634*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_OWE;
2635*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_DPP:
2636*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_DPP;
2637*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384:
2638*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384;
2639*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_PSK_SHA384:
2640*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_PSK_SHA384;
2641*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_PSK_SHA384:
2642*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA384;
2643*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_SAE_EXT_KEY:
2644*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY;
2645*5113495bSYour Name 	case RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY:
2646*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY;
2647*5113495bSYour Name 	}
2648*5113495bSYour Name 
2649*5113495bSYour Name 	return status;
2650*5113495bSYour Name }
2651*5113495bSYour Name 
wlan_crypto_wpaie_check(struct wlan_crypto_params * crypto_params,const uint8_t * frm)2652*5113495bSYour Name QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params,
2653*5113495bSYour Name 				   const uint8_t *frm)
2654*5113495bSYour Name {
2655*5113495bSYour Name 	uint8_t len = frm[1];
2656*5113495bSYour Name 	int32_t w;
2657*5113495bSYour Name 	int n;
2658*5113495bSYour Name 
2659*5113495bSYour Name 	/*
2660*5113495bSYour Name 	 * Check the length once for fixed parts: OUI, type,
2661*5113495bSYour Name 	 * version, mcast cipher, and 2 selector counts.
2662*5113495bSYour Name 	 * Other, variable-length data, must be checked separately.
2663*5113495bSYour Name 	 */
2664*5113495bSYour Name 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WPA);
2665*5113495bSYour Name 
2666*5113495bSYour Name 	if (len < 14)
2667*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2668*5113495bSYour Name 
2669*5113495bSYour Name 	frm += 6, len -= 4;
2670*5113495bSYour Name 
2671*5113495bSYour Name 	w = LE_READ_2(frm);
2672*5113495bSYour Name 	if (w != WPA_VERSION)
2673*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2674*5113495bSYour Name 
2675*5113495bSYour Name 	frm += 2, len -= 2;
2676*5113495bSYour Name 
2677*5113495bSYour Name 	/* multicast/group cipher */
2678*5113495bSYour Name 	w = wlan_crypto_wpa_suite_to_cipher(frm);
2679*5113495bSYour Name 	if (w < 0)
2680*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2681*5113495bSYour Name 	SET_MCAST_CIPHER(crypto_params, w);
2682*5113495bSYour Name 	frm += 4, len -= 4;
2683*5113495bSYour Name 
2684*5113495bSYour Name 	/* unicast ciphers */
2685*5113495bSYour Name 	n = LE_READ_2(frm);
2686*5113495bSYour Name 	frm += 2, len -= 2;
2687*5113495bSYour Name 	if (len < n*4+2)
2688*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2689*5113495bSYour Name 
2690*5113495bSYour Name 	for (; n > 0; n--) {
2691*5113495bSYour Name 		w = wlan_crypto_wpa_suite_to_cipher(frm);
2692*5113495bSYour Name 		if (w < 0)
2693*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2694*5113495bSYour Name 		SET_UCAST_CIPHER(crypto_params, w);
2695*5113495bSYour Name 		frm += 4, len -= 4;
2696*5113495bSYour Name 	}
2697*5113495bSYour Name 
2698*5113495bSYour Name 	if (!crypto_params->ucastcipherset)
2699*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2700*5113495bSYour Name 
2701*5113495bSYour Name 	/* key management algorithms */
2702*5113495bSYour Name 	n = LE_READ_2(frm);
2703*5113495bSYour Name 	frm += 2, len -= 2;
2704*5113495bSYour Name 	if (len < n*4)
2705*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2706*5113495bSYour Name 
2707*5113495bSYour Name 	w = 0;
2708*5113495bSYour Name 	for (; n > 0; n--) {
2709*5113495bSYour Name 		w = wlan_crypto_wpa_suite_to_keymgmt(frm);
2710*5113495bSYour Name 		if (w < 0)
2711*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2712*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, w);
2713*5113495bSYour Name 		frm += 4, len -= 4;
2714*5113495bSYour Name 	}
2715*5113495bSYour Name 
2716*5113495bSYour Name 	/* optional capabilities */
2717*5113495bSYour Name 	if (len >= 2) {
2718*5113495bSYour Name 		crypto_params->rsn_caps = LE_READ_2(frm);
2719*5113495bSYour Name 		frm += 2, len -= 2;
2720*5113495bSYour Name 	}
2721*5113495bSYour Name 
2722*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2723*5113495bSYour Name }
2724*5113495bSYour Name 
2725*5113495bSYour Name #ifdef WLAN_ADAPTIVE_11R
2726*5113495bSYour Name /**
2727*5113495bSYour Name  * wlan_crypto_store_akm_list_in_order() - store AMK list in order
2728*5113495bSYour Name  * @crypto_params: crypto param structure
2729*5113495bSYour Name  * @key_mgmt: key management
2730*5113495bSYour Name  * @akm_index: place at which AMK present in RSN IE of Beacon/Probe response
2731*5113495bSYour Name  *
2732*5113495bSYour Name  * Return: none
2733*5113495bSYour Name  */
2734*5113495bSYour Name static void
wlan_crypto_store_akm_list_in_order(struct wlan_crypto_params * crypto_params,int32_t key_mgmt,int akm_index)2735*5113495bSYour Name wlan_crypto_store_akm_list_in_order(struct wlan_crypto_params *crypto_params,
2736*5113495bSYour Name 				    int32_t key_mgmt, int akm_index)
2737*5113495bSYour Name {
2738*5113495bSYour Name 	if (akm_index >= WLAN_CRYPTO_KEY_MGMT_MAX) {
2739*5113495bSYour Name 		crypto_debug("Invalid AKM Index");
2740*5113495bSYour Name 		return;
2741*5113495bSYour Name 	}
2742*5113495bSYour Name 
2743*5113495bSYour Name 	crypto_params->akm_list[akm_index].key_mgmt = key_mgmt;
2744*5113495bSYour Name }
2745*5113495bSYour Name #else
2746*5113495bSYour Name static inline void
wlan_crypto_store_akm_list_in_order(struct wlan_crypto_params * crypto_params,int32_t key_mgmt,int akm_index)2747*5113495bSYour Name wlan_crypto_store_akm_list_in_order(struct wlan_crypto_params *crypto_params,
2748*5113495bSYour Name 				    int32_t key_mgmt, int akm_index)
2749*5113495bSYour Name {
2750*5113495bSYour Name }
2751*5113495bSYour Name #endif
2752*5113495bSYour Name 
wlan_crypto_rsnxie_check(struct wlan_crypto_params * crypto_params,const uint8_t * rsnxe)2753*5113495bSYour Name void wlan_crypto_rsnxie_check(struct wlan_crypto_params *crypto_params,
2754*5113495bSYour Name 			      const uint8_t *rsnxe)
2755*5113495bSYour Name {
2756*5113495bSYour Name 	uint8_t i = 0, len = rsnxe[1];
2757*5113495bSYour Name 
2758*5113495bSYour Name 	for (; len > 0 ; len--) {
2759*5113495bSYour Name 		((uint8_t *)(&crypto_params->rsnx_caps))[i] = rsnxe[2 + i];
2760*5113495bSYour Name 		i++;
2761*5113495bSYour Name 	}
2762*5113495bSYour Name 	/*First 4bits of RSNX capabilitities field is the length of
2763*5113495bSYour Name 	 *the Extended RSN capabilities field -1
2764*5113495bSYour Name 	 *Hence Ignoring them
2765*5113495bSYour Name 	 */
2766*5113495bSYour Name 	((uint8_t *)(&crypto_params->rsnx_caps))[0] &= 0xf0;
2767*5113495bSYour Name }
2768*5113495bSYour Name 
wlan_crypto_rsnie_check(struct wlan_crypto_params * crypto_params,const uint8_t * frm)2769*5113495bSYour Name QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *crypto_params,
2770*5113495bSYour Name 				   const uint8_t *frm)
2771*5113495bSYour Name {
2772*5113495bSYour Name 	uint8_t len = frm[1];
2773*5113495bSYour Name 	int32_t w;
2774*5113495bSYour Name 	int n, akm_index;
2775*5113495bSYour Name 
2776*5113495bSYour Name 	/* Check the length once for fixed parts: OUI, type & version */
2777*5113495bSYour Name 	if (len < 2)
2778*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2779*5113495bSYour Name 
2780*5113495bSYour Name 	/* initialize crypto params */
2781*5113495bSYour Name 	qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
2782*5113495bSYour Name 
2783*5113495bSYour Name 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_RSNA);
2784*5113495bSYour Name 
2785*5113495bSYour Name 	frm += 2;
2786*5113495bSYour Name 	/* NB: iswapoui already validated the OUI and type */
2787*5113495bSYour Name 	w = LE_READ_2(frm);
2788*5113495bSYour Name 	if (w != RSN_VERSION)
2789*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2790*5113495bSYour Name 
2791*5113495bSYour Name 	frm += 2, len -= 2;
2792*5113495bSYour Name 
2793*5113495bSYour Name 	if (!len) {
2794*5113495bSYour Name 		/* set defaults */
2795*5113495bSYour Name 		/* default group cipher CCMP-128 */
2796*5113495bSYour Name 		SET_MCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2797*5113495bSYour Name 		/* default ucast cipher CCMP-128 */
2798*5113495bSYour Name 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2799*5113495bSYour Name 		/* default key mgmt 8021x */
2800*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2801*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2802*5113495bSYour Name 	} else if (len < 4) {
2803*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2804*5113495bSYour Name 	}
2805*5113495bSYour Name 
2806*5113495bSYour Name 	/* multicast/group cipher */
2807*5113495bSYour Name 	w = wlan_crypto_rsn_suite_to_cipher(frm);
2808*5113495bSYour Name 	if (w < 0)
2809*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2810*5113495bSYour Name 	else {
2811*5113495bSYour Name 		SET_MCAST_CIPHER(crypto_params, w);
2812*5113495bSYour Name 		frm += 4, len -= 4;
2813*5113495bSYour Name 	}
2814*5113495bSYour Name 
2815*5113495bSYour Name 	if (crypto_params->mcastcipherset == 0)
2816*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2817*5113495bSYour Name 
2818*5113495bSYour Name 	if (!len) {
2819*5113495bSYour Name 		/* default ucast cipher CCMP-128 */
2820*5113495bSYour Name 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2821*5113495bSYour Name 		/* default key mgmt 8021x */
2822*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2823*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2824*5113495bSYour Name 	} else if (len < 2) {
2825*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2826*5113495bSYour Name 	}
2827*5113495bSYour Name 
2828*5113495bSYour Name 	/* unicast ciphers */
2829*5113495bSYour Name 	n = LE_READ_2(frm);
2830*5113495bSYour Name 	frm += 2, len -= 2;
2831*5113495bSYour Name 	if (n) {
2832*5113495bSYour Name 		if (len < n * 4)
2833*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2834*5113495bSYour Name 
2835*5113495bSYour Name 		for (; n > 0; n--) {
2836*5113495bSYour Name 			w = wlan_crypto_rsn_suite_to_cipher(frm);
2837*5113495bSYour Name 			if (w >= 0)
2838*5113495bSYour Name 				SET_UCAST_CIPHER(crypto_params, w);
2839*5113495bSYour Name 			frm += 4, len -= 4;
2840*5113495bSYour Name 		}
2841*5113495bSYour Name 	} else {
2842*5113495bSYour Name 		/* default ucast cipher CCMP-128 */
2843*5113495bSYour Name 		SET_UCAST_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CCM);
2844*5113495bSYour Name 	}
2845*5113495bSYour Name 
2846*5113495bSYour Name 	if (crypto_params->ucastcipherset == 0)
2847*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2848*5113495bSYour Name 
2849*5113495bSYour Name 	if (!len) {
2850*5113495bSYour Name 		/* default key mgmt 8021x */
2851*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2852*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2853*5113495bSYour Name 	} else if (len < 2) {
2854*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2855*5113495bSYour Name 	}
2856*5113495bSYour Name 
2857*5113495bSYour Name 	/* key management algorithms */
2858*5113495bSYour Name 	n = LE_READ_2(frm);
2859*5113495bSYour Name 	frm += 2, len -= 2;
2860*5113495bSYour Name 
2861*5113495bSYour Name 	if (n) {
2862*5113495bSYour Name 		if (len < n * 4)
2863*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2864*5113495bSYour Name 		akm_index = 0;
2865*5113495bSYour Name 		for (; n > 0; n--) {
2866*5113495bSYour Name 			w = wlan_crypto_rsn_suite_to_keymgmt(frm);
2867*5113495bSYour Name 			if (w >= 0) {
2868*5113495bSYour Name 				SET_KEY_MGMT(crypto_params, w);
2869*5113495bSYour Name 				wlan_crypto_store_akm_list_in_order(
2870*5113495bSYour Name 						crypto_params, w, akm_index);
2871*5113495bSYour Name 				akm_index++;
2872*5113495bSYour Name 			}
2873*5113495bSYour Name 
2874*5113495bSYour Name 			frm += 4, len -= 4;
2875*5113495bSYour Name 		}
2876*5113495bSYour Name 	} else {
2877*5113495bSYour Name 		/* default key mgmt 8021x */
2878*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2879*5113495bSYour Name 	}
2880*5113495bSYour Name 
2881*5113495bSYour Name 	if (crypto_params->key_mgmt == 0)
2882*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2883*5113495bSYour Name 
2884*5113495bSYour Name 	/* optional capabilities */
2885*5113495bSYour Name 	if (len >= 2) {
2886*5113495bSYour Name 		crypto_params->rsn_caps = LE_READ_2(frm);
2887*5113495bSYour Name 		frm += 2, len -= 2;
2888*5113495bSYour Name 	} else if (len && len < 2) {
2889*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2890*5113495bSYour Name 	}
2891*5113495bSYour Name 
2892*5113495bSYour Name 
2893*5113495bSYour Name 	/* PMKID */
2894*5113495bSYour Name 	if (len >= 2) {
2895*5113495bSYour Name 		n = LE_READ_2(frm);
2896*5113495bSYour Name 		frm += 2, len -= 2;
2897*5113495bSYour Name 		if (n && len) {
2898*5113495bSYour Name 			if (len >= n * PMKID_LEN)
2899*5113495bSYour Name 				frm += (n * PMKID_LEN), len -= (n * PMKID_LEN);
2900*5113495bSYour Name 			else
2901*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
2902*5113495bSYour Name 		} else if (n && !len) {
2903*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2904*5113495bSYour Name 		}
2905*5113495bSYour Name 		/*TODO: Save pmkid in params for further reference */
2906*5113495bSYour Name 	} else if (len == 1) {
2907*5113495bSYour Name 		crypto_err("PMKID is truncated");
2908*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2909*5113495bSYour Name 	}
2910*5113495bSYour Name 
2911*5113495bSYour Name 	/* BIP */
2912*5113495bSYour Name 	if (!len) {
2913*5113495bSYour Name 		/* when no BIP mentioned and MFP capable use CMAC as default*/
2914*5113495bSYour Name 		if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)
2915*5113495bSYour Name 			SET_MGMT_CIPHER(crypto_params,
2916*5113495bSYour Name 					WLAN_CRYPTO_CIPHER_AES_CMAC);
2917*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2918*5113495bSYour Name 	} else if (len < 4) {
2919*5113495bSYour Name 		crypto_err("Mgmt cipher is truncated");
2920*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2921*5113495bSYour Name 	}
2922*5113495bSYour Name 	w = wlan_crypto_rsn_suite_to_cipher(frm);
2923*5113495bSYour Name 	frm += 4, len -= 4;
2924*5113495bSYour Name 	SET_MGMT_CIPHER(crypto_params, w);
2925*5113495bSYour Name 
2926*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2927*5113495bSYour Name }
2928*5113495bSYour Name 
wlan_crypto_build_wpaie(struct wlan_objmgr_vdev * vdev,uint8_t * iebuf)2929*5113495bSYour Name uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev,
2930*5113495bSYour Name 					uint8_t *iebuf)
2931*5113495bSYour Name {
2932*5113495bSYour Name 	uint8_t *frm = iebuf;
2933*5113495bSYour Name 	uint8_t *selcnt;
2934*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
2935*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
2936*5113495bSYour Name 
2937*5113495bSYour Name 	if (!frm)
2938*5113495bSYour Name 		return NULL;
2939*5113495bSYour Name 
2940*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
2941*5113495bSYour Name 
2942*5113495bSYour Name 	if (!crypto_params)
2943*5113495bSYour Name 		return NULL;
2944*5113495bSYour Name 
2945*5113495bSYour Name 	*frm++ = WLAN_ELEMID_VENDOR;
2946*5113495bSYour Name 	*frm++ = 0;
2947*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm, WPA_TYPE_OUI);
2948*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, WPA_VERSION);
2949*5113495bSYour Name 
2950*5113495bSYour Name 
2951*5113495bSYour Name 	/* multicast cipher */
2952*5113495bSYour Name 	if (MCIPHER_IS_TKIP(crypto_params))
2953*5113495bSYour Name 		WPA_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_TKIP);
2954*5113495bSYour Name 	else if (MCIPHER_IS_CCMP128(crypto_params))
2955*5113495bSYour Name 		WPA_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM);
2956*5113495bSYour Name 
2957*5113495bSYour Name 	/* unicast cipher list */
2958*5113495bSYour Name 	selcnt = frm;
2959*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2960*5113495bSYour Name 	/* do not use CCMP unicast cipher in WPA mode */
2961*5113495bSYour Name 	if (UCIPHER_IS_CCMP128(crypto_params)) {
2962*5113495bSYour Name 		selcnt[0]++;
2963*5113495bSYour Name 		WPA_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM);
2964*5113495bSYour Name 	}
2965*5113495bSYour Name 	if (UCIPHER_IS_TKIP(crypto_params)) {
2966*5113495bSYour Name 		selcnt[0]++;
2967*5113495bSYour Name 		WPA_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_TKIP);
2968*5113495bSYour Name 	}
2969*5113495bSYour Name 
2970*5113495bSYour Name 	/* authenticator selector list */
2971*5113495bSYour Name 	selcnt = frm;
2972*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
2973*5113495bSYour Name 
2974*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
2975*5113495bSYour Name 		selcnt[0]++;
2976*5113495bSYour Name 		WPA_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
2977*5113495bSYour Name 	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
2978*5113495bSYour Name 		selcnt[0]++;
2979*5113495bSYour Name 		WPA_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_PSK);
2980*5113495bSYour Name 	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
2981*5113495bSYour Name 		selcnt[0]++;
2982*5113495bSYour Name 		WPA_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_CCKM);
2983*5113495bSYour Name 	} else {
2984*5113495bSYour Name 		selcnt[0]++;
2985*5113495bSYour Name 		WPA_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_NONE);
2986*5113495bSYour Name 	}
2987*5113495bSYour Name 
2988*5113495bSYour Name 	/* optional capabilities */
2989*5113495bSYour Name 	if (crypto_params->rsn_caps != 0 &&
2990*5113495bSYour Name 	    crypto_params->rsn_caps != WLAN_CRYPTO_RSN_CAP_PREAUTH) {
2991*5113495bSYour Name 		WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
2992*5113495bSYour Name 	}
2993*5113495bSYour Name 
2994*5113495bSYour Name 	/* calculate element length */
2995*5113495bSYour Name 	iebuf[1] = frm - iebuf - 2;
2996*5113495bSYour Name 
2997*5113495bSYour Name 	return frm;
2998*5113495bSYour Name }
2999*5113495bSYour Name 
wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev * vdev,uint8_t * iebuf,struct wlan_crypto_pmksa * pmksa)3000*5113495bSYour Name uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev,
3001*5113495bSYour Name 					    uint8_t *iebuf,
3002*5113495bSYour Name 					    struct wlan_crypto_pmksa *pmksa)
3003*5113495bSYour Name {
3004*5113495bSYour Name 	uint8_t *frm = iebuf;
3005*5113495bSYour Name 	uint8_t *selcnt;
3006*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3007*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
3008*5113495bSYour Name 
3009*5113495bSYour Name 	if (!frm) {
3010*5113495bSYour Name 		return NULL;
3011*5113495bSYour Name 	}
3012*5113495bSYour Name 
3013*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
3014*5113495bSYour Name 
3015*5113495bSYour Name 	if (!crypto_params) {
3016*5113495bSYour Name 		return NULL;
3017*5113495bSYour Name 	}
3018*5113495bSYour Name 
3019*5113495bSYour Name 	*frm++ = WLAN_ELEMID_RSN;
3020*5113495bSYour Name 	*frm++ = 0;
3021*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, RSN_VERSION);
3022*5113495bSYour Name 
3023*5113495bSYour Name 
3024*5113495bSYour Name 	/* multicast cipher */
3025*5113495bSYour Name 	if (MCIPHER_IS_TKIP(crypto_params))
3026*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_TKIP);
3027*5113495bSYour Name 	else if (MCIPHER_IS_CCMP128(crypto_params))
3028*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM);
3029*5113495bSYour Name 	else if (MCIPHER_IS_CCMP256(crypto_params))
3030*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM_256);
3031*5113495bSYour Name 	else if (MCIPHER_IS_GCMP128(crypto_params))
3032*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_GCM);
3033*5113495bSYour Name 	else if (MCIPHER_IS_GCMP256(crypto_params))
3034*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_GCM_256);
3035*5113495bSYour Name 
3036*5113495bSYour Name 	/* unicast cipher list */
3037*5113495bSYour Name 	selcnt = frm;
3038*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
3039*5113495bSYour Name 
3040*5113495bSYour Name 	if (UCIPHER_IS_CCMP256(crypto_params)) {
3041*5113495bSYour Name 		selcnt[0]++;
3042*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM_256);
3043*5113495bSYour Name 	}
3044*5113495bSYour Name 	if (UCIPHER_IS_GCMP256(crypto_params)) {
3045*5113495bSYour Name 		selcnt[0]++;
3046*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_GCM_256);
3047*5113495bSYour Name 	}
3048*5113495bSYour Name 	if (UCIPHER_IS_CCMP128(crypto_params)) {
3049*5113495bSYour Name 		selcnt[0]++;
3050*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_CCM);
3051*5113495bSYour Name 	}
3052*5113495bSYour Name 	if (UCIPHER_IS_GCMP128(crypto_params)) {
3053*5113495bSYour Name 		selcnt[0]++;
3054*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_AES_GCM);
3055*5113495bSYour Name 	}
3056*5113495bSYour Name 	if (UCIPHER_IS_TKIP(crypto_params)) {
3057*5113495bSYour Name 		selcnt[0]++;
3058*5113495bSYour Name 		RSN_ADD_CIPHER_TO_SUITE(frm, WLAN_CRYPTO_CIPHER_TKIP);
3059*5113495bSYour Name 	}
3060*5113495bSYour Name 
3061*5113495bSYour Name 	/* authenticator selector list */
3062*5113495bSYour Name 	selcnt = frm;
3063*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
3064*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
3065*5113495bSYour Name 		selcnt[0]++;
3066*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_CCKM);
3067*5113495bSYour Name 		/* Other key mgmt should not be added after CCKM */
3068*5113495bSYour Name 		goto add_rsn_caps;
3069*5113495bSYour Name 	}
3070*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
3071*5113495bSYour Name 		selcnt[0]++;
3072*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X);
3073*5113495bSYour Name 	}
3074*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
3075*5113495bSYour Name 		selcnt[0]++;
3076*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_PSK);
3077*5113495bSYour Name 	}
3078*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X)) {
3079*5113495bSYour Name 		selcnt[0]++;
3080*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm,
3081*5113495bSYour Name 					 WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X);
3082*5113495bSYour Name 	}
3083*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_PSK)) {
3084*5113495bSYour Name 		selcnt[0]++;
3085*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_FT_PSK);
3086*5113495bSYour Name 	}
3087*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params,
3088*5113495bSYour Name 			 WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) {
3089*5113495bSYour Name 		selcnt[0]++;
3090*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm,
3091*5113495bSYour Name 					 WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256);
3092*5113495bSYour Name 	}
3093*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) {
3094*5113495bSYour Name 		selcnt[0]++;
3095*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256);
3096*5113495bSYour Name 	}
3097*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_SAE)) {
3098*5113495bSYour Name 		selcnt[0]++;
3099*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_SAE);
3100*5113495bSYour Name 	}
3101*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_SAE)) {
3102*5113495bSYour Name 		selcnt[0]++;
3103*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_FT_SAE);
3104*5113495bSYour Name 	}
3105*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params,
3106*5113495bSYour Name 			 WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B)) {
3107*5113495bSYour Name 		uint32_t kmgmt = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B;
3108*5113495bSYour Name 
3109*5113495bSYour Name 		selcnt[0]++;
3110*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, kmgmt);
3111*5113495bSYour Name 	}
3112*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params,
3113*5113495bSYour Name 			 WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192)) {
3114*5113495bSYour Name 		uint32_t kmgmt =  WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192;
3115*5113495bSYour Name 
3116*5113495bSYour Name 		selcnt[0]++;
3117*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, kmgmt);
3118*5113495bSYour Name 	}
3119*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256)) {
3120*5113495bSYour Name 		selcnt[0]++;
3121*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256);
3122*5113495bSYour Name 	}
3123*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params,	WLAN_CRYPTO_KEY_MGMT_FILS_SHA384)) {
3124*5113495bSYour Name 		selcnt[0]++;
3125*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384);
3126*5113495bSYour Name 	}
3127*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256)) {
3128*5113495bSYour Name 		selcnt[0]++;
3129*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm,
3130*5113495bSYour Name 					 WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256);
3131*5113495bSYour Name 	}
3132*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384)) {
3133*5113495bSYour Name 		selcnt[0]++;
3134*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm,
3135*5113495bSYour Name 					 WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384);
3136*5113495bSYour Name 	}
3137*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_OWE)) {
3138*5113495bSYour Name 		selcnt[0]++;
3139*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_OWE);
3140*5113495bSYour Name 	}
3141*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_DPP)) {
3142*5113495bSYour Name 		selcnt[0]++;
3143*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_DPP);
3144*5113495bSYour Name 	}
3145*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_OSEN)) {
3146*5113495bSYour Name 		selcnt[0]++;
3147*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_OSEN);
3148*5113495bSYour Name 	}
3149*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY)) {
3150*5113495bSYour Name 		selcnt[0]++;
3151*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY);
3152*5113495bSYour Name 	}
3153*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params,
3154*5113495bSYour Name 			 WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) {
3155*5113495bSYour Name 		uint32_t kmgmt = WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384;
3156*5113495bSYour Name 
3157*5113495bSYour Name 		selcnt[0]++;
3158*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm, kmgmt);
3159*5113495bSYour Name 	}
3160*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) {
3161*5113495bSYour Name 		selcnt[0]++;
3162*5113495bSYour Name 		RSN_ADD_KEYMGMT_TO_SUITE(frm,
3163*5113495bSYour Name 					 WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY);
3164*5113495bSYour Name 	}
3165*5113495bSYour Name add_rsn_caps:
3166*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
3167*5113495bSYour Name 	/* optional capabilities */
3168*5113495bSYour Name 	if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) {
3169*5113495bSYour Name 		/* PMK list */
3170*5113495bSYour Name 		if (pmksa) {
3171*5113495bSYour Name 			WLAN_CRYPTO_ADDSHORT(frm, 1);
3172*5113495bSYour Name 			qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
3173*5113495bSYour Name 			frm += PMKID_LEN;
3174*5113495bSYour Name 		} else {
3175*5113495bSYour Name 			WLAN_CRYPTO_ADDSHORT(frm, 0);
3176*5113495bSYour Name 		}
3177*5113495bSYour Name 
3178*5113495bSYour Name 		if (HAS_MGMT_CIPHER(crypto_params,
3179*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_CMAC)) {
3180*5113495bSYour Name 			RSN_ADD_CIPHER_TO_SUITE(frm,
3181*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_CMAC);
3182*5113495bSYour Name 		}
3183*5113495bSYour Name 		if (HAS_MGMT_CIPHER(crypto_params,
3184*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_GMAC)) {
3185*5113495bSYour Name 			RSN_ADD_CIPHER_TO_SUITE(frm,
3186*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_GMAC);
3187*5113495bSYour Name 		}
3188*5113495bSYour Name 		if (HAS_MGMT_CIPHER(crypto_params,
3189*5113495bSYour Name 					 WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
3190*5113495bSYour Name 			RSN_ADD_CIPHER_TO_SUITE(frm,
3191*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_CMAC_256
3192*5113495bSYour Name 						);
3193*5113495bSYour Name 		}
3194*5113495bSYour Name 
3195*5113495bSYour Name 		if (HAS_MGMT_CIPHER(crypto_params,
3196*5113495bSYour Name 					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
3197*5113495bSYour Name 			RSN_ADD_CIPHER_TO_SUITE(frm,
3198*5113495bSYour Name 						WLAN_CRYPTO_CIPHER_AES_GMAC_256
3199*5113495bSYour Name 						);
3200*5113495bSYour Name 		}
3201*5113495bSYour Name 	} else {
3202*5113495bSYour Name 		/* PMK list */
3203*5113495bSYour Name 		if (pmksa) {
3204*5113495bSYour Name 			WLAN_CRYPTO_ADDSHORT(frm, 1);
3205*5113495bSYour Name 			qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
3206*5113495bSYour Name 			frm += PMKID_LEN;
3207*5113495bSYour Name 		}
3208*5113495bSYour Name 	}
3209*5113495bSYour Name 
3210*5113495bSYour Name 	/* calculate element length */
3211*5113495bSYour Name 	iebuf[1] = frm - iebuf - 2;
3212*5113495bSYour Name 
3213*5113495bSYour Name 	return frm;
3214*5113495bSYour Name }
3215*5113495bSYour Name 
wlan_crypto_build_rsnie(struct wlan_objmgr_vdev * vdev,uint8_t * iebuf,struct qdf_mac_addr * bssid)3216*5113495bSYour Name uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
3217*5113495bSYour Name 				 uint8_t *iebuf,
3218*5113495bSYour Name 				 struct qdf_mac_addr *bssid)
3219*5113495bSYour Name {
3220*5113495bSYour Name 	struct wlan_crypto_pmksa *pmksa = NULL;
3221*5113495bSYour Name 
3222*5113495bSYour Name 	if (bssid)
3223*5113495bSYour Name 		pmksa = wlan_crypto_get_pmksa(vdev, bssid);
3224*5113495bSYour Name 
3225*5113495bSYour Name 	return wlan_crypto_build_rsnie_with_pmksa(vdev, iebuf, pmksa);
3226*5113495bSYour Name }
3227*5113495bSYour Name 
wlan_crypto_rsn_info(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_params * crypto_params)3228*5113495bSYour Name bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
3229*5113495bSYour Name 				struct wlan_crypto_params *crypto_params)
3230*5113495bSYour Name {
3231*5113495bSYour Name 	struct wlan_crypto_params *my_crypto_params;
3232*5113495bSYour Name 	my_crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
3233*5113495bSYour Name 
3234*5113495bSYour Name 	if (!my_crypto_params) {
3235*5113495bSYour Name 		crypto_debug("vdev crypto params is NULL");
3236*5113495bSYour Name 		return false;
3237*5113495bSYour Name 	}
3238*5113495bSYour Name 	/*
3239*5113495bSYour Name 	 * Check peer's pairwise ciphers.
3240*5113495bSYour Name 	 * At least one must match with our unicast cipher
3241*5113495bSYour Name 	 */
3242*5113495bSYour Name 	if (!UCAST_CIPHER_MATCH(crypto_params, my_crypto_params)) {
3243*5113495bSYour Name 		crypto_debug("Unicast cipher match failed");
3244*5113495bSYour Name 		return false;
3245*5113495bSYour Name 	}
3246*5113495bSYour Name 	/*
3247*5113495bSYour Name 	 * Check peer's group cipher is our enabled multicast cipher.
3248*5113495bSYour Name 	 */
3249*5113495bSYour Name 	if (!MCAST_CIPHER_MATCH(crypto_params, my_crypto_params)) {
3250*5113495bSYour Name 		crypto_debug("Multicast cipher match failed");
3251*5113495bSYour Name 		return false;
3252*5113495bSYour Name 	}
3253*5113495bSYour Name 	/*
3254*5113495bSYour Name 	 * Check peer's key management class set (PSK or UNSPEC)
3255*5113495bSYour Name 	 */
3256*5113495bSYour Name 	if (!KEY_MGMTSET_MATCH(crypto_params, my_crypto_params)) {
3257*5113495bSYour Name 		crypto_debug("Key mgmt match failed");
3258*5113495bSYour Name 		return false;
3259*5113495bSYour Name 	}
3260*5113495bSYour Name 	if (wlan_crypto_vdev_is_pmf_required(vdev) &&
3261*5113495bSYour Name 	    !(crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) {
3262*5113495bSYour Name 		crypto_debug("Peer is not PMF capable");
3263*5113495bSYour Name 		return false;
3264*5113495bSYour Name 	}
3265*5113495bSYour Name 	if (!wlan_crypto_vdev_is_pmf_enabled(vdev) &&
3266*5113495bSYour Name 	    (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
3267*5113495bSYour Name 		crypto_debug("Peer needs PMF, but vdev is not capable");
3268*5113495bSYour Name 		return false;
3269*5113495bSYour Name 	}
3270*5113495bSYour Name 
3271*5113495bSYour Name 	return true;
3272*5113495bSYour Name }
3273*5113495bSYour Name 
3274*5113495bSYour Name /*
3275*5113495bSYour Name  * Convert an WAPI CIPHER suite to to an internal code.
3276*5113495bSYour Name  */
wlan_crypto_wapi_suite_to_cipher(const uint8_t * sel)3277*5113495bSYour Name static int32_t wlan_crypto_wapi_suite_to_cipher(const uint8_t *sel)
3278*5113495bSYour Name {
3279*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
3280*5113495bSYour Name 	int32_t status = -1;
3281*5113495bSYour Name 
3282*5113495bSYour Name 	switch (w) {
3283*5113495bSYour Name 	case (WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER)):
3284*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_WAPI_SMS4;
3285*5113495bSYour Name 	}
3286*5113495bSYour Name 
3287*5113495bSYour Name 	return status;
3288*5113495bSYour Name }
3289*5113495bSYour Name 
3290*5113495bSYour Name /*
3291*5113495bSYour Name  * Convert an WAPI key management/authentication algorithm
3292*5113495bSYour Name  * to an internal code.
3293*5113495bSYour Name  */
wlan_crypto_wapi_keymgmt(const u_int8_t * sel)3294*5113495bSYour Name static int32_t wlan_crypto_wapi_keymgmt(const u_int8_t *sel)
3295*5113495bSYour Name {
3296*5113495bSYour Name 	uint32_t w = LE_READ_4(sel);
3297*5113495bSYour Name 	int32_t status = -1;
3298*5113495bSYour Name 
3299*5113495bSYour Name 	switch (w) {
3300*5113495bSYour Name 	case (WLAN_WAPI_SEL(WLAN_WAI_PSK)):
3301*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WAPI_PSK;
3302*5113495bSYour Name 	case (WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4)):
3303*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WAPI_CERT;
3304*5113495bSYour Name 	}
3305*5113495bSYour Name 
3306*5113495bSYour Name 	return status;
3307*5113495bSYour Name }
3308*5113495bSYour Name 
wlan_crypto_wapiie_check(struct wlan_crypto_params * crypto_params,const uint8_t * frm)3309*5113495bSYour Name QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
3310*5113495bSYour Name 				    const uint8_t *frm)
3311*5113495bSYour Name {
3312*5113495bSYour Name 	uint8_t len = frm[1];
3313*5113495bSYour Name 	int32_t w;
3314*5113495bSYour Name 	int n;
3315*5113495bSYour Name 
3316*5113495bSYour Name 	/*
3317*5113495bSYour Name 	 * Check the length once for fixed parts: OUI, type,
3318*5113495bSYour Name 	 * version, mcast cipher, and 2 selector counts.
3319*5113495bSYour Name 	 * Other, variable-length data, must be checked separately.
3320*5113495bSYour Name 	 */
3321*5113495bSYour Name 	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WAPI);
3322*5113495bSYour Name 
3323*5113495bSYour Name 	if (len < WLAN_CRYPTO_WAPI_IE_LEN)
3324*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3325*5113495bSYour Name 
3326*5113495bSYour Name 
3327*5113495bSYour Name 	frm += 2;
3328*5113495bSYour Name 
3329*5113495bSYour Name 	w = LE_READ_2(frm);
3330*5113495bSYour Name 	frm += 2, len -= 2;
3331*5113495bSYour Name 	if (w != WAPI_VERSION)
3332*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3333*5113495bSYour Name 
3334*5113495bSYour Name 	n = LE_READ_2(frm);
3335*5113495bSYour Name 	frm += 2, len -= 2;
3336*5113495bSYour Name 	if (len < n*4+2)
3337*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3338*5113495bSYour Name 
3339*5113495bSYour Name 	for (; n > 0; n--) {
3340*5113495bSYour Name 		w = wlan_crypto_wapi_keymgmt(frm);
3341*5113495bSYour Name 		if (w < 0)
3342*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
3343*5113495bSYour Name 
3344*5113495bSYour Name 		SET_KEY_MGMT(crypto_params, w);
3345*5113495bSYour Name 		frm += 4, len -= 4;
3346*5113495bSYour Name 	}
3347*5113495bSYour Name 
3348*5113495bSYour Name 	/* unicast ciphers */
3349*5113495bSYour Name 	n = LE_READ_2(frm);
3350*5113495bSYour Name 	frm += 2, len -= 2;
3351*5113495bSYour Name 	if (len < n*4+2)
3352*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3353*5113495bSYour Name 
3354*5113495bSYour Name 	for (; n > 0; n--) {
3355*5113495bSYour Name 		w = wlan_crypto_wapi_suite_to_cipher(frm);
3356*5113495bSYour Name 		if (w < 0)
3357*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
3358*5113495bSYour Name 		SET_UCAST_CIPHER(crypto_params, w);
3359*5113495bSYour Name 		frm += 4, len -= 4;
3360*5113495bSYour Name 	}
3361*5113495bSYour Name 
3362*5113495bSYour Name 	if (!crypto_params->ucastcipherset)
3363*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3364*5113495bSYour Name 
3365*5113495bSYour Name 	/* multicast/group cipher */
3366*5113495bSYour Name 	w = wlan_crypto_wapi_suite_to_cipher(frm);
3367*5113495bSYour Name 
3368*5113495bSYour Name 	if (w < 0)
3369*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3370*5113495bSYour Name 
3371*5113495bSYour Name 	SET_MCAST_CIPHER(crypto_params, w);
3372*5113495bSYour Name 	frm += 4, len -= 4;
3373*5113495bSYour Name 
3374*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3375*5113495bSYour Name }
3376*5113495bSYour Name 
wlan_crypto_build_wapiie(struct wlan_objmgr_vdev * vdev,uint8_t * iebuf)3377*5113495bSYour Name uint8_t *wlan_crypto_build_wapiie(struct wlan_objmgr_vdev *vdev,
3378*5113495bSYour Name 				uint8_t *iebuf)
3379*5113495bSYour Name {
3380*5113495bSYour Name 	uint8_t *frm;
3381*5113495bSYour Name 	uint8_t *selcnt;
3382*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3383*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
3384*5113495bSYour Name 
3385*5113495bSYour Name 	frm = iebuf;
3386*5113495bSYour Name 	if (!frm) {
3387*5113495bSYour Name 		crypto_err("ie buffer NULL");
3388*5113495bSYour Name 		return NULL;
3389*5113495bSYour Name 	}
3390*5113495bSYour Name 
3391*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
3392*5113495bSYour Name 
3393*5113495bSYour Name 	if (!crypto_params) {
3394*5113495bSYour Name 		crypto_err("crypto_params NULL");
3395*5113495bSYour Name 		return NULL;
3396*5113495bSYour Name 	}
3397*5113495bSYour Name 
3398*5113495bSYour Name 	*frm++ = WLAN_ELEMID_WAPI;
3399*5113495bSYour Name 	*frm++ = 0;
3400*5113495bSYour Name 
3401*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, WAPI_VERSION);
3402*5113495bSYour Name 
3403*5113495bSYour Name 	/* authenticator selector list */
3404*5113495bSYour Name 	selcnt = frm;
3405*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
3406*5113495bSYour Name 
3407*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK)) {
3408*5113495bSYour Name 		selcnt[0]++;
3409*5113495bSYour Name 		WLAN_CRYPTO_ADDSELECTOR(frm,
3410*5113495bSYour Name 				WLAN_WAPI_SEL(WLAN_WAI_PSK));
3411*5113495bSYour Name 	}
3412*5113495bSYour Name 
3413*5113495bSYour Name 	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT)) {
3414*5113495bSYour Name 		selcnt[0]++;
3415*5113495bSYour Name 		WLAN_CRYPTO_ADDSELECTOR(frm,
3416*5113495bSYour Name 				WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4));
3417*5113495bSYour Name 	}
3418*5113495bSYour Name 
3419*5113495bSYour Name 	/* unicast cipher list */
3420*5113495bSYour Name 	selcnt = frm;
3421*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, 0);
3422*5113495bSYour Name 
3423*5113495bSYour Name 	if (UCIPHER_IS_SMS4(crypto_params)) {
3424*5113495bSYour Name 		selcnt[0]++;
3425*5113495bSYour Name 		WLAN_CRYPTO_ADDSELECTOR(frm,
3426*5113495bSYour Name 				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
3427*5113495bSYour Name 	}
3428*5113495bSYour Name 
3429*5113495bSYour Name 	WLAN_CRYPTO_ADDSELECTOR(frm,
3430*5113495bSYour Name 				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
3431*5113495bSYour Name 
3432*5113495bSYour Name 	/* optional capabilities */
3433*5113495bSYour Name 	WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
3434*5113495bSYour Name 
3435*5113495bSYour Name 	/* bkid count */
3436*5113495bSYour Name 	if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE ||
3437*5113495bSYour Name 	    vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE)
3438*5113495bSYour Name 		WLAN_CRYPTO_ADDSHORT(frm, 0);
3439*5113495bSYour Name 
3440*5113495bSYour Name 	/* calculate element length */
3441*5113495bSYour Name 	iebuf[1] = frm - iebuf - 2;
3442*5113495bSYour Name 
3443*5113495bSYour Name 	return frm;
3444*5113495bSYour Name 
3445*5113495bSYour Name }
3446*5113495bSYour Name 
wlan_crypto_pn_check(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf)3447*5113495bSYour Name QDF_STATUS wlan_crypto_pn_check(struct wlan_objmgr_vdev *vdev,
3448*5113495bSYour Name 				qdf_nbuf_t wbuf)
3449*5113495bSYour Name {
3450*5113495bSYour Name 	/* Need to check is there real requirement for this function
3451*5113495bSYour Name 	 * as PN check is already handled in decap function.
3452*5113495bSYour Name 	 */
3453*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3454*5113495bSYour Name }
3455*5113495bSYour Name 
wlan_crypto_vdev_get_crypto_params(struct wlan_objmgr_vdev * vdev)3456*5113495bSYour Name struct wlan_crypto_params *wlan_crypto_vdev_get_crypto_params(
3457*5113495bSYour Name 						struct wlan_objmgr_vdev *vdev)
3458*5113495bSYour Name {
3459*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3460*5113495bSYour Name 
3461*5113495bSYour Name 	return wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
3462*5113495bSYour Name }
3463*5113495bSYour Name 
wlan_crypto_peer_get_crypto_params(struct wlan_objmgr_peer * peer)3464*5113495bSYour Name struct wlan_crypto_params *wlan_crypto_peer_get_crypto_params(
3465*5113495bSYour Name 						struct wlan_objmgr_peer *peer)
3466*5113495bSYour Name {
3467*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3468*5113495bSYour Name 
3469*5113495bSYour Name 	return wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
3470*5113495bSYour Name }
3471*5113495bSYour Name 
3472*5113495bSYour Name 
wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)3473*5113495bSYour Name QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev,
3474*5113495bSYour Name 					struct wlan_objmgr_peer *peer)
3475*5113495bSYour Name {
3476*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3477*5113495bSYour Name 	struct wlan_crypto_comp_priv *sta_crypto_priv;
3478*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
3479*5113495bSYour Name 	struct wlan_crypto_key *key;
3480*5113495bSYour Name 	struct wlan_crypto_key *sta_key;
3481*5113495bSYour Name 	struct wlan_crypto_keys *sta_priv = NULL;
3482*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
3483*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
3484*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
3485*5113495bSYour Name 	uint8_t *mac_addr;
3486*5113495bSYour Name 	int i;
3487*5113495bSYour Name 	enum QDF_OPMODE opmode;
3488*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3489*5113495bSYour Name 
3490*5113495bSYour Name 	if (!vdev)
3491*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3492*5113495bSYour Name 
3493*5113495bSYour Name 	if (!peer) {
3494*5113495bSYour Name 		crypto_debug("peer NULL");
3495*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3496*5113495bSYour Name 	}
3497*5113495bSYour Name 
3498*5113495bSYour Name 	opmode = wlan_vdev_mlme_get_opmode(vdev);
3499*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
3500*5113495bSYour Name 
3501*5113495bSYour Name 	if (!psoc) {
3502*5113495bSYour Name 		crypto_err("psoc NULL");
3503*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3504*5113495bSYour Name 	}
3505*5113495bSYour Name 
3506*5113495bSYour Name 	wlan_peer_obj_lock(peer);
3507*5113495bSYour Name 	mac_addr = wlan_peer_get_macaddr(peer);
3508*5113495bSYour Name 	wlan_peer_obj_unlock(peer);
3509*5113495bSYour Name 
3510*5113495bSYour Name 	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
3511*5113495bSYour Name 							&crypto_priv);
3512*5113495bSYour Name 	if (!crypto_priv) {
3513*5113495bSYour Name 		crypto_err("crypto_priv NULL");
3514*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3515*5113495bSYour Name 	}
3516*5113495bSYour Name 
3517*5113495bSYour Name 	/* push only valid static WEP keys from vap */
3518*5113495bSYour Name 	if (AUTH_IS_8021X(crypto_params))
3519*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3520*5113495bSYour Name 
3521*5113495bSYour Name 	if (opmode == QDF_STA_MODE) {
3522*5113495bSYour Name 		peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_CRYPTO_ID);
3523*5113495bSYour Name 		if (!peer) {
3524*5113495bSYour Name 			crypto_debug("peer NULL");
3525*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
3526*5113495bSYour Name 		}
3527*5113495bSYour Name 	}
3528*5113495bSYour Name 
3529*5113495bSYour Name 	wlan_crypto_peer_get_comp_params(peer, &sta_crypto_priv);
3530*5113495bSYour Name 	if (!sta_crypto_priv) {
3531*5113495bSYour Name 		crypto_err("sta priv is null");
3532*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
3533*5113495bSYour Name 		goto exit;
3534*5113495bSYour Name 	}
3535*5113495bSYour Name 
3536*5113495bSYour Name 	sta_priv = &sta_crypto_priv->crypto_key;
3537*5113495bSYour Name 
3538*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
3539*5113495bSYour Name 		if (crypto_priv->crypto_key.key[i]) {
3540*5113495bSYour Name 			key = crypto_priv->crypto_key.key[i];
3541*5113495bSYour Name 			if (!key || !key->valid)
3542*5113495bSYour Name 				continue;
3543*5113495bSYour Name 
3544*5113495bSYour Name 			cipher_table = (struct wlan_crypto_cipher *)
3545*5113495bSYour Name 							key->cipher_table;
3546*5113495bSYour Name 
3547*5113495bSYour Name 			if (!cipher_table)
3548*5113495bSYour Name 				continue;
3549*5113495bSYour Name 			if (cipher_table->cipher == WLAN_CRYPTO_CIPHER_WEP) {
3550*5113495bSYour Name 				tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
3551*5113495bSYour Name 				if (!tx_ops) {
3552*5113495bSYour Name 					crypto_err("tx_ops is NULL");
3553*5113495bSYour Name 					return QDF_STATUS_E_INVAL;
3554*5113495bSYour Name 				}
3555*5113495bSYour Name 
3556*5113495bSYour Name 				sta_key = qdf_mem_malloc(
3557*5113495bSYour Name 						sizeof(struct wlan_crypto_key));
3558*5113495bSYour Name 				if (!sta_key) {
3559*5113495bSYour Name 					status = QDF_STATUS_E_NOMEM;
3560*5113495bSYour Name 					goto exit;
3561*5113495bSYour Name 				}
3562*5113495bSYour Name 
3563*5113495bSYour Name 				sta_priv->key[i] = sta_key;
3564*5113495bSYour Name 				qdf_mem_copy(sta_key, key,
3565*5113495bSYour Name 						sizeof(struct wlan_crypto_key));
3566*5113495bSYour Name 
3567*5113495bSYour Name 				sta_key->flags &= ~WLAN_CRYPTO_KEY_DEFAULT;
3568*5113495bSYour Name 
3569*5113495bSYour Name 				if (crypto_priv->crypto_key.def_tx_keyid == i) {
3570*5113495bSYour Name 					sta_key->flags
3571*5113495bSYour Name 						|= WLAN_CRYPTO_KEY_DEFAULT;
3572*5113495bSYour Name 					sta_priv->def_tx_keyid =
3573*5113495bSYour Name 					crypto_priv->crypto_key.def_tx_keyid;
3574*5113495bSYour Name 				}
3575*5113495bSYour Name 				/* setting the broadcast/multicast key for sta*/
3576*5113495bSYour Name 				if (opmode == QDF_STA_MODE ||
3577*5113495bSYour Name 						opmode == QDF_IBSS_MODE){
3578*5113495bSYour Name 					if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
3579*5113495bSYour Name 						WLAN_CRYPTO_TX_OPS_SETKEY(
3580*5113495bSYour Name 							tx_ops)(vdev, sta_key,
3581*5113495bSYour Name 							mac_addr,
3582*5113495bSYour Name 							cipher_table->cipher);
3583*5113495bSYour Name 					}
3584*5113495bSYour Name 				}
3585*5113495bSYour Name 
3586*5113495bSYour Name 				/* setting unicast key */
3587*5113495bSYour Name 				sta_key->flags &= ~WLAN_CRYPTO_KEY_GROUP;
3588*5113495bSYour Name 				if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
3589*5113495bSYour Name 					WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)(
3590*5113495bSYour Name 							vdev, sta_key,
3591*5113495bSYour Name 							mac_addr,
3592*5113495bSYour Name 							cipher_table->cipher);
3593*5113495bSYour Name 				}
3594*5113495bSYour Name 			}
3595*5113495bSYour Name 		}
3596*5113495bSYour Name 	}
3597*5113495bSYour Name 
3598*5113495bSYour Name exit:
3599*5113495bSYour Name 	if (opmode == QDF_STA_MODE)
3600*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
3601*5113495bSYour Name 
3602*5113495bSYour Name 	return status;
3603*5113495bSYour Name }
3604*5113495bSYour Name 
wlan_crypto_register_crypto_rx_ops(struct wlan_lmac_if_crypto_rx_ops * crypto_rx_ops)3605*5113495bSYour Name QDF_STATUS wlan_crypto_register_crypto_rx_ops(
3606*5113495bSYour Name 			struct wlan_lmac_if_crypto_rx_ops *crypto_rx_ops)
3607*5113495bSYour Name {
3608*5113495bSYour Name 	crypto_rx_ops->crypto_encap      = wlan_crypto_encap;
3609*5113495bSYour Name 	crypto_rx_ops->crypto_decap      = wlan_crypto_decap;
3610*5113495bSYour Name 	crypto_rx_ops->crypto_enmic      = wlan_crypto_enmic;
3611*5113495bSYour Name 	crypto_rx_ops->crypto_demic      = wlan_crypto_demic;
3612*5113495bSYour Name 	crypto_rx_ops->set_peer_wep_keys = wlan_crypto_set_peer_wep_keys;
3613*5113495bSYour Name 
3614*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3615*5113495bSYour Name }
3616*5113495bSYour Name 
wlan_crypto_get_crypto_rx_ops(struct wlan_objmgr_psoc * psoc)3617*5113495bSYour Name struct wlan_lmac_if_crypto_rx_ops *wlan_crypto_get_crypto_rx_ops(
3618*5113495bSYour Name 					struct wlan_objmgr_psoc *psoc)
3619*5113495bSYour Name {
3620*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
3621*5113495bSYour Name 
3622*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
3623*5113495bSYour Name 
3624*5113495bSYour Name 	if (!rx_ops) {
3625*5113495bSYour Name 		crypto_err("rx_ops is NULL");
3626*5113495bSYour Name 		return NULL;
3627*5113495bSYour Name 	}
3628*5113495bSYour Name 
3629*5113495bSYour Name 	return &rx_ops->crypto_rx_ops;
3630*5113495bSYour Name }
3631*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_crypto_rx_ops);
3632*5113495bSYour Name 
wlan_crypto_vdev_has_auth_mode(struct wlan_objmgr_vdev * vdev,wlan_crypto_auth_mode authvalue)3633*5113495bSYour Name bool wlan_crypto_vdev_has_auth_mode(struct wlan_objmgr_vdev *vdev,
3634*5113495bSYour Name 					wlan_crypto_auth_mode authvalue)
3635*5113495bSYour Name {
3636*5113495bSYour Name 	int res;
3637*5113495bSYour Name 
3638*5113495bSYour Name 	res = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE);
3639*5113495bSYour Name 
3640*5113495bSYour Name 	if (res != -1)
3641*5113495bSYour Name 		return (res & authvalue) ? true : false;
3642*5113495bSYour Name 	return false;
3643*5113495bSYour Name }
3644*5113495bSYour Name qdf_export_symbol(wlan_crypto_vdev_has_auth_mode);
3645*5113495bSYour Name 
wlan_crypto_peer_has_auth_mode(struct wlan_objmgr_peer * peer,wlan_crypto_auth_mode authvalue)3646*5113495bSYour Name bool wlan_crypto_peer_has_auth_mode(struct wlan_objmgr_peer *peer,
3647*5113495bSYour Name 					wlan_crypto_auth_mode authvalue)
3648*5113495bSYour Name {
3649*5113495bSYour Name 	int res;
3650*5113495bSYour Name 
3651*5113495bSYour Name 	res = wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_AUTH_MODE);
3652*5113495bSYour Name 
3653*5113495bSYour Name 	if (res != -1)
3654*5113495bSYour Name 		return (res & authvalue) ? true : false;
3655*5113495bSYour Name 
3656*5113495bSYour Name 	return false;
3657*5113495bSYour Name }
3658*5113495bSYour Name qdf_export_symbol(wlan_crypto_peer_has_auth_mode);
3659*5113495bSYour Name 
wlan_crypto_vdev_has_ucastcipher(struct wlan_objmgr_vdev * vdev,wlan_crypto_cipher_type ucastcipher)3660*5113495bSYour Name bool wlan_crypto_vdev_has_ucastcipher(struct wlan_objmgr_vdev *vdev,
3661*5113495bSYour Name 					wlan_crypto_cipher_type ucastcipher)
3662*5113495bSYour Name {
3663*5113495bSYour Name 	int res;
3664*5113495bSYour Name 
3665*5113495bSYour Name 	res = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER);
3666*5113495bSYour Name 
3667*5113495bSYour Name 	if (res != -1)
3668*5113495bSYour Name 		return (res & ucastcipher) ? true : false;
3669*5113495bSYour Name 
3670*5113495bSYour Name 	return false;
3671*5113495bSYour Name }
3672*5113495bSYour Name qdf_export_symbol(wlan_crypto_vdev_has_ucastcipher);
3673*5113495bSYour Name 
wlan_crypto_peer_has_ucastcipher(struct wlan_objmgr_peer * peer,wlan_crypto_cipher_type ucastcipher)3674*5113495bSYour Name bool wlan_crypto_peer_has_ucastcipher(struct wlan_objmgr_peer *peer,
3675*5113495bSYour Name 					wlan_crypto_cipher_type ucastcipher)
3676*5113495bSYour Name {
3677*5113495bSYour Name 	int res;
3678*5113495bSYour Name 
3679*5113495bSYour Name 	res = wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER);
3680*5113495bSYour Name 
3681*5113495bSYour Name 	if (res != -1)
3682*5113495bSYour Name 		return (res & ucastcipher) ? true : false;
3683*5113495bSYour Name 
3684*5113495bSYour Name 	return false;
3685*5113495bSYour Name }
3686*5113495bSYour Name qdf_export_symbol(wlan_crypto_peer_has_ucastcipher);
3687*5113495bSYour Name 
wlan_crypto_vdev_has_mcastcipher(struct wlan_objmgr_vdev * vdev,wlan_crypto_cipher_type mcastcipher)3688*5113495bSYour Name bool wlan_crypto_vdev_has_mcastcipher(struct wlan_objmgr_vdev *vdev,
3689*5113495bSYour Name 					wlan_crypto_cipher_type mcastcipher)
3690*5113495bSYour Name {
3691*5113495bSYour Name 	int res;
3692*5113495bSYour Name 
3693*5113495bSYour Name 	res = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER);
3694*5113495bSYour Name 
3695*5113495bSYour Name 	if (res != -1)
3696*5113495bSYour Name 		return (res & mcastcipher) ? true : false;
3697*5113495bSYour Name 
3698*5113495bSYour Name 	return false;
3699*5113495bSYour Name }
3700*5113495bSYour Name qdf_export_symbol(wlan_crypto_vdev_has_mcastcipher);
3701*5113495bSYour Name 
wlan_crypto_peer_has_mcastcipher(struct wlan_objmgr_peer * peer,wlan_crypto_cipher_type mcastcipher)3702*5113495bSYour Name bool wlan_crypto_peer_has_mcastcipher(struct wlan_objmgr_peer *peer,
3703*5113495bSYour Name 					wlan_crypto_cipher_type mcastcipher)
3704*5113495bSYour Name {
3705*5113495bSYour Name 	int res;
3706*5113495bSYour Name 
3707*5113495bSYour Name 	res = wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_MCAST_CIPHER);
3708*5113495bSYour Name 
3709*5113495bSYour Name 	if (res != -1)
3710*5113495bSYour Name 		return (res & mcastcipher) ? true : false;
3711*5113495bSYour Name 
3712*5113495bSYour Name 	return false;
3713*5113495bSYour Name }
3714*5113495bSYour Name qdf_export_symbol(wlan_crypto_peer_has_mcastcipher);
3715*5113495bSYour Name 
wlan_crypto_vdev_has_mgmtcipher(struct wlan_objmgr_vdev * vdev,uint32_t mgmtcipher)3716*5113495bSYour Name bool wlan_crypto_vdev_has_mgmtcipher(struct wlan_objmgr_vdev *vdev,
3717*5113495bSYour Name 				     uint32_t mgmtcipher)
3718*5113495bSYour Name {
3719*5113495bSYour Name 	int res;
3720*5113495bSYour Name 
3721*5113495bSYour Name 	res = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MGMT_CIPHER);
3722*5113495bSYour Name 
3723*5113495bSYour Name 	if (res != -1)
3724*5113495bSYour Name 		return (res & mgmtcipher) ? true : false;
3725*5113495bSYour Name 
3726*5113495bSYour Name 	return false;
3727*5113495bSYour Name }
3728*5113495bSYour Name 
3729*5113495bSYour Name qdf_export_symbol(wlan_crypto_vdev_has_mgmtcipher);
3730*5113495bSYour Name 
wlan_crypto_peer_has_mgmtcipher(struct wlan_objmgr_peer * peer,uint32_t mgmtcipher)3731*5113495bSYour Name bool wlan_crypto_peer_has_mgmtcipher(struct wlan_objmgr_peer *peer,
3732*5113495bSYour Name 				     uint32_t mgmtcipher)
3733*5113495bSYour Name {
3734*5113495bSYour Name 	int res;
3735*5113495bSYour Name 
3736*5113495bSYour Name 	res = wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_MGMT_CIPHER);
3737*5113495bSYour Name 
3738*5113495bSYour Name 	if (res != -1)
3739*5113495bSYour Name 		return (res & mgmtcipher) ? true : false;
3740*5113495bSYour Name 
3741*5113495bSYour Name 	return false;
3742*5113495bSYour Name }
3743*5113495bSYour Name 
3744*5113495bSYour Name qdf_export_symbol(wlan_crypto_peer_has_mgmtcipher);
3745*5113495bSYour Name 
wlan_crypto_get_peer_fils_aead(struct wlan_objmgr_peer * peer)3746*5113495bSYour Name uint8_t wlan_crypto_get_peer_fils_aead(struct wlan_objmgr_peer *peer)
3747*5113495bSYour Name {
3748*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv = NULL;
3749*5113495bSYour Name 
3750*5113495bSYour Name 	if (!peer) {
3751*5113495bSYour Name 		crypto_err("Invalid Input");
3752*5113495bSYour Name 		return 0;
3753*5113495bSYour Name 	}
3754*5113495bSYour Name 
3755*5113495bSYour Name 	crypto_priv = wlan_get_peer_crypto_obj(peer);
3756*5113495bSYour Name 	if (!crypto_priv) {
3757*5113495bSYour Name 		crypto_err("crypto_priv NULL");
3758*5113495bSYour Name 		return 0;
3759*5113495bSYour Name 	}
3760*5113495bSYour Name 
3761*5113495bSYour Name 	return crypto_priv->fils_aead_set;
3762*5113495bSYour Name }
3763*5113495bSYour Name 
3764*5113495bSYour Name void
wlan_crypto_set_peer_fils_aead(struct wlan_objmgr_peer * peer,uint8_t value)3765*5113495bSYour Name wlan_crypto_set_peer_fils_aead(struct wlan_objmgr_peer *peer, uint8_t value)
3766*5113495bSYour Name {
3767*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv = NULL;
3768*5113495bSYour Name 
3769*5113495bSYour Name 	if (!peer) {
3770*5113495bSYour Name 		crypto_err("Invalid Input");
3771*5113495bSYour Name 		return;
3772*5113495bSYour Name 	}
3773*5113495bSYour Name 
3774*5113495bSYour Name 	crypto_priv = wlan_get_peer_crypto_obj(peer);
3775*5113495bSYour Name 	if (!crypto_priv) {
3776*5113495bSYour Name 		crypto_err("crypto_priv NULL");
3777*5113495bSYour Name 		return;
3778*5113495bSYour Name 	}
3779*5113495bSYour Name 
3780*5113495bSYour Name 	crypto_priv->fils_aead_set = value;
3781*5113495bSYour Name }
3782*5113495bSYour Name 
wlan_crypto_get_key_header(struct wlan_crypto_key * key)3783*5113495bSYour Name uint8_t wlan_crypto_get_key_header(struct wlan_crypto_key *key)
3784*5113495bSYour Name {
3785*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
3786*5113495bSYour Name 
3787*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3788*5113495bSYour Name 	if (cipher_table)
3789*5113495bSYour Name 		return cipher_table->header;
3790*5113495bSYour Name 	else
3791*5113495bSYour Name 		return 0;
3792*5113495bSYour Name }
3793*5113495bSYour Name 
3794*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_key_header);
3795*5113495bSYour Name 
wlan_crypto_get_key_trailer(struct wlan_crypto_key * key)3796*5113495bSYour Name uint8_t wlan_crypto_get_key_trailer(struct wlan_crypto_key *key)
3797*5113495bSYour Name {
3798*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
3799*5113495bSYour Name 
3800*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3801*5113495bSYour Name 	if (cipher_table)
3802*5113495bSYour Name 		return cipher_table->trailer;
3803*5113495bSYour Name 	else
3804*5113495bSYour Name 		return 0;
3805*5113495bSYour Name }
3806*5113495bSYour Name 
3807*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_key_trailer);
3808*5113495bSYour Name 
wlan_crypto_get_key_miclen(struct wlan_crypto_key * key)3809*5113495bSYour Name uint8_t wlan_crypto_get_key_miclen(struct wlan_crypto_key *key)
3810*5113495bSYour Name {
3811*5113495bSYour Name 	struct wlan_crypto_cipher *cipher_table;
3812*5113495bSYour Name 
3813*5113495bSYour Name 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
3814*5113495bSYour Name 	if (cipher_table)
3815*5113495bSYour Name 		return cipher_table->miclen;
3816*5113495bSYour Name 	else
3817*5113495bSYour Name 		return 0;
3818*5113495bSYour Name }
3819*5113495bSYour Name 
3820*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_key_miclen);
3821*5113495bSYour Name 
wlan_crypto_get_keyid(uint8_t * data,int hdrlen)3822*5113495bSYour Name uint16_t wlan_crypto_get_keyid(uint8_t *data, int hdrlen)
3823*5113495bSYour Name {
3824*5113495bSYour Name 	struct wlan_frame_hdr *hdr = (struct wlan_frame_hdr *)data;
3825*5113495bSYour Name 	uint8_t *iv;
3826*5113495bSYour Name 	uint8_t stype = WLAN_FC0_GET_STYPE(hdr->i_fc[0]);
3827*5113495bSYour Name 	uint8_t type = WLAN_FC0_GET_TYPE(hdr->i_fc[0]);
3828*5113495bSYour Name 
3829*5113495bSYour Name 	/*
3830*5113495bSYour Name 	 * In FILS SK (Re)Association request/response frame has
3831*5113495bSYour Name 	 * to be decrypted
3832*5113495bSYour Name 	 */
3833*5113495bSYour Name 	if ((type == WLAN_FC0_TYPE_MGMT) &&
3834*5113495bSYour Name 	    ((stype == WLAN_FC0_STYPE_ASSOC_REQ) ||
3835*5113495bSYour Name 	    (stype == WLAN_FC0_STYPE_REASSOC_REQ) ||
3836*5113495bSYour Name 	    (stype == WLAN_FC0_STYPE_ASSOC_RESP) ||
3837*5113495bSYour Name 	    (stype == WLAN_FC0_STYPE_REASSOC_RESP))) {
3838*5113495bSYour Name 		return 0;
3839*5113495bSYour Name 	}
3840*5113495bSYour Name 
3841*5113495bSYour Name 	if (hdr->i_fc[1] & WLAN_FC1_ISWEP) {
3842*5113495bSYour Name 		iv = data + hdrlen;
3843*5113495bSYour Name 		/*
3844*5113495bSYour Name 		 * iv[3] is the Key ID octet in the CCMP/TKIP/WEP headers
3845*5113495bSYour Name 		 * Bits 6–7 of the Key ID octet are for the Key ID subfield
3846*5113495bSYour Name 		 */
3847*5113495bSYour Name 		return ((iv[3] >> 6) & 0x3);
3848*5113495bSYour Name 	} else {
3849*5113495bSYour Name 		return WLAN_CRYPTO_KEYIX_NONE;
3850*5113495bSYour Name 	}
3851*5113495bSYour Name }
3852*5113495bSYour Name 
3853*5113495bSYour Name qdf_export_symbol(wlan_crypto_get_keyid);
3854*5113495bSYour Name 
3855*5113495bSYour Name /**
3856*5113495bSYour Name  * crypto_plumb_peer_keys() - called during radio reset
3857*5113495bSYour Name  * @vdev: vdev
3858*5113495bSYour Name  * @object: peer
3859*5113495bSYour Name  * @arg: psoc
3860*5113495bSYour Name  *
3861*5113495bSYour Name  * Restore unicast and persta hardware keys
3862*5113495bSYour Name  *
3863*5113495bSYour Name  * Return: void
3864*5113495bSYour Name  */
crypto_plumb_peer_keys(struct wlan_objmgr_vdev * vdev,void * object,void * arg)3865*5113495bSYour Name static void crypto_plumb_peer_keys(struct wlan_objmgr_vdev *vdev,
3866*5113495bSYour Name 				   void *object, void *arg)
3867*5113495bSYour Name {
3868*5113495bSYour Name 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)object;
3869*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)arg;
3870*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3871*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
3872*5113495bSYour Name 	struct wlan_crypto_key *key = NULL;
3873*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
3874*5113495bSYour Name 	int i;
3875*5113495bSYour Name 
3876*5113495bSYour Name 	if ((!peer) || (!vdev) || (!psoc)) {
3877*5113495bSYour Name 		crypto_err("Peer or vdev or psoc objects are null!");
3878*5113495bSYour Name 		return;
3879*5113495bSYour Name 	}
3880*5113495bSYour Name 
3881*5113495bSYour Name 	crypto_params = wlan_crypto_peer_get_comp_params(peer,
3882*5113495bSYour Name 							 &crypto_priv);
3883*5113495bSYour Name 
3884*5113495bSYour Name 	if (!crypto_priv) {
3885*5113495bSYour Name 		crypto_err("crypto_priv NULL");
3886*5113495bSYour Name 		return;
3887*5113495bSYour Name 	}
3888*5113495bSYour Name 
3889*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
3890*5113495bSYour Name 		key = crypto_priv->crypto_key.key[i];
3891*5113495bSYour Name 		if (key && key->valid) {
3892*5113495bSYour Name 			tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
3893*5113495bSYour Name 
3894*5113495bSYour Name 			if (!tx_ops) {
3895*5113495bSYour Name 				crypto_err("tx_ops is NULL");
3896*5113495bSYour Name 				return;
3897*5113495bSYour Name 			}
3898*5113495bSYour Name 			if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
3899*5113495bSYour Name 				WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)
3900*5113495bSYour Name 					(
3901*5113495bSYour Name 					 vdev,
3902*5113495bSYour Name 					 key,
3903*5113495bSYour Name 					 wlan_peer_get_macaddr(peer),
3904*5113495bSYour Name 					 wlan_crypto_get_key_type(key)
3905*5113495bSYour Name 					);
3906*5113495bSYour Name 			}
3907*5113495bSYour Name 		}
3908*5113495bSYour Name 	}
3909*5113495bSYour Name }
3910*5113495bSYour Name 
wlan_crypto_restore_keys(struct wlan_objmgr_vdev * vdev)3911*5113495bSYour Name void wlan_crypto_restore_keys(struct wlan_objmgr_vdev *vdev)
3912*5113495bSYour Name {
3913*5113495bSYour Name 	int i;
3914*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
3915*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
3916*5113495bSYour Name 	struct wlan_crypto_key *key;
3917*5113495bSYour Name 	uint8_t macaddr[QDF_MAC_ADDR_SIZE] =
3918*5113495bSYour Name 			{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3919*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
3920*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = NULL;
3921*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
3922*5113495bSYour Name 
3923*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
3924*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
3925*5113495bSYour Name 	if (!pdev) {
3926*5113495bSYour Name 		crypto_err("pdev is NULL");
3927*5113495bSYour Name 		return;
3928*5113495bSYour Name 	}
3929*5113495bSYour Name 	if (!psoc) {
3930*5113495bSYour Name 		crypto_err("psoc is NULL");
3931*5113495bSYour Name 		return;
3932*5113495bSYour Name 	}
3933*5113495bSYour Name 
3934*5113495bSYour Name 	/* TBD: QWRAP key restore*/
3935*5113495bSYour Name 	/* crypto is on */
3936*5113495bSYour Name 	if (wlan_vdev_mlme_feat_cap_get(vdev, WLAN_VDEV_F_PRIVACY)) {
3937*5113495bSYour Name 		/* restore static shared keys */
3938*5113495bSYour Name 		for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
3939*5113495bSYour Name 			crypto_params = wlan_crypto_vdev_get_comp_params
3940*5113495bSYour Name 				(
3941*5113495bSYour Name 				 vdev,
3942*5113495bSYour Name 				 &crypto_priv
3943*5113495bSYour Name 				);
3944*5113495bSYour Name 			if (!crypto_priv) {
3945*5113495bSYour Name 				crypto_err("crypto_priv is NULL");
3946*5113495bSYour Name 				return;
3947*5113495bSYour Name 			}
3948*5113495bSYour Name 			key = crypto_priv->crypto_key.key[i];
3949*5113495bSYour Name 			if (key && key->valid) {
3950*5113495bSYour Name 				tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
3951*5113495bSYour Name 				if (!tx_ops) {
3952*5113495bSYour Name 					crypto_err("tx_ops is NULL");
3953*5113495bSYour Name 					return;
3954*5113495bSYour Name 				}
3955*5113495bSYour Name 				if (WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)) {
3956*5113495bSYour Name 					WLAN_CRYPTO_TX_OPS_SETKEY(tx_ops)
3957*5113495bSYour Name 						(
3958*5113495bSYour Name 						 vdev,
3959*5113495bSYour Name 						 key,
3960*5113495bSYour Name 						 macaddr,
3961*5113495bSYour Name 						 wlan_crypto_get_key_type(key)
3962*5113495bSYour Name 						 );
3963*5113495bSYour Name 				}
3964*5113495bSYour Name 			}
3965*5113495bSYour Name 		}
3966*5113495bSYour Name 
3967*5113495bSYour Name 		wlan_objmgr_iterate_peerobj_list(vdev,
3968*5113495bSYour Name 						 crypto_plumb_peer_keys,
3969*5113495bSYour Name 						 psoc,
3970*5113495bSYour Name 						 WLAN_CRYPTO_ID);
3971*5113495bSYour Name 	}
3972*5113495bSYour Name }
3973*5113495bSYour Name 
3974*5113495bSYour Name QDF_STATUS
wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params * crypto_params,const uint8_t * ie_ptr,uint16_t ie_len)3975*5113495bSYour Name wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
3976*5113495bSYour Name 				   const uint8_t *ie_ptr, uint16_t ie_len)
3977*5113495bSYour Name {
3978*5113495bSYour Name 	const uint8_t *rsn_ie = NULL;
3979*5113495bSYour Name 	QDF_STATUS status;
3980*5113495bSYour Name 
3981*5113495bSYour Name 	qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
3982*5113495bSYour Name 	rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSN, ie_ptr, ie_len);
3983*5113495bSYour Name 	if (!rsn_ie) {
3984*5113495bSYour Name 		crypto_debug("RSN IE not present");
3985*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3986*5113495bSYour Name 	}
3987*5113495bSYour Name 
3988*5113495bSYour Name 	status = wlan_crypto_rsnie_check(crypto_params, rsn_ie);
3989*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
3990*5113495bSYour Name 		crypto_err("RSN IE check failed");
3991*5113495bSYour Name 		return status;
3992*5113495bSYour Name 	}
3993*5113495bSYour Name 
3994*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3995*5113495bSYour Name }
3996*5113495bSYour Name 
3997*5113495bSYour Name QDF_STATUS
wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params * crypto_params,const uint8_t * ie_ptr,uint16_t ie_len)3998*5113495bSYour Name wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
3999*5113495bSYour Name 				   const uint8_t *ie_ptr, uint16_t ie_len)
4000*5113495bSYour Name {
4001*5113495bSYour Name 	const uint8_t *wpa_ie = NULL;
4002*5113495bSYour Name 	uint32_t wpa_oui;
4003*5113495bSYour Name 	QDF_STATUS status;
4004*5113495bSYour Name 
4005*5113495bSYour Name 	qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
4006*5113495bSYour Name 
4007*5113495bSYour Name 	wpa_oui = WLAN_WPA_SEL(WLAN_WPA_OUI_TYPE);
4008*5113495bSYour Name 	wpa_ie = wlan_get_vendor_ie_ptr_from_oui((uint8_t *)&wpa_oui,
4009*5113495bSYour Name 						 WLAN_OUI_SIZE, ie_ptr, ie_len);
4010*5113495bSYour Name 	if (!wpa_ie) {
4011*5113495bSYour Name 		crypto_debug("WPA IE not present");
4012*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4013*5113495bSYour Name 	}
4014*5113495bSYour Name 
4015*5113495bSYour Name 	status = wlan_crypto_wpaie_check(crypto_params, wpa_ie);
4016*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
4017*5113495bSYour Name 		crypto_err("WPA IE check failed");
4018*5113495bSYour Name 		return status;
4019*5113495bSYour Name 	}
4020*5113495bSYour Name 
4021*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4022*5113495bSYour Name }
4023*5113495bSYour Name 
4024*5113495bSYour Name #ifdef FEATURE_WLAN_WAPI
4025*5113495bSYour Name QDF_STATUS
wlan_get_crypto_params_from_wapi_ie(struct wlan_crypto_params * crypto_params,const uint8_t * ie_ptr,uint16_t ie_len)4026*5113495bSYour Name wlan_get_crypto_params_from_wapi_ie(struct wlan_crypto_params *crypto_params,
4027*5113495bSYour Name 				    const uint8_t *ie_ptr, uint16_t ie_len)
4028*5113495bSYour Name {
4029*5113495bSYour Name 	const uint8_t *wapi_ie;
4030*5113495bSYour Name 	QDF_STATUS status;
4031*5113495bSYour Name 
4032*5113495bSYour Name 	qdf_mem_zero(crypto_params, sizeof(*crypto_params));
4033*5113495bSYour Name 	wapi_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_WAPI, ie_ptr, ie_len);
4034*5113495bSYour Name 	if (!wapi_ie) {
4035*5113495bSYour Name 		crypto_debug("WAPI ie not present");
4036*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4037*5113495bSYour Name 	}
4038*5113495bSYour Name 
4039*5113495bSYour Name 	status = wlan_crypto_wapiie_check(crypto_params, wapi_ie);
4040*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4041*5113495bSYour Name 		crypto_err("WAPI IE check failed");
4042*5113495bSYour Name 		return status;
4043*5113495bSYour Name 	}
4044*5113495bSYour Name 
4045*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4046*5113495bSYour Name }
4047*5113495bSYour Name #endif
4048*5113495bSYour Name 
wlan_crypto_check_rsn_match(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * ie_ptr,uint16_t ie_len,struct wlan_crypto_params * peer_crypto_params)4049*5113495bSYour Name bool wlan_crypto_check_rsn_match(struct wlan_objmgr_psoc *psoc,
4050*5113495bSYour Name 				 uint8_t vdev_id, uint8_t *ie_ptr,
4051*5113495bSYour Name 				 uint16_t ie_len, struct wlan_crypto_params *
4052*5113495bSYour Name 				 peer_crypto_params)
4053*5113495bSYour Name {
4054*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
4055*5113495bSYour Name 	bool match = true;
4056*5113495bSYour Name 	QDF_STATUS status;
4057*5113495bSYour Name 
4058*5113495bSYour Name 	if (!psoc) {
4059*5113495bSYour Name 		crypto_err("PSOC is NULL");
4060*5113495bSYour Name 		return false;
4061*5113495bSYour Name 	}
4062*5113495bSYour Name 	status = wlan_get_crypto_params_from_rsn_ie(peer_crypto_params,
4063*5113495bSYour Name 						    ie_ptr, ie_len);
4064*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
4065*5113495bSYour Name 		crypto_err("get crypto prarams from RSN IE failed");
4066*5113495bSYour Name 		return false;
4067*5113495bSYour Name 	}
4068*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4069*5113495bSYour Name 						    WLAN_CRYPTO_ID);
4070*5113495bSYour Name 	if (!vdev) {
4071*5113495bSYour Name 		crypto_err("vdev is NULL");
4072*5113495bSYour Name 		return false;
4073*5113495bSYour Name 	}
4074*5113495bSYour Name 
4075*5113495bSYour Name 	match = wlan_crypto_rsn_info(vdev, peer_crypto_params);
4076*5113495bSYour Name 
4077*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
4078*5113495bSYour Name 
4079*5113495bSYour Name 	return match;
4080*5113495bSYour Name }
4081*5113495bSYour Name 
wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * ie_ptr,uint16_t ie_len,struct wlan_crypto_params * peer_crypto_params)4082*5113495bSYour Name bool wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc *psoc,
4083*5113495bSYour Name 				 uint8_t vdev_id, uint8_t *ie_ptr,
4084*5113495bSYour Name 				 uint16_t ie_len, struct wlan_crypto_params *
4085*5113495bSYour Name 				 peer_crypto_params)
4086*5113495bSYour Name {
4087*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
4088*5113495bSYour Name 	bool match = true;
4089*5113495bSYour Name 	QDF_STATUS status;
4090*5113495bSYour Name 
4091*5113495bSYour Name 	if (!psoc) {
4092*5113495bSYour Name 		crypto_err("PSOC is NULL");
4093*5113495bSYour Name 		return false;
4094*5113495bSYour Name 	}
4095*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4096*5113495bSYour Name 						    WLAN_CRYPTO_ID);
4097*5113495bSYour Name 	if (!vdev) {
4098*5113495bSYour Name 		crypto_err("vdev is NULL");
4099*5113495bSYour Name 		return false;
4100*5113495bSYour Name 	}
4101*5113495bSYour Name 
4102*5113495bSYour Name 	status = wlan_get_crypto_params_from_wpa_ie(peer_crypto_params,
4103*5113495bSYour Name 						    ie_ptr, ie_len);
4104*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
4105*5113495bSYour Name 		crypto_err("get crypto prarams from WPA IE failed");
4106*5113495bSYour Name 		match = false;
4107*5113495bSYour Name 		goto send_res;
4108*5113495bSYour Name 	}
4109*5113495bSYour Name 	match = wlan_crypto_rsn_info(vdev, peer_crypto_params);
4110*5113495bSYour Name 
4111*5113495bSYour Name send_res:
4112*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
4113*5113495bSYour Name 
4114*5113495bSYour Name 	return match;
4115*5113495bSYour Name }
4116*5113495bSYour Name 
4117*5113495bSYour Name 
4118*5113495bSYour Name static void
wlan_crypto_merge_prarams(struct wlan_crypto_params * dst_params,struct wlan_crypto_params * src_params)4119*5113495bSYour Name wlan_crypto_merge_prarams(struct wlan_crypto_params *dst_params,
4120*5113495bSYour Name 			  struct wlan_crypto_params *src_params)
4121*5113495bSYour Name {
4122*5113495bSYour Name 	dst_params->authmodeset |= src_params->authmodeset;
4123*5113495bSYour Name 	dst_params->ucastcipherset |= src_params->ucastcipherset;
4124*5113495bSYour Name 	dst_params->mcastcipherset |= src_params->mcastcipherset;
4125*5113495bSYour Name 	dst_params->mgmtcipherset |= src_params->mgmtcipherset;
4126*5113495bSYour Name 	dst_params->cipher_caps |= src_params->cipher_caps;
4127*5113495bSYour Name 	dst_params->key_mgmt |= src_params->key_mgmt;
4128*5113495bSYour Name 	dst_params->rsn_caps |= src_params->rsn_caps;
4129*5113495bSYour Name }
4130*5113495bSYour Name 
4131*5113495bSYour Name static void
wlan_crypto_reset_prarams(struct wlan_crypto_params * params)4132*5113495bSYour Name wlan_crypto_reset_prarams(struct wlan_crypto_params *params)
4133*5113495bSYour Name {
4134*5113495bSYour Name 	params->authmodeset = 0;
4135*5113495bSYour Name 	params->ucastcipherset = 0;
4136*5113495bSYour Name 	params->mcastcipherset = 0;
4137*5113495bSYour Name 	params->mgmtcipherset = 0;
4138*5113495bSYour Name 	params->key_mgmt = 0;
4139*5113495bSYour Name 	params->rsn_caps = 0;
4140*5113495bSYour Name }
4141*5113495bSYour Name 
4142*5113495bSYour Name const uint8_t *
wlan_crypto_parse_rsnxe_ie(const uint8_t * rsnxe_ie,uint8_t * cap_len)4143*5113495bSYour Name wlan_crypto_parse_rsnxe_ie(const uint8_t *rsnxe_ie, uint8_t *cap_len)
4144*5113495bSYour Name {
4145*5113495bSYour Name 	uint8_t len;
4146*5113495bSYour Name 	const uint8_t *ie;
4147*5113495bSYour Name 
4148*5113495bSYour Name 	if (!rsnxe_ie)
4149*5113495bSYour Name 		return NULL;
4150*5113495bSYour Name 
4151*5113495bSYour Name 	ie = rsnxe_ie;
4152*5113495bSYour Name 	len = ie[1];
4153*5113495bSYour Name 	ie += 2;
4154*5113495bSYour Name 
4155*5113495bSYour Name 	if (!len)
4156*5113495bSYour Name 		return NULL;
4157*5113495bSYour Name 
4158*5113495bSYour Name 	*cap_len = ie[0] & 0xf;
4159*5113495bSYour Name 
4160*5113495bSYour Name 	return ie;
4161*5113495bSYour Name }
4162*5113495bSYour Name 
wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev * vdev,uint8_t * ie_ptr,uint16_t ie_len)4163*5113495bSYour Name QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev,
4164*5113495bSYour Name 						uint8_t *ie_ptr,
4165*5113495bSYour Name 						uint16_t ie_len)
4166*5113495bSYour Name {
4167*5113495bSYour Name 	struct wlan_crypto_params crypto_params;
4168*5113495bSYour Name 	QDF_STATUS status;
4169*5113495bSYour Name 	struct wlan_crypto_params *vdev_crypto_params;
4170*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4171*5113495bSYour Name 	bool send_fail = false;
4172*5113495bSYour Name 
4173*5113495bSYour Name 	if (!vdev) {
4174*5113495bSYour Name 		crypto_err("VDEV is NULL");
4175*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4176*5113495bSYour Name 	}
4177*5113495bSYour Name 
4178*5113495bSYour Name 	if (!ie_ptr) {
4179*5113495bSYour Name 		crypto_err("IE ptr is NULL");
4180*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4181*5113495bSYour Name 	}
4182*5113495bSYour Name 
4183*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
4184*5113495bSYour Name 		       wlan_get_vdev_crypto_obj(vdev);
4185*5113495bSYour Name 
4186*5113495bSYour Name 	if (!crypto_priv) {
4187*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4188*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4189*5113495bSYour Name 	}
4190*5113495bSYour Name 
4191*5113495bSYour Name 	vdev_crypto_params = &crypto_priv->crypto_params;
4192*5113495bSYour Name 
4193*5113495bSYour Name 	wlan_crypto_reset_prarams(vdev_crypto_params);
4194*5113495bSYour Name 	status = wlan_get_crypto_params_from_rsn_ie(&crypto_params,
4195*5113495bSYour Name 						    ie_ptr, ie_len);
4196*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status))
4197*5113495bSYour Name 		wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params);
4198*5113495bSYour Name 	else
4199*5113495bSYour Name 		send_fail = true;
4200*5113495bSYour Name 
4201*5113495bSYour Name 	status = wlan_get_crypto_params_from_wpa_ie(&crypto_params,
4202*5113495bSYour Name 						    ie_ptr, ie_len);
4203*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status)) {
4204*5113495bSYour Name 		wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params);
4205*5113495bSYour Name 		send_fail = false;
4206*5113495bSYour Name 	}
4207*5113495bSYour Name 
4208*5113495bSYour Name 	status = wlan_get_crypto_params_from_wapi_ie(&crypto_params,
4209*5113495bSYour Name 						     ie_ptr, ie_len);
4210*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status)) {
4211*5113495bSYour Name 		wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params);
4212*5113495bSYour Name 		send_fail = false;
4213*5113495bSYour Name 	}
4214*5113495bSYour Name 
4215*5113495bSYour Name 	return send_fail ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
4216*5113495bSYour Name }
4217*5113495bSYour Name 
wlan_crypto_get_default_key_idx(struct wlan_objmgr_vdev * vdev,bool igtk)4218*5113495bSYour Name int8_t wlan_crypto_get_default_key_idx(struct wlan_objmgr_vdev *vdev, bool igtk)
4219*5113495bSYour Name {
4220*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4221*5113495bSYour Name 
4222*5113495bSYour Name 	crypto_priv = wlan_get_vdev_crypto_obj(vdev);
4223*5113495bSYour Name 	if (!crypto_priv) {
4224*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4225*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4226*5113495bSYour Name 	}
4227*5113495bSYour Name 
4228*5113495bSYour Name 	if (igtk)
4229*5113495bSYour Name 		return crypto_priv->crypto_key.def_igtk_tx_keyid;
4230*5113495bSYour Name 	else
4231*5113495bSYour Name 		return crypto_priv->crypto_key.def_tx_keyid;
4232*5113495bSYour Name }
4233*5113495bSYour Name 
4234*5113495bSYour Name enum wlan_crypto_cipher_type
wlan_crypto_get_cipher(struct wlan_objmgr_vdev * vdev,bool pairwise,uint8_t key_index)4235*5113495bSYour Name wlan_crypto_get_cipher(struct wlan_objmgr_vdev *vdev,
4236*5113495bSYour Name 		       bool pairwise, uint8_t key_index)
4237*5113495bSYour Name {
4238*5113495bSYour Name 	struct wlan_crypto_key *crypto_key;
4239*5113495bSYour Name 
4240*5113495bSYour Name 	crypto_key = wlan_crypto_get_key(vdev, key_index);
4241*5113495bSYour Name 
4242*5113495bSYour Name 	if (crypto_key)
4243*5113495bSYour Name 		return crypto_key->cipher_type;
4244*5113495bSYour Name 	else
4245*5113495bSYour Name 		return WLAN_CRYPTO_CIPHER_INVALID;
4246*5113495bSYour Name }
4247*5113495bSYour Name 
wlan_crypto_get_secure_akm_available(uint32_t akm)4248*5113495bSYour Name wlan_crypto_key_mgmt wlan_crypto_get_secure_akm_available(uint32_t akm)
4249*5113495bSYour Name {
4250*5113495bSYour Name 	if (!akm)
4251*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_MAX;
4252*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384))
4253*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384;
4254*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256))
4255*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256;
4256*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384))
4257*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA384;
4258*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256))
4259*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FILS_SHA256;
4260*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384))
4261*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384;
4262*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192))
4263*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192;
4264*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B))
4265*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B;
4266*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY))
4267*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY;
4268*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))
4269*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY;
4270*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE))
4271*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_SAE;
4272*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE))
4273*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_SAE;
4274*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE))
4275*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_OWE;
4276*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_DPP))
4277*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_DPP;
4278*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256))
4279*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256;
4280*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X))
4281*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X;
4282*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
4283*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
4284*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK_SHA384))
4285*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_PSK_SHA384;
4286*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA384))
4287*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA384;
4288*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256))
4289*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA256;
4290*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK))
4291*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_FT_PSK;
4292*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
4293*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_PSK;
4294*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK))
4295*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WAPI_PSK;
4296*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))
4297*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WAPI_CERT;
4298*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
4299*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_CCKM;
4300*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OSEN))
4301*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_OSEN;
4302*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WPS))
4303*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WPS;
4304*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_NO_WPA))
4305*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_NO_WPA;
4306*5113495bSYour Name 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WPA_NONE))
4307*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_WPA_NONE;
4308*5113495bSYour Name 	else /* Return MAX if no AKM matches */
4309*5113495bSYour Name 		return WLAN_CRYPTO_KEY_MGMT_MAX;
4310*5113495bSYour Name }
4311*5113495bSYour Name 
4312*5113495bSYour Name #ifdef CRYPTO_SET_KEY_CONVERGED
wlan_crypto_validate_key_params(enum wlan_crypto_cipher_type cipher,uint8_t key_index,uint8_t key_len,uint8_t seq_len)4313*5113495bSYour Name QDF_STATUS wlan_crypto_validate_key_params(enum wlan_crypto_cipher_type cipher,
4314*5113495bSYour Name 					   uint8_t key_index, uint8_t key_len,
4315*5113495bSYour Name 					   uint8_t seq_len)
4316*5113495bSYour Name {
4317*5113495bSYour Name 	if (!is_valid_keyix(key_index)) {
4318*5113495bSYour Name 		crypto_err("Invalid Key index %d", key_index);
4319*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4320*5113495bSYour Name 	}
4321*5113495bSYour Name 	if (cipher == WLAN_CRYPTO_CIPHER_INVALID) {
4322*5113495bSYour Name 		crypto_err("Invalid Cipher %d", cipher);
4323*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4324*5113495bSYour Name 	}
4325*5113495bSYour Name 	if ((!(cipher == WLAN_CRYPTO_CIPHER_AES_CMAC ||
4326*5113495bSYour Name 	       cipher == WLAN_CRYPTO_CIPHER_AES_CMAC_256 ||
4327*5113495bSYour Name 	       cipher == WLAN_CRYPTO_CIPHER_AES_GMAC ||
4328*5113495bSYour Name 	       cipher == WLAN_CRYPTO_CIPHER_AES_GMAC_256)) &&
4329*5113495bSYour Name 	    (key_index >= WLAN_CRYPTO_MAXKEYIDX)) {
4330*5113495bSYour Name 		crypto_err("Invalid key index %d for cipher %d",
4331*5113495bSYour Name 			   key_index, cipher);
4332*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4333*5113495bSYour Name 	}
4334*5113495bSYour Name 	if (key_len > (WLAN_CRYPTO_KEYBUF_SIZE + WLAN_CRYPTO_MICBUF_SIZE)) {
4335*5113495bSYour Name 		crypto_err("Invalid key length %d", key_len);
4336*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4337*5113495bSYour Name 	}
4338*5113495bSYour Name 
4339*5113495bSYour Name 	if (seq_len > WLAN_CRYPTO_RSC_SIZE) {
4340*5113495bSYour Name 		crypto_err("Invalid seq length %d", seq_len);
4341*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4342*5113495bSYour Name 	}
4343*5113495bSYour Name 
4344*5113495bSYour Name 	crypto_debug("key: idx:%d, len:%d, seq len:%d",
4345*5113495bSYour Name 		     key_index, key_len, seq_len);
4346*5113495bSYour Name 
4347*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4348*5113495bSYour Name }
4349*5113495bSYour Name 
4350*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
is_mlo_adv_enable(void)4351*5113495bSYour Name static bool is_mlo_adv_enable(void)
4352*5113495bSYour Name {
4353*5113495bSYour Name 	return true;
4354*5113495bSYour Name }
4355*5113495bSYour Name #else
is_mlo_adv_enable(void)4356*5113495bSYour Name static bool is_mlo_adv_enable(void)
4357*5113495bSYour Name {
4358*5113495bSYour Name 	return false;
4359*5113495bSYour Name }
4360*5113495bSYour Name 
4361*5113495bSYour Name #endif
4362*5113495bSYour Name 
4363*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
wlan_crypto_save_ml_sta_key(struct wlan_objmgr_psoc * psoc,uint8_t key_index,struct wlan_crypto_key * crypto_key,struct qdf_mac_addr * link_addr,uint8_t link_id)4364*5113495bSYour Name QDF_STATUS wlan_crypto_save_ml_sta_key(
4365*5113495bSYour Name 				struct wlan_objmgr_psoc *psoc,
4366*5113495bSYour Name 				uint8_t key_index,
4367*5113495bSYour Name 				struct wlan_crypto_key *crypto_key,
4368*5113495bSYour Name 				struct qdf_mac_addr *link_addr, uint8_t link_id)
4369*5113495bSYour Name {
4370*5113495bSYour Name 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
4371*5113495bSYour Name 	int status = QDF_STATUS_SUCCESS;
4372*5113495bSYour Name 
4373*5113495bSYour Name 	crypto_debug("save crypto key index %d link_id %d link addr "
4374*5113495bSYour Name 		     QDF_MAC_ADDR_FMT, key_index, link_id,
4375*5113495bSYour Name 		     QDF_MAC_ADDR_REF(link_addr->bytes));
4376*5113495bSYour Name 	if (!is_valid_keyix(key_index)) {
4377*5113495bSYour Name 		crypto_err("Invalid Key index %d", key_index);
4378*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4379*5113495bSYour Name 	}
4380*5113495bSYour Name 
4381*5113495bSYour Name 	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
4382*5113495bSYour Name 						psoc,
4383*5113495bSYour Name 						WLAN_UMAC_COMP_CRYPTO);
4384*5113495bSYour Name 	if (!crypto_psoc_obj) {
4385*5113495bSYour Name 		crypto_err("crypto_psoc_obj NULL");
4386*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4387*5113495bSYour Name 	}
4388*5113495bSYour Name 
4389*5113495bSYour Name 	crypto_key->valid = true;
4390*5113495bSYour Name 
4391*5113495bSYour Name 	status = crypto_add_entry(crypto_psoc_obj,
4392*5113495bSYour Name 				  link_id, (uint8_t *)link_addr,
4393*5113495bSYour Name 				  crypto_key, key_index);
4394*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4395*5113495bSYour Name 		crypto_err("failed to add crypto entry %d", status);
4396*5113495bSYour Name 		return status;
4397*5113495bSYour Name 	}
4398*5113495bSYour Name 	crypto_key->valid = true;
4399*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4400*5113495bSYour Name }
4401*5113495bSYour Name #else
wlan_crypto_save_ml_sta_key(struct wlan_objmgr_psoc * psoc,uint8_t key_index,struct wlan_crypto_key * crypto_key,struct qdf_mac_addr * link_addr,uint8_t link_id)4402*5113495bSYour Name QDF_STATUS wlan_crypto_save_ml_sta_key(
4403*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
4404*5113495bSYour Name 			uint8_t key_index,
4405*5113495bSYour Name 			struct wlan_crypto_key *crypto_key,
4406*5113495bSYour Name 			struct qdf_mac_addr *link_addr, uint8_t link_id)
4407*5113495bSYour Name {
4408*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4409*5113495bSYour Name }
4410*5113495bSYour Name #endif
4411*5113495bSYour Name 
4412*5113495bSYour Name /**
4413*5113495bSYour Name  * wlan_crypto_save_key_at_psoc() - Allocate memory for storing key in PSOC
4414*5113495bSYour Name  * @vdev: vdev object
4415*5113495bSYour Name  * @key_index: the index of the key that needs to be allocated
4416*5113495bSYour Name  * @crypto_key: Pointer to crypto key
4417*5113495bSYour Name  *
4418*5113495bSYour Name  * Return: QDF_STATUS
4419*5113495bSYour Name  */
4420*5113495bSYour Name static QDF_STATUS
wlan_crypto_save_key_at_psoc(struct wlan_objmgr_vdev * vdev,uint8_t key_index,struct wlan_crypto_key * crypto_key)4421*5113495bSYour Name wlan_crypto_save_key_at_psoc(struct wlan_objmgr_vdev *vdev, uint8_t key_index,
4422*5113495bSYour Name 			     struct wlan_crypto_key *crypto_key)
4423*5113495bSYour Name {
4424*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
4425*5113495bSYour Name 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
4426*5113495bSYour Name 	struct qdf_mac_addr *link_addr;
4427*5113495bSYour Name 	uint8_t link_id = CRYPTO_MAX_LINK_IDX;
4428*5113495bSYour Name 	int status = QDF_STATUS_SUCCESS;
4429*5113495bSYour Name 
4430*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
4431*5113495bSYour Name 	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
4432*5113495bSYour Name 			psoc,
4433*5113495bSYour Name 			WLAN_UMAC_COMP_CRYPTO);
4434*5113495bSYour Name 	if (!crypto_psoc_obj) {
4435*5113495bSYour Name 		crypto_err("crypto_psoc_obj NULL");
4436*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4437*5113495bSYour Name 	}
4438*5113495bSYour Name 
4439*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
4440*5113495bSYour Name 		link_id = wlan_vdev_get_link_id(vdev);
4441*5113495bSYour Name 
4442*5113495bSYour Name 	link_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_linkaddr(vdev);
4443*5113495bSYour Name 	if (!link_addr) {
4444*5113495bSYour Name 		crypto_err("link_addr NULL");
4445*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4446*5113495bSYour Name 	}
4447*5113495bSYour Name 
4448*5113495bSYour Name 	crypto_debug("save crypto key index %d link_id %d link addr "
4449*5113495bSYour Name 		     QDF_MAC_ADDR_FMT, key_index, link_id,
4450*5113495bSYour Name 		     QDF_MAC_ADDR_REF(link_addr->bytes));
4451*5113495bSYour Name 	status = crypto_add_entry(crypto_psoc_obj,
4452*5113495bSYour Name 				  link_id, (uint8_t *)link_addr,
4453*5113495bSYour Name 				  crypto_key, key_index);
4454*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4455*5113495bSYour Name 		crypto_err("failed to add crypto entry %d", status);
4456*5113495bSYour Name 		return status;
4457*5113495bSYour Name 	}
4458*5113495bSYour Name 
4459*5113495bSYour Name 	crypto_key->valid = true;
4460*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4461*5113495bSYour Name }
4462*5113495bSYour Name 
wlan_crypto_save_key(struct wlan_objmgr_vdev * vdev,uint8_t key_index,struct wlan_crypto_key * crypto_key)4463*5113495bSYour Name QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev,
4464*5113495bSYour Name 				uint8_t key_index,
4465*5113495bSYour Name 				struct wlan_crypto_key *crypto_key)
4466*5113495bSYour Name {
4467*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4468*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
4469*5113495bSYour Name 
4470*5113495bSYour Name 	crypto_priv = wlan_get_vdev_crypto_obj(vdev);
4471*5113495bSYour Name 	if (!crypto_priv) {
4472*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4473*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4474*5113495bSYour Name 	}
4475*5113495bSYour Name 
4476*5113495bSYour Name 	if (!is_valid_keyix(key_index)) {
4477*5113495bSYour Name 		crypto_err("Invalid Key index %d", key_index);
4478*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4479*5113495bSYour Name 	}
4480*5113495bSYour Name 	if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
4481*5113495bSYour Name 	     wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) &&
4482*5113495bSYour Name 	    wlan_vdev_mlme_is_mlo_vdev(vdev) &&
4483*5113495bSYour Name 	    is_mlo_adv_enable()) {
4484*5113495bSYour Name 		wlan_crypto_save_key_at_psoc(vdev, key_index, crypto_key);
4485*5113495bSYour Name 	} else {
4486*5113495bSYour Name 		priv_key = &crypto_priv->crypto_key;
4487*5113495bSYour Name 		if (key_index < WLAN_CRYPTO_MAXKEYIDX) {
4488*5113495bSYour Name 			priv_key->key[key_index] = crypto_key;
4489*5113495bSYour Name 		} else if (is_igtk(key_index)) {
4490*5113495bSYour Name 			priv_key->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX] =
4491*5113495bSYour Name 			crypto_key;
4492*5113495bSYour Name 			priv_key->def_igtk_tx_keyid =
4493*5113495bSYour Name 				key_index - WLAN_CRYPTO_MAXKEYIDX;
4494*5113495bSYour Name 			priv_key->igtk_key_type = crypto_key->cipher_type;
4495*5113495bSYour Name 		} else {
4496*5113495bSYour Name 			priv_key->bigtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX
4497*5113495bSYour Name 				- WLAN_CRYPTO_MAXIGTKKEYIDX] = crypto_key;
4498*5113495bSYour Name 			priv_key->def_bigtk_tx_keyid =
4499*5113495bSYour Name 				key_index - WLAN_CRYPTO_MAXKEYIDX
4500*5113495bSYour Name 				- WLAN_CRYPTO_MAXIGTKKEYIDX;
4501*5113495bSYour Name 		}
4502*5113495bSYour Name 		crypto_key->valid = true;
4503*5113495bSYour Name 	}
4504*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4505*5113495bSYour Name }
4506*5113495bSYour Name 
4507*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
wlan_crypto_get_ml_sta_link_key(struct wlan_objmgr_psoc * psoc,uint8_t key_index,struct qdf_mac_addr * link_addr,uint8_t link_id)4508*5113495bSYour Name struct wlan_crypto_key *wlan_crypto_get_ml_sta_link_key(
4509*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
4510*5113495bSYour Name 			uint8_t key_index,
4511*5113495bSYour Name 			struct qdf_mac_addr *link_addr, uint8_t link_id)
4512*5113495bSYour Name {
4513*5113495bSYour Name 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
4514*5113495bSYour Name 	struct wlan_crypto_key_entry *key_entry = NULL;
4515*5113495bSYour Name 
4516*5113495bSYour Name 	crypto_debug("crypto get key index %d link_id %d ", key_index, link_id);
4517*5113495bSYour Name 
4518*5113495bSYour Name 	if (!psoc) {
4519*5113495bSYour Name 		crypto_err("psoc NULL");
4520*5113495bSYour Name 		return NULL;
4521*5113495bSYour Name 	}
4522*5113495bSYour Name 
4523*5113495bSYour Name 	if (!link_addr) {
4524*5113495bSYour Name 		crypto_err("link_addr NULL");
4525*5113495bSYour Name 		return NULL;
4526*5113495bSYour Name 	}
4527*5113495bSYour Name 
4528*5113495bSYour Name 	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
4529*5113495bSYour Name 							psoc,
4530*5113495bSYour Name 							WLAN_UMAC_COMP_CRYPTO);
4531*5113495bSYour Name 	if (!crypto_psoc_obj) {
4532*5113495bSYour Name 		crypto_err("crypto_psoc_obj NULL");
4533*5113495bSYour Name 		return NULL;
4534*5113495bSYour Name 	}
4535*5113495bSYour Name 
4536*5113495bSYour Name 	key_entry = crypto_hash_find_by_linkid_and_macaddr(
4537*5113495bSYour Name 							crypto_psoc_obj,
4538*5113495bSYour Name 							link_id,
4539*5113495bSYour Name 							(uint8_t *)link_addr);
4540*5113495bSYour Name 	if (key_entry) {
4541*5113495bSYour Name 		if (key_index < WLAN_CRYPTO_MAXKEYIDX)
4542*5113495bSYour Name 			return key_entry->keys.key[key_index];
4543*5113495bSYour Name 		else if (is_igtk(key_index))
4544*5113495bSYour Name 			return key_entry->keys.igtk_key[key_index
4545*5113495bSYour Name 						- WLAN_CRYPTO_MAXKEYIDX];
4546*5113495bSYour Name 		else
4547*5113495bSYour Name 			return key_entry->keys.bigtk_key[key_index
4548*5113495bSYour Name 						- WLAN_CRYPTO_MAXKEYIDX
4549*5113495bSYour Name 						- WLAN_CRYPTO_MAXIGTKKEYIDX];
4550*5113495bSYour Name 	}
4551*5113495bSYour Name 	return NULL;
4552*5113495bSYour Name }
4553*5113495bSYour Name #else
wlan_crypto_get_ml_sta_link_key(struct wlan_objmgr_psoc * psoc,uint8_t key_index,struct qdf_mac_addr * link_addr,uint8_t link_id)4554*5113495bSYour Name struct wlan_crypto_key *wlan_crypto_get_ml_sta_link_key(
4555*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
4556*5113495bSYour Name 			uint8_t key_index,
4557*5113495bSYour Name 			struct qdf_mac_addr *link_addr, uint8_t link_id)
4558*5113495bSYour Name {
4559*5113495bSYour Name 	return NULL;
4560*5113495bSYour Name }
4561*5113495bSYour Name #endif
4562*5113495bSYour Name 
4563*5113495bSYour Name /**
4564*5113495bSYour Name  * wlan_crypto_get_ml_keys_from_index() - Get the stored key information from
4565*5113495bSYour Name  * key index
4566*5113495bSYour Name  * @vdev: vdev object
4567*5113495bSYour Name  * @key_index: the index of the key that needs to be retrieved
4568*5113495bSYour Name  *
4569*5113495bSYour Name  * Return: Key material
4570*5113495bSYour Name  */
4571*5113495bSYour Name static struct wlan_crypto_key *
wlan_crypto_get_ml_keys_from_index(struct wlan_objmgr_vdev * vdev,uint8_t key_index)4572*5113495bSYour Name wlan_crypto_get_ml_keys_from_index(struct wlan_objmgr_vdev *vdev,
4573*5113495bSYour Name 				   uint8_t key_index)
4574*5113495bSYour Name {
4575*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
4576*5113495bSYour Name 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
4577*5113495bSYour Name 	struct qdf_mac_addr *link_addr;
4578*5113495bSYour Name 	struct wlan_crypto_key_entry *key_entry = NULL;
4579*5113495bSYour Name 	uint8_t link_id = CRYPTO_MAX_LINK_IDX;
4580*5113495bSYour Name 
4581*5113495bSYour Name 	crypto_debug("crypto get key index %d", key_index);
4582*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
4583*5113495bSYour Name 	if (!psoc) {
4584*5113495bSYour Name 		crypto_err("psoc NULL");
4585*5113495bSYour Name 		return NULL;
4586*5113495bSYour Name 	}
4587*5113495bSYour Name 
4588*5113495bSYour Name 	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
4589*5113495bSYour Name 							psoc,
4590*5113495bSYour Name 							WLAN_UMAC_COMP_CRYPTO);
4591*5113495bSYour Name 	if (!crypto_psoc_obj) {
4592*5113495bSYour Name 		crypto_err("crypto_psoc_obj NULL");
4593*5113495bSYour Name 		return NULL;
4594*5113495bSYour Name 	}
4595*5113495bSYour Name 
4596*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
4597*5113495bSYour Name 		link_id = wlan_vdev_get_link_id(vdev);
4598*5113495bSYour Name 
4599*5113495bSYour Name 	link_addr =
4600*5113495bSYour Name 		(struct qdf_mac_addr *)wlan_vdev_mlme_get_linkaddr(vdev);
4601*5113495bSYour Name 	if (!link_addr) {
4602*5113495bSYour Name 		crypto_err("link_addr NULL");
4603*5113495bSYour Name 		return NULL;
4604*5113495bSYour Name 	}
4605*5113495bSYour Name 
4606*5113495bSYour Name 	key_entry = crypto_hash_find_by_linkid_and_macaddr(
4607*5113495bSYour Name 						       crypto_psoc_obj,
4608*5113495bSYour Name 						       link_id,
4609*5113495bSYour Name 						       (uint8_t *)link_addr);
4610*5113495bSYour Name 	if (key_entry) {
4611*5113495bSYour Name 		if (key_index < WLAN_CRYPTO_MAXKEYIDX)
4612*5113495bSYour Name 			return key_entry->keys.key[key_index];
4613*5113495bSYour Name 		else if (is_igtk(key_index))
4614*5113495bSYour Name 			return key_entry->keys.igtk_key[key_index
4615*5113495bSYour Name 						- WLAN_CRYPTO_MAXKEYIDX];
4616*5113495bSYour Name 		else
4617*5113495bSYour Name 			return key_entry->keys.bigtk_key[key_index
4618*5113495bSYour Name 						- WLAN_CRYPTO_MAXKEYIDX
4619*5113495bSYour Name 						- WLAN_CRYPTO_MAXIGTKKEYIDX];
4620*5113495bSYour Name 	}
4621*5113495bSYour Name 
4622*5113495bSYour Name 	return NULL;
4623*5113495bSYour Name }
4624*5113495bSYour Name 
wlan_crypto_get_key(struct wlan_objmgr_vdev * vdev,uint8_t key_index)4625*5113495bSYour Name struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev,
4626*5113495bSYour Name 					    uint8_t key_index)
4627*5113495bSYour Name {
4628*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4629*5113495bSYour Name 	struct wlan_crypto_keys *priv_key = NULL;
4630*5113495bSYour Name 
4631*5113495bSYour Name 	crypto_priv = wlan_get_vdev_crypto_obj(vdev);
4632*5113495bSYour Name 	if (!crypto_priv) {
4633*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4634*5113495bSYour Name 		return NULL;
4635*5113495bSYour Name 	}
4636*5113495bSYour Name 	priv_key = &crypto_priv->crypto_key;
4637*5113495bSYour Name 
4638*5113495bSYour Name 	if (!is_valid_keyix(key_index)) {
4639*5113495bSYour Name 		crypto_err("Invalid Key index %d", key_index);
4640*5113495bSYour Name 		return NULL;
4641*5113495bSYour Name 	}
4642*5113495bSYour Name 
4643*5113495bSYour Name 	if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
4644*5113495bSYour Name 	     wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) &&
4645*5113495bSYour Name 	    wlan_vdev_mlme_is_mlo_vdev(vdev) &&
4646*5113495bSYour Name 	    is_mlo_adv_enable()) {
4647*5113495bSYour Name 		return wlan_crypto_get_ml_keys_from_index(vdev, key_index);
4648*5113495bSYour Name 	} else {
4649*5113495bSYour Name 		if (key_index < WLAN_CRYPTO_MAXKEYIDX)
4650*5113495bSYour Name 			return priv_key->key[key_index];
4651*5113495bSYour Name 		else if (is_igtk(key_index))
4652*5113495bSYour Name 			return priv_key->igtk_key[key_index
4653*5113495bSYour Name 					- WLAN_CRYPTO_MAXKEYIDX];
4654*5113495bSYour Name 		else
4655*5113495bSYour Name 			return priv_key->bigtk_key[key_index
4656*5113495bSYour Name 					- WLAN_CRYPTO_MAXKEYIDX
4657*5113495bSYour Name 						- WLAN_CRYPTO_MAXIGTKKEYIDX];
4658*5113495bSYour Name 	}
4659*5113495bSYour Name 	return NULL;
4660*5113495bSYour Name }
4661*5113495bSYour Name 
wlan_crypto_set_key_req(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_key * req,enum wlan_crypto_key_type key_type)4662*5113495bSYour Name QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
4663*5113495bSYour Name 				   struct wlan_crypto_key *req,
4664*5113495bSYour Name 				   enum wlan_crypto_key_type key_type)
4665*5113495bSYour Name {
4666*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
4667*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
4668*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4669*5113495bSYour Name 
4670*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
4671*5113495bSYour Name 
4672*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
4673*5113495bSYour Name 	if (!tx_ops) {
4674*5113495bSYour Name 		crypto_err("tx_ops is NULL");
4675*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4676*5113495bSYour Name 	}
4677*5113495bSYour Name 
4678*5113495bSYour Name 	if (psoc && WLAN_CRYPTO_TX_OPS_SET_KEY(tx_ops))
4679*5113495bSYour Name 		status = WLAN_CRYPTO_TX_OPS_SET_KEY(tx_ops)(vdev, req,
4680*5113495bSYour Name 							    key_type);
4681*5113495bSYour Name 
4682*5113495bSYour Name 	return status;
4683*5113495bSYour Name }
4684*5113495bSYour Name 
wlan_crypto_update_set_key_peer(struct wlan_objmgr_vdev * vdev,bool pairwise,uint8_t key_index,struct qdf_mac_addr * peer_mac)4685*5113495bSYour Name void wlan_crypto_update_set_key_peer(struct wlan_objmgr_vdev *vdev,
4686*5113495bSYour Name 				     bool pairwise, uint8_t key_index,
4687*5113495bSYour Name 				     struct qdf_mac_addr *peer_mac)
4688*5113495bSYour Name {
4689*5113495bSYour Name 	struct wlan_crypto_key *crypto_key;
4690*5113495bSYour Name 
4691*5113495bSYour Name 	crypto_key = wlan_crypto_get_key(vdev, key_index);
4692*5113495bSYour Name 	if (!crypto_key) {
4693*5113495bSYour Name 		crypto_err("crypto_key not present for key_idx %d", key_index);
4694*5113495bSYour Name 		return;
4695*5113495bSYour Name 	}
4696*5113495bSYour Name 
4697*5113495bSYour Name 	qdf_mem_copy(crypto_key->macaddr, peer_mac, QDF_MAC_ADDR_SIZE);
4698*5113495bSYour Name }
4699*5113495bSYour Name 
4700*5113495bSYour Name #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
wlan_crypto_selective_clear_sae_single_pmk_entries(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * conn_bssid)4701*5113495bSYour Name void wlan_crypto_selective_clear_sae_single_pmk_entries(
4702*5113495bSYour Name 			struct wlan_objmgr_vdev *vdev,
4703*5113495bSYour Name 			struct qdf_mac_addr *conn_bssid)
4704*5113495bSYour Name {
4705*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
4706*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4707*5113495bSYour Name 	int i;
4708*5113495bSYour Name 
4709*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
4710*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
4711*5113495bSYour Name 
4712*5113495bSYour Name 	if (!crypto_priv) {
4713*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4714*5113495bSYour Name 		return;
4715*5113495bSYour Name 	}
4716*5113495bSYour Name 
4717*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
4718*5113495bSYour Name 
4719*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
4720*5113495bSYour Name 		if (!crypto_params->pmksa[i])
4721*5113495bSYour Name 			continue;
4722*5113495bSYour Name 
4723*5113495bSYour Name 		if (crypto_params->pmksa[i]->single_pmk_supported &&
4724*5113495bSYour Name 		    !qdf_is_macaddr_equal(conn_bssid,
4725*5113495bSYour Name 					  &crypto_params->pmksa[i]->bssid)) {
4726*5113495bSYour Name 			qdf_mem_zero(crypto_params->pmksa[i],
4727*5113495bSYour Name 				     sizeof(struct wlan_crypto_pmksa));
4728*5113495bSYour Name 			qdf_mem_free(crypto_params->pmksa[i]);
4729*5113495bSYour Name 			crypto_params->pmksa[i] = NULL;
4730*5113495bSYour Name 		}
4731*5113495bSYour Name 	}
4732*5113495bSYour Name }
4733*5113495bSYour Name 
wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bssid,bool single_pmk_capable_bss)4734*5113495bSYour Name void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev,
4735*5113495bSYour Name 					    struct qdf_mac_addr *bssid,
4736*5113495bSYour Name 					    bool single_pmk_capable_bss)
4737*5113495bSYour Name {
4738*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
4739*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4740*5113495bSYour Name 	int i;
4741*5113495bSYour Name 
4742*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
4743*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
4744*5113495bSYour Name 
4745*5113495bSYour Name 	if (!crypto_priv) {
4746*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4747*5113495bSYour Name 		return;
4748*5113495bSYour Name 	}
4749*5113495bSYour Name 
4750*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
4751*5113495bSYour Name 
4752*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
4753*5113495bSYour Name 		if (!crypto_params->pmksa[i])
4754*5113495bSYour Name 			continue;
4755*5113495bSYour Name 
4756*5113495bSYour Name 		if (qdf_is_macaddr_equal(bssid,
4757*5113495bSYour Name 					 &crypto_params->pmksa[i]->bssid))
4758*5113495bSYour Name 			crypto_params->pmksa[i]->single_pmk_supported =
4759*5113495bSYour Name 					single_pmk_capable_bss;
4760*5113495bSYour Name 	}
4761*5113495bSYour Name }
4762*5113495bSYour Name 
4763*5113495bSYour Name void
wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * roam_sync_pmksa)4764*5113495bSYour Name wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev,
4765*5113495bSYour Name 				    struct wlan_crypto_pmksa *roam_sync_pmksa)
4766*5113495bSYour Name {
4767*5113495bSYour Name 	struct wlan_crypto_params *crypto_params;
4768*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4769*5113495bSYour Name 	int i;
4770*5113495bSYour Name 
4771*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
4772*5113495bSYour Name 					wlan_get_vdev_crypto_obj(vdev);
4773*5113495bSYour Name 
4774*5113495bSYour Name 	if (!crypto_priv) {
4775*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4776*5113495bSYour Name 		return;
4777*5113495bSYour Name 	}
4778*5113495bSYour Name 
4779*5113495bSYour Name 	crypto_params = &crypto_priv->crypto_params;
4780*5113495bSYour Name 
4781*5113495bSYour Name 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
4782*5113495bSYour Name 		if (!crypto_params->pmksa[i])
4783*5113495bSYour Name 			continue;
4784*5113495bSYour Name 		if (qdf_is_macaddr_equal(&roam_sync_pmksa->bssid,
4785*5113495bSYour Name 					 &crypto_params->pmksa[i]->bssid) &&
4786*5113495bSYour Name 		    roam_sync_pmksa->single_pmk_supported &&
4787*5113495bSYour Name 		    roam_sync_pmksa->pmk_len) {
4788*5113495bSYour Name 			crypto_params->pmksa[i]->single_pmk_supported =
4789*5113495bSYour Name 					roam_sync_pmksa->single_pmk_supported;
4790*5113495bSYour Name 			crypto_params->pmksa[i]->pmk_len =
4791*5113495bSYour Name 						roam_sync_pmksa->pmk_len;
4792*5113495bSYour Name 			qdf_mem_copy(crypto_params->pmksa[i]->pmk,
4793*5113495bSYour Name 				     roam_sync_pmksa->pmk,
4794*5113495bSYour Name 				     roam_sync_pmksa->pmk_len);
4795*5113495bSYour Name 		}
4796*5113495bSYour Name 	}
4797*5113495bSYour Name }
4798*5113495bSYour Name 
4799*5113495bSYour Name #endif
4800*5113495bSYour Name 
wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev * vdev)4801*5113495bSYour Name void wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev *vdev)
4802*5113495bSYour Name {
4803*5113495bSYour Name 	struct wlan_crypto_comp_priv *crypto_priv;
4804*5113495bSYour Name 
4805*5113495bSYour Name 	crypto_debug("reset params for vdev %d", wlan_vdev_get_id(vdev));
4806*5113495bSYour Name 	crypto_priv = (struct wlan_crypto_comp_priv *)
4807*5113495bSYour Name 		       wlan_get_vdev_crypto_obj(vdev);
4808*5113495bSYour Name 
4809*5113495bSYour Name 	if (!crypto_priv) {
4810*5113495bSYour Name 		crypto_err("crypto_priv NULL");
4811*5113495bSYour Name 		return;
4812*5113495bSYour Name 	}
4813*5113495bSYour Name 
4814*5113495bSYour Name 	wlan_crypto_reset_prarams(&crypto_priv->crypto_params);
4815*5113495bSYour Name }
4816*5113495bSYour Name 
wlan_crypto_psoc_enable(struct wlan_objmgr_psoc * psoc)4817*5113495bSYour Name QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc)
4818*5113495bSYour Name {
4819*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
4820*5113495bSYour Name 
4821*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
4822*5113495bSYour Name 	if (!tx_ops) {
4823*5113495bSYour Name 		crypto_err("tx_ops is NULL");
4824*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4825*5113495bSYour Name 	}
4826*5113495bSYour Name 
4827*5113495bSYour Name 	if (WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(tx_ops))
4828*5113495bSYour Name 		return WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(tx_ops)(psoc);
4829*5113495bSYour Name 
4830*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
4831*5113495bSYour Name }
4832*5113495bSYour Name 
wlan_crypto_psoc_disable(struct wlan_objmgr_psoc * psoc)4833*5113495bSYour Name QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc)
4834*5113495bSYour Name {
4835*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
4836*5113495bSYour Name 
4837*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
4838*5113495bSYour Name 	if (!tx_ops) {
4839*5113495bSYour Name 		crypto_err("tx_ops is NULL");
4840*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4841*5113495bSYour Name 	}
4842*5113495bSYour Name 
4843*5113495bSYour Name 	if (WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(tx_ops))
4844*5113495bSYour Name 		return WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(tx_ops)(psoc);
4845*5113495bSYour Name 
4846*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
4847*5113495bSYour Name }
4848*5113495bSYour Name #endif
4849*5113495bSYour Name 
4850*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
wlan_crypto_create_fils_rik(uint8_t * rrk,uint8_t rrk_len,uint8_t * rik,uint32_t * rik_len)4851*5113495bSYour Name QDF_STATUS wlan_crypto_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
4852*5113495bSYour Name 				       uint8_t *rik, uint32_t *rik_len)
4853*5113495bSYour Name {
4854*5113495bSYour Name 	uint8_t optional_data[WLAN_CRYPTO_FILS_OPTIONAL_DATA_LEN];
4855*5113495bSYour Name 	uint8_t label[] = WLAN_CRYPTO_FILS_RIK_LABEL;
4856*5113495bSYour Name 	QDF_STATUS status;
4857*5113495bSYour Name 
4858*5113495bSYour Name 	if (!rrk || !rik) {
4859*5113495bSYour Name 		crypto_err("FILS rrk/rik NULL");
4860*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4861*5113495bSYour Name 	}
4862*5113495bSYour Name 
4863*5113495bSYour Name 	optional_data[0] = HMAC_SHA256_128;
4864*5113495bSYour Name 	/* basic validation */
4865*5113495bSYour Name 	if (rrk_len <= 0) {
4866*5113495bSYour Name 		crypto_err("invalid r_rk length %d", rrk_len);
4867*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4868*5113495bSYour Name 	}
4869*5113495bSYour Name 
4870*5113495bSYour Name 	wlan_crypto_put_be16(&optional_data[1], rrk_len);
4871*5113495bSYour Name 	status = qdf_default_hmac_sha256_kdf(rrk, rrk_len, label, optional_data,
4872*5113495bSYour Name 					     sizeof(optional_data), rik,
4873*5113495bSYour Name 					     rrk_len);
4874*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4875*5113495bSYour Name 		crypto_err("failed to create rik");
4876*5113495bSYour Name 		return status;
4877*5113495bSYour Name 	}
4878*5113495bSYour Name 	*rik_len = rrk_len;
4879*5113495bSYour Name 
4880*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4881*5113495bSYour Name }
4882*5113495bSYour Name #endif /* WLAN_FEATURE_FILS_SK */
4883*5113495bSYour Name 
4884*5113495bSYour Name #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
4885*5113495bSYour Name QDF_STATUS
wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc * psoc,struct wlan_crypto_ltf_keyseed_data * data)4886*5113495bSYour Name wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc,
4887*5113495bSYour Name 			    struct wlan_crypto_ltf_keyseed_data *data)
4888*5113495bSYour Name {
4889*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4890*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
4891*5113495bSYour Name 
4892*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
4893*5113495bSYour Name 	if (!tx_ops) {
4894*5113495bSYour Name 		crypto_err("tx_ops is NULL");
4895*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4896*5113495bSYour Name 	}
4897*5113495bSYour Name 
4898*5113495bSYour Name 	if (WLAN_CRYPTO_TX_OPS_SET_LTF_KEYSEED(tx_ops))
4899*5113495bSYour Name 		status = WLAN_CRYPTO_TX_OPS_SET_LTF_KEYSEED(tx_ops)(psoc, data);
4900*5113495bSYour Name 
4901*5113495bSYour Name 	return status;
4902*5113495bSYour Name }
4903*5113495bSYour Name #endif
4904*5113495bSYour Name 
4905*5113495bSYour Name QDF_STATUS
wlan_crypto_vdev_set_param(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t param_id,uint32_t param_value)4906*5113495bSYour Name wlan_crypto_vdev_set_param(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id,
4907*5113495bSYour Name 			   uint32_t param_id, uint32_t param_value)
4908*5113495bSYour Name {
4909*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4910*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
4911*5113495bSYour Name 
4912*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
4913*5113495bSYour Name 	if (!tx_ops) {
4914*5113495bSYour Name 		crypto_err("tx_ops is NULL");
4915*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4916*5113495bSYour Name 	}
4917*5113495bSYour Name 
4918*5113495bSYour Name 	if (WLAN_CRYPTO_TX_OPS_SET_VDEV_PARAM(tx_ops))
4919*5113495bSYour Name 		status = WLAN_CRYPTO_TX_OPS_SET_VDEV_PARAM(tx_ops) (psoc,
4920*5113495bSYour Name 								    vdev_id,
4921*5113495bSYour Name 								    param_id,
4922*5113495bSYour Name 								    param_value);
4923*5113495bSYour Name 
4924*5113495bSYour Name 	return status;
4925*5113495bSYour Name }
4926