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