]> git.ipfire.org Git - thirdparty/hostap.git/blob - wlantest/rx_eapol.c
wlantest: Add support for FT-PSK initial association key derivation
[thirdparty/hostap.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_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 }