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_key_mgmt_ft(sta->key_mgmt)) {
105 u8 pmk_r0_name[WPA_PMK_NAME_LEN];
107 u8 pmk_r1_name[WPA_PMK_NAME_LEN];
108 u8 ptk_name[WPA_PMK_NAME_LEN];
110 wpa_derive_pmk_r0(pmk->pmk, sizeof(pmk->pmk),
111 bss->ssid, bss->ssid_len, bss->mdid,
112 bss->r0kh_id, bss->r0kh_id_len,
113 sta->addr, pmk_r0, pmk_r0_name);
114 wpa_hexdump(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
115 wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name,
117 wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, bss->r1kh_id,
118 sta->addr, pmk_r1, pmk_r1_name);
119 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
120 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name,
122 if (wpa_pmk_r1_to_ptk(pmk_r1, sta->snonce, sta->anonce,
124 bss->bssid, pmk_r1_name, &ptk, ptk_name,
126 sta->pairwise_cipher) < 0 ||
127 check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
130 } else if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
131 "Pairwise key expansion",
132 bss->bssid, sta->addr, sta->anonce,
133 sta->snonce, &ptk, sta->key_mgmt,
134 sta->pairwise_cipher) < 0 ||
135 check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
140 sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
141 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
142 MAC2STR(sta->addr), MAC2STR(bss->bssid));
143 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
146 * Rekeying - use new PTK for EAPOL-Key frames, but continue
147 * using the old PTK for frame decryption.
149 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
150 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
151 wpa_hexdump(MSG_DEBUG, "TPTK:KCK",
152 sta->tptk.kck, sta->tptk.kck_len);
153 wpa_hexdump(MSG_DEBUG, "TPTK:KEK",
154 sta->tptk.kek, sta->tptk.kek_len);
155 wpa_hexdump(MSG_DEBUG, "TPTK:TK",
156 sta->tptk.tk, sta->tptk.tk_len);
160 add_note(wt, MSG_DEBUG, "Derived new PTK");
161 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
162 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, sta->ptk.kck_len);
163 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, sta->ptk.kek_len);
164 wpa_hexdump(MSG_DEBUG, "PTK:TK", sta->ptk.tk, sta->ptk.tk_len);
166 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
167 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
172 static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
173 struct wlantest_sta *sta, u16 ver,
174 const u8 *data, size_t len)
176 struct wlantest_pmk *pmk;
178 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR " (ver %u)",
179 MAC2STR(sta->addr), ver);
180 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
181 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
182 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
186 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
187 wpa_printf(MSG_DEBUG, "Try global PMK");
188 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
193 struct wlantest_ptk *ptk;
194 int prev_level = wpa_debug_level;
196 wpa_debug_level = MSG_WARNING;
197 dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
198 if (check_mic(ptk->ptk.kck, ptk->ptk.kck_len,
199 sta->key_mgmt, ver, data, len) < 0)
201 wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
202 MACSTR " BSSID " MACSTR,
203 MAC2STR(sta->addr), MAC2STR(bss->bssid));
204 add_note(wt, MSG_DEBUG, "Using pre-set PTK");
206 wpa_cipher_key_len(sta->pairwise_cipher);
207 os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
208 wpa_hexdump(MSG_DEBUG, "PTK:KCK",
209 sta->ptk.kck, sta->ptk.kck_len);
210 wpa_hexdump(MSG_DEBUG, "PTK:KEK",
211 sta->ptk.kek, sta->ptk.kek_len);
212 wpa_hexdump(MSG_DEBUG, "PTK:TK",
213 sta->ptk.tk, sta->ptk.tk_len);
215 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
216 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
218 wpa_debug_level = prev_level;
221 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
225 static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
226 const u8 *src, const u8 *data, size_t len)
228 struct wlantest_bss *bss;
229 struct wlantest_sta *sta;
230 const struct ieee802_1x_hdr *eapol;
231 const struct wpa_eapol_key *hdr;
232 const u8 *key_data, *kck;
234 u16 key_info, key_data_len;
235 struct wpa_eapol_ie_parse ie;
237 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
238 MAC2STR(src), MAC2STR(dst));
239 bss = bss_get(wt, dst);
242 sta = sta_get(bss, src);
246 eapol = (const struct ieee802_1x_hdr *) data;
247 hdr = (const struct wpa_eapol_key *) (eapol + 1);
248 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
249 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
250 " used zero nonce", MAC2STR(src));
252 if (!is_zero(hdr->key_rsc, 8)) {
253 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
254 " used non-zero Key RSC", MAC2STR(src));
256 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
257 key_info = WPA_GET_BE16(hdr->key_info);
258 key_data_len = WPA_GET_BE16(hdr->key_data_length);
259 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
261 if (!sta->ptk_set && !sta->tptk_set) {
262 add_note(wt, MSG_DEBUG,
263 "No PTK known to process EAPOL-Key 2/4");
268 kck_len = sta->ptk.kck_len;
270 add_note(wt, MSG_DEBUG,
271 "Use TPTK for validation EAPOL-Key MIC");
273 kck_len = sta->tptk.kck_len;
275 if (check_mic(kck, kck_len, sta->key_mgmt,
276 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
277 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
280 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
282 key_data = (const u8 *) (hdr + 1);
284 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
285 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
290 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
291 ie.wpa_ie, ie.wpa_ie_len);
292 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
293 struct ieee802_11_elems elems;
294 add_note(wt, MSG_INFO,
295 "Mismatch in WPA IE between EAPOL-Key 2/4 "
296 "and (Re)Association Request from " MACSTR,
298 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
299 ie.wpa_ie, ie.wpa_ie_len);
300 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
303 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
305 * The sniffer may have missed (Re)Association
306 * Request, so try to survive with the information from
309 os_memset(&elems, 0, sizeof(elems));
310 elems.wpa_ie = ie.wpa_ie + 2;
311 elems.wpa_ie_len = ie.wpa_ie_len - 2;
312 wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
313 "IE in EAPOL-Key 2/4");
314 sta_update_assoc(sta, &elems);
319 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
320 ie.rsn_ie, ie.rsn_ie_len);
321 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
322 struct ieee802_11_elems elems;
323 add_note(wt, MSG_INFO,
324 "Mismatch in RSN IE between EAPOL-Key 2/4 "
325 "and (Re)Association Request from " MACSTR,
327 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
328 ie.rsn_ie, ie.rsn_ie_len);
329 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
332 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
334 * The sniffer may have missed (Re)Association
335 * Request, so try to survive with the information from
338 os_memset(&elems, 0, sizeof(elems));
339 elems.rsn_ie = ie.rsn_ie + 2;
340 elems.rsn_ie_len = ie.rsn_ie_len - 2;
341 wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
342 "IE in EAPOL-Key 2/4");
343 sta_update_assoc(sta, &elems);
349 static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
350 const struct wpa_eapol_key *hdr,
354 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
356 buf = os_malloc(keydatalen);
360 os_memcpy(ek, hdr->key_iv, 16);
361 os_memcpy(ek + 16, kek, 16);
362 os_memcpy(buf, hdr + 1, keydatalen);
363 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
364 add_note(wt, MSG_INFO, "RC4 failed");
374 static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
375 const struct wpa_eapol_key *hdr,
379 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
381 if (keydatalen % 8) {
382 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
386 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
387 buf = os_malloc(keydatalen);
390 if (aes_unwrap(kek, 16, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
392 add_note(wt, MSG_INFO,
393 "AES unwrap failed - could not decrypt EAPOL-Key "
403 static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek,
404 size_t kek_len, u16 ver,
405 const struct wpa_eapol_key *hdr,
411 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
412 return decrypt_eapol_key_data_rc4(wt, kek, hdr, len);
413 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
414 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
415 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
416 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
417 /* For now, assume this is OSEN */
418 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
420 add_note(wt, MSG_INFO,
421 "Unsupported EAPOL-Key Key Descriptor Version %u",
428 static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
429 struct wlantest_sta *sta,
430 const u8 *buf, size_t len, const u8 *rsc)
432 struct wpa_eapol_ie_parse ie;
434 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
435 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
440 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
441 ie.wpa_ie, ie.wpa_ie_len);
445 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
446 ie.rsn_ie, ie.rsn_ie_len);
450 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
452 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
454 id = ie.gtk[0] & 0x03;
455 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
456 id, !!(ie.gtk[0] & 0x04));
457 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
458 add_note(wt, MSG_INFO,
459 "GTK KDE: Reserved field set: "
460 "%02x %02x", ie.gtk[0], ie.gtk[1]);
462 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
464 bss->gtk_len[id] = ie.gtk_len - 2;
465 sta->gtk_len = ie.gtk_len - 2;
466 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
467 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
468 bss->rsc[id][0] = rsc[5];
469 bss->rsc[id][1] = rsc[4];
470 bss->rsc[id][2] = rsc[3];
471 bss->rsc[id][3] = rsc[2];
472 bss->rsc[id][4] = rsc[1];
473 bss->rsc[id][5] = rsc[0];
476 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
478 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
479 (unsigned) ie.gtk_len);
484 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
485 ie.igtk, ie.igtk_len);
486 if (ie.igtk_len == 24) {
488 id = WPA_GET_LE16(ie.igtk);
490 add_note(wt, MSG_INFO,
491 "Unexpected IGTK KeyID %u", id);
494 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
495 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
496 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
498 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
499 bss->igtk_len[id] = 16;
501 bss->ipn[id][0] = ipn[5];
502 bss->ipn[id][1] = ipn[4];
503 bss->ipn[id][2] = ipn[3];
504 bss->ipn[id][3] = ipn[2];
505 bss->ipn[id][4] = ipn[1];
506 bss->ipn[id][5] = ipn[0];
509 } else if (ie.igtk_len == 40) {
511 id = WPA_GET_LE16(ie.igtk);
513 add_note(wt, MSG_INFO,
514 "Unexpected IGTK KeyID %u", id);
517 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
518 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
519 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
521 os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
522 bss->igtk_len[id] = 32;
524 bss->ipn[id][0] = ipn[5];
525 bss->ipn[id][1] = ipn[4];
526 bss->ipn[id][2] = ipn[3];
527 bss->ipn[id][3] = ipn[2];
528 bss->ipn[id][4] = ipn[1];
529 bss->ipn[id][5] = ipn[0];
533 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
534 (unsigned) ie.igtk_len);
540 static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
541 const u8 *src, const u8 *data, size_t len)
543 struct wlantest_bss *bss;
544 struct wlantest_sta *sta;
545 const struct ieee802_1x_hdr *eapol;
546 const struct wpa_eapol_key *hdr;
547 const u8 *key_data, *kck, *kek;
548 size_t kck_len, kek_len;
551 u8 *decrypted_buf = NULL;
553 size_t decrypted_len = 0;
554 struct wpa_eapol_ie_parse ie;
556 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
557 MAC2STR(src), MAC2STR(dst));
558 bss = bss_get(wt, src);
561 sta = sta_get(bss, dst);
565 eapol = (const struct ieee802_1x_hdr *) data;
566 hdr = (const struct wpa_eapol_key *) (eapol + 1);
567 key_info = WPA_GET_BE16(hdr->key_info);
569 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
570 add_note(wt, MSG_INFO,
571 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
574 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
576 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
580 if (!sta->ptk_set && !sta->tptk_set) {
581 add_note(wt, MSG_DEBUG,
582 "No PTK known to process EAPOL-Key 3/4");
587 kek_len = sta->ptk.kek_len;
589 kck_len = sta->ptk.kck_len;
591 add_note(wt, MSG_DEBUG,
592 "Use TPTK for validation EAPOL-Key MIC");
594 kck_len = sta->tptk.kck_len;
596 kek_len = sta->tptk.kek_len;
598 if (check_mic(kck, kck_len, sta->key_mgmt,
599 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
600 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
603 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
605 key_data = (const u8 *) (hdr + 1);
606 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
607 if (sta->proto & WPA_PROTO_RSN)
608 add_note(wt, MSG_INFO,
609 "EAPOL-Key 3/4 without EncrKeyData bit");
610 decrypted = key_data;
611 decrypted_len = WPA_GET_BE16(hdr->key_data_length);
613 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
614 decrypted_buf = decrypt_eapol_key_data(wt, kek, kek_len, ver,
615 hdr, &decrypted_len);
616 if (decrypted_buf == NULL) {
617 add_note(wt, MSG_INFO,
618 "Failed to decrypt EAPOL-Key Key Data");
621 decrypted = decrypted_buf;
622 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
623 decrypted, decrypted_len);
625 if (wt->write_pcap_dumper && decrypted != key_data) {
626 /* Fill in a dummy Data frame header */
627 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
628 struct ieee80211_hdr *h;
629 struct wpa_eapol_key *k;
634 plain_len = decrypted_len;
636 while (p + 1 < decrypted + decrypted_len) {
637 if (p[0] == 0xdd && p[1] == 0x00) {
639 plain_len = p - decrypted;
645 os_memset(buf, 0, sizeof(buf));
646 h = (struct ieee80211_hdr *) buf;
647 h->frame_control = host_to_le16(0x0208);
648 os_memcpy(h->addr1, dst, ETH_ALEN);
649 os_memcpy(h->addr2, src, ETH_ALEN);
650 os_memcpy(h->addr3, src, ETH_ALEN);
651 pos = (u8 *) (h + 1);
652 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
654 os_memcpy(pos, eapol, sizeof(*eapol));
655 pos += sizeof(*eapol);
656 os_memcpy(pos, hdr, sizeof(*hdr));
657 k = (struct wpa_eapol_key *) pos;
658 WPA_PUT_BE16(k->key_info,
659 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
660 WPA_PUT_BE16(k->key_data_length, plain_len);
661 write_pcap_decrypted(wt, buf, sizeof(buf),
662 decrypted, plain_len);
665 if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
666 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
667 os_free(decrypted_buf);
672 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
673 (ie.wpa_ie == NULL && bss->wpaie[0])) {
674 add_note(wt, MSG_INFO,
675 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
676 "Beacon/Probe Response from " MACSTR,
677 MAC2STR(bss->bssid));
678 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
679 ie.wpa_ie, ie.wpa_ie_len);
680 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
683 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
687 os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
688 (ie.rsn_ie == NULL && bss->rsnie[0])) {
689 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
690 "3/4 and Beacon/Probe Response from " MACSTR,
691 MAC2STR(bss->bssid));
692 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
693 ie.rsn_ie, ie.rsn_ie_len);
694 wpa_hexdump(MSG_INFO, "RSN IE in Beacon/Probe Response",
696 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
699 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
700 os_free(decrypted_buf);
704 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
705 const u8 *src, const u8 *data, size_t len)
707 struct wlantest_bss *bss;
708 struct wlantest_sta *sta;
709 const struct ieee802_1x_hdr *eapol;
710 const struct wpa_eapol_key *hdr;
715 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
716 MAC2STR(src), MAC2STR(dst));
717 bss = bss_get(wt, dst);
720 sta = sta_get(bss, src);
724 eapol = (const struct ieee802_1x_hdr *) data;
725 hdr = (const struct wpa_eapol_key *) (eapol + 1);
726 if (!is_zero(hdr->key_rsc, 8)) {
727 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
728 "non-zero Key RSC", MAC2STR(src));
730 key_info = WPA_GET_BE16(hdr->key_info);
732 if (!sta->ptk_set && !sta->tptk_set) {
733 add_note(wt, MSG_DEBUG,
734 "No PTK known to process EAPOL-Key 4/4");
739 kck_len = sta->ptk.kck_len;
741 add_note(wt, MSG_DEBUG,
742 "Use TPTK for validation EAPOL-Key MIC");
744 kck_len = sta->tptk.kck_len;
746 if (check_mic(kck, kck_len, sta->key_mgmt,
747 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
748 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
751 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
753 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
754 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
757 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
758 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
763 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
764 const u8 *src, const u8 *data, size_t len)
766 struct wlantest_bss *bss;
767 struct wlantest_sta *sta;
768 const struct ieee802_1x_hdr *eapol;
769 const struct wpa_eapol_key *hdr;
772 size_t decrypted_len = 0;
774 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
775 MAC2STR(src), MAC2STR(dst));
776 bss = bss_get(wt, src);
779 sta = sta_get(bss, dst);
783 eapol = (const struct ieee802_1x_hdr *) data;
784 hdr = (const struct wpa_eapol_key *) (eapol + 1);
785 key_info = WPA_GET_BE16(hdr->key_info);
788 add_note(wt, MSG_DEBUG,
789 "No PTK known to process EAPOL-Key 1/2");
794 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
795 key_info & WPA_KEY_INFO_TYPE_MASK,
797 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
800 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
802 if (sta->proto & WPA_PROTO_RSN &&
803 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
804 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
807 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
808 decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, sta->ptk.kek_len,
809 ver, hdr, &decrypted_len);
810 if (decrypted == NULL) {
811 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
814 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
815 decrypted, decrypted_len);
816 if (wt->write_pcap_dumper) {
817 /* Fill in a dummy Data frame header */
818 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
819 struct ieee80211_hdr *h;
820 struct wpa_eapol_key *k;
824 plain_len = decrypted_len;
826 while (pos + 1 < decrypted + decrypted_len) {
827 if (pos[0] == 0xdd && pos[1] == 0x00) {
829 plain_len = pos - decrypted;
835 os_memset(buf, 0, sizeof(buf));
836 h = (struct ieee80211_hdr *) buf;
837 h->frame_control = host_to_le16(0x0208);
838 os_memcpy(h->addr1, dst, ETH_ALEN);
839 os_memcpy(h->addr2, src, ETH_ALEN);
840 os_memcpy(h->addr3, src, ETH_ALEN);
841 pos = (u8 *) (h + 1);
842 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
844 os_memcpy(pos, eapol, sizeof(*eapol));
845 pos += sizeof(*eapol);
846 os_memcpy(pos, hdr, sizeof(*hdr));
847 k = (struct wpa_eapol_key *) pos;
848 WPA_PUT_BE16(k->key_info,
849 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
850 WPA_PUT_BE16(k->key_data_length, plain_len);
851 write_pcap_decrypted(wt, buf, sizeof(buf),
852 decrypted, plain_len);
854 if (sta->proto & WPA_PROTO_RSN)
855 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
858 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
859 if (decrypted_len == klen) {
860 const u8 *rsc = hdr->key_rsc;
862 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
863 WPA_KEY_INFO_KEY_INDEX_SHIFT;
864 add_note(wt, MSG_DEBUG, "GTK key index %d", id);
865 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
867 bss->gtk_len[id] = decrypted_len;
868 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
869 bss->rsc[id][0] = rsc[5];
870 bss->rsc[id][1] = rsc[4];
871 bss->rsc[id][2] = rsc[3];
872 bss->rsc[id][3] = rsc[2];
873 bss->rsc[id][4] = rsc[1];
874 bss->rsc[id][5] = rsc[0];
875 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
877 add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
878 "in Group Key msg 1/2 from " MACSTR,
886 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
887 const u8 *src, const u8 *data, size_t len)
889 struct wlantest_bss *bss;
890 struct wlantest_sta *sta;
891 const struct ieee802_1x_hdr *eapol;
892 const struct wpa_eapol_key *hdr;
895 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
896 MAC2STR(src), MAC2STR(dst));
897 bss = bss_get(wt, dst);
900 sta = sta_get(bss, src);
904 eapol = (const struct ieee802_1x_hdr *) data;
905 hdr = (const struct wpa_eapol_key *) (eapol + 1);
906 if (!is_zero(hdr->key_rsc, 8)) {
907 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
908 "non-zero Key RSC", MAC2STR(src));
910 key_info = WPA_GET_BE16(hdr->key_info);
913 add_note(wt, MSG_DEBUG,
914 "No PTK known to process EAPOL-Key 2/2");
919 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
920 key_info & WPA_KEY_INFO_TYPE_MASK,
922 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
925 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
929 static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
930 const u8 *src, const u8 *data, size_t len,
933 const struct ieee802_1x_hdr *eapol;
934 const struct wpa_eapol_key *hdr;
936 u16 key_info, key_length, ver, key_data_length;
938 eapol = (const struct ieee802_1x_hdr *) data;
939 hdr = (const struct wpa_eapol_key *) (eapol + 1);
941 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
942 (const u8 *) hdr, len - sizeof(*eapol));
943 if (len < sizeof(*hdr)) {
944 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
949 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
950 /* TODO: EAPOL-Key RC4 for WEP */
951 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
952 MACSTR, MAC2STR(src));
956 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
957 hdr->type != EAPOL_KEY_TYPE_WPA) {
958 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
959 "%u from " MACSTR, hdr->type, MAC2STR(src));
963 key_info = WPA_GET_BE16(hdr->key_info);
964 key_length = WPA_GET_BE16(hdr->key_length);
965 key_data_length = WPA_GET_BE16(hdr->key_data_length);
966 key_data = (const u8 *) (hdr + 1);
967 if (key_data + key_data_length > data + len) {
968 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
972 if (key_data + key_data_length < data + len) {
973 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
974 "field", key_data + key_data_length,
975 data + len - key_data - key_data_length);
979 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
980 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
982 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
983 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
984 WPA_KEY_INFO_KEY_INDEX_SHIFT,
985 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
986 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
987 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
988 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
989 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
990 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
991 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
992 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
995 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
996 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
997 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
998 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
999 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
1000 "Version %u from " MACSTR, ver, MAC2STR(src));
1004 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
1005 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
1006 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
1007 hdr->key_nonce, WPA_NONCE_LEN);
1008 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
1010 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
1011 hdr->key_rsc, WPA_KEY_RSC_LEN);
1012 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
1014 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
1015 key_data, key_data_length);
1017 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
1018 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
1020 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
1021 "Key Info bits 0x%x from " MACSTR,
1022 key_info, MAC2STR(src));
1025 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
1026 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
1027 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
1028 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
1029 "Key Info bits 0x%x from " MACSTR,
1030 key_info, MAC2STR(src));
1033 if (key_length > 32) {
1034 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
1035 "from " MACSTR, key_length, MAC2STR(src));
1038 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1039 !is_zero(hdr->key_iv, 16)) {
1040 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
1041 "(reserved with ver=%d) field from " MACSTR,
1043 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
1047 if (!is_zero(hdr->key_id, 8)) {
1048 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
1049 "(reserved) field from " MACSTR, MAC2STR(src));
1050 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
1054 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
1055 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
1056 "(last two are unused)" MACSTR, MAC2STR(src));
1059 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
1062 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
1065 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1066 /* 4-Way Handshake */
1067 switch (key_info & (WPA_KEY_INFO_SECURE |
1070 WPA_KEY_INFO_INSTALL)) {
1071 case WPA_KEY_INFO_ACK:
1072 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
1074 case WPA_KEY_INFO_MIC:
1075 if (key_data_length == 0)
1076 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1079 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1082 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1083 WPA_KEY_INFO_INSTALL:
1084 /* WPA does not include Secure bit in 3/4 */
1085 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1087 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1088 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1089 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1091 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1092 if (key_data_length == 0)
1093 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1096 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1100 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1104 /* Group Key Handshake */
1105 switch (key_info & (WPA_KEY_INFO_SECURE |
1107 WPA_KEY_INFO_ACK)) {
1108 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1110 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1112 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1113 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1116 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1123 void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
1124 const u8 *data, size_t len, int prot)
1126 const struct ieee802_1x_hdr *hdr;
1130 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1131 if (len < sizeof(*hdr)) {
1132 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1137 hdr = (const struct ieee802_1x_hdr *) data;
1138 length = be_to_host16(hdr->length);
1139 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1141 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1142 hdr->version, hdr->type, length);
1143 if (hdr->version < 1 || hdr->version > 3) {
1144 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1145 MACSTR, hdr->version, MAC2STR(src));
1147 if (sizeof(*hdr) + length > len) {
1148 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1153 if (sizeof(*hdr) + length < len) {
1154 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1155 (int) (len - sizeof(*hdr) - length));
1157 p = (const u8 *) (hdr + 1);
1159 switch (hdr->type) {
1160 case IEEE802_1X_TYPE_EAP_PACKET:
1161 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1163 case IEEE802_1X_TYPE_EAPOL_START:
1164 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1166 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1167 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1169 case IEEE802_1X_TYPE_EAPOL_KEY:
1170 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
1173 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1174 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1178 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);