2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010, 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, int ver, const u8 *data, size_t len)
38 struct ieee802_1x_hdr *hdr;
39 struct wpa_eapol_key *key;
45 os_memcpy(buf, data, len);
46 hdr = (struct ieee802_1x_hdr *) buf;
47 key = (struct wpa_eapol_key *) (hdr + 1);
49 os_memcpy(rx_mic, key->key_mic, 16);
50 os_memset(key->key_mic, 0, 16);
52 if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
53 os_memcmp(rx_mic, key->key_mic, 16) == 0)
62 static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
63 const u8 *src, const u8 *data, size_t len)
65 struct wlantest_bss *bss;
66 struct wlantest_sta *sta;
67 const struct ieee802_1x_hdr *eapol;
68 const struct wpa_eapol_key *hdr;
70 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
71 MAC2STR(src), MAC2STR(dst));
72 bss = bss_get(wt, src);
75 sta = sta_get(bss, dst);
79 eapol = (const struct ieee802_1x_hdr *) data;
80 hdr = (const struct wpa_eapol_key *) (eapol + 1);
81 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
82 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
83 " used zero nonce", MAC2STR(src));
85 if (!is_zero(hdr->key_rsc, 8)) {
86 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
87 " used non-zero Key RSC", MAC2STR(src));
89 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
93 static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
94 struct wlantest_sta *sta, u16 ver,
95 const u8 *data, size_t len,
96 struct wlantest_pmk *pmk)
99 size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48;
100 wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
101 "Pairwise key expansion",
102 bss->bssid, sta->addr, sta->anonce, sta->snonce,
103 (u8 *) &ptk, ptk_len,
104 wpa_key_mgmt_sha256(sta->key_mgmt));
105 if (check_mic(ptk.kck, ver, data, len) < 0)
108 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
109 MAC2STR(sta->addr), MAC2STR(bss->bssid));
110 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
113 * Rekeying - use new PTK for EAPOL-Key frames, but continue
114 * using the old PTK for frame decryption.
116 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
117 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
118 wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16);
119 wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16);
120 wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16);
122 wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2,
127 add_note(wt, MSG_DEBUG, "Derived new PTK");
128 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
129 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
130 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
131 wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
133 wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16);
135 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
136 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
141 static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
142 struct wlantest_sta *sta, u16 ver,
143 const u8 *data, size_t len)
145 struct wlantest_pmk *pmk;
147 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR,
149 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
150 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
151 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
155 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
156 wpa_printf(MSG_DEBUG, "Try global PMK");
157 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
160 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
164 static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
165 const u8 *src, const u8 *data, size_t len)
167 struct wlantest_bss *bss;
168 struct wlantest_sta *sta;
169 const struct ieee802_1x_hdr *eapol;
170 const struct wpa_eapol_key *hdr;
171 const u8 *key_data, *kck;
172 u16 key_info, key_data_len;
173 struct wpa_eapol_ie_parse ie;
175 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
176 MAC2STR(src), MAC2STR(dst));
177 bss = bss_get(wt, dst);
180 sta = sta_get(bss, src);
184 eapol = (const struct ieee802_1x_hdr *) data;
185 hdr = (const struct wpa_eapol_key *) (eapol + 1);
186 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
187 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
188 " used zero nonce", MAC2STR(src));
190 if (!is_zero(hdr->key_rsc, 8)) {
191 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
192 " used non-zero Key RSC", MAC2STR(src));
194 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
195 key_info = WPA_GET_BE16(hdr->key_info);
196 key_data_len = WPA_GET_BE16(hdr->key_data_length);
197 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
199 if (!sta->ptk_set && !sta->tptk_set) {
200 add_note(wt, MSG_DEBUG,
201 "No PTK known to process EAPOL-Key 2/4");
207 add_note(wt, MSG_DEBUG,
208 "Use TPTK for validation EAPOL-Key MIC");
211 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
212 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
215 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
217 key_data = (const u8 *) (hdr + 1);
219 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
220 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
225 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
226 ie.wpa_ie, ie.wpa_ie_len);
227 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
228 struct ieee802_11_elems elems;
229 add_note(wt, MSG_INFO,
230 "Mismatch in WPA IE between EAPOL-Key 2/4 "
231 "and (Re)Association Request from " MACSTR,
233 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
234 ie.wpa_ie, ie.wpa_ie_len);
235 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
238 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
240 * The sniffer may have missed (Re)Association
241 * Request, so try to survive with the information from
244 os_memset(&elems, 0, sizeof(elems));
245 elems.wpa_ie = ie.wpa_ie + 2;
246 elems.wpa_ie_len = ie.wpa_ie_len - 2;
247 wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
248 "IE in EAPOL-Key 2/4");
249 sta_update_assoc(sta, &elems);
254 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
255 ie.rsn_ie, ie.rsn_ie_len);
256 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
257 struct ieee802_11_elems elems;
258 add_note(wt, MSG_INFO,
259 "Mismatch in RSN IE between EAPOL-Key 2/4 "
260 "and (Re)Association Request from " MACSTR,
262 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
263 ie.rsn_ie, ie.rsn_ie_len);
264 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
267 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
269 * The sniffer may have missed (Re)Association
270 * Request, so try to survive with the information from
273 os_memset(&elems, 0, sizeof(elems));
274 elems.rsn_ie = ie.rsn_ie + 2;
275 elems.rsn_ie_len = ie.rsn_ie_len - 2;
276 wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
277 "IE in EAPOL-Key 2/4");
278 sta_update_assoc(sta, &elems);
284 static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
285 const struct wpa_eapol_key *hdr,
289 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
291 buf = os_malloc(keydatalen);
295 os_memcpy(ek, hdr->key_iv, 16);
296 os_memcpy(ek + 16, kek, 16);
297 os_memcpy(buf, hdr + 1, keydatalen);
298 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
299 add_note(wt, MSG_INFO, "RC4 failed");
309 static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
310 const struct wpa_eapol_key *hdr,
314 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
316 if (keydatalen % 8) {
317 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
321 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
322 buf = os_malloc(keydatalen);
325 if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
327 add_note(wt, MSG_INFO,
328 "AES unwrap failed - could not decrypt EAPOL-Key "
338 static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek, u16 ver,
339 const struct wpa_eapol_key *hdr,
343 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
344 return decrypt_eapol_key_data_rc4(wt, kek, hdr, len);
345 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
346 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
347 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
349 add_note(wt, MSG_INFO,
350 "Unsupported EAPOL-Key Key Descriptor Version %u",
357 static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
358 struct wlantest_sta *sta,
359 const u8 *buf, size_t len, const u8 *rsc)
361 struct wpa_eapol_ie_parse ie;
363 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
364 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
369 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
370 ie.wpa_ie, ie.wpa_ie_len);
374 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
375 ie.rsn_ie, ie.rsn_ie_len);
379 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
381 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
383 id = ie.gtk[0] & 0x03;
384 wpa_printf(MSG_DEBUG, "GTK KeyID=%u tx=%u",
385 id, !!(ie.gtk[0] & 0x04));
386 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
387 add_note(wt, MSG_INFO,
388 "GTK KDE: Reserved field set: "
389 "%02x %02x", ie.gtk[0], ie.gtk[1]);
391 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
393 bss->gtk_len[id] = ie.gtk_len - 2;
394 sta->gtk_len = ie.gtk_len - 2;
395 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
396 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
397 bss->rsc[id][0] = rsc[5];
398 bss->rsc[id][1] = rsc[4];
399 bss->rsc[id][2] = rsc[3];
400 bss->rsc[id][3] = rsc[2];
401 bss->rsc[id][4] = rsc[1];
402 bss->rsc[id][5] = rsc[0];
405 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
407 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
408 (unsigned) ie.gtk_len);
413 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
414 ie.igtk, ie.igtk_len);
415 if (ie.igtk_len == 24) {
417 id = WPA_GET_LE16(ie.igtk);
419 add_note(wt, MSG_INFO,
420 "Unexpected IGTK KeyID %u", id);
423 wpa_printf(MSG_DEBUG, "IGTK KeyID %u", id);
424 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
425 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
427 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
428 bss->igtk_set[id] = 1;
430 bss->ipn[id][0] = ipn[5];
431 bss->ipn[id][1] = ipn[4];
432 bss->ipn[id][2] = ipn[3];
433 bss->ipn[id][3] = ipn[2];
434 bss->ipn[id][4] = ipn[1];
435 bss->ipn[id][5] = ipn[0];
439 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
440 (unsigned) ie.igtk_len);
446 static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
447 const u8 *src, const u8 *data, size_t len)
449 struct wlantest_bss *bss;
450 struct wlantest_sta *sta;
451 const struct ieee802_1x_hdr *eapol;
452 const struct wpa_eapol_key *hdr;
453 const u8 *key_data, *kck, *kek;
456 u8 *decrypted_buf = NULL;
458 size_t decrypted_len = 0;
459 struct wpa_eapol_ie_parse ie;
461 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
462 MAC2STR(src), MAC2STR(dst));
463 bss = bss_get(wt, src);
466 sta = sta_get(bss, dst);
470 eapol = (const struct ieee802_1x_hdr *) data;
471 hdr = (const struct wpa_eapol_key *) (eapol + 1);
472 key_info = WPA_GET_BE16(hdr->key_info);
474 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
475 add_note(wt, MSG_INFO,
476 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
479 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
481 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
485 if (!sta->ptk_set && !sta->tptk_set) {
486 add_note(wt, MSG_DEBUG,
487 "No PTK known to process EAPOL-Key 3/4");
494 add_note(wt, MSG_DEBUG,
495 "Use TPTK for validation EAPOL-Key MIC");
499 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
500 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
503 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
505 key_data = (const u8 *) (hdr + 1);
506 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
507 if (sta->proto & WPA_PROTO_RSN)
508 add_note(wt, MSG_INFO,
509 "EAPOL-Key 3/4 without EncrKeyData bit");
510 decrypted = key_data;
511 decrypted_len = WPA_GET_BE16(hdr->key_data_length);
513 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
514 decrypted_buf = decrypt_eapol_key_data(wt, kek, ver, hdr,
516 if (decrypted_buf == NULL) {
517 add_note(wt, MSG_INFO,
518 "Failed to decrypt EAPOL-Key Key Data");
521 decrypted = decrypted_buf;
522 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
523 decrypted, decrypted_len);
525 if (wt->write_pcap_dumper && decrypted != key_data) {
526 /* Fill in a dummy Data frame header */
527 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
528 struct ieee80211_hdr *h;
529 struct wpa_eapol_key *k;
534 plain_len = decrypted_len;
536 while (p + 1 < decrypted + decrypted_len) {
537 if (p[0] == 0xdd && p[1] == 0x00) {
539 plain_len = p - decrypted;
545 os_memset(buf, 0, sizeof(buf));
546 h = (struct ieee80211_hdr *) buf;
547 h->frame_control = host_to_le16(0x0208);
548 os_memcpy(h->addr1, dst, ETH_ALEN);
549 os_memcpy(h->addr2, src, ETH_ALEN);
550 os_memcpy(h->addr3, src, ETH_ALEN);
551 pos = (u8 *) (h + 1);
552 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
554 os_memcpy(pos, eapol, sizeof(*eapol));
555 pos += sizeof(*eapol);
556 os_memcpy(pos, hdr, sizeof(*hdr));
557 k = (struct wpa_eapol_key *) pos;
558 WPA_PUT_BE16(k->key_info,
559 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
560 WPA_PUT_BE16(k->key_data_length, plain_len);
561 write_pcap_decrypted(wt, buf, sizeof(buf),
562 decrypted, plain_len);
565 if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
566 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
567 os_free(decrypted_buf);
572 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
573 (ie.wpa_ie == NULL && bss->wpaie[0])) {
574 add_note(wt, MSG_INFO,
575 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
576 "Beacon/Probe Response from " MACSTR,
577 MAC2STR(bss->bssid));
578 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
579 ie.wpa_ie, ie.wpa_ie_len);
580 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
583 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
587 os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
588 (ie.rsn_ie == NULL && bss->rsnie[0])) {
589 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
590 "3/4 and Beacon/Probe Response from " MACSTR,
591 MAC2STR(bss->bssid));
592 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
593 ie.rsn_ie, ie.rsn_ie_len);
594 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
597 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
600 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
601 os_free(decrypted_buf);
605 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
606 const u8 *src, const u8 *data, size_t len)
608 struct wlantest_bss *bss;
609 struct wlantest_sta *sta;
610 const struct ieee802_1x_hdr *eapol;
611 const struct wpa_eapol_key *hdr;
615 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
616 MAC2STR(src), MAC2STR(dst));
617 bss = bss_get(wt, dst);
620 sta = sta_get(bss, src);
624 eapol = (const struct ieee802_1x_hdr *) data;
625 hdr = (const struct wpa_eapol_key *) (eapol + 1);
626 if (!is_zero(hdr->key_rsc, 8)) {
627 wpa_printf(MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
628 "non-zero Key RSC", MAC2STR(src));
630 key_info = WPA_GET_BE16(hdr->key_info);
632 if (!sta->ptk_set && !sta->tptk_set) {
633 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 4/4");
639 wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
642 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
643 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
646 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
648 wpa_printf(MSG_DEBUG, "Update PTK (rekeying)");
649 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
652 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
653 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
658 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
659 const u8 *src, const u8 *data, size_t len)
661 struct wlantest_bss *bss;
662 struct wlantest_sta *sta;
663 const struct ieee802_1x_hdr *eapol;
664 const struct wpa_eapol_key *hdr;
667 size_t decrypted_len = 0;
669 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
670 MAC2STR(src), MAC2STR(dst));
671 bss = bss_get(wt, src);
674 sta = sta_get(bss, dst);
678 eapol = (const struct ieee802_1x_hdr *) data;
679 hdr = (const struct wpa_eapol_key *) (eapol + 1);
680 key_info = WPA_GET_BE16(hdr->key_info);
683 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 1/2");
688 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
690 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
693 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
695 if (sta->proto & WPA_PROTO_RSN &&
696 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
697 wpa_printf(MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
700 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
701 decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, ver, hdr,
703 if (decrypted == NULL) {
704 wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
707 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
708 decrypted, decrypted_len);
709 if (wt->write_pcap_dumper) {
710 /* Fill in a dummy Data frame header */
711 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
712 struct ieee80211_hdr *h;
713 struct wpa_eapol_key *k;
717 plain_len = decrypted_len;
719 while (pos + 1 < decrypted + decrypted_len) {
720 if (pos[0] == 0xdd && pos[1] == 0x00) {
722 plain_len = pos - decrypted;
728 os_memset(buf, 0, sizeof(buf));
729 h = (struct ieee80211_hdr *) buf;
730 h->frame_control = host_to_le16(0x0208);
731 os_memcpy(h->addr1, dst, ETH_ALEN);
732 os_memcpy(h->addr2, src, ETH_ALEN);
733 os_memcpy(h->addr3, src, ETH_ALEN);
734 pos = (u8 *) (h + 1);
735 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
737 os_memcpy(pos, eapol, sizeof(*eapol));
738 pos += sizeof(*eapol);
739 os_memcpy(pos, hdr, sizeof(*hdr));
740 k = (struct wpa_eapol_key *) pos;
741 WPA_PUT_BE16(k->key_info,
742 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
743 WPA_PUT_BE16(k->key_data_length, plain_len);
744 write_pcap_decrypted(wt, buf, sizeof(buf),
745 decrypted, plain_len);
747 if (sta->proto & WPA_PROTO_RSN)
748 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
751 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
752 if (decrypted_len == klen) {
753 const u8 *rsc = hdr->key_rsc;
755 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
756 WPA_KEY_INFO_KEY_INDEX_SHIFT;
757 wpa_printf(MSG_DEBUG, "GTK key index %d", id);
758 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
760 bss->gtk_len[id] = decrypted_len;
761 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
762 bss->rsc[id][0] = rsc[5];
763 bss->rsc[id][1] = rsc[4];
764 bss->rsc[id][2] = rsc[3];
765 bss->rsc[id][3] = rsc[2];
766 bss->rsc[id][4] = rsc[1];
767 bss->rsc[id][5] = rsc[0];
768 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
770 wpa_printf(MSG_INFO, "Unexpected WPA Key Data length "
771 "in Group Key msg 1/2 from " MACSTR,
779 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
780 const u8 *src, const u8 *data, size_t len)
782 struct wlantest_bss *bss;
783 struct wlantest_sta *sta;
784 const struct ieee802_1x_hdr *eapol;
785 const struct wpa_eapol_key *hdr;
788 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
789 MAC2STR(src), MAC2STR(dst));
790 bss = bss_get(wt, dst);
793 sta = sta_get(bss, src);
797 eapol = (const struct ieee802_1x_hdr *) data;
798 hdr = (const struct wpa_eapol_key *) (eapol + 1);
799 if (!is_zero(hdr->key_rsc, 8)) {
800 wpa_printf(MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
801 "non-zero Key RSC", MAC2STR(src));
803 key_info = WPA_GET_BE16(hdr->key_info);
806 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/2");
811 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
813 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
816 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
820 static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
821 const u8 *src, const u8 *data, size_t len,
824 const struct ieee802_1x_hdr *eapol;
825 const struct wpa_eapol_key *hdr;
827 u16 key_info, key_length, ver, key_data_length;
829 eapol = (const struct ieee802_1x_hdr *) data;
830 hdr = (const struct wpa_eapol_key *) (eapol + 1);
832 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
833 (const u8 *) hdr, len - sizeof(*eapol));
834 if (len < sizeof(*hdr)) {
835 wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
840 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
841 /* TODO: EAPOL-Key RC4 for WEP */
842 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
843 MACSTR, MAC2STR(src));
847 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
848 hdr->type != EAPOL_KEY_TYPE_WPA) {
849 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
850 "%u from " MACSTR, hdr->type, MAC2STR(src));
854 key_info = WPA_GET_BE16(hdr->key_info);
855 key_length = WPA_GET_BE16(hdr->key_length);
856 key_data_length = WPA_GET_BE16(hdr->key_data_length);
857 key_data = (const u8 *) (hdr + 1);
858 if (key_data + key_data_length > data + len) {
859 wpa_printf(MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
863 if (key_data + key_data_length < data + len) {
864 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
865 "field", key_data + key_data_length,
866 data + len - key_data - key_data_length);
870 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
871 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
873 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
874 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
875 WPA_KEY_INFO_KEY_INDEX_SHIFT,
876 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
877 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
878 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
879 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
880 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
881 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
882 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
883 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
886 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
887 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
888 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
889 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
890 "Version %u from " MACSTR, ver, MAC2STR(src));
894 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
895 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
896 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
897 hdr->key_nonce, WPA_NONCE_LEN);
898 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
900 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
901 hdr->key_rsc, WPA_KEY_RSC_LEN);
902 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
904 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
905 key_data, key_data_length);
907 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
908 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
910 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
911 "Key Info bits 0x%x from " MACSTR,
912 key_info, MAC2STR(src));
915 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
916 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
917 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
918 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
919 "Key Info bits 0x%x from " MACSTR,
920 key_info, MAC2STR(src));
923 if (key_length > 32) {
924 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
925 "from " MACSTR, key_length, MAC2STR(src));
928 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
929 !is_zero(hdr->key_iv, 16)) {
930 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
931 "(reserved with ver=%d) field from " MACSTR,
933 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
937 if (!is_zero(hdr->key_id, 8)) {
938 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
939 "(reserved) field from " MACSTR, MAC2STR(src));
940 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
944 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
945 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
946 "(last two are unused)" MACSTR, MAC2STR(src));
949 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
952 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
955 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
956 /* 4-Way Handshake */
957 switch (key_info & (WPA_KEY_INFO_SECURE |
960 WPA_KEY_INFO_INSTALL)) {
961 case WPA_KEY_INFO_ACK:
962 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
964 case WPA_KEY_INFO_MIC:
965 if (key_data_length == 0)
966 rx_data_eapol_key_4_of_4(wt, dst, src, data,
969 rx_data_eapol_key_2_of_4(wt, dst, src, data,
972 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
973 WPA_KEY_INFO_INSTALL:
974 /* WPA does not include Secure bit in 3/4 */
975 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
977 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
978 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
979 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
981 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
982 if (key_data_length == 0)
983 rx_data_eapol_key_4_of_4(wt, dst, src, data,
986 rx_data_eapol_key_2_of_4(wt, dst, src, data,
990 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
994 /* Group Key Handshake */
995 switch (key_info & (WPA_KEY_INFO_SECURE |
998 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1000 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1002 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1003 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1006 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1013 void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
1014 const u8 *data, size_t len, int prot)
1016 const struct ieee802_1x_hdr *hdr;
1020 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1021 if (len < sizeof(*hdr)) {
1022 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1027 hdr = (const struct ieee802_1x_hdr *) data;
1028 length = be_to_host16(hdr->length);
1029 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1031 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1032 hdr->version, hdr->type, length);
1033 if (hdr->version < 1 || hdr->version > 3) {
1034 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1035 MACSTR, hdr->version, MAC2STR(src));
1037 if (sizeof(*hdr) + length > len) {
1038 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1043 if (sizeof(*hdr) + length < len) {
1044 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1045 (int) (len - sizeof(*hdr) - length));
1047 p = (const u8 *) (hdr + 1);
1049 switch (hdr->type) {
1050 case IEEE802_1X_TYPE_EAP_PACKET:
1051 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1053 case IEEE802_1X_TYPE_EAPOL_START:
1054 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1056 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1057 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1059 case IEEE802_1X_TYPE_EAPOL_KEY:
1060 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
1063 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1064 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1068 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);