]> git.ipfire.org Git - thirdparty/hostap.git/blob - wlantest/rx_eapol.c
Declare wpa_debug_* variables in src/utils/wpa_debug.h
[thirdparty/hostap.git] / wlantest / rx_eapol.c
1 /*
2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
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"
20 #include "wlantest.h"
21
22
23 static int is_zero(const u8 *buf, size_t len)
24 {
25 size_t i;
26 for (i = 0; i < len; i++) {
27 if (buf[i])
28 return 0;
29 }
30 return 1;
31 }
32
33
34 static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
35 {
36 u8 *buf;
37 int ret = -1;
38 struct ieee802_1x_hdr *hdr;
39 struct wpa_eapol_key *key;
40 u8 rx_mic[16];
41
42 buf = os_malloc(len);
43 if (buf == NULL)
44 return -1;
45 os_memcpy(buf, data, len);
46 hdr = (struct ieee802_1x_hdr *) buf;
47 key = (struct wpa_eapol_key *) (hdr + 1);
48
49 os_memcpy(rx_mic, key->key_mic, 16);
50 os_memset(key->key_mic, 0, 16);
51
52 if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
53 os_memcmp(rx_mic, key->key_mic, 16) == 0)
54 ret = 0;
55
56 os_free(buf);
57
58 return ret;
59 }
60
61
62 static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
63 const u8 *src, const u8 *data, size_t len)
64 {
65 struct wlantest_bss *bss;
66 struct wlantest_sta *sta;
67 const struct ieee802_1x_hdr *eapol;
68 const struct wpa_eapol_key *hdr;
69
70 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
71 MAC2STR(src), MAC2STR(dst));
72 bss = bss_get(wt, src);
73 if (bss == NULL)
74 return;
75 sta = sta_get(bss, dst);
76 if (sta == NULL)
77 return;
78
79 eapol = (const struct ieee802_1x_hdr *) data;
80 hdr = (const struct wpa_eapol_key *) (eapol + 1);
81 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
82 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
83 " used zero nonce", MAC2STR(src));
84 }
85 if (!is_zero(hdr->key_rsc, 8)) {
86 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
87 " used non-zero Key RSC", MAC2STR(src));
88 }
89 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
90 }
91
92
93 static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
94 struct wlantest_sta *sta, u16 ver,
95 const u8 *data, size_t len,
96 struct wlantest_pmk *pmk)
97 {
98 struct wpa_ptk ptk;
99 size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48;
100 wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
101 "Pairwise key expansion",
102 bss->bssid, sta->addr, sta->anonce, sta->snonce,
103 (u8 *) &ptk, ptk_len,
104 wpa_key_mgmt_sha256(sta->key_mgmt));
105 if (check_mic(ptk.kck, ver, data, len) < 0)
106 return -1;
107
108 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
109 MAC2STR(sta->addr), MAC2STR(bss->bssid));
110 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
111 if (sta->ptk_set) {
112 /*
113 * Rekeying - use new PTK for EAPOL-Key frames, but continue
114 * using the old PTK for frame decryption.
115 */
116 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
117 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
118 wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16);
119 wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16);
120 wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16);
121 if (ptk_len > 48)
122 wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2,
123 16);
124 sta->tptk_set = 1;
125 return 0;
126 }
127 add_note(wt, MSG_DEBUG, "Derived new PTK");
128 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
129 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
130 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
131 wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
132 if (ptk_len > 48)
133 wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16);
134 sta->ptk_set = 1;
135 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
136 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
137 return 0;
138 }
139
140
141 static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
142 struct wlantest_sta *sta, u16 ver,
143 const u8 *data, size_t len)
144 {
145 struct wlantest_pmk *pmk;
146
147 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR,
148 MAC2STR(sta->addr));
149 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
150 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
151 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
152 return;
153 }
154
155 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
156 wpa_printf(MSG_DEBUG, "Try global PMK");
157 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
158 return;
159 }
160
161 if (!sta->ptk_set) {
162 struct wlantest_ptk *ptk;
163 int prev_level = wpa_debug_level;
164
165 wpa_debug_level = MSG_WARNING;
166 dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
167 if (check_mic(ptk->ptk.kck, ver, data, len) < 0)
168 continue;
169 wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
170 MACSTR " BSSID " MACSTR,
171 MAC2STR(sta->addr), MAC2STR(bss->bssid));
172 add_note(wt, MSG_DEBUG, "Using pre-set PTK");
173 os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
174 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
175 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
176 wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
177 if (ptk->ptk_len > 48)
178 wpa_hexdump(MSG_DEBUG, "PTK:TK2",
179 sta->ptk.u.tk2, 16);
180 sta->ptk_set = 1;
181 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
182 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
183 }
184 wpa_debug_level = prev_level;
185 }
186
187 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
188 }
189
190
191 static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
192 const u8 *src, const u8 *data, size_t len)
193 {
194 struct wlantest_bss *bss;
195 struct wlantest_sta *sta;
196 const struct ieee802_1x_hdr *eapol;
197 const struct wpa_eapol_key *hdr;
198 const u8 *key_data, *kck;
199 u16 key_info, key_data_len;
200 struct wpa_eapol_ie_parse ie;
201
202 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
203 MAC2STR(src), MAC2STR(dst));
204 bss = bss_get(wt, dst);
205 if (bss == NULL)
206 return;
207 sta = sta_get(bss, src);
208 if (sta == NULL)
209 return;
210
211 eapol = (const struct ieee802_1x_hdr *) data;
212 hdr = (const struct wpa_eapol_key *) (eapol + 1);
213 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
214 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
215 " used zero nonce", MAC2STR(src));
216 }
217 if (!is_zero(hdr->key_rsc, 8)) {
218 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
219 " used non-zero Key RSC", MAC2STR(src));
220 }
221 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
222 key_info = WPA_GET_BE16(hdr->key_info);
223 key_data_len = WPA_GET_BE16(hdr->key_data_length);
224 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
225
226 if (!sta->ptk_set && !sta->tptk_set) {
227 add_note(wt, MSG_DEBUG,
228 "No PTK known to process EAPOL-Key 2/4");
229 return;
230 }
231
232 kck = sta->ptk.kck;
233 if (sta->tptk_set) {
234 add_note(wt, MSG_DEBUG,
235 "Use TPTK for validation EAPOL-Key MIC");
236 kck = sta->tptk.kck;
237 }
238 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
239 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
240 return;
241 }
242 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
243
244 key_data = (const u8 *) (hdr + 1);
245
246 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
247 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
248 return;
249 }
250
251 if (ie.wpa_ie) {
252 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
253 ie.wpa_ie, ie.wpa_ie_len);
254 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
255 struct ieee802_11_elems elems;
256 add_note(wt, MSG_INFO,
257 "Mismatch in WPA IE between EAPOL-Key 2/4 "
258 "and (Re)Association Request from " MACSTR,
259 MAC2STR(sta->addr));
260 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
261 ie.wpa_ie, ie.wpa_ie_len);
262 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
263 "Request",
264 sta->rsnie,
265 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
266 /*
267 * The sniffer may have missed (Re)Association
268 * Request, so try to survive with the information from
269 * EAPOL-Key.
270 */
271 os_memset(&elems, 0, sizeof(elems));
272 elems.wpa_ie = ie.wpa_ie + 2;
273 elems.wpa_ie_len = ie.wpa_ie_len - 2;
274 wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
275 "IE in EAPOL-Key 2/4");
276 sta_update_assoc(sta, &elems);
277 }
278 }
279
280 if (ie.rsn_ie) {
281 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
282 ie.rsn_ie, ie.rsn_ie_len);
283 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
284 struct ieee802_11_elems elems;
285 add_note(wt, MSG_INFO,
286 "Mismatch in RSN IE between EAPOL-Key 2/4 "
287 "and (Re)Association Request from " MACSTR,
288 MAC2STR(sta->addr));
289 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
290 ie.rsn_ie, ie.rsn_ie_len);
291 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
292 "Request",
293 sta->rsnie,
294 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
295 /*
296 * The sniffer may have missed (Re)Association
297 * Request, so try to survive with the information from
298 * EAPOL-Key.
299 */
300 os_memset(&elems, 0, sizeof(elems));
301 elems.rsn_ie = ie.rsn_ie + 2;
302 elems.rsn_ie_len = ie.rsn_ie_len - 2;
303 wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
304 "IE in EAPOL-Key 2/4");
305 sta_update_assoc(sta, &elems);
306 }
307 }
308 }
309
310
311 static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
312 const struct wpa_eapol_key *hdr,
313 size_t *len)
314 {
315 u8 ek[32], *buf;
316 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
317
318 buf = os_malloc(keydatalen);
319 if (buf == NULL)
320 return NULL;
321
322 os_memcpy(ek, hdr->key_iv, 16);
323 os_memcpy(ek + 16, kek, 16);
324 os_memcpy(buf, hdr + 1, keydatalen);
325 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
326 add_note(wt, MSG_INFO, "RC4 failed");
327 os_free(buf);
328 return NULL;
329 }
330
331 *len = keydatalen;
332 return buf;
333 }
334
335
336 static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
337 const struct wpa_eapol_key *hdr,
338 size_t *len)
339 {
340 u8 *buf;
341 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
342
343 if (keydatalen % 8) {
344 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
345 keydatalen);
346 return NULL;
347 }
348 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
349 buf = os_malloc(keydatalen);
350 if (buf == NULL)
351 return NULL;
352 if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
353 os_free(buf);
354 add_note(wt, MSG_INFO,
355 "AES unwrap failed - could not decrypt EAPOL-Key "
356 "key data");
357 return NULL;
358 }
359
360 *len = keydatalen;
361 return buf;
362 }
363
364
365 static u8 * decrypt_eapol_key_data(struct wlantest *wt, const u8 *kek, u16 ver,
366 const struct wpa_eapol_key *hdr,
367 size_t *len)
368 {
369 switch (ver) {
370 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
371 return decrypt_eapol_key_data_rc4(wt, kek, hdr, len);
372 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
373 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
374 return decrypt_eapol_key_data_aes(wt, kek, hdr, len);
375 default:
376 add_note(wt, MSG_INFO,
377 "Unsupported EAPOL-Key Key Descriptor Version %u",
378 ver);
379 return NULL;
380 }
381 }
382
383
384 static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
385 struct wlantest_sta *sta,
386 const u8 *buf, size_t len, const u8 *rsc)
387 {
388 struct wpa_eapol_ie_parse ie;
389
390 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
391 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
392 return;
393 }
394
395 if (ie.wpa_ie) {
396 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
397 ie.wpa_ie, ie.wpa_ie_len);
398 }
399
400 if (ie.rsn_ie) {
401 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
402 ie.rsn_ie, ie.rsn_ie_len);
403 }
404
405 if (ie.gtk) {
406 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
407 ie.gtk, ie.gtk_len);
408 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
409 int id;
410 id = ie.gtk[0] & 0x03;
411 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
412 id, !!(ie.gtk[0] & 0x04));
413 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
414 add_note(wt, MSG_INFO,
415 "GTK KDE: Reserved field set: "
416 "%02x %02x", ie.gtk[0], ie.gtk[1]);
417 }
418 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
419 ie.gtk_len - 2);
420 bss->gtk_len[id] = ie.gtk_len - 2;
421 sta->gtk_len = ie.gtk_len - 2;
422 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
423 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
424 bss->rsc[id][0] = rsc[5];
425 bss->rsc[id][1] = rsc[4];
426 bss->rsc[id][2] = rsc[3];
427 bss->rsc[id][3] = rsc[2];
428 bss->rsc[id][4] = rsc[1];
429 bss->rsc[id][5] = rsc[0];
430 bss->gtk_idx = id;
431 sta->gtk_idx = id;
432 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
433 } else {
434 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
435 (unsigned) ie.gtk_len);
436 }
437 }
438
439 if (ie.igtk) {
440 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
441 ie.igtk, ie.igtk_len);
442 if (ie.igtk_len == 24) {
443 u16 id;
444 id = WPA_GET_LE16(ie.igtk);
445 if (id > 5) {
446 add_note(wt, MSG_INFO,
447 "Unexpected IGTK KeyID %u", id);
448 } else {
449 const u8 *ipn;
450 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
451 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
452 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
453 16);
454 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
455 bss->igtk_set[id] = 1;
456 ipn = ie.igtk + 2;
457 bss->ipn[id][0] = ipn[5];
458 bss->ipn[id][1] = ipn[4];
459 bss->ipn[id][2] = ipn[3];
460 bss->ipn[id][3] = ipn[2];
461 bss->ipn[id][4] = ipn[1];
462 bss->ipn[id][5] = ipn[0];
463 bss->igtk_idx = id;
464 }
465 } else {
466 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
467 (unsigned) ie.igtk_len);
468 }
469 }
470 }
471
472
473 static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
474 const u8 *src, const u8 *data, size_t len)
475 {
476 struct wlantest_bss *bss;
477 struct wlantest_sta *sta;
478 const struct ieee802_1x_hdr *eapol;
479 const struct wpa_eapol_key *hdr;
480 const u8 *key_data, *kck, *kek;
481 int recalc = 0;
482 u16 key_info, ver;
483 u8 *decrypted_buf = NULL;
484 const u8 *decrypted;
485 size_t decrypted_len = 0;
486 struct wpa_eapol_ie_parse ie;
487
488 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
489 MAC2STR(src), MAC2STR(dst));
490 bss = bss_get(wt, src);
491 if (bss == NULL)
492 return;
493 sta = sta_get(bss, dst);
494 if (sta == NULL)
495 return;
496
497 eapol = (const struct ieee802_1x_hdr *) data;
498 hdr = (const struct wpa_eapol_key *) (eapol + 1);
499 key_info = WPA_GET_BE16(hdr->key_info);
500
501 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
502 add_note(wt, MSG_INFO,
503 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
504 recalc = 1;
505 }
506 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
507 if (recalc) {
508 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
509 data, len);
510 }
511
512 if (!sta->ptk_set && !sta->tptk_set) {
513 add_note(wt, MSG_DEBUG,
514 "No PTK known to process EAPOL-Key 3/4");
515 return;
516 }
517
518 kek = sta->ptk.kek;
519 kck = sta->ptk.kck;
520 if (sta->tptk_set) {
521 add_note(wt, MSG_DEBUG,
522 "Use TPTK for validation EAPOL-Key MIC");
523 kck = sta->tptk.kck;
524 kek = sta->tptk.kek;
525 }
526 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
527 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
528 return;
529 }
530 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
531
532 key_data = (const u8 *) (hdr + 1);
533 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
534 if (sta->proto & WPA_PROTO_RSN)
535 add_note(wt, MSG_INFO,
536 "EAPOL-Key 3/4 without EncrKeyData bit");
537 decrypted = key_data;
538 decrypted_len = WPA_GET_BE16(hdr->key_data_length);
539 } else {
540 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
541 decrypted_buf = decrypt_eapol_key_data(wt, kek, ver, hdr,
542 &decrypted_len);
543 if (decrypted_buf == NULL) {
544 add_note(wt, MSG_INFO,
545 "Failed to decrypt EAPOL-Key Key Data");
546 return;
547 }
548 decrypted = decrypted_buf;
549 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
550 decrypted, decrypted_len);
551 }
552 if (wt->write_pcap_dumper && decrypted != key_data) {
553 /* Fill in a dummy Data frame header */
554 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
555 struct ieee80211_hdr *h;
556 struct wpa_eapol_key *k;
557 const u8 *p;
558 u8 *pos;
559 size_t plain_len;
560
561 plain_len = decrypted_len;
562 p = decrypted;
563 while (p + 1 < decrypted + decrypted_len) {
564 if (p[0] == 0xdd && p[1] == 0x00) {
565 /* Remove padding */
566 plain_len = p - decrypted;
567 break;
568 }
569 p += 2 + p[1];
570 }
571
572 os_memset(buf, 0, sizeof(buf));
573 h = (struct ieee80211_hdr *) buf;
574 h->frame_control = host_to_le16(0x0208);
575 os_memcpy(h->addr1, dst, ETH_ALEN);
576 os_memcpy(h->addr2, src, ETH_ALEN);
577 os_memcpy(h->addr3, src, ETH_ALEN);
578 pos = (u8 *) (h + 1);
579 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
580 pos += 8;
581 os_memcpy(pos, eapol, sizeof(*eapol));
582 pos += sizeof(*eapol);
583 os_memcpy(pos, hdr, sizeof(*hdr));
584 k = (struct wpa_eapol_key *) pos;
585 WPA_PUT_BE16(k->key_info,
586 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
587 WPA_PUT_BE16(k->key_data_length, plain_len);
588 write_pcap_decrypted(wt, buf, sizeof(buf),
589 decrypted, plain_len);
590 }
591
592 if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
593 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
594 os_free(decrypted_buf);
595 return;
596 }
597
598 if ((ie.wpa_ie &&
599 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
600 (ie.wpa_ie == NULL && bss->wpaie[0])) {
601 add_note(wt, MSG_INFO,
602 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
603 "Beacon/Probe Response from " MACSTR,
604 MAC2STR(bss->bssid));
605 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
606 ie.wpa_ie, ie.wpa_ie_len);
607 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
608 "Response",
609 bss->wpaie,
610 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
611 }
612
613 if ((ie.rsn_ie &&
614 os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
615 (ie.rsn_ie == NULL && bss->rsnie[0])) {
616 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
617 "3/4 and Beacon/Probe Response from " MACSTR,
618 MAC2STR(bss->bssid));
619 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
620 ie.rsn_ie, ie.rsn_ie_len);
621 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
622 "Request",
623 bss->rsnie,
624 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
625 }
626
627 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
628 os_free(decrypted_buf);
629 }
630
631
632 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
633 const u8 *src, const u8 *data, size_t len)
634 {
635 struct wlantest_bss *bss;
636 struct wlantest_sta *sta;
637 const struct ieee802_1x_hdr *eapol;
638 const struct wpa_eapol_key *hdr;
639 u16 key_info;
640 const u8 *kck;
641
642 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
643 MAC2STR(src), MAC2STR(dst));
644 bss = bss_get(wt, dst);
645 if (bss == NULL)
646 return;
647 sta = sta_get(bss, src);
648 if (sta == NULL)
649 return;
650
651 eapol = (const struct ieee802_1x_hdr *) data;
652 hdr = (const struct wpa_eapol_key *) (eapol + 1);
653 if (!is_zero(hdr->key_rsc, 8)) {
654 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
655 "non-zero Key RSC", MAC2STR(src));
656 }
657 key_info = WPA_GET_BE16(hdr->key_info);
658
659 if (!sta->ptk_set && !sta->tptk_set) {
660 add_note(wt, MSG_DEBUG,
661 "No PTK known to process EAPOL-Key 4/4");
662 return;
663 }
664
665 kck = sta->ptk.kck;
666 if (sta->tptk_set) {
667 add_note(wt, MSG_DEBUG,
668 "Use TPTK for validation EAPOL-Key MIC");
669 kck = sta->tptk.kck;
670 }
671 if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
672 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
673 return;
674 }
675 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
676 if (sta->tptk_set) {
677 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
678 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
679 sta->ptk_set = 1;
680 sta->tptk_set = 0;
681 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
682 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
683 }
684 }
685
686
687 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
688 const u8 *src, const u8 *data, size_t len)
689 {
690 struct wlantest_bss *bss;
691 struct wlantest_sta *sta;
692 const struct ieee802_1x_hdr *eapol;
693 const struct wpa_eapol_key *hdr;
694 u16 key_info, ver;
695 u8 *decrypted;
696 size_t decrypted_len = 0;
697
698 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
699 MAC2STR(src), MAC2STR(dst));
700 bss = bss_get(wt, src);
701 if (bss == NULL)
702 return;
703 sta = sta_get(bss, dst);
704 if (sta == NULL)
705 return;
706
707 eapol = (const struct ieee802_1x_hdr *) data;
708 hdr = (const struct wpa_eapol_key *) (eapol + 1);
709 key_info = WPA_GET_BE16(hdr->key_info);
710
711 if (!sta->ptk_set) {
712 add_note(wt, MSG_DEBUG,
713 "No PTK known to process EAPOL-Key 1/2");
714 return;
715 }
716
717 if (sta->ptk_set &&
718 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
719 data, len) < 0) {
720 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
721 return;
722 }
723 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
724
725 if (sta->proto & WPA_PROTO_RSN &&
726 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
727 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
728 return;
729 }
730 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
731 decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, ver, hdr,
732 &decrypted_len);
733 if (decrypted == NULL) {
734 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
735 return;
736 }
737 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
738 decrypted, decrypted_len);
739 if (wt->write_pcap_dumper) {
740 /* Fill in a dummy Data frame header */
741 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
742 struct ieee80211_hdr *h;
743 struct wpa_eapol_key *k;
744 u8 *pos;
745 size_t plain_len;
746
747 plain_len = decrypted_len;
748 pos = decrypted;
749 while (pos + 1 < decrypted + decrypted_len) {
750 if (pos[0] == 0xdd && pos[1] == 0x00) {
751 /* Remove padding */
752 plain_len = pos - decrypted;
753 break;
754 }
755 pos += 2 + pos[1];
756 }
757
758 os_memset(buf, 0, sizeof(buf));
759 h = (struct ieee80211_hdr *) buf;
760 h->frame_control = host_to_le16(0x0208);
761 os_memcpy(h->addr1, dst, ETH_ALEN);
762 os_memcpy(h->addr2, src, ETH_ALEN);
763 os_memcpy(h->addr3, src, ETH_ALEN);
764 pos = (u8 *) (h + 1);
765 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
766 pos += 8;
767 os_memcpy(pos, eapol, sizeof(*eapol));
768 pos += sizeof(*eapol);
769 os_memcpy(pos, hdr, sizeof(*hdr));
770 k = (struct wpa_eapol_key *) pos;
771 WPA_PUT_BE16(k->key_info,
772 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
773 WPA_PUT_BE16(k->key_data_length, plain_len);
774 write_pcap_decrypted(wt, buf, sizeof(buf),
775 decrypted, plain_len);
776 }
777 if (sta->proto & WPA_PROTO_RSN)
778 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
779 hdr->key_rsc);
780 else {
781 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
782 if (decrypted_len == klen) {
783 const u8 *rsc = hdr->key_rsc;
784 int id;
785 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
786 WPA_KEY_INFO_KEY_INDEX_SHIFT;
787 add_note(wt, MSG_DEBUG, "GTK key index %d", id);
788 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
789 decrypted_len);
790 bss->gtk_len[id] = decrypted_len;
791 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
792 bss->rsc[id][0] = rsc[5];
793 bss->rsc[id][1] = rsc[4];
794 bss->rsc[id][2] = rsc[3];
795 bss->rsc[id][3] = rsc[2];
796 bss->rsc[id][4] = rsc[1];
797 bss->rsc[id][5] = rsc[0];
798 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
799 } else {
800 add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
801 "in Group Key msg 1/2 from " MACSTR,
802 MAC2STR(src));
803 }
804 }
805 os_free(decrypted);
806 }
807
808
809 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
810 const u8 *src, const u8 *data, size_t len)
811 {
812 struct wlantest_bss *bss;
813 struct wlantest_sta *sta;
814 const struct ieee802_1x_hdr *eapol;
815 const struct wpa_eapol_key *hdr;
816 u16 key_info;
817
818 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
819 MAC2STR(src), MAC2STR(dst));
820 bss = bss_get(wt, dst);
821 if (bss == NULL)
822 return;
823 sta = sta_get(bss, src);
824 if (sta == NULL)
825 return;
826
827 eapol = (const struct ieee802_1x_hdr *) data;
828 hdr = (const struct wpa_eapol_key *) (eapol + 1);
829 if (!is_zero(hdr->key_rsc, 8)) {
830 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
831 "non-zero Key RSC", MAC2STR(src));
832 }
833 key_info = WPA_GET_BE16(hdr->key_info);
834
835 if (!sta->ptk_set) {
836 add_note(wt, MSG_DEBUG,
837 "No PTK known to process EAPOL-Key 2/2");
838 return;
839 }
840
841 if (sta->ptk_set &&
842 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
843 data, len) < 0) {
844 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
845 return;
846 }
847 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
848 }
849
850
851 static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
852 const u8 *src, const u8 *data, size_t len,
853 int prot)
854 {
855 const struct ieee802_1x_hdr *eapol;
856 const struct wpa_eapol_key *hdr;
857 const u8 *key_data;
858 u16 key_info, key_length, ver, key_data_length;
859
860 eapol = (const struct ieee802_1x_hdr *) data;
861 hdr = (const struct wpa_eapol_key *) (eapol + 1);
862
863 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
864 (const u8 *) hdr, len - sizeof(*eapol));
865 if (len < sizeof(*hdr)) {
866 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
867 MAC2STR(src));
868 return;
869 }
870
871 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
872 /* TODO: EAPOL-Key RC4 for WEP */
873 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
874 MACSTR, MAC2STR(src));
875 return;
876 }
877
878 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
879 hdr->type != EAPOL_KEY_TYPE_WPA) {
880 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
881 "%u from " MACSTR, hdr->type, MAC2STR(src));
882 return;
883 }
884
885 key_info = WPA_GET_BE16(hdr->key_info);
886 key_length = WPA_GET_BE16(hdr->key_length);
887 key_data_length = WPA_GET_BE16(hdr->key_data_length);
888 key_data = (const u8 *) (hdr + 1);
889 if (key_data + key_data_length > data + len) {
890 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
891 MAC2STR(src));
892 return;
893 }
894 if (key_data + key_data_length < data + len) {
895 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
896 "field", key_data + key_data_length,
897 data + len - key_data - key_data_length);
898 }
899
900
901 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
902 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
903 "datalen=%u",
904 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
905 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
906 WPA_KEY_INFO_KEY_INDEX_SHIFT,
907 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
908 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
909 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
910 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
911 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
912 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
913 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
914 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
915 key_data_length);
916
917 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
918 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
919 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
920 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
921 "Version %u from " MACSTR, ver, MAC2STR(src));
922 return;
923 }
924
925 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
926 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
927 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
928 hdr->key_nonce, WPA_NONCE_LEN);
929 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
930 hdr->key_iv, 16);
931 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
932 hdr->key_rsc, WPA_KEY_RSC_LEN);
933 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
934 hdr->key_mic, 16);
935 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
936 key_data, key_data_length);
937
938 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
939 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
940 0) {
941 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
942 "Key Info bits 0x%x from " MACSTR,
943 key_info, MAC2STR(src));
944 }
945
946 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
947 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
948 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
949 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
950 "Key Info bits 0x%x from " MACSTR,
951 key_info, MAC2STR(src));
952 }
953
954 if (key_length > 32) {
955 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
956 "from " MACSTR, key_length, MAC2STR(src));
957 }
958
959 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
960 !is_zero(hdr->key_iv, 16)) {
961 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
962 "(reserved with ver=%d) field from " MACSTR,
963 ver, MAC2STR(src));
964 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
965 hdr->key_iv, 16);
966 }
967
968 if (!is_zero(hdr->key_id, 8)) {
969 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
970 "(reserved) field from " MACSTR, MAC2STR(src));
971 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
972 hdr->key_id, 8);
973 }
974
975 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
976 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
977 "(last two are unused)" MACSTR, MAC2STR(src));
978 }
979
980 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
981 return;
982
983 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
984 return;
985
986 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
987 /* 4-Way Handshake */
988 switch (key_info & (WPA_KEY_INFO_SECURE |
989 WPA_KEY_INFO_MIC |
990 WPA_KEY_INFO_ACK |
991 WPA_KEY_INFO_INSTALL)) {
992 case WPA_KEY_INFO_ACK:
993 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
994 break;
995 case WPA_KEY_INFO_MIC:
996 if (key_data_length == 0)
997 rx_data_eapol_key_4_of_4(wt, dst, src, data,
998 len);
999 else
1000 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1001 len);
1002 break;
1003 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1004 WPA_KEY_INFO_INSTALL:
1005 /* WPA does not include Secure bit in 3/4 */
1006 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1007 break;
1008 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1009 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1010 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1011 break;
1012 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1013 if (key_data_length == 0)
1014 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1015 len);
1016 else
1017 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1018 len);
1019 break;
1020 default:
1021 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1022 break;
1023 }
1024 } else {
1025 /* Group Key Handshake */
1026 switch (key_info & (WPA_KEY_INFO_SECURE |
1027 WPA_KEY_INFO_MIC |
1028 WPA_KEY_INFO_ACK)) {
1029 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1030 WPA_KEY_INFO_ACK:
1031 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1032 break;
1033 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1034 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1035 break;
1036 default:
1037 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1038 break;
1039 }
1040 }
1041 }
1042
1043
1044 void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
1045 const u8 *data, size_t len, int prot)
1046 {
1047 const struct ieee802_1x_hdr *hdr;
1048 u16 length;
1049 const u8 *p;
1050
1051 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1052 if (len < sizeof(*hdr)) {
1053 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1054 MAC2STR(src));
1055 return;
1056 }
1057
1058 hdr = (const struct ieee802_1x_hdr *) data;
1059 length = be_to_host16(hdr->length);
1060 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1061 "type=%u len=%u",
1062 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1063 hdr->version, hdr->type, length);
1064 if (hdr->version < 1 || hdr->version > 3) {
1065 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1066 MACSTR, hdr->version, MAC2STR(src));
1067 }
1068 if (sizeof(*hdr) + length > len) {
1069 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1070 MAC2STR(src));
1071 return;
1072 }
1073
1074 if (sizeof(*hdr) + length < len) {
1075 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1076 (int) (len - sizeof(*hdr) - length));
1077 }
1078 p = (const u8 *) (hdr + 1);
1079
1080 switch (hdr->type) {
1081 case IEEE802_1X_TYPE_EAP_PACKET:
1082 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1083 break;
1084 case IEEE802_1X_TYPE_EAPOL_START:
1085 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1086 break;
1087 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1088 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1089 break;
1090 case IEEE802_1X_TYPE_EAPOL_KEY:
1091 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
1092 prot);
1093 break;
1094 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1095 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1096 p, length);
1097 break;
1098 default:
1099 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
1100 break;
1101 }
1102 }