blob: 5a38123ac745f6322f85e892681f079334964ee6 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010-2020, 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
23static 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
34static size_t determine_mic_len(struct wlantest_sta *sta)
35{
36 size_t pmk_len = PMK_LEN;
37
38 if (sta && wpa_key_mgmt_sae_ext_key(sta->key_mgmt) &&
39 sta->sae_group) {
40 switch (sta->sae_group) {
41 case 20:
42 pmk_len = 48;
43 break;
44 case 21:
45 pmk_len = 64;
46 break;
47 }
48 }
49
50 return wpa_mic_len(sta->key_mgmt, pmk_len);
51}
52
53
54static int check_mic(struct wlantest_sta *sta, const u8 *kck, size_t kck_len,
55 int ver, const u8 *data, size_t len)
56{
57 u8 *buf;
58 int ret = -1;
59 struct ieee802_1x_hdr *hdr;
60 struct wpa_eapol_key *key;
61 u8 rx_mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
62 size_t mic_len = determine_mic_len(sta);
63
64 buf = os_memdup(data, len);
65 if (buf == NULL)
66 return -1;
67 hdr = (struct ieee802_1x_hdr *) buf;
68 key = (struct wpa_eapol_key *) (hdr + 1);
69
70 os_memcpy(rx_mic, key + 1, mic_len);
71 os_memset(key + 1, 0, mic_len);
72
73 if (wpa_eapol_key_mic(kck, kck_len, sta->key_mgmt, ver, buf, len,
74 (u8 *) (key + 1)) == 0 &&
75 os_memcmp(rx_mic, key + 1, mic_len) == 0)
76 ret = 0;
77
78 os_free(buf);
79
80 return ret;
81}
82
83
84static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
85 const u8 *src, const u8 *bssid,
86 const u8 *data, size_t len)
87{
88 struct wlantest_bss *bss, *bss_mld;
89 struct wlantest_sta *sta;
90 const struct ieee802_1x_hdr *eapol;
91 const struct wpa_eapol_key *hdr;
92 const u8 *key_data, *mic;
93 size_t mic_len, left;
94 u16 key_data_len;
95 struct wpa_eapol_ie_parse ie;
96
97 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR " (BSSID "
98 MACSTR ")",
99 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
100 if (os_memcmp(src, bssid, ETH_ALEN) == 0) {
101 bss = bss_get(wt, src);
102 } else {
103 bss = bss_find(wt, bssid);
104 bss_mld = bss_find(wt, src);
105 if (bss_mld && (!bss || sta_find(bss_mld, src)))
106 bss = bss_get(wt, src);
107 else
108 bss = bss_get(wt, bssid);
109 }
110 if (bss == NULL)
111 return;
112 sta = sta_get(bss, dst);
113 if (sta == NULL)
114 return;
115
116 eapol = (const struct ieee802_1x_hdr *) data;
117 hdr = (const struct wpa_eapol_key *) (eapol + 1);
118 left = len - sizeof(*hdr);
119 mic_len = determine_mic_len(sta);
120 if (mic_len > left) {
121 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
122 " has a truncated MIC field", MAC2STR(src));
123 return;
124 }
125 left -= mic_len;
126 mic = (const u8 *) (hdr + 1);
127 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
128 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
129 " used zero nonce", MAC2STR(src));
130 }
131 if (!is_zero(hdr->key_rsc, 8)) {
132 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
133 " used non-zero Key RSC", MAC2STR(src));
134 }
135 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
136 if (left < 2) {
137 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
138 " has a truncated Key Data Length field",
139 MAC2STR(src));
140 return;
141 }
142 left -= 2;
143 key_data = mic + mic_len + 2;
144 key_data_len = WPA_GET_BE16(mic + mic_len);
145 if (key_data_len > left) {
146 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
147 " has a truncated Key Data field",
148 MAC2STR(src));
149 return;
150 }
151
152 if (wpa_parse_kde_ies(key_data, key_data_len, &ie) < 0) {
153 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
154 return;
155 }
156
157 if (ie.mac_addr) {
158 if (is_zero_ether_addr(bss->mld_mac_addr)) {
159 wpa_printf(MSG_DEBUG,
160 "Learned AP MLD MAC Address from EAPOL-Key 1/4: "
161 MACSTR, MAC2STR(ie.mac_addr));
162 } else {
163 wpa_printf(MSG_DEBUG,
164 "Updated AP MLD MAC Address from EAPOL-Key 1/4: "
165 MACSTR " --> " MACSTR,
166 MAC2STR(bss->mld_mac_addr),
167 MAC2STR(ie.mac_addr));
168 }
169 os_memcpy(bss->mld_mac_addr, ie.mac_addr, ETH_ALEN);
170 }
171}
172
173
174static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
175 struct wlantest_sta *sta, u16 ver,
176 const u8 *data, size_t len,
177 struct wlantest_pmk *pmk)
178{
179 struct wpa_ptk ptk;
180 const u8 *sa, *aa;
181 bool mlo;
182 size_t kdk_len;
183
184 mlo = !is_zero_ether_addr(sta->mld_mac_addr) &&
185 !is_zero_ether_addr(bss->mld_mac_addr);
186 sa = mlo ? sta->mld_mac_addr : sta->addr;
187 aa = mlo ? bss->mld_mac_addr : bss->bssid;
188
189 if (ieee802_11_rsnx_capab_len(bss->rsnxe, bss->rsnxe_len,
190 WLAN_RSNX_CAPAB_SECURE_LTF) &&
191 ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
192 WLAN_RSNX_CAPAB_SECURE_LTF))
193 kdk_len = WPA_KDK_MAX_LEN;
194 else
195 kdk_len = 0;
196
197 if (wpa_key_mgmt_ft(sta->key_mgmt)) {
198 u8 ptk_name[WPA_PMK_NAME_LEN];
199 int use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
200
201 if (wpa_derive_pmk_r0(pmk->pmk, pmk->pmk_len,
202 bss->ssid, bss->ssid_len, bss->mdid,
203 bss->r0kh_id, bss->r0kh_id_len,
204 sa, sta->pmk_r0, sta->pmk_r0_name,
205 sta->key_mgmt) < 0)
206 return -1;
207 if (wpa_key_mgmt_sae_ext_key(sta->key_mgmt))
208 sta->pmk_r0_len = pmk->pmk_len;
209 else
210 sta->pmk_r0_len = use_sha384 ? PMK_LEN_SUITE_B_192 :
211 PMK_LEN;
212 if (wpa_derive_pmk_r1(sta->pmk_r0, sta->pmk_r0_len,
213 sta->pmk_r0_name,
214 bss->r1kh_id, sa,
215 sta->pmk_r1, sta->pmk_r1_name) < 0)
216 return -1;
217 sta->pmk_r1_len = sta->pmk_r0_len;
218 if (wpa_pmk_r1_to_ptk(sta->pmk_r1, sta->pmk_r1_len,
219 sta->snonce, sta->anonce, sa,
220 aa, sta->pmk_r1_name,
221 &ptk, ptk_name, sta->key_mgmt,
222 sta->pairwise_cipher, 0) < 0 ||
223 check_mic(sta, ptk.kck, ptk.kck_len, ver, data, len) < 0)
224 return -1;
225 } else if (wpa_pmk_to_ptk(pmk->pmk, pmk->pmk_len,
226 "Pairwise key expansion",
227 aa, sa, sta->anonce,
228 sta->snonce, &ptk, sta->key_mgmt,
229 sta->pairwise_cipher, NULL, 0, kdk_len) < 0 ||
230 check_mic(sta, ptk.kck, ptk.kck_len, ver, data, len) < 0) {
231 return -1;
232 }
233
234 if (mlo) {
235 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " (MLD "
236 MACSTR ") BSSID " MACSTR " (MLD " MACSTR ")",
237 MAC2STR(sta->addr), MAC2STR(sta->mld_mac_addr),
238 MAC2STR(bss->bssid), MAC2STR(bss->mld_mac_addr));
239 } else {
240 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR
241 " BSSID " MACSTR,
242 MAC2STR(sta->addr), MAC2STR(bss->bssid));
243 }
244 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
245 if (sta->ptk_set) {
246 /*
247 * Rekeying - use new PTK for EAPOL-Key frames, but continue
248 * using the old PTK for frame decryption.
249 */
250 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
251 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
252 wpa_hexdump(MSG_DEBUG, "TPTK:KCK",
253 sta->tptk.kck, sta->tptk.kck_len);
254 wpa_hexdump(MSG_DEBUG, "TPTK:KEK",
255 sta->tptk.kek, sta->tptk.kek_len);
256 wpa_hexdump(MSG_DEBUG, "TPTK:TK",
257 sta->tptk.tk, sta->tptk.tk_len);
258 sta->tptk_set = 1;
259 return 0;
260 }
261 sta_new_ptk(wt, sta, &ptk);
262 return 0;
263}
264
265
266static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
267 struct wlantest_sta *sta, u16 ver,
268 const u8 *data, size_t len)
269{
270 struct wlantest_pmk *pmk;
271
272 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR " (MLD " MACSTR
273 ") (ver %u)",
274 MAC2STR(sta->addr), MAC2STR(sta->mld_mac_addr), ver);
275 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
276 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
277 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
278 return;
279 }
280
281 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
282 wpa_printf(MSG_DEBUG, "Try global PMK");
283 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
284 return;
285 }
286
287 if (!sta->ptk_set) {
288 struct wlantest_ptk *ptk;
289 int prev_level = wpa_debug_level;
290
291 wpa_debug_level = MSG_WARNING;
292 dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
293 if (check_mic(sta, ptk->ptk.kck, ptk->ptk.kck_len,
294 ver, data, len) < 0)
295 continue;
296 wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
297 MACSTR " BSSID " MACSTR,
298 MAC2STR(sta->addr), MAC2STR(bss->bssid));
299 add_note(wt, MSG_DEBUG, "Using pre-set PTK");
300 ptk->ptk_len = 32 +
301 wpa_cipher_key_len(sta->pairwise_cipher);
302 os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
303 wpa_hexdump(MSG_DEBUG, "PTK:KCK",
304 sta->ptk.kck, sta->ptk.kck_len);
305 wpa_hexdump(MSG_DEBUG, "PTK:KEK",
306 sta->ptk.kek, sta->ptk.kek_len);
307 wpa_hexdump(MSG_DEBUG, "PTK:TK",
308 sta->ptk.tk, sta->ptk.tk_len);
309 sta->ptk_set = 1;
310 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
311 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
312 }
313 wpa_debug_level = prev_level;
314 }
315
316 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
317}
318
319
320static void elems_from_eapol_ie(struct ieee802_11_elems *elems,
321 struct wpa_eapol_ie_parse *ie)
322{
323 os_memset(elems, 0, sizeof(*elems));
324 if (ie->wpa_ie) {
325 elems->wpa_ie = ie->wpa_ie + 2;
326 elems->wpa_ie_len = ie->wpa_ie_len - 2;
327 }
328 if (ie->rsn_ie) {
329 elems->rsn_ie = ie->rsn_ie + 2;
330 elems->rsn_ie_len = ie->rsn_ie_len - 2;
331 }
332 if (ie->osen) {
333 elems->osen = ie->osen + 2;
334 elems->osen_len = ie->osen_len - 2;
335 }
336}
337
338
339static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
340 const u8 *src, const u8 *bssid,
341 const u8 *data, size_t len)
342{
343 struct wlantest_bss *bss, *bss_mld;
344 struct wlantest_sta *sta;
345 const struct ieee802_1x_hdr *eapol;
346 const struct wpa_eapol_key *hdr;
347 const u8 *key_data, *kck, *mic;
348 size_t kck_len, mic_len, left;
349 u16 key_info, key_data_len;
350 struct wpa_eapol_ie_parse ie;
351 int link_id;
352
353 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR " (BSSID "
354 MACSTR ")",
355 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
356 if (os_memcmp(dst, bssid, ETH_ALEN) == 0) {
357 bss = bss_get(wt, dst);
358 } else {
359 bss = bss_find(wt, bssid);
360 bss_mld = bss_find(wt, dst);
361 if (bss_mld && (!bss || sta_find(bss_mld, src)))
362 bss = bss_get(wt, dst);
363 else
364 bss = bss_get(wt, bssid);
365 }
366 if (bss == NULL)
367 return;
368 sta = sta_get(bss, src);
369 if (sta == NULL)
370 return;
371
372 eapol = (const struct ieee802_1x_hdr *) data;
373 hdr = (const struct wpa_eapol_key *) (eapol + 1);
374 left = len - sizeof(*hdr);
375 mic_len = determine_mic_len(sta);
376 if (mic_len > left) {
377 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
378 " has a truncated MIC field", MAC2STR(src));
379 return;
380 }
381 left -= mic_len;
382 mic = (const u8 *) (hdr + 1);
383 if (!is_zero(hdr->key_rsc, 8)) {
384 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
385 " used non-zero Key RSC", MAC2STR(src));
386 }
387 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
388 key_info = WPA_GET_BE16(hdr->key_info);
389 if (left < 2) {
390 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
391 " has a truncated Key Data Length field",
392 MAC2STR(src));
393 return;
394 }
395 left -= 2;
396 key_data = mic + mic_len + 2;
397 key_data_len = WPA_GET_BE16(mic + mic_len);
398 if (key_data_len > left) {
399 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
400 " has a truncated Key Data field",
401 MAC2STR(src));
402 return;
403 }
404
405 if (wpa_parse_kde_ies(key_data, key_data_len, &ie) < 0) {
406 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
407 return;
408 }
409
410 if (!sta->assocreq_seen) {
411 struct ieee802_11_elems elems;
412
413 elems_from_eapol_ie(&elems, &ie);
414 wpa_printf(MSG_DEBUG,
415 "Update STA data based on IEs in EAPOL-Key 2/4");
416 sta_update_assoc(sta, &elems);
417 }
418
419 if (ie.mac_addr) {
420 if (is_zero_ether_addr(sta->mld_mac_addr)) {
421 wpa_printf(MSG_DEBUG,
422 "Learned non-AP STA MLD MAC Address from EAPOL-Key 2/4: "
423 MACSTR, MAC2STR(ie.mac_addr));
424 } else {
425 wpa_printf(MSG_DEBUG,
426 "Updated non-AP STA MLD MAC Address from EAPOL-Key 2/4: "
427 MACSTR " --> " MACSTR,
428 MAC2STR(sta->mld_mac_addr),
429 MAC2STR(ie.mac_addr));
430 }
431 os_memcpy(sta->mld_mac_addr, ie.mac_addr, ETH_ALEN);
432 }
433
434 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
435
436 if (!sta->ptk_set && !sta->tptk_set) {
437 add_note(wt, MSG_DEBUG,
438 "No PTK known to process EAPOL-Key 2/4");
439 return;
440 }
441
442 kck = sta->ptk.kck;
443 kck_len = sta->ptk.kck_len;
444 if (sta->tptk_set) {
445 add_note(wt, MSG_DEBUG,
446 "Use TPTK for validation EAPOL-Key MIC");
447 kck = sta->tptk.kck;
448 kck_len = sta->tptk.kck_len;
449 }
450 if (check_mic(sta, kck, kck_len,
451 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
452 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
453 return;
454 }
455 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
456
457 if (ie.wpa_ie) {
458 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
459 ie.wpa_ie, ie.wpa_ie_len);
460 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
461 add_note(wt, MSG_INFO,
462 "Mismatch in WPA IE between EAPOL-Key 2/4 "
463 "and (Re)Association Request from " MACSTR,
464 MAC2STR(sta->addr));
465 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
466 ie.wpa_ie, ie.wpa_ie_len);
467 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
468 "Request",
469 sta->rsnie,
470 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
471 }
472 }
473
474 if (ie.rsn_ie) {
475 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
476 ie.rsn_ie, ie.rsn_ie_len);
477 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
478 add_note(wt, MSG_INFO,
479 "Mismatch in RSN IE between EAPOL-Key 2/4 "
480 "and (Re)Association Request from " MACSTR,
481 MAC2STR(sta->addr));
482 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
483 ie.rsn_ie, ie.rsn_ie_len);
484 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
485 "Request",
486 sta->rsnie,
487 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
488 }
489 }
490
491 for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) {
492 const u8 *addr;
493
494 if (!ie.mlo_link[link_id])
495 continue;
496 addr = &ie.mlo_link[link_id][RSN_MLO_LINK_KDE_LINK_MAC_INDEX];
497 wpa_printf(MSG_DEBUG,
498 "Learned Link ID %u MAC address " MACSTR
499 " from EAPOL-Key 2/4",
500 link_id, MAC2STR(addr));
501 os_memcpy(sta->link_addr[link_id], addr, ETH_ALEN);
502 }
503}
504
505
506static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
507 const struct wpa_eapol_key *hdr,
508 const u8 *keydata, u16 keydatalen,
509 size_t *len)
510{
511 u8 ek[32], *buf;
512
513 buf = os_memdup(keydata, keydatalen);
514 if (buf == NULL)
515 return NULL;
516
517 os_memcpy(ek, hdr->key_iv, 16);
518 os_memcpy(ek + 16, kek, 16);
519 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
520 add_note(wt, MSG_INFO, "RC4 failed");
521 os_free(buf);
522 return NULL;
523 }
524
525 *len = keydatalen;
526 return buf;
527}
528
529
530static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
531 size_t kek_len,
532 const struct wpa_eapol_key *hdr,
533 const u8 *keydata, u16 keydatalen,
534 size_t *len)
535{
536 u8 *buf;
537
538 if (keydatalen % 8) {
539 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
540 keydatalen);
541 return NULL;
542 }
543 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
544 buf = os_malloc(keydatalen);
545 if (buf == NULL)
546 return NULL;
547 if (aes_unwrap(kek, kek_len, keydatalen / 8, keydata, buf)) {
548 os_free(buf);
549 add_note(wt, MSG_INFO,
550 "AES unwrap failed - could not decrypt EAPOL-Key "
551 "key data");
552 return NULL;
553 }
554
555 *len = keydatalen;
556 return buf;
557}
558
559
560static u8 * decrypt_eapol_key_data(struct wlantest *wt,
561 struct wlantest_sta *sta, const u8 *kek,
562 size_t kek_len, u16 ver,
563 const struct wpa_eapol_key *hdr,
564 const u8 *end, size_t *len)
565{
566 size_t mic_len;
567 u16 keydatalen;
568 const u8 *mic, *keydata;
569
570 mic = (const u8 *) (hdr + 1);
571 mic_len = determine_mic_len(sta);
572 if (mic_len + 2 > end - mic)
573 return NULL;
574 keydata = mic + mic_len + 2;
575 keydatalen = WPA_GET_BE16(mic + mic_len);
576 if (keydatalen > end - keydata)
577 return NULL;
578
579 switch (ver) {
580 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
581 if (kek_len != 16)
582 return NULL;
583 return decrypt_eapol_key_data_rc4(wt, kek, hdr, keydata,
584 keydatalen, len);
585 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
586 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
587 return decrypt_eapol_key_data_aes(wt, kek, kek_len, hdr,
588 keydata, keydatalen, len);
589 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
590 /* For now, assume this is OSEN */
591 return decrypt_eapol_key_data_aes(wt, kek, kek_len, hdr,
592 keydata, keydatalen, len);
593 default:
594 add_note(wt, MSG_INFO,
595 "Unsupported EAPOL-Key Key Descriptor Version %u",
596 ver);
597 return NULL;
598 }
599}
600
601
602static void learn_kde_keys_mlo(struct wlantest *wt, struct wlantest_bss *bss,
603 struct wlantest_sta *sta, int link_id,
604 struct wpa_eapol_ie_parse *ie)
605{
606 const u8 *key, *pn;
607 size_t key_len;
608 unsigned int key_id;
609 bool tx;
610
611 if (ie->mlo_gtk[link_id]) {
612 pn = ie->mlo_gtk[link_id] + 1;
613 key = ie->mlo_gtk[link_id] + RSN_MLO_GTK_KDE_PREFIX_LENGTH;
614 key_len = ie->mlo_gtk_len[link_id] -
615 RSN_MLO_GTK_KDE_PREFIX_LENGTH;
616 key_id = ie->mlo_gtk[link_id][0] &
617 RSN_MLO_GTK_KDE_PREFIX0_KEY_ID_MASK;
618 tx = ie->mlo_gtk[link_id][0] & RSN_MLO_GTK_KDE_PREFIX0_TX;
619 if (key_len <= WPA_GTK_MAX_LEN) {
620 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
621 key_id, tx);
622 if (ie->mlo_gtk[link_id][0] & BIT(3)) {
623 add_note(wt, MSG_INFO,
624 "MLO GTK KDE: Reserved field set");
625 }
626 wpa_hexdump(MSG_DEBUG, "GTK", key, key_len);
627 bss->gtk_len[key_id] = key_len;
628 if (sta)
629 sta->gtk_len = key_len;
630 os_memcpy(bss->gtk[key_id], key, key_len);
631 if (sta)
632 os_memcpy(sta->gtk, key, key_len);
633 bss->rsc[key_id][0] = pn[5];
634 bss->rsc[key_id][1] = pn[4];
635 bss->rsc[key_id][2] = pn[3];
636 bss->rsc[key_id][3] = pn[2];
637 bss->rsc[key_id][4] = pn[1];
638 bss->rsc[key_id][5] = pn[0];
639 bss->gtk_idx = key_id;
640 if (sta)
641 sta->gtk_idx = key_id;
642 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[key_id], 6);
643 } else {
644 add_note(wt, MSG_INFO,
645 "Invalid MLO GTK KDE key length %zu",
646 key_len);
647 }
648 }
649
650 if (ie->mlo_igtk[link_id]) {
651 pn = ie->mlo_igtk[link_id] + 2;
652 key = ie->mlo_igtk[link_id] + RSN_MLO_IGTK_KDE_PREFIX_LENGTH;
653 key_len = ie->mlo_igtk_len[link_id] -
654 RSN_MLO_IGTK_KDE_PREFIX_LENGTH;
655 key_id = WPA_GET_LE16(ie->mlo_igtk[link_id]);
656 if (key_len <= WPA_IGTK_MAX_LEN && key_id >= 4 && key_id <= 5) {
657 add_note(wt, MSG_DEBUG, "IGTK KeyID=%u", key_id);
658 if (ie->mlo_igtk[link_id][2 + 6] & 0x0f) {
659 add_note(wt, MSG_INFO,
660 "MLO IGTK KDE: Reserved field set");
661 }
662 wpa_hexdump(MSG_DEBUG, "IGTK", key, key_len);
663 wpa_hexdump(MSG_DEBUG, "IPN", pn, 6);
664 bss->igtk_len[key_id] = key_len;
665 os_memcpy(bss->igtk[key_id], key, key_len);
666 bss->ipn[key_id][0] = pn[5];
667 bss->ipn[key_id][1] = pn[4];
668 bss->ipn[key_id][2] = pn[3];
669 bss->ipn[key_id][3] = pn[2];
670 bss->ipn[key_id][4] = pn[1];
671 bss->ipn[key_id][5] = pn[0];
672 bss->igtk_idx = key_id;
673 } else {
674 add_note(wt, MSG_INFO,
675 "Invalid MLO IGTK KDE ID %u or key length %zu",
676 key_id, key_len);
677 }
678 }
679
680 if (ie->mlo_bigtk[link_id]) {
681 pn = ie->mlo_bigtk[link_id] + 2;
682 key = ie->mlo_bigtk[link_id] + RSN_MLO_BIGTK_KDE_PREFIX_LENGTH;
683 key_len = ie->mlo_bigtk_len[link_id] -
684 RSN_MLO_BIGTK_KDE_PREFIX_LENGTH;
685 key_id = WPA_GET_LE16(ie->mlo_bigtk[link_id]);
686 if (key_len <= WPA_BIGTK_MAX_LEN &&
687 key_id >= 6 && key_id <= 7) {
688 add_note(wt, MSG_DEBUG, "BIGTK KeyID=%u", key_id);
689 if (ie->mlo_bigtk[link_id][2 + 6] & 0x0f) {
690 add_note(wt, MSG_INFO,
691 "MLO BIGTK KDE: Reserved field set");
692 }
693 wpa_hexdump(MSG_DEBUG, "BIGTK", key, key_len);
694 wpa_hexdump(MSG_DEBUG, "BIPN", pn, 6);
695 bss->igtk_len[key_id] = key_len;
696 os_memcpy(bss->igtk[key_id], key, key_len);
697 bss->ipn[key_id][0] = pn[5];
698 bss->ipn[key_id][1] = pn[4];
699 bss->ipn[key_id][2] = pn[3];
700 bss->ipn[key_id][3] = pn[2];
701 bss->ipn[key_id][4] = pn[1];
702 bss->ipn[key_id][5] = pn[0];
703 bss->bigtk_idx = key_id;
704 } else {
705 add_note(wt, MSG_INFO,
706 "Invalid MLO IGTK KDE ID %u or key length %zu",
707 key_id, key_len);
708 }
709 }
710}
711
712
713static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
714 struct wlantest_sta *sta,
715 const u8 *buf, size_t len, const u8 *rsc)
716{
717 struct wpa_eapol_ie_parse ie;
718 int link_id;
719
720 if (wpa_parse_kde_ies(buf, len, &ie) < 0) {
721 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
722 return;
723 }
724
725 if (ie.wpa_ie) {
726 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
727 ie.wpa_ie, ie.wpa_ie_len);
728 }
729
730 if (ie.rsn_ie) {
731 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
732 ie.rsn_ie, ie.rsn_ie_len);
733 }
734
735 if (ie.key_id)
736 add_note(wt, MSG_DEBUG, "KeyID %u", ie.key_id[0]);
737
738 if (ie.gtk) {
739 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
740 ie.gtk, ie.gtk_len);
741 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
742 int id;
743 id = ie.gtk[0] & 0x03;
744 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
745 id, !!(ie.gtk[0] & 0x04));
746 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
747 add_note(wt, MSG_INFO,
748 "GTK KDE: Reserved field set: "
749 "%02x %02x", ie.gtk[0], ie.gtk[1]);
750 }
751 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
752 ie.gtk_len - 2);
753 bss->gtk_len[id] = ie.gtk_len - 2;
754 sta->gtk_len = ie.gtk_len - 2;
755 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
756 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
757 bss->rsc[id][0] = rsc[5];
758 bss->rsc[id][1] = rsc[4];
759 bss->rsc[id][2] = rsc[3];
760 bss->rsc[id][3] = rsc[2];
761 bss->rsc[id][4] = rsc[1];
762 bss->rsc[id][5] = rsc[0];
763 bss->gtk_idx = id;
764 sta->gtk_idx = id;
765 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
766 } else {
767 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
768 (unsigned) ie.gtk_len);
769 }
770 }
771
772 if (ie.igtk) {
773 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
774 ie.igtk, ie.igtk_len);
775 if (ie.igtk_len == 24) {
776 u16 id;
777 id = WPA_GET_LE16(ie.igtk);
778 if (id > 5) {
779 add_note(wt, MSG_INFO,
780 "Unexpected IGTK KeyID %u", id);
781 } else {
782 const u8 *ipn;
783 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
784 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
785 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
786 16);
787 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
788 bss->igtk_len[id] = 16;
789 ipn = ie.igtk + 2;
790 bss->ipn[id][0] = ipn[5];
791 bss->ipn[id][1] = ipn[4];
792 bss->ipn[id][2] = ipn[3];
793 bss->ipn[id][3] = ipn[2];
794 bss->ipn[id][4] = ipn[1];
795 bss->ipn[id][5] = ipn[0];
796 bss->igtk_idx = id;
797 }
798 } else if (ie.igtk_len == 40) {
799 u16 id;
800 id = WPA_GET_LE16(ie.igtk);
801 if (id > 5) {
802 add_note(wt, MSG_INFO,
803 "Unexpected IGTK KeyID %u", id);
804 } else {
805 const u8 *ipn;
806 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
807 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
808 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
809 32);
810 os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
811 bss->igtk_len[id] = 32;
812 ipn = ie.igtk + 2;
813 bss->ipn[id][0] = ipn[5];
814 bss->ipn[id][1] = ipn[4];
815 bss->ipn[id][2] = ipn[3];
816 bss->ipn[id][3] = ipn[2];
817 bss->ipn[id][4] = ipn[1];
818 bss->ipn[id][5] = ipn[0];
819 bss->igtk_idx = id;
820 }
821 } else {
822 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
823 (unsigned) ie.igtk_len);
824 }
825 }
826
827 if (ie.bigtk) {
828 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - BIGTK KDE",
829 ie.bigtk, ie.bigtk_len);
830 if (ie.bigtk_len == 24) {
831 u16 id;
832
833 id = WPA_GET_LE16(ie.bigtk);
834 if (id < 6 || id > 7) {
835 add_note(wt, MSG_INFO,
836 "Unexpected BIGTK KeyID %u", id);
837 } else {
838 const u8 *ipn;
839
840 add_note(wt, MSG_DEBUG, "BIGTK KeyID %u", id);
841 wpa_hexdump(MSG_DEBUG, "BIPN", ie.bigtk + 2, 6);
842 wpa_hexdump(MSG_DEBUG, "BIGTK", ie.bigtk + 8,
843 16);
844 os_memcpy(bss->igtk[id], ie.bigtk + 8, 16);
845 bss->igtk_len[id] = 16;
846 ipn = ie.bigtk + 2;
847 bss->ipn[id][0] = ipn[5];
848 bss->ipn[id][1] = ipn[4];
849 bss->ipn[id][2] = ipn[3];
850 bss->ipn[id][3] = ipn[2];
851 bss->ipn[id][4] = ipn[1];
852 bss->ipn[id][5] = ipn[0];
853 bss->bigtk_idx = id;
854 }
855 } else if (ie.bigtk_len == 40) {
856 u16 id;
857
858 id = WPA_GET_LE16(ie.bigtk);
859 if (id < 6 || id > 7) {
860 add_note(wt, MSG_INFO,
861 "Unexpected BIGTK KeyID %u", id);
862 } else {
863 const u8 *ipn;
864
865 add_note(wt, MSG_DEBUG, "BIGTK KeyID %u", id);
866 wpa_hexdump(MSG_DEBUG, "BIPN", ie.bigtk + 2, 6);
867 wpa_hexdump(MSG_DEBUG, "BIGTK", ie.bigtk + 8,
868 32);
869 os_memcpy(bss->igtk[id], ie.bigtk + 8, 32);
870 bss->igtk_len[id] = 32;
871 ipn = ie.bigtk + 2;
872 bss->ipn[id][0] = ipn[5];
873 bss->ipn[id][1] = ipn[4];
874 bss->ipn[id][2] = ipn[3];
875 bss->ipn[id][3] = ipn[2];
876 bss->ipn[id][4] = ipn[1];
877 bss->ipn[id][5] = ipn[0];
878 bss->bigtk_idx = id;
879 }
880 } else {
881 add_note(wt, MSG_INFO, "Invalid BIGTK KDE length %u",
882 (unsigned) ie.bigtk_len);
883 }
884 }
885
886 for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) {
887 const u8 *addr;
888
889 if (!ie.mlo_link[link_id])
890 continue;
891 addr = &ie.mlo_link[link_id][RSN_MLO_LINK_KDE_LINK_MAC_INDEX];
892 if (os_memcmp(addr, bss->bssid, ETH_ALEN) == 0) {
893 wpa_printf(MSG_DEBUG,
894 "Trying to learn keys for the current MLO link (ID %u)",
895 link_id);
896 learn_kde_keys_mlo(wt, bss, sta, link_id, &ie);
897 } else {
898 struct wlantest_bss *obss;
899
900 wpa_printf(MSG_DEBUG,
901 "Trying to learn keys for another MLO link (ID %u addr " MACSTR ")",
902 link_id, MAC2STR(addr));
903 obss = bss_get(wt, addr);
904 if (!obss) {
905 wpa_printf(MSG_DEBUG,
906 "No BSS entry for the other BSS found");
907 continue;
908 }
909 learn_kde_keys_mlo(wt, obss, NULL, link_id, &ie);
910 }
911 }
912}
913
914
915static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
916 const u8 *src, const u8 *bssid,
917 const u8 *data, size_t len)
918{
919 struct wlantest_bss *bss, *bss_mld;
920 struct wlantest_sta *sta;
921 const struct ieee802_1x_hdr *eapol;
922 const struct wpa_eapol_key *hdr;
923 const u8 *key_data, *kck, *kek, *mic;
924 size_t kck_len, kek_len, mic_len;
925 int recalc = 0;
926 u16 key_info, ver;
927 u8 *decrypted_buf = NULL;
928 const u8 *decrypted;
929 size_t decrypted_len = 0;
930 struct wpa_eapol_ie_parse ie;
931 struct wpa_ie_data rsn;
932 const u8 *rsne;
933 size_t rsne_len;
934 int link_id;
935
936 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR " (BSSID "
937 MACSTR ")",
938 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
939 if (os_memcmp(src, bssid, ETH_ALEN) == 0) {
940 bss = bss_get(wt, src);
941 } else {
942 bss = bss_find(wt, bssid);
943 bss_mld = bss_find(wt, src);
944 if (bss_mld && (!bss || sta_find(bss_mld, src)))
945 bss = bss_get(wt, src);
946 else
947 bss = bss_get(wt, bssid);
948 }
949 if (bss == NULL)
950 return;
951 sta = sta_get(bss, dst);
952 if (sta == NULL)
953 return;
954 mic_len = determine_mic_len(sta);
955
956 eapol = (const struct ieee802_1x_hdr *) data;
957 hdr = (const struct wpa_eapol_key *) (eapol + 1);
958 mic = (const u8 *) (hdr + 1);
959 key_info = WPA_GET_BE16(hdr->key_info);
960
961 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
962 add_note(wt, MSG_INFO,
963 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
964 recalc = 1;
965 }
966 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
967 if (recalc) {
968 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
969 data, len);
970 }
971
972 if (!sta->ptk_set && !sta->tptk_set) {
973 add_note(wt, MSG_DEBUG,
974 "No PTK known to process EAPOL-Key 3/4");
975 return;
976 }
977
978 kek = sta->ptk.kek;
979 kek_len = sta->ptk.kek_len;
980 kck = sta->ptk.kck;
981 kck_len = sta->ptk.kck_len;
982 if (sta->tptk_set) {
983 add_note(wt, MSG_DEBUG,
984 "Use TPTK for validation EAPOL-Key MIC");
985 kck = sta->tptk.kck;
986 kck_len = sta->tptk.kck_len;
987 kek = sta->tptk.kek;
988 kek_len = sta->tptk.kek_len;
989 }
990 if (check_mic(sta, kck, kck_len,
991 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
992 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
993 return;
994 }
995 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
996
997 key_data = mic + mic_len + 2;
998 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
999 if (sta->proto & WPA_PROTO_RSN)
1000 add_note(wt, MSG_INFO,
1001 "EAPOL-Key 3/4 without EncrKeyData bit");
1002 decrypted = key_data;
1003 decrypted_len = WPA_GET_BE16(mic + mic_len);
1004 } else {
1005 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1006 decrypted_buf = decrypt_eapol_key_data(wt, sta,
1007 kek, kek_len, ver,
1008 hdr, data + len,
1009 &decrypted_len);
1010 if (decrypted_buf == NULL) {
1011 add_note(wt, MSG_INFO,
1012 "Failed to decrypt EAPOL-Key Key Data");
1013 return;
1014 }
1015 decrypted = decrypted_buf;
1016 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
1017 decrypted, decrypted_len);
1018 }
1019 if ((wt->write_pcap_dumper || wt->pcapng) && decrypted != key_data) {
1020 /* Fill in a stub Data frame header */
1021 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr) + 64];
1022 struct ieee80211_hdr *h;
1023 struct wpa_eapol_key *k;
1024 const u8 *p;
1025 u8 *pos;
1026 size_t plain_len;
1027
1028 plain_len = decrypted_len;
1029 p = decrypted;
1030 while (p + 1 < decrypted + decrypted_len) {
1031 if (p[0] == 0xdd && p[1] == 0x00) {
1032 /* Remove padding */
1033 plain_len = p - decrypted;
1034 p = NULL;
1035 break;
1036 }
1037 p += 2 + p[1];
1038 }
1039 if (p && p > decrypted && p + 1 == decrypted + decrypted_len &&
1040 *p == 0xdd) {
1041 /* Remove padding */
1042 plain_len = p - decrypted;
1043 }
1044
1045 os_memset(buf, 0, sizeof(buf));
1046 h = (struct ieee80211_hdr *) buf;
1047 h->frame_control = host_to_le16(0x0208);
1048 os_memcpy(h->addr1, dst, ETH_ALEN);
1049 os_memcpy(h->addr2, src, ETH_ALEN);
1050 os_memcpy(h->addr3, src, ETH_ALEN);
1051 pos = (u8 *) (h + 1);
1052 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
1053 pos += 8;
1054 os_memcpy(pos, eapol, sizeof(*eapol));
1055 pos += sizeof(*eapol);
1056 os_memcpy(pos, hdr, sizeof(*hdr) + mic_len);
1057 k = (struct wpa_eapol_key *) pos;
1058 pos += sizeof(struct wpa_eapol_key) + mic_len;
1059 WPA_PUT_BE16(k->key_info,
1060 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
1061 WPA_PUT_BE16(pos, plain_len);
1062 write_pcap_decrypted(wt, buf, 24 + 8 + sizeof(*eapol) +
1063 sizeof(*hdr) + mic_len + 2,
1064 decrypted, plain_len);
1065 }
1066
1067 if (wpa_parse_kde_ies(decrypted, decrypted_len, &ie) < 0) {
1068 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
1069 os_free(decrypted_buf);
1070 return;
1071 }
1072
1073 if (!bss->ies_set) {
1074 struct ieee802_11_elems elems;
1075
1076 elems_from_eapol_ie(&elems, &ie);
1077 wpa_printf(MSG_DEBUG,
1078 "Update BSS data based on IEs in EAPOL-Key 3/4");
1079 bss_update(wt, bss, &elems, 0);
1080 }
1081
1082 if ((ie.wpa_ie &&
1083 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
1084 (ie.wpa_ie == NULL && bss->wpaie[0])) {
1085 add_note(wt, MSG_INFO,
1086 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
1087 "Beacon/Probe Response from " MACSTR,
1088 MAC2STR(bss->bssid));
1089 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
1090 ie.wpa_ie, ie.wpa_ie_len);
1091 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
1092 "Response",
1093 bss->wpaie,
1094 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
1095 }
1096
1097 rsne = ie.rsn_ie;
1098 rsne_len = ie.rsn_ie_len;
1099 for (link_id = 0; !rsne && link_id < MAX_NUM_MLO_LINKS; link_id++) {
1100 const u8 *addr, *pos, *end;
1101
1102 if (!ie.mlo_link[link_id])
1103 continue;
1104 addr = &ie.mlo_link[link_id][RSN_MLO_LINK_KDE_LINK_MAC_INDEX];
1105 if (os_memcmp(addr, bss->bssid, ETH_ALEN) != 0)
1106 continue;
1107 if (!(ie.mlo_link[link_id][0] & RSN_MLO_LINK_KDE_LI_RSNE_INFO))
1108 continue;
1109 pos = ie.mlo_link[link_id] + RSN_MLO_LINK_KDE_FIXED_LENGTH;
1110 end = ie.mlo_link[link_id] + ie.mlo_link_len[link_id];
1111 if (end - pos < 2 || pos[0] != WLAN_EID_RSN ||
1112 end - pos < 2 + pos[1]) {
1113 add_note(wt, MSG_INFO, "Invalid MLO Link KDE from "
1114 MACSTR " - RSNE info missing",
1115 MAC2STR(bss->bssid));
1116 break;
1117 }
1118 wpa_printf(MSG_DEBUG,
1119 "Using RSNE from MLO Link KDE for Link ID %u",
1120 link_id);
1121 rsne = pos;
1122 rsne_len = 2 + pos[1];
1123 break;
1124 }
1125
1126 if ((rsne &&
1127 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sta->key_mgmt),
1128 rsne, rsne_len,
1129 bss->rsnie, 2 + bss->rsnie[1])) ||
1130 (!rsne && bss->rsnie[0])) {
1131 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
1132 "3/4 and Beacon/Probe Response from " MACSTR,
1133 MAC2STR(bss->bssid));
1134 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
1135 rsne, rsne_len);
1136 wpa_hexdump(MSG_INFO, "RSN IE in Beacon/Probe Response",
1137 bss->rsnie,
1138 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
1139 }
1140
1141 if (wpa_key_mgmt_ft(sta->key_mgmt) &&
1142 (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) < 0 ||
1143 rsn.num_pmkid != 1 || !rsn.pmkid ||
1144 os_memcmp_const(rsn.pmkid, sta->pmk_r1_name,
1145 WPA_PMK_NAME_LEN) != 0))
1146 add_note(wt, MSG_INFO,
1147 "FT: No matching PMKR1Name in FT 4-way handshake message 3/4");
1148
1149 /* TODO: validate MDE and FTE match */
1150
1151 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
1152 os_free(decrypted_buf);
1153}
1154
1155
1156static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
1157 const u8 *src, const u8 *bssid,
1158 const u8 *data, size_t len)
1159{
1160 struct wlantest_bss *bss, *bss_mld;
1161 struct wlantest_sta *sta;
1162 const struct ieee802_1x_hdr *eapol;
1163 const struct wpa_eapol_key *hdr;
1164 u16 key_info;
1165 const u8 *kck;
1166 size_t kck_len;
1167
1168 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR " (BSSID "
1169 MACSTR ")",
1170 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
1171 if (os_memcmp(dst, bssid, ETH_ALEN) == 0) {
1172 bss = bss_get(wt, dst);
1173 } else {
1174 bss = bss_find(wt, bssid);
1175 bss_mld = bss_find(wt, dst);
1176 if (bss_mld && (!bss || sta_find(bss_mld, src)))
1177 bss = bss_get(wt, dst);
1178 else
1179 bss = bss_get(wt, bssid);
1180 }
1181 if (bss == NULL)
1182 return;
1183 sta = sta_get(bss, src);
1184 if (sta == NULL)
1185 return;
1186
1187 eapol = (const struct ieee802_1x_hdr *) data;
1188 hdr = (const struct wpa_eapol_key *) (eapol + 1);
1189 if (!is_zero(hdr->key_rsc, 8)) {
1190 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
1191 "non-zero Key RSC", MAC2STR(src));
1192 }
1193 key_info = WPA_GET_BE16(hdr->key_info);
1194
1195 if (!sta->ptk_set && !sta->tptk_set) {
1196 add_note(wt, MSG_DEBUG,
1197 "No PTK known to process EAPOL-Key 4/4");
1198 return;
1199 }
1200
1201 kck = sta->ptk.kck;
1202 kck_len = sta->ptk.kck_len;
1203 if (sta->tptk_set) {
1204 add_note(wt, MSG_DEBUG,
1205 "Use TPTK for validation EAPOL-Key MIC");
1206 kck = sta->tptk.kck;
1207 kck_len = sta->tptk.kck_len;
1208 }
1209 if (check_mic(sta, kck, kck_len,
1210 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
1211 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
1212 return;
1213 }
1214 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
1215 if (sta->tptk_set) {
1216 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
1217 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
1218 sta->ptk_set = 1;
1219 sta->tptk_set = 0;
1220 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
1221 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
1222 }
1223}
1224
1225
1226static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
1227 const u8 *src, const u8 *bssid,
1228 const u8 *data, size_t len)
1229{
1230 struct wlantest_bss *bss, *bss_mld;
1231 struct wlantest_sta *sta;
1232 const struct ieee802_1x_hdr *eapol;
1233 const struct wpa_eapol_key *hdr;
1234 u16 key_info, ver;
1235 u8 *decrypted;
1236 size_t decrypted_len = 0;
1237 size_t mic_len;
1238
1239 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR " (BSSID "
1240 MACSTR ")",
1241 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
1242 if (os_memcmp(src, bssid, ETH_ALEN) == 0) {
1243 bss = bss_get(wt, src);
1244 } else {
1245 bss = bss_find(wt, bssid);
1246 bss_mld = bss_find(wt, src);
1247 if (bss_mld && (!bss || sta_find(bss_mld, src)))
1248 bss = bss_get(wt, src);
1249 else
1250 bss = bss_get(wt, bssid);
1251 }
1252 if (bss == NULL)
1253 return;
1254 sta = sta_get(bss, dst);
1255 if (sta == NULL)
1256 return;
1257 mic_len = determine_mic_len(sta);
1258
1259 eapol = (const struct ieee802_1x_hdr *) data;
1260 hdr = (const struct wpa_eapol_key *) (eapol + 1);
1261 key_info = WPA_GET_BE16(hdr->key_info);
1262
1263 if (!sta->ptk_set) {
1264 add_note(wt, MSG_DEBUG,
1265 "No PTK known to process EAPOL-Key 1/2");
1266 return;
1267 }
1268
1269 if (sta->ptk_set &&
1270 check_mic(sta, sta->ptk.kck, sta->ptk.kck_len,
1271 key_info & WPA_KEY_INFO_TYPE_MASK,
1272 data, len) < 0) {
1273 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
1274 return;
1275 }
1276 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
1277
1278 if (sta->proto & WPA_PROTO_RSN &&
1279 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1280 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
1281 return;
1282 }
1283 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1284 decrypted = decrypt_eapol_key_data(wt, sta,
1285 sta->ptk.kek, sta->ptk.kek_len,
1286 ver, hdr, data + len,
1287 &decrypted_len);
1288 if (decrypted == NULL) {
1289 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
1290 return;
1291 }
1292 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
1293 decrypted, decrypted_len);
1294 if (wt->write_pcap_dumper || wt->pcapng) {
1295 /* Fill in a stub Data frame header */
1296 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr) + 64];
1297 struct ieee80211_hdr *h;
1298 struct wpa_eapol_key *k;
1299 u8 *pos;
1300 size_t plain_len;
1301
1302 plain_len = decrypted_len;
1303 pos = decrypted;
1304 while (pos + 1 < decrypted + decrypted_len) {
1305 if (pos[0] == 0xdd && pos[1] == 0x00) {
1306 /* Remove padding */
1307 plain_len = pos - decrypted;
1308 break;
1309 }
1310 pos += 2 + pos[1];
1311 }
1312
1313 os_memset(buf, 0, sizeof(buf));
1314 h = (struct ieee80211_hdr *) buf;
1315 h->frame_control = host_to_le16(0x0208);
1316 os_memcpy(h->addr1, dst, ETH_ALEN);
1317 os_memcpy(h->addr2, src, ETH_ALEN);
1318 os_memcpy(h->addr3, src, ETH_ALEN);
1319 pos = (u8 *) (h + 1);
1320 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
1321 pos += 8;
1322 os_memcpy(pos, eapol, sizeof(*eapol));
1323 pos += sizeof(*eapol);
1324 os_memcpy(pos, hdr, sizeof(*hdr) + mic_len);
1325 k = (struct wpa_eapol_key *) pos;
1326 pos += sizeof(struct wpa_eapol_key) + mic_len;
1327 WPA_PUT_BE16(k->key_info,
1328 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
1329 WPA_PUT_BE16(pos, plain_len);
1330 write_pcap_decrypted(wt, buf, 24 + 8 + sizeof(*eapol) +
1331 sizeof(*hdr) + mic_len + 2,
1332 decrypted, plain_len);
1333 }
1334 if (sta->proto & WPA_PROTO_RSN)
1335 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
1336 hdr->key_rsc);
1337 else {
1338 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
1339 if (decrypted_len == klen) {
1340 const u8 *rsc = hdr->key_rsc;
1341 int id;
1342 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1343 WPA_KEY_INFO_KEY_INDEX_SHIFT;
1344 add_note(wt, MSG_DEBUG, "GTK key index %d", id);
1345 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
1346 decrypted_len);
1347 bss->gtk_len[id] = decrypted_len;
1348 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
1349 bss->rsc[id][0] = rsc[5];
1350 bss->rsc[id][1] = rsc[4];
1351 bss->rsc[id][2] = rsc[3];
1352 bss->rsc[id][3] = rsc[2];
1353 bss->rsc[id][4] = rsc[1];
1354 bss->rsc[id][5] = rsc[0];
1355 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
1356 } else {
1357 add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
1358 "in Group Key msg 1/2 from " MACSTR,
1359 MAC2STR(src));
1360 }
1361 }
1362 os_free(decrypted);
1363}
1364
1365
1366static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
1367 const u8 *src, const u8 *bssid,
1368 const u8 *data, size_t len)
1369{
1370 struct wlantest_bss *bss, *bss_mld;
1371 struct wlantest_sta *sta;
1372 const struct ieee802_1x_hdr *eapol;
1373 const struct wpa_eapol_key *hdr;
1374 u16 key_info;
1375
1376 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR " (BSSID "
1377 MACSTR ")",
1378 MAC2STR(src), MAC2STR(dst), MAC2STR(bssid));
1379 if (os_memcmp(dst, bssid, ETH_ALEN) == 0) {
1380 bss = bss_get(wt, dst);
1381 } else {
1382 bss = bss_find(wt, bssid);
1383 bss_mld = bss_find(wt, dst);
1384 if (bss_mld && (!bss || sta_find(bss_mld, src)))
1385 bss = bss_get(wt, dst);
1386 else
1387 bss = bss_get(wt, bssid);
1388 }
1389 if (bss == NULL)
1390 return;
1391 sta = sta_get(bss, src);
1392 if (sta == NULL)
1393 return;
1394
1395 eapol = (const struct ieee802_1x_hdr *) data;
1396 hdr = (const struct wpa_eapol_key *) (eapol + 1);
1397 if (!is_zero(hdr->key_rsc, 8)) {
1398 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
1399 "non-zero Key RSC", MAC2STR(src));
1400 }
1401 key_info = WPA_GET_BE16(hdr->key_info);
1402
1403 if (!sta->ptk_set) {
1404 add_note(wt, MSG_DEBUG,
1405 "No PTK known to process EAPOL-Key 2/2");
1406 return;
1407 }
1408
1409 if (sta->ptk_set &&
1410 check_mic(sta, sta->ptk.kck, sta->ptk.kck_len,
1411 key_info & WPA_KEY_INFO_TYPE_MASK,
1412 data, len) < 0) {
1413 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
1414 return;
1415 }
1416 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
1417}
1418
1419
1420static void rx_data_eapol_key(struct wlantest *wt, const u8 *bssid,
1421 const u8 *sta_addr, const u8 *dst,
1422 const u8 *src, const u8 *data, size_t len,
1423 int prot)
1424{
1425 const struct ieee802_1x_hdr *eapol;
1426 const struct wpa_eapol_key *hdr;
1427 const u8 *key_data;
1428 u16 key_info, key_length, ver, key_data_length;
1429 size_t mic_len = 16;
1430 const u8 *mic;
1431 struct wlantest_bss *bss;
1432 struct wlantest_sta *sta;
1433
1434 bss = bss_get(wt, bssid);
1435 if (bss) {
1436 if (sta_addr)
1437 sta = sta_get(bss, sta_addr);
1438 else
1439 sta = NULL;
1440 mic_len = determine_mic_len(sta);
1441 }
1442
1443 eapol = (const struct ieee802_1x_hdr *) data;
1444 hdr = (const struct wpa_eapol_key *) (eapol + 1);
1445
1446 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
1447 (const u8 *) hdr, len - sizeof(*eapol));
1448 if (len < sizeof(*hdr) + mic_len + 2) {
1449 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
1450 MAC2STR(src));
1451 return;
1452 }
1453 mic = (const u8 *) (hdr + 1);
1454
1455 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
1456 /* TODO: EAPOL-Key RC4 for WEP */
1457 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
1458 MACSTR, MAC2STR(src));
1459 return;
1460 }
1461
1462 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
1463 hdr->type != EAPOL_KEY_TYPE_WPA) {
1464 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
1465 "%u from " MACSTR, hdr->type, MAC2STR(src));
1466 return;
1467 }
1468
1469 key_info = WPA_GET_BE16(hdr->key_info);
1470 key_length = WPA_GET_BE16(hdr->key_length);
1471 key_data_length = WPA_GET_BE16(mic + mic_len);
1472 key_data = mic + mic_len + 2;
1473 if (key_data + key_data_length > data + len) {
1474 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
1475 MAC2STR(src));
1476 return;
1477 }
1478 if (key_data + key_data_length < data + len) {
1479 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
1480 "field", key_data + key_data_length,
1481 data + len - key_data - key_data_length);
1482 }
1483
1484
1485 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1486 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
1487 "datalen=%u",
1488 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
1489 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1490 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1491 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
1492 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
1493 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
1494 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
1495 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
1496 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
1497 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
1498 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
1499 key_data_length);
1500
1501 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1502 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
1503 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1504 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
1505 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
1506 "Version %u from " MACSTR, ver, MAC2STR(src));
1507 return;
1508 }
1509
1510 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
1511 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
1512 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
1513 hdr->key_nonce, WPA_NONCE_LEN);
1514 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
1515 hdr->key_iv, 16);
1516 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
1517 hdr->key_rsc, WPA_KEY_RSC_LEN);
1518 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
1519 mic, mic_len);
1520 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
1521 key_data, key_data_length);
1522
1523 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
1524 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
1525 0) {
1526 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
1527 "Key Info bits 0x%x from " MACSTR,
1528 key_info, MAC2STR(src));
1529 }
1530
1531 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
1532 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
1533 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
1534 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
1535 "Key Info bits 0x%x from " MACSTR,
1536 key_info, MAC2STR(src));
1537 }
1538
1539 if (key_length > 32) {
1540 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
1541 "from " MACSTR, key_length, MAC2STR(src));
1542 }
1543
1544 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1545 !is_zero(hdr->key_iv, 16)) {
1546 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
1547 "(reserved with ver=%d) field from " MACSTR,
1548 ver, MAC2STR(src));
1549 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
1550 hdr->key_iv, 16);
1551 }
1552
1553 if (!is_zero(hdr->key_id, 8)) {
1554 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
1555 "(reserved) field from " MACSTR, MAC2STR(src));
1556 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
1557 hdr->key_id, 8);
1558 }
1559
1560 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
1561 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
1562 "(last two are unused)" MACSTR, MAC2STR(src));
1563 }
1564
1565 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
1566 return;
1567
1568 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
1569 return;
1570
1571 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1572 /* 4-Way Handshake */
1573 switch (key_info & (WPA_KEY_INFO_SECURE |
1574 WPA_KEY_INFO_MIC |
1575 WPA_KEY_INFO_ACK |
1576 WPA_KEY_INFO_INSTALL)) {
1577 case WPA_KEY_INFO_ACK:
1578 rx_data_eapol_key_1_of_4(wt, dst, src, bssid,
1579 data, len);
1580 break;
1581 case WPA_KEY_INFO_MIC:
1582 if (key_data_length == 0 ||
1583 is_zero(hdr->key_nonce, WPA_NONCE_LEN))
1584 rx_data_eapol_key_4_of_4(wt, dst, src, bssid,
1585 data, len);
1586 else
1587 rx_data_eapol_key_2_of_4(wt, dst, src, bssid,
1588 data, len);
1589 break;
1590 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1591 WPA_KEY_INFO_INSTALL:
1592 /* WPA does not include Secure bit in 3/4 */
1593 rx_data_eapol_key_3_of_4(wt, dst, src, bssid,
1594 data, len);
1595 break;
1596 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1597 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1598 case WPA_KEY_INFO_SECURE |
1599 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1600 rx_data_eapol_key_3_of_4(wt, dst, src, bssid,
1601 data, len);
1602 break;
1603 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1604 case WPA_KEY_INFO_SECURE:
1605 if (key_data_length == 0 ||
1606 is_zero(hdr->key_nonce, WPA_NONCE_LEN))
1607 rx_data_eapol_key_4_of_4(wt, dst, src, bssid,
1608 data, len);
1609 else
1610 rx_data_eapol_key_2_of_4(wt, dst, src, bssid,
1611 data, len);
1612 break;
1613 default:
1614 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1615 break;
1616 }
1617 } else {
1618 /* Group Key Handshake */
1619 switch (key_info & (WPA_KEY_INFO_SECURE |
1620 WPA_KEY_INFO_MIC |
1621 WPA_KEY_INFO_ACK)) {
1622 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1623 WPA_KEY_INFO_ACK:
1624 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ACK:
1625 rx_data_eapol_key_1_of_2(wt, dst, src, bssid,
1626 data, len);
1627 break;
1628 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1629 case WPA_KEY_INFO_SECURE:
1630 rx_data_eapol_key_2_of_2(wt, dst, src, bssid,
1631 data, len);
1632 break;
1633 default:
1634 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1635 break;
1636 }
1637 }
1638}
1639
1640
1641void rx_data_eapol(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
1642 const u8 *dst, const u8 *src,
1643 const u8 *data, size_t len, int prot)
1644{
1645 const struct ieee802_1x_hdr *hdr;
1646 u16 length;
1647 const u8 *p;
1648
1649 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1650 if (len < sizeof(*hdr)) {
1651 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1652 MAC2STR(src));
1653 return;
1654 }
1655
1656 hdr = (const struct ieee802_1x_hdr *) data;
1657 length = be_to_host16(hdr->length);
1658 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1659 "type=%u len=%u",
1660 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1661 hdr->version, hdr->type, length);
1662 if (hdr->version < 1 || hdr->version > 3) {
1663 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1664 MACSTR, hdr->version, MAC2STR(src));
1665 }
1666 if (sizeof(*hdr) + length > len) {
1667 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1668 MAC2STR(src));
1669 return;
1670 }
1671
1672 if (sizeof(*hdr) + length < len) {
1673 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1674 (int) (len - sizeof(*hdr) - length));
1675 }
1676 p = (const u8 *) (hdr + 1);
1677
1678 switch (hdr->type) {
1679 case IEEE802_1X_TYPE_EAP_PACKET:
1680 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1681 break;
1682 case IEEE802_1X_TYPE_EAPOL_START:
1683 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1684 break;
1685 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1686 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1687 break;
1688 case IEEE802_1X_TYPE_EAPOL_KEY:
1689 rx_data_eapol_key(wt, bssid, sta_addr, dst, src, data,
1690 sizeof(*hdr) + length, prot);
1691 break;
1692 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1693 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1694 p, length);
1695 break;
1696 default:
1697 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
1698 break;
1699 }
1700}