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