xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmwpa.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *   bcmwpa.c - shared WPA-related functions
3  *
4  * Broadcom Proprietary and Confidential. Copyright (C) 2020,
5  * All Rights Reserved.
6  *
7  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
8  * the contents of this file may not be disclosed to third parties,
9  * copied or duplicated in any form, in whole or in part, without
10  * the prior written permission of Broadcom.
11  *
12  *
13  * <<Broadcom-WL-IPTag/Proprietary:>>
14  */
15 
16 /* include wl driver config file if this file is compiled for driver */
17 #ifdef BCMDRIVER
18 #include <osl.h>
19 /* HACK: this case for external supplicant use */
20 #else
21 #include <string.h>
22 #if defined(BCMEXTSUP)
23 #include <bcm_osl.h>
24 #else
25 #ifndef ASSERT
26 #define ASSERT(exp)
27 #endif
28 #endif /* BCMEXTSUP */
29 #endif /* BCMDRIVER */
30 
31 #include <ethernet.h>
32 #include <eapol.h>
33 #include <802.11.h>
34 #include <wpa.h>
35 #include <802.11r.h>
36 
37 #include <bcmutils.h>
38 #include <bcmendian.h>
39 #include <bcmwpa.h>
40 #include <aeskeywrap.h>
41 
42 #include <bcmstdlib_s.h>
43 
44 #include <wlioctl.h>
45 
46 #include <bcmutils.h>
47 #include <bcmwpa.h>
48 #ifdef WL_OCV
49 #include <bcm_ocv.h>
50 #endif /* WL_OCV */
51 
52 #if defined(BCMSUP_PSK) || defined(WLFBT) || defined(BCMAUTH_PSK) || \
53 	defined(WL_OKC) || defined(WLTDLS) || defined(GTKOE) || defined(WLHOSTFBT)
54 #ifdef WLHOSTFBT
55 #include <string.h>
56 #endif
57 #endif /* defined(BCMSUP_PSK) || defined(WLFBT) || defined(BCMAUTH_PSK) ||
58 	* defined(WL_OKC) || defined(WLTDLS) || defined(GTKOE) || defined(WLHOSTFBT)
59 	*/
60 
61 /* prefix strings */
62 #define PMK_NAME_PFX "PMK Name"
63 #define FT_PTK_PFX "FT-PTK"
64 #define FT_R0_PFX "FT-R0"
65 #define FT_R0N_PFX "FT-R0N"
66 #define FT_R1_PFX "FT-R1"
67 #define FT_R1N_PFX "FT-R1N"
68 #define WPA_PTK_PFX "Pairwise key expansion"
69 #define TDLS_PMK_PFX "TDLS PMK"
70 /* end prefix strings */
71 
72 #ifndef BIT
73 #define BIT(x) (1 << (x))
74 #endif
75 
76 #define PRF_PREFIXES_NUM	5u
77 
78 typedef struct key_length_entry {
79 	uint8 suite;
80 	uint8 len;
81 } key_length_entry_t;
82 
83 /* EAPOL key(PMK/KCK/KEK/TK) length lookup tables */
84 static const key_length_entry_t eapol_pmk_len[] = {
85 	{RSN_AKM_SUITEB_SHA384_1X, EAPOL_WPA_PMK_SHA384_LEN},
86 	{RSN_AKM_FBT_SHA384_1X, EAPOL_WPA_PMK_SHA384_LEN},
87 	{RSN_AKM_FBT_SHA384_PSK, EAPOL_WPA_PMK_SHA384_LEN},
88 	{0u, EAPOL_WPA_PMK_DEFAULT_LEN} /* default */
89 };
90 
91 static const key_length_entry_t eapol_kck_mic_len[] = {
92 	{RSN_AKM_SUITEB_SHA384_1X, EAPOL_WPA_KCK_MIC_SHA384_LEN},
93 	{RSN_AKM_FILS_SHA256, 0u},
94 	{RSN_AKM_FILS_SHA384, 0u},
95 	{RSN_AKM_FBT_SHA256_FILS, EAPOL_WPA_KCK_MIC_DEFAULT_LEN},
96 	{RSN_AKM_FBT_SHA384_FILS, EAPOL_WPA_KCK2_SHA384_LEN},
97 	{RSN_AKM_OWE, EAPOL_WPA_KCK_MIC_DEFAULT_LEN},
98 	{RSN_AKM_FBT_SHA384_1X, EAPOL_WPA_KCK_MIC_SHA384_LEN},
99 	{RSN_AKM_FBT_SHA384_PSK, EAPOL_WPA_KCK_MIC_SHA384_LEN},
100 	{0u, EAPOL_WPA_KCK_MIC_DEFAULT_LEN} /* default */
101 };
102 
103 static const key_length_entry_t eapol_kck_len[] = {
104 	{RSN_AKM_SUITEB_SHA384_1X, EAPOL_WPA_KCK_SHA384_LEN},
105 	{RSN_AKM_FILS_SHA256, 0u},
106 	{RSN_AKM_FILS_SHA384, 0u},
107 	{RSN_AKM_FBT_SHA256_FILS, 0u},
108 	{RSN_AKM_FBT_SHA384_FILS, 0u},
109 	{RSN_AKM_OWE, EAPOL_WPA_KCK_DEFAULT_LEN},
110 	{RSN_AKM_FBT_SHA384_1X, EAPOL_WPA_KCK_SHA384_LEN},
111 	{RSN_AKM_FBT_SHA384_PSK, EAPOL_WPA_KCK_SHA384_LEN},
112 	{0u, EAPOL_WPA_KCK_DEFAULT_LEN} /* default */
113 };
114 
115 static const key_length_entry_t eapol_kek_len[] = {
116 	{RSN_AKM_FILS_SHA384, EAPOL_WPA_ENCR_KEY_MAX_LEN},
117 	{RSN_AKM_FBT_SHA384_FILS, EAPOL_WPA_ENCR_KEY_MAX_LEN},
118 	{RSN_AKM_SUITEB_SHA384_1X, EAPOL_WPA_ENCR_KEY_MAX_LEN / 2},
119 	{RSN_AKM_FILS_SHA256, EAPOL_WPA_ENCR_KEY_MAX_LEN / 2},
120 	{RSN_AKM_FBT_SHA256_FILS, EAPOL_WPA_ENCR_KEY_MAX_LEN / 2},
121 	{RSN_AKM_OWE, EAPOL_WPA_ENCR_KEY_DEFAULT_LEN},
122 	{RSN_AKM_FBT_SHA384_1X, EAPOL_WPA_ENCR_KEY_MAX_LEN / 2},
123 	{RSN_AKM_FBT_SHA384_PSK, EAPOL_WPA_ENCR_KEY_MAX_LEN / 2},
124 	{0u, EAPOL_WPA_ENCR_KEY_DEFAULT_LEN} /* default */
125 };
126 
127 static const key_length_entry_t eapol_tk_len[] = {
128 	{WPA_CIPHER_CCMP_256, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN},
129 	{WPA_CIPHER_AES_GCM256, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN},
130 	{WPA_CIPHER_BIP_GMAC_256, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN},
131 	{WPA_CIPHER_BIP_CMAC_256, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN},
132 	{WPA_CIPHER_AES_CCM, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN / 2},
133 	{WPA_CIPHER_AES_GCM, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN / 2},
134 	{WPA_CIPHER_BIP_GMAC_128, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN / 2},
135 	{WPA_CIPHER_TKIP, EAPOL_WPA_TEMP_ENCR_KEY_MAX_LEN},
136 	{0u, 0u} /* default */
137 };
138 
139 #if defined(WL_FILS) && defined(WLFBT)
140 static const key_length_entry_t eapol_kck2_len[] = {
141 	{RSN_AKM_FBT_SHA256_FILS, EAPOL_WPA_KCK2_SHA256_LEN},
142 	{RSN_AKM_FBT_SHA384_FILS, EAPOL_WPA_KCK2_SHA384_LEN},
143 	{0u, 0u} /* default */
144 };
145 
146 static const key_length_entry_t eapol_kek2_len[] = {
147 	{RSN_AKM_FBT_SHA256_FILS, EAPOL_WPA_KEK2_SHA256_LEN},
148 	{RSN_AKM_FBT_SHA384_FILS, EAPOL_WPA_KEK2_SHA384_LEN},
149 	{0u, 0u} /* default */
150 };
151 #endif /* WL_FILS && WLFBT */
152 
153 typedef struct key_length_lookup {
154 	const eapol_key_type_t key;
155 	const key_length_entry_t *key_entry;
156 } key_length_lookup_t;
157 
158 static const key_length_lookup_t eapol_key_lookup_tbl[] = {
159 	{EAPOL_KEY_PMK, eapol_pmk_len},
160 	{EAPOL_KEY_KCK_MIC, eapol_kck_mic_len},
161 	{EAPOL_KEY_KCK, eapol_kck_len},
162 	{EAPOL_KEY_KEK, eapol_kek_len},
163 	{EAPOL_KEY_TK, eapol_tk_len},
164 #if defined(WL_FILS) && defined(WLFBT)
165 	{EAPOL_KEY_KCK2, eapol_kck2_len},
166 	{EAPOL_KEY_KEK2, eapol_kek2_len},
167 #endif /* WL_FILS && WLFBT */
168 };
169 
170 typedef struct rsn_akm_lookup_entry {
171 	const rsn_akm_t rsn_akm;
172 	const sha2_hash_type_t hash_type;
173 } rsn_akm_lookup_entry_t;
174 
175 static const rsn_akm_lookup_entry_t rsn_akm_lookup_tbl[] = {
176 	{RSN_AKM_NONE, HASH_SHA1},
177 	{RSN_AKM_UNSPECIFIED, HASH_SHA1},
178 	{RSN_AKM_PSK, HASH_SHA1},
179 	{RSN_AKM_FBT_1X, HASH_SHA256},
180 	{RSN_AKM_FBT_PSK, HASH_SHA256},
181 	{RSN_AKM_MFP_1X, HASH_SHA256},
182 	{RSN_AKM_MFP_PSK, HASH_SHA256},
183 	{RSN_AKM_SHA256_1X, HASH_SHA256},
184 	{RSN_AKM_SHA256_PSK, HASH_SHA256},
185 	{RSN_AKM_TPK, HASH_SHA256},
186 	{RSN_AKM_SAE_PSK, HASH_SHA256},
187 	{RSN_AKM_SAE_FBT, HASH_SHA256},
188 	{RSN_AKM_SUITEB_SHA256_1X, HASH_SHA256},
189 	{RSN_AKM_SUITEB_SHA384_1X, HASH_SHA384},
190 	{RSN_AKM_FBT_SHA384_1X, HASH_SHA384},
191 	{RSN_AKM_FILS_SHA256, HASH_SHA256},
192 	{RSN_AKM_FILS_SHA384, HASH_SHA384},
193 	{RSN_AKM_FBT_SHA256_FILS, HASH_SHA256},
194 	{RSN_AKM_FBT_SHA384_FILS, HASH_SHA384},
195 	{RSN_AKM_OWE, HASH_SHA256},
196 	{RSN_AKM_FBT_SHA384_PSK, HASH_SHA384},
197 	{RSN_AKM_PSK_SHA384, HASH_SHA384},
198 };
199 
200 typedef struct rsn_akm_cipher_match_entry {
201 	uint16  akm_type;
202 	uint32	u_cast; /* BITMAP */
203 	uint32	m_cast; /* BITMAP */
204 	uint32	g_mgmt; /* BITMAP */
205 } rsn_akm_cipher_match_entry_t;
206 
207 /* list only explicit cipher restriction for given AKM (e.g SuiteB)
208  * refer to 802.11 spec 9.4.2.24.3
209  * If not listed here, it means no restriction in using any ciphers.
210  */
211 static const rsn_akm_cipher_match_entry_t rsn_akm_cipher_match_table[] = {
212 	{RSN_AKM_SUITEB_SHA256_1X,
213 	BCM_BIT(WPA_CIPHER_AES_GCM),
214 	BCM_BIT(WPA_CIPHER_AES_GCM),
215 	BCM_BIT(WPA_CIPHER_BIP_GMAC_128)},
216 	{RSN_AKM_SUITEB_SHA384_1X,
217 	BCM_BIT(WPA_CIPHER_AES_GCM256) | BCM_BIT(WPA_CIPHER_CCMP_256),
218 	BCM_BIT(WPA_CIPHER_AES_GCM256) | BCM_BIT(WPA_CIPHER_AES_GCM256),
219 	BCM_BIT(WPA_CIPHER_BIP_GMAC_256) | BCM_BIT(WPA_CIPHER_BIP_CMAC_256)},
220 	{RSN_AKM_FBT_SHA384_1X,
221 	BCM_BIT(WPA_CIPHER_AES_GCM256) | BCM_BIT(WPA_CIPHER_CCMP_256),
222 	BCM_BIT(WPA_CIPHER_AES_GCM256) | BCM_BIT(WPA_CIPHER_AES_GCM256),
223 	BCM_BIT(WPA_CIPHER_BIP_GMAC_256) | BCM_BIT(WPA_CIPHER_BIP_CMAC_256)}
224 };
225 
226 #if defined(WL_BAND6G)
227 static const rsn_akm_mask_t rsn_akm_6g_inval_mask =
228 	BCM_BIT(RSN_AKM_PSK) |
229 	BCM_BIT(RSN_AKM_FBT_PSK) |
230 	BCM_BIT(RSN_AKM_SHA256_PSK) |
231 	BCM_BIT(RSN_AKM_FBT_SHA384_PSK) |
232 	BCM_BIT(RSN_AKM_PSK_SHA384);
233 
234 static const rsn_ciphers_t cipher_6g_inval_mask =
235 	BCM_BIT(WPA_CIPHER_NONE) |
236 	BCM_BIT(WPA_CIPHER_WEP_40) |
237 	BCM_BIT(WPA_CIPHER_TKIP) |
238 	BCM_BIT(WPA_CIPHER_WEP_104);
239 #endif /* WL_BAND6G */
240 
241 #if defined(BCMSUP_PSK) || defined(BCMSUPPL)
242 typedef struct group_cipher_algo_entry {
243 	rsn_cipher_t g_mgmt_cipher;
244 	uint8 bip_algo;
245 } group_cipher_algo_entry_t;
246 
247 static const group_cipher_algo_entry_t group_mgmt_cipher_algo[] = {
248 	{WPA_CIPHER_BIP_GMAC_256, CRYPTO_ALGO_BIP_GMAC256},
249 	{WPA_CIPHER_BIP_CMAC_256, CRYPTO_ALGO_BIP_CMAC256},
250 	{WPA_CIPHER_BIP_GMAC_128, CRYPTO_ALGO_BIP_GMAC},
251 	{WPA_CIPHER_BIP, CRYPTO_ALGO_BIP},
252 };
253 #endif /* defined(BCMSUP_PSK) || defined(BCMSUPPL) */
254 
255 static uint16 wlc_calc_rsn_desc_version(const rsn_ie_info_t *rsn_info);
256 static int bcmwpa_is_valid_akm(const rsn_akm_t akm);
257 #if defined(BCMSUP_PSK) || defined(BCMAUTH_PSK) || defined(WLFBT) || defined(GTKOE)
258 static sha2_hash_type_t bcmwpa_rsn_akm_to_hash(const rsn_akm_t akm);
259 #ifdef RSN_IE_INFO_STRUCT_RELOCATED
260 static int bcmwpa_decode_cipher_suite(rsn_ie_info_t *info, const uint8 **ptr, uint ie_len, uint
261 	*remain_len, uint16 *p_count);
262 #endif
263 #endif /* defined(BCMSUP_PSK) || defined(BCMAUTH_PSK) || defined(WLFBT) || defined(GTKOE) */
264 #if defined(BCMSUP_PSK) || defined(WLFBT) || defined(WL_OKC) || defined(WLHOSTFBT)
265 #include <rc4.h>
266 
267 /* calculate wpa PMKID: HMAC-SHA1-128(PMK, "PMK Name" | AA | SPA) */
268 static void
wpa_calc_pmkid_impl(sha2_hash_type_t hash_type,const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * pmk,uint pmk_len,uint8 * pmkid)269 wpa_calc_pmkid_impl(sha2_hash_type_t hash_type,
270 	const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
271 	const uint8 *pmk, uint pmk_len, uint8 *pmkid)
272 {
273 	int err;
274 	hmac_sha2_ctx_t ctx;
275 
276 	err = hmac_sha2_init(&ctx, hash_type, pmk, pmk_len);
277 	if (err != BCME_OK)
278 		goto done;
279 	hmac_sha2_update(&ctx, (const uint8 *)PMK_NAME_PFX, sizeof(PMK_NAME_PFX) - 1);
280 	hmac_sha2_update(&ctx, (const uint8 *)auth_ea, ETHER_ADDR_LEN);
281 	hmac_sha2_update(&ctx, (const uint8 *)sta_ea, ETHER_ADDR_LEN);
282 	hmac_sha2_final(&ctx, pmkid, WPA2_PMKID_LEN);
283 done:;
284 }
285 
286 void
wpa_calc_pmkid(const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * pmk,uint pmk_len,uint8 * pmkid)287 wpa_calc_pmkid(const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
288 	const uint8 *pmk, uint pmk_len, uint8 *pmkid)
289 {
290 	wpa_calc_pmkid_impl(HASH_SHA1, auth_ea, sta_ea, pmk, pmk_len, pmkid);
291 }
292 
293 void
kdf_calc_pmkid(const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * key,uint key_len,uint8 * pmkid,rsn_ie_info_t * rsn_info)294 kdf_calc_pmkid(const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
295 	const uint8 *key, uint key_len, uint8 *pmkid, rsn_ie_info_t *rsn_info)
296 {
297 	sha2_hash_type_t hash_type;
298 
299 	if (rsn_info->sta_akm == RSN_AKM_SUITEB_SHA384_1X) {
300 		hash_type = HASH_SHA384;
301 	} else {
302 		hash_type = HASH_SHA256;
303 	}
304 
305 	wpa_calc_pmkid_impl(hash_type, auth_ea, sta_ea, key, key_len, pmkid);
306 }
307 
308 #if defined(WLFBT) || defined(WLHOSTFBT)
309 void
wpa_calc_pmkR0(sha2_hash_type_t hash_type,const uint8 * ssid,uint ssid_len,uint16 mdid,const uint8 * r0kh,uint r0kh_len,const struct ether_addr * sta_ea,const uint8 * pmk,uint pmk_len,uint8 * pmkr0,uint8 * pmkr0name)310 wpa_calc_pmkR0(sha2_hash_type_t hash_type, const uint8 *ssid, uint ssid_len,
311 	uint16 mdid, const uint8 *r0kh, uint r0kh_len, const struct ether_addr *sta_ea,
312 	const uint8 *pmk, uint pmk_len, uint8 *pmkr0, uint8 *pmkr0name)
313 {
314 	uint8 out[FBT_R0KH_ID_LEN + WPA2_PMKID_LEN - 1];
315 	int out_len = FBT_R0KH_ID_LEN - 1;
316 	bcm_const_xlvp_t pfx[7];
317 	bcm_const_xlvp_t pfx2[2];
318 	int npfx = 0;
319 	int npfx2 = 0;
320 	uint8 mdid_le[2];
321 	uint8 pfx_ssid_len;
322 	uint8 pfx_r0kh_len;
323 
324 	if (hash_type == HASH_SHA384) {
325 		out_len += WPA2_PMKID_LEN;
326 	}
327 
328 	/* create prefixes for pmkr0 */
329 	pfx[npfx].len = sizeof(FT_R0_PFX) - 1;
330 	pfx[npfx++].data = (uint8 *)FT_R0_PFX;
331 
332 	/* ssid length and ssid */
333 	pfx_ssid_len = ssid_len & 0xff;
334 	pfx[npfx].len = (uint16)sizeof(pfx_ssid_len);
335 	pfx[npfx++].data = &pfx_ssid_len;
336 
337 	pfx[npfx].len = (uint16)(ssid_len & 0xffff);
338 	pfx[npfx++].data = ssid;
339 
340 	/* mdid */
341 	htol16_ua_store(mdid, mdid_le);
342 	pfx[npfx].len = sizeof(mdid_le);
343 	pfx[npfx++].data = mdid_le;
344 
345 	/* r0kh len and r0kh */
346 	pfx_r0kh_len = r0kh_len & 0xff;
347 	pfx[npfx].len = sizeof(pfx_r0kh_len);
348 	pfx[npfx++].data = &pfx_r0kh_len;
349 
350 	pfx[npfx].len = (uint16)(r0kh_len & 0xffff);
351 	pfx[npfx++].data = r0kh;
352 
353 	/* sta addr */
354 	pfx[npfx].len = ETHER_ADDR_LEN;
355 	pfx[npfx++].data = (const uint8 *)sta_ea;
356 
357 	hmac_sha2_n(hash_type, pmk, pmk_len, pfx, npfx, NULL, 0, out, out_len);
358 	(void)memcpy_s(pmkr0, pmk_len, out, pmk_len);
359 
360 	/* coverity checks overflow if pfx size changes */
361 
362 	/* create prefixes for pmkr0 name */
363 	pfx2[npfx2].len = sizeof(FT_R0N_PFX) - 1;
364 	pfx2[npfx2++].data = (uint8 *)FT_R0N_PFX;
365 	pfx2[npfx2].len = WPA2_PMKID_LEN;
366 	pfx2[npfx2++].data = &out[pmk_len];
367 
368 	(void)sha2(hash_type, pfx2, npfx2, NULL, 0, pmkr0name, WPA2_PMKID_LEN);
369 }
370 
371 void
wpa_calc_pmkR1(sha2_hash_type_t hash_type,const struct ether_addr * r1kh,const struct ether_addr * sta_ea,const uint8 * pmk,uint pmk_len,const uint8 * pmkr0name,uint8 * pmkr1,uint8 * pmkr1name)372 wpa_calc_pmkR1(sha2_hash_type_t hash_type, const struct ether_addr *r1kh,
373 	const struct ether_addr *sta_ea, const uint8 *pmk, uint pmk_len, const uint8 *pmkr0name,
374 	uint8 *pmkr1, uint8 *pmkr1name)
375 {
376 	bcm_const_xlvp_t pfx[3];
377 	bcm_const_xlvp_t pfx2[4];
378 	int npfx = 0;
379 	int npfx2 = 0;
380 
381 	if (!pmkr1 && !pmkr1name)
382 		goto done;
383 	else if (!pmkr1)
384 		goto calc_r1name;
385 
386 	/* create prefixes for pmkr1 */
387 	pfx[npfx].len = sizeof(FT_R1_PFX) - 1;
388 	pfx[npfx++].data = (uint8 *)FT_R1_PFX;
389 
390 	pfx[npfx].len = ETHER_ADDR_LEN;
391 	pfx[npfx++].data = (const uint8 *)r1kh;
392 
393 	pfx[npfx].len = ETHER_ADDR_LEN;
394 	pfx[npfx++].data = (const uint8 *)sta_ea;
395 
396 	hmac_sha2_n(hash_type, pmk, pmk_len, pfx, npfx, NULL, 0,
397 		pmkr1, sha2_digest_len(hash_type));
398 
399 calc_r1name:
400 	/* create prefixes for pmkr1 name */
401 	pfx2[npfx2].len = sizeof(FT_R1N_PFX) - 1;
402 	pfx2[npfx2++].data = (uint8 *)FT_R1N_PFX;
403 
404 	pfx2[npfx2].len = WPA2_PMKID_LEN;
405 	pfx2[npfx2++].data = pmkr0name;
406 
407 	pfx2[npfx2].len = ETHER_ADDR_LEN;
408 	pfx2[npfx2++].data = (const uint8 *)r1kh;
409 
410 	pfx2[npfx2].len = ETHER_ADDR_LEN;
411 	pfx2[npfx2++].data = (const uint8 *)sta_ea;
412 
413 	sha2(hash_type, pfx2, npfx2, NULL, 0, pmkr1name, WPA2_PMKID_LEN);
414 done:;
415 }
416 
417 void
wpa_calc_ft_ptk(sha2_hash_type_t hash_type,const struct ether_addr * bssid,const struct ether_addr * sta_ea,const uint8 * anonce,const uint8 * snonce,const uint8 * pmk,uint pmk_len,uint8 * ptk,uint ptk_len)418 wpa_calc_ft_ptk(sha2_hash_type_t hash_type,
419 	const struct ether_addr *bssid, const struct ether_addr *sta_ea,
420 	const uint8 *anonce, const uint8* snonce,
421 	const uint8 *pmk, uint pmk_len, uint8 *ptk, uint ptk_len)
422 {
423 	bcm_const_xlvp_t pfx[5];
424 	int npfx = 0;
425 
426 	/* FT-PTK||SNONCE||ANONCE||BSSID||STA Addr */
427 
428 	pfx[npfx].len = sizeof(FT_PTK_PFX) - 1;
429 	pfx[npfx++].data = (uint8 *)FT_PTK_PFX;
430 
431 	pfx[npfx].len = EAPOL_WPA_KEY_NONCE_LEN;
432 	pfx[npfx++].data = snonce;
433 
434 	pfx[npfx].len = EAPOL_WPA_KEY_NONCE_LEN;
435 	pfx[npfx++].data = anonce;
436 
437 	pfx[npfx].len = ETHER_ADDR_LEN;
438 	pfx[npfx++].data = (const uint8 *)bssid;
439 
440 	pfx[npfx].len = ETHER_ADDR_LEN;
441 	pfx[npfx++].data = (const uint8 *)sta_ea;
442 
443 	hmac_sha2_n(hash_type, pmk, pmk_len, pfx, npfx, NULL, 0, ptk, ptk_len);
444 }
445 
446 void
wpa_derive_pmkR1_name(sha2_hash_type_t hash_type,struct ether_addr * r1kh,struct ether_addr * sta_ea,uint8 * pmkr0name,uint8 * pmkr1name)447 wpa_derive_pmkR1_name(sha2_hash_type_t hash_type,
448 	struct ether_addr *r1kh, struct ether_addr *sta_ea,
449 	uint8 *pmkr0name, uint8 *pmkr1name)
450 {
451 	wpa_calc_pmkR1(hash_type, r1kh, sta_ea, NULL /* pmk */, 0,
452 		pmkr0name, NULL /* pmkr1 */, pmkr1name);
453 }
454 #endif /* WLFBT || WLHOSTFBT */
455 #endif /* BCMSUP_PSK || WLFBT || WL_OKC */
456 
457 #if defined(BCMSUP_PSK) || defined(GTKOE) || defined(BCMAUTH_PSK) || defined(WLFBT)
458 /* Decrypt a key data from a WPA key message */
459 int
wpa_decr_key_data(eapol_wpa_key_header_t * body,uint16 key_info,uint8 * ekey,uint8 * encrkey,rc4_ks_t * rc4key,const rsn_ie_info_t * rsn_info,uint16 * dec_len)460 wpa_decr_key_data(eapol_wpa_key_header_t *body, uint16 key_info, uint8 *ekey,
461 	uint8 *encrkey, rc4_ks_t *rc4key, const rsn_ie_info_t *rsn_info, uint16 *dec_len)
462 {
463 	uint16 len;
464 	int err = BCME_OK;
465 	uint8 *key_data;
466 
467 	switch (key_info & (WPA_KEY_DESC_V1 | WPA_KEY_DESC_V2)) {
468 	case WPA_KEY_DESC_V1:
469 		err = memcpy_s(encrkey, EAPOL_WPA_KEY_IV_LEN + EAPOL_WPA_ENCR_KEY_MAX_LEN,
470 			body->iv, EAPOL_WPA_KEY_IV_LEN);
471 		if (err) {
472 			ASSERT(0);
473 			return err;
474 		}
475 		err = memcpy_s(&encrkey[EAPOL_WPA_KEY_IV_LEN], EAPOL_WPA_ENCR_KEY_MAX_LEN,
476 			ekey, rsn_info->kek_len);
477 		if (err) {
478 			ASSERT(0);
479 			return err;
480 		}
481 		/* decrypt the key data */
482 		prepare_key(encrkey, EAPOL_WPA_KEY_IV_LEN + rsn_info->kek_len, rc4key);
483 		rc4(NULL, WPA_KEY_DATA_LEN_256, rc4key); /* dump 256 bytes */
484 		len = ntoh16_ua(EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body, rsn_info->kck_mic_len));
485 		key_data = EAPOL_WPA_KEY_HDR_DATA_PTR(body, rsn_info->kck_mic_len);
486 		rc4(key_data, len, rc4key);
487 		break;
488 
489 	case WPA_KEY_DESC_V2:
490 	case WPA_KEY_DESC_V3:
491 	case WPA_KEY_DESC_V0:
492 		/* fallthrough */
493 		len = ntoh16_ua(EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body, rsn_info->kck_mic_len));
494 		if (!len) {
495 			*dec_len = 0;
496 			break; /* ignore zero length */
497 		}
498 		key_data = EAPOL_WPA_KEY_HDR_DATA_PTR(body, rsn_info->kck_mic_len);
499 		if (aes_unwrap(rsn_info->kek_len, ekey, len, key_data, key_data)) {
500 			*dec_len = 0;
501 			err = BCME_DECERR;
502 			break;
503 		}
504 		*dec_len = (len > AKW_BLOCK_LEN) ? (len - AKW_BLOCK_LEN) : 0;
505 		break;
506 
507 	default:
508 		*dec_len = 0;
509 		err = BCME_UNSUPPORTED; /* may need revisiting - see 802.11-2016 */
510 		break;
511 	}
512 
513 	return err;
514 }
515 
516 /* internal function - assumes enouch space allocated, retuns written number */
517 static int
wpa_calc_ptk_prefixes(const uint8 * prefix,uint prefix_len,const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * anonce,uint8 anonce_len,const uint8 * snonce,uint8 snonce_len,bcm_const_xlvp_t * pfx)518 wpa_calc_ptk_prefixes(const uint8 *prefix, uint prefix_len,
519 	const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
520 	const uint8 *anonce, uint8 anonce_len, const uint8 *snonce, uint8 snonce_len,
521 	bcm_const_xlvp_t *pfx)
522 {
523 	int npfx = 0;
524 	const uint8 *nonce;
525 
526 	/* prefix || min ea || max ea || min nonce || max nonce */
527 	pfx[npfx].len = (uint16)(prefix_len & 0xffff);
528 	pfx[npfx++].data = prefix;
529 
530 	pfx[npfx].len = ETHER_ADDR_LEN;
531 	pfx[npfx++].data = (const uint8 *) wpa_array_cmp(MIN_ARRAY,
532 		(const uint8 *)auth_ea, (const uint8 *)sta_ea, ETHER_ADDR_LEN);
533 
534 	pfx[npfx].len = ETHER_ADDR_LEN;
535 	pfx[npfx++].data = (const uint8 *) wpa_array_cmp(MAX_ARRAY,
536 		(const uint8 *)auth_ea, (const uint8 *)sta_ea, ETHER_ADDR_LEN);
537 
538 	nonce = (const uint8 *)wpa_array_cmp(MIN_ARRAY, snonce, anonce, snonce_len);
539 
540 	if (nonce == snonce) {
541 		pfx[npfx].len = snonce_len;
542 		pfx[npfx++].data = snonce;
543 		pfx[npfx].len = anonce_len;
544 		pfx[npfx++].data = anonce;
545 	} else {
546 		pfx[npfx].len = anonce_len;
547 		pfx[npfx++].data = anonce;
548 		pfx[npfx].len = snonce_len;
549 		pfx[npfx++].data = snonce;
550 	}
551 
552 	return npfx;
553 }
554 
555 void
kdf_calc_ptk(const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * anonce,const uint8 * snonce,const uint8 * pmk,uint pmk_len,uint8 * ptk,uint ptk_len)556 kdf_calc_ptk(const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
557 	const uint8 *anonce, const uint8* snonce,
558 	const uint8 *pmk, uint pmk_len, uint8 *ptk, uint ptk_len)
559 {
560 	bcm_const_xlvp_t pfx[5];
561 	int npfx;
562 
563 	/* note: kdf omits trailing NULL in prefix */
564 	npfx = wpa_calc_ptk_prefixes((uint8 *)WPA_PTK_PFX, sizeof(WPA_PTK_PFX) - 1,
565 		auth_ea, sta_ea, anonce, EAPOL_WPA_KEY_NONCE_LEN, snonce,
566 		EAPOL_WPA_KEY_NONCE_LEN, pfx);
567 	hmac_sha2_n(HASH_SHA256, pmk, pmk_len, pfx, npfx, NULL, 0, ptk, ptk_len);
568 }
569 #endif	/* BCMSUP_PSK || GTKOE || BCMAUTH_PSK || WLFBT */
570 
571 #if defined(BCMSUP_PSK) || defined(BCMAUTH_PSK) || defined(WLFBT) || defined(GTKOE)
572 /* Compute Message Integrity Code (MIC) over EAPOL message */
573 int
wpa_make_mic(eapol_header_t * eapol,uint key_desc,uint8 * mic_key,rsn_ie_info_t * rsn_info,uchar * mic,uint mic_len)574 wpa_make_mic(eapol_header_t *eapol, uint key_desc, uint8 *mic_key,
575 	rsn_ie_info_t *rsn_info, uchar *mic, uint mic_len)
576 {
577 	uint data_len;
578 	int err = BCME_OK;
579 	sha2_hash_type_t type = HASH_NONE;
580 
581 	/* length of eapol pkt from the version field on */
582 	data_len = 4 + ntoh16_ua((uint8 *)&eapol->length);
583 
584 	/* Create the MIC for the pkt */
585 	switch (key_desc) {
586 		case WPA_KEY_DESC_V1:
587 			type = HASH_MD5;
588 			break;
589 		case WPA_KEY_DESC_V2:
590 			/* note: transparent truncation to mic_len */
591 			type = HASH_SHA1;
592 			break;
593 		case WPA_KEY_DESC_V3:
594 			aes_cmac_calc(NULL, 0, &eapol->version, data_len, mic_key,
595 				mic_len, mic, AES_BLOCK_SZ);
596 			goto exit;
597 		case WPA_KEY_DESC_V0:
598 			ASSERT(rsn_info != NULL);
599 			if (rsn_info == NULL) {
600 				return BCME_BADARG;
601 			}
602 			if (IS_SAE_AKM(rsn_info->sta_akm)) {
603 				aes_cmac_calc(NULL, 0, &eapol->version, data_len, mic_key,
604 					mic_len, mic, AES_BLOCK_SZ);
605 					goto exit;
606 			}
607 			type = bcmwpa_rsn_akm_to_hash(rsn_info->sta_akm);
608 			break;
609 		default:
610 			/* 11mc D8.0 some AKMs use descriptor version 0 */
611 			err = BCME_UNSUPPORTED;
612 			goto exit;
613 	}
614 
615 	if (type) {
616 		err = hmac_sha2(type, mic_key, mic_len, NULL, 0, (uint8 *)&eapol->version, data_len,
617 			mic, mic_len);
618 	}
619 exit:
620 	return err;
621 }
622 
623 int
wpa_calc_ptk(rsn_akm_t akm,const struct ether_addr * auth_ea,const struct ether_addr * sta_ea,const uint8 * anonce,uint8 anon_len,const uint8 * snonce,uint8 snon_len,const uint8 * pmk,uint pmk_len,uint8 * ptk,uint ptk_len)624 wpa_calc_ptk(rsn_akm_t akm, const struct ether_addr *auth_ea, const struct ether_addr *sta_ea,
625 	const uint8 *anonce, uint8 anon_len, const uint8 *snonce, uint8 snon_len, const uint8 *pmk,
626 	uint pmk_len, uint8 *ptk, uint ptk_len)
627 {
628 	bcm_const_xlvp_t pfx[PRF_PREFIXES_NUM];
629 	int npfx;
630 	int ret = BCME_OK;
631 	sha2_hash_type_t hash_type;
632 	uint label_len;
633 
634 	if (RSN_AKM_USE_KDF(akm)) {
635 		label_len = sizeof(WPA_PTK_PFX) - 1u;
636 	} else { //WPA AKMS
637 		label_len = sizeof(WPA_PTK_PFX); /* note: wpa needs trailing NULL in prefix */
638 	}
639 
640 	hash_type = bcmwpa_rsn_akm_to_hash(akm);
641 
642 	npfx = wpa_calc_ptk_prefixes((uint8 *)WPA_PTK_PFX, label_len,
643 		auth_ea, sta_ea, anonce, anon_len, snonce, snon_len, pfx);
644 	ret = hmac_sha2_n(hash_type, pmk, pmk_len, pfx, npfx, NULL, 0, ptk, ptk_len);
645 	return ret;
646 }
647 
648 bool
wpa_encr_key_data(eapol_wpa_key_header_t * body,uint16 key_info,uint8 * ekey,uint8 * gtk,uint8 * data,uint8 * encrkey,rc4_ks_t * rc4key,const rsn_ie_info_t * rsn_info)649 wpa_encr_key_data(eapol_wpa_key_header_t *body, uint16 key_info, uint8 *ekey,
650 	uint8 *gtk, uint8 *data, uint8 *encrkey, rc4_ks_t *rc4key, const rsn_ie_info_t *rsn_info)
651 {
652 	uint16 len;
653 	uint8 *key_data;
654 
655 	switch (key_info & (WPA_KEY_DESC_V1 | WPA_KEY_DESC_V2)) {
656 		case WPA_KEY_DESC_V1:
657 			if (gtk) {
658 				len = ntoh16_ua((uint8 *)&body->key_len);
659 			} else {
660 				len = ntoh16_ua(EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body,
661 					rsn_info->kck_mic_len));
662 			}
663 
664 			/* create the iv/ptk key */
665 			if (memcpy_s(encrkey, EAPOL_WPA_KEY_IV_LEN, body->iv, sizeof(body->iv))) {
666 				return FALSE;
667 			}
668 			if (memcpy_s(&encrkey[EAPOL_WPA_KEY_IV_LEN], EAPOL_WPA_ENCR_KEY_DEFAULT_LEN,
669 				ekey, EAPOL_WPA_ENCR_KEY_DEFAULT_LEN)) {
670 				return FALSE;
671 			}
672 			/* encrypt the key data */
673 			prepare_key(encrkey, EAPOL_WPA_KEY_IV_LEN + EAPOL_WPA_ENCR_KEY_DEFAULT_LEN,
674 				rc4key);
675 			rc4(data, WPA_KEY_DATA_LEN_256, rc4key); /* dump 256 bytes */
676 			key_data = EAPOL_WPA_KEY_HDR_DATA_PTR(body, rsn_info->kck_mic_len);
677 			rc4(key_data, len, rc4key);
678 			break;
679 		case WPA_KEY_DESC_V2: /* fall through */
680 		case WPA_KEY_DESC_V3:
681 		case WPA_KEY_DESC_V0:
682 			len = ntoh16_ua(EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body,
683 					rsn_info->kck_mic_len));
684 			/* FIXME: data_len is length to encrypt, but need to make sure
685 			 * buffer is big enought
686 			 * for expansion.  how?  problem for caller?
687 			 */
688 			key_data = EAPOL_WPA_KEY_HDR_DATA_PTR(body, rsn_info->kck_mic_len);
689 			/* pad if needed - min. 16 bytes, 8 byte aligned */
690 			/* padding is 0xdd followed by 0's */
691 			if (len < 2u *AKW_BLOCK_LEN) {
692 				key_data[len] = WPA2_KEY_DATA_PAD;
693 				bzero(&key_data[len + 1u], 2u * AKW_BLOCK_LEN - (len + 1u));
694 				len = 2u *AKW_BLOCK_LEN;
695 			} else if (len % AKW_BLOCK_LEN) {
696 				key_data[len] = WPA2_KEY_DATA_PAD;
697 				bzero(&key_data[len + 1u],
698 					AKW_BLOCK_LEN - ((len + 1u) % AKW_BLOCK_LEN));
699 				len += AKW_BLOCK_LEN - (len % AKW_BLOCK_LEN);
700 			}
701 			if (aes_wrap(rsn_info->kek_len, ekey, len, key_data, key_data)) {
702 				return FALSE;
703 			}
704 			len += AKW_BLOCK_LEN;
705 			hton16_ua_store(len,
706 				(uint8 *)EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body,
707 				rsn_info->kck_mic_len));
708 			break;
709 		default:
710 			/* 11mc D8.0 key descriptor version 0 used */
711 			return FALSE;
712 	}
713 
714 	return TRUE;
715 }
716 
717 /* Check MIC of EAPOL message */
718 bool
wpa_check_mic(eapol_header_t * eapol,uint key_desc,uint8 * mic_key,rsn_ie_info_t * rsn_info)719 wpa_check_mic(eapol_header_t *eapol, uint key_desc, uint8 *mic_key, rsn_ie_info_t *rsn_info)
720 {
721 	eapol_wpa_key_header_t *body = NULL;
722 	uchar digest[SHA2_MAX_DIGEST_LEN];
723 	uchar mic[EAPOL_WPA_KEY_MAX_MIC_LEN];
724 
725 	if (!mic_key || !rsn_info || !eapol) {
726 		return FALSE;
727 	}
728 
729 	body = (eapol_wpa_key_header_t *)eapol->body;
730 
731 #ifndef EAPOL_KEY_HDR_VER_V2
732 	if (rsn_info->kck_mic_len != EAPOL_WPA_KCK_DEFAULT_LEN)
733 #else
734 	if (rsn_info->kck_mic_len > EAPOL_WPA_KEY_MAX_MIC_LEN)
735 #endif /* EAPOL_KEY_HDR_VER_V2 */
736 	{
737 		ASSERT(0);
738 		return FALSE;
739 	}
740 	/* save MIC and clear its space in message */
741 	if (memcpy_s(mic, sizeof(mic), EAPOL_WPA_KEY_HDR_MIC_PTR(body),
742 		rsn_info->kck_mic_len)) {
743 		return FALSE;
744 	}
745 	bzero(EAPOL_WPA_KEY_HDR_MIC_PTR(body), rsn_info->kck_mic_len);
746 	if (wpa_make_mic(eapol, key_desc, mic_key, rsn_info, digest, rsn_info->kck_mic_len)
747 		!= BCME_OK) {
748 		return FALSE;
749 	}
750 	return !memcmp(digest, mic, rsn_info->kck_mic_len);
751 }
752 
bcmwpa_rsn_akm_to_hash(const rsn_akm_t akm)753 static sha2_hash_type_t bcmwpa_rsn_akm_to_hash(const rsn_akm_t akm)
754 {
755 	uint i = 0;
756 	sha2_hash_type_t type = HASH_NONE;
757 
758 	for (i = 0; i < ARRAYSIZE(rsn_akm_lookup_tbl); i++) {
759 		if (akm == rsn_akm_lookup_tbl[i].rsn_akm) {
760 			type = rsn_akm_lookup_tbl[i].hash_type;
761 			break;
762 		}
763 	}
764 	return type;
765 }
766 #endif /* BCMSUP_PSK || BCMAUTH_PSK  || WLFBT || GTKOE */
767 
768 #ifdef WLTDLS
769 void
wpa_calc_tpk(const struct ether_addr * init_ea,const struct ether_addr * resp_ea,const struct ether_addr * bssid,const uint8 * anonce,const uint8 * snonce,uint8 * tpk,uint tpk_len)770 wpa_calc_tpk(const struct ether_addr *init_ea, const struct ether_addr *resp_ea,
771 	const struct ether_addr *bssid, const uint8 *anonce, const uint8* snonce,
772 	uint8 *tpk, uint tpk_len)
773 {
774 	uint8 pmk[SHA2_MAX_DIGEST_LEN];
775 	uint pmk_len;
776 	bcm_const_xlvp_t ikpfx[2];
777 	int nikpfx = 0;
778 	bcm_const_xlvp_t  tpkpfx[4];
779 	int ntpkpfx = 0;
780 
781 	pmk_len = sha2_digest_len(HASH_SHA256);
782 
783 	/* compute pmk to use - using anonce and snonce  - min and then max */
784 	ikpfx[nikpfx].len = EAPOL_WPA_KEY_NONCE_LEN;
785 	ikpfx[nikpfx++].data = wpa_array_cmp(MIN_ARRAY, snonce, anonce,
786 	                    EAPOL_WPA_KEY_NONCE_LEN),
787 
788 	ikpfx[nikpfx].len = EAPOL_WPA_KEY_NONCE_LEN;
789 	ikpfx[nikpfx++].data = wpa_array_cmp(MAX_ARRAY, snonce, anonce,
790 	                    EAPOL_WPA_KEY_NONCE_LEN),
791 
792 	(void)sha2(HASH_SHA256, ikpfx, nikpfx, NULL, 0, pmk, SHA2_SHA256_DIGEST_LEN);
793 
794 	/* compute the tpk - using prefix, min ea, max ea, bssid */
795 	tpkpfx[ntpkpfx].len = sizeof(TDLS_PMK_PFX) - 1;
796 	tpkpfx[ntpkpfx++].data = (const uint8 *)TDLS_PMK_PFX;
797 
798 	tpkpfx[ntpkpfx].len = ETHER_ADDR_LEN;
799 	tpkpfx[ntpkpfx++].data = wpa_array_cmp(MIN_ARRAY, (const uint8 *)init_ea,
800 		(const uint8 *)resp_ea, ETHER_ADDR_LEN),
801 
802 	tpkpfx[ntpkpfx].len = ETHER_ADDR_LEN;
803 	tpkpfx[ntpkpfx++].data = wpa_array_cmp(MAX_ARRAY, (const uint8 *)init_ea,
804 		(const uint8 *)resp_ea, ETHER_ADDR_LEN),
805 
806 	tpkpfx[ntpkpfx].len = ETHER_ADDR_LEN;
807 	tpkpfx[ntpkpfx++].data = (const uint8 *)bssid;
808 
809 	(void)hmac_sha2_n(HASH_SHA256, pmk, pmk_len, tpkpfx, ntpkpfx, NULL, 0, tpk, tpk_len);
810 }
811 #endif /* WLTDLS */
812 
813 /* Convert WPA/WPA2 IE cipher suite to locally used value */
814 static bool
rsn_cipher(wpa_suite_t * suite,ushort * cipher,const uint8 * std_oui,bool wep_ok)815 rsn_cipher(wpa_suite_t *suite, ushort *cipher, const uint8 *std_oui, bool wep_ok)
816 {
817 	bool ret = TRUE;
818 
819 	if (!memcmp((const char *)suite->oui, std_oui, DOT11_OUI_LEN)) {
820 		switch (suite->type) {
821 		case WPA_CIPHER_TKIP:
822 			*cipher = CRYPTO_ALGO_TKIP;
823 			break;
824 		case WPA_CIPHER_AES_CCM:
825 			*cipher = CRYPTO_ALGO_AES_CCM;
826 			break;
827 		case WPA_CIPHER_AES_GCM:
828 			*cipher = CRYPTO_ALGO_AES_GCM;
829 			break;
830 		case WPA_CIPHER_AES_GCM256:
831 			*cipher = CRYPTO_ALGO_AES_GCM256;
832 			break;
833 		case WPA_CIPHER_WEP_40:
834 			if (wep_ok)
835 				*cipher = CRYPTO_ALGO_WEP1;
836 			else
837 				ret = FALSE;
838 			break;
839 		case WPA_CIPHER_WEP_104:
840 			if (wep_ok)
841 				*cipher = CRYPTO_ALGO_WEP128;
842 			else
843 				ret = FALSE;
844 			break;
845 		default:
846 			ret = FALSE;
847 			break;
848 		}
849 		return ret;
850 	}
851 
852 	return FALSE;
853 }
854 
855 bool
wpa_cipher(wpa_suite_t * suite,ushort * cipher,bool wep_ok)856 wpa_cipher(wpa_suite_t *suite, ushort *cipher, bool wep_ok)
857 {
858 	return rsn_cipher(suite, cipher, (const uchar*)WPA_OUI, wep_ok);
859 }
860 
861 bool
wpa2_cipher(wpa_suite_t * suite,ushort * cipher,bool wep_ok)862 wpa2_cipher(wpa_suite_t *suite, ushort *cipher, bool wep_ok)
863 {
864 	return rsn_cipher(suite, cipher, (const uchar*)WPA2_OUI, wep_ok);
865 }
866 
867 /* Is any of the tlvs the expected entry? If
868  * not update the tlvs buffer pointer/length.
869  */
870 bool
bcm_has_ie(uint8 * ie,uint8 ** tlvs,uint * tlvs_len,const uint8 * oui,uint oui_len,uint8 type)871 bcm_has_ie(uint8 *ie, uint8 **tlvs, uint *tlvs_len, const uint8 *oui, uint oui_len, uint8 type)
872 {
873 	/* If the contents match the OUI and the type */
874 	if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
875 	    !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
876 	    type == ie[TLV_BODY_OFF + oui_len]) {
877 		return TRUE;
878 	}
879 
880 	/* point to the next ie */
881 	ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
882 	/* calculate the length of the rest of the buffer */
883 	*tlvs_len -= (uint)(ie - *tlvs);
884 	/* update the pointer to the start of the buffer */
885 	*tlvs = ie;
886 
887 	return FALSE;
888 }
889 
890 wpa_ie_fixed_t *
bcm_find_wpaie(uint8 * parse,uint len)891 bcm_find_wpaie(uint8 *parse, uint len)
892 {
893 	return (wpa_ie_fixed_t *) bcm_find_ie(parse, len, DOT11_MNG_VS_ID,
894 		WPA_OUI_LEN, (const char*) WPA_OUI, WPA_OUI_TYPE);
895 }
896 
897 int
bcm_find_security_ies(uint8 * buf,uint buflen,void ** wpa_ie,void ** rsn_ie)898 bcm_find_security_ies(uint8 *buf, uint buflen, void **wpa_ie,
899 		void **rsn_ie)
900 {
901 	bcm_tlv_t *tlv = NULL;
902 	uint totlen = 0;
903 	uint8 *end = NULL;
904 	uint len = 0;
905 	uint tlvs_len = 0;
906 	uint8 *tlvs = NULL;
907 
908 	if ((tlv = (bcm_tlv_t*)buf) == NULL ||
909 			!wpa_ie || !rsn_ie || buflen == 0) {
910 		return BCME_BADARG;
911 	}
912 
913 	totlen = buflen;
914 	*rsn_ie = *wpa_ie = NULL;
915 	end = buf;
916 	end += buflen;
917 
918 	/* find rsn ie and wpa ie */
919 	while (totlen >= TLV_HDR_LEN) {
920 		len = tlv->len;
921 		tlvs_len = buflen;
922 		tlvs = buf;
923 
924 		/* check if tlv overruns buffer */
925 		if (totlen < (len + TLV_HDR_LEN)) {
926 			return BCME_BUFTOOSHORT;
927 		}
928 
929 		/* validate remaining totlen */
930 		if (totlen >= (len + TLV_HDR_LEN)) {
931 			if ((*rsn_ie == NULL) && (tlv->id == DOT11_MNG_RSN_ID)) {
932 				*rsn_ie = tlv;
933 			} else if ((*wpa_ie == NULL) && (tlv->id == DOT11_MNG_VS_ID)) {
934 				/* if vendor ie, check if its wpa ie */
935 				if (bcm_is_wpa_ie((uint8 *)tlv, &tlvs, &tlvs_len))
936 					*wpa_ie = tlv;
937 			}
938 		}
939 
940 		if (*rsn_ie && *wpa_ie)
941 			break;
942 
943 		tlv = (bcm_tlv_t*)((uint8*)tlv + (len + TLV_HDR_LEN));
944 		totlen -= (len + TLV_HDR_LEN);
945 
946 		if (totlen > buflen) {
947 			return BCME_BUFTOOLONG;
948 		}
949 
950 		if ((uint8 *)tlv > end) {
951 			return BCME_BUFTOOSHORT;
952 		}
953 
954 	}
955 
956 	if (*wpa_ie || *rsn_ie)
957 		return BCME_OK;
958 	else
959 		return BCME_NOTFOUND;
960 }
961 
962 bcm_tlv_t *
bcm_find_wmeie(uint8 * parse,uint len,uint8 subtype,uint8 subtype_len)963 bcm_find_wmeie(uint8 *parse, uint len, uint8 subtype, uint8 subtype_len)
964 {
965 	bcm_tlv_t *ie;
966 	if ((ie = bcm_find_ie(parse, len, DOT11_MNG_VS_ID, WME_OUI_LEN,
967 		(const char*) WME_OUI, WME_OUI_TYPE))) {
968 		uint ie_len = TLV_HDR_LEN + ie->len;
969 		wme_ie_t *ie_data = (wme_ie_t *)ie->data;
970 		/* the subtype_len must include OUI+type+subtype */
971 		if (subtype_len > WME_OUI_LEN + 1 &&
972 		    ie_len == (uint)TLV_HDR_LEN + subtype_len &&
973 		    ie_data->subtype == subtype) {
974 			return ie;
975 		}
976 		/* move to next IE */
977 		len -= (uint)((uint8 *)ie + ie_len - parse);
978 		parse = (uint8 *)ie + ie_len;
979 	}
980 	return NULL;
981 }
982 
983 wps_ie_fixed_t *
bcm_find_wpsie(const uint8 * parse,uint len)984 bcm_find_wpsie(const uint8 *parse, uint len)
985 {
986 	uint8 type = WPS_OUI_TYPE;
987 
988 	return (wps_ie_fixed_t *)bcm_find_vendor_ie(parse, len, WPS_OUI, &type, sizeof(type));
989 }
990 
991 /* locate the Attribute in the WPS IE */
992 /* assume the caller has validated the WPS IE tag and length */
993 wps_at_fixed_t *
bcm_wps_find_at(wps_at_fixed_t * at,uint len,uint16 id)994 bcm_wps_find_at(wps_at_fixed_t *at, uint len, uint16 id)
995 {
996 	while ((int)len >= WPS_AT_FIXED_LEN) {
997 		uint alen = WPS_AT_FIXED_LEN + ntoh16_ua(((wps_at_fixed_t *)at)->len);
998 		if (ntoh16_ua(((wps_at_fixed_t *)at)->at) == id && alen <= len)
999 			return at;
1000 		at = (wps_at_fixed_t *)((uint8 *)at + alen);
1001 		len -= alen;
1002 	}
1003 	return NULL;
1004 }
1005 
1006 #ifdef WLP2P
1007 wifi_p2p_ie_t *
bcm_find_p2pie(const uint8 * parse,uint len)1008 bcm_find_p2pie(const uint8 *parse, uint len)
1009 {
1010 	uint8 type = P2P_OUI_TYPE;
1011 
1012 	return (wifi_p2p_ie_t *)bcm_find_vendor_ie(parse, len, P2P_OUI, &type, sizeof(type));
1013 }
1014 #endif
1015 
1016 bcm_tlv_t *
bcm_find_hs20ie(uint8 * parse,uint len)1017 bcm_find_hs20ie(uint8 *parse, uint len)
1018 {
1019 	return bcm_find_ie(parse, len, DOT11_MNG_VS_ID, WFA_OUI_LEN,
1020 		(const char *)WFA_OUI, WFA_OUI_TYPE_HS20);
1021 }
1022 
1023 bcm_tlv_t *
bcm_find_osenie(uint8 * parse,uint len)1024 bcm_find_osenie(uint8 *parse, uint len)
1025 {
1026 	return bcm_find_ie(parse, len, DOT11_MNG_VS_ID, WFA_OUI_LEN,
1027 		(const char *) WFA_OUI, WFA_OUI_TYPE_OSEN);
1028 }
1029 
1030 #if defined(BCMSUP_PSK) || defined(BCMSUPPL) || defined(GTKOE) || defined(WL_FILS)
1031 #define wpa_is_kde(ie, tlvs, len, type)	bcm_has_ie(ie, tlvs, len, \
1032 	(const uint8 *)WPA2_OUI, WPA2_OUI_LEN, type)
1033 
1034 eapol_wpa2_encap_data_t *
wpa_find_kde(const uint8 * parse,uint len,uint8 type)1035 wpa_find_kde(const uint8 *parse, uint len, uint8 type)
1036 {
1037 	return (eapol_wpa2_encap_data_t *) bcm_find_ie(parse, len,
1038 		DOT11_MNG_PROPR_ID, WPA2_OUI_LEN, (const char *) WPA2_OUI, type);
1039 }
1040 
1041 bool
wpa_is_gtk_encap(uint8 * ie,uint8 ** tlvs,uint * tlvs_len)1042 wpa_is_gtk_encap(uint8 *ie, uint8 **tlvs, uint *tlvs_len)
1043 {
1044 	return wpa_is_kde(ie, tlvs, tlvs_len, WPA2_KEY_DATA_SUBTYPE_GTK);
1045 }
1046 
1047 eapol_wpa2_encap_data_t *
wpa_find_gtk_encap(uint8 * parse,uint len)1048 wpa_find_gtk_encap(uint8 *parse, uint len)
1049 {
1050 	eapol_wpa2_encap_data_t *data;
1051 
1052 	/* minimum length includes kde upto gtk field in eapol_wpa2_key_gtk_encap_t */
1053 	data = wpa_find_kde(parse, len, WPA2_KEY_DATA_SUBTYPE_GTK);
1054 	if (data && (data->length < EAPOL_WPA2_GTK_ENCAP_MIN_LEN)) {
1055 		data = NULL;
1056 	}
1057 
1058 	return data;
1059 }
1060 
1061 int
wpa_find_eapol_kde_data(eapol_header_t * eapol,uint8 eapol_mic_len,uint8 subtype,eapol_wpa2_encap_data_t ** out_data)1062 wpa_find_eapol_kde_data(eapol_header_t* eapol, uint8 eapol_mic_len,
1063 	uint8 subtype, eapol_wpa2_encap_data_t **out_data)
1064 {
1065 	eapol_wpa_key_header_t *body;
1066 	uint8 *parse;
1067 	uint16 body_len;
1068 	uint16 data_len;
1069 
1070 	if (!eapol) {
1071 		return BCME_BADARG;
1072 	}
1073 
1074 	body = (eapol_wpa_key_header_t *)eapol->body;
1075 	body_len = ntoh16_ua(&eapol->length);
1076 
1077 	data_len = ntoh16_ua(EAPOL_WPA_KEY_HDR_DATA_LEN_PTR(body,
1078 			eapol_mic_len));
1079 
1080 	parse = EAPOL_WPA_KEY_HDR_DATA_PTR(body, eapol_mic_len);
1081 
1082 	if (((uint8 *)body + body_len) < ((uint8 *)parse + data_len)) {
1083 		return BCME_BUFTOOSHORT;
1084 	}
1085 
1086 	return wpa_find_kde_data(parse, data_len, subtype, out_data);
1087 }
1088 
1089 int
wpa_find_kde_data(const uint8 * kde_buf,uint16 buf_len,uint8 subtype,eapol_wpa2_encap_data_t ** out_data)1090 wpa_find_kde_data(const uint8 *kde_buf, uint16 buf_len,
1091 	uint8 subtype, eapol_wpa2_encap_data_t **out_data)
1092 {
1093 	eapol_wpa2_encap_data_t *data;
1094 	uint8 min_len;
1095 
1096 	if (!kde_buf) {
1097 		return BCME_BADARG;
1098 	}
1099 
1100 	/* minimum length includes kde upto gtk field in eapol_wpa2_key_gtk_encap_t */
1101 	data = wpa_find_kde(kde_buf, buf_len, subtype);
1102 	if (!data) {
1103 		return BCME_IE_NOTFOUND;
1104 	}
1105 
1106 	switch (subtype) {
1107 	case WPA2_KEY_DATA_SUBTYPE_GTK:
1108 		min_len = EAPOL_WPA2_GTK_ENCAP_MIN_LEN;
1109 		break;
1110 	case WPA2_KEY_DATA_SUBTYPE_IGTK:
1111 		min_len = EAPOL_WPA2_BIGTK_ENCAP_MIN_LEN;
1112 		break;
1113 	case WPA2_KEY_DATA_SUBTYPE_BIGTK:
1114 		min_len = EAPOL_WPA2_IGTK_ENCAP_MIN_LEN;
1115 		break;
1116 #ifdef WL_OCV
1117 	case WPA2_KEY_DATA_SUBTYPE_OCI:
1118 		min_len = EAPOL_WPA2_OCI_ENCAP_MIN_LEN;
1119 		break;
1120 #endif /* WL_OCV */
1121 	default:
1122 		return BCME_UNSUPPORTED;
1123 	}
1124 
1125 	if (data->length < min_len) {
1126 		return BCME_BADLEN;
1127 	}
1128 
1129 	*out_data = data;
1130 
1131 	return BCME_OK;
1132 }
1133 
1134 #ifdef WL_OCV
1135 bool
wpa_check_ocv_caps(uint16 local_caps,uint16 peer_caps)1136 wpa_check_ocv_caps(uint16 local_caps, uint16 peer_caps)
1137 {
1138 	bool ocv_enabled =
1139 		((local_caps & RSN_CAP_OCVC) &&
1140 		(peer_caps & RSN_CAP_OCVC));
1141 	bool mfp_enabled =
1142 		((peer_caps & RSN_CAP_MFPC) ||
1143 		(peer_caps & RSN_CAP_MFPR));
1144 
1145 	return (ocv_enabled && mfp_enabled);
1146 }
1147 
1148 int
wpa_add_oci_encap(chanspec_t chspec,uint8 * buf,uint buf_len)1149 wpa_add_oci_encap(chanspec_t chspec, uint8* buf, uint buf_len)
1150 {
1151 	int retval = BCME_OK;
1152 	eapol_wpa2_encap_data_t* oci_kde;
1153 	uint len = buf_len;
1154 
1155 	if (buf_len < WPA_OCV_OCI_KDE_SIZE) {
1156 		retval = BCME_BUFTOOSHORT;
1157 		goto done;
1158 	}
1159 
1160 	oci_kde = (eapol_wpa2_encap_data_t*)buf;
1161 
1162 	oci_kde->type = DOT11_MNG_WPA_ID;
1163 	oci_kde->subtype = WPA2_KEY_DATA_SUBTYPE_OCI;
1164 	oci_kde->length = (WPA_OCV_OCI_KDE_SIZE - TLV_HDR_LEN);
1165 
1166 	oci_kde->oui[0u] = WPA2_OUI[0u];
1167 	oci_kde->oui[1u] = WPA2_OUI[1u];
1168 	oci_kde->oui[2u] = WPA2_OUI[2u];
1169 
1170 	buf += EAPOL_WPA2_ENCAP_DATA_HDR_LEN;
1171 	len -= EAPOL_WPA2_ENCAP_DATA_HDR_LEN;
1172 
1173 	retval = bcm_ocv_write_oci(chspec, buf, len);
1174 	if (retval != BCME_OK) {
1175 		goto done;
1176 	}
1177 
1178 done:
1179 	return retval;
1180 }
1181 
1182 int
wpa_add_oci_ie(chanspec_t chspec,uint8 * buf,uint buf_len)1183 wpa_add_oci_ie(chanspec_t chspec, uint8* buf, uint buf_len)
1184 {
1185 	int retval = BCME_OK;
1186 	uint8* oci_buf = buf + BCM_TLV_EXT_HDR_SIZE;
1187 
1188 	if (buf_len < (bcm_ocv_get_oci_len() + BCM_TLV_EXT_HDR_SIZE)) {
1189 		retval = BCME_BUFTOOSHORT;
1190 		goto done;
1191 	}
1192 
1193 	retval = bcm_ocv_write_oci(chspec, oci_buf, bcm_ocv_get_oci_len());
1194 	if (retval != BCME_OK) {
1195 		goto done;
1196 	}
1197 
1198 	(void)bcm_write_tlv_ext(DOT11_MNG_ID_EXT_ID,
1199 		OCV_EXTID_MNG_OCI_ID, oci_buf, bcm_ocv_get_oci_len(), buf);
1200 
1201 done:
1202 	return retval;
1203 }
1204 
1205 int
wpa_add_oci_ft_subelem(chanspec_t chspec,uint8 * buf,uint buf_len)1206 wpa_add_oci_ft_subelem(chanspec_t chspec, uint8* buf, uint buf_len)
1207 {
1208 	int retval = BCME_OK;
1209 	uint8* oci_buf = buf + BCM_TLV_HDR_SIZE;
1210 
1211 	if (buf_len < (bcm_ocv_get_oci_len() + BCM_TLV_HDR_SIZE)) {
1212 		retval = BCME_BUFTOOSHORT;
1213 		goto done;
1214 	}
1215 
1216 	retval = bcm_ocv_write_oci(chspec, oci_buf, bcm_ocv_get_oci_len());
1217 	if (retval != BCME_OK) {
1218 		goto done;
1219 	}
1220 
1221 	bcm_write_tlv_safe(DOT11_FBT_SUBELEM_ID_OCI,
1222 		oci_buf, bcm_ocv_get_oci_len(), buf, buf_len);
1223 
1224 done:
1225 	return retval;
1226 }
1227 
wpa_validate_oci_encap(chanspec_t chspec,const uint8 * buf,uint buf_len)1228 int wpa_validate_oci_encap(chanspec_t chspec, const uint8* buf, uint buf_len)
1229 {
1230 	int retval = BCME_OK;
1231 	eapol_wpa2_encap_data_t *encap = NULL;
1232 
1233 	retval = wpa_find_kde_data(buf, buf_len, WPA2_KEY_DATA_SUBTYPE_OCI, &encap);
1234 	if (retval != BCME_OK) {
1235 		retval = BCME_NOTFOUND;
1236 		goto done;
1237 	}
1238 
1239 	retval = bcm_ocv_validate_oci(chspec,
1240 		encap->data, encap->length);
1241 	if (retval != BCME_OK) {
1242 		goto done;
1243 	}
1244 
1245 done:
1246 	return retval;
1247 }
1248 
wpa_validate_oci_ie(chanspec_t chspec,const uint8 * buf,uint buf_len)1249 int wpa_validate_oci_ie(chanspec_t chspec, const uint8* buf, uint buf_len)
1250 {
1251 	int retval = BCME_OK;
1252 	bcm_tlv_ext_t *oci_ie;
1253 
1254 	oci_ie = (bcm_tlv_ext_t *)bcm_parse_tlvs_dot11(buf, buf_len,
1255 			OCV_EXTID_MNG_OCI_ID, TRUE);
1256 
1257 	if (!oci_ie) {
1258 		retval = BCME_NOTFOUND;
1259 		goto done;
1260 	}
1261 
1262 	retval = bcm_ocv_validate_oci(chspec, oci_ie->data, oci_ie->len);
1263 	if (retval != BCME_OK) {
1264 		goto done;
1265 	}
1266 
1267 done:
1268 	return retval;
1269 }
1270 
wpa_validate_oci_ft_subelem(chanspec_t chspec,const uint8 * buf,uint buf_len)1271 int wpa_validate_oci_ft_subelem(chanspec_t chspec, const uint8* buf, uint buf_len)
1272 {
1273 	int retval = BCME_OK;
1274 	bcm_tlv_t *oci_ie;
1275 
1276 	oci_ie = (bcm_tlv_t *)bcm_parse_tlvs_dot11(buf, buf_len,
1277 			DOT11_FBT_SUBELEM_ID_OCI, FALSE);
1278 
1279 	if (!oci_ie) {
1280 		retval = BCME_NOTFOUND;
1281 		goto done;
1282 	}
1283 
1284 	retval = bcm_ocv_validate_oci(chspec, oci_ie->data, oci_ie->len);
1285 	if (retval != BCME_OK) {
1286 		goto done;
1287 	}
1288 
1289 done:
1290 	return retval;
1291 }
1292 #endif /* WL_OCV */
1293 #endif /* defined(BCMSUP_PSK) || defined(BCMSUPPL) || defined(GTKOE) || defined(WL_FILS) */
1294 
1295 const uint8 *
wpa_array_cmp(int max_array,const uint8 * x,const uint8 * y,uint len)1296 wpa_array_cmp(int max_array, const uint8 *x, const uint8 *y, uint len)
1297 {
1298 	uint i;
1299 	const uint8 *ret = x;
1300 
1301 	for (i = 0; i < len; i++)
1302 		if (x[i] != y[i])
1303 			break;
1304 
1305 	if (i == len) {
1306 		/* returning null will cause crash, return value used for copying */
1307 		/* return first param in this case to close security loophole */
1308 		return x;
1309 	}
1310 	if (max_array && (y[i] > x[i]))
1311 		ret = y;
1312 	if (!max_array && (y[i] < x[i]))
1313 		ret = y;
1314 
1315 	return (ret);
1316 }
1317 
1318 void
wpa_incr_array(uint8 * array,uint len)1319 wpa_incr_array(uint8 *array, uint len)
1320 {
1321 	int i;
1322 
1323 	for (i = (len-1); i >= 0; i--)
1324 		if (array[i]++ != 0xff) {
1325 			break;
1326 		}
1327 }
1328 
1329 bool
bcmwpa_akm2WPAauth(uint8 * akm,uint32 * auth,bool sta_iswpa)1330 bcmwpa_akm2WPAauth(uint8 *akm, uint32 *auth, bool sta_iswpa)
1331 {
1332 	uint i;
1333 	oui_akm_wpa_tbl_t wpa_auth_tbl_match[] = {
1334 		{WPA2_OUI, RSN_AKM_NONE, WPA_AUTH_NONE},
1335 		{WPA2_OUI, RSN_AKM_UNSPECIFIED, WPA2_AUTH_UNSPECIFIED},
1336 		{WPA2_OUI, RSN_AKM_PSK, WPA2_AUTH_PSK},
1337 		{WPA2_OUI, RSN_AKM_FBT_1X, WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT},
1338 		{WPA2_OUI, RSN_AKM_FBT_PSK, WPA2_AUTH_PSK | WPA2_AUTH_FT},
1339 		{WPA2_OUI, RSN_AKM_SHA256_1X, WPA2_AUTH_1X_SHA256},
1340 		{WPA2_OUI, RSN_AKM_SHA256_PSK, WPA2_AUTH_PSK_SHA256},
1341 		{WPA2_OUI, RSN_AKM_FILS_SHA256, WPA2_AUTH_FILS_SHA256},
1342 		{WPA2_OUI, RSN_AKM_FILS_SHA384, WPA2_AUTH_FILS_SHA384},
1343 		{WPA2_OUI, RSN_AKM_FBT_SHA256_FILS, WPA2_AUTH_FILS_SHA256 | WPA2_AUTH_FT},
1344 		{WPA2_OUI, RSN_AKM_FBT_SHA384_FILS, WPA2_AUTH_FILS_SHA384 | WPA2_AUTH_FT},
1345 		{WPA2_OUI, RSN_AKM_SAE_PSK, WPA3_AUTH_SAE_PSK},
1346 		{WPA2_OUI, RSN_AKM_SAE_FBT, WPA3_AUTH_SAE_PSK | WPA2_AUTH_FT},
1347 		{WPA2_OUI, RSN_AKM_OWE, WPA3_AUTH_OWE},
1348 		{WPA2_OUI, RSN_AKM_SUITEB_SHA256_1X, WPA3_AUTH_1X_SUITE_B_SHA256},
1349 		{WPA2_OUI, RSN_AKM_SUITEB_SHA384_1X, WPA3_AUTH_1X_SUITE_B_SHA384},
1350 		{WFA_OUI, OSEN_AKM_UNSPECIFIED, WPA2_AUTH_UNSPECIFIED},
1351 		{WFA_OUI, RSN_AKM_FBT_SHA256_FILS, WPA2_AUTH_FILS_SHA256 | WPA2_AUTH_FT},
1352 		{WFA_OUI, RSN_AKM_FBT_SHA384_FILS, WPA2_AUTH_FILS_SHA384 | WPA2_AUTH_FT},
1353 		{WFA_OUI, RSN_AKM_DPP, WPA3_AUTH_DPP_AKM},
1354 
1355 #ifdef BCMWAPI_WAI
1356 		{WAPI_OUI, RSN_AKM_NONE, WAPI_AUTH_NONE},
1357 		{WAPI_OUI, RSN_AKM_UNSPECIFIED, WAPI_AUTH_UNSPECIFIED},
1358 		{WAPI_OUI, RSN_AKM_PSK, WAPI_AUTH_PSK},
1359 #endif /* BCMWAPI_WAI */
1360 
1361 		{WPA_OUI, RSN_AKM_NONE, WPA_AUTH_NONE},
1362 		{WPA_OUI, RSN_AKM_UNSPECIFIED, WPA_AUTH_UNSPECIFIED},
1363 		{WPA_OUI, RSN_AKM_PSK, WPA_AUTH_PSK},
1364 	};
1365 
1366 	BCM_REFERENCE(sta_iswpa);
1367 
1368 	for (i = 0; i < ARRAYSIZE(wpa_auth_tbl_match); i++)  {
1369 		if (!memcmp(akm, wpa_auth_tbl_match[i].oui, DOT11_OUI_LEN)) {
1370 			if (wpa_auth_tbl_match[i].rsn_akm == akm[DOT11_OUI_LEN]) {
1371 				*auth = wpa_auth_tbl_match[i].wpa_auth;
1372 				return TRUE;
1373 			}
1374 		}
1375 	}
1376 	return FALSE;
1377 }
1378 
1379 /* map cipher suite to internal WSEC_XXXX */
1380 /* cs points 4 byte cipher suite, and only the type is used for non CCX ciphers */
1381 bool
bcmwpa_cipher2wsec(uint8 * cipher,uint32 * wsec)1382 bcmwpa_cipher2wsec(uint8 *cipher, uint32 *wsec)
1383 {
1384 
1385 #ifdef BCMWAPI_WAI
1386 	if (!memcmp(cipher, WAPI_OUI, DOT11_OUI_LEN)) {
1387 		switch (WAPI_CSE_WPI_2_CIPHER(cipher[DOT11_OUI_LEN])) {
1388 		case WAPI_CIPHER_NONE:
1389 			*wsec = 0;
1390 			break;
1391 		case WAPI_CIPHER_SMS4:
1392 			*wsec = SMS4_ENABLED;
1393 			break;
1394 		default:
1395 			return FALSE;
1396 		}
1397 		return TRUE;
1398 	}
1399 #endif /* BCMWAPI_WAI */
1400 
1401 	switch (cipher[DOT11_OUI_LEN]) {
1402 	case WPA_CIPHER_NONE:
1403 		*wsec = 0;
1404 		break;
1405 	case WPA_CIPHER_WEP_40:
1406 	case WPA_CIPHER_WEP_104:
1407 		*wsec = WEP_ENABLED;
1408 		break;
1409 	case WPA_CIPHER_TKIP:
1410 		*wsec = TKIP_ENABLED;
1411 		break;
1412 	case WPA_CIPHER_AES_CCM:
1413 		/* fall through */
1414 	case WPA_CIPHER_AES_GCM:
1415 		/* fall through */
1416 	case WPA_CIPHER_AES_GCM256:
1417 		*wsec = AES_ENABLED;
1418 		break;
1419 
1420 #ifdef BCMWAPI_WAI
1421 	case WAPI_CIPHER_SMS4:
1422 		*wsec = SMS4_ENABLED;
1423 		break;
1424 #endif /* BCMWAPI_WAI */
1425 
1426 	default:
1427 		return FALSE;
1428 	}
1429 	return TRUE;
1430 }
1431 
1432 #ifdef RSN_IE_INFO_STRUCT_RELOCATED
1433 /* map WPA/RSN cipher to internal WSEC */
1434 uint32
bcmwpa_wpaciphers2wsec(uint32 wpacipher)1435 bcmwpa_wpaciphers2wsec(uint32 wpacipher)
1436 {
1437 	uint32 wsec = 0;
1438 
1439 	switch (wpacipher) {
1440 	case BCM_BIT(WPA_CIPHER_WEP_40):
1441 		case BCM_BIT(WPA_CIPHER_WEP_104):
1442 			wsec = WEP_ENABLED;
1443 			break;
1444 		case BCM_BIT(WPA_CIPHER_TKIP):
1445 			wsec = TKIP_ENABLED;
1446 			break;
1447 		case BCM_BIT(WPA_CIPHER_AES_OCB):
1448 			/* fall through */
1449 		case BCM_BIT(WPA_CIPHER_AES_CCM):
1450 			wsec = AES_ENABLED;
1451 			break;
1452 		case BCM_BIT(WPA_CIPHER_AES_GCM):
1453 			/* fall through */
1454 		case BCM_BIT(WPA_CIPHER_AES_GCM256):
1455 			wsec = AES_ENABLED;
1456 		break;
1457 
1458 #ifdef BCMWAPI_WAI
1459 		case BCM_BIT(WAPI_CIPHER_SMS4):
1460 			wsec = SMS4_ENABLED;
1461 			break;
1462 #endif /* BCMWAPI_WAI */
1463 
1464 		default:
1465 			break;
1466 	}
1467 
1468 	return wsec;
1469 }
1470 
1471 uint32
wlc_convert_rsn_to_wsec_bitmap(uint32 ap_cipher_mask)1472 wlc_convert_rsn_to_wsec_bitmap(uint32 ap_cipher_mask)
1473 {
1474 
1475 	uint32 ap_wsec = 0;
1476 	uint32 tmp_mask = ap_cipher_mask;
1477 	uint32 c;
1478 
1479 	FOREACH_BIT(c, tmp_mask) {
1480 		ap_wsec |= bcmwpa_wpaciphers2wsec(c);
1481 	}
1482 
1483 	return ap_wsec;
1484 }
1485 
1486 #else /* Not RSN_IE_INFO_STRUCT_RELOCATED */
1487 uint32
bcmwpa_wpaciphers2wsec(uint8 wpacipher)1488 bcmwpa_wpaciphers2wsec(uint8 wpacipher)
1489 {
1490 	uint32 wsec = 0;
1491 
1492 	switch (wpacipher) {
1493 	case WPA_CIPHER_NONE:
1494 		break;
1495 	case WPA_CIPHER_WEP_40:
1496 	case WPA_CIPHER_WEP_104:
1497 		wsec = WEP_ENABLED;
1498 		break;
1499 	case WPA_CIPHER_TKIP:
1500 		wsec = TKIP_ENABLED;
1501 		break;
1502 	case WPA_CIPHER_AES_OCB:
1503 		/* fall through */
1504 	case WPA_CIPHER_AES_CCM:
1505 		wsec = AES_ENABLED;
1506 		break;
1507 	case WPA_CIPHER_AES_GCM:
1508 	/* fall through */
1509 	case WPA_CIPHER_AES_GCM256:
1510 		wsec = AES_ENABLED;
1511 		break;
1512 
1513 #ifdef BCMWAPI_WAI
1514 	case WAPI_CIPHER_SMS4:
1515 		wsec = SMS4_ENABLED;
1516 		break;
1517 #endif /* BCMWAPI_WAI */
1518 
1519 	default:
1520 		break;
1521 	}
1522 
1523 	return wsec;
1524 }
1525 #endif /* RSN_IE_INFO_STRUCT_RELOCATED */
1526 
1527 bool
bcmwpa_is_wpa_auth(uint32 auth)1528 bcmwpa_is_wpa_auth(uint32 auth)
1529 {
1530 	if ((auth == WPA_AUTH_NONE) ||
1531 	   (auth == WPA_AUTH_UNSPECIFIED) ||
1532 	   (auth == WPA_AUTH_PSK))
1533 		return TRUE;
1534 	else
1535 		return FALSE;
1536 }
1537 
1538 bool
bcmwpa_includes_wpa_auth(uint32 auth)1539 bcmwpa_includes_wpa_auth(uint32 auth)
1540 {
1541 	if (auth & (WPA_AUTH_NONE |
1542 		WPA_AUTH_UNSPECIFIED |
1543 		WPA_AUTH_PSK))
1544 		return TRUE;
1545 	else
1546 		return FALSE;
1547 }
1548 
1549 bool
bcmwpa_is_rsn_auth(uint32 auth)1550 bcmwpa_is_rsn_auth(uint32 auth)
1551 {
1552 	auth = auth & ~WPA2_AUTH_FT;
1553 
1554 	if ((auth == WPA2_AUTH_UNSPECIFIED) ||
1555 	    (auth == WPA2_AUTH_PSK) ||
1556 	    (auth == BRCM_AUTH_PSK) ||
1557 	    (auth == WPA2_AUTH_1X_SHA256) ||
1558 	    (auth == WPA2_AUTH_PSK_SHA256) ||
1559 	    (auth == WPA3_AUTH_SAE_PSK) ||
1560 	    (auth == WPA3_AUTH_OWE) ||
1561 	    WPA2_AUTH_IS_FILS(auth) ||
1562 	    (auth == WPA3_AUTH_1X_SUITE_B_SHA256) ||
1563 	    (auth == WPA3_AUTH_1X_SUITE_B_SHA384) ||
1564 	    (auth == WPA3_AUTH_PSK_SHA384) ||
1565 	    (auth == WPA3_AUTH_DPP_AKM)) {
1566 		return TRUE;
1567 	} else {
1568 		return FALSE;
1569 	}
1570 }
1571 
1572 bool
bcmwpa_includes_rsn_auth(uint32 auth)1573 bcmwpa_includes_rsn_auth(uint32 auth)
1574 {
1575 	if (auth & (WPA2_AUTH_UNSPECIFIED |
1576 	            WPA2_AUTH_PSK |
1577 	            BRCM_AUTH_PSK | WPA2_AUTH_1X_SHA256 | WPA2_AUTH_PSK_SHA256 |
1578 	            WPA2_AUTH_IS_FILS(auth) | WPA3_AUTH_SAE_PSK | WPA3_AUTH_OWE |
1579 	            WPA3_AUTH_1X_SUITE_B_SHA256 | WPA3_AUTH_1X_SUITE_B_SHA384 |
1580 			WPA3_AUTH_PSK_SHA384 | WPA3_AUTH_DPP_AKM))
1581 		return TRUE;
1582 	else
1583 		return FALSE;
1584 }
1585 
1586 #ifdef RSN_IE_INFO_STRUCT_RELOCATED
1587 /* decode unicast/multicast cipher in RSNIE */
1588 static int
bcmwpa_decode_cipher_suite(rsn_ie_info_t * info,const uint8 ** ptr_inc,uint ie_len,uint * remain_len,uint16 * p_count)1589 bcmwpa_decode_cipher_suite(rsn_ie_info_t *info, const uint8 **ptr_inc, uint ie_len, uint
1590 	*remain_len, uint16 *p_count)
1591 {
1592 	const wpa_suite_ucast_t *ucast;
1593 	const wpa_suite_mcast_t *mcast;
1594 	uint i;
1595 
1596 	if (!(*remain_len)) {
1597 		info->g_cipher = WPA_CIPHER_UNSPECIFIED;
1598 		info->p_ciphers = WPA_P_CIPHERS_UNSPECIFIED;
1599 		goto done; /* only have upto ver */
1600 	}
1601 	*ptr_inc += ie_len - *remain_len;
1602 
1603 	if (*remain_len < sizeof(wpa_suite_mcast_t)) {
1604 		info->parse_status = BCME_BADLEN;
1605 		goto done;
1606 	}
1607 	mcast = (const wpa_suite_mcast_t *)*ptr_inc;
1608 
1609 	if (IS_WPA_CIPHER(mcast->type)) {
1610 		info->g_cipher = mcast->type;
1611 	} else {
1612 		info->parse_status = BCME_BAD_IE_DATA;
1613 		goto done;
1614 	}
1615 
1616 	/* for rsn pairwise cipher suite */
1617 	*ptr_inc += sizeof(wpa_suite_mcast_t);
1618 	*remain_len -= sizeof(wpa_suite_mcast_t);
1619 
1620 	if (!(*remain_len)) {
1621 		info->p_ciphers = WPA_P_CIPHERS_UNSPECIFIED;
1622 		info->sta_akm = WPA_CIPHER_UNSPECIFIED;
1623 		goto done;
1624 	}
1625 
1626 	ucast = (const wpa_suite_ucast_t *)*ptr_inc;
1627 
1628 	if ((*remain_len) < sizeof(ucast->count)) {
1629 		info->parse_status = BCME_BADLEN;
1630 		goto done;
1631 	}
1632 
1633 	if (!ucast->count.low && !ucast->count.high) {
1634 		info->parse_status = BCME_BADLEN;
1635 		goto done;
1636 	}
1637 
1638 	*p_count = ltoh16_ua(&ucast->count);
1639 	if (info->dev_type == DEV_STA && *p_count != 1u) {
1640 		info->parse_status = BCME_BAD_IE_DATA;
1641 		goto done;
1642 	}
1643 	if ((*remain_len) < (*p_count * WPA_SUITE_LEN + sizeof(ucast->count))) {
1644 		info->parse_status = BCME_BADLEN;
1645 		goto done;
1646 	}
1647 
1648 	if (info->dev_type == DEV_STA) {
1649 		if (IS_WPA_CIPHER(ucast->list[0].type)) {
1650 			/* update the pairwise cipher */
1651 			info->sta_cipher = ucast->list[0].type;
1652 		} else {
1653 			info->parse_status = BCME_BAD_IE_DATA;
1654 			goto done;
1655 		}
1656 	} else {
1657 		for (i = 0; i < *p_count; i++) {
1658 			if (IS_WPA_CIPHER(ucast->list[i].type)) {
1659 				info->p_ciphers |= BIT(ucast->list[i].type);
1660 				info->rsn_p_ciphers = info->p_ciphers;
1661 			} else {
1662 				info->parse_status = BCME_BAD_IE_DATA;
1663 				goto done;
1664 			}
1665 		}
1666 	}
1667 
1668 	/* update buffer ptr and remaining length */
1669 	*ptr_inc += (*p_count * WPA_SUITE_LEN) + sizeof(ucast->count);
1670 	*remain_len -= (*p_count * WPA_SUITE_LEN) + sizeof(ucast->count);
1671 
1672 done:
1673 
1674 	if (info->parse_status == BCME_OK) {
1675 		if (info->g_cipher == WPA_CIPHER_UNSPECIFIED) {
1676 			info->g_cipher = WPA_CIPHER_AES_CCM;
1677 		}
1678 		if (info->p_ciphers == WPA_P_CIPHERS_UNSPECIFIED) {
1679 			info->p_ciphers = BIT(WPA_CIPHER_AES_CCM);
1680 			info->rsn_p_ciphers = info->p_ciphers;
1681 		}
1682 	}
1683 
1684 	return info->parse_status;
1685 }
1686 /* sta_akm/sta_cipher must be set before this call */
1687 int
bcmwpa_rsnie_eapol_key_len(rsn_ie_info_t * info)1688 bcmwpa_rsnie_eapol_key_len(rsn_ie_info_t *info)
1689 {
1690 	info->pmk_len = bcmwpa_eapol_key_length(EAPOL_KEY_PMK, info->sta_akm, 0);
1691 	info->kck_mic_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK_MIC, info->sta_akm, 0);
1692 	info->kck_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK, info->sta_akm, 0);
1693 	info->kek_len = bcmwpa_eapol_key_length(EAPOL_KEY_KEK, info->sta_akm, 0);
1694 	info->tk_len = bcmwpa_eapol_key_length(EAPOL_KEY_TK, 0, info->sta_cipher);
1695 	info->ptk_len = info->kck_len + info->kek_len + info->tk_len;
1696 #if defined(WL_FILS) && defined(WLFBT)
1697 	info->kck2_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK2, info->sta_akm, 0);
1698 	info->kek2_len = bcmwpa_eapol_key_length(EAPOL_KEY_KEK2, info->sta_akm, 0);
1699 	if (WPA_IS_FILS_FT_AKM(info->sta_akm)) {
1700 		info->ptk_len += (info->kck2_len + info->kek2_len);
1701 	}
1702 #endif /* WL_FILS && WLFBT */
1703 	return BCME_OK;
1704 }
1705 /* Extract and store information from WPA or RSN IEs
1706  *
1707  * called after either
1708  *  -an association request has been built (STA),
1709  * - an association was received (AP)
1710  * - a probe request has been built (AP)
1711  * - a probe response was received (STA)
1712  *
1713  * All available information is extracted to be used for subsequent
1714  * bss pruning, association request validation, key descriptor compuation etc.
1715  *
1716  * To be expanded as needed.
1717  *
1718  * ie: RSN IE input
1719  * rsn_info:  parsed information. Placed in either bsscfg for self, or scb for peer.
1720  * dev_type: STA_RSN or AP_RSN
1721  *
1722  * Return : parse status.
1723  * NOTE: the parse status is also saved in the the parse_status field.
1724  * NOTE 2 : the IE itself is copied at the end of the structure. Since there is
1725  * no reference to the osh available here, the allocation has to happen outside
1726  * and so the structure cannot be zeroed in this function.
1727  * For the STA, it should happen everytime.
1728  * For the AP, it should happen right after a new beacon/probe has been acquired.
1729  */
1730 
1731 int
bcmwpa_parse_rsnie(const bcm_tlv_t * ie,rsn_ie_info_t * info,device_type_t dev_type)1732 bcmwpa_parse_rsnie(const bcm_tlv_t *ie, rsn_ie_info_t *info, device_type_t dev_type)
1733 {
1734 
1735 	const uint8 *ptr_inc = NULL;
1736 	const wpa_suite_mcast_t *mcast;
1737 	const wpa_suite_auth_key_mgmt_t *mgmt;
1738 	const wpa_pmkid_list_t *pmkid_list;
1739 	uint32 remain_len = 0, i;
1740 	uint8 auth_ie_type;
1741 	uint16 p_count = 0;
1742 	uint16 akm_count;
1743 
1744 	ASSERT(info != NULL);
1745 
1746 	/* this function might be called from place where there
1747 	 * is no error detection.
1748 	 * e.g. fron the iem callback. Store status here.
1749 	 */
1750 
1751 	info->parse_status = BCME_OK;
1752 
1753 	if (!ie) {
1754 		info->parse_status = BCME_BADARG;
1755 		goto done;
1756 	}
1757 
1758 	/* For AP, do not zero this structure since there could be multiple
1759 	 * IEs. In that case, add to the existing
1760 	 * bits in field (ciphers, akms) as necessary.
1761 	 */
1762 	if (dev_type == DEV_AP) {
1763 		/* if already created, check device type */
1764 		if (info->dev_type != DEV_NONE) {
1765 			if (info->dev_type != DEV_AP) {
1766 				info->parse_status = BCME_BADARG;
1767 				goto done;
1768 			}
1769 		}
1770 	}
1771 	info->dev_type = dev_type;
1772 	ptr_inc = ie->data;
1773 
1774 	/* decode auth IE (WPA vs RSN). Fill in the auth_ie_type and version.
1775 	 * Modify remain_len to indicate the position of the pointer.
1776 	 */
1777 	/* NOTE the status field will be updated in this call */
1778 	if (bcmwpa_decode_ie_type(ie, info, &remain_len, &auth_ie_type) != BCME_OK) {
1779 		goto done;
1780 	}
1781 
1782 	/* decode multicast, unicast ciphers */
1783 	if (bcmwpa_decode_cipher_suite(info, &ptr_inc, ie->len, &remain_len, &p_count) != BCME_OK) {
1784 		goto done;
1785 	}
1786 
1787 	if (!(remain_len)) {
1788 		info->akms = BIT(RSN_AKM_UNSPECIFIED);
1789 		goto done;
1790 	}
1791 
1792 	mgmt = (const wpa_suite_auth_key_mgmt_t *)ptr_inc;
1793 
1794 	if (remain_len < sizeof(mgmt->count)) {
1795 		info->parse_status = BCME_BADLEN;
1796 		goto done;
1797 	}
1798 
1799 	akm_count = ltoh16_ua(&mgmt->count);
1800 
1801 	if (!akm_count) {
1802 		info->parse_status = BCME_BADARG;
1803 		goto done;
1804 	}
1805 
1806 	if (dev_type == DEV_STA && akm_count != 1) {
1807 		info->parse_status = BCME_BADARG;
1808 		goto done;
1809 	}
1810 
1811 	if ((remain_len) < (akm_count * WPA_SUITE_LEN + sizeof(mgmt->count))) {
1812 		info->parse_status = BCME_BADLEN;
1813 		goto done;
1814 	}
1815 
1816 	if (dev_type == DEV_STA) {
1817 		info->sta_akm = mgmt->list[0].type;
1818 	}
1819 	for (i = 0; i < akm_count; i++) {
1820 		if (bcmwpa_is_valid_akm(mgmt->list[i].type) == BCME_OK) {
1821 			ASSERT((mgmt->list[i].type) <
1822 				(sizeof(info->akms) * NBBY));
1823 			info->akms |= BIT(mgmt->list[i].type);
1824 		}
1825 	}
1826 
1827 	/* save IE dependent values in their respective fields */
1828 	if (dev_type == DEV_AP) {
1829 		if (auth_ie_type == RSN_AUTH_IE) {
1830 			info->rsn_akms = info->akms;
1831 		} else if (auth_ie_type == WPA_AUTH_IE) {
1832 			info->wpa_akms = info->akms;
1833 			info->wpa_p_ciphers = info->p_ciphers;
1834 		}
1835 	}
1836 
1837 	/* as a STA,  at this point, we can compute the key descriptor version */
1838 	if (dev_type == DEV_STA) {
1839 		info->key_desc = wlc_calc_rsn_desc_version(info);
1840 		/* For STA, we can set the auth ie */
1841 		if (auth_ie_type == RSN_AUTH_IE) {
1842 			info->auth_ie = info->rsn_ie;
1843 			info->auth_ie_len = info->rsn_ie_len;
1844 		} else {
1845 			info->auth_ie = info->wpa_ie;
1846 			info->auth_ie_len = info->wpa_ie_len;
1847 		}
1848 	}
1849 
1850 	/* RSN AKM/cipher suite related EAPOL key length update */
1851 	bcmwpa_rsnie_eapol_key_len(info);
1852 
1853 	/* for rsn capabilities */
1854 	ptr_inc += akm_count * WPA_SUITE_LEN + sizeof(mgmt->count);
1855 	remain_len -=  akm_count * WPA_SUITE_LEN + sizeof(mgmt->count);
1856 
1857 	if (!(remain_len)) {
1858 		goto done;
1859 	}
1860 	if (remain_len < RSN_CAP_LEN) {
1861 		info->parse_status = BCME_BADLEN;
1862 		goto done;
1863 	}
1864 
1865 	if (ie->id == DOT11_MNG_RSN_ID) {
1866 		info->caps = ltoh16_ua(ptr_inc);
1867 	}
1868 
1869 	/* check if AKMs require MFP capable to be set */
1870 	if ((info->akms & RSN_MFPC_AKM_MASK) && !(info->caps & RSN_CAP_MFPC)) {
1871 		/* NOTE: Acting as WPA3 CTT testbed device, it requires to send assoc request frame
1872 		with user provided mfp value as is. So should not return error here.
1873 		*/
1874 #ifndef WPA3_CTT
1875 		info->parse_status = BCME_EPERM;
1876 		goto done;
1877 #endif /* WPA3_CTT */
1878 	}
1879 
1880 	/* for rsn PMKID */
1881 	ptr_inc += RSN_CAP_LEN;
1882 	remain_len -= RSN_CAP_LEN;
1883 
1884 	if (!(remain_len)) {
1885 		goto done;
1886 	}
1887 
1888 	/* here's possible cases after RSN_CAP parsed
1889 	 * a) pmkid_count 2B(00 00)
1890 	 * b) pmkid_count 2B(00 00) + BIP 4B
1891 	 * c) pmkid_count 2B(non zero) + pmkid_count * 16B
1892 	 * d) pmkid_count 2B(non zero) + pmkid_count * 16B + BIP 4B
1893 	 */
1894 
1895 	/* pmkids_offset set to
1896 	 * 1) if pmkid_count field(2B) present, point to first PMKID offset in the RSN ID
1897 	 *    no matter what pmkid_count value is. (true, even if pmkid_count == 00 00)
1898 	 * 2) if pmkid_count field(2B) not present, it shall be zero.
1899 	 */
1900 
1901 	pmkid_list = (const wpa_pmkid_list_t*)ptr_inc;
1902 
1903 	if ((remain_len) < sizeof(pmkid_list->count)) {
1904 		info->parse_status = BCME_BADLEN;
1905 		goto done;
1906 	}
1907 
1908 	info->pmkid_count = (uint8)ltoh16_ua(&pmkid_list->count);
1909 	ptr_inc += sizeof(pmkid_list->count);
1910 	remain_len -= sizeof(pmkid_list->count);
1911 
1912 	if (remain_len < (uint32)(info->pmkid_count * WPA2_PMKID_LEN)) {
1913 		info->parse_status = BCME_BADLEN;
1914 		goto done;
1915 	}
1916 
1917 	info->pmkids_offset = ie->len + TLV_HDR_LEN - remain_len;
1918 	/* for rsn group management cipher suite */
1919 	ptr_inc += info->pmkid_count * WPA2_PMKID_LEN;
1920 	remain_len -= info->pmkid_count * WPA2_PMKID_LEN;
1921 
1922 	if (!(remain_len)) {
1923 		goto done;
1924 	}
1925 	/*
1926 	 * from WPA2_Security_Improvements_Test_Plan_v1.0
1927 	 * 4.2.4 APUT RSNE bounds verification using WPA2-PSK
1928 	 * May content RSNE extensibile element ay this point
1929 	 */
1930 	if (remain_len < sizeof(wpa_suite_mcast_t)) {
1931 		info->parse_status = BCME_BADLEN;
1932 		goto done;
1933 	}
1934 
1935 	mcast = (const wpa_suite_mcast_t *)ptr_inc;
1936 	if (IS_VALID_BIP_CIPHER((rsn_cipher_t)mcast->type)) {
1937 		info->g_mgmt_cipher = (rsn_cipher_t)mcast->type;
1938 	}
1939 
1940 done:
1941 	return info->parse_status;
1942 }
1943 
1944 /* Determine if the IE is of WPA or RSN type. Decode
1945  * up to version field. Modify the remaining len parameter to
1946  * indicate where the next field is.
1947  * Store and return error status.
1948  */
1949 
1950 int
bcmwpa_decode_ie_type(const bcm_tlv_t * ie,rsn_ie_info_t * info,uint32 * remaining,uint8 * type)1951 bcmwpa_decode_ie_type(const bcm_tlv_t *ie, rsn_ie_info_t *info, uint32 *remaining,
1952     uint8 *type)
1953 {
1954 	const uint8 * ptr_inc = (const uint8 *)ie->data;
1955 	uint32 remain_len = ie->len;
1956 	uint8 version, version_len;
1957 
1958 	if (ie->id == DOT11_MNG_WPA_ID) {
1959 		/* min len check */
1960 		if (remain_len < WPA_IE_FIXED_LEN) {
1961 			info->parse_status = BCME_BADLEN;
1962 			goto done;
1963 		}
1964 		/* WPA IE */
1965 		if (memcmp(WPA_OUI, ie->data, WPA_OUI_LEN)) {
1966 			/* bad OUI */
1967 			info->parse_status = BCME_BADARG;
1968 			goto done;
1969 		}
1970 		ptr_inc += WPA_OUI_LEN;
1971 		if (*ptr_inc == WPA_OUI_TYPE) {
1972 			*type = WPA_AUTH_IE;
1973 		} else if  (*ptr_inc == WFA_OUI_TYPE_OSEN) {
1974 			*type = OSEN_AUTH_IE;
1975 		}
1976 		else {
1977 			/* wrong type */
1978 			info->parse_status = BCME_BADARG;
1979 			goto done;
1980 		}
1981 
1982 		ptr_inc ++;
1983 		remain_len -= WPA_OUI_LEN + 1u;
1984 		version_len = WPA_VERSION_LEN;
1985 	}
1986 	else if  (ie->id == DOT11_MNG_RSN_ID) {
1987 		if (remain_len < WPA2_VERSION_LEN) {
1988 			info->parse_status = BCME_BADLEN;
1989 			goto done;
1990 		}
1991 		/* RSN IE */
1992 		*type = RSN_AUTH_IE;
1993 		version_len = WPA2_VERSION_LEN;
1994 	} else {
1995 		printf("IE ID %d\n", ie->id);
1996 		/* TODO : add support for CCX, WAPI ? */
1997 		info->parse_status = BCME_UNSUPPORTED;
1998 		goto done;
1999 	}
2000 	info->auth_ie_type |= *type;
2001 	/* mask down to uint8 for Windows build */
2002 	version = 0xff & ltoh16_ua(ptr_inc);
2003 	if (version > MAX_RSNE_SUPPORTED_VERSION) {
2004 		info->parse_status = BCME_UNSUPPORTED;
2005 		goto done;
2006 	}
2007 
2008 	info->version = (uint8)version;
2009 	*remaining = remain_len - version_len;
2010 done:
2011 	return info->parse_status;
2012 }
2013 
2014 /* rsn info allocation management.
2015  *
2016  * In some cases, the rsn ie info structures are embedded in the scan results
2017  * which can be shared by different lists.
2018  * To keep track of their allocation, we use a reference counter.
2019  * The counter is incremented on demand by rsn_ie_info_add_ref()
2020  * at the time the reference is shared.
2021  * It is decremented in rsn_ie_info_rel_ref
2022  * When ref_count gets to 0, bcmwpa_rsn_ie_info_free_mem
2023  * is called to free the whole structure.
2024  */
2025 
2026 /* free rsn_ie and wpa_ie, if any, and zero the rsn_info */
2027 void
bcmwpa_rsn_ie_info_reset(rsn_ie_info_t * rsn_info,osl_t * osh)2028 bcmwpa_rsn_ie_info_reset(rsn_ie_info_t *rsn_info, osl_t *osh)
2029 {
2030 	uint8 ref_count;
2031 	if (rsn_info == NULL) {
2032 		return;
2033 	}
2034 	ref_count = rsn_info->ref_count;
2035 	MFREE(osh, rsn_info->rsn_ie, rsn_info->rsn_ie_len);
2036 	MFREE(osh, rsn_info->wpa_ie, rsn_info->wpa_ie_len);
2037 	MFREE(osh, rsn_info->rsnxe, rsn_info->rsnxe_len);
2038 	bzero(rsn_info, sizeof(*rsn_info));
2039 	rsn_info->ref_count = ref_count;
2040 
2041 }
2042 
2043 static
bcmwpa_rsn_ie_info_free_mem(rsn_ie_info_t ** rsn_info,osl_t * osh)2044 void bcmwpa_rsn_ie_info_free_mem(rsn_ie_info_t **rsn_info, osl_t *osh)
2045 {
2046 	bcmwpa_rsn_ie_info_reset(*rsn_info, osh);
2047 	MFREE(osh, *rsn_info, sizeof(**rsn_info));
2048 	*rsn_info = NULL;
2049 }
2050 
bcmwpa_rsn_ie_info_rel_ref(rsn_ie_info_t ** rsn_info,osl_t * osh)2051 void bcmwpa_rsn_ie_info_rel_ref(rsn_ie_info_t **rsn_info, osl_t *osh)
2052 {
2053 
2054 	if (rsn_info == NULL || *rsn_info == NULL) {
2055 		return;
2056 	}
2057 
2058 	/* already freed ? */
2059 	if ((*rsn_info)->ref_count == 0) {
2060 		ASSERT(0);
2061 		return;
2062 	}
2063 	/* decrement ref count */
2064 	(*rsn_info)->ref_count -= 1;
2065 	/* clear reference. */
2066 	if ((*rsn_info)->ref_count > 0) {
2067 		*rsn_info = NULL;
2068 		return;
2069 	}
2070 	/* free memory and clear reference */
2071 	bcmwpa_rsn_ie_info_free_mem(rsn_info, osh);
2072 }
2073 
2074 int
bcmwpa_rsn_ie_info_add_ref(rsn_ie_info_t * rsn_info)2075 bcmwpa_rsn_ie_info_add_ref(rsn_ie_info_t *rsn_info)
2076 {
2077 	int status = BCME_OK;
2078 	if (rsn_info == NULL) {
2079 		goto done;
2080 	}
2081 	if (rsn_info->ref_count == 0) {
2082 		/* don't increase from 0, which means this structure has been freed earlier.
2083 		 * That reference should not exist anymore.
2084 		 */
2085 		ASSERT(0);
2086 		status = BCME_BADARG;
2087 		goto  done;
2088 	}
2089 	rsn_info->ref_count++;
2090 done:
2091 	return status;
2092 }
2093 
2094 #else /* Not RSN_IE_INFO_STRUCT_RELOCATED */
2095 
2096 int
bcmwpa_parse_rsnie(const bcm_tlv_t * ie,rsn_ie_info_t * info,device_type_t dev_type)2097 bcmwpa_parse_rsnie(const bcm_tlv_t *ie, rsn_ie_info_t *info, device_type_t dev_type)
2098 {
2099 
2100 	const uint8 *ptr_inc = NULL;
2101 	const wpa_suite_ucast_t *ucast;
2102 	const wpa_suite_mcast_t *mcast;
2103 	const wpa_suite_auth_key_mgmt_t *mgmt;
2104 	const wpa_pmkid_list_t *pmkid_list;
2105 	uint32 remain_len = 0, i;
2106 
2107 	ASSERT(info != NULL);
2108 
2109 	/* this function might be called from place where there
2110 	 * is no error detection.
2111 	 * e.g. fron the iem callback. Store status here.
2112 	 */
2113 
2114 	info->parse_status = BCME_OK;
2115 
2116 	if (!ie) {
2117 			info->parse_status = BCME_BADARG;
2118 			goto done;
2119 	}
2120 
2121 	/* For AP, do not zero this structure since there could be multiple
2122 	 * IEs. In that case, add to the existing
2123 	 * bits in field (ciphers, akms) as necessary.
2124 	 */
2125 	if (dev_type != DEV_AP) {
2126 		bzero(info, sizeof(*info));
2127 	} else {
2128 		/* if already created, check device type */
2129 		if (info->dev_type != DEV_NONE) {
2130 			if (info->dev_type != DEV_AP) {
2131 				info->parse_status = BCME_BADARG;
2132 				goto done;
2133 			}
2134 		}
2135 	}
2136 	info->dev_type = dev_type;
2137 	ptr_inc = ie->data;
2138 
2139 	/* decode auth IE (WPA vs RSN). Fill in the auth_ie_type and version.
2140 	 * Modify remain_len to indicate the position of the pointer.
2141 	 */
2142 	/* NOTE the status field will be updated in this call */
2143 	if (bcmwpa_decode_ie_type(ie, info, &remain_len) != BCME_OK) {
2144 		goto done;
2145 	}
2146 
2147 	if (!(remain_len)) {
2148 		info->g_cipher = WPA_CIPHER_NONE;
2149 		goto done; /* only have upto ver */
2150 	}
2151 	ptr_inc += ie->len - remain_len;
2152 
2153 	if (remain_len < sizeof(wpa_suite_mcast_t)) {
2154 		info->parse_status = BCME_BADLEN;
2155 		goto done;
2156 	}
2157 	mcast = (const wpa_suite_mcast_t *)ptr_inc;
2158 
2159 	if (IS_WPA_CIPHER(mcast->type)) {
2160 		info->g_cipher = mcast->type;
2161 	}
2162 
2163 	/* for rsn pairwise cipher suite */
2164 	ptr_inc += sizeof(wpa_suite_mcast_t);
2165 	remain_len -= sizeof(wpa_suite_mcast_t);
2166 
2167 	if (!(remain_len)) {
2168 		goto done;
2169 	}
2170 
2171 	ucast = (const wpa_suite_ucast_t *)ptr_inc;
2172 
2173 	if ((remain_len) < sizeof(ucast->count)) {
2174 		info->parse_status = BCME_BADLEN;
2175 		goto done;
2176 	}
2177 
2178 	if (!ucast->count.low && !ucast->count.high) {
2179 		info->parse_status = BCME_BADLEN;
2180 		goto done;
2181 	}
2182 
2183 	info->p_count = (uint8)ltoh16_ua(&ucast->count);
2184 
2185 	if (dev_type == DEV_STA && info->p_count != 1) {
2186 		info->parse_status = BCME_BADARG;
2187 		goto done;
2188 	}
2189 	if ((remain_len) < (info->p_count * WPA_SUITE_LEN + sizeof(ucast->count))) {
2190 		info->parse_status = BCME_BADLEN;
2191 		goto done;
2192 	}
2193 
2194 	if (IS_WPA_CIPHER(ucast->list[0].type)) {
2195 		/* update the pairwise cipher */
2196 		/* set cipher to invald value */
2197 		if (dev_type == DEV_STA) {
2198 			info->sta_cipher = ucast->list[0].type;
2199 		} else {
2200 			for (i = 0; i < info->p_count; i++) {
2201 				if (IS_WPA_CIPHER(ucast->list[i].type)) {
2202 					info->p_ciphers |= BIT(ucast->list[i].type);
2203 				} else {
2204 					info->parse_status = BCME_BAD_IE_DATA;
2205 					goto done;
2206 				}
2207 			}
2208 		}
2209 	} else {
2210 		info->parse_status = BCME_BAD_IE_DATA;
2211 		goto done;
2212 	}
2213 
2214 	/* for rsn AKM authentication */
2215 	ptr_inc += info->p_count * WPA_SUITE_LEN + sizeof(ucast->count);
2216 	remain_len -= (info->p_count * WPA_SUITE_LEN + sizeof(ucast->count));
2217 
2218 	mgmt = (const wpa_suite_auth_key_mgmt_t *)ptr_inc;
2219 
2220 	if (remain_len < sizeof(mgmt->count)) {
2221 		info->parse_status = BCME_BADLEN;
2222 		goto done;
2223 	}
2224 
2225 	info->akm_count = (uint8)ltoh16_ua(&mgmt->count);
2226 
2227 	if (!info->akm_count) {
2228 		info->parse_status = BCME_BADARG;
2229 		goto done;
2230 	}
2231 
2232 	if (dev_type == DEV_STA && info->akm_count != 1) {
2233 		info->parse_status = BCME_BADARG;
2234 		goto done;
2235 	}
2236 
2237 	if ((remain_len) < (info->akm_count * WPA_SUITE_LEN + sizeof(mgmt->count))) {
2238 		info->parse_status = BCME_BADLEN;
2239 		goto done;
2240 	}
2241 
2242 	if (dev_type == DEV_STA) {
2243 		info->sta_akm = mgmt->list[0].type;
2244 	}
2245 	for (i = 0; i < info->akm_count; i++) {
2246 		if (bcmwpa_is_valid_akm(mgmt->list[i].type) == BCME_OK) {
2247 			ASSERT((mgmt->list[i].type) <
2248 				(sizeof(info->akms) * NBBY));
2249 			info->akms |= BIT(mgmt->list[i].type);
2250 		}
2251 	}
2252 
2253 	/* RSN AKM/cipher suite related EAPOL key length update */
2254 	info->pmk_len = bcmwpa_eapol_key_length(EAPOL_KEY_PMK, info->sta_akm, 0);
2255 	info->kck_mic_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK_MIC, info->sta_akm, 0);
2256 	info->kck_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK, info->sta_akm, 0);
2257 	info->kek_len = bcmwpa_eapol_key_length(EAPOL_KEY_KEK, info->sta_akm, 0);
2258 	info->tk_len = bcmwpa_eapol_key_length(EAPOL_KEY_TK, 0, info->sta_cipher);
2259 	info->ptk_len = info->kck_mic_len + info->kek_len + info->tk_len;
2260 #if defined(WL_FILS) && defined(WLFBT)
2261 	info->kck2_len = bcmwpa_eapol_key_length(EAPOL_KEY_KCK2, info->sta_akm, 0);
2262 	info->kek2_len = bcmwpa_eapol_key_length(EAPOL_KEY_KEK2, info->sta_akm, 0);
2263 #endif /* WL_FILS && WLFBT */
2264 
2265 	/* for rsn capabilities */
2266 	ptr_inc += info->akm_count * WPA_SUITE_LEN + sizeof(mgmt->count);
2267 	remain_len -=  info->akm_count * WPA_SUITE_LEN + sizeof(mgmt->count);
2268 
2269 	/* as a STA,  at this point, we can compute the key descriptor version */
2270 	if (dev_type == DEV_STA) {
2271 		info->key_desc = wlc_calc_rsn_desc_version(info);
2272 	}
2273 
2274 	if (!(remain_len)) {
2275 		goto done;
2276 	}
2277 	if (remain_len < RSN_CAP_LEN) {
2278 		info->parse_status = BCME_BADLEN;
2279 		goto done;
2280 	}
2281 
2282 	if (ie->id == DOT11_MNG_RSN_ID) {
2283 		info->caps = ltoh16_ua(ptr_inc);
2284 	}
2285 
2286 	/* for WFA If MFP required, check that we are using a SHA256 AKM
2287 	 * or higher  and nothing else.
2288 	 * In case MFP Required and MFP Capable do not enforce check of AKM.
2289 	 */
2290 	if ((info->caps & RSN_CAP_MFPR) && !(info->akms & (1u << RSN_AKM_PSK))) {
2291 		if ((info->akms & (AKM_SHA256_MASK | AKM_SHA384_MASK)) == 0 ||
2292 			(info->akms & ~(AKM_SHA256_MASK | AKM_SHA384_MASK))) {
2293 			info->parse_status = BCME_EPERM;
2294 			goto done;
2295 		}
2296 	}
2297 
2298 	/* check if AKMs require MFP capable to be set */
2299 	if ((info->akms & RSN_MFPC_AKM_MASK) && !(info->caps & RSN_CAP_MFPC)) {
2300 		info->parse_status = BCME_EPERM;
2301 		goto done;
2302 	}
2303 
2304 	/* for rsn PMKID */
2305 	ptr_inc += RSN_CAP_LEN;
2306 	remain_len -= RSN_CAP_LEN;
2307 
2308 	if (!(remain_len)) {
2309 		goto done;
2310 	}
2311 
2312 	pmkid_list = (const wpa_pmkid_list_t*)ptr_inc;
2313 
2314 	if ((remain_len) < sizeof(pmkid_list->count)) {
2315 		info->parse_status = BCME_BADLEN;
2316 		goto done;
2317 	}
2318 
2319 	info->pmkid_count = (uint8)ltoh16_ua(&pmkid_list->count);
2320 	ptr_inc += sizeof(pmkid_list->count);
2321 	remain_len -= sizeof(pmkid_list->count);
2322 
2323 	if (info->pmkid_count) {
2324 		if (remain_len < (uint32)(info->pmkid_count * WPA2_PMKID_LEN)) {
2325 			info->parse_status = BCME_BADLEN;
2326 			goto done;
2327 		}
2328 		info->pmkids_offset = ie->len + TLV_HDR_LEN - remain_len;
2329 		/* for rsn group management cipher suite */
2330 		ptr_inc += info->pmkid_count * WPA2_PMKID_LEN;
2331 		remain_len -= info->pmkid_count * WPA2_PMKID_LEN;
2332 	}
2333 
2334 	if (!(remain_len)) {
2335 		goto done;
2336 	}
2337 	/*
2338 	 * from WPA2_Security_Improvements_Test_Plan_v1.0
2339 	 * 4.2.4 APUT RSNE bounds verification using WPA2-PSK
2340 	 * May content RSNE extensibile element ay this point
2341 	 */
2342 	if (remain_len < sizeof(wpa_suite_mcast_t)) {
2343 		info->parse_status = BCME_BADLEN;
2344 		goto done;
2345 	}
2346 
2347 	mcast = (const wpa_suite_mcast_t *)ptr_inc;
2348 	if (IS_VALID_BIP_CIPHER((rsn_cipher_t)mcast->type)) {
2349 		info->g_mgmt_cipher = (rsn_cipher_t)mcast->type;
2350 	}
2351 
2352 done:
2353 	return info->parse_status;
2354 }
2355 
2356 /* Determine if the IE is of WPA or RSN type. Decode
2357  * up to version field. Modify the remaining len parameter to
2358  * indicate where the next field is.
2359  * Store and return error status.
2360  */
2361 
2362 int
bcmwpa_decode_ie_type(const bcm_tlv_t * ie,rsn_ie_info_t * info,uint32 * remaining)2363 bcmwpa_decode_ie_type(const bcm_tlv_t *ie, rsn_ie_info_t *info, uint32 *remaining)
2364 {
2365 	const uint8 * ptr_inc = (const uint8 *)ie->data;
2366 	uint32 remain_len = ie->len;
2367 	uint8 version, version_len;
2368 
2369 	if (ie->id == DOT11_MNG_WPA_ID) {
2370 		/* min len check */
2371 		if (remain_len < WPA_IE_FIXED_LEN) {
2372 			info->parse_status = BCME_BADLEN;
2373 			goto done;
2374 		}
2375 		/* WPA IE */
2376 		if (memcmp(WPA_OUI, ie->data, WPA_OUI_LEN)) {
2377 			/* bad OUI */
2378 			info->parse_status = BCME_BADARG;
2379 			goto done;
2380 		}
2381 		ptr_inc += WPA_OUI_LEN;
2382 		if (*ptr_inc != WPA_OUI_TYPE) {
2383 			/* wrong type */
2384 			info->parse_status = BCME_BADARG;
2385 			goto done;
2386 		}
2387 		ptr_inc ++;
2388 		remain_len -= WPA_OUI_LEN + 1u;
2389 		info->auth_ie_type |= WPA_AUTH_IE;
2390 		version_len = WPA_VERSION_LEN;
2391 	}
2392 	else if  (ie->id == DOT11_MNG_RSN_ID) {
2393 		if (remain_len < WPA2_VERSION_LEN) {
2394 			info->parse_status = BCME_BADLEN;
2395 			goto done;
2396 		}
2397 		/* RSN IE */
2398 		info->auth_ie_type |= RSN_AUTH_IE;
2399 		version_len = WPA2_VERSION_LEN;
2400 	} else {
2401 		/* TODO : add support for CCX, WAPI ? */
2402 		info->parse_status = BCME_UNSUPPORTED;
2403 		goto done;
2404 	}
2405 
2406 	/* mask down to uint8 for Windows build */
2407 	version = 0xff & ltoh16_ua(ptr_inc);
2408 	if (version > MAX_RSNE_SUPPORTED_VERSION) {
2409 		info->parse_status = BCME_UNSUPPORTED;
2410 		goto done;
2411 	}
2412 
2413 	info->version = (uint8)version;
2414 	*remaining = remain_len - version_len;
2415 done:
2416 	return info->parse_status;
2417 }
2418 
2419 #endif /* RSN_IE_INFO_STRUCT_RELOCATED */
2420 
2421 /* return the key descriptor version based on the AKM suite
2422  * applicable only for STA with RSN
2423  */
2424 static uint16
wlc_calc_rsn_desc_version(const rsn_ie_info_t * rsn_info)2425 wlc_calc_rsn_desc_version(const rsn_ie_info_t *rsn_info)
2426 {
2427 	uint16 key_desc_ver = WPA_KEY_DESC_V0;
2428 	uint8 akm;
2429 
2430 	ASSERT(rsn_info != NULL);
2431 	ASSERT(rsn_info->dev_type == DEV_STA);
2432 	akm = rsn_info->sta_akm;
2433 
2434 	/* Refer Draft 802.11REVmd_D1.0.pdf  Section 12.7.2 */
2435 	if ((akm == RSN_AKM_UNSPECIFIED) ||
2436 		(akm == RSN_AKM_PSK)) {
2437 		if ((rsn_info->sta_cipher == WPA_CIPHER_TKIP) ||
2438 			(rsn_info->sta_cipher == WPA_CIPHER_NONE)) {
2439 			key_desc_ver = WPA_KEY_DESC_V1;
2440 		} else if ((rsn_info->sta_cipher != WPA_CIPHER_TKIP) ||
2441 			(rsn_info->g_cipher != WPA_CIPHER_TKIP)) {
2442 			key_desc_ver = WPA_KEY_DESC_V2;
2443 		}
2444 	} else if ((akm == RSN_AKM_FBT_1X) ||
2445 		(akm == RSN_AKM_FBT_PSK) ||
2446 		(akm == RSN_AKM_SHA256_1X) ||
2447 		(akm == RSN_AKM_SHA256_PSK)) {
2448 			key_desc_ver = WPA_KEY_DESC_V3;
2449 	}
2450 	return key_desc_ver;
2451 }
2452 
2453 /* get EAPOL key length based on RSN IE AKM/Cipher(unicast) suite
2454  * key: EAPOL key type
2455  * akm: RSN AKM suite selector
2456  * cipher: RSN unicast cipher suite selector
2457  * return: key length found in matching key_length_entry table
2458  */
2459 uint8
bcmwpa_eapol_key_length(eapol_key_type_t key,rsn_akm_t akm,rsn_cipher_t cipher)2460 bcmwpa_eapol_key_length(eapol_key_type_t key, rsn_akm_t akm, rsn_cipher_t cipher)
2461 {
2462 	uint i;
2463 	uint8 key_length = 0;
2464 	uint8 suite;
2465 	const key_length_entry_t *key_entry = NULL;
2466 
2467 	if (key == EAPOL_KEY_TK) {
2468 		suite = cipher;
2469 	} else {
2470 		suite = akm;
2471 	}
2472 	for (i = 0; i < ARRAYSIZE(eapol_key_lookup_tbl); i++) {
2473 		if (eapol_key_lookup_tbl[i].key == key) {
2474 			key_entry = eapol_key_lookup_tbl[i].key_entry;
2475 			break;
2476 		}
2477 	}
2478 
2479 	if (key_entry) {
2480 		i = 0;
2481 		do {
2482 			if (key_entry[i].suite == suite || key_entry[i].suite == 0) {
2483 				key_length = key_entry[i].len;
2484 				break;
2485 			}
2486 			i++;
2487 		} while (i > 0);
2488 	}
2489 
2490 	return key_length;
2491 }
2492 
2493 /* check if RSM AKM suite is valid */
bcmwpa_is_valid_akm(const rsn_akm_t akm)2494 static int bcmwpa_is_valid_akm(const rsn_akm_t akm)
2495 {
2496 	uint i = 0;
2497 	for (i = 0; i < ARRAYSIZE(rsn_akm_lookup_tbl); i++) {
2498 		if (akm == rsn_akm_lookup_tbl[i].rsn_akm) {
2499 			return BCME_OK;
2500 		}
2501 	}
2502 	return BCME_ERROR;
2503 }
2504 
2505 /* checking cipher suite selector restriction based on AKM */
2506 int
bcmwpa_rsn_akm_cipher_match(rsn_ie_info_t * rsn_info)2507 bcmwpa_rsn_akm_cipher_match(rsn_ie_info_t *rsn_info)
2508 {
2509 	uint i;
2510 	const rsn_akm_cipher_match_entry_t *p_entry = NULL;
2511 
2512 	for (i = 0; i < ARRAYSIZE(rsn_akm_cipher_match_table); i++) {
2513 		/* akm match */
2514 		if (rsn_info->sta_akm == rsn_akm_cipher_match_table[i].akm_type) {
2515 			p_entry = &rsn_akm_cipher_match_table[i];
2516 			break;
2517 		}
2518 	}
2519 
2520 	if (p_entry) {
2521 		/* unicast cipher match */
2522 		if (!(rsn_info->p_ciphers & p_entry->u_cast)) {
2523 			return BCME_UNSUPPORTED;
2524 		}
2525 		/* multicast cipher match */
2526 		if (!(BCM_BIT(rsn_info->g_cipher) & p_entry->m_cast)) {
2527 			return BCME_UNSUPPORTED;
2528 		}
2529 		/* group management cipher match */
2530 		if (!(BCM_BIT(rsn_info->g_mgmt_cipher) & p_entry->g_mgmt)) {
2531 			return BCME_UNSUPPORTED;
2532 		}
2533 	}
2534 	return BCME_OK;
2535 }
2536 
2537 #if defined(BCMSUP_PSK) || defined(BCMSUPPL)
bcmwpa_find_group_mgmt_algo(rsn_cipher_t g_mgmt_cipher)2538 uint8 bcmwpa_find_group_mgmt_algo(rsn_cipher_t g_mgmt_cipher)
2539 {
2540 	uint8 i;
2541 	uint8 algo = CRYPTO_ALGO_BIP;
2542 
2543 	for (i = 0; i < ARRAYSIZE(group_mgmt_cipher_algo); i++) {
2544 		if ((group_mgmt_cipher_algo[i].g_mgmt_cipher == g_mgmt_cipher)) {
2545 			algo = group_mgmt_cipher_algo[i].bip_algo;
2546 			break;
2547 		}
2548 	}
2549 
2550 	return algo;
2551 }
2552 #endif /* defined(BCMSUP_PSK) || defined(BCMSUPPL) */
2553 
2554 #if defined(WL_BAND6G)
2555 bool
bcmwpa_is_invalid_6g_akm(const rsn_akm_mask_t akms_bmp)2556 bcmwpa_is_invalid_6g_akm(const rsn_akm_mask_t akms_bmp)
2557 {
2558 	if (akms_bmp & rsn_akm_6g_inval_mask) {
2559 		return TRUE;
2560 	}
2561 	return FALSE;
2562 }
2563 
2564 bool
bcmwpa_is_invalid_6g_cipher(const rsn_ciphers_t ciphers_bmp)2565 bcmwpa_is_invalid_6g_cipher(const rsn_ciphers_t ciphers_bmp)
2566 {
2567 	if (ciphers_bmp & cipher_6g_inval_mask) {
2568 		return TRUE;
2569 	}
2570 	return FALSE;
2571 }
2572 #endif /* WL_BAND6G */
2573 
2574 /*
2575  * bcmwpa_get_algo_key_len returns the key_length for the algorithm.
2576  * API : bcm_get_algorithm key length
2577  * input: algo: Get the crypto algorithm.
2578  *        km: Keymgmt information.
2579  * output: returns the key length and error status.
2580  *         BCME_OK is valid else BCME_UNSUPPORTED if not supported
2581  */
2582 int
bcmwpa_get_algo_key_len(uint8 algo,uint16 * key_len)2583 bcmwpa_get_algo_key_len(uint8 algo, uint16 *key_len)
2584 {
2585 	int err = BCME_OK;
2586 
2587 	if (key_len == NULL) {
2588 		return BCME_BADARG;
2589 	}
2590 
2591 	switch (algo) {
2592 		case CRYPTO_ALGO_WEP1:
2593 			*key_len = WEP1_KEY_SIZE;
2594 			break;
2595 
2596 		case CRYPTO_ALGO_TKIP:
2597 			*key_len = TKIP_KEY_SIZE;
2598 			break;
2599 
2600 		case CRYPTO_ALGO_WEP128:
2601 			*key_len = WEP128_KEY_SIZE;
2602 			break;
2603 
2604 		case CRYPTO_ALGO_AES_CCM:       /* fall through */
2605 		case CRYPTO_ALGO_AES_GCM:       /* fall through */
2606 		case CRYPTO_ALGO_AES_OCB_MSDU : /* fall through */
2607 		case CRYPTO_ALGO_AES_OCB_MPDU:
2608 			*key_len = AES_KEY_SIZE;
2609 			break;
2610 
2611 #ifdef BCMWAPI_WPI
2612 		/* TODO: Need to double check */
2613 		case CRYPTO_ALGO_SMS4:
2614 			*key_len = SMS4_KEY_LEN + SMS4_WPI_CBC_MAC_LEN;
2615 			break;
2616 #endif /* BCMWAPI_WPI */
2617 
2618 		case CRYPTO_ALGO_BIP: /* fall through */
2619 		case CRYPTO_ALGO_BIP_GMAC:
2620 			*key_len = BIP_KEY_SIZE;
2621 			break;
2622 
2623 		case CRYPTO_ALGO_AES_CCM256:  /* fall through */
2624 		case CRYPTO_ALGO_AES_GCM256:  /* fall through */
2625 		case CRYPTO_ALGO_BIP_CMAC256: /* fall through */
2626 		case CRYPTO_ALGO_BIP_GMAC256:
2627 			*key_len = AES256_KEY_SIZE;
2628 			break;
2629 
2630 		case CRYPTO_ALGO_OFF:
2631 			*key_len = 0;
2632 			break;
2633 
2634 #if !defined(BCMCCX) && !defined(BCMEXTCCX)
2635 		case CRYPTO_ALGO_NALG:     /* fall through */
2636 #else
2637 		case CRYPTO_ALGO_CKIP:     /* fall through */
2638 		case CRYPTO_ALGO_CKIP_MMH: /* fall through */
2639 		case CRYPTO_ALGO_WEP_MMH:  /* fall through */
2640 		case CRYPTO_ALGO_PMK:      /* fall through default */
2641 #endif /* !defined(BCMCCX) && !defined(BCMEXTCCX) */
2642 		default:
2643 			*key_len = 0;
2644 			err = BCME_UNSUPPORTED;
2645 			break;
2646 	}
2647 	return err;
2648 }
2649