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
" (ver %u)",
148 MAC2STR(sta
->addr
), ver
);
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)
162 struct wlantest_ptk
*ptk
;
163 int prev_level
= wpa_debug_level
;
165 wpa_debug_level
= MSG_WARNING
;
166 dl_list_for_each(ptk
, &wt
->ptk
, struct wlantest_ptk
, list
) {
167 if (check_mic(ptk
->ptk
.kck
, ver
, data
, len
) < 0)
169 wpa_printf(MSG_INFO
, "Pre-set PTK matches for STA "
170 MACSTR
" BSSID " MACSTR
,
171 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
172 add_note(wt
, MSG_DEBUG
, "Using pre-set PTK");
173 os_memcpy(&sta
->ptk
, &ptk
->ptk
, sizeof(ptk
->ptk
));
174 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
175 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
176 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
177 if (ptk
->ptk_len
> 48)
178 wpa_hexdump(MSG_DEBUG
, "PTK:TK2",
181 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
182 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
184 wpa_debug_level
= prev_level
;
187 add_note(wt
, MSG_DEBUG
, "No matching PMK found to derive PTK");
191 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
192 const u8
*src
, const u8
*data
, size_t len
)
194 struct wlantest_bss
*bss
;
195 struct wlantest_sta
*sta
;
196 const struct ieee802_1x_hdr
*eapol
;
197 const struct wpa_eapol_key
*hdr
;
198 const u8
*key_data
, *kck
;
199 u16 key_info
, key_data_len
;
200 struct wpa_eapol_ie_parse ie
;
202 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
203 MAC2STR(src
), MAC2STR(dst
));
204 bss
= bss_get(wt
, dst
);
207 sta
= sta_get(bss
, src
);
211 eapol
= (const struct ieee802_1x_hdr
*) data
;
212 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
213 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
214 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
215 " used zero nonce", MAC2STR(src
));
217 if (!is_zero(hdr
->key_rsc
, 8)) {
218 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
219 " used non-zero Key RSC", MAC2STR(src
));
221 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
222 key_info
= WPA_GET_BE16(hdr
->key_info
);
223 key_data_len
= WPA_GET_BE16(hdr
->key_data_length
);
224 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
226 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
227 add_note(wt
, MSG_DEBUG
,
228 "No PTK known to process EAPOL-Key 2/4");
234 add_note(wt
, MSG_DEBUG
,
235 "Use TPTK for validation EAPOL-Key MIC");
238 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
239 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
242 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
244 key_data
= (const u8
*) (hdr
+ 1);
246 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
247 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
252 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
253 ie
.wpa_ie
, ie
.wpa_ie_len
);
254 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
255 struct ieee802_11_elems elems
;
256 add_note(wt
, MSG_INFO
,
257 "Mismatch in WPA IE between EAPOL-Key 2/4 "
258 "and (Re)Association Request from " MACSTR
,
260 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
261 ie
.wpa_ie
, ie
.wpa_ie_len
);
262 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
265 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
267 * The sniffer may have missed (Re)Association
268 * Request, so try to survive with the information from
271 os_memset(&elems
, 0, sizeof(elems
));
272 elems
.wpa_ie
= ie
.wpa_ie
+ 2;
273 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
274 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
275 "IE in EAPOL-Key 2/4");
276 sta_update_assoc(sta
, &elems
);
281 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
282 ie
.rsn_ie
, ie
.rsn_ie_len
);
283 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
284 struct ieee802_11_elems elems
;
285 add_note(wt
, MSG_INFO
,
286 "Mismatch in RSN IE between EAPOL-Key 2/4 "
287 "and (Re)Association Request from " MACSTR
,
289 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
290 ie
.rsn_ie
, ie
.rsn_ie_len
);
291 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
294 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
296 * The sniffer may have missed (Re)Association
297 * Request, so try to survive with the information from
300 os_memset(&elems
, 0, sizeof(elems
));
301 elems
.rsn_ie
= ie
.rsn_ie
+ 2;
302 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
303 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
304 "IE in EAPOL-Key 2/4");
305 sta_update_assoc(sta
, &elems
);
311 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
312 const struct wpa_eapol_key
*hdr
,
316 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
318 buf
= os_malloc(keydatalen
);
322 os_memcpy(ek
, hdr
->key_iv
, 16);
323 os_memcpy(ek
+ 16, kek
, 16);
324 os_memcpy(buf
, hdr
+ 1, keydatalen
);
325 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
326 add_note(wt
, MSG_INFO
, "RC4 failed");
336 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
337 const struct wpa_eapol_key
*hdr
,
341 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
343 if (keydatalen
% 8) {
344 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
348 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
349 buf
= os_malloc(keydatalen
);
352 if (aes_unwrap(kek
, keydatalen
/ 8, (u8
*) (hdr
+ 1), buf
)) {
354 add_note(wt
, MSG_INFO
,
355 "AES unwrap failed - could not decrypt EAPOL-Key "
365 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, const u8
*kek
, u16 ver
,
366 const struct wpa_eapol_key
*hdr
,
370 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
371 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, len
);
372 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
373 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
374 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, len
);
375 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
376 /* For now, assume this is OSEN */
377 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, len
);
379 add_note(wt
, MSG_INFO
,
380 "Unsupported EAPOL-Key Key Descriptor Version %u",
387 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
388 struct wlantest_sta
*sta
,
389 const u8
*buf
, size_t len
, const u8
*rsc
)
391 struct wpa_eapol_ie_parse ie
;
393 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
394 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
399 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
400 ie
.wpa_ie
, ie
.wpa_ie_len
);
404 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
405 ie
.rsn_ie
, ie
.rsn_ie_len
);
409 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
411 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
413 id
= ie
.gtk
[0] & 0x03;
414 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
415 id
, !!(ie
.gtk
[0] & 0x04));
416 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
417 add_note(wt
, MSG_INFO
,
418 "GTK KDE: Reserved field set: "
419 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
421 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
423 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
424 sta
->gtk_len
= ie
.gtk_len
- 2;
425 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
426 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
427 bss
->rsc
[id
][0] = rsc
[5];
428 bss
->rsc
[id
][1] = rsc
[4];
429 bss
->rsc
[id
][2] = rsc
[3];
430 bss
->rsc
[id
][3] = rsc
[2];
431 bss
->rsc
[id
][4] = rsc
[1];
432 bss
->rsc
[id
][5] = rsc
[0];
435 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
437 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
438 (unsigned) ie
.gtk_len
);
443 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
444 ie
.igtk
, ie
.igtk_len
);
445 if (ie
.igtk_len
== 24) {
447 id
= WPA_GET_LE16(ie
.igtk
);
449 add_note(wt
, MSG_INFO
,
450 "Unexpected IGTK KeyID %u", id
);
453 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
454 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
455 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
457 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
458 bss
->igtk_set
[id
] = 1;
460 bss
->ipn
[id
][0] = ipn
[5];
461 bss
->ipn
[id
][1] = ipn
[4];
462 bss
->ipn
[id
][2] = ipn
[3];
463 bss
->ipn
[id
][3] = ipn
[2];
464 bss
->ipn
[id
][4] = ipn
[1];
465 bss
->ipn
[id
][5] = ipn
[0];
469 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
470 (unsigned) ie
.igtk_len
);
476 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
477 const u8
*src
, const u8
*data
, size_t len
)
479 struct wlantest_bss
*bss
;
480 struct wlantest_sta
*sta
;
481 const struct ieee802_1x_hdr
*eapol
;
482 const struct wpa_eapol_key
*hdr
;
483 const u8
*key_data
, *kck
, *kek
;
486 u8
*decrypted_buf
= NULL
;
488 size_t decrypted_len
= 0;
489 struct wpa_eapol_ie_parse ie
;
491 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
492 MAC2STR(src
), MAC2STR(dst
));
493 bss
= bss_get(wt
, src
);
496 sta
= sta_get(bss
, dst
);
500 eapol
= (const struct ieee802_1x_hdr
*) data
;
501 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
502 key_info
= WPA_GET_BE16(hdr
->key_info
);
504 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
505 add_note(wt
, MSG_INFO
,
506 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
509 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
511 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
515 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
516 add_note(wt
, MSG_DEBUG
,
517 "No PTK known to process EAPOL-Key 3/4");
524 add_note(wt
, MSG_DEBUG
,
525 "Use TPTK for validation EAPOL-Key MIC");
529 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
530 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
533 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
535 key_data
= (const u8
*) (hdr
+ 1);
536 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
537 if (sta
->proto
& WPA_PROTO_RSN
)
538 add_note(wt
, MSG_INFO
,
539 "EAPOL-Key 3/4 without EncrKeyData bit");
540 decrypted
= key_data
;
541 decrypted_len
= WPA_GET_BE16(hdr
->key_data_length
);
543 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
544 decrypted_buf
= decrypt_eapol_key_data(wt
, kek
, ver
, hdr
,
546 if (decrypted_buf
== NULL
) {
547 add_note(wt
, MSG_INFO
,
548 "Failed to decrypt EAPOL-Key Key Data");
551 decrypted
= decrypted_buf
;
552 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
553 decrypted
, decrypted_len
);
555 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
556 /* Fill in a dummy Data frame header */
557 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
558 struct ieee80211_hdr
*h
;
559 struct wpa_eapol_key
*k
;
564 plain_len
= decrypted_len
;
566 while (p
+ 1 < decrypted
+ decrypted_len
) {
567 if (p
[0] == 0xdd && p
[1] == 0x00) {
569 plain_len
= p
- decrypted
;
575 os_memset(buf
, 0, sizeof(buf
));
576 h
= (struct ieee80211_hdr
*) buf
;
577 h
->frame_control
= host_to_le16(0x0208);
578 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
579 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
580 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
581 pos
= (u8
*) (h
+ 1);
582 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
584 os_memcpy(pos
, eapol
, sizeof(*eapol
));
585 pos
+= sizeof(*eapol
);
586 os_memcpy(pos
, hdr
, sizeof(*hdr
));
587 k
= (struct wpa_eapol_key
*) pos
;
588 WPA_PUT_BE16(k
->key_info
,
589 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
590 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
591 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
592 decrypted
, plain_len
);
595 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
596 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
597 os_free(decrypted_buf
);
602 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
603 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
604 add_note(wt
, MSG_INFO
,
605 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
606 "Beacon/Probe Response from " MACSTR
,
607 MAC2STR(bss
->bssid
));
608 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
609 ie
.wpa_ie
, ie
.wpa_ie_len
);
610 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
613 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
617 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
618 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
619 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
620 "3/4 and Beacon/Probe Response from " MACSTR
,
621 MAC2STR(bss
->bssid
));
622 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
623 ie
.rsn_ie
, ie
.rsn_ie_len
);
624 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
627 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
630 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
631 os_free(decrypted_buf
);
635 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
636 const u8
*src
, const u8
*data
, size_t len
)
638 struct wlantest_bss
*bss
;
639 struct wlantest_sta
*sta
;
640 const struct ieee802_1x_hdr
*eapol
;
641 const struct wpa_eapol_key
*hdr
;
645 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
646 MAC2STR(src
), MAC2STR(dst
));
647 bss
= bss_get(wt
, dst
);
650 sta
= sta_get(bss
, src
);
654 eapol
= (const struct ieee802_1x_hdr
*) data
;
655 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
656 if (!is_zero(hdr
->key_rsc
, 8)) {
657 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
658 "non-zero Key RSC", MAC2STR(src
));
660 key_info
= WPA_GET_BE16(hdr
->key_info
);
662 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
663 add_note(wt
, MSG_DEBUG
,
664 "No PTK known to process EAPOL-Key 4/4");
670 add_note(wt
, MSG_DEBUG
,
671 "Use TPTK for validation EAPOL-Key MIC");
674 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
675 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
678 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
680 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
681 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
684 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
685 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
690 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
691 const u8
*src
, const u8
*data
, size_t len
)
693 struct wlantest_bss
*bss
;
694 struct wlantest_sta
*sta
;
695 const struct ieee802_1x_hdr
*eapol
;
696 const struct wpa_eapol_key
*hdr
;
699 size_t decrypted_len
= 0;
701 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
702 MAC2STR(src
), MAC2STR(dst
));
703 bss
= bss_get(wt
, src
);
706 sta
= sta_get(bss
, dst
);
710 eapol
= (const struct ieee802_1x_hdr
*) data
;
711 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
712 key_info
= WPA_GET_BE16(hdr
->key_info
);
715 add_note(wt
, MSG_DEBUG
,
716 "No PTK known to process EAPOL-Key 1/2");
721 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
723 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
726 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
728 if (sta
->proto
& WPA_PROTO_RSN
&&
729 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
730 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
733 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
734 decrypted
= decrypt_eapol_key_data(wt
, sta
->ptk
.kek
, ver
, hdr
,
736 if (decrypted
== NULL
) {
737 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
740 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
741 decrypted
, decrypted_len
);
742 if (wt
->write_pcap_dumper
) {
743 /* Fill in a dummy Data frame header */
744 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
745 struct ieee80211_hdr
*h
;
746 struct wpa_eapol_key
*k
;
750 plain_len
= decrypted_len
;
752 while (pos
+ 1 < decrypted
+ decrypted_len
) {
753 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
755 plain_len
= pos
- decrypted
;
761 os_memset(buf
, 0, sizeof(buf
));
762 h
= (struct ieee80211_hdr
*) buf
;
763 h
->frame_control
= host_to_le16(0x0208);
764 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
765 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
766 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
767 pos
= (u8
*) (h
+ 1);
768 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
770 os_memcpy(pos
, eapol
, sizeof(*eapol
));
771 pos
+= sizeof(*eapol
);
772 os_memcpy(pos
, hdr
, sizeof(*hdr
));
773 k
= (struct wpa_eapol_key
*) pos
;
774 WPA_PUT_BE16(k
->key_info
,
775 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
776 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
777 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
778 decrypted
, plain_len
);
780 if (sta
->proto
& WPA_PROTO_RSN
)
781 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
784 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
785 if (decrypted_len
== klen
) {
786 const u8
*rsc
= hdr
->key_rsc
;
788 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
789 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
790 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
791 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
793 bss
->gtk_len
[id
] = decrypted_len
;
794 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
795 bss
->rsc
[id
][0] = rsc
[5];
796 bss
->rsc
[id
][1] = rsc
[4];
797 bss
->rsc
[id
][2] = rsc
[3];
798 bss
->rsc
[id
][3] = rsc
[2];
799 bss
->rsc
[id
][4] = rsc
[1];
800 bss
->rsc
[id
][5] = rsc
[0];
801 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
803 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
804 "in Group Key msg 1/2 from " MACSTR
,
812 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
813 const u8
*src
, const u8
*data
, size_t len
)
815 struct wlantest_bss
*bss
;
816 struct wlantest_sta
*sta
;
817 const struct ieee802_1x_hdr
*eapol
;
818 const struct wpa_eapol_key
*hdr
;
821 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
822 MAC2STR(src
), MAC2STR(dst
));
823 bss
= bss_get(wt
, dst
);
826 sta
= sta_get(bss
, src
);
830 eapol
= (const struct ieee802_1x_hdr
*) data
;
831 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
832 if (!is_zero(hdr
->key_rsc
, 8)) {
833 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
834 "non-zero Key RSC", MAC2STR(src
));
836 key_info
= WPA_GET_BE16(hdr
->key_info
);
839 add_note(wt
, MSG_DEBUG
,
840 "No PTK known to process EAPOL-Key 2/2");
845 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
847 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
850 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
854 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*dst
,
855 const u8
*src
, const u8
*data
, size_t len
,
858 const struct ieee802_1x_hdr
*eapol
;
859 const struct wpa_eapol_key
*hdr
;
861 u16 key_info
, key_length
, ver
, key_data_length
;
863 eapol
= (const struct ieee802_1x_hdr
*) data
;
864 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
866 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
867 (const u8
*) hdr
, len
- sizeof(*eapol
));
868 if (len
< sizeof(*hdr
)) {
869 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
874 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
875 /* TODO: EAPOL-Key RC4 for WEP */
876 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
877 MACSTR
, MAC2STR(src
));
881 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
882 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
883 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
884 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
888 key_info
= WPA_GET_BE16(hdr
->key_info
);
889 key_length
= WPA_GET_BE16(hdr
->key_length
);
890 key_data_length
= WPA_GET_BE16(hdr
->key_data_length
);
891 key_data
= (const u8
*) (hdr
+ 1);
892 if (key_data
+ key_data_length
> data
+ len
) {
893 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
897 if (key_data
+ key_data_length
< data
+ len
) {
898 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
899 "field", key_data
+ key_data_length
,
900 data
+ len
- key_data
- key_data_length
);
904 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
905 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
907 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
908 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
909 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
910 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
911 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
912 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
913 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
914 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
915 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
916 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
917 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
920 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
921 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
922 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
&&
923 ver
!= WPA_KEY_INFO_TYPE_AKM_DEFINED
) {
924 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
925 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
929 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
930 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
931 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
932 hdr
->key_nonce
, WPA_NONCE_LEN
);
933 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
935 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
936 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
937 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
939 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
940 key_data
, key_data_length
);
942 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
943 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
945 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
946 "Key Info bits 0x%x from " MACSTR
,
947 key_info
, MAC2STR(src
));
950 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
951 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
952 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
953 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
954 "Key Info bits 0x%x from " MACSTR
,
955 key_info
, MAC2STR(src
));
958 if (key_length
> 32) {
959 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
960 "from " MACSTR
, key_length
, MAC2STR(src
));
963 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
964 !is_zero(hdr
->key_iv
, 16)) {
965 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
966 "(reserved with ver=%d) field from " MACSTR
,
968 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
972 if (!is_zero(hdr
->key_id
, 8)) {
973 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
974 "(reserved) field from " MACSTR
, MAC2STR(src
));
975 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
979 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
980 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
981 "(last two are unused)" MACSTR
, MAC2STR(src
));
984 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
987 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
990 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
991 /* 4-Way Handshake */
992 switch (key_info
& (WPA_KEY_INFO_SECURE
|
995 WPA_KEY_INFO_INSTALL
)) {
996 case WPA_KEY_INFO_ACK
:
997 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
999 case WPA_KEY_INFO_MIC
:
1000 if (key_data_length
== 0)
1001 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1004 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1007 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1008 WPA_KEY_INFO_INSTALL
:
1009 /* WPA does not include Secure bit in 3/4 */
1010 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1012 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1013 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1014 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1016 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1017 if (key_data_length
== 0)
1018 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1021 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1025 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1029 /* Group Key Handshake */
1030 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1032 WPA_KEY_INFO_ACK
)) {
1033 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1035 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1037 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1038 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1041 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1048 void rx_data_eapol(struct wlantest
*wt
, const u8
*dst
, const u8
*src
,
1049 const u8
*data
, size_t len
, int prot
)
1051 const struct ieee802_1x_hdr
*hdr
;
1055 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1056 if (len
< sizeof(*hdr
)) {
1057 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1062 hdr
= (const struct ieee802_1x_hdr
*) data
;
1063 length
= be_to_host16(hdr
->length
);
1064 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1066 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1067 hdr
->version
, hdr
->type
, length
);
1068 if (hdr
->version
< 1 || hdr
->version
> 3) {
1069 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1070 MACSTR
, hdr
->version
, MAC2STR(src
));
1072 if (sizeof(*hdr
) + length
> len
) {
1073 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1078 if (sizeof(*hdr
) + length
< len
) {
1079 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1080 (int) (len
- sizeof(*hdr
) - length
));
1082 p
= (const u8
*) (hdr
+ 1);
1084 switch (hdr
->type
) {
1085 case IEEE802_1X_TYPE_EAP_PACKET
:
1086 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1088 case IEEE802_1X_TYPE_EAPOL_START
:
1089 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1091 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1092 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1094 case IEEE802_1X_TYPE_EAPOL_KEY
:
1095 rx_data_eapol_key(wt
, dst
, src
, data
, sizeof(*hdr
) + length
,
1098 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1099 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1103 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);