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