xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c (revision 8b3dca18206e1a0461492f082fa6e270b092c035)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20  /**
21  * DOC: Public API intialization of crypto service with object manager
22  */
23 #include <qdf_types.h>
24 #include <wlan_cmn.h>
25 #include <wlan_objmgr_cmn.h>
26 
27 #include <wlan_objmgr_global_obj.h>
28 #include <wlan_objmgr_psoc_obj.h>
29 #include <wlan_objmgr_pdev_obj.h>
30 #include <wlan_objmgr_vdev_obj.h>
31 #include <wlan_objmgr_peer_obj.h>
32 
33 #include "wlan_crypto_global_def.h"
34 #include "wlan_crypto_global_api.h"
35 #include "wlan_crypto_def_i.h"
36 #include "wlan_crypto_main_i.h"
37 #include "wlan_crypto_obj_mgr_i.h"
38 #ifdef WLAN_CRYPTO_SUPPORT_FILS
39 #include "wlan_crypto_fils_api.h"
40 #endif
41 
42 
43 extern const struct wlan_crypto_cipher
44 				*wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
45 
46 static QDF_STATUS wlan_crypto_register_all_ciphers(
47 					struct wlan_crypto_params *crypto_param)
48 {
49 
50 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) {
51 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP]
52 							= wep_register();
53 	}
54 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) {
55 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP]
56 							= tkip_register();
57 	}
58 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) {
59 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM]
60 							= ccmp_register();
61 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256]
62 							= ccmp256_register();
63 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM]
64 							= gcmp_register();
65 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256]
66 							= gcmp256_register();
67 	}
68 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) {
69 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4]
70 							= wapi_register();
71 	}
72 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD)) {
73 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_FILS_AEAD]
74 							= fils_register();
75 	}
76 
77 	return QDF_STATUS_SUCCESS;
78 }
79 
80 static QDF_STATUS wlan_crypto_vdev_obj_create_handler(
81 						struct wlan_objmgr_vdev *vdev,
82 						void *arg)
83 {
84 	struct wlan_crypto_comp_priv *crypto_priv;
85 	struct wlan_objmgr_pdev *pdev;
86 	struct wlan_crypto_params *crypto_param;
87 	QDF_STATUS status;
88 
89 	if (!vdev)
90 		return QDF_STATUS_E_INVAL;
91 
92 	crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
93 	if (!crypto_priv)
94 		return QDF_STATUS_E_NOMEM;
95 
96 	crypto_param = &(crypto_priv->crypto_params);
97 
98 	RESET_AUTHMODE(crypto_param);
99 	RESET_UCAST_CIPHERS(crypto_param);
100 	RESET_MCAST_CIPHERS(crypto_param);
101 	RESET_MGMT_CIPHERS(crypto_param);
102 	RESET_KEY_MGMT(crypto_param);
103 	RESET_CIPHER_CAP(crypto_param);
104 
105 	pdev = wlan_vdev_get_pdev(vdev);
106 	wlan_pdev_obj_lock(pdev);
107 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP))
108 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP);
109 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP))
110 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC);
111 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) {
112 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES);
113 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256);
114 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM);
115 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256);
116 	}
117 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP))
118 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP);
119 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI))
120 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4);
121 	SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD);
122 	wlan_pdev_obj_unlock(pdev);
123 	/* update the crypto cipher table based on the fw caps*/
124 	/* update the fw_caps into ciphercaps then attach to objmgr*/
125 	wlan_crypto_register_all_ciphers(crypto_param);
126 
127 	status = wlan_objmgr_vdev_component_obj_attach(vdev,
128 							WLAN_UMAC_COMP_CRYPTO,
129 							(void *)crypto_priv,
130 							QDF_STATUS_SUCCESS);
131 	if (status != QDF_STATUS_SUCCESS)
132 		qdf_mem_free(crypto_priv);
133 
134 	return status;
135 }
136 
137 static QDF_STATUS wlan_crypto_peer_obj_create_handler(
138 						struct wlan_objmgr_peer *peer,
139 						void *arg)
140 {
141 	struct wlan_crypto_comp_priv *crypto_priv;
142 	struct wlan_crypto_params *crypto_param;
143 	QDF_STATUS status;
144 
145 	if (!peer)
146 		return QDF_STATUS_E_INVAL;
147 
148 	crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
149 	if (!crypto_priv)
150 		return QDF_STATUS_E_NOMEM;
151 
152 	status = wlan_objmgr_peer_component_obj_attach(peer,
153 				WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv,
154 				QDF_STATUS_SUCCESS);
155 
156 	if (status == QDF_STATUS_SUCCESS) {
157 		crypto_param = &crypto_priv->crypto_params;
158 		RESET_AUTHMODE(crypto_param);
159 		RESET_UCAST_CIPHERS(crypto_param);
160 		RESET_MCAST_CIPHERS(crypto_param);
161 		RESET_MGMT_CIPHERS(crypto_param);
162 		RESET_KEY_MGMT(crypto_param);
163 		RESET_CIPHER_CAP(crypto_param);
164 		if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) {
165 			wlan_crypto_set_peer_wep_keys(
166 					wlan_peer_get_vdev(peer), peer);
167 		}
168 	} else {
169 		crypto_err("peer obj failed status %d", status);
170 		qdf_mem_free(crypto_priv);
171 	}
172 
173 	return status;
174 }
175 
176 static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv)
177 {
178 	uint8_t i;
179 
180 	if (!crypto_priv) {
181 		crypto_err("crypto_priv NULL");
182 		return;
183 	}
184 
185 	for (i = 0; i < WLAN_CRYPTO_MAX_VLANKEYIX; i++) {
186 		if (crypto_priv->key[i]) {
187 			qdf_mem_free(crypto_priv->key[i]);
188 			crypto_priv->key[i] = NULL;
189 		}
190 	}
191 
192 	for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) {
193 		if (crypto_priv->igtk_key[i]) {
194 			qdf_mem_free(crypto_priv->igtk_key[i]);
195 			crypto_priv->igtk_key[i] = NULL;
196 		}
197 	}
198 
199 	for (i = 0; i < WLAN_CRYPTO_MAXBIGTKKEYIDX; i++) {
200 		if (crypto_priv->bigtk_key[i]) {
201 			qdf_mem_free(crypto_priv->bigtk_key[i]);
202 			crypto_priv->bigtk_key[i] = NULL;
203 		}
204 	}
205 	/* Reset All key index as well */
206 	crypto_priv->def_tx_keyid = 0;
207 	crypto_priv->def_igtk_tx_keyid = 0;
208 	crypto_priv->def_bigtk_tx_keyid = 0;
209 }
210 
211 #ifdef CRYPTO_SET_KEY_CONVERGED
212 void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev)
213 {
214 	struct wlan_crypto_comp_priv *crypto_priv;
215 
216 	crypto_debug("free key for vdev %d", wlan_vdev_get_id(vdev));
217 	crypto_priv = wlan_get_vdev_crypto_obj(vdev);
218 	if (!crypto_priv) {
219 		crypto_err("crypto_priv NULL");
220 		return;
221 	}
222 
223 	wlan_crypto_free_key(crypto_priv);
224 }
225 #endif
226 
227 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler(
228 						struct wlan_objmgr_vdev *vdev,
229 						void *arg){
230 	struct wlan_crypto_comp_priv *crypto_priv;
231 
232 	if (!vdev) {
233 		crypto_err("Vdev NULL");
234 		return QDF_STATUS_E_INVAL;
235 	}
236 
237 	crypto_priv = (struct wlan_crypto_comp_priv *)
238 				wlan_get_vdev_crypto_obj(vdev);
239 
240 	if (!crypto_priv) {
241 		crypto_err("crypto_priv NULL");
242 		return QDF_STATUS_E_INVAL;
243 	}
244 
245 	wlan_objmgr_vdev_component_obj_detach(vdev,
246 						WLAN_UMAC_COMP_CRYPTO,
247 						(void *)crypto_priv);
248 
249 	wlan_crypto_pmksa_flush(&crypto_priv->crypto_params);
250 	wlan_crypto_free_key(crypto_priv);
251 	qdf_mem_free(crypto_priv);
252 
253 	return QDF_STATUS_SUCCESS;
254 }
255 
256 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler(
257 						struct wlan_objmgr_peer *peer,
258 						void *arg){
259 	struct wlan_crypto_comp_priv *crypto_priv;
260 
261 	if (!peer) {
262 		crypto_err("Peer NULL");
263 		return QDF_STATUS_E_INVAL;
264 	}
265 	crypto_priv = (struct wlan_crypto_comp_priv *)
266 				wlan_get_peer_crypto_obj(peer);
267 	if (!crypto_priv) {
268 		crypto_err("crypto_priv NULL");
269 		return QDF_STATUS_E_INVAL;
270 	}
271 
272 	wlan_objmgr_peer_component_obj_detach(peer,
273 						WLAN_UMAC_COMP_CRYPTO,
274 						(void *)crypto_priv);
275 	wlan_crypto_free_key(crypto_priv);
276 	qdf_mem_free(crypto_priv);
277 
278 	return QDF_STATUS_SUCCESS;
279 }
280 /**
281  * __wlan_crypto_init - Init the crypto service with object manager
282  *                    Called from crypto init context.
283  *
284  * Return: QDF_STATUS_SUCCESS - in case of success
285  */
286 QDF_STATUS __wlan_crypto_init(void)
287 {
288 	QDF_STATUS status = QDF_STATUS_SUCCESS;
289 
290 	status = wlan_objmgr_register_vdev_create_handler(
291 				WLAN_UMAC_COMP_CRYPTO,
292 				wlan_crypto_vdev_obj_create_handler, NULL);
293 	if (status != QDF_STATUS_SUCCESS)
294 		return status;
295 
296 	status = wlan_objmgr_register_peer_create_handler(
297 				WLAN_UMAC_COMP_CRYPTO,
298 				wlan_crypto_peer_obj_create_handler, NULL);
299 	if (status != QDF_STATUS_SUCCESS)
300 		goto err_peer_create;
301 
302 	status = wlan_objmgr_register_vdev_destroy_handler(
303 				WLAN_UMAC_COMP_CRYPTO,
304 				wlan_crypto_vdev_obj_destroy_handler, NULL);
305 	if (status != QDF_STATUS_SUCCESS)
306 		goto err_vdev_delete;
307 
308 	status = wlan_objmgr_register_peer_destroy_handler(
309 				WLAN_UMAC_COMP_CRYPTO,
310 				wlan_crypto_peer_obj_destroy_handler, NULL);
311 	if (status != QDF_STATUS_SUCCESS)
312 		goto err_peer_delete;
313 
314 	goto register_success;
315 err_peer_delete:
316 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
317 			wlan_crypto_vdev_obj_destroy_handler, NULL);
318 err_vdev_delete:
319 	wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
320 			wlan_crypto_peer_obj_create_handler, NULL);
321 err_peer_create:
322 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
323 			wlan_crypto_vdev_obj_create_handler, NULL);
324 
325 register_success:
326 	return status;
327 }
328 
329 /**
330  * __wlan_crypto_deinit - Deinit the crypto service with object manager
331  *                         Called from crypto context.
332  *
333  * Return: QDF_STATUS_SUCCESS - in case of success
334  */
335 QDF_STATUS __wlan_crypto_deinit(void)
336 {
337 
338 	if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
339 			wlan_crypto_vdev_obj_create_handler, NULL)
340 			!= QDF_STATUS_SUCCESS) {
341 		return QDF_STATUS_E_FAILURE;
342 	}
343 
344 	if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
345 			wlan_crypto_peer_obj_create_handler, NULL)
346 			!= QDF_STATUS_SUCCESS) {
347 		return QDF_STATUS_E_FAILURE;
348 	}
349 
350 	if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
351 			wlan_crypto_vdev_obj_destroy_handler, NULL)
352 			!= QDF_STATUS_SUCCESS) {
353 		return QDF_STATUS_E_FAILURE;
354 	}
355 
356 	if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
357 			wlan_crypto_peer_obj_destroy_handler, NULL)
358 			!= QDF_STATUS_SUCCESS) {
359 		return QDF_STATUS_E_FAILURE;
360 	}
361 
362 	return QDF_STATUS_SUCCESS;
363 }
364