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