xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c (revision a175314c51a4ce5cec2835cc8a8c7dc0c1810915)
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 *wep_register(void);
41 extern const struct wlan_crypto_cipher *tkip_register(void);
42 extern const struct wlan_crypto_cipher *ccmp_register(void);
43 extern const struct wlan_crypto_cipher *ccmp256_register(void);
44 extern const struct wlan_crypto_cipher *gcmp_register(void);
45 extern const struct wlan_crypto_cipher *gcmp256_register(void);
46 extern const struct wlan_crypto_cipher *wapi_register(void);
47 
48 extern const struct wlan_crypto_cipher
49 				*wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
50 
51 static QDF_STATUS wlan_crypto_register_all_ciphers(
52 					struct wlan_crypto_params *crypto_param)
53 {
54 
55 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) {
56 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP]
57 							= wep_register();
58 	}
59 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) {
60 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP]
61 							= tkip_register();
62 	}
63 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) {
64 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM]
65 							= ccmp_register();
66 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256]
67 							= ccmp256_register();
68 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM]
69 							= gcmp_register();
70 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256]
71 							= gcmp256_register();
72 	}
73 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) {
74 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4]
75 							= wapi_register();
76 	}
77 	if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD)) {
78 		wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_FILS_AEAD]
79 							= fils_register();
80 	}
81 
82 	return QDF_STATUS_SUCCESS;
83 }
84 
85 static QDF_STATUS wlan_crypto_psoc_obj_create_handler(
86 						struct wlan_objmgr_psoc *psoc,
87 						void *arg)
88 {
89 	return QDF_STATUS_SUCCESS;
90 }
91 
92 static QDF_STATUS wlan_crypto_pdev_obj_create_handler(
93 						struct wlan_objmgr_pdev *pdev,
94 						void *arg)
95 {
96 	return QDF_STATUS_SUCCESS;
97 }
98 
99 static QDF_STATUS wlan_crypto_vdev_obj_create_handler(
100 						struct wlan_objmgr_vdev *vdev,
101 						void *arg)
102 {
103 	struct wlan_crypto_comp_priv *crypto_priv;
104 	struct wlan_objmgr_pdev *pdev;
105 	struct wlan_crypto_params *crypto_param;
106 	QDF_STATUS status;
107 
108 	if (!vdev)
109 		return QDF_STATUS_E_INVAL;
110 
111 	crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
112 	if (!crypto_priv)
113 		return QDF_STATUS_E_NOMEM;
114 
115 	crypto_param = &(crypto_priv->crypto_params);
116 
117 	RESET_AUTHMODE(crypto_param);
118 	RESET_UCAST_CIPHERS(crypto_param);
119 	RESET_MCAST_CIPHERS(crypto_param);
120 	RESET_MGMT_CIPHERS(crypto_param);
121 	RESET_KEY_MGMT(crypto_param);
122 	RESET_CIPHER_CAP(crypto_param);
123 
124 	pdev = wlan_vdev_get_pdev(vdev);
125 	wlan_pdev_obj_lock(pdev);
126 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP))
127 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP);
128 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP))
129 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC);
130 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) {
131 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES);
132 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256);
133 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM);
134 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256);
135 	}
136 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP))
137 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP);
138 	if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI))
139 		SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4);
140 	SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD);
141 	wlan_pdev_obj_unlock(pdev);
142 	/* update the crypto cipher table based on the fw caps*/
143 	/* update the fw_caps into ciphercaps then attach to objmgr*/
144 	wlan_crypto_register_all_ciphers(crypto_param);
145 
146 	status = wlan_objmgr_vdev_component_obj_attach(vdev,
147 							WLAN_UMAC_COMP_CRYPTO,
148 							(void *)crypto_priv,
149 							QDF_STATUS_SUCCESS);
150 	if (status != QDF_STATUS_SUCCESS)
151 		qdf_mem_free(crypto_priv);
152 
153 	return status;
154 }
155 
156 static QDF_STATUS wlan_crypto_peer_obj_create_handler(
157 						struct wlan_objmgr_peer *peer,
158 						void *arg)
159 {
160 	struct wlan_crypto_comp_priv *crypto_priv;
161 	struct wlan_crypto_params *crypto_param;
162 	QDF_STATUS status;
163 
164 	if (!peer)
165 		return QDF_STATUS_E_INVAL;
166 
167 	crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
168 	if (!crypto_priv)
169 		return QDF_STATUS_E_NOMEM;
170 
171 	status = wlan_objmgr_peer_component_obj_attach(peer,
172 				WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv,
173 				QDF_STATUS_SUCCESS);
174 
175 	if (status == QDF_STATUS_SUCCESS) {
176 		crypto_param = &crypto_priv->crypto_params;
177 		RESET_AUTHMODE(crypto_param);
178 		RESET_UCAST_CIPHERS(crypto_param);
179 		RESET_MCAST_CIPHERS(crypto_param);
180 		RESET_MGMT_CIPHERS(crypto_param);
181 		RESET_KEY_MGMT(crypto_param);
182 		RESET_CIPHER_CAP(crypto_param);
183 		if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) {
184 			wlan_crypto_set_peer_wep_keys(
185 					wlan_peer_get_vdev(peer), peer);
186 		}
187 	} else {
188 		qdf_print("%s[%d] peer obj failed status %d\n",
189 					__func__, __LINE__, status);
190 		qdf_mem_free(crypto_priv);
191 	}
192 
193 	return status;
194 }
195 
196 static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler(
197 						struct wlan_objmgr_psoc *psoc,
198 						void *arg){
199 
200 	return QDF_STATUS_COMP_DISABLED;
201 }
202 
203 static QDF_STATUS wlan_crypto_pdev_obj_destroy_handler(
204 						struct wlan_objmgr_pdev *pdev,
205 						void *arg){
206 
207 	return QDF_STATUS_SUCCESS;
208 }
209 
210 static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv)
211 {
212 	uint8_t i;
213 
214 	if (!crypto_priv) {
215 		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
216 		return;
217 	}
218 
219 	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
220 		if (crypto_priv->key[i]) {
221 			qdf_mem_free(crypto_priv->key[i]);
222 			crypto_priv->key[i] = NULL;
223 		}
224 	}
225 
226 	for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) {
227 		if (crypto_priv->igtk_key[i]) {
228 			qdf_mem_free(crypto_priv->igtk_key[i]);
229 			crypto_priv->igtk_key[i] = NULL;
230 		}
231 	}
232 
233 }
234 
235 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler(
236 						struct wlan_objmgr_vdev *vdev,
237 						void *arg){
238 	struct wlan_crypto_comp_priv *crypto_priv;
239 
240 	if (!vdev) {
241 		qdf_print("%s[%d] Vdev NULL\n", __func__, __LINE__);
242 		return QDF_STATUS_E_INVAL;
243 	}
244 
245 	crypto_priv = (struct wlan_crypto_comp_priv *)
246 				wlan_get_vdev_crypto_obj(vdev);
247 
248 	if (!crypto_priv) {
249 		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
250 		return QDF_STATUS_E_INVAL;
251 	}
252 	wlan_objmgr_vdev_component_obj_detach(vdev,
253 						WLAN_UMAC_COMP_CRYPTO,
254 						(void *)crypto_priv);
255 	wlan_crypto_free_key(crypto_priv);
256 	qdf_mem_free(crypto_priv);
257 
258 	return QDF_STATUS_SUCCESS;
259 }
260 
261 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler(
262 						struct wlan_objmgr_peer *peer,
263 						void *arg){
264 	struct wlan_crypto_comp_priv *crypto_priv;
265 
266 	if (!peer) {
267 		qdf_print("%s[%d] Peer NULL\n", __func__, __LINE__);
268 		return QDF_STATUS_E_INVAL;
269 	}
270 	crypto_priv = (struct wlan_crypto_comp_priv *)
271 				wlan_get_peer_crypto_obj(peer);
272 	if (!crypto_priv) {
273 		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
274 		return QDF_STATUS_E_INVAL;
275 	}
276 
277 	wlan_objmgr_peer_component_obj_detach(peer,
278 						WLAN_UMAC_COMP_CRYPTO,
279 						(void *)crypto_priv);
280 	wlan_crypto_free_key(crypto_priv);
281 	qdf_mem_free(crypto_priv);
282 
283 	return QDF_STATUS_SUCCESS;
284 }
285 /**
286  * __wlan_crypto_init - Init the crypto service with object manager
287  *                    Called from crypto init context.
288  *
289  * Return: QDF_STATUS_SUCCESS - in case of success
290  */
291 QDF_STATUS __wlan_crypto_init(void)
292 {
293 	QDF_STATUS status = QDF_STATUS_SUCCESS;
294 
295 	status = wlan_objmgr_register_vdev_create_handler(
296 				WLAN_UMAC_COMP_CRYPTO,
297 				wlan_crypto_vdev_obj_create_handler, NULL);
298 	if (status != QDF_STATUS_SUCCESS)
299 		goto err_vdev_create;
300 
301 	status = wlan_objmgr_register_peer_create_handler(
302 				WLAN_UMAC_COMP_CRYPTO,
303 				wlan_crypto_peer_obj_create_handler, NULL);
304 	if (status != QDF_STATUS_SUCCESS)
305 		goto err_peer_create;
306 
307 	status = wlan_objmgr_register_vdev_destroy_handler(
308 				WLAN_UMAC_COMP_CRYPTO,
309 				wlan_crypto_vdev_obj_destroy_handler, NULL);
310 	if (status != QDF_STATUS_SUCCESS)
311 		goto err_vdev_delete;
312 
313 	status = wlan_objmgr_register_peer_destroy_handler(
314 				WLAN_UMAC_COMP_CRYPTO,
315 				wlan_crypto_peer_obj_destroy_handler, NULL);
316 	if (status != QDF_STATUS_SUCCESS)
317 		goto err_peer_delete;
318 
319 	goto register_success;
320 err_peer_delete:
321 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
322 			wlan_crypto_vdev_obj_destroy_handler, NULL);
323 err_vdev_delete:
324 	wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
325 			wlan_crypto_peer_obj_create_handler, NULL);
326 err_peer_create:
327 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
328 			wlan_crypto_vdev_obj_create_handler, NULL);
329 err_vdev_create:
330 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
331 			wlan_crypto_pdev_obj_create_handler, NULL);
332 register_success:
333 	return status;
334 }
335 
336 /**
337  * __wlan_crypto_deinit - Deinit the crypto service with object manager
338  *                         Called from crypto context.
339  *
340  * Return: QDF_STATUS_SUCCESS - in case of success
341  */
342 QDF_STATUS __wlan_crypto_deinit(void)
343 {
344 
345 	if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
346 			wlan_crypto_vdev_obj_create_handler, NULL)
347 			!= QDF_STATUS_SUCCESS) {
348 		return QDF_STATUS_E_FAILURE;
349 	}
350 
351 	if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
352 			wlan_crypto_peer_obj_create_handler, NULL)
353 			!= QDF_STATUS_SUCCESS) {
354 		return QDF_STATUS_E_FAILURE;
355 	}
356 
357 	if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
358 			wlan_crypto_vdev_obj_destroy_handler, NULL)
359 			!= QDF_STATUS_SUCCESS) {
360 		return QDF_STATUS_E_FAILURE;
361 	}
362 
363 	if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
364 			wlan_crypto_peer_obj_destroy_handler, NULL)
365 			!= QDF_STATUS_SUCCESS) {
366 		return QDF_STATUS_E_FAILURE;
367 	}
368 
369 	return QDF_STATUS_SUCCESS;
370 }
371