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
);
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_r0_name
[WPA_PMK_NAME_LEN
];
106 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
107 u8 ptk_name
[WPA_PMK_NAME_LEN
];
109 wpa_derive_pmk_r0(pmk
->pmk
, sizeof(pmk
->pmk
),
110 bss
->ssid
, bss
->ssid_len
, bss
->mdid
,
111 bss
->r0kh_id
, bss
->r0kh_id_len
,
112 sta
->addr
, pmk_r0
, pmk_r0_name
);
113 wpa_hexdump(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, PMK_LEN
);
114 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
,
116 wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, bss
->r1kh_id
,
117 sta
->addr
, pmk_r1
, pmk_r1_name
);
118 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
119 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
,
121 if (wpa_pmk_r1_to_ptk(pmk_r1
, sta
->snonce
, sta
->anonce
,
123 bss
->bssid
, pmk_r1_name
, &ptk
, ptk_name
,
125 sta
->pairwise_cipher
) < 0 ||
126 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
129 } else if (wpa_pmk_to_ptk(pmk
->pmk
, sizeof(pmk
->pmk
),
130 "Pairwise key expansion",
131 bss
->bssid
, sta
->addr
, sta
->anonce
,
132 sta
->snonce
, &ptk
, sta
->key_mgmt
,
133 sta
->pairwise_cipher
) < 0 ||
134 check_mic(ptk
.kck
, ptk
.kck_len
, sta
->key_mgmt
, ver
, data
,
139 sta
->tk_len
= wpa_cipher_key_len(sta
->pairwise_cipher
);
140 wpa_printf(MSG_INFO
, "Derived PTK for STA " MACSTR
" BSSID " MACSTR
,
141 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
142 sta
->counters
[WLANTEST_STA_COUNTER_PTK_LEARNED
]++;
145 * Rekeying - use new PTK for EAPOL-Key frames, but continue
146 * using the old PTK for frame decryption.
148 add_note(wt
, MSG_DEBUG
, "Derived PTK during rekeying");
149 os_memcpy(&sta
->tptk
, &ptk
, sizeof(ptk
));
150 wpa_hexdump(MSG_DEBUG
, "TPTK:KCK",
151 sta
->tptk
.kck
, sta
->tptk
.kck_len
);
152 wpa_hexdump(MSG_DEBUG
, "TPTK:KEK",
153 sta
->tptk
.kek
, sta
->tptk
.kek_len
);
154 wpa_hexdump(MSG_DEBUG
, "TPTK:TK",
155 sta
->tptk
.tk
, sta
->tptk
.tk_len
);
159 add_note(wt
, MSG_DEBUG
, "Derived new PTK");
160 os_memcpy(&sta
->ptk
, &ptk
, sizeof(ptk
));
161 wpa_hexdump(MSG_DEBUG
, "PTK:KCK", sta
->ptk
.kck
, sta
->ptk
.kck_len
);
162 wpa_hexdump(MSG_DEBUG
, "PTK:KEK", sta
->ptk
.kek
, sta
->ptk
.kek_len
);
163 wpa_hexdump(MSG_DEBUG
, "PTK:TK", sta
->ptk
.tk
, sta
->ptk
.tk_len
);
165 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
166 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
171 static void derive_ptk(struct wlantest
*wt
, struct wlantest_bss
*bss
,
172 struct wlantest_sta
*sta
, u16 ver
,
173 const u8
*data
, size_t len
)
175 struct wlantest_pmk
*pmk
;
177 wpa_printf(MSG_DEBUG
, "Trying to derive PTK for " MACSTR
" (ver %u)",
178 MAC2STR(sta
->addr
), ver
);
179 dl_list_for_each(pmk
, &bss
->pmk
, struct wlantest_pmk
, list
) {
180 wpa_printf(MSG_DEBUG
, "Try per-BSS PMK");
181 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
185 dl_list_for_each(pmk
, &wt
->pmk
, struct wlantest_pmk
, list
) {
186 wpa_printf(MSG_DEBUG
, "Try global PMK");
187 if (try_pmk(wt
, bss
, sta
, ver
, data
, len
, pmk
) == 0)
192 struct wlantest_ptk
*ptk
;
193 int prev_level
= wpa_debug_level
;
195 wpa_debug_level
= MSG_WARNING
;
196 dl_list_for_each(ptk
, &wt
->ptk
, struct wlantest_ptk
, list
) {
197 if (check_mic(ptk
->ptk
.kck
, ptk
->ptk
.kck_len
,
198 sta
->key_mgmt
, ver
, data
, len
) < 0)
200 wpa_printf(MSG_INFO
, "Pre-set PTK matches for STA "
201 MACSTR
" BSSID " MACSTR
,
202 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
203 add_note(wt
, MSG_DEBUG
, "Using pre-set PTK");
205 wpa_cipher_key_len(sta
->pairwise_cipher
);
206 os_memcpy(&sta
->ptk
, &ptk
->ptk
, sizeof(ptk
->ptk
));
207 wpa_hexdump(MSG_DEBUG
, "PTK:KCK",
208 sta
->ptk
.kck
, sta
->ptk
.kck_len
);
209 wpa_hexdump(MSG_DEBUG
, "PTK:KEK",
210 sta
->ptk
.kek
, sta
->ptk
.kek_len
);
211 wpa_hexdump(MSG_DEBUG
, "PTK:TK",
212 sta
->ptk
.tk
, sta
->ptk
.tk_len
);
214 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
215 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
217 wpa_debug_level
= prev_level
;
220 add_note(wt
, MSG_DEBUG
, "No matching PMK found to derive PTK");
224 static void rx_data_eapol_key_2_of_4(struct wlantest
*wt
, const u8
*dst
,
225 const u8
*src
, const u8
*data
, size_t len
)
227 struct wlantest_bss
*bss
;
228 struct wlantest_sta
*sta
;
229 const struct ieee802_1x_hdr
*eapol
;
230 const struct wpa_eapol_key
*hdr
;
231 const u8
*key_data
, *kck
, *mic
;
232 size_t kck_len
, mic_len
;
233 u16 key_info
, key_data_len
;
234 struct wpa_eapol_ie_parse ie
;
236 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/4 " MACSTR
" -> " MACSTR
,
237 MAC2STR(src
), MAC2STR(dst
));
238 bss
= bss_get(wt
, dst
);
241 sta
= sta_get(bss
, src
);
245 eapol
= (const struct ieee802_1x_hdr
*) data
;
246 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
247 mic_len
= wpa_mic_len(sta
->key_mgmt
);
248 mic
= (const u8
*) (hdr
+ 1);
249 if (is_zero(hdr
->key_nonce
, WPA_NONCE_LEN
)) {
250 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
251 " used zero nonce", MAC2STR(src
));
253 if (!is_zero(hdr
->key_rsc
, 8)) {
254 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/4 from " MACSTR
255 " used non-zero Key RSC", MAC2STR(src
));
257 os_memcpy(sta
->snonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
258 key_info
= WPA_GET_BE16(hdr
->key_info
);
259 key_data_len
= WPA_GET_BE16(mic
+ mic_len
);
260 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
);
262 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
263 add_note(wt
, MSG_DEBUG
,
264 "No PTK known to process EAPOL-Key 2/4");
269 kck_len
= sta
->ptk
.kck_len
;
271 add_note(wt
, MSG_DEBUG
,
272 "Use TPTK for validation EAPOL-Key MIC");
274 kck_len
= sta
->tptk
.kck_len
;
276 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
277 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
278 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/4 MIC");
281 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/4");
283 key_data
= mic
+ mic_len
+ 2;
285 if (wpa_supplicant_parse_ies(key_data
, key_data_len
, &ie
) < 0) {
286 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
291 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
292 ie
.wpa_ie
, ie
.wpa_ie_len
);
293 if (os_memcmp(ie
.wpa_ie
, sta
->rsnie
, ie
.wpa_ie_len
) != 0) {
294 struct ieee802_11_elems elems
;
295 add_note(wt
, MSG_INFO
,
296 "Mismatch in WPA IE between EAPOL-Key 2/4 "
297 "and (Re)Association Request from " MACSTR
,
299 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
300 ie
.wpa_ie
, ie
.wpa_ie_len
);
301 wpa_hexdump(MSG_INFO
, "WPA IE in (Re)Association "
304 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
306 * The sniffer may have missed (Re)Association
307 * Request, so try to survive with the information from
310 os_memset(&elems
, 0, sizeof(elems
));
311 elems
.wpa_ie
= ie
.wpa_ie
+ 2;
312 elems
.wpa_ie_len
= ie
.wpa_ie_len
- 2;
313 wpa_printf(MSG_DEBUG
, "Update STA data based on WPA "
314 "IE in EAPOL-Key 2/4");
315 sta_update_assoc(sta
, &elems
);
320 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
321 ie
.rsn_ie
, ie
.rsn_ie_len
);
322 if (os_memcmp(ie
.rsn_ie
, sta
->rsnie
, ie
.rsn_ie_len
) != 0) {
323 struct ieee802_11_elems elems
;
324 add_note(wt
, MSG_INFO
,
325 "Mismatch in RSN IE between EAPOL-Key 2/4 "
326 "and (Re)Association Request from " MACSTR
,
328 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
329 ie
.rsn_ie
, ie
.rsn_ie_len
);
330 wpa_hexdump(MSG_INFO
, "RSN IE in (Re)Association "
333 sta
->rsnie
[0] ? 2 + sta
->rsnie
[1] : 0);
335 * The sniffer may have missed (Re)Association
336 * Request, so try to survive with the information from
339 os_memset(&elems
, 0, sizeof(elems
));
340 elems
.rsn_ie
= ie
.rsn_ie
+ 2;
341 elems
.rsn_ie_len
= ie
.rsn_ie_len
- 2;
342 wpa_printf(MSG_DEBUG
, "Update STA data based on RSN "
343 "IE in EAPOL-Key 2/4");
344 sta_update_assoc(sta
, &elems
);
350 static u8
* decrypt_eapol_key_data_rc4(struct wlantest
*wt
, const u8
*kek
,
351 const struct wpa_eapol_key
*hdr
,
352 const u8
*keydata
, u16 keydatalen
,
357 buf
= os_memdup(keydata
, keydatalen
);
361 os_memcpy(ek
, hdr
->key_iv
, 16);
362 os_memcpy(ek
+ 16, kek
, 16);
363 if (rc4_skip(ek
, 32, 256, buf
, keydatalen
)) {
364 add_note(wt
, MSG_INFO
, "RC4 failed");
374 static u8
* decrypt_eapol_key_data_aes(struct wlantest
*wt
, const u8
*kek
,
375 const struct wpa_eapol_key
*hdr
,
376 const u8
*keydata
, u16 keydatalen
,
381 if (keydatalen
% 8) {
382 add_note(wt
, MSG_INFO
, "Unsupported AES-WRAP len %d",
386 keydatalen
-= 8; /* AES-WRAP adds 8 bytes */
387 buf
= os_malloc(keydatalen
);
390 if (aes_unwrap(kek
, 16, keydatalen
/ 8, keydata
, buf
)) {
392 add_note(wt
, MSG_INFO
,
393 "AES unwrap failed - could not decrypt EAPOL-Key "
403 static u8
* decrypt_eapol_key_data(struct wlantest
*wt
, int akmp
, const u8
*kek
,
404 size_t kek_len
, u16 ver
,
405 const struct wpa_eapol_key
*hdr
,
410 const u8
*mic
, *keydata
;
415 mic
= (const u8
*) (hdr
+ 1);
416 mic_len
= wpa_mic_len(akmp
);
417 keydata
= mic
+ mic_len
+ 2;
418 keydatalen
= WPA_GET_BE16(mic
+ mic_len
);
421 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
:
422 return decrypt_eapol_key_data_rc4(wt
, kek
, hdr
, keydata
,
424 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
:
425 case WPA_KEY_INFO_TYPE_AES_128_CMAC
:
426 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
428 case WPA_KEY_INFO_TYPE_AKM_DEFINED
:
429 /* For now, assume this is OSEN */
430 return decrypt_eapol_key_data_aes(wt
, kek
, hdr
, keydata
,
433 add_note(wt
, MSG_INFO
,
434 "Unsupported EAPOL-Key Key Descriptor Version %u",
441 static void learn_kde_keys(struct wlantest
*wt
, struct wlantest_bss
*bss
,
442 struct wlantest_sta
*sta
,
443 const u8
*buf
, size_t len
, const u8
*rsc
)
445 struct wpa_eapol_ie_parse ie
;
447 if (wpa_supplicant_parse_ies(buf
, len
, &ie
) < 0) {
448 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
453 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - WPA IE",
454 ie
.wpa_ie
, ie
.wpa_ie_len
);
458 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - RSN IE",
459 ie
.rsn_ie
, ie
.rsn_ie_len
);
463 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - GTK KDE",
465 if (ie
.gtk_len
>= 2 && ie
.gtk_len
<= 2 + 32) {
467 id
= ie
.gtk
[0] & 0x03;
468 add_note(wt
, MSG_DEBUG
, "GTK KeyID=%u tx=%u",
469 id
, !!(ie
.gtk
[0] & 0x04));
470 if ((ie
.gtk
[0] & 0xf8) || ie
.gtk
[1]) {
471 add_note(wt
, MSG_INFO
,
472 "GTK KDE: Reserved field set: "
473 "%02x %02x", ie
.gtk
[0], ie
.gtk
[1]);
475 wpa_hexdump(MSG_DEBUG
, "GTK", ie
.gtk
+ 2,
477 bss
->gtk_len
[id
] = ie
.gtk_len
- 2;
478 sta
->gtk_len
= ie
.gtk_len
- 2;
479 os_memcpy(bss
->gtk
[id
], ie
.gtk
+ 2, ie
.gtk_len
- 2);
480 os_memcpy(sta
->gtk
, ie
.gtk
+ 2, ie
.gtk_len
- 2);
481 bss
->rsc
[id
][0] = rsc
[5];
482 bss
->rsc
[id
][1] = rsc
[4];
483 bss
->rsc
[id
][2] = rsc
[3];
484 bss
->rsc
[id
][3] = rsc
[2];
485 bss
->rsc
[id
][4] = rsc
[1];
486 bss
->rsc
[id
][5] = rsc
[0];
489 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
491 add_note(wt
, MSG_INFO
, "Invalid GTK KDE length %u",
492 (unsigned) ie
.gtk_len
);
497 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data - IGTK KDE",
498 ie
.igtk
, ie
.igtk_len
);
499 if (ie
.igtk_len
== 24) {
501 id
= WPA_GET_LE16(ie
.igtk
);
503 add_note(wt
, MSG_INFO
,
504 "Unexpected IGTK KeyID %u", id
);
507 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
508 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
509 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
511 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 16);
512 bss
->igtk_len
[id
] = 16;
514 bss
->ipn
[id
][0] = ipn
[5];
515 bss
->ipn
[id
][1] = ipn
[4];
516 bss
->ipn
[id
][2] = ipn
[3];
517 bss
->ipn
[id
][3] = ipn
[2];
518 bss
->ipn
[id
][4] = ipn
[1];
519 bss
->ipn
[id
][5] = ipn
[0];
522 } else if (ie
.igtk_len
== 40) {
524 id
= WPA_GET_LE16(ie
.igtk
);
526 add_note(wt
, MSG_INFO
,
527 "Unexpected IGTK KeyID %u", id
);
530 add_note(wt
, MSG_DEBUG
, "IGTK KeyID %u", id
);
531 wpa_hexdump(MSG_DEBUG
, "IPN", ie
.igtk
+ 2, 6);
532 wpa_hexdump(MSG_DEBUG
, "IGTK", ie
.igtk
+ 8,
534 os_memcpy(bss
->igtk
[id
], ie
.igtk
+ 8, 32);
535 bss
->igtk_len
[id
] = 32;
537 bss
->ipn
[id
][0] = ipn
[5];
538 bss
->ipn
[id
][1] = ipn
[4];
539 bss
->ipn
[id
][2] = ipn
[3];
540 bss
->ipn
[id
][3] = ipn
[2];
541 bss
->ipn
[id
][4] = ipn
[1];
542 bss
->ipn
[id
][5] = ipn
[0];
546 add_note(wt
, MSG_INFO
, "Invalid IGTK KDE length %u",
547 (unsigned) ie
.igtk_len
);
553 static void rx_data_eapol_key_3_of_4(struct wlantest
*wt
, const u8
*dst
,
554 const u8
*src
, const u8
*data
, size_t len
)
556 struct wlantest_bss
*bss
;
557 struct wlantest_sta
*sta
;
558 const struct ieee802_1x_hdr
*eapol
;
559 const struct wpa_eapol_key
*hdr
;
560 const u8
*key_data
, *kck
, *kek
, *mic
;
561 size_t kck_len
, kek_len
, mic_len
;
564 u8
*decrypted_buf
= NULL
;
566 size_t decrypted_len
= 0;
567 struct wpa_eapol_ie_parse ie
;
569 wpa_printf(MSG_DEBUG
, "EAPOL-Key 3/4 " MACSTR
" -> " MACSTR
,
570 MAC2STR(src
), MAC2STR(dst
));
571 bss
= bss_get(wt
, src
);
574 sta
= sta_get(bss
, dst
);
577 mic_len
= wpa_mic_len(sta
->key_mgmt
);
579 eapol
= (const struct ieee802_1x_hdr
*) data
;
580 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
581 mic
= (const u8
*) (hdr
+ 1);
582 key_info
= WPA_GET_BE16(hdr
->key_info
);
584 if (os_memcmp(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
) != 0) {
585 add_note(wt
, MSG_INFO
,
586 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
589 os_memcpy(sta
->anonce
, hdr
->key_nonce
, WPA_NONCE_LEN
);
591 derive_ptk(wt
, bss
, sta
, key_info
& WPA_KEY_INFO_TYPE_MASK
,
595 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
596 add_note(wt
, MSG_DEBUG
,
597 "No PTK known to process EAPOL-Key 3/4");
602 kek_len
= sta
->ptk
.kek_len
;
604 kck_len
= sta
->ptk
.kck_len
;
606 add_note(wt
, MSG_DEBUG
,
607 "Use TPTK for validation EAPOL-Key MIC");
609 kck_len
= sta
->tptk
.kck_len
;
611 kek_len
= sta
->tptk
.kek_len
;
613 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
614 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
615 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 3/4 MIC");
618 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 3/4");
620 key_data
= mic
+ mic_len
+ 2;
621 if (!(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
622 if (sta
->proto
& WPA_PROTO_RSN
)
623 add_note(wt
, MSG_INFO
,
624 "EAPOL-Key 3/4 without EncrKeyData bit");
625 decrypted
= key_data
;
626 decrypted_len
= WPA_GET_BE16(mic
+ mic_len
);
628 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
629 decrypted_buf
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
631 hdr
, &decrypted_len
);
632 if (decrypted_buf
== NULL
) {
633 add_note(wt
, MSG_INFO
,
634 "Failed to decrypt EAPOL-Key Key Data");
637 decrypted
= decrypted_buf
;
638 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
639 decrypted
, decrypted_len
);
641 if ((wt
->write_pcap_dumper
|| wt
->pcapng
) && decrypted
!= key_data
) {
642 /* Fill in a dummy Data frame header */
643 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
) + 64];
644 struct ieee80211_hdr
*h
;
645 struct wpa_eapol_key
*k
;
650 plain_len
= decrypted_len
;
652 while (p
+ 1 < decrypted
+ decrypted_len
) {
653 if (p
[0] == 0xdd && p
[1] == 0x00) {
655 plain_len
= p
- decrypted
;
661 if (p
&& p
> decrypted
&& *p
== 0xdd &&
662 p
+ 1 == decrypted
+ decrypted_len
) {
665 plain_len
= p
- decrypted
;
668 os_memset(buf
, 0, sizeof(buf
));
669 h
= (struct ieee80211_hdr
*) buf
;
670 h
->frame_control
= host_to_le16(0x0208);
671 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
672 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
673 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
674 pos
= (u8
*) (h
+ 1);
675 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
677 os_memcpy(pos
, eapol
, sizeof(*eapol
));
678 pos
+= sizeof(*eapol
);
679 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
680 k
= (struct wpa_eapol_key
*) pos
;
681 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
682 WPA_PUT_BE16(k
->key_info
,
683 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
684 WPA_PUT_BE16(pos
, plain_len
);
685 write_pcap_decrypted(wt
, buf
, 24 + 8 + sizeof(*eapol
) +
686 sizeof(*hdr
) + mic_len
+ 2,
687 decrypted
, plain_len
);
690 if (wpa_supplicant_parse_ies(decrypted
, decrypted_len
, &ie
) < 0) {
691 add_note(wt
, MSG_INFO
, "Failed to parse EAPOL-Key Key Data");
692 os_free(decrypted_buf
);
697 os_memcmp(ie
.wpa_ie
, bss
->wpaie
, ie
.wpa_ie_len
) != 0) ||
698 (ie
.wpa_ie
== NULL
&& bss
->wpaie
[0])) {
699 add_note(wt
, MSG_INFO
,
700 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
701 "Beacon/Probe Response from " MACSTR
,
702 MAC2STR(bss
->bssid
));
703 wpa_hexdump(MSG_INFO
, "WPA IE in EAPOL-Key",
704 ie
.wpa_ie
, ie
.wpa_ie_len
);
705 wpa_hexdump(MSG_INFO
, "WPA IE in Beacon/Probe "
708 bss
->wpaie
[0] ? 2 + bss
->wpaie
[1] : 0);
712 os_memcmp(ie
.rsn_ie
, bss
->rsnie
, ie
.rsn_ie_len
) != 0) ||
713 (ie
.rsn_ie
== NULL
&& bss
->rsnie
[0])) {
714 add_note(wt
, MSG_INFO
, "Mismatch in RSN IE between EAPOL-Key "
715 "3/4 and Beacon/Probe Response from " MACSTR
,
716 MAC2STR(bss
->bssid
));
717 wpa_hexdump(MSG_INFO
, "RSN IE in EAPOL-Key",
718 ie
.rsn_ie
, ie
.rsn_ie_len
);
719 wpa_hexdump(MSG_INFO
, "RSN IE in Beacon/Probe Response",
721 bss
->rsnie
[0] ? 2 + bss
->rsnie
[1] : 0);
724 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
, hdr
->key_rsc
);
725 os_free(decrypted_buf
);
729 static void rx_data_eapol_key_4_of_4(struct wlantest
*wt
, const u8
*dst
,
730 const u8
*src
, const u8
*data
, size_t len
)
732 struct wlantest_bss
*bss
;
733 struct wlantest_sta
*sta
;
734 const struct ieee802_1x_hdr
*eapol
;
735 const struct wpa_eapol_key
*hdr
;
740 wpa_printf(MSG_DEBUG
, "EAPOL-Key 4/4 " MACSTR
" -> " MACSTR
,
741 MAC2STR(src
), MAC2STR(dst
));
742 bss
= bss_get(wt
, dst
);
745 sta
= sta_get(bss
, src
);
749 eapol
= (const struct ieee802_1x_hdr
*) data
;
750 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
751 if (!is_zero(hdr
->key_rsc
, 8)) {
752 add_note(wt
, MSG_INFO
, "EAPOL-Key 4/4 from " MACSTR
" used "
753 "non-zero Key RSC", MAC2STR(src
));
755 key_info
= WPA_GET_BE16(hdr
->key_info
);
757 if (!sta
->ptk_set
&& !sta
->tptk_set
) {
758 add_note(wt
, MSG_DEBUG
,
759 "No PTK known to process EAPOL-Key 4/4");
764 kck_len
= sta
->ptk
.kck_len
;
766 add_note(wt
, MSG_DEBUG
,
767 "Use TPTK for validation EAPOL-Key MIC");
769 kck_len
= sta
->tptk
.kck_len
;
771 if (check_mic(kck
, kck_len
, sta
->key_mgmt
,
772 key_info
& WPA_KEY_INFO_TYPE_MASK
, data
, len
) < 0) {
773 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 4/4 MIC");
776 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 4/4");
778 add_note(wt
, MSG_DEBUG
, "Update PTK (rekeying)");
779 os_memcpy(&sta
->ptk
, &sta
->tptk
, sizeof(sta
->ptk
));
782 os_memset(sta
->rsc_tods
, 0, sizeof(sta
->rsc_tods
));
783 os_memset(sta
->rsc_fromds
, 0, sizeof(sta
->rsc_fromds
));
788 static void rx_data_eapol_key_1_of_2(struct wlantest
*wt
, const u8
*dst
,
789 const u8
*src
, const u8
*data
, size_t len
)
791 struct wlantest_bss
*bss
;
792 struct wlantest_sta
*sta
;
793 const struct ieee802_1x_hdr
*eapol
;
794 const struct wpa_eapol_key
*hdr
;
797 size_t decrypted_len
= 0;
800 wpa_printf(MSG_DEBUG
, "EAPOL-Key 1/2 " MACSTR
" -> " MACSTR
,
801 MAC2STR(src
), MAC2STR(dst
));
802 bss
= bss_get(wt
, src
);
805 sta
= sta_get(bss
, dst
);
808 mic_len
= wpa_mic_len(sta
->key_mgmt
);
810 eapol
= (const struct ieee802_1x_hdr
*) data
;
811 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
812 key_info
= WPA_GET_BE16(hdr
->key_info
);
815 add_note(wt
, MSG_DEBUG
,
816 "No PTK known to process EAPOL-Key 1/2");
821 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
822 key_info
& WPA_KEY_INFO_TYPE_MASK
,
824 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 1/2 MIC");
827 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 1/2");
829 if (sta
->proto
& WPA_PROTO_RSN
&&
830 !(key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
)) {
831 add_note(wt
, MSG_INFO
, "EAPOL-Key 1/2 without EncrKeyData bit");
834 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
835 decrypted
= decrypt_eapol_key_data(wt
, sta
->key_mgmt
,
836 sta
->ptk
.kek
, sta
->ptk
.kek_len
,
837 ver
, hdr
, &decrypted_len
);
838 if (decrypted
== NULL
) {
839 add_note(wt
, MSG_INFO
, "Failed to decrypt EAPOL-Key Key Data");
842 wpa_hexdump(MSG_DEBUG
, "Decrypted EAPOL-Key Key Data",
843 decrypted
, decrypted_len
);
844 if (wt
->write_pcap_dumper
|| wt
->pcapng
) {
845 /* Fill in a dummy Data frame header */
846 u8 buf
[24 + 8 + sizeof(*eapol
) + sizeof(*hdr
) + 64];
847 struct ieee80211_hdr
*h
;
848 struct wpa_eapol_key
*k
;
852 plain_len
= decrypted_len
;
854 while (pos
+ 1 < decrypted
+ decrypted_len
) {
855 if (pos
[0] == 0xdd && pos
[1] == 0x00) {
857 plain_len
= pos
- decrypted
;
863 os_memset(buf
, 0, sizeof(buf
));
864 h
= (struct ieee80211_hdr
*) buf
;
865 h
->frame_control
= host_to_le16(0x0208);
866 os_memcpy(h
->addr1
, dst
, ETH_ALEN
);
867 os_memcpy(h
->addr2
, src
, ETH_ALEN
);
868 os_memcpy(h
->addr3
, src
, ETH_ALEN
);
869 pos
= (u8
*) (h
+ 1);
870 os_memcpy(pos
, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
872 os_memcpy(pos
, eapol
, sizeof(*eapol
));
873 pos
+= sizeof(*eapol
);
874 os_memcpy(pos
, hdr
, sizeof(*hdr
) + mic_len
);
875 k
= (struct wpa_eapol_key
*) pos
;
876 pos
+= sizeof(struct wpa_eapol_key
) + mic_len
;
877 WPA_PUT_BE16(k
->key_info
,
878 key_info
& ~WPA_KEY_INFO_ENCR_KEY_DATA
);
879 WPA_PUT_BE16(pos
, plain_len
);
880 write_pcap_decrypted(wt
, buf
, 24 + 8 + sizeof(*eapol
) +
881 sizeof(*hdr
) + mic_len
+ 2,
882 decrypted
, plain_len
);
884 if (sta
->proto
& WPA_PROTO_RSN
)
885 learn_kde_keys(wt
, bss
, sta
, decrypted
, decrypted_len
,
888 int klen
= bss
->group_cipher
== WPA_CIPHER_TKIP
? 32 : 16;
889 if (decrypted_len
== klen
) {
890 const u8
*rsc
= hdr
->key_rsc
;
892 id
= (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
893 WPA_KEY_INFO_KEY_INDEX_SHIFT
;
894 add_note(wt
, MSG_DEBUG
, "GTK key index %d", id
);
895 wpa_hexdump(MSG_DEBUG
, "GTK", decrypted
,
897 bss
->gtk_len
[id
] = decrypted_len
;
898 os_memcpy(bss
->gtk
[id
], decrypted
, decrypted_len
);
899 bss
->rsc
[id
][0] = rsc
[5];
900 bss
->rsc
[id
][1] = rsc
[4];
901 bss
->rsc
[id
][2] = rsc
[3];
902 bss
->rsc
[id
][3] = rsc
[2];
903 bss
->rsc
[id
][4] = rsc
[1];
904 bss
->rsc
[id
][5] = rsc
[0];
905 wpa_hexdump(MSG_DEBUG
, "RSC", bss
->rsc
[id
], 6);
907 add_note(wt
, MSG_INFO
, "Unexpected WPA Key Data length "
908 "in Group Key msg 1/2 from " MACSTR
,
916 static void rx_data_eapol_key_2_of_2(struct wlantest
*wt
, const u8
*dst
,
917 const u8
*src
, const u8
*data
, size_t len
)
919 struct wlantest_bss
*bss
;
920 struct wlantest_sta
*sta
;
921 const struct ieee802_1x_hdr
*eapol
;
922 const struct wpa_eapol_key
*hdr
;
925 wpa_printf(MSG_DEBUG
, "EAPOL-Key 2/2 " MACSTR
" -> " MACSTR
,
926 MAC2STR(src
), MAC2STR(dst
));
927 bss
= bss_get(wt
, dst
);
930 sta
= sta_get(bss
, src
);
934 eapol
= (const struct ieee802_1x_hdr
*) data
;
935 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
936 if (!is_zero(hdr
->key_rsc
, 8)) {
937 add_note(wt
, MSG_INFO
, "EAPOL-Key 2/2 from " MACSTR
" used "
938 "non-zero Key RSC", MAC2STR(src
));
940 key_info
= WPA_GET_BE16(hdr
->key_info
);
943 add_note(wt
, MSG_DEBUG
,
944 "No PTK known to process EAPOL-Key 2/2");
949 check_mic(sta
->ptk
.kck
, sta
->ptk
.kck_len
, sta
->key_mgmt
,
950 key_info
& WPA_KEY_INFO_TYPE_MASK
,
952 add_note(wt
, MSG_INFO
, "Mismatch in EAPOL-Key 2/2 MIC");
955 add_note(wt
, MSG_DEBUG
, "Valid MIC found in EAPOL-Key 2/2");
959 static void rx_data_eapol_key(struct wlantest
*wt
, const u8
*bssid
,
960 const u8
*sta_addr
, const u8
*dst
,
961 const u8
*src
, const u8
*data
, size_t len
,
964 const struct ieee802_1x_hdr
*eapol
;
965 const struct wpa_eapol_key
*hdr
;
967 u16 key_info
, key_length
, ver
, key_data_length
;
970 struct wlantest_bss
*bss
;
971 struct wlantest_sta
*sta
;
973 bss
= bss_get(wt
, bssid
);
975 sta
= sta_get(bss
, sta_addr
);
977 mic_len
= wpa_mic_len(sta
->key_mgmt
);
980 eapol
= (const struct ieee802_1x_hdr
*) data
;
981 hdr
= (const struct wpa_eapol_key
*) (eapol
+ 1);
983 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key",
984 (const u8
*) hdr
, len
- sizeof(*eapol
));
985 if (len
< sizeof(*hdr
) + mic_len
+ 2) {
986 add_note(wt
, MSG_INFO
, "Too short EAPOL-Key frame from " MACSTR
,
990 mic
= (const u8
*) (hdr
+ 1);
992 if (hdr
->type
== EAPOL_KEY_TYPE_RC4
) {
993 /* TODO: EAPOL-Key RC4 for WEP */
994 wpa_printf(MSG_INFO
, "EAPOL-Key Descriptor Type RC4 from "
995 MACSTR
, MAC2STR(src
));
999 if (hdr
->type
!= EAPOL_KEY_TYPE_RSN
&&
1000 hdr
->type
!= EAPOL_KEY_TYPE_WPA
) {
1001 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Descriptor Type "
1002 "%u from " MACSTR
, hdr
->type
, MAC2STR(src
));
1006 key_info
= WPA_GET_BE16(hdr
->key_info
);
1007 key_length
= WPA_GET_BE16(hdr
->key_length
);
1008 key_data_length
= WPA_GET_BE16(mic
+ mic_len
);
1009 key_data
= mic
+ mic_len
+ 2;
1010 if (key_data
+ key_data_length
> data
+ len
) {
1011 add_note(wt
, MSG_INFO
, "Truncated EAPOL-Key from " MACSTR
,
1015 if (key_data
+ key_data_length
< data
+ len
) {
1016 wpa_hexdump(MSG_DEBUG
, "Extra data after EAPOL-Key Key Data "
1017 "field", key_data
+ key_data_length
,
1018 data
+ len
- key_data
- key_data_length
);
1022 ver
= key_info
& WPA_KEY_INFO_TYPE_MASK
;
1023 wpa_printf(MSG_DEBUG
, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
1025 ver
, key_info
& WPA_KEY_INFO_KEY_TYPE
? 'P' : 'G',
1026 (key_info
& WPA_KEY_INFO_KEY_INDEX_MASK
) >>
1027 WPA_KEY_INFO_KEY_INDEX_SHIFT
,
1028 (key_info
& WPA_KEY_INFO_INSTALL
) ? " Install" : "",
1029 (key_info
& WPA_KEY_INFO_ACK
) ? " ACK" : "",
1030 (key_info
& WPA_KEY_INFO_MIC
) ? " MIC" : "",
1031 (key_info
& WPA_KEY_INFO_SECURE
) ? " Secure" : "",
1032 (key_info
& WPA_KEY_INFO_ERROR
) ? " Error" : "",
1033 (key_info
& WPA_KEY_INFO_REQUEST
) ? " Request" : "",
1034 (key_info
& WPA_KEY_INFO_ENCR_KEY_DATA
) ? " Encr" : "",
1035 (key_info
& WPA_KEY_INFO_SMK_MESSAGE
) ? " SMK" : "",
1038 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1039 ver
!= WPA_KEY_INFO_TYPE_HMAC_SHA1_AES
&&
1040 ver
!= WPA_KEY_INFO_TYPE_AES_128_CMAC
&&
1041 ver
!= WPA_KEY_INFO_TYPE_AKM_DEFINED
) {
1042 wpa_printf(MSG_INFO
, "Unsupported EAPOL-Key Key Descriptor "
1043 "Version %u from " MACSTR
, ver
, MAC2STR(src
));
1047 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Replay Counter",
1048 hdr
->replay_counter
, WPA_REPLAY_COUNTER_LEN
);
1049 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Nonce",
1050 hdr
->key_nonce
, WPA_NONCE_LEN
);
1051 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key IV",
1053 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key RSC",
1054 hdr
->key_rsc
, WPA_KEY_RSC_LEN
);
1055 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key MIC",
1057 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Key Key Data",
1058 key_data
, key_data_length
);
1060 if (hdr
->type
== EAPOL_KEY_TYPE_RSN
&&
1061 (key_info
& (WPA_KEY_INFO_KEY_INDEX_MASK
| BIT(14) | BIT(15))) !=
1063 wpa_printf(MSG_INFO
, "RSN EAPOL-Key with non-zero reserved "
1064 "Key Info bits 0x%x from " MACSTR
,
1065 key_info
, MAC2STR(src
));
1068 if (hdr
->type
== EAPOL_KEY_TYPE_WPA
&&
1069 (key_info
& (WPA_KEY_INFO_ENCR_KEY_DATA
|
1070 WPA_KEY_INFO_SMK_MESSAGE
|BIT(14) | BIT(15))) != 0) {
1071 wpa_printf(MSG_INFO
, "WPA EAPOL-Key with non-zero reserved "
1072 "Key Info bits 0x%x from " MACSTR
,
1073 key_info
, MAC2STR(src
));
1076 if (key_length
> 32) {
1077 wpa_printf(MSG_INFO
, "EAPOL-Key with invalid Key Length %d "
1078 "from " MACSTR
, key_length
, MAC2STR(src
));
1081 if (ver
!= WPA_KEY_INFO_TYPE_HMAC_MD5_RC4
&&
1082 !is_zero(hdr
->key_iv
, 16)) {
1083 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key IV "
1084 "(reserved with ver=%d) field from " MACSTR
,
1086 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key IV (reserved)",
1090 if (!is_zero(hdr
->key_id
, 8)) {
1091 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key ID "
1092 "(reserved) field from " MACSTR
, MAC2STR(src
));
1093 wpa_hexdump(MSG_INFO
, "EAPOL-Key Key ID (reserved)",
1097 if (hdr
->key_rsc
[6] || hdr
->key_rsc
[7]) {
1098 wpa_printf(MSG_INFO
, "EAPOL-Key with non-zero Key RSC octets "
1099 "(last two are unused)" MACSTR
, MAC2STR(src
));
1102 if (key_info
& (WPA_KEY_INFO_ERROR
| WPA_KEY_INFO_REQUEST
))
1105 if (key_info
& WPA_KEY_INFO_SMK_MESSAGE
)
1108 if (key_info
& WPA_KEY_INFO_KEY_TYPE
) {
1109 /* 4-Way Handshake */
1110 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1113 WPA_KEY_INFO_INSTALL
)) {
1114 case WPA_KEY_INFO_ACK
:
1115 rx_data_eapol_key_1_of_4(wt
, dst
, src
, data
, len
);
1117 case WPA_KEY_INFO_MIC
:
1118 if (key_data_length
== 0)
1119 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1122 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1125 case WPA_KEY_INFO_MIC
| WPA_KEY_INFO_ACK
|
1126 WPA_KEY_INFO_INSTALL
:
1127 /* WPA does not include Secure bit in 3/4 */
1128 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1130 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1131 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1132 case WPA_KEY_INFO_SECURE
|
1133 WPA_KEY_INFO_ACK
| WPA_KEY_INFO_INSTALL
:
1134 rx_data_eapol_key_3_of_4(wt
, dst
, src
, data
, len
);
1136 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1137 case WPA_KEY_INFO_SECURE
:
1138 if (key_data_length
== 0)
1139 rx_data_eapol_key_4_of_4(wt
, dst
, src
, data
,
1142 rx_data_eapol_key_2_of_4(wt
, dst
, src
, data
,
1146 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1150 /* Group Key Handshake */
1151 switch (key_info
& (WPA_KEY_INFO_SECURE
|
1153 WPA_KEY_INFO_ACK
)) {
1154 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
|
1156 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_ACK
:
1157 rx_data_eapol_key_1_of_2(wt
, dst
, src
, data
, len
);
1159 case WPA_KEY_INFO_SECURE
| WPA_KEY_INFO_MIC
:
1160 case WPA_KEY_INFO_SECURE
:
1161 rx_data_eapol_key_2_of_2(wt
, dst
, src
, data
, len
);
1164 wpa_printf(MSG_DEBUG
, "Unsupported EAPOL-Key frame");
1171 void rx_data_eapol(struct wlantest
*wt
, const u8
*bssid
, const u8
*sta_addr
,
1172 const u8
*dst
, const u8
*src
,
1173 const u8
*data
, size_t len
, int prot
)
1175 const struct ieee802_1x_hdr
*hdr
;
1179 wpa_hexdump(MSG_EXCESSIVE
, "EAPOL", data
, len
);
1180 if (len
< sizeof(*hdr
)) {
1181 wpa_printf(MSG_INFO
, "Too short EAPOL frame from " MACSTR
,
1186 hdr
= (const struct ieee802_1x_hdr
*) data
;
1187 length
= be_to_host16(hdr
->length
);
1188 wpa_printf(MSG_DEBUG
, "RX EAPOL: " MACSTR
" -> " MACSTR
"%s ver=%u "
1190 MAC2STR(src
), MAC2STR(dst
), prot
? " Prot" : "",
1191 hdr
->version
, hdr
->type
, length
);
1192 if (hdr
->version
< 1 || hdr
->version
> 3) {
1193 wpa_printf(MSG_INFO
, "Unexpected EAPOL version %u from "
1194 MACSTR
, hdr
->version
, MAC2STR(src
));
1196 if (sizeof(*hdr
) + length
> len
) {
1197 wpa_printf(MSG_INFO
, "Truncated EAPOL frame from " MACSTR
,
1202 if (sizeof(*hdr
) + length
< len
) {
1203 wpa_printf(MSG_INFO
, "EAPOL frame with %d extra bytes",
1204 (int) (len
- sizeof(*hdr
) - length
));
1206 p
= (const u8
*) (hdr
+ 1);
1208 switch (hdr
->type
) {
1209 case IEEE802_1X_TYPE_EAP_PACKET
:
1210 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - EAP packet", p
, length
);
1212 case IEEE802_1X_TYPE_EAPOL_START
:
1213 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Start", p
, length
);
1215 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1216 wpa_hexdump(MSG_MSGDUMP
, "EAPOL-Logoff", p
, length
);
1218 case IEEE802_1X_TYPE_EAPOL_KEY
:
1219 rx_data_eapol_key(wt
, bssid
, sta_addr
, dst
, src
, data
,
1220 sizeof(*hdr
) + length
, prot
);
1222 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1223 wpa_hexdump(MSG_MSGDUMP
, "EAPOL - Encapsulated ASF alert",
1227 wpa_hexdump(MSG_MSGDUMP
, "Unknown EAPOL payload", p
, length
);