2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010-2015, 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
, size_t kck_len
, int akmp
, int ver
,
35 const u8
*data
, size_t len
)
39 struct ieee802_1x_hdr
*hdr
;
40 struct wpa_eapol_key
*key
;
41 u8 rx_mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
42 size_t mic_len
= wpa_mic_len(akmp
);
47 os_memcpy(buf
, data
, len
);
48 hdr
= (struct ieee802_1x_hdr
*) buf
;
49 key
= (struct wpa_eapol_key
*) (hdr
+ 1);
51 os_memcpy(rx_mic
, key
+ 1, mic_len
);
52 os_memset(key
+ 1, 0, mic_len
);
54 if (wpa_eapol_key_mic(kck
, kck_len
, akmp
, ver
, buf
, len
,
55 (u8
*) (key
+ 1)) == 0 &&
56 os_memcmp(rx_mic
, key
+ 1, mic_len
) == 0)
65 static void rx_data_eapol_key_1_of_4(struct wlantest
*wt
, const u8
*dst
,
66 const u8
*src
, const u8
*data
, size_t len
)
68 struct wlantest_bss
*bss
;
69 struct wlantest_sta
*sta
;
70 const struct ieee802_1x_hdr
*eapol
;
71 const struct wpa_eapol_key
*hdr
;
73 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/4 " MACSTR
" -> " MACSTR
,
74 MAC2STR(src
), MAC2STR(dst
));
75 bss
= bss_get(wt
, src
);
78 sta
= sta_get(bss
, dst
);
82 eapol
= (const struct ieee802_1x_hdr
*) data
;
83 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
84 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
85 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
86 " used zero nonce", MAC2STR(src
));
88 if (!is_zero(hdr
->key_rsc
, 8)) {
89 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
90 " used non-zero Key RSC", MAC2STR(src
));
92 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
96 static int try_pmk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
97 struct wlantest_sta
*sta
, u16 ver
,
98 const u8
*data
, size_t len
,
99 struct wlantest_pmk
*pmk
)
103 if (wpa_key_mgmt_ft(sta
->key_mgmt
)) {
105 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
107 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
108 u8 ptk_name
[WPA_PMK_NAME_LEN
];
110 wpa_derive_pmk_r0(pmk
->pmk
, sizeof(pmk
->pmk
),
111 bss
->ssid
, bss
->ssid_len
, bss
->mdid
,
112 bss
->r0kh_id
, bss
->r0kh_id_len
,
113 sta
->addr
, pmk_r0
, pmk_r0_name
);
114 wpa_hexdump(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, PMK_LEN
);
115 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
,
117 wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, bss
->r1kh_id
,
118 sta
->addr
, pmk_r1
, pmk_r1_name
);
119 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
120 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
,
122 if (wpa_pmk_r1_to_ptk(pmk_r1
, sta
->snonce
, sta
->anonce
,
124 bss
->bssid
, pmk_r1_name
, &ptk
, ptk_name
,
126 sta
->pairwise_cipher
) < 0 ||
127 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
130 } else if (wpa_pmk_to_ptk(pmk
->pmk
, sizeof(pmk
->pmk
),
131 "Pairwise key expansion",
132 bss
->bssid
, sta
->addr
, sta
->anonce
,
133 sta
->snonce
, &ptk
, sta
->key_mgmt
,
134 sta
->pairwise_cipher
) < 0 ||
135 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
140 sta
->tk_len
= wpa_cipher_key_len(sta
->pairwise_cipher
);
141 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
142 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
143 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
146 * Rekeying - use new PTK for EAPOL-Key frames, but continue
147 * using the old PTK for frame decryption.
149 add_note(wt
, MSG_DEBUG
, "Derived PTK during rekeying");
150 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
151 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK",
152 sta
->tptk
.kck
, sta
->tptk
.kck_len
);
153 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK",
154 sta
->tptk
.kek
, sta
->tptk
.kek_len
);
155 wpa_hexdump(MSG_DEBUG
, "TPTK:TK",
156 sta
->tptk
.tk
, sta
->tptk
.tk_len
);
160 add_note(wt
, MSG_DEBUG
, "Derived new PTK");
161 os_memcpy(&sta
->ptk
, &ptk
, sizeof(ptk
));
162 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, sta
->ptk
.kck_len
);
163 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, sta
->ptk
.kek_len
);
164 wpa_hexdump(MSG_DEBUG
, "PTK:TK", sta
->ptk
.tk
, sta
->ptk
.tk_len
);
166 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
167 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
172 static void derive_ptk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
173 struct wlantest_sta
*sta
, u16 ver
,
174 const u8
*data
, size_t len
)
176 struct wlantest_pmk
*pmk
;
178 wpa_printf(MSG_DEBUG
, "Trying to derive PTK for " MACSTR
" (ver %u)",
179 MAC2STR(sta
->addr
), ver
);
180 dl_list_for_each(pmk
, &bss
->pmk
, struct wlantest_pmk
, list
) {
181 wpa_printf(MSG_DEBUG
, "Try per-BSS PMK");
182 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
186 dl_list_for_each(pmk
, &wt
->pmk
, struct wlantest_pmk
, list
) {
187 wpa_printf(MSG_DEBUG
, "Try global PMK");
188 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
193 struct wlantest_ptk
*ptk
;
194 int prev_level
= wpa_debug_level
;
196 wpa_debug_level
= MSG_WARNING
;
197 dl_list_for_each(ptk
, &wt
->ptk
, struct wlantest_ptk
, list
) {
198 if (check_mic(ptk
->ptk
.kck
, ptk
->ptk
.kck_len
,
199 sta
->key_mgmt
, ver
, data
, len
) < 0)
201 wpa_printf(MSG_INFO
, "Pre-set PTK matches for STA "
202 MACSTR
" BSSID " MACSTR
,
203 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
204 add_note(wt
, MSG_DEBUG
, "Using pre-set PTK");
206 wpa_cipher_key_len(sta
->pairwise_cipher
);
207 os_memcpy(&sta
->ptk
, &ptk
->ptk
, sizeof(ptk
->ptk
));
208 wpa_hexdump(MSG_DEBUG
, "PTK:KCK",
209 sta
->ptk
.kck
, sta
->ptk
.kck_len
);
210 wpa_hexdump(MSG_DEBUG
, "PTK:KEK",
211 sta
->ptk
.kek
, sta
->ptk
.kek_len
);
212 wpa_hexdump(MSG_DEBUG
, "PTK:TK",
213 sta
->ptk
.tk
, sta
->ptk
.tk_len
);
215 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
216 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
218 wpa_debug_level
= prev_level
;
221 add_note(wt
, MSG_DEBUG
, "No matching PMK found to derive PTK");
225 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
226 const u8
*src
, const u8
*data
, size_t len
)
228 struct wlantest_bss
*bss
;
229 struct wlantest_sta
*sta
;
230 const struct ieee802_1x_hdr
*eapol
;
231 const struct wpa_eapol_key
*hdr
;
232 const u8
*key_data
, *kck
, *mic
;
233 size_t kck_len
, mic_len
;
234 u16 key_info
, key_data_len
;
235 struct wpa_eapol_ie_parse ie
;
237 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
238 MAC2STR(src
), MAC2STR(dst
));
239 bss
= bss_get(wt
, dst
);
242 sta
= sta_get(bss
, src
);
246 eapol
= (const struct ieee802_1x_hdr
*) data
;
247 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
248 mic_len
= wpa_mic_len(sta
->key_mgmt
);
249 mic
= (const u8
*) (hdr
+ 1);
250 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
251 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
252 " used zero nonce", MAC2STR(src
));
254 if (!is_zero(hdr
->key_rsc
, 8)) {
255 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
256 " used non-zero Key RSC", MAC2STR(src
));
258 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
259 key_info
= WPA_GET_BE16(hdr
->key_info
);
260 key_data_len
= WPA_GET_BE16(mic
+ mic_len
);
261 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
263 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
264 add_note(wt
, MSG_DEBUG
,
265 "No PTK known to process EAPOL-Key 2/4");
270 kck_len
= sta
->ptk
.kck_len
;
272 add_note(wt
, MSG_DEBUG
,
273 "Use TPTK for validation EAPOL-Key MIC");
275 kck_len
= sta
->tptk
.kck_len
;
277 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
278 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
279 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
282 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
284 key_data
= mic
+ mic_len
+ 2;
286 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
287 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
292 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
293 ie
.wpa_ie
, ie
.wpa_ie_len
);
294 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
295 struct ieee802_11_elems elems
;
296 add_note(wt
, MSG_INFO
,
297 "Mismatch in WPA IE between EAPOL-Key 2/4 "
298 "and (Re)Association Request from " MACSTR
,
300 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
301 ie
.wpa_ie
, ie
.wpa_ie_len
);
302 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
305 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
307 * The sniffer may have missed (Re)Association
308 * Request, so try to survive with the information from
311 os_memset(&elems
, 0, sizeof(elems
));
312 elems
.wpa_ie
= ie
.wpa_ie
+ 2;
313 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
314 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
315 "IE in EAPOL-Key 2/4");
316 sta_update_assoc(sta
, &elems
);
321 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
322 ie
.rsn_ie
, ie
.rsn_ie_len
);
323 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
324 struct ieee802_11_elems elems
;
325 add_note(wt
, MSG_INFO
,
326 "Mismatch in RSN IE between EAPOL-Key 2/4 "
327 "and (Re)Association Request from " MACSTR
,
329 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
330 ie
.rsn_ie
, ie
.rsn_ie_len
);
331 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
334 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
336 * The sniffer may have missed (Re)Association
337 * Request, so try to survive with the information from
340 os_memset(&elems
, 0, sizeof(elems
));
341 elems
.rsn_ie
= ie
.rsn_ie
+ 2;
342 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
343 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
344 "IE in EAPOL-Key 2/4");
345 sta_update_assoc(sta
, &elems
);
351 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
352 const struct wpa_eapol_key
*hdr
,
353 const u8
*keydata
, u16 keydatalen
,
358 buf
= os_malloc(keydatalen
);
362 os_memcpy(ek
, hdr
->key_iv
, 16);
363 os_memcpy(ek
+ 16, kek
, 16);
364 os_memcpy(buf
, keydata
, keydatalen
);
365 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
366 add_note(wt
, MSG_INFO
, "RC4 failed");
376 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
377 const struct wpa_eapol_key
*hdr
,
378 const u8
*keydata
, u16 keydatalen
,
383 if (keydatalen
% 8) {
384 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
388 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
389 buf
= os_malloc(keydatalen
);
392 if (aes_unwrap(kek
, 16, keydatalen
/ 8, keydata
, buf
)) {
394 add_note(wt
, MSG_INFO
,
395 "AES unwrap failed - could not decrypt EAPOL-Key "
405 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, int akmp
, const u8
*kek
,
406 size_t kek_len
, u16 ver
,
407 const struct wpa_eapol_key
*hdr
,
412 const u8
*mic
, *keydata
;
417 mic
= (const u8
*) (hdr
+ 1);
418 mic_len
= wpa_mic_len(akmp
);
419 keydata
= mic
+ mic_len
+ 2;
420 keydatalen
= WPA_GET_BE16(mic
+ mic_len
);
423 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
424 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, keydata
,
426 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
427 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
428 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
430 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
431 /* For now, assume this is OSEN */
432 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
435 add_note(wt
, MSG_INFO
,
436 "Unsupported EAPOL-Key Key Descriptor Version %u",
443 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
444 struct wlantest_sta
*sta
,
445 const u8
*buf
, size_t len
, const u8
*rsc
)
447 struct wpa_eapol_ie_parse ie
;
449 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
450 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
455 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
456 ie
.wpa_ie
, ie
.wpa_ie_len
);
460 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
461 ie
.rsn_ie
, ie
.rsn_ie_len
);
465 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
467 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
469 id
= ie
.gtk
[0] & 0x03;
470 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
471 id
, !!(ie
.gtk
[0] & 0x04));
472 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
473 add_note(wt
, MSG_INFO
,
474 "GTK KDE: Reserved field set: "
475 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
477 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
479 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
480 sta
->gtk_len
= ie
.gtk_len
- 2;
481 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
482 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
483 bss
->rsc
[id
][0] = rsc
[5];
484 bss
->rsc
[id
][1] = rsc
[4];
485 bss
->rsc
[id
][2] = rsc
[3];
486 bss
->rsc
[id
][3] = rsc
[2];
487 bss
->rsc
[id
][4] = rsc
[1];
488 bss
->rsc
[id
][5] = rsc
[0];
491 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
493 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
494 (unsigned) ie
.gtk_len
);
499 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
500 ie
.igtk
, ie
.igtk_len
);
501 if (ie
.igtk_len
== 24) {
503 id
= WPA_GET_LE16(ie
.igtk
);
505 add_note(wt
, MSG_INFO
,
506 "Unexpected IGTK KeyID %u", id
);
509 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
510 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
511 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
513 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
514 bss
->igtk_len
[id
] = 16;
516 bss
->ipn
[id
][0] = ipn
[5];
517 bss
->ipn
[id
][1] = ipn
[4];
518 bss
->ipn
[id
][2] = ipn
[3];
519 bss
->ipn
[id
][3] = ipn
[2];
520 bss
->ipn
[id
][4] = ipn
[1];
521 bss
->ipn
[id
][5] = ipn
[0];
524 } else if (ie
.igtk_len
== 40) {
526 id
= WPA_GET_LE16(ie
.igtk
);
528 add_note(wt
, MSG_INFO
,
529 "Unexpected IGTK KeyID %u", id
);
532 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
533 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
534 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
536 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 32);
537 bss
->igtk_len
[id
] = 32;
539 bss
->ipn
[id
][0] = ipn
[5];
540 bss
->ipn
[id
][1] = ipn
[4];
541 bss
->ipn
[id
][2] = ipn
[3];
542 bss
->ipn
[id
][3] = ipn
[2];
543 bss
->ipn
[id
][4] = ipn
[1];
544 bss
->ipn
[id
][5] = ipn
[0];
548 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
549 (unsigned) ie
.igtk_len
);
555 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
556 const u8
*src
, const u8
*data
, size_t len
)
558 struct wlantest_bss
*bss
;
559 struct wlantest_sta
*sta
;
560 const struct ieee802_1x_hdr
*eapol
;
561 const struct wpa_eapol_key
*hdr
;
562 const u8
*key_data
, *kck
, *kek
, *mic
;
563 size_t kck_len
, kek_len
, mic_len
;
566 u8
*decrypted_buf
= NULL
;
568 size_t decrypted_len
= 0;
569 struct wpa_eapol_ie_parse ie
;
571 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
572 MAC2STR(src
), MAC2STR(dst
));
573 bss
= bss_get(wt
, src
);
576 sta
= sta_get(bss
, dst
);
579 mic_len
= wpa_mic_len(sta
->key_mgmt
);
581 eapol
= (const struct ieee802_1x_hdr
*) data
;
582 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
583 mic
= (const u8
*) (hdr
+ 1);
584 key_info
= WPA_GET_BE16(hdr
->key_info
);
586 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
587 add_note(wt
, MSG_INFO
,
588 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
591 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
593 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
597 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
598 add_note(wt
, MSG_DEBUG
,
599 "No PTK known to process EAPOL-Key 3/4");
604 kek_len
= sta
->ptk
.kek_len
;
606 kck_len
= sta
->ptk
.kck_len
;
608 add_note(wt
, MSG_DEBUG
,
609 "Use TPTK for validation EAPOL-Key MIC");
611 kck_len
= sta
->tptk
.kck_len
;
613 kek_len
= sta
->tptk
.kek_len
;
615 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
616 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
617 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
620 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
622 key_data
= mic
+ mic_len
+ 2;
623 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
624 if (sta
->proto
& WPA_PROTO_RSN
)
625 add_note(wt
, MSG_INFO
,
626 "EAPOL-Key 3/4 without EncrKeyData bit");
627 decrypted
= key_data
;
628 decrypted_len
= WPA_GET_BE16(mic
+ mic_len
);
630 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
631 decrypted_buf
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
633 hdr
, &decrypted_len
);
634 if (decrypted_buf
== NULL
) {
635 add_note(wt
, MSG_INFO
,
636 "Failed to decrypt EAPOL-Key Key Data");
639 decrypted
= decrypted_buf
;
640 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
641 decrypted
, decrypted_len
);
643 if (wt
->write_pcap_dumper
&& decrypted
!= key_data
) {
644 /* Fill in a dummy Data frame header */
645 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
646 struct ieee80211_hdr
*h
;
647 struct wpa_eapol_key
*k
;
652 plain_len
= decrypted_len
;
654 while (p
+ 1 < decrypted
+ decrypted_len
) {
655 if (p
[0] == 0xdd && p
[1] == 0x00) {
657 plain_len
= p
- decrypted
;
663 os_memset(buf
, 0, sizeof(buf
));
664 h
= (struct ieee80211_hdr
*) buf
;
665 h
->frame_control
= host_to_le16(0x0208);
666 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
667 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
668 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
669 pos
= (u8
*) (h
+ 1);
670 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
672 os_memcpy(pos
, eapol
, sizeof(*eapol
));
673 pos
+= sizeof(*eapol
);
674 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
675 k
= (struct wpa_eapol_key
*) pos
;
676 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
677 WPA_PUT_BE16(k
->key_info
,
678 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
679 WPA_PUT_BE16(pos
, plain_len
);
680 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
681 decrypted
, plain_len
);
684 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
685 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
686 os_free(decrypted_buf
);
691 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
692 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
693 add_note(wt
, MSG_INFO
,
694 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
695 "Beacon/Probe Response from " MACSTR
,
696 MAC2STR(bss
->bssid
));
697 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
698 ie
.wpa_ie
, ie
.wpa_ie_len
);
699 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
702 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
706 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
707 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
708 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
709 "3/4 and Beacon/Probe Response from " MACSTR
,
710 MAC2STR(bss
->bssid
));
711 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
712 ie
.rsn_ie
, ie
.rsn_ie_len
);
713 wpa_hexdump(MSG_INFO
, "RSN IE in Beacon/Probe Response",
715 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
718 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
719 os_free(decrypted_buf
);
723 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
724 const u8
*src
, const u8
*data
, size_t len
)
726 struct wlantest_bss
*bss
;
727 struct wlantest_sta
*sta
;
728 const struct ieee802_1x_hdr
*eapol
;
729 const struct wpa_eapol_key
*hdr
;
734 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
735 MAC2STR(src
), MAC2STR(dst
));
736 bss
= bss_get(wt
, dst
);
739 sta
= sta_get(bss
, src
);
743 eapol
= (const struct ieee802_1x_hdr
*) data
;
744 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
745 if (!is_zero(hdr
->key_rsc
, 8)) {
746 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
747 "non-zero Key RSC", MAC2STR(src
));
749 key_info
= WPA_GET_BE16(hdr
->key_info
);
751 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
752 add_note(wt
, MSG_DEBUG
,
753 "No PTK known to process EAPOL-Key 4/4");
758 kck_len
= sta
->ptk
.kck_len
;
760 add_note(wt
, MSG_DEBUG
,
761 "Use TPTK for validation EAPOL-Key MIC");
763 kck_len
= sta
->tptk
.kck_len
;
765 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
766 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
767 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
770 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
772 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
773 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
776 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
777 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
782 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
783 const u8
*src
, const u8
*data
, size_t len
)
785 struct wlantest_bss
*bss
;
786 struct wlantest_sta
*sta
;
787 const struct ieee802_1x_hdr
*eapol
;
788 const struct wpa_eapol_key
*hdr
;
791 size_t decrypted_len
= 0;
794 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
795 MAC2STR(src
), MAC2STR(dst
));
796 bss
= bss_get(wt
, src
);
799 sta
= sta_get(bss
, dst
);
802 mic_len
= wpa_mic_len(sta
->key_mgmt
);
804 eapol
= (const struct ieee802_1x_hdr
*) data
;
805 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
806 key_info
= WPA_GET_BE16(hdr
->key_info
);
809 add_note(wt
, MSG_DEBUG
,
810 "No PTK known to process EAPOL-Key 1/2");
815 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
816 key_info
& WPA_KEY_INFO_TYPE_MASK
,
818 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
821 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
823 if (sta
->proto
& WPA_PROTO_RSN
&&
824 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
825 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
828 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
829 decrypted
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
830 sta
->ptk
.kek
, sta
->ptk
.kek_len
,
831 ver
, hdr
, &decrypted_len
);
832 if (decrypted
== NULL
) {
833 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
836 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
837 decrypted
, decrypted_len
);
838 if (wt
->write_pcap_dumper
) {
839 /* Fill in a dummy Data frame header */
840 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
)];
841 struct ieee80211_hdr
*h
;
842 struct wpa_eapol_key
*k
;
846 plain_len
= decrypted_len
;
848 while (pos
+ 1 < decrypted
+ decrypted_len
) {
849 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
851 plain_len
= pos
- decrypted
;
857 os_memset(buf
, 0, sizeof(buf
));
858 h
= (struct ieee80211_hdr
*) buf
;
859 h
->frame_control
= host_to_le16(0x0208);
860 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
861 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
862 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
863 pos
= (u8
*) (h
+ 1);
864 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
866 os_memcpy(pos
, eapol
, sizeof(*eapol
));
867 pos
+= sizeof(*eapol
);
868 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
869 k
= (struct wpa_eapol_key
*) pos
;
870 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
871 WPA_PUT_BE16(k
->key_info
,
872 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
873 WPA_PUT_BE16(pos
, plain_len
);
874 write_pcap_decrypted(wt
, buf
, sizeof(buf
),
875 decrypted
, plain_len
);
877 if (sta
->proto
& WPA_PROTO_RSN
)
878 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
881 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
882 if (decrypted_len
== klen
) {
883 const u8
*rsc
= hdr
->key_rsc
;
885 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
886 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
887 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
888 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
890 bss
->gtk_len
[id
] = decrypted_len
;
891 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
892 bss
->rsc
[id
][0] = rsc
[5];
893 bss
->rsc
[id
][1] = rsc
[4];
894 bss
->rsc
[id
][2] = rsc
[3];
895 bss
->rsc
[id
][3] = rsc
[2];
896 bss
->rsc
[id
][4] = rsc
[1];
897 bss
->rsc
[id
][5] = rsc
[0];
898 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
900 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
901 "in Group Key msg 1/2 from " MACSTR
,
909 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
910 const u8
*src
, const u8
*data
, size_t len
)
912 struct wlantest_bss
*bss
;
913 struct wlantest_sta
*sta
;
914 const struct ieee802_1x_hdr
*eapol
;
915 const struct wpa_eapol_key
*hdr
;
918 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
919 MAC2STR(src
), MAC2STR(dst
));
920 bss
= bss_get(wt
, dst
);
923 sta
= sta_get(bss
, src
);
927 eapol
= (const struct ieee802_1x_hdr
*) data
;
928 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
929 if (!is_zero(hdr
->key_rsc
, 8)) {
930 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
931 "non-zero Key RSC", MAC2STR(src
));
933 key_info
= WPA_GET_BE16(hdr
->key_info
);
936 add_note(wt
, MSG_DEBUG
,
937 "No PTK known to process EAPOL-Key 2/2");
942 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
943 key_info
& WPA_KEY_INFO_TYPE_MASK
,
945 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
948 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
952 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*bssid
,
953 const u8
*sta_addr
, const u8
*dst
,
954 const u8
*src
, const u8
*data
, size_t len
,
957 const struct ieee802_1x_hdr
*eapol
;
958 const struct wpa_eapol_key
*hdr
;
960 u16 key_info
, key_length
, ver
, key_data_length
;
963 struct wlantest_bss
*bss
;
964 struct wlantest_sta
*sta
;
966 bss
= bss_get(wt
, bssid
);
968 sta
= sta_get(bss
, sta_addr
);
970 mic_len
= wpa_mic_len(sta
->key_mgmt
);
973 eapol
= (const struct ieee802_1x_hdr
*) data
;
974 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
976 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
977 (const u8
*) hdr
, len
- sizeof(*eapol
));
978 if (len
< sizeof(*hdr
) + mic_len
+ 2) {
979 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
983 mic
= (const u8
*) (hdr
+ 1);
985 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
986 /* TODO: EAPOL-Key RC4 for WEP */
987 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
988 MACSTR
, MAC2STR(src
));
992 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
993 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
994 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
995 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
999 key_info
= WPA_GET_BE16(hdr
->key_info
);
1000 key_length
= WPA_GET_BE16(hdr
->key_length
);
1001 key_data_length
= WPA_GET_BE16(mic
+ mic_len
);
1002 key_data
= mic
+ mic_len
+ 2;
1003 if (key_data
+ key_data_length
> data
+ len
) {
1004 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
1008 if (key_data
+ key_data_length
< data
+ len
) {
1009 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
1010 "field", key_data
+ key_data_length
,
1011 data
+ len
- key_data
- key_data_length
);
1015 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
1016 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
1018 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
1019 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
1020 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
1021 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
1022 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
1023 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
1024 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
1025 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
1026 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
1027 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
1028 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
1031 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1032 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
1033 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
&&
1034 ver
!= WPA_KEY_INFO_TYPE_AKM_DEFINED
) {
1035 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
1036 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
1040 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
1041 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
1042 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
1043 hdr
->key_nonce
, WPA_NONCE_LEN
);
1044 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
1046 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
1047 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
1048 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
1050 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
1051 key_data
, key_data_length
);
1053 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
1054 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
1056 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
1057 "Key Info bits 0x%x from " MACSTR
,
1058 key_info
, MAC2STR(src
));
1061 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
1062 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
1063 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
1064 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
1065 "Key Info bits 0x%x from " MACSTR
,
1066 key_info
, MAC2STR(src
));
1069 if (key_length
> 32) {
1070 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
1071 "from " MACSTR
, key_length
, MAC2STR(src
));
1074 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1075 !is_zero(hdr
->key_iv
, 16)) {
1076 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
1077 "(reserved with ver=%d) field from " MACSTR
,
1079 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
1083 if (!is_zero(hdr
->key_id
, 8)) {
1084 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
1085 "(reserved) field from " MACSTR
, MAC2STR(src
));
1086 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
1090 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
1091 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
1092 "(last two are unused)" MACSTR
, MAC2STR(src
));
1095 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
1098 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
1101 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
1102 /* 4-Way Handshake */
1103 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1106 WPA_KEY_INFO_INSTALL
)) {
1107 case WPA_KEY_INFO_ACK
:
1108 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
1110 case WPA_KEY_INFO_MIC
:
1111 if (key_data_length
== 0)
1112 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1115 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1118 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1119 WPA_KEY_INFO_INSTALL
:
1120 /* WPA does not include Secure bit in 3/4 */
1121 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1123 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1124 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1125 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1127 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1128 if (key_data_length
== 0)
1129 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1132 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1136 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1140 /* Group Key Handshake */
1141 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1143 WPA_KEY_INFO_ACK
)) {
1144 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1146 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1148 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1149 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1152 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1159 void rx_data_eapol(struct wlantest
*wt
, const u8
*bssid
, const u8
*sta_addr
,
1160 const u8
*dst
, const u8
*src
,
1161 const u8
*data
, size_t len
, int prot
)
1163 const struct ieee802_1x_hdr
*hdr
;
1167 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1168 if (len
< sizeof(*hdr
)) {
1169 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1174 hdr
= (const struct ieee802_1x_hdr
*) data
;
1175 length
= be_to_host16(hdr
->length
);
1176 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1178 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1179 hdr
->version
, hdr
->type
, length
);
1180 if (hdr
->version
< 1 || hdr
->version
> 3) {
1181 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1182 MACSTR
, hdr
->version
, MAC2STR(src
));
1184 if (sizeof(*hdr
) + length
> len
) {
1185 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1190 if (sizeof(*hdr
) + length
< len
) {
1191 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1192 (int) (len
- sizeof(*hdr
) - length
));
1194 p
= (const u8
*) (hdr
+ 1);
1196 switch (hdr
->type
) {
1197 case IEEE802_1X_TYPE_EAP_PACKET
:
1198 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1200 case IEEE802_1X_TYPE_EAPOL_START
:
1201 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1203 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1204 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1206 case IEEE802_1X_TYPE_EAPOL_KEY
:
1207 rx_data_eapol_key(wt
, bssid
, sta_addr
, dst
, src
, data
,
1208 sizeof(*hdr
) + length
, prot
);
1210 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1211 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1215 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);