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