xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: Public API initialization of crypto service with object manager
22  */
23 #include <qdf_types.h>
24 #include <wlan_cmn.h>
25 #include <wlan_objmgr_cmn.h>
26 
27 #include <wlan_objmgr_global_obj.h>
28 #include <wlan_objmgr_psoc_obj.h>
29 #include <wlan_objmgr_pdev_obj.h>
30 #include <wlan_objmgr_vdev_obj.h>
31 #include <wlan_objmgr_peer_obj.h>
32 
33 #include "wlan_crypto_global_def.h"
34 #include "wlan_crypto_global_api.h"
35 #include "wlan_crypto_def_i.h"
36 #include "wlan_crypto_main_i.h"
37 #include "wlan_crypto_obj_mgr_i.h"
38 #ifdef WLAN_CRYPTO_SUPPORT_FILS
39 #include "wlan_crypto_fils_api.h"
40 #endif
41 
42 
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 {
231 	struct wlan_crypto_comp_priv *crypto_priv;
232 
233 	if (!vdev) {
234 		crypto_err("Vdev NULL");
235 		return QDF_STATUS_E_INVAL;
236 	}
237 
238 	crypto_priv = (struct wlan_crypto_comp_priv *)
239 				wlan_get_vdev_crypto_obj(vdev);
240 
241 	if (!crypto_priv) {
242 		crypto_err("crypto_priv NULL");
243 		return QDF_STATUS_E_INVAL;
244 	}
245 
246 	wlan_objmgr_vdev_component_obj_detach(vdev,
247 						WLAN_UMAC_COMP_CRYPTO,
248 						(void *)crypto_priv);
249 
250 	wlan_crypto_pmksa_flush(&crypto_priv->crypto_params);
251 	wlan_crypto_free_key(crypto_priv);
252 	qdf_mem_free(crypto_priv);
253 
254 	return QDF_STATUS_SUCCESS;
255 }
256 
257 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler(
258 						struct wlan_objmgr_peer *peer,
259 						void *arg)
260 {
261 	struct wlan_crypto_comp_priv *crypto_priv;
262 
263 	if (!peer) {
264 		crypto_err("Peer NULL");
265 		return QDF_STATUS_E_INVAL;
266 	}
267 	crypto_priv = (struct wlan_crypto_comp_priv *)
268 				wlan_get_peer_crypto_obj(peer);
269 	if (!crypto_priv) {
270 		crypto_err("crypto_priv NULL");
271 		return QDF_STATUS_E_INVAL;
272 	}
273 
274 	wlan_objmgr_peer_component_obj_detach(peer,
275 						WLAN_UMAC_COMP_CRYPTO,
276 						(void *)crypto_priv);
277 	wlan_crypto_free_key(crypto_priv);
278 	qdf_mem_free(crypto_priv);
279 
280 	return QDF_STATUS_SUCCESS;
281 }
282 
283 QDF_STATUS __wlan_crypto_init(void)
284 {
285 	QDF_STATUS status = QDF_STATUS_SUCCESS;
286 
287 	status = wlan_objmgr_register_vdev_create_handler(
288 				WLAN_UMAC_COMP_CRYPTO,
289 				wlan_crypto_vdev_obj_create_handler, NULL);
290 	if (status != QDF_STATUS_SUCCESS)
291 		return status;
292 
293 	status = wlan_objmgr_register_peer_create_handler(
294 				WLAN_UMAC_COMP_CRYPTO,
295 				wlan_crypto_peer_obj_create_handler, NULL);
296 	if (status != QDF_STATUS_SUCCESS)
297 		goto err_peer_create;
298 
299 	status = wlan_objmgr_register_vdev_destroy_handler(
300 				WLAN_UMAC_COMP_CRYPTO,
301 				wlan_crypto_vdev_obj_destroy_handler, NULL);
302 	if (status != QDF_STATUS_SUCCESS)
303 		goto err_vdev_delete;
304 
305 	status = wlan_objmgr_register_peer_destroy_handler(
306 				WLAN_UMAC_COMP_CRYPTO,
307 				wlan_crypto_peer_obj_destroy_handler, NULL);
308 	if (status != QDF_STATUS_SUCCESS)
309 		goto err_peer_delete;
310 
311 	goto register_success;
312 err_peer_delete:
313 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
314 			wlan_crypto_vdev_obj_destroy_handler, NULL);
315 err_vdev_delete:
316 	wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
317 			wlan_crypto_peer_obj_create_handler, NULL);
318 err_peer_create:
319 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
320 			wlan_crypto_vdev_obj_create_handler, NULL);
321 
322 register_success:
323 	return status;
324 }
325 
326 QDF_STATUS __wlan_crypto_deinit(void)
327 {
328 
329 	if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
330 			wlan_crypto_vdev_obj_create_handler, NULL)
331 			!= QDF_STATUS_SUCCESS) {
332 		return QDF_STATUS_E_FAILURE;
333 	}
334 
335 	if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
336 			wlan_crypto_peer_obj_create_handler, NULL)
337 			!= QDF_STATUS_SUCCESS) {
338 		return QDF_STATUS_E_FAILURE;
339 	}
340 
341 	if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
342 			wlan_crypto_vdev_obj_destroy_handler, NULL)
343 			!= QDF_STATUS_SUCCESS) {
344 		return QDF_STATUS_E_FAILURE;
345 	}
346 
347 	if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
348 			wlan_crypto_peer_obj_destroy_handler, NULL)
349 			!= QDF_STATUS_SUCCESS) {
350 		return QDF_STATUS_E_FAILURE;
351 	}
352 
353 	return QDF_STATUS_SUCCESS;
354 }
355