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