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
, PMK_LEN
);
44 buf
= os_memdup(data
, len
);
47 hdr
= (struct ieee802_1x_hdr
*) buf
;
48 key
= (struct wpa_eapol_key
*) (hdr
+ 1);
50 os_memcpy(rx_mic
, key
+ 1, mic_len
);
51 os_memset(key
+ 1, 0, mic_len
);
53 if (wpa_eapol_key_mic(kck
, kck_len
, akmp
, ver
, buf
, len
,
54 (u8
*) (key
+ 1)) == 0 &&
55 os_memcmp(rx_mic
, key
+ 1, mic_len
) == 0)
64 static void rx_data_eapol_key_1_of_4(struct wlantest
*wt
, const u8
*dst
,
65 const u8
*src
, const u8
*data
, size_t len
)
67 struct wlantest_bss
*bss
;
68 struct wlantest_sta
*sta
;
69 const struct ieee802_1x_hdr
*eapol
;
70 const struct wpa_eapol_key
*hdr
;
72 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/4 " MACSTR
" -> " MACSTR
,
73 MAC2STR(src
), MAC2STR(dst
));
74 bss
= bss_get(wt
, src
);
77 sta
= sta_get(bss
, dst
);
81 eapol
= (const struct ieee802_1x_hdr
*) data
;
82 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
83 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
84 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
85 " used zero nonce", MAC2STR(src
));
87 if (!is_zero(hdr
->key_rsc
, 8)) {
88 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/4 from " MACSTR
89 " used non-zero Key RSC", MAC2STR(src
));
91 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
95 static int try_pmk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
96 struct wlantest_sta
*sta
, u16 ver
,
97 const u8
*data
, size_t len
,
98 struct wlantest_pmk
*pmk
)
102 if (wpa_key_mgmt_ft(sta
->key_mgmt
)) {
104 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
105 u8 ptk_name
[WPA_PMK_NAME_LEN
];
107 if (wpa_derive_pmk_r0(pmk
->pmk
, PMK_LEN
,
108 bss
->ssid
, bss
->ssid_len
, bss
->mdid
,
109 bss
->r0kh_id
, bss
->r0kh_id_len
,
110 sta
->addr
, sta
->pmk_r0
, sta
->pmk_r0_name
,
113 wpa_hexdump(MSG_DEBUG
, "FT: PMK-R0", sta
->pmk_r0
, PMK_LEN
);
114 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", sta
->pmk_r0_name
,
116 if (wpa_derive_pmk_r1(sta
->pmk_r0
, PMK_LEN
, sta
->pmk_r0_name
,
117 bss
->r1kh_id
, sta
->addr
,
118 pmk_r1
, pmk_r1_name
) < 0)
120 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
121 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
,
123 if (wpa_pmk_r1_to_ptk(pmk_r1
, PMK_LEN
, sta
->snonce
, sta
->anonce
,
125 bss
->bssid
, pmk_r1_name
, &ptk
, ptk_name
,
127 sta
->pairwise_cipher
) < 0 ||
128 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
131 } else if (wpa_pmk_to_ptk(pmk
->pmk
, PMK_LEN
,
132 "Pairwise key expansion",
133 bss
->bssid
, sta
->addr
, sta
->anonce
,
134 sta
->snonce
, &ptk
, sta
->key_mgmt
,
135 sta
->pairwise_cipher
, NULL
, 0) < 0 ||
136 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
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 elems_from_eapol_ie(struct ieee802_11_elems
*elems
,
226 struct wpa_eapol_ie_parse
*ie
)
228 os_memset(elems
, 0, sizeof(*elems
));
230 elems
->wpa_ie
= ie
->wpa_ie
+ 2;
231 elems
->wpa_ie_len
= ie
->wpa_ie_len
- 2;
234 elems
->rsn_ie
= ie
->rsn_ie
+ 2;
235 elems
->rsn_ie_len
= ie
->rsn_ie_len
- 2;
238 elems
->osen
= ie
->osen
+ 2;
239 elems
->osen_len
= ie
->osen_len
- 2;
244 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
245 const u8
*src
, const u8
*data
, size_t len
)
247 struct wlantest_bss
*bss
;
248 struct wlantest_sta
*sta
;
249 const struct ieee802_1x_hdr
*eapol
;
250 const struct wpa_eapol_key
*hdr
;
251 const u8
*key_data
, *kck
, *mic
;
252 size_t kck_len
, mic_len
;
253 u16 key_info
, key_data_len
;
254 struct wpa_eapol_ie_parse ie
;
256 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
257 MAC2STR(src
), MAC2STR(dst
));
258 bss
= bss_get(wt
, dst
);
261 sta
= sta_get(bss
, src
);
265 eapol
= (const struct ieee802_1x_hdr
*) data
;
266 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
267 mic_len
= wpa_mic_len(sta
->key_mgmt
, PMK_LEN
);
268 mic
= (const u8
*) (hdr
+ 1);
269 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
270 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
271 " used zero nonce", MAC2STR(src
));
273 if (!is_zero(hdr
->key_rsc
, 8)) {
274 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
275 " used non-zero Key RSC", MAC2STR(src
));
277 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
278 key_info
= WPA_GET_BE16(hdr
->key_info
);
279 key_data
= mic
+ mic_len
+ 2;
280 key_data_len
= WPA_GET_BE16(mic
+ mic_len
);
282 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
283 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
287 if (!sta
->assocreq_seen
) {
288 struct ieee802_11_elems elems
;
290 elems_from_eapol_ie(&elems
, &ie
);
291 wpa_printf(MSG_DEBUG
,
292 "Update STA data based on IEs in EAPOL-Key 2/4");
293 sta_update_assoc(sta
, &elems
);
296 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
298 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
299 add_note(wt
, MSG_DEBUG
,
300 "No PTK known to process EAPOL-Key 2/4");
305 kck_len
= sta
->ptk
.kck_len
;
307 add_note(wt
, MSG_DEBUG
,
308 "Use TPTK for validation EAPOL-Key MIC");
310 kck_len
= sta
->tptk
.kck_len
;
312 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
313 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
314 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
317 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
320 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
321 ie
.wpa_ie
, ie
.wpa_ie_len
);
322 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
323 add_note(wt
, MSG_INFO
,
324 "Mismatch in WPA IE between EAPOL-Key 2/4 "
325 "and (Re)Association Request from " MACSTR
,
327 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
328 ie
.wpa_ie
, ie
.wpa_ie_len
);
329 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
332 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
337 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
338 ie
.rsn_ie
, ie
.rsn_ie_len
);
339 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
340 add_note(wt
, MSG_INFO
,
341 "Mismatch in RSN IE between EAPOL-Key 2/4 "
342 "and (Re)Association Request from " MACSTR
,
344 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
345 ie
.rsn_ie
, ie
.rsn_ie_len
);
346 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
349 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
355 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
356 const struct wpa_eapol_key
*hdr
,
357 const u8
*keydata
, u16 keydatalen
,
362 buf
= os_memdup(keydata
, keydatalen
);
366 os_memcpy(ek
, hdr
->key_iv
, 16);
367 os_memcpy(ek
+ 16, kek
, 16);
368 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
369 add_note(wt
, MSG_INFO
, "RC4 failed");
379 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
380 const struct wpa_eapol_key
*hdr
,
381 const u8
*keydata
, u16 keydatalen
,
386 if (keydatalen
% 8) {
387 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
391 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
392 buf
= os_malloc(keydatalen
);
395 if (aes_unwrap(kek
, 16, keydatalen
/ 8, keydata
, buf
)) {
397 add_note(wt
, MSG_INFO
,
398 "AES unwrap failed - could not decrypt EAPOL-Key "
408 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, int akmp
, const u8
*kek
,
409 size_t kek_len
, u16 ver
,
410 const struct wpa_eapol_key
*hdr
,
415 const u8
*mic
, *keydata
;
420 mic
= (const u8
*) (hdr
+ 1);
421 mic_len
= wpa_mic_len(akmp
, PMK_LEN
);
422 keydata
= mic
+ mic_len
+ 2;
423 keydatalen
= WPA_GET_BE16(mic
+ mic_len
);
426 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
427 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, keydata
,
429 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
430 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
431 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
433 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
434 /* For now, assume this is OSEN */
435 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
438 add_note(wt
, MSG_INFO
,
439 "Unsupported EAPOL-Key Key Descriptor Version %u",
446 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
447 struct wlantest_sta
*sta
,
448 const u8
*buf
, size_t len
, const u8
*rsc
)
450 struct wpa_eapol_ie_parse ie
;
452 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
453 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
458 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
459 ie
.wpa_ie
, ie
.wpa_ie_len
);
463 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
464 ie
.rsn_ie
, ie
.rsn_ie_len
);
468 add_note(wt
, MSG_DEBUG
, "KeyID %u", ie
.key_id
[0]);
471 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
473 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
475 id
= ie
.gtk
[0] & 0x03;
476 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
477 id
, !!(ie
.gtk
[0] & 0x04));
478 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
479 add_note(wt
, MSG_INFO
,
480 "GTK KDE: Reserved field set: "
481 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
483 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
485 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
486 sta
->gtk_len
= ie
.gtk_len
- 2;
487 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
488 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
489 bss
->rsc
[id
][0] = rsc
[5];
490 bss
->rsc
[id
][1] = rsc
[4];
491 bss
->rsc
[id
][2] = rsc
[3];
492 bss
->rsc
[id
][3] = rsc
[2];
493 bss
->rsc
[id
][4] = rsc
[1];
494 bss
->rsc
[id
][5] = rsc
[0];
497 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
499 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
500 (unsigned) ie
.gtk_len
);
505 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
506 ie
.igtk
, ie
.igtk_len
);
507 if (ie
.igtk_len
== 24) {
509 id
= WPA_GET_LE16(ie
.igtk
);
511 add_note(wt
, MSG_INFO
,
512 "Unexpected IGTK KeyID %u", id
);
515 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
516 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
517 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
519 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
520 bss
->igtk_len
[id
] = 16;
522 bss
->ipn
[id
][0] = ipn
[5];
523 bss
->ipn
[id
][1] = ipn
[4];
524 bss
->ipn
[id
][2] = ipn
[3];
525 bss
->ipn
[id
][3] = ipn
[2];
526 bss
->ipn
[id
][4] = ipn
[1];
527 bss
->ipn
[id
][5] = ipn
[0];
530 } else if (ie
.igtk_len
== 40) {
532 id
= WPA_GET_LE16(ie
.igtk
);
534 add_note(wt
, MSG_INFO
,
535 "Unexpected IGTK KeyID %u", id
);
538 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
539 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
540 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
542 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 32);
543 bss
->igtk_len
[id
] = 32;
545 bss
->ipn
[id
][0] = ipn
[5];
546 bss
->ipn
[id
][1] = ipn
[4];
547 bss
->ipn
[id
][2] = ipn
[3];
548 bss
->ipn
[id
][3] = ipn
[2];
549 bss
->ipn
[id
][4] = ipn
[1];
550 bss
->ipn
[id
][5] = ipn
[0];
554 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
555 (unsigned) ie
.igtk_len
);
560 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - BIGTK KDE",
561 ie
.bigtk
, ie
.bigtk_len
);
562 if (ie
.bigtk_len
== 24) {
565 id
= WPA_GET_LE16(ie
.bigtk
);
566 if (id
< 6 || id
> 7) {
567 add_note(wt
, MSG_INFO
,
568 "Unexpected BIGTK KeyID %u", id
);
572 add_note(wt
, MSG_DEBUG
, "BIGTK KeyID %u", id
);
573 wpa_hexdump(MSG_DEBUG
, "BIPN", ie
.bigtk
+ 2, 6);
574 wpa_hexdump(MSG_DEBUG
, "BIGTK", ie
.bigtk
+ 8,
576 os_memcpy(bss
->igtk
[id
], ie
.bigtk
+ 8, 16);
577 bss
->igtk_len
[id
] = 16;
579 bss
->ipn
[id
][0] = ipn
[5];
580 bss
->ipn
[id
][1] = ipn
[4];
581 bss
->ipn
[id
][2] = ipn
[3];
582 bss
->ipn
[id
][3] = ipn
[2];
583 bss
->ipn
[id
][4] = ipn
[1];
584 bss
->ipn
[id
][5] = ipn
[0];
587 } else if (ie
.bigtk_len
== 40) {
590 id
= WPA_GET_LE16(ie
.bigtk
);
591 if (id
< 6 || id
> 7) {
592 add_note(wt
, MSG_INFO
,
593 "Unexpected BIGTK KeyID %u", id
);
597 add_note(wt
, MSG_DEBUG
, "BIGTK KeyID %u", id
);
598 wpa_hexdump(MSG_DEBUG
, "BIPN", ie
.bigtk
+ 2, 6);
599 wpa_hexdump(MSG_DEBUG
, "BIGTK", ie
.bigtk
+ 8,
601 os_memcpy(bss
->igtk
[id
], ie
.bigtk
+ 8, 32);
602 bss
->igtk_len
[id
] = 32;
604 bss
->ipn
[id
][0] = ipn
[5];
605 bss
->ipn
[id
][1] = ipn
[4];
606 bss
->ipn
[id
][2] = ipn
[3];
607 bss
->ipn
[id
][3] = ipn
[2];
608 bss
->ipn
[id
][4] = ipn
[1];
609 bss
->ipn
[id
][5] = ipn
[0];
613 add_note(wt
, MSG_INFO
, "Invalid BIGTK KDE length %u",
614 (unsigned) ie
.bigtk_len
);
620 static void rx_data_eapol_key_3_of_4(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
;
627 const u8
*key_data
, *kck
, *kek
, *mic
;
628 size_t kck_len
, kek_len
, mic_len
;
631 u8
*decrypted_buf
= NULL
;
633 size_t decrypted_len
= 0;
634 struct wpa_eapol_ie_parse ie
;
636 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
637 MAC2STR(src
), MAC2STR(dst
));
638 bss
= bss_get(wt
, src
);
641 sta
= sta_get(bss
, dst
);
644 mic_len
= wpa_mic_len(sta
->key_mgmt
, PMK_LEN
);
646 eapol
= (const struct ieee802_1x_hdr
*) data
;
647 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
648 mic
= (const u8
*) (hdr
+ 1);
649 key_info
= WPA_GET_BE16(hdr
->key_info
);
651 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
652 add_note(wt
, MSG_INFO
,
653 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
656 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
658 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
662 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
663 add_note(wt
, MSG_DEBUG
,
664 "No PTK known to process EAPOL-Key 3/4");
669 kek_len
= sta
->ptk
.kek_len
;
671 kck_len
= sta
->ptk
.kck_len
;
673 add_note(wt
, MSG_DEBUG
,
674 "Use TPTK for validation EAPOL-Key MIC");
676 kck_len
= sta
->tptk
.kck_len
;
678 kek_len
= sta
->tptk
.kek_len
;
680 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
681 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
682 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
685 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
687 key_data
= mic
+ mic_len
+ 2;
688 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
689 if (sta
->proto
& WPA_PROTO_RSN
)
690 add_note(wt
, MSG_INFO
,
691 "EAPOL-Key 3/4 without EncrKeyData bit");
692 decrypted
= key_data
;
693 decrypted_len
= WPA_GET_BE16(mic
+ mic_len
);
695 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
696 decrypted_buf
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
698 hdr
, &decrypted_len
);
699 if (decrypted_buf
== NULL
) {
700 add_note(wt
, MSG_INFO
,
701 "Failed to decrypt EAPOL-Key Key Data");
704 decrypted
= decrypted_buf
;
705 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
706 decrypted
, decrypted_len
);
708 if ((wt
->write_pcap_dumper
|| wt
->pcapng
) && decrypted
!= key_data
) {
709 /* Fill in a dummy Data frame header */
710 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
) + 64];
711 struct ieee80211_hdr
*h
;
712 struct wpa_eapol_key
*k
;
717 plain_len
= decrypted_len
;
719 while (p
+ 1 < decrypted
+ decrypted_len
) {
720 if (p
[0] == 0xdd && p
[1] == 0x00) {
722 plain_len
= p
- decrypted
;
728 if (p
&& p
> decrypted
&& *p
== 0xdd &&
729 p
+ 1 == decrypted
+ decrypted_len
) {
732 plain_len
= p
- decrypted
;
735 os_memset(buf
, 0, sizeof(buf
));
736 h
= (struct ieee80211_hdr
*) buf
;
737 h
->frame_control
= host_to_le16(0x0208);
738 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
739 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
740 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
741 pos
= (u8
*) (h
+ 1);
742 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
744 os_memcpy(pos
, eapol
, sizeof(*eapol
));
745 pos
+= sizeof(*eapol
);
746 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
747 k
= (struct wpa_eapol_key
*) pos
;
748 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
749 WPA_PUT_BE16(k
->key_info
,
750 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
751 WPA_PUT_BE16(pos
, plain_len
);
752 write_pcap_decrypted(wt
, buf
, 24 + 8 + sizeof(*eapol
) +
753 sizeof(*hdr
) + mic_len
+ 2,
754 decrypted
, plain_len
);
757 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
758 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
759 os_free(decrypted_buf
);
764 struct ieee802_11_elems elems
;
766 elems_from_eapol_ie(&elems
, &ie
);
767 wpa_printf(MSG_DEBUG
,
768 "Update BSS data based on IEs in EAPOL-Key 3/4");
769 bss_update(wt
, bss
, &elems
, 0);
773 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
774 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
775 add_note(wt
, MSG_INFO
,
776 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
777 "Beacon/Probe Response from " MACSTR
,
778 MAC2STR(bss
->bssid
));
779 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
780 ie
.wpa_ie
, ie
.wpa_ie_len
);
781 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
784 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
788 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
789 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
790 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
791 "3/4 and Beacon/Probe Response from " MACSTR
,
792 MAC2STR(bss
->bssid
));
793 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
794 ie
.rsn_ie
, ie
.rsn_ie_len
);
795 wpa_hexdump(MSG_INFO
, "RSN IE in Beacon/Probe Response",
797 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
800 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
801 os_free(decrypted_buf
);
805 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
806 const u8
*src
, const u8
*data
, size_t len
)
808 struct wlantest_bss
*bss
;
809 struct wlantest_sta
*sta
;
810 const struct ieee802_1x_hdr
*eapol
;
811 const struct wpa_eapol_key
*hdr
;
816 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
817 MAC2STR(src
), MAC2STR(dst
));
818 bss
= bss_get(wt
, dst
);
821 sta
= sta_get(bss
, src
);
825 eapol
= (const struct ieee802_1x_hdr
*) data
;
826 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
827 if (!is_zero(hdr
->key_rsc
, 8)) {
828 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
829 "non-zero Key RSC", MAC2STR(src
));
831 key_info
= WPA_GET_BE16(hdr
->key_info
);
833 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
834 add_note(wt
, MSG_DEBUG
,
835 "No PTK known to process EAPOL-Key 4/4");
840 kck_len
= sta
->ptk
.kck_len
;
842 add_note(wt
, MSG_DEBUG
,
843 "Use TPTK for validation EAPOL-Key MIC");
845 kck_len
= sta
->tptk
.kck_len
;
847 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
848 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
849 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
852 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
854 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
855 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
858 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
859 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
864 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
865 const u8
*src
, const u8
*data
, size_t len
)
867 struct wlantest_bss
*bss
;
868 struct wlantest_sta
*sta
;
869 const struct ieee802_1x_hdr
*eapol
;
870 const struct wpa_eapol_key
*hdr
;
873 size_t decrypted_len
= 0;
876 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
877 MAC2STR(src
), MAC2STR(dst
));
878 bss
= bss_get(wt
, src
);
881 sta
= sta_get(bss
, dst
);
884 mic_len
= wpa_mic_len(sta
->key_mgmt
, PMK_LEN
);
886 eapol
= (const struct ieee802_1x_hdr
*) data
;
887 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
888 key_info
= WPA_GET_BE16(hdr
->key_info
);
891 add_note(wt
, MSG_DEBUG
,
892 "No PTK known to process EAPOL-Key 1/2");
897 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
898 key_info
& WPA_KEY_INFO_TYPE_MASK
,
900 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
903 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
905 if (sta
->proto
& WPA_PROTO_RSN
&&
906 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
907 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
910 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
911 decrypted
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
912 sta
->ptk
.kek
, sta
->ptk
.kek_len
,
913 ver
, hdr
, &decrypted_len
);
914 if (decrypted
== NULL
) {
915 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
918 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
919 decrypted
, decrypted_len
);
920 if (wt
->write_pcap_dumper
|| wt
->pcapng
) {
921 /* Fill in a dummy Data frame header */
922 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
) + 64];
923 struct ieee80211_hdr
*h
;
924 struct wpa_eapol_key
*k
;
928 plain_len
= decrypted_len
;
930 while (pos
+ 1 < decrypted
+ decrypted_len
) {
931 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
933 plain_len
= pos
- decrypted
;
939 os_memset(buf
, 0, sizeof(buf
));
940 h
= (struct ieee80211_hdr
*) buf
;
941 h
->frame_control
= host_to_le16(0x0208);
942 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
943 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
944 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
945 pos
= (u8
*) (h
+ 1);
946 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
948 os_memcpy(pos
, eapol
, sizeof(*eapol
));
949 pos
+= sizeof(*eapol
);
950 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
951 k
= (struct wpa_eapol_key
*) pos
;
952 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
953 WPA_PUT_BE16(k
->key_info
,
954 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
955 WPA_PUT_BE16(pos
, plain_len
);
956 write_pcap_decrypted(wt
, buf
, 24 + 8 + sizeof(*eapol
) +
957 sizeof(*hdr
) + mic_len
+ 2,
958 decrypted
, plain_len
);
960 if (sta
->proto
& WPA_PROTO_RSN
)
961 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
964 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
965 if (decrypted_len
== klen
) {
966 const u8
*rsc
= hdr
->key_rsc
;
968 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
969 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
970 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
971 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
973 bss
->gtk_len
[id
] = decrypted_len
;
974 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
975 bss
->rsc
[id
][0] = rsc
[5];
976 bss
->rsc
[id
][1] = rsc
[4];
977 bss
->rsc
[id
][2] = rsc
[3];
978 bss
->rsc
[id
][3] = rsc
[2];
979 bss
->rsc
[id
][4] = rsc
[1];
980 bss
->rsc
[id
][5] = rsc
[0];
981 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
983 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
984 "in Group Key msg 1/2 from " MACSTR
,
992 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
993 const u8
*src
, const u8
*data
, size_t len
)
995 struct wlantest_bss
*bss
;
996 struct wlantest_sta
*sta
;
997 const struct ieee802_1x_hdr
*eapol
;
998 const struct wpa_eapol_key
*hdr
;
1001 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
1002 MAC2STR(src
), MAC2STR(dst
));
1003 bss
= bss_get(wt
, dst
);
1006 sta
= sta_get(bss
, src
);
1010 eapol
= (const struct ieee802_1x_hdr
*) data
;
1011 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
1012 if (!is_zero(hdr
->key_rsc
, 8)) {
1013 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
1014 "non-zero Key RSC", MAC2STR(src
));
1016 key_info
= WPA_GET_BE16(hdr
->key_info
);
1018 if (!sta
->ptk_set
) {
1019 add_note(wt
, MSG_DEBUG
,
1020 "No PTK known to process EAPOL-Key 2/2");
1025 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
1026 key_info
& WPA_KEY_INFO_TYPE_MASK
,
1028 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
1031 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
1035 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*bssid
,
1036 const u8
*sta_addr
, const u8
*dst
,
1037 const u8
*src
, const u8
*data
, size_t len
,
1040 const struct ieee802_1x_hdr
*eapol
;
1041 const struct wpa_eapol_key
*hdr
;
1043 u16 key_info
, key_length
, ver
, key_data_length
;
1044 size_t mic_len
= 16;
1046 struct wlantest_bss
*bss
;
1047 struct wlantest_sta
*sta
;
1049 bss
= bss_get(wt
, bssid
);
1051 sta
= sta_get(bss
, sta_addr
);
1053 mic_len
= wpa_mic_len(sta
->key_mgmt
, PMK_LEN
);
1056 eapol
= (const struct ieee802_1x_hdr
*) data
;
1057 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
1059 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
1060 (const u8
*) hdr
, len
- sizeof(*eapol
));
1061 if (len
< sizeof(*hdr
) + mic_len
+ 2) {
1062 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
1066 mic
= (const u8
*) (hdr
+ 1);
1068 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
1069 /* TODO: EAPOL-Key RC4 for WEP */
1070 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
1071 MACSTR
, MAC2STR(src
));
1075 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
1076 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
1077 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
1078 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
1082 key_info
= WPA_GET_BE16(hdr
->key_info
);
1083 key_length
= WPA_GET_BE16(hdr
->key_length
);
1084 key_data_length
= WPA_GET_BE16(mic
+ mic_len
);
1085 key_data
= mic
+ mic_len
+ 2;
1086 if (key_data
+ key_data_length
> data
+ len
) {
1087 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
1091 if (key_data
+ key_data_length
< data
+ len
) {
1092 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
1093 "field", key_data
+ key_data_length
,
1094 data
+ len
- key_data
- key_data_length
);
1098 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
1099 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
1101 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
1102 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
1103 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
1104 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
1105 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
1106 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
1107 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
1108 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
1109 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
1110 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
1111 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
1114 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1115 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
1116 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
&&
1117 ver
!= WPA_KEY_INFO_TYPE_AKM_DEFINED
) {
1118 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
1119 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
1123 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
1124 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
1125 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
1126 hdr
->key_nonce
, WPA_NONCE_LEN
);
1127 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
1129 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
1130 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
1131 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
1133 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
1134 key_data
, key_data_length
);
1136 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
1137 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
1139 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
1140 "Key Info bits 0x%x from " MACSTR
,
1141 key_info
, MAC2STR(src
));
1144 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
1145 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
1146 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
1147 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
1148 "Key Info bits 0x%x from " MACSTR
,
1149 key_info
, MAC2STR(src
));
1152 if (key_length
> 32) {
1153 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
1154 "from " MACSTR
, key_length
, MAC2STR(src
));
1157 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1158 !is_zero(hdr
->key_iv
, 16)) {
1159 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
1160 "(reserved with ver=%d) field from " MACSTR
,
1162 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
1166 if (!is_zero(hdr
->key_id
, 8)) {
1167 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
1168 "(reserved) field from " MACSTR
, MAC2STR(src
));
1169 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
1173 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
1174 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
1175 "(last two are unused)" MACSTR
, MAC2STR(src
));
1178 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
1181 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
1184 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
1185 /* 4-Way Handshake */
1186 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1189 WPA_KEY_INFO_INSTALL
)) {
1190 case WPA_KEY_INFO_ACK
:
1191 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
1193 case WPA_KEY_INFO_MIC
:
1194 if (key_data_length
== 0)
1195 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1198 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1201 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1202 WPA_KEY_INFO_INSTALL
:
1203 /* WPA does not include Secure bit in 3/4 */
1204 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1206 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1207 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1208 case WPA_KEY_INFO_SECURE
|
1209 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1210 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1212 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1213 case WPA_KEY_INFO_SECURE
:
1214 if (key_data_length
== 0)
1215 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1218 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1222 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1226 /* Group Key Handshake */
1227 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1229 WPA_KEY_INFO_ACK
)) {
1230 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1232 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_ACK
:
1233 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1235 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1236 case WPA_KEY_INFO_SECURE
:
1237 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1240 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1247 void rx_data_eapol(struct wlantest
*wt
, const u8
*bssid
, const u8
*sta_addr
,
1248 const u8
*dst
, const u8
*src
,
1249 const u8
*data
, size_t len
, int prot
)
1251 const struct ieee802_1x_hdr
*hdr
;
1255 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1256 if (len
< sizeof(*hdr
)) {
1257 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1262 hdr
= (const struct ieee802_1x_hdr
*) data
;
1263 length
= be_to_host16(hdr
->length
);
1264 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1266 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1267 hdr
->version
, hdr
->type
, length
);
1268 if (hdr
->version
< 1 || hdr
->version
> 3) {
1269 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1270 MACSTR
, hdr
->version
, MAC2STR(src
));
1272 if (sizeof(*hdr
) + length
> len
) {
1273 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1278 if (sizeof(*hdr
) + length
< len
) {
1279 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1280 (int) (len
- sizeof(*hdr
) - length
));
1282 p
= (const u8
*) (hdr
+ 1);
1284 switch (hdr
->type
) {
1285 case IEEE802_1X_TYPE_EAP_PACKET
:
1286 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1288 case IEEE802_1X_TYPE_EAPOL_START
:
1289 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1291 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1292 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1294 case IEEE802_1X_TYPE_EAPOL_KEY
:
1295 rx_data_eapol_key(wt
, bssid
, sta_addr
, dst
, src
, data
,
1296 sizeof(*hdr
) + length
, prot
);
1298 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1299 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1303 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);