2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "crypto/aes_wrap.h"
13 #include "crypto/crypto.h"
14 #include "common/defs.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/ieee802_11_common.h"
17 #include "common/eapol_common.h"
18 #include "common/wpa_common.h"
19 #include "rsn_supp/wpa_ie.h"
23 static int is_zero(const u8 *buf, size_t len)
26 for (i = 0; i < len; i++) {
34 static int check_mic(const u8 *kck, size_t kck_len, int akmp, int ver,
35 const u8 *data, size_t len)
39 struct ieee802_1x_hdr *hdr;
40 struct wpa_eapol_key *key;
41 u8 rx_mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
47 os_memcpy(buf, data, len);
48 hdr = (struct ieee802_1x_hdr *) buf;
49 key = (struct wpa_eapol_key *) (hdr + 1);
51 os_memcpy(rx_mic, key->key_mic, mic_len);
52 os_memset(key->key_mic, 0, mic_len);
54 if (wpa_eapol_key_mic(kck, kck_len, akmp, ver, buf, len,
56 os_memcmp(rx_mic, key->key_mic, mic_len) == 0)
65 static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
66 const u8 *src, const u8 *data, size_t len)
68 struct wlantest_bss *bss;
69 struct wlantest_sta *sta;
70 const struct ieee802_1x_hdr *eapol;
71 const struct wpa_eapol_key *hdr;
73 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
74 MAC2STR(src), MAC2STR(dst));
75 bss = bss_get(wt, src);
78 sta = sta_get(bss, dst);
82 eapol = (const struct ieee802_1x_hdr *) data;
83 hdr = (const struct wpa_eapol_key *) (eapol + 1);
84 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
85 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
86 " used zero nonce", MAC2STR(src));
88 if (!is_zero(hdr->key_rsc, 8)) {
89 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
90 " used non-zero Key RSC", MAC2STR(src));
92 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
96 static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
97 struct wlantest_sta *sta, u16 ver,
98 const u8 *data, size_t len,
99 struct wlantest_pmk *pmk)
103 if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
104 "Pairwise key expansion",
105 bss->bssid, sta->addr, sta->anonce, sta->snonce,
106 &ptk, sta->key_mgmt, sta->pairwise_cipher) < 0 ||
107 check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data, len) < 0)
110 sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
111 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
112 MAC2STR(sta->addr), MAC2STR(bss->bssid));
113 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
116 * Rekeying - use new PTK for EAPOL-Key frames, but continue
117 * using the old PTK for frame decryption.
119 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
120 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
121 wpa_hexdump(MSG_DEBUG, "TPTK:KCK",
122 sta->tptk.kck, sta->tptk.kck_len);
123 wpa_hexdump(MSG_DEBUG, "TPTK:KEK",
124 sta->tptk.kek, sta->tptk.kek_len);
125 wpa_hexdump(MSG_DEBUG, "TPTK:TK",
126 sta->tptk.tk, sta->tptk.tk_len);
130 add_note(wt, MSG_DEBUG, "Derived new PTK");
131 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
132 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, sta->ptk.kck_len);
133 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, sta->ptk.kek_len);
134 wpa_hexdump(MSG_DEBUG, "PTK:TK", sta->ptk.tk, sta->ptk.tk_len);
136 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
137 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
142 static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
143 struct wlantest_sta *sta, u16 ver,
144 const u8 *data, size_t len)
146 struct wlantest_pmk *pmk;
148 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR " (ver %u)",
149 MAC2STR(sta->addr), ver);
150 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
151 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
152 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
156 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
157 wpa_printf(MSG_DEBUG, "Try global PMK");
158 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
163 struct wlantest_ptk *ptk;
164 int prev_level = wpa_debug_level;
166 wpa_debug_level = MSG_WARNING;
167 dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
168 if (check_mic(ptk->ptk.kck, ptk->ptk.kck_len,
169 sta->key_mgmt, ver, data, len) < 0)
171 wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
172 MACSTR " BSSID " MACSTR,
173 MAC2STR(sta->addr), MAC2STR(bss->bssid));
174 add_note(wt, MSG_DEBUG, "Using pre-set PTK");
176 wpa_cipher_key_len(sta->pairwise_cipher);
177 os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
178 wpa_hexdump(MSG_DEBUG, "PTK:KCK",
179 sta->ptk.kck, sta->ptk.kck_len);
180 wpa_hexdump(MSG_DEBUG, "PTK:KEK",
181 sta->ptk.kek, sta->ptk.kek_len);
182 wpa_hexdump(MSG_DEBUG, "PTK:TK",
183 sta->ptk.tk, sta->ptk.tk_len);
185 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
186 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
188 wpa_debug_level = prev_level;
191 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
195 static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
196 const u8 *src, const u8 *data, size_t len)
198 struct wlantest_bss *bss;
199 struct wlantest_sta *sta;
200 const struct ieee802_1x_hdr *eapol;
201 const struct wpa_eapol_key *hdr;
202 const u8 *key_data, *kck;
204 u16 key_info, key_data_len;
205 struct wpa_eapol_ie_parse ie;
207 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
208 MAC2STR(src), MAC2STR(dst));
209 bss = bss_get(wt, dst);
212 sta = sta_get(bss, src);
216 eapol = (const struct ieee802_1x_hdr *) data;
217 hdr = (const struct wpa_eapol_key *) (eapol + 1);
218 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
219 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
220 " used zero nonce", MAC2STR(src));
222 if (!is_zero(hdr->key_rsc, 8)) {
223 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
224 " used non-zero Key RSC", MAC2STR(src));
226 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
227 key_info = WPA_GET_BE16(hdr->key_info);
228 key_data_len = WPA_GET_BE16(hdr->key_data_length);
229 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
231 if (!sta->ptk_set && !sta->tptk_set) {
232 add_note(wt, MSG_DEBUG,
233 "No PTK known to process EAPOL-Key 2/4");
238 kck_len = sta->ptk.kck_len;
240 add_note(wt, MSG_DEBUG,
241 "Use TPTK for validation EAPOL-Key MIC");
243 kck_len = sta->tptk.kck_len;
245 if (check_mic(kck, kck_len, sta->key_mgmt,
246 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
247 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
250 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
252 key_data = (const u8 *) (hdr + 1);
254 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
255 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
260 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
261 ie.wpa_ie, ie.wpa_ie_len);
262 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
263 struct ieee802_11_elems elems;
264 add_note(wt, MSG_INFO,
265 "Mismatch in WPA IE between EAPOL-Key 2/4 "
266 "and (Re)Association Request from " MACSTR,
268 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
269 ie.wpa_ie, ie.wpa_ie_len);
270 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
273 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
275 * The sniffer may have missed (Re)Association
276 * Request, so try to survive with the information from
279 os_memset(&elems, 0, sizeof(elems));
280 elems.wpa_ie = ie.wpa_ie + 2;
281 elems.wpa_ie_len = ie.wpa_ie_len - 2;
282 wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
283 "IE in EAPOL-Key 2/4");
284 sta_update_assoc(sta, &elems);
289 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
290 ie.rsn_ie, ie.rsn_ie_len);
291 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
292 struct ieee802_11_elems elems;
293 add_note(wt, MSG_INFO,
294 "Mismatch in RSN IE between EAPOL-Key 2/4 "
295 "and (Re)Association Request from " MACSTR,
297 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
298 ie.rsn_ie, ie.rsn_ie_len);
299 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
302 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
304 * The sniffer may have missed (Re)Association
305 * Request, so try to survive with the information from
308 os_memset(&elems, 0, sizeof(elems));
309 elems.rsn_ie = ie.rsn_ie + 2;
310 elems.rsn_ie_len = ie.rsn_ie_len - 2;
311 wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
312 "IE in EAPOL-Key 2/4");
313 sta_update_assoc(sta, &elems);
319 static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
320 const struct wpa_eapol_key *hdr,
324 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
326 buf = os_malloc(keydatalen);
330 os_memcpy(ek, hdr->key_iv, 16);
331 os_memcpy(ek + 16, kek, 16);
332 os_memcpy(buf, hdr + 1, keydatalen);
333 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
334 add_note(wt, MSG_INFO, "RC4 failed");
344 static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
345 const struct wpa_eapol_key *hdr,
349 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
351 if (keydatalen % 8) {
352 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
356 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
357 buf = os_malloc(keydatalen);
360 if (aes_unwrap(kek, 16, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
362 add_note(wt, MSG_INFO,
363 "AES unwrap failed - could not decrypt EAPOL-Key "
373 static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek,
374 size_t kek_len, u16 ver,
375 const struct wpa_eapol_key *hdr,
381 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
382 return decrypt_eapol_key_data_rc4(wt, kek, hdr, len);
383 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
384 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
385 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
386 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
387 /* For now, assume this is OSEN */
388 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
390 add_note(wt, MSG_INFO,
391 "Unsupported EAPOL-Key Key Descriptor Version %u",
398 static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
399 struct wlantest_sta *sta,
400 const u8 *buf, size_t len, const u8 *rsc)
402 struct wpa_eapol_ie_parse ie;
404 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
405 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
410 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
411 ie.wpa_ie, ie.wpa_ie_len);
415 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
416 ie.rsn_ie, ie.rsn_ie_len);
420 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
422 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
424 id = ie.gtk[0] & 0x03;
425 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
426 id, !!(ie.gtk[0] & 0x04));
427 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
428 add_note(wt, MSG_INFO,
429 "GTK KDE: Reserved field set: "
430 "%02x %02x", ie.gtk[0], ie.gtk[1]);
432 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
434 bss->gtk_len[id] = ie.gtk_len - 2;
435 sta->gtk_len = ie.gtk_len - 2;
436 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
437 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
438 bss->rsc[id][0] = rsc[5];
439 bss->rsc[id][1] = rsc[4];
440 bss->rsc[id][2] = rsc[3];
441 bss->rsc[id][3] = rsc[2];
442 bss->rsc[id][4] = rsc[1];
443 bss->rsc[id][5] = rsc[0];
446 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
448 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
449 (unsigned) ie.gtk_len);
454 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
455 ie.igtk, ie.igtk_len);
456 if (ie.igtk_len == 24) {
458 id = WPA_GET_LE16(ie.igtk);
460 add_note(wt, MSG_INFO,
461 "Unexpected IGTK KeyID %u", id);
464 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
465 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
466 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
468 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
469 bss->igtk_len[id] = 16;
471 bss->ipn[id][0] = ipn[5];
472 bss->ipn[id][1] = ipn[4];
473 bss->ipn[id][2] = ipn[3];
474 bss->ipn[id][3] = ipn[2];
475 bss->ipn[id][4] = ipn[1];
476 bss->ipn[id][5] = ipn[0];
479 } else if (ie.igtk_len == 40) {
481 id = WPA_GET_LE16(ie.igtk);
483 add_note(wt, MSG_INFO,
484 "Unexpected IGTK KeyID %u", id);
487 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
488 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
489 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
491 os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
492 bss->igtk_len[id] = 32;
494 bss->ipn[id][0] = ipn[5];
495 bss->ipn[id][1] = ipn[4];
496 bss->ipn[id][2] = ipn[3];
497 bss->ipn[id][3] = ipn[2];
498 bss->ipn[id][4] = ipn[1];
499 bss->ipn[id][5] = ipn[0];
503 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
504 (unsigned) ie.igtk_len);
510 static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
511 const u8 *src, const u8 *data, size_t len)
513 struct wlantest_bss *bss;
514 struct wlantest_sta *sta;
515 const struct ieee802_1x_hdr *eapol;
516 const struct wpa_eapol_key *hdr;
517 const u8 *key_data, *kck, *kek;
518 size_t kck_len, kek_len;
521 u8 *decrypted_buf = NULL;
523 size_t decrypted_len = 0;
524 struct wpa_eapol_ie_parse ie;
526 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
527 MAC2STR(src), MAC2STR(dst));
528 bss = bss_get(wt, src);
531 sta = sta_get(bss, dst);
535 eapol = (const struct ieee802_1x_hdr *) data;
536 hdr = (const struct wpa_eapol_key *) (eapol + 1);
537 key_info = WPA_GET_BE16(hdr->key_info);
539 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
540 add_note(wt, MSG_INFO,
541 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
544 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
546 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
550 if (!sta->ptk_set && !sta->tptk_set) {
551 add_note(wt, MSG_DEBUG,
552 "No PTK known to process EAPOL-Key 3/4");
557 kek_len = sta->ptk.kek_len;
559 kck_len = sta->ptk.kck_len;
561 add_note(wt, MSG_DEBUG,
562 "Use TPTK for validation EAPOL-Key MIC");
564 kck_len = sta->tptk.kck_len;
566 kek_len = sta->tptk.kek_len;
568 if (check_mic(kck, kck_len, sta->key_mgmt,
569 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
570 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
573 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
575 key_data = (const u8 *) (hdr + 1);
576 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
577 if (sta->proto & WPA_PROTO_RSN)
578 add_note(wt, MSG_INFO,
579 "EAPOL-Key 3/4 without EncrKeyData bit");
580 decrypted = key_data;
581 decrypted_len = WPA_GET_BE16(hdr->key_data_length);
583 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
584 decrypted_buf = decrypt_eapol_key_data(wt, kek, kek_len, ver,
585 hdr, &decrypted_len);
586 if (decrypted_buf == NULL) {
587 add_note(wt, MSG_INFO,
588 "Failed to decrypt EAPOL-Key Key Data");
591 decrypted = decrypted_buf;
592 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
593 decrypted, decrypted_len);
595 if (wt->write_pcap_dumper && decrypted != key_data) {
596 /* Fill in a dummy Data frame header */
597 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
598 struct ieee80211_hdr *h;
599 struct wpa_eapol_key *k;
604 plain_len = decrypted_len;
606 while (p + 1 < decrypted + decrypted_len) {
607 if (p[0] == 0xdd && p[1] == 0x00) {
609 plain_len = p - decrypted;
615 os_memset(buf, 0, sizeof(buf));
616 h = (struct ieee80211_hdr *) buf;
617 h->frame_control = host_to_le16(0x0208);
618 os_memcpy(h->addr1, dst, ETH_ALEN);
619 os_memcpy(h->addr2, src, ETH_ALEN);
620 os_memcpy(h->addr3, src, ETH_ALEN);
621 pos = (u8 *) (h + 1);
622 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
624 os_memcpy(pos, eapol, sizeof(*eapol));
625 pos += sizeof(*eapol);
626 os_memcpy(pos, hdr, sizeof(*hdr));
627 k = (struct wpa_eapol_key *) pos;
628 WPA_PUT_BE16(k->key_info,
629 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
630 WPA_PUT_BE16(k->key_data_length, plain_len);
631 write_pcap_decrypted(wt, buf, sizeof(buf),
632 decrypted, plain_len);
635 if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
636 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
637 os_free(decrypted_buf);
642 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
643 (ie.wpa_ie == NULL && bss->wpaie[0])) {
644 add_note(wt, MSG_INFO,
645 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
646 "Beacon/Probe Response from " MACSTR,
647 MAC2STR(bss->bssid));
648 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
649 ie.wpa_ie, ie.wpa_ie_len);
650 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
653 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
657 os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
658 (ie.rsn_ie == NULL && bss->rsnie[0])) {
659 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
660 "3/4 and Beacon/Probe Response from " MACSTR,
661 MAC2STR(bss->bssid));
662 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
663 ie.rsn_ie, ie.rsn_ie_len);
664 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
667 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
670 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
671 os_free(decrypted_buf);
675 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
676 const u8 *src, const u8 *data, size_t len)
678 struct wlantest_bss *bss;
679 struct wlantest_sta *sta;
680 const struct ieee802_1x_hdr *eapol;
681 const struct wpa_eapol_key *hdr;
686 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
687 MAC2STR(src), MAC2STR(dst));
688 bss = bss_get(wt, dst);
691 sta = sta_get(bss, src);
695 eapol = (const struct ieee802_1x_hdr *) data;
696 hdr = (const struct wpa_eapol_key *) (eapol + 1);
697 if (!is_zero(hdr->key_rsc, 8)) {
698 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
699 "non-zero Key RSC", MAC2STR(src));
701 key_info = WPA_GET_BE16(hdr->key_info);
703 if (!sta->ptk_set && !sta->tptk_set) {
704 add_note(wt, MSG_DEBUG,
705 "No PTK known to process EAPOL-Key 4/4");
710 kck_len = sta->ptk.kck_len;
712 add_note(wt, MSG_DEBUG,
713 "Use TPTK for validation EAPOL-Key MIC");
715 kck_len = sta->tptk.kck_len;
717 if (check_mic(kck, kck_len, sta->key_mgmt,
718 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
719 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
722 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
724 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
725 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
728 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
729 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
734 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
735 const u8 *src, const u8 *data, size_t len)
737 struct wlantest_bss *bss;
738 struct wlantest_sta *sta;
739 const struct ieee802_1x_hdr *eapol;
740 const struct wpa_eapol_key *hdr;
743 size_t decrypted_len = 0;
745 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
746 MAC2STR(src), MAC2STR(dst));
747 bss = bss_get(wt, src);
750 sta = sta_get(bss, dst);
754 eapol = (const struct ieee802_1x_hdr *) data;
755 hdr = (const struct wpa_eapol_key *) (eapol + 1);
756 key_info = WPA_GET_BE16(hdr->key_info);
759 add_note(wt, MSG_DEBUG,
760 "No PTK known to process EAPOL-Key 1/2");
765 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
766 key_info & WPA_KEY_INFO_TYPE_MASK,
768 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
771 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
773 if (sta->proto & WPA_PROTO_RSN &&
774 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
775 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
778 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
779 decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, sta->ptk.kek_len,
780 ver, hdr, &decrypted_len);
781 if (decrypted == NULL) {
782 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
785 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
786 decrypted, decrypted_len);
787 if (wt->write_pcap_dumper) {
788 /* Fill in a dummy Data frame header */
789 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
790 struct ieee80211_hdr *h;
791 struct wpa_eapol_key *k;
795 plain_len = decrypted_len;
797 while (pos + 1 < decrypted + decrypted_len) {
798 if (pos[0] == 0xdd && pos[1] == 0x00) {
800 plain_len = pos - decrypted;
806 os_memset(buf, 0, sizeof(buf));
807 h = (struct ieee80211_hdr *) buf;
808 h->frame_control = host_to_le16(0x0208);
809 os_memcpy(h->addr1, dst, ETH_ALEN);
810 os_memcpy(h->addr2, src, ETH_ALEN);
811 os_memcpy(h->addr3, src, ETH_ALEN);
812 pos = (u8 *) (h + 1);
813 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
815 os_memcpy(pos, eapol, sizeof(*eapol));
816 pos += sizeof(*eapol);
817 os_memcpy(pos, hdr, sizeof(*hdr));
818 k = (struct wpa_eapol_key *) pos;
819 WPA_PUT_BE16(k->key_info,
820 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
821 WPA_PUT_BE16(k->key_data_length, plain_len);
822 write_pcap_decrypted(wt, buf, sizeof(buf),
823 decrypted, plain_len);
825 if (sta->proto & WPA_PROTO_RSN)
826 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
829 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
830 if (decrypted_len == klen) {
831 const u8 *rsc = hdr->key_rsc;
833 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
834 WPA_KEY_INFO_KEY_INDEX_SHIFT;
835 add_note(wt, MSG_DEBUG, "GTK key index %d", id);
836 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
838 bss->gtk_len[id] = decrypted_len;
839 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
840 bss->rsc[id][0] = rsc[5];
841 bss->rsc[id][1] = rsc[4];
842 bss->rsc[id][2] = rsc[3];
843 bss->rsc[id][3] = rsc[2];
844 bss->rsc[id][4] = rsc[1];
845 bss->rsc[id][5] = rsc[0];
846 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
848 add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
849 "in Group Key msg 1/2 from " MACSTR,
857 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
858 const u8 *src, const u8 *data, size_t len)
860 struct wlantest_bss *bss;
861 struct wlantest_sta *sta;
862 const struct ieee802_1x_hdr *eapol;
863 const struct wpa_eapol_key *hdr;
866 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
867 MAC2STR(src), MAC2STR(dst));
868 bss = bss_get(wt, dst);
871 sta = sta_get(bss, src);
875 eapol = (const struct ieee802_1x_hdr *) data;
876 hdr = (const struct wpa_eapol_key *) (eapol + 1);
877 if (!is_zero(hdr->key_rsc, 8)) {
878 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
879 "non-zero Key RSC", MAC2STR(src));
881 key_info = WPA_GET_BE16(hdr->key_info);
884 add_note(wt, MSG_DEBUG,
885 "No PTK known to process EAPOL-Key 2/2");
890 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
891 key_info & WPA_KEY_INFO_TYPE_MASK,
893 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
896 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
900 static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
901 const u8 *src, const u8 *data, size_t len,
904 const struct ieee802_1x_hdr *eapol;
905 const struct wpa_eapol_key *hdr;
907 u16 key_info, key_length, ver, key_data_length;
909 eapol = (const struct ieee802_1x_hdr *) data;
910 hdr = (const struct wpa_eapol_key *) (eapol + 1);
912 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
913 (const u8 *) hdr, len - sizeof(*eapol));
914 if (len < sizeof(*hdr)) {
915 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
920 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
921 /* TODO: EAPOL-Key RC4 for WEP */
922 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
923 MACSTR, MAC2STR(src));
927 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
928 hdr->type != EAPOL_KEY_TYPE_WPA) {
929 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
930 "%u from " MACSTR, hdr->type, MAC2STR(src));
934 key_info = WPA_GET_BE16(hdr->key_info);
935 key_length = WPA_GET_BE16(hdr->key_length);
936 key_data_length = WPA_GET_BE16(hdr->key_data_length);
937 key_data = (const u8 *) (hdr + 1);
938 if (key_data + key_data_length > data + len) {
939 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
943 if (key_data + key_data_length < data + len) {
944 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
945 "field", key_data + key_data_length,
946 data + len - key_data - key_data_length);
950 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
951 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
953 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
954 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
955 WPA_KEY_INFO_KEY_INDEX_SHIFT,
956 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
957 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
958 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
959 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
960 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
961 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
962 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
963 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
966 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
967 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
968 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
969 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
970 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
971 "Version %u from " MACSTR, ver, MAC2STR(src));
975 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
976 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
977 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
978 hdr->key_nonce, WPA_NONCE_LEN);
979 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
981 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
982 hdr->key_rsc, WPA_KEY_RSC_LEN);
983 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
985 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
986 key_data, key_data_length);
988 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
989 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
991 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
992 "Key Info bits 0x%x from " MACSTR,
993 key_info, MAC2STR(src));
996 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
997 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
998 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
999 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
1000 "Key Info bits 0x%x from " MACSTR,
1001 key_info, MAC2STR(src));
1004 if (key_length > 32) {
1005 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
1006 "from " MACSTR, key_length, MAC2STR(src));
1009 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1010 !is_zero(hdr->key_iv, 16)) {
1011 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
1012 "(reserved with ver=%d) field from " MACSTR,
1014 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
1018 if (!is_zero(hdr->key_id, 8)) {
1019 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
1020 "(reserved) field from " MACSTR, MAC2STR(src));
1021 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
1025 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
1026 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
1027 "(last two are unused)" MACSTR, MAC2STR(src));
1030 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
1033 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
1036 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1037 /* 4-Way Handshake */
1038 switch (key_info & (WPA_KEY_INFO_SECURE |
1041 WPA_KEY_INFO_INSTALL)) {
1042 case WPA_KEY_INFO_ACK:
1043 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
1045 case WPA_KEY_INFO_MIC:
1046 if (key_data_length == 0)
1047 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1050 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1053 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1054 WPA_KEY_INFO_INSTALL:
1055 /* WPA does not include Secure bit in 3/4 */
1056 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1058 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1059 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1060 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1062 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1063 if (key_data_length == 0)
1064 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1067 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1071 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1075 /* Group Key Handshake */
1076 switch (key_info & (WPA_KEY_INFO_SECURE |
1078 WPA_KEY_INFO_ACK)) {
1079 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1081 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1083 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1084 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1087 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1094 void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
1095 const u8 *data, size_t len, int prot)
1097 const struct ieee802_1x_hdr *hdr;
1101 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1102 if (len < sizeof(*hdr)) {
1103 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1108 hdr = (const struct ieee802_1x_hdr *) data;
1109 length = be_to_host16(hdr->length);
1110 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1112 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1113 hdr->version, hdr->type, length);
1114 if (hdr->version < 1 || hdr->version > 3) {
1115 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1116 MACSTR, hdr->version, MAC2STR(src));
1118 if (sizeof(*hdr) + length > len) {
1119 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1124 if (sizeof(*hdr) + length < len) {
1125 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1126 (int) (len - sizeof(*hdr) - length));
1128 p = (const u8 *) (hdr + 1);
1130 switch (hdr->type) {
1131 case IEEE802_1X_TYPE_EAP_PACKET:
1132 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1134 case IEEE802_1X_TYPE_EAPOL_START:
1135 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1137 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1138 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1140 case IEEE802_1X_TYPE_EAPOL_KEY:
1141 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
1144 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1145 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1149 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);