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