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