1 /*
2 * WPA/RSN - Shared functions for supplicant and authenticator
3 * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14 #ifdef ESP_SUPPLICANT
15
16 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "common/defs.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/wpa_common.h"
21 #include "rsn_supp/wpa.h"
22 #include "crypto/sha1.h"
23 #include "crypto/sha256.h"
24 #include "crypto/md5.h"
25 #include "crypto/aes.h"
26
27 #define MD5_MAC_LEN 16
28
29 #ifndef CONFIG_NO_WPA2
rsn_selector_to_bitfield(const u8 * s)30 static int rsn_selector_to_bitfield(const u8 *s)
31 {
32 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
33 return WPA_CIPHER_NONE;
34 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
35 return WPA_CIPHER_WEP40;
36 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
37 return WPA_CIPHER_TKIP;
38 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
39 return WPA_CIPHER_CCMP;
40 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
41 return WPA_CIPHER_WEP104;
42 #ifdef CONFIG_IEEE80211W
43 if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
44 return WPA_CIPHER_AES_128_CMAC;
45 #endif /* CONFIG_IEEE80211W */
46 return 0;
47 }
48
rsn_key_mgmt_to_bitfield(const u8 * s)49 static int rsn_key_mgmt_to_bitfield(const u8 *s)
50 {
51 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
52 return WPA_KEY_MGMT_IEEE8021X;
53 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
54 return WPA_KEY_MGMT_PSK;
55 #ifdef CONFIG_IEEE80211R
56 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
57 return WPA_KEY_MGMT_FT_IEEE8021X;
58 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
59 return WPA_KEY_MGMT_FT_PSK;
60 #endif /* CONFIG_IEEE80211R */
61 #ifdef CONFIG_IEEE80211W
62 #ifdef CONFIG_WPA3_SAE
63 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
64 return WPA_KEY_MGMT_SAE;
65 #endif /* CONFIG_WPA3_SAE */
66 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
67 return WPA_KEY_MGMT_IEEE8021X_SHA256;
68 if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
69 return WPA_KEY_MGMT_PSK_SHA256;
70 #endif /* CONFIG_IEEE80211W */
71 return 0;
72 }
73
wpa_selector_to_bitfield(const u8 * s)74 static int wpa_selector_to_bitfield(const u8 *s)
75 {
76 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
77 return WPA_CIPHER_NONE;
78 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
79 return WPA_CIPHER_WEP40;
80 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
81 return WPA_CIPHER_TKIP;
82 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
83 return WPA_CIPHER_CCMP;
84 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
85 return WPA_CIPHER_WEP104;
86 return 0;
87 }
88
wpa_key_mgmt_to_bitfield(const u8 * s)89 static int wpa_key_mgmt_to_bitfield(const u8 *s)
90 {
91 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
92 return WPA_KEY_MGMT_IEEE8021X;
93 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
94 return WPA_KEY_MGMT_PSK;
95 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
96 return WPA_KEY_MGMT_WPA_NONE;
97 return 0;
98 }
99 #endif /* CONFIG_NO_WPA2 */
100 /**
101 * wpa_parse_wpa_ie_rsn - Parse RSN IE
102 * @rsn_ie: Buffer containing RSN IE
103 * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
104 * @data: Pointer to structure that will be filled in with parsed data
105 * Returns: 0 on success, <0 on failure
106 */
wpa_parse_wpa_ie_rsn(const u8 * rsn_ie,size_t rsn_ie_len,struct wpa_ie_data * data)107 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
108 struct wpa_ie_data *data)
109 {
110 #ifndef CONFIG_NO_WPA2
111 const struct rsn_ie_hdr *hdr;
112 const u8 *pos;
113 int left;
114 int i, count;
115
116 memset(data, 0, sizeof(*data));
117 data->proto = WPA_PROTO_RSN;
118 data->pairwise_cipher = WPA_CIPHER_CCMP;
119 data->group_cipher = WPA_CIPHER_CCMP;
120 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
121 data->capabilities = 0;
122 data->pmkid = NULL;
123 data->num_pmkid = 0;
124 data->mgmt_group_cipher = 0;
125
126 if (rsn_ie_len == 0) {
127 /* No RSN IE - fail silently */
128 return -1;
129 }
130
131 if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
132 #ifdef DEBUG_PRINT
133 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
134 __func__, (unsigned long) rsn_ie_len);
135 #endif
136 return -1;
137 }
138
139 hdr = (const struct rsn_ie_hdr *) rsn_ie;
140
141 if (hdr->elem_id != WLAN_EID_RSN ||
142 hdr->len != rsn_ie_len - 2 ||
143 WPA_GET_LE16(hdr->version) != RSN_VERSION) {
144 #ifdef DEBUG_PRINT
145 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
146 __func__);
147 #endif
148 return -2;
149 }
150
151 pos = (const u8 *) (hdr + 1);
152 left = rsn_ie_len - sizeof(*hdr);
153
154 if (left >= RSN_SELECTOR_LEN) {
155 data->group_cipher = rsn_selector_to_bitfield(pos);
156 pos += RSN_SELECTOR_LEN;
157 left -= RSN_SELECTOR_LEN;
158 } else if (left > 0) {
159 #ifdef DEBUG_PRINT
160 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
161 __func__, left);
162 #endif
163 return -3;
164 }
165
166 if (left >= 2) {
167 data->pairwise_cipher = 0;
168 count = WPA_GET_LE16(pos);
169 pos += 2;
170 left -= 2;
171 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
172 #ifdef DEBUG_PRINT
173 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
174 "count %u left %u", __func__, count, left);
175 #endif
176 return -4;
177 }
178 for (i = 0; i < count; i++) {
179 data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
180 pos += RSN_SELECTOR_LEN;
181 left -= RSN_SELECTOR_LEN;
182 }
183 } else if (left == 1) {
184 #ifdef DEBUG_PRINT
185 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
186 __func__);
187 #endif
188 return -5;
189 }
190
191 if (left >= 2) {
192 data->key_mgmt = 0;
193 count = WPA_GET_LE16(pos);
194 pos += 2;
195 left -= 2;
196 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
197 #ifdef DEBUG_PRINT
198 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
199 "count %u left %u", __func__, count, left);
200 #endif
201 return -6;
202 }
203 for (i = 0; i < count; i++) {
204 data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
205 pos += RSN_SELECTOR_LEN;
206 left -= RSN_SELECTOR_LEN;
207 }
208 } else if (left == 1) {
209 #ifdef DEBUG_PRINT
210 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
211 __func__);
212 #endif
213 return -7;
214 }
215
216 if (left >= 2) {
217 data->capabilities = WPA_GET_LE16(pos);
218 pos += 2;
219 left -= 2;
220 }
221
222 if (left >= 2) {
223 data->num_pmkid = WPA_GET_LE16(pos);
224 pos += 2;
225 left -= 2;
226 if (left < (int) data->num_pmkid * PMKID_LEN) {
227 #ifdef DEBUG_PRINT
228 wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
229 "(num_pmkid=%lu left=%d)",
230 __func__, (unsigned long) data->num_pmkid,
231 left);
232 #endif
233 data->num_pmkid = 0;
234 return -9;
235 } else {
236 data->pmkid = pos;
237 pos += data->num_pmkid * PMKID_LEN;
238 left -= data->num_pmkid * PMKID_LEN;
239 }
240 }
241
242 if (left > 0) {
243 #ifdef DEBUG_PRINT
244 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
245 __func__, left);
246 #endif
247 }
248
249 return 0;
250 #else /* CONFIG_NO_WPA2 */
251 return -1;
252 #endif /* CONFIG_NO_WPA2 */
253 }
254
wpa_parse_wpa_ie_wpa(const u8 * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)255 int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
256 struct wpa_ie_data *data)
257 {
258 const struct wpa_ie_hdr *hdr;
259 const u8 *pos;
260 int left;
261 int i, count;
262
263 memset(data, 0, sizeof(*data));
264 data->proto = WPA_PROTO_WPA;
265 data->pairwise_cipher = WPA_CIPHER_TKIP;
266 data->group_cipher = WPA_CIPHER_TKIP;
267 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
268 data->capabilities = 0;
269 data->pmkid = NULL;
270 data->num_pmkid = 0;
271 data->mgmt_group_cipher = 0;
272
273 if (wpa_ie_len == 0) {
274 /* No WPA IE - fail silently */
275 return -1;
276 }
277
278 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
279 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
280 __func__, (unsigned long) wpa_ie_len);
281 return -1;
282 }
283
284 hdr = (const struct wpa_ie_hdr *) wpa_ie;
285
286 if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
287 hdr->len != wpa_ie_len - 2 ||
288 RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
289 WPA_GET_LE16(hdr->version) != WPA_VERSION) {
290 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
291 __func__);
292 return -2;
293 }
294
295 pos = (const u8 *) (hdr + 1);
296 left = wpa_ie_len - sizeof(*hdr);
297
298 if (left >= WPA_SELECTOR_LEN) {
299 data->group_cipher = wpa_selector_to_bitfield(pos);
300 pos += WPA_SELECTOR_LEN;
301 left -= WPA_SELECTOR_LEN;
302 } else if (left > 0) {
303 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
304 __func__, left);
305 return -3;
306 }
307
308 if (left >= 2) {
309 data->pairwise_cipher = 0;
310 count = WPA_GET_LE16(pos);
311 pos += 2;
312 left -= 2;
313 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
314 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
315 "count %u left %u", __func__, count, left);
316 return -4;
317 }
318 for (i = 0; i < count; i++) {
319 data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
320 pos += WPA_SELECTOR_LEN;
321 left -= WPA_SELECTOR_LEN;
322 }
323 } else if (left == 1) {
324 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
325 __func__);
326 return -5;
327 }
328
329 if (left >= 2) {
330 data->key_mgmt = 0;
331 count = WPA_GET_LE16(pos);
332 pos += 2;
333 left -= 2;
334 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
335 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
336 "count %u left %u", __func__, count, left);
337 return -6;
338 }
339 for (i = 0; i < count; i++) {
340 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
341 pos += WPA_SELECTOR_LEN;
342 left -= WPA_SELECTOR_LEN;
343 }
344 } else if (left == 1) {
345 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
346 __func__);
347 return -7;
348 }
349
350 if (left >= 2) {
351 data->capabilities = WPA_GET_LE16(pos);
352 pos += 2;
353 left -= 2;
354 }
355
356 if (left > 0) {
357 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
358 __func__, left);
359 }
360
361 return 0;
362 }
363
364
365 /**
366 * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
367 * @key: EAPOL-Key Key Confirmation Key (KCK)
368 * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
369 * @buf: Pointer to the beginning of the EAPOL header (version field)
370 * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
371 * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
372 * Returns: 0 on success, -1 on failure
373 *
374 * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
375 * to be cleared (all zeroes) when calling this function.
376 *
377 * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
378 * description of the Key MIC calculation. It includes packet data from the
379 * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
380 * happened during final editing of the standard and the correct behavior is
381 * defined in the last draft (IEEE 802.11i/D10).
382 */
wpa_eapol_key_mic(const u8 * key,int ver,const u8 * buf,size_t len,u8 * mic)383 int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
384 u8 *mic)
385 {
386 u8 hash[SHA1_MAC_LEN];
387
388 switch (ver) {
389 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
390 return hmac_md5(key, 16, buf, len, mic);
391 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
392 if (hmac_sha1(key, 16, buf, len, hash))
393 return -1;
394 memcpy(mic, hash, MD5_MAC_LEN);
395 break;
396 #ifdef CONFIG_IEEE80211W
397 #ifdef CONFIG_WPA3_SAE
398 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
399 #endif /* CONFIG_WPA3_SAE */
400 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
401 return omac1_aes_128(key, buf, len, mic);
402 #endif /* CONFIG_IEEE80211W */
403 default:
404 return -1;
405 }
406
407 return 0;
408 }
409
wpa_compare_rsn_ie(int ft_initial_assoc,const u8 * ie1,size_t ie1len,const u8 * ie2,size_t ie2len)410 int wpa_compare_rsn_ie(int ft_initial_assoc,
411 const u8 *ie1, size_t ie1len,
412 const u8 *ie2, size_t ie2len)
413 {
414 if (ie1 == NULL || ie2 == NULL)
415 return -1;
416
417 if (ie1len == ie2len && memcmp(ie1, ie2, ie1len) == 0)
418 return 0; /* identical IEs */
419
420 #ifdef CONFIG_IEEE80211R
421 if (ft_initial_assoc) {
422 struct wpa_ie_data ie1d, ie2d;
423 /*
424 * The PMKID-List in RSN IE is different between Beacon/Probe
425 * Response/(Re)Association Request frames and EAPOL-Key
426 * messages in FT initial mobility domain association. Allow
427 * for this, but verify that other parts of the RSN IEs are
428 * identical.
429 */
430 if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
431 wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
432 return -1;
433 if (ie1d.proto == ie2d.proto &&
434 ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
435 ie1d.group_cipher == ie2d.group_cipher &&
436 ie1d.key_mgmt == ie2d.key_mgmt &&
437 ie1d.capabilities == ie2d.capabilities &&
438 ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
439 return 0;
440 }
441 #endif /* CONFIG_IEEE80211R */
442
443 return -1;
444 }
445
446 #ifdef DEBUG_PRINT
447 /**
448 * wpa_cipher_txt - Convert cipher suite to a text string
449 * @cipher: Cipher suite (WPA_CIPHER_* enum)
450 * Returns: Pointer to a text string of the cipher suite name
451 */
wpa_cipher_txt(int cipher)452 const char * wpa_cipher_txt(int cipher)
453 {
454 switch (cipher) {
455 case WPA_CIPHER_NONE:
456 return "NONE";
457 case WPA_CIPHER_WEP40:
458 return "WEP-40";
459 case WPA_CIPHER_WEP104:
460 return "WEP-104";
461 case WPA_CIPHER_TKIP:
462 return "TKIP";
463 case WPA_CIPHER_CCMP:
464 return "CCMP";
465 case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
466 return "CCMP+TKIP";
467 default:
468 return "UNKNOWN";
469 }
470 }
471 #endif
472
473 /**
474 * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
475 * @pmk: Pairwise master key
476 * @pmk_len: Length of PMK
477 * @label: Label to use in derivation
478 * @addr1: AA or SA
479 * @addr2: SA or AA
480 * @nonce1: ANonce or SNonce
481 * @nonce2: SNonce or ANonce
482 * @ptk: Buffer for pairwise transient key
483 * @ptk_len: Length of PTK
484 * @use_sha256: Whether to use SHA256-based KDF
485 *
486 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
487 * PTK = PRF-X(PMK, "Pairwise key expansion",
488 * Min(AA, SA) || Max(AA, SA) ||
489 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
490 *
491 * STK = PRF-X(SMK, "Peer key expansion",
492 * Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
493 * Min(INonce, PNonce) || Max(INonce, PNonce))
494 */
wpa_pmk_to_ptk(const u8 * pmk,size_t pmk_len,const char * label,const u8 * addr1,const u8 * addr2,const u8 * nonce1,const u8 * nonce2,u8 * ptk,size_t ptk_len,int use_sha256)495 void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
496 const u8 *addr1, const u8 *addr2,
497 const u8 *nonce1, const u8 *nonce2,
498 u8 *ptk, size_t ptk_len, int use_sha256)
499 {
500 u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
501
502 if (memcmp(addr1, addr2, ETH_ALEN) < 0) {
503 memcpy(data, addr1, ETH_ALEN);
504 memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
505 } else {
506 memcpy(data, addr2, ETH_ALEN);
507 memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
508 }
509
510 if (memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
511 memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
512 memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
513 WPA_NONCE_LEN);
514 } else {
515 memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
516 memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
517 WPA_NONCE_LEN);
518 }
519
520 if (use_sha256) {
521 sha256_prf(pmk, pmk_len, label, data, sizeof(data),
522 ptk, ptk_len);
523 }
524 else
525 {
526 sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk, ptk_len);
527 }
528 wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR"\n",
529 MAC2STR(addr1), MAC2STR(addr2));
530
531 wpa_hexdump(MSG_MSGDUMP, "WPA: PMK", pmk, pmk_len);
532 wpa_hexdump(MSG_MSGDUMP, "WPA: PTK", ptk, ptk_len);
533 }
534
535 /**
536 * rsn_pmkid - Calculate PMK identifier
537 * @pmk: Pairwise master key
538 * @pmk_len: Length of pmk in bytes
539 * @aa: Authenticator address
540 * @spa: Supplicant address
541 * @pmkid: Buffer for PMKID
542 * @use_sha256: Whether to use SHA256-based KDF
543 *
544 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
545 * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
546 */
rsn_pmkid(const u8 * pmk,size_t pmk_len,const u8 * aa,const u8 * spa,u8 * pmkid,int use_sha256)547 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
548 u8 *pmkid, int use_sha256)
549 {
550 char title[9];
551 const u8 *addr[3];
552 const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
553 unsigned char hash[SHA256_MAC_LEN];
554
555 os_memcpy(title, "PMK Name", sizeof("PMK Name"));
556 addr[0] = (u8 *) title;
557 addr[1] = aa;
558 addr[2] = spa;
559
560 #ifdef CONFIG_IEEE80211W
561 if (use_sha256) {
562 hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
563 }
564 else
565 #endif /* CONFIG_IEEE80211W */
566 hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
567 memcpy(pmkid, hash, PMKID_LEN);
568 }
569
wpa_cipher_key_len(int cipher)570 int wpa_cipher_key_len(int cipher)
571 {
572 switch (cipher) {
573 case WPA_CIPHER_CCMP:
574 case WPA_CIPHER_GCMP:
575 return 16;
576 case WPA_CIPHER_TKIP:
577 return 32;
578 case WPA_CIPHER_WEP104:
579 return 13;
580 case WPA_CIPHER_WEP40:
581 return 5;
582 }
583
584 return 0;
585 }
586
wpa_cipher_to_alg(int cipher)587 int wpa_cipher_to_alg(int cipher)
588 {
589 switch (cipher) {
590 case WPA_CIPHER_CCMP:
591 return WIFI_WPA_ALG_CCMP;
592 case WPA_CIPHER_GCMP:
593 return WIFI_WPA_ALG_GCMP;
594 case WPA_CIPHER_TKIP:
595 return WIFI_WPA_ALG_TKIP;
596 case WPA_CIPHER_WEP104:
597 case WPA_CIPHER_WEP40:
598 return WIFI_WPA_ALG_WEP;
599 }
600 return WIFI_WPA_ALG_NONE;
601 }
602
wpa_cipher_to_suite(int proto,int cipher)603 u32 wpa_cipher_to_suite(int proto, int cipher)
604 {
605 if (cipher & WPA_CIPHER_CCMP)
606 return (proto == WPA_PROTO_RSN ?
607 RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
608 if (cipher & WPA_CIPHER_GCMP)
609 return RSN_CIPHER_SUITE_GCMP;
610 if (cipher & WPA_CIPHER_TKIP)
611 return (proto == WPA_PROTO_RSN ?
612 RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
613 if (cipher & WPA_CIPHER_WEP104)
614 return (proto == WPA_PROTO_RSN ?
615 RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
616 if (cipher & WPA_CIPHER_WEP40)
617 return (proto == WPA_PROTO_RSN ?
618 RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
619 if (cipher & WPA_CIPHER_NONE)
620 return (proto == WPA_PROTO_RSN ?
621 RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
622 return 0;
623 }
624
rsn_cipher_put_suites(u8 * pos,int ciphers)625 int rsn_cipher_put_suites(u8 *pos, int ciphers)
626 {
627 int num_suites = 0;
628
629 if (ciphers & WPA_CIPHER_CCMP) {
630 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
631 pos += RSN_SELECTOR_LEN;
632 num_suites++;
633 }
634 if (ciphers & WPA_CIPHER_GCMP) {
635 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
636 pos += RSN_SELECTOR_LEN;
637 num_suites++;
638 }
639 if (ciphers & WPA_CIPHER_TKIP) {
640 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
641 pos += RSN_SELECTOR_LEN;
642 num_suites++;
643 }
644 if (ciphers & WPA_CIPHER_NONE) {
645 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
646 pos += RSN_SELECTOR_LEN;
647 num_suites++;
648 }
649
650 return num_suites;
651 }
652
wpa_cipher_put_suites(u8 * pos,int ciphers)653 int wpa_cipher_put_suites(u8 *pos, int ciphers)
654 {
655 int num_suites = 0;
656
657 if (ciphers & WPA_CIPHER_CCMP) {
658 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
659 pos += WPA_SELECTOR_LEN;
660 num_suites++;
661 }
662 if (ciphers & WPA_CIPHER_TKIP) {
663 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
664 pos += WPA_SELECTOR_LEN;
665 num_suites++;
666 }
667 if (ciphers & WPA_CIPHER_NONE) {
668 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
669 pos += WPA_SELECTOR_LEN;
670 num_suites++;
671 }
672
673 return num_suites;
674 }
675
676 #endif // ESP_SUPPLICANT
677