Preparations for variable length KCK and KEK
[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 (Re)Association "
665                             "Request",
666                             bss->rsnie,
667                             bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
668         }
669
670         learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
671         os_free(decrypted_buf);
672 }
673
674
675 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
676                                      const u8 *src, const u8 *data, size_t len)
677 {
678         struct wlantest_bss *bss;
679         struct wlantest_sta *sta;
680         const struct ieee802_1x_hdr *eapol;
681         const struct wpa_eapol_key *hdr;
682         u16 key_info;
683         const u8 *kck;
684         size_t kck_len;
685
686         wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
687                    MAC2STR(src), MAC2STR(dst));
688         bss = bss_get(wt, dst);
689         if (bss == NULL)
690                 return;
691         sta = sta_get(bss, src);
692         if (sta == NULL)
693                 return;
694
695         eapol = (const struct ieee802_1x_hdr *) data;
696         hdr = (const struct wpa_eapol_key *) (eapol + 1);
697         if (!is_zero(hdr->key_rsc, 8)) {
698                 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
699                          "non-zero Key RSC", MAC2STR(src));
700         }
701         key_info = WPA_GET_BE16(hdr->key_info);
702
703         if (!sta->ptk_set && !sta->tptk_set) {
704                 add_note(wt, MSG_DEBUG,
705                          "No PTK known to process EAPOL-Key 4/4");
706                 return;
707         }
708
709         kck = sta->ptk.kck;
710         kck_len = sta->ptk.kck_len;
711         if (sta->tptk_set) {
712                 add_note(wt, MSG_DEBUG,
713                          "Use TPTK for validation EAPOL-Key MIC");
714                 kck = sta->tptk.kck;
715                 kck_len = sta->tptk.kck_len;
716         }
717         if (check_mic(kck, kck_len, sta->key_mgmt,
718                       key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
719                 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
720                 return;
721         }
722         add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
723         if (sta->tptk_set) {
724                 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
725                 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
726                 sta->ptk_set = 1;
727                 sta->tptk_set = 0;
728                 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
729                 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
730         }
731 }
732
733
734 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
735                                      const u8 *src, const u8 *data, size_t len)
736 {
737         struct wlantest_bss *bss;
738         struct wlantest_sta *sta;
739         const struct ieee802_1x_hdr *eapol;
740         const struct wpa_eapol_key *hdr;
741         u16 key_info, ver;
742         u8 *decrypted;
743         size_t decrypted_len = 0;
744
745         wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
746                    MAC2STR(src), MAC2STR(dst));
747         bss = bss_get(wt, src);
748         if (bss == NULL)
749                 return;
750         sta = sta_get(bss, dst);
751         if (sta == NULL)
752                 return;
753
754         eapol = (const struct ieee802_1x_hdr *) data;
755         hdr = (const struct wpa_eapol_key *) (eapol + 1);
756         key_info = WPA_GET_BE16(hdr->key_info);
757
758         if (!sta->ptk_set) {
759                 add_note(wt, MSG_DEBUG,
760                          "No PTK known to process EAPOL-Key 1/2");
761                 return;
762         }
763
764         if (sta->ptk_set &&
765             check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
766                       key_info & WPA_KEY_INFO_TYPE_MASK,
767                       data, len) < 0) {
768                 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
769                 return;
770         }
771         add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
772
773         if (sta->proto & WPA_PROTO_RSN &&
774             !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
775                 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
776                 return;
777         }
778         ver = key_info & WPA_KEY_INFO_TYPE_MASK;
779         decrypted = decrypt_eapol_key_data(wt, sta->ptk.kek, sta->ptk.kek_len,
780                                            ver, hdr, &decrypted_len);
781         if (decrypted == NULL) {
782                 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
783                 return;
784         }
785         wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
786                     decrypted, decrypted_len);
787         if (wt->write_pcap_dumper) {
788                 /* Fill in a dummy Data frame header */
789                 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
790                 struct ieee80211_hdr *h;
791                 struct wpa_eapol_key *k;
792                 u8 *pos;
793                 size_t plain_len;
794
795                 plain_len = decrypted_len;
796                 pos = decrypted;
797                 while (pos + 1 < decrypted + decrypted_len) {
798                         if (pos[0] == 0xdd && pos[1] == 0x00) {
799                                 /* Remove padding */
800                                 plain_len = pos - decrypted;
801                                 break;
802                         }
803                         pos += 2 + pos[1];
804                 }
805
806                 os_memset(buf, 0, sizeof(buf));
807                 h = (struct ieee80211_hdr *) buf;
808                 h->frame_control = host_to_le16(0x0208);
809                 os_memcpy(h->addr1, dst, ETH_ALEN);
810                 os_memcpy(h->addr2, src, ETH_ALEN);
811                 os_memcpy(h->addr3, src, ETH_ALEN);
812                 pos = (u8 *) (h + 1);
813                 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
814                 pos += 8;
815                 os_memcpy(pos, eapol, sizeof(*eapol));
816                 pos += sizeof(*eapol);
817                 os_memcpy(pos, hdr, sizeof(*hdr));
818                 k = (struct wpa_eapol_key *) pos;
819                 WPA_PUT_BE16(k->key_info,
820                              key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
821                 WPA_PUT_BE16(k->key_data_length, plain_len);
822                 write_pcap_decrypted(wt, buf, sizeof(buf),
823                                      decrypted, plain_len);
824         }
825         if (sta->proto & WPA_PROTO_RSN)
826                 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
827                                hdr->key_rsc);
828         else {
829                 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
830                 if (decrypted_len == klen) {
831                         const u8 *rsc = hdr->key_rsc;
832                         int id;
833                         id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
834                                 WPA_KEY_INFO_KEY_INDEX_SHIFT;
835                         add_note(wt, MSG_DEBUG, "GTK key index %d", id);
836                         wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
837                                     decrypted_len);
838                         bss->gtk_len[id] = decrypted_len;
839                         os_memcpy(bss->gtk[id], decrypted, decrypted_len);
840                         bss->rsc[id][0] = rsc[5];
841                         bss->rsc[id][1] = rsc[4];
842                         bss->rsc[id][2] = rsc[3];
843                         bss->rsc[id][3] = rsc[2];
844                         bss->rsc[id][4] = rsc[1];
845                         bss->rsc[id][5] = rsc[0];
846                         wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
847                 } else {
848                         add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
849                                  "in Group Key msg 1/2 from " MACSTR,
850                                  MAC2STR(src));
851                 }
852         }
853         os_free(decrypted);
854 }
855
856
857 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
858                                      const u8 *src, const u8 *data, size_t len)
859 {
860         struct wlantest_bss *bss;
861         struct wlantest_sta *sta;
862         const struct ieee802_1x_hdr *eapol;
863         const struct wpa_eapol_key *hdr;
864         u16 key_info;
865
866         wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
867                    MAC2STR(src), MAC2STR(dst));
868         bss = bss_get(wt, dst);
869         if (bss == NULL)
870                 return;
871         sta = sta_get(bss, src);
872         if (sta == NULL)
873                 return;
874
875         eapol = (const struct ieee802_1x_hdr *) data;
876         hdr = (const struct wpa_eapol_key *) (eapol + 1);
877         if (!is_zero(hdr->key_rsc, 8)) {
878                 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
879                          "non-zero Key RSC", MAC2STR(src));
880         }
881         key_info = WPA_GET_BE16(hdr->key_info);
882
883         if (!sta->ptk_set) {
884                 add_note(wt, MSG_DEBUG,
885                          "No PTK known to process EAPOL-Key 2/2");
886                 return;
887         }
888
889         if (sta->ptk_set &&
890             check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
891                       key_info & WPA_KEY_INFO_TYPE_MASK,
892                       data, len) < 0) {
893                 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
894                 return;
895         }
896         add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
897 }
898
899
900 static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
901                               const u8 *src, const u8 *data, size_t len,
902                               int prot)
903 {
904         const struct ieee802_1x_hdr *eapol;
905         const struct wpa_eapol_key *hdr;
906         const u8 *key_data;
907         u16 key_info, key_length, ver, key_data_length;
908
909         eapol = (const struct ieee802_1x_hdr *) data;
910         hdr = (const struct wpa_eapol_key *) (eapol + 1);
911
912         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
913                     (const u8 *) hdr, len - sizeof(*eapol));
914         if (len < sizeof(*hdr)) {
915                 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
916                          MAC2STR(src));
917                 return;
918         }
919
920         if (hdr->type == EAPOL_KEY_TYPE_RC4) {
921                 /* TODO: EAPOL-Key RC4 for WEP */
922                 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
923                            MACSTR, MAC2STR(src));
924                 return;
925         }
926
927         if (hdr->type != EAPOL_KEY_TYPE_RSN &&
928             hdr->type != EAPOL_KEY_TYPE_WPA) {
929                 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
930                            "%u from " MACSTR, hdr->type, MAC2STR(src));
931                 return;
932         }
933
934         key_info = WPA_GET_BE16(hdr->key_info);
935         key_length = WPA_GET_BE16(hdr->key_length);
936         key_data_length = WPA_GET_BE16(hdr->key_data_length);
937         key_data = (const u8 *) (hdr + 1);
938         if (key_data + key_data_length > data + len) {
939                 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
940                          MAC2STR(src));
941                 return;
942         }
943         if (key_data + key_data_length < data + len) {
944                 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
945                             "field", key_data + key_data_length,
946                         data + len - key_data - key_data_length);
947         }
948
949
950         ver = key_info & WPA_KEY_INFO_TYPE_MASK;
951         wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
952                    "datalen=%u",
953                    ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
954                    (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
955                    WPA_KEY_INFO_KEY_INDEX_SHIFT,
956                    (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
957                    (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
958                    (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
959                    (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
960                    (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
961                    (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
962                    (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
963                    (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
964                    key_data_length);
965
966         if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
967             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
968             ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
969             ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
970                 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
971                            "Version %u from " MACSTR, ver, MAC2STR(src));
972                 return;
973         }
974
975         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
976                     hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
977         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
978                     hdr->key_nonce, WPA_NONCE_LEN);
979         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
980                     hdr->key_iv, 16);
981         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
982                     hdr->key_rsc, WPA_KEY_RSC_LEN);
983         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
984                     hdr->key_mic, 16);
985         wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
986                     key_data, key_data_length);
987
988         if (hdr->type == EAPOL_KEY_TYPE_RSN &&
989             (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
990             0) {
991                 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
992                            "Key Info bits 0x%x from " MACSTR,
993                            key_info, MAC2STR(src));
994         }
995
996         if (hdr->type == EAPOL_KEY_TYPE_WPA &&
997             (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
998                          WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
999                 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
1000                            "Key Info bits 0x%x from " MACSTR,
1001                            key_info, MAC2STR(src));
1002         }
1003
1004         if (key_length > 32) {
1005                 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
1006                            "from " MACSTR, key_length, MAC2STR(src));
1007         }
1008
1009         if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1010             !is_zero(hdr->key_iv, 16)) {
1011                 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
1012                            "(reserved with ver=%d) field from " MACSTR,
1013                            ver, MAC2STR(src));
1014                 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
1015                             hdr->key_iv, 16);
1016         }
1017
1018         if (!is_zero(hdr->key_id, 8)) {
1019                 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
1020                            "(reserved) field from " MACSTR, MAC2STR(src));
1021                 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
1022                             hdr->key_id, 8);
1023         }
1024
1025         if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
1026                 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
1027                            "(last two are unused)" MACSTR, MAC2STR(src));
1028         }
1029
1030         if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
1031                 return;
1032
1033         if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
1034                 return;
1035
1036         if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1037                 /* 4-Way Handshake */
1038                 switch (key_info & (WPA_KEY_INFO_SECURE |
1039                                     WPA_KEY_INFO_MIC |
1040                                     WPA_KEY_INFO_ACK |
1041                                     WPA_KEY_INFO_INSTALL)) {
1042                 case WPA_KEY_INFO_ACK:
1043                         rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
1044                         break;
1045                 case WPA_KEY_INFO_MIC:
1046                         if (key_data_length == 0)
1047                                 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1048                                                          len);
1049                         else
1050                                 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1051                                                          len);
1052                         break;
1053                 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1054                         WPA_KEY_INFO_INSTALL:
1055                         /* WPA does not include Secure bit in 3/4 */
1056                         rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1057                         break;
1058                 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1059                         WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1060                         rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1061                         break;
1062                 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1063                         if (key_data_length == 0)
1064                                 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1065                                                          len);
1066                         else
1067                                 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1068                                                          len);
1069                         break;
1070                 default:
1071                         wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1072                         break;
1073                 }
1074         } else {
1075                 /* Group Key Handshake */
1076                 switch (key_info & (WPA_KEY_INFO_SECURE |
1077                                     WPA_KEY_INFO_MIC |
1078                                     WPA_KEY_INFO_ACK)) {
1079                 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1080                         WPA_KEY_INFO_ACK:
1081                         rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1082                         break;
1083                 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1084                         rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1085                         break;
1086                 default:
1087                         wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1088                         break;
1089                 }
1090         }
1091 }
1092
1093
1094 void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
1095                    const u8 *data, size_t len, int prot)
1096 {
1097         const struct ieee802_1x_hdr *hdr;
1098         u16 length;
1099         const u8 *p;
1100
1101         wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1102         if (len < sizeof(*hdr)) {
1103                 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1104                            MAC2STR(src));
1105                 return;
1106         }
1107
1108         hdr = (const struct ieee802_1x_hdr *) data;
1109         length = be_to_host16(hdr->length);
1110         wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1111                    "type=%u len=%u",
1112                    MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1113                    hdr->version, hdr->type, length);
1114         if (hdr->version < 1 || hdr->version > 3) {
1115                 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1116                            MACSTR, hdr->version, MAC2STR(src));
1117         }
1118         if (sizeof(*hdr) + length > len) {
1119                 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1120                            MAC2STR(src));
1121                 return;
1122         }
1123
1124         if (sizeof(*hdr) + length < len) {
1125                 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1126                            (int) (len - sizeof(*hdr) - length));
1127         }
1128         p = (const u8 *) (hdr + 1);
1129
1130         switch (hdr->type) {
1131         case IEEE802_1X_TYPE_EAP_PACKET:
1132                 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1133                 break;
1134         case IEEE802_1X_TYPE_EAPOL_START:
1135                 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1136                 break;
1137         case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1138                 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1139                 break;
1140         case IEEE802_1X_TYPE_EAPOL_KEY:
1141                 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
1142                                   prot);
1143                 break;
1144         case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1145                 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1146                             p, length);
1147                 break;
1148         default:
1149                 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
1150                 break;
1151         }
1152 }