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 wpa_printf(MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
" used "
83 "zero nonce", MAC2STR(src
));
85 if (!is_zero(hdr
->key_rsc
, 8)) {
86 wpa_printf(MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
" used "
87 "non-zero Key RSC", MAC2STR(src
));
89 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
93 static int try_pmk(struct wlantest_bss
*bss
, struct wlantest_sta
*sta
,
94 u16 ver
, const u8
*data
, size_t len
,
95 struct wlantest_pmk
*pmk
)
98 size_t ptk_len
= sta
->pairwise_cipher
== WPA_CIPHER_TKIP
? 64 : 48;
99 wpa_pmk_to_ptk(pmk
->pmk
, sizeof(pmk
->pmk
),
100 "Pairwise key expansion",
101 bss
->bssid
, sta
->addr
, sta
->anonce
, sta
->snonce
,
102 (u8
*) &ptk
, ptk_len
,
103 wpa_key_mgmt_sha256(sta
->key_mgmt
));
104 if (check_mic(ptk
.kck
, ver
, data
, len
) < 0)
107 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
108 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
109 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
112 * Rekeying - use new PTK for EAPOL-Key frames, but continue
113 * using the old PTK for frame decryption.
115 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
116 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK", sta
->tptk
.kck
, 16);
117 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK", sta
->tptk
.kek
, 16);
118 wpa_hexdump(MSG_DEBUG
, "TPTK:TK1", sta
->tptk
.tk1
, 16);
120 wpa_hexdump(MSG_DEBUG
, "TPTK:TK2", sta
->tptk
.u
.tk2
,
125 os_memcpy(&sta
->ptk
, &ptk
, sizeof(ptk
));
126 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, 16);
127 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, 16);
128 wpa_hexdump(MSG_DEBUG
, "PTK:TK1", sta
->ptk
.tk1
, 16);
130 wpa_hexdump(MSG_DEBUG
, "PTK:TK2", sta
->ptk
.u
.tk2
, 16);
132 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
133 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
138 static void derive_ptk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
139 struct wlantest_sta
*sta
, u16 ver
,
140 const u8
*data
, size_t len
)
142 struct wlantest_pmk
*pmk
;
144 wpa_printf(MSG_DEBUG
, "Trying to derive PTK for " MACSTR
,
146 dl_list_for_each(pmk
, &bss
->pmk
, struct wlantest_pmk
, list
) {
147 wpa_printf(MSG_DEBUG
, "Try per-BSS PMK");
148 if (try_pmk(bss
, sta
, ver
, data
, len
, pmk
) == 0)
152 dl_list_for_each(pmk
, &wt
->pmk
, struct wlantest_pmk
, list
) {
153 wpa_printf(MSG_DEBUG
, "Try global PMK");
154 if (try_pmk(bss
, sta
, ver
, data
, len
, pmk
) == 0)
157 wpa_printf(MSG_DEBUG
, "No matching PMK found to derive PTK");
161 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
162 const u8
*src
, const u8
*data
, size_t len
)
164 struct wlantest_bss
*bss
;
165 struct wlantest_sta
*sta
;
166 const struct ieee802_1x_hdr
*eapol
;
167 const struct wpa_eapol_key
*hdr
;
168 const u8
*key_data
, *kck
;
169 u16 key_info
, key_data_len
;
170 struct wpa_eapol_ie_parse ie
;
172 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
173 MAC2STR(src
), MAC2STR(dst
));
174 bss
= bss_get(wt
, dst
);
177 sta
= sta_get(bss
, src
);
181 eapol
= (const struct ieee802_1x_hdr
*) data
;
182 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
183 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
184 wpa_printf(MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
" used "
185 "zero nonce", MAC2STR(src
));
187 if (!is_zero(hdr
->key_rsc
, 8)) {
188 wpa_printf(MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
" used "
189 "non-zero Key RSC", MAC2STR(src
));
191 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
192 key_info
= WPA_GET_BE16(hdr
->key_info
);
193 key_data_len
= WPA_GET_BE16(hdr
->key_data_length
);
194 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
196 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
197 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 2/4");
203 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
206 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
207 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
210 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
212 key_data
= (const u8
*) (hdr
+ 1);
214 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
215 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
220 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
221 ie
.wpa_ie
, ie
.wpa_ie_len
);
222 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
223 struct ieee802_11_elems elems
;
224 wpa_printf(MSG_INFO
, "Mismatch in WPA IE between "
225 "EAPOL-Key 2/4 and (Re)Association "
226 "Request from " MACSTR
, MAC2STR(sta
->addr
));
227 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
228 ie
.wpa_ie
, ie
.wpa_ie_len
);
229 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
232 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
234 * The sniffer may have missed (Re)Association
235 * Request, so try to survive with the information from
238 os_memset(&elems
, 0, sizeof(elems
));
239 elems
.wpa_ie
= ie
.wpa_ie
+ 2;
240 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
241 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
242 "IE in EAPOL-Key 2/4");
243 sta_update_assoc(sta
, &elems
);
248 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
249 ie
.rsn_ie
, ie
.rsn_ie_len
);
250 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
251 struct ieee802_11_elems elems
;
252 wpa_printf(MSG_INFO
, "Mismatch in RSN IE between "
253 "EAPOL-Key 2/4 and (Re)Association "
254 "Request from " MACSTR
, MAC2STR(sta
->addr
));
255 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
256 ie
.rsn_ie
, ie
.rsn_ie_len
);
257 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
260 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
262 * The sniffer may have missed (Re)Association
263 * Request, so try to survive with the information from
266 os_memset(&elems
, 0, sizeof(elems
));
267 elems
.rsn_ie
= ie
.rsn_ie
+ 2;
268 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
269 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
270 "IE in EAPOL-Key 2/4");
271 sta_update_assoc(sta
, &elems
);
277 static u8
* decrypt_eapol_key_data_rc4(const u8
*kek
,
278 const struct wpa_eapol_key
*hdr
,
282 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
284 buf
= os_malloc(keydatalen
);
288 os_memcpy(ek
, hdr
->key_iv
, 16);
289 os_memcpy(ek
+ 16, kek
, 16);
290 os_memcpy(buf
, hdr
+ 1, keydatalen
);
291 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
292 wpa_printf(MSG_INFO
, "RC4 failed");
302 static u8
* decrypt_eapol_key_data_aes(const u8
*kek
,
303 const struct wpa_eapol_key
*hdr
,
307 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
309 if (keydatalen
% 8) {
310 wpa_printf(MSG_INFO
, "Unsupported AES-WRAP len %d",
314 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
315 buf
= os_malloc(keydatalen
);
318 if (aes_unwrap(kek
, keydatalen
/ 8, (u8
*) (hdr
+ 1), buf
)) {
320 wpa_printf(MSG_INFO
, "AES unwrap failed - "
321 "could not decrypt EAPOL-Key key data");
330 static u8
* decrypt_eapol_key_data(const u8
*kek
, u16 ver
,
331 const struct wpa_eapol_key
*hdr
,
335 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
336 return decrypt_eapol_key_data_rc4(kek
, hdr
, len
);
337 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
338 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
339 return decrypt_eapol_key_data_aes(kek
, hdr
, len
);
341 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
348 static void learn_kde_keys(struct wlantest_bss
*bss
, struct wlantest_sta
*sta
,
349 const u8
*buf
, size_t len
, const u8
*rsc
)
351 struct wpa_eapol_ie_parse ie
;
353 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
354 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
359 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
360 ie
.wpa_ie
, ie
.wpa_ie_len
);
364 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
365 ie
.rsn_ie
, ie
.rsn_ie_len
);
369 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
371 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
373 id
= ie
.gtk
[0] & 0x03;
374 wpa_printf(MSG_DEBUG
, "GTK KeyID=%u tx=%u",
375 id
, !!(ie
.gtk
[0] & 0x04));
376 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1])
377 wpa_printf(MSG_INFO
, "GTK KDE: Reserved field "
379 ie
.gtk
[0], ie
.gtk
[1]);
380 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
382 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
383 sta
->gtk_len
= ie
.gtk_len
- 2;
384 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
385 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
386 bss
->rsc
[id
][0] = rsc
[5];
387 bss
->rsc
[id
][1] = rsc
[4];
388 bss
->rsc
[id
][2] = rsc
[3];
389 bss
->rsc
[id
][3] = rsc
[2];
390 bss
->rsc
[id
][4] = rsc
[1];
391 bss
->rsc
[id
][5] = rsc
[0];
394 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
396 wpa_printf(MSG_INFO
, "Invalid GTK KDE length %u",
397 (unsigned) ie
.gtk_len
);
402 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
403 ie
.igtk
, ie
.igtk_len
);
404 if (ie
.igtk_len
== 24) {
406 id
= WPA_GET_LE16(ie
.igtk
);
408 wpa_printf(MSG_INFO
, "Unexpected IGTK KeyID "
412 wpa_printf(MSG_DEBUG
, "IGTK KeyID %u", id
);
413 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
414 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
416 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
417 bss
->igtk_set
[id
] = 1;
419 bss
->ipn
[id
][0] = ipn
[5];
420 bss
->ipn
[id
][1] = ipn
[4];
421 bss
->ipn
[id
][2] = ipn
[3];
422 bss
->ipn
[id
][3] = ipn
[2];
423 bss
->ipn
[id
][4] = ipn
[1];
424 bss
->ipn
[id
][5] = ipn
[0];
428 wpa_printf(MSG_INFO
, "Invalid IGTK KDE length %u",
429 (unsigned) ie
.igtk_len
);
435 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
436 const u8
*src
, const u8
*data
, size_t len
)
438 struct wlantest_bss
*bss
;
439 struct wlantest_sta
*sta
;
440 const struct ieee802_1x_hdr
*eapol
;
441 const struct wpa_eapol_key
*hdr
;
442 const u8
*key_data
, *kck
, *kek
;
445 u8
*decrypted_buf
= NULL
;
447 size_t decrypted_len
= 0;
448 struct wpa_eapol_ie_parse ie
;
450 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
451 MAC2STR(src
), MAC2STR(dst
));
452 bss
= bss_get(wt
, src
);
455 sta
= sta_get(bss
, dst
);
459 eapol
= (const struct ieee802_1x_hdr
*) data
;
460 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
461 key_info
= WPA_GET_BE16(hdr
->key_info
);
463 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
464 wpa_printf(MSG_INFO
, "EAPOL-Key ANonce mismatch between 1/4 "
468 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
470 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
474 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
475 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 3/4");
482 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
486 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
487 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
490 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
492 key_data
= (const u8
*) (hdr
+ 1);
493 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
494 if (sta
->proto
& WPA_PROTO_RSN
)
495 wpa_printf(MSG_INFO
, "EAPOL-Key 3/4 without "
497 decrypted
= key_data
;
498 decrypted_len
= WPA_GET_BE16(hdr
->key_data_length
);
500 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
501 decrypted_buf
= decrypt_eapol_key_data(kek
, ver
, hdr
,
503 if (decrypted_buf
== NULL
) {
504 wpa_printf(MSG_INFO
, "Failed to decrypt EAPOL-Key Key "
508 decrypted
= decrypted_buf
;
509 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
510 decrypted
, decrypted_len
);
512 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
513 /* Fill in a dummy Data frame header */
514 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
515 struct ieee80211_hdr
*h
;
516 struct wpa_eapol_key
*k
;
521 plain_len
= decrypted_len
;
523 while (p
+ 1 < decrypted
+ decrypted_len
) {
524 if (p
[0] == 0xdd && p
[1] == 0x00) {
526 plain_len
= p
- decrypted
;
532 os_memset(buf
, 0, sizeof(buf
));
533 h
= (struct ieee80211_hdr
*) buf
;
534 h
->frame_control
= host_to_le16(0x0208);
535 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
536 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
537 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
538 pos
= (u8
*) (h
+ 1);
539 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
541 os_memcpy(pos
, eapol
, sizeof(*eapol
));
542 pos
+= sizeof(*eapol
);
543 os_memcpy(pos
, hdr
, sizeof(*hdr
));
544 k
= (struct wpa_eapol_key
*) pos
;
545 WPA_PUT_BE16(k
->key_info
,
546 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
547 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
548 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
549 decrypted
, plain_len
);
552 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
553 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
554 os_free(decrypted_buf
);
559 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
560 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
561 wpa_printf(MSG_INFO
, "Mismatch in WPA IE between "
562 "EAPOL-Key 3/4 and Beacon/Probe Response "
563 "from " MACSTR
, MAC2STR(bss
->bssid
));
564 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
565 ie
.wpa_ie
, ie
.wpa_ie_len
);
566 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
569 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
573 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
574 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
575 wpa_printf(MSG_INFO
, "Mismatch in RSN IE between "
576 "EAPOL-Key 3/4 and Beacon/Probe Response "
577 "from " MACSTR
, MAC2STR(bss
->bssid
));
578 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
579 ie
.rsn_ie
, ie
.rsn_ie_len
);
580 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
583 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
586 learn_kde_keys(bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
587 os_free(decrypted_buf
);
591 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
592 const u8
*src
, const u8
*data
, size_t len
)
594 struct wlantest_bss
*bss
;
595 struct wlantest_sta
*sta
;
596 const struct ieee802_1x_hdr
*eapol
;
597 const struct wpa_eapol_key
*hdr
;
601 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
602 MAC2STR(src
), MAC2STR(dst
));
603 bss
= bss_get(wt
, dst
);
606 sta
= sta_get(bss
, src
);
610 eapol
= (const struct ieee802_1x_hdr
*) data
;
611 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
612 if (!is_zero(hdr
->key_rsc
, 8)) {
613 wpa_printf(MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
614 "non-zero Key RSC", MAC2STR(src
));
616 key_info
= WPA_GET_BE16(hdr
->key_info
);
618 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
619 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 4/4");
625 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
628 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
629 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
632 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
634 wpa_printf(MSG_DEBUG
, "Update PTK (rekeying)");
635 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
638 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
639 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
644 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
645 const u8
*src
, const u8
*data
, size_t len
)
647 struct wlantest_bss
*bss
;
648 struct wlantest_sta
*sta
;
649 const struct ieee802_1x_hdr
*eapol
;
650 const struct wpa_eapol_key
*hdr
;
653 size_t decrypted_len
= 0;
655 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
656 MAC2STR(src
), MAC2STR(dst
));
657 bss
= bss_get(wt
, src
);
660 sta
= sta_get(bss
, dst
);
664 eapol
= (const struct ieee802_1x_hdr
*) data
;
665 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
666 key_info
= WPA_GET_BE16(hdr
->key_info
);
669 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 1/2");
674 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
676 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
679 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
681 if (sta
->proto
& WPA_PROTO_RSN
&&
682 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
683 wpa_printf(MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
686 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
687 decrypted
= decrypt_eapol_key_data(sta
->ptk
.kek
, ver
, hdr
,
689 if (decrypted
== NULL
) {
690 wpa_printf(MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
693 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
694 decrypted
, decrypted_len
);
695 if (wt
->write_pcap_dumper
) {
696 /* Fill in a dummy Data frame header */
697 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
698 struct ieee80211_hdr
*h
;
699 struct wpa_eapol_key
*k
;
703 plain_len
= decrypted_len
;
705 while (pos
+ 1 < decrypted
+ decrypted_len
) {
706 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
708 plain_len
= pos
- decrypted
;
714 os_memset(buf
, 0, sizeof(buf
));
715 h
= (struct ieee80211_hdr
*) buf
;
716 h
->frame_control
= host_to_le16(0x0208);
717 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
718 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
719 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
720 pos
= (u8
*) (h
+ 1);
721 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
723 os_memcpy(pos
, eapol
, sizeof(*eapol
));
724 pos
+= sizeof(*eapol
);
725 os_memcpy(pos
, hdr
, sizeof(*hdr
));
726 k
= (struct wpa_eapol_key
*) pos
;
727 WPA_PUT_BE16(k
->key_info
,
728 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
729 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
730 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
731 decrypted
, plain_len
);
733 if (sta
->proto
& WPA_PROTO_RSN
)
734 learn_kde_keys(bss
, sta
, decrypted
, decrypted_len
,
737 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
738 if (decrypted_len
== klen
) {
739 const u8
*rsc
= hdr
->key_rsc
;
741 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
742 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
743 wpa_printf(MSG_DEBUG
, "GTK key index %d", id
);
744 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
746 bss
->gtk_len
[id
] = decrypted_len
;
747 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
748 bss
->rsc
[id
][0] = rsc
[5];
749 bss
->rsc
[id
][1] = rsc
[4];
750 bss
->rsc
[id
][2] = rsc
[3];
751 bss
->rsc
[id
][3] = rsc
[2];
752 bss
->rsc
[id
][4] = rsc
[1];
753 bss
->rsc
[id
][5] = rsc
[0];
754 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
756 wpa_printf(MSG_INFO
, "Unexpected WPA Key Data length "
757 "in Group Key msg 1/2 from " MACSTR
,
765 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
766 const u8
*src
, const u8
*data
, size_t len
)
768 struct wlantest_bss
*bss
;
769 struct wlantest_sta
*sta
;
770 const struct ieee802_1x_hdr
*eapol
;
771 const struct wpa_eapol_key
*hdr
;
774 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
775 MAC2STR(src
), MAC2STR(dst
));
776 bss
= bss_get(wt
, dst
);
779 sta
= sta_get(bss
, src
);
783 eapol
= (const struct ieee802_1x_hdr
*) data
;
784 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
785 if (!is_zero(hdr
->key_rsc
, 8)) {
786 wpa_printf(MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
787 "non-zero Key RSC", MAC2STR(src
));
789 key_info
= WPA_GET_BE16(hdr
->key_info
);
792 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 2/2");
797 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
799 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
802 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
806 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*dst
,
807 const u8
*src
, const u8
*data
, size_t len
,
810 const struct ieee802_1x_hdr
*eapol
;
811 const struct wpa_eapol_key
*hdr
;
813 u16 key_info
, key_length
, ver
, key_data_length
;
815 eapol
= (const struct ieee802_1x_hdr
*) data
;
816 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
818 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
819 (const u8
*) hdr
, len
- sizeof(*eapol
));
820 if (len
< sizeof(*hdr
)) {
821 wpa_printf(MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
826 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
827 /* TODO: EAPOL-Key RC4 for WEP */
828 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
829 MACSTR
, MAC2STR(src
));
833 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
834 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
835 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
836 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
840 key_info
= WPA_GET_BE16(hdr
->key_info
);
841 key_length
= WPA_GET_BE16(hdr
->key_length
);
842 key_data_length
= WPA_GET_BE16(hdr
->key_data_length
);
843 key_data
= (const u8
*) (hdr
+ 1);
844 if (key_data
+ key_data_length
> data
+ len
) {
845 wpa_printf(MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
849 if (key_data
+ key_data_length
< data
+ len
) {
850 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
851 "field", key_data
+ key_data_length
,
852 data
+ len
- key_data
- key_data_length
);
856 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
857 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
859 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
860 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
861 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
862 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
863 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
864 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
865 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
866 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
867 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
868 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
869 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
872 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
873 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
874 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
) {
875 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
876 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
880 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
881 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
882 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
883 hdr
->key_nonce
, WPA_NONCE_LEN
);
884 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
886 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
887 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
888 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
890 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
891 key_data
, key_data_length
);
893 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
894 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
896 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
897 "Key Info bits 0x%x from " MACSTR
,
898 key_info
, MAC2STR(src
));
901 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
902 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
903 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
904 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
905 "Key Info bits 0x%x from " MACSTR
,
906 key_info
, MAC2STR(src
));
909 if (key_length
> 32) {
910 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
911 "from " MACSTR
, key_length
, MAC2STR(src
));
914 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
915 !is_zero(hdr
->key_iv
, 16)) {
916 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
917 "(reserved with ver=%d) field from " MACSTR
,
919 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
923 if (!is_zero(hdr
->key_id
, 8)) {
924 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
925 "(reserved) field from " MACSTR
, MAC2STR(src
));
926 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
930 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
931 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
932 "(last two are unused)" MACSTR
, MAC2STR(src
));
935 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
938 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
941 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
942 /* 4-Way Handshake */
943 switch (key_info
& (WPA_KEY_INFO_SECURE
|
946 WPA_KEY_INFO_INSTALL
)) {
947 case WPA_KEY_INFO_ACK
:
948 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
950 case WPA_KEY_INFO_MIC
:
951 if (key_data_length
== 0)
952 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
955 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
958 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
959 WPA_KEY_INFO_INSTALL
:
960 /* WPA does not include Secure bit in 3/4 */
961 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
963 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
964 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
965 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
967 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
968 if (key_data_length
== 0)
969 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
972 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
976 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
980 /* Group Key Handshake */
981 switch (key_info
& (WPA_KEY_INFO_SECURE
|
984 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
986 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
988 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
989 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
992 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
999 void rx_data_eapol(struct wlantest
*wt
, const u8
*dst
, const u8
*src
,
1000 const u8
*data
, size_t len
, int prot
)
1002 const struct ieee802_1x_hdr
*hdr
;
1006 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1007 if (len
< sizeof(*hdr
)) {
1008 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1013 hdr
= (const struct ieee802_1x_hdr
*) data
;
1014 length
= be_to_host16(hdr
->length
);
1015 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1017 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1018 hdr
->version
, hdr
->type
, length
);
1019 if (hdr
->version
< 1 || hdr
->version
> 3) {
1020 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1021 MACSTR
, hdr
->version
, MAC2STR(src
));
1023 if (sizeof(*hdr
) + length
> len
) {
1024 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1029 if (sizeof(*hdr
) + length
< len
) {
1030 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1031 (int) (len
- sizeof(*hdr
) - length
));
1033 p
= (const u8
*) (hdr
+ 1);
1035 switch (hdr
->type
) {
1036 case IEEE802_1X_TYPE_EAP_PACKET
:
1037 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1039 case IEEE802_1X_TYPE_EAPOL_START
:
1040 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1042 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1043 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1045 case IEEE802_1X_TYPE_EAPOL_KEY
:
1046 rx_data_eapol_key(wt
, dst
, src
, data
, sizeof(*hdr
) + length
,
1049 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1050 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1054 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);