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