1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_nl_to_crypto_params.c
22  *
23  * Conversion of NL param type to Crypto param type APIs implementation
24  *
25  */
26 
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/version.h>
30 #include <linux/netdevice.h>
31 #include <net/netlink.h>
32 #include <net/cfg80211.h>
33 
34 #include <qdf_types.h>
35 #include "wlan_objmgr_vdev_obj.h"
36 #include <qdf_module.h>
37 
38 #include "wlan_nl_to_crypto_params.h"
39 #include "wlan_crypto_global_def.h"
40 
41 /**
42  * struct osif_akm_type_crypto_mapping - mapping akm type received from
43  *                                 NL to internal crypto type
44  * @akm_suite: NL akm type
45  * @akm_type_crypto: akm crypto type
46  *
47  * mapping akm type received from NL to internal crypto type
48  */
49 struct osif_akm_type_crypto_mapping {
50 	u32 akm_suite;
51 	wlan_crypto_key_mgmt akm_type_crypto;
52 };
53 
54 /**
55  * struct osif_cipher_crypto_mapping - mapping cipher type received from NL
56  *                                    to internal crypto cipher type
57  * @cipher_suite: NL cipher type
58  * @cipher_crypto: cipher crypto type
59  * @cipher_len: Length of the cipher
60  *
61  * mapping cipher type received from NL to internal crypto cipher type
62  */
63 struct osif_cipher_crypto_mapping {
64 	u32 cipher_suite;
65 	wlan_crypto_cipher_type cipher_crypto;
66 	u32 cipher_len;
67 };
68 
69 /*
70  * mapping table for auth type received from NL and crypto auth type
71  */
72 static const wlan_crypto_auth_mode
73 	osif_auth_type_crypto_mapping[] = {
74 	[NL80211_AUTHTYPE_AUTOMATIC] = WLAN_CRYPTO_AUTH_AUTO,
75 	[NL80211_AUTHTYPE_OPEN_SYSTEM] = WLAN_CRYPTO_AUTH_OPEN,
76 	[NL80211_AUTHTYPE_FT] = WLAN_CRYPTO_AUTH_OPEN,
77 	[NL80211_AUTHTYPE_SHARED_KEY] = WLAN_CRYPTO_AUTH_SHARED,
78 	[NL80211_AUTHTYPE_NETWORK_EAP] = WLAN_CRYPTO_AUTH_8021X,
79 #if defined(WLAN_FEATURE_FILS_SK) && \
80 	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
81 		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
82 	[NL80211_AUTHTYPE_FILS_SK] = WLAN_CRYPTO_AUTH_FILS_SK,
83 #endif
84 	[NL80211_AUTHTYPE_SAE] = WLAN_CRYPTO_AUTH_SAE,
85 };
86 
87 /* mapping table for akm type received from NL and crypto akm type */
88 static const struct osif_akm_type_crypto_mapping
89 	osif_akm_type_crypto_mapping[] = {
90 	{
91 		.akm_suite = WLAN_AKM_SUITE_8021X,
92 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X,
93 	},
94 	{
95 		.akm_suite = WLAN_AKM_SUITE_PSK,
96 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_PSK,
97 	},
98 	{
99 		.akm_suite = WLAN_AKM_SUITE_8021X_SHA256,
100 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256,
101 	},
102 	{
103 		.akm_suite = WLAN_AKM_SUITE_PSK_SHA256,
104 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_PSK_SHA256,
105 	},
106 	{
107 		.akm_suite = WLAN_AKM_SUITE_SAE,
108 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_SAE,
109 	},
110 	{
111 		.akm_suite = WLAN_AKM_SUITE_FT_OVER_SAE,
112 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_SAE,
113 	},
114 #if defined(WLAN_AKM_SUITE_FT_8021X) || \
115 			defined(FEATURE_WLAN_FT_IEEE8021X)
116 	{
117 		.akm_suite = WLAN_AKM_SUITE_FT_8021X,
118 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X,
119 	},
120 #endif
121 #if defined(WLAN_AKM_SUITE_FT_PSK) || \
122 			defined(FEATURE_WLAN_FT_PSK)
123 	{
124 		.akm_suite = WLAN_AKM_SUITE_FT_PSK,
125 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_PSK,
126 	},
127 #endif
128 #ifdef FEATURE_WLAN_ESE
129 	{
130 #ifndef WLAN_AKM_SUITE_CCKM
131 #define WLAN_AKM_SUITE_CCKM         0x00409600
132 #endif
133 		.akm_suite = WLAN_AKM_SUITE_CCKM,
134 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_CCKM,
135 	},
136 #endif
137 	{
138 #ifndef WLAN_AKM_SUITE_OSEN
139 #define WLAN_AKM_SUITE_OSEN         0x506f9a01
140 #endif
141 		.akm_suite = WLAN_AKM_SUITE_OSEN,
142 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_OSEN,
143 	},
144 #if defined(WLAN_AKM_SUITE_8021X_SUITE_B) || \
145 		defined(FEATURE_WLAN_IEEE8021X_SUITE_B)
146 	{
147 		.akm_suite = WLAN_AKM_SUITE_8021X_SUITE_B,
148 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B,
149 	},
150 #endif
151 #if defined(WLAN_AKM_SUITE_8021X_SUITE_B_192) || \
152 		defined(FEATURE_WLAN_IEEE8021X_SUITE_B)
153 	{
154 		.akm_suite = WLAN_AKM_SUITE_8021X_SUITE_B_192,
155 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192,
156 	},
157 #endif
158 #if defined(WLAN_AKM_SUITE_FILS_SHA256) || \
159 				defined(FEATURE_WLAN_FILS)
160 	{
161 		.akm_suite = WLAN_AKM_SUITE_FILS_SHA256,
162 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FILS_SHA256,
163 	},
164 #endif
165 #if defined(WLAN_AKM_SUITE_FILS_SHA384) || \
166 				defined(FEATURE_WLAN_FILS)
167 	{
168 		.akm_suite = WLAN_AKM_SUITE_FILS_SHA384,
169 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FILS_SHA384,
170 	},
171 #endif
172 #if defined(WLAN_AKM_SUITE_FT_FILS_SHA256) || \
173 				defined(FEATURE_WLAN_FILS)
174 	{
175 		.akm_suite = WLAN_AKM_SUITE_FT_FILS_SHA256,
176 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256,
177 	},
178 #endif
179 #if defined(WLAN_AKM_SUITE_FT_FILS_SHA384) || \
180 				defined(FEATURE_WLAN_FILS)
181 	{
182 		.akm_suite = WLAN_AKM_SUITE_FT_FILS_SHA384,
183 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384,
184 	},
185 #endif
186 	{
187 #ifndef WLAN_AKM_SUITE_OWE
188 #define WLAN_AKM_SUITE_OWE          0x000FAC12
189 #endif
190 		.akm_suite = WLAN_AKM_SUITE_OWE,
191 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_OWE,
192 	},
193 	{
194 #ifndef WLAN_AKM_SUITE_DPP
195 #define WLAN_AKM_SUITE_DPP      0x506f9a02
196 #endif
197 		.akm_suite = WLAN_AKM_SUITE_DPP,
198 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_DPP,
199 	},
200 	{
201 #ifndef WLAN_AKM_SUITE_SAE_EXT_KEY
202 #define WLAN_AKM_SUITE_SAE_EXT_KEY 0x000FAC18
203 #endif
204 		.akm_suite = WLAN_AKM_SUITE_SAE_EXT_KEY,
205 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY,
206 	},
207 	{
208 #ifndef WLAN_AKM_SUITE_FT_SAE_EXT_KEY
209 #define WLAN_AKM_SUITE_FT_SAE_EXT_KEY 0x000FAC19
210 #endif
211 		.akm_suite = WLAN_AKM_SUITE_FT_SAE_EXT_KEY,
212 		.akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY,
213 	},
214 };
215 
216 /* mapping table for cipher type received from NL and crypto cipher type */
217 static const struct osif_cipher_crypto_mapping
218 	osif_cipher_crypto_mapping[] = {
219 	{
220 		.cipher_suite = IW_AUTH_CIPHER_NONE,
221 		.cipher_crypto = WLAN_CRYPTO_CIPHER_NONE,
222 		.cipher_len = 0,
223 	},
224 	{
225 		.cipher_suite = WLAN_CIPHER_SUITE_WEP40,
226 		.cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_40,
227 		.cipher_len = WLAN_CRYPTO_KEY_WEP40_LEN,
228 	},
229 	{
230 		.cipher_suite = WLAN_CIPHER_SUITE_TKIP,
231 		.cipher_crypto = WLAN_CRYPTO_CIPHER_TKIP,
232 		.cipher_len = WLAN_CRYPTO_KEY_TKIP_LEN,
233 	},
234 	{
235 		.cipher_suite = WLAN_CIPHER_SUITE_CCMP,
236 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM,
237 		.cipher_len = WLAN_CRYPTO_KEY_CCMP_LEN,
238 	},
239 	{
240 		.cipher_suite = WLAN_CIPHER_SUITE_WEP104,
241 		.cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_104,
242 		.cipher_len = WLAN_CRYPTO_KEY_WEP104_LEN,
243 	},
244 	{
245 		.cipher_suite = WLAN_CIPHER_SUITE_GCMP,
246 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM,
247 		.cipher_len = WLAN_CRYPTO_KEY_GCMP_LEN,
248 	},
249 	{
250 		.cipher_suite = WLAN_CIPHER_SUITE_GCMP_256,
251 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM_256,
252 		.cipher_len = WLAN_CRYPTO_KEY_GCMP_256_LEN,
253 	},
254 	{
255 		.cipher_suite = WLAN_CIPHER_SUITE_CCMP_256,
256 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM_256,
257 		.cipher_len = WLAN_CRYPTO_KEY_CCMP_256_LEN,
258 	},
259 	{
260 		.cipher_suite = WLAN_CIPHER_SUITE_AES_CMAC,
261 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC,
262 		.cipher_len = WLAN_CRYPTO_KEY_CCMP_LEN,
263 	},
264 #ifdef WLAN_CIPHER_SUITE_BIP_GMAC_128
265 	{
266 		.cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_128,
267 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC,
268 		.cipher_len = WLAN_CRYPTO_KEY_GMAC_LEN,
269 	},
270 #endif
271 #ifdef WLAN_CIPHER_SUITE_BIP_GMAC_256
272 	{
273 		.cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_256,
274 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC_256,
275 		.cipher_len = WLAN_CRYPTO_KEY_GMAC_256_LEN,
276 	},
277 #endif
278 #ifdef WLAN_CIPHER_SUITE_BIP_CMAC_256
279 	{
280 		.cipher_suite = WLAN_CIPHER_SUITE_BIP_CMAC_256,
281 		.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC_256,
282 		.cipher_len = WLAN_CRYPTO_KEY_CCMP_256_LEN,
283 	},
284 #endif
285 #ifdef FEATURE_WLAN_WAPI
286 	{
287 		.cipher_suite = WLAN_CIPHER_SUITE_SMS4,
288 		.cipher_crypto = WLAN_CRYPTO_CIPHER_WAPI_SMS4,
289 		.cipher_len = WLAN_CRYPTO_KEY_WAPI_LEN,
290 	},
291 #endif
292 };
293 
294 wlan_crypto_auth_mode
osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type)295 osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type)
296 {
297 	wlan_crypto_auth_mode crypto_auth_type = WLAN_CRYPTO_AUTH_NONE;
298 
299 	if (auth_type < NL80211_AUTHTYPE_OPEN_SYSTEM ||
300 	    auth_type >= QDF_ARRAY_SIZE(osif_auth_type_crypto_mapping)) {
301 		QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d",
302 				auth_type);
303 		return crypto_auth_type;
304 	}
305 
306 	crypto_auth_type = osif_auth_type_crypto_mapping[auth_type];
307 	QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Auth type, NL: %d, crypto: %d",
308 			auth_type, crypto_auth_type);
309 
310 	return crypto_auth_type;
311 }
312 
osif_nl_to_crypto_akm_type(u32 key_mgmt)313 wlan_crypto_key_mgmt osif_nl_to_crypto_akm_type(u32 key_mgmt)
314 {
315 	uint8_t index;
316 	wlan_crypto_key_mgmt crypto_akm_type = WLAN_CRYPTO_KEY_MGMT_NONE;
317 	bool akm_type_crypto_exist = false;
318 
319 	for (index = 0; index < QDF_ARRAY_SIZE(osif_akm_type_crypto_mapping);
320 	     index++) {
321 		if (osif_akm_type_crypto_mapping[index].akm_suite == key_mgmt) {
322 			crypto_akm_type = osif_akm_type_crypto_mapping[index].
323 							akm_type_crypto;
324 			akm_type_crypto_exist = true;
325 			break;
326 		}
327 	}
328 	if (!akm_type_crypto_exist)
329 		QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d",
330 				key_mgmt);
331 	else
332 		QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Akm suite, NL: %d, crypto: %d",
333 				key_mgmt, crypto_akm_type);
334 
335 	return crypto_akm_type;
336 }
337 
osif_nl_to_crypto_cipher_type(u32 cipher)338 enum wlan_crypto_cipher_type osif_nl_to_crypto_cipher_type(u32 cipher)
339 {
340 	uint8_t index;
341 	bool cipher_crypto_exist = false;
342 	wlan_crypto_cipher_type crypto_cipher_type = WLAN_CRYPTO_CIPHER_NONE;
343 
344 	for (index = 0; index < QDF_ARRAY_SIZE(osif_cipher_crypto_mapping);
345 	     index++) {
346 		if (osif_cipher_crypto_mapping[index].cipher_suite == cipher) {
347 			crypto_cipher_type = osif_cipher_crypto_mapping[index].
348 								cipher_crypto;
349 			cipher_crypto_exist = true;
350 			break;
351 		}
352 	}
353 	if (!cipher_crypto_exist) {
354 		QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d",
355 				cipher);
356 		return WLAN_CRYPTO_CIPHER_INVALID;
357 	}
358 	QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Cipher suite, NL: %d, crypto: %d",
359 			cipher, crypto_cipher_type);
360 
361 	return crypto_cipher_type;
362 }
363 
osif_nl_to_crypto_cipher_len(u32 cipher)364 int osif_nl_to_crypto_cipher_len(u32 cipher)
365 {
366 	uint8_t index;
367 
368 	for (index = 0; index < QDF_ARRAY_SIZE(osif_cipher_crypto_mapping);
369 	     index++) {
370 		if (osif_cipher_crypto_mapping[index].cipher_suite == cipher)
371 			return osif_cipher_crypto_mapping[index].cipher_len;
372 	}
373 
374 	return -EINVAL;
375 }
376 
377