Line data Source code
1 : /*
2 : * WPA/RSN - Shared functions for supplicant and authenticator
3 : * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "includes.h"
10 :
11 : #include "common.h"
12 : #include "crypto/md5.h"
13 : #include "crypto/sha1.h"
14 : #include "crypto/sha256.h"
15 : #include "crypto/sha384.h"
16 : #include "crypto/aes_wrap.h"
17 : #include "crypto/crypto.h"
18 : #include "ieee802_11_defs.h"
19 : #include "defs.h"
20 : #include "wpa_common.h"
21 :
22 :
23 3083 : static unsigned int wpa_kck_len(int akmp)
24 : {
25 3083 : if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
26 4 : return 24;
27 3079 : return 16;
28 : }
29 :
30 :
31 3083 : static unsigned int wpa_kek_len(int akmp)
32 : {
33 3083 : if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
34 4 : return 32;
35 3079 : return 16;
36 : }
37 :
38 :
39 17318 : unsigned int wpa_mic_len(int akmp)
40 : {
41 17318 : if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
42 26 : return 24;
43 17292 : return 16;
44 : }
45 :
46 :
47 : /**
48 : * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
49 : * @key: EAPOL-Key Key Confirmation Key (KCK)
50 : * @key_len: KCK length in octets
51 : * @akmp: WPA_KEY_MGMT_* used in key derivation
52 : * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
53 : * @buf: Pointer to the beginning of the EAPOL header (version field)
54 : * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
55 : * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
56 : * Returns: 0 on success, -1 on failure
57 : *
58 : * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
59 : * to be cleared (all zeroes) when calling this function.
60 : *
61 : * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
62 : * description of the Key MIC calculation. It includes packet data from the
63 : * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
64 : * happened during final editing of the standard and the correct behavior is
65 : * defined in the last draft (IEEE 802.11i/D10).
66 : */
67 7996 : int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
68 : const u8 *buf, size_t len, u8 *mic)
69 : {
70 : u8 hash[SHA384_MAC_LEN];
71 :
72 7996 : switch (ver) {
73 : #ifndef CONFIG_FIPS
74 : case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
75 236 : return hmac_md5(key, key_len, buf, len, mic);
76 : #endif /* CONFIG_FIPS */
77 : case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
78 7406 : if (hmac_sha1(key, key_len, buf, len, hash))
79 0 : return -1;
80 7406 : os_memcpy(mic, hash, MD5_MAC_LEN);
81 7406 : break;
82 : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
83 : case WPA_KEY_INFO_TYPE_AES_128_CMAC:
84 318 : return omac1_aes_128(key, buf, len, mic);
85 : #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
86 : case WPA_KEY_INFO_TYPE_AKM_DEFINED:
87 36 : switch (akmp) {
88 : #ifdef CONFIG_HS20
89 : case WPA_KEY_MGMT_OSEN:
90 12 : return omac1_aes_128(key, buf, len, mic);
91 : #endif /* CONFIG_HS20 */
92 : #ifdef CONFIG_SUITEB
93 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
94 12 : if (hmac_sha256(key, key_len, buf, len, hash))
95 0 : return -1;
96 12 : os_memcpy(mic, hash, MD5_MAC_LEN);
97 12 : break;
98 : #endif /* CONFIG_SUITEB */
99 : #ifdef CONFIG_SUITEB192
100 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
101 12 : if (hmac_sha384(key, key_len, buf, len, hash))
102 0 : return -1;
103 12 : os_memcpy(mic, hash, 24);
104 12 : break;
105 : #endif /* CONFIG_SUITEB192 */
106 : default:
107 0 : return -1;
108 : }
109 24 : break;
110 : default:
111 0 : return -1;
112 : }
113 :
114 7430 : return 0;
115 : }
116 :
117 :
118 : /**
119 : * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
120 : * @pmk: Pairwise master key
121 : * @pmk_len: Length of PMK
122 : * @label: Label to use in derivation
123 : * @addr1: AA or SA
124 : * @addr2: SA or AA
125 : * @nonce1: ANonce or SNonce
126 : * @nonce2: SNonce or ANonce
127 : * @ptk: Buffer for pairwise transient key
128 : * @akmp: Negotiated AKM
129 : * @cipher: Negotiated pairwise cipher
130 : * Returns: 0 on success, -1 on failure
131 : *
132 : * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
133 : * PTK = PRF-X(PMK, "Pairwise key expansion",
134 : * Min(AA, SA) || Max(AA, SA) ||
135 : * Min(ANonce, SNonce) || Max(ANonce, SNonce))
136 : *
137 : * STK = PRF-X(SMK, "Peer key expansion",
138 : * Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
139 : * Min(INonce, PNonce) || Max(INonce, PNonce))
140 : */
141 2593 : int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
142 : const u8 *addr1, const u8 *addr2,
143 : const u8 *nonce1, const u8 *nonce2,
144 : struct wpa_ptk *ptk, int akmp, int cipher)
145 : {
146 : u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
147 : u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
148 : size_t ptk_len;
149 :
150 2593 : if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
151 1294 : os_memcpy(data, addr1, ETH_ALEN);
152 1294 : os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
153 : } else {
154 1299 : os_memcpy(data, addr2, ETH_ALEN);
155 1299 : os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
156 : }
157 :
158 2593 : if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
159 1293 : os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
160 1293 : os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
161 : WPA_NONCE_LEN);
162 : } else {
163 1300 : os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
164 1300 : os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
165 : WPA_NONCE_LEN);
166 : }
167 :
168 2593 : ptk->kck_len = wpa_kck_len(akmp);
169 2593 : ptk->kek_len = wpa_kek_len(akmp);
170 2593 : ptk->tk_len = wpa_cipher_key_len(cipher);
171 2593 : ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
172 :
173 : #ifdef CONFIG_IEEE80211W
174 2593 : if (wpa_key_mgmt_sha256(akmp))
175 62 : sha256_prf(pmk, pmk_len, label, data, sizeof(data),
176 : tmp, ptk_len);
177 : else
178 : #endif /* CONFIG_IEEE80211W */
179 2531 : sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp, ptk_len);
180 :
181 31116 : wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
182 31116 : MAC2STR(addr1), MAC2STR(addr2));
183 2593 : wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
184 2593 : wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
185 2593 : wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
186 2593 : wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
187 :
188 2593 : os_memcpy(ptk->kck, tmp, ptk->kck_len);
189 2593 : wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
190 :
191 2593 : os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
192 2593 : wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
193 :
194 2593 : os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
195 2593 : wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
196 :
197 2593 : os_memset(tmp, 0, sizeof(tmp));
198 2593 : return 0;
199 : }
200 :
201 :
202 : #ifdef CONFIG_IEEE80211R
203 884 : int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
204 : const u8 *ap_addr, u8 transaction_seqnum,
205 : const u8 *mdie, size_t mdie_len,
206 : const u8 *ftie, size_t ftie_len,
207 : const u8 *rsnie, size_t rsnie_len,
208 : const u8 *ric, size_t ric_len, u8 *mic)
209 : {
210 : u8 *buf, *pos;
211 : size_t buf_len;
212 :
213 884 : if (kck_len != 16) {
214 0 : wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
215 : (unsigned int) kck_len);
216 0 : return -1;
217 : }
218 :
219 884 : buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
220 884 : buf = os_malloc(buf_len);
221 884 : if (buf == NULL)
222 0 : return -1;
223 :
224 884 : pos = buf;
225 884 : os_memcpy(pos, sta_addr, ETH_ALEN);
226 884 : pos += ETH_ALEN;
227 884 : os_memcpy(pos, ap_addr, ETH_ALEN);
228 884 : pos += ETH_ALEN;
229 884 : *pos++ = transaction_seqnum;
230 884 : if (rsnie) {
231 884 : os_memcpy(pos, rsnie, rsnie_len);
232 884 : pos += rsnie_len;
233 : }
234 884 : if (mdie) {
235 884 : os_memcpy(pos, mdie, mdie_len);
236 884 : pos += mdie_len;
237 : }
238 884 : if (ftie) {
239 : struct rsn_ftie *_ftie;
240 884 : os_memcpy(pos, ftie, ftie_len);
241 884 : if (ftie_len < 2 + sizeof(*_ftie)) {
242 0 : os_free(buf);
243 0 : return -1;
244 : }
245 884 : _ftie = (struct rsn_ftie *) (pos + 2);
246 884 : os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
247 884 : pos += ftie_len;
248 : }
249 884 : if (ric) {
250 0 : os_memcpy(pos, ric, ric_len);
251 0 : pos += ric_len;
252 : }
253 :
254 884 : wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
255 884 : if (omac1_aes_128(kck, buf, pos - buf, mic)) {
256 0 : os_free(buf);
257 0 : return -1;
258 : }
259 :
260 884 : os_free(buf);
261 :
262 884 : return 0;
263 : }
264 :
265 :
266 1358 : static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
267 : struct wpa_ft_ies *parse)
268 : {
269 : const u8 *end, *pos;
270 :
271 1358 : parse->ftie = ie;
272 1358 : parse->ftie_len = ie_len;
273 :
274 1358 : pos = ie + sizeof(struct rsn_ftie);
275 1358 : end = ie + ie_len;
276 :
277 5653 : while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
278 2937 : switch (pos[0]) {
279 : case FTIE_SUBELEM_R1KH_ID:
280 1129 : if (pos[1] != FT_R1KH_ID_LEN) {
281 0 : wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
282 0 : "length in FTIE: %d", pos[1]);
283 0 : return -1;
284 : }
285 1129 : parse->r1kh_id = pos + 2;
286 1129 : break;
287 : case FTIE_SUBELEM_GTK:
288 442 : parse->gtk = pos + 2;
289 442 : parse->gtk_len = pos[1];
290 442 : break;
291 : case FTIE_SUBELEM_R0KH_ID:
292 1358 : if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
293 0 : wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
294 0 : "length in FTIE: %d", pos[1]);
295 0 : return -1;
296 : }
297 1358 : parse->r0kh_id = pos + 2;
298 1358 : parse->r0kh_id_len = pos[1];
299 1358 : break;
300 : #ifdef CONFIG_IEEE80211W
301 : case FTIE_SUBELEM_IGTK:
302 8 : parse->igtk = pos + 2;
303 8 : parse->igtk_len = pos[1];
304 8 : break;
305 : #endif /* CONFIG_IEEE80211W */
306 : }
307 :
308 2937 : pos += 2 + pos[1];
309 : }
310 :
311 1358 : return 0;
312 : }
313 :
314 :
315 6039 : int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
316 : struct wpa_ft_ies *parse)
317 : {
318 : const u8 *end, *pos;
319 : struct wpa_ie_data data;
320 : int ret;
321 : const struct rsn_ftie *ftie;
322 6039 : int prot_ie_count = 0;
323 :
324 6039 : os_memset(parse, 0, sizeof(*parse));
325 6039 : if (ies == NULL)
326 2293 : return 0;
327 :
328 3746 : pos = ies;
329 3746 : end = ies + ies_len;
330 33075 : while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
331 25583 : switch (pos[0]) {
332 : case WLAN_EID_RSN:
333 1358 : parse->rsn = pos + 2;
334 1358 : parse->rsn_len = pos[1];
335 1358 : ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
336 1358 : parse->rsn_len + 2,
337 : &data);
338 1358 : if (ret < 0) {
339 0 : wpa_printf(MSG_DEBUG, "FT: Failed to parse "
340 : "RSN IE: %d", ret);
341 0 : return -1;
342 : }
343 1358 : if (data.num_pmkid == 1 && data.pmkid)
344 1334 : parse->rsn_pmkid = data.pmkid;
345 1358 : break;
346 : case WLAN_EID_MOBILITY_DOMAIN:
347 1530 : parse->mdie = pos + 2;
348 1530 : parse->mdie_len = pos[1];
349 1530 : break;
350 : case WLAN_EID_FAST_BSS_TRANSITION:
351 1358 : if (pos[1] < sizeof(*ftie))
352 0 : return -1;
353 1358 : ftie = (const struct rsn_ftie *) (pos + 2);
354 1358 : prot_ie_count = ftie->mic_control[1];
355 1358 : if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
356 0 : return -1;
357 1358 : break;
358 : case WLAN_EID_TIMEOUT_INTERVAL:
359 0 : parse->tie = pos + 2;
360 0 : parse->tie_len = pos[1];
361 0 : break;
362 : case WLAN_EID_RIC_DATA:
363 0 : if (parse->ric == NULL)
364 0 : parse->ric = pos;
365 0 : break;
366 : }
367 :
368 25583 : pos += 2 + pos[1];
369 : }
370 :
371 3746 : if (prot_ie_count == 0)
372 2862 : return 0; /* no MIC */
373 :
374 : /*
375 : * Check that the protected IE count matches with IEs included in the
376 : * frame.
377 : */
378 884 : if (parse->rsn)
379 884 : prot_ie_count--;
380 884 : if (parse->mdie)
381 884 : prot_ie_count--;
382 884 : if (parse->ftie)
383 884 : prot_ie_count--;
384 884 : if (prot_ie_count < 0) {
385 0 : wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
386 : "the protected IE count");
387 0 : return -1;
388 : }
389 :
390 884 : if (prot_ie_count == 0 && parse->ric) {
391 0 : wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
392 : "included in protected IE count");
393 0 : return -1;
394 : }
395 :
396 : /* Determine the end of the RIC IE(s) */
397 884 : pos = parse->ric;
398 1768 : while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
399 : prot_ie_count) {
400 0 : prot_ie_count--;
401 0 : pos += 2 + pos[1];
402 : }
403 884 : parse->ric_len = pos - parse->ric;
404 884 : if (prot_ie_count) {
405 0 : wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
406 : "frame", (int) prot_ie_count);
407 0 : return -1;
408 : }
409 :
410 884 : return 0;
411 : }
412 : #endif /* CONFIG_IEEE80211R */
413 :
414 :
415 18871 : static int rsn_selector_to_bitfield(const u8 *s)
416 : {
417 18871 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
418 0 : return WPA_CIPHER_NONE;
419 18871 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
420 0 : return WPA_CIPHER_WEP40;
421 18871 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
422 284 : return WPA_CIPHER_TKIP;
423 18587 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
424 17687 : return WPA_CIPHER_CCMP;
425 900 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
426 0 : return WPA_CIPHER_WEP104;
427 : #ifdef CONFIG_IEEE80211W
428 900 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
429 735 : return WPA_CIPHER_AES_128_CMAC;
430 : #endif /* CONFIG_IEEE80211W */
431 165 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
432 31 : return WPA_CIPHER_GCMP;
433 134 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
434 8 : return WPA_CIPHER_CCMP_256;
435 126 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
436 30 : return WPA_CIPHER_GCMP_256;
437 96 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
438 18 : return WPA_CIPHER_BIP_GMAC_128;
439 78 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
440 22 : return WPA_CIPHER_BIP_GMAC_256;
441 56 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
442 10 : return WPA_CIPHER_BIP_CMAC_256;
443 46 : if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
444 44 : return WPA_CIPHER_GTK_NOT_USED;
445 2 : return 0;
446 : }
447 :
448 :
449 9343 : static int rsn_key_mgmt_to_bitfield(const u8 *s)
450 : {
451 9343 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
452 3828 : return WPA_KEY_MGMT_IEEE8021X;
453 5515 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
454 2504 : return WPA_KEY_MGMT_PSK;
455 : #ifdef CONFIG_IEEE80211R
456 3011 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
457 133 : return WPA_KEY_MGMT_FT_IEEE8021X;
458 2878 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
459 2234 : return WPA_KEY_MGMT_FT_PSK;
460 : #endif /* CONFIG_IEEE80211R */
461 : #ifdef CONFIG_IEEE80211W
462 644 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
463 56 : return WPA_KEY_MGMT_IEEE8021X_SHA256;
464 588 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
465 177 : return WPA_KEY_MGMT_PSK_SHA256;
466 : #endif /* CONFIG_IEEE80211W */
467 : #ifdef CONFIG_SAE
468 411 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
469 221 : return WPA_KEY_MGMT_SAE;
470 190 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
471 124 : return WPA_KEY_MGMT_FT_SAE;
472 : #endif /* CONFIG_SAE */
473 66 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
474 11 : return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
475 55 : if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
476 11 : return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
477 44 : return 0;
478 : }
479 :
480 :
481 9012 : static int wpa_cipher_valid_group(int cipher)
482 : {
483 18069 : return wpa_cipher_valid_pairwise(cipher) ||
484 45 : cipher == WPA_CIPHER_WEP104 ||
485 9057 : cipher == WPA_CIPHER_WEP40 ||
486 : cipher == WPA_CIPHER_GTK_NOT_USED;
487 : }
488 :
489 :
490 : #ifdef CONFIG_IEEE80211W
491 3940 : int wpa_cipher_valid_mgmt_group(int cipher)
492 : {
493 7037 : return cipher == WPA_CIPHER_AES_128_CMAC ||
494 3070 : cipher == WPA_CIPHER_BIP_GMAC_128 ||
495 6978 : cipher == WPA_CIPHER_BIP_GMAC_256 ||
496 : cipher == WPA_CIPHER_BIP_CMAC_256;
497 : }
498 : #endif /* CONFIG_IEEE80211W */
499 :
500 :
501 : /**
502 : * wpa_parse_wpa_ie_rsn - Parse RSN IE
503 : * @rsn_ie: Buffer containing RSN IE
504 : * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
505 : * @data: Pointer to structure that will be filled in with parsed data
506 : * Returns: 0 on success, <0 on failure
507 : */
508 9020 : int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
509 : struct wpa_ie_data *data)
510 : {
511 : const struct rsn_ie_hdr *hdr;
512 : const u8 *pos;
513 : int left;
514 : int i, count;
515 :
516 9020 : os_memset(data, 0, sizeof(*data));
517 9020 : data->proto = WPA_PROTO_RSN;
518 9020 : data->pairwise_cipher = WPA_CIPHER_CCMP;
519 9020 : data->group_cipher = WPA_CIPHER_CCMP;
520 9020 : data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
521 9020 : data->capabilities = 0;
522 9020 : data->pmkid = NULL;
523 9020 : data->num_pmkid = 0;
524 : #ifdef CONFIG_IEEE80211W
525 9020 : data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
526 : #else /* CONFIG_IEEE80211W */
527 : data->mgmt_group_cipher = 0;
528 : #endif /* CONFIG_IEEE80211W */
529 :
530 9020 : if (rsn_ie_len == 0) {
531 : /* No RSN IE - fail silently */
532 1 : return -1;
533 : }
534 :
535 9019 : if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
536 1 : wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
537 : __func__, (unsigned long) rsn_ie_len);
538 1 : return -1;
539 : }
540 :
541 9018 : hdr = (const struct rsn_ie_hdr *) rsn_ie;
542 :
543 18036 : if (hdr->elem_id != WLAN_EID_RSN ||
544 18035 : hdr->len != rsn_ie_len - 2 ||
545 9017 : WPA_GET_LE16(hdr->version) != RSN_VERSION) {
546 4 : wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
547 : __func__);
548 4 : return -2;
549 : }
550 :
551 9014 : pos = (const u8 *) (hdr + 1);
552 9014 : left = rsn_ie_len - sizeof(*hdr);
553 :
554 9014 : if (left >= RSN_SELECTOR_LEN) {
555 9012 : data->group_cipher = rsn_selector_to_bitfield(pos);
556 9012 : if (!wpa_cipher_valid_group(data->group_cipher)) {
557 1 : wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x",
558 : __func__, data->group_cipher);
559 1 : return -1;
560 : }
561 9011 : pos += RSN_SELECTOR_LEN;
562 9011 : left -= RSN_SELECTOR_LEN;
563 2 : } else if (left > 0) {
564 1 : wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
565 : __func__, left);
566 1 : return -3;
567 : }
568 :
569 9012 : if (left >= 2) {
570 9009 : data->pairwise_cipher = 0;
571 9009 : count = WPA_GET_LE16(pos);
572 9009 : pos += 2;
573 9009 : left -= 2;
574 9009 : if (count == 0 || count > left / RSN_SELECTOR_LEN) {
575 3 : wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
576 : "count %u left %u", __func__, count, left);
577 3 : return -4;
578 : }
579 18080 : for (i = 0; i < count; i++) {
580 9074 : data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
581 9074 : pos += RSN_SELECTOR_LEN;
582 9074 : left -= RSN_SELECTOR_LEN;
583 : }
584 : #ifdef CONFIG_IEEE80211W
585 9006 : if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
586 1 : wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
587 : "pairwise cipher", __func__);
588 1 : return -1;
589 : }
590 : #endif /* CONFIG_IEEE80211W */
591 3 : } else if (left == 1) {
592 1 : wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
593 : __func__);
594 1 : return -5;
595 : }
596 :
597 9007 : if (left >= 2) {
598 8998 : data->key_mgmt = 0;
599 8998 : count = WPA_GET_LE16(pos);
600 8998 : pos += 2;
601 8998 : left -= 2;
602 8998 : if (count == 0 || count > left / RSN_SELECTOR_LEN) {
603 2 : wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
604 : "count %u left %u", __func__, count, left);
605 2 : return -6;
606 : }
607 18339 : for (i = 0; i < count; i++) {
608 9343 : data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
609 9343 : pos += RSN_SELECTOR_LEN;
610 9343 : left -= RSN_SELECTOR_LEN;
611 : }
612 9 : } else if (left == 1) {
613 1 : wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
614 : __func__);
615 1 : return -7;
616 : }
617 :
618 9004 : if (left >= 2) {
619 8993 : data->capabilities = WPA_GET_LE16(pos);
620 8993 : pos += 2;
621 8993 : left -= 2;
622 : }
623 :
624 9004 : if (left >= 2) {
625 2459 : u16 num_pmkid = WPA_GET_LE16(pos);
626 2459 : pos += 2;
627 2459 : left -= 2;
628 2459 : if (num_pmkid > (unsigned int) left / PMKID_LEN) {
629 1 : wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
630 : "(num_pmkid=%u left=%d)",
631 : __func__, num_pmkid, left);
632 1 : data->num_pmkid = 0;
633 1 : return -9;
634 : } else {
635 2458 : data->num_pmkid = num_pmkid;
636 2458 : data->pmkid = pos;
637 2458 : pos += data->num_pmkid * PMKID_LEN;
638 2458 : left -= data->num_pmkid * PMKID_LEN;
639 : }
640 : }
641 :
642 : #ifdef CONFIG_IEEE80211W
643 9003 : if (left >= 4) {
644 785 : data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
645 785 : if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
646 1 : wpa_printf(MSG_DEBUG, "%s: Unsupported management "
647 : "group cipher 0x%x", __func__,
648 : data->mgmt_group_cipher);
649 1 : return -10;
650 : }
651 784 : pos += RSN_SELECTOR_LEN;
652 784 : left -= RSN_SELECTOR_LEN;
653 : }
654 : #endif /* CONFIG_IEEE80211W */
655 :
656 9002 : if (left > 0) {
657 2 : wpa_hexdump(MSG_DEBUG,
658 : "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
659 : pos, left);
660 : }
661 :
662 9002 : return 0;
663 : }
664 :
665 :
666 270 : static int wpa_selector_to_bitfield(const u8 *s)
667 : {
668 270 : if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
669 1 : return WPA_CIPHER_NONE;
670 269 : if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
671 0 : return WPA_CIPHER_WEP40;
672 269 : if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
673 228 : return WPA_CIPHER_TKIP;
674 41 : if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
675 41 : return WPA_CIPHER_CCMP;
676 0 : if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
677 0 : return WPA_CIPHER_WEP104;
678 0 : return 0;
679 : }
680 :
681 :
682 130 : static int wpa_key_mgmt_to_bitfield(const u8 *s)
683 : {
684 130 : if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
685 17 : return WPA_KEY_MGMT_IEEE8021X;
686 113 : if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
687 110 : return WPA_KEY_MGMT_PSK;
688 3 : if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
689 3 : return WPA_KEY_MGMT_WPA_NONE;
690 0 : return 0;
691 : }
692 :
693 :
694 119 : int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
695 : struct wpa_ie_data *data)
696 : {
697 : const struct wpa_ie_hdr *hdr;
698 : const u8 *pos;
699 : int left;
700 : int i, count;
701 :
702 119 : os_memset(data, 0, sizeof(*data));
703 119 : data->proto = WPA_PROTO_WPA;
704 119 : data->pairwise_cipher = WPA_CIPHER_TKIP;
705 119 : data->group_cipher = WPA_CIPHER_TKIP;
706 119 : data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
707 119 : data->capabilities = 0;
708 119 : data->pmkid = NULL;
709 119 : data->num_pmkid = 0;
710 119 : data->mgmt_group_cipher = 0;
711 :
712 119 : if (wpa_ie_len == 0) {
713 : /* No WPA IE - fail silently */
714 0 : return -1;
715 : }
716 :
717 119 : if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
718 0 : wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
719 : __func__, (unsigned long) wpa_ie_len);
720 0 : return -1;
721 : }
722 :
723 119 : hdr = (const struct wpa_ie_hdr *) wpa_ie;
724 :
725 238 : if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
726 238 : hdr->len != wpa_ie_len - 2 ||
727 238 : RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
728 119 : WPA_GET_LE16(hdr->version) != WPA_VERSION) {
729 0 : wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
730 : __func__);
731 0 : return -2;
732 : }
733 :
734 119 : pos = (const u8 *) (hdr + 1);
735 119 : left = wpa_ie_len - sizeof(*hdr);
736 :
737 119 : if (left >= WPA_SELECTOR_LEN) {
738 119 : data->group_cipher = wpa_selector_to_bitfield(pos);
739 119 : pos += WPA_SELECTOR_LEN;
740 119 : left -= WPA_SELECTOR_LEN;
741 0 : } else if (left > 0) {
742 0 : wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
743 : __func__, left);
744 0 : return -3;
745 : }
746 :
747 119 : if (left >= 2) {
748 119 : data->pairwise_cipher = 0;
749 119 : count = WPA_GET_LE16(pos);
750 119 : pos += 2;
751 119 : left -= 2;
752 119 : if (count == 0 || count > left / WPA_SELECTOR_LEN) {
753 0 : wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
754 : "count %u left %u", __func__, count, left);
755 0 : return -4;
756 : }
757 270 : for (i = 0; i < count; i++) {
758 151 : data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
759 151 : pos += WPA_SELECTOR_LEN;
760 151 : left -= WPA_SELECTOR_LEN;
761 : }
762 0 : } else if (left == 1) {
763 0 : wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
764 : __func__);
765 0 : return -5;
766 : }
767 :
768 119 : if (left >= 2) {
769 119 : data->key_mgmt = 0;
770 119 : count = WPA_GET_LE16(pos);
771 119 : pos += 2;
772 119 : left -= 2;
773 119 : if (count == 0 || count > left / WPA_SELECTOR_LEN) {
774 0 : wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
775 : "count %u left %u", __func__, count, left);
776 0 : return -6;
777 : }
778 249 : for (i = 0; i < count; i++) {
779 130 : data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
780 130 : pos += WPA_SELECTOR_LEN;
781 130 : left -= WPA_SELECTOR_LEN;
782 : }
783 0 : } else if (left == 1) {
784 0 : wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
785 : __func__);
786 0 : return -7;
787 : }
788 :
789 119 : if (left >= 2) {
790 0 : data->capabilities = WPA_GET_LE16(pos);
791 0 : pos += 2;
792 0 : left -= 2;
793 : }
794 :
795 119 : if (left > 0) {
796 0 : wpa_hexdump(MSG_DEBUG,
797 : "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
798 : pos, left);
799 : }
800 :
801 119 : return 0;
802 : }
803 :
804 :
805 : #ifdef CONFIG_IEEE80211R
806 :
807 : /**
808 : * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
809 : *
810 : * IEEE Std 802.11r-2008 - 8.5.1.5.3
811 : */
812 48 : void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
813 : const u8 *ssid, size_t ssid_len,
814 : const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
815 : const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
816 : {
817 : u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
818 : FT_R0KH_ID_MAX_LEN + ETH_ALEN];
819 : u8 *pos, r0_key_data[48], hash[32];
820 : const u8 *addr[2];
821 : size_t len[2];
822 :
823 : /*
824 : * R0-Key-Data = KDF-384(XXKey, "FT-R0",
825 : * SSIDlength || SSID || MDID || R0KHlength ||
826 : * R0KH-ID || S0KH-ID)
827 : * XXKey is either the second 256 bits of MSK or PSK.
828 : * PMK-R0 = L(R0-Key-Data, 0, 256)
829 : * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
830 : */
831 48 : if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
832 48 : return;
833 48 : pos = buf;
834 48 : *pos++ = ssid_len;
835 48 : os_memcpy(pos, ssid, ssid_len);
836 48 : pos += ssid_len;
837 48 : os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
838 48 : pos += MOBILITY_DOMAIN_ID_LEN;
839 48 : *pos++ = r0kh_id_len;
840 48 : os_memcpy(pos, r0kh_id, r0kh_id_len);
841 48 : pos += r0kh_id_len;
842 48 : os_memcpy(pos, s0kh_id, ETH_ALEN);
843 48 : pos += ETH_ALEN;
844 :
845 48 : sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
846 : r0_key_data, sizeof(r0_key_data));
847 48 : os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
848 :
849 : /*
850 : * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
851 : */
852 48 : addr[0] = (const u8 *) "FT-R0N";
853 48 : len[0] = 6;
854 48 : addr[1] = r0_key_data + PMK_LEN;
855 48 : len[1] = 16;
856 :
857 48 : sha256_vector(2, addr, len, hash);
858 48 : os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
859 : }
860 :
861 :
862 : /**
863 : * wpa_derive_pmk_r1_name - Derive PMKR1Name
864 : *
865 : * IEEE Std 802.11r-2008 - 8.5.1.5.4
866 : */
867 516 : void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
868 : const u8 *s1kh_id, u8 *pmk_r1_name)
869 : {
870 : u8 hash[32];
871 : const u8 *addr[4];
872 : size_t len[4];
873 :
874 : /*
875 : * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
876 : * R1KH-ID || S1KH-ID))
877 : */
878 516 : addr[0] = (const u8 *) "FT-R1N";
879 516 : len[0] = 6;
880 516 : addr[1] = pmk_r0_name;
881 516 : len[1] = WPA_PMK_NAME_LEN;
882 516 : addr[2] = r1kh_id;
883 516 : len[2] = FT_R1KH_ID_LEN;
884 516 : addr[3] = s1kh_id;
885 516 : len[3] = ETH_ALEN;
886 :
887 516 : sha256_vector(4, addr, len, hash);
888 516 : os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
889 516 : }
890 :
891 :
892 : /**
893 : * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
894 : *
895 : * IEEE Std 802.11r-2008 - 8.5.1.5.4
896 : */
897 287 : void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
898 : const u8 *r1kh_id, const u8 *s1kh_id,
899 : u8 *pmk_r1, u8 *pmk_r1_name)
900 : {
901 : u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
902 : u8 *pos;
903 :
904 : /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
905 287 : pos = buf;
906 287 : os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
907 287 : pos += FT_R1KH_ID_LEN;
908 287 : os_memcpy(pos, s1kh_id, ETH_ALEN);
909 287 : pos += ETH_ALEN;
910 :
911 287 : sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
912 :
913 287 : wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
914 287 : }
915 :
916 :
917 : /**
918 : * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
919 : *
920 : * IEEE Std 802.11r-2008 - 8.5.1.5.5
921 : */
922 490 : int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
923 : const u8 *sta_addr, const u8 *bssid,
924 : const u8 *pmk_r1_name,
925 : struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher)
926 : {
927 : u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
928 : u8 *pos, hash[32];
929 : const u8 *addr[6];
930 : size_t len[6];
931 : u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
932 : size_t ptk_len;
933 :
934 : /*
935 : * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
936 : * BSSID || STA-ADDR)
937 : */
938 490 : pos = buf;
939 490 : os_memcpy(pos, snonce, WPA_NONCE_LEN);
940 490 : pos += WPA_NONCE_LEN;
941 490 : os_memcpy(pos, anonce, WPA_NONCE_LEN);
942 490 : pos += WPA_NONCE_LEN;
943 490 : os_memcpy(pos, bssid, ETH_ALEN);
944 490 : pos += ETH_ALEN;
945 490 : os_memcpy(pos, sta_addr, ETH_ALEN);
946 490 : pos += ETH_ALEN;
947 :
948 490 : ptk->kck_len = wpa_kck_len(akmp);
949 490 : ptk->kek_len = wpa_kek_len(akmp);
950 490 : ptk->tk_len = wpa_cipher_key_len(cipher);
951 490 : ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
952 :
953 490 : sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, tmp, ptk_len);
954 :
955 : /*
956 : * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
957 : * ANonce || BSSID || STA-ADDR))
958 : */
959 490 : addr[0] = pmk_r1_name;
960 490 : len[0] = WPA_PMK_NAME_LEN;
961 490 : addr[1] = (const u8 *) "FT-PTKN";
962 490 : len[1] = 7;
963 490 : addr[2] = snonce;
964 490 : len[2] = WPA_NONCE_LEN;
965 490 : addr[3] = anonce;
966 490 : len[3] = WPA_NONCE_LEN;
967 490 : addr[4] = bssid;
968 490 : len[4] = ETH_ALEN;
969 490 : addr[5] = sta_addr;
970 490 : len[5] = ETH_ALEN;
971 :
972 490 : sha256_vector(6, addr, len, hash);
973 490 : os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
974 :
975 490 : os_memcpy(ptk->kck, tmp, ptk->kck_len);
976 490 : os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
977 490 : os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
978 :
979 490 : wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
980 490 : wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
981 490 : wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
982 490 : wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
983 :
984 490 : os_memset(tmp, 0, sizeof(tmp));
985 :
986 490 : return 0;
987 : }
988 :
989 : #endif /* CONFIG_IEEE80211R */
990 :
991 :
992 : /**
993 : * rsn_pmkid - Calculate PMK identifier
994 : * @pmk: Pairwise master key
995 : * @pmk_len: Length of pmk in bytes
996 : * @aa: Authenticator address
997 : * @spa: Supplicant address
998 : * @pmkid: Buffer for PMKID
999 : * @use_sha256: Whether to use SHA256-based KDF
1000 : *
1001 : * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
1002 : * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
1003 : */
1004 1839 : void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
1005 : u8 *pmkid, int use_sha256)
1006 : {
1007 1839 : char *title = "PMK Name";
1008 : const u8 *addr[3];
1009 1839 : const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1010 : unsigned char hash[SHA256_MAC_LEN];
1011 :
1012 1839 : addr[0] = (u8 *) title;
1013 1839 : addr[1] = aa;
1014 1839 : addr[2] = spa;
1015 :
1016 : #ifdef CONFIG_IEEE80211W
1017 1839 : if (use_sha256)
1018 12 : hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
1019 : else
1020 : #endif /* CONFIG_IEEE80211W */
1021 1827 : hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
1022 1839 : os_memcpy(pmkid, hash, PMKID_LEN);
1023 1839 : }
1024 :
1025 :
1026 : #ifdef CONFIG_SUITEB
1027 : /**
1028 : * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
1029 : * @kck: Key confirmation key
1030 : * @kck_len: Length of kck in bytes
1031 : * @aa: Authenticator address
1032 : * @spa: Supplicant address
1033 : * @pmkid: Buffer for PMKID
1034 : * Returns: 0 on success, -1 on failure
1035 : *
1036 : * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1037 : * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
1038 : */
1039 3 : int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
1040 : const u8 *spa, u8 *pmkid)
1041 : {
1042 3 : char *title = "PMK Name";
1043 : const u8 *addr[3];
1044 3 : const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1045 : unsigned char hash[SHA256_MAC_LEN];
1046 :
1047 3 : addr[0] = (u8 *) title;
1048 3 : addr[1] = aa;
1049 3 : addr[2] = spa;
1050 :
1051 3 : if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
1052 0 : return -1;
1053 3 : os_memcpy(pmkid, hash, PMKID_LEN);
1054 3 : return 0;
1055 : }
1056 : #endif /* CONFIG_SUITEB */
1057 :
1058 :
1059 : #ifdef CONFIG_SUITEB192
1060 : /**
1061 : * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
1062 : * @kck: Key confirmation key
1063 : * @kck_len: Length of kck in bytes
1064 : * @aa: Authenticator address
1065 : * @spa: Supplicant address
1066 : * @pmkid: Buffer for PMKID
1067 : * Returns: 0 on success, -1 on failure
1068 : *
1069 : * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1070 : * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
1071 : */
1072 3 : int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
1073 : const u8 *spa, u8 *pmkid)
1074 : {
1075 3 : char *title = "PMK Name";
1076 : const u8 *addr[3];
1077 3 : const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1078 : unsigned char hash[SHA384_MAC_LEN];
1079 :
1080 3 : addr[0] = (u8 *) title;
1081 3 : addr[1] = aa;
1082 3 : addr[2] = spa;
1083 :
1084 3 : if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
1085 0 : return -1;
1086 3 : os_memcpy(pmkid, hash, PMKID_LEN);
1087 3 : return 0;
1088 : }
1089 : #endif /* CONFIG_SUITEB192 */
1090 :
1091 :
1092 : /**
1093 : * wpa_cipher_txt - Convert cipher suite to a text string
1094 : * @cipher: Cipher suite (WPA_CIPHER_* enum)
1095 : * Returns: Pointer to a text string of the cipher suite name
1096 : */
1097 10632 : const char * wpa_cipher_txt(int cipher)
1098 : {
1099 10632 : switch (cipher) {
1100 : case WPA_CIPHER_NONE:
1101 1016 : return "NONE";
1102 : case WPA_CIPHER_WEP40:
1103 98 : return "WEP-40";
1104 : case WPA_CIPHER_WEP104:
1105 16 : return "WEP-104";
1106 : case WPA_CIPHER_TKIP:
1107 402 : return "TKIP";
1108 : case WPA_CIPHER_CCMP:
1109 9055 : return "CCMP";
1110 : case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
1111 3 : return "CCMP+TKIP";
1112 : case WPA_CIPHER_GCMP:
1113 16 : return "GCMP";
1114 : case WPA_CIPHER_GCMP_256:
1115 16 : return "GCMP-256";
1116 : case WPA_CIPHER_CCMP_256:
1117 6 : return "CCMP-256";
1118 : case WPA_CIPHER_GTK_NOT_USED:
1119 4 : return "GTK_NOT_USED";
1120 : default:
1121 0 : return "UNKNOWN";
1122 : }
1123 : }
1124 :
1125 :
1126 : /**
1127 : * wpa_key_mgmt_txt - Convert key management suite to a text string
1128 : * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
1129 : * @proto: WPA/WPA2 version (WPA_PROTO_*)
1130 : * Returns: Pointer to a text string of the key management suite name
1131 : */
1132 4041 : const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
1133 : {
1134 4041 : switch (key_mgmt) {
1135 : case WPA_KEY_MGMT_IEEE8021X:
1136 235 : if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1137 0 : return "WPA2+WPA/IEEE 802.1X/EAP";
1138 235 : return proto == WPA_PROTO_RSN ?
1139 235 : "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
1140 : case WPA_KEY_MGMT_PSK:
1141 1880 : if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1142 518 : return "WPA2-PSK+WPA-PSK";
1143 1362 : return proto == WPA_PROTO_RSN ?
1144 1362 : "WPA2-PSK" : "WPA-PSK";
1145 : case WPA_KEY_MGMT_NONE:
1146 971 : return "NONE";
1147 : case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
1148 5 : return "IEEE 802.1X (no WPA)";
1149 : #ifdef CONFIG_IEEE80211R
1150 : case WPA_KEY_MGMT_FT_IEEE8021X:
1151 27 : return "FT-EAP";
1152 : case WPA_KEY_MGMT_FT_PSK:
1153 725 : return "FT-PSK";
1154 : #endif /* CONFIG_IEEE80211R */
1155 : #ifdef CONFIG_IEEE80211W
1156 : case WPA_KEY_MGMT_IEEE8021X_SHA256:
1157 12 : return "WPA2-EAP-SHA256";
1158 : case WPA_KEY_MGMT_PSK_SHA256:
1159 70 : return "WPA2-PSK-SHA256";
1160 : #endif /* CONFIG_IEEE80211W */
1161 : case WPA_KEY_MGMT_WPS:
1162 1 : return "WPS";
1163 : case WPA_KEY_MGMT_SAE:
1164 59 : return "SAE";
1165 : case WPA_KEY_MGMT_FT_SAE:
1166 25 : return "FT-SAE";
1167 : case WPA_KEY_MGMT_OSEN:
1168 2 : return "OSEN";
1169 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
1170 5 : return "WPA2-EAP-SUITE-B";
1171 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
1172 5 : return "WPA2-EAP-SUITE-B-192";
1173 : default:
1174 19 : return "UNKNOWN";
1175 : }
1176 : }
1177 :
1178 :
1179 3614 : u32 wpa_akm_to_suite(int akm)
1180 : {
1181 3614 : if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
1182 12 : return WLAN_AKM_SUITE_FT_8021X;
1183 3602 : if (akm & WPA_KEY_MGMT_FT_PSK)
1184 0 : return WLAN_AKM_SUITE_FT_PSK;
1185 3602 : if (akm & WPA_KEY_MGMT_IEEE8021X)
1186 3591 : return WLAN_AKM_SUITE_8021X;
1187 11 : if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
1188 11 : return WLAN_AKM_SUITE_8021X_SHA256;
1189 0 : if (akm & WPA_KEY_MGMT_IEEE8021X)
1190 0 : return WLAN_AKM_SUITE_8021X;
1191 0 : if (akm & WPA_KEY_MGMT_PSK_SHA256)
1192 0 : return WLAN_AKM_SUITE_PSK_SHA256;
1193 0 : if (akm & WPA_KEY_MGMT_PSK)
1194 0 : return WLAN_AKM_SUITE_PSK;
1195 0 : if (akm & WPA_KEY_MGMT_CCKM)
1196 0 : return WLAN_AKM_SUITE_CCKM;
1197 0 : if (akm & WPA_KEY_MGMT_OSEN)
1198 0 : return WLAN_AKM_SUITE_OSEN;
1199 0 : if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
1200 0 : return WLAN_AKM_SUITE_8021X_SUITE_B;
1201 0 : if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
1202 0 : return WLAN_AKM_SUITE_8021X_SUITE_B_192;
1203 0 : return 0;
1204 : }
1205 :
1206 :
1207 2591 : int wpa_compare_rsn_ie(int ft_initial_assoc,
1208 : const u8 *ie1, size_t ie1len,
1209 : const u8 *ie2, size_t ie2len)
1210 : {
1211 2591 : if (ie1 == NULL || ie2 == NULL)
1212 0 : return -1;
1213 :
1214 2591 : if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
1215 2543 : return 0; /* identical IEs */
1216 :
1217 : #ifdef CONFIG_IEEE80211R
1218 48 : if (ft_initial_assoc) {
1219 : struct wpa_ie_data ie1d, ie2d;
1220 : /*
1221 : * The PMKID-List in RSN IE is different between Beacon/Probe
1222 : * Response/(Re)Association Request frames and EAPOL-Key
1223 : * messages in FT initial mobility domain association. Allow
1224 : * for this, but verify that other parts of the RSN IEs are
1225 : * identical.
1226 : */
1227 96 : if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
1228 48 : wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
1229 48 : return -1;
1230 96 : if (ie1d.proto == ie2d.proto &&
1231 96 : ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
1232 96 : ie1d.group_cipher == ie2d.group_cipher &&
1233 96 : ie1d.key_mgmt == ie2d.key_mgmt &&
1234 96 : ie1d.capabilities == ie2d.capabilities &&
1235 48 : ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
1236 48 : return 0;
1237 : }
1238 : #endif /* CONFIG_IEEE80211R */
1239 :
1240 0 : return -1;
1241 : }
1242 :
1243 :
1244 : #ifdef CONFIG_IEEE80211R
1245 48 : int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
1246 : {
1247 : u8 *start, *end, *rpos, *rend;
1248 48 : int added = 0;
1249 :
1250 48 : start = ies;
1251 48 : end = ies + ies_len;
1252 :
1253 96 : while (start < end) {
1254 48 : if (*start == WLAN_EID_RSN)
1255 48 : break;
1256 0 : start += 2 + start[1];
1257 : }
1258 48 : if (start >= end) {
1259 0 : wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
1260 : "IEs data");
1261 0 : return -1;
1262 : }
1263 48 : wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
1264 48 : start, 2 + start[1]);
1265 :
1266 : /* Find start of PMKID-Count */
1267 48 : rpos = start + 2;
1268 48 : rend = rpos + start[1];
1269 :
1270 : /* Skip Version and Group Data Cipher Suite */
1271 48 : rpos += 2 + 4;
1272 : /* Skip Pairwise Cipher Suite Count and List */
1273 48 : rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1274 : /* Skip AKM Suite Count and List */
1275 48 : rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1276 :
1277 48 : if (rpos == rend) {
1278 : /* Add RSN Capabilities */
1279 0 : os_memmove(rpos + 2, rpos, end - rpos);
1280 0 : *rpos++ = 0;
1281 0 : *rpos++ = 0;
1282 : } else {
1283 : /* Skip RSN Capabilities */
1284 48 : rpos += 2;
1285 48 : if (rpos > rend) {
1286 0 : wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
1287 : "IEs data");
1288 0 : return -1;
1289 : }
1290 : }
1291 :
1292 48 : if (rpos == rend) {
1293 : /* No PMKID-Count field included; add it */
1294 39 : os_memmove(rpos + 2 + PMKID_LEN, rpos, end - rpos);
1295 39 : WPA_PUT_LE16(rpos, 1);
1296 39 : rpos += 2;
1297 39 : os_memcpy(rpos, pmkid, PMKID_LEN);
1298 39 : added += 2 + PMKID_LEN;
1299 39 : start[1] += 2 + PMKID_LEN;
1300 : } else {
1301 : /* PMKID-Count was included; use it */
1302 9 : if (WPA_GET_LE16(rpos) != 0) {
1303 0 : wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
1304 : "in RSN IE in EAPOL-Key data");
1305 0 : return -1;
1306 : }
1307 9 : WPA_PUT_LE16(rpos, 1);
1308 9 : rpos += 2;
1309 9 : os_memmove(rpos + PMKID_LEN, rpos, end - rpos);
1310 9 : os_memcpy(rpos, pmkid, PMKID_LEN);
1311 9 : added += PMKID_LEN;
1312 9 : start[1] += PMKID_LEN;
1313 : }
1314 :
1315 48 : wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
1316 48 : "(PMKID inserted)", start, 2 + start[1]);
1317 :
1318 48 : return added;
1319 : }
1320 : #endif /* CONFIG_IEEE80211R */
1321 :
1322 :
1323 14903 : int wpa_cipher_key_len(int cipher)
1324 : {
1325 14903 : switch (cipher) {
1326 : case WPA_CIPHER_CCMP_256:
1327 : case WPA_CIPHER_GCMP_256:
1328 : case WPA_CIPHER_BIP_GMAC_256:
1329 : case WPA_CIPHER_BIP_CMAC_256:
1330 63 : return 32;
1331 : case WPA_CIPHER_CCMP:
1332 : case WPA_CIPHER_GCMP:
1333 : case WPA_CIPHER_AES_128_CMAC:
1334 : case WPA_CIPHER_BIP_GMAC_128:
1335 14560 : return 16;
1336 : case WPA_CIPHER_TKIP:
1337 268 : return 32;
1338 : case WPA_CIPHER_WEP104:
1339 0 : return 13;
1340 : case WPA_CIPHER_WEP40:
1341 0 : return 5;
1342 : }
1343 :
1344 12 : return 0;
1345 : }
1346 :
1347 :
1348 2811 : int wpa_cipher_rsc_len(int cipher)
1349 : {
1350 2811 : switch (cipher) {
1351 : case WPA_CIPHER_CCMP_256:
1352 : case WPA_CIPHER_GCMP_256:
1353 : case WPA_CIPHER_CCMP:
1354 : case WPA_CIPHER_GCMP:
1355 : case WPA_CIPHER_TKIP:
1356 2811 : return 6;
1357 : case WPA_CIPHER_WEP104:
1358 : case WPA_CIPHER_WEP40:
1359 0 : return 0;
1360 : }
1361 :
1362 0 : return 0;
1363 : }
1364 :
1365 :
1366 6856 : int wpa_cipher_to_alg(int cipher)
1367 : {
1368 6856 : switch (cipher) {
1369 : case WPA_CIPHER_CCMP_256:
1370 5 : return WPA_ALG_CCMP_256;
1371 : case WPA_CIPHER_GCMP_256:
1372 13 : return WPA_ALG_GCMP_256;
1373 : case WPA_CIPHER_CCMP:
1374 6366 : return WPA_ALG_CCMP;
1375 : case WPA_CIPHER_GCMP:
1376 13 : return WPA_ALG_GCMP;
1377 : case WPA_CIPHER_TKIP:
1378 162 : return WPA_ALG_TKIP;
1379 : case WPA_CIPHER_WEP104:
1380 : case WPA_CIPHER_WEP40:
1381 0 : return WPA_ALG_WEP;
1382 : case WPA_CIPHER_AES_128_CMAC:
1383 280 : return WPA_ALG_IGTK;
1384 : case WPA_CIPHER_BIP_GMAC_128:
1385 7 : return WPA_ALG_BIP_GMAC_128;
1386 : case WPA_CIPHER_BIP_GMAC_256:
1387 7 : return WPA_ALG_BIP_GMAC_256;
1388 : case WPA_CIPHER_BIP_CMAC_256:
1389 3 : return WPA_ALG_BIP_CMAC_256;
1390 : }
1391 0 : return WPA_ALG_NONE;
1392 : }
1393 :
1394 :
1395 13974 : int wpa_cipher_valid_pairwise(int cipher)
1396 : {
1397 27942 : return cipher == WPA_CIPHER_CCMP_256 ||
1398 13947 : cipher == WPA_CIPHER_GCMP_256 ||
1399 326 : cipher == WPA_CIPHER_CCMP ||
1400 14279 : cipher == WPA_CIPHER_GCMP ||
1401 : cipher == WPA_CIPHER_TKIP;
1402 : }
1403 :
1404 :
1405 18758 : u32 wpa_cipher_to_suite(int proto, int cipher)
1406 : {
1407 18758 : if (cipher & WPA_CIPHER_CCMP_256)
1408 5 : return RSN_CIPHER_SUITE_CCMP_256;
1409 18753 : if (cipher & WPA_CIPHER_GCMP_256)
1410 14 : return RSN_CIPHER_SUITE_GCMP_256;
1411 18739 : if (cipher & WPA_CIPHER_CCMP)
1412 17751 : return (proto == WPA_PROTO_RSN ?
1413 17751 : RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
1414 988 : if (cipher & WPA_CIPHER_GCMP)
1415 26 : return RSN_CIPHER_SUITE_GCMP;
1416 962 : if (cipher & WPA_CIPHER_TKIP)
1417 284 : return (proto == WPA_PROTO_RSN ?
1418 284 : RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
1419 678 : if (cipher & WPA_CIPHER_WEP104)
1420 0 : return (proto == WPA_PROTO_RSN ?
1421 0 : RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
1422 678 : if (cipher & WPA_CIPHER_WEP40)
1423 0 : return (proto == WPA_PROTO_RSN ?
1424 0 : RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
1425 678 : if (cipher & WPA_CIPHER_NONE)
1426 32 : return (proto == WPA_PROTO_RSN ?
1427 32 : RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
1428 646 : if (cipher & WPA_CIPHER_GTK_NOT_USED)
1429 2 : return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
1430 644 : if (cipher & WPA_CIPHER_AES_128_CMAC)
1431 635 : return RSN_CIPHER_SUITE_AES_128_CMAC;
1432 9 : if (cipher & WPA_CIPHER_BIP_GMAC_128)
1433 3 : return RSN_CIPHER_SUITE_BIP_GMAC_128;
1434 6 : if (cipher & WPA_CIPHER_BIP_GMAC_256)
1435 4 : return RSN_CIPHER_SUITE_BIP_GMAC_256;
1436 2 : if (cipher & WPA_CIPHER_BIP_CMAC_256)
1437 2 : return RSN_CIPHER_SUITE_BIP_CMAC_256;
1438 0 : return 0;
1439 : }
1440 :
1441 :
1442 1313 : int rsn_cipher_put_suites(u8 *start, int ciphers)
1443 : {
1444 1313 : u8 *pos = start;
1445 :
1446 1313 : if (ciphers & WPA_CIPHER_CCMP_256) {
1447 1 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
1448 1 : pos += RSN_SELECTOR_LEN;
1449 : }
1450 1313 : if (ciphers & WPA_CIPHER_GCMP_256) {
1451 2 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
1452 2 : pos += RSN_SELECTOR_LEN;
1453 : }
1454 1313 : if (ciphers & WPA_CIPHER_CCMP) {
1455 1306 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1456 1306 : pos += RSN_SELECTOR_LEN;
1457 : }
1458 1313 : if (ciphers & WPA_CIPHER_GCMP) {
1459 2 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
1460 2 : pos += RSN_SELECTOR_LEN;
1461 : }
1462 1313 : if (ciphers & WPA_CIPHER_TKIP) {
1463 17 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
1464 17 : pos += RSN_SELECTOR_LEN;
1465 : }
1466 1313 : if (ciphers & WPA_CIPHER_NONE) {
1467 0 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
1468 0 : pos += RSN_SELECTOR_LEN;
1469 : }
1470 :
1471 1313 : return (pos - start) / RSN_SELECTOR_LEN;
1472 : }
1473 :
1474 :
1475 31 : int wpa_cipher_put_suites(u8 *start, int ciphers)
1476 : {
1477 31 : u8 *pos = start;
1478 :
1479 31 : if (ciphers & WPA_CIPHER_CCMP) {
1480 13 : RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
1481 13 : pos += WPA_SELECTOR_LEN;
1482 : }
1483 31 : if (ciphers & WPA_CIPHER_TKIP) {
1484 29 : RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
1485 29 : pos += WPA_SELECTOR_LEN;
1486 : }
1487 31 : if (ciphers & WPA_CIPHER_NONE) {
1488 1 : RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
1489 1 : pos += WPA_SELECTOR_LEN;
1490 : }
1491 :
1492 31 : return (pos - start) / RSN_SELECTOR_LEN;
1493 : }
1494 :
1495 :
1496 3935 : int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
1497 : {
1498 3935 : if (ciphers & WPA_CIPHER_CCMP_256)
1499 2 : return WPA_CIPHER_CCMP_256;
1500 3933 : if (ciphers & WPA_CIPHER_GCMP_256)
1501 6 : return WPA_CIPHER_GCMP_256;
1502 3927 : if (ciphers & WPA_CIPHER_CCMP)
1503 3876 : return WPA_CIPHER_CCMP;
1504 51 : if (ciphers & WPA_CIPHER_GCMP)
1505 6 : return WPA_CIPHER_GCMP;
1506 45 : if (ciphers & WPA_CIPHER_TKIP)
1507 43 : return WPA_CIPHER_TKIP;
1508 2 : if (none_allowed && (ciphers & WPA_CIPHER_NONE))
1509 0 : return WPA_CIPHER_NONE;
1510 2 : return -1;
1511 : }
1512 :
1513 :
1514 1826 : int wpa_pick_group_cipher(int ciphers)
1515 : {
1516 1826 : if (ciphers & WPA_CIPHER_CCMP_256)
1517 1 : return WPA_CIPHER_CCMP_256;
1518 1825 : if (ciphers & WPA_CIPHER_GCMP_256)
1519 3 : return WPA_CIPHER_GCMP_256;
1520 1822 : if (ciphers & WPA_CIPHER_CCMP)
1521 1760 : return WPA_CIPHER_CCMP;
1522 62 : if (ciphers & WPA_CIPHER_GCMP)
1523 3 : return WPA_CIPHER_GCMP;
1524 59 : if (ciphers & WPA_CIPHER_GTK_NOT_USED)
1525 2 : return WPA_CIPHER_GTK_NOT_USED;
1526 57 : if (ciphers & WPA_CIPHER_TKIP)
1527 57 : return WPA_CIPHER_TKIP;
1528 0 : if (ciphers & WPA_CIPHER_WEP104)
1529 0 : return WPA_CIPHER_WEP104;
1530 0 : if (ciphers & WPA_CIPHER_WEP40)
1531 0 : return WPA_CIPHER_WEP40;
1532 0 : return -1;
1533 : }
1534 :
1535 :
1536 830 : int wpa_parse_cipher(const char *value)
1537 : {
1538 830 : int val = 0, last;
1539 : char *start, *end, *buf;
1540 :
1541 830 : buf = os_strdup(value);
1542 830 : if (buf == NULL)
1543 2 : return -1;
1544 828 : start = buf;
1545 :
1546 1668 : while (*start != '\0') {
1547 1684 : while (*start == ' ' || *start == '\t')
1548 6 : start++;
1549 839 : if (*start == '\0')
1550 1 : break;
1551 838 : end = start;
1552 5104 : while (*end != ' ' && *end != '\t' && *end != '\0')
1553 3428 : end++;
1554 838 : last = *end == '\0';
1555 838 : *end = '\0';
1556 838 : if (os_strcmp(start, "CCMP-256") == 0)
1557 5 : val |= WPA_CIPHER_CCMP_256;
1558 833 : else if (os_strcmp(start, "GCMP-256") == 0)
1559 8 : val |= WPA_CIPHER_GCMP_256;
1560 825 : else if (os_strcmp(start, "CCMP") == 0)
1561 761 : val |= WPA_CIPHER_CCMP;
1562 64 : else if (os_strcmp(start, "GCMP") == 0)
1563 8 : val |= WPA_CIPHER_GCMP;
1564 56 : else if (os_strcmp(start, "TKIP") == 0)
1565 43 : val |= WPA_CIPHER_TKIP;
1566 13 : else if (os_strcmp(start, "WEP104") == 0)
1567 3 : val |= WPA_CIPHER_WEP104;
1568 10 : else if (os_strcmp(start, "WEP40") == 0)
1569 4 : val |= WPA_CIPHER_WEP40;
1570 6 : else if (os_strcmp(start, "NONE") == 0)
1571 2 : val |= WPA_CIPHER_NONE;
1572 4 : else if (os_strcmp(start, "GTK_NOT_USED") == 0)
1573 2 : val |= WPA_CIPHER_GTK_NOT_USED;
1574 : else {
1575 2 : os_free(buf);
1576 2 : return -1;
1577 : }
1578 :
1579 836 : if (last)
1580 824 : break;
1581 12 : start = end + 1;
1582 : }
1583 826 : os_free(buf);
1584 :
1585 826 : return val;
1586 : }
1587 :
1588 :
1589 5102 : int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
1590 : {
1591 5102 : char *pos = start;
1592 : int ret;
1593 :
1594 5102 : if (ciphers & WPA_CIPHER_CCMP_256) {
1595 2 : ret = os_snprintf(pos, end - pos, "%sCCMP-256",
1596 : pos == start ? "" : delim);
1597 2 : if (os_snprintf_error(end - pos, ret))
1598 0 : return -1;
1599 2 : pos += ret;
1600 : }
1601 5102 : if (ciphers & WPA_CIPHER_GCMP_256) {
1602 3 : ret = os_snprintf(pos, end - pos, "%sGCMP-256",
1603 : pos == start ? "" : delim);
1604 3 : if (os_snprintf_error(end - pos, ret))
1605 0 : return -1;
1606 3 : pos += ret;
1607 : }
1608 5102 : if (ciphers & WPA_CIPHER_CCMP) {
1609 339 : ret = os_snprintf(pos, end - pos, "%sCCMP",
1610 : pos == start ? "" : delim);
1611 339 : if (os_snprintf_error(end - pos, ret))
1612 0 : return -1;
1613 339 : pos += ret;
1614 : }
1615 5102 : if (ciphers & WPA_CIPHER_GCMP) {
1616 4 : ret = os_snprintf(pos, end - pos, "%sGCMP",
1617 : pos == start ? "" : delim);
1618 4 : if (os_snprintf_error(end - pos, ret))
1619 0 : return -1;
1620 4 : pos += ret;
1621 : }
1622 5102 : if (ciphers & WPA_CIPHER_TKIP) {
1623 42 : ret = os_snprintf(pos, end - pos, "%sTKIP",
1624 : pos == start ? "" : delim);
1625 42 : if (os_snprintf_error(end - pos, ret))
1626 0 : return -1;
1627 42 : pos += ret;
1628 : }
1629 5102 : if (ciphers & WPA_CIPHER_WEP104) {
1630 5 : ret = os_snprintf(pos, end - pos, "%sWEP104",
1631 : pos == start ? "" : delim);
1632 5 : if (os_snprintf_error(end - pos, ret))
1633 0 : return -1;
1634 5 : pos += ret;
1635 : }
1636 5102 : if (ciphers & WPA_CIPHER_WEP40) {
1637 5 : ret = os_snprintf(pos, end - pos, "%sWEP40",
1638 : pos == start ? "" : delim);
1639 5 : if (os_snprintf_error(end - pos, ret))
1640 0 : return -1;
1641 5 : pos += ret;
1642 : }
1643 5102 : if (ciphers & WPA_CIPHER_NONE) {
1644 0 : ret = os_snprintf(pos, end - pos, "%sNONE",
1645 : pos == start ? "" : delim);
1646 0 : if (os_snprintf_error(end - pos, ret))
1647 0 : return -1;
1648 0 : pos += ret;
1649 : }
1650 :
1651 5102 : return pos - start;
1652 : }
1653 :
1654 :
1655 17115 : int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
1656 : {
1657 17115 : int pairwise = 0;
1658 :
1659 : /* Select group cipher based on the enabled pairwise cipher suites */
1660 17115 : if (wpa & 1)
1661 121 : pairwise |= wpa_pairwise;
1662 17115 : if (wpa & 2)
1663 7932 : pairwise |= rsn_pairwise;
1664 :
1665 17115 : if (pairwise & WPA_CIPHER_TKIP)
1666 91 : return WPA_CIPHER_TKIP;
1667 17024 : if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
1668 13 : return WPA_CIPHER_GCMP;
1669 17011 : if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
1670 : WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
1671 13 : return WPA_CIPHER_GCMP_256;
1672 16998 : if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
1673 : WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
1674 2 : return WPA_CIPHER_CCMP_256;
1675 16996 : return WPA_CIPHER_CCMP;
1676 : }
|