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