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 akmp
, int ver
, const u8
*data
,
39 struct ieee802_1x_hdr
*hdr
;
40 struct wpa_eapol_key
*key
;
46 os_memcpy(buf
, data
, len
);
47 hdr
= (struct ieee802_1x_hdr
*) buf
;
48 key
= (struct wpa_eapol_key
*) (hdr
+ 1);
50 os_memcpy(rx_mic
, key
->key_mic
, 16);
51 os_memset(key
->key_mic
, 0, 16);
53 if (wpa_eapol_key_mic(kck
, akmp
, ver
, buf
, len
, key
->key_mic
) == 0 &&
54 os_memcmp(rx_mic
, key
->key_mic
, 16) == 0)
63 static void rx_data_eapol_key_1_of_4(struct wlantest
*wt
, const u8
*dst
,
64 const u8
*src
, const u8
*data
, size_t len
)
66 struct wlantest_bss
*bss
;
67 struct wlantest_sta
*sta
;
68 const struct ieee802_1x_hdr
*eapol
;
69 const struct wpa_eapol_key
*hdr
;
71 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/4 " MACSTR
" -> " MACSTR
,
72 MAC2STR(src
), MAC2STR(dst
));
73 bss
= bss_get(wt
, src
);
76 sta
= sta_get(bss
, dst
);
80 eapol
= (const struct ieee802_1x_hdr
*) data
;
81 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
82 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
83 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
84 " used zero nonce", MAC2STR(src
));
86 if (!is_zero(hdr
->key_rsc
, 8)) {
87 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
88 " used non-zero Key RSC", MAC2STR(src
));
90 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
94 static int try_pmk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
95 struct wlantest_sta
*sta
, u16 ver
,
96 const u8
*data
, size_t len
,
97 struct wlantest_pmk
*pmk
)
102 ptk_len
= wpa_cipher_key_len(sta
->pairwise_cipher
) + 32;
104 wpa_pmk_to_ptk(pmk
->pmk
, sizeof(pmk
->pmk
),
105 "Pairwise key expansion",
106 bss
->bssid
, sta
->addr
, sta
->anonce
, sta
->snonce
,
107 (u8
*) &ptk
, ptk_len
,
108 wpa_key_mgmt_sha256(sta
->key_mgmt
));
109 if (check_mic(ptk
.kck
, sta
->key_mgmt
, ver
, data
, len
) < 0)
112 sta
->tk_len
= wpa_cipher_key_len(sta
->pairwise_cipher
);
113 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
114 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
115 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
118 * Rekeying - use new PTK for EAPOL-Key frames, but continue
119 * using the old PTK for frame decryption.
121 add_note(wt
, MSG_DEBUG
, "Derived PTK during rekeying");
122 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
123 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK", sta
->tptk
.kck
, 16);
124 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK", sta
->tptk
.kek
, 16);
125 wpa_hexdump(MSG_DEBUG
, "TPTK:TK1", sta
->tptk
.tk1
, 16);
127 wpa_hexdump(MSG_DEBUG
, "TPTK:TK2", sta
->tptk
.u
.tk2
,
132 add_note(wt
, MSG_DEBUG
, "Derived new PTK");
133 os_memcpy(&sta
->ptk
, &ptk
, sizeof(ptk
));
134 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
135 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
136 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
138 wpa_hexdump(MSG_DEBUG
, "PTK:TK2", sta
->ptk
.u
.tk2
, 16);
140 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
141 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
146 static void derive_ptk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
147 struct wlantest_sta
*sta
, u16 ver
,
148 const u8
*data
, size_t len
)
150 struct wlantest_pmk
*pmk
;
152 wpa_printf(MSG_DEBUG
, "Trying to derive PTK for " MACSTR
" (ver %u)",
153 MAC2STR(sta
->addr
), ver
);
154 dl_list_for_each(pmk
, &bss
->pmk
, struct wlantest_pmk
, list
) {
155 wpa_printf(MSG_DEBUG
, "Try per-BSS PMK");
156 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
160 dl_list_for_each(pmk
, &wt
->pmk
, struct wlantest_pmk
, list
) {
161 wpa_printf(MSG_DEBUG
, "Try global PMK");
162 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
167 struct wlantest_ptk
*ptk
;
168 int prev_level
= wpa_debug_level
;
170 wpa_debug_level
= MSG_WARNING
;
171 dl_list_for_each(ptk
, &wt
->ptk
, struct wlantest_ptk
, list
) {
172 if (check_mic(ptk
->ptk
.kck
, sta
->key_mgmt
, ver
, data
,
175 wpa_printf(MSG_INFO
, "Pre-set PTK matches for STA "
176 MACSTR
" BSSID " MACSTR
,
177 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
178 add_note(wt
, MSG_DEBUG
, "Using pre-set PTK");
180 wpa_cipher_key_len(sta
->pairwise_cipher
);
181 os_memcpy(&sta
->ptk
, &ptk
->ptk
, sizeof(ptk
->ptk
));
182 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
183 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
184 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
185 if (ptk
->ptk_len
> 48)
186 wpa_hexdump(MSG_DEBUG
, "PTK:TK2",
189 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
190 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
192 wpa_debug_level
= prev_level
;
195 add_note(wt
, MSG_DEBUG
, "No matching PMK found to derive PTK");
199 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
200 const u8
*src
, const u8
*data
, size_t len
)
202 struct wlantest_bss
*bss
;
203 struct wlantest_sta
*sta
;
204 const struct ieee802_1x_hdr
*eapol
;
205 const struct wpa_eapol_key
*hdr
;
206 const u8
*key_data
, *kck
;
207 u16 key_info
, key_data_len
;
208 struct wpa_eapol_ie_parse ie
;
210 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
211 MAC2STR(src
), MAC2STR(dst
));
212 bss
= bss_get(wt
, dst
);
215 sta
= sta_get(bss
, src
);
219 eapol
= (const struct ieee802_1x_hdr
*) data
;
220 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
221 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
222 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
223 " used zero nonce", MAC2STR(src
));
225 if (!is_zero(hdr
->key_rsc
, 8)) {
226 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
227 " used non-zero Key RSC", MAC2STR(src
));
229 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
230 key_info
= WPA_GET_BE16(hdr
->key_info
);
231 key_data_len
= WPA_GET_BE16(hdr
->key_data_length
);
232 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
234 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
235 add_note(wt
, MSG_DEBUG
,
236 "No PTK known to process EAPOL-Key 2/4");
242 add_note(wt
, MSG_DEBUG
,
243 "Use TPTK for validation EAPOL-Key MIC");
246 if (check_mic(kck
, sta
->key_mgmt
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
248 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
251 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
253 key_data
= (const u8
*) (hdr
+ 1);
255 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
256 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
261 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
262 ie
.wpa_ie
, ie
.wpa_ie_len
);
263 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
264 struct ieee802_11_elems elems
;
265 add_note(wt
, MSG_INFO
,
266 "Mismatch in WPA IE between EAPOL-Key 2/4 "
267 "and (Re)Association Request from " MACSTR
,
269 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
270 ie
.wpa_ie
, ie
.wpa_ie_len
);
271 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
274 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
276 * The sniffer may have missed (Re)Association
277 * Request, so try to survive with the information from
280 os_memset(&elems
, 0, sizeof(elems
));
281 elems
.wpa_ie
= ie
.wpa_ie
+ 2;
282 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
283 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
284 "IE in EAPOL-Key 2/4");
285 sta_update_assoc(sta
, &elems
);
290 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
291 ie
.rsn_ie
, ie
.rsn_ie_len
);
292 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
293 struct ieee802_11_elems elems
;
294 add_note(wt
, MSG_INFO
,
295 "Mismatch in RSN IE between EAPOL-Key 2/4 "
296 "and (Re)Association Request from " MACSTR
,
298 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
299 ie
.rsn_ie
, ie
.rsn_ie_len
);
300 wpa_hexdump(MSG_INFO
, "RSN 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
.rsn_ie
= ie
.rsn_ie
+ 2;
311 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
312 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
313 "IE in EAPOL-Key 2/4");
314 sta_update_assoc(sta
, &elems
);
320 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
321 const struct wpa_eapol_key
*hdr
,
325 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
327 buf
= os_malloc(keydatalen
);
331 os_memcpy(ek
, hdr
->key_iv
, 16);
332 os_memcpy(ek
+ 16, kek
, 16);
333 os_memcpy(buf
, hdr
+ 1, keydatalen
);
334 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
335 add_note(wt
, MSG_INFO
, "RC4 failed");
345 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
346 const struct wpa_eapol_key
*hdr
,
350 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
352 if (keydatalen
% 8) {
353 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
357 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
358 buf
= os_malloc(keydatalen
);
361 if (aes_unwrap(kek
, 16, keydatalen
/ 8, (u8
*) (hdr
+ 1), buf
)) {
363 add_note(wt
, MSG_INFO
,
364 "AES unwrap failed - could not decrypt EAPOL-Key "
374 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, const u8
*kek
, u16 ver
,
375 const struct wpa_eapol_key
*hdr
,
379 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
380 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, len
);
381 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
382 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
383 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, len
);
384 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
385 /* For now, assume this is OSEN */
386 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, len
);
388 add_note(wt
, MSG_INFO
,
389 "Unsupported EAPOL-Key Key Descriptor Version %u",
396 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
397 struct wlantest_sta
*sta
,
398 const u8
*buf
, size_t len
, const u8
*rsc
)
400 struct wpa_eapol_ie_parse ie
;
402 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
403 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
408 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
409 ie
.wpa_ie
, ie
.wpa_ie_len
);
413 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
414 ie
.rsn_ie
, ie
.rsn_ie_len
);
418 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
420 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
422 id
= ie
.gtk
[0] & 0x03;
423 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
424 id
, !!(ie
.gtk
[0] & 0x04));
425 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
426 add_note(wt
, MSG_INFO
,
427 "GTK KDE: Reserved field set: "
428 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
430 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
432 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
433 sta
->gtk_len
= ie
.gtk_len
- 2;
434 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
435 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
436 bss
->rsc
[id
][0] = rsc
[5];
437 bss
->rsc
[id
][1] = rsc
[4];
438 bss
->rsc
[id
][2] = rsc
[3];
439 bss
->rsc
[id
][3] = rsc
[2];
440 bss
->rsc
[id
][4] = rsc
[1];
441 bss
->rsc
[id
][5] = rsc
[0];
444 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
446 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
447 (unsigned) ie
.gtk_len
);
452 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
453 ie
.igtk
, ie
.igtk_len
);
454 if (ie
.igtk_len
== 24) {
456 id
= WPA_GET_LE16(ie
.igtk
);
458 add_note(wt
, MSG_INFO
,
459 "Unexpected IGTK KeyID %u", id
);
462 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
463 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
464 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
466 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
467 bss
->igtk_len
[id
] = 16;
469 bss
->ipn
[id
][0] = ipn
[5];
470 bss
->ipn
[id
][1] = ipn
[4];
471 bss
->ipn
[id
][2] = ipn
[3];
472 bss
->ipn
[id
][3] = ipn
[2];
473 bss
->ipn
[id
][4] = ipn
[1];
474 bss
->ipn
[id
][5] = ipn
[0];
477 } else if (ie
.igtk_len
== 40) {
479 id
= WPA_GET_LE16(ie
.igtk
);
481 add_note(wt
, MSG_INFO
,
482 "Unexpected IGTK KeyID %u", id
);
485 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
486 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
487 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
489 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 32);
490 bss
->igtk_len
[id
] = 32;
492 bss
->ipn
[id
][0] = ipn
[5];
493 bss
->ipn
[id
][1] = ipn
[4];
494 bss
->ipn
[id
][2] = ipn
[3];
495 bss
->ipn
[id
][3] = ipn
[2];
496 bss
->ipn
[id
][4] = ipn
[1];
497 bss
->ipn
[id
][5] = ipn
[0];
501 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
502 (unsigned) ie
.igtk_len
);
508 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
509 const u8
*src
, const u8
*data
, size_t len
)
511 struct wlantest_bss
*bss
;
512 struct wlantest_sta
*sta
;
513 const struct ieee802_1x_hdr
*eapol
;
514 const struct wpa_eapol_key
*hdr
;
515 const u8
*key_data
, *kck
, *kek
;
518 u8
*decrypted_buf
= NULL
;
520 size_t decrypted_len
= 0;
521 struct wpa_eapol_ie_parse ie
;
523 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
524 MAC2STR(src
), MAC2STR(dst
));
525 bss
= bss_get(wt
, src
);
528 sta
= sta_get(bss
, dst
);
532 eapol
= (const struct ieee802_1x_hdr
*) data
;
533 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
534 key_info
= WPA_GET_BE16(hdr
->key_info
);
536 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
537 add_note(wt
, MSG_INFO
,
538 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
541 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
543 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
547 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
548 add_note(wt
, MSG_DEBUG
,
549 "No PTK known to process EAPOL-Key 3/4");
556 add_note(wt
, MSG_DEBUG
,
557 "Use TPTK for validation EAPOL-Key MIC");
561 if (check_mic(kck
, sta
->key_mgmt
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
563 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
566 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
568 key_data
= (const u8
*) (hdr
+ 1);
569 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
570 if (sta
->proto
& WPA_PROTO_RSN
)
571 add_note(wt
, MSG_INFO
,
572 "EAPOL-Key 3/4 without EncrKeyData bit");
573 decrypted
= key_data
;
574 decrypted_len
= WPA_GET_BE16(hdr
->key_data_length
);
576 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
577 decrypted_buf
= decrypt_eapol_key_data(wt
, kek
, ver
, hdr
,
579 if (decrypted_buf
== NULL
) {
580 add_note(wt
, MSG_INFO
,
581 "Failed to decrypt EAPOL-Key Key Data");
584 decrypted
= decrypted_buf
;
585 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
586 decrypted
, decrypted_len
);
588 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
589 /* Fill in a dummy Data frame header */
590 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
591 struct ieee80211_hdr
*h
;
592 struct wpa_eapol_key
*k
;
597 plain_len
= decrypted_len
;
599 while (p
+ 1 < decrypted
+ decrypted_len
) {
600 if (p
[0] == 0xdd && p
[1] == 0x00) {
602 plain_len
= p
- decrypted
;
608 os_memset(buf
, 0, sizeof(buf
));
609 h
= (struct ieee80211_hdr
*) buf
;
610 h
->frame_control
= host_to_le16(0x0208);
611 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
612 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
613 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
614 pos
= (u8
*) (h
+ 1);
615 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
617 os_memcpy(pos
, eapol
, sizeof(*eapol
));
618 pos
+= sizeof(*eapol
);
619 os_memcpy(pos
, hdr
, sizeof(*hdr
));
620 k
= (struct wpa_eapol_key
*) pos
;
621 WPA_PUT_BE16(k
->key_info
,
622 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
623 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
624 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
625 decrypted
, plain_len
);
628 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
629 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
630 os_free(decrypted_buf
);
635 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
636 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
637 add_note(wt
, MSG_INFO
,
638 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
639 "Beacon/Probe Response from " MACSTR
,
640 MAC2STR(bss
->bssid
));
641 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
642 ie
.wpa_ie
, ie
.wpa_ie_len
);
643 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
646 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
650 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
651 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
652 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
653 "3/4 and Beacon/Probe Response from " MACSTR
,
654 MAC2STR(bss
->bssid
));
655 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
656 ie
.rsn_ie
, ie
.rsn_ie_len
);
657 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
660 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
663 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
664 os_free(decrypted_buf
);
668 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
669 const u8
*src
, const u8
*data
, size_t len
)
671 struct wlantest_bss
*bss
;
672 struct wlantest_sta
*sta
;
673 const struct ieee802_1x_hdr
*eapol
;
674 const struct wpa_eapol_key
*hdr
;
678 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
679 MAC2STR(src
), MAC2STR(dst
));
680 bss
= bss_get(wt
, dst
);
683 sta
= sta_get(bss
, src
);
687 eapol
= (const struct ieee802_1x_hdr
*) data
;
688 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
689 if (!is_zero(hdr
->key_rsc
, 8)) {
690 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
691 "non-zero Key RSC", MAC2STR(src
));
693 key_info
= WPA_GET_BE16(hdr
->key_info
);
695 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
696 add_note(wt
, MSG_DEBUG
,
697 "No PTK known to process EAPOL-Key 4/4");
703 add_note(wt
, MSG_DEBUG
,
704 "Use TPTK for validation EAPOL-Key MIC");
707 if (check_mic(kck
, sta
->key_mgmt
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
709 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
712 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
714 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
715 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
718 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
719 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
724 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
725 const u8
*src
, const u8
*data
, size_t len
)
727 struct wlantest_bss
*bss
;
728 struct wlantest_sta
*sta
;
729 const struct ieee802_1x_hdr
*eapol
;
730 const struct wpa_eapol_key
*hdr
;
733 size_t decrypted_len
= 0;
735 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
736 MAC2STR(src
), MAC2STR(dst
));
737 bss
= bss_get(wt
, src
);
740 sta
= sta_get(bss
, dst
);
744 eapol
= (const struct ieee802_1x_hdr
*) data
;
745 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
746 key_info
= WPA_GET_BE16(hdr
->key_info
);
749 add_note(wt
, MSG_DEBUG
,
750 "No PTK known to process EAPOL-Key 1/2");
755 check_mic(sta
->ptk
.kck
, sta
->key_mgmt
,
756 key_info
& WPA_KEY_INFO_TYPE_MASK
,
758 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
761 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
763 if (sta
->proto
& WPA_PROTO_RSN
&&
764 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
765 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
768 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
769 decrypted
= decrypt_eapol_key_data(wt
, sta
->ptk
.kek
, ver
, hdr
,
771 if (decrypted
== NULL
) {
772 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
775 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
776 decrypted
, decrypted_len
);
777 if (wt
->write_pcap_dumper
) {
778 /* Fill in a dummy Data frame header */
779 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
780 struct ieee80211_hdr
*h
;
781 struct wpa_eapol_key
*k
;
785 plain_len
= decrypted_len
;
787 while (pos
+ 1 < decrypted
+ decrypted_len
) {
788 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
790 plain_len
= pos
- decrypted
;
796 os_memset(buf
, 0, sizeof(buf
));
797 h
= (struct ieee80211_hdr
*) buf
;
798 h
->frame_control
= host_to_le16(0x0208);
799 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
800 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
801 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
802 pos
= (u8
*) (h
+ 1);
803 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
805 os_memcpy(pos
, eapol
, sizeof(*eapol
));
806 pos
+= sizeof(*eapol
);
807 os_memcpy(pos
, hdr
, sizeof(*hdr
));
808 k
= (struct wpa_eapol_key
*) pos
;
809 WPA_PUT_BE16(k
->key_info
,
810 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
811 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
812 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
813 decrypted
, plain_len
);
815 if (sta
->proto
& WPA_PROTO_RSN
)
816 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
819 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
820 if (decrypted_len
== klen
) {
821 const u8
*rsc
= hdr
->key_rsc
;
823 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
824 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
825 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
826 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
828 bss
->gtk_len
[id
] = decrypted_len
;
829 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
830 bss
->rsc
[id
][0] = rsc
[5];
831 bss
->rsc
[id
][1] = rsc
[4];
832 bss
->rsc
[id
][2] = rsc
[3];
833 bss
->rsc
[id
][3] = rsc
[2];
834 bss
->rsc
[id
][4] = rsc
[1];
835 bss
->rsc
[id
][5] = rsc
[0];
836 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
838 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
839 "in Group Key msg 1/2 from " MACSTR
,
847 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
848 const u8
*src
, const u8
*data
, size_t len
)
850 struct wlantest_bss
*bss
;
851 struct wlantest_sta
*sta
;
852 const struct ieee802_1x_hdr
*eapol
;
853 const struct wpa_eapol_key
*hdr
;
856 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
857 MAC2STR(src
), MAC2STR(dst
));
858 bss
= bss_get(wt
, dst
);
861 sta
= sta_get(bss
, src
);
865 eapol
= (const struct ieee802_1x_hdr
*) data
;
866 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
867 if (!is_zero(hdr
->key_rsc
, 8)) {
868 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
869 "non-zero Key RSC", MAC2STR(src
));
871 key_info
= WPA_GET_BE16(hdr
->key_info
);
874 add_note(wt
, MSG_DEBUG
,
875 "No PTK known to process EAPOL-Key 2/2");
880 check_mic(sta
->ptk
.kck
, sta
->key_mgmt
,
881 key_info
& WPA_KEY_INFO_TYPE_MASK
,
883 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
886 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
890 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*dst
,
891 const u8
*src
, const u8
*data
, size_t len
,
894 const struct ieee802_1x_hdr
*eapol
;
895 const struct wpa_eapol_key
*hdr
;
897 u16 key_info
, key_length
, ver
, key_data_length
;
899 eapol
= (const struct ieee802_1x_hdr
*) data
;
900 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
902 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
903 (const u8
*) hdr
, len
- sizeof(*eapol
));
904 if (len
< sizeof(*hdr
)) {
905 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
910 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
911 /* TODO: EAPOL-Key RC4 for WEP */
912 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
913 MACSTR
, MAC2STR(src
));
917 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
918 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
919 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
920 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
924 key_info
= WPA_GET_BE16(hdr
->key_info
);
925 key_length
= WPA_GET_BE16(hdr
->key_length
);
926 key_data_length
= WPA_GET_BE16(hdr
->key_data_length
);
927 key_data
= (const u8
*) (hdr
+ 1);
928 if (key_data
+ key_data_length
> data
+ len
) {
929 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
933 if (key_data
+ key_data_length
< data
+ len
) {
934 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
935 "field", key_data
+ key_data_length
,
936 data
+ len
- key_data
- key_data_length
);
940 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
941 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
943 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
944 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
945 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
946 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
947 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
948 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
949 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
950 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
951 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
952 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
953 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
956 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
957 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
958 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
&&
959 ver
!= WPA_KEY_INFO_TYPE_AKM_DEFINED
) {
960 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
961 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
965 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
966 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
967 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
968 hdr
->key_nonce
, WPA_NONCE_LEN
);
969 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
971 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
972 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
973 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
975 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
976 key_data
, key_data_length
);
978 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
979 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
981 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
982 "Key Info bits 0x%x from " MACSTR
,
983 key_info
, MAC2STR(src
));
986 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
987 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
988 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
989 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
990 "Key Info bits 0x%x from " MACSTR
,
991 key_info
, MAC2STR(src
));
994 if (key_length
> 32) {
995 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
996 "from " MACSTR
, key_length
, MAC2STR(src
));
999 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1000 !is_zero(hdr
->key_iv
, 16)) {
1001 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
1002 "(reserved with ver=%d) field from " MACSTR
,
1004 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
1008 if (!is_zero(hdr
->key_id
, 8)) {
1009 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
1010 "(reserved) field from " MACSTR
, MAC2STR(src
));
1011 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
1015 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
1016 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
1017 "(last two are unused)" MACSTR
, MAC2STR(src
));
1020 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
1023 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
1026 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
1027 /* 4-Way Handshake */
1028 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1031 WPA_KEY_INFO_INSTALL
)) {
1032 case WPA_KEY_INFO_ACK
:
1033 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
1035 case WPA_KEY_INFO_MIC
:
1036 if (key_data_length
== 0)
1037 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1040 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1043 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1044 WPA_KEY_INFO_INSTALL
:
1045 /* WPA does not include Secure bit in 3/4 */
1046 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1048 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1049 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1050 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1052 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1053 if (key_data_length
== 0)
1054 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1057 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1061 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1065 /* Group Key Handshake */
1066 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1068 WPA_KEY_INFO_ACK
)) {
1069 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1071 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1073 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1074 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1077 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1084 void rx_data_eapol(struct wlantest
*wt
, const u8
*dst
, const u8
*src
,
1085 const u8
*data
, size_t len
, int prot
)
1087 const struct ieee802_1x_hdr
*hdr
;
1091 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1092 if (len
< sizeof(*hdr
)) {
1093 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1098 hdr
= (const struct ieee802_1x_hdr
*) data
;
1099 length
= be_to_host16(hdr
->length
);
1100 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1102 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1103 hdr
->version
, hdr
->type
, length
);
1104 if (hdr
->version
< 1 || hdr
->version
> 3) {
1105 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1106 MACSTR
, hdr
->version
, MAC2STR(src
));
1108 if (sizeof(*hdr
) + length
> len
) {
1109 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1114 if (sizeof(*hdr
) + length
< len
) {
1115 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1116 (int) (len
- sizeof(*hdr
) - length
));
1118 p
= (const u8
*) (hdr
+ 1);
1120 switch (hdr
->type
) {
1121 case IEEE802_1X_TYPE_EAP_PACKET
:
1122 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1124 case IEEE802_1X_TYPE_EAPOL_START
:
1125 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1127 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1128 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1130 case IEEE802_1X_TYPE_EAPOL_KEY
:
1131 rx_data_eapol_key(wt
, dst
, src
, data
, sizeof(*hdr
) + length
,
1134 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1135 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1139 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);