xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41) !
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 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler(
208 						struct wlan_objmgr_vdev *vdev,
209 						void *arg){
210 	struct wlan_crypto_comp_priv *crypto_priv;
211 
212 	if (!vdev) {
213 		crypto_err("Vdev NULL");
214 		return QDF_STATUS_E_INVAL;
215 	}
216 
217 	crypto_priv = (struct wlan_crypto_comp_priv *)
218 				wlan_get_vdev_crypto_obj(vdev);
219 
220 	if (!crypto_priv) {
221 		crypto_err("crypto_priv NULL");
222 		return QDF_STATUS_E_INVAL;
223 	}
224 
225 	wlan_objmgr_vdev_component_obj_detach(vdev,
226 						WLAN_UMAC_COMP_CRYPTO,
227 						(void *)crypto_priv);
228 
229 	wlan_crypto_pmksa_flush(&crypto_priv->crypto_params);
230 	wlan_crypto_free_key(crypto_priv);
231 	qdf_mem_free(crypto_priv);
232 
233 	return QDF_STATUS_SUCCESS;
234 }
235 
236 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler(
237 						struct wlan_objmgr_peer *peer,
238 						void *arg){
239 	struct wlan_crypto_comp_priv *crypto_priv;
240 
241 	if (!peer) {
242 		crypto_err("Peer NULL");
243 		return QDF_STATUS_E_INVAL;
244 	}
245 	crypto_priv = (struct wlan_crypto_comp_priv *)
246 				wlan_get_peer_crypto_obj(peer);
247 	if (!crypto_priv) {
248 		crypto_err("crypto_priv NULL");
249 		return QDF_STATUS_E_INVAL;
250 	}
251 
252 	wlan_objmgr_peer_component_obj_detach(peer,
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  * __wlan_crypto_init - Init the crypto service with object manager
262  *                    Called from crypto init context.
263  *
264  * Return: QDF_STATUS_SUCCESS - in case of success
265  */
266 QDF_STATUS __wlan_crypto_init(void)
267 {
268 	QDF_STATUS status = QDF_STATUS_SUCCESS;
269 
270 	status = wlan_objmgr_register_vdev_create_handler(
271 				WLAN_UMAC_COMP_CRYPTO,
272 				wlan_crypto_vdev_obj_create_handler, NULL);
273 	if (status != QDF_STATUS_SUCCESS)
274 		return status;
275 
276 	status = wlan_objmgr_register_peer_create_handler(
277 				WLAN_UMAC_COMP_CRYPTO,
278 				wlan_crypto_peer_obj_create_handler, NULL);
279 	if (status != QDF_STATUS_SUCCESS)
280 		goto err_peer_create;
281 
282 	status = wlan_objmgr_register_vdev_destroy_handler(
283 				WLAN_UMAC_COMP_CRYPTO,
284 				wlan_crypto_vdev_obj_destroy_handler, NULL);
285 	if (status != QDF_STATUS_SUCCESS)
286 		goto err_vdev_delete;
287 
288 	status = wlan_objmgr_register_peer_destroy_handler(
289 				WLAN_UMAC_COMP_CRYPTO,
290 				wlan_crypto_peer_obj_destroy_handler, NULL);
291 	if (status != QDF_STATUS_SUCCESS)
292 		goto err_peer_delete;
293 
294 	goto register_success;
295 err_peer_delete:
296 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
297 			wlan_crypto_vdev_obj_destroy_handler, NULL);
298 err_vdev_delete:
299 	wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
300 			wlan_crypto_peer_obj_create_handler, NULL);
301 err_peer_create:
302 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
303 			wlan_crypto_vdev_obj_create_handler, NULL);
304 
305 register_success:
306 	return status;
307 }
308 
309 /**
310  * __wlan_crypto_deinit - Deinit the crypto service with object manager
311  *                         Called from crypto context.
312  *
313  * Return: QDF_STATUS_SUCCESS - in case of success
314  */
315 QDF_STATUS __wlan_crypto_deinit(void)
316 {
317 
318 	if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
319 			wlan_crypto_vdev_obj_create_handler, NULL)
320 			!= QDF_STATUS_SUCCESS) {
321 		return QDF_STATUS_E_FAILURE;
322 	}
323 
324 	if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
325 			wlan_crypto_peer_obj_create_handler, NULL)
326 			!= QDF_STATUS_SUCCESS) {
327 		return QDF_STATUS_E_FAILURE;
328 	}
329 
330 	if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
331 			wlan_crypto_vdev_obj_destroy_handler, NULL)
332 			!= QDF_STATUS_SUCCESS) {
333 		return QDF_STATUS_E_FAILURE;
334 	}
335 
336 	if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
337 			wlan_crypto_peer_obj_destroy_handler, NULL)
338 			!= QDF_STATUS_SUCCESS) {
339 		return QDF_STATUS_E_FAILURE;
340 	}
341 
342 	return QDF_STATUS_SUCCESS;
343 }
344