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"
22 extern int wpa_debug_level
;
25 static int is_zero(const u8
*buf
, size_t len
)
28 for (i
= 0; i
< len
; i
++) {
36 static int check_mic(const u8
*kck
, int ver
, const u8
*data
, size_t len
)
40 struct ieee802_1x_hdr
*hdr
;
41 struct wpa_eapol_key
*key
;
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
, 16);
52 os_memset(key
->key_mic
, 0, 16);
54 if (wpa_eapol_key_mic(kck
, ver
, buf
, len
, key
->key_mic
) == 0 &&
55 os_memcmp(rx_mic
, key
->key_mic
, 16) == 0)
64 static void rx_data_eapol_key_1_of_4(struct wlantest
*wt
, const u8
*dst
,
65 const u8
*src
, const u8
*data
, size_t len
)
67 struct wlantest_bss
*bss
;
68 struct wlantest_sta
*sta
;
69 const struct ieee802_1x_hdr
*eapol
;
70 const struct wpa_eapol_key
*hdr
;
72 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/4 " MACSTR
" -> " MACSTR
,
73 MAC2STR(src
), MAC2STR(dst
));
74 bss
= bss_get(wt
, src
);
77 sta
= sta_get(bss
, dst
);
81 eapol
= (const struct ieee802_1x_hdr
*) data
;
82 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
83 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
84 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
85 " used zero nonce", MAC2STR(src
));
87 if (!is_zero(hdr
->key_rsc
, 8)) {
88 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
89 " used non-zero Key RSC", MAC2STR(src
));
91 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
95 static int try_pmk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
96 struct wlantest_sta
*sta
, u16 ver
,
97 const u8
*data
, size_t len
,
98 struct wlantest_pmk
*pmk
)
101 size_t ptk_len
= sta
->pairwise_cipher
== WPA_CIPHER_TKIP
? 64 : 48;
102 wpa_pmk_to_ptk(pmk
->pmk
, sizeof(pmk
->pmk
),
103 "Pairwise key expansion",
104 bss
->bssid
, sta
->addr
, sta
->anonce
, sta
->snonce
,
105 (u8
*) &ptk
, ptk_len
,
106 wpa_key_mgmt_sha256(sta
->key_mgmt
));
107 if (check_mic(ptk
.kck
, ver
, data
, len
) < 0)
110 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
111 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
112 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
115 * Rekeying - use new PTK for EAPOL-Key frames, but continue
116 * using the old PTK for frame decryption.
118 add_note(wt
, MSG_DEBUG
, "Derived PTK during rekeying");
119 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
120 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK", sta
->tptk
.kck
, 16);
121 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK", sta
->tptk
.kek
, 16);
122 wpa_hexdump(MSG_DEBUG
, "TPTK:TK1", sta
->tptk
.tk1
, 16);
124 wpa_hexdump(MSG_DEBUG
, "TPTK:TK2", sta
->tptk
.u
.tk2
,
129 add_note(wt
, MSG_DEBUG
, "Derived new PTK");
130 os_memcpy(&sta
->ptk
, &ptk
, sizeof(ptk
));
131 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
132 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
133 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
135 wpa_hexdump(MSG_DEBUG
, "PTK:TK2", sta
->ptk
.u
.tk2
, 16);
137 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
138 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
143 static void derive_ptk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
144 struct wlantest_sta
*sta
, u16 ver
,
145 const u8
*data
, size_t len
)
147 struct wlantest_pmk
*pmk
;
149 wpa_printf(MSG_DEBUG
, "Trying to derive PTK for " MACSTR
,
151 dl_list_for_each(pmk
, &bss
->pmk
, struct wlantest_pmk
, list
) {
152 wpa_printf(MSG_DEBUG
, "Try per-BSS PMK");
153 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
157 dl_list_for_each(pmk
, &wt
->pmk
, struct wlantest_pmk
, list
) {
158 wpa_printf(MSG_DEBUG
, "Try global PMK");
159 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
164 struct wlantest_ptk
*ptk
;
165 int prev_level
= wpa_debug_level
;
167 wpa_debug_level
= MSG_WARNING
;
168 dl_list_for_each(ptk
, &wt
->ptk
, struct wlantest_ptk
, list
) {
169 if (check_mic(ptk
->ptk
.kck
, 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");
175 os_memcpy(&sta
->ptk
, &ptk
->ptk
, sizeof(ptk
->ptk
));
176 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
177 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
178 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
179 if (ptk
->ptk_len
> 48)
180 wpa_hexdump(MSG_DEBUG
, "PTK:TK2",
183 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
184 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
186 wpa_debug_level
= prev_level
;
189 add_note(wt
, MSG_DEBUG
, "No matching PMK found to derive PTK");
193 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
194 const u8
*src
, const u8
*data
, size_t len
)
196 struct wlantest_bss
*bss
;
197 struct wlantest_sta
*sta
;
198 const struct ieee802_1x_hdr
*eapol
;
199 const struct wpa_eapol_key
*hdr
;
200 const u8
*key_data
, *kck
;
201 u16 key_info
, key_data_len
;
202 struct wpa_eapol_ie_parse ie
;
204 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
205 MAC2STR(src
), MAC2STR(dst
));
206 bss
= bss_get(wt
, dst
);
209 sta
= sta_get(bss
, src
);
213 eapol
= (const struct ieee802_1x_hdr
*) data
;
214 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
215 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
216 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
217 " used zero nonce", MAC2STR(src
));
219 if (!is_zero(hdr
->key_rsc
, 8)) {
220 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
221 " used non-zero Key RSC", MAC2STR(src
));
223 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
224 key_info
= WPA_GET_BE16(hdr
->key_info
);
225 key_data_len
= WPA_GET_BE16(hdr
->key_data_length
);
226 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
228 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
229 add_note(wt
, MSG_DEBUG
,
230 "No PTK known to process EAPOL-Key 2/4");
236 add_note(wt
, MSG_DEBUG
,
237 "Use TPTK for validation EAPOL-Key MIC");
240 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
241 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
244 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
246 key_data
= (const u8
*) (hdr
+ 1);
248 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
249 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
254 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
255 ie
.wpa_ie
, ie
.wpa_ie_len
);
256 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
257 struct ieee802_11_elems elems
;
258 add_note(wt
, MSG_INFO
,
259 "Mismatch in WPA IE between EAPOL-Key 2/4 "
260 "and (Re)Association Request from " MACSTR
,
262 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
263 ie
.wpa_ie
, ie
.wpa_ie_len
);
264 wpa_hexdump(MSG_INFO
, "WPA 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
.wpa_ie
= ie
.wpa_ie
+ 2;
275 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
276 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
277 "IE in EAPOL-Key 2/4");
278 sta_update_assoc(sta
, &elems
);
283 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
284 ie
.rsn_ie
, ie
.rsn_ie_len
);
285 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
286 struct ieee802_11_elems elems
;
287 add_note(wt
, MSG_INFO
,
288 "Mismatch in RSN IE between EAPOL-Key 2/4 "
289 "and (Re)Association Request from " MACSTR
,
291 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
292 ie
.rsn_ie
, ie
.rsn_ie_len
);
293 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
296 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
298 * The sniffer may have missed (Re)Association
299 * Request, so try to survive with the information from
302 os_memset(&elems
, 0, sizeof(elems
));
303 elems
.rsn_ie
= ie
.rsn_ie
+ 2;
304 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
305 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
306 "IE in EAPOL-Key 2/4");
307 sta_update_assoc(sta
, &elems
);
313 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
314 const struct wpa_eapol_key
*hdr
,
318 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
320 buf
= os_malloc(keydatalen
);
324 os_memcpy(ek
, hdr
->key_iv
, 16);
325 os_memcpy(ek
+ 16, kek
, 16);
326 os_memcpy(buf
, hdr
+ 1, keydatalen
);
327 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
328 add_note(wt
, MSG_INFO
, "RC4 failed");
338 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
339 const struct wpa_eapol_key
*hdr
,
343 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
345 if (keydatalen
% 8) {
346 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
350 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
351 buf
= os_malloc(keydatalen
);
354 if (aes_unwrap(kek
, keydatalen
/ 8, (u8
*) (hdr
+ 1), buf
)) {
356 add_note(wt
, MSG_INFO
,
357 "AES unwrap failed - could not decrypt EAPOL-Key "
367 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, const u8
*kek
, u16 ver
,
368 const struct wpa_eapol_key
*hdr
,
372 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
373 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, len
);
374 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
375 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
376 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, len
);
378 add_note(wt
, MSG_INFO
,
379 "Unsupported EAPOL-Key Key Descriptor Version %u",
386 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
387 struct wlantest_sta
*sta
,
388 const u8
*buf
, size_t len
, const u8
*rsc
)
390 struct wpa_eapol_ie_parse ie
;
392 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
393 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
398 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
399 ie
.wpa_ie
, ie
.wpa_ie_len
);
403 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
404 ie
.rsn_ie
, ie
.rsn_ie_len
);
408 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
410 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
412 id
= ie
.gtk
[0] & 0x03;
413 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
414 id
, !!(ie
.gtk
[0] & 0x04));
415 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
416 add_note(wt
, MSG_INFO
,
417 "GTK KDE: Reserved field set: "
418 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
420 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
422 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
423 sta
->gtk_len
= ie
.gtk_len
- 2;
424 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
425 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
426 bss
->rsc
[id
][0] = rsc
[5];
427 bss
->rsc
[id
][1] = rsc
[4];
428 bss
->rsc
[id
][2] = rsc
[3];
429 bss
->rsc
[id
][3] = rsc
[2];
430 bss
->rsc
[id
][4] = rsc
[1];
431 bss
->rsc
[id
][5] = rsc
[0];
434 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
436 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
437 (unsigned) ie
.gtk_len
);
442 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
443 ie
.igtk
, ie
.igtk_len
);
444 if (ie
.igtk_len
== 24) {
446 id
= WPA_GET_LE16(ie
.igtk
);
448 add_note(wt
, MSG_INFO
,
449 "Unexpected IGTK KeyID %u", id
);
452 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
453 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
454 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
456 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
457 bss
->igtk_set
[id
] = 1;
459 bss
->ipn
[id
][0] = ipn
[5];
460 bss
->ipn
[id
][1] = ipn
[4];
461 bss
->ipn
[id
][2] = ipn
[3];
462 bss
->ipn
[id
][3] = ipn
[2];
463 bss
->ipn
[id
][4] = ipn
[1];
464 bss
->ipn
[id
][5] = ipn
[0];
468 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
469 (unsigned) ie
.igtk_len
);
475 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
476 const u8
*src
, const u8
*data
, size_t len
)
478 struct wlantest_bss
*bss
;
479 struct wlantest_sta
*sta
;
480 const struct ieee802_1x_hdr
*eapol
;
481 const struct wpa_eapol_key
*hdr
;
482 const u8
*key_data
, *kck
, *kek
;
485 u8
*decrypted_buf
= NULL
;
487 size_t decrypted_len
= 0;
488 struct wpa_eapol_ie_parse ie
;
490 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
491 MAC2STR(src
), MAC2STR(dst
));
492 bss
= bss_get(wt
, src
);
495 sta
= sta_get(bss
, dst
);
499 eapol
= (const struct ieee802_1x_hdr
*) data
;
500 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
501 key_info
= WPA_GET_BE16(hdr
->key_info
);
503 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
504 add_note(wt
, MSG_INFO
,
505 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
508 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
510 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
514 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
515 add_note(wt
, MSG_DEBUG
,
516 "No PTK known to process EAPOL-Key 3/4");
523 add_note(wt
, MSG_DEBUG
,
524 "Use TPTK for validation EAPOL-Key MIC");
528 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
529 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
532 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
534 key_data
= (const u8
*) (hdr
+ 1);
535 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
536 if (sta
->proto
& WPA_PROTO_RSN
)
537 add_note(wt
, MSG_INFO
,
538 "EAPOL-Key 3/4 without EncrKeyData bit");
539 decrypted
= key_data
;
540 decrypted_len
= WPA_GET_BE16(hdr
->key_data_length
);
542 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
543 decrypted_buf
= decrypt_eapol_key_data(wt
, kek
, ver
, hdr
,
545 if (decrypted_buf
== NULL
) {
546 add_note(wt
, MSG_INFO
,
547 "Failed to decrypt EAPOL-Key Key Data");
550 decrypted
= decrypted_buf
;
551 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
552 decrypted
, decrypted_len
);
554 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
555 /* Fill in a dummy Data frame header */
556 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
557 struct ieee80211_hdr
*h
;
558 struct wpa_eapol_key
*k
;
563 plain_len
= decrypted_len
;
565 while (p
+ 1 < decrypted
+ decrypted_len
) {
566 if (p
[0] == 0xdd && p
[1] == 0x00) {
568 plain_len
= p
- decrypted
;
574 os_memset(buf
, 0, sizeof(buf
));
575 h
= (struct ieee80211_hdr
*) buf
;
576 h
->frame_control
= host_to_le16(0x0208);
577 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
578 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
579 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
580 pos
= (u8
*) (h
+ 1);
581 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
583 os_memcpy(pos
, eapol
, sizeof(*eapol
));
584 pos
+= sizeof(*eapol
);
585 os_memcpy(pos
, hdr
, sizeof(*hdr
));
586 k
= (struct wpa_eapol_key
*) pos
;
587 WPA_PUT_BE16(k
->key_info
,
588 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
589 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
590 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
591 decrypted
, plain_len
);
594 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
595 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
596 os_free(decrypted_buf
);
601 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
602 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
603 add_note(wt
, MSG_INFO
,
604 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
605 "Beacon/Probe Response from " MACSTR
,
606 MAC2STR(bss
->bssid
));
607 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
608 ie
.wpa_ie
, ie
.wpa_ie_len
);
609 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
612 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
616 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
617 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
618 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
619 "3/4 and Beacon/Probe Response from " MACSTR
,
620 MAC2STR(bss
->bssid
));
621 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
622 ie
.rsn_ie
, ie
.rsn_ie_len
);
623 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
626 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
629 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
630 os_free(decrypted_buf
);
634 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
635 const u8
*src
, const u8
*data
, size_t len
)
637 struct wlantest_bss
*bss
;
638 struct wlantest_sta
*sta
;
639 const struct ieee802_1x_hdr
*eapol
;
640 const struct wpa_eapol_key
*hdr
;
644 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
645 MAC2STR(src
), MAC2STR(dst
));
646 bss
= bss_get(wt
, dst
);
649 sta
= sta_get(bss
, src
);
653 eapol
= (const struct ieee802_1x_hdr
*) data
;
654 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
655 if (!is_zero(hdr
->key_rsc
, 8)) {
656 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
657 "non-zero Key RSC", MAC2STR(src
));
659 key_info
= WPA_GET_BE16(hdr
->key_info
);
661 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
662 add_note(wt
, MSG_DEBUG
,
663 "No PTK known to process EAPOL-Key 4/4");
669 add_note(wt
, MSG_DEBUG
,
670 "Use TPTK for validation EAPOL-Key MIC");
673 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
674 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
677 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
679 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
680 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
683 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
684 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
689 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
690 const u8
*src
, const u8
*data
, size_t len
)
692 struct wlantest_bss
*bss
;
693 struct wlantest_sta
*sta
;
694 const struct ieee802_1x_hdr
*eapol
;
695 const struct wpa_eapol_key
*hdr
;
698 size_t decrypted_len
= 0;
700 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
701 MAC2STR(src
), MAC2STR(dst
));
702 bss
= bss_get(wt
, src
);
705 sta
= sta_get(bss
, dst
);
709 eapol
= (const struct ieee802_1x_hdr
*) data
;
710 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
711 key_info
= WPA_GET_BE16(hdr
->key_info
);
714 add_note(wt
, MSG_DEBUG
,
715 "No PTK known to process EAPOL-Key 1/2");
720 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
722 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
725 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
727 if (sta
->proto
& WPA_PROTO_RSN
&&
728 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
729 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
732 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
733 decrypted
= decrypt_eapol_key_data(wt
, sta
->ptk
.kek
, ver
, hdr
,
735 if (decrypted
== NULL
) {
736 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
739 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
740 decrypted
, decrypted_len
);
741 if (wt
->write_pcap_dumper
) {
742 /* Fill in a dummy Data frame header */
743 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
744 struct ieee80211_hdr
*h
;
745 struct wpa_eapol_key
*k
;
749 plain_len
= decrypted_len
;
751 while (pos
+ 1 < decrypted
+ decrypted_len
) {
752 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
754 plain_len
= pos
- decrypted
;
760 os_memset(buf
, 0, sizeof(buf
));
761 h
= (struct ieee80211_hdr
*) buf
;
762 h
->frame_control
= host_to_le16(0x0208);
763 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
764 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
765 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
766 pos
= (u8
*) (h
+ 1);
767 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
769 os_memcpy(pos
, eapol
, sizeof(*eapol
));
770 pos
+= sizeof(*eapol
);
771 os_memcpy(pos
, hdr
, sizeof(*hdr
));
772 k
= (struct wpa_eapol_key
*) pos
;
773 WPA_PUT_BE16(k
->key_info
,
774 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
775 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
776 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
777 decrypted
, plain_len
);
779 if (sta
->proto
& WPA_PROTO_RSN
)
780 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
783 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
784 if (decrypted_len
== klen
) {
785 const u8
*rsc
= hdr
->key_rsc
;
787 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
788 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
789 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
790 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
792 bss
->gtk_len
[id
] = decrypted_len
;
793 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
794 bss
->rsc
[id
][0] = rsc
[5];
795 bss
->rsc
[id
][1] = rsc
[4];
796 bss
->rsc
[id
][2] = rsc
[3];
797 bss
->rsc
[id
][3] = rsc
[2];
798 bss
->rsc
[id
][4] = rsc
[1];
799 bss
->rsc
[id
][5] = rsc
[0];
800 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
802 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
803 "in Group Key msg 1/2 from " MACSTR
,
811 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
812 const u8
*src
, const u8
*data
, size_t len
)
814 struct wlantest_bss
*bss
;
815 struct wlantest_sta
*sta
;
816 const struct ieee802_1x_hdr
*eapol
;
817 const struct wpa_eapol_key
*hdr
;
820 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
821 MAC2STR(src
), MAC2STR(dst
));
822 bss
= bss_get(wt
, dst
);
825 sta
= sta_get(bss
, src
);
829 eapol
= (const struct ieee802_1x_hdr
*) data
;
830 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
831 if (!is_zero(hdr
->key_rsc
, 8)) {
832 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
833 "non-zero Key RSC", MAC2STR(src
));
835 key_info
= WPA_GET_BE16(hdr
->key_info
);
838 add_note(wt
, MSG_DEBUG
,
839 "No PTK known to process EAPOL-Key 2/2");
844 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
846 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
849 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
853 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*dst
,
854 const u8
*src
, const u8
*data
, size_t len
,
857 const struct ieee802_1x_hdr
*eapol
;
858 const struct wpa_eapol_key
*hdr
;
860 u16 key_info
, key_length
, ver
, key_data_length
;
862 eapol
= (const struct ieee802_1x_hdr
*) data
;
863 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
865 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
866 (const u8
*) hdr
, len
- sizeof(*eapol
));
867 if (len
< sizeof(*hdr
)) {
868 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
873 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
874 /* TODO: EAPOL-Key RC4 for WEP */
875 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
876 MACSTR
, MAC2STR(src
));
880 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
881 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
882 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
883 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
887 key_info
= WPA_GET_BE16(hdr
->key_info
);
888 key_length
= WPA_GET_BE16(hdr
->key_length
);
889 key_data_length
= WPA_GET_BE16(hdr
->key_data_length
);
890 key_data
= (const u8
*) (hdr
+ 1);
891 if (key_data
+ key_data_length
> data
+ len
) {
892 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
896 if (key_data
+ key_data_length
< data
+ len
) {
897 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
898 "field", key_data
+ key_data_length
,
899 data
+ len
- key_data
- key_data_length
);
903 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
904 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
906 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
907 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
908 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
909 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
910 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
911 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
912 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
913 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
914 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
915 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
916 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
919 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
920 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
921 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
) {
922 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
923 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
927 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
928 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
929 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
930 hdr
->key_nonce
, WPA_NONCE_LEN
);
931 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
933 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
934 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
935 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
937 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
938 key_data
, key_data_length
);
940 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
941 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
943 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
944 "Key Info bits 0x%x from " MACSTR
,
945 key_info
, MAC2STR(src
));
948 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
949 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
950 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
951 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
952 "Key Info bits 0x%x from " MACSTR
,
953 key_info
, MAC2STR(src
));
956 if (key_length
> 32) {
957 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
958 "from " MACSTR
, key_length
, MAC2STR(src
));
961 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
962 !is_zero(hdr
->key_iv
, 16)) {
963 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
964 "(reserved with ver=%d) field from " MACSTR
,
966 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
970 if (!is_zero(hdr
->key_id
, 8)) {
971 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
972 "(reserved) field from " MACSTR
, MAC2STR(src
));
973 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
977 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
978 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
979 "(last two are unused)" MACSTR
, MAC2STR(src
));
982 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
985 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
988 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
989 /* 4-Way Handshake */
990 switch (key_info
& (WPA_KEY_INFO_SECURE
|
993 WPA_KEY_INFO_INSTALL
)) {
994 case WPA_KEY_INFO_ACK
:
995 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
997 case WPA_KEY_INFO_MIC
:
998 if (key_data_length
== 0)
999 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1002 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1005 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1006 WPA_KEY_INFO_INSTALL
:
1007 /* WPA does not include Secure bit in 3/4 */
1008 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1010 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1011 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1012 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1014 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1015 if (key_data_length
== 0)
1016 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1019 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1023 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1027 /* Group Key Handshake */
1028 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1030 WPA_KEY_INFO_ACK
)) {
1031 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1033 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1035 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1036 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1039 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1046 void rx_data_eapol(struct wlantest
*wt
, const u8
*dst
, const u8
*src
,
1047 const u8
*data
, size_t len
, int prot
)
1049 const struct ieee802_1x_hdr
*hdr
;
1053 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1054 if (len
< sizeof(*hdr
)) {
1055 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1060 hdr
= (const struct ieee802_1x_hdr
*) data
;
1061 length
= be_to_host16(hdr
->length
);
1062 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1064 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1065 hdr
->version
, hdr
->type
, length
);
1066 if (hdr
->version
< 1 || hdr
->version
> 3) {
1067 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1068 MACSTR
, hdr
->version
, MAC2STR(src
));
1070 if (sizeof(*hdr
) + length
> len
) {
1071 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1076 if (sizeof(*hdr
) + length
< len
) {
1077 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1078 (int) (len
- sizeof(*hdr
) - length
));
1080 p
= (const u8
*) (hdr
+ 1);
1082 switch (hdr
->type
) {
1083 case IEEE802_1X_TYPE_EAP_PACKET
:
1084 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1086 case IEEE802_1X_TYPE_EAPOL_START
:
1087 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1089 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1090 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1092 case IEEE802_1X_TYPE_EAPOL_KEY
:
1093 rx_data_eapol_key(wt
, dst
, src
, data
, sizeof(*hdr
) + length
,
1096 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1097 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1101 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);