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