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