2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "crypto/aes_wrap.h"
19 #include "crypto/crypto.h"
20 #include "common/defs.h"
21 #include "common/ieee802_11_defs.h"
22 #include "common/eapol_common.h"
23 #include "common/wpa_common.h"
24 #include "rsn_supp/wpa_ie.h"
28 static int is_zero(const u8
*buf
, size_t len
)
31 for (i
= 0; i
< len
; i
++) {
39 static int check_mic(const u8
*kck
, int ver
, const u8
*data
, size_t len
)
43 struct ieee802_1x_hdr
*hdr
;
44 struct wpa_eapol_key
*key
;
50 os_memcpy(buf
, data
, len
);
51 hdr
= (struct ieee802_1x_hdr
*) buf
;
52 key
= (struct wpa_eapol_key
*) (hdr
+ 1);
54 os_memcpy(rx_mic
, key
->key_mic
, 16);
55 os_memset(key
->key_mic
, 0, 16);
57 if (wpa_eapol_key_mic(kck
, ver
, buf
, len
, key
->key_mic
) == 0 &&
58 os_memcmp(rx_mic
, key
->key_mic
, 16) == 0)
67 static void rx_data_eapol_key_1_of_4(struct wlantest
*wt
, const u8
*dst
,
68 const u8
*src
, const u8
*data
, size_t len
)
70 struct wlantest_bss
*bss
;
71 struct wlantest_sta
*sta
;
72 const struct ieee802_1x_hdr
*eapol
;
73 const struct wpa_eapol_key
*hdr
;
75 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/4 " MACSTR
" -> " MACSTR
,
76 MAC2STR(src
), MAC2STR(dst
));
77 bss
= bss_get(wt
, src
);
80 sta
= sta_get(bss
, dst
);
84 eapol
= (const struct ieee802_1x_hdr
*) data
;
85 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
86 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
87 wpa_printf(MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
" used "
88 "zero nonce", MAC2STR(src
));
90 if (!is_zero(hdr
->key_rsc
, 8)) {
91 wpa_printf(MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
" used "
92 "non-zero Key RSC", MAC2STR(src
));
94 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
98 static int try_pmk(struct wlantest_bss
*bss
, struct wlantest_sta
*sta
,
99 u16 ver
, const u8
*data
, size_t len
,
100 struct wlantest_pmk
*pmk
)
103 size_t ptk_len
= sta
->pairwise_cipher
== WPA_CIPHER_TKIP
? 64 : 48;
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
, ver
, data
, len
) < 0)
112 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
113 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
114 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
117 * Rekeying - use new PTK for EAPOL-Key frames, but continue
118 * using the old PTK for frame decryption.
120 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
121 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK", sta
->tptk
.kck
, 16);
122 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK", sta
->tptk
.kek
, 16);
123 wpa_hexdump(MSG_DEBUG
, "TPTK:TK1", sta
->tptk
.tk1
, 16);
125 wpa_hexdump(MSG_DEBUG
, "TPTK:TK2", sta
->tptk
.u
.tk2
,
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(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(bss
, sta
, ver
, data
, len
, pmk
) == 0)
162 wpa_printf(MSG_DEBUG
, "No matching PMK found to derive PTK");
166 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
167 const u8
*src
, const u8
*data
, size_t len
)
169 struct wlantest_bss
*bss
;
170 struct wlantest_sta
*sta
;
171 const struct ieee802_1x_hdr
*eapol
;
172 const struct wpa_eapol_key
*hdr
;
173 const u8
*key_data
, *kck
;
174 u16 key_info
, key_data_len
;
175 struct wpa_eapol_ie_parse ie
;
177 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
178 MAC2STR(src
), MAC2STR(dst
));
179 bss
= bss_get(wt
, dst
);
182 sta
= sta_get(bss
, src
);
186 eapol
= (const struct ieee802_1x_hdr
*) data
;
187 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
188 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
189 wpa_printf(MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
" used "
190 "zero nonce", MAC2STR(src
));
192 if (!is_zero(hdr
->key_rsc
, 8)) {
193 wpa_printf(MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
" used "
194 "non-zero Key RSC", MAC2STR(src
));
196 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
197 key_info
= WPA_GET_BE16(hdr
->key_info
);
198 key_data_len
= WPA_GET_BE16(hdr
->key_data_length
);
199 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
201 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
202 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 2/4");
208 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
211 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
212 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
215 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
217 key_data
= (const u8
*) (hdr
+ 1);
219 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
220 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
225 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
226 ie
.wpa_ie
, ie
.wpa_ie_len
);
227 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
228 wpa_printf(MSG_INFO
, "Mismatch in WPA IE between "
229 "EAPOL-Key 2/4 and (Re)Association "
230 "Request from " MACSTR
, MAC2STR(sta
->addr
));
231 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
232 ie
.wpa_ie
, ie
.wpa_ie_len
);
233 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
236 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
241 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
242 ie
.rsn_ie
, ie
.rsn_ie_len
);
243 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
244 wpa_printf(MSG_INFO
, "Mismatch in RSN IE between "
245 "EAPOL-Key 2/4 and (Re)Association "
246 "Request from " MACSTR
, MAC2STR(sta
->addr
));
247 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
248 ie
.rsn_ie
, ie
.rsn_ie_len
);
249 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
252 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
258 static u8
* decrypt_eapol_key_data_rc4(const u8
*kek
,
259 const struct wpa_eapol_key
*hdr
,
263 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
265 buf
= os_malloc(keydatalen
);
269 os_memcpy(ek
, hdr
->key_iv
, 16);
270 os_memcpy(ek
+ 16, kek
, 16);
271 os_memcpy(buf
, hdr
+ 1, keydatalen
);
272 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
273 wpa_printf(MSG_INFO
, "RC4 failed");
283 static u8
* decrypt_eapol_key_data_aes(const u8
*kek
,
284 const struct wpa_eapol_key
*hdr
,
288 u16 keydatalen
= WPA_GET_BE16(hdr
->key_data_length
);
290 if (keydatalen
% 8) {
291 wpa_printf(MSG_INFO
, "Unsupported AES-WRAP len %d",
295 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
296 buf
= os_malloc(keydatalen
);
299 if (aes_unwrap(kek
, keydatalen
/ 8, (u8
*) (hdr
+ 1), buf
)) {
301 wpa_printf(MSG_INFO
, "AES unwrap failed - "
302 "could not decrypt EAPOL-Key key data");
311 static u8
* decrypt_eapol_key_data(const u8
*kek
, u16 ver
,
312 const struct wpa_eapol_key
*hdr
,
316 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
317 return decrypt_eapol_key_data_rc4(kek
, hdr
, len
);
318 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
319 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
320 return decrypt_eapol_key_data_aes(kek
, hdr
, len
);
322 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
329 static void learn_kde_keys(struct wlantest_bss
*bss
, const u8
*buf
, size_t len
,
332 struct wpa_eapol_ie_parse ie
;
334 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
335 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
340 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
341 ie
.wpa_ie
, ie
.wpa_ie_len
);
345 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
346 ie
.rsn_ie
, ie
.rsn_ie_len
);
350 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
352 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
354 id
= ie
.gtk
[0] & 0x03;
355 wpa_printf(MSG_DEBUG
, "GTK KeyID=%u tx=%u",
356 id
, !!(ie
.gtk
[0] & 0x04));
357 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1])
358 wpa_printf(MSG_INFO
, "GTK KDE: Reserved field "
360 ie
.gtk
[0], ie
.gtk
[1]);
361 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
363 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
364 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
365 bss
->rsc
[id
][0] = rsc
[5];
366 bss
->rsc
[id
][1] = rsc
[4];
367 bss
->rsc
[id
][2] = rsc
[3];
368 bss
->rsc
[id
][3] = rsc
[2];
369 bss
->rsc
[id
][4] = rsc
[1];
370 bss
->rsc
[id
][5] = rsc
[0];
372 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
374 wpa_printf(MSG_INFO
, "Invalid GTK KDE length %u",
375 (unsigned) ie
.gtk_len
);
380 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
381 ie
.igtk
, ie
.igtk_len
);
382 if (ie
.igtk_len
== 24) {
384 id
= WPA_GET_LE16(ie
.igtk
);
386 wpa_printf(MSG_INFO
, "Unexpected IGTK KeyID "
390 wpa_printf(MSG_DEBUG
, "IGTK KeyID %u", id
);
391 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
392 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
394 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
395 bss
->igtk_set
[id
] = 1;
397 bss
->ipn
[id
][0] = ipn
[5];
398 bss
->ipn
[id
][1] = ipn
[4];
399 bss
->ipn
[id
][2] = ipn
[3];
400 bss
->ipn
[id
][3] = ipn
[2];
401 bss
->ipn
[id
][4] = ipn
[1];
402 bss
->ipn
[id
][5] = ipn
[0];
406 wpa_printf(MSG_INFO
, "Invalid IGTK KDE length %u",
407 (unsigned) ie
.igtk_len
);
413 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
414 const u8
*src
, const u8
*data
, size_t len
)
416 struct wlantest_bss
*bss
;
417 struct wlantest_sta
*sta
;
418 const struct ieee802_1x_hdr
*eapol
;
419 const struct wpa_eapol_key
*hdr
;
420 const u8
*key_data
, *kck
;
423 u8
*decrypted_buf
= NULL
;
425 size_t decrypted_len
= 0;
426 struct wpa_eapol_ie_parse ie
;
428 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
429 MAC2STR(src
), MAC2STR(dst
));
430 bss
= bss_get(wt
, src
);
433 sta
= sta_get(bss
, dst
);
437 eapol
= (const struct ieee802_1x_hdr
*) data
;
438 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
439 key_info
= WPA_GET_BE16(hdr
->key_info
);
441 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
442 wpa_printf(MSG_INFO
, "EAPOL-Key ANonce mismatch between 1/4 "
446 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
448 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
452 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
453 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 3/4");
459 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
462 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
463 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
466 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
468 key_data
= (const u8
*) (hdr
+ 1);
469 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
470 if (sta
->proto
& WPA_PROTO_RSN
)
471 wpa_printf(MSG_INFO
, "EAPOL-Key 3/4 without "
473 decrypted
= key_data
;
474 decrypted_len
= WPA_GET_BE16(hdr
->key_data_length
);
476 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
477 decrypted_buf
= decrypt_eapol_key_data(sta
->ptk
.kek
, ver
, hdr
,
479 if (decrypted_buf
== NULL
) {
480 wpa_printf(MSG_INFO
, "Failed to decrypt EAPOL-Key Key "
484 decrypted
= decrypted_buf
;
485 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
486 decrypted
, decrypted_len
);
488 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
489 /* Fill in a dummy Data frame header */
490 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
491 struct ieee80211_hdr
*h
;
492 struct wpa_eapol_key
*k
;
497 plain_len
= decrypted_len
;
499 while (p
+ 1 < decrypted
+ decrypted_len
) {
500 if (p
[0] == 0xdd && p
[1] == 0x00) {
502 plain_len
= p
- decrypted
;
508 os_memset(buf
, 0, sizeof(buf
));
509 h
= (struct ieee80211_hdr
*) buf
;
510 h
->frame_control
= host_to_le16(0x0208);
511 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
512 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
513 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
514 pos
= (u8
*) (h
+ 1);
515 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
517 os_memcpy(pos
, eapol
, sizeof(*eapol
));
518 pos
+= sizeof(*eapol
);
519 os_memcpy(pos
, hdr
, sizeof(*hdr
));
520 k
= (struct wpa_eapol_key
*) pos
;
521 WPA_PUT_BE16(k
->key_info
,
522 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
523 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
524 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
525 decrypted
, plain_len
);
528 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
529 wpa_printf(MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
530 os_free(decrypted_buf
);
535 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
536 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
537 wpa_printf(MSG_INFO
, "Mismatch in WPA IE between "
538 "EAPOL-Key 3/4 and Beacon/Probe Response "
539 "from " MACSTR
, MAC2STR(bss
->bssid
));
540 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
541 ie
.wpa_ie
, ie
.wpa_ie_len
);
542 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
545 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
549 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
550 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
551 wpa_printf(MSG_INFO
, "Mismatch in RSN IE between "
552 "EAPOL-Key 3/4 and Beacon/Probe Response "
553 "from " MACSTR
, MAC2STR(bss
->bssid
));
554 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
555 ie
.rsn_ie
, ie
.rsn_ie_len
);
556 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
559 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
562 learn_kde_keys(bss
, decrypted
, decrypted_len
, hdr
->key_rsc
);
563 os_free(decrypted_buf
);
567 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
568 const u8
*src
, const u8
*data
, size_t len
)
570 struct wlantest_bss
*bss
;
571 struct wlantest_sta
*sta
;
572 const struct ieee802_1x_hdr
*eapol
;
573 const struct wpa_eapol_key
*hdr
;
577 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
578 MAC2STR(src
), MAC2STR(dst
));
579 bss
= bss_get(wt
, dst
);
582 sta
= sta_get(bss
, src
);
586 eapol
= (const struct ieee802_1x_hdr
*) data
;
587 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
588 if (!is_zero(hdr
->key_rsc
, 8)) {
589 wpa_printf(MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
590 "non-zero Key RSC", MAC2STR(src
));
592 key_info
= WPA_GET_BE16(hdr
->key_info
);
594 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
595 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 4/4");
601 wpa_printf(MSG_DEBUG
, "Use TPTK for validation EAPOL-Key MIC");
604 if (check_mic(kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
605 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
608 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
610 wpa_printf(MSG_DEBUG
, "Update PTK (rekeying)");
611 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
614 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
615 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
620 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
621 const u8
*src
, const u8
*data
, size_t len
)
623 struct wlantest_bss
*bss
;
624 struct wlantest_sta
*sta
;
625 const struct ieee802_1x_hdr
*eapol
;
626 const struct wpa_eapol_key
*hdr
;
630 size_t decrypted_len
= 0;
632 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
633 MAC2STR(src
), MAC2STR(dst
));
634 bss
= bss_get(wt
, src
);
637 sta
= sta_get(bss
, dst
);
641 eapol
= (const struct ieee802_1x_hdr
*) data
;
642 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
643 key_info
= WPA_GET_BE16(hdr
->key_info
);
646 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 1/2");
651 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
653 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
656 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
658 key_data
= (const u8
*) (hdr
+ 1);
659 if (sta
->proto
& WPA_PROTO_RSN
&&
660 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
661 wpa_printf(MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
664 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
665 decrypted
= decrypt_eapol_key_data(sta
->ptk
.kek
, ver
, hdr
,
667 if (decrypted
== NULL
) {
668 wpa_printf(MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
671 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
672 decrypted
, decrypted_len
);
673 if (wt
->write_pcap_dumper
) {
674 /* Fill in a dummy Data frame header */
675 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
676 struct ieee80211_hdr
*h
;
677 struct wpa_eapol_key
*k
;
681 plain_len
= decrypted_len
;
683 while (pos
+ 1 < decrypted
+ decrypted_len
) {
684 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
686 plain_len
= pos
- decrypted
;
692 os_memset(buf
, 0, sizeof(buf
));
693 h
= (struct ieee80211_hdr
*) buf
;
694 h
->frame_control
= host_to_le16(0x0208);
695 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
696 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
697 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
698 pos
= (u8
*) (h
+ 1);
699 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
701 os_memcpy(pos
, eapol
, sizeof(*eapol
));
702 pos
+= sizeof(*eapol
);
703 os_memcpy(pos
, hdr
, sizeof(*hdr
));
704 k
= (struct wpa_eapol_key
*) pos
;
705 WPA_PUT_BE16(k
->key_info
,
706 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
707 WPA_PUT_BE16(k
->key_data_length
, plain_len
);
708 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
709 decrypted
, plain_len
);
711 if (sta
->proto
& WPA_PROTO_RSN
)
712 learn_kde_keys(bss
, decrypted
, decrypted_len
, hdr
->key_rsc
);
714 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
715 if (decrypted_len
== klen
) {
716 const u8
*rsc
= hdr
->key_rsc
;
718 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
719 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
720 wpa_printf(MSG_DEBUG
, "GTK key index %d", id
);
721 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
723 bss
->gtk_len
[id
] = decrypted_len
;
724 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
725 bss
->rsc
[id
][0] = rsc
[5];
726 bss
->rsc
[id
][1] = rsc
[4];
727 bss
->rsc
[id
][2] = rsc
[3];
728 bss
->rsc
[id
][3] = rsc
[2];
729 bss
->rsc
[id
][4] = rsc
[1];
730 bss
->rsc
[id
][5] = rsc
[0];
731 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
733 wpa_printf(MSG_INFO
, "Unexpected WPA Key Data length "
734 "in Group Key msg 1/2 from " MACSTR
,
742 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
743 const u8
*src
, const u8
*data
, size_t len
)
745 struct wlantest_bss
*bss
;
746 struct wlantest_sta
*sta
;
747 const struct ieee802_1x_hdr
*eapol
;
748 const struct wpa_eapol_key
*hdr
;
751 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
752 MAC2STR(src
), MAC2STR(dst
));
753 bss
= bss_get(wt
, dst
);
756 sta
= sta_get(bss
, src
);
760 eapol
= (const struct ieee802_1x_hdr
*) data
;
761 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
762 if (!is_zero(hdr
->key_rsc
, 8)) {
763 wpa_printf(MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
764 "non-zero Key RSC", MAC2STR(src
));
766 key_info
= WPA_GET_BE16(hdr
->key_info
);
769 wpa_printf(MSG_DEBUG
, "No PTK known to process EAPOL-Key 2/2");
774 check_mic(sta
->ptk
.kck
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
776 wpa_printf(MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
779 wpa_printf(MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
783 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*dst
,
784 const u8
*src
, const u8
*data
, size_t len
,
787 const struct ieee802_1x_hdr
*eapol
;
788 const struct wpa_eapol_key
*hdr
;
790 u16 key_info
, key_length
, ver
, key_data_length
;
792 eapol
= (const struct ieee802_1x_hdr
*) data
;
793 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
795 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
796 (const u8
*) hdr
, len
- sizeof(*eapol
));
797 if (len
< sizeof(*hdr
)) {
798 wpa_printf(MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
803 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
804 /* TODO: EAPOL-Key RC4 for WEP */
805 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
806 MACSTR
, MAC2STR(src
));
810 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
811 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
812 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
813 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
817 key_info
= WPA_GET_BE16(hdr
->key_info
);
818 key_length
= WPA_GET_BE16(hdr
->key_length
);
819 key_data_length
= WPA_GET_BE16(hdr
->key_data_length
);
820 key_data
= (const u8
*) (hdr
+ 1);
821 if (key_data
+ key_data_length
> data
+ len
) {
822 wpa_printf(MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
826 if (key_data
+ key_data_length
< data
+ len
) {
827 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
828 "field", key_data
+ key_data_length
,
829 data
+ len
- key_data
- key_data_length
);
833 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
834 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
836 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
837 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
838 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
839 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
840 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
841 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
842 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
843 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
844 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
845 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
846 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
849 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
850 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
851 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
) {
852 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
853 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
857 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
858 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
859 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
860 hdr
->key_nonce
, WPA_NONCE_LEN
);
861 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
863 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
864 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
865 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
867 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
868 key_data
, key_data_length
);
870 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
871 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
873 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
874 "Key Info bits 0x%x from " MACSTR
,
875 key_info
, MAC2STR(src
));
878 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
879 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
880 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
881 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
882 "Key Info bits 0x%x from " MACSTR
,
883 key_info
, MAC2STR(src
));
886 if (key_length
> 32) {
887 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
888 "from " MACSTR
, key_length
, MAC2STR(src
));
891 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
892 !is_zero(hdr
->key_iv
, 16)) {
893 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
894 "(reserved with ver=%d) field from " MACSTR
,
896 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
900 if (!is_zero(hdr
->key_id
, 8)) {
901 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
902 "(reserved) field from " MACSTR
, MAC2STR(src
));
903 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
907 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
908 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
909 "(last two are unused)" MACSTR
, MAC2STR(src
));
912 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
915 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
918 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
919 /* 4-Way Handshake */
920 switch (key_info
& (WPA_KEY_INFO_SECURE
|
923 WPA_KEY_INFO_INSTALL
)) {
924 case WPA_KEY_INFO_ACK
:
925 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
927 case WPA_KEY_INFO_MIC
:
928 if (key_data_length
== 0)
929 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
932 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
935 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
936 WPA_KEY_INFO_INSTALL
:
937 /* WPA does not include Secure bit in 3/4 */
938 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
940 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
941 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
942 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
944 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
945 if (key_data_length
== 0)
946 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
949 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
953 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
957 /* Group Key Handshake */
958 switch (key_info
& (WPA_KEY_INFO_SECURE
|
961 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
963 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
965 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
966 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
969 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
976 void rx_data_eapol(struct wlantest
*wt
, const u8
*dst
, const u8
*src
,
977 const u8
*data
, size_t len
, int prot
)
979 const struct ieee802_1x_hdr
*hdr
;
983 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
984 if (len
< sizeof(*hdr
)) {
985 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
990 hdr
= (const struct ieee802_1x_hdr
*) data
;
991 length
= be_to_host16(hdr
->length
);
992 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
994 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
995 hdr
->version
, hdr
->type
, length
);
996 if (hdr
->version
< 1 || hdr
->version
> 3) {
997 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
998 MACSTR
, hdr
->version
, MAC2STR(src
));
1000 if (sizeof(*hdr
) + length
> len
) {
1001 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1006 if (sizeof(*hdr
) + length
< len
) {
1007 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1008 (int) (len
- sizeof(*hdr
) - length
));
1010 p
= (const u8
*) (hdr
+ 1);
1012 switch (hdr
->type
) {
1013 case IEEE802_1X_TYPE_EAP_PACKET
:
1014 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1016 case IEEE802_1X_TYPE_EAPOL_START
:
1017 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1019 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1020 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1022 case IEEE802_1X_TYPE_EAPOL_KEY
:
1023 rx_data_eapol_key(wt
, dst
, src
, data
, sizeof(*hdr
) + length
,
1026 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1027 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1031 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);