]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/common/wpa_common.c
FT: PMK-R1 derivation using SHA384-based AKM
[thirdparty/hostap.git] / src / common / wpa_common.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA/RSN - Shared functions for supplicant and authenticator
c22bb5bb 3 * Copyright (c) 2002-2018, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
9#include "includes.h"
10
11#include "common.h"
03da66bd
JM
12#include "crypto/md5.h"
13#include "crypto/sha1.h"
14#include "crypto/sha256.h"
5e3b5197 15#include "crypto/sha384.h"
567da5bb 16#include "crypto/sha512.h"
03da66bd
JM
17#include "crypto/aes_wrap.h"
18#include "crypto/crypto.h"
6fc6879b
JM
19#include "ieee802_11_defs.h"
20#include "defs.h"
21#include "wpa_common.h"
22
23
567da5bb 24static unsigned int wpa_kck_len(int akmp, size_t pmk_len)
98cd3d1c 25{
94318a0d
JM
26 switch (akmp) {
27 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
c22bb5bb 28 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
5e3b5197 29 return 24;
94318a0d
JM
30 case WPA_KEY_MGMT_FILS_SHA256:
31 case WPA_KEY_MGMT_FT_FILS_SHA256:
32 case WPA_KEY_MGMT_FILS_SHA384:
33 case WPA_KEY_MGMT_FT_FILS_SHA384:
34 return 0;
567da5bb
JM
35 case WPA_KEY_MGMT_DPP:
36 return pmk_len / 2;
6c472618
JM
37 case WPA_KEY_MGMT_OWE:
38 return pmk_len / 2;
94318a0d
JM
39 default:
40 return 16;
41 }
98cd3d1c
JM
42}
43
44
2f373878
JM
45#ifdef CONFIG_IEEE80211R
46static unsigned int wpa_kck2_len(int akmp)
47{
48 switch (akmp) {
49 case WPA_KEY_MGMT_FT_FILS_SHA256:
50 return 16;
51 case WPA_KEY_MGMT_FT_FILS_SHA384:
52 return 24;
53 default:
54 return 0;
55 }
56}
57#endif /* CONFIG_IEEE80211R */
58
59
567da5bb 60static unsigned int wpa_kek_len(int akmp, size_t pmk_len)
98cd3d1c 61{
94318a0d
JM
62 switch (akmp) {
63 case WPA_KEY_MGMT_FILS_SHA384:
64 case WPA_KEY_MGMT_FT_FILS_SHA384:
65 return 64;
66 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
67 case WPA_KEY_MGMT_FILS_SHA256:
68 case WPA_KEY_MGMT_FT_FILS_SHA256:
c22bb5bb 69 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
5e3b5197 70 return 32;
567da5bb
JM
71 case WPA_KEY_MGMT_DPP:
72 return pmk_len <= 32 ? 16 : 32;
6c472618
JM
73 case WPA_KEY_MGMT_OWE:
74 return pmk_len <= 32 ? 16 : 32;
94318a0d
JM
75 default:
76 return 16;
77 }
5e3b5197
JM
78}
79
80
2f373878
JM
81#ifdef CONFIG_IEEE80211R
82static unsigned int wpa_kek2_len(int akmp)
83{
84 switch (akmp) {
85 case WPA_KEY_MGMT_FT_FILS_SHA256:
86 return 16;
87 case WPA_KEY_MGMT_FT_FILS_SHA384:
88 return 32;
89 default:
90 return 0;
91 }
92}
93#endif /* CONFIG_IEEE80211R */
94
95
567da5bb 96unsigned int wpa_mic_len(int akmp, size_t pmk_len)
5e3b5197 97{
94318a0d
JM
98 switch (akmp) {
99 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
c22bb5bb 100 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
5e3b5197 101 return 24;
94318a0d
JM
102 case WPA_KEY_MGMT_FILS_SHA256:
103 case WPA_KEY_MGMT_FILS_SHA384:
104 case WPA_KEY_MGMT_FT_FILS_SHA256:
105 case WPA_KEY_MGMT_FT_FILS_SHA384:
106 return 0;
567da5bb
JM
107 case WPA_KEY_MGMT_DPP:
108 return pmk_len / 2;
6c472618
JM
109 case WPA_KEY_MGMT_OWE:
110 return pmk_len / 2;
94318a0d
JM
111 default:
112 return 16;
113 }
98cd3d1c
JM
114}
115
116
4bc801ab
JM
117/**
118 * wpa_use_akm_defined - Is AKM-defined Key Descriptor Version used
119 * @akmp: WPA_KEY_MGMT_* used in key derivation
120 * Returns: 1 if AKM-defined Key Descriptor Version is used; 0 otherwise
121 */
122int wpa_use_akm_defined(int akmp)
123{
124 return akmp == WPA_KEY_MGMT_OSEN ||
125 akmp == WPA_KEY_MGMT_OWE ||
126 akmp == WPA_KEY_MGMT_DPP ||
c22bb5bb 127 akmp == WPA_KEY_MGMT_FT_IEEE8021X_SHA384 ||
4bc801ab
JM
128 wpa_key_mgmt_sae(akmp) ||
129 wpa_key_mgmt_suite_b(akmp) ||
130 wpa_key_mgmt_fils(akmp);
131}
132
133
134/**
135 * wpa_use_cmac - Is CMAC integrity algorithm used for EAPOL-Key MIC
136 * @akmp: WPA_KEY_MGMT_* used in key derivation
137 * Returns: 1 if CMAC is used; 0 otherwise
138 */
139int wpa_use_cmac(int akmp)
140{
141 return akmp == WPA_KEY_MGMT_OSEN ||
142 akmp == WPA_KEY_MGMT_OWE ||
143 akmp == WPA_KEY_MGMT_DPP ||
144 wpa_key_mgmt_ft(akmp) ||
145 wpa_key_mgmt_sha256(akmp) ||
146 wpa_key_mgmt_sae(akmp) ||
147 wpa_key_mgmt_suite_b(akmp);
148}
149
150
151/**
152 * wpa_use_aes_key_wrap - Is AES Keywrap algorithm used for EAPOL-Key Key Data
153 * @akmp: WPA_KEY_MGMT_* used in key derivation
154 * Returns: 1 if AES Keywrap is used; 0 otherwise
155 *
156 * Note: AKM 00-0F-AC:1 and 00-0F-AC:2 have special rules for selecting whether
157 * to use AES Keywrap based on the negotiated pairwise cipher. This function
158 * does not cover those special cases.
159 */
160int wpa_use_aes_key_wrap(int akmp)
161{
162 return akmp == WPA_KEY_MGMT_OSEN ||
163 akmp == WPA_KEY_MGMT_OWE ||
164 akmp == WPA_KEY_MGMT_DPP ||
165 wpa_key_mgmt_ft(akmp) ||
166 wpa_key_mgmt_sha256(akmp) ||
167 wpa_key_mgmt_sae(akmp) ||
168 wpa_key_mgmt_suite_b(akmp);
169}
170
171
6fc6879b
JM
172/**
173 * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
174 * @key: EAPOL-Key Key Confirmation Key (KCK)
98cd3d1c 175 * @key_len: KCK length in octets
929a2ea5 176 * @akmp: WPA_KEY_MGMT_* used in key derivation
6fc6879b
JM
177 * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
178 * @buf: Pointer to the beginning of the EAPOL header (version field)
179 * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
180 * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
181 * Returns: 0 on success, -1 on failure
182 *
183 * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
184 * to be cleared (all zeroes) when calling this function.
185 *
186 * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
187 * description of the Key MIC calculation. It includes packet data from the
188 * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
189 * happened during final editing of the standard and the correct behavior is
190 * defined in the last draft (IEEE 802.11i/D10).
191 */
98cd3d1c
JM
192int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
193 const u8 *buf, size_t len, u8 *mic)
6fc6879b 194{
567da5bb 195 u8 hash[SHA512_MAC_LEN];
6fc6879b 196
a6ea6653
JM
197 if (key_len == 0) {
198 wpa_printf(MSG_DEBUG,
199 "WPA: KCK not set - cannot calculate MIC");
200 return -1;
201 }
202
6fc6879b 203 switch (ver) {
6e6909a9 204#ifndef CONFIG_FIPS
6fc6879b 205 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
ef9627cb 206 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-MD5");
98cd3d1c 207 return hmac_md5(key, key_len, buf, len, mic);
6e6909a9 208#endif /* CONFIG_FIPS */
6fc6879b 209 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
ef9627cb 210 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-SHA1");
98cd3d1c 211 if (hmac_sha1(key, key_len, buf, len, hash))
04b6b3ed 212 return -1;
6fc6879b
JM
213 os_memcpy(mic, hash, MD5_MAC_LEN);
214 break;
a20088e5 215#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
6fc6879b 216 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
ef9627cb 217 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using AES-CMAC");
6fc6879b 218 return omac1_aes_128(key, buf, len, mic);
a20088e5 219#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
a5d75636 220 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
929a2ea5 221 switch (akmp) {
4bc801ab
JM
222#ifdef CONFIG_SAE
223 case WPA_KEY_MGMT_SAE:
224 case WPA_KEY_MGMT_FT_SAE:
225 wpa_printf(MSG_DEBUG,
226 "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - SAE)");
227 return omac1_aes_128(key, buf, len, mic);
228#endif /* CONFIG_SAE */
929a2ea5
JM
229#ifdef CONFIG_HS20
230 case WPA_KEY_MGMT_OSEN:
ef9627cb
JM
231 wpa_printf(MSG_DEBUG,
232 "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - OSEN)");
929a2ea5 233 return omac1_aes_128(key, buf, len, mic);
a5d75636 234#endif /* CONFIG_HS20 */
929a2ea5
JM
235#ifdef CONFIG_SUITEB
236 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
ef9627cb
JM
237 wpa_printf(MSG_DEBUG,
238 "WPA: EAPOL-Key MIC using HMAC-SHA256 (AKM-defined - Suite B)");
98cd3d1c 239 if (hmac_sha256(key, key_len, buf, len, hash))
929a2ea5
JM
240 return -1;
241 os_memcpy(mic, hash, MD5_MAC_LEN);
242 break;
243#endif /* CONFIG_SUITEB */
5e3b5197
JM
244#ifdef CONFIG_SUITEB192
245 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
ef9627cb
JM
246 wpa_printf(MSG_DEBUG,
247 "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - Suite B 192-bit)");
5e3b5197
JM
248 if (hmac_sha384(key, key_len, buf, len, hash))
249 return -1;
250 os_memcpy(mic, hash, 24);
251 break;
252#endif /* CONFIG_SUITEB192 */
07a5fe82
JM
253#ifdef CONFIG_OWE
254 case WPA_KEY_MGMT_OWE:
255 wpa_printf(MSG_DEBUG,
6c472618
JM
256 "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - OWE)",
257 (unsigned int) key_len * 8 * 2);
258 if (key_len == 128 / 8) {
259 if (hmac_sha256(key, key_len, buf, len, hash))
260 return -1;
261 } else if (key_len == 192 / 8) {
262 if (hmac_sha384(key, key_len, buf, len, hash))
263 return -1;
264 } else if (key_len == 256 / 8) {
265 if (hmac_sha512(key, key_len, buf, len, hash))
266 return -1;
267 } else {
268 wpa_printf(MSG_INFO,
269 "OWE: Unsupported KCK length: %u",
270 (unsigned int) key_len);
07a5fe82 271 return -1;
6c472618
JM
272 }
273 os_memcpy(mic, hash, key_len);
07a5fe82
JM
274 break;
275#endif /* CONFIG_OWE */
567da5bb
JM
276#ifdef CONFIG_DPP
277 case WPA_KEY_MGMT_DPP:
278 wpa_printf(MSG_DEBUG,
279 "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - DPP)",
280 (unsigned int) key_len * 8 * 2);
281 if (key_len == 128 / 8) {
282 if (hmac_sha256(key, key_len, buf, len, hash))
283 return -1;
284 } else if (key_len == 192 / 8) {
285 if (hmac_sha384(key, key_len, buf, len, hash))
286 return -1;
287 } else if (key_len == 256 / 8) {
8b5579e1 288 if (hmac_sha512(key, key_len, buf, len, hash))
567da5bb
JM
289 return -1;
290 } else {
291 wpa_printf(MSG_INFO,
292 "DPP: Unsupported KCK length: %u",
293 (unsigned int) key_len);
294 return -1;
295 }
8b5579e1 296 os_memcpy(mic, hash, key_len);
567da5bb
JM
297 break;
298#endif /* CONFIG_DPP */
c49a9d6b
JM
299#if defined(CONFIG_IEEE80211R) && defined(CONFIG_SHA384)
300 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
301 wpa_printf(MSG_DEBUG,
302 "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - FT 802.1X SHA384)");
303 if (hmac_sha384(key, key_len, buf, len, hash))
304 return -1;
305 os_memcpy(mic, hash, 24);
306 break;
307#endif /* CONFIG_IEEE80211R && CONFIG_SHA384 */
929a2ea5 308 default:
ef9627cb
JM
309 wpa_printf(MSG_DEBUG,
310 "WPA: EAPOL-Key MIC algorithm not known (AKM-defined - akmp=0x%x)",
311 akmp);
929a2ea5
JM
312 return -1;
313 }
314 break;
6fc6879b 315 default:
ef9627cb
JM
316 wpa_printf(MSG_DEBUG,
317 "WPA: EAPOL-Key MIC algorithm not known (ver=%d)",
318 ver);
6fc6879b
JM
319 return -1;
320 }
321
322 return 0;
323}
324
325
326/**
327 * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
328 * @pmk: Pairwise master key
329 * @pmk_len: Length of PMK
330 * @label: Label to use in derivation
331 * @addr1: AA or SA
332 * @addr2: SA or AA
333 * @nonce1: ANonce or SNonce
334 * @nonce2: SNonce or ANonce
335 * @ptk: Buffer for pairwise transient key
98cd3d1c
JM
336 * @akmp: Negotiated AKM
337 * @cipher: Negotiated pairwise cipher
338 * Returns: 0 on success, -1 on failure
6fc6879b
JM
339 *
340 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
341 * PTK = PRF-X(PMK, "Pairwise key expansion",
342 * Min(AA, SA) || Max(AA, SA) ||
343 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
6fc6879b 344 */
98cd3d1c
JM
345int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
346 const u8 *addr1, const u8 *addr2,
347 const u8 *nonce1, const u8 *nonce2,
348 struct wpa_ptk *ptk, int akmp, int cipher)
6fc6879b
JM
349{
350 u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
98cd3d1c
JM
351 u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
352 size_t ptk_len;
6fc6879b 353
b488a129 354 if (pmk_len == 0) {
8e402d16 355 wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
b488a129
JM
356 return -1;
357 }
358
6fc6879b
JM
359 if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
360 os_memcpy(data, addr1, ETH_ALEN);
361 os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
362 } else {
363 os_memcpy(data, addr2, ETH_ALEN);
364 os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
365 }
366
367 if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
368 os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
369 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
370 WPA_NONCE_LEN);
371 } else {
372 os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
373 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
374 WPA_NONCE_LEN);
375 }
376
567da5bb
JM
377 ptk->kck_len = wpa_kck_len(akmp, pmk_len);
378 ptk->kek_len = wpa_kek_len(akmp, pmk_len);
98cd3d1c 379 ptk->tk_len = wpa_cipher_key_len(cipher);
1d624a07
JM
380 if (ptk->tk_len == 0) {
381 wpa_printf(MSG_ERROR,
382 "WPA: Unsupported cipher (0x%x) used in PTK derivation",
383 cipher);
384 return -1;
385 }
98cd3d1c
JM
386 ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
387
ef9627cb 388 if (wpa_key_mgmt_sha384(akmp)) {
e491389e 389#if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS)
ef9627cb
JM
390 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
391 if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
392 tmp, ptk_len) < 0)
393 return -1;
394#else /* CONFIG_SUITEB192 || CONFIG_FILS */
395 return -1;
e491389e 396#endif /* CONFIG_SUITEB192 || CONFIG_FILS */
07a5fe82 397 } else if (wpa_key_mgmt_sha256(akmp) || akmp == WPA_KEY_MGMT_OWE) {
2598e693 398#if defined(CONFIG_IEEE80211W) || defined(CONFIG_SAE) || defined(CONFIG_FILS)
ef9627cb
JM
399 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
400 if (sha256_prf(pmk, pmk_len, label, data, sizeof(data),
401 tmp, ptk_len) < 0)
402 return -1;
2598e693 403#else /* CONFIG_IEEE80211W or CONFIG_SAE or CONFIG_FILS */
ef9627cb 404 return -1;
2598e693 405#endif /* CONFIG_IEEE80211W or CONFIG_SAE or CONFIG_FILS */
567da5bb
JM
406#ifdef CONFIG_DPP
407 } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
408 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
409 if (sha256_prf(pmk, pmk_len, label, data, sizeof(data),
410 tmp, ptk_len) < 0)
411 return -1;
412 } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
413 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
414 if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
415 tmp, ptk_len) < 0)
416 return -1;
417 } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
418 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
419 if (sha512_prf(pmk, pmk_len, label, data, sizeof(data),
420 tmp, ptk_len) < 0)
421 return -1;
422 } else if (akmp == WPA_KEY_MGMT_DPP) {
423 wpa_printf(MSG_INFO, "DPP: Unknown PMK length %u",
424 (unsigned int) pmk_len);
425 return -1;
426#endif /* CONFIG_DPP */
ef9627cb
JM
427 } else {
428 wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
429 if (sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp,
430 ptk_len) < 0)
431 return -1;
432 }
6fc6879b
JM
433
434 wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
435 MAC2STR(addr1), MAC2STR(addr2));
bc8318ac
JM
436 wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
437 wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
6fc6879b 438 wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
98cd3d1c
JM
439 wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
440
441 os_memcpy(ptk->kck, tmp, ptk->kck_len);
442 wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
443
444 os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
445 wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
446
447 os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
448 wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
449
2f373878
JM
450 ptk->kek2_len = 0;
451 ptk->kck2_len = 0;
452
98cd3d1c
JM
453 os_memset(tmp, 0, sizeof(tmp));
454 return 0;
6fc6879b
JM
455}
456
c089bc57 457#ifdef CONFIG_FILS
a852ab4c 458
fcd3d6ce
JM
459int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
460 const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
461 size_t dh_ss_len, u8 *pmk, size_t *pmk_len)
462{
463 u8 nonces[2 * FILS_NONCE_LEN];
464 const u8 *addr[2];
465 size_t len[2];
466 size_t num_elem;
467 int res;
468
469 /* PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ]) */
470 wpa_printf(MSG_DEBUG, "FILS: rMSK to PMK derivation");
471
472 if (wpa_key_mgmt_sha384(akmp))
473 *pmk_len = SHA384_MAC_LEN;
474 else if (wpa_key_mgmt_sha256(akmp))
475 *pmk_len = SHA256_MAC_LEN;
476 else
477 return -1;
478
479 wpa_hexdump_key(MSG_DEBUG, "FILS: rMSK", rmsk, rmsk_len);
480 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
481 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
482 wpa_hexdump(MSG_DEBUG, "FILS: DHss", dh_ss, dh_ss_len);
483
484 os_memcpy(nonces, snonce, FILS_NONCE_LEN);
485 os_memcpy(&nonces[FILS_NONCE_LEN], anonce, FILS_NONCE_LEN);
486 addr[0] = rmsk;
487 len[0] = rmsk_len;
488 num_elem = 1;
489 if (dh_ss) {
490 addr[1] = dh_ss;
491 len[1] = dh_ss_len;
492 num_elem++;
493 }
494 if (wpa_key_mgmt_sha384(akmp))
495 res = hmac_sha384_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
496 addr, len, pmk);
497 else
498 res = hmac_sha256_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
499 addr, len, pmk);
500 if (res == 0)
501 wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, *pmk_len);
1bd13110
JM
502 else
503 *pmk_len = 0;
fcd3d6ce
JM
504 return res;
505}
506
507
508int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
509 u8 *pmkid)
510{
511 const u8 *addr[1];
512 size_t len[1];
513 u8 hash[SHA384_MAC_LEN];
514 int res;
515
516 /* PMKID = Truncate-128(Hash(EAP-Initiate/Reauth)) */
517 addr[0] = reauth;
518 len[0] = reauth_len;
519 if (wpa_key_mgmt_sha384(akmp))
520 res = sha384_vector(1, addr, len, hash);
521 else if (wpa_key_mgmt_sha256(akmp))
522 res = sha256_vector(1, addr, len, hash);
523 else
524 return -1;
525 if (res)
526 return res;
527 os_memcpy(pmkid, hash, PMKID_LEN);
528 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
529 return 0;
530}
531
532
c089bc57 533int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
4cada9dc
JM
534 const u8 *snonce, const u8 *anonce, const u8 *dhss,
535 size_t dhss_len, struct wpa_ptk *ptk,
215eaa74
JM
536 u8 *ick, size_t *ick_len, int akmp, int cipher,
537 u8 *fils_ft, size_t *fils_ft_len)
c089bc57 538{
4cada9dc
JM
539 u8 *data, *pos;
540 size_t data_len;
215eaa74
JM
541 u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
542 FILS_FT_MAX_LEN];
c089bc57
JM
543 size_t key_data_len;
544 const char *label = "FILS PTK Derivation";
4cada9dc 545 int ret = -1;
c089bc57
JM
546
547 /*
548 * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
4cada9dc 549 * SPA || AA || SNonce || ANonce [ || DHss ])
c089bc57
JM
550 * ICK = L(FILS-Key-Data, 0, ICK_bits)
551 * KEK = L(FILS-Key-Data, ICK_bits, KEK_bits)
552 * TK = L(FILS-Key-Data, ICK_bits + KEK_bits, TK_bits)
553 * If doing FT initial mobility domain association:
554 * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
555 * FILS-FT_bits)
556 */
4cada9dc
JM
557 data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
558 data = os_malloc(data_len);
559 if (!data)
560 goto err;
561 pos = data;
562 os_memcpy(pos, spa, ETH_ALEN);
563 pos += ETH_ALEN;
564 os_memcpy(pos, aa, ETH_ALEN);
565 pos += ETH_ALEN;
566 os_memcpy(pos, snonce, FILS_NONCE_LEN);
567 pos += FILS_NONCE_LEN;
568 os_memcpy(pos, anonce, FILS_NONCE_LEN);
569 pos += FILS_NONCE_LEN;
570 if (dhss)
571 os_memcpy(pos, dhss, dhss_len);
c089bc57
JM
572
573 ptk->kck_len = 0;
567da5bb 574 ptk->kek_len = wpa_kek_len(akmp, pmk_len);
c089bc57
JM
575 ptk->tk_len = wpa_cipher_key_len(cipher);
576 if (wpa_key_mgmt_sha384(akmp))
577 *ick_len = 48;
578 else if (wpa_key_mgmt_sha256(akmp))
579 *ick_len = 32;
580 else
4cada9dc 581 goto err;
c089bc57
JM
582 key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
583
215eaa74
JM
584 if (fils_ft && fils_ft_len) {
585 if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
586 *fils_ft_len = 32;
587 } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
588 *fils_ft_len = 48;
589 } else {
590 *fils_ft_len = 0;
591 fils_ft = NULL;
592 }
593 key_data_len += *fils_ft_len;
594 }
595
ef9627cb
JM
596 if (wpa_key_mgmt_sha384(akmp)) {
597 wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
4cada9dc 598 if (sha384_prf(pmk, pmk_len, label, data, data_len,
ef9627cb 599 tmp, key_data_len) < 0)
4cada9dc 600 goto err;
ef9627cb
JM
601 } else {
602 wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA256)");
4cada9dc 603 if (sha256_prf(pmk, pmk_len, label, data, data_len,
ef9627cb 604 tmp, key_data_len) < 0)
4cada9dc 605 goto err;
ef9627cb 606 }
c089bc57
JM
607
608 wpa_printf(MSG_DEBUG, "FILS: PTK derivation - SPA=" MACSTR
609 " AA=" MACSTR, MAC2STR(spa), MAC2STR(aa));
610 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
611 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
4cada9dc
JM
612 if (dhss)
613 wpa_hexdump_key(MSG_DEBUG, "FILS: DHss", dhss, dhss_len);
c089bc57
JM
614 wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, pmk_len);
615 wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
616
617 os_memcpy(ick, tmp, *ick_len);
618 wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
619
620 os_memcpy(ptk->kek, tmp + *ick_len, ptk->kek_len);
621 wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
622
623 os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
624 wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
625
215eaa74
JM
626 if (fils_ft && fils_ft_len) {
627 os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
628 *fils_ft_len);
629 wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
630 fils_ft, *fils_ft_len);
631 }
c089bc57 632
2f373878
JM
633 ptk->kek2_len = 0;
634 ptk->kck2_len = 0;
635
c089bc57 636 os_memset(tmp, 0, sizeof(tmp));
4cada9dc
JM
637 ret = 0;
638err:
639 bin_clear_free(data, data_len);
640 return ret;
c089bc57
JM
641}
642
a852ab4c
JM
643
644int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
645 const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
646 const u8 *g_sta, size_t g_sta_len,
647 const u8 *g_ap, size_t g_ap_len,
648 int akmp, u8 *key_auth_sta, u8 *key_auth_ap,
649 size_t *key_auth_len)
650{
651 const u8 *addr[6];
652 size_t len[6];
653 size_t num_elem = 4;
654 int res;
655
4d0a61c5
JM
656 wpa_printf(MSG_DEBUG, "FILS: Key-Auth derivation: STA-MAC=" MACSTR
657 " AP-BSSID=" MACSTR, MAC2STR(sta_addr), MAC2STR(bssid));
658 wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, ick_len);
659 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
660 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
661 wpa_hexdump(MSG_DEBUG, "FILS: gSTA", g_sta, g_sta_len);
662 wpa_hexdump(MSG_DEBUG, "FILS: gAP", g_ap, g_ap_len);
663
a852ab4c
JM
664 /*
665 * For (Re)Association Request frame (STA->AP):
666 * Key-Auth = HMAC-Hash(ICK, SNonce || ANonce || STA-MAC || AP-BSSID
667 * [ || gSTA || gAP ])
668 */
669 addr[0] = snonce;
670 len[0] = FILS_NONCE_LEN;
671 addr[1] = anonce;
672 len[1] = FILS_NONCE_LEN;
673 addr[2] = sta_addr;
674 len[2] = ETH_ALEN;
675 addr[3] = bssid;
676 len[3] = ETH_ALEN;
677 if (g_sta && g_ap_len && g_ap && g_ap_len) {
678 addr[4] = g_sta;
679 len[4] = g_sta_len;
680 addr[5] = g_ap;
681 len[5] = g_ap_len;
682 num_elem = 6;
683 }
684
685 if (wpa_key_mgmt_sha384(akmp)) {
686 *key_auth_len = 48;
687 res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
688 key_auth_sta);
689 } else if (wpa_key_mgmt_sha256(akmp)) {
690 *key_auth_len = 32;
691 res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
692 key_auth_sta);
693 } else {
694 return -1;
695 }
696 if (res < 0)
697 return res;
698
699 /*
700 * For (Re)Association Response frame (AP->STA):
701 * Key-Auth = HMAC-Hash(ICK, ANonce || SNonce || AP-BSSID || STA-MAC
702 * [ || gAP || gSTA ])
703 */
704 addr[0] = anonce;
705 addr[1] = snonce;
706 addr[2] = bssid;
707 addr[3] = sta_addr;
708 if (g_sta && g_ap_len && g_ap && g_ap_len) {
709 addr[4] = g_ap;
710 len[4] = g_ap_len;
711 addr[5] = g_sta;
712 len[5] = g_sta_len;
713 }
714
715 if (wpa_key_mgmt_sha384(akmp))
716 res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
717 key_auth_ap);
718 else if (wpa_key_mgmt_sha256(akmp))
719 res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
720 key_auth_ap);
721 if (res < 0)
722 return res;
723
724 wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (STA)",
725 key_auth_sta, *key_auth_len);
726 wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (AP)",
727 key_auth_ap, *key_auth_len);
728
729 return 0;
730}
731
c089bc57
JM
732#endif /* CONFIG_FILS */
733
6fc6879b
JM
734
735#ifdef CONFIG_IEEE80211R
98cd3d1c
JM
736int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
737 const u8 *ap_addr, u8 transaction_seqnum,
738 const u8 *mdie, size_t mdie_len,
6fc6879b
JM
739 const u8 *ftie, size_t ftie_len,
740 const u8 *rsnie, size_t rsnie_len,
741 const u8 *ric, size_t ric_len, u8 *mic)
742{
8b949804
JM
743 const u8 *addr[9];
744 size_t len[9];
745 size_t i, num_elem = 0;
b327026a
JM
746 u8 zero_mic[24];
747 size_t mic_len, fte_fixed_len;
748
749 if (kck_len == 16) {
750 mic_len = 16;
751#ifdef CONFIG_SHA384
752 } else if (kck_len == 24) {
753 mic_len = 24;
754#endif /* CONFIG_SHA384 */
755 } else {
98cd3d1c
JM
756 wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
757 (unsigned int) kck_len);
758 return -1;
759 }
760
b327026a
JM
761 fte_fixed_len = sizeof(struct rsn_ftie) - 16 + mic_len;
762
8b949804
JM
763 addr[num_elem] = sta_addr;
764 len[num_elem] = ETH_ALEN;
765 num_elem++;
766
767 addr[num_elem] = ap_addr;
768 len[num_elem] = ETH_ALEN;
769 num_elem++;
770
771 addr[num_elem] = &transaction_seqnum;
772 len[num_elem] = 1;
773 num_elem++;
6fc6879b 774
6fc6879b 775 if (rsnie) {
8b949804
JM
776 addr[num_elem] = rsnie;
777 len[num_elem] = rsnie_len;
778 num_elem++;
6fc6879b
JM
779 }
780 if (mdie) {
8b949804
JM
781 addr[num_elem] = mdie;
782 len[num_elem] = mdie_len;
783 num_elem++;
6fc6879b
JM
784 }
785 if (ftie) {
b327026a 786 if (ftie_len < 2 + fte_fixed_len)
6fc6879b 787 return -1;
8b949804
JM
788
789 /* IE hdr and mic_control */
790 addr[num_elem] = ftie;
791 len[num_elem] = 2 + 2;
792 num_elem++;
793
794 /* MIC field with all zeros */
b327026a 795 os_memset(zero_mic, 0, mic_len);
8b949804 796 addr[num_elem] = zero_mic;
b327026a 797 len[num_elem] = mic_len;
8b949804
JM
798 num_elem++;
799
800 /* Rest of FTIE */
b327026a
JM
801 addr[num_elem] = ftie + 2 + 2 + mic_len;
802 len[num_elem] = ftie_len - (2 + 2 + mic_len);
8b949804 803 num_elem++;
6fc6879b
JM
804 }
805 if (ric) {
8b949804
JM
806 addr[num_elem] = ric;
807 len[num_elem] = ric_len;
808 num_elem++;
6fc6879b
JM
809 }
810
8b949804
JM
811 for (i = 0; i < num_elem; i++)
812 wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
b327026a
JM
813#ifdef CONFIG_SHA384
814 if (kck_len == 24) {
815 u8 hash[SHA384_MAC_LEN];
816
817 if (hmac_sha384_vector(kck, kck_len, num_elem, addr, len, hash))
818 return -1;
819 os_memcpy(mic, hash, 24);
820 }
821#endif /* CONFIG_SHA384 */
822 if (kck_len == 16 &&
823 omac1_aes_128_vector(kck, num_elem, addr, len, mic))
6fc6879b 824 return -1;
6fc6879b
JM
825
826 return 0;
827}
6554237f
JM
828
829
830static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
831 struct wpa_ft_ies *parse)
832{
833 const u8 *end, *pos;
834
835 parse->ftie = ie;
836 parse->ftie_len = ie_len;
837
838 pos = ie + sizeof(struct rsn_ftie);
839 end = ie + ie_len;
840
7b5880fc
JM
841 while (end - pos >= 2) {
842 u8 id, len;
843
844 id = *pos++;
845 len = *pos++;
846 if (len > end - pos)
847 break;
848
849 switch (id) {
6554237f 850 case FTIE_SUBELEM_R1KH_ID:
7b5880fc
JM
851 if (len != FT_R1KH_ID_LEN) {
852 wpa_printf(MSG_DEBUG,
853 "FT: Invalid R1KH-ID length in FTIE: %d",
854 len);
6554237f
JM
855 return -1;
856 }
7b5880fc 857 parse->r1kh_id = pos;
6554237f
JM
858 break;
859 case FTIE_SUBELEM_GTK:
7b5880fc
JM
860 parse->gtk = pos;
861 parse->gtk_len = len;
6554237f
JM
862 break;
863 case FTIE_SUBELEM_R0KH_ID:
7b5880fc
JM
864 if (len < 1 || len > FT_R0KH_ID_MAX_LEN) {
865 wpa_printf(MSG_DEBUG,
866 "FT: Invalid R0KH-ID length in FTIE: %d",
867 len);
6554237f
JM
868 return -1;
869 }
7b5880fc
JM
870 parse->r0kh_id = pos;
871 parse->r0kh_id_len = len;
6554237f
JM
872 break;
873#ifdef CONFIG_IEEE80211W
874 case FTIE_SUBELEM_IGTK:
7b5880fc
JM
875 parse->igtk = pos;
876 parse->igtk_len = len;
6554237f
JM
877 break;
878#endif /* CONFIG_IEEE80211W */
879 }
880
7b5880fc 881 pos += len;
6554237f
JM
882 }
883
884 return 0;
885}
886
887
888int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
889 struct wpa_ft_ies *parse)
890{
891 const u8 *end, *pos;
892 struct wpa_ie_data data;
893 int ret;
894 const struct rsn_ftie *ftie;
895 int prot_ie_count = 0;
896
897 os_memset(parse, 0, sizeof(*parse));
898 if (ies == NULL)
899 return 0;
900
901 pos = ies;
902 end = ies + ies_len;
7b5880fc
JM
903 while (end - pos >= 2) {
904 u8 id, len;
905
906 id = *pos++;
907 len = *pos++;
908 if (len > end - pos)
909 break;
910
911 switch (id) {
6554237f 912 case WLAN_EID_RSN:
7b5880fc
JM
913 parse->rsn = pos;
914 parse->rsn_len = len;
6554237f
JM
915 ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
916 parse->rsn_len + 2,
917 &data);
918 if (ret < 0) {
919 wpa_printf(MSG_DEBUG, "FT: Failed to parse "
920 "RSN IE: %d", ret);
921 return -1;
922 }
923 if (data.num_pmkid == 1 && data.pmkid)
924 parse->rsn_pmkid = data.pmkid;
96590564
MB
925 parse->key_mgmt = data.key_mgmt;
926 parse->pairwise_cipher = data.pairwise_cipher;
6554237f
JM
927 break;
928 case WLAN_EID_MOBILITY_DOMAIN:
7b5880fc 929 if (len < sizeof(struct rsn_mdie))
ae7a42bd 930 return -1;
7b5880fc
JM
931 parse->mdie = pos;
932 parse->mdie_len = len;
6554237f
JM
933 break;
934 case WLAN_EID_FAST_BSS_TRANSITION:
7b5880fc 935 if (len < sizeof(*ftie))
6554237f 936 return -1;
7b5880fc 937 ftie = (const struct rsn_ftie *) pos;
6554237f 938 prot_ie_count = ftie->mic_control[1];
7b5880fc 939 if (wpa_ft_parse_ftie(pos, len, parse) < 0)
6554237f
JM
940 return -1;
941 break;
942 case WLAN_EID_TIMEOUT_INTERVAL:
7b5880fc 943 if (len != 5)
ae7a42bd 944 break;
7b5880fc
JM
945 parse->tie = pos;
946 parse->tie_len = len;
6554237f
JM
947 break;
948 case WLAN_EID_RIC_DATA:
949 if (parse->ric == NULL)
7b5880fc 950 parse->ric = pos - 2;
6554237f
JM
951 break;
952 }
953
7b5880fc 954 pos += len;
6554237f
JM
955 }
956
957 if (prot_ie_count == 0)
958 return 0; /* no MIC */
959
960 /*
961 * Check that the protected IE count matches with IEs included in the
962 * frame.
963 */
964 if (parse->rsn)
965 prot_ie_count--;
966 if (parse->mdie)
967 prot_ie_count--;
968 if (parse->ftie)
969 prot_ie_count--;
970 if (prot_ie_count < 0) {
971 wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
972 "the protected IE count");
973 return -1;
974 }
975
976 if (prot_ie_count == 0 && parse->ric) {
977 wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
978 "included in protected IE count");
979 return -1;
980 }
981
982 /* Determine the end of the RIC IE(s) */
7b5880fc
JM
983 if (parse->ric) {
984 pos = parse->ric;
985 while (end - pos >= 2 && 2 + pos[1] <= end - pos &&
986 prot_ie_count) {
987 prot_ie_count--;
988 pos += 2 + pos[1];
989 }
990 parse->ric_len = pos - parse->ric;
6554237f 991 }
6554237f
JM
992 if (prot_ie_count) {
993 wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
994 "frame", (int) prot_ie_count);
995 return -1;
996 }
997
998 return 0;
999}
6fc6879b
JM
1000#endif /* CONFIG_IEEE80211R */
1001
1002
6fc6879b
JM
1003static int rsn_selector_to_bitfield(const u8 *s)
1004{
1005 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
1006 return WPA_CIPHER_NONE;
6fc6879b
JM
1007 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
1008 return WPA_CIPHER_TKIP;
1009 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
1010 return WPA_CIPHER_CCMP;
6fc6879b
JM
1011#ifdef CONFIG_IEEE80211W
1012 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
1013 return WPA_CIPHER_AES_128_CMAC;
1014#endif /* CONFIG_IEEE80211W */
eb7719ff
JM
1015 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
1016 return WPA_CIPHER_GCMP;
30675c34
JM
1017 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
1018 return WPA_CIPHER_CCMP_256;
1019 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
1020 return WPA_CIPHER_GCMP_256;
1021 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
1022 return WPA_CIPHER_BIP_GMAC_128;
1023 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
1024 return WPA_CIPHER_BIP_GMAC_256;
1025 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
1026 return WPA_CIPHER_BIP_CMAC_256;
8dd9f9cd
JM
1027 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
1028 return WPA_CIPHER_GTK_NOT_USED;
6fc6879b
JM
1029 return 0;
1030}
1031
1032
1033static int rsn_key_mgmt_to_bitfield(const u8 *s)
1034{
1035 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
1036 return WPA_KEY_MGMT_IEEE8021X;
1037 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
1038 return WPA_KEY_MGMT_PSK;
1039#ifdef CONFIG_IEEE80211R
1040 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
1041 return WPA_KEY_MGMT_FT_IEEE8021X;
1042 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
1043 return WPA_KEY_MGMT_FT_PSK;
c22bb5bb
JM
1044#ifdef CONFIG_SHA384
1045 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384)
1046 return WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
1047#endif /* CONFIG_SHA384 */
6fc6879b 1048#endif /* CONFIG_IEEE80211R */
56586197
JM
1049#ifdef CONFIG_IEEE80211W
1050 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
1051 return WPA_KEY_MGMT_IEEE8021X_SHA256;
1052 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
1053 return WPA_KEY_MGMT_PSK_SHA256;
1054#endif /* CONFIG_IEEE80211W */
c10347f2
JM
1055#ifdef CONFIG_SAE
1056 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
1057 return WPA_KEY_MGMT_SAE;
1058 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
1059 return WPA_KEY_MGMT_FT_SAE;
1060#endif /* CONFIG_SAE */
666497c8
JM
1061 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
1062 return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
5e3b5197
JM
1063 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
1064 return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
94318a0d
JM
1065 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA256)
1066 return WPA_KEY_MGMT_FILS_SHA256;
1067 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA384)
1068 return WPA_KEY_MGMT_FILS_SHA384;
1069 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA256)
1070 return WPA_KEY_MGMT_FT_FILS_SHA256;
1071 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA384)
1072 return WPA_KEY_MGMT_FT_FILS_SHA384;
a1ea1b45
JM
1073#ifdef CONFIG_OWE
1074 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
1075 return WPA_KEY_MGMT_OWE;
1076#endif /* CONFIG_OWE */
567da5bb
JM
1077#ifdef CONFIG_DPP
1078 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_DPP)
1079 return WPA_KEY_MGMT_DPP;
1080#endif /* CONFIG_DPP */
0f8385e6
BG
1081 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
1082 return WPA_KEY_MGMT_OSEN;
6fc6879b
JM
1083 return 0;
1084}
6fc6879b
JM
1085
1086
05a90d78 1087int wpa_cipher_valid_group(int cipher)
8dd9f9cd
JM
1088{
1089 return wpa_cipher_valid_pairwise(cipher) ||
8dd9f9cd
JM
1090 cipher == WPA_CIPHER_GTK_NOT_USED;
1091}
1092
1093
1094#ifdef CONFIG_IEEE80211W
1095int wpa_cipher_valid_mgmt_group(int cipher)
1096{
1097 return cipher == WPA_CIPHER_AES_128_CMAC ||
1098 cipher == WPA_CIPHER_BIP_GMAC_128 ||
1099 cipher == WPA_CIPHER_BIP_GMAC_256 ||
1100 cipher == WPA_CIPHER_BIP_CMAC_256;
1101}
1102#endif /* CONFIG_IEEE80211W */
1103
1104
6fc6879b
JM
1105/**
1106 * wpa_parse_wpa_ie_rsn - Parse RSN IE
1107 * @rsn_ie: Buffer containing RSN IE
1108 * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
1109 * @data: Pointer to structure that will be filled in with parsed data
1110 * Returns: 0 on success, <0 on failure
1111 */
1112int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
1113 struct wpa_ie_data *data)
1114{
6fc6879b
JM
1115 const u8 *pos;
1116 int left;
1117 int i, count;
1118
1119 os_memset(data, 0, sizeof(*data));
1120 data->proto = WPA_PROTO_RSN;
1121 data->pairwise_cipher = WPA_CIPHER_CCMP;
1122 data->group_cipher = WPA_CIPHER_CCMP;
1123 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1124 data->capabilities = 0;
1125 data->pmkid = NULL;
1126 data->num_pmkid = 0;
1127#ifdef CONFIG_IEEE80211W
1128 data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1129#else /* CONFIG_IEEE80211W */
1130 data->mgmt_group_cipher = 0;
1131#endif /* CONFIG_IEEE80211W */
1132
1133 if (rsn_ie_len == 0) {
1134 /* No RSN IE - fail silently */
1135 return -1;
1136 }
1137
1138 if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
1139 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
1140 __func__, (unsigned long) rsn_ie_len);
1141 return -1;
1142 }
1143
0f8385e6
BG
1144 if (rsn_ie_len >= 6 && rsn_ie[1] >= 4 &&
1145 rsn_ie[1] == rsn_ie_len - 2 &&
1146 WPA_GET_BE32(&rsn_ie[2]) == OSEN_IE_VENDOR_TYPE) {
1147 pos = rsn_ie + 6;
1148 left = rsn_ie_len - 6;
6fc6879b 1149
0f8385e6
BG
1150 data->proto = WPA_PROTO_OSEN;
1151 } else {
1152 const struct rsn_ie_hdr *hdr;
1153
1154 hdr = (const struct rsn_ie_hdr *) rsn_ie;
6fc6879b 1155
0f8385e6
BG
1156 if (hdr->elem_id != WLAN_EID_RSN ||
1157 hdr->len != rsn_ie_len - 2 ||
1158 WPA_GET_LE16(hdr->version) != RSN_VERSION) {
1159 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
1160 __func__);
1161 return -2;
1162 }
1163
1164 pos = (const u8 *) (hdr + 1);
1165 left = rsn_ie_len - sizeof(*hdr);
1166 }
6fc6879b
JM
1167
1168 if (left >= RSN_SELECTOR_LEN) {
1169 data->group_cipher = rsn_selector_to_bitfield(pos);
8dd9f9cd 1170 if (!wpa_cipher_valid_group(data->group_cipher)) {
0b905c8a
JM
1171 wpa_printf(MSG_DEBUG,
1172 "%s: invalid group cipher 0x%x (%08x)",
1173 __func__, data->group_cipher,
1174 WPA_GET_BE32(pos));
6fc6879b
JM
1175 return -1;
1176 }
6fc6879b
JM
1177 pos += RSN_SELECTOR_LEN;
1178 left -= RSN_SELECTOR_LEN;
1179 } else if (left > 0) {
1180 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
1181 __func__, left);
1182 return -3;
1183 }
1184
1185 if (left >= 2) {
1186 data->pairwise_cipher = 0;
1187 count = WPA_GET_LE16(pos);
1188 pos += 2;
1189 left -= 2;
649c0a69 1190 if (count == 0 || count > left / RSN_SELECTOR_LEN) {
6fc6879b
JM
1191 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
1192 "count %u left %u", __func__, count, left);
1193 return -4;
1194 }
1195 for (i = 0; i < count; i++) {
1196 data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
1197 pos += RSN_SELECTOR_LEN;
1198 left -= RSN_SELECTOR_LEN;
1199 }
1200#ifdef CONFIG_IEEE80211W
1201 if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
1202 wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
1203 "pairwise cipher", __func__);
1204 return -1;
1205 }
1206#endif /* CONFIG_IEEE80211W */
1207 } else if (left == 1) {
1208 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
1209 __func__);
1210 return -5;
1211 }
1212
1213 if (left >= 2) {
1214 data->key_mgmt = 0;
1215 count = WPA_GET_LE16(pos);
1216 pos += 2;
1217 left -= 2;
649c0a69 1218 if (count == 0 || count > left / RSN_SELECTOR_LEN) {
6fc6879b
JM
1219 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
1220 "count %u left %u", __func__, count, left);
1221 return -6;
1222 }
1223 for (i = 0; i < count; i++) {
1224 data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
1225 pos += RSN_SELECTOR_LEN;
1226 left -= RSN_SELECTOR_LEN;
1227 }
1228 } else if (left == 1) {
1229 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
1230 __func__);
1231 return -7;
1232 }
1233
1234 if (left >= 2) {
1235 data->capabilities = WPA_GET_LE16(pos);
1236 pos += 2;
1237 left -= 2;
1238 }
1239
1240 if (left >= 2) {
46a03525 1241 u16 num_pmkid = WPA_GET_LE16(pos);
6fc6879b
JM
1242 pos += 2;
1243 left -= 2;
46a03525 1244 if (num_pmkid > (unsigned int) left / PMKID_LEN) {
6fc6879b 1245 wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
46a03525
JM
1246 "(num_pmkid=%u left=%d)",
1247 __func__, num_pmkid, left);
6fc6879b
JM
1248 data->num_pmkid = 0;
1249 return -9;
1250 } else {
46a03525 1251 data->num_pmkid = num_pmkid;
6fc6879b
JM
1252 data->pmkid = pos;
1253 pos += data->num_pmkid * PMKID_LEN;
1254 left -= data->num_pmkid * PMKID_LEN;
1255 }
1256 }
1257
1258#ifdef CONFIG_IEEE80211W
1259 if (left >= 4) {
1260 data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
8dd9f9cd 1261 if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
b0ecbd3a
JM
1262 wpa_printf(MSG_DEBUG,
1263 "%s: Unsupported management group cipher 0x%x (%08x)",
1264 __func__, data->mgmt_group_cipher,
1265 WPA_GET_BE32(pos));
6fc6879b
JM
1266 return -10;
1267 }
1268 pos += RSN_SELECTOR_LEN;
1269 left -= RSN_SELECTOR_LEN;
1270 }
1271#endif /* CONFIG_IEEE80211W */
1272
1273 if (left > 0) {
749fa140
JM
1274 wpa_hexdump(MSG_DEBUG,
1275 "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
1276 pos, left);
6fc6879b
JM
1277 }
1278
1279 return 0;
6fc6879b
JM
1280}
1281
1282
f3b87561
JM
1283static int wpa_selector_to_bitfield(const u8 *s)
1284{
1285 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
1286 return WPA_CIPHER_NONE;
f3b87561
JM
1287 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
1288 return WPA_CIPHER_TKIP;
1289 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
1290 return WPA_CIPHER_CCMP;
f3b87561
JM
1291 return 0;
1292}
1293
1294
1295static int wpa_key_mgmt_to_bitfield(const u8 *s)
1296{
1297 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
1298 return WPA_KEY_MGMT_IEEE8021X;
1299 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
1300 return WPA_KEY_MGMT_PSK;
1301 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
1302 return WPA_KEY_MGMT_WPA_NONE;
1303 return 0;
1304}
1305
1306
1307int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
1308 struct wpa_ie_data *data)
1309{
1310 const struct wpa_ie_hdr *hdr;
1311 const u8 *pos;
1312 int left;
1313 int i, count;
1314
1315 os_memset(data, 0, sizeof(*data));
1316 data->proto = WPA_PROTO_WPA;
1317 data->pairwise_cipher = WPA_CIPHER_TKIP;
1318 data->group_cipher = WPA_CIPHER_TKIP;
1319 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1320 data->capabilities = 0;
1321 data->pmkid = NULL;
1322 data->num_pmkid = 0;
1323 data->mgmt_group_cipher = 0;
1324
f3b87561
JM
1325 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
1326 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
1327 __func__, (unsigned long) wpa_ie_len);
1328 return -1;
1329 }
1330
1331 hdr = (const struct wpa_ie_hdr *) wpa_ie;
1332
1333 if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
1334 hdr->len != wpa_ie_len - 2 ||
1335 RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
1336 WPA_GET_LE16(hdr->version) != WPA_VERSION) {
1337 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
1338 __func__);
1339 return -2;
1340 }
1341
1342 pos = (const u8 *) (hdr + 1);
1343 left = wpa_ie_len - sizeof(*hdr);
1344
1345 if (left >= WPA_SELECTOR_LEN) {
1346 data->group_cipher = wpa_selector_to_bitfield(pos);
1347 pos += WPA_SELECTOR_LEN;
1348 left -= WPA_SELECTOR_LEN;
1349 } else if (left > 0) {
1350 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
1351 __func__, left);
1352 return -3;
1353 }
1354
1355 if (left >= 2) {
1356 data->pairwise_cipher = 0;
1357 count = WPA_GET_LE16(pos);
1358 pos += 2;
1359 left -= 2;
649c0a69 1360 if (count == 0 || count > left / WPA_SELECTOR_LEN) {
f3b87561
JM
1361 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
1362 "count %u left %u", __func__, count, left);
1363 return -4;
1364 }
1365 for (i = 0; i < count; i++) {
1366 data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
1367 pos += WPA_SELECTOR_LEN;
1368 left -= WPA_SELECTOR_LEN;
1369 }
1370 } else if (left == 1) {
1371 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
1372 __func__);
1373 return -5;
1374 }
1375
1376 if (left >= 2) {
1377 data->key_mgmt = 0;
1378 count = WPA_GET_LE16(pos);
1379 pos += 2;
1380 left -= 2;
649c0a69 1381 if (count == 0 || count > left / WPA_SELECTOR_LEN) {
f3b87561
JM
1382 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
1383 "count %u left %u", __func__, count, left);
1384 return -6;
1385 }
1386 for (i = 0; i < count; i++) {
1387 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
1388 pos += WPA_SELECTOR_LEN;
1389 left -= WPA_SELECTOR_LEN;
1390 }
1391 } else if (left == 1) {
1392 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
1393 __func__);
1394 return -7;
1395 }
1396
1397 if (left >= 2) {
1398 data->capabilities = WPA_GET_LE16(pos);
1399 pos += 2;
1400 left -= 2;
1401 }
1402
1403 if (left > 0) {
749fa140
JM
1404 wpa_hexdump(MSG_DEBUG,
1405 "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
1406 pos, left);
f3b87561
JM
1407 }
1408
1409 return 0;
1410}
1411
1412
6fc6879b
JM
1413#ifdef CONFIG_IEEE80211R
1414
1415/**
1416 * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
1417 *
c1e033b0 1418 * IEEE Std 802.11r-2008 - 8.5.1.5.3
6fc6879b 1419 */
364c064a
JM
1420int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
1421 const u8 *ssid, size_t ssid_len,
1422 const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
1423 const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
6fc6879b 1424{
6fb761c6 1425 u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
6fc6879b
JM
1426 FT_R0KH_ID_MAX_LEN + ETH_ALEN];
1427 u8 *pos, r0_key_data[48], hash[32];
1428 const u8 *addr[2];
1429 size_t len[2];
1430
1431 /*
1432 * R0-Key-Data = KDF-384(XXKey, "FT-R0",
1433 * SSIDlength || SSID || MDID || R0KHlength ||
1434 * R0KH-ID || S0KH-ID)
1435 * XXKey is either the second 256 bits of MSK or PSK.
1436 * PMK-R0 = L(R0-Key-Data, 0, 256)
1437 * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
1438 */
6fb761c6 1439 if (ssid_len > SSID_MAX_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
364c064a 1440 return -1;
6fc6879b
JM
1441 pos = buf;
1442 *pos++ = ssid_len;
1443 os_memcpy(pos, ssid, ssid_len);
1444 pos += ssid_len;
1445 os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
1446 pos += MOBILITY_DOMAIN_ID_LEN;
1447 *pos++ = r0kh_id_len;
1448 os_memcpy(pos, r0kh_id, r0kh_id_len);
1449 pos += r0kh_id_len;
1450 os_memcpy(pos, s0kh_id, ETH_ALEN);
1451 pos += ETH_ALEN;
1452
364c064a
JM
1453 if (sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
1454 r0_key_data, sizeof(r0_key_data)) < 0)
1455 return -1;
6fc6879b
JM
1456 os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
1457
1458 /*
1459 * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
1460 */
1461 addr[0] = (const u8 *) "FT-R0N";
1462 len[0] = 6;
1463 addr[1] = r0_key_data + PMK_LEN;
1464 len[1] = 16;
1465
364c064a
JM
1466 if (sha256_vector(2, addr, len, hash) < 0)
1467 return -1;
6fc6879b 1468 os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
364c064a 1469 return 0;
6fc6879b
JM
1470}
1471
1472
1473/**
1474 * wpa_derive_pmk_r1_name - Derive PMKR1Name
1475 *
c1e033b0 1476 * IEEE Std 802.11r-2008 - 8.5.1.5.4
6fc6879b 1477 */
364c064a
JM
1478int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
1479 const u8 *s1kh_id, u8 *pmk_r1_name)
6fc6879b
JM
1480{
1481 u8 hash[32];
1482 const u8 *addr[4];
1483 size_t len[4];
1484
1485 /*
1486 * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
1487 * R1KH-ID || S1KH-ID))
1488 */
1489 addr[0] = (const u8 *) "FT-R1N";
1490 len[0] = 6;
1491 addr[1] = pmk_r0_name;
1492 len[1] = WPA_PMK_NAME_LEN;
1493 addr[2] = r1kh_id;
1494 len[2] = FT_R1KH_ID_LEN;
1495 addr[3] = s1kh_id;
1496 len[3] = ETH_ALEN;
1497
364c064a
JM
1498 if (sha256_vector(4, addr, len, hash) < 0)
1499 return -1;
6fc6879b 1500 os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
364c064a 1501 return 0;
6fc6879b
JM
1502}
1503
1504
1505/**
1506 * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
1507 *
c1e033b0 1508 * IEEE Std 802.11r-2008 - 8.5.1.5.4
6fc6879b 1509 */
a3e18dbb
JM
1510int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
1511 const u8 *pmk_r0_name,
364c064a
JM
1512 const u8 *r1kh_id, const u8 *s1kh_id,
1513 u8 *pmk_r1, u8 *pmk_r1_name)
6fc6879b
JM
1514{
1515 u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
1516 u8 *pos;
1517
1518 /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
7880a6a2
JM
1519 wpa_printf(MSG_DEBUG, "FT: Derive PMK-R1 using KDF-%s",
1520 pmk_r0_len == SHA384_MAC_LEN ? "SHA384" : "SHA256");
1521 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len);
1522 wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", r1kh_id, FT_R1KH_ID_LEN);
1523 wpa_printf(MSG_DEBUG, "FT: S1KH-ID: " MACSTR, MAC2STR(s1kh_id));
6fc6879b
JM
1524 pos = buf;
1525 os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
1526 pos += FT_R1KH_ID_LEN;
1527 os_memcpy(pos, s1kh_id, ETH_ALEN);
1528 pos += ETH_ALEN;
1529
7880a6a2
JM
1530#ifdef CONFIG_SHA384
1531 if (pmk_r0_len == SHA384_MAC_LEN &&
1532 sha384_prf(pmk_r0, pmk_r0_len, "FT-R1",
1533 buf, pos - buf, pmk_r1, pmk_r0_len) < 0)
1534 return -1;
1535#endif /* CONFIG_SHA384 */
1536 if (pmk_r0_len == PMK_LEN &&
1537 sha256_prf(pmk_r0, pmk_r0_len, "FT-R1",
1538 buf, pos - buf, pmk_r1, pmk_r0_len) < 0)
364c064a 1539 return -1;
7880a6a2
JM
1540 if (pmk_r0_len != SHA384_MAC_LEN && pmk_r0_len != PMK_LEN) {
1541 wpa_printf(MSG_ERROR, "FT: Unexpected PMK-R0 length %d",
1542 (int) pmk_r0_len);
1543 return -1;
1544 }
1545 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len);
6fc6879b 1546
364c064a
JM
1547 return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
1548 pmk_r1_name);
6fc6879b
JM
1549}
1550
1551
1552/**
1553 * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
1554 *
c1e033b0 1555 * IEEE Std 802.11r-2008 - 8.5.1.5.5
6fc6879b 1556 */
a3e18dbb
JM
1557int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
1558 const u8 *snonce, const u8 *anonce,
98cd3d1c
JM
1559 const u8 *sta_addr, const u8 *bssid,
1560 const u8 *pmk_r1_name,
1561 struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher)
6fc6879b
JM
1562{
1563 u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
1564 u8 *pos, hash[32];
1565 const u8 *addr[6];
1566 size_t len[6];
2f373878
JM
1567 u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
1568 size_t ptk_len, offset;
6fc6879b
JM
1569
1570 /*
1571 * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
1572 * BSSID || STA-ADDR)
1573 */
1574 pos = buf;
1575 os_memcpy(pos, snonce, WPA_NONCE_LEN);
1576 pos += WPA_NONCE_LEN;
1577 os_memcpy(pos, anonce, WPA_NONCE_LEN);
1578 pos += WPA_NONCE_LEN;
1579 os_memcpy(pos, bssid, ETH_ALEN);
1580 pos += ETH_ALEN;
1581 os_memcpy(pos, sta_addr, ETH_ALEN);
1582 pos += ETH_ALEN;
1583
567da5bb 1584 ptk->kck_len = wpa_kck_len(akmp, PMK_LEN);
2f373878 1585 ptk->kck2_len = wpa_kck2_len(akmp);
567da5bb 1586 ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
2f373878 1587 ptk->kek2_len = wpa_kek2_len(akmp);
98cd3d1c 1588 ptk->tk_len = wpa_cipher_key_len(cipher);
2f373878
JM
1589 ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
1590 ptk->kck2_len + ptk->kek2_len;
98cd3d1c 1591
364c064a
JM
1592 if (sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf,
1593 tmp, ptk_len) < 0)
1594 return -1;
6fc6879b
JM
1595
1596 /*
1597 * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
1598 * ANonce || BSSID || STA-ADDR))
1599 */
1600 addr[0] = pmk_r1_name;
1601 len[0] = WPA_PMK_NAME_LEN;
1602 addr[1] = (const u8 *) "FT-PTKN";
1603 len[1] = 7;
1604 addr[2] = snonce;
1605 len[2] = WPA_NONCE_LEN;
1606 addr[3] = anonce;
1607 len[3] = WPA_NONCE_LEN;
1608 addr[4] = bssid;
1609 len[4] = ETH_ALEN;
1610 addr[5] = sta_addr;
1611 len[5] = ETH_ALEN;
1612
364c064a
JM
1613 if (sha256_vector(6, addr, len, hash) < 0)
1614 return -1;
6fc6879b 1615 os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
98cd3d1c
JM
1616
1617 os_memcpy(ptk->kck, tmp, ptk->kck_len);
2f373878
JM
1618 offset = ptk->kck_len;
1619 os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
1620 offset += ptk->kek_len;
1621 os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
1622 offset += ptk->tk_len;
1623 os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
1624 offset = ptk->kck2_len;
1625 os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
98cd3d1c
JM
1626
1627 wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
1628 wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
2f373878
JM
1629 if (ptk->kck2_len)
1630 wpa_hexdump_key(MSG_DEBUG, "FT: KCK2",
1631 ptk->kck2, ptk->kck2_len);
1632 if (ptk->kek2_len)
1633 wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
1634 ptk->kek2, ptk->kek2_len);
98cd3d1c
JM
1635 wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
1636 wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
1637
1638 os_memset(tmp, 0, sizeof(tmp));
1639
1640 return 0;
6fc6879b
JM
1641}
1642
1643#endif /* CONFIG_IEEE80211R */
13268290
JM
1644
1645
1646/**
1647 * rsn_pmkid - Calculate PMK identifier
1648 * @pmk: Pairwise master key
1649 * @pmk_len: Length of pmk in bytes
1650 * @aa: Authenticator address
1651 * @spa: Supplicant address
1652 * @pmkid: Buffer for PMKID
41b81914 1653 * @akmp: Negotiated key management protocol
13268290 1654 *
41b81914
JM
1655 * IEEE Std 802.11-2016 - 12.7.1.3 Pairwise key hierarchy
1656 * AKM: 00-0F-AC:5, 00-0F-AC:6, 00-0F-AC:14, 00-0F-AC:16
1657 * PMKID = Truncate-128(HMAC-SHA-256(PMK, "PMK Name" || AA || SPA))
1658 * AKM: 00-0F-AC:11
1659 * See rsn_pmkid_suite_b()
1660 * AKM: 00-0F-AC:12
1661 * See rsn_pmkid_suite_b_192()
1662 * AKM: 00-0F-AC:15, 00-0F-AC:17
1663 * PMKID = Truncate-128(HMAC-SHA-384(PMK, "PMK Name" || AA || SPA))
1664 * Otherwise:
1665 * PMKID = Truncate-128(HMAC-SHA-1(PMK, "PMK Name" || AA || SPA))
13268290
JM
1666 */
1667void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
41b81914 1668 u8 *pmkid, int akmp)
13268290
JM
1669{
1670 char *title = "PMK Name";
1671 const u8 *addr[3];
1672 const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
41b81914 1673 unsigned char hash[SHA384_MAC_LEN];
13268290
JM
1674
1675 addr[0] = (u8 *) title;
1676 addr[1] = aa;
1677 addr[2] = spa;
1678
41b81914
JM
1679 if (0) {
1680#ifdef CONFIG_FILS
1681 } else if (wpa_key_mgmt_sha384(akmp)) {
1682 wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-384");
1683 hmac_sha384_vector(pmk, pmk_len, 3, addr, len, hash);
1684#endif /* CONFIG_FILS */
1685#if defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS)
1686 } else if (wpa_key_mgmt_sha256(akmp)) {
1687 wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-256");
13268290 1688 hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
41b81914
JM
1689#endif /* CONFIG_IEEE80211W || CONFIG_FILS */
1690 } else {
1691 wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-1");
13268290 1692 hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
41b81914
JM
1693 }
1694 wpa_hexdump(MSG_DEBUG, "RSN: Derived PMKID", hash, PMKID_LEN);
13268290
JM
1695 os_memcpy(pmkid, hash, PMKID_LEN);
1696}
43fb5297
JM
1697
1698
087a1f4e
JM
1699#ifdef CONFIG_SUITEB
1700/**
1701 * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
1702 * @kck: Key confirmation key
1703 * @kck_len: Length of kck in bytes
1704 * @aa: Authenticator address
1705 * @spa: Supplicant address
1706 * @pmkid: Buffer for PMKID
1707 * Returns: 0 on success, -1 on failure
1708 *
1709 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1710 * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
1711 */
1712int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
1713 const u8 *spa, u8 *pmkid)
1714{
1715 char *title = "PMK Name";
1716 const u8 *addr[3];
1717 const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1718 unsigned char hash[SHA256_MAC_LEN];
1719
1720 addr[0] = (u8 *) title;
1721 addr[1] = aa;
1722 addr[2] = spa;
1723
1724 if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
1725 return -1;
1726 os_memcpy(pmkid, hash, PMKID_LEN);
1727 return 0;
1728}
1729#endif /* CONFIG_SUITEB */
1730
1731
5e3b5197
JM
1732#ifdef CONFIG_SUITEB192
1733/**
1734 * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
1735 * @kck: Key confirmation key
1736 * @kck_len: Length of kck in bytes
1737 * @aa: Authenticator address
1738 * @spa: Supplicant address
1739 * @pmkid: Buffer for PMKID
1740 * Returns: 0 on success, -1 on failure
1741 *
1742 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1743 * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
1744 */
1745int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
1746 const u8 *spa, u8 *pmkid)
1747{
1748 char *title = "PMK Name";
1749 const u8 *addr[3];
1750 const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1751 unsigned char hash[SHA384_MAC_LEN];
1752
1753 addr[0] = (u8 *) title;
1754 addr[1] = aa;
1755 addr[2] = spa;
1756
1757 if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
1758 return -1;
1759 os_memcpy(pmkid, hash, PMKID_LEN);
1760 return 0;
1761}
1762#endif /* CONFIG_SUITEB192 */
1763
1764
43fb5297
JM
1765/**
1766 * wpa_cipher_txt - Convert cipher suite to a text string
1767 * @cipher: Cipher suite (WPA_CIPHER_* enum)
1768 * Returns: Pointer to a text string of the cipher suite name
1769 */
1770const char * wpa_cipher_txt(int cipher)
1771{
1772 switch (cipher) {
1773 case WPA_CIPHER_NONE:
1774 return "NONE";
1775 case WPA_CIPHER_WEP40:
1776 return "WEP-40";
1777 case WPA_CIPHER_WEP104:
1778 return "WEP-104";
1779 case WPA_CIPHER_TKIP:
1780 return "TKIP";
1781 case WPA_CIPHER_CCMP:
1782 return "CCMP";
1783 case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
1784 return "CCMP+TKIP";
eb7719ff
JM
1785 case WPA_CIPHER_GCMP:
1786 return "GCMP";
30675c34
JM
1787 case WPA_CIPHER_GCMP_256:
1788 return "GCMP-256";
1789 case WPA_CIPHER_CCMP_256:
1790 return "CCMP-256";
3a5954ef
JM
1791 case WPA_CIPHER_AES_128_CMAC:
1792 return "BIP";
1793 case WPA_CIPHER_BIP_GMAC_128:
1794 return "BIP-GMAC-128";
1795 case WPA_CIPHER_BIP_GMAC_256:
1796 return "BIP-GMAC-256";
1797 case WPA_CIPHER_BIP_CMAC_256:
1798 return "BIP-CMAC-256";
dff1e285
JM
1799 case WPA_CIPHER_GTK_NOT_USED:
1800 return "GTK_NOT_USED";
43fb5297
JM
1801 default:
1802 return "UNKNOWN";
1803 }
1804}
1805
1806
1807/**
1808 * wpa_key_mgmt_txt - Convert key management suite to a text string
1809 * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
1810 * @proto: WPA/WPA2 version (WPA_PROTO_*)
1811 * Returns: Pointer to a text string of the key management suite name
1812 */
1813const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
1814{
1815 switch (key_mgmt) {
1816 case WPA_KEY_MGMT_IEEE8021X:
1817 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1818 return "WPA2+WPA/IEEE 802.1X/EAP";
1819 return proto == WPA_PROTO_RSN ?
1820 "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
1821 case WPA_KEY_MGMT_PSK:
1822 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1823 return "WPA2-PSK+WPA-PSK";
1824 return proto == WPA_PROTO_RSN ?
1825 "WPA2-PSK" : "WPA-PSK";
1826 case WPA_KEY_MGMT_NONE:
1827 return "NONE";
4ac5f2f8
SB
1828 case WPA_KEY_MGMT_WPA_NONE:
1829 return "WPA-NONE";
43fb5297
JM
1830 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
1831 return "IEEE 802.1X (no WPA)";
1832#ifdef CONFIG_IEEE80211R
1833 case WPA_KEY_MGMT_FT_IEEE8021X:
1834 return "FT-EAP";
c22bb5bb
JM
1835 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
1836 return "FT-EAP-SHA384";
43fb5297
JM
1837 case WPA_KEY_MGMT_FT_PSK:
1838 return "FT-PSK";
1839#endif /* CONFIG_IEEE80211R */
1840#ifdef CONFIG_IEEE80211W
1841 case WPA_KEY_MGMT_IEEE8021X_SHA256:
1842 return "WPA2-EAP-SHA256";
1843 case WPA_KEY_MGMT_PSK_SHA256:
1844 return "WPA2-PSK-SHA256";
1845#endif /* CONFIG_IEEE80211W */
72c5c289
JM
1846 case WPA_KEY_MGMT_WPS:
1847 return "WPS";
1848 case WPA_KEY_MGMT_SAE:
1849 return "SAE";
1850 case WPA_KEY_MGMT_FT_SAE:
1851 return "FT-SAE";
1852 case WPA_KEY_MGMT_OSEN:
1853 return "OSEN";
666497c8
JM
1854 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
1855 return "WPA2-EAP-SUITE-B";
5e3b5197
JM
1856 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
1857 return "WPA2-EAP-SUITE-B-192";
94318a0d
JM
1858 case WPA_KEY_MGMT_FILS_SHA256:
1859 return "FILS-SHA256";
1860 case WPA_KEY_MGMT_FILS_SHA384:
1861 return "FILS-SHA384";
1862 case WPA_KEY_MGMT_FT_FILS_SHA256:
1863 return "FT-FILS-SHA256";
1864 case WPA_KEY_MGMT_FT_FILS_SHA384:
1865 return "FT-FILS-SHA384";
88850232
JM
1866 case WPA_KEY_MGMT_OWE:
1867 return "OWE";
1868 case WPA_KEY_MGMT_DPP:
1869 return "DPP";
43fb5297
JM
1870 default:
1871 return "UNKNOWN";
1872 }
1873}
26e23750
JM
1874
1875
6c460eaf
JM
1876u32 wpa_akm_to_suite(int akm)
1877{
c22bb5bb
JM
1878 if (akm & WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
1879 return RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384;
6c460eaf 1880 if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
bf9f8a05 1881 return RSN_AUTH_KEY_MGMT_FT_802_1X;
6c460eaf 1882 if (akm & WPA_KEY_MGMT_FT_PSK)
bf9f8a05 1883 return RSN_AUTH_KEY_MGMT_FT_PSK;
6c460eaf 1884 if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
bf9f8a05 1885 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
6c460eaf 1886 if (akm & WPA_KEY_MGMT_IEEE8021X)
bf9f8a05 1887 return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
6c460eaf 1888 if (akm & WPA_KEY_MGMT_PSK_SHA256)
bf9f8a05 1889 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
6c460eaf 1890 if (akm & WPA_KEY_MGMT_PSK)
bf9f8a05 1891 return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
6c460eaf 1892 if (akm & WPA_KEY_MGMT_CCKM)
bf9f8a05 1893 return RSN_AUTH_KEY_MGMT_CCKM;
6c460eaf 1894 if (akm & WPA_KEY_MGMT_OSEN)
bf9f8a05 1895 return RSN_AUTH_KEY_MGMT_OSEN;
666497c8 1896 if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
bf9f8a05 1897 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
5e3b5197 1898 if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
bf9f8a05 1899 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
94318a0d 1900 if (akm & WPA_KEY_MGMT_FILS_SHA256)
bf9f8a05 1901 return RSN_AUTH_KEY_MGMT_FILS_SHA256;
94318a0d 1902 if (akm & WPA_KEY_MGMT_FILS_SHA384)
bf9f8a05 1903 return RSN_AUTH_KEY_MGMT_FILS_SHA384;
94318a0d 1904 if (akm & WPA_KEY_MGMT_FT_FILS_SHA256)
bf9f8a05 1905 return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
94318a0d 1906 if (akm & WPA_KEY_MGMT_FT_FILS_SHA384)
bf9f8a05 1907 return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
6c460eaf
JM
1908 return 0;
1909}
1910
1911
26e23750
JM
1912int wpa_compare_rsn_ie(int ft_initial_assoc,
1913 const u8 *ie1, size_t ie1len,
1914 const u8 *ie2, size_t ie2len)
1915{
d3ccead3
JM
1916 if (ie1 == NULL || ie2 == NULL)
1917 return -1;
1918
26e23750
JM
1919 if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
1920 return 0; /* identical IEs */
1921
1922#ifdef CONFIG_IEEE80211R
1923 if (ft_initial_assoc) {
1924 struct wpa_ie_data ie1d, ie2d;
1925 /*
1926 * The PMKID-List in RSN IE is different between Beacon/Probe
1927 * Response/(Re)Association Request frames and EAPOL-Key
1928 * messages in FT initial mobility domain association. Allow
1929 * for this, but verify that other parts of the RSN IEs are
1930 * identical.
1931 */
1932 if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
1933 wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
1934 return -1;
1935 if (ie1d.proto == ie2d.proto &&
1936 ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
1937 ie1d.group_cipher == ie2d.group_cipher &&
1938 ie1d.key_mgmt == ie2d.key_mgmt &&
1939 ie1d.capabilities == ie2d.capabilities &&
1940 ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
1941 return 0;
1942 }
1943#endif /* CONFIG_IEEE80211R */
1944
1945 return -1;
1946}
1947
1948
14de9e31 1949#if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
59e78c24 1950int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid)
26e23750
JM
1951{
1952 u8 *start, *end, *rpos, *rend;
1953 int added = 0;
1954
1955 start = ies;
59e78c24 1956 end = ies + *ies_len;
26e23750
JM
1957
1958 while (start < end) {
1959 if (*start == WLAN_EID_RSN)
1960 break;
1961 start += 2 + start[1];
1962 }
1963 if (start >= end) {
1964 wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
1965 "IEs data");
1966 return -1;
1967 }
1968 wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
1969 start, 2 + start[1]);
1970
1971 /* Find start of PMKID-Count */
1972 rpos = start + 2;
1973 rend = rpos + start[1];
1974
1975 /* Skip Version and Group Data Cipher Suite */
1976 rpos += 2 + 4;
1977 /* Skip Pairwise Cipher Suite Count and List */
1978 rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1979 /* Skip AKM Suite Count and List */
1980 rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1981
1982 if (rpos == rend) {
1983 /* Add RSN Capabilities */
1984 os_memmove(rpos + 2, rpos, end - rpos);
1985 *rpos++ = 0;
1986 *rpos++ = 0;
3bc25adb
JM
1987 added += 2;
1988 start[1] += 2;
1989 rend = rpos;
26e23750
JM
1990 } else {
1991 /* Skip RSN Capabilities */
1992 rpos += 2;
1993 if (rpos > rend) {
1994 wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
1995 "IEs data");
1996 return -1;
1997 }
1998 }
1999
2000 if (rpos == rend) {
2001 /* No PMKID-Count field included; add it */
3bc25adb 2002 os_memmove(rpos + 2 + PMKID_LEN, rpos, end + added - rpos);
26e23750
JM
2003 WPA_PUT_LE16(rpos, 1);
2004 rpos += 2;
2005 os_memcpy(rpos, pmkid, PMKID_LEN);
2006 added += 2 + PMKID_LEN;
2007 start[1] += 2 + PMKID_LEN;
2008 } else {
59e78c24
JM
2009 u16 num_pmkid;
2010
2011 if (rend - rpos < 2)
26e23750 2012 return -1;
59e78c24
JM
2013 num_pmkid = WPA_GET_LE16(rpos);
2014 /* PMKID-Count was included; use it */
2015 if (num_pmkid != 0) {
2016 u8 *after;
2017
2018 if (num_pmkid * PMKID_LEN > rend - rpos - 2)
2019 return -1;
2020 /*
2021 * PMKID may have been included in RSN IE in
2022 * (Re)Association Request frame, so remove the old
2023 * PMKID(s) first before adding the new one.
2024 */
2025 wpa_printf(MSG_DEBUG,
2026 "FT: Remove %u old PMKID(s) from RSN IE",
2027 num_pmkid);
2028 after = rpos + 2 + num_pmkid * PMKID_LEN;
2029 os_memmove(rpos + 2, after, rend - after);
2030 start[1] -= num_pmkid * PMKID_LEN;
2031 added -= num_pmkid * PMKID_LEN;
26e23750
JM
2032 }
2033 WPA_PUT_LE16(rpos, 1);
2034 rpos += 2;
3bc25adb 2035 os_memmove(rpos + PMKID_LEN, rpos, end + added - rpos);
26e23750
JM
2036 os_memcpy(rpos, pmkid, PMKID_LEN);
2037 added += PMKID_LEN;
2038 start[1] += PMKID_LEN;
2039 }
2040
2041 wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
2042 "(PMKID inserted)", start, 2 + start[1]);
2043
59e78c24
JM
2044 *ies_len += added;
2045
2046 return 0;
26e23750 2047}
14de9e31 2048#endif /* CONFIG_IEEE80211R || CONFIG_FILS */
c3550295
JM
2049
2050
2051int wpa_cipher_key_len(int cipher)
2052{
2053 switch (cipher) {
30675c34
JM
2054 case WPA_CIPHER_CCMP_256:
2055 case WPA_CIPHER_GCMP_256:
8dd9f9cd
JM
2056 case WPA_CIPHER_BIP_GMAC_256:
2057 case WPA_CIPHER_BIP_CMAC_256:
30675c34 2058 return 32;
c3550295
JM
2059 case WPA_CIPHER_CCMP:
2060 case WPA_CIPHER_GCMP:
8dd9f9cd
JM
2061 case WPA_CIPHER_AES_128_CMAC:
2062 case WPA_CIPHER_BIP_GMAC_128:
c3550295
JM
2063 return 16;
2064 case WPA_CIPHER_TKIP:
2065 return 32;
c3550295
JM
2066 }
2067
2068 return 0;
2069}
2070
2071
2072int wpa_cipher_rsc_len(int cipher)
2073{
2074 switch (cipher) {
30675c34
JM
2075 case WPA_CIPHER_CCMP_256:
2076 case WPA_CIPHER_GCMP_256:
c3550295
JM
2077 case WPA_CIPHER_CCMP:
2078 case WPA_CIPHER_GCMP:
2079 case WPA_CIPHER_TKIP:
2080 return 6;
c3550295
JM
2081 }
2082
2083 return 0;
2084}
2085
2086
04f02faa 2087enum wpa_alg wpa_cipher_to_alg(int cipher)
c3550295
JM
2088{
2089 switch (cipher) {
30675c34
JM
2090 case WPA_CIPHER_CCMP_256:
2091 return WPA_ALG_CCMP_256;
2092 case WPA_CIPHER_GCMP_256:
2093 return WPA_ALG_GCMP_256;
c3550295
JM
2094 case WPA_CIPHER_CCMP:
2095 return WPA_ALG_CCMP;
2096 case WPA_CIPHER_GCMP:
2097 return WPA_ALG_GCMP;
2098 case WPA_CIPHER_TKIP:
2099 return WPA_ALG_TKIP;
8dd9f9cd
JM
2100 case WPA_CIPHER_AES_128_CMAC:
2101 return WPA_ALG_IGTK;
2102 case WPA_CIPHER_BIP_GMAC_128:
2103 return WPA_ALG_BIP_GMAC_128;
2104 case WPA_CIPHER_BIP_GMAC_256:
2105 return WPA_ALG_BIP_GMAC_256;
2106 case WPA_CIPHER_BIP_CMAC_256:
2107 return WPA_ALG_BIP_CMAC_256;
c3550295
JM
2108 }
2109 return WPA_ALG_NONE;
2110}
2111
2112
2113int wpa_cipher_valid_pairwise(int cipher)
2114{
30675c34
JM
2115 return cipher == WPA_CIPHER_CCMP_256 ||
2116 cipher == WPA_CIPHER_GCMP_256 ||
2117 cipher == WPA_CIPHER_CCMP ||
c3550295
JM
2118 cipher == WPA_CIPHER_GCMP ||
2119 cipher == WPA_CIPHER_TKIP;
2120}
2121
2122
2123u32 wpa_cipher_to_suite(int proto, int cipher)
2124{
30675c34
JM
2125 if (cipher & WPA_CIPHER_CCMP_256)
2126 return RSN_CIPHER_SUITE_CCMP_256;
2127 if (cipher & WPA_CIPHER_GCMP_256)
2128 return RSN_CIPHER_SUITE_GCMP_256;
c3550295
JM
2129 if (cipher & WPA_CIPHER_CCMP)
2130 return (proto == WPA_PROTO_RSN ?
2131 RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
2132 if (cipher & WPA_CIPHER_GCMP)
2133 return RSN_CIPHER_SUITE_GCMP;
2134 if (cipher & WPA_CIPHER_TKIP)
2135 return (proto == WPA_PROTO_RSN ?
2136 RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
c3550295
JM
2137 if (cipher & WPA_CIPHER_NONE)
2138 return (proto == WPA_PROTO_RSN ?
2139 RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
dff1e285
JM
2140 if (cipher & WPA_CIPHER_GTK_NOT_USED)
2141 return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
8dd9f9cd
JM
2142 if (cipher & WPA_CIPHER_AES_128_CMAC)
2143 return RSN_CIPHER_SUITE_AES_128_CMAC;
2144 if (cipher & WPA_CIPHER_BIP_GMAC_128)
2145 return RSN_CIPHER_SUITE_BIP_GMAC_128;
2146 if (cipher & WPA_CIPHER_BIP_GMAC_256)
2147 return RSN_CIPHER_SUITE_BIP_GMAC_256;
2148 if (cipher & WPA_CIPHER_BIP_CMAC_256)
2149 return RSN_CIPHER_SUITE_BIP_CMAC_256;
c3550295
JM
2150 return 0;
2151}
2152
2153
8a4ce280 2154int rsn_cipher_put_suites(u8 *start, int ciphers)
c3550295 2155{
8a4ce280 2156 u8 *pos = start;
c3550295 2157
30675c34
JM
2158 if (ciphers & WPA_CIPHER_CCMP_256) {
2159 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
2160 pos += RSN_SELECTOR_LEN;
30675c34
JM
2161 }
2162 if (ciphers & WPA_CIPHER_GCMP_256) {
2163 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
2164 pos += RSN_SELECTOR_LEN;
30675c34 2165 }
c3550295
JM
2166 if (ciphers & WPA_CIPHER_CCMP) {
2167 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
2168 pos += RSN_SELECTOR_LEN;
c3550295
JM
2169 }
2170 if (ciphers & WPA_CIPHER_GCMP) {
2171 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
2172 pos += RSN_SELECTOR_LEN;
c3550295
JM
2173 }
2174 if (ciphers & WPA_CIPHER_TKIP) {
2175 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
2176 pos += RSN_SELECTOR_LEN;
c3550295
JM
2177 }
2178 if (ciphers & WPA_CIPHER_NONE) {
2179 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
2180 pos += RSN_SELECTOR_LEN;
c3550295
JM
2181 }
2182
8a4ce280 2183 return (pos - start) / RSN_SELECTOR_LEN;
c3550295
JM
2184}
2185
2186
8a4ce280 2187int wpa_cipher_put_suites(u8 *start, int ciphers)
c3550295 2188{
8a4ce280 2189 u8 *pos = start;
c3550295
JM
2190
2191 if (ciphers & WPA_CIPHER_CCMP) {
2192 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
2193 pos += WPA_SELECTOR_LEN;
c3550295
JM
2194 }
2195 if (ciphers & WPA_CIPHER_TKIP) {
2196 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
2197 pos += WPA_SELECTOR_LEN;
c3550295
JM
2198 }
2199 if (ciphers & WPA_CIPHER_NONE) {
2200 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
2201 pos += WPA_SELECTOR_LEN;
c3550295
JM
2202 }
2203
8a4ce280 2204 return (pos - start) / RSN_SELECTOR_LEN;
c3550295 2205}
edbd2a19
JM
2206
2207
2208int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
2209{
30675c34
JM
2210 if (ciphers & WPA_CIPHER_CCMP_256)
2211 return WPA_CIPHER_CCMP_256;
2212 if (ciphers & WPA_CIPHER_GCMP_256)
2213 return WPA_CIPHER_GCMP_256;
edbd2a19
JM
2214 if (ciphers & WPA_CIPHER_CCMP)
2215 return WPA_CIPHER_CCMP;
2216 if (ciphers & WPA_CIPHER_GCMP)
2217 return WPA_CIPHER_GCMP;
2218 if (ciphers & WPA_CIPHER_TKIP)
2219 return WPA_CIPHER_TKIP;
2220 if (none_allowed && (ciphers & WPA_CIPHER_NONE))
2221 return WPA_CIPHER_NONE;
2222 return -1;
2223}
2224
2225
2226int wpa_pick_group_cipher(int ciphers)
2227{
30675c34
JM
2228 if (ciphers & WPA_CIPHER_CCMP_256)
2229 return WPA_CIPHER_CCMP_256;
2230 if (ciphers & WPA_CIPHER_GCMP_256)
2231 return WPA_CIPHER_GCMP_256;
edbd2a19
JM
2232 if (ciphers & WPA_CIPHER_CCMP)
2233 return WPA_CIPHER_CCMP;
2234 if (ciphers & WPA_CIPHER_GCMP)
2235 return WPA_CIPHER_GCMP;
dff1e285
JM
2236 if (ciphers & WPA_CIPHER_GTK_NOT_USED)
2237 return WPA_CIPHER_GTK_NOT_USED;
edbd2a19
JM
2238 if (ciphers & WPA_CIPHER_TKIP)
2239 return WPA_CIPHER_TKIP;
edbd2a19
JM
2240 return -1;
2241}
a39c78be
JM
2242
2243
2244int wpa_parse_cipher(const char *value)
2245{
2246 int val = 0, last;
2247 char *start, *end, *buf;
2248
2249 buf = os_strdup(value);
2250 if (buf == NULL)
2251 return -1;
2252 start = buf;
2253
2254 while (*start != '\0') {
2255 while (*start == ' ' || *start == '\t')
2256 start++;
2257 if (*start == '\0')
2258 break;
2259 end = start;
2260 while (*end != ' ' && *end != '\t' && *end != '\0')
2261 end++;
2262 last = *end == '\0';
2263 *end = '\0';
30675c34
JM
2264 if (os_strcmp(start, "CCMP-256") == 0)
2265 val |= WPA_CIPHER_CCMP_256;
2266 else if (os_strcmp(start, "GCMP-256") == 0)
2267 val |= WPA_CIPHER_GCMP_256;
2268 else if (os_strcmp(start, "CCMP") == 0)
a39c78be
JM
2269 val |= WPA_CIPHER_CCMP;
2270 else if (os_strcmp(start, "GCMP") == 0)
2271 val |= WPA_CIPHER_GCMP;
2272 else if (os_strcmp(start, "TKIP") == 0)
2273 val |= WPA_CIPHER_TKIP;
2274 else if (os_strcmp(start, "WEP104") == 0)
2275 val |= WPA_CIPHER_WEP104;
2276 else if (os_strcmp(start, "WEP40") == 0)
2277 val |= WPA_CIPHER_WEP40;
2278 else if (os_strcmp(start, "NONE") == 0)
2279 val |= WPA_CIPHER_NONE;
dff1e285
JM
2280 else if (os_strcmp(start, "GTK_NOT_USED") == 0)
2281 val |= WPA_CIPHER_GTK_NOT_USED;
61a56c14
JM
2282 else if (os_strcmp(start, "AES-128-CMAC") == 0)
2283 val |= WPA_CIPHER_AES_128_CMAC;
2284 else if (os_strcmp(start, "BIP-GMAC-128") == 0)
2285 val |= WPA_CIPHER_BIP_GMAC_128;
2286 else if (os_strcmp(start, "BIP-GMAC-256") == 0)
2287 val |= WPA_CIPHER_BIP_GMAC_256;
2288 else if (os_strcmp(start, "BIP-CMAC-256") == 0)
2289 val |= WPA_CIPHER_BIP_CMAC_256;
a39c78be
JM
2290 else {
2291 os_free(buf);
2292 return -1;
2293 }
2294
2295 if (last)
2296 break;
2297 start = end + 1;
2298 }
2299 os_free(buf);
2300
2301 return val;
2302}
0282a8c4
JM
2303
2304
2305int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
2306{
2307 char *pos = start;
2308 int ret;
2309
30675c34
JM
2310 if (ciphers & WPA_CIPHER_CCMP_256) {
2311 ret = os_snprintf(pos, end - pos, "%sCCMP-256",
2312 pos == start ? "" : delim);
d85e1fc8 2313 if (os_snprintf_error(end - pos, ret))
30675c34
JM
2314 return -1;
2315 pos += ret;
2316 }
2317 if (ciphers & WPA_CIPHER_GCMP_256) {
2318 ret = os_snprintf(pos, end - pos, "%sGCMP-256",
2319 pos == start ? "" : delim);
d85e1fc8 2320 if (os_snprintf_error(end - pos, ret))
30675c34
JM
2321 return -1;
2322 pos += ret;
2323 }
0282a8c4
JM
2324 if (ciphers & WPA_CIPHER_CCMP) {
2325 ret = os_snprintf(pos, end - pos, "%sCCMP",
2326 pos == start ? "" : delim);
d85e1fc8 2327 if (os_snprintf_error(end - pos, ret))
0282a8c4
JM
2328 return -1;
2329 pos += ret;
2330 }
2331 if (ciphers & WPA_CIPHER_GCMP) {
2332 ret = os_snprintf(pos, end - pos, "%sGCMP",
2333 pos == start ? "" : delim);
d85e1fc8 2334 if (os_snprintf_error(end - pos, ret))
0282a8c4
JM
2335 return -1;
2336 pos += ret;
2337 }
2338 if (ciphers & WPA_CIPHER_TKIP) {
2339 ret = os_snprintf(pos, end - pos, "%sTKIP",
2340 pos == start ? "" : delim);
d85e1fc8 2341 if (os_snprintf_error(end - pos, ret))
0282a8c4
JM
2342 return -1;
2343 pos += ret;
2344 }
61a56c14
JM
2345 if (ciphers & WPA_CIPHER_AES_128_CMAC) {
2346 ret = os_snprintf(pos, end - pos, "%sAES-128-CMAC",
2347 pos == start ? "" : delim);
2348 if (os_snprintf_error(end - pos, ret))
2349 return -1;
2350 pos += ret;
2351 }
2352 if (ciphers & WPA_CIPHER_BIP_GMAC_128) {
2353 ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-128",
2354 pos == start ? "" : delim);
2355 if (os_snprintf_error(end - pos, ret))
2356 return -1;
2357 pos += ret;
2358 }
2359 if (ciphers & WPA_CIPHER_BIP_GMAC_256) {
2360 ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-256",
2361 pos == start ? "" : delim);
2362 if (os_snprintf_error(end - pos, ret))
2363 return -1;
2364 pos += ret;
2365 }
2366 if (ciphers & WPA_CIPHER_BIP_CMAC_256) {
2367 ret = os_snprintf(pos, end - pos, "%sBIP-CMAC-256",
2368 pos == start ? "" : delim);
2369 if (os_snprintf_error(end - pos, ret))
2370 return -1;
2371 pos += ret;
2372 }
0282a8c4
JM
2373 if (ciphers & WPA_CIPHER_NONE) {
2374 ret = os_snprintf(pos, end - pos, "%sNONE",
2375 pos == start ? "" : delim);
d85e1fc8 2376 if (os_snprintf_error(end - pos, ret))
0282a8c4
JM
2377 return -1;
2378 pos += ret;
2379 }
2380
2381 return pos - start;
2382}
cf830c1c
JM
2383
2384
2385int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
2386{
2387 int pairwise = 0;
2388
2389 /* Select group cipher based on the enabled pairwise cipher suites */
2390 if (wpa & 1)
2391 pairwise |= wpa_pairwise;
2392 if (wpa & 2)
2393 pairwise |= rsn_pairwise;
2394
2395 if (pairwise & WPA_CIPHER_TKIP)
2396 return WPA_CIPHER_TKIP;
2397 if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
2398 return WPA_CIPHER_GCMP;
30675c34
JM
2399 if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
2400 WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
2401 return WPA_CIPHER_GCMP_256;
2402 if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
2403 WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
2404 return WPA_CIPHER_CCMP_256;
cf830c1c
JM
2405 return WPA_CIPHER_CCMP;
2406}
94f66e8a
JM
2407
2408
2409#ifdef CONFIG_FILS
42b847ac 2410int fils_domain_name_hash(const char *domain, u8 *hash)
94f66e8a
JM
2411{
2412 char buf[255], *wpos = buf;
2413 const char *pos = domain;
2414 size_t len;
42b847ac
JM
2415 const u8 *addr[1];
2416 u8 mac[SHA256_MAC_LEN];
94f66e8a
JM
2417
2418 for (len = 0; len < sizeof(buf) && *pos; len++) {
2419 if (isalpha(*pos) && isupper(*pos))
2420 *wpos++ = tolower(*pos);
2421 else
2422 *wpos++ = *pos;
2423 pos++;
2424 }
2425
42b847ac
JM
2426 addr[0] = (const u8 *) buf;
2427 if (sha256_vector(1, addr, &len, mac) < 0)
2428 return -1;
2429 os_memcpy(hash, mac, 2);
2430 return 0;
94f66e8a
JM
2431}
2432#endif /* CONFIG_FILS */