1 /*
2  * Received Management frame processing
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 "common/defs.h"
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "common/wpa_common.h"
16 #include "crypto/aes.h"
17 #include "crypto/aes_siv.h"
18 #include "crypto/aes_wrap.h"
19 #include "wlantest.h"
20 
21 
22 static int check_mmie_mic(unsigned int mgmt_group_cipher,
23 			  const u8 *igtk, size_t igtk_len,
24 			  const u8 *data, size_t len);
25 
26 
mgmt_stype(u16 stype)27 static const char * mgmt_stype(u16 stype)
28 {
29 	switch (stype) {
30 	case WLAN_FC_STYPE_ASSOC_REQ:
31 		return "ASSOC-REQ";
32 	case WLAN_FC_STYPE_ASSOC_RESP:
33 		return "ASSOC-RESP";
34 	case WLAN_FC_STYPE_REASSOC_REQ:
35 		return "REASSOC-REQ";
36 	case WLAN_FC_STYPE_REASSOC_RESP:
37 		return "REASSOC-RESP";
38 	case WLAN_FC_STYPE_PROBE_REQ:
39 		return "PROBE-REQ";
40 	case WLAN_FC_STYPE_PROBE_RESP:
41 		return "PROBE-RESP";
42 	case WLAN_FC_STYPE_BEACON:
43 		return "BEACON";
44 	case WLAN_FC_STYPE_ATIM:
45 		return "ATIM";
46 	case WLAN_FC_STYPE_DISASSOC:
47 		return "DISASSOC";
48 	case WLAN_FC_STYPE_AUTH:
49 		return "AUTH";
50 	case WLAN_FC_STYPE_DEAUTH:
51 		return "DEAUTH";
52 	case WLAN_FC_STYPE_ACTION:
53 		return "ACTION";
54 	case WLAN_FC_STYPE_ACTION_NO_ACK:
55 		return "ACTION-NO-ACK";
56 	}
57 	return "??";
58 }
59 
60 
parse_basic_ml(const u8 * ie,size_t len,bool ap,struct wlantest_sta * sta,size_t fields_len)61 static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
62 			   struct wlantest_sta *sta, size_t fields_len)
63 {
64 	const u8 *pos, *end, *ci_end, *info_end, *li_end;
65 	u16 ctrl, eml, cap;
66 	const struct element *elem;
67 	struct wpabuf *profile = NULL;
68 
69 	wpa_hexdump(MSG_MSGDUMP, "Basic MLE", ie, len);
70 	pos = ie;
71 	end = ie + len;
72 
73 	if (end - pos < 2)
74 		return;
75 	ctrl = WPA_GET_LE16(pos);
76 	wpa_printf(MSG_DEBUG,
77 		   "Multi-Link Control: Type=%u Reserved=%u Presence Bitmap=0x%x",
78 		   ctrl & MULTI_LINK_CONTROL_TYPE_MASK,
79 		   ctrl & BIT(3),
80 		   ctrl >> 4);
81 	pos += 2;
82 
83 	/* Common Info */
84 
85 	if (end - pos < 1)
86 		return;
87 	len = *pos;
88 	if (len > end - pos) {
89 		wpa_printf(MSG_INFO,
90 			   "Truncated Multi-Link Common Info (len=%zu left=%zu)",
91 			   len, (size_t) (end - pos));
92 		return;
93 	}
94 	if (len < 1 + ETH_ALEN) {
95 		wpa_printf(MSG_INFO,
96 			   "No room for MLD MAC Address in Multi-Link Common Info");
97 		return;
98 	}
99 	ci_end = pos + len;
100 
101 	pos++;
102 	wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Common Info", pos, ci_end - pos);
103 	wpa_printf(MSG_DEBUG, "MLD MAC Address: " MACSTR, MAC2STR(pos));
104 	if (!ap && sta && is_zero_ether_addr(sta->mld_mac_addr)) {
105 		os_memcpy(sta->mld_mac_addr, pos, ETH_ALEN);
106 		wpa_printf(MSG_DEBUG,
107 			   "Learned non-AP STA MLD MAC Address from Basic MLE: "
108 			   MACSTR, MAC2STR(sta->mld_mac_addr));
109 	}
110 	pos += ETH_ALEN;
111 
112 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID) {
113 		if (ci_end - pos < 1) {
114 			wpa_printf(MSG_INFO,
115 				   "No room for Link ID Info in Multi-Link Common Info");
116 			return;
117 		}
118 		wpa_printf(MSG_DEBUG, "Link ID Info: 0x%x", *pos);
119 		if (!ap)
120 			wpa_printf(MSG_INFO,
121 				   "Unexpected Link ID Info in Common Info from a non-AP STA");
122 		pos++;
123 	}
124 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT) {
125 		if (ci_end - pos < 1) {
126 			wpa_printf(MSG_INFO,
127 				   "No room for BSS Parameters Change Count in Multi-Link Common Info");
128 			return;
129 		}
130 		wpa_printf(MSG_DEBUG, "BSS Parameters Change Count: %u", *pos);
131 		if (!ap)
132 			wpa_printf(MSG_INFO,
133 				   "Unexpected BSS Parameters Change Count in Common Info from a non-AP STA");
134 		pos++;
135 	}
136 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) {
137 		if (ci_end - pos < 2) {
138 			wpa_printf(MSG_INFO,
139 				   "No room for Medium Synchronization Delay Information in Multi-Link Common Info");
140 			return;
141 		}
142 		wpa_printf(MSG_DEBUG,
143 			   "Medium Synchronization Delay Information: 0x%x",
144 			   WPA_GET_LE16(pos));
145 		if (!ap)
146 			wpa_printf(MSG_INFO,
147 				   "Unexpected Medium Synchronization Delay Information in Common Info from a non-AP STA");
148 		pos += 2;
149 	}
150 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) {
151 		if (ci_end - pos < 2) {
152 			wpa_printf(MSG_INFO,
153 				   "No room for EML Capabilities in Multi-Link Common Info");
154 			return;
155 		}
156 		eml = WPA_GET_LE16(pos);
157 		pos += 2;
158 		wpa_printf(MSG_DEBUG,
159 			   "EML Capabilities: 0x%x (EMLSR=%u EMLSR_Padding_Delay=%u EMLSR_Transition_Delay=%u EMLMR=%u EMLMR_Delay=%u Transition_Timeout=%u Reserved=%u)",
160 			   eml,
161 			   !!(eml & EHT_ML_EML_CAPA_EMLSR_SUPP),
162 			   (eml & EHT_ML_EML_CAPA_EMLSR_PADDING_DELAY_MASK) >>
163 			   1,
164 			   (eml & EHT_ML_EML_CAPA_EMLSR_TRANS_DELAY_MASK) >> 4,
165 			   !!(eml & EHT_ML_EML_CAPA_EMLMR_SUPP),
166 			   (eml & EHT_ML_EML_CAPA_EMLMR_DELAY_MASK) >> 8,
167 			   (eml & EHT_ML_EML_CAPA_TRANSITION_TIMEOUT_MASK) >>
168 			   11,
169 			   !!(eml & BIT(15)));
170 	}
171 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) {
172 		if (ci_end - pos < 2) {
173 			wpa_printf(MSG_INFO,
174 				   "No room for MLD Capabilities and Operations in Multi-Link Common Info");
175 			return;
176 		}
177 		cap = WPA_GET_LE16(pos);
178 		pos += 2;
179 		wpa_printf(MSG_DEBUG,
180 			   "MLD Capabilities and Operations: 0x%x (Max_Simultaneous_Links=%u SRS=%u T2L=0x%x Freq_Sep_STR=0x%x AAR=%u Reserved=0x%x)",
181 			   cap,
182 			   cap & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK,
183 			   !!(cap & EHT_ML_MLD_CAPA_SRS_SUPP),
184 			   (cap &
185 			    EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK) >> 5,
186 			   (cap & EHT_ML_MLD_CAPA_FREQ_SEP_FOR_STR_MASK) >> 7,
187 			   !!(cap & EHT_ML_MLD_CAPA_AAR_SUPP),
188 			   (cap & 0xe000) >> 13);
189 	}
190 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID) {
191 		if (ci_end - pos < 1) {
192 			wpa_printf(MSG_INFO,
193 				   "No room for AP MLD ID in Multi-Link Common Info");
194 			return;
195 		}
196 		wpa_printf(MSG_DEBUG, "AP MLD ID: %u", *pos);
197 		pos++;
198 	}
199 
200 	if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_EXT_MLD_CAP) {
201 		if (ci_end - pos < 2) {
202 			wpa_printf(MSG_INFO,
203 				   "No room for Extended MLD Capabilities And Operations in Multi-Link Common Info");
204 			return;
205 		}
206 		wpa_printf(MSG_DEBUG,
207 			   "Extended MLD Capabilities And Operations: 0x%x",
208 			   WPA_GET_LE16(pos));
209 		pos += 2;
210 	}
211 
212 	if (pos < ci_end) {
213 		wpa_hexdump(MSG_INFO,
214 			    "Extra information at the end of Common Info",
215 			    pos, ci_end - pos);
216 		pos = ci_end;
217 	}
218 
219 	/* Link Info */
220 	wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Link Info", pos, end - pos);
221 
222 	li_end = end;
223 	for_each_element(elem, pos, li_end - pos) {
224 		u8 link_id;
225 		const u8 *fpos;
226 		u8 flen;
227 
228 		if (elem->id == EHT_ML_SUB_ELEM_FRAGMENT)
229 			continue;
230 
231 		if (elem->id != EHT_ML_SUB_ELEM_PER_STA_PROFILE) {
232 			wpa_printf(MSG_DEBUG, "Link Info subelement id=%u",
233 				   elem->id);
234 			wpa_hexdump(MSG_DEBUG, "Link Info subelement data",
235 				    elem->data, elem->datalen);
236 			continue;
237 		}
238 
239 		wpabuf_free(profile);
240 		profile = wpabuf_alloc_copy(elem->data, elem->datalen);
241 		if (!profile)
242 			continue;
243 		flen = elem->datalen;
244 		fpos = elem->data + flen;
245 		while (flen == 255 && li_end - fpos >= 2 &&
246 		       *fpos == EHT_ML_SUB_ELEM_FRAGMENT &&
247 		       li_end - fpos >= 2 + fpos[1]) {
248 			/* Reassemble truncated subelement */
249 			fpos++;
250 			flen = *fpos++;
251 			if (wpabuf_resize(&profile, flen) < 0)
252 				continue;
253 			wpabuf_put_data(profile, fpos, flen);
254 			fpos += flen;
255 		}
256 		pos = wpabuf_head(profile);
257 		end = pos + wpabuf_len(profile);
258 
259 		if (end - pos < 2) {
260 			wpa_printf(MSG_INFO,
261 				   "Truncated Per-STA Profile subelement");
262 			continue;
263 		}
264 		wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Per-STA Profile",
265 			    pos, end - pos);
266 		ctrl = WPA_GET_LE16(pos);
267 		pos += 2;
268 
269 		link_id = ctrl & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
270 		wpa_printf(MSG_DEBUG, "Per-STA Profile: len=%zu Link_ID=%u Complete=%u Reserved=0x%x",
271 			   wpabuf_len(profile),
272 			   link_id,
273 			   !!(ctrl & BASIC_MLE_STA_CTRL_COMPLETE_PROFILE),
274 			   (ctrl & 0xf000) >> 12);
275 
276 		if (end - pos < 1) {
277 			wpa_printf(MSG_INFO, "No room for STA Info field");
278 			continue;
279 		}
280 		len = *pos;
281 		if (len < 1 || len > end - pos) {
282 			wpa_printf(MSG_INFO, "Truncated STA Info field");
283 			continue;
284 		}
285 		info_end = pos + len;
286 		pos++;
287 		if (ctrl & BASIC_MLE_STA_CTRL_PRES_STA_MAC) {
288 			if (info_end - pos < ETH_ALEN) {
289 				wpa_printf(MSG_INFO,
290 					   "Truncated STA MAC Address in STA Info");
291 				continue;
292 			}
293 			wpa_printf(MSG_DEBUG, "STA MAC Address: " MACSTR,
294 				   MAC2STR(pos));
295 			if (sta && link_id < MAX_NUM_MLD_LINKS) {
296 				os_memcpy(sta->link_addr[link_id], pos,
297 					  ETH_ALEN);
298 				wpa_printf(MSG_DEBUG,
299 					   "Learned Link ID %u MAC address "
300 					   MACSTR
301 					   " from Association Request",
302 					   link_id, MAC2STR(pos));
303 			}
304 			pos += ETH_ALEN;
305 		}
306 		if (ctrl & BASIC_MLE_STA_CTRL_PRES_BEACON_INT) {
307 			if (info_end - pos < 2) {
308 				wpa_printf(MSG_INFO,
309 					   "Truncated Beacon Interval in STA Info");
310 				continue;
311 			}
312 			wpa_printf(MSG_DEBUG, "Beacon Interval: %u",
313 				   WPA_GET_LE16(pos));
314 			pos += 2;
315 		}
316 		if (ctrl & BASIC_MLE_STA_CTRL_PRES_TSF_OFFSET) {
317 			if (info_end - pos < 8) {
318 				wpa_printf(MSG_INFO,
319 					   "Truncated TSF Offset in STA Info");
320 				continue;
321 			}
322 			wpa_printf(MSG_DEBUG, "TSF Offset: 0x%llx",
323 				   (long long unsigned) WPA_GET_LE64(pos));
324 			pos += 8;
325 		}
326 		if (ctrl & BASIC_MLE_STA_CTRL_PRES_DTIM_INFO) {
327 			if (info_end - pos < 2) {
328 				wpa_printf(MSG_INFO,
329 					   "Truncated DTIM Info in STA Info");
330 				continue;
331 			}
332 			wpa_printf(MSG_DEBUG, "DTIM Info: 0x%x",
333 				   WPA_GET_LE16(pos));
334 			pos += 2;
335 		}
336 		if ((ctrl & (BASIC_MLE_STA_CTRL_COMPLETE_PROFILE |
337 			     BASIC_MLE_STA_CTRL_PRES_NSTR_LINK_PAIR)) ==
338 		    (BASIC_MLE_STA_CTRL_COMPLETE_PROFILE |
339 		     BASIC_MLE_STA_CTRL_PRES_NSTR_LINK_PAIR)) {
340 			if (ctrl & BASIC_MLE_STA_CTRL_NSTR_BITMAP) {
341 				if (info_end - pos < 2) {
342 					wpa_printf(MSG_INFO,
343 						   "Truncated NSTR Indication Bitmap in STA Info");
344 					continue;
345 				}
346 				wpa_printf(MSG_DEBUG, "NSTR Indication Bitmap: 0x%04x",
347 					   WPA_GET_LE16(pos));
348 				pos += 2;
349 			} else {
350 				if (info_end - pos < 1) {
351 					wpa_printf(MSG_INFO,
352 						   "Truncated NSTR Indication Bitmap in STA Info");
353 					continue;
354 				}
355 				wpa_printf(MSG_DEBUG, "NSTR Indication Bitmap: 0x%02x",
356 					   *pos);
357 				pos++;
358 			}
359 		}
360 		if (ctrl & BASIC_MLE_STA_CTRL_PRES_BSS_PARAM_COUNT) {
361 			if (info_end - pos < 1) {
362 				wpa_printf(MSG_INFO,
363 					   "Truncated BSS Parameters Change Count in STA Info");
364 				continue;
365 			}
366 			wpa_printf(MSG_DEBUG, "BSS Parameters Change Count: %u",
367 				   *pos);
368 			pos++;
369 		}
370 		if (info_end > pos) {
371 			wpa_hexdump(MSG_INFO,
372 				    "Extra information at the end of STA Info",
373 				    pos, info_end - pos);
374 			pos = info_end;
375 		}
376 
377 		wpa_hexdump(MSG_DEBUG, "STA Profile", pos, end - pos);
378 		if (end - pos > fields_len) {
379 			struct ieee802_11_elems elems;
380 
381 			if (ieee802_11_parse_elems(pos + fields_len,
382 						   end - pos - fields_len,
383 						   &elems, 0) != ParseFailed) {
384 				if (elems.rsn_ie)
385 					wpa_hexdump(MSG_DEBUG, "RSNE",
386 						    elems.rsn_ie,
387 						    elems.rsn_ie_len);
388 				if (elems.rsnxe)
389 					wpa_hexdump(MSG_DEBUG, "RSNXE",
390 						    elems.rsnxe,
391 						    elems.rsnxe_len);
392 			}
393 		}
394 	}
395 
396 	wpabuf_free(profile);
397 }
398 
399 
parse_basic_ml_elems(struct ieee802_11_elems * elems,bool ap,struct wlantest_sta * sta,size_t fields_len)400 static void parse_basic_ml_elems(struct ieee802_11_elems *elems, bool ap,
401 				 struct wlantest_sta *sta, size_t fields_len)
402 {
403 	struct wpabuf *mlbuf;
404 
405 	mlbuf = ieee802_11_defrag(elems->basic_mle, elems->basic_mle_len, true);
406 	if (mlbuf) {
407 		parse_basic_ml(wpabuf_head(mlbuf), wpabuf_len(mlbuf), ap, sta,
408 			       fields_len);
409 		wpabuf_free(mlbuf);
410 	}
411 }
412 
413 
parse_reconfig_ml(const u8 * ie,size_t len,struct wlantest_sta * sta)414 static void parse_reconfig_ml(const u8 *ie, size_t len,
415 			      struct wlantest_sta *sta)
416 {
417 	const u8 *pos, *end, *ci_end, *info_end, *li_end;
418 	u16 ctrl, eml, cap, bitmap;
419 	const struct element *elem;
420 	struct wpabuf *profile = NULL;
421 	size_t fields_len = 2;
422 
423 	wpa_hexdump(MSG_MSGDUMP, "Reconfiguration MLE", ie, len);
424 	pos = ie;
425 	end = ie + len;
426 
427 	if (end - pos < 2)
428 		return;
429 	ctrl = WPA_GET_LE16(pos);
430 	bitmap = ctrl >> 4;
431 	wpa_printf(MSG_DEBUG,
432 		   "Multi-Link Control: Type=%u Reserved=%u Presence Bitmap=0x%x",
433 		   ctrl & MULTI_LINK_CONTROL_TYPE_MASK,
434 		   ctrl & BIT(3),
435 		   bitmap);
436 	pos += 2;
437 
438 	/* Common Info */
439 
440 	if (end - pos < 1)
441 		return;
442 	len = *pos;
443 	if (len > end - pos) {
444 		wpa_printf(MSG_INFO,
445 			   "Truncated Multi-Link Common Info (len=%zu left=%zu)",
446 			   len, (size_t) (end - pos));
447 		return;
448 	}
449 	if (len < 1) {
450 		wpa_printf(MSG_INFO, "Too short Multi-Link Common Info");
451 		return;
452 	}
453 	ci_end = pos + len;
454 
455 	pos++;
456 	wpa_hexdump(MSG_MSGDUMP, "Reconfiguration MLE - Common Info",
457 		    pos, ci_end - pos);
458 
459 	if (bitmap & RECONF_MULTI_LINK_CTRL_PRES_MLD_MAC_ADDR) {
460 		if (ci_end - pos < ETH_ALEN) {
461 			wpa_printf(MSG_INFO,
462 				   "No room for MLD MAC Address in Multi-Link Common Info");
463 			return;
464 		}
465 		wpa_printf(MSG_DEBUG, "MLD MAC Address: " MACSTR, MAC2STR(pos));
466 		if (sta && is_zero_ether_addr(sta->mld_mac_addr)) {
467 			os_memcpy(sta->mld_mac_addr, pos, ETH_ALEN);
468 			wpa_printf(MSG_DEBUG,
469 				   "Learned non-AP STA MLD MAC Address from Reconfig MLE: "
470 				   MACSTR, MAC2STR(sta->mld_mac_addr));
471 		}
472 		pos += ETH_ALEN;
473 	}
474 
475 	if (bitmap & RECONF_MULTI_LINK_CTRL_PRES_EML_CAPA) {
476 		if (ci_end - pos < 2) {
477 			wpa_printf(MSG_INFO,
478 				   "No room for EML Capabilities in Multi-Link Common Info");
479 			return;
480 		}
481 		eml = WPA_GET_LE16(pos);
482 		pos += 2;
483 		wpa_printf(MSG_DEBUG,
484 			   "EML Capabilities: 0x%x (EMLSR=%u EMLSR_Padding_Delay=%u EMLSR_Transition_Delay=%u EMLMR=%u EMLMR_Delay=%u Transition_Timeout=%u Reserved=%u)",
485 			   eml,
486 			   !!(eml & EHT_ML_EML_CAPA_EMLSR_SUPP),
487 			   (eml & EHT_ML_EML_CAPA_EMLSR_PADDING_DELAY_MASK) >>
488 			   1,
489 			   (eml & EHT_ML_EML_CAPA_EMLSR_TRANS_DELAY_MASK) >> 4,
490 			   !!(eml & EHT_ML_EML_CAPA_EMLMR_SUPP),
491 			   (eml & EHT_ML_EML_CAPA_EMLMR_DELAY_MASK) >> 8,
492 			   (eml & EHT_ML_EML_CAPA_TRANSITION_TIMEOUT_MASK) >>
493 			   11,
494 			   !!(eml & BIT(15)));
495 	}
496 
497 	if (bitmap & RECONF_MULTI_LINK_CTRL_PRES_MLD_CAPA) {
498 		if (ci_end - pos < 2) {
499 			wpa_printf(MSG_INFO,
500 				   "No room for MLD Capabilities and Operations in Multi-Link Common Info");
501 			return;
502 		}
503 		cap = WPA_GET_LE16(pos);
504 		pos += 2;
505 		wpa_printf(MSG_DEBUG,
506 			   "MLD Capabilities and Operations: 0x%x (Max_Simultaneous_Links=%u SRS=%u T2L=0x%x Freq_Sep_STR=0x%x AAR=%u Reserved=0x%x)",
507 			   cap,
508 			   cap & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK,
509 			   !!(cap & EHT_ML_MLD_CAPA_SRS_SUPP),
510 			   (cap &
511 			    EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK) >> 5,
512 			   (cap & EHT_ML_MLD_CAPA_FREQ_SEP_FOR_STR_MASK) >> 7,
513 			   !!(cap & EHT_ML_MLD_CAPA_AAR_SUPP),
514 			   (cap & 0xe000) >> 13);
515 	}
516 
517 	if (bitmap & RECONF_MULTI_LINK_CTRL_PRES_EXT_MLD_CAP) {
518 		if (ci_end - pos < 2) {
519 			wpa_printf(MSG_INFO,
520 				   "No room for Extended MLD Capabilities And Operations in Multi-Link Common Info");
521 			return;
522 		}
523 		wpa_printf(MSG_DEBUG,
524 			   "Extended MLD Capabilities And Operations: 0x%x",
525 			   WPA_GET_LE16(pos));
526 		pos += 2;
527 	}
528 
529 	if (pos < ci_end) {
530 		wpa_hexdump(MSG_INFO,
531 			    "Extra information at the end of Common Info",
532 			    pos, ci_end - pos);
533 		pos = ci_end;
534 	}
535 
536 	/* Link Info */
537 	wpa_hexdump(MSG_MSGDUMP, "Reconfiguration MLE - Link Info",
538 		    pos, end - pos);
539 
540 	li_end = end;
541 	for_each_element(elem, pos, li_end - pos) {
542 		u8 link_id;
543 		const u8 *fpos;
544 		u8 flen;
545 
546 		if (elem->id == EHT_ML_SUB_ELEM_FRAGMENT)
547 			continue;
548 
549 		if (elem->id != EHT_ML_SUB_ELEM_PER_STA_PROFILE) {
550 			wpa_printf(MSG_DEBUG, "Link Info subelement id=%u",
551 				   elem->id);
552 			wpa_hexdump(MSG_DEBUG, "Link Info subelement data",
553 				    elem->data, elem->datalen);
554 			continue;
555 		}
556 
557 		wpabuf_free(profile);
558 		profile = wpabuf_alloc_copy(elem->data, elem->datalen);
559 		if (!profile)
560 			continue;
561 		flen = elem->datalen;
562 		fpos = elem->data + flen;
563 		while (flen == 255 && li_end - fpos >= 2 &&
564 		       *fpos == EHT_ML_SUB_ELEM_FRAGMENT &&
565 		       li_end - fpos >= 2 + fpos[1]) {
566 			/* Reassemble truncated subelement */
567 			fpos++;
568 			flen = *fpos++;
569 			if (wpabuf_resize(&profile, flen) < 0)
570 				continue;
571 			wpabuf_put_data(profile, fpos, flen);
572 			fpos += flen;
573 		}
574 		pos = wpabuf_head(profile);
575 		end = pos + wpabuf_len(profile);
576 
577 		if (end - pos < 2) {
578 			wpa_printf(MSG_INFO,
579 				   "Truncated Per-STA Profile subelement");
580 			continue;
581 		}
582 		wpa_hexdump(MSG_MSGDUMP,
583 			    "Reconfiguration MLE - Per-STA Profile",
584 			    pos, end - pos);
585 		ctrl = WPA_GET_LE16(pos);
586 		pos += 2;
587 
588 		link_id = ctrl & EHT_PER_STA_RECONF_CTRL_LINK_ID_MSK;
589 		wpa_printf(MSG_DEBUG, "Per-STA Profile: len=%zu Link_ID=%u Complete=%u Reserved=0x%x",
590 			   wpabuf_len(profile),
591 			   link_id,
592 			   !!(ctrl & EHT_PER_STA_RECONF_CTRL_COMPLETE_PROFILE),
593 			   (ctrl & 0xc000) >> 14);
594 
595 		if (end - pos < 1) {
596 			wpa_printf(MSG_INFO, "No room for STA Info field");
597 			continue;
598 		}
599 		len = *pos;
600 		if (len < 1 || len > end - pos) {
601 			wpa_printf(MSG_INFO, "Truncated STA Info field");
602 			continue;
603 		}
604 		info_end = pos + len;
605 		pos++;
606 
607 		if (ctrl & EHT_PER_STA_RECONF_CTRL_MAC_ADDR) {
608 			if (info_end - pos < ETH_ALEN) {
609 				wpa_printf(MSG_INFO,
610 					   "Truncated STA MAC Address in STA Info");
611 				continue;
612 			}
613 			wpa_printf(MSG_DEBUG, "STA MAC Address: " MACSTR,
614 				   MAC2STR(pos));
615 			if (sta && link_id < MAX_NUM_MLD_LINKS) {
616 				os_memcpy(sta->link_addr[link_id], pos,
617 					  ETH_ALEN);
618 				wpa_printf(MSG_DEBUG,
619 					   "Learned Link ID %u MAC address "
620 					   MACSTR
621 					   " from Link Reconfiguration Request",
622 					   link_id, MAC2STR(pos));
623 			}
624 			pos += ETH_ALEN;
625 		}
626 
627 		if (ctrl & EHT_PER_STA_RECONF_CTRL_AP_REMOVAL_TIMER) {
628 			if (info_end - pos < 2) {
629 				wpa_printf(MSG_INFO,
630 					   "Truncated AP Removal Timer in STA Info");
631 				continue;
632 			}
633 			pos += 2;
634 		}
635 
636 		if (ctrl & EHT_PER_STA_RECONF_CTRL_OP_PARAMS) {
637 			if (info_end - pos < 3) {
638 				wpa_printf(MSG_INFO,
639 					   "Truncated Operation Parameters in STA Info");
640 				continue;
641 			}
642 			pos += 3;
643 		}
644 
645 		if (info_end > pos) {
646 			wpa_hexdump(MSG_INFO,
647 				    "Extra information at the end of STA Info",
648 				    pos, info_end - pos);
649 			pos = info_end;
650 		}
651 
652 		wpa_hexdump(MSG_DEBUG, "STA Profile", pos, end - pos);
653 		if (end - pos > fields_len) {
654 			struct ieee802_11_elems elems;
655 
656 			if (ieee802_11_parse_elems(pos + fields_len,
657 						   end - pos - fields_len,
658 						   &elems, 0) != ParseFailed) {
659 				if (elems.rsn_ie)
660 					wpa_hexdump(MSG_DEBUG, "RSNE",
661 						    elems.rsn_ie,
662 						    elems.rsn_ie_len);
663 				if (elems.rsnxe)
664 					wpa_hexdump(MSG_DEBUG, "RSNXE",
665 						    elems.rsnxe,
666 						    elems.rsnxe_len);
667 			}
668 		}
669 	}
670 
671 	wpabuf_free(profile);
672 }
673 
674 
parse_reconfig_ml_elems(struct ieee802_11_elems * elems,struct wlantest_sta * sta)675 static void parse_reconfig_ml_elems(struct ieee802_11_elems *elems,
676 				    struct wlantest_sta *sta)
677 {
678 	struct wpabuf *mlbuf;
679 
680 	mlbuf = ieee802_11_defrag(elems->reconf_mle, elems->reconf_mle_len,
681 				  true);
682 	if (mlbuf) {
683 		parse_reconfig_ml(wpabuf_head(mlbuf), wpabuf_len(mlbuf), sta);
684 		wpabuf_free(mlbuf);
685 	}
686 }
687 
688 
rx_mgmt_beacon(struct wlantest * wt,const u8 * data,size_t len)689 static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
690 {
691 	const struct ieee80211_mgmt *mgmt;
692 	struct wlantest_bss *bss;
693 	struct ieee802_11_elems elems;
694 	size_t offset;
695 	const u8 *mme;
696 	size_t mic_len;
697 	u16 keyid;
698 	u64 rx_bipn;
699 
700 	mgmt = (const struct ieee80211_mgmt *) data;
701 	offset = mgmt->u.beacon.variable - data;
702 	if (len < offset)
703 		return;
704 	bss = bss_get(wt, mgmt->bssid);
705 	if (bss == NULL)
706 		return;
707 	/* do not override with Beacon data */
708 	if (!bss->proberesp_seen)
709 		bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info);
710 	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - offset,
711 				   &elems, 0) == ParseFailed) {
712 		if (bss->parse_error_reported)
713 			return;
714 		add_note(wt, MSG_INFO, "Invalid IEs in a Beacon frame from "
715 			 MACSTR, MAC2STR(mgmt->sa));
716 		bss->parse_error_reported = 1;
717 		return;
718 	}
719 
720 	if (elems.rsnxe) {
721 		os_memcpy(bss->rsnxe, elems.rsnxe, elems.rsnxe_len);
722 		bss->rsnxe_len = elems.rsnxe_len;
723 	} else {
724 		bss->rsnxe_len = 0;
725 	}
726 
727 	if (elems.rsnxe_override) {
728 		os_memcpy(bss->rsnxoe, elems.rsnxe_override + 4,
729 			  elems.rsnxe_override_len - 4);
730 		bss->rsnxoe_len = elems.rsnxe_override_len;
731 	} else {
732 		bss->rsnxoe_len = 0;
733 	}
734 
735 	if (!bss->proberesp_seen)
736 		bss_update(wt, bss, &elems, 1);
737 
738 	if (elems.mbssid) {
739 		const u8 *pos = elems.mbssid;
740 		const u8 *end = elems.mbssid + elems.mbssid_len;
741 		u8 max_bss = *pos++;
742 
743 		while (end - pos > 2) {
744 			u8 s_id, s_len, ssid_len, bssid_idx;
745 			const u8 *s_data, *ssid;
746 			u16 capa;
747 			u8 bssid[ETH_ALEN], b;
748 			struct ieee802_11_elems m_elems, merged;
749 			struct wlantest_bss *m_bss;
750 
751 			s_id = *pos++;
752 			s_len = *pos++;
753 
754 			if (end - pos < s_len)
755 				break;
756 			s_data = pos;
757 			pos += s_len;
758 
759 			if (s_id !=
760 			    WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE)
761 				continue;
762 
763 			/* Nontransmitted BSSID Capability element */
764 			if (pos - s_data < 4 ||
765 			    s_data[0] != WLAN_EID_NONTRANSMITTED_BSSID_CAPA ||
766 			    s_data[1] < 2)
767 				continue;
768 			capa = WPA_GET_LE16(&s_data[2]);
769 			s_data += 2 + s_data[1];
770 
771 			/* SSID element */
772 			if (pos - s_data < 2 ||
773 			    s_data[0] != WLAN_EID_SSID)
774 				continue;
775 			ssid = &s_data[2];
776 			ssid_len = s_data[1];
777 			s_data += 2 + s_data[1];
778 
779 			/* Multiple BSSID-Index element */
780 			if (pos - s_data < 3 ||
781 			    s_data[0] != WLAN_EID_MULTIPLE_BSSID_INDEX)
782 				continue;
783 			bssid_idx = s_data[2];
784 			s_data += 2 + s_data[1];
785 
786 			if (max_bss < 1 || max_bss > 8)
787 				break;
788 			os_memcpy(bssid, mgmt->bssid, ETH_ALEN);
789 			b = bssid[5] % (1 << max_bss);
790 			bssid[5] = bssid[5] - b +
791 				(b + bssid_idx) % (1 << max_bss);
792 			wpa_printf(MSG_MSGDUMP, "MBSSID: " MACSTR
793 				   " Capa 0x%x idx=%u MaxBSSID Indicator=%u",
794 				   MAC2STR(bssid), capa, bssid_idx, max_bss);
795 
796 			wpa_hexdump(MSG_MSGDUMP, "MBSSID: SSID",
797 				    ssid, ssid_len);
798 
799 			/* Rest of the elements */
800 			wpa_hexdump(MSG_MSGDUMP, "MBSSID: Elements",
801 				    s_data, pos - s_data);
802 			if (ieee802_11_parse_elems(s_data, pos - s_data,
803 						   &m_elems,
804 						   0) == ParseFailed) {
805 				wpa_printf(MSG_DEBUG,
806 					   "MBSSID: Failed to parse nontransmitted BSS elements");
807 				continue;
808 			}
809 
810 			/* TODO: Noninheritance and rest of elements */
811 			os_memcpy(&merged, &elems, sizeof(merged));
812 			merged.ssid = ssid;
813 			merged.ssid_len = ssid_len;
814 
815 			m_bss = bss_get(wt, bssid);
816 			if (!m_bss)
817 				continue;
818 			if (!m_bss->proberesp_seen)
819 				m_bss->capab_info = capa;
820 
821 			if (m_elems.basic_mle) {
822 				merged.basic_mle = m_elems.basic_mle;
823 				merged.basic_mle_len = m_elems.basic_mle_len;
824 			}
825 			if (m_elems.rsn_ie) {
826 				merged.rsn_ie = m_elems.rsn_ie;
827 				merged.rsn_ie_len = m_elems.rsn_ie_len;
828 			}
829 			if (m_elems.rsnxe) {
830 				merged.rsnxe = m_elems.rsnxe;
831 				merged.rsnxe_len = m_elems.rsnxe_len;
832 			}
833 			if (m_elems.rsnxe_override) {
834 				merged.rsnxe_override = m_elems.rsnxe_override;
835 				merged.rsnxe_override_len =
836 					m_elems.rsnxe_override_len;
837 			}
838 
839 			if (merged.rsnxe) {
840 				os_memcpy(m_bss->rsnxe, merged.rsnxe,
841 					  merged.rsnxe_len);
842 				m_bss->rsnxe_len = merged.rsnxe_len;
843 			} else {
844 				m_bss->rsnxe_len = 0;
845 			}
846 
847 			if (merged.rsnxe_override) {
848 				os_memcpy(m_bss->rsnxoe,
849 					  merged.rsnxe_override + 4,
850 					  merged.rsnxe_override_len - 4);
851 				m_bss->rsnxoe_len =
852 					merged.rsnxe_override_len - 4;
853 			} else {
854 				m_bss->rsnxoe_len = 0;
855 			}
856 
857 			if (!m_bss->proberesp_seen)
858 				bss_update(wt, m_bss, &merged, 1);
859 		}
860 	}
861 
862 	mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE);
863 	if (!mme) {
864 		if (bss->bigtk_idx) {
865 			add_note(wt, MSG_INFO,
866 				 "Unexpected unprotected Beacon frame from "
867 				 MACSTR, MAC2STR(mgmt->sa));
868 			bss->counters[WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE]++;
869 		}
870 		return;
871 	}
872 
873 	mic_len = bss->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;
874 	if (len < 24 + 10 + mic_len ||
875 	    data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
876 	    data[len - (10 + mic_len - 1)] != 8 + mic_len) {
877 		add_note(wt, MSG_INFO, "Invalid MME in a Beacon frame from "
878 			 MACSTR, MAC2STR(mgmt->sa));
879 		return;
880 	}
881 
882 	mme += 2;
883 	keyid = WPA_GET_LE16(mme);
884 	if (keyid < 6 || keyid > 7) {
885 		add_note(wt, MSG_INFO, "Unexpected MME KeyID %u from " MACSTR,
886 			 keyid, MAC2STR(mgmt->sa));
887 		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
888 		return;
889 	}
890 
891 	rx_bipn = WPA_GET_LE48(mme + 2);
892 	wpa_printf(MSG_DEBUG, "Beacon frame BSSID " MACSTR
893 		   " MME KeyID %u BIPN 0x%llx",
894 		   MAC2STR(mgmt->bssid), keyid,
895 		   (long long unsigned int) rx_bipn);
896 	wpa_hexdump(MSG_MSGDUMP, "MME MIC", mme + 8, mic_len);
897 
898 	if (!bss->igtk_len[keyid]) {
899 		add_note(wt, MSG_DEBUG,
900 			 "No BIGTK known to validate BIP frame from " MACSTR,
901 			 MAC2STR(mgmt->sa));
902 		return;
903 	}
904 
905 	if (rx_bipn <= bss->ipn[keyid]) {
906 		add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR
907 			 " RX BIPN 0x%llx <= 0x%llx",
908 			 MAC2STR(mgmt->sa), (long long unsigned int) rx_bipn,
909 			 (long long unsigned int) bss->ipn[keyid]);
910 	}
911 
912 	if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
913 			   bss->igtk_len[keyid], data, len) < 0) {
914 		add_note(wt, MSG_INFO, "Invalid MME MIC in a Beacon frame from "
915 			 MACSTR, MAC2STR(mgmt->sa));
916 		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
917 		return;
918 	}
919 
920 	add_note(wt, MSG_DEBUG, "Valid MME MIC in Beacon frame");
921 	bss->ipn[keyid] = rx_bipn;
922 }
923 
924 
rx_mgmt_probe_resp(struct wlantest * wt,const u8 * data,size_t len)925 static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
926 {
927 	const struct ieee80211_mgmt *mgmt;
928 	struct wlantest_bss *bss;
929 	struct ieee802_11_elems elems;
930 	size_t offset;
931 
932 	mgmt = (const struct ieee80211_mgmt *) data;
933 	offset = mgmt->u.probe_resp.variable - data;
934 	if (len < offset)
935 		return;
936 	bss = bss_get(wt, mgmt->bssid);
937 	if (bss == NULL)
938 		return;
939 
940 	bss->counters[WLANTEST_BSS_COUNTER_PROBE_RESPONSE]++;
941 	bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info);
942 	if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - offset,
943 				   &elems, 0) == ParseFailed) {
944 		if (bss->parse_error_reported)
945 			return;
946 		add_note(wt, MSG_INFO, "Invalid IEs in a Probe Response frame "
947 			 "from " MACSTR, MAC2STR(mgmt->sa));
948 		bss->parse_error_reported = 1;
949 		return;
950 	}
951 
952 	bss_update(wt, bss, &elems, 2);
953 }
954 
955 
process_fils_auth(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len)956 static void process_fils_auth(struct wlantest *wt, struct wlantest_bss *bss,
957 			      struct wlantest_sta *sta,
958 			      const struct ieee80211_mgmt *mgmt, size_t len)
959 {
960 	struct ieee802_11_elems elems;
961 	u16 trans;
962 	struct wpa_ie_data data;
963 
964 	if (sta->auth_alg != WLAN_AUTH_FILS_SK ||
965 	    len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth))
966 		return;
967 
968 	trans = le_to_host16(mgmt->u.auth.auth_transaction);
969 
970 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
971 				   len - IEEE80211_HDRLEN -
972 				   sizeof(mgmt->u.auth), &elems, 0) ==
973 	    ParseFailed)
974 		return;
975 
976 	if (trans == 1) {
977 		if (!elems.rsn_ie) {
978 			add_note(wt, MSG_INFO,
979 				 "FILS Authentication frame missing RSNE");
980 			return;
981 		}
982 		if (wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
983 					 elems.rsn_ie_len + 2, &data) < 0) {
984 			add_note(wt, MSG_INFO,
985 				 "Invalid RSNE in FILS Authentication frame");
986 			return;
987 		}
988 		sta->key_mgmt = data.key_mgmt;
989 		sta->pairwise_cipher = data.pairwise_cipher;
990 	}
991 
992 	if (!elems.fils_nonce) {
993 		add_note(wt, MSG_INFO,
994 			 "FILS Authentication frame missing nonce");
995 		return;
996 	}
997 
998 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
999 		os_memcpy(sta->anonce, elems.fils_nonce, FILS_NONCE_LEN);
1000 	else
1001 		os_memcpy(sta->snonce, elems.fils_nonce, FILS_NONCE_LEN);
1002 }
1003 
1004 
process_ft_auth(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len)1005 static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
1006 			    struct wlantest_sta *sta,
1007 			    const struct ieee80211_mgmt *mgmt, size_t len)
1008 {
1009 	u16 trans;
1010 	struct wpa_ft_ies parse;
1011 	struct wpa_ptk ptk;
1012 	u8 ptk_name[WPA_PMK_NAME_LEN];
1013 	struct wlantest_bss *old_bss;
1014 	struct wlantest_sta *old_sta = NULL;
1015 	const u8 *spa, *aa;
1016 	struct ieee802_11_elems elems;
1017 	const u8 *ie;
1018 	size_t ie_len, kdk_len;
1019 	const u8 *rsnxe;
1020 	size_t rsnxe_len;
1021 
1022 	if (sta->auth_alg != WLAN_AUTH_FT ||
1023 	    len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth))
1024 		return;
1025 
1026 	trans = le_to_host16(mgmt->u.auth.auth_transaction);
1027 
1028 	ie = mgmt->u.auth.variable;
1029 	ie_len = len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth);
1030 	if (wpa_ft_parse_ies(ie, ie_len, &parse, 0, false)) {
1031 		add_note(wt, MSG_INFO,
1032 			 "Could not parse FT Authentication Response frame");
1033 		return;
1034 	}
1035 
1036 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed)
1037 		wpa_printf(MSG_INFO,
1038 			   "FT: Failed to parse IEs in FT Authentication frame");
1039 
1040 	if (trans == 1) {
1041 		if (elems.basic_mle)
1042 			parse_basic_ml_elems(&elems, false, sta, 6);
1043 		sta->key_mgmt = parse.key_mgmt;
1044 		sta->pairwise_cipher = parse.pairwise_cipher;
1045 		if (parse.fte_snonce)
1046 			os_memcpy(sta->snonce, parse.fte_snonce, WPA_NONCE_LEN);
1047 		if (elems.rsnxe) {
1048 			os_memcpy(sta->rsnxe, elems.rsnxe, elems.rsnxe_len);
1049 			sta->rsnxe_len = elems.rsnxe_len;
1050 		} else {
1051 			sta->rsnxe_len = 0;
1052 		}
1053 		goto out;
1054 	}
1055 
1056 	if (trans != 2)
1057 		goto out;
1058 
1059 	spa = elems.basic_mle ? sta->mld_mac_addr : sta->addr;
1060 	aa = elems.basic_mle ? bss->mld_mac_addr : bss->bssid;
1061 
1062 	if (!parse.fte_snonce ||
1063 	    os_memcmp(sta->snonce, parse.fte_snonce, WPA_NONCE_LEN) != 0) {
1064 		add_note(wt, MSG_INFO, "FT: SNonce mismatch in FTE");
1065 		wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
1066 			    parse.fte_snonce, WPA_NONCE_LEN);
1067 		wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
1068 			    sta->snonce, WPA_NONCE_LEN);
1069 	}
1070 
1071 	if (parse.fte_anonce)
1072 		os_memcpy(sta->anonce, parse.fte_anonce, WPA_NONCE_LEN);
1073 
1074 	/* TODO: Should find the latest updated PMK-R0 value here instead
1075 	 * copying the one from the first found matching old STA entry. */
1076 	dl_list_for_each(old_bss, &wt->bss, struct wlantest_bss, list) {
1077 		if (old_bss == bss)
1078 			continue;
1079 		old_sta = sta_find(old_bss, sta->addr);
1080 		if (old_sta)
1081 			break;
1082 	}
1083 	if (!old_sta)
1084 		goto out;
1085 
1086 	os_memcpy(sta->pmk_r0, old_sta->pmk_r0, old_sta->pmk_r0_len);
1087 	sta->pmk_r0_len = old_sta->pmk_r0_len;
1088 	os_memcpy(sta->pmk_r0_name, old_sta->pmk_r0_name,
1089 		  sizeof(sta->pmk_r0_name));
1090 
1091 	if (parse.r1kh_id)
1092 		os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
1093 
1094 	if (wpa_derive_pmk_r1(sta->pmk_r0, sta->pmk_r0_len, sta->pmk_r0_name,
1095 			      bss->r1kh_id, spa, sta->pmk_r1,
1096 			      sta->pmk_r1_name) < 0)
1097 		goto out;
1098 	sta->pmk_r1_len = sta->pmk_r0_len;
1099 
1100 	if ((sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE ||
1101 	     sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE_2) &&
1102 	    bss->rsnxoe_len) {
1103 		rsnxe = bss->rsnxoe;
1104 		rsnxe_len = bss->rsnxoe_len;
1105 	} else {
1106 		rsnxe = bss->rsnxe;
1107 		rsnxe_len = bss->rsnxe_len;
1108 	}
1109 	if (ieee802_11_rsnx_capab_len(rsnxe, rsnxe_len,
1110 				      WLAN_RSNX_CAPAB_SECURE_LTF) &&
1111 	    ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
1112 				      WLAN_RSNX_CAPAB_SECURE_LTF))
1113 		kdk_len = WPA_KDK_MAX_LEN;
1114 	else
1115 		kdk_len = 0;
1116 
1117 	if (!parse.fte_anonce || !parse.fte_snonce ||
1118 	    wpa_pmk_r1_to_ptk(sta->pmk_r1, sta->pmk_r1_len, parse.fte_snonce,
1119 			      parse.fte_anonce, spa, aa,
1120 			      sta->pmk_r1_name, &ptk, ptk_name, sta->key_mgmt,
1121 			      sta->pairwise_cipher, kdk_len) < 0)
1122 		goto out;
1123 
1124 	sta_new_ptk(wt, sta, &ptk);
1125 out:
1126 	wpa_ft_parse_ies_free(&parse);
1127 }
1128 
1129 
process_sae_auth(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len)1130 static void process_sae_auth(struct wlantest *wt, struct wlantest_bss *bss,
1131 			     struct wlantest_sta *sta,
1132 			     const struct ieee80211_mgmt *mgmt, size_t len)
1133 {
1134 	u16 trans, status, group;
1135 
1136 	if (sta->auth_alg != WLAN_AUTH_SAE ||
1137 	    len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 2)
1138 		return;
1139 
1140 	trans = le_to_host16(mgmt->u.auth.auth_transaction);
1141 	if (trans != 1)
1142 		return;
1143 
1144 	status = le_to_host16(mgmt->u.auth.status_code);
1145 	if (status != WLAN_STATUS_SUCCESS &&
1146 	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
1147 	    status != WLAN_STATUS_SAE_PK)
1148 		return;
1149 
1150 	group = WPA_GET_LE16(mgmt->u.auth.variable);
1151 	wpa_printf(MSG_DEBUG, "SAE Commit using group %u", group);
1152 	sta->sae_group = group;
1153 }
1154 
1155 
rx_mgmt_auth(struct wlantest * wt,const u8 * data,size_t len)1156 static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
1157 {
1158 	const struct ieee80211_mgmt *mgmt;
1159 	struct wlantest_bss *bss;
1160 	struct wlantest_sta *sta;
1161 	u16 alg, trans, status;
1162 	bool from_ap;
1163 
1164 	mgmt = (const struct ieee80211_mgmt *) data;
1165 	bss = bss_get(wt, mgmt->bssid);
1166 	if (bss == NULL)
1167 		return;
1168 	from_ap = ether_addr_equal(mgmt->sa, mgmt->bssid);
1169 	if (from_ap)
1170 		sta = sta_get(bss, mgmt->da);
1171 	else
1172 		sta = sta_get(bss, mgmt->sa);
1173 	if (sta == NULL)
1174 		return;
1175 
1176 	if (len < 24 + 6) {
1177 		add_note(wt, MSG_INFO, "Too short Authentication frame from "
1178 			 MACSTR, MAC2STR(mgmt->sa));
1179 		return;
1180 	}
1181 
1182 	alg = le_to_host16(mgmt->u.auth.auth_alg);
1183 	sta->auth_alg = alg;
1184 	trans = le_to_host16(mgmt->u.auth.auth_transaction);
1185 	status = le_to_host16(mgmt->u.auth.status_code);
1186 
1187 	wpa_printf(MSG_DEBUG, "AUTH " MACSTR " -> " MACSTR
1188 		   " (alg=%u trans=%u status=%u)",
1189 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), alg, trans, status);
1190 
1191 	if (status == WLAN_STATUS_SUCCESS &&
1192 	    ((alg == WLAN_AUTH_OPEN && trans == 2) ||
1193 	     (alg == WLAN_AUTH_SAE && trans == 2 && from_ap))) {
1194 		if (sta->state == STATE1) {
1195 			add_note(wt, MSG_DEBUG, "STA " MACSTR
1196 				 " moved to State 2 with " MACSTR,
1197 				 MAC2STR(sta->addr), MAC2STR(bss->bssid));
1198 			sta->state = STATE2;
1199 		}
1200 	}
1201 
1202 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
1203 		sta->counters[WLANTEST_STA_COUNTER_AUTH_RX]++;
1204 	else
1205 		sta->counters[WLANTEST_STA_COUNTER_AUTH_TX]++;
1206 
1207 	process_fils_auth(wt, bss, sta, mgmt, len);
1208 	process_ft_auth(wt, bss, sta, mgmt, len);
1209 	process_sae_auth(wt, bss, sta, mgmt, len);
1210 }
1211 
1212 
deauth_all_stas(struct wlantest * wt,struct wlantest_bss * bss)1213 static void deauth_all_stas(struct wlantest *wt, struct wlantest_bss *bss)
1214 {
1215 	struct wlantest_sta *sta;
1216 	dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
1217 		if (sta->state == STATE1)
1218 			continue;
1219 		add_note(wt, MSG_DEBUG, "STA " MACSTR
1220 			 " moved to State 1 with " MACSTR,
1221 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
1222 		sta->state = STATE1;
1223 	}
1224 }
1225 
1226 
tdls_link_down(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta)1227 static void tdls_link_down(struct wlantest *wt, struct wlantest_bss *bss,
1228 			   struct wlantest_sta *sta)
1229 {
1230 	struct wlantest_tdls *tdls;
1231 	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
1232 		if ((tdls->init == sta || tdls->resp == sta) && tdls->link_up)
1233 		{
1234 			add_note(wt, MSG_DEBUG, "TDLS: Set link down based on "
1235 				 "STA deauth/disassoc");
1236 			tdls->link_up = 0;
1237 		}
1238 	}
1239 }
1240 
1241 
rx_mgmt_deauth(struct wlantest * wt,const u8 * data,size_t len,int valid)1242 static void rx_mgmt_deauth(struct wlantest *wt, const u8 *data, size_t len,
1243 			   int valid)
1244 {
1245 	const struct ieee80211_mgmt *mgmt;
1246 	struct wlantest_bss *bss;
1247 	struct wlantest_sta *sta;
1248 	u16 fc, reason;
1249 
1250 	mgmt = (const struct ieee80211_mgmt *) data;
1251 	bss = bss_get(wt, mgmt->bssid);
1252 	if (bss == NULL)
1253 		return;
1254 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
1255 		sta = sta_get(bss, mgmt->da);
1256 	else
1257 		sta = sta_get(bss, mgmt->sa);
1258 
1259 	if (len < 24 + 2) {
1260 		add_note(wt, MSG_INFO, "Too short Deauthentication frame from "
1261 			 MACSTR, MAC2STR(mgmt->sa));
1262 		return;
1263 	}
1264 
1265 	reason = le_to_host16(mgmt->u.deauth.reason_code);
1266 	wpa_printf(MSG_DEBUG, "DEAUTH " MACSTR " -> " MACSTR
1267 		   " (reason=%u) (valid=%d)",
1268 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
1269 		   reason, valid);
1270 	wpa_hexdump(MSG_MSGDUMP, "DEAUTH payload", data + 24, len - 24);
1271 
1272 	if (sta == NULL) {
1273 		if (valid && mgmt->da[0] == 0xff)
1274 			deauth_all_stas(wt, bss);
1275 		return;
1276 	}
1277 
1278 	if (ether_addr_equal(mgmt->sa, mgmt->bssid)) {
1279 		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_RX :
1280 			      WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX]++;
1281 		if (sta->pwrmgt && !sta->pspoll)
1282 			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP]++;
1283 		else
1284 			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE]++;
1285 
1286 		fc = le_to_host16(mgmt->frame_control);
1287 		if (!(fc & WLAN_FC_ISWEP) && reason == 6)
1288 			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC6]++;
1289 		else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
1290 			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC7]++;
1291 	} else
1292 		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_TX :
1293 			      WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX]++;
1294 
1295 	if (!valid) {
1296 		add_note(wt, MSG_INFO, "Do not change STA " MACSTR " State "
1297 			 "since Disassociation frame was not protected "
1298 			 "correctly", MAC2STR(sta->addr));
1299 		return;
1300 	}
1301 
1302 	if (sta->state != STATE1) {
1303 		add_note(wt, MSG_DEBUG, "STA " MACSTR
1304 			 " moved to State 1 with " MACSTR,
1305 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
1306 		sta->state = STATE1;
1307 	}
1308 	tdls_link_down(wt, bss, sta);
1309 }
1310 
1311 
get_fils_session(const u8 * ies,size_t ies_len)1312 static const u8 * get_fils_session(const u8 *ies, size_t ies_len)
1313 {
1314 	const u8 *ie, *end;
1315 
1316 	ie = ies;
1317 	end = ((const u8 *) ie) + ies_len;
1318 	while (ie + 1 < end) {
1319 		if (ie + 2 + ie[1] > end)
1320 			break;
1321 		if (ie[0] == WLAN_EID_EXTENSION &&
1322 		    ie[1] >= 1 + FILS_SESSION_LEN &&
1323 		    ie[2] == WLAN_EID_EXT_FILS_SESSION)
1324 			return ie;
1325 		ie += 2 + ie[1];
1326 	}
1327 	return NULL;
1328 }
1329 
1330 
try_rmsk(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,struct wlantest_pmk * pmk,const u8 * frame_start,const u8 * frame_ad,const u8 * frame_ad_end,const u8 * encr_end)1331 static int try_rmsk(struct wlantest *wt, struct wlantest_bss *bss,
1332 		    struct wlantest_sta *sta, struct wlantest_pmk *pmk,
1333 		    const u8 *frame_start, const u8 *frame_ad,
1334 		    const u8 *frame_ad_end, const u8 *encr_end)
1335 {
1336 	size_t pmk_len = 0;
1337 	u8 pmk_buf[PMK_LEN_MAX];
1338 	struct wpa_ptk ptk;
1339 	u8 ick[FILS_ICK_MAX_LEN];
1340 	size_t ick_len;
1341 	const u8 *aad[5];
1342 	size_t aad_len[5];
1343 	u8 buf[2000];
1344 
1345 	if (fils_rmsk_to_pmk(sta->key_mgmt, pmk->pmk, pmk->pmk_len,
1346 			     sta->snonce, sta->anonce, NULL, 0,
1347 			     pmk_buf, &pmk_len) < 0)
1348 		return -1;
1349 
1350 	if (fils_pmk_to_ptk(pmk_buf, pmk_len, sta->addr, bss->bssid,
1351 			    sta->snonce, sta->anonce, NULL, 0,
1352 			    &ptk, ick, &ick_len,
1353 			    sta->key_mgmt, sta->pairwise_cipher,
1354 			    NULL, NULL, 0) < 0)
1355 		return -1;
1356 
1357 	/* Check AES-SIV decryption with the derived key */
1358 
1359 	/* AES-SIV AAD vectors */
1360 
1361 	/* The STA's MAC address */
1362 	aad[0] = sta->addr;
1363 	aad_len[0] = ETH_ALEN;
1364 	/* The AP's BSSID */
1365 	aad[1] = bss->bssid;
1366 	aad_len[1] = ETH_ALEN;
1367 	/* The STA's nonce */
1368 	aad[2] = sta->snonce;
1369 	aad_len[2] = FILS_NONCE_LEN;
1370 	/* The AP's nonce */
1371 	aad[3] = sta->anonce;
1372 	aad_len[3] = FILS_NONCE_LEN;
1373 	/*
1374 	 * The (Re)Association Request frame from the Capability Information
1375 	 * field to the FILS Session element (both inclusive).
1376 	 */
1377 	aad[4] = frame_ad;
1378 	aad_len[4] = frame_ad_end - frame_ad;
1379 
1380 	if (encr_end - frame_ad_end < AES_BLOCK_SIZE ||
1381 	    encr_end - frame_ad_end > sizeof(buf))
1382 		return -1;
1383 	if (aes_siv_decrypt(ptk.kek, ptk.kek_len,
1384 			    frame_ad_end, encr_end - frame_ad_end,
1385 			    5, aad, aad_len, buf) < 0) {
1386 		wpa_printf(MSG_DEBUG,
1387 			   "FILS: Derived PTK did not match AES-SIV data");
1388 		return -1;
1389 	}
1390 
1391 	add_note(wt, MSG_DEBUG, "Derived FILS PTK");
1392 	os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
1393 	sta->ptk_set = 1;
1394 	sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
1395 	wpa_hexdump(MSG_DEBUG, "FILS: Decrypted Association Request elements",
1396 		    buf, encr_end - frame_ad_end - AES_BLOCK_SIZE);
1397 
1398 	if (wt->write_pcap_dumper || wt->pcapng) {
1399 		write_pcap_decrypted(wt, frame_start,
1400 				     frame_ad_end - frame_start,
1401 				     buf,
1402 				     encr_end - frame_ad_end - AES_BLOCK_SIZE);
1403 	}
1404 
1405 	return 0;
1406 }
1407 
1408 
derive_fils_keys(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * frame_start,const u8 * frame_ad,const u8 * frame_ad_end,const u8 * encr_end)1409 static void derive_fils_keys(struct wlantest *wt, struct wlantest_bss *bss,
1410 			     struct wlantest_sta *sta, const u8 *frame_start,
1411 			     const u8 *frame_ad, const u8 *frame_ad_end,
1412 			     const u8 *encr_end)
1413 {
1414 	struct wlantest_pmk *pmk;
1415 
1416 	wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR
1417 		   " from FILS rMSK", MAC2STR(sta->addr));
1418 
1419 	dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk,
1420 			 list) {
1421 		wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
1422 		if (try_rmsk(wt, bss, sta, pmk, frame_start, frame_ad,
1423 			     frame_ad_end, encr_end) == 0)
1424 			return;
1425 	}
1426 
1427 	dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
1428 		wpa_printf(MSG_DEBUG, "Try global PMK");
1429 		if (try_rmsk(wt, bss, sta, pmk, frame_start, frame_ad,
1430 			     frame_ad_end, encr_end) == 0)
1431 			return;
1432 	}
1433 }
1434 
1435 
dump_mld_info(struct wlantest * wt,struct wlantest_sta * sta)1436 static void dump_mld_info(struct wlantest *wt, struct wlantest_sta *sta)
1437 {
1438 	int link_id;
1439 	struct wlantest_bss *bss;
1440 	u8 zero[ETH_ALEN];
1441 	const u8 *bssid;
1442 
1443 	wpa_printf(MSG_INFO, "MLO association - AP MLD: " MACSTR
1444 		   "  STA MLD: " MACSTR,
1445 		   MAC2STR(sta->bss->mld_mac_addr), MAC2STR(sta->mld_mac_addr));
1446 
1447 	os_memset(zero, 0, ETH_ALEN);
1448 
1449 	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
1450 		bss = bss_find_mld(wt, sta->bss->mld_mac_addr, link_id);
1451 		if (!bss &&
1452 		    is_zero_ether_addr(sta->link_addr[link_id]))
1453 			continue;
1454 		if (bss)
1455 			bssid = bss->bssid;
1456 		else
1457 			bssid = zero;
1458 		wpa_printf(MSG_INFO, "  Link %u - AP: " MACSTR "  STA: " MACSTR,
1459 			   link_id, MAC2STR(bssid),
1460 			   MAC2STR(sta->link_addr[link_id]));
1461 	}
1462 }
1463 
1464 
rx_mgmt_assoc_req(struct wlantest * wt,const u8 * data,size_t len)1465 static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
1466 {
1467 	const struct ieee80211_mgmt *mgmt;
1468 	struct wlantest_bss *bss;
1469 	struct wlantest_sta *sta;
1470 	struct ieee802_11_elems elems;
1471 	const u8 *ie;
1472 	size_t ie_len;
1473 
1474 	mgmt = (const struct ieee80211_mgmt *) data;
1475 	bss = bss_get(wt, mgmt->bssid);
1476 	if (bss == NULL)
1477 		return;
1478 	sta = sta_get(bss, mgmt->sa);
1479 	if (sta == NULL)
1480 		return;
1481 
1482 	if (len < 24 + 4) {
1483 		add_note(wt, MSG_INFO, "Too short Association Request frame "
1484 			 "from " MACSTR, MAC2STR(mgmt->sa));
1485 		return;
1486 	}
1487 
1488 	wpa_printf(MSG_DEBUG, "ASSOCREQ " MACSTR " -> " MACSTR
1489 		   " (capab=0x%x listen_int=%u)",
1490 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
1491 		   le_to_host16(mgmt->u.assoc_req.capab_info),
1492 		   le_to_host16(mgmt->u.assoc_req.listen_interval));
1493 
1494 	sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX]++;
1495 
1496 	ie = mgmt->u.assoc_req.variable;
1497 	ie_len = len - (mgmt->u.assoc_req.variable - data);
1498 
1499 	if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
1500 		const u8 *session, *frame_ad, *frame_ad_end, *encr_end;
1501 
1502 		session = get_fils_session(ie, ie_len);
1503 		if (session) {
1504 			frame_ad = (const u8 *) &mgmt->u.assoc_req.capab_info;
1505 			frame_ad_end = session + 2 + session[1];
1506 			encr_end = data + len;
1507 			derive_fils_keys(wt, bss, sta, data, frame_ad,
1508 					 frame_ad_end, encr_end);
1509 			ie_len = session - ie;
1510 		}
1511 	}
1512 
1513 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
1514 		add_note(wt, MSG_INFO, "Invalid IEs in Association Request "
1515 			 "frame from " MACSTR, MAC2STR(mgmt->sa));
1516 		return;
1517 	}
1518 
1519 	if (elems.rsn_selection) {
1520 		sta->rsn_selection = elems.rsn_selection[0];
1521 		wpa_printf(MSG_DEBUG, "RSNO: RSN Selection %u",
1522 			   sta->rsn_selection);
1523 	} else {
1524 		sta->rsn_selection = RSN_SELECTION_RSNE;
1525 	}
1526 
1527 	if (elems.rsnxe) {
1528 		os_memcpy(sta->rsnxe, elems.rsnxe, elems.rsnxe_len);
1529 		sta->rsnxe_len = elems.rsnxe_len;
1530 	}
1531 
1532 	if (elems.owe_dh && elems.owe_dh_len >= 2) {
1533 		sta->owe_group = WPA_GET_LE16(elems.owe_dh);
1534 		wpa_printf(MSG_DEBUG, "OWE using group %u", sta->owe_group);
1535 	}
1536 
1537 	sta->assocreq_capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
1538 	sta->assocreq_listen_int =
1539 		le_to_host16(mgmt->u.assoc_req.listen_interval);
1540 	os_free(sta->assocreq_ies);
1541 	sta->assocreq_ies_len = len - (mgmt->u.assoc_req.variable - data);
1542 	sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
1543 	if (sta->assocreq_ies)
1544 		os_memcpy(sta->assocreq_ies, mgmt->u.assoc_req.variable,
1545 			  sta->assocreq_ies_len);
1546 
1547 	sta->assocreq_seen = 1;
1548 	sta_update_assoc(sta, &elems);
1549 	if (elems.basic_mle) {
1550 		if (bss->link_id_set) {
1551 			os_memcpy(sta->link_addr[bss->link_id], mgmt->sa,
1552 				  ETH_ALEN);
1553 			wpa_printf(MSG_DEBUG,
1554 				   "Learned Link ID %u MAC address "
1555 				   MACSTR
1556 				   " from Association Request (assoc link)",
1557 				   bss->link_id, MAC2STR(mgmt->sa));
1558 		}
1559 		parse_basic_ml_elems(&elems, false, sta, 2);
1560 		dump_mld_info(wt, sta);
1561 	}
1562 }
1563 
1564 
decrypt_fils_assoc_resp(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * frame_start,const u8 * frame_ad,const u8 * frame_ad_end,const u8 * encr_end)1565 static void decrypt_fils_assoc_resp(struct wlantest *wt,
1566 				    struct wlantest_bss *bss,
1567 				    struct wlantest_sta *sta,
1568 				    const u8 *frame_start, const u8 *frame_ad,
1569 				    const u8 *frame_ad_end, const u8 *encr_end)
1570 {
1571 	const u8 *aad[5];
1572 	size_t aad_len[5];
1573 	u8 buf[2000];
1574 
1575 	if (!sta->ptk_set)
1576 		return;
1577 
1578 	/* Check AES-SIV decryption with the derived key */
1579 
1580 	/* AES-SIV AAD vectors */
1581 
1582 	/* The AP's BSSID */
1583 	aad[0] = bss->bssid;
1584 	aad_len[0] = ETH_ALEN;
1585 	/* The STA's MAC address */
1586 	aad[1] = sta->addr;
1587 	aad_len[1] = ETH_ALEN;
1588 	/* The AP's nonce */
1589 	aad[2] = sta->anonce;
1590 	aad_len[2] = FILS_NONCE_LEN;
1591 	/* The STA's nonce */
1592 	aad[3] = sta->snonce;
1593 	aad_len[3] = FILS_NONCE_LEN;
1594 	/*
1595 	 * The (Re)Association Response frame from the Capability Information
1596 	 * field to the FILS Session element (both inclusive).
1597 	 */
1598 	aad[4] = frame_ad;
1599 	aad_len[4] = frame_ad_end - frame_ad;
1600 
1601 	if (encr_end - frame_ad_end < AES_BLOCK_SIZE ||
1602 	    encr_end - frame_ad_end > sizeof(buf))
1603 		return;
1604 	if (aes_siv_decrypt(sta->ptk.kek, sta->ptk.kek_len,
1605 			    frame_ad_end, encr_end - frame_ad_end,
1606 			    5, aad, aad_len, buf) < 0) {
1607 		wpa_printf(MSG_DEBUG,
1608 			   "FILS: Derived PTK did not match AES-SIV data");
1609 		return;
1610 	}
1611 
1612 	wpa_hexdump(MSG_DEBUG, "FILS: Decrypted Association Response elements",
1613 		    buf, encr_end - frame_ad_end - AES_BLOCK_SIZE);
1614 
1615 	if (wt->write_pcap_dumper || wt->pcapng) {
1616 		write_pcap_decrypted(wt, frame_start,
1617 				     frame_ad_end - frame_start,
1618 				     buf,
1619 				     encr_end - frame_ad_end - AES_BLOCK_SIZE);
1620 	}
1621 }
1622 
1623 
rx_mgmt_assoc_resp(struct wlantest * wt,const u8 * data,size_t len)1624 static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
1625 {
1626 	const struct ieee80211_mgmt *mgmt;
1627 	struct wlantest_bss *bss;
1628 	struct wlantest_sta *sta;
1629 	u16 capab, status, aid;
1630 	struct ieee802_11_elems elems;
1631 	const u8 *ies;
1632 	size_t ies_len;
1633 	struct wpa_ft_ies parse;
1634 	const u8 *ml;
1635 
1636 	mgmt = (const struct ieee80211_mgmt *) data;
1637 	bss = bss_get(wt, mgmt->bssid);
1638 	if (bss == NULL)
1639 		return;
1640 	sta = sta_get(bss, mgmt->da);
1641 	if (sta == NULL)
1642 		return;
1643 
1644 	if (len < 24 + 6) {
1645 		add_note(wt, MSG_INFO, "Too short Association Response frame "
1646 			 "from " MACSTR, MAC2STR(mgmt->sa));
1647 		return;
1648 	}
1649 
1650 	ies = mgmt->u.assoc_resp.variable;
1651 	ies_len = len - (mgmt->u.assoc_resp.variable - data);
1652 
1653 	capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
1654 	status = le_to_host16(mgmt->u.assoc_resp.status_code);
1655 	aid = le_to_host16(mgmt->u.assoc_resp.aid);
1656 
1657 	wpa_printf(MSG_DEBUG, "ASSOCRESP " MACSTR " -> " MACSTR
1658 		   " (capab=0x%x status=%u aid=%u)",
1659 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
1660 		   aid & 0x3fff);
1661 
1662 	ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC);
1663 	if (ml &&
1664 	    ieee802_11_parse_elems(ies, ies_len, &elems, 0) != ParseFailed)
1665 		parse_basic_ml_elems(&elems, true, NULL, 4);
1666 
1667 	if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
1668 		const u8 *session, *frame_ad, *frame_ad_end, *encr_end;
1669 
1670 		session = get_fils_session(ies, ies_len);
1671 		if (session) {
1672 			frame_ad = (const u8 *) &mgmt->u.assoc_resp.capab_info;
1673 			frame_ad_end = session + 2 + session[1];
1674 			encr_end = data + len;
1675 			decrypt_fils_assoc_resp(wt, bss, sta, data, frame_ad,
1676 						frame_ad_end, encr_end);
1677 			ies_len = session - ies;
1678 		}
1679 	}
1680 
1681 	if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
1682 		add_note(wt, MSG_INFO,
1683 			 "Failed to parse IEs in AssocResp from " MACSTR,
1684 			 MAC2STR(mgmt->sa));
1685 	}
1686 
1687 	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
1688 		if (!elems.timeout_int ||
1689 		    elems.timeout_int[0] != WLAN_TIMEOUT_ASSOC_COMEBACK) {
1690 			add_note(wt, MSG_INFO, "No valid Timeout Interval IE "
1691 				 "with Assoc Comeback time in AssocResp "
1692 				 "(status=30) from " MACSTR,
1693 				 MAC2STR(mgmt->sa));
1694 		} else {
1695 			sta->counters[
1696 				WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK]++;
1697 		}
1698 	}
1699 
1700 	if (status)
1701 		return;
1702 
1703 	if ((aid & 0xc000) != 0xc000) {
1704 		add_note(wt, MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
1705 			 "in Association Response from " MACSTR,
1706 			 MAC2STR(mgmt->sa));
1707 	}
1708 	sta->aid = aid & 0xc000;
1709 
1710 	if (sta->state < STATE2) {
1711 		add_note(wt, MSG_DEBUG,
1712 			 "STA " MACSTR " was not in State 2 when "
1713 			 "getting associated", MAC2STR(sta->addr));
1714 	}
1715 
1716 	if (sta->state < STATE3) {
1717 		add_note(wt, MSG_DEBUG, "STA " MACSTR
1718 			 " moved to State 3 with " MACSTR,
1719 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
1720 		sta->state = STATE3;
1721 	}
1722 
1723 	if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false) == 0) {
1724 		if (parse.r0kh_id) {
1725 			os_memcpy(bss->r0kh_id, parse.r0kh_id,
1726 				  parse.r0kh_id_len);
1727 			bss->r0kh_id_len = parse.r0kh_id_len;
1728 		}
1729 		if (parse.r1kh_id)
1730 			os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
1731 		wpa_ft_parse_ies_free(&parse);
1732 	}
1733 
1734 	if (elems.owe_dh && elems.owe_dh_len >= 2) {
1735 		sta->owe_group = WPA_GET_LE16(elems.owe_dh);
1736 		wpa_printf(MSG_DEBUG, "OWE using group %u", sta->owe_group);
1737 	}
1738 }
1739 
1740 
rx_mgmt_reassoc_req(struct wlantest * wt,const u8 * data,size_t len)1741 static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
1742 				size_t len)
1743 {
1744 	const struct ieee80211_mgmt *mgmt;
1745 	struct wlantest_bss *bss;
1746 	struct wlantest_sta *sta;
1747 	struct ieee802_11_elems elems;
1748 	const u8 *ie;
1749 	size_t ie_len;
1750 
1751 	mgmt = (const struct ieee80211_mgmt *) data;
1752 	bss = bss_get(wt, mgmt->bssid);
1753 	if (bss == NULL)
1754 		return;
1755 
1756 	if (len < 24 + 4 + ETH_ALEN) {
1757 		add_note(wt, MSG_INFO, "Too short Reassociation Request frame "
1758 			 "from " MACSTR, MAC2STR(mgmt->sa));
1759 		return;
1760 	}
1761 
1762 	wpa_printf(MSG_DEBUG, "REASSOCREQ " MACSTR " -> " MACSTR
1763 		   " (capab=0x%x listen_int=%u current_ap=" MACSTR ")",
1764 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
1765 		   le_to_host16(mgmt->u.reassoc_req.capab_info),
1766 		   le_to_host16(mgmt->u.reassoc_req.listen_interval),
1767 		   MAC2STR(mgmt->u.reassoc_req.current_ap));
1768 
1769 	ie = mgmt->u.reassoc_req.variable;
1770 	ie_len = len - (mgmt->u.reassoc_req.variable - data);
1771 
1772 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
1773 		add_note(wt, MSG_INFO,
1774 			 "Invalid IEs in Reassociation Request frame from "
1775 			 MACSTR, MAC2STR(mgmt->sa));
1776 		return;
1777 	}
1778 
1779 	sta = sta_find_mlo(wt, bss, mgmt->sa);
1780 	/*
1781 	 * In the case of FT over-the-DS roaming, STA entry was created with the
1782 	 * MLD MAC address and attached to one of the BSSs affiliated with the
1783 	 * AP MLD but that BSS might not be in the STA's requested reassociation
1784 	 * links, so move it to reassociation link BSS and update STA link
1785 	 * address.
1786 	 */
1787 	if (!sta && elems.basic_mle) {
1788 		const u8 *mld_addr;
1789 		struct wlantest_sta *sta1;
1790 
1791 		mld_addr = get_basic_mle_mld_addr(elems.basic_mle,
1792 						  elems.basic_mle_len);
1793 		if (!mld_addr)
1794 			return;
1795 
1796 		sta1 = sta_find_mlo(wt, bss, mld_addr);
1797 		if (sta1 && sta1->ft_over_ds) {
1798 			dl_list_del(&sta1->list);
1799 			dl_list_add(&bss->sta, &sta1->list);
1800 			wpa_printf(MSG_DEBUG,
1801 				   "Move existing STA entry from another affiliated BSS to the reassociation BSS (addr "
1802 				   MACSTR " -> " MACSTR ")",
1803 				   MAC2STR(sta1->addr), MAC2STR(mgmt->sa));
1804 			os_memcpy(sta1->addr, mgmt->sa, ETH_ALEN);
1805 			sta = sta1;
1806 		}
1807 	}
1808 	if (!sta)
1809 		sta = sta_get(bss, mgmt->sa);
1810 	if (!sta)
1811 		return;
1812 
1813 	sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX]++;
1814 
1815 	if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
1816 		const u8 *session, *frame_ad, *frame_ad_end, *encr_end;
1817 
1818 		session = get_fils_session(ie, ie_len);
1819 		if (session) {
1820 			frame_ad = (const u8 *) &mgmt->u.reassoc_req.capab_info;
1821 			frame_ad_end = session + 2 + session[1];
1822 			encr_end = data + len;
1823 			derive_fils_keys(wt, bss, sta, data, frame_ad,
1824 					 frame_ad_end, encr_end);
1825 			ie_len = session - ie;
1826 		}
1827 	}
1828 
1829 	if (elems.rsnxe) {
1830 		os_memcpy(sta->rsnxe, elems.rsnxe, elems.rsnxe_len);
1831 		sta->rsnxe_len = elems.rsnxe_len;
1832 	}
1833 
1834 	if (elems.owe_dh && elems.owe_dh_len >= 2) {
1835 		sta->owe_group = WPA_GET_LE16(elems.owe_dh);
1836 		wpa_printf(MSG_DEBUG, "OWE using group %u", sta->owe_group);
1837 	}
1838 
1839 	sta->assocreq_capab_info =
1840 		le_to_host16(mgmt->u.reassoc_req.capab_info);
1841 	sta->assocreq_listen_int =
1842 		le_to_host16(mgmt->u.reassoc_req.listen_interval);
1843 	os_free(sta->assocreq_ies);
1844 	sta->assocreq_ies_len = len - (mgmt->u.reassoc_req.variable - data);
1845 	sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
1846 	if (sta->assocreq_ies)
1847 		os_memcpy(sta->assocreq_ies, mgmt->u.reassoc_req.variable,
1848 			  sta->assocreq_ies_len);
1849 
1850 	sta->assocreq_seen = 1;
1851 	sta_update_assoc(sta, &elems);
1852 	if (elems.basic_mle) {
1853 		os_memset(sta->link_addr, 0, sizeof(sta->link_addr));
1854 		if (bss->link_id_set) {
1855 			os_memcpy(sta->link_addr[bss->link_id], mgmt->sa,
1856 				  ETH_ALEN);
1857 			wpa_printf(MSG_DEBUG,
1858 				   "Learned Link ID %u MAC address "
1859 				   MACSTR
1860 				   " from Reassociation Request (assoc link)",
1861 				   bss->link_id, MAC2STR(mgmt->sa));
1862 		}
1863 		parse_basic_ml_elems(&elems, false, sta, 2);
1864 		dump_mld_info(wt, sta);
1865 	}
1866 
1867 	if (elems.ftie) {
1868 		struct wpa_ft_ies parse;
1869 		int use_sha384;
1870 		struct rsn_mdie *mde;
1871 		const u8 *anonce, *snonce, *fte_mic;
1872 		u8 fte_elem_count;
1873 		unsigned int count;
1874 		u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
1875 		size_t mic_len = 16;
1876 		const u8 *kck;
1877 		size_t kck_len;
1878 		const u8 *aa, *spa;
1879 		struct wpabuf *extra = NULL;
1880 
1881 		if (elems.basic_mle) {
1882 			aa = bss->mld_mac_addr;
1883 			spa = sta->mld_mac_addr;
1884 		} else {
1885 			aa = bss->bssid;
1886 			spa = sta->addr;
1887 		}
1888 
1889 		use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
1890 
1891 		if (wpa_ft_parse_ies(ie, ie_len, &parse, sta->key_mgmt,
1892 				     false) < 0) {
1893 			add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
1894 			return;
1895 		}
1896 
1897 		if (!parse.rsn) {
1898 			add_note(wt, MSG_INFO, "FT: No RSNE in Reassoc Req");
1899 			goto out;
1900 		}
1901 
1902 		if (!parse.rsn_pmkid) {
1903 			add_note(wt, MSG_INFO, "FT: No PMKID in RSNE");
1904 			goto out;
1905 		}
1906 
1907 		if (os_memcmp_const(parse.rsn_pmkid, sta->pmk_r1_name,
1908 				    WPA_PMK_NAME_LEN) != 0) {
1909 			add_note(wt, MSG_INFO,
1910 				 "FT: PMKID in Reassoc Req did not match PMKR1Name");
1911 			wpa_hexdump(MSG_DEBUG,
1912 				    "FT: Received RSNE[PMKR1Name]",
1913 				    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
1914 			wpa_hexdump(MSG_DEBUG,
1915 				    "FT: Previously derived PMKR1Name",
1916 				    sta->pmk_r1_name, WPA_PMK_NAME_LEN);
1917 			goto out;
1918 		}
1919 
1920 		mde = (struct rsn_mdie *) parse.mdie;
1921 		if (!mde || parse.mdie_len < sizeof(*mde) ||
1922 		    os_memcmp(mde->mobility_domain, bss->mdid,
1923 			      MOBILITY_DOMAIN_ID_LEN) != 0) {
1924 			add_note(wt, MSG_INFO, "FT: Invalid MDE");
1925 		}
1926 
1927 		if (use_sha384) {
1928 			struct rsn_ftie_sha384 *fte;
1929 
1930 			fte = (struct rsn_ftie_sha384 *) parse.ftie;
1931 			if (!fte || parse.ftie_len < sizeof(*fte)) {
1932 				add_note(wt, MSG_INFO, "FT: Invalid FTE");
1933 				goto out;
1934 			}
1935 
1936 			anonce = fte->anonce;
1937 			snonce = fte->snonce;
1938 			fte_elem_count = fte->mic_control[1];
1939 			fte_mic = fte->mic;
1940 		} else {
1941 			struct rsn_ftie *fte;
1942 
1943 			fte = (struct rsn_ftie *) parse.ftie;
1944 			if (!fte || parse.ftie_len < sizeof(*fte)) {
1945 				add_note(wt, MSG_INFO, "FT: Invalid FTIE");
1946 				goto out;
1947 			}
1948 
1949 			anonce = fte->anonce;
1950 			snonce = fte->snonce;
1951 			fte_elem_count = fte->mic_control[1];
1952 			fte_mic = fte->mic;
1953 		}
1954 
1955 		if (os_memcmp(snonce, sta->snonce, WPA_NONCE_LEN) != 0) {
1956 			add_note(wt, MSG_INFO, "FT: SNonce mismatch in FTIE");
1957 			wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
1958 				    snonce, WPA_NONCE_LEN);
1959 			wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
1960 				    sta->snonce, WPA_NONCE_LEN);
1961 			goto out;
1962 		}
1963 
1964 		if (os_memcmp(anonce, sta->anonce, WPA_NONCE_LEN) != 0) {
1965 			add_note(wt, MSG_INFO, "FT: ANonce mismatch in FTIE");
1966 			wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
1967 				    anonce, WPA_NONCE_LEN);
1968 			wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
1969 				    sta->anonce, WPA_NONCE_LEN);
1970 			goto out;
1971 		}
1972 
1973 		if (!parse.r0kh_id) {
1974 			add_note(wt, MSG_INFO, "FT: No R0KH-ID subelem in FTE");
1975 			goto out;
1976 		}
1977 		os_memcpy(bss->r0kh_id, parse.r0kh_id, parse.r0kh_id_len);
1978 		bss->r0kh_id_len = parse.r0kh_id_len;
1979 
1980 		if (!parse.r1kh_id) {
1981 			add_note(wt, MSG_INFO, "FT: No R1KH-ID subelem in FTE");
1982 			goto out;
1983 		}
1984 
1985 		os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
1986 
1987 		if (!parse.rsn_pmkid ||
1988 		    os_memcmp_const(parse.rsn_pmkid, sta->pmk_r1_name,
1989 				    WPA_PMK_NAME_LEN)) {
1990 			add_note(wt, MSG_INFO,
1991 				 "FT: No matching PMKR1Name (PMKID) in RSNE (pmkid=%d)",
1992 				 !!parse.rsn_pmkid);
1993 			goto out;
1994 		}
1995 
1996 		count = 3;
1997 		if (parse.ric)
1998 			count += ieee802_11_ie_count(parse.ric, parse.ric_len);
1999 		if (parse.rsnxe)
2000 			count++;
2001 		if (fte_elem_count != count) {
2002 			add_note(wt, MSG_INFO,
2003 				 "FT: Unexpected IE count in MIC Control: received %u expected %u",
2004 				 fte_elem_count, count);
2005 			goto out;
2006 		}
2007 
2008 		if (wpa_key_mgmt_fils(sta->key_mgmt)) {
2009 			kck = sta->ptk.kck2;
2010 			kck_len = sta->ptk.kck2_len;
2011 		} else {
2012 			kck = sta->ptk.kck;
2013 			kck_len = sta->ptk.kck_len;
2014 		}
2015 
2016 		if (elems.basic_mle) {
2017 			int i;
2018 
2019 			extra = wpabuf_alloc(MAX_NUM_MLD_LINKS * ETH_ALEN);
2020 			if (!extra)
2021 				goto out;
2022 			for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
2023 				if (!is_zero_ether_addr(sta->link_addr[i]))
2024 					wpabuf_put_data(extra,
2025 							sta->link_addr[i],
2026 							ETH_ALEN);
2027 			}
2028 		}
2029 
2030 		if (wpa_ft_mic(sta->key_mgmt, kck, kck_len,
2031 			       spa, aa, 5,
2032 			       parse.mdie - 2, parse.mdie_len + 2,
2033 			       parse.ftie - 2, parse.ftie_len + 2,
2034 			       parse.rsn - 2, parse.rsn_len + 2,
2035 			       parse.ric, parse.ric_len,
2036 			       parse.rsnxe ? parse.rsnxe - 2 : NULL,
2037 			       parse.rsnxe ? parse.rsnxe_len + 2 : 0,
2038 			       extra,
2039 			       mic) < 0) {
2040 			wpabuf_free(extra);
2041 			add_note(wt, MSG_INFO, "FT: Failed to calculate MIC");
2042 			goto out;
2043 		}
2044 		wpabuf_free(extra);
2045 
2046 		if (os_memcmp_const(mic, fte_mic, mic_len) != 0) {
2047 			int link_id;
2048 
2049 			add_note(wt, MSG_INFO, "FT: Invalid MIC in FTE");
2050 			wpa_printf(MSG_DEBUG,
2051 				   "FT: addr=" MACSTR " auth_addr=" MACSTR,
2052 				   MAC2STR(spa), MAC2STR(aa));
2053 			wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
2054 				    fte_mic, mic_len);
2055 			wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC",
2056 				    mic, mic_len);
2057 			wpa_hexdump(MSG_MSGDUMP, "FT: MDE",
2058 				    parse.mdie - 2, parse.mdie_len + 2);
2059 			wpa_hexdump(MSG_MSGDUMP, "FT: FTE",
2060 				    parse.ftie - 2, parse.ftie_len + 2);
2061 			wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
2062 				    parse.rsn - 2, parse.rsn_len + 2);
2063 			wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE",
2064 				    parse.rsnxe ? parse.rsnxe - 2 : NULL,
2065 				    parse.rsnxe ? parse.rsnxe_len + 2 : 0);
2066 			for (link_id = 0; link_id < MAX_NUM_MLD_LINKS;
2067 			     link_id++) {
2068 				if (is_zero_ether_addr(sta->link_addr[link_id]))
2069 					continue;
2070 				wpa_printf(MSG_DEBUG,
2071 					   "FT: STA link %d address: " MACSTR,
2072 					   link_id,
2073 					   MAC2STR(sta->link_addr[link_id]));
2074 			}
2075 			goto out;
2076 		}
2077 
2078 		add_note(wt, MSG_INFO, "FT: Valid FTE MIC");
2079 	out:
2080 		wpa_ft_parse_ies_free(&parse);
2081 	}
2082 }
2083 
2084 
process_gtk_subelem(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * kek,size_t kek_len,const u8 * gtk_elem,size_t gtk_elem_len,bool mlo)2085 static void process_gtk_subelem(struct wlantest *wt, struct wlantest_bss *bss,
2086 				struct wlantest_sta *sta,
2087 				const u8 *kek, size_t kek_len,
2088 				const u8 *gtk_elem,
2089 				size_t gtk_elem_len, bool mlo)
2090 {
2091 	u8 gtk[32];
2092 	int keyidx;
2093 	enum wpa_alg alg;
2094 	size_t gtk_len, keylen;
2095 	const u8 *rsc;
2096 	size_t hlen;
2097 
2098 	if (!gtk_elem) {
2099 		add_note(wt, MSG_INFO, "FT: No GTK included in FTE");
2100 		return;
2101 	}
2102 
2103 	wpa_hexdump(MSG_DEBUG, "FT: Received GTK in Reassoc Resp",
2104 		    gtk_elem, gtk_elem_len);
2105 
2106 	hlen = 2 + 1 + 8;
2107 	if (mlo)
2108 		hlen++;
2109 	if (gtk_elem_len < hlen + 24 || (gtk_elem_len - hlen) % 8 ||
2110 	    gtk_elem_len - (hlen + 8) > sizeof(gtk)) {
2111 		add_note(wt, MSG_INFO, "FT: Invalid GTK sub-elem length %zu",
2112 			 gtk_elem_len);
2113 		return;
2114 	}
2115 	gtk_len = gtk_elem_len - (hlen + 8);
2116 	if (aes_unwrap(kek, kek_len, gtk_len / 8, gtk_elem + hlen, gtk)) {
2117 		add_note(wt, MSG_INFO,
2118 			 "FT: AES unwrap failed - could not decrypt GTK");
2119 		return;
2120 	}
2121 
2122 	keylen = wpa_cipher_key_len(bss->group_cipher);
2123 	alg = wpa_cipher_to_alg(bss->group_cipher);
2124 	if (alg == WPA_ALG_NONE) {
2125 		add_note(wt, MSG_INFO, "FT: Unsupported Group Cipher %d",
2126 			 bss->group_cipher);
2127 		return;
2128 	}
2129 
2130 	if (gtk_len < keylen) {
2131 		add_note(wt, MSG_INFO, "FT: Too short GTK in FTE");
2132 		return;
2133 	}
2134 
2135 	/* Key Info[2] | [Link ID Info[1] | Key Length[1] | RSC[8] |
2136 	 * Key[5..32]. */
2137 
2138 	keyidx = WPA_GET_LE16(gtk_elem) & 0x03;
2139 
2140 	if (gtk_elem[hlen - 8 - 1] != keylen) {
2141 		add_note(wt, MSG_INFO,
2142 			 "FT: GTK length mismatch: received %u negotiated %zu",
2143 			 gtk_elem[hlen - 8 - 1], keylen);
2144 		return;
2145 	}
2146 
2147 	add_note(wt, MSG_DEBUG, "GTK KeyID=%u", keyidx);
2148 	wpa_hexdump(MSG_DEBUG, "FT: GTK from Reassoc Resp", gtk, keylen);
2149 	if (bss->group_cipher == WPA_CIPHER_TKIP) {
2150 		/* Swap Tx/Rx keys for Michael MIC */
2151 		u8 tmp[8];
2152 
2153 		os_memcpy(tmp, gtk + 16, 8);
2154 		os_memcpy(gtk + 16, gtk + 24, 8);
2155 		os_memcpy(gtk + 24, tmp, 8);
2156 	}
2157 
2158 	bss->gtk_len[keyidx] = gtk_len;
2159 	if (sta)
2160 		sta->gtk_len = gtk_len;
2161 	os_memcpy(bss->gtk[keyidx], gtk, gtk_len);
2162 	if (sta)
2163 		os_memcpy(sta->gtk, gtk, gtk_len);
2164 	rsc = gtk_elem + hlen - 8;
2165 	bss->rsc[keyidx][0] = rsc[5];
2166 	bss->rsc[keyidx][1] = rsc[4];
2167 	bss->rsc[keyidx][2] = rsc[3];
2168 	bss->rsc[keyidx][3] = rsc[2];
2169 	bss->rsc[keyidx][4] = rsc[1];
2170 	bss->rsc[keyidx][5] = rsc[0];
2171 	bss->gtk_idx = keyidx;
2172 	if (sta)
2173 		sta->gtk_idx = keyidx;
2174 	wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[keyidx], 6);
2175 }
2176 
2177 
process_igtk_subelem(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * kek,size_t kek_len,const u8 * igtk_elem,size_t igtk_elem_len,bool mlo)2178 static void process_igtk_subelem(struct wlantest *wt, struct wlantest_bss *bss,
2179 				 struct wlantest_sta *sta,
2180 				 const u8 *kek, size_t kek_len,
2181 				 const u8 *igtk_elem, size_t igtk_elem_len,
2182 				 bool mlo)
2183 {
2184 	u8 igtk[WPA_IGTK_MAX_LEN];
2185 	size_t igtk_len;
2186 	u16 keyidx;
2187 	const u8 *ipn;
2188 	size_t hlen;
2189 
2190 	if (bss->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC &&
2191 	    bss->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 &&
2192 	    bss->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 &&
2193 	    bss->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256)
2194 		return;
2195 
2196 	if (!igtk_elem) {
2197 		add_note(wt, MSG_INFO, "FT: No IGTK included in FTE");
2198 		return;
2199 	}
2200 
2201 	wpa_hexdump(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp",
2202 		    igtk_elem, igtk_elem_len);
2203 
2204 	igtk_len = wpa_cipher_key_len(bss->mgmt_group_cipher);
2205 	hlen = 2 + 6 + 1;
2206 	if (mlo)
2207 		hlen++;
2208 	if (igtk_elem_len != hlen + igtk_len + 8) {
2209 		add_note(wt, MSG_INFO, "FT: Invalid IGTK sub-elem length %zu",
2210 			 igtk_elem_len);
2211 		return;
2212 	}
2213 	if (igtk_elem[hlen - 1] != igtk_len) {
2214 		add_note(wt, MSG_INFO,
2215 			 "FT: Invalid IGTK sub-elem Key Length %d",
2216 			 igtk_elem[hlen - 1]);
2217 		return;
2218 	}
2219 
2220 	if (aes_unwrap(kek, kek_len, igtk_len / 8, igtk_elem + hlen, igtk)) {
2221 		add_note(wt, MSG_INFO,
2222 			 "FT: AES unwrap failed - could not decrypt IGTK");
2223 		return;
2224 	}
2225 
2226 	/* KeyID[2] | IPN[6] | [Link ID info[1]] | Key Length[1] | Key[16+8] */
2227 
2228 	keyidx = WPA_GET_LE16(igtk_elem);
2229 
2230 	wpa_hexdump(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk, igtk_len);
2231 
2232 	if (keyidx < 4 || keyidx > 5) {
2233 		add_note(wt, MSG_INFO, "Unexpected IGTK KeyID %u", keyidx);
2234 		return;
2235 	}
2236 
2237 	add_note(wt, MSG_DEBUG, "IGTK KeyID %u", keyidx);
2238 	wpa_hexdump(MSG_DEBUG, "IPN", igtk_elem + 2, 6);
2239 	wpa_hexdump(MSG_DEBUG, "IGTK", igtk, igtk_len);
2240 	os_memcpy(bss->igtk[keyidx], igtk, igtk_len);
2241 	bss->igtk_len[keyidx] = igtk_len;
2242 	ipn = igtk_elem + 2;
2243 	bss->ipn[keyidx] = WPA_GET_LE48(ipn);
2244 	bss->igtk_idx = keyidx;
2245 }
2246 
2247 
process_bigtk_subelem(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * kek,size_t kek_len,const u8 * bigtk_elem,size_t bigtk_elem_len,bool mlo)2248 static void process_bigtk_subelem(struct wlantest *wt, struct wlantest_bss *bss,
2249 				  struct wlantest_sta *sta,
2250 				  const u8 *kek, size_t kek_len,
2251 				  const u8 *bigtk_elem, size_t bigtk_elem_len,
2252 				  bool mlo)
2253 {
2254 	u8 bigtk[WPA_BIGTK_MAX_LEN];
2255 	size_t bigtk_len;
2256 	u16 keyidx;
2257 	const u8 *ipn;
2258 	size_t hlen;
2259 
2260 	if (!bigtk_elem ||
2261 	    (bss->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC &&
2262 	     bss->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 &&
2263 	     bss->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 &&
2264 	     bss->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256))
2265 	    return;
2266 
2267 	wpa_hexdump_key(MSG_DEBUG, "FT: Received BIGTK in Reassoc Resp",
2268 			bigtk_elem, bigtk_elem_len);
2269 
2270 	bigtk_len = wpa_cipher_key_len(bss->mgmt_group_cipher);
2271 	hlen = 2 + 6 + 1;
2272 	if (mlo)
2273 		hlen++;
2274 	if (bigtk_elem_len != hlen + bigtk_len + 8) {
2275 		add_note(wt, MSG_INFO,
2276 			 "FT: Invalid BIGTK sub-elem length %zu",
2277 			 bigtk_elem_len);
2278 		return;
2279 	}
2280 	if (bigtk_elem[hlen - 1] != bigtk_len) {
2281 		add_note(wt, MSG_INFO,
2282 			 "FT: Invalid BIGTK sub-elem Key Length %d",
2283 			 bigtk_elem[8]);
2284 		return;
2285 	}
2286 
2287 	if (aes_unwrap(kek, kek_len, bigtk_len / 8, bigtk_elem + hlen, bigtk)) {
2288 		add_note(wt, MSG_INFO,
2289 			 "FT: AES unwrap failed - could not decrypt BIGTK");
2290 		return;
2291 	}
2292 
2293 	/* KeyID[2] | IPN[6] | [Link ID Info[1]] | Key Length[1] | Key[16+8] */
2294 
2295 	keyidx = WPA_GET_LE16(bigtk_elem);
2296 
2297 	wpa_hexdump(MSG_DEBUG, "FT: BIGTK from Reassoc Resp", bigtk, bigtk_len);
2298 
2299 	if (keyidx < 6 || keyidx > 7) {
2300 		add_note(wt, MSG_INFO, "Unexpected BIGTK KeyID %u", keyidx);
2301 		return;
2302 	}
2303 
2304 	add_note(wt, MSG_DEBUG, "BIGTK KeyID %u", keyidx);
2305 	wpa_hexdump(MSG_DEBUG, "BIPN", bigtk_elem + 2, 6);
2306 	wpa_hexdump(MSG_DEBUG, "BIGTK", bigtk, bigtk_len);
2307 	os_memcpy(bss->igtk[keyidx], bigtk, bigtk_len);
2308 	bss->igtk_len[keyidx] = bigtk_len;
2309 	ipn = bigtk_elem + 2;
2310 	bss->ipn[keyidx] = WPA_GET_LE48(ipn);
2311 	bss->bigtk_idx = keyidx;
2312 }
2313 
2314 
process_fte_group_keys(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * kek,size_t kek_len,struct wpa_ft_ies * parse)2315 static void process_fte_group_keys(struct wlantest *wt,
2316 				   struct wlantest_bss *bss,
2317 				   struct wlantest_sta *sta,
2318 				   const u8 *kek, size_t kek_len,
2319 				   struct wpa_ft_ies *parse)
2320 {
2321 	process_gtk_subelem(wt, bss, sta, kek, kek_len,
2322 			    parse->gtk, parse->gtk_len, false);
2323 	process_igtk_subelem(wt, bss, sta, kek, kek_len,
2324 			     parse->igtk, parse->igtk_len, false);
2325 	process_bigtk_subelem(wt, bss, sta, kek, kek_len,
2326 			      parse->bigtk, parse->bigtk_len, false);
2327 }
2328 
2329 
process_fte_group_keys_mlo(struct wlantest * wt,struct wlantest_bss * bss,struct wlantest_sta * sta,const u8 * kek,size_t kek_len,struct wpa_ft_ies * parse)2330 static void process_fte_group_keys_mlo(struct wlantest *wt,
2331 				       struct wlantest_bss *bss,
2332 				       struct wlantest_sta *sta,
2333 				       const u8 *kek, size_t kek_len,
2334 				       struct wpa_ft_ies *parse)
2335 {
2336 	int link_id;
2337 
2338 	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
2339 		struct wlantest_bss *l_bss;
2340 		struct wlantest_sta *l_sta;
2341 
2342 		if (!(parse->valid_mlo_gtks & BIT(link_id)))
2343 			continue;
2344 
2345 		l_bss = bss_find_mld(wt, bss->mld_mac_addr, link_id);
2346 		if (!l_bss) {
2347 			wpa_printf(MSG_DEBUG,
2348 				   "FT: No BSS entry found for AP MLD " MACSTR
2349 				   " link ID %u",
2350 				   MAC2STR(bss->mld_mac_addr),link_id);
2351 			continue;
2352 		}
2353 
2354 		wpa_printf(MSG_DEBUG,
2355 			   "Trying to learn group keys for Link ID %u",
2356 			   link_id);
2357 		l_sta = bss == l_bss ? sta : NULL;
2358 
2359 		process_gtk_subelem(wt, l_bss, l_sta, kek, kek_len,
2360 				    parse->mlo_gtk[link_id],
2361 				    parse->mlo_gtk_len[link_id], true);
2362 		process_igtk_subelem(wt, l_bss, l_sta, kek, kek_len,
2363 				     parse->mlo_igtk[link_id],
2364 				     parse->mlo_igtk_len[link_id], true);
2365 		process_bigtk_subelem(wt, l_bss, l_sta, kek, kek_len,
2366 				      parse->mlo_bigtk[link_id],
2367 				      parse->mlo_bigtk_len[link_id], true);
2368 	}
2369 }
2370 
2371 
rx_mgmt_reassoc_resp(struct wlantest * wt,const u8 * data,size_t len)2372 static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
2373 				 size_t len)
2374 {
2375 	const struct ieee80211_mgmt *mgmt;
2376 	struct wlantest_bss *bss;
2377 	struct wlantest_sta *sta;
2378 	u16 capab, status, aid;
2379 	const u8 *ies;
2380 	size_t ies_len;
2381 	struct ieee802_11_elems elems;
2382 	const u8 *ml;
2383 
2384 	mgmt = (const struct ieee80211_mgmt *) data;
2385 	bss = bss_get(wt, mgmt->bssid);
2386 	if (bss == NULL)
2387 		return;
2388 	sta = sta_find_mlo(wt, bss, mgmt->da);
2389 	if (!sta)
2390 		sta = sta_get(bss, mgmt->da);
2391 	if (sta == NULL)
2392 		return;
2393 
2394 	if (len < 24 + 6) {
2395 		add_note(wt, MSG_INFO, "Too short Reassociation Response frame "
2396 			 "from " MACSTR, MAC2STR(mgmt->sa));
2397 		return;
2398 	}
2399 
2400 	ies = mgmt->u.reassoc_resp.variable;
2401 	ies_len = len - (mgmt->u.reassoc_resp.variable - data);
2402 
2403 	capab = le_to_host16(mgmt->u.reassoc_resp.capab_info);
2404 	status = le_to_host16(mgmt->u.reassoc_resp.status_code);
2405 	aid = le_to_host16(mgmt->u.reassoc_resp.aid);
2406 
2407 	wpa_printf(MSG_DEBUG, "REASSOCRESP " MACSTR " -> " MACSTR
2408 		   " (capab=0x%x status=%u aid=%u)",
2409 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
2410 		   aid & 0x3fff);
2411 
2412 	ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC);
2413 	if (ml &&
2414 	    ieee802_11_parse_elems(ies, ies_len, &elems, 0) != ParseFailed)
2415 		parse_basic_ml_elems(&elems, true, NULL, 4);
2416 
2417 	if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
2418 		const u8 *session, *frame_ad, *frame_ad_end, *encr_end;
2419 
2420 		session = get_fils_session(ies, ies_len);
2421 		if (session) {
2422 			frame_ad = (const u8 *)
2423 				&mgmt->u.reassoc_resp.capab_info;
2424 			frame_ad_end = session + 2 + session[1];
2425 			encr_end = data + len;
2426 			decrypt_fils_assoc_resp(wt, bss, sta, data, frame_ad,
2427 						frame_ad_end, encr_end);
2428 			ies_len = session - ies;
2429 		}
2430 	}
2431 
2432 	if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
2433 		add_note(wt, MSG_INFO,
2434 			 "Failed to parse IEs in ReassocResp from " MACSTR,
2435 			 MAC2STR(mgmt->sa));
2436 	}
2437 
2438 	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
2439 		if (!elems.timeout_int ||
2440 		    elems.timeout_int[0] != WLAN_TIMEOUT_ASSOC_COMEBACK) {
2441 			add_note(wt, MSG_INFO, "No valid Timeout Interval IE "
2442 				 "with Assoc Comeback time in ReassocResp "
2443 				 "(status=30) from " MACSTR,
2444 				 MAC2STR(mgmt->sa));
2445 		} else {
2446 			sta->counters[
2447 				WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK]++;
2448 		}
2449 	}
2450 
2451 	if (status)
2452 		return;
2453 
2454 	if ((aid & 0xc000) != 0xc000) {
2455 		add_note(wt, MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
2456 			 "in Reassociation Response from " MACSTR,
2457 			 MAC2STR(mgmt->sa));
2458 	}
2459 	sta->aid = aid & 0xc000;
2460 
2461 	if (sta->state < STATE2 && !sta->ft_over_ds) {
2462 		add_note(wt, MSG_DEBUG,
2463 			 "STA " MACSTR " was not in State 2 when "
2464 			 "getting associated", MAC2STR(sta->addr));
2465 	}
2466 
2467 	if (sta->state < STATE3) {
2468 		add_note(wt, MSG_DEBUG, "STA " MACSTR
2469 			 " moved to State 3 with " MACSTR,
2470 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
2471 		sta->state = STATE3;
2472 	}
2473 
2474 	if (elems.ftie) {
2475 		struct wpa_ft_ies parse;
2476 		int use_sha384;
2477 		struct rsn_mdie *mde;
2478 		const u8 *anonce, *snonce, *fte_mic;
2479 		u8 fte_elem_count;
2480 		unsigned int count;
2481 		u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
2482 		size_t mic_len = 16;
2483 		const u8 *kck, *kek;
2484 		size_t kck_len, kek_len;
2485 		const u8 *aa, *spa;
2486 		struct wpabuf *extra = NULL, *rsne = NULL, *rsnxe = NULL;
2487 
2488 		if (ml) {
2489 			aa = bss->mld_mac_addr;
2490 			spa = sta->mld_mac_addr;
2491 		} else {
2492 			aa = bss->bssid;
2493 			spa = sta->addr;
2494 		}
2495 
2496 		use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
2497 
2498 		if (wpa_ft_parse_ies(ies, ies_len, &parse, sta->key_mgmt,
2499 				     true) < 0) {
2500 			add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
2501 			return;
2502 		}
2503 
2504 		if (!parse.rsn) {
2505 			add_note(wt, MSG_INFO, "FT: No RSNE in Reassoc Resp");
2506 			goto out;
2507 		}
2508 
2509 		if (!parse.rsn_pmkid) {
2510 			add_note(wt, MSG_INFO, "FT: No PMKID in RSNE");
2511 			goto out;
2512 		}
2513 
2514 		if (os_memcmp_const(parse.rsn_pmkid, sta->pmk_r1_name,
2515 				    WPA_PMK_NAME_LEN) != 0) {
2516 			add_note(wt, MSG_INFO,
2517 				 "FT: PMKID in Reassoc Resp did not match PMKR1Name");
2518 			wpa_hexdump(MSG_DEBUG,
2519 				    "FT: Received RSNE[PMKR1Name]",
2520 				    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
2521 			wpa_hexdump(MSG_DEBUG,
2522 				    "FT: Previously derived PMKR1Name",
2523 				    sta->pmk_r1_name, WPA_PMK_NAME_LEN);
2524 			goto out;
2525 		}
2526 
2527 		mde = (struct rsn_mdie *) parse.mdie;
2528 		if (!mde || parse.mdie_len < sizeof(*mde) ||
2529 		    os_memcmp(mde->mobility_domain, bss->mdid,
2530 			      MOBILITY_DOMAIN_ID_LEN) != 0) {
2531 			add_note(wt, MSG_INFO, "FT: Invalid MDE");
2532 		}
2533 
2534 		if (use_sha384) {
2535 			struct rsn_ftie_sha384 *fte;
2536 
2537 			fte = (struct rsn_ftie_sha384 *) parse.ftie;
2538 			if (!fte || parse.ftie_len < sizeof(*fte)) {
2539 				add_note(wt, MSG_INFO, "FT: Invalid FTE");
2540 				goto out;
2541 			}
2542 
2543 			anonce = fte->anonce;
2544 			snonce = fte->snonce;
2545 			fte_elem_count = fte->mic_control[1];
2546 			fte_mic = fte->mic;
2547 		} else {
2548 			struct rsn_ftie *fte;
2549 
2550 			fte = (struct rsn_ftie *) parse.ftie;
2551 			if (!fte || parse.ftie_len < sizeof(*fte)) {
2552 				add_note(wt, MSG_INFO, "FT: Invalid FTIE");
2553 				goto out;
2554 			}
2555 
2556 			anonce = fte->anonce;
2557 			snonce = fte->snonce;
2558 			fte_elem_count = fte->mic_control[1];
2559 			fte_mic = fte->mic;
2560 		}
2561 
2562 		if (os_memcmp(snonce, sta->snonce, WPA_NONCE_LEN) != 0) {
2563 			add_note(wt, MSG_INFO, "FT: SNonce mismatch in FTIE");
2564 			wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
2565 				    snonce, WPA_NONCE_LEN);
2566 			wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
2567 				    sta->snonce, WPA_NONCE_LEN);
2568 			goto out;
2569 		}
2570 
2571 		if (os_memcmp(anonce, sta->anonce, WPA_NONCE_LEN) != 0) {
2572 			add_note(wt, MSG_INFO, "FT: ANonce mismatch in FTIE");
2573 			wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
2574 				    anonce, WPA_NONCE_LEN);
2575 			wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
2576 				    sta->anonce, WPA_NONCE_LEN);
2577 			goto out;
2578 		}
2579 
2580 		if (!parse.r0kh_id) {
2581 			add_note(wt, MSG_INFO, "FT: No R0KH-ID subelem in FTE");
2582 			goto out;
2583 		}
2584 
2585 		if (parse.r0kh_id_len != bss->r0kh_id_len ||
2586 		    os_memcmp_const(parse.r0kh_id, bss->r0kh_id,
2587 				    parse.r0kh_id_len) != 0) {
2588 			add_note(wt, MSG_INFO,
2589 				 "FT: R0KH-ID in FTE did not match the current R0KH-ID");
2590 			wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
2591 				    parse.r0kh_id, parse.r0kh_id_len);
2592 			wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
2593 				    bss->r0kh_id, bss->r0kh_id_len);
2594 			os_memcpy(bss->r0kh_id, parse.r0kh_id,
2595 				  parse.r0kh_id_len);
2596 			bss->r0kh_id_len = parse.r0kh_id_len;
2597 		}
2598 
2599 		if (!parse.r1kh_id) {
2600 			add_note(wt, MSG_INFO, "FT: No R1KH-ID subelem in FTE");
2601 			goto out;
2602 		}
2603 
2604 		if (os_memcmp_const(parse.r1kh_id, bss->r1kh_id,
2605 				    FT_R1KH_ID_LEN) != 0) {
2606 			add_note(wt, MSG_INFO,
2607 				 "FT: Unknown R1KH-ID used in ReassocResp");
2608 			os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
2609 		}
2610 
2611 		count = 2; /* MDE and FTE */
2612 		if (ml) {
2613 			int link_id;
2614 			struct wlantest_bss *l_bss;
2615 			u8 rsne_buf[257];
2616 			size_t rsne_len;
2617 
2618 			extra = wpabuf_alloc(MAX_NUM_MLD_LINKS * ETH_ALEN);
2619 			rsne = wpabuf_alloc(MAX_NUM_MLD_LINKS * 256);
2620 			rsnxe = wpabuf_alloc(MAX_NUM_MLD_LINKS * 256);
2621 			if (!extra || !rsne || !rsnxe)
2622 				goto out;
2623 
2624 			for (link_id = 0; link_id < MAX_NUM_MLD_LINKS;
2625 			     link_id++) {
2626 				struct wpa_ie_data ie_data;
2627 
2628 				if (is_zero_ether_addr(sta->link_addr[link_id]))
2629 					continue;
2630 
2631 				l_bss = bss_find_mld(wt, bss->mld_mac_addr,
2632 						     link_id);
2633 				if (!l_bss) {
2634 					wpa_printf(MSG_DEBUG,
2635 						   "FT: No BSS entry found for AP MLD "
2636 						   MACSTR " link ID %u",
2637 						   MAC2STR(bss->mld_mac_addr),
2638 						   link_id);
2639 					continue;
2640 				}
2641 
2642 				/* Insert PMKID=PMKR1Name into each RSNE */
2643 				rsne_len = 2 + l_bss->rsnie[1];
2644 				if (wpa_parse_wpa_ie_rsn(l_bss->rsnie,
2645 							 rsne_len, &ie_data) <
2646 				    0 ||
2647 				    rsne_len > 200) {
2648 					wpa_printf(MSG_DEBUG,
2649 						   "FT: Could not parse AP RSNE (or too long element) for link ID %u ",
2650 						   link_id);
2651 					continue;
2652 				}
2653 
2654 				os_memcpy(rsne_buf, l_bss->rsnie, rsne_len);
2655 				if (wpa_insert_pmkid(rsne_buf, &rsne_len,
2656 						     sta->pmk_r1_name,
2657 						     true) < 0) {
2658 					wpa_printf(MSG_DEBUG,
2659 						   "FT: Could not insert PMKR1Name into AP RSNE for link ID %u ",
2660 						   link_id);
2661 					continue;
2662 				}
2663 
2664 				count++; /* RSNE */
2665 				wpabuf_put_data(rsne, rsne_buf, rsne_len);
2666 
2667 				if (l_bss->rsnxe_len) {
2668 					count++;
2669 					wpabuf_put_u8(rsnxe, WLAN_EID_RSNX);
2670 					wpabuf_put_u8(rsnxe, l_bss->rsnxe_len);
2671 					wpabuf_put_data(rsnxe,
2672 							l_bss->rsnxe,
2673 							l_bss->rsnxe_len);
2674 				}
2675 
2676 				wpabuf_put_data(extra, l_bss->bssid, ETH_ALEN);
2677 			}
2678 		} else {
2679 			count++; /* RSNE */
2680 			rsne = wpabuf_alloc_copy(parse.rsn - 2,
2681 						 parse.rsn_len + 2);
2682 			if (!rsne)
2683 				goto out;
2684 			if (parse.rsnxe) {
2685 				count++;
2686 				rsnxe = wpabuf_alloc_copy(parse.rsnxe - 2,
2687 							  parse.rsnxe_len + 2);
2688 				if (!rsnxe)
2689 					goto out;
2690 			}
2691 		}
2692 		if (parse.ric)
2693 			count += ieee802_11_ie_count(parse.ric, parse.ric_len);
2694 		if (fte_elem_count != count) {
2695 			add_note(wt, MSG_INFO,
2696 				 "FT: Unexpected IE count in MIC Control: received %u expected %u",
2697 				 fte_elem_count, count);
2698 			goto out;
2699 		}
2700 
2701 		if (wpa_key_mgmt_fils(sta->key_mgmt)) {
2702 			kck = sta->ptk.kck2;
2703 			kck_len = sta->ptk.kck2_len;
2704 			kek = sta->ptk.kek2;
2705 			kek_len = sta->ptk.kek2_len;
2706 		} else {
2707 			kck = sta->ptk.kck;
2708 			kck_len = sta->ptk.kck_len;
2709 			kek = sta->ptk.kek;
2710 			kek_len = sta->ptk.kek_len;
2711 		}
2712 
2713 		/* FTE might be fragmented. If it is, the separate Fragment
2714 		 * elements are included in MIC calculation as full elements. */
2715 		if (wpa_ft_mic(sta->key_mgmt, kck, kck_len,
2716 			       spa, aa, 6,
2717 			       parse.mdie - 2, parse.mdie_len + 2,
2718 			       elems.ftie - 2, elems.fte_defrag_len + 2,
2719 			       wpabuf_head(rsne), wpabuf_len(rsne),
2720 			       parse.ric, parse.ric_len,
2721 			       rsnxe ? wpabuf_head(rsnxe) : NULL,
2722 			       rsnxe ? wpabuf_len(rsnxe) : 0,
2723 			       extra,
2724 			       mic) < 0) {
2725 			add_note(wt, MSG_INFO, "FT: Failed to calculate MIC");
2726 			goto out;
2727 		}
2728 
2729 		if (os_memcmp_const(mic, fte_mic, mic_len) != 0) {
2730 			int link_id;
2731 
2732 			add_note(wt, MSG_INFO, "FT: Invalid MIC in FTE");
2733 			wpa_printf(MSG_DEBUG,
2734 				   "FT: addr=" MACSTR " auth_addr=" MACSTR,
2735 				   MAC2STR(spa), MAC2STR(aa));
2736 			wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
2737 				    fte_mic, mic_len);
2738 			wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC",
2739 				    mic, mic_len);
2740 			wpa_hexdump(MSG_MSGDUMP, "FT: MDE",
2741 				    parse.mdie - 2, parse.mdie_len + 2);
2742 			wpa_hexdump(MSG_MSGDUMP, "FT: FTE",
2743 				    elems.ftie - 2, elems.fte_defrag_len + 2);
2744 			wpa_hexdump_buf(MSG_MSGDUMP, "FT: RSNE", rsne);
2745 			wpa_hexdump_buf(MSG_MSGDUMP, "FT: RSNXE", rsnxe);
2746 			for (link_id = 0; link_id < MAX_NUM_MLD_LINKS;
2747 			     link_id++) {
2748 				struct wlantest_bss *l_bss;
2749 
2750 				if (is_zero_ether_addr(sta->link_addr[link_id]))
2751 					continue;
2752 				l_bss = bss_find_mld(wt, bss->mld_mac_addr,
2753 						     link_id);
2754 				if (l_bss)
2755 					wpa_printf(MSG_DEBUG,
2756 						   "FT: AP link %d address: "
2757 						   MACSTR, link_id,
2758 						   MAC2STR(l_bss->bssid));
2759 			}
2760 			goto out;
2761 		}
2762 
2763 		add_note(wt, MSG_INFO, "FT: Valid FTE MIC");
2764 
2765 		if (wpa_compare_rsn_ie(wpa_key_mgmt_ft(sta->key_mgmt),
2766 				       bss->rsnie, 2 + bss->rsnie[1],
2767 				       parse.rsn - 2, parse.rsn_len + 2)) {
2768 			add_note(wt, MSG_INFO,
2769 				 "FT: RSNE mismatch between Beacon/ProbeResp and FT protocol Reassociation Response frame");
2770 			wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp",
2771 				    &bss->rsnie[2], bss->rsnie[1]);
2772 			wpa_hexdump(MSG_INFO,
2773 				    "RSNE in FT protocol Reassociation Response frame",
2774 				    parse.rsn ? parse.rsn - 2 : NULL,
2775 				    parse.rsn ? parse.rsn_len + 2 : 0);
2776 		}
2777 
2778 		if (ml)
2779 			process_fte_group_keys_mlo(wt, bss, sta, kek, kek_len,
2780 						   &parse);
2781 		else
2782 			process_fte_group_keys(wt, bss, sta, kek, kek_len,
2783 					       &parse);
2784 
2785 	out:
2786 		wpa_ft_parse_ies_free(&parse);
2787 		wpabuf_free(rsne);
2788 		wpabuf_free(rsnxe);
2789 		wpabuf_free(extra);
2790 	}
2791 
2792 	if (elems.owe_dh && elems.owe_dh_len >= 2) {
2793 		sta->owe_group = WPA_GET_LE16(elems.owe_dh);
2794 		wpa_printf(MSG_DEBUG, "OWE using group %u", sta->owe_group);
2795 	}
2796 }
2797 
2798 
disassoc_all_stas(struct wlantest * wt,struct wlantest_bss * bss)2799 static void disassoc_all_stas(struct wlantest *wt, struct wlantest_bss *bss)
2800 {
2801 	struct wlantest_sta *sta;
2802 	dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
2803 		if (sta->state <= STATE2)
2804 			continue;
2805 		add_note(wt, MSG_DEBUG, "STA " MACSTR
2806 			 " moved to State 2 with " MACSTR,
2807 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
2808 		sta->state = STATE2;
2809 	}
2810 }
2811 
2812 
rx_mgmt_disassoc(struct wlantest * wt,const u8 * data,size_t len,int valid)2813 static void rx_mgmt_disassoc(struct wlantest *wt, const u8 *data, size_t len,
2814 			     int valid)
2815 {
2816 	const struct ieee80211_mgmt *mgmt;
2817 	struct wlantest_bss *bss;
2818 	struct wlantest_sta *sta;
2819 	u16 fc, reason;
2820 
2821 	mgmt = (const struct ieee80211_mgmt *) data;
2822 	bss = bss_get(wt, mgmt->bssid);
2823 	if (bss == NULL)
2824 		return;
2825 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
2826 		sta = sta_get(bss, mgmt->da);
2827 	else
2828 		sta = sta_get(bss, mgmt->sa);
2829 
2830 	if (len < 24 + 2) {
2831 		add_note(wt, MSG_INFO, "Too short Disassociation frame from "
2832 			 MACSTR, MAC2STR(mgmt->sa));
2833 		return;
2834 	}
2835 
2836 	reason = le_to_host16(mgmt->u.disassoc.reason_code);
2837 	wpa_printf(MSG_DEBUG, "DISASSOC " MACSTR " -> " MACSTR
2838 		   " (reason=%u) (valid=%d)",
2839 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
2840 		   reason, valid);
2841 	wpa_hexdump(MSG_MSGDUMP, "DISASSOC payload", data + 24, len - 24);
2842 
2843 	if (sta == NULL) {
2844 		if (valid && mgmt->da[0] == 0xff)
2845 			disassoc_all_stas(wt, bss);
2846 		return;
2847 	}
2848 
2849 	if (ether_addr_equal(mgmt->sa, mgmt->bssid)) {
2850 		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_RX :
2851 			      WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX]++;
2852 		if (sta->pwrmgt && !sta->pspoll)
2853 			sta->counters[
2854 				WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP]++;
2855 		else
2856 			sta->counters[
2857 				WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE]++;
2858 
2859 		fc = le_to_host16(mgmt->frame_control);
2860 		if (!(fc & WLAN_FC_ISWEP) && reason == 6)
2861 			sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC6]++;
2862 		else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
2863 			sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC7]++;
2864 	} else
2865 		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_TX :
2866 			      WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX]++;
2867 
2868 	if (!valid) {
2869 		add_note(wt, MSG_INFO, "Do not change STA " MACSTR " State "
2870 			 "since Disassociation frame was not protected "
2871 			 "correctly", MAC2STR(sta->addr));
2872 		return;
2873 	}
2874 
2875 	if (sta->state < STATE2) {
2876 		add_note(wt, MSG_DEBUG,
2877 			 "STA " MACSTR " was not in State 2 or 3 "
2878 			 "when getting disassociated", MAC2STR(sta->addr));
2879 	}
2880 
2881 	if (sta->state > STATE2) {
2882 		add_note(wt, MSG_DEBUG, "STA " MACSTR
2883 			 " moved to State 2 with " MACSTR,
2884 			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
2885 		sta->state = STATE2;
2886 	}
2887 	tdls_link_down(wt, bss, sta);
2888 }
2889 
2890 
rx_mgmt_action_ft_request(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len)2891 static void rx_mgmt_action_ft_request(struct wlantest *wt,
2892 				      const struct ieee80211_mgmt *mgmt,
2893 				      size_t len)
2894 {
2895 	const u8 *ies;
2896 	size_t ies_len;
2897 	struct wpa_ft_ies parse;
2898 	const u8 *spa, *aa;
2899 	struct wlantest_bss *bss, *bss2;
2900 	struct wlantest_sta *sta;
2901 
2902 	if (len < 24 + 2 + 2 * ETH_ALEN) {
2903 		add_note(wt, MSG_INFO, "Too short FT Request frame");
2904 		return;
2905 	}
2906 
2907 	spa = mgmt->u.action.u.ft_action_resp.sta_addr;
2908 	aa = mgmt->u.action.u.ft_action_resp.target_ap_addr;
2909 	wpa_printf(MSG_DEBUG, "FT Request: STA Address: " MACSTR
2910 		   " Target AP Address: " MACSTR,
2911 		   MAC2STR(spa), MAC2STR(aa));
2912 	ies = mgmt->u.action.u.ft_action_req.variable;
2913 	ies_len = len - (24 + 2 + 2 * ETH_ALEN);
2914 	wpa_hexdump(MSG_DEBUG, "FT Request frame body", ies, ies_len);
2915 
2916 	if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false)) {
2917 		add_note(wt, MSG_INFO, "Could not parse FT Request frame body");
2918 		return;
2919 	}
2920 
2921 	bss = bss_find(wt, aa);
2922 	bss2 = bss_find_mld(wt, aa, -1);
2923 	if (!bss)
2924 		bss = bss2;
2925 	if (bss && bss2 && bss != bss2 && !sta_find(bss, spa))
2926 		bss = bss2;
2927 	if (!bss)
2928 		bss = bss_get(wt, aa);
2929 	if (!bss) {
2930 		add_note(wt, MSG_INFO, "No BSS entry for Target AP");
2931 		goto out;
2932 	}
2933 
2934 	sta = sta_find_mlo(wt, bss, spa);
2935 	if (!sta)
2936 		sta = sta_get(bss, spa);
2937 	if (!sta)
2938 		goto out;
2939 
2940 	sta->ft_over_ds = true;
2941 	sta->key_mgmt = parse.key_mgmt;
2942 	sta->pairwise_cipher = parse.pairwise_cipher;
2943 	if (parse.rsnxe) {
2944 		os_memcpy(sta->rsnxe, parse.rsnxe, parse.rsnxe_len);
2945 		sta->rsnxe_len = parse.rsnxe_len;
2946 	} else {
2947 		sta->rsnxe_len = 0;
2948 	}
2949 
2950 out:
2951 	wpa_ft_parse_ies_free(&parse);
2952 }
2953 
2954 
rx_mgmt_action_ft_response(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len)2955 static void rx_mgmt_action_ft_response(struct wlantest *wt,
2956 				       struct wlantest_sta *sta,
2957 				       const struct ieee80211_mgmt *mgmt,
2958 				       size_t len)
2959 {
2960 	struct wlantest_bss *bss, *bss2;
2961 	struct wlantest_sta *new_sta;
2962 	const u8 *spa, *aa;
2963 	const u8 *ies;
2964 	size_t ies_len, kdk_len;
2965 	struct wpa_ft_ies parse;
2966 	struct wpa_ptk ptk;
2967 	u8 ptk_name[WPA_PMK_NAME_LEN];
2968 	const u8 *rsnxe;
2969 	size_t rsnxe_len;
2970 
2971 	if (len < 24 + 2 + 2 * ETH_ALEN + 2) {
2972 		add_note(wt, MSG_INFO, "Too short FT Response frame from "
2973 			 MACSTR, MAC2STR(mgmt->sa));
2974 		return;
2975 	}
2976 
2977 	spa = mgmt->u.action.u.ft_action_resp.sta_addr;
2978 	aa = mgmt->u.action.u.ft_action_resp.target_ap_addr;
2979 	wpa_printf(MSG_DEBUG, "FT Response: STA Address: " MACSTR
2980 		   " Target AP Address: " MACSTR " Status Code: %u",
2981 		   MAC2STR(spa), MAC2STR(aa),
2982 		   le_to_host16(mgmt->u.action.u.ft_action_resp.status_code));
2983 	ies = mgmt->u.action.u.ft_action_req.variable;
2984 	ies_len = len - (24 + 2 + 2 * ETH_ALEN);
2985 	wpa_hexdump(MSG_DEBUG, "FT Response frame body", ies, ies_len);
2986 
2987 	if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false)) {
2988 		add_note(wt, MSG_INFO,
2989 			 "Could not parse FT Response frame body");
2990 		return;
2991 	}
2992 
2993 	bss = bss_find(wt, aa);
2994 	bss2 = bss_find_mld(wt, aa, -1);
2995 	if (!bss)
2996 		bss = bss2;
2997 	if (bss && bss2 && bss != bss2 && !sta_find(bss, spa))
2998 		bss = bss2;
2999 	if (!bss)
3000 		bss = bss_get(wt, aa);
3001 
3002 	if (!bss) {
3003 		add_note(wt, MSG_INFO, "No BSS entry for Target AP");
3004 		goto out;
3005 	}
3006 
3007 	if (parse.r1kh_id)
3008 		os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
3009 
3010 	if (wpa_derive_pmk_r1(sta->pmk_r0, sta->pmk_r0_len, sta->pmk_r0_name,
3011 			      bss->r1kh_id, spa, sta->pmk_r1,
3012 			      sta->pmk_r1_name) < 0)
3013 		goto out;
3014 	sta->pmk_r1_len = sta->pmk_r0_len;
3015 
3016 	new_sta = sta_find_mlo(wt, bss, spa);
3017 	if (!new_sta)
3018 		new_sta = sta_get(bss, spa);
3019 	if (!new_sta)
3020 		goto out;
3021 	os_memcpy(new_sta->pmk_r0, sta->pmk_r0, sta->pmk_r0_len);
3022 	new_sta->pmk_r0_len = sta->pmk_r0_len;
3023 	os_memcpy(new_sta->pmk_r0_name, sta->pmk_r0_name,
3024 		  sizeof(sta->pmk_r0_name));
3025 	os_memcpy(new_sta->pmk_r1, sta->pmk_r1, sta->pmk_r1_len);
3026 	new_sta->pmk_r1_len = sta->pmk_r1_len;
3027 	os_memcpy(new_sta->pmk_r1_name, sta->pmk_r1_name,
3028 		  sizeof(sta->pmk_r1_name));
3029 
3030 	if ((sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE ||
3031 	     sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE_2) &&
3032 	    bss->rsnxoe_len) {
3033 		rsnxe = bss->rsnxoe;
3034 		rsnxe_len = bss->rsnxoe_len;
3035 	} else {
3036 		rsnxe = bss->rsnxe;
3037 		rsnxe_len = bss->rsnxe_len;
3038 	}
3039 	if (ieee802_11_rsnx_capab_len(rsnxe, rsnxe_len,
3040 				      WLAN_RSNX_CAPAB_SECURE_LTF) &&
3041 	    ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
3042 				      WLAN_RSNX_CAPAB_SECURE_LTF))
3043 		kdk_len = WPA_KDK_MAX_LEN;
3044 	else
3045 		kdk_len = 0;
3046 
3047 	if (!parse.fte_anonce || !parse.fte_snonce ||
3048 	    wpa_pmk_r1_to_ptk(sta->pmk_r1, sta->pmk_r1_len, parse.fte_snonce,
3049 			      parse.fte_anonce, spa, aa,
3050 			      sta->pmk_r1_name, &ptk, ptk_name,
3051 			      new_sta->key_mgmt, new_sta->pairwise_cipher,
3052 			      kdk_len) < 0)
3053 		goto out;
3054 
3055 	sta_new_ptk(wt, new_sta, &ptk);
3056 	os_memcpy(new_sta->snonce, parse.fte_snonce, WPA_NONCE_LEN);
3057 	os_memcpy(new_sta->anonce, parse.fte_anonce, WPA_NONCE_LEN);
3058 out:
3059 	wpa_ft_parse_ies_free(&parse);
3060 }
3061 
3062 
rx_mgmt_action_ft(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len,int valid)3063 static void rx_mgmt_action_ft(struct wlantest *wt, struct wlantest_sta *sta,
3064 			      const struct ieee80211_mgmt *mgmt,
3065 			      size_t len, int valid)
3066 {
3067 	if (len < 24 + 2) {
3068 		add_note(wt, MSG_INFO, "Too short FT Action frame from " MACSTR,
3069 			 MAC2STR(mgmt->sa));
3070 		return;
3071 	}
3072 
3073 	switch (mgmt->u.action.u.ft_action_req.action) {
3074 	case 1:
3075 		rx_mgmt_action_ft_request(wt, mgmt, len);
3076 		break;
3077 	case 2:
3078 		rx_mgmt_action_ft_response(wt, sta, mgmt, len);
3079 		break;
3080 	default:
3081 		add_note(wt, MSG_INFO, "Unsupported FT action value %u from "
3082 			 MACSTR, mgmt->u.action.u.ft_action_req.action,
3083 			 MAC2STR(mgmt->sa));
3084 	}
3085 }
3086 
3087 
rx_mgmt_action_sa_query_req(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len,int valid)3088 static void rx_mgmt_action_sa_query_req(struct wlantest *wt,
3089 					struct wlantest_sta *sta,
3090 					const struct ieee80211_mgmt *mgmt,
3091 					size_t len, int valid)
3092 {
3093 	const u8 *rx_id;
3094 	u8 *id;
3095 
3096 	rx_id = (const u8 *) mgmt->u.action.u.sa_query_req.trans_id;
3097 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
3098 		id = sta->ap_sa_query_tr;
3099 	else
3100 		id = sta->sta_sa_query_tr;
3101 	add_note(wt, MSG_INFO, "SA Query Request " MACSTR " -> " MACSTR
3102 		 " (trans_id=%02x%02x)%s",
3103 		 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
3104 		 valid ? "" : " (invalid protection)");
3105 	os_memcpy(id, mgmt->u.action.u.sa_query_req.trans_id, 2);
3106 	if (ether_addr_equal(mgmt->sa, sta->addr))
3107 		sta->counters[valid ?
3108 			      WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX :
3109 			      WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX]++;
3110 	else
3111 		sta->counters[valid ?
3112 			      WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX :
3113 			      WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX]++;
3114 }
3115 
3116 
rx_mgmt_action_sa_query_resp(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len,int valid)3117 static void rx_mgmt_action_sa_query_resp(struct wlantest *wt,
3118 					 struct wlantest_sta *sta,
3119 					 const struct ieee80211_mgmt *mgmt,
3120 					 size_t len, int valid)
3121 {
3122 	const u8 *rx_id;
3123 	u8 *id;
3124 	int match;
3125 
3126 	rx_id = (const u8 *) mgmt->u.action.u.sa_query_resp.trans_id;
3127 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
3128 		id = sta->sta_sa_query_tr;
3129 	else
3130 		id = sta->ap_sa_query_tr;
3131 	match = os_memcmp(rx_id, id, 2) == 0;
3132 	add_note(wt, MSG_INFO, "SA Query Response " MACSTR " -> " MACSTR
3133 		 " (trans_id=%02x%02x; %s)%s",
3134 		 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
3135 		 match ? "match" : "mismatch",
3136 		 valid ? "" : " (invalid protection)");
3137 	if (ether_addr_equal(mgmt->sa, sta->addr))
3138 		sta->counters[(valid && match) ?
3139 			      WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX :
3140 			      WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX]++;
3141 	else
3142 		sta->counters[(valid && match) ?
3143 			      WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX :
3144 			      WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX]++;
3145 }
3146 
3147 
rx_mgmt_action_sa_query(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len,int valid)3148 static void rx_mgmt_action_sa_query(struct wlantest *wt,
3149 				    struct wlantest_sta *sta,
3150 				    const struct ieee80211_mgmt *mgmt,
3151 				    size_t len, int valid)
3152 {
3153 	if (len < 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
3154 		add_note(wt, MSG_INFO, "Too short SA Query frame from " MACSTR,
3155 			 MAC2STR(mgmt->sa));
3156 		return;
3157 	}
3158 
3159 	if (len > 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
3160 		size_t elen = len - (24 + 2 + WLAN_SA_QUERY_TR_ID_LEN);
3161 		add_note(wt, MSG_INFO, "Unexpected %u octets of extra data at "
3162 			 "the end of SA Query frame from " MACSTR,
3163 			 (unsigned) elen, MAC2STR(mgmt->sa));
3164 		wpa_hexdump(MSG_INFO, "SA Query extra data",
3165 			    ((const u8 *) mgmt) + len - elen, elen);
3166 	}
3167 
3168 	switch (mgmt->u.action.u.sa_query_req.action) {
3169 	case WLAN_SA_QUERY_REQUEST:
3170 		rx_mgmt_action_sa_query_req(wt, sta, mgmt, len, valid);
3171 		break;
3172 	case WLAN_SA_QUERY_RESPONSE:
3173 		rx_mgmt_action_sa_query_resp(wt, sta, mgmt, len, valid);
3174 		break;
3175 	default:
3176 		add_note(wt, MSG_INFO, "Unexpected SA Query action value %u "
3177 			 "from " MACSTR,
3178 			 mgmt->u.action.u.sa_query_req.action,
3179 			 MAC2STR(mgmt->sa));
3180 	}
3181 }
3182 
3183 
rx_mgmt_action_link_reconfig_request(struct wlantest * wt,struct wlantest_sta * sta,const u8 * pos,const u8 * end)3184 static void rx_mgmt_action_link_reconfig_request(struct wlantest *wt,
3185 						 struct wlantest_sta *sta,
3186 						 const u8 *pos, const u8 *end)
3187 {
3188 	struct ieee802_11_elems elems;
3189 	const u8 *ml;
3190 
3191 	wpa_printf(MSG_DEBUG, "Link Reconfiguration Request");
3192 	if (end - pos < 1 + 3)
3193 		return;
3194 
3195 	wpa_printf(MSG_DEBUG, "Dialog token: %u", *pos);
3196 	pos++;
3197 
3198 	if (pos[0] != WLAN_EID_EXTENSION ||
3199 	    pos[1] < 1 + 2 ||
3200 	    2 + pos[1] > end - pos ||
3201 	    pos[2] != WLAN_EID_EXT_MULTI_LINK ||
3202 	    (WPA_GET_LE16(&pos[3]) & 0x0007) !=
3203 	    MULTI_LINK_CONTROL_TYPE_RECONF) {
3204 		wpa_printf(MSG_INFO,
3205 			   "No valid Reconfiguration Multi-Link element in Link Reconfiguration Request");
3206 		return;
3207 	}
3208 	wpa_hexdump(MSG_MSGDUMP, "Reconfiguration Multi-Link element",
3209 		    pos, 2 + pos[0]);
3210 	ml = get_ml_ie(pos, end - pos, MULTI_LINK_CONTROL_TYPE_RECONF);
3211 	if (ml &&
3212 	    ieee802_11_parse_elems(pos, end - pos, &elems, 0) != ParseFailed) {
3213 		parse_reconfig_ml_elems(&elems, sta);
3214 		dump_mld_info(wt, sta);
3215 	}
3216 }
3217 
3218 
rx_mgmt_action_link_reconfig_response(struct wlantest * wt,struct wlantest_sta * sta,const u8 * pos,const u8 * end)3219 static void rx_mgmt_action_link_reconfig_response(struct wlantest *wt,
3220 						  struct wlantest_sta *sta,
3221 						  const u8 *pos, const u8 *end)
3222 {
3223 	u8 count;
3224 	struct ieee802_11_elems elems;
3225 	const u8 *ml;
3226 
3227 	wpa_printf(MSG_DEBUG, "Link Reconfiguration Response");
3228 	if (end - pos < 1 + 1)
3229 		return;
3230 
3231 	wpa_printf(MSG_DEBUG, "Dialog token: %u", *pos);
3232 	pos++;
3233 
3234 	count = *pos++;
3235 	if (count * 3 > end - pos) {
3236 		wpa_printf(MSG_INFO,
3237 			   "No room for %u Reconfiguration Status List duples in Link Reconfiguraiton Response",
3238 			   count);
3239 		return;
3240 	}
3241 	while (count > 0) {
3242 		count--;
3243 		wpa_printf(MSG_DEBUG, "Link ID %u - Status %u",
3244 			   pos[0] & 0x0f, WPA_GET_LE16(&pos[1]));
3245 		pos += 3;
3246 	}
3247 
3248 	/* Group Key Data (optional) */
3249 	if (end - pos > 1 + 2 + 4 &&
3250 	    end - pos >= 1 + pos[0] &&
3251 	    pos[1] == 0xdd) {
3252 		wpa_hexdump(MSG_MSGDUMP, "Group Key Data KDEs",
3253 			    pos + 1, pos[0]);
3254 		/* TODO: Update group keys in BSS entries */
3255 		pos += 1 + pos[0];
3256 	}
3257 
3258 	/* OCI element (optional) */
3259 	if (end - pos > 3 &&
3260 	    end - pos >= 2 + pos[1] &&
3261 	    pos[0] == WLAN_EID_EXTENSION &&
3262 	    pos[1] >= 1 &&
3263 	    pos[2] == WLAN_EID_EXT_OCV_OCI) {
3264 		wpa_hexdump(MSG_MSGDUMP, "OCI", pos, 2 + pos[1]);
3265 		pos += 2 + pos[1];
3266 	}
3267 
3268 	wpa_hexdump(MSG_MSGDUMP,
3269 		    "Basic Multi-Link element in Link Reconfiguration Response",
3270 		    pos, end - pos);
3271 	ml = get_ml_ie(pos, end - pos, MULTI_LINK_CONTROL_TYPE_BASIC);
3272 	if (ml &&
3273 	    ieee802_11_parse_elems(pos, end - pos, &elems, 0) != ParseFailed)
3274 		parse_basic_ml_elems(&elems, true, NULL, 4);
3275 }
3276 
3277 
rx_mgmt_action_protected_eht(struct wlantest * wt,struct wlantest_sta * sta,const struct ieee80211_mgmt * mgmt,size_t len,int valid)3278 static void rx_mgmt_action_protected_eht(struct wlantest *wt,
3279 					 struct wlantest_sta *sta,
3280 					 const struct ieee80211_mgmt *mgmt,
3281 					 size_t len, int valid)
3282 {
3283 	const u8 *pos, *end;
3284 	u8 action;
3285 
3286 	if (!valid)
3287 		return;
3288 
3289 	pos = (const u8 *) &mgmt->u.action;
3290 	end = ((const u8 *) mgmt) + len;
3291 
3292 	pos++; /* category */
3293 	action = *pos++;
3294 	wpa_printf(MSG_DEBUG, "Protected EHT Action %u from " MACSTR,
3295 		   action, MAC2STR(mgmt->sa));
3296 	wpa_hexdump(MSG_DEBUG, "Protected EHT Action payload", pos, end - pos);
3297 
3298 	switch (action) {
3299 	case WLAN_PROT_EHT_LINK_RECONFIG_REQUEST:
3300 		rx_mgmt_action_link_reconfig_request(wt, sta, pos, end);
3301 		break;
3302 	case WLAN_PROT_EHT_LINK_RECONFIG_RESPONSE:
3303 		rx_mgmt_action_link_reconfig_response(wt, sta, pos, end);
3304 		break;
3305 	default:
3306 		add_note(wt, MSG_INFO,
3307 			 "Unknown Protected EHT Action value %u from " MACSTR,
3308 			 action, MAC2STR(mgmt->sa));
3309 		break;
3310 	}
3311 }
3312 
3313 
3314 static void
rx_mgmt_location_measurement_report(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3315 rx_mgmt_location_measurement_report(struct wlantest *wt,
3316 				    const struct ieee80211_mgmt *mgmt,
3317 				    size_t len, bool no_ack)
3318 {
3319 	const u8 *pos = mgmt->u.action.u.public_action.variable;
3320 	const u8 *end = ((const u8 *) mgmt) + len;
3321 
3322 	if (end - pos < 1) {
3323 		add_note(wt, MSG_INFO,
3324 			 "Too short Location Measurement Report frame from "
3325 			 MACSTR, MAC2STR(mgmt->sa));
3326 		return;
3327 	}
3328 
3329 	wpa_printf(MSG_DEBUG, "Location Measurement Report " MACSTR " --> "
3330 		   MACSTR " (dialog token %u)",
3331 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), *pos);
3332 	pos++;
3333 
3334 	if (!no_ack)
3335 		add_note(wt, MSG_INFO,
3336 			 "Protected Fine Timing Measurement Report incorrectly as an Action frame from "
3337 			 MACSTR, MAC2STR(mgmt->sa));
3338 
3339 	wpa_hexdump(MSG_MSGDUMP, "Location Measurement Report contents",
3340 		    pos, end - pos);
3341 }
3342 
3343 
rx_mgmt_action_no_bss_public(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3344 static void rx_mgmt_action_no_bss_public(struct wlantest *wt,
3345 					 const struct ieee80211_mgmt *mgmt,
3346 					 size_t len, bool no_ack)
3347 {
3348 	switch (mgmt->u.action.u.public_action.action) {
3349 	case WLAN_PA_LOCATION_MEASUREMENT_REPORT:
3350 		rx_mgmt_location_measurement_report(wt, mgmt, len, no_ack);
3351 		break;
3352 	}
3353 }
3354 
3355 
rx_mgmt_prot_ftm_request(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3356 static void rx_mgmt_prot_ftm_request(struct wlantest *wt,
3357 				     const struct ieee80211_mgmt *mgmt,
3358 				     size_t len, bool no_ack)
3359 {
3360 	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement Request "
3361 		   MACSTR " --> " MACSTR,
3362 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
3363 	if (no_ack)
3364 		add_note(wt, MSG_INFO,
3365 			 "Protected Fine Timing Measurement Request incorrectly as an Action No Ack frame from "
3366 			 MACSTR, MAC2STR(mgmt->sa));
3367 }
3368 
3369 
rx_mgmt_prot_ftm(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3370 static void rx_mgmt_prot_ftm(struct wlantest *wt,
3371 			     const struct ieee80211_mgmt *mgmt,
3372 			     size_t len, bool no_ack)
3373 {
3374 	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement "
3375 		   MACSTR " --> " MACSTR,
3376 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
3377 	if (no_ack)
3378 		add_note(wt, MSG_INFO,
3379 			 "Protected Fine Timing Measurement incorrectly as an Action No Ack frame from "
3380 			 MACSTR, MAC2STR(mgmt->sa));
3381 }
3382 
3383 
rx_mgmt_prot_ftm_report(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3384 static void rx_mgmt_prot_ftm_report(struct wlantest *wt,
3385 				     const struct ieee80211_mgmt *mgmt,
3386 				     size_t len, bool no_ack)
3387 {
3388 	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement Report "
3389 		   MACSTR " --> " MACSTR,
3390 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
3391 	if (!no_ack)
3392 		add_note(wt, MSG_INFO,
3393 			 "Protected Fine Timing Measurement Report incorrectly as an Action frame from "
3394 			 MACSTR, MAC2STR(mgmt->sa));
3395 }
3396 
3397 
3398 static void
rx_mgmt_action_no_bss_protected_ftm(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3399 rx_mgmt_action_no_bss_protected_ftm(struct wlantest *wt,
3400 				    const struct ieee80211_mgmt *mgmt,
3401 				    size_t len, bool no_ack)
3402 {
3403 	switch (mgmt->u.action.u.public_action.action) {
3404 	case WLAN_PROT_FTM_REQUEST:
3405 		rx_mgmt_prot_ftm_request(wt, mgmt, len, no_ack);
3406 		break;
3407 	case WLAN_PROT_FTM:
3408 		rx_mgmt_prot_ftm(wt, mgmt, len, no_ack);
3409 		break;
3410 	case WLAN_PROT_FTM_REPORT:
3411 		rx_mgmt_prot_ftm_report(wt, mgmt, len, no_ack);
3412 		break;
3413 	}
3414 }
3415 
3416 
rx_mgmt_action_no_bss(struct wlantest * wt,const struct ieee80211_mgmt * mgmt,size_t len,bool no_ack)3417 static void rx_mgmt_action_no_bss(struct wlantest *wt,
3418 				  const struct ieee80211_mgmt *mgmt, size_t len,
3419 				  bool no_ack)
3420 {
3421 	switch (mgmt->u.action.category) {
3422 	case WLAN_ACTION_PUBLIC:
3423 		rx_mgmt_action_no_bss_public(wt, mgmt, len, no_ack);
3424 		break;
3425 	case WLAN_ACTION_PROTECTED_FTM:
3426 		rx_mgmt_action_no_bss_protected_ftm(wt, mgmt, len, no_ack);
3427 		break;
3428 	}
3429 }
3430 
3431 
rx_mgmt_action(struct wlantest * wt,const u8 * data,size_t len,int valid,bool no_ack)3432 static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
3433 			   int valid, bool no_ack)
3434 {
3435 	const struct ieee80211_mgmt *mgmt;
3436 	struct wlantest_bss *bss;
3437 	struct wlantest_sta *sta;
3438 
3439 	mgmt = (const struct ieee80211_mgmt *) data;
3440 	if (mgmt->da[0] & 0x01) {
3441 		add_note(wt, MSG_DEBUG, "Group addressed Action frame: DA="
3442 			 MACSTR " SA=" MACSTR " BSSID=" MACSTR
3443 			 " category=%u",
3444 			 MAC2STR(mgmt->da), MAC2STR(mgmt->sa),
3445 			 MAC2STR(mgmt->bssid), mgmt->u.action.category);
3446 		return; /* Ignore group addressed Action frames for now */
3447 	}
3448 
3449 	if (len < 24 + 2) {
3450 		add_note(wt, MSG_INFO, "Too short Action frame from " MACSTR,
3451 			 MAC2STR(mgmt->sa));
3452 		return;
3453 	}
3454 
3455 	wpa_printf(MSG_DEBUG, "ACTION%s " MACSTR " -> " MACSTR
3456 		   " BSSID=" MACSTR " (category=%u) (valid=%d)",
3457 		   no_ack ? "-NO-ACK" : "",
3458 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), MAC2STR(mgmt->bssid),
3459 		   mgmt->u.action.category, valid);
3460 	wpa_hexdump(MSG_MSGDUMP, "ACTION payload", data + 24, len - 24);
3461 
3462 	if (is_broadcast_ether_addr(mgmt->bssid)) {
3463 		rx_mgmt_action_no_bss(wt, mgmt, len, no_ack);
3464 		return;
3465 	}
3466 	bss = bss_get(wt, mgmt->bssid);
3467 	if (bss == NULL)
3468 		return;
3469 	if (ether_addr_equal(mgmt->sa, mgmt->bssid)) {
3470 		sta = sta_find_mlo(wt, bss, mgmt->da);
3471 		if (!sta)
3472 			sta = sta_get(bss, mgmt->da);
3473 	} else {
3474 		sta = sta_find_mlo(wt, bss, mgmt->sa);
3475 		if (!sta)
3476 			sta = sta_get(bss, mgmt->sa);
3477 	}
3478 	if (sta == NULL)
3479 		return;
3480 
3481 	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
3482 	    sta->state < STATE3) {
3483 		add_note(wt, MSG_INFO, "Action frame sent when STA is not in "
3484 			 "State 3 (SA=" MACSTR " DATA=" MACSTR ")",
3485 			 MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
3486 	}
3487 
3488 	switch (mgmt->u.action.category) {
3489 	case WLAN_ACTION_FT:
3490 		rx_mgmt_action_ft(wt, sta, mgmt, len, valid);
3491 		break;
3492 	case WLAN_ACTION_SA_QUERY:
3493 		rx_mgmt_action_sa_query(wt, sta, mgmt, len, valid);
3494 		break;
3495 	case WLAN_ACTION_PROTECTED_EHT:
3496 		rx_mgmt_action_protected_eht(wt, sta, mgmt, len, valid);
3497 		break;
3498 	}
3499 }
3500 
3501 
check_mmie_mic(unsigned int mgmt_group_cipher,const u8 * igtk,size_t igtk_len,const u8 * data,size_t len)3502 static int check_mmie_mic(unsigned int mgmt_group_cipher,
3503 			  const u8 *igtk, size_t igtk_len,
3504 			  const u8 *data, size_t len)
3505 {
3506 	u8 *buf;
3507 	u8 mic[16];
3508 	u16 fc;
3509 	const struct ieee80211_hdr *hdr;
3510 	int ret, mic_len;
3511 
3512 	if (!mgmt_group_cipher || igtk_len < 16)
3513 		return -1;
3514 	mic_len = mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;
3515 
3516 	if (len < 24 || len - 24 < mic_len)
3517 		return -1;
3518 
3519 	buf = os_malloc(len + 20 - 24);
3520 	if (buf == NULL)
3521 		return -1;
3522 
3523 	/* BIP AAD: FC(masked) A1 A2 A3 */
3524 	hdr = (const struct ieee80211_hdr *) data;
3525 	fc = le_to_host16(hdr->frame_control);
3526 	fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
3527 	WPA_PUT_LE16(buf, fc);
3528 	os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
3529 
3530 	/* Frame body with MMIE MIC masked to zero */
3531 	os_memcpy(buf + 20, data + 24, len - 24 - mic_len);
3532 	os_memset(buf + 20 + len - 24 - mic_len, 0, mic_len);
3533 
3534 	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) {
3535 		/* Timestamp field masked to zero */
3536 		os_memset(buf + 20, 0, 8);
3537 	}
3538 
3539 	wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
3540 	/* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
3541 	if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
3542 		ret = omac1_aes_128(igtk, buf, len + 20 - 24, mic);
3543 	} else if (mgmt_group_cipher == WPA_CIPHER_BIP_CMAC_256) {
3544 		ret = omac1_aes_256(igtk, buf, len + 20 - 24, mic);
3545 	} else if (mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_128 ||
3546 		 mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_256) {
3547 		u8 nonce[12], *npos;
3548 		const u8 *ipn;
3549 
3550 		ipn = data + len - mic_len - 6;
3551 
3552 		/* Nonce: A2 | IPN */
3553 		os_memcpy(nonce, hdr->addr2, ETH_ALEN);
3554 		npos = nonce + ETH_ALEN;
3555 		*npos++ = ipn[5];
3556 		*npos++ = ipn[4];
3557 		*npos++ = ipn[3];
3558 		*npos++ = ipn[2];
3559 		*npos++ = ipn[1];
3560 		*npos++ = ipn[0];
3561 
3562 		ret = aes_gmac(igtk, igtk_len, nonce, sizeof(nonce),
3563 			       buf, len + 20 - 24, mic);
3564 	} else {
3565 		ret = -1;
3566 	}
3567 	if (ret < 0) {
3568 		os_free(buf);
3569 		return -1;
3570 	}
3571 
3572 	os_free(buf);
3573 
3574 	if (os_memcmp(data + len - mic_len, mic, mic_len) != 0)
3575 		return -1;
3576 
3577 	return 0;
3578 }
3579 
3580 
check_bip(struct wlantest * wt,const u8 * data,size_t len)3581 static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
3582 {
3583 	const struct ieee80211_mgmt *mgmt;
3584 	u16 fc, stype;
3585 	const u8 *mmie;
3586 	u16 keyid;
3587 	struct wlantest_bss *bss;
3588 	size_t mic_len;
3589 	u64 rx_ipn;
3590 
3591 	mgmt = (const struct ieee80211_mgmt *) data;
3592 	fc = le_to_host16(mgmt->frame_control);
3593 	stype = WLAN_FC_GET_STYPE(fc);
3594 
3595 	if (stype == WLAN_FC_STYPE_ACTION ||
3596 	    stype == WLAN_FC_STYPE_ACTION_NO_ACK) {
3597 		if (len < 24 + 1)
3598 			return 0;
3599 		if (mgmt->u.action.category == WLAN_ACTION_PUBLIC)
3600 			return 0; /* Not a robust management frame */
3601 	}
3602 
3603 	bss = bss_get(wt, mgmt->bssid);
3604 	if (bss == NULL)
3605 		return 0; /* No key known yet */
3606 
3607 	mic_len = bss->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;
3608 
3609 	if (len < 24 + 10 + mic_len ||
3610 	    data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
3611 	    data[len - (10 + mic_len - 1)] != 8 + mic_len) {
3612 		/* No MMIE */
3613 		if (bss->rsn_capab & WPA_CAPABILITY_MFPC) {
3614 			add_note(wt, MSG_INFO, "Robust group-addressed "
3615 				 "management frame sent without BIP by "
3616 				 MACSTR, MAC2STR(mgmt->sa));
3617 			bss->counters[WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE]++;
3618 			return -1;
3619 		}
3620 		return 0;
3621 	}
3622 
3623 	mmie = data + len - (8 + mic_len);
3624 	keyid = WPA_GET_LE16(mmie);
3625 	if (keyid & 0xf000) {
3626 		add_note(wt, MSG_INFO, "MMIE KeyID reserved bits not zero "
3627 			 "(%04x) from " MACSTR, keyid, MAC2STR(mgmt->sa));
3628 		keyid &= 0x0fff;
3629 	}
3630 	if (keyid < 4 || keyid > 5) {
3631 		add_note(wt, MSG_INFO, "Unexpected MMIE KeyID %u from " MACSTR,
3632 			 keyid, MAC2STR(mgmt->sa));
3633 		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
3634 		return 0;
3635 	}
3636 
3637 	rx_ipn = WPA_GET_LE48(mmie + 2);
3638 	wpa_printf(MSG_DEBUG, "MME KeyID %u IPN 0x%llx", keyid,
3639 		   (long long unsigned int) rx_ipn);
3640 	wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, mic_len);
3641 
3642 	if (!bss->igtk_len[keyid]) {
3643 		add_note(wt, MSG_DEBUG, "No IGTK known to validate BIP frame");
3644 		return 0;
3645 	}
3646 
3647 	if (rx_ipn <= bss->ipn[keyid]) {
3648 		add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR
3649 			 " RX IPN 0x%llx <= 0x%llx",
3650 			 MAC2STR(mgmt->sa), (long long unsigned int) rx_ipn,
3651 			 (long long unsigned int) bss->ipn[keyid]);
3652 	}
3653 
3654 	if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
3655 			   bss->igtk_len[keyid], data, len) < 0) {
3656 		add_note(wt, MSG_INFO, "Invalid MMIE MIC in a frame from "
3657 			 MACSTR, MAC2STR(mgmt->sa));
3658 		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
3659 		return -1;
3660 	}
3661 
3662 	add_note(wt, MSG_DEBUG, "Valid MMIE MIC");
3663 	bss->ipn[keyid] = rx_ipn;
3664 	bss->counters[WLANTEST_BSS_COUNTER_VALID_BIP_MMIE]++;
3665 
3666 	if (stype == WLAN_FC_STYPE_DEAUTH)
3667 		bss->counters[WLANTEST_BSS_COUNTER_BIP_DEAUTH]++;
3668 	else if (stype == WLAN_FC_STYPE_DISASSOC)
3669 		bss->counters[WLANTEST_BSS_COUNTER_BIP_DISASSOC]++;
3670 
3671 	return 0;
3672 }
3673 
3674 
try_tk(struct wpa_ptk * ptk,const u8 * data,size_t len,size_t * dlen)3675 static u8 * try_tk(struct wpa_ptk *ptk,
3676 		   const u8 *data, size_t len, size_t *dlen)
3677 {
3678 	const struct ieee80211_hdr *hdr;
3679 	u8 *decrypted, *frame;
3680 
3681 	hdr = (const struct ieee80211_hdr *) data;
3682 	if (ptk->tk_len == 16) {
3683 		decrypted = ccmp_decrypt(ptk->tk, hdr, NULL, NULL, NULL,
3684 					 data + 24, len - 24, dlen);
3685 		if (!decrypted)
3686 			decrypted = gcmp_decrypt(ptk->tk, 16, hdr, NULL, NULL,
3687 						 NULL,
3688 						 data + 24, len - 24, dlen);
3689 	} else if (ptk->tk_len == 32) {
3690 		decrypted = ccmp_256_decrypt(ptk->tk, hdr, NULL, NULL, NULL,
3691 					     data + 24, len - 24, dlen);
3692 		if (!decrypted)
3693 			decrypted = gcmp_decrypt(ptk->tk, 32, hdr, NULL, NULL,
3694 						 NULL,
3695 						 data + 24, len - 24, dlen);
3696 	} else {
3697 		decrypted = NULL;
3698 	}
3699 	if (!decrypted)
3700 		return NULL;
3701 
3702 	frame = os_malloc(24 + *dlen);
3703 	if (frame) {
3704 		os_memcpy(frame, data, 24);
3705 		os_memcpy(frame + 24, decrypted, *dlen);
3706 		*dlen += 24;
3707 	}
3708 	os_free(decrypted);
3709 	return frame;
3710 }
3711 
3712 
mgmt_decrypt_tk(struct wlantest * wt,const u8 * data,size_t len,size_t * dlen)3713 static u8 * mgmt_decrypt_tk(struct wlantest *wt, const u8 *data, size_t len,
3714 			    size_t *dlen)
3715 {
3716 	struct wlantest_ptk *ptk;
3717 	u8 *decrypted;
3718 	int prev_level = wpa_debug_level;
3719 	int keyid;
3720 
3721 	keyid = data[24 + 3] >> 6;
3722 
3723 	wpa_debug_level = MSG_WARNING;
3724 	dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
3725 		decrypted = try_tk(&ptk->ptk, data, len, dlen);
3726 		if (decrypted) {
3727 			wpa_debug_level = prev_level;
3728 			add_note(wt, MSG_DEBUG,
3729 				 "Found TK match from the list of all known TKs");
3730 			write_decrypted_note(wt, decrypted, ptk->ptk.tk,
3731 					     ptk->ptk.tk_len, keyid);
3732 			return decrypted;
3733 		}
3734 	}
3735 	wpa_debug_level = prev_level;
3736 
3737 	return NULL;
3738 }
3739 
3740 
mgmt_decrypt(struct wlantest * wt,const u8 * data,size_t len,size_t * dlen)3741 static u8 * mgmt_decrypt(struct wlantest *wt, const u8 *data, size_t len,
3742 			 size_t *dlen)
3743 {
3744 	struct wlantest_bss *bss;
3745 	struct wlantest_sta *sta;
3746 	const struct ieee80211_hdr *hdr;
3747 	int keyid;
3748 	u8 *decrypted, *frame = NULL;
3749 	u8 pn[6], *rsc;
3750 	u16 fc;
3751 	u8 mask;
3752 	size_t hdrlen = 24;
3753 
3754 	hdr = (const struct ieee80211_hdr *) data;
3755 	fc = le_to_host16(hdr->frame_control);
3756 
3757 	if (fc & WLAN_FC_HTC)
3758 		hdrlen += 4; /* HT Control field */
3759 
3760 	if (len < hdrlen + 4)
3761 		return NULL;
3762 
3763 	if (!(data[hdrlen + 3] & 0x20)) {
3764 		add_note(wt, MSG_INFO, "Expected CCMP/GCMP frame from " MACSTR
3765 			 " did not have ExtIV bit set to 1",
3766 			 MAC2STR(hdr->addr2));
3767 		return NULL;
3768 	}
3769 
3770 	mask = 0x1f;
3771 	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
3772 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK)
3773 		mask &= ~0x10; /* FTM */
3774 	if (data[hdrlen + 2] != 0 || (data[hdrlen + 3] & mask) != 0) {
3775 		add_note(wt, MSG_INFO, "CCMP/GCMP mgmt frame from " MACSTR
3776 			 " used non-zero reserved bit", MAC2STR(hdr->addr2));
3777 	}
3778 
3779 	keyid = data[hdrlen + 3] >> 6;
3780 	if (keyid != 0) {
3781 		add_note(wt, MSG_INFO, "Unexpected non-zero KeyID %d in "
3782 			 "individually addressed Management frame from "
3783 			 MACSTR, keyid, MAC2STR(hdr->addr2));
3784 	}
3785 
3786 	bss = bss_get(wt, hdr->addr3);
3787 	if (bss == NULL)
3788 		return mgmt_decrypt_tk(wt, data, len, dlen);
3789 	if (ether_addr_equal(hdr->addr1, hdr->addr3)) {
3790 		sta = sta_find_mlo(wt, bss, hdr->addr2);
3791 		if (!sta)
3792 			sta = sta_get(bss, hdr->addr2);
3793 	} else {
3794 		sta = sta_find_mlo(wt, bss, hdr->addr1);
3795 		if (!sta)
3796 			sta = sta_get(bss, hdr->addr1);
3797 	}
3798 	if (sta == NULL || !sta->ptk_set) {
3799 		decrypted = mgmt_decrypt_tk(wt, data, len, dlen);
3800 		if (!decrypted)
3801 			add_note(wt, MSG_MSGDUMP,
3802 				 "No PTK known to decrypt the frame");
3803 		return decrypted;
3804 	}
3805 
3806 	if (ether_addr_equal(hdr->addr1, hdr->addr3))
3807 		rsc = sta->rsc_tods[16];
3808 	else
3809 		rsc = sta->rsc_fromds[16];
3810 
3811 	ccmp_get_pn(pn, data + hdrlen);
3812 	if (os_memcmp(pn, rsc, 6) <= 0) {
3813 		u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
3814 		add_note(wt, MSG_INFO, "replay detected: A1=" MACSTR
3815 			 " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s",
3816 			 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
3817 			 MAC2STR(hdr->addr3),
3818 			 WLAN_GET_SEQ_SEQ(seq_ctrl),
3819 			 WLAN_GET_SEQ_FRAG(seq_ctrl),
3820 			 (le_to_host16(hdr->frame_control) & WLAN_FC_RETRY) ?
3821 			 " Retry" : "");
3822 		wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
3823 		wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
3824 	}
3825 
3826 	if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256) {
3827 		decrypted = ccmp_256_decrypt(sta->ptk.tk, hdr, NULL, NULL, NULL,
3828 					     data + hdrlen, len - hdrlen, dlen);
3829 		write_decrypted_note(wt, decrypted, sta->ptk.tk, 32, keyid);
3830 	} else if (sta->pairwise_cipher == WPA_CIPHER_GCMP ||
3831 		   sta->pairwise_cipher == WPA_CIPHER_GCMP_256) {
3832 		decrypted = gcmp_decrypt(sta->ptk.tk, sta->ptk.tk_len, hdr,
3833 					 NULL, NULL, NULL,
3834 					 data + hdrlen, len - hdrlen, dlen);
3835 		write_decrypted_note(wt, decrypted, sta->ptk.tk,
3836 				     sta->ptk.tk_len, keyid);
3837 	} else {
3838 		decrypted = ccmp_decrypt(sta->ptk.tk, hdr, NULL, NULL, NULL,
3839 					 data + hdrlen, len - hdrlen, dlen);
3840 		write_decrypted_note(wt, decrypted, sta->ptk.tk, 16, keyid);
3841 	}
3842 	if (decrypted) {
3843 		os_memcpy(rsc, pn, 6);
3844 		frame = os_malloc(hdrlen + *dlen);
3845 		if (frame) {
3846 			os_memcpy(frame, data, hdrlen);
3847 			os_memcpy(frame + hdrlen, decrypted, *dlen);
3848 			*dlen += hdrlen;
3849 		}
3850 	} else {
3851 		/* Assume the frame was corrupted and there was no FCS to check.
3852 		 * Allow retry of this particular frame to be processed so that
3853 		 * it could end up getting decrypted if it was received without
3854 		 * corruption. */
3855 		sta->allow_duplicate = 1;
3856 	}
3857 
3858 	os_free(decrypted);
3859 
3860 	return frame;
3861 }
3862 
3863 
is_robust_action_category(u8 category)3864 static bool is_robust_action_category(u8 category)
3865 {
3866 	return category != WLAN_ACTION_PUBLIC &&
3867 		category != WLAN_ACTION_HT &&
3868 		category != WLAN_ACTION_UNPROTECTED_WNM &&
3869 		category != WLAN_ACTION_SELF_PROTECTED &&
3870 		category != WLAN_ACTION_UNPROTECTED_DMG &&
3871 		category != WLAN_ACTION_VHT &&
3872 		category != WLAN_ACTION_UNPROTECTED_S1G &&
3873 		category != WLAN_ACTION_HE &&
3874 		category != WLAN_ACTION_EHT &&
3875 		category != WLAN_ACTION_VENDOR_SPECIFIC;
3876 }
3877 
3878 
check_mgmt_ccmp_gcmp(struct wlantest * wt,const u8 * data,size_t len)3879 static int check_mgmt_ccmp_gcmp(struct wlantest *wt, const u8 *data, size_t len)
3880 {
3881 	const struct ieee80211_mgmt *mgmt;
3882 	u16 fc;
3883 	struct wlantest_bss *bss;
3884 	struct wlantest_sta *sta;
3885 	int category = -1;
3886 
3887 	mgmt = (const struct ieee80211_mgmt *) data;
3888 	fc = le_to_host16(mgmt->frame_control);
3889 
3890 	if ((WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
3891 	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK) &&
3892 	    len > 24) {
3893 		category = mgmt->u.action.category;
3894 		if (!is_robust_action_category(category))
3895 			return 0; /* Not a robust management frame */
3896 	}
3897 
3898 	bss = bss_get(wt, mgmt->bssid);
3899 	if (bss == NULL)
3900 		return 0;
3901 	if (ether_addr_equal(mgmt->da, mgmt->bssid))
3902 		sta = sta_get(bss, mgmt->sa);
3903 	else
3904 		sta = sta_get(bss, mgmt->da);
3905 	if (sta == NULL)
3906 		return 0;
3907 
3908 	if ((bss->rsn_capab & WPA_CAPABILITY_MFPC) &&
3909 	    (sta->rsn_capab & WPA_CAPABILITY_MFPC) &&
3910 	    (sta->state == STATE3 ||
3911 	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
3912 	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK)) {
3913 		add_note(wt, MSG_INFO,
3914 			 "Robust individually-addressed management frame (stype=%u category=%d) sent without CCMP/GCMP by "
3915 			 MACSTR, WLAN_FC_GET_STYPE(fc), category,
3916 			 MAC2STR(mgmt->sa));
3917 		return -1;
3918 	}
3919 
3920 	return 0;
3921 }
3922 
3923 
rx_mgmt(struct wlantest * wt,const u8 * data,size_t len)3924 void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
3925 {
3926 	const struct ieee80211_hdr *hdr;
3927 	u16 fc, stype;
3928 	int valid = 1;
3929 	u8 *decrypted = NULL;
3930 	size_t dlen;
3931 
3932 	if (len < 24)
3933 		return;
3934 
3935 	hdr = (const struct ieee80211_hdr *) data;
3936 	fc = le_to_host16(hdr->frame_control);
3937 	wt->rx_mgmt++;
3938 	stype = WLAN_FC_GET_STYPE(fc);
3939 
3940 	if ((hdr->addr1[0] & 0x01) &&
3941 	    (stype == WLAN_FC_STYPE_DEAUTH ||
3942 	     stype == WLAN_FC_STYPE_DISASSOC ||
3943 	     stype == WLAN_FC_STYPE_ACTION ||
3944 	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
3945 		if (check_bip(wt, data, len) < 0)
3946 			valid = 0;
3947 	}
3948 
3949 	wpa_printf((stype == WLAN_FC_STYPE_BEACON ||
3950 		    stype == WLAN_FC_STYPE_PROBE_RESP ||
3951 		    stype == WLAN_FC_STYPE_PROBE_REQ) ?
3952 		   MSG_EXCESSIVE : MSG_MSGDUMP,
3953 		   "MGMT %s%s%s DA=" MACSTR " SA=" MACSTR " BSSID=" MACSTR,
3954 		   mgmt_stype(stype),
3955 		   fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
3956 		   fc & WLAN_FC_ISWEP ? " Prot" : "",
3957 		   MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
3958 		   MAC2STR(hdr->addr3));
3959 
3960 	if ((fc & WLAN_FC_ISWEP) &&
3961 	    !(hdr->addr1[0] & 0x01) &&
3962 	    (stype == WLAN_FC_STYPE_DEAUTH ||
3963 	     stype == WLAN_FC_STYPE_DISASSOC ||
3964 	     stype == WLAN_FC_STYPE_ACTION ||
3965 	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
3966 		decrypted = mgmt_decrypt(wt, data, len, &dlen);
3967 		if (decrypted) {
3968 			write_pcap_decrypted(wt, decrypted, dlen, NULL, 0);
3969 			data = decrypted;
3970 			len = dlen;
3971 		} else
3972 			valid = 0;
3973 	}
3974 
3975 	if (!(fc & WLAN_FC_ISWEP) &&
3976 	    !(hdr->addr1[0] & 0x01) &&
3977 	    (stype == WLAN_FC_STYPE_DEAUTH ||
3978 	     stype == WLAN_FC_STYPE_DISASSOC ||
3979 	     stype == WLAN_FC_STYPE_ACTION ||
3980 	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
3981 		if (check_mgmt_ccmp_gcmp(wt, data, len) < 0)
3982 			valid = 0;
3983 	}
3984 
3985 	switch (stype) {
3986 	case WLAN_FC_STYPE_BEACON:
3987 		rx_mgmt_beacon(wt, data, len);
3988 		break;
3989 	case WLAN_FC_STYPE_PROBE_RESP:
3990 		rx_mgmt_probe_resp(wt, data, len);
3991 		break;
3992 	case WLAN_FC_STYPE_AUTH:
3993 		rx_mgmt_auth(wt, data, len);
3994 		break;
3995 	case WLAN_FC_STYPE_DEAUTH:
3996 		rx_mgmt_deauth(wt, data, len, valid);
3997 		break;
3998 	case WLAN_FC_STYPE_ASSOC_REQ:
3999 		rx_mgmt_assoc_req(wt, data, len);
4000 		break;
4001 	case WLAN_FC_STYPE_ASSOC_RESP:
4002 		rx_mgmt_assoc_resp(wt, data, len);
4003 		break;
4004 	case WLAN_FC_STYPE_REASSOC_REQ:
4005 		rx_mgmt_reassoc_req(wt, data, len);
4006 		break;
4007 	case WLAN_FC_STYPE_REASSOC_RESP:
4008 		rx_mgmt_reassoc_resp(wt, data, len);
4009 		break;
4010 	case WLAN_FC_STYPE_DISASSOC:
4011 		rx_mgmt_disassoc(wt, data, len, valid);
4012 		break;
4013 	case WLAN_FC_STYPE_ACTION:
4014 		rx_mgmt_action(wt, data, len, valid, false);
4015 		break;
4016 	case WLAN_FC_STYPE_ACTION_NO_ACK:
4017 		rx_mgmt_action(wt, data, len, valid, true);
4018 		break;
4019 	}
4020 
4021 	os_free(decrypted);
4022 
4023 	wt->last_mgmt_valid = valid;
4024 }
4025 
4026 
rx_mgmt_deauth_ack(struct wlantest * wt,const struct ieee80211_hdr * hdr)4027 static void rx_mgmt_deauth_ack(struct wlantest *wt,
4028 			       const struct ieee80211_hdr *hdr)
4029 {
4030 	const struct ieee80211_mgmt *mgmt;
4031 	struct wlantest_bss *bss;
4032 	struct wlantest_sta *sta;
4033 
4034 	mgmt = (const struct ieee80211_mgmt *) hdr;
4035 	bss = bss_get(wt, mgmt->bssid);
4036 	if (bss == NULL)
4037 		return;
4038 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
4039 		sta = sta_get(bss, mgmt->da);
4040 	else
4041 		sta = sta_get(bss, mgmt->sa);
4042 	if (sta == NULL)
4043 		return;
4044 
4045 	add_note(wt, MSG_DEBUG, "DEAUTH from " MACSTR " acknowledged by "
4046 		 MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
4047 	if (ether_addr_equal(mgmt->sa, mgmt->bssid)) {
4048 		int c;
4049 		c = wt->last_mgmt_valid ?
4050 			WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK :
4051 			WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK;
4052 		sta->counters[c]++;
4053 	}
4054 }
4055 
4056 
rx_mgmt_disassoc_ack(struct wlantest * wt,const struct ieee80211_hdr * hdr)4057 static void rx_mgmt_disassoc_ack(struct wlantest *wt,
4058 				 const struct ieee80211_hdr *hdr)
4059 {
4060 	const struct ieee80211_mgmt *mgmt;
4061 	struct wlantest_bss *bss;
4062 	struct wlantest_sta *sta;
4063 
4064 	mgmt = (const struct ieee80211_mgmt *) hdr;
4065 	bss = bss_get(wt, mgmt->bssid);
4066 	if (bss == NULL)
4067 		return;
4068 	if (ether_addr_equal(mgmt->sa, mgmt->bssid))
4069 		sta = sta_get(bss, mgmt->da);
4070 	else
4071 		sta = sta_get(bss, mgmt->sa);
4072 	if (sta == NULL)
4073 		return;
4074 
4075 	add_note(wt, MSG_DEBUG, "DISASSOC from " MACSTR " acknowledged by "
4076 		 MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
4077 	if (ether_addr_equal(mgmt->sa, mgmt->bssid)) {
4078 		int c;
4079 		c = wt->last_mgmt_valid ?
4080 			WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK :
4081 			WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK;
4082 		sta->counters[c]++;
4083 	}
4084 }
4085 
4086 
rx_mgmt_ack(struct wlantest * wt,const struct ieee80211_hdr * hdr)4087 void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
4088 {
4089 	u16 fc, stype;
4090 	fc = le_to_host16(hdr->frame_control);
4091 	stype = WLAN_FC_GET_STYPE(fc);
4092 
4093 	wpa_printf(MSG_MSGDUMP, "MGMT ACK: stype=%u a1=" MACSTR " a2=" MACSTR
4094 		   " a3=" MACSTR,
4095 		   stype, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
4096 		   MAC2STR(hdr->addr3));
4097 
4098 	switch (stype) {
4099 	case WLAN_FC_STYPE_DEAUTH:
4100 		rx_mgmt_deauth_ack(wt, hdr);
4101 		break;
4102 	case WLAN_FC_STYPE_DISASSOC:
4103 		rx_mgmt_disassoc_ack(wt, hdr);
4104 		break;
4105 	}
4106 }
4107