1 /*
2  * WPA/RSN - Shared functions for supplicant and authenticator
3  * Copyright (c) 2002-2018, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "crypto/md5.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "crypto/sha384.h"
16 #include "crypto/sha512.h"
17 #include "crypto/aes_wrap.h"
18 #include "crypto/crypto.h"
19 #include "ieee802_11_defs.h"
20 #include "ieee802_11_common.h"
21 #include "defs.h"
22 #include "wpa_common.h"
23 
24 
wpa_kck_len(int akmp,size_t pmk_len)25 static unsigned int wpa_kck_len(int akmp, size_t pmk_len)
26 {
27           switch (akmp) {
28           case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
29           case WPA_KEY_MGMT_IEEE8021X_SHA384:
30           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
31                     return 24;
32           case WPA_KEY_MGMT_FILS_SHA256:
33           case WPA_KEY_MGMT_FT_FILS_SHA256:
34           case WPA_KEY_MGMT_FILS_SHA384:
35           case WPA_KEY_MGMT_FT_FILS_SHA384:
36                     return 0;
37           case WPA_KEY_MGMT_DPP:
38                     return pmk_len / 2;
39           case WPA_KEY_MGMT_OWE:
40                     return pmk_len / 2;
41           case WPA_KEY_MGMT_SAE_EXT_KEY:
42           case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
43                     return pmk_len / 2;
44           default:
45                     return 16;
46           }
47 }
48 
49 
50 #ifdef CONFIG_IEEE80211R
wpa_kck2_len(int akmp)51 static unsigned int wpa_kck2_len(int akmp)
52 {
53           switch (akmp) {
54           case WPA_KEY_MGMT_FT_FILS_SHA256:
55                     return 16;
56           case WPA_KEY_MGMT_FT_FILS_SHA384:
57                     return 24;
58           default:
59                     return 0;
60           }
61 }
62 #endif /* CONFIG_IEEE80211R */
63 
64 
wpa_kek_len(int akmp,size_t pmk_len)65 static unsigned int wpa_kek_len(int akmp, size_t pmk_len)
66 {
67           switch (akmp) {
68           case WPA_KEY_MGMT_FILS_SHA384:
69           case WPA_KEY_MGMT_FT_FILS_SHA384:
70                     return 64;
71           case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
72           case WPA_KEY_MGMT_FILS_SHA256:
73           case WPA_KEY_MGMT_FT_FILS_SHA256:
74           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
75           case WPA_KEY_MGMT_IEEE8021X_SHA384:
76                     return 32;
77           case WPA_KEY_MGMT_DPP:
78                     return pmk_len <= 32 ? 16 : 32;
79           case WPA_KEY_MGMT_OWE:
80                     return pmk_len <= 32 ? 16 : 32;
81           case WPA_KEY_MGMT_SAE_EXT_KEY:
82           case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
83                     return pmk_len <= 32 ? 16 : 32;
84           default:
85                     return 16;
86           }
87 }
88 
89 
90 #ifdef CONFIG_IEEE80211R
wpa_kek2_len(int akmp)91 static unsigned int wpa_kek2_len(int akmp)
92 {
93           switch (akmp) {
94           case WPA_KEY_MGMT_FT_FILS_SHA256:
95                     return 16;
96           case WPA_KEY_MGMT_FT_FILS_SHA384:
97                     return 32;
98           default:
99                     return 0;
100           }
101 }
102 #endif /* CONFIG_IEEE80211R */
103 
104 
wpa_mic_len(int akmp,size_t pmk_len)105 unsigned int wpa_mic_len(int akmp, size_t pmk_len)
106 {
107           switch (akmp) {
108           case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
109           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
110           case WPA_KEY_MGMT_IEEE8021X_SHA384:
111                     return 24;
112           case WPA_KEY_MGMT_FILS_SHA256:
113           case WPA_KEY_MGMT_FILS_SHA384:
114           case WPA_KEY_MGMT_FT_FILS_SHA256:
115           case WPA_KEY_MGMT_FT_FILS_SHA384:
116                     return 0;
117           case WPA_KEY_MGMT_DPP:
118                     return pmk_len / 2;
119           case WPA_KEY_MGMT_OWE:
120                     return pmk_len / 2;
121           case WPA_KEY_MGMT_SAE_EXT_KEY:
122           case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
123                     return pmk_len / 2;
124           default:
125                     return 16;
126           }
127 }
128 
129 
130 /**
131  * wpa_use_akm_defined - Is AKM-defined Key Descriptor Version used
132  * @akmp: WPA_KEY_MGMT_* used in key derivation
133  * Returns: 1 if AKM-defined Key Descriptor Version is used; 0 otherwise
134  */
wpa_use_akm_defined(int akmp)135 int wpa_use_akm_defined(int akmp)
136 {
137           return akmp == WPA_KEY_MGMT_OSEN ||
138                     akmp == WPA_KEY_MGMT_OWE ||
139                     akmp == WPA_KEY_MGMT_DPP ||
140                     akmp == WPA_KEY_MGMT_FT_IEEE8021X_SHA384 ||
141                     akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
142                     wpa_key_mgmt_sae(akmp) ||
143                     wpa_key_mgmt_suite_b(akmp) ||
144                     wpa_key_mgmt_fils(akmp);
145 }
146 
147 
148 /**
149  * wpa_use_cmac - Is CMAC integrity algorithm used for EAPOL-Key MIC
150  * @akmp: WPA_KEY_MGMT_* used in key derivation
151  * Returns: 1 if CMAC is used; 0 otherwise
152  */
wpa_use_cmac(int akmp)153 int wpa_use_cmac(int akmp)
154 {
155           return akmp == WPA_KEY_MGMT_OSEN ||
156                     akmp == WPA_KEY_MGMT_OWE ||
157                     akmp == WPA_KEY_MGMT_DPP ||
158                     wpa_key_mgmt_ft(akmp) ||
159                     wpa_key_mgmt_sha256(akmp) ||
160                     (wpa_key_mgmt_sae(akmp) &&
161                      !wpa_key_mgmt_sae_ext_key(akmp)) ||
162                     wpa_key_mgmt_suite_b(akmp);
163 }
164 
165 
166 /**
167  * wpa_use_aes_key_wrap - Is AES Keywrap algorithm used for EAPOL-Key Key Data
168  * @akmp: WPA_KEY_MGMT_* used in key derivation
169  * Returns: 1 if AES Keywrap is used; 0 otherwise
170  *
171  * Note: AKM 00-0F-AC:1 and 00-0F-AC:2 have special rules for selecting whether
172  * to use AES Keywrap based on the negotiated pairwise cipher. This function
173  * does not cover those special cases.
174  */
wpa_use_aes_key_wrap(int akmp)175 int wpa_use_aes_key_wrap(int akmp)
176 {
177           return akmp == WPA_KEY_MGMT_OSEN ||
178                     akmp == WPA_KEY_MGMT_OWE ||
179                     akmp == WPA_KEY_MGMT_DPP ||
180                     akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
181                     wpa_key_mgmt_ft(akmp) ||
182                     wpa_key_mgmt_sha256(akmp) ||
183                     wpa_key_mgmt_sae(akmp) ||
184                     wpa_key_mgmt_suite_b(akmp);
185 }
186 
187 
188 /**
189  * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
190  * @key: EAPOL-Key Key Confirmation Key (KCK)
191  * @key_len: KCK length in octets
192  * @akmp: WPA_KEY_MGMT_* used in key derivation
193  * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
194  * @buf: Pointer to the beginning of the EAPOL header (version field)
195  * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
196  * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
197  * Returns: 0 on success, -1 on failure
198  *
199  * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
200  * to be cleared (all zeroes) when calling this function.
201  *
202  * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
203  * description of the Key MIC calculation. It includes packet data from the
204  * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
205  * happened during final editing of the standard and the correct behavior is
206  * defined in the last draft (IEEE 802.11i/D10).
207  */
wpa_eapol_key_mic(const u8 * key,size_t key_len,int akmp,int ver,const u8 * buf,size_t len,u8 * mic)208 int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
209                           const u8 *buf, size_t len, u8 *mic)
210 {
211           u8 hash[SHA512_MAC_LEN];
212 
213           if (key_len == 0) {
214                     wpa_printf(MSG_DEBUG,
215                                  "WPA: KCK not set - cannot calculate MIC");
216                     return -1;
217           }
218 
219           switch (ver) {
220 #ifndef CONFIG_FIPS
221           case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
222                     wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-MD5");
223                     return hmac_md5(key, key_len, buf, len, mic);
224 #endif /* CONFIG_FIPS */
225           case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
226                     wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-SHA1");
227                     if (hmac_sha1(key, key_len, buf, len, hash))
228                               return -1;
229                     os_memcpy(mic, hash, MD5_MAC_LEN);
230                     break;
231           case WPA_KEY_INFO_TYPE_AES_128_CMAC:
232                     wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using AES-CMAC");
233                     return omac1_aes_128(key, buf, len, mic);
234           case WPA_KEY_INFO_TYPE_AKM_DEFINED:
235                     switch (akmp) {
236 #ifdef CONFIG_SAE
237                     case WPA_KEY_MGMT_SAE:
238                     case WPA_KEY_MGMT_FT_SAE:
239                               wpa_printf(MSG_DEBUG,
240                                            "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - SAE)");
241                               return omac1_aes_128(key, buf, len, mic);
242                     case WPA_KEY_MGMT_SAE_EXT_KEY:
243                     case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
244                               wpa_printf(MSG_DEBUG,
245                                            "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - SAE-EXT-KEY)",
246                                            (unsigned int) key_len * 8 * 2);
247                               if (key_len == 128 / 8) {
248                                         if (hmac_sha256(key, key_len, buf, len, hash))
249                                                   return -1;
250 #ifdef CONFIG_SHA384
251                               } else if (key_len == 192 / 8) {
252                                         if (hmac_sha384(key, key_len, buf, len, hash))
253                                                   return -1;
254 #endif /* CONFIG_SHA384 */
255 #ifdef CONFIG_SHA512
256                               } else if (key_len == 256 / 8) {
257                                         if (hmac_sha512(key, key_len, buf, len, hash))
258                                                   return -1;
259 #endif /* CONFIG_SHA512 */
260                               } else {
261                                         wpa_printf(MSG_INFO,
262                                                      "SAE: Unsupported KCK length: %u",
263                                                      (unsigned int) key_len);
264                                         return -1;
265                               }
266                               os_memcpy(mic, hash, key_len);
267                               break;
268 #endif /* CONFIG_SAE */
269 #ifdef CONFIG_HS20
270                     case WPA_KEY_MGMT_OSEN:
271                               wpa_printf(MSG_DEBUG,
272                                            "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - OSEN)");
273                               return omac1_aes_128(key, buf, len, mic);
274 #endif /* CONFIG_HS20 */
275 #ifdef CONFIG_SUITEB
276                     case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
277                               wpa_printf(MSG_DEBUG,
278                                            "WPA: EAPOL-Key MIC using HMAC-SHA256 (AKM-defined - Suite B)");
279                               if (hmac_sha256(key, key_len, buf, len, hash))
280                                         return -1;
281                               os_memcpy(mic, hash, MD5_MAC_LEN);
282                               break;
283 #endif /* CONFIG_SUITEB */
284 #ifdef CONFIG_SUITEB192
285                     case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
286                               wpa_printf(MSG_DEBUG,
287                                            "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - Suite B 192-bit)");
288                               if (hmac_sha384(key, key_len, buf, len, hash))
289                                         return -1;
290                               os_memcpy(mic, hash, 24);
291                               break;
292 #endif /* CONFIG_SUITEB192 */
293 #ifdef CONFIG_OWE
294                     case WPA_KEY_MGMT_OWE:
295                               wpa_printf(MSG_DEBUG,
296                                            "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - OWE)",
297                                            (unsigned int) key_len * 8 * 2);
298                               if (key_len == 128 / 8) {
299                                         if (hmac_sha256(key, key_len, buf, len, hash))
300                                                   return -1;
301                               } else if (key_len == 192 / 8) {
302                                         if (hmac_sha384(key, key_len, buf, len, hash))
303                                                   return -1;
304                               } else if (key_len == 256 / 8) {
305                                         if (hmac_sha512(key, key_len, buf, len, hash))
306                                                   return -1;
307                               } else {
308                                         wpa_printf(MSG_INFO,
309                                                      "OWE: Unsupported KCK length: %u",
310                                                      (unsigned int) key_len);
311                                         return -1;
312                               }
313                               os_memcpy(mic, hash, key_len);
314                               break;
315 #endif /* CONFIG_OWE */
316 #ifdef CONFIG_DPP
317                     case WPA_KEY_MGMT_DPP:
318                               wpa_printf(MSG_DEBUG,
319                                            "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - DPP)",
320                                            (unsigned int) key_len * 8 * 2);
321                               if (key_len == 128 / 8) {
322                                         if (hmac_sha256(key, key_len, buf, len, hash))
323                                                   return -1;
324                               } else if (key_len == 192 / 8) {
325                                         if (hmac_sha384(key, key_len, buf, len, hash))
326                                                   return -1;
327                               } else if (key_len == 256 / 8) {
328                                         if (hmac_sha512(key, key_len, buf, len, hash))
329                                                   return -1;
330                               } else {
331                                         wpa_printf(MSG_INFO,
332                                                      "DPP: Unsupported KCK length: %u",
333                                                      (unsigned int) key_len);
334                                         return -1;
335                               }
336                               os_memcpy(mic, hash, key_len);
337                               break;
338 #endif /* CONFIG_DPP */
339 #ifdef CONFIG_SHA384
340                     case WPA_KEY_MGMT_IEEE8021X_SHA384:
341 #ifdef CONFIG_IEEE80211R
342                     case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
343 #endif /* CONFIG_IEEE80211R */
344                               wpa_printf(MSG_DEBUG,
345                                            "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - 802.1X SHA384)");
346                               if (hmac_sha384(key, key_len, buf, len, hash))
347                                         return -1;
348                               os_memcpy(mic, hash, 24);
349                               break;
350 #endif /* CONFIG_SHA384 */
351                     default:
352                               wpa_printf(MSG_DEBUG,
353                                            "WPA: EAPOL-Key MIC algorithm not known (AKM-defined - akmp=0x%x)",
354                                            akmp);
355                               return -1;
356                     }
357                     break;
358           default:
359                     wpa_printf(MSG_DEBUG,
360                                  "WPA: EAPOL-Key MIC algorithm not known (ver=%d)",
361                                  ver);
362                     return -1;
363           }
364 
365           return 0;
366 }
367 
368 
369 /**
370  * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
371  * @pmk: Pairwise master key
372  * @pmk_len: Length of PMK
373  * @label: Label to use in derivation
374  * @addr1: AA or SA
375  * @addr2: SA or AA
376  * @nonce1: ANonce or SNonce
377  * @nonce2: SNonce or ANonce
378  * @ptk: Buffer for pairwise transient key
379  * @akmp: Negotiated AKM
380  * @cipher: Negotiated pairwise cipher
381  * @kdk_len: The length in octets that should be derived for KDK
382  * Returns: 0 on success, -1 on failure
383  *
384  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
385  * PTK = PRF-X(PMK, "Pairwise key expansion",
386  *             Min(AA, SA) || Max(AA, SA) ||
387  *             Min(ANonce, SNonce) || Max(ANonce, SNonce)
388  *             [ || Z.x ])
389  *
390  * The optional Z.x component is used only with DPP and that part is not defined
391  * in IEEE 802.11.
392  */
wpa_pmk_to_ptk(const u8 * pmk,size_t pmk_len,const char * label,const u8 * addr1,const u8 * addr2,const u8 * nonce1,const u8 * nonce2,struct wpa_ptk * ptk,int akmp,int cipher,const u8 * z,size_t z_len,size_t kdk_len)393 int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
394                        const u8 *addr1, const u8 *addr2,
395                        const u8 *nonce1, const u8 *nonce2,
396                        struct wpa_ptk *ptk, int akmp, int cipher,
397                        const u8 *z, size_t z_len, size_t kdk_len)
398 {
399 #define MAX_Z_LEN 66 /* with NIST P-521 */
400           u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
401           size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
402           u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
403                     WPA_KDK_MAX_LEN];
404           size_t ptk_len;
405 #ifdef CONFIG_OWE
406           int owe_ptk_workaround = 0;
407 
408           if (akmp == (WPA_KEY_MGMT_OWE | WPA_KEY_MGMT_PSK_SHA256)) {
409                     owe_ptk_workaround = 1;
410                     akmp = WPA_KEY_MGMT_OWE;
411           }
412 #endif /* CONFIG_OWE */
413 
414           if (pmk_len == 0) {
415                     wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
416                     return -1;
417           }
418 
419           if (z_len > MAX_Z_LEN)
420                     return -1;
421 
422           if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
423                     os_memcpy(data, addr1, ETH_ALEN);
424                     os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
425           } else {
426                     os_memcpy(data, addr2, ETH_ALEN);
427                     os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
428           }
429 
430           if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
431                     os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
432                     os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
433                                 WPA_NONCE_LEN);
434           } else {
435                     os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
436                     os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
437                                 WPA_NONCE_LEN);
438           }
439 
440           if (z && z_len) {
441                     os_memcpy(data + 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, z, z_len);
442                     data_len += z_len;
443           }
444 
445           if (kdk_len > WPA_KDK_MAX_LEN) {
446                     wpa_printf(MSG_ERROR,
447                                  "WPA: KDK len=%zu exceeds max supported len",
448                                  kdk_len);
449                     return -1;
450           }
451 
452           ptk->kck_len = wpa_kck_len(akmp, pmk_len);
453           ptk->kek_len = wpa_kek_len(akmp, pmk_len);
454           ptk->tk_len = wpa_cipher_key_len(cipher);
455           ptk->kdk_len = kdk_len;
456           if (ptk->tk_len == 0) {
457                     wpa_printf(MSG_ERROR,
458                                  "WPA: Unsupported cipher (0x%x) used in PTK derivation",
459                                  cipher);
460                     return -1;
461           }
462           ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
463 
464           if (wpa_key_mgmt_sha384(akmp)) {
465 #ifdef CONFIG_SHA384
466                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
467                     if (sha384_prf(pmk, pmk_len, label, data, data_len,
468                                      tmp, ptk_len) < 0)
469                               return -1;
470 #else /* CONFIG_SHA384 */
471                     return -1;
472 #endif /* CONFIG_SHA384 */
473           } else if (wpa_key_mgmt_sha256(akmp)) {
474                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
475                     if (sha256_prf(pmk, pmk_len, label, data, data_len,
476                                      tmp, ptk_len) < 0)
477                               return -1;
478 #ifdef CONFIG_OWE
479           } else if (akmp == WPA_KEY_MGMT_OWE && (pmk_len == 32 ||
480                                                             owe_ptk_workaround)) {
481                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
482                     if (sha256_prf(pmk, pmk_len, label, data, data_len,
483                                      tmp, ptk_len) < 0)
484                               return -1;
485           } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 48) {
486                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
487                     if (sha384_prf(pmk, pmk_len, label, data, data_len,
488                                      tmp, ptk_len) < 0)
489                               return -1;
490           } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 64) {
491                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
492                     if (sha512_prf(pmk, pmk_len, label, data, data_len,
493                                      tmp, ptk_len) < 0)
494                               return -1;
495           } else if (akmp == WPA_KEY_MGMT_OWE) {
496                     wpa_printf(MSG_INFO, "OWE: Unknown PMK length %u",
497                                  (unsigned int) pmk_len);
498                     return -1;
499 #endif /* CONFIG_OWE */
500 #ifdef CONFIG_DPP
501           } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
502                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
503                     if (sha256_prf(pmk, pmk_len, label, data, data_len,
504                                      tmp, ptk_len) < 0)
505                               return -1;
506           } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
507                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
508                     if (sha384_prf(pmk, pmk_len, label, data, data_len,
509                                      tmp, ptk_len) < 0)
510                               return -1;
511           } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
512                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
513                     if (sha512_prf(pmk, pmk_len, label, data, data_len,
514                                      tmp, ptk_len) < 0)
515                               return -1;
516           } else if (akmp == WPA_KEY_MGMT_DPP) {
517                     wpa_printf(MSG_INFO, "DPP: Unknown PMK length %u",
518                                  (unsigned int) pmk_len);
519                     return -1;
520 #endif /* CONFIG_DPP */
521 #ifdef CONFIG_SAE
522           } else if (wpa_key_mgmt_sae_ext_key(akmp)) {
523                     if (pmk_len == 32) {
524                               wpa_printf(MSG_DEBUG,
525                                            "SAE: PTK derivation using PRF(SHA256)");
526                               if (sha256_prf(pmk, pmk_len, label, data, data_len,
527                                                tmp, ptk_len) < 0)
528                                         return -1;
529 #ifdef CONFIG_SHA384
530                     } else if (pmk_len == 48) {
531                               wpa_printf(MSG_DEBUG,
532                                            "SAE: PTK derivation using PRF(SHA384)");
533                               if (sha384_prf(pmk, pmk_len, label, data, data_len,
534                                                tmp, ptk_len) < 0)
535                                         return -1;
536 #endif /* CONFIG_SHA384 */
537 #ifdef CONFIG_SHA512
538                     } else if (pmk_len == 64) {
539                               wpa_printf(MSG_DEBUG,
540                                            "SAE: PTK derivation using PRF(SHA512)");
541                               if (sha512_prf(pmk, pmk_len, label, data, data_len,
542                                                tmp, ptk_len) < 0)
543                                         return -1;
544 #endif /* CONFIG_SHA512 */
545                     } else {
546                               wpa_printf(MSG_INFO, "SAE: Unknown PMK length %u",
547                                            (unsigned int) pmk_len);
548                               return -1;
549                     }
550 #endif /* CONFIG_SAE */
551           } else {
552                     wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
553                     if (sha1_prf(pmk, pmk_len, label, data, data_len, tmp,
554                                    ptk_len) < 0)
555                               return -1;
556           }
557 
558           wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
559                        MAC2STR(addr1), MAC2STR(addr2));
560           wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
561           wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
562           if (z && z_len)
563                     wpa_hexdump_key(MSG_DEBUG, "WPA: Z.x", z, z_len);
564           wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
565           wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
566 
567           os_memcpy(ptk->kck, tmp, ptk->kck_len);
568           wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
569 
570           os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
571           wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
572 
573           os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
574           wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
575 
576           if (kdk_len) {
577                     os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
578                                 ptk->tk_len, ptk->kdk_len);
579                     wpa_hexdump_key(MSG_DEBUG, "WPA: KDK", ptk->kdk, ptk->kdk_len);
580           }
581 
582           ptk->kek2_len = 0;
583           ptk->kck2_len = 0;
584 
585           os_memset(tmp, 0, sizeof(tmp));
586           os_memset(data, 0, data_len);
587           return 0;
588 }
589 
590 #ifdef CONFIG_FILS
591 
fils_rmsk_to_pmk(int akmp,const u8 * rmsk,size_t rmsk_len,const u8 * snonce,const u8 * anonce,const u8 * dh_ss,size_t dh_ss_len,u8 * pmk,size_t * pmk_len)592 int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
593                          const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
594                          size_t dh_ss_len, u8 *pmk, size_t *pmk_len)
595 {
596           u8 nonces[2 * FILS_NONCE_LEN];
597           const u8 *addr[2];
598           size_t len[2];
599           size_t num_elem;
600           int res;
601 
602           /* PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ]) */
603           wpa_printf(MSG_DEBUG, "FILS: rMSK to PMK derivation");
604 
605           if (wpa_key_mgmt_sha384(akmp))
606                     *pmk_len = SHA384_MAC_LEN;
607           else if (wpa_key_mgmt_sha256(akmp))
608                     *pmk_len = SHA256_MAC_LEN;
609           else
610                     return -1;
611 
612           wpa_hexdump_key(MSG_DEBUG, "FILS: rMSK", rmsk, rmsk_len);
613           wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
614           wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
615           wpa_hexdump(MSG_DEBUG, "FILS: DHss", dh_ss, dh_ss_len);
616 
617           os_memcpy(nonces, snonce, FILS_NONCE_LEN);
618           os_memcpy(&nonces[FILS_NONCE_LEN], anonce, FILS_NONCE_LEN);
619           addr[0] = rmsk;
620           len[0] = rmsk_len;
621           num_elem = 1;
622           if (dh_ss) {
623                     addr[1] = dh_ss;
624                     len[1] = dh_ss_len;
625                     num_elem++;
626           }
627           if (wpa_key_mgmt_sha384(akmp))
628                     res = hmac_sha384_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
629                                                    addr, len, pmk);
630           else
631                     res = hmac_sha256_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
632                                                    addr, len, pmk);
633           if (res == 0)
634                     wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, *pmk_len);
635           else
636                     *pmk_len = 0;
637           return res;
638 }
639 
640 
fils_pmkid_erp(int akmp,const u8 * reauth,size_t reauth_len,u8 * pmkid)641 int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
642                        u8 *pmkid)
643 {
644           const u8 *addr[1];
645           size_t len[1];
646           u8 hash[SHA384_MAC_LEN];
647           int res;
648 
649           /* PMKID = Truncate-128(Hash(EAP-Initiate/Reauth)) */
650           addr[0] = reauth;
651           len[0] = reauth_len;
652           if (wpa_key_mgmt_sha384(akmp))
653                     res = sha384_vector(1, addr, len, hash);
654           else if (wpa_key_mgmt_sha256(akmp))
655                     res = sha256_vector(1, addr, len, hash);
656           else
657                     return -1;
658           if (res)
659                     return res;
660           os_memcpy(pmkid, hash, PMKID_LEN);
661           wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
662           return 0;
663 }
664 
665 
fils_pmk_to_ptk(const u8 * pmk,size_t pmk_len,const u8 * spa,const u8 * aa,const u8 * snonce,const u8 * anonce,const u8 * dhss,size_t dhss_len,struct wpa_ptk * ptk,u8 * ick,size_t * ick_len,int akmp,int cipher,u8 * fils_ft,size_t * fils_ft_len,size_t kdk_len)666 int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
667                         const u8 *snonce, const u8 *anonce, const u8 *dhss,
668                         size_t dhss_len, struct wpa_ptk *ptk,
669                         u8 *ick, size_t *ick_len, int akmp, int cipher,
670                         u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
671 {
672           u8 *data, *pos;
673           size_t data_len;
674           u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
675                  FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
676           size_t key_data_len;
677           const char *label = "FILS PTK Derivation";
678           int ret = -1;
679           size_t offset;
680 
681           /*
682            * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
683            *                       SPA || AA || SNonce || ANonce [ || DHss ])
684            * ICK = L(FILS-Key-Data, 0, ICK_bits)
685            * KEK = L(FILS-Key-Data, ICK_bits, KEK_bits)
686            * TK = L(FILS-Key-Data, ICK_bits + KEK_bits, TK_bits)
687            * If doing FT initial mobility domain association:
688            * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
689            *             FILS-FT_bits)
690            * When a KDK is derived:
691            * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
692            *           KDK_bits)
693            */
694           data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
695           data = os_malloc(data_len);
696           if (!data)
697                     goto err;
698           pos = data;
699           os_memcpy(pos, spa, ETH_ALEN);
700           pos += ETH_ALEN;
701           os_memcpy(pos, aa, ETH_ALEN);
702           pos += ETH_ALEN;
703           os_memcpy(pos, snonce, FILS_NONCE_LEN);
704           pos += FILS_NONCE_LEN;
705           os_memcpy(pos, anonce, FILS_NONCE_LEN);
706           pos += FILS_NONCE_LEN;
707           if (dhss)
708                     os_memcpy(pos, dhss, dhss_len);
709 
710           ptk->kck_len = 0;
711           ptk->kek_len = wpa_kek_len(akmp, pmk_len);
712           ptk->tk_len = wpa_cipher_key_len(cipher);
713           if (wpa_key_mgmt_sha384(akmp))
714                     *ick_len = 48;
715           else if (wpa_key_mgmt_sha256(akmp))
716                     *ick_len = 32;
717           else
718                     goto err;
719           key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
720 
721           if (kdk_len) {
722                     if (kdk_len > WPA_KDK_MAX_LEN) {
723                               wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
724                                            kdk_len);
725                               goto err;
726                     }
727 
728                     ptk->kdk_len = kdk_len;
729                     key_data_len += kdk_len;
730           } else {
731                     ptk->kdk_len = 0;
732           }
733 
734           if (fils_ft && fils_ft_len) {
735                     if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
736                               *fils_ft_len = 32;
737                     } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
738                               *fils_ft_len = 48;
739                     } else {
740                               *fils_ft_len = 0;
741                               fils_ft = NULL;
742                     }
743                     key_data_len += *fils_ft_len;
744           }
745 
746           if (wpa_key_mgmt_sha384(akmp)) {
747                     wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
748                     if (sha384_prf(pmk, pmk_len, label, data, data_len,
749                                      tmp, key_data_len) < 0)
750                               goto err;
751           } else {
752                     wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA256)");
753                     if (sha256_prf(pmk, pmk_len, label, data, data_len,
754                                      tmp, key_data_len) < 0)
755                               goto err;
756           }
757 
758           wpa_printf(MSG_DEBUG, "FILS: PTK derivation - SPA=" MACSTR
759                        " AA=" MACSTR, MAC2STR(spa), MAC2STR(aa));
760           wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
761           wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
762           if (dhss)
763                     wpa_hexdump_key(MSG_DEBUG, "FILS: DHss", dhss, dhss_len);
764           wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, pmk_len);
765           wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
766 
767           os_memcpy(ick, tmp, *ick_len);
768           offset = *ick_len;
769           wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
770 
771           os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
772           wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
773           offset += ptk->kek_len;
774 
775           os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
776           wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
777           offset += ptk->tk_len;
778 
779           if (fils_ft && fils_ft_len) {
780                     os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
781                     wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
782                                         fils_ft, *fils_ft_len);
783                     offset += *fils_ft_len;
784           }
785 
786           if (ptk->kdk_len) {
787                     os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
788                     wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
789           }
790 
791           ptk->kek2_len = 0;
792           ptk->kck2_len = 0;
793 
794           os_memset(tmp, 0, sizeof(tmp));
795           ret = 0;
796 err:
797           bin_clear_free(data, data_len);
798           return ret;
799 }
800 
801 
fils_key_auth_sk(const u8 * ick,size_t ick_len,const u8 * snonce,const u8 * anonce,const u8 * sta_addr,const u8 * bssid,const u8 * g_sta,size_t g_sta_len,const u8 * g_ap,size_t g_ap_len,int akmp,u8 * key_auth_sta,u8 * key_auth_ap,size_t * key_auth_len)802 int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
803                          const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
804                          const u8 *g_sta, size_t g_sta_len,
805                          const u8 *g_ap, size_t g_ap_len,
806                          int akmp, u8 *key_auth_sta, u8 *key_auth_ap,
807                          size_t *key_auth_len)
808 {
809           const u8 *addr[6];
810           size_t len[6];
811           size_t num_elem = 4;
812           int res;
813 
814           wpa_printf(MSG_DEBUG, "FILS: Key-Auth derivation: STA-MAC=" MACSTR
815                        " AP-BSSID=" MACSTR, MAC2STR(sta_addr), MAC2STR(bssid));
816           wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, ick_len);
817           wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
818           wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
819           wpa_hexdump(MSG_DEBUG, "FILS: gSTA", g_sta, g_sta_len);
820           wpa_hexdump(MSG_DEBUG, "FILS: gAP", g_ap, g_ap_len);
821 
822           /*
823            * For (Re)Association Request frame (STA->AP):
824            * Key-Auth = HMAC-Hash(ICK, SNonce || ANonce || STA-MAC || AP-BSSID
825            *                      [ || gSTA || gAP ])
826            */
827           addr[0] = snonce;
828           len[0] = FILS_NONCE_LEN;
829           addr[1] = anonce;
830           len[1] = FILS_NONCE_LEN;
831           addr[2] = sta_addr;
832           len[2] = ETH_ALEN;
833           addr[3] = bssid;
834           len[3] = ETH_ALEN;
835           if (g_sta && g_sta_len && g_ap && g_ap_len) {
836                     addr[4] = g_sta;
837                     len[4] = g_sta_len;
838                     addr[5] = g_ap;
839                     len[5] = g_ap_len;
840                     num_elem = 6;
841           }
842 
843           if (wpa_key_mgmt_sha384(akmp)) {
844                     *key_auth_len = 48;
845                     res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
846                                                    key_auth_sta);
847           } else if (wpa_key_mgmt_sha256(akmp)) {
848                     *key_auth_len = 32;
849                     res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
850                                                    key_auth_sta);
851           } else {
852                     return -1;
853           }
854           if (res < 0)
855                     return res;
856 
857           /*
858            * For (Re)Association Response frame (AP->STA):
859            * Key-Auth = HMAC-Hash(ICK, ANonce || SNonce || AP-BSSID || STA-MAC
860            *                      [ || gAP || gSTA ])
861            */
862           addr[0] = anonce;
863           addr[1] = snonce;
864           addr[2] = bssid;
865           addr[3] = sta_addr;
866           if (g_sta && g_sta_len && g_ap && g_ap_len) {
867                     addr[4] = g_ap;
868                     len[4] = g_ap_len;
869                     addr[5] = g_sta;
870                     len[5] = g_sta_len;
871           }
872 
873           if (wpa_key_mgmt_sha384(akmp))
874                     res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
875                                                    key_auth_ap);
876           else if (wpa_key_mgmt_sha256(akmp))
877                     res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
878                                                    key_auth_ap);
879           if (res < 0)
880                     return res;
881 
882           wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (STA)",
883                         key_auth_sta, *key_auth_len);
884           wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (AP)",
885                         key_auth_ap, *key_auth_len);
886 
887           return 0;
888 }
889 
890 #endif /* CONFIG_FILS */
891 
892 
893 #ifdef CONFIG_IEEE80211R
wpa_ft_mic(int key_mgmt,const u8 * kck,size_t kck_len,const u8 * sta_addr,const u8 * ap_addr,u8 transaction_seqnum,const u8 * mdie,size_t mdie_len,const u8 * ftie,size_t ftie_len,const u8 * rsnie,size_t rsnie_len,const u8 * ric,size_t ric_len,const u8 * rsnxe,size_t rsnxe_len,const struct wpabuf * extra,u8 * mic)894 int wpa_ft_mic(int key_mgmt, const u8 *kck, size_t kck_len, const u8 *sta_addr,
895                  const u8 *ap_addr, u8 transaction_seqnum,
896                  const u8 *mdie, size_t mdie_len,
897                  const u8 *ftie, size_t ftie_len,
898                  const u8 *rsnie, size_t rsnie_len,
899                  const u8 *ric, size_t ric_len,
900                  const u8 *rsnxe, size_t rsnxe_len,
901                  const struct wpabuf *extra,
902                  u8 *mic)
903 {
904           const u8 *addr[11];
905           size_t len[11];
906           size_t i, num_elem = 0;
907           u8 zero_mic[32];
908           size_t mic_len, fte_fixed_len;
909           int res;
910 
911           if (kck_len == 16) {
912                     mic_len = 16;
913 #ifdef CONFIG_SHA384
914           } else if (kck_len == 24) {
915                     mic_len = 24;
916 #endif /* CONFIG_SHA384 */
917 #ifdef CONFIG_SHA512
918           } else if (kck_len == 32) {
919                     mic_len = 32;
920 #endif /* CONFIG_SHA512 */
921           } else {
922                     wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
923                                  (unsigned int) kck_len);
924                     return -1;
925           }
926 
927           fte_fixed_len = sizeof(struct rsn_ftie) - 16 + mic_len;
928 
929           addr[num_elem] = sta_addr;
930           len[num_elem] = ETH_ALEN;
931           num_elem++;
932 
933           addr[num_elem] = ap_addr;
934           len[num_elem] = ETH_ALEN;
935           num_elem++;
936 
937           addr[num_elem] = &transaction_seqnum;
938           len[num_elem] = 1;
939           num_elem++;
940 
941           if (rsnie) {
942                     addr[num_elem] = rsnie;
943                     len[num_elem] = rsnie_len;
944                     num_elem++;
945           }
946           if (mdie) {
947                     addr[num_elem] = mdie;
948                     len[num_elem] = mdie_len;
949                     num_elem++;
950           }
951           if (ftie) {
952                     if (ftie_len < 2 + fte_fixed_len)
953                               return -1;
954 
955                     /* IE hdr and mic_control */
956                     addr[num_elem] = ftie;
957                     len[num_elem] = 2 + 2;
958                     num_elem++;
959 
960                     /* MIC field with all zeros */
961                     os_memset(zero_mic, 0, mic_len);
962                     addr[num_elem] = zero_mic;
963                     len[num_elem] = mic_len;
964                     num_elem++;
965 
966                     /* Rest of FTIE */
967                     addr[num_elem] = ftie + 2 + 2 + mic_len;
968                     len[num_elem] = ftie_len - (2 + 2 + mic_len);
969                     num_elem++;
970           }
971           if (ric) {
972                     addr[num_elem] = ric;
973                     len[num_elem] = ric_len;
974                     num_elem++;
975           }
976 
977           if (rsnxe) {
978                     addr[num_elem] = rsnxe;
979                     len[num_elem] = rsnxe_len;
980                     num_elem++;
981           }
982 
983           if (extra) {
984                     addr[num_elem] = wpabuf_head(extra);
985                     len[num_elem] = wpabuf_len(extra);
986                     num_elem++;
987           }
988 
989           for (i = 0; i < num_elem; i++)
990                     wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
991           res = -1;
992 #ifdef CONFIG_SHA512
993           if (kck_len == 32) {
994                     u8 hash[SHA512_MAC_LEN];
995 
996                     if (hmac_sha512_vector(kck, kck_len, num_elem, addr, len, hash))
997                               return -1;
998                     os_memcpy(mic, hash, 32);
999                     res = 0;
1000           }
1001 #endif /* CONFIG_SHA384 */
1002 #ifdef CONFIG_SHA384
1003           if (kck_len == 24) {
1004                     u8 hash[SHA384_MAC_LEN];
1005 
1006                     if (hmac_sha384_vector(kck, kck_len, num_elem, addr, len, hash))
1007                               return -1;
1008                     os_memcpy(mic, hash, 24);
1009                     res = 0;
1010           }
1011 #endif /* CONFIG_SHA384 */
1012           if (kck_len == 16 && key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1013                     u8 hash[SHA256_MAC_LEN];
1014 
1015                     if (hmac_sha256_vector(kck, kck_len, num_elem, addr, len, hash))
1016                               return -1;
1017                     os_memcpy(mic, hash, 16);
1018                     res = 0;
1019           }
1020           if (kck_len == 16 && key_mgmt != WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
1021               omac1_aes_128_vector(kck, num_elem, addr, len, mic) == 0)
1022                     res = 0;
1023 
1024           return res;
1025 }
1026 
1027 
wpa_ft_parse_ftie(const u8 * ie,size_t ie_len,struct wpa_ft_ies * parse,const u8 * opt)1028 static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
1029                                    struct wpa_ft_ies *parse, const u8 *opt)
1030 {
1031           const u8 *end, *pos;
1032           u8 link_id;
1033 
1034           pos = opt;
1035           end = ie + ie_len;
1036           wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos);
1037 
1038           while (end - pos >= 2) {
1039                     u8 id, len;
1040 
1041                     id = *pos++;
1042                     len = *pos++;
1043                     if (len > end - pos) {
1044                               wpa_printf(MSG_DEBUG, "FT: Truncated subelement");
1045                               return -1;
1046                     }
1047 
1048                     switch (id) {
1049                     case FTIE_SUBELEM_R1KH_ID:
1050                               if (len != FT_R1KH_ID_LEN) {
1051                                         wpa_printf(MSG_DEBUG,
1052                                                      "FT: Invalid R1KH-ID length in FTIE: %d",
1053                                                      len);
1054                                         return -1;
1055                               }
1056                               parse->r1kh_id = pos;
1057                               wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID",
1058                                             parse->r1kh_id, FT_R1KH_ID_LEN);
1059                               break;
1060                     case FTIE_SUBELEM_GTK:
1061                               wpa_printf(MSG_DEBUG, "FT: GTK");
1062                               parse->gtk = pos;
1063                               parse->gtk_len = len;
1064                               break;
1065                     case FTIE_SUBELEM_R0KH_ID:
1066                               if (len < 1 || len > FT_R0KH_ID_MAX_LEN) {
1067                                         wpa_printf(MSG_DEBUG,
1068                                                      "FT: Invalid R0KH-ID length in FTIE: %d",
1069                                                      len);
1070                                         return -1;
1071                               }
1072                               parse->r0kh_id = pos;
1073                               parse->r0kh_id_len = len;
1074                               wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
1075                                             parse->r0kh_id, parse->r0kh_id_len);
1076                               break;
1077                     case FTIE_SUBELEM_IGTK:
1078                               wpa_printf(MSG_DEBUG, "FT: IGTK");
1079                               parse->igtk = pos;
1080                               parse->igtk_len = len;
1081                               break;
1082 #ifdef CONFIG_OCV
1083                     case FTIE_SUBELEM_OCI:
1084                               parse->oci = pos;
1085                               parse->oci_len = len;
1086                               wpa_hexdump(MSG_DEBUG, "FT: OCI",
1087                                             parse->oci, parse->oci_len);
1088                               break;
1089 #endif /* CONFIG_OCV */
1090                     case FTIE_SUBELEM_BIGTK:
1091                               wpa_printf(MSG_DEBUG, "FT: BIGTK");
1092                               parse->bigtk = pos;
1093                               parse->bigtk_len = len;
1094                               break;
1095                     case FTIE_SUBELEM_MLO_GTK:
1096                               if (len < 2 + 1 + 1 + 8) {
1097                                         wpa_printf(MSG_DEBUG,
1098                                                      "FT: Too short MLO GTK in FTE");
1099                                         return -1;
1100                               }
1101                               link_id = pos[2] & 0x0f;
1102                               wpa_printf(MSG_DEBUG, "FT: MLO GTK (Link ID %u)",
1103                                            link_id);
1104                               if (link_id >= MAX_NUM_MLD_LINKS)
1105                                         break;
1106                               parse->valid_mlo_gtks |= BIT(link_id);
1107                               parse->mlo_gtk[link_id] = pos;
1108                               parse->mlo_gtk_len[link_id] = len;
1109                               break;
1110                     case FTIE_SUBELEM_MLO_IGTK:
1111                               if (len < 2 + 6 + 1 + 1) {
1112                                         wpa_printf(MSG_DEBUG,
1113                                                      "FT: Too short MLO IGTK in FTE");
1114                                         return -1;
1115                               }
1116                               link_id = pos[2 + 6] & 0x0f;
1117                               wpa_printf(MSG_DEBUG, "FT: MLO IGTK (Link ID %u)",
1118                                            link_id);
1119                               if (link_id >= MAX_NUM_MLD_LINKS)
1120                                         break;
1121                               parse->valid_mlo_igtks |= BIT(link_id);
1122                               parse->mlo_igtk[link_id] = pos;
1123                               parse->mlo_igtk_len[link_id] = len;
1124                               break;
1125                     case FTIE_SUBELEM_MLO_BIGTK:
1126                               if (len < 2 + 6 + 1 + 1) {
1127                                         wpa_printf(MSG_DEBUG,
1128                                                      "FT: Too short MLO BIGTK in FTE");
1129                                         return -1;
1130                               }
1131                               link_id = pos[2 + 6] & 0x0f;
1132                               wpa_printf(MSG_DEBUG, "FT: MLO BIGTK (Link ID %u)",
1133                                            link_id);
1134                               if (link_id >= MAX_NUM_MLD_LINKS)
1135                                         break;
1136                               parse->valid_mlo_bigtks |= BIT(link_id);
1137                               parse->mlo_bigtk[link_id] = pos;
1138                               parse->mlo_bigtk_len[link_id] = len;
1139                               break;
1140                     default:
1141                               wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id);
1142                               break;
1143                     }
1144 
1145                     pos += len;
1146           }
1147 
1148           return 0;
1149 }
1150 
1151 
wpa_ft_parse_fte(int key_mgmt,const u8 * ie,size_t len,struct wpa_ft_ies * parse)1152 static int wpa_ft_parse_fte(int key_mgmt, const u8 *ie, size_t len,
1153                                   struct wpa_ft_ies *parse)
1154 {
1155           size_t mic_len;
1156           u8 mic_len_info;
1157           const u8 *pos = ie;
1158           const u8 *end = pos + len;
1159 
1160           wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC Control", pos, 2);
1161           parse->fte_rsnxe_used = pos[0] & FTE_MIC_CTRL_RSNXE_USED;
1162           mic_len_info = (pos[0] & FTE_MIC_CTRL_MIC_LEN_MASK) >>
1163                     FTE_MIC_CTRL_MIC_LEN_SHIFT;
1164           parse->fte_elem_count = pos[1];
1165           pos += 2;
1166 
1167           if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1168                     switch (mic_len_info) {
1169                     case FTE_MIC_LEN_16:
1170                               mic_len = 16;
1171                               break;
1172                     case FTE_MIC_LEN_24:
1173                               mic_len = 24;
1174                               break;
1175                     case FTE_MIC_LEN_32:
1176                               mic_len = 32;
1177                               break;
1178                     default:
1179                               wpa_printf(MSG_DEBUG,
1180                                            "FT: Unknown MIC Length subfield value %u",
1181                                            mic_len_info);
1182                               return -1;
1183                     }
1184           } else {
1185                     mic_len = wpa_key_mgmt_sha384(key_mgmt) ? 24 : 16;
1186           }
1187           if (mic_len > (size_t) (end - pos)) {
1188                     wpa_printf(MSG_DEBUG, "FT: No room for %zu octet MIC in FTE",
1189                                  mic_len);
1190                     return -1;
1191           }
1192           wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC", pos, mic_len);
1193           parse->fte_mic = pos;
1194           parse->fte_mic_len = mic_len;
1195           pos += mic_len;
1196 
1197           if (2 * WPA_NONCE_LEN > end - pos)
1198                     return -1;
1199           parse->fte_anonce = pos;
1200           wpa_hexdump(MSG_DEBUG, "FT: FTE-ANonce",
1201                         parse->fte_anonce, WPA_NONCE_LEN);
1202           pos += WPA_NONCE_LEN;
1203           parse->fte_snonce = pos;
1204           wpa_hexdump(MSG_DEBUG, "FT: FTE-SNonce",
1205                         parse->fte_snonce, WPA_NONCE_LEN);
1206           pos += WPA_NONCE_LEN;
1207 
1208           return wpa_ft_parse_ftie(ie, len, parse, pos);
1209 }
1210 
1211 
wpa_ft_parse_ies(const u8 * ies,size_t ies_len,struct wpa_ft_ies * parse,int key_mgmt,bool reassoc_resp)1212 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
1213                          int key_mgmt, bool reassoc_resp)
1214 {
1215           const u8 *end, *pos;
1216           struct wpa_ie_data data;
1217           int ret;
1218           int prot_ie_count = 0;
1219           const u8 *fte = NULL;
1220           size_t fte_len = 0;
1221           bool is_fte = false;
1222           struct ieee802_11_elems elems;
1223 
1224           os_memset(parse, 0, sizeof(*parse));
1225           if (ies == NULL)
1226                     return 0;
1227 
1228           if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
1229                     wpa_printf(MSG_DEBUG, "FT: Failed to parse elements");
1230                     goto fail;
1231           }
1232 
1233           pos = ies;
1234           end = ies + ies_len;
1235           while (end - pos >= 2) {
1236                     u8 id, len;
1237 
1238                     id = *pos++;
1239                     len = *pos++;
1240                     if (len > end - pos)
1241                               break;
1242 
1243                     if (id != WLAN_EID_FAST_BSS_TRANSITION &&
1244                         id != WLAN_EID_FRAGMENT)
1245                               is_fte = false;
1246 
1247                     switch (id) {
1248                     case WLAN_EID_RSN:
1249                               wpa_hexdump(MSG_DEBUG, "FT: RSNE", pos, len);
1250                               parse->rsn = pos;
1251                               parse->rsn_len = len;
1252                               ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
1253                                                                parse->rsn_len + 2,
1254                                                                &data);
1255                               if (ret < 0) {
1256                                         wpa_printf(MSG_DEBUG, "FT: Failed to parse "
1257                                                      "RSN IE: %d", ret);
1258                                         goto fail;
1259                               }
1260                               parse->rsn_capab = data.capabilities;
1261                               if (data.num_pmkid == 1 && data.pmkid)
1262                                         parse->rsn_pmkid = data.pmkid;
1263                               parse->key_mgmt = data.key_mgmt;
1264                               parse->pairwise_cipher = data.pairwise_cipher;
1265                               if (!key_mgmt)
1266                                         key_mgmt = parse->key_mgmt;
1267                               break;
1268                     case WLAN_EID_RSNX:
1269                               wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len);
1270                               if (len < 1)
1271                                         break;
1272                               parse->rsnxe = pos;
1273                               parse->rsnxe_len = len;
1274                               break;
1275                     case WLAN_EID_MOBILITY_DOMAIN:
1276                               wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len);
1277                               if (len < sizeof(struct rsn_mdie))
1278                                         goto fail;
1279                               parse->mdie = pos;
1280                               parse->mdie_len = len;
1281                               break;
1282                     case WLAN_EID_FAST_BSS_TRANSITION:
1283                               wpa_hexdump(MSG_DEBUG, "FT: FTE", pos, len);
1284                               /* The first two octets (MIC Control field) is in the
1285                                * same offset for all cases, but the second field (MIC)
1286                                * has variable length with three different values.
1287                                * In particular the FT-SAE-EXT-KEY is inconvinient to
1288                                * parse, so try to handle this in pieces instead of
1289                                * using the struct rsn_ftie* definitions. */
1290 
1291                               if (len < 2)
1292                                         goto fail;
1293                               prot_ie_count = pos[1]; /* Element Count field in
1294                                                              * MIC Control */
1295                               is_fte = true;
1296                               fte = pos;
1297                               fte_len = len;
1298                               break;
1299                     case WLAN_EID_FRAGMENT:
1300                               if (is_fte) {
1301                                         wpa_hexdump(MSG_DEBUG, "FT: FTE fragment",
1302                                                       pos, len);
1303                                         fte_len += 2 + len;
1304                               }
1305                               break;
1306                     case WLAN_EID_TIMEOUT_INTERVAL:
1307                               wpa_hexdump(MSG_DEBUG, "FT: Timeout Interval",
1308                                             pos, len);
1309                               if (len != 5)
1310                                         break;
1311                               parse->tie = pos;
1312                               parse->tie_len = len;
1313                               break;
1314                     case WLAN_EID_RIC_DATA:
1315                               if (parse->ric == NULL)
1316                                         parse->ric = pos - 2;
1317                               break;
1318                     }
1319 
1320                     pos += len;
1321           }
1322 
1323           if (fte) {
1324                     int res;
1325 
1326                     if (fte_len < 255) {
1327                               res = wpa_ft_parse_fte(key_mgmt, fte, fte_len, parse);
1328                     } else {
1329                               parse->fte_buf = ieee802_11_defrag(fte, fte_len, false);
1330                               if (!parse->fte_buf)
1331                                         goto fail;
1332                               res = wpa_ft_parse_fte(key_mgmt,
1333                                                          wpabuf_head(parse->fte_buf),
1334                                                          wpabuf_len(parse->fte_buf),
1335                                                          parse);
1336                     }
1337                     if (res < 0)
1338                               goto fail;
1339 
1340                     /* FTE might be fragmented. If it is, the separate Fragment
1341                      * elements are included in MIC calculation as full elements. */
1342                     parse->ftie = fte;
1343                     parse->ftie_len = fte_len;
1344           }
1345 
1346           if (prot_ie_count == 0)
1347                     return 0; /* no MIC */
1348 
1349           /*
1350            * Check that the protected IE count matches with IEs included in the
1351            * frame.
1352            */
1353           if (reassoc_resp && elems.basic_mle) {
1354                     unsigned int link_id;
1355 
1356                     /* TODO: This count should be done based on all _requested_,
1357                      * not _accepted_ links. */
1358                     for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
1359                               if (parse->mlo_gtk[link_id]) {
1360                                         if (parse->rsn)
1361                                                   prot_ie_count--;
1362                                         if (parse->rsnxe)
1363                                                   prot_ie_count--;
1364                               }
1365                     }
1366           } else {
1367                     if (parse->rsn)
1368                               prot_ie_count--;
1369                     if (parse->rsnxe)
1370                               prot_ie_count--;
1371           }
1372           if (parse->mdie)
1373                     prot_ie_count--;
1374           if (parse->ftie)
1375                     prot_ie_count--;
1376           if (prot_ie_count < 0) {
1377                     wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
1378                                  "the protected IE count");
1379                     goto fail;
1380           }
1381 
1382           if (prot_ie_count == 0 && parse->ric) {
1383                     wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
1384                                  "included in protected IE count");
1385                     goto fail;
1386           }
1387 
1388           /* Determine the end of the RIC IE(s) */
1389           if (parse->ric) {
1390                     pos = parse->ric;
1391                     while (end - pos >= 2 && 2 + pos[1] <= end - pos &&
1392                            prot_ie_count) {
1393                               prot_ie_count--;
1394                               pos += 2 + pos[1];
1395                     }
1396                     parse->ric_len = pos - parse->ric;
1397           }
1398           if (prot_ie_count) {
1399                     wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
1400                                  "frame", (int) prot_ie_count);
1401                     goto fail;
1402           }
1403 
1404           return 0;
1405 
1406 fail:
1407           wpa_ft_parse_ies_free(parse);
1408           return -1;
1409 }
1410 
1411 
wpa_ft_parse_ies_free(struct wpa_ft_ies * parse)1412 void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse)
1413 {
1414           if (!parse)
1415                     return;
1416           wpabuf_free(parse->fte_buf);
1417           parse->fte_buf = NULL;
1418 }
1419 
1420 #endif /* CONFIG_IEEE80211R */
1421 
1422 
1423 #ifdef CONFIG_PASN
1424 
1425 /*
1426  * pasn_use_sha384 - Should SHA384 be used or SHA256
1427  *
1428  * @akmp: Authentication and key management protocol
1429  * @cipher: The cipher suite
1430  *
1431  * According to IEEE P802.11az/D2.7, 12.12.7, the hash algorithm to use is the
1432  * hash algorithm defined for the Base AKM (see Table 9-151 (AKM suite
1433  * selectors)). When there is no Base AKM, the hash algorithm is selected based
1434  * on the pairwise cipher suite provided in the RSNE by the AP in the second
1435  * PASN frame. SHA-256 is used as the hash algorithm, except for the ciphers
1436  * 00-0F-AC:9 and 00-0F-AC:10 for which SHA-384 is used.
1437  */
pasn_use_sha384(int akmp,int cipher)1438 bool pasn_use_sha384(int akmp, int cipher)
1439 {
1440           return (akmp == WPA_KEY_MGMT_PASN && (cipher == WPA_CIPHER_CCMP_256 ||
1441                                                         cipher == WPA_CIPHER_GCMP_256)) ||
1442                     wpa_key_mgmt_sha384(akmp);
1443 }
1444 
1445 
1446 /**
1447  * pasn_pmk_to_ptk - Calculate PASN PTK from PMK, addresses, etc.
1448  * @pmk: Pairwise master key
1449  * @pmk_len: Length of PMK
1450  * @spa: Suppplicant address
1451  * @bssid: AP BSSID
1452  * @dhss: Is the shared secret (DHss) derived from the PASN ephemeral key
1453  *        exchange encoded as an octet string
1454  * @dhss_len: The length of dhss in octets
1455  * @ptk: Buffer for pairwise transient key
1456  * @akmp: Negotiated AKM
1457  * @cipher: Negotiated pairwise cipher
1458  * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
1459  * Returns: 0 on success, -1 on failure
1460  */
pasn_pmk_to_ptk(const u8 * pmk,size_t pmk_len,const u8 * spa,const u8 * bssid,const u8 * dhss,size_t dhss_len,struct wpa_ptk * ptk,int akmp,int cipher,size_t kdk_len)1461 int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
1462                         const u8 *spa, const u8 *bssid,
1463                         const u8 *dhss, size_t dhss_len,
1464                         struct wpa_ptk *ptk, int akmp, int cipher,
1465                         size_t kdk_len)
1466 {
1467           u8 tmp[WPA_KCK_MAX_LEN + WPA_TK_MAX_LEN + WPA_KDK_MAX_LEN];
1468           u8 *data;
1469           size_t data_len, ptk_len;
1470           int ret = -1;
1471           const char *label = "PASN PTK Derivation";
1472 
1473           if (!pmk || !pmk_len) {
1474                     wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
1475                     return -1;
1476           }
1477 
1478           if (!dhss || !dhss_len) {
1479                     wpa_printf(MSG_ERROR, "PASN: No DHss set for PTK derivation");
1480                     return -1;
1481           }
1482 
1483           /*
1484            * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
1485            *
1486            * KCK = L(PASN-PTK, 0, 256)
1487            * TK = L(PASN-PTK, 256, TK_bits)
1488            * KDK = L(PASN-PTK, 256 + TK_bits, kdk_len * 8)
1489            */
1490           data_len = 2 * ETH_ALEN + dhss_len;
1491           data = os_zalloc(data_len);
1492           if (!data)
1493                     return -1;
1494 
1495           os_memcpy(data, spa, ETH_ALEN);
1496           os_memcpy(data + ETH_ALEN, bssid, ETH_ALEN);
1497           os_memcpy(data + 2 * ETH_ALEN, dhss, dhss_len);
1498 
1499           ptk->kck_len = WPA_PASN_KCK_LEN;
1500           ptk->tk_len = wpa_cipher_key_len(cipher);
1501           ptk->kdk_len = kdk_len;
1502           ptk->kek_len = 0;
1503           ptk->kek2_len = 0;
1504           ptk->kck2_len = 0;
1505 
1506           if (ptk->tk_len == 0) {
1507                     wpa_printf(MSG_ERROR,
1508                                  "PASN: Unsupported cipher (0x%x) used in PTK derivation",
1509                                  cipher);
1510                     goto err;
1511           }
1512 
1513           ptk_len = ptk->kck_len + ptk->tk_len + ptk->kdk_len;
1514           if (ptk_len > sizeof(tmp))
1515                     goto err;
1516 
1517           if (pasn_use_sha384(akmp, cipher)) {
1518                     wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA384");
1519 
1520                     if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp,
1521                                      ptk_len) < 0)
1522                               goto err;
1523           } else {
1524                     wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA256");
1525 
1526                     if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp,
1527                                      ptk_len) < 0)
1528                               goto err;
1529           }
1530 
1531           wpa_printf(MSG_DEBUG,
1532                        "PASN: PTK derivation: SPA=" MACSTR " BSSID=" MACSTR,
1533                        MAC2STR(spa), MAC2STR(bssid));
1534 
1535           wpa_hexdump_key(MSG_DEBUG, "PASN: DHss", dhss, dhss_len);
1536           wpa_hexdump_key(MSG_DEBUG, "PASN: PMK", pmk, pmk_len);
1537           wpa_hexdump_key(MSG_DEBUG, "PASN: PASN-PTK", tmp, ptk_len);
1538 
1539           os_memcpy(ptk->kck, tmp, WPA_PASN_KCK_LEN);
1540           wpa_hexdump_key(MSG_DEBUG, "PASN: KCK:", ptk->kck, WPA_PASN_KCK_LEN);
1541 
1542           os_memcpy(ptk->tk, tmp + WPA_PASN_KCK_LEN, ptk->tk_len);
1543           wpa_hexdump_key(MSG_DEBUG, "PASN: TK:", ptk->tk, ptk->tk_len);
1544 
1545           if (kdk_len) {
1546                     os_memcpy(ptk->kdk, tmp + WPA_PASN_KCK_LEN + ptk->tk_len,
1547                                 ptk->kdk_len);
1548                     wpa_hexdump_key(MSG_DEBUG, "PASN: KDK:",
1549                                         ptk->kdk, ptk->kdk_len);
1550           }
1551 
1552           forced_memzero(tmp, sizeof(tmp));
1553           ret = 0;
1554 err:
1555           bin_clear_free(data, data_len);
1556           return ret;
1557 }
1558 
1559 
1560 /*
1561  * pasn_mic_len - Returns the MIC length for PASN authentication
1562  */
pasn_mic_len(int akmp,int cipher)1563 u8 pasn_mic_len(int akmp, int cipher)
1564 {
1565           if (pasn_use_sha384(akmp, cipher))
1566                     return 24;
1567 
1568           return 16;
1569 }
1570 
1571 
1572 /**
1573  * wpa_ltf_keyseed - Compute LTF keyseed from KDK
1574  * @ptk: Buffer that holds pairwise transient key
1575  * @akmp: Negotiated AKM
1576  * @cipher: Negotiated pairwise cipher
1577  * Returns: 0 on success, -1 on failure
1578  */
wpa_ltf_keyseed(struct wpa_ptk * ptk,int akmp,int cipher)1579 int wpa_ltf_keyseed(struct wpa_ptk *ptk, int akmp, int cipher)
1580 {
1581           u8 *buf;
1582           size_t buf_len;
1583           u8 hash[SHA384_MAC_LEN];
1584           const u8 *kdk = ptk->kdk;
1585           size_t kdk_len = ptk->kdk_len;
1586           const char *label = "Secure LTF key seed";
1587 
1588           if (!kdk || !kdk_len) {
1589                     wpa_printf(MSG_ERROR, "WPA: No KDK for LTF keyseed generation");
1590                     return -1;
1591           }
1592 
1593           buf = (u8 *)label;
1594           buf_len = os_strlen(label);
1595 
1596           if (pasn_use_sha384(akmp, cipher)) {
1597                     wpa_printf(MSG_DEBUG,
1598                                  "WPA: Secure LTF keyseed using HMAC-SHA384");
1599 
1600                     if (hmac_sha384(kdk, kdk_len, buf, buf_len, hash)) {
1601                               wpa_printf(MSG_ERROR,
1602                                            "WPA: HMAC-SHA384 compute failed");
1603                               return -1;
1604                     }
1605                     os_memcpy(ptk->ltf_keyseed, hash, SHA384_MAC_LEN);
1606                     ptk->ltf_keyseed_len = SHA384_MAC_LEN;
1607                     wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
1608                                         ptk->ltf_keyseed, ptk->ltf_keyseed_len);
1609 
1610           } else {
1611                     wpa_printf(MSG_DEBUG, "WPA: LTF keyseed using HMAC-SHA256");
1612 
1613                     if (hmac_sha256(kdk, kdk_len, buf, buf_len, hash)) {
1614                               wpa_printf(MSG_ERROR,
1615                                            "WPA: HMAC-SHA256 compute failed");
1616                               return -1;
1617                     }
1618                     os_memcpy(ptk->ltf_keyseed, hash, SHA256_MAC_LEN);
1619                     ptk->ltf_keyseed_len = SHA256_MAC_LEN;
1620                     wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
1621                                         ptk->ltf_keyseed, ptk->ltf_keyseed_len);
1622           }
1623 
1624           return 0;
1625 }
1626 
1627 
1628 /**
1629  * pasn_mic - Calculate PASN MIC
1630  * @kck: The key confirmation key for the PASN PTKSA
1631  * @akmp: Negotiated AKM
1632  * @cipher: Negotiated pairwise cipher
1633  * @addr1: For the 2nd PASN frame supplicant address; for the 3rd frame the
1634  *        BSSID
1635  * @addr2: For the 2nd PASN frame the BSSID; for the 3rd frame the supplicant
1636  *        address
1637  * @data: For calculating the MIC for the 2nd PASN frame, this should hold the
1638  *        Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
1639  *        frame, this should hold the hash of the body of the PASN 1st frame.
1640  * @data_len: The length of data
1641  * @frame: The body of the PASN frame including the MIC element with the octets
1642  *        in the MIC field of the MIC element set to 0.
1643  * @frame_len: The length of frame
1644  * @mic: Buffer to hold the MIC on success. Should be big enough to handle the
1645  *        maximal MIC length
1646  * Returns: 0 on success, -1 on failure
1647  */
pasn_mic(const u8 * kck,int akmp,int cipher,const u8 * addr1,const u8 * addr2,const u8 * data,size_t data_len,const u8 * frame,size_t frame_len,u8 * mic)1648 int pasn_mic(const u8 *kck, int akmp, int cipher,
1649                const u8 *addr1, const u8 *addr2,
1650                const u8 *data, size_t data_len,
1651                const u8 *frame, size_t frame_len, u8 *mic)
1652 {
1653           u8 *buf;
1654           u8 hash[SHA384_MAC_LEN];
1655           size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
1656           int ret = -1;
1657 
1658           if (!kck) {
1659                     wpa_printf(MSG_ERROR, "PASN: No KCK for MIC calculation");
1660                     return -1;
1661           }
1662 
1663           if (!data || !data_len) {
1664                     wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
1665                     return -1;
1666           }
1667 
1668           if (!frame || !frame_len) {
1669                     wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
1670                     return -1;
1671           }
1672 
1673           buf = os_zalloc(buf_len);
1674           if (!buf)
1675                     return -1;
1676 
1677           os_memcpy(buf, addr1, ETH_ALEN);
1678           os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
1679 
1680           wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: data", data, data_len);
1681           os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
1682 
1683           wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: frame", frame, frame_len);
1684           os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
1685 
1686           wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: KCK", kck, WPA_PASN_KCK_LEN);
1687           wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: buf", buf, buf_len);
1688 
1689           if (pasn_use_sha384(akmp, cipher)) {
1690                     wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA384");
1691 
1692                     if (hmac_sha384(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
1693                               goto err;
1694 
1695                     os_memcpy(mic, hash, 24);
1696                     wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 24);
1697           } else {
1698                     wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA256");
1699 
1700                     if (hmac_sha256(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
1701                               goto err;
1702 
1703                     os_memcpy(mic, hash, 16);
1704                     wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 16);
1705           }
1706 
1707           ret = 0;
1708 err:
1709           bin_clear_free(buf, buf_len);
1710           return ret;
1711 }
1712 
1713 
1714 /**
1715  * pasn_auth_frame_hash - Computes a hash of an Authentication frame body
1716  * @akmp: Negotiated AKM
1717  * @cipher: Negotiated pairwise cipher
1718  * @data: Pointer to the Authentication frame body
1719  * @len: Length of the Authentication frame body
1720  * @hash: On return would hold the computed hash. Should be big enough to handle
1721  *        SHA384.
1722  * Returns: 0 on success, -1 on failure
1723  */
pasn_auth_frame_hash(int akmp,int cipher,const u8 * data,size_t len,u8 * hash)1724 int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
1725                                u8 *hash)
1726 {
1727           if (pasn_use_sha384(akmp, cipher)) {
1728                     wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-384");
1729                     return sha384_vector(1, &data, &len, hash);
1730           } else {
1731                     wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-256");
1732                     return sha256_vector(1, &data, &len, hash);
1733           }
1734 }
1735 
1736 #endif /* CONFIG_PASN */
1737 
1738 
rsn_selector_to_bitfield(const u8 * s)1739 static int rsn_selector_to_bitfield(const u8 *s)
1740 {
1741           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
1742                     return WPA_CIPHER_NONE;
1743           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
1744                     return WPA_CIPHER_TKIP;
1745           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
1746                     return WPA_CIPHER_CCMP;
1747           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
1748                     return WPA_CIPHER_AES_128_CMAC;
1749           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
1750                     return WPA_CIPHER_GCMP;
1751           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
1752                     return WPA_CIPHER_CCMP_256;
1753           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
1754                     return WPA_CIPHER_GCMP_256;
1755           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
1756                     return WPA_CIPHER_BIP_GMAC_128;
1757           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
1758                     return WPA_CIPHER_BIP_GMAC_256;
1759           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
1760                     return WPA_CIPHER_BIP_CMAC_256;
1761           if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
1762                     return WPA_CIPHER_GTK_NOT_USED;
1763           return 0;
1764 }
1765 
1766 
rsn_key_mgmt_to_bitfield(const u8 * s)1767 static int rsn_key_mgmt_to_bitfield(const u8 *s)
1768 {
1769           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
1770                     return WPA_KEY_MGMT_IEEE8021X;
1771           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
1772                     return WPA_KEY_MGMT_PSK;
1773 #ifdef CONFIG_IEEE80211R
1774           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
1775                     return WPA_KEY_MGMT_FT_IEEE8021X;
1776           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
1777                     return WPA_KEY_MGMT_FT_PSK;
1778 #ifdef CONFIG_SHA384
1779           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384)
1780                     return WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
1781 #endif /* CONFIG_SHA384 */
1782 #endif /* CONFIG_IEEE80211R */
1783 #ifdef CONFIG_SHA384
1784           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA384)
1785                     return WPA_KEY_MGMT_IEEE8021X_SHA384;
1786 #endif /* CONFIG_SHA384 */
1787           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
1788                     return WPA_KEY_MGMT_IEEE8021X_SHA256;
1789           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
1790                     return WPA_KEY_MGMT_PSK_SHA256;
1791 #ifdef CONFIG_SAE
1792           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
1793                     return WPA_KEY_MGMT_SAE;
1794           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
1795                     return WPA_KEY_MGMT_SAE_EXT_KEY;
1796           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
1797                     return WPA_KEY_MGMT_FT_SAE;
1798           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY)
1799                     return WPA_KEY_MGMT_FT_SAE_EXT_KEY;
1800 #endif /* CONFIG_SAE */
1801           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
1802                     return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1803           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
1804                     return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1805           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA256)
1806                     return WPA_KEY_MGMT_FILS_SHA256;
1807           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA384)
1808                     return WPA_KEY_MGMT_FILS_SHA384;
1809           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA256)
1810                     return WPA_KEY_MGMT_FT_FILS_SHA256;
1811           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA384)
1812                     return WPA_KEY_MGMT_FT_FILS_SHA384;
1813 #ifdef CONFIG_OWE
1814           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
1815                     return WPA_KEY_MGMT_OWE;
1816 #endif /* CONFIG_OWE */
1817 #ifdef CONFIG_DPP
1818           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_DPP)
1819                     return WPA_KEY_MGMT_DPP;
1820 #endif /* CONFIG_DPP */
1821           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
1822                     return WPA_KEY_MGMT_OSEN;
1823 #ifdef CONFIG_PASN
1824           if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PASN)
1825                     return WPA_KEY_MGMT_PASN;
1826 #endif /* CONFIG_PASN */
1827           return 0;
1828 }
1829 
1830 
wpa_cipher_valid_group(int cipher)1831 int wpa_cipher_valid_group(int cipher)
1832 {
1833           return wpa_cipher_valid_pairwise(cipher) ||
1834                     cipher == WPA_CIPHER_GTK_NOT_USED;
1835 }
1836 
1837 
wpa_cipher_valid_mgmt_group(int cipher)1838 int wpa_cipher_valid_mgmt_group(int cipher)
1839 {
1840           return cipher == WPA_CIPHER_GTK_NOT_USED ||
1841                     cipher == WPA_CIPHER_AES_128_CMAC ||
1842                     cipher == WPA_CIPHER_BIP_GMAC_128 ||
1843                     cipher == WPA_CIPHER_BIP_GMAC_256 ||
1844                     cipher == WPA_CIPHER_BIP_CMAC_256;
1845 }
1846 
1847 
1848 /**
1849  * wpa_parse_wpa_ie_rsn - Parse RSN IE
1850  * @rsn_ie: Buffer containing RSN IE
1851  * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
1852  * @data: Pointer to structure that will be filled in with parsed data
1853  * Returns: 0 on success, <0 on failure
1854  */
wpa_parse_wpa_ie_rsn(const u8 * rsn_ie,size_t rsn_ie_len,struct wpa_ie_data * data)1855 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
1856                                struct wpa_ie_data *data)
1857 {
1858           const u8 *pos;
1859           int left;
1860           int i, count;
1861 
1862           os_memset(data, 0, sizeof(*data));
1863           data->proto = WPA_PROTO_RSN;
1864           data->pairwise_cipher = WPA_CIPHER_CCMP;
1865           data->group_cipher = WPA_CIPHER_CCMP;
1866           data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1867           data->capabilities = 0;
1868           data->pmkid = NULL;
1869           data->num_pmkid = 0;
1870           data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1871 
1872           if (rsn_ie_len == 0) {
1873                     /* No RSN IE - fail silently */
1874                     return -1;
1875           }
1876 
1877           if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
1878                     wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
1879                                  __func__, (unsigned long) rsn_ie_len);
1880                     return -1;
1881           }
1882 
1883           if (rsn_ie_len >= 6 && rsn_ie[1] >= 4 &&
1884               rsn_ie[1] == rsn_ie_len - 2 &&
1885               WPA_GET_BE32(&rsn_ie[2]) == OSEN_IE_VENDOR_TYPE) {
1886                     pos = rsn_ie + 6;
1887                     left = rsn_ie_len - 6;
1888 
1889                     data->group_cipher = WPA_CIPHER_GTK_NOT_USED;
1890                     data->has_group = 1;
1891                     data->key_mgmt = WPA_KEY_MGMT_OSEN;
1892                     data->proto = WPA_PROTO_OSEN;
1893           } else {
1894                     const struct rsn_ie_hdr *hdr;
1895 
1896                     hdr = (const struct rsn_ie_hdr *) rsn_ie;
1897 
1898                     if (hdr->elem_id != WLAN_EID_RSN ||
1899                         hdr->len != rsn_ie_len - 2 ||
1900                         WPA_GET_LE16(hdr->version) != RSN_VERSION) {
1901                               wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
1902                                            __func__);
1903                               return -2;
1904                     }
1905 
1906                     pos = (const u8 *) (hdr + 1);
1907                     left = rsn_ie_len - sizeof(*hdr);
1908           }
1909 
1910           if (left >= RSN_SELECTOR_LEN) {
1911                     data->group_cipher = rsn_selector_to_bitfield(pos);
1912                     data->has_group = 1;
1913                     if (!wpa_cipher_valid_group(data->group_cipher)) {
1914                               wpa_printf(MSG_DEBUG,
1915                                            "%s: invalid group cipher 0x%x (%08x)",
1916                                            __func__, data->group_cipher,
1917                                            WPA_GET_BE32(pos));
1918 #ifdef CONFIG_NO_TKIP
1919                               if (RSN_SELECTOR_GET(pos) == RSN_CIPHER_SUITE_TKIP) {
1920                                         wpa_printf(MSG_DEBUG,
1921                                                      "%s: TKIP as group cipher not supported in CONFIG_NO_TKIP=y build",
1922                                                      __func__);
1923                               }
1924 #endif /* CONFIG_NO_TKIP */
1925                               return -1;
1926                     }
1927                     pos += RSN_SELECTOR_LEN;
1928                     left -= RSN_SELECTOR_LEN;
1929           } else if (left > 0) {
1930                     wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
1931                                  __func__, left);
1932                     return -3;
1933           }
1934 
1935           if (left >= 2) {
1936                     data->pairwise_cipher = 0;
1937                     count = WPA_GET_LE16(pos);
1938                     pos += 2;
1939                     left -= 2;
1940                     if (count == 0 || count > left / RSN_SELECTOR_LEN) {
1941                               wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
1942                                            "count %u left %u", __func__, count, left);
1943                               return -4;
1944                     }
1945                     if (count)
1946                               data->has_pairwise = 1;
1947                     for (i = 0; i < count; i++) {
1948                               data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
1949                               pos += RSN_SELECTOR_LEN;
1950                               left -= RSN_SELECTOR_LEN;
1951                     }
1952                     if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
1953                               wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
1954                                            "pairwise cipher", __func__);
1955                               return -1;
1956                     }
1957           } else if (left == 1) {
1958                     wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
1959                                  __func__);
1960                     return -5;
1961           }
1962 
1963           if (left >= 2) {
1964                     data->key_mgmt = 0;
1965                     count = WPA_GET_LE16(pos);
1966                     pos += 2;
1967                     left -= 2;
1968                     if (count == 0 || count > left / RSN_SELECTOR_LEN) {
1969                               wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
1970                                            "count %u left %u", __func__, count, left);
1971                               return -6;
1972                     }
1973                     for (i = 0; i < count; i++) {
1974                               data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
1975                               pos += RSN_SELECTOR_LEN;
1976                               left -= RSN_SELECTOR_LEN;
1977                     }
1978           } else if (left == 1) {
1979                     wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
1980                                  __func__);
1981                     return -7;
1982           }
1983 
1984           if (left >= 2) {
1985                     data->capabilities = WPA_GET_LE16(pos);
1986                     pos += 2;
1987                     left -= 2;
1988           }
1989 
1990           if (left >= 2) {
1991                     u16 num_pmkid = WPA_GET_LE16(pos);
1992                     pos += 2;
1993                     left -= 2;
1994                     if (num_pmkid > (unsigned int) left / PMKID_LEN) {
1995                               wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
1996                                            "(num_pmkid=%u left=%d)",
1997                                            __func__, num_pmkid, left);
1998                               data->num_pmkid = 0;
1999                               return -9;
2000                     } else {
2001                               data->num_pmkid = num_pmkid;
2002                               data->pmkid = pos;
2003                               pos += data->num_pmkid * PMKID_LEN;
2004                               left -= data->num_pmkid * PMKID_LEN;
2005                     }
2006           }
2007 
2008           if (left >= 4) {
2009                     data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
2010                     if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
2011                               wpa_printf(MSG_DEBUG,
2012                                            "%s: Unsupported management group cipher 0x%x (%08x)",
2013                                            __func__, data->mgmt_group_cipher,
2014                                            WPA_GET_BE32(pos));
2015                               return -10;
2016                     }
2017                     pos += RSN_SELECTOR_LEN;
2018                     left -= RSN_SELECTOR_LEN;
2019           }
2020 
2021           if (left > 0) {
2022                     wpa_hexdump(MSG_DEBUG,
2023                                   "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
2024                                   pos, left);
2025           }
2026 
2027           return 0;
2028 }
2029 
2030 
wpa_selector_to_bitfield(const u8 * s)2031 static int wpa_selector_to_bitfield(const u8 *s)
2032 {
2033           if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
2034                     return WPA_CIPHER_NONE;
2035           if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
2036                     return WPA_CIPHER_TKIP;
2037           if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
2038                     return WPA_CIPHER_CCMP;
2039           return 0;
2040 }
2041 
2042 
wpa_key_mgmt_to_bitfield(const u8 * s)2043 static int wpa_key_mgmt_to_bitfield(const u8 *s)
2044 {
2045           if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
2046                     return WPA_KEY_MGMT_IEEE8021X;
2047           if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
2048                     return WPA_KEY_MGMT_PSK;
2049           if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
2050                     return WPA_KEY_MGMT_WPA_NONE;
2051           return 0;
2052 }
2053 
2054 
wpa_parse_wpa_ie_wpa(const u8 * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)2055 int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
2056                                struct wpa_ie_data *data)
2057 {
2058           const struct wpa_ie_hdr *hdr;
2059           const u8 *pos;
2060           int left;
2061           int i, count;
2062 
2063           os_memset(data, 0, sizeof(*data));
2064           data->proto = WPA_PROTO_WPA;
2065           data->pairwise_cipher = WPA_CIPHER_TKIP;
2066           data->group_cipher = WPA_CIPHER_TKIP;
2067           data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
2068           data->capabilities = 0;
2069           data->pmkid = NULL;
2070           data->num_pmkid = 0;
2071           data->mgmt_group_cipher = 0;
2072 
2073           if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
2074                     wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
2075                                  __func__, (unsigned long) wpa_ie_len);
2076                     return -1;
2077           }
2078 
2079           hdr = (const struct wpa_ie_hdr *) wpa_ie;
2080 
2081           if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
2082               hdr->len != wpa_ie_len - 2 ||
2083               RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
2084               WPA_GET_LE16(hdr->version) != WPA_VERSION) {
2085                     wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
2086                                  __func__);
2087                     return -2;
2088           }
2089 
2090           pos = (const u8 *) (hdr + 1);
2091           left = wpa_ie_len - sizeof(*hdr);
2092 
2093           if (left >= WPA_SELECTOR_LEN) {
2094                     data->group_cipher = wpa_selector_to_bitfield(pos);
2095                     pos += WPA_SELECTOR_LEN;
2096                     left -= WPA_SELECTOR_LEN;
2097           } else if (left > 0) {
2098                     wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
2099                                  __func__, left);
2100                     return -3;
2101           }
2102 
2103           if (left >= 2) {
2104                     data->pairwise_cipher = 0;
2105                     count = WPA_GET_LE16(pos);
2106                     pos += 2;
2107                     left -= 2;
2108                     if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2109                               wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
2110                                            "count %u left %u", __func__, count, left);
2111                               return -4;
2112                     }
2113                     for (i = 0; i < count; i++) {
2114                               data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
2115                               pos += WPA_SELECTOR_LEN;
2116                               left -= WPA_SELECTOR_LEN;
2117                     }
2118           } else if (left == 1) {
2119                     wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
2120                                  __func__);
2121                     return -5;
2122           }
2123 
2124           if (left >= 2) {
2125                     data->key_mgmt = 0;
2126                     count = WPA_GET_LE16(pos);
2127                     pos += 2;
2128                     left -= 2;
2129                     if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2130                               wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
2131                                            "count %u left %u", __func__, count, left);
2132                               return -6;
2133                     }
2134                     for (i = 0; i < count; i++) {
2135                               data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
2136                               pos += WPA_SELECTOR_LEN;
2137                               left -= WPA_SELECTOR_LEN;
2138                     }
2139           } else if (left == 1) {
2140                     wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
2141                                  __func__);
2142                     return -7;
2143           }
2144 
2145           if (left >= 2) {
2146                     data->capabilities = WPA_GET_LE16(pos);
2147                     pos += 2;
2148                     left -= 2;
2149           }
2150 
2151           if (left > 0) {
2152                     wpa_hexdump(MSG_DEBUG,
2153                                   "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
2154                                   pos, left);
2155           }
2156 
2157           return 0;
2158 }
2159 
2160 
wpa_default_rsn_cipher(int freq)2161 int wpa_default_rsn_cipher(int freq)
2162 {
2163           if (freq > 56160)
2164                     return WPA_CIPHER_GCMP; /* DMG */
2165 
2166           return WPA_CIPHER_CCMP;
2167 }
2168 
2169 
2170 #ifdef CONFIG_IEEE80211R
2171 
2172 /**
2173  * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
2174  *
2175  * IEEE Std 802.11r-2008 - 8.5.1.5.3
2176  */
wpa_derive_pmk_r0(const u8 * xxkey,size_t xxkey_len,const u8 * ssid,size_t ssid_len,const u8 * mdid,const u8 * r0kh_id,size_t r0kh_id_len,const u8 * s0kh_id,u8 * pmk_r0,u8 * pmk_r0_name,int key_mgmt)2177 int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
2178                           const u8 *ssid, size_t ssid_len,
2179                           const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
2180                           const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name,
2181                           int key_mgmt)
2182 {
2183           u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
2184                  FT_R0KH_ID_MAX_LEN + ETH_ALEN];
2185           u8 *pos, r0_key_data[64 + 16], hash[64];
2186           const u8 *addr[2];
2187           size_t len[2];
2188           size_t q, r0_key_data_len;
2189           int res;
2190 
2191           if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
2192               (xxkey_len == SHA256_MAC_LEN || xxkey_len == SHA384_MAC_LEN ||
2193                xxkey_len == SHA512_MAC_LEN))
2194                     q = xxkey_len;
2195           else if (wpa_key_mgmt_sha384(key_mgmt))
2196                     q = SHA384_MAC_LEN;
2197           else
2198                     q = SHA256_MAC_LEN;
2199           r0_key_data_len = q + 16;
2200 
2201           /*
2202            * R0-Key-Data = KDF-Hash-Length(XXKey, "FT-R0",
2203            *                       SSIDlength || SSID || MDID || R0KHlength ||
2204            *                       R0KH-ID || S0KH-ID)
2205            * XXKey is either the second 256 bits of MSK or PSK; or the first
2206            * 384 bits of MSK for FT-EAP-SHA384; or PMK from SAE.
2207            * PMK-R0 = L(R0-Key-Data, 0, Q)
2208            * PMK-R0Name-Salt = L(R0-Key-Data, Q, 128)
2209            * Q = 384 for FT-EAP-SHA384; the length of the digest generated by H()
2210            * for FT-SAE-EXT-KEY; or otherwise, 256
2211            */
2212           if (ssid_len > SSID_MAX_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
2213                     return -1;
2214           wpa_printf(MSG_DEBUG, "FT: Derive PMK-R0 using KDF-SHA%zu", q * 8);
2215           wpa_hexdump_key(MSG_DEBUG, "FT: XXKey", xxkey, xxkey_len);
2216           wpa_hexdump_ascii(MSG_DEBUG, "FT: SSID", ssid, ssid_len);
2217           wpa_hexdump(MSG_DEBUG, "FT: MDID", mdid, MOBILITY_DOMAIN_ID_LEN);
2218           wpa_hexdump_ascii(MSG_DEBUG, "FT: R0KH-ID", r0kh_id, r0kh_id_len);
2219           wpa_printf(MSG_DEBUG, "FT: S0KH-ID: " MACSTR, MAC2STR(s0kh_id));
2220           pos = buf;
2221           *pos++ = ssid_len;
2222           os_memcpy(pos, ssid, ssid_len);
2223           pos += ssid_len;
2224           os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
2225           pos += MOBILITY_DOMAIN_ID_LEN;
2226           *pos++ = r0kh_id_len;
2227           os_memcpy(pos, r0kh_id, r0kh_id_len);
2228           pos += r0kh_id_len;
2229           os_memcpy(pos, s0kh_id, ETH_ALEN);
2230           pos += ETH_ALEN;
2231 
2232           res = -1;
2233 #ifdef CONFIG_SHA512
2234           if (q == SHA512_MAC_LEN) {
2235                     if (xxkey_len != SHA512_MAC_LEN) {
2236                               wpa_printf(MSG_ERROR,
2237                                            "FT: Unexpected XXKey length %d (expected %d)",
2238                                            (int) xxkey_len, SHA512_MAC_LEN);
2239                               return -1;
2240                     }
2241                     res = sha512_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2242                                          r0_key_data, r0_key_data_len);
2243           }
2244 #endif /* CONFIG_SHA512 */
2245 #ifdef CONFIG_SHA384
2246           if (q == SHA384_MAC_LEN) {
2247                     if (xxkey_len != SHA384_MAC_LEN) {
2248                               wpa_printf(MSG_ERROR,
2249                                            "FT: Unexpected XXKey length %d (expected %d)",
2250                                            (int) xxkey_len, SHA384_MAC_LEN);
2251                               return -1;
2252                     }
2253                     res = sha384_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2254                                          r0_key_data, r0_key_data_len);
2255           }
2256 #endif /* CONFIG_SHA384 */
2257           if (q == SHA256_MAC_LEN) {
2258                     if (xxkey_len != PMK_LEN) {
2259                               wpa_printf(MSG_ERROR,
2260                                            "FT: Unexpected XXKey length %d (expected %d)",
2261                                            (int) xxkey_len, PMK_LEN);
2262                               return -1;
2263                     }
2264                     res = sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2265                                          r0_key_data, r0_key_data_len);
2266           }
2267           if (res < 0)
2268                     return res;
2269           os_memcpy(pmk_r0, r0_key_data, q);
2270           wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, q);
2271           wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0Name-Salt", &r0_key_data[q], 16);
2272 
2273           /*
2274            * PMKR0Name = Truncate-128(Hash("FT-R0N" || PMK-R0Name-Salt)
2275            */
2276           addr[0] = (const u8 *) "FT-R0N";
2277           len[0] = 6;
2278           addr[1] = &r0_key_data[q];
2279           len[1] = 16;
2280 
2281           res = -1;
2282 #ifdef CONFIG_SHA512
2283           if (q == SHA512_MAC_LEN)
2284                     res = sha512_vector(2, addr, len, hash);
2285 #endif /* CONFIG_SHA512 */
2286 #ifdef CONFIG_SHA384
2287           if (q == SHA384_MAC_LEN)
2288                     res = sha384_vector(2, addr, len, hash);
2289 #endif /* CONFIG_SHA384 */
2290           if (q == SHA256_MAC_LEN)
2291                     res = sha256_vector(2, addr, len, hash);
2292           if (res < 0) {
2293                     wpa_printf(MSG_DEBUG,
2294                                  "FT: Failed to derive PMKR0Name (PMK-R0 len %zu)",
2295                                  q);
2296                     return res;
2297           }
2298           os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
2299           wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
2300           forced_memzero(r0_key_data, sizeof(r0_key_data));
2301           return 0;
2302 }
2303 
2304 
2305 /**
2306  * wpa_derive_pmk_r1_name - Derive PMKR1Name
2307  *
2308  * IEEE Std 802.11r-2008 - 8.5.1.5.4
2309  */
wpa_derive_pmk_r1_name(const u8 * pmk_r0_name,const u8 * r1kh_id,const u8 * s1kh_id,u8 * pmk_r1_name,size_t pmk_r1_len)2310 int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
2311                                  const u8 *s1kh_id, u8 *pmk_r1_name,
2312                                  size_t pmk_r1_len)
2313 {
2314           u8 hash[64];
2315           const u8 *addr[4];
2316           size_t len[4];
2317           int res;
2318           const char *title;
2319 
2320           /*
2321            * PMKR1Name = Truncate-128(Hash("FT-R1N" || PMKR0Name ||
2322            *                               R1KH-ID || S1KH-ID))
2323            */
2324           addr[0] = (const u8 *) "FT-R1N";
2325           len[0] = 6;
2326           addr[1] = pmk_r0_name;
2327           len[1] = WPA_PMK_NAME_LEN;
2328           addr[2] = r1kh_id;
2329           len[2] = FT_R1KH_ID_LEN;
2330           addr[3] = s1kh_id;
2331           len[3] = ETH_ALEN;
2332 
2333           res = -1;
2334 #ifdef CONFIG_SHA512
2335           if (pmk_r1_len == SHA512_MAC_LEN) {
2336                     title = "FT: PMKR1Name (using SHA512)";
2337                     res = sha512_vector(4, addr, len, hash);
2338           }
2339 #endif /* CONFIG_SHA512 */
2340 #ifdef CONFIG_SHA384
2341           if (pmk_r1_len == SHA384_MAC_LEN) {
2342                     title = "FT: PMKR1Name (using SHA384)";
2343                     res = sha384_vector(4, addr, len, hash);
2344           }
2345 #endif /* CONFIG_SHA384 */
2346           if (pmk_r1_len == SHA256_MAC_LEN) {
2347                     title = "FT: PMKR1Name (using SHA256)";
2348                     res = sha256_vector(4, addr, len, hash);
2349           }
2350           if (res < 0) {
2351                     wpa_printf(MSG_DEBUG,
2352                                  "FT: Failed to derive PMKR1Name (PMK-R1 len %zu)",
2353                                  pmk_r1_len);
2354                     return res;
2355           }
2356           os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
2357           wpa_hexdump(MSG_DEBUG, title, pmk_r1_name, WPA_PMK_NAME_LEN);
2358           return 0;
2359 }
2360 
2361 
2362 /**
2363  * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
2364  *
2365  * IEEE Std 802.11r-2008 - 8.5.1.5.4
2366  */
wpa_derive_pmk_r1(const u8 * pmk_r0,size_t pmk_r0_len,const u8 * pmk_r0_name,const u8 * r1kh_id,const u8 * s1kh_id,u8 * pmk_r1,u8 * pmk_r1_name)2367 int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
2368                           const u8 *pmk_r0_name,
2369                           const u8 *r1kh_id, const u8 *s1kh_id,
2370                           u8 *pmk_r1, u8 *pmk_r1_name)
2371 {
2372           u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
2373           u8 *pos;
2374           int res;
2375 
2376           /* PMK-R1 = KDF-Hash(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
2377           wpa_printf(MSG_DEBUG, "FT: Derive PMK-R1 using KDF-SHA%zu",
2378                        pmk_r0_len * 8);
2379           wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len);
2380           wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", r1kh_id, FT_R1KH_ID_LEN);
2381           wpa_printf(MSG_DEBUG, "FT: S1KH-ID: " MACSTR, MAC2STR(s1kh_id));
2382           pos = buf;
2383           os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
2384           pos += FT_R1KH_ID_LEN;
2385           os_memcpy(pos, s1kh_id, ETH_ALEN);
2386           pos += ETH_ALEN;
2387 
2388           res = -1;
2389 #ifdef CONFIG_SHA512
2390           if (pmk_r0_len == SHA512_MAC_LEN)
2391                     res = sha512_prf(pmk_r0, pmk_r0_len, "FT-R1",
2392                                          buf, pos - buf, pmk_r1, pmk_r0_len);
2393 #endif /* CONFIG_SHA512 */
2394 #ifdef CONFIG_SHA384
2395           if (pmk_r0_len == SHA384_MAC_LEN)
2396                     res = sha384_prf(pmk_r0, pmk_r0_len, "FT-R1",
2397                                          buf, pos - buf, pmk_r1, pmk_r0_len);
2398 #endif /* CONFIG_SHA384 */
2399           if (pmk_r0_len == SHA256_MAC_LEN)
2400                     res = sha256_prf(pmk_r0, pmk_r0_len, "FT-R1",
2401                                          buf, pos - buf, pmk_r1, pmk_r0_len);
2402           if (res < 0) {
2403                     wpa_printf(MSG_ERROR, "FT: Failed to derive PMK-R1");
2404                     return res;
2405           }
2406           wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len);
2407 
2408           return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
2409                                               pmk_r1_name, pmk_r0_len);
2410 }
2411 
2412 
2413 /**
2414  * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
2415  *
2416  * IEEE Std 802.11r-2008 - 8.5.1.5.5
2417  */
wpa_pmk_r1_to_ptk(const u8 * pmk_r1,size_t pmk_r1_len,const u8 * snonce,const u8 * anonce,const u8 * sta_addr,const u8 * bssid,const u8 * pmk_r1_name,struct wpa_ptk * ptk,u8 * ptk_name,int akmp,int cipher,size_t kdk_len)2418 int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
2419                           const u8 *snonce, const u8 *anonce,
2420                           const u8 *sta_addr, const u8 *bssid,
2421                           const u8 *pmk_r1_name,
2422                           struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
2423                           size_t kdk_len)
2424 {
2425           u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
2426           u8 *pos, hash[32];
2427           const u8 *addr[6];
2428           size_t len[6];
2429           u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
2430                  WPA_KDK_MAX_LEN];
2431           size_t ptk_len, offset;
2432           size_t key_len;
2433           int res;
2434 
2435           if (kdk_len > WPA_KDK_MAX_LEN) {
2436                     wpa_printf(MSG_ERROR,
2437                                  "FT: KDK len=%zu exceeds max supported len",
2438                                  kdk_len);
2439                     return -1;
2440           }
2441 
2442           if (akmp == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
2443               (pmk_r1_len == SHA256_MAC_LEN || pmk_r1_len == SHA384_MAC_LEN ||
2444                pmk_r1_len == SHA512_MAC_LEN))
2445                     key_len = pmk_r1_len;
2446           else if (wpa_key_mgmt_sha384(akmp))
2447                     key_len = SHA384_MAC_LEN;
2448           else
2449                     key_len = SHA256_MAC_LEN;
2450 
2451           /*
2452            * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
2453            *                  BSSID || STA-ADDR)
2454            */
2455           wpa_printf(MSG_DEBUG, "FT: Derive PTK using KDF-SHA%zu", key_len * 8);
2456           wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len);
2457           wpa_hexdump(MSG_DEBUG, "FT: SNonce", snonce, WPA_NONCE_LEN);
2458           wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
2459           wpa_printf(MSG_DEBUG, "FT: BSSID=" MACSTR " STA-ADDR=" MACSTR,
2460                        MAC2STR(bssid), MAC2STR(sta_addr));
2461           pos = buf;
2462           os_memcpy(pos, snonce, WPA_NONCE_LEN);
2463           pos += WPA_NONCE_LEN;
2464           os_memcpy(pos, anonce, WPA_NONCE_LEN);
2465           pos += WPA_NONCE_LEN;
2466           os_memcpy(pos, bssid, ETH_ALEN);
2467           pos += ETH_ALEN;
2468           os_memcpy(pos, sta_addr, ETH_ALEN);
2469           pos += ETH_ALEN;
2470 
2471           ptk->kck_len = wpa_kck_len(akmp, key_len);
2472           ptk->kck2_len = wpa_kck2_len(akmp);
2473           ptk->kek_len = wpa_kek_len(akmp, key_len);
2474           ptk->kek2_len = wpa_kek2_len(akmp);
2475           ptk->tk_len = wpa_cipher_key_len(cipher);
2476           ptk->kdk_len = kdk_len;
2477           ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
2478                     ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
2479 
2480           res = -1;
2481 #ifdef CONFIG_SHA512
2482           if (key_len == SHA512_MAC_LEN) {
2483                     if (pmk_r1_len != SHA512_MAC_LEN) {
2484                               wpa_printf(MSG_ERROR,
2485                                            "FT: Unexpected PMK-R1 length %d (expected %d)",
2486                                            (int) pmk_r1_len, SHA512_MAC_LEN);
2487                               return -1;
2488                     }
2489                     res = sha512_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2490                                          buf, pos - buf, tmp, ptk_len);
2491           }
2492 #endif /* CONFIG_SHA512 */
2493 #ifdef CONFIG_SHA384
2494           if (key_len == SHA384_MAC_LEN) {
2495                     if (pmk_r1_len != SHA384_MAC_LEN) {
2496                               wpa_printf(MSG_ERROR,
2497                                            "FT: Unexpected PMK-R1 length %d (expected %d)",
2498                                            (int) pmk_r1_len, SHA384_MAC_LEN);
2499                               return -1;
2500                     }
2501                     res = sha384_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2502                                          buf, pos - buf, tmp, ptk_len);
2503           }
2504 #endif /* CONFIG_SHA384 */
2505           if (key_len == SHA256_MAC_LEN) {
2506                     if (pmk_r1_len != PMK_LEN) {
2507                               wpa_printf(MSG_ERROR,
2508                                            "FT: Unexpected PMK-R1 length %d (expected %d)",
2509                                            (int) pmk_r1_len, PMK_LEN);
2510                               return -1;
2511                     }
2512                     res = sha256_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2513                                          buf, pos - buf, tmp, ptk_len);
2514           }
2515           if (res < 0)
2516                     return -1;
2517           wpa_hexdump_key(MSG_DEBUG, "FT: PTK", tmp, ptk_len);
2518 
2519           /*
2520            * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
2521            *                                ANonce || BSSID || STA-ADDR))
2522            */
2523           wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
2524           addr[0] = pmk_r1_name;
2525           len[0] = WPA_PMK_NAME_LEN;
2526           addr[1] = (const u8 *) "FT-PTKN";
2527           len[1] = 7;
2528           addr[2] = snonce;
2529           len[2] = WPA_NONCE_LEN;
2530           addr[3] = anonce;
2531           len[3] = WPA_NONCE_LEN;
2532           addr[4] = bssid;
2533           len[4] = ETH_ALEN;
2534           addr[5] = sta_addr;
2535           len[5] = ETH_ALEN;
2536 
2537           if (sha256_vector(6, addr, len, hash) < 0)
2538                     return -1;
2539           os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
2540 
2541           os_memcpy(ptk->kck, tmp, ptk->kck_len);
2542           offset = ptk->kck_len;
2543           os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
2544           offset += ptk->kek_len;
2545           os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
2546           offset += ptk->tk_len;
2547           os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
2548           offset += ptk->kck2_len;
2549           os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
2550           offset += ptk->kek2_len;
2551           os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
2552 
2553           wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
2554           wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
2555           if (ptk->kck2_len)
2556                     wpa_hexdump_key(MSG_DEBUG, "FT: KCK2",
2557                                         ptk->kck2, ptk->kck2_len);
2558           if (ptk->kek2_len)
2559                     wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
2560                                         ptk->kek2, ptk->kek2_len);
2561           if (ptk->kdk_len)
2562                     wpa_hexdump_key(MSG_DEBUG, "FT: KDK", ptk->kdk, ptk->kdk_len);
2563 
2564           wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
2565           wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
2566 
2567           forced_memzero(tmp, sizeof(tmp));
2568 
2569           return 0;
2570 }
2571 
2572 #endif /* CONFIG_IEEE80211R */
2573 
2574 
2575 /**
2576  * rsn_pmkid - Calculate PMK identifier
2577  * @pmk: Pairwise master key
2578  * @pmk_len: Length of pmk in bytes
2579  * @aa: Authenticator address
2580  * @spa: Supplicant address
2581  * @pmkid: Buffer for PMKID
2582  * @akmp: Negotiated key management protocol
2583  *
2584  * IEEE Std 802.11-2016 - 12.7.1.3 Pairwise key hierarchy
2585  * AKM: 00-0F-AC:3, 00-0F-AC:5, 00-0F-AC:6, 00-0F-AC:14, 00-0F-AC:16
2586  * PMKID = Truncate-128(HMAC-SHA-256(PMK, "PMK Name" || AA || SPA))
2587  * AKM: 00-0F-AC:11
2588  * See rsn_pmkid_suite_b()
2589  * AKM: 00-0F-AC:12
2590  * See rsn_pmkid_suite_b_192()
2591  * AKM: 00-0F-AC:13, 00-0F-AC:15, 00-0F-AC:17
2592  * PMKID = Truncate-128(HMAC-SHA-384(PMK, "PMK Name" || AA || SPA))
2593  * Otherwise:
2594  * PMKID = Truncate-128(HMAC-SHA-1(PMK, "PMK Name" || AA || SPA))
2595  */
rsn_pmkid(const u8 * pmk,size_t pmk_len,const u8 * aa,const u8 * spa,u8 * pmkid,int akmp)2596 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
2597                  u8 *pmkid, int akmp)
2598 {
2599           char *title = "PMK Name";
2600           const u8 *addr[3];
2601           const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2602           unsigned char hash[SHA384_MAC_LEN];
2603 
2604           addr[0] = (u8 *) title;
2605           addr[1] = aa;
2606           addr[2] = spa;
2607 
2608           if (0) {
2609 #if defined(CONFIG_FILS) || defined(CONFIG_SHA384)
2610           } else if (wpa_key_mgmt_sha384(akmp)) {
2611                     wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-384");
2612                     hmac_sha384_vector(pmk, pmk_len, 3, addr, len, hash);
2613 #endif /* CONFIG_FILS || CONFIG_SHA384 */
2614           } else if (wpa_key_mgmt_sha256(akmp)) {
2615                     wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-256");
2616                     hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
2617           } else {
2618                     wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-1");
2619                     hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
2620           }
2621           wpa_hexdump(MSG_DEBUG, "RSN: Derived PMKID", hash, PMKID_LEN);
2622           os_memcpy(pmkid, hash, PMKID_LEN);
2623 }
2624 
2625 
2626 #ifdef CONFIG_SUITEB
2627 /**
2628  * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
2629  * @kck: Key confirmation key
2630  * @kck_len: Length of kck in bytes
2631  * @aa: Authenticator address
2632  * @spa: Supplicant address
2633  * @pmkid: Buffer for PMKID
2634  * Returns: 0 on success, -1 on failure
2635  *
2636  * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
2637  * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
2638  */
rsn_pmkid_suite_b(const u8 * kck,size_t kck_len,const u8 * aa,const u8 * spa,u8 * pmkid)2639 int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
2640                           const u8 *spa, u8 *pmkid)
2641 {
2642           char *title = "PMK Name";
2643           const u8 *addr[3];
2644           const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2645           unsigned char hash[SHA256_MAC_LEN];
2646 
2647           addr[0] = (u8 *) title;
2648           addr[1] = aa;
2649           addr[2] = spa;
2650 
2651           if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
2652                     return -1;
2653           os_memcpy(pmkid, hash, PMKID_LEN);
2654           return 0;
2655 }
2656 #endif /* CONFIG_SUITEB */
2657 
2658 
2659 #ifdef CONFIG_SUITEB192
2660 /**
2661  * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
2662  * @kck: Key confirmation key
2663  * @kck_len: Length of kck in bytes
2664  * @aa: Authenticator address
2665  * @spa: Supplicant address
2666  * @pmkid: Buffer for PMKID
2667  * Returns: 0 on success, -1 on failure
2668  *
2669  * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
2670  * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
2671  */
rsn_pmkid_suite_b_192(const u8 * kck,size_t kck_len,const u8 * aa,const u8 * spa,u8 * pmkid)2672 int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
2673                                 const u8 *spa, u8 *pmkid)
2674 {
2675           char *title = "PMK Name";
2676           const u8 *addr[3];
2677           const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2678           unsigned char hash[SHA384_MAC_LEN];
2679 
2680           addr[0] = (u8 *) title;
2681           addr[1] = aa;
2682           addr[2] = spa;
2683 
2684           if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
2685                     return -1;
2686           os_memcpy(pmkid, hash, PMKID_LEN);
2687           return 0;
2688 }
2689 #endif /* CONFIG_SUITEB192 */
2690 
2691 
2692 /**
2693  * wpa_cipher_txt - Convert cipher suite to a text string
2694  * @cipher: Cipher suite (WPA_CIPHER_* enum)
2695  * Returns: Pointer to a text string of the cipher suite name
2696  */
wpa_cipher_txt(int cipher)2697 const char * wpa_cipher_txt(int cipher)
2698 {
2699           switch (cipher) {
2700           case WPA_CIPHER_NONE:
2701                     return "NONE";
2702 #ifdef CONFIG_WEP
2703           case WPA_CIPHER_WEP40:
2704                     return "WEP-40";
2705           case WPA_CIPHER_WEP104:
2706                     return "WEP-104";
2707 #endif /* CONFIG_WEP */
2708           case WPA_CIPHER_TKIP:
2709                     return "TKIP";
2710           case WPA_CIPHER_CCMP:
2711                     return "CCMP";
2712           case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
2713                     return "CCMP+TKIP";
2714           case WPA_CIPHER_GCMP:
2715                     return "GCMP";
2716           case WPA_CIPHER_GCMP_256:
2717                     return "GCMP-256";
2718           case WPA_CIPHER_CCMP_256:
2719                     return "CCMP-256";
2720           case WPA_CIPHER_AES_128_CMAC:
2721                     return "BIP";
2722           case WPA_CIPHER_BIP_GMAC_128:
2723                     return "BIP-GMAC-128";
2724           case WPA_CIPHER_BIP_GMAC_256:
2725                     return "BIP-GMAC-256";
2726           case WPA_CIPHER_BIP_CMAC_256:
2727                     return "BIP-CMAC-256";
2728           case WPA_CIPHER_GTK_NOT_USED:
2729                     return "GTK_NOT_USED";
2730           default:
2731                     return "UNKNOWN";
2732           }
2733 }
2734 
2735 
2736 /**
2737  * wpa_key_mgmt_txt - Convert key management suite to a text string
2738  * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
2739  * @proto: WPA/WPA2 version (WPA_PROTO_*)
2740  * Returns: Pointer to a text string of the key management suite name
2741  */
wpa_key_mgmt_txt(int key_mgmt,int proto)2742 const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
2743 {
2744           switch (key_mgmt) {
2745           case WPA_KEY_MGMT_IEEE8021X:
2746                     if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
2747                               return "WPA2+WPA/IEEE 802.1X/EAP";
2748                     return proto == WPA_PROTO_RSN ?
2749                               "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
2750           case WPA_KEY_MGMT_PSK:
2751                     if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
2752                               return "WPA2-PSK+WPA-PSK";
2753                     return proto == WPA_PROTO_RSN ?
2754                               "WPA2-PSK" : "WPA-PSK";
2755           case WPA_KEY_MGMT_NONE:
2756                     return "NONE";
2757           case WPA_KEY_MGMT_WPA_NONE:
2758                     return "WPA-NONE";
2759           case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
2760                     return "IEEE 802.1X (no WPA)";
2761 #ifdef CONFIG_IEEE80211R
2762           case WPA_KEY_MGMT_FT_IEEE8021X:
2763                     return "FT-EAP";
2764           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
2765                     return "FT-EAP-SHA384";
2766           case WPA_KEY_MGMT_FT_PSK:
2767                     return "FT-PSK";
2768 #endif /* CONFIG_IEEE80211R */
2769           case WPA_KEY_MGMT_IEEE8021X_SHA256:
2770                     return "WPA2-EAP-SHA256";
2771           case WPA_KEY_MGMT_PSK_SHA256:
2772                     return "WPA2-PSK-SHA256";
2773           case WPA_KEY_MGMT_WPS:
2774                     return "WPS";
2775           case WPA_KEY_MGMT_SAE:
2776                     return "SAE";
2777           case WPA_KEY_MGMT_SAE_EXT_KEY:
2778                     return "SAE-EXT-KEY";
2779           case WPA_KEY_MGMT_FT_SAE:
2780                     return "FT-SAE";
2781           case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
2782                     return "FT-SAE-EXT-KEY";
2783           case WPA_KEY_MGMT_OSEN:
2784                     return "OSEN";
2785           case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2786                     return "WPA2-EAP-SUITE-B";
2787           case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2788                     return "WPA2-EAP-SUITE-B-192";
2789           case WPA_KEY_MGMT_FILS_SHA256:
2790                     return "FILS-SHA256";
2791           case WPA_KEY_MGMT_FILS_SHA384:
2792                     return "FILS-SHA384";
2793           case WPA_KEY_MGMT_FT_FILS_SHA256:
2794                     return "FT-FILS-SHA256";
2795           case WPA_KEY_MGMT_FT_FILS_SHA384:
2796                     return "FT-FILS-SHA384";
2797           case WPA_KEY_MGMT_OWE:
2798                     return "OWE";
2799           case WPA_KEY_MGMT_DPP:
2800                     return "DPP";
2801           case WPA_KEY_MGMT_PASN:
2802                     return "PASN";
2803           case WPA_KEY_MGMT_IEEE8021X_SHA384:
2804                     return "WPA2-EAP-SHA384";
2805           default:
2806                     return "UNKNOWN";
2807           }
2808 }
2809 
2810 
wpa_akm_to_suite(int akm)2811 u32 wpa_akm_to_suite(int akm)
2812 {
2813           if (akm & WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
2814                     return RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384;
2815           if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
2816                     return RSN_AUTH_KEY_MGMT_FT_802_1X;
2817           if (akm & WPA_KEY_MGMT_FT_PSK)
2818                     return RSN_AUTH_KEY_MGMT_FT_PSK;
2819           if (akm & WPA_KEY_MGMT_IEEE8021X_SHA384)
2820                     return RSN_AUTH_KEY_MGMT_802_1X_SHA384;
2821           if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
2822                     return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2823           if (akm & WPA_KEY_MGMT_IEEE8021X)
2824                     return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
2825           if (akm & WPA_KEY_MGMT_PSK_SHA256)
2826                     return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2827           if (akm & WPA_KEY_MGMT_PSK)
2828                     return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
2829           if (akm & WPA_KEY_MGMT_CCKM)
2830                     return RSN_AUTH_KEY_MGMT_CCKM;
2831           if (akm & WPA_KEY_MGMT_OSEN)
2832                     return RSN_AUTH_KEY_MGMT_OSEN;
2833           if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
2834                     return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
2835           if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
2836                     return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
2837           if (akm & WPA_KEY_MGMT_FILS_SHA256)
2838                     return RSN_AUTH_KEY_MGMT_FILS_SHA256;
2839           if (akm & WPA_KEY_MGMT_FILS_SHA384)
2840                     return RSN_AUTH_KEY_MGMT_FILS_SHA384;
2841           if (akm & WPA_KEY_MGMT_FT_FILS_SHA256)
2842                     return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
2843           if (akm & WPA_KEY_MGMT_FT_FILS_SHA384)
2844                     return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
2845           if (akm & WPA_KEY_MGMT_SAE)
2846                     return RSN_AUTH_KEY_MGMT_SAE;
2847           if (akm & WPA_KEY_MGMT_SAE_EXT_KEY)
2848                     return RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
2849           if (akm & WPA_KEY_MGMT_FT_SAE)
2850                     return RSN_AUTH_KEY_MGMT_FT_SAE;
2851           if (akm & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
2852                     return RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
2853           if (akm & WPA_KEY_MGMT_OWE)
2854                     return RSN_AUTH_KEY_MGMT_OWE;
2855           if (akm & WPA_KEY_MGMT_DPP)
2856                     return RSN_AUTH_KEY_MGMT_DPP;
2857           return 0;
2858 }
2859 
2860 
wpa_compare_rsn_ie(int ft_initial_assoc,const u8 * ie1,size_t ie1len,const u8 * ie2,size_t ie2len)2861 int wpa_compare_rsn_ie(int ft_initial_assoc,
2862                            const u8 *ie1, size_t ie1len,
2863                            const u8 *ie2, size_t ie2len)
2864 {
2865           if (ie1 == NULL || ie2 == NULL)
2866                     return -1;
2867 
2868           if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
2869                     return 0; /* identical IEs */
2870 
2871 #ifdef CONFIG_IEEE80211R
2872           if (ft_initial_assoc) {
2873                     struct wpa_ie_data ie1d, ie2d;
2874                     /*
2875                      * The PMKID-List in RSN IE is different between Beacon/Probe
2876                      * Response/(Re)Association Request frames and EAPOL-Key
2877                      * messages in FT initial mobility domain association. Allow
2878                      * for this, but verify that other parts of the RSN IEs are
2879                      * identical.
2880                      */
2881                     if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
2882                         wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
2883                               return -1;
2884                     if (ie1d.proto == ie2d.proto &&
2885                         ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
2886                         ie1d.group_cipher == ie2d.group_cipher &&
2887                         ie1d.key_mgmt == ie2d.key_mgmt &&
2888                         ie1d.capabilities == ie2d.capabilities &&
2889                         ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
2890                               return 0;
2891           }
2892 #endif /* CONFIG_IEEE80211R */
2893 
2894           return -1;
2895 }
2896 
2897 
wpa_insert_pmkid(u8 * ies,size_t * ies_len,const u8 * pmkid,bool replace)2898 int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid, bool replace)
2899 {
2900           u8 *start, *end, *rpos, *rend;
2901           int added = 0;
2902 
2903           start = ies;
2904           end = ies + *ies_len;
2905 
2906           while (start < end) {
2907                     if (*start == WLAN_EID_RSN)
2908                               break;
2909                     start += 2 + start[1];
2910           }
2911           if (start >= end) {
2912                     wpa_printf(MSG_ERROR, "RSN: Could not find RSNE in IEs data");
2913                     return -1;
2914           }
2915           wpa_hexdump(MSG_DEBUG, "RSN: RSNE before modification",
2916                         start, 2 + start[1]);
2917 
2918           /* Find start of PMKID-Count */
2919           rpos = start + 2;
2920           rend = rpos + start[1];
2921 
2922           /* Skip Version and Group Data Cipher Suite */
2923           rpos += 2 + 4;
2924           /* Skip Pairwise Cipher Suite Count and List */
2925           rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
2926           /* Skip AKM Suite Count and List */
2927           rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
2928 
2929           if (rpos == rend) {
2930                     /* Add RSN Capabilities */
2931                     os_memmove(rpos + 2, rpos, end - rpos);
2932                     *rpos++ = 0;
2933                     *rpos++ = 0;
2934                     added += 2;
2935                     start[1] += 2;
2936                     rend = rpos;
2937           } else {
2938                     /* Skip RSN Capabilities */
2939                     rpos += 2;
2940                     if (rpos > rend) {
2941                               wpa_printf(MSG_ERROR,
2942                                            "RSN: Could not parse RSNE in IEs data");
2943                               return -1;
2944                     }
2945           }
2946 
2947           if (rpos == rend) {
2948                     /* No PMKID-Count field included; add it */
2949                     os_memmove(rpos + 2 + PMKID_LEN, rpos, end + added - rpos);
2950                     WPA_PUT_LE16(rpos, 1);
2951                     rpos += 2;
2952                     os_memcpy(rpos, pmkid, PMKID_LEN);
2953                     added += 2 + PMKID_LEN;
2954                     start[1] += 2 + PMKID_LEN;
2955           } else {
2956                     u16 num_pmkid;
2957 
2958                     if (rend - rpos < 2)
2959                               return -1;
2960                     num_pmkid = WPA_GET_LE16(rpos);
2961                     if (num_pmkid * PMKID_LEN > rend - rpos - 2)
2962                               return -1;
2963                     /* PMKID-Count was included; use it */
2964                     if (replace && num_pmkid != 0) {
2965                               u8 *after;
2966 
2967                               /*
2968                                * PMKID may have been included in RSN IE in
2969                                * (Re)Association Request frame, so remove the old
2970                                * PMKID(s) first before adding the new one.
2971                                */
2972                               wpa_printf(MSG_DEBUG,
2973                                            "RSN: Remove %u old PMKID(s) from RSNE",
2974                                            num_pmkid);
2975                               after = rpos + 2 + num_pmkid * PMKID_LEN;
2976                               os_memmove(rpos + 2, after, end - after);
2977                               start[1] -= num_pmkid * PMKID_LEN;
2978                               added -= num_pmkid * PMKID_LEN;
2979                               num_pmkid = 0;
2980                     }
2981                     WPA_PUT_LE16(rpos, num_pmkid + 1);
2982                     rpos += 2;
2983                     os_memmove(rpos + PMKID_LEN, rpos, end + added - rpos);
2984                     os_memcpy(rpos, pmkid, PMKID_LEN);
2985                     added += PMKID_LEN;
2986                     start[1] += PMKID_LEN;
2987           }
2988 
2989           wpa_hexdump(MSG_DEBUG, "RSN: RSNE after modification (PMKID inserted)",
2990                         start, 2 + start[1]);
2991 
2992           *ies_len += added;
2993 
2994           return 0;
2995 }
2996 
2997 
wpa_cipher_key_len(int cipher)2998 int wpa_cipher_key_len(int cipher)
2999 {
3000           switch (cipher) {
3001           case WPA_CIPHER_CCMP_256:
3002           case WPA_CIPHER_GCMP_256:
3003           case WPA_CIPHER_BIP_GMAC_256:
3004           case WPA_CIPHER_BIP_CMAC_256:
3005                     return 32;
3006           case WPA_CIPHER_CCMP:
3007           case WPA_CIPHER_GCMP:
3008           case WPA_CIPHER_AES_128_CMAC:
3009           case WPA_CIPHER_BIP_GMAC_128:
3010                     return 16;
3011           case WPA_CIPHER_TKIP:
3012                     return 32;
3013           default:
3014                     return 0;
3015           }
3016 }
3017 
3018 
wpa_cipher_rsc_len(int cipher)3019 int wpa_cipher_rsc_len(int cipher)
3020 {
3021           switch (cipher) {
3022           case WPA_CIPHER_CCMP_256:
3023           case WPA_CIPHER_GCMP_256:
3024           case WPA_CIPHER_CCMP:
3025           case WPA_CIPHER_GCMP:
3026           case WPA_CIPHER_TKIP:
3027                     return 6;
3028           default:
3029                     return 0;
3030           }
3031 }
3032 
3033 
wpa_cipher_to_alg(int cipher)3034 enum wpa_alg wpa_cipher_to_alg(int cipher)
3035 {
3036           switch (cipher) {
3037           case WPA_CIPHER_CCMP_256:
3038                     return WPA_ALG_CCMP_256;
3039           case WPA_CIPHER_GCMP_256:
3040                     return WPA_ALG_GCMP_256;
3041           case WPA_CIPHER_CCMP:
3042                     return WPA_ALG_CCMP;
3043           case WPA_CIPHER_GCMP:
3044                     return WPA_ALG_GCMP;
3045           case WPA_CIPHER_TKIP:
3046                     return WPA_ALG_TKIP;
3047           case WPA_CIPHER_AES_128_CMAC:
3048                     return WPA_ALG_BIP_CMAC_128;
3049           case WPA_CIPHER_BIP_GMAC_128:
3050                     return WPA_ALG_BIP_GMAC_128;
3051           case WPA_CIPHER_BIP_GMAC_256:
3052                     return WPA_ALG_BIP_GMAC_256;
3053           case WPA_CIPHER_BIP_CMAC_256:
3054                     return WPA_ALG_BIP_CMAC_256;
3055           default:
3056                     return WPA_ALG_NONE;
3057           }
3058 }
3059 
3060 
wpa_cipher_valid_pairwise(int cipher)3061 int wpa_cipher_valid_pairwise(int cipher)
3062 {
3063 #ifdef CONFIG_NO_TKIP
3064           return cipher == WPA_CIPHER_CCMP_256 ||
3065                     cipher == WPA_CIPHER_GCMP_256 ||
3066                     cipher == WPA_CIPHER_CCMP ||
3067                     cipher == WPA_CIPHER_GCMP;
3068 #else /* CONFIG_NO_TKIP */
3069           return cipher == WPA_CIPHER_CCMP_256 ||
3070                     cipher == WPA_CIPHER_GCMP_256 ||
3071                     cipher == WPA_CIPHER_CCMP ||
3072                     cipher == WPA_CIPHER_GCMP ||
3073                     cipher == WPA_CIPHER_TKIP;
3074 #endif /* CONFIG_NO_TKIP */
3075 }
3076 
3077 
wpa_cipher_to_suite(int proto,int cipher)3078 u32 wpa_cipher_to_suite(int proto, int cipher)
3079 {
3080           if (cipher & WPA_CIPHER_CCMP_256)
3081                     return RSN_CIPHER_SUITE_CCMP_256;
3082           if (cipher & WPA_CIPHER_GCMP_256)
3083                     return RSN_CIPHER_SUITE_GCMP_256;
3084           if (cipher & WPA_CIPHER_CCMP)
3085                     return (proto == WPA_PROTO_RSN ?
3086                               RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
3087           if (cipher & WPA_CIPHER_GCMP)
3088                     return RSN_CIPHER_SUITE_GCMP;
3089           if (cipher & WPA_CIPHER_TKIP)
3090                     return (proto == WPA_PROTO_RSN ?
3091                               RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
3092           if (cipher & WPA_CIPHER_NONE)
3093                     return (proto == WPA_PROTO_RSN ?
3094                               RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
3095           if (cipher & WPA_CIPHER_GTK_NOT_USED)
3096                     return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
3097           if (cipher & WPA_CIPHER_AES_128_CMAC)
3098                     return RSN_CIPHER_SUITE_AES_128_CMAC;
3099           if (cipher & WPA_CIPHER_BIP_GMAC_128)
3100                     return RSN_CIPHER_SUITE_BIP_GMAC_128;
3101           if (cipher & WPA_CIPHER_BIP_GMAC_256)
3102                     return RSN_CIPHER_SUITE_BIP_GMAC_256;
3103           if (cipher & WPA_CIPHER_BIP_CMAC_256)
3104                     return RSN_CIPHER_SUITE_BIP_CMAC_256;
3105           return 0;
3106 }
3107 
3108 
rsn_cipher_put_suites(u8 * start,int ciphers)3109 int rsn_cipher_put_suites(u8 *start, int ciphers)
3110 {
3111           u8 *pos = start;
3112 
3113           if (ciphers & WPA_CIPHER_CCMP_256) {
3114                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
3115                     pos += RSN_SELECTOR_LEN;
3116           }
3117           if (ciphers & WPA_CIPHER_GCMP_256) {
3118                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
3119                     pos += RSN_SELECTOR_LEN;
3120           }
3121           if (ciphers & WPA_CIPHER_CCMP) {
3122                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
3123                     pos += RSN_SELECTOR_LEN;
3124           }
3125           if (ciphers & WPA_CIPHER_GCMP) {
3126                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
3127                     pos += RSN_SELECTOR_LEN;
3128           }
3129           if (ciphers & WPA_CIPHER_TKIP) {
3130                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
3131                     pos += RSN_SELECTOR_LEN;
3132           }
3133           if (ciphers & WPA_CIPHER_NONE) {
3134                     RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
3135                     pos += RSN_SELECTOR_LEN;
3136           }
3137 
3138           return (pos - start) / RSN_SELECTOR_LEN;
3139 }
3140 
3141 
wpa_cipher_put_suites(u8 * start,int ciphers)3142 int wpa_cipher_put_suites(u8 *start, int ciphers)
3143 {
3144           u8 *pos = start;
3145 
3146           if (ciphers & WPA_CIPHER_CCMP) {
3147                     RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
3148                     pos += WPA_SELECTOR_LEN;
3149           }
3150           if (ciphers & WPA_CIPHER_TKIP) {
3151                     RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
3152                     pos += WPA_SELECTOR_LEN;
3153           }
3154           if (ciphers & WPA_CIPHER_NONE) {
3155                     RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
3156                     pos += WPA_SELECTOR_LEN;
3157           }
3158 
3159           return (pos - start) / RSN_SELECTOR_LEN;
3160 }
3161 
3162 
wpa_pick_pairwise_cipher(int ciphers,int none_allowed)3163 int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
3164 {
3165           if (ciphers & WPA_CIPHER_CCMP_256)
3166                     return WPA_CIPHER_CCMP_256;
3167           if (ciphers & WPA_CIPHER_GCMP_256)
3168                     return WPA_CIPHER_GCMP_256;
3169           if (ciphers & WPA_CIPHER_CCMP)
3170                     return WPA_CIPHER_CCMP;
3171           if (ciphers & WPA_CIPHER_GCMP)
3172                     return WPA_CIPHER_GCMP;
3173           if (ciphers & WPA_CIPHER_TKIP)
3174                     return WPA_CIPHER_TKIP;
3175           if (none_allowed && (ciphers & WPA_CIPHER_NONE))
3176                     return WPA_CIPHER_NONE;
3177           return -1;
3178 }
3179 
3180 
wpa_pick_group_cipher(int ciphers)3181 int wpa_pick_group_cipher(int ciphers)
3182 {
3183           if (ciphers & WPA_CIPHER_CCMP_256)
3184                     return WPA_CIPHER_CCMP_256;
3185           if (ciphers & WPA_CIPHER_GCMP_256)
3186                     return WPA_CIPHER_GCMP_256;
3187           if (ciphers & WPA_CIPHER_CCMP)
3188                     return WPA_CIPHER_CCMP;
3189           if (ciphers & WPA_CIPHER_GCMP)
3190                     return WPA_CIPHER_GCMP;
3191           if (ciphers & WPA_CIPHER_GTK_NOT_USED)
3192                     return WPA_CIPHER_GTK_NOT_USED;
3193           if (ciphers & WPA_CIPHER_TKIP)
3194                     return WPA_CIPHER_TKIP;
3195           return -1;
3196 }
3197 
3198 
wpa_parse_cipher(const char * value)3199 int wpa_parse_cipher(const char *value)
3200 {
3201           int val = 0, last;
3202           char *start, *end, *buf;
3203 
3204           buf = os_strdup(value);
3205           if (buf == NULL)
3206                     return -1;
3207           start = buf;
3208 
3209           while (*start != '\0') {
3210                     while (*start == ' ' || *start == '\t')
3211                               start++;
3212                     if (*start == '\0')
3213                               break;
3214                     end = start;
3215                     while (*end != ' ' && *end != '\t' && *end != '\0')
3216                               end++;
3217                     last = *end == '\0';
3218                     *end = '\0';
3219                     if (os_strcmp(start, "CCMP-256") == 0)
3220                               val |= WPA_CIPHER_CCMP_256;
3221                     else if (os_strcmp(start, "GCMP-256") == 0)
3222                               val |= WPA_CIPHER_GCMP_256;
3223                     else if (os_strcmp(start, "CCMP") == 0)
3224                               val |= WPA_CIPHER_CCMP;
3225                     else if (os_strcmp(start, "GCMP") == 0)
3226                               val |= WPA_CIPHER_GCMP;
3227 #ifndef CONFIG_NO_TKIP
3228                     else if (os_strcmp(start, "TKIP") == 0)
3229                               val |= WPA_CIPHER_TKIP;
3230 #endif /* CONFIG_NO_TKIP */
3231 #ifdef CONFIG_WEP
3232                     else if (os_strcmp(start, "WEP104") == 0)
3233                               val |= WPA_CIPHER_WEP104;
3234                     else if (os_strcmp(start, "WEP40") == 0)
3235                               val |= WPA_CIPHER_WEP40;
3236 #endif /* CONFIG_WEP */
3237                     else if (os_strcmp(start, "NONE") == 0)
3238                               val |= WPA_CIPHER_NONE;
3239                     else if (os_strcmp(start, "GTK_NOT_USED") == 0)
3240                               val |= WPA_CIPHER_GTK_NOT_USED;
3241                     else if (os_strcmp(start, "AES-128-CMAC") == 0)
3242                               val |= WPA_CIPHER_AES_128_CMAC;
3243                     else if (os_strcmp(start, "BIP-GMAC-128") == 0)
3244                               val |= WPA_CIPHER_BIP_GMAC_128;
3245                     else if (os_strcmp(start, "BIP-GMAC-256") == 0)
3246                               val |= WPA_CIPHER_BIP_GMAC_256;
3247                     else if (os_strcmp(start, "BIP-CMAC-256") == 0)
3248                               val |= WPA_CIPHER_BIP_CMAC_256;
3249                     else {
3250                               os_free(buf);
3251                               return -1;
3252                     }
3253 
3254                     if (last)
3255                               break;
3256                     start = end + 1;
3257           }
3258           os_free(buf);
3259 
3260           return val;
3261 }
3262 
3263 
wpa_write_ciphers(char * start,char * end,int ciphers,const char * delim)3264 int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
3265 {
3266           char *pos = start;
3267           int ret;
3268 
3269           if (ciphers & WPA_CIPHER_CCMP_256) {
3270                     ret = os_snprintf(pos, end - pos, "%sCCMP-256",
3271                                           pos == start ? "" : delim);
3272                     if (os_snprintf_error(end - pos, ret))
3273                               return -1;
3274                     pos += ret;
3275           }
3276           if (ciphers & WPA_CIPHER_GCMP_256) {
3277                     ret = os_snprintf(pos, end - pos, "%sGCMP-256",
3278                                           pos == start ? "" : delim);
3279                     if (os_snprintf_error(end - pos, ret))
3280                               return -1;
3281                     pos += ret;
3282           }
3283           if (ciphers & WPA_CIPHER_CCMP) {
3284                     ret = os_snprintf(pos, end - pos, "%sCCMP",
3285                                           pos == start ? "" : delim);
3286                     if (os_snprintf_error(end - pos, ret))
3287                               return -1;
3288                     pos += ret;
3289           }
3290           if (ciphers & WPA_CIPHER_GCMP) {
3291                     ret = os_snprintf(pos, end - pos, "%sGCMP",
3292                                           pos == start ? "" : delim);
3293                     if (os_snprintf_error(end - pos, ret))
3294                               return -1;
3295                     pos += ret;
3296           }
3297           if (ciphers & WPA_CIPHER_TKIP) {
3298                     ret = os_snprintf(pos, end - pos, "%sTKIP",
3299                                           pos == start ? "" : delim);
3300                     if (os_snprintf_error(end - pos, ret))
3301                               return -1;
3302                     pos += ret;
3303           }
3304           if (ciphers & WPA_CIPHER_AES_128_CMAC) {
3305                     ret = os_snprintf(pos, end - pos, "%sAES-128-CMAC",
3306                                           pos == start ? "" : delim);
3307                     if (os_snprintf_error(end - pos, ret))
3308                               return -1;
3309                     pos += ret;
3310           }
3311           if (ciphers & WPA_CIPHER_BIP_GMAC_128) {
3312                     ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-128",
3313                                           pos == start ? "" : delim);
3314                     if (os_snprintf_error(end - pos, ret))
3315                               return -1;
3316                     pos += ret;
3317           }
3318           if (ciphers & WPA_CIPHER_BIP_GMAC_256) {
3319                     ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-256",
3320                                           pos == start ? "" : delim);
3321                     if (os_snprintf_error(end - pos, ret))
3322                               return -1;
3323                     pos += ret;
3324           }
3325           if (ciphers & WPA_CIPHER_BIP_CMAC_256) {
3326                     ret = os_snprintf(pos, end - pos, "%sBIP-CMAC-256",
3327                                           pos == start ? "" : delim);
3328                     if (os_snprintf_error(end - pos, ret))
3329                               return -1;
3330                     pos += ret;
3331           }
3332           if (ciphers & WPA_CIPHER_NONE) {
3333                     ret = os_snprintf(pos, end - pos, "%sNONE",
3334                                           pos == start ? "" : delim);
3335                     if (os_snprintf_error(end - pos, ret))
3336                               return -1;
3337                     pos += ret;
3338           }
3339 
3340           return pos - start;
3341 }
3342 
3343 
wpa_select_ap_group_cipher(int wpa,int wpa_pairwise,int rsn_pairwise)3344 int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
3345 {
3346           int pairwise = 0;
3347 
3348           /* Select group cipher based on the enabled pairwise cipher suites */
3349           if (wpa & 1)
3350                     pairwise |= wpa_pairwise;
3351           if (wpa & 2)
3352                     pairwise |= rsn_pairwise;
3353 
3354           if (pairwise & WPA_CIPHER_TKIP)
3355                     return WPA_CIPHER_TKIP;
3356           if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
3357                     return WPA_CIPHER_GCMP;
3358           if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
3359                                WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
3360                     return WPA_CIPHER_GCMP_256;
3361           if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
3362                                WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
3363                     return WPA_CIPHER_CCMP_256;
3364           return WPA_CIPHER_CCMP;
3365 }
3366 
3367 
3368 #ifdef CONFIG_FILS
fils_domain_name_hash(const char * domain,u8 * hash)3369 int fils_domain_name_hash(const char *domain, u8 *hash)
3370 {
3371           char buf[255], *wpos = buf;
3372           const char *pos = domain;
3373           size_t len;
3374           const u8 *addr[1];
3375           u8 mac[SHA256_MAC_LEN];
3376 
3377           for (len = 0; len < sizeof(buf) && *pos; len++) {
3378                     if (isalpha(*pos) && isupper(*pos))
3379                               *wpos++ = tolower(*pos);
3380                     else
3381                               *wpos++ = *pos;
3382                     pos++;
3383           }
3384 
3385           addr[0] = (const u8 *) buf;
3386           if (sha256_vector(1, addr, &len, mac) < 0)
3387                     return -1;
3388           os_memcpy(hash, mac, 2);
3389           return 0;
3390 }
3391 #endif /* CONFIG_FILS */
3392 
3393 
3394 /**
3395  * wpa_parse_vendor_specific - Parse Vendor Specific IEs
3396  * @pos: Pointer to the IE header
3397  * @end: Pointer to the end of the Key Data buffer
3398  * @ie: Pointer to parsed IE data
3399  */
wpa_parse_vendor_specific(const u8 * pos,const u8 * end,struct wpa_eapol_ie_parse * ie)3400 static void wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
3401                                               struct wpa_eapol_ie_parse *ie)
3402 {
3403           unsigned int oui;
3404 
3405           if (pos[1] < 4) {
3406                     wpa_printf(MSG_MSGDUMP,
3407                                  "Too short vendor specific IE ignored (len=%u)",
3408                                  pos[1]);
3409                     return;
3410           }
3411 
3412           oui = WPA_GET_BE24(&pos[2]);
3413           if (oui == OUI_MICROSOFT && pos[5] == WMM_OUI_TYPE && pos[1] > 4) {
3414                     if (pos[6] == WMM_OUI_SUBTYPE_INFORMATION_ELEMENT) {
3415                               ie->wmm = &pos[2];
3416                               ie->wmm_len = pos[1];
3417                               wpa_hexdump(MSG_DEBUG, "WPA: WMM IE",
3418                                             ie->wmm, ie->wmm_len);
3419                     } else if (pos[6] == WMM_OUI_SUBTYPE_PARAMETER_ELEMENT) {
3420                               ie->wmm = &pos[2];
3421                               ie->wmm_len = pos[1];
3422                               wpa_hexdump(MSG_DEBUG, "WPA: WMM Parameter Element",
3423                                             ie->wmm, ie->wmm_len);
3424                     }
3425           }
3426 }
3427 
3428 
3429 /**
3430  * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
3431  * @pos: Pointer to the IE header
3432  * @ie: Pointer to parsed IE data
3433  * Returns: 0 on success, 1 if end mark is found, 2 if KDE is not recognized
3434  */
wpa_parse_generic(const u8 * pos,struct wpa_eapol_ie_parse * ie)3435 static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
3436 {
3437           u8 len = pos[1];
3438           size_t dlen = 2 + len;
3439           u32 selector;
3440           const u8 *p;
3441           size_t left;
3442           u8 link_id;
3443           char title[50];
3444           int ret;
3445 
3446           if (len == 0)
3447                     return 1;
3448 
3449           if (len < RSN_SELECTOR_LEN)
3450                     return 2;
3451 
3452           p = pos + 2;
3453           selector = RSN_SELECTOR_GET(p);
3454           p += RSN_SELECTOR_LEN;
3455           left = len - RSN_SELECTOR_LEN;
3456 
3457           if (left >= 2 && selector == WPA_OUI_TYPE && p[0] == 1 && p[1] == 0) {
3458                     ie->wpa_ie = pos;
3459                     ie->wpa_ie_len = dlen;
3460                     wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
3461                                   ie->wpa_ie, ie->wpa_ie_len);
3462                     return 0;
3463           }
3464 
3465           if (selector == OSEN_IE_VENDOR_TYPE) {
3466                     ie->osen = pos;
3467                     ie->osen_len = dlen;
3468                     return 0;
3469           }
3470 
3471           if (left >= PMKID_LEN && selector == RSN_KEY_DATA_PMKID) {
3472                     ie->pmkid = p;
3473                     wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key", pos, dlen);
3474                     return 0;
3475           }
3476 
3477           if (left >= 2 && selector == RSN_KEY_DATA_KEYID) {
3478                     ie->key_id = p;
3479                     wpa_hexdump(MSG_DEBUG, "WPA: KeyID in EAPOL-Key", pos, dlen);
3480                     return 0;
3481           }
3482 
3483           if (left > 2 && selector == RSN_KEY_DATA_GROUPKEY) {
3484                     ie->gtk = p;
3485                     ie->gtk_len = left;
3486                     wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key", pos, dlen);
3487                     return 0;
3488           }
3489 
3490           if (left >= ETH_ALEN && selector == RSN_KEY_DATA_MAC_ADDR) {
3491                     ie->mac_addr = p;
3492                     wpa_printf(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key: " MACSTR,
3493                                  MAC2STR(ie->mac_addr));
3494                     return 0;
3495           }
3496 
3497           if (left > 2 && selector == RSN_KEY_DATA_IGTK) {
3498                     ie->igtk = p;
3499                     ie->igtk_len = left;
3500                     wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
3501                                         pos, dlen);
3502                     return 0;
3503           }
3504 
3505           if (left > 2 && selector == RSN_KEY_DATA_BIGTK) {
3506                     ie->bigtk = p;
3507                     ie->bigtk_len = left;
3508                     wpa_hexdump_key(MSG_DEBUG, "WPA: BIGTK in EAPOL-Key",
3509                                         pos, dlen);
3510                     return 0;
3511           }
3512 
3513           if (left >= 1 && selector == WFA_KEY_DATA_IP_ADDR_REQ) {
3514                     ie->ip_addr_req = p;
3515                     wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
3516                                   ie->ip_addr_req, left);
3517                     return 0;
3518           }
3519 
3520           if (left >= 3 * 4 && selector == WFA_KEY_DATA_IP_ADDR_ALLOC) {
3521                     ie->ip_addr_alloc = p;
3522                     wpa_hexdump(MSG_DEBUG,
3523                                   "WPA: IP Address Allocation in EAPOL-Key",
3524                                   ie->ip_addr_alloc, left);
3525                     return 0;
3526           }
3527 
3528           if (left > 2 && selector == RSN_KEY_DATA_OCI) {
3529                     ie->oci = p;
3530                     ie->oci_len = left;
3531                     wpa_hexdump(MSG_DEBUG, "WPA: OCI KDE in EAPOL-Key",
3532                                   pos, dlen);
3533                     return 0;
3534           }
3535 
3536           if (left >= 1 && selector == WFA_KEY_DATA_TRANSITION_DISABLE) {
3537                     ie->transition_disable = p;
3538                     ie->transition_disable_len = left;
3539                     wpa_hexdump(MSG_DEBUG,
3540                                   "WPA: Transition Disable KDE in EAPOL-Key",
3541                                   pos, dlen);
3542                     return 0;
3543           }
3544 
3545           if (left >= 2 && selector == WFA_KEY_DATA_DPP) {
3546                     ie->dpp_kde = p;
3547                     ie->dpp_kde_len = left;
3548                     wpa_hexdump(MSG_DEBUG, "WPA: DPP KDE in EAPOL-Key", pos, dlen);
3549                     return 0;
3550           }
3551 
3552           if (left >= RSN_MLO_GTK_KDE_PREFIX_LENGTH &&
3553               selector == RSN_KEY_DATA_MLO_GTK) {
3554                     link_id = (p[0] & RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK) >>
3555                               RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT;
3556                     if (link_id >= MAX_NUM_MLD_LINKS)
3557                               return 2;
3558 
3559                     ie->valid_mlo_gtks |= BIT(link_id);
3560                     ie->mlo_gtk[link_id] = p;
3561                     ie->mlo_gtk_len[link_id] = left;
3562                     ret = os_snprintf(title, sizeof(title),
3563                                           "RSN: Link ID %u - MLO GTK KDE in EAPOL-Key",
3564                                           link_id);
3565                     if (!os_snprintf_error(sizeof(title), ret))
3566                               wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3567                     return 0;
3568           }
3569 
3570           if (left >= RSN_MLO_IGTK_KDE_PREFIX_LENGTH &&
3571               selector == RSN_KEY_DATA_MLO_IGTK) {
3572                     link_id = (p[8] & RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK) >>
3573                                 RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT;
3574                     if (link_id >= MAX_NUM_MLD_LINKS)
3575                               return 2;
3576 
3577                     ie->valid_mlo_igtks |= BIT(link_id);
3578                     ie->mlo_igtk[link_id] = p;
3579                     ie->mlo_igtk_len[link_id] = left;
3580                     ret = os_snprintf(title, sizeof(title),
3581                                           "RSN: Link ID %u - MLO IGTK KDE in EAPOL-Key",
3582                                           link_id);
3583                     if (!os_snprintf_error(sizeof(title), ret))
3584                               wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3585                     return 0;
3586           }
3587 
3588           if (left >= RSN_MLO_BIGTK_KDE_PREFIX_LENGTH &&
3589               selector == RSN_KEY_DATA_MLO_BIGTK) {
3590                     link_id = (p[8] & RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK) >>
3591                                 RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT;
3592                     if (link_id >= MAX_NUM_MLD_LINKS)
3593                               return 2;
3594 
3595                     ie->valid_mlo_bigtks |= BIT(link_id);
3596                     ie->mlo_bigtk[link_id] = p;
3597                     ie->mlo_bigtk_len[link_id] = left;
3598                     ret = os_snprintf(title, sizeof(title),
3599                                           "RSN: Link ID %u - MLO BIGTK KDE in EAPOL-Key",
3600                                           link_id);
3601                     if (!os_snprintf_error(sizeof(title), ret))
3602                               wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3603                     return 0;
3604           }
3605 
3606           if (left >= RSN_MLO_LINK_KDE_FIXED_LENGTH &&
3607               selector == RSN_KEY_DATA_MLO_LINK) {
3608                     link_id = (p[0] & RSN_MLO_LINK_KDE_LI_LINK_ID_MASK) >>
3609                                 RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT;
3610                     if (link_id >= MAX_NUM_MLD_LINKS)
3611                               return 2;
3612 
3613                     ie->valid_mlo_links |= BIT(link_id);
3614                     ie->mlo_link[link_id] = p;
3615                     ie->mlo_link_len[link_id] = left;
3616                     ret = os_snprintf(title, sizeof(title),
3617                                           "RSN: Link ID %u - MLO Link KDE in EAPOL-Key",
3618                                           link_id);
3619                     if (!os_snprintf_error(sizeof(title), ret))
3620                               wpa_hexdump(MSG_DEBUG, title, pos, dlen);
3621                     return 0;
3622           }
3623 
3624           return 2;
3625 }
3626 
3627 
3628 /**
3629  * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
3630  * @buf: Pointer to the Key Data buffer
3631  * @len: Key Data Length
3632  * @ie: Pointer to parsed IE data
3633  * Returns: 0 on success, -1 on failure
3634  */
wpa_parse_kde_ies(const u8 * buf,size_t len,struct wpa_eapol_ie_parse * ie)3635 int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
3636 {
3637           const u8 *pos, *end;
3638           int ret = 0;
3639           size_t dlen = 0;
3640 
3641           os_memset(ie, 0, sizeof(*ie));
3642           for (pos = buf, end = pos + len; end - pos > 1; pos += dlen) {
3643                     if (pos[0] == 0xdd &&
3644                         ((pos == buf + len - 1) || pos[1] == 0)) {
3645                               /* Ignore padding */
3646                               break;
3647                     }
3648                     dlen = 2 + pos[1];
3649                     if ((int) dlen > end - pos) {
3650                               wpa_printf(MSG_DEBUG,
3651                                            "WPA: EAPOL-Key Key Data underflow (ie=%d len=%d pos=%d)",
3652                                            pos[0], pos[1], (int) (pos - buf));
3653                               wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", buf, len);
3654                               ret = -1;
3655                               break;
3656                     }
3657                     if (*pos == WLAN_EID_RSN) {
3658                               ie->rsn_ie = pos;
3659                               ie->rsn_ie_len = dlen;
3660                               wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
3661                                             ie->rsn_ie, ie->rsn_ie_len);
3662                     } else if (*pos == WLAN_EID_RSNX) {
3663                               ie->rsnxe = pos;
3664                               ie->rsnxe_len = dlen;
3665                               wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
3666                                             ie->rsnxe, ie->rsnxe_len);
3667                     } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
3668                               ie->mdie = pos;
3669                               ie->mdie_len = dlen;
3670                               wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
3671                                             ie->mdie, ie->mdie_len);
3672                     } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
3673                               ie->ftie = pos;
3674                               ie->ftie_len = dlen;
3675                               wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
3676                                             ie->ftie, ie->ftie_len);
3677                     } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
3678                               if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
3679                                         ie->reassoc_deadline = pos;
3680                                         wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
3681                                                       "in EAPOL-Key",
3682                                                       ie->reassoc_deadline, dlen);
3683                               } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
3684                                         ie->key_lifetime = pos;
3685                                         wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
3686                                                       "in EAPOL-Key",
3687                                                       ie->key_lifetime, dlen);
3688                               } else {
3689                                         wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
3690                                                       "EAPOL-Key Key Data IE",
3691                                                       pos, dlen);
3692                               }
3693                     } else if (*pos == WLAN_EID_LINK_ID) {
3694                               if (pos[1] >= 18) {
3695                                         ie->lnkid = pos;
3696                                         ie->lnkid_len = dlen;
3697                               }
3698                     } else if (*pos == WLAN_EID_EXT_CAPAB) {
3699                               ie->ext_capab = pos;
3700                               ie->ext_capab_len = dlen;
3701                     } else if (*pos == WLAN_EID_SUPP_RATES) {
3702                               ie->supp_rates = pos;
3703                               ie->supp_rates_len = dlen;
3704                     } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
3705                               ie->ext_supp_rates = pos;
3706                               ie->ext_supp_rates_len = dlen;
3707                     } else if (*pos == WLAN_EID_HT_CAP &&
3708                                  pos[1] >= sizeof(struct ieee80211_ht_capabilities)) {
3709                               ie->ht_capabilities = pos + 2;
3710                     } else if (*pos == WLAN_EID_AID) {
3711                               if (pos[1] >= 2)
3712                                         ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
3713                     } else if (*pos == WLAN_EID_VHT_CAP &&
3714                                  pos[1] >= sizeof(struct ieee80211_vht_capabilities))
3715                     {
3716                               ie->vht_capabilities = pos + 2;
3717                     } else if (*pos == WLAN_EID_EXTENSION &&
3718                                  pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN &&
3719                                  pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) {
3720                               ie->he_capabilities = pos + 3;
3721                               ie->he_capab_len = pos[1] - 1;
3722                     } else if (*pos == WLAN_EID_EXTENSION &&
3723                                  pos[1] >= 1 +
3724                                  sizeof(struct ieee80211_he_6ghz_band_cap) &&
3725                                  pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) {
3726                               ie->he_6ghz_capabilities = pos + 3;
3727                     } else if (*pos == WLAN_EID_EXTENSION &&
3728                                  pos[1] >= 1 + IEEE80211_EHT_CAPAB_MIN_LEN &&
3729                                  pos[2] == WLAN_EID_EXT_EHT_CAPABILITIES) {
3730                               ie->eht_capabilities = pos + 3;
3731                               ie->eht_capab_len = pos[1] - 1;
3732                     } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
3733                               ie->qosinfo = pos[2];
3734                     } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
3735                               ie->supp_channels = pos + 2;
3736                               ie->supp_channels_len = pos[1];
3737                     } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
3738                               /*
3739                                * The value of the Length field of the Supported
3740                                * Operating Classes element is between 2 and 253.
3741                                * Silently skip invalid elements to avoid interop
3742                                * issues when trying to use the value.
3743                                */
3744                               if (pos[1] >= 2 && pos[1] <= 253) {
3745                                         ie->supp_oper_classes = pos + 2;
3746                                         ie->supp_oper_classes_len = pos[1];
3747                               }
3748                     } else if (*pos == WLAN_EID_SSID) {
3749                               ie->ssid = pos + 2;
3750                               ie->ssid_len = pos[1];
3751                               wpa_hexdump_ascii(MSG_DEBUG, "RSN: SSID in EAPOL-Key",
3752                                                     ie->ssid, ie->ssid_len);
3753                     } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
3754                               ret = wpa_parse_generic(pos, ie);
3755                               if (ret == 1) {
3756                                         /* end mark found */
3757                                         ret = 0;
3758                                         break;
3759                               }
3760 
3761                               if (ret == 2) {
3762                                         /* not a known KDE */
3763                                         wpa_parse_vendor_specific(pos, end, ie);
3764                               }
3765 
3766                               ret = 0;
3767                     } else {
3768                               wpa_hexdump(MSG_DEBUG,
3769                                             "WPA: Unrecognized EAPOL-Key Key Data IE",
3770                                             pos, dlen);
3771                     }
3772           }
3773 
3774           return ret;
3775 }
3776 
3777 
3778 #ifdef CONFIG_PASN
3779 
3780 /*
3781  * wpa_pasn_build_auth_header - Add the MAC header and initialize Authentication
3782  * frame for PASN
3783  *
3784  * @buf: Buffer in which the header will be added
3785  * @bssid: The BSSID of the AP
3786  * @src: Source address
3787  * @dst: Destination address
3788  * @trans_seq: Authentication transaction sequence number
3789  * @status: Authentication status
3790  */
wpa_pasn_build_auth_header(struct wpabuf * buf,const u8 * bssid,const u8 * src,const u8 * dst,u8 trans_seq,u16 status)3791 void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
3792                                         const u8 *src, const u8 *dst,
3793                                         u8 trans_seq, u16 status)
3794 {
3795           struct ieee80211_mgmt *auth;
3796 
3797           wpa_printf(MSG_DEBUG, "PASN: Add authentication header. trans_seq=%u",
3798                        trans_seq);
3799 
3800           auth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
3801                                                   u.auth.variable));
3802 
3803           auth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
3804                                                      (WLAN_FC_STYPE_AUTH << 4));
3805 
3806           os_memcpy(auth->da, dst, ETH_ALEN);
3807           os_memcpy(auth->sa, src, ETH_ALEN);
3808           os_memcpy(auth->bssid, bssid, ETH_ALEN);
3809           auth->seq_ctrl = 0;
3810 
3811           auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_PASN);
3812           auth->u.auth.auth_transaction = host_to_le16(trans_seq);
3813           auth->u.auth.status_code = host_to_le16(status);
3814 }
3815 
3816 
3817 /*
3818  * wpa_pasn_add_rsne - Add an RSNE for PASN authentication
3819  * @buf: Buffer in which the IE will be added
3820  * @pmkid: Optional PMKID. Can be NULL.
3821  * @akmp: Authentication and key management protocol
3822  * @cipher: The cipher suite
3823  */
wpa_pasn_add_rsne(struct wpabuf * buf,const u8 * pmkid,int akmp,int cipher)3824 int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid, int akmp, int cipher)
3825 {
3826           struct rsn_ie_hdr *hdr;
3827           u32 suite;
3828           u16 capab;
3829           u8 *pos;
3830           u8 rsne_len;
3831 
3832           wpa_printf(MSG_DEBUG, "PASN: Add RSNE");
3833 
3834           rsne_len = sizeof(*hdr) + RSN_SELECTOR_LEN +
3835                     2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN +
3836                     2 + RSN_SELECTOR_LEN + 2 + (pmkid ? PMKID_LEN : 0);
3837 
3838           if (wpabuf_tailroom(buf) < rsne_len)
3839                     return -1;
3840           hdr = wpabuf_put(buf, rsne_len);
3841           hdr->elem_id = WLAN_EID_RSN;
3842           hdr->len = rsne_len - 2;
3843           WPA_PUT_LE16(hdr->version, RSN_VERSION);
3844           pos = (u8 *) (hdr + 1);
3845 
3846           /* Group addressed data is not allowed */
3847           RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
3848           pos += RSN_SELECTOR_LEN;
3849 
3850           /* Add the pairwise cipher */
3851           WPA_PUT_LE16(pos, 1);
3852           pos += 2;
3853           suite = wpa_cipher_to_suite(WPA_PROTO_RSN, cipher);
3854           RSN_SELECTOR_PUT(pos, suite);
3855           pos += RSN_SELECTOR_LEN;
3856 
3857           /* Add the AKM suite */
3858           WPA_PUT_LE16(pos, 1);
3859           pos += 2;
3860 
3861           switch (akmp) {
3862           case WPA_KEY_MGMT_PASN:
3863                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
3864                     break;
3865 #ifdef CONFIG_SAE
3866           case WPA_KEY_MGMT_SAE:
3867                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
3868                     break;
3869           case WPA_KEY_MGMT_SAE_EXT_KEY:
3870                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
3871                     break;
3872 #endif /* CONFIG_SAE */
3873 #ifdef CONFIG_FILS
3874           case WPA_KEY_MGMT_FILS_SHA256:
3875                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
3876                     break;
3877           case WPA_KEY_MGMT_FILS_SHA384:
3878                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
3879                     break;
3880 #endif /* CONFIG_FILS */
3881 #ifdef CONFIG_IEEE80211R
3882           case WPA_KEY_MGMT_FT_PSK:
3883                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
3884                     break;
3885           case WPA_KEY_MGMT_FT_IEEE8021X:
3886                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
3887                     break;
3888           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
3889                     RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
3890                     break;
3891 #endif /* CONFIG_IEEE80211R */
3892           default:
3893                     wpa_printf(MSG_ERROR, "PASN: Invalid AKMP=0x%x", akmp);
3894                     return -1;
3895           }
3896           pos += RSN_SELECTOR_LEN;
3897 
3898           /* RSN Capabilities: PASN mandates both MFP capable and required */
3899           capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
3900           WPA_PUT_LE16(pos, capab);
3901           pos += 2;
3902 
3903           if (pmkid) {
3904                     wpa_printf(MSG_DEBUG, "PASN: Adding PMKID");
3905 
3906                     WPA_PUT_LE16(pos, 1);
3907                     pos += 2;
3908                     os_memcpy(pos, pmkid, PMKID_LEN);
3909                     pos += PMKID_LEN;
3910           } else {
3911                     WPA_PUT_LE16(pos, 0);
3912                     pos += 2;
3913           }
3914 
3915           /* Group addressed management is not allowed */
3916           RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
3917 
3918           return 0;
3919 }
3920 
3921 
3922 /*
3923  * wpa_pasn_add_parameter_ie - Add PASN Parameters IE for PASN authentication
3924  * @buf: Buffer in which the IE will be added
3925  * @pasn_group: Finite Cyclic Group ID for PASN authentication
3926  * @wrapped_data_format: Format of the data in the Wrapped Data IE
3927  * @pubkey: A buffer holding the local public key. Can be NULL
3928  * @compressed: In case pubkey is included, indicates if the public key is
3929  *     compressed (only x coordinate is included) or not (both x and y
3930  *     coordinates are included)
3931  * @comeback: A buffer holding the comeback token. Can be NULL
3932  * @after: If comeback is set, defined the comeback time in seconds. -1 to not
3933  *        include the Comeback After field (frames from non-AP STA).
3934  */
wpa_pasn_add_parameter_ie(struct wpabuf * buf,u16 pasn_group,u8 wrapped_data_format,const struct wpabuf * pubkey,bool compressed,const struct wpabuf * comeback,int after)3935 void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
3936                                      u8 wrapped_data_format,
3937                                      const struct wpabuf *pubkey, bool compressed,
3938                                      const struct wpabuf *comeback, int after)
3939 {
3940           struct pasn_parameter_ie *params;
3941 
3942           wpa_printf(MSG_DEBUG, "PASN: Add PASN Parameters element");
3943 
3944           params = wpabuf_put(buf, sizeof(*params));
3945 
3946           params->id = WLAN_EID_EXTENSION;
3947           params->len = sizeof(*params) - 2;
3948           params->id_ext = WLAN_EID_EXT_PASN_PARAMS;
3949           params->control = 0;
3950           params->wrapped_data_format = wrapped_data_format;
3951 
3952           if (comeback) {
3953                     wpa_printf(MSG_DEBUG, "PASN: Adding comeback data");
3954 
3955                     /*
3956                      * 2 octets for the 'after' field + 1 octet for the length +
3957                      * actual cookie data
3958                      */
3959                     if (after >= 0)
3960                               params->len += 2;
3961                     params->len += 1 + wpabuf_len(comeback);
3962                     params->control |= WPA_PASN_CTRL_COMEBACK_INFO_PRESENT;
3963 
3964                     if (after >= 0)
3965                               wpabuf_put_le16(buf, after);
3966                     wpabuf_put_u8(buf, wpabuf_len(comeback));
3967                     wpabuf_put_buf(buf, comeback);
3968           }
3969 
3970           if (pubkey) {
3971                     wpa_printf(MSG_DEBUG,
3972                                  "PASN: Adding public key and group ID %u",
3973                                  pasn_group);
3974 
3975                     /*
3976                      * 2 octets for the finite cyclic group + 2 octets public key
3977                      * length + 1 octet for the compressed/uncompressed indication +
3978                      * the actual key.
3979                      */
3980                     params->len += 2 + 1 + 1 + wpabuf_len(pubkey);
3981                     params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
3982 
3983                     wpabuf_put_le16(buf, pasn_group);
3984 
3985                     /*
3986                      * The first octet indicates whether the public key is
3987                      * compressed, as defined in RFC 5480 section 2.2.
3988                      */
3989                     wpabuf_put_u8(buf, wpabuf_len(pubkey) + 1);
3990                     wpabuf_put_u8(buf, compressed ? WPA_PASN_PUBKEY_COMPRESSED_0 :
3991                                     WPA_PASN_PUBKEY_UNCOMPRESSED);
3992 
3993                     wpabuf_put_buf(buf, pubkey);
3994           }
3995 }
3996 
3997 /*
3998  * wpa_pasn_add_wrapped_data - Add a Wrapped Data IE to PASN Authentication
3999  * frame. If needed, the Wrapped Data IE would be fragmented.
4000  *
4001  * @buf: Buffer in which the IE will be added
4002  * @wrapped_data_buf: Buffer holding the wrapped data
4003  */
wpa_pasn_add_wrapped_data(struct wpabuf * buf,struct wpabuf * wrapped_data_buf)4004 int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
4005                                     struct wpabuf *wrapped_data_buf)
4006 {
4007           const u8 *data;
4008           size_t data_len;
4009           u8 len;
4010 
4011           if (!wrapped_data_buf)
4012                     return 0;
4013 
4014           wpa_printf(MSG_DEBUG, "PASN: Add wrapped data");
4015 
4016           data = wpabuf_head_u8(wrapped_data_buf);
4017           data_len = wpabuf_len(wrapped_data_buf);
4018 
4019           /* nothing to add */
4020           if (!data_len)
4021                     return 0;
4022 
4023           if (data_len <= 254)
4024                     len = 1 + data_len;
4025           else
4026                     len = 255;
4027 
4028           if (wpabuf_tailroom(buf) < 3 + data_len)
4029                     return -1;
4030 
4031           wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
4032           wpabuf_put_u8(buf, len);
4033           wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
4034           wpabuf_put_data(buf, data, len - 1);
4035 
4036           data += len - 1;
4037           data_len -= len - 1;
4038 
4039           while (data_len) {
4040                     if (wpabuf_tailroom(buf) < 1 + data_len)
4041                               return -1;
4042                     wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
4043                     len = data_len > 255 ? 255 : data_len;
4044                     wpabuf_put_u8(buf, len);
4045                     wpabuf_put_data(buf, data, len);
4046                     data += len;
4047                     data_len -= len;
4048           }
4049 
4050           return 0;
4051 }
4052 
4053 
4054 /*
4055  * wpa_pasn_validate_rsne - Validate PSAN specific data of RSNE
4056  * @data: Parsed representation of an RSNE
4057  * Returns -1 for invalid data; otherwise 0
4058  */
wpa_pasn_validate_rsne(const struct wpa_ie_data * data)4059 int wpa_pasn_validate_rsne(const struct wpa_ie_data *data)
4060 {
4061           u16 capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
4062 
4063           if (data->proto != WPA_PROTO_RSN)
4064                     return -1;
4065 
4066           if ((data->capabilities & capab) != capab) {
4067                     wpa_printf(MSG_DEBUG, "PASN: Invalid RSNE capabilities");
4068                     return -1;
4069           }
4070 
4071           if (!data->has_group || data->group_cipher != WPA_CIPHER_GTK_NOT_USED) {
4072                     wpa_printf(MSG_DEBUG, "PASN: Invalid group data cipher");
4073                     return -1;
4074           }
4075 
4076           if (!data->has_pairwise || !data->pairwise_cipher ||
4077               (data->pairwise_cipher & (data->pairwise_cipher - 1))) {
4078                     wpa_printf(MSG_DEBUG, "PASN: No valid pairwise suite");
4079                     return -1;
4080           }
4081 
4082           switch (data->key_mgmt) {
4083 #ifdef CONFIG_SAE
4084           case WPA_KEY_MGMT_SAE:
4085           case WPA_KEY_MGMT_SAE_EXT_KEY:
4086           /* fall through */
4087 #endif /* CONFIG_SAE */
4088 #ifdef CONFIG_FILS
4089           case WPA_KEY_MGMT_FILS_SHA256:
4090           case WPA_KEY_MGMT_FILS_SHA384:
4091           /* fall through */
4092 #endif /* CONFIG_FILS */
4093 #ifdef CONFIG_IEEE80211R
4094           case WPA_KEY_MGMT_FT_PSK:
4095           case WPA_KEY_MGMT_FT_IEEE8021X:
4096           case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
4097           /* fall through */
4098 #endif /* CONFIG_IEEE80211R */
4099           case WPA_KEY_MGMT_PASN:
4100                     break;
4101           default:
4102                     wpa_printf(MSG_ERROR, "PASN: invalid key_mgmt: 0x%0x",
4103                                  data->key_mgmt);
4104                     return -1;
4105           }
4106 
4107           if (data->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED) {
4108                     wpa_printf(MSG_DEBUG, "PASN: Invalid group mgmt cipher");
4109                     return -1;
4110           }
4111 
4112           if (data->num_pmkid > 1) {
4113                     wpa_printf(MSG_DEBUG, "PASN: Invalid number of PMKIDs");
4114                     return -1;
4115           }
4116 
4117           return 0;
4118 }
4119 
4120 
4121 /*
4122  * wpa_pasn_parse_parameter_ie - Validates PASN Parameters IE
4123  * @data: Pointer to the PASN Parameters IE (starting with the EID).
4124  * @len: Length of the data in the PASN Parameters IE
4125  * @from_ap: Whether this was received from an AP
4126  * @pasn_params: On successful return would hold the parsed PASN parameters.
4127  * Returns: -1 for invalid data; otherwise 0
4128  *
4129  * Note: On successful return, the pointers in &pasn_params point to the data in
4130  * the IE and are not locally allocated (so they should not be freed etc.).
4131  */
wpa_pasn_parse_parameter_ie(const u8 * data,u8 len,bool from_ap,struct wpa_pasn_params_data * pasn_params)4132 int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
4133                                         struct wpa_pasn_params_data *pasn_params)
4134 {
4135           struct pasn_parameter_ie *params = (struct pasn_parameter_ie *) data;
4136           const u8 *pos = (const u8 *) (params + 1);
4137 
4138           if (!pasn_params) {
4139                     wpa_printf(MSG_DEBUG, "PASN: Invalid params");
4140                     return -1;
4141           }
4142 
4143           if (!params || ((size_t) (params->len + 2) < sizeof(*params)) ||
4144               len < sizeof(*params) || params->len + 2 != len) {
4145                     wpa_printf(MSG_DEBUG,
4146                                  "PASN: Invalid parameters IE. len=(%u, %u)",
4147                                  params ? params->len : 0, len);
4148                     return -1;
4149           }
4150 
4151           os_memset(pasn_params, 0, sizeof(*pasn_params));
4152 
4153           switch (params->wrapped_data_format) {
4154           case WPA_PASN_WRAPPED_DATA_NO:
4155           case WPA_PASN_WRAPPED_DATA_SAE:
4156           case WPA_PASN_WRAPPED_DATA_FILS_SK:
4157           case WPA_PASN_WRAPPED_DATA_FT:
4158                     break;
4159           default:
4160                     wpa_printf(MSG_DEBUG, "PASN: Invalid wrapped data format");
4161                     return -1;
4162           }
4163 
4164           pasn_params->wrapped_data_format = params->wrapped_data_format;
4165 
4166           len -= sizeof(*params);
4167 
4168           if (params->control & WPA_PASN_CTRL_COMEBACK_INFO_PRESENT) {
4169                     if (from_ap) {
4170                               if (len < 2) {
4171                                         wpa_printf(MSG_DEBUG,
4172                                                      "PASN: Invalid Parameters IE: Truncated Comeback After");
4173                                         return -1;
4174                               }
4175                               pasn_params->after = WPA_GET_LE16(pos);
4176                               pos += 2;
4177                               len -= 2;
4178                     }
4179 
4180                     if (len < 1 || len < 1 + *pos) {
4181                               wpa_printf(MSG_DEBUG,
4182                                            "PASN: Invalid Parameters IE: comeback len");
4183                               return -1;
4184                     }
4185 
4186                     pasn_params->comeback_len = *pos++;
4187                     len--;
4188                     pasn_params->comeback = pos;
4189                     len -=  pasn_params->comeback_len;
4190                     pos += pasn_params->comeback_len;
4191           }
4192 
4193           if (params->control & WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT) {
4194                     if (len < 3 || len < 3 + pos[2]) {
4195                               wpa_printf(MSG_DEBUG,
4196                                            "PASN: Invalid Parameters IE: group and key");
4197                               return -1;
4198                     }
4199 
4200                     pasn_params->group = WPA_GET_LE16(pos);
4201                     pos += 2;
4202                     len -= 2;
4203                     pasn_params->pubkey_len = *pos++;
4204                     len--;
4205                     pasn_params->pubkey = pos;
4206                     len -= pasn_params->pubkey_len;
4207                     pos += pasn_params->pubkey_len;
4208           }
4209 
4210           if (len) {
4211                     wpa_printf(MSG_DEBUG,
4212                                  "PASN: Invalid Parameters IE. Bytes left=%u", len);
4213                     return -1;
4214           }
4215 
4216           return 0;
4217 }
4218 
4219 
wpa_pasn_add_rsnxe(struct wpabuf * buf,u16 capab)4220 void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab)
4221 {
4222           size_t flen;
4223 
4224           flen = (capab & 0xff00) ? 2 : 1;
4225           if (!capab)
4226                     return; /* no supported extended RSN capabilities */
4227           if (wpabuf_tailroom(buf) < 2 + flen)
4228                     return;
4229           capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
4230 
4231           wpabuf_put_u8(buf, WLAN_EID_RSNX);
4232           wpabuf_put_u8(buf, flen);
4233           wpabuf_put_u8(buf, capab & 0x00ff);
4234           capab >>= 8;
4235           if (capab)
4236                     wpabuf_put_u8(buf, capab);
4237 }
4238 
4239 
4240 /*
4241  * wpa_pasn_add_extra_ies - Add protocol specific IEs in Authentication
4242  * frame for PASN.
4243  *
4244  * @buf: Buffer in which the elements will be added
4245  * @extra_ies: Protocol specific elements to add
4246  * @len: Length of the elements
4247  * Returns: 0 on success, -1 on failure
4248  */
4249 
wpa_pasn_add_extra_ies(struct wpabuf * buf,const u8 * extra_ies,size_t len)4250 int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len)
4251 {
4252           if (!len || !extra_ies || !buf)
4253                     return 0;
4254 
4255           if (wpabuf_tailroom(buf) < sizeof(len))
4256                     return -1;
4257 
4258           wpabuf_put_data(buf, extra_ies, len);
4259           return 0;
4260 }
4261 
4262 #endif /* CONFIG_PASN */
4263