• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant - TDLS
3  * Copyright (c) 2010-2011, Atheros Communications
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 "utils/eloop.h"
13 #include "utils/os.h"
14 #include "common/ieee802_11_defs.h"
15 #include "common/ieee802_11_common.h"
16 #include "crypto/sha256.h"
17 #include "crypto/crypto.h"
18 #include "crypto/aes_wrap.h"
19 #include "rsn_supp/wpa.h"
20 #include "rsn_supp/wpa_ie.h"
21 #include "rsn_supp/wpa_i.h"
22 #include "drivers/driver.h"
23 #include "l2_packet/l2_packet.h"
24 
25 #ifdef CONFIG_TDLS_TESTING
26 #define TDLS_TESTING_LONG_FRAME BIT(0)
27 #define TDLS_TESTING_ALT_RSN_IE BIT(1)
28 #define TDLS_TESTING_DIFF_BSSID BIT(2)
29 #define TDLS_TESTING_SHORT_LIFETIME BIT(3)
30 #define TDLS_TESTING_WRONG_LIFETIME_RESP BIT(4)
31 #define TDLS_TESTING_WRONG_LIFETIME_CONF BIT(5)
32 #define TDLS_TESTING_LONG_LIFETIME BIT(6)
33 #define TDLS_TESTING_CONCURRENT_INIT BIT(7)
34 #define TDLS_TESTING_NO_TPK_EXPIRATION BIT(8)
35 #define TDLS_TESTING_DECLINE_RESP BIT(9)
36 #define TDLS_TESTING_IGNORE_AP_PROHIBIT BIT(10)
37 #define TDLS_TESTING_WRONG_MIC BIT(11)
38 #define TDLS_TESTING_DOUBLE_TPK_M2 BIT(12)
39 unsigned int tdls_testing = 0;
40 #endif /* CONFIG_TDLS_TESTING */
41 
42 #define TPK_LIFETIME 43200 /* 12 hours */
43 #define TPK_M1_RETRY_COUNT 3
44 #define TPK_M1_TIMEOUT 5000 /* in milliseconds */
45 #define TPK_M2_RETRY_COUNT 10
46 #define TPK_M2_TIMEOUT 500 /* in milliseconds */
47 
48 #define TDLS_MIC_LEN		16
49 
50 #define TDLS_TIMEOUT_LEN	4
51 
52 struct wpa_tdls_ftie {
53 	u8 ie_type; /* FTIE */
54 	u8 ie_len;
55 	u8 mic_ctrl[2];
56 	u8 mic[TDLS_MIC_LEN];
57 	u8 Anonce[WPA_NONCE_LEN]; /* Responder Nonce in TDLS */
58 	u8 Snonce[WPA_NONCE_LEN]; /* Initiator Nonce in TDLS */
59 	/* followed by optional elements */
60 } STRUCT_PACKED;
61 
62 struct wpa_tdls_timeoutie {
63 	u8 ie_type; /* Timeout IE */
64 	u8 ie_len;
65 	u8 interval_type;
66 	u8 value[TDLS_TIMEOUT_LEN];
67 } STRUCT_PACKED;
68 
69 struct wpa_tdls_lnkid {
70 	u8 ie_type; /* Link Identifier IE */
71 	u8 ie_len;
72 	u8 bssid[ETH_ALEN];
73 	u8 init_sta[ETH_ALEN];
74 	u8 resp_sta[ETH_ALEN];
75 } STRUCT_PACKED;
76 
77 /* TDLS frame headers as per IEEE Std 802.11z-2010 */
78 struct wpa_tdls_frame {
79 	u8 payloadtype; /* IEEE80211_TDLS_RFTYPE */
80 	u8 category; /* Category */
81 	u8 action; /* Action (enum tdls_frame_type) */
82 } STRUCT_PACKED;
83 
84 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
85 static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx);
86 static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
87 static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
88 				       struct wpa_tdls_peer *peer);
89 static int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr,
90 				  u16 reason_code);
91 
92 
93 #define TDLS_MAX_IE_LEN 80
94 #define IEEE80211_MAX_SUPP_RATES 32
95 
96 struct wpa_tdls_peer {
97 	struct wpa_tdls_peer *next;
98 	unsigned int reconfig_key:1;
99 	int initiator; /* whether this end was initiator for TDLS setup */
100 	u8 addr[ETH_ALEN]; /* other end MAC address */
101 	u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
102 	u8 rnonce[WPA_NONCE_LEN]; /* Responder Nonce */
103 	u8 rsnie_i[TDLS_MAX_IE_LEN]; /* Initiator RSN IE */
104 	size_t rsnie_i_len;
105 	u8 rsnie_p[TDLS_MAX_IE_LEN]; /* Peer RSN IE */
106 	size_t rsnie_p_len;
107 	u32 lifetime;
108 	int cipher; /* Selected cipher (WPA_CIPHER_*) */
109 	u8 dtoken;
110 
111 	struct tpk {
112 		u8 kck[16]; /* TPK-KCK */
113 		u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
114 	} tpk;
115 	int tpk_set;
116 	int tk_set; /* TPK-TK configured to the driver */
117 	int tpk_success;
118 	int tpk_in_progress;
119 
120 	struct tpk_timer {
121 		u8 dest[ETH_ALEN];
122 		int count;      /* Retry Count */
123 		int timer;      /* Timeout in milliseconds */
124 		u8 action_code; /* TDLS frame type */
125 		u8 dialog_token;
126 		u16 status_code;
127 		u32 peer_capab;
128 		int buf_len;    /* length of TPK message for retransmission */
129 		u8 *buf;        /* buffer for TPK message */
130 	} sm_tmr;
131 
132 	u16 capability;
133 
134 	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
135 	size_t supp_rates_len;
136 
137 	struct ieee80211_ht_capabilities *ht_capabilities;
138 	struct ieee80211_vht_capabilities *vht_capabilities;
139 	struct ieee80211_he_capabilities *he_capabilities;
140 	size_t he_capab_len;
141 	struct ieee80211_he_6ghz_band_cap *he_6ghz_band_capabilities;
142 
143 	u8 qos_info;
144 
145 	u16 aid;
146 
147 	u8 *ext_capab;
148 	size_t ext_capab_len;
149 
150 	u8 *supp_channels;
151 	size_t supp_channels_len;
152 
153 	u8 *supp_oper_classes;
154 	size_t supp_oper_classes_len;
155 
156 	u8 wmm_capable;
157 
158 	/* channel switch currently enabled */
159 	int chan_switch_enabled;
160 };
161 
162 
wpa_tdls_get_privacy(struct wpa_sm * sm)163 static int wpa_tdls_get_privacy(struct wpa_sm *sm)
164 {
165 	/*
166 	 * Get info needed from supplicant to check if the current BSS supports
167 	 * security. Other than OPEN mode, rest are considered secured
168 	 * WEP/WPA/WPA2 hence TDLS frames are processed for TPK handshake.
169 	 */
170 	return sm->pairwise_cipher != WPA_CIPHER_NONE;
171 }
172 
173 
wpa_add_ie(u8 * pos,const u8 * ie,size_t ie_len)174 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
175 {
176 	os_memcpy(pos, ie, ie_len);
177 	return pos + ie_len;
178 }
179 
180 
wpa_tdls_del_key(struct wpa_sm * sm,struct wpa_tdls_peer * peer)181 static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
182 {
183 	if (wpa_sm_set_key(sm, -1, WPA_ALG_NONE, peer->addr,
184 			   0, 0, NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE) < 0) {
185 		wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from "
186 			   "the driver");
187 		return -1;
188 	}
189 
190 	return 0;
191 }
192 
193 
wpa_tdls_set_key(struct wpa_sm * sm,struct wpa_tdls_peer * peer)194 static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
195 {
196 	u8 key_len;
197 	u8 rsc[6];
198 	enum wpa_alg alg;
199 
200 	if (peer->tk_set) {
201 		/*
202 		 * This same TPK-TK has already been configured to the driver
203 		 * and this new configuration attempt (likely due to an
204 		 * unexpected retransmitted frame) would result in clearing
205 		 * the TX/RX sequence number which can break security, so must
206 		 * not allow that to happen.
207 		 */
208 		wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR
209 			   " has already been configured to the driver - do not reconfigure",
210 			   MAC2STR(peer->addr));
211 		return -1;
212 	}
213 
214 	os_memset(rsc, 0, 6);
215 
216 	switch (peer->cipher) {
217 	case WPA_CIPHER_CCMP:
218 		alg = WPA_ALG_CCMP;
219 		key_len = 16;
220 		break;
221 	case WPA_CIPHER_NONE:
222 		wpa_printf(MSG_DEBUG, "TDLS: Pairwise Cipher Suite: "
223 			   "NONE - do not use pairwise keys");
224 		return -1;
225 	default:
226 		wpa_printf(MSG_WARNING, "TDLS: Unsupported pairwise cipher %d",
227 			   sm->pairwise_cipher);
228 		return -1;
229 	}
230 
231 	wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
232 		   MAC2STR(peer->addr));
233 	if (wpa_sm_set_key(sm, -1, alg, peer->addr, 0, 1, rsc, sizeof(rsc),
234 			   peer->tpk.tk, key_len,
235 			   KEY_FLAG_PAIRWISE_RX_TX) < 0) {
236 		wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
237 			   "driver");
238 		return -1;
239 	}
240 	peer->tk_set = 1;
241 	return 0;
242 }
243 
244 
wpa_tdls_send_tpk_msg(struct wpa_sm * sm,const u8 * dst,u8 action_code,u8 dialog_token,u16 status_code,u32 peer_capab,int initiator,const u8 * buf,size_t len)245 static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
246 				 u8 action_code, u8 dialog_token,
247 				 u16 status_code, u32 peer_capab,
248 				 int initiator, const u8 *buf, size_t len)
249 {
250 	return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
251 				     status_code, peer_capab, initiator, buf,
252 				     len);
253 }
254 
255 
wpa_tdls_tpk_send(struct wpa_sm * sm,const u8 * dest,u8 action_code,u8 dialog_token,u16 status_code,u32 peer_capab,int initiator,const u8 * msg,size_t msg_len)256 static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
257 			     u8 dialog_token, u16 status_code, u32 peer_capab,
258 			     int initiator, const u8 *msg, size_t msg_len)
259 {
260 	struct wpa_tdls_peer *peer;
261 
262 	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
263 		   "dialog_token=%u status_code=%u peer_capab=%u initiator=%d "
264 		   "msg_len=%u",
265 		   MAC2STR(dest), action_code, dialog_token, status_code,
266 		   peer_capab, initiator, (unsigned int) msg_len);
267 
268 	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
269 				  status_code, peer_capab, initiator, msg,
270 				  msg_len)) {
271 		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
272 			   "(action_code=%u)", action_code);
273 		return -1;
274 	}
275 
276 	if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
277 	    action_code == WLAN_TDLS_TEARDOWN ||
278 	    action_code == WLAN_TDLS_DISCOVERY_REQUEST ||
279 	    action_code == WLAN_TDLS_DISCOVERY_RESPONSE)
280 		return 0; /* No retries */
281 
282 	for (peer = sm->tdls; peer; peer = peer->next) {
283 		if (os_memcmp(peer->addr, dest, ETH_ALEN) == 0)
284 			break;
285 	}
286 
287 	if (peer == NULL) {
288 		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
289 			   "retry " MACSTR, MAC2STR(dest));
290 		return 0;
291 	}
292 
293 	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
294 
295 	if (action_code == WLAN_TDLS_SETUP_RESPONSE) {
296 		peer->sm_tmr.count = TPK_M2_RETRY_COUNT;
297 		peer->sm_tmr.timer = TPK_M2_TIMEOUT;
298 	} else {
299 		peer->sm_tmr.count = TPK_M1_RETRY_COUNT;
300 		peer->sm_tmr.timer = TPK_M1_TIMEOUT;
301 	}
302 
303 	/* Copy message to resend on timeout */
304 	os_memcpy(peer->sm_tmr.dest, dest, ETH_ALEN);
305 	peer->sm_tmr.action_code = action_code;
306 	peer->sm_tmr.dialog_token = dialog_token;
307 	peer->sm_tmr.status_code = status_code;
308 	peer->sm_tmr.peer_capab = peer_capab;
309 	peer->sm_tmr.buf_len = msg_len;
310 	os_free(peer->sm_tmr.buf);
311 	peer->sm_tmr.buf = os_memdup(msg, msg_len);
312 	if (peer->sm_tmr.buf == NULL)
313 		return -1;
314 
315 	wpa_printf(MSG_DEBUG, "TDLS: Retry timeout registered "
316 		   "(action_code=%u)", action_code);
317 	eloop_register_timeout(peer->sm_tmr.timer / 1000,
318 			       (peer->sm_tmr.timer % 1000) * 1000,
319 			       wpa_tdls_tpk_retry_timeout, sm, peer);
320 	return 0;
321 }
322 
323 
wpa_tdls_do_teardown(struct wpa_sm * sm,struct wpa_tdls_peer * peer,u16 reason_code)324 static int wpa_tdls_do_teardown(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
325 				u16 reason_code)
326 {
327 	int ret;
328 
329 	ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code);
330 	/* disable the link after teardown was sent */
331 	wpa_tdls_disable_peer_link(sm, peer);
332 
333 	return ret;
334 }
335 
336 
wpa_tdls_tpk_retry_timeout(void * eloop_ctx,void * timeout_ctx)337 static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx)
338 {
339 
340 	struct wpa_sm *sm = eloop_ctx;
341 	struct wpa_tdls_peer *peer = timeout_ctx;
342 
343 	if (peer->sm_tmr.count) {
344 		peer->sm_tmr.count--;
345 
346 		wpa_printf(MSG_INFO, "TDLS: Retrying sending of message "
347 			   "(action_code=%u)",
348 			   peer->sm_tmr.action_code);
349 
350 		if (peer->sm_tmr.buf == NULL) {
351 			wpa_printf(MSG_INFO, "TDLS: No retry buffer available "
352 				   "for action_code=%u",
353 				   peer->sm_tmr.action_code);
354 			eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm,
355 					     peer);
356 			return;
357 		}
358 
359 		/* resend TPK Handshake Message to Peer */
360 		if (wpa_tdls_send_tpk_msg(sm, peer->sm_tmr.dest,
361 					  peer->sm_tmr.action_code,
362 					  peer->sm_tmr.dialog_token,
363 					  peer->sm_tmr.status_code,
364 					  peer->sm_tmr.peer_capab,
365 					  peer->initiator,
366 					  peer->sm_tmr.buf,
367 					  peer->sm_tmr.buf_len)) {
368 			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
369 				   "transmission");
370 		}
371 
372 		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
373 		eloop_register_timeout(peer->sm_tmr.timer / 1000,
374 				       (peer->sm_tmr.timer % 1000) * 1000,
375 				       wpa_tdls_tpk_retry_timeout, sm, peer);
376 	} else {
377 		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
378 
379 		wpa_printf(MSG_DEBUG, "TDLS: Sending Teardown Request");
380 		wpa_tdls_do_teardown(sm, peer,
381 				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
382 	}
383 }
384 
385 
wpa_tdls_tpk_retry_timeout_cancel(struct wpa_sm * sm,struct wpa_tdls_peer * peer,u8 action_code)386 static void wpa_tdls_tpk_retry_timeout_cancel(struct wpa_sm *sm,
387 					      struct wpa_tdls_peer *peer,
388 					      u8 action_code)
389 {
390 	if (action_code == peer->sm_tmr.action_code) {
391 		wpa_printf(MSG_DEBUG, "TDLS: Retry timeout cancelled for "
392 			   "action_code=%u", action_code);
393 
394 		/* Cancel Timeout registered */
395 		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
396 
397 		/* free all resources meant for retry */
398 		os_free(peer->sm_tmr.buf);
399 		peer->sm_tmr.buf = NULL;
400 
401 		peer->sm_tmr.count = 0;
402 		peer->sm_tmr.timer = 0;
403 		peer->sm_tmr.buf_len = 0;
404 		peer->sm_tmr.action_code = 0xff;
405 	} else {
406 		wpa_printf(MSG_INFO, "TDLS: Error in cancelling retry timeout "
407 			   "(Unknown action_code=%u)", action_code);
408 	}
409 }
410 
411 
wpa_tdls_generate_tpk(struct wpa_tdls_peer * peer,const u8 * own_addr,const u8 * bssid)412 static void wpa_tdls_generate_tpk(struct wpa_tdls_peer *peer,
413 				  const u8 *own_addr, const u8 *bssid)
414 {
415 	u8 key_input[SHA256_MAC_LEN];
416 	const u8 *nonce[2];
417 	size_t len[2];
418 	u8 data[3 * ETH_ALEN];
419 
420 	/* IEEE Std 802.11-2016 12.7.9.2:
421 	 * TPK-Key-Input = Hash(min(SNonce, ANonce) || max(SNonce, ANonce))
422 	 * Hash = SHA-256 for TDLS
423 	 */
424 	len[0] = WPA_NONCE_LEN;
425 	len[1] = WPA_NONCE_LEN;
426 	if (os_memcmp(peer->inonce, peer->rnonce, WPA_NONCE_LEN) < 0) {
427 		nonce[0] = peer->inonce;
428 		nonce[1] = peer->rnonce;
429 	} else {
430 		nonce[0] = peer->rnonce;
431 		nonce[1] = peer->inonce;
432 	}
433 	wpa_hexdump(MSG_DEBUG, "TDLS: min(Nonce)", nonce[0], WPA_NONCE_LEN);
434 	wpa_hexdump(MSG_DEBUG, "TDLS: max(Nonce)", nonce[1], WPA_NONCE_LEN);
435 	sha256_vector(2, nonce, len, key_input);
436 	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input",
437 			key_input, SHA256_MAC_LEN);
438 
439 	/*
440 	 * TPK = KDF-Hash-Length(TPK-Key-Input, "TDLS PMK",
441 	 *	min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID)
442 	 */
443 
444 	if (os_memcmp(own_addr, peer->addr, ETH_ALEN) < 0) {
445 		os_memcpy(data, own_addr, ETH_ALEN);
446 		os_memcpy(data + ETH_ALEN, peer->addr, ETH_ALEN);
447 	} else {
448 		os_memcpy(data, peer->addr, ETH_ALEN);
449 		os_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN);
450 	}
451 	os_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN);
452 	wpa_hexdump(MSG_DEBUG, "TDLS: KDF Context", data, sizeof(data));
453 
454 	sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data),
455 		   (u8 *) &peer->tpk, sizeof(peer->tpk));
456 	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK",
457 			peer->tpk.kck, sizeof(peer->tpk.kck));
458 	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK",
459 			peer->tpk.tk, sizeof(peer->tpk.tk));
460 	peer->tpk_set = 1;
461 }
462 
463 
464 /**
465  * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC
466  * @kck: TPK-KCK
467  * @lnkid: Pointer to the beginning of Link Identifier IE
468  * @rsne: Pointer to the beginning of RSNE used for handshake
469  * @rsne_len: Length of RSNE in octets
470  * @timeoutie: Pointer to the beginning of Timeout IE used for handshake
471  * @fte: Pointer to the beginning of FTE
472  * @fre_len: Length of FTE in octets
473  * @mic: Pointer for writing MIC
474  *
475  * Calculate MIC for TDLS frame.
476  */
wpa_tdls_ftie_mic(const u8 * kck,u8 trans_seq,const u8 * lnkid,const u8 * rsne,size_t rsne_len,const u8 * timeoutie,const u8 * fte,size_t fte_len,u8 * mic)477 static int wpa_tdls_ftie_mic(const u8 *kck, u8 trans_seq, const u8 *lnkid,
478 			     const u8 *rsne, size_t rsne_len,
479 			     const u8 *timeoutie,
480 			     const u8 *fte, size_t fte_len, u8 *mic)
481 {
482 	u8 *buf, *pos;
483 	struct wpa_tdls_ftie *_ftie;
484 	const struct wpa_tdls_lnkid *_lnkid;
485 	int ret;
486 	int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + rsne_len +
487 		2 + timeoutie[1] + fte_len;
488 	buf = os_zalloc(len);
489 	if (!buf) {
490 		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
491 		return -1;
492 	}
493 
494 	pos = buf;
495 	_lnkid = (const struct wpa_tdls_lnkid *) lnkid;
496 	/* 1) TDLS initiator STA MAC address */
497 	os_memcpy(pos, _lnkid->init_sta, ETH_ALEN);
498 	pos += ETH_ALEN;
499 	/* 2) TDLS responder STA MAC address */
500 	os_memcpy(pos, _lnkid->resp_sta, ETH_ALEN);
501 	pos += ETH_ALEN;
502 	/* 3) Transaction Sequence number */
503 	*pos++ = trans_seq;
504 	/* 4) Link Identifier IE */
505 	os_memcpy(pos, lnkid, 2 + lnkid[1]);
506 	pos += 2 + lnkid[1];
507 	/* 5) RSN IE */
508 	os_memcpy(pos, rsne, rsne_len);
509 	pos += rsne_len;
510 	/* 6) Timeout Interval IE */
511 	os_memcpy(pos, timeoutie, 2 + timeoutie[1]);
512 	pos += 2 + timeoutie[1];
513 	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
514 	os_memcpy(pos, fte, fte_len);
515 	_ftie = (struct wpa_tdls_ftie *) pos;
516 	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
517 	pos += fte_len;
518 
519 	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
520 	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
521 	ret = omac1_aes_128(kck, buf, pos - buf, mic);
522 	os_free(buf);
523 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
524 	return ret;
525 }
526 
527 
528 /**
529  * wpa_tdls_key_mic_teardown - Calculate TDLS FTIE MIC for Teardown frame
530  * @kck: TPK-KCK
531  * @trans_seq: Transaction Sequence Number (4 - Teardown)
532  * @rcode: Reason code for Teardown
533  * @dtoken: Dialog Token used for that particular link
534  * @lnkid: Pointer to the beginning of Link Identifier IE
535  * @fte: Pointer to the beginning of FTE
536  * @fre_len: Length of FTE in octets
537  * @mic: Pointer for writing MIC
538  *
539  * Calculate MIC for TDLS frame.
540  */
wpa_tdls_key_mic_teardown(const u8 * kck,u8 trans_seq,u16 rcode,u8 dtoken,const u8 * lnkid,const u8 * fte,size_t fte_len,u8 * mic)541 static int wpa_tdls_key_mic_teardown(const u8 *kck, u8 trans_seq, u16 rcode,
542 				     u8 dtoken, const u8 *lnkid,
543 				     const u8 *fte, size_t fte_len, u8 *mic)
544 {
545 	u8 *buf, *pos;
546 	struct wpa_tdls_ftie *_ftie;
547 	int ret;
548 	int len;
549 
550 	if (lnkid == NULL)
551 		return -1;
552 
553 	len = 2 + lnkid[1] + sizeof(rcode) + sizeof(dtoken) +
554 		sizeof(trans_seq) + fte_len;
555 
556 	buf = os_zalloc(len);
557 	if (!buf) {
558 		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
559 		return -1;
560 	}
561 
562 	pos = buf;
563 	/* 1) Link Identifier IE */
564 	os_memcpy(pos, lnkid, 2 + lnkid[1]);
565 	pos += 2 + lnkid[1];
566 	/* 2) Reason Code */
567 	WPA_PUT_LE16(pos, rcode);
568 	pos += sizeof(rcode);
569 	/* 3) Dialog token */
570 	*pos++ = dtoken;
571 	/* 4) Transaction Sequence number */
572 	*pos++ = trans_seq;
573 	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
574 	os_memcpy(pos, fte, fte_len);
575 	_ftie = (struct wpa_tdls_ftie *) pos;
576 	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
577 	pos += fte_len;
578 
579 	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
580 	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
581 	ret = omac1_aes_128(kck, buf, pos - buf, mic);
582 	os_free(buf);
583 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
584 	return ret;
585 }
586 
587 
wpa_supplicant_verify_tdls_mic(u8 trans_seq,struct wpa_tdls_peer * peer,const u8 * lnkid,const u8 * timeoutie,const struct wpa_tdls_ftie * ftie,size_t fte_len)588 static int wpa_supplicant_verify_tdls_mic(u8 trans_seq,
589 					  struct wpa_tdls_peer *peer,
590 					  const u8 *lnkid, const u8 *timeoutie,
591 					  const struct wpa_tdls_ftie *ftie,
592 					  size_t fte_len)
593 {
594 	u8 mic[16];
595 
596 	if (peer->tpk_set) {
597 		wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid,
598 				  peer->rsnie_p, peer->rsnie_p_len, timeoutie,
599 				  (const u8 *) ftie, fte_len, mic);
600 		if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
601 			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - "
602 				   "dropping packet");
603 			wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC",
604 				    ftie->mic, 16);
605 			wpa_hexdump(MSG_DEBUG, "TDLS: Calculated MIC",
606 				    mic, 16);
607 			return -1;
608 		}
609 	} else {
610 		wpa_printf(MSG_WARNING, "TDLS: Could not verify TDLS MIC, "
611 			   "TPK not set - dropping packet");
612 		return -1;
613 	}
614 	return 0;
615 }
616 
617 
wpa_supplicant_verify_tdls_mic_teardown(u8 trans_seq,u16 rcode,u8 dtoken,struct wpa_tdls_peer * peer,const u8 * lnkid,const struct wpa_tdls_ftie * ftie,size_t fte_len)618 static int wpa_supplicant_verify_tdls_mic_teardown(
619 	u8 trans_seq, u16 rcode, u8 dtoken, struct wpa_tdls_peer *peer,
620 	const u8 *lnkid, const struct wpa_tdls_ftie *ftie, size_t fte_len)
621 {
622 	u8 mic[16];
623 
624 	if (peer->tpk_set) {
625 		wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode,
626 					  dtoken, lnkid, (const u8 *) ftie,
627 					  fte_len, mic);
628 		if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
629 			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - "
630 				   "dropping packet");
631 			return -1;
632 		}
633 	} else {
634 		wpa_printf(MSG_INFO, "TDLS: Could not verify TDLS Teardown "
635 			   "MIC, TPK not set - dropping packet");
636 		return -1;
637 	}
638 	return 0;
639 }
640 
641 
wpa_tdls_tpk_timeout(void * eloop_ctx,void * timeout_ctx)642 static void wpa_tdls_tpk_timeout(void *eloop_ctx, void *timeout_ctx)
643 {
644 	struct wpa_sm *sm = eloop_ctx;
645 	struct wpa_tdls_peer *peer = timeout_ctx;
646 
647 	/*
648 	 * On TPK lifetime expiration, we have an option of either tearing down
649 	 * the direct link or trying to re-initiate it. The selection of what
650 	 * to do is not strictly speaking controlled by our role in the expired
651 	 * link, but for now, use that to select whether to renew or tear down
652 	 * the link.
653 	 */
654 
655 	if (peer->initiator) {
656 		u8 addr[ETH_ALEN];
657 
658 		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
659 			   " - try to renew", MAC2STR(peer->addr));
660 		/* cache the peer address before do_teardown */
661 		os_memcpy(addr, peer->addr, ETH_ALEN);
662 		wpa_tdls_do_teardown(sm, peer,
663 				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
664 		wpa_tdls_start(sm, addr);
665 	} else {
666 		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
667 			   " - tear down", MAC2STR(peer->addr));
668 		wpa_tdls_do_teardown(sm, peer,
669 				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
670 	}
671 }
672 
673 
wpa_tdls_peer_remove_from_list(struct wpa_sm * sm,struct wpa_tdls_peer * peer)674 static void wpa_tdls_peer_remove_from_list(struct wpa_sm *sm,
675 					   struct wpa_tdls_peer *peer)
676 {
677 	struct wpa_tdls_peer *cur, *prev;
678 
679 	cur = sm->tdls;
680 	prev = NULL;
681 	while (cur && cur != peer) {
682 		prev = cur;
683 		cur = cur->next;
684 	}
685 
686 	if (cur != peer) {
687 		wpa_printf(MSG_ERROR, "TDLS: Could not find peer " MACSTR
688 			   " to remove it from the list",
689 			   MAC2STR(peer->addr));
690 		return;
691 	}
692 
693 	if (prev)
694 		prev->next = peer->next;
695 	else
696 		sm->tdls = peer->next;
697 }
698 
699 
wpa_tdls_peer_clear(struct wpa_sm * sm,struct wpa_tdls_peer * peer)700 static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
701 {
702 	wpa_printf(MSG_DEBUG, "TDLS: Clear state for peer " MACSTR,
703 		   MAC2STR(peer->addr));
704 	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
705 	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
706 	peer->reconfig_key = 0;
707 	peer->initiator = 0;
708 	peer->tpk_in_progress = 0;
709 	os_free(peer->sm_tmr.buf);
710 	peer->sm_tmr.buf = NULL;
711 	os_free(peer->ht_capabilities);
712 	peer->ht_capabilities = NULL;
713 	os_free(peer->vht_capabilities);
714 	peer->vht_capabilities = NULL;
715 	os_free(peer->he_capabilities);
716 	peer->he_capabilities = NULL;
717 	os_free(peer->he_6ghz_band_capabilities);
718 	peer->he_6ghz_band_capabilities = NULL;
719 	os_free(peer->ext_capab);
720 	peer->ext_capab = NULL;
721 	os_free(peer->supp_channels);
722 	peer->supp_channels = NULL;
723 	os_free(peer->supp_oper_classes);
724 	peer->supp_oper_classes = NULL;
725 	peer->rsnie_i_len = peer->rsnie_p_len = 0;
726 	peer->cipher = 0;
727 	peer->qos_info = 0;
728 	peer->wmm_capable = 0;
729 	peer->tk_set = peer->tpk_set = peer->tpk_success = 0;
730 	peer->chan_switch_enabled = 0;
731 	os_memset(&peer->tpk, 0, sizeof(peer->tpk));
732 	os_memset(peer->inonce, 0, WPA_NONCE_LEN);
733 	os_memset(peer->rnonce, 0, WPA_NONCE_LEN);
734 }
735 
736 
wpa_tdls_peer_free(struct wpa_sm * sm,struct wpa_tdls_peer * peer)737 static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
738 {
739 	wpa_tdls_peer_clear(sm, peer);
740 	wpa_tdls_peer_remove_from_list(sm, peer);
741 	os_free(peer);
742 }
743 
744 
wpa_tdls_linkid(struct wpa_sm * sm,struct wpa_tdls_peer * peer,struct wpa_tdls_lnkid * lnkid)745 static void wpa_tdls_linkid(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
746 			    struct wpa_tdls_lnkid *lnkid)
747 {
748 	lnkid->ie_type = WLAN_EID_LINK_ID;
749 	lnkid->ie_len = 3 * ETH_ALEN;
750 	os_memcpy(lnkid->bssid, sm->bssid, ETH_ALEN);
751 	if (peer->initiator) {
752 		os_memcpy(lnkid->init_sta, sm->own_addr, ETH_ALEN);
753 		os_memcpy(lnkid->resp_sta, peer->addr, ETH_ALEN);
754 	} else {
755 		os_memcpy(lnkid->init_sta, peer->addr, ETH_ALEN);
756 		os_memcpy(lnkid->resp_sta, sm->own_addr, ETH_ALEN);
757 	}
758 }
759 
760 
wpa_tdls_send_teardown(struct wpa_sm * sm,const u8 * addr,u16 reason_code)761 static int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr,
762 				  u16 reason_code)
763 {
764 	struct wpa_tdls_peer *peer;
765 	struct wpa_tdls_ftie *ftie;
766 	struct wpa_tdls_lnkid lnkid;
767 	u8 dialog_token;
768 	u8 *rbuf, *pos;
769 	int ielen;
770 
771 	if (sm->tdls_disabled || !sm->tdls_supported)
772 		return -1;
773 
774 	/* Find the node and free from the list */
775 	for (peer = sm->tdls; peer; peer = peer->next) {
776 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
777 			break;
778 	}
779 
780 	if (peer == NULL) {
781 		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
782 			   "Teardown " MACSTR, MAC2STR(addr));
783 		return 0;
784 	}
785 
786 	/* Cancel active channel switch before teardown */
787 	if (peer->chan_switch_enabled) {
788 		wpa_printf(MSG_DEBUG, "TDLS: First returning link with " MACSTR
789 			   " to base channel", MAC2STR(addr));
790 		wpa_sm_tdls_disable_channel_switch(sm, peer->addr);
791 	}
792 
793 	dialog_token = peer->dtoken;
794 
795 	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown for " MACSTR,
796 		   MAC2STR(addr));
797 
798 	ielen = 0;
799 	if (wpa_tdls_get_privacy(sm) && peer->tpk_set && peer->tpk_success) {
800 		/* To add FTIE for Teardown request and compute MIC */
801 		ielen += sizeof(*ftie);
802 #ifdef CONFIG_TDLS_TESTING
803 		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
804 			ielen += 170;
805 #endif /* CONFIG_TDLS_TESTING */
806 	}
807 
808 	rbuf = os_zalloc(ielen + 1);
809 	if (rbuf == NULL)
810 		return -1;
811 	pos = rbuf;
812 
813 	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
814 		goto skip_ies;
815 
816 	ftie = (struct wpa_tdls_ftie *) pos;
817 	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
818 	/* Using the recent nonce which should be for CONFIRM frame */
819 	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
820 	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
821 	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
822 	pos = (u8 *) (ftie + 1);
823 #ifdef CONFIG_TDLS_TESTING
824 	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
825 		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
826 			   "FTIE");
827 		ftie->ie_len += 170;
828 		*pos++ = 255; /* FTIE subelem */
829 		*pos++ = 168; /* FTIE subelem length */
830 		pos += 168;
831 	}
832 #endif /* CONFIG_TDLS_TESTING */
833 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TDLS Teardown handshake",
834 		    (u8 *) ftie, pos - (u8 *) ftie);
835 
836 	/* compute MIC before sending */
837 	wpa_tdls_linkid(sm, peer, &lnkid);
838 	wpa_tdls_key_mic_teardown(peer->tpk.kck, 4, reason_code,
839 				  dialog_token, (const u8 *) &lnkid,
840 				  (const u8 *) ftie, 2 + ftie->ie_len,
841 				  ftie->mic);
842 
843 skip_ies:
844 	/* TODO: register for a Timeout handler, if Teardown is not received at
845 	 * the other end, then try again another time */
846 
847 	/* request driver to send Teardown using this FTIE */
848 	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
849 			  reason_code, 0, peer->initiator, rbuf, pos - rbuf);
850 	os_free(rbuf);
851 
852 	return 0;
853 }
854 
855 
wpa_tdls_teardown_link(struct wpa_sm * sm,const u8 * addr,u16 reason_code)856 int wpa_tdls_teardown_link(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
857 {
858 	struct wpa_tdls_peer *peer;
859 
860 	if (sm->tdls_disabled || !sm->tdls_supported)
861 		return -1;
862 
863 	for (peer = sm->tdls; peer; peer = peer->next) {
864 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
865 			break;
866 	}
867 
868 	if (peer == NULL) {
869 		wpa_printf(MSG_DEBUG, "TDLS: Could not find peer " MACSTR
870 		   " for link Teardown", MAC2STR(addr));
871 		return -1;
872 	}
873 
874 	if (!peer->tpk_success) {
875 		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
876 		   " not connected - cannot Teardown link", MAC2STR(addr));
877 		return -1;
878 	}
879 
880 	return wpa_tdls_do_teardown(sm, peer, reason_code);
881 }
882 
883 
wpa_tdls_disable_peer_link(struct wpa_sm * sm,struct wpa_tdls_peer * peer)884 static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
885 				       struct wpa_tdls_peer *peer)
886 {
887 	wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
888 	wpa_tdls_peer_free(sm, peer);
889 }
890 
891 
wpa_tdls_disable_unreachable_link(struct wpa_sm * sm,const u8 * addr)892 void wpa_tdls_disable_unreachable_link(struct wpa_sm *sm, const u8 *addr)
893 {
894 	struct wpa_tdls_peer *peer;
895 
896 	for (peer = sm->tdls; peer; peer = peer->next) {
897 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
898 			break;
899 	}
900 
901 	if (!peer || !peer->tpk_success) {
902 		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
903 			   " not connected - cannot teardown unreachable link",
904 			   MAC2STR(addr));
905 		return;
906 	}
907 
908 	if (wpa_tdls_is_external_setup(sm)) {
909 		/*
910 		 * Get us on the base channel, disable the link, send a
911 		 * teardown packet through the AP, and then reset link data.
912 		 */
913 		if (peer->chan_switch_enabled)
914 			wpa_sm_tdls_disable_channel_switch(sm, peer->addr);
915 		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
916 		wpa_tdls_send_teardown(sm, addr,
917 				       WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE);
918 		wpa_tdls_peer_free(sm, peer);
919 	} else {
920 		wpa_tdls_disable_peer_link(sm, peer);
921 	}
922 }
923 
924 
wpa_tdls_get_link_status(struct wpa_sm * sm,const u8 * addr)925 const char * wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr)
926 {
927 	struct wpa_tdls_peer *peer;
928 
929 	if (sm->tdls_disabled || !sm->tdls_supported)
930 		return "disabled";
931 
932 	for (peer = sm->tdls; peer; peer = peer->next) {
933 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
934 			break;
935 	}
936 
937 	if (peer == NULL)
938 		return "peer does not exist";
939 
940 	if (!peer->tpk_success)
941 		return "peer not connected";
942 
943 	return "connected";
944 }
945 
946 
wpa_tdls_recv_teardown(struct wpa_sm * sm,const u8 * src_addr,const u8 * buf,size_t len)947 static int wpa_tdls_recv_teardown(struct wpa_sm *sm, const u8 *src_addr,
948 				  const u8 *buf, size_t len)
949 {
950 	struct wpa_tdls_peer *peer = NULL;
951 	struct wpa_tdls_ftie *ftie;
952 	struct wpa_tdls_lnkid *lnkid;
953 	struct wpa_eapol_ie_parse kde;
954 	u16 reason_code;
955 	const u8 *pos;
956 	int ielen;
957 
958 	/* Find the node and free from the list */
959 	for (peer = sm->tdls; peer; peer = peer->next) {
960 		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
961 			break;
962 	}
963 
964 	if (peer == NULL) {
965 		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
966 			   "Teardown " MACSTR, MAC2STR(src_addr));
967 		return 0;
968 	}
969 
970 	pos = buf;
971 	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
972 
973 	reason_code = WPA_GET_LE16(pos);
974 	pos += 2;
975 
976 	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown Request from " MACSTR
977 		   " (reason code %u)", MAC2STR(src_addr), reason_code);
978 
979 	ielen = len - (pos - buf); /* start of IE in buf */
980 
981 	/*
982 	 * Don't reject the message if failing to parse IEs. The IEs we need are
983 	 * explicitly checked below. Some APs may add arbitrary padding to the
984 	 * end of short TDLS frames and that would look like invalid IEs.
985 	 */
986 	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0)
987 		wpa_printf(MSG_DEBUG,
988 			   "TDLS: Failed to parse IEs in Teardown - ignore as an interop workaround");
989 
990 	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
991 		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TDLS "
992 			   "Teardown");
993 		return -1;
994 	}
995 	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
996 
997 	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
998 		goto skip_ftie;
999 
1000 	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
1001 		wpa_printf(MSG_INFO, "TDLS: No FTIE in TDLS Teardown");
1002 		return -1;
1003 	}
1004 
1005 	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1006 
1007 	/* Process MIC check to see if TDLS Teardown is right */
1008 	if (wpa_supplicant_verify_tdls_mic_teardown(4, reason_code,
1009 						    peer->dtoken, peer,
1010 						    (const u8 *) lnkid,
1011 						    ftie, kde.ftie_len) < 0) {
1012 		wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS "
1013 			   "Teardown Request from " MACSTR, MAC2STR(src_addr));
1014 		return -1;
1015 	}
1016 
1017 skip_ftie:
1018 	/*
1019 	 * Request the driver to disable the direct link and clear associated
1020 	 * keys.
1021 	 */
1022 	wpa_tdls_disable_peer_link(sm, peer);
1023 	return 0;
1024 }
1025 
1026 
1027 /**
1028  * wpa_tdls_send_error - To send suitable TDLS status response with
1029  *	appropriate status code mentioning reason for error/failure.
1030  * @dst 	- MAC addr of Peer station
1031  * @tdls_action - TDLS frame type for which error code is sent
1032  * @initiator   - was this end the initiator of the connection
1033  * @status 	- status code mentioning reason
1034  */
1035 
wpa_tdls_send_error(struct wpa_sm * sm,const u8 * dst,u8 tdls_action,u8 dialog_token,int initiator,u16 status)1036 static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
1037 			       u8 tdls_action, u8 dialog_token, int initiator,
1038 			       u16 status)
1039 {
1040 	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
1041 		   " (action=%u status=%u)",
1042 		   MAC2STR(dst), tdls_action, status);
1043 	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
1044 				 0, initiator, NULL, 0);
1045 }
1046 
1047 
1048 static struct wpa_tdls_peer *
wpa_tdls_add_peer(struct wpa_sm * sm,const u8 * addr,int * existing)1049 wpa_tdls_add_peer(struct wpa_sm *sm, const u8 *addr, int *existing)
1050 {
1051 	struct wpa_tdls_peer *peer;
1052 
1053 	if (existing)
1054 		*existing = 0;
1055 	for (peer = sm->tdls; peer; peer = peer->next) {
1056 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) {
1057 			if (existing)
1058 				*existing = 1;
1059 			return peer; /* re-use existing entry */
1060 		}
1061 	}
1062 
1063 	wpa_printf(MSG_INFO, "TDLS: Creating peer entry for " MACSTR,
1064 		   MAC2STR(addr));
1065 
1066 	peer = os_zalloc(sizeof(*peer));
1067 	if (peer == NULL)
1068 		return NULL;
1069 
1070 	os_memcpy(peer->addr, addr, ETH_ALEN);
1071 	peer->next = sm->tdls;
1072 	sm->tdls = peer;
1073 
1074 	return peer;
1075 }
1076 
1077 
wpa_tdls_send_tpk_m1(struct wpa_sm * sm,struct wpa_tdls_peer * peer)1078 static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm,
1079 				struct wpa_tdls_peer *peer)
1080 {
1081 	size_t buf_len;
1082 	struct wpa_tdls_timeoutie timeoutie;
1083 	u16 rsn_capab;
1084 	struct wpa_tdls_ftie *ftie;
1085 	u8 *rbuf, *pos, *count_pos;
1086 	u16 count;
1087 	struct rsn_ie_hdr *hdr;
1088 	int status;
1089 
1090 	if (!wpa_tdls_get_privacy(sm)) {
1091 		wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
1092 		peer->rsnie_i_len = 0;
1093 		goto skip_rsnie;
1094 	}
1095 
1096 	/*
1097 	 * TPK Handshake Message 1:
1098 	 * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I,
1099 	 * Timeout Interval IE))
1100 	 */
1101 
1102 	/* Filling RSN IE */
1103 	hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
1104 	hdr->elem_id = WLAN_EID_RSN;
1105 	WPA_PUT_LE16(hdr->version, RSN_VERSION);
1106 
1107 	pos = (u8 *) (hdr + 1);
1108 	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1109 	pos += RSN_SELECTOR_LEN;
1110 	count_pos = pos;
1111 	pos += 2;
1112 
1113 	count = 0;
1114 
1115 	/*
1116 	 * AES-CCMP is the default Encryption preferred for TDLS, so
1117 	 * RSN IE is filled only with CCMP CIPHER
1118 	 * Note: TKIP is not used to encrypt TDLS link.
1119 	 *
1120 	 * Regardless of the cipher used on the AP connection, select CCMP
1121 	 * here.
1122 	 */
1123 	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1124 	pos += RSN_SELECTOR_LEN;
1125 	count++;
1126 
1127 	WPA_PUT_LE16(count_pos, count);
1128 
1129 	WPA_PUT_LE16(pos, 1);
1130 	pos += 2;
1131 	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1132 	pos += RSN_SELECTOR_LEN;
1133 
1134 	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1135 	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1136 #ifdef CONFIG_TDLS_TESTING
1137 	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
1138 		wpa_printf(MSG_DEBUG, "TDLS: Use alternative RSN IE for "
1139 			   "testing");
1140 		rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1141 	}
1142 #endif /* CONFIG_TDLS_TESTING */
1143 	WPA_PUT_LE16(pos, rsn_capab);
1144 	pos += 2;
1145 #ifdef CONFIG_TDLS_TESTING
1146 	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
1147 		/* Number of PMKIDs */
1148 		*pos++ = 0x00;
1149 		*pos++ = 0x00;
1150 	}
1151 #endif /* CONFIG_TDLS_TESTING */
1152 
1153 	hdr->len = (pos - peer->rsnie_i) - 2;
1154 	peer->rsnie_i_len = pos - peer->rsnie_i;
1155 	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
1156 		    peer->rsnie_i, peer->rsnie_i_len);
1157 
1158 skip_rsnie:
1159 	buf_len = 0;
1160 	if (wpa_tdls_get_privacy(sm))
1161 		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1162 			sizeof(struct wpa_tdls_timeoutie);
1163 #ifdef CONFIG_TDLS_TESTING
1164 	if (wpa_tdls_get_privacy(sm) &&
1165 	    (tdls_testing & TDLS_TESTING_LONG_FRAME))
1166 		buf_len += 170;
1167 	if (tdls_testing & TDLS_TESTING_DIFF_BSSID)
1168 		buf_len += sizeof(struct wpa_tdls_lnkid);
1169 #endif /* CONFIG_TDLS_TESTING */
1170 	rbuf = os_zalloc(buf_len + 1);
1171 	if (rbuf == NULL) {
1172 		wpa_tdls_peer_free(sm, peer);
1173 		return -2;
1174 	}
1175 	pos = rbuf;
1176 
1177 	if (!wpa_tdls_get_privacy(sm))
1178 		goto skip_ies;
1179 
1180 	/* Initiator RSN IE */
1181 	pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
1182 
1183 	ftie = (struct wpa_tdls_ftie *) pos;
1184 	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1185 	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1186 
1187 	if (os_get_random(peer->inonce, WPA_NONCE_LEN)) {
1188 		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1189 			"TDLS: Failed to get random data for initiator Nonce");
1190 		os_free(rbuf);
1191 		wpa_tdls_peer_free(sm, peer);
1192 		return -2;
1193 	}
1194 	peer->tk_set = 0; /* A new nonce results in a new TK */
1195 	wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
1196 		    peer->inonce, WPA_NONCE_LEN);
1197 	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1198 
1199 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK Handshake M1",
1200 		    (u8 *) ftie, sizeof(struct wpa_tdls_ftie));
1201 
1202 	pos = (u8 *) (ftie + 1);
1203 
1204 #ifdef CONFIG_TDLS_TESTING
1205 	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1206 		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1207 			   "FTIE");
1208 		ftie->ie_len += 170;
1209 		*pos++ = 255; /* FTIE subelem */
1210 		*pos++ = 168; /* FTIE subelem length */
1211 		pos += 168;
1212 	}
1213 #endif /* CONFIG_TDLS_TESTING */
1214 
1215 	/* Lifetime */
1216 	peer->lifetime = TPK_LIFETIME;
1217 #ifdef CONFIG_TDLS_TESTING
1218 	if (tdls_testing & TDLS_TESTING_SHORT_LIFETIME) {
1219 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK "
1220 			   "lifetime");
1221 		peer->lifetime = 301;
1222 	}
1223 	if (tdls_testing & TDLS_TESTING_LONG_LIFETIME) {
1224 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK "
1225 			   "lifetime");
1226 		peer->lifetime = 0xffffffff;
1227 	}
1228 #endif /* CONFIG_TDLS_TESTING */
1229 	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1230 				     sizeof(timeoutie), peer->lifetime);
1231 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1232 
1233 skip_ies:
1234 
1235 #ifdef CONFIG_TDLS_TESTING
1236 	if (tdls_testing & TDLS_TESTING_DIFF_BSSID) {
1237 		struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos;
1238 
1239 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in "
1240 			   "Link Identifier");
1241 		wpa_tdls_linkid(sm, peer, l);
1242 		l->bssid[5] ^= 0x01;
1243 		pos += sizeof(*l);
1244 	}
1245 #endif /* CONFIG_TDLS_TESTING */
1246 
1247 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Request / TPK "
1248 		   "Handshake Message 1 (peer " MACSTR ")",
1249 		   MAC2STR(peer->addr));
1250 
1251 	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
1252 				   1, 0, 0, peer->initiator, rbuf, pos - rbuf);
1253 	os_free(rbuf);
1254 
1255 	return status;
1256 }
1257 
1258 
wpa_tdls_send_tpk_m2(struct wpa_sm * sm,const unsigned char * src_addr,u8 dtoken,struct wpa_tdls_lnkid * lnkid,const struct wpa_tdls_peer * peer)1259 static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
1260 				const unsigned char *src_addr, u8 dtoken,
1261 				struct wpa_tdls_lnkid *lnkid,
1262 				const struct wpa_tdls_peer *peer)
1263 {
1264 	u8 *rbuf, *pos;
1265 	size_t buf_len;
1266 	u32 lifetime;
1267 	struct wpa_tdls_timeoutie timeoutie;
1268 	struct wpa_tdls_ftie *ftie;
1269 	int status;
1270 
1271 	buf_len = 0;
1272 	if (wpa_tdls_get_privacy(sm)) {
1273 		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1274 		 * Lifetime */
1275 		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1276 			sizeof(struct wpa_tdls_timeoutie);
1277 #ifdef CONFIG_TDLS_TESTING
1278 		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1279 			buf_len += 170;
1280 #endif /* CONFIG_TDLS_TESTING */
1281 	}
1282 
1283 	rbuf = os_zalloc(buf_len + 1);
1284 	if (rbuf == NULL)
1285 		return -1;
1286 	pos = rbuf;
1287 
1288 	if (!wpa_tdls_get_privacy(sm))
1289 		goto skip_ies;
1290 
1291 	/* Peer RSN IE */
1292 	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1293 
1294 	ftie = (struct wpa_tdls_ftie *) pos;
1295 	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1296 	/* TODO: ftie->mic_control to set 2-RESPONSE */
1297 	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1298 	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1299 	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1300 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK M2",
1301 		    (u8 *) ftie, sizeof(*ftie));
1302 
1303 	pos = (u8 *) (ftie + 1);
1304 
1305 #ifdef CONFIG_TDLS_TESTING
1306 	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1307 		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1308 			   "FTIE");
1309 		ftie->ie_len += 170;
1310 		*pos++ = 255; /* FTIE subelem */
1311 		*pos++ = 168; /* FTIE subelem length */
1312 		pos += 168;
1313 	}
1314 #endif /* CONFIG_TDLS_TESTING */
1315 
1316 	/* Lifetime */
1317 	lifetime = peer->lifetime;
1318 #ifdef CONFIG_TDLS_TESTING
1319 	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_RESP) {
1320 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1321 			   "lifetime in response");
1322 		lifetime++;
1323 	}
1324 #endif /* CONFIG_TDLS_TESTING */
1325 	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1326 				     sizeof(timeoutie), lifetime);
1327 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds from initiator",
1328 		   lifetime);
1329 
1330 	/* compute MIC before sending */
1331 	wpa_tdls_ftie_mic(peer->tpk.kck, 2, (const u8 *) lnkid, peer->rsnie_p,
1332 			  peer->rsnie_p_len, (const u8 *) &timeoutie,
1333 			  (const u8 *) ftie, 2 + ftie->ie_len, ftie->mic);
1334 #ifdef CONFIG_TDLS_TESTING
1335 	if (tdls_testing & TDLS_TESTING_WRONG_MIC) {
1336 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC");
1337 		ftie->mic[0] ^= 0x01;
1338 	}
1339 #endif /* CONFIG_TDLS_TESTING */
1340 
1341 skip_ies:
1342 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
1343 				   dtoken, 0, 0, peer->initiator, rbuf,
1344 				   pos - rbuf);
1345 	os_free(rbuf);
1346 
1347 	return status;
1348 }
1349 
1350 
wpa_tdls_send_tpk_m3(struct wpa_sm * sm,const unsigned char * src_addr,u8 dtoken,struct wpa_tdls_lnkid * lnkid,const struct wpa_tdls_peer * peer)1351 static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm,
1352 				const unsigned char *src_addr, u8 dtoken,
1353 				struct wpa_tdls_lnkid *lnkid,
1354 				const struct wpa_tdls_peer *peer)
1355 {
1356 	u8 *rbuf, *pos;
1357 	size_t buf_len;
1358 	struct wpa_tdls_ftie *ftie;
1359 	struct wpa_tdls_timeoutie timeoutie;
1360 	u32 lifetime;
1361 	int status;
1362 	u32 peer_capab = 0;
1363 
1364 	buf_len = 0;
1365 	if (wpa_tdls_get_privacy(sm)) {
1366 		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1367 		 * Lifetime */
1368 		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1369 			sizeof(struct wpa_tdls_timeoutie);
1370 #ifdef CONFIG_TDLS_TESTING
1371 		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1372 			buf_len += 170;
1373 #endif /* CONFIG_TDLS_TESTING */
1374 	}
1375 
1376 	rbuf = os_zalloc(buf_len + 1);
1377 	if (rbuf == NULL)
1378 		return -1;
1379 	pos = rbuf;
1380 
1381 	if (!wpa_tdls_get_privacy(sm))
1382 		goto skip_ies;
1383 
1384 	/* Peer RSN IE */
1385 	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1386 
1387 	ftie = (struct wpa_tdls_ftie *) pos;
1388 	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1389 	/*TODO: ftie->mic_control to set 3-CONFIRM */
1390 	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1391 	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1392 	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1393 
1394 	pos = (u8 *) (ftie + 1);
1395 
1396 #ifdef CONFIG_TDLS_TESTING
1397 	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1398 		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1399 			   "FTIE");
1400 		ftie->ie_len += 170;
1401 		*pos++ = 255; /* FTIE subelem */
1402 		*pos++ = 168; /* FTIE subelem length */
1403 		pos += 168;
1404 	}
1405 #endif /* CONFIG_TDLS_TESTING */
1406 
1407 	/* Lifetime */
1408 	lifetime = peer->lifetime;
1409 #ifdef CONFIG_TDLS_TESTING
1410 	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_CONF) {
1411 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1412 			   "lifetime in confirm");
1413 		lifetime++;
1414 	}
1415 #endif /* CONFIG_TDLS_TESTING */
1416 	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1417 				     sizeof(timeoutie), lifetime);
1418 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds",
1419 		   lifetime);
1420 
1421 	/* compute MIC before sending */
1422 	wpa_tdls_ftie_mic(peer->tpk.kck, 3, (const u8 *) lnkid, peer->rsnie_p,
1423 			  peer->rsnie_p_len, (const u8 *) &timeoutie,
1424 			  (const u8 *) ftie, 2 + ftie->ie_len, ftie->mic);
1425 #ifdef CONFIG_TDLS_TESTING
1426 	if (tdls_testing & TDLS_TESTING_WRONG_MIC) {
1427 		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC");
1428 		ftie->mic[0] ^= 0x01;
1429 	}
1430 #endif /* CONFIG_TDLS_TESTING */
1431 
1432 skip_ies:
1433 
1434 	if (peer->he_capabilities)
1435 		peer_capab |= TDLS_PEER_HE;
1436 	if (peer->vht_capabilities)
1437 		peer_capab |= TDLS_PEER_VHT;
1438 	if (peer->ht_capabilities)
1439 		peer_capab |= TDLS_PEER_HT;
1440 	if (peer->wmm_capable)
1441 		peer_capab |= TDLS_PEER_WMM;
1442 
1443 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
1444 				   dtoken, 0, peer_capab, peer->initiator,
1445 				   rbuf, pos - rbuf);
1446 	os_free(rbuf);
1447 
1448 	return status;
1449 }
1450 
1451 
wpa_tdls_send_discovery_response(struct wpa_sm * sm,struct wpa_tdls_peer * peer,u8 dialog_token)1452 static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
1453 					    struct wpa_tdls_peer *peer,
1454 					    u8 dialog_token)
1455 {
1456 	size_t buf_len = 0;
1457 	struct wpa_tdls_timeoutie timeoutie;
1458 	u16 rsn_capab;
1459 	u8 *rbuf, *pos, *count_pos;
1460 	u16 count;
1461 	struct rsn_ie_hdr *hdr;
1462 	int status;
1463 
1464 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Discovery Response "
1465 		   "(peer " MACSTR ")", MAC2STR(peer->addr));
1466 	if (!wpa_tdls_get_privacy(sm))
1467 		goto skip_rsn_ies;
1468 
1469 	/* Filling RSN IE */
1470 	hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
1471 	hdr->elem_id = WLAN_EID_RSN;
1472 	WPA_PUT_LE16(hdr->version, RSN_VERSION);
1473 	pos = (u8 *) (hdr + 1);
1474 	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1475 	pos += RSN_SELECTOR_LEN;
1476 	count_pos = pos;
1477 	pos += 2;
1478 	count = 0;
1479 
1480 	/*
1481 	* AES-CCMP is the default encryption preferred for TDLS, so
1482 	* RSN IE is filled only with CCMP cipher suite.
1483 	* Note: TKIP is not used to encrypt TDLS link.
1484 	*
1485 	* Regardless of the cipher used on the AP connection, select CCMP
1486 	* here.
1487 	*/
1488 	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1489 	pos += RSN_SELECTOR_LEN;
1490 	count++;
1491 	WPA_PUT_LE16(count_pos, count);
1492 	WPA_PUT_LE16(pos, 1);
1493 	pos += 2;
1494 	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1495 	pos += RSN_SELECTOR_LEN;
1496 
1497 	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1498 	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1499 	WPA_PUT_LE16(pos, rsn_capab);
1500 	pos += 2;
1501 	hdr->len = (pos - (u8 *) hdr) - 2;
1502 	peer->rsnie_i_len = pos - peer->rsnie_i;
1503 
1504 	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for Discovery Response",
1505 		    (u8 *) hdr, hdr->len + 2);
1506 skip_rsn_ies:
1507 	buf_len = 0;
1508 	if (wpa_tdls_get_privacy(sm)) {
1509 		/* Peer RSN IE, Lifetime */
1510 		buf_len += peer->rsnie_i_len +
1511 			sizeof(struct wpa_tdls_timeoutie);
1512 	}
1513 	rbuf = os_zalloc(buf_len + 1);
1514 	if (rbuf == NULL) {
1515 		wpa_tdls_peer_free(sm, peer);
1516 		return -1;
1517 	}
1518 	pos = rbuf;
1519 
1520 	if (!wpa_tdls_get_privacy(sm))
1521 		goto skip_ies;
1522 	/* Initiator RSN IE */
1523 	pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
1524 	/* Lifetime */
1525 	peer->lifetime = TPK_LIFETIME;
1526 	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1527 				     sizeof(timeoutie), peer->lifetime);
1528 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1529 skip_ies:
1530 	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
1531 				   dialog_token, 0, 0, 0, rbuf, pos - rbuf);
1532 	os_free(rbuf);
1533 
1534 	return status;
1535 }
1536 
1537 
1538 static int
wpa_tdls_process_discovery_request(struct wpa_sm * sm,const u8 * addr,const u8 * buf,size_t len)1539 wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr,
1540 				   const u8 *buf, size_t len)
1541 {
1542 	struct wpa_eapol_ie_parse kde;
1543 	const struct wpa_tdls_lnkid *lnkid;
1544 	struct wpa_tdls_peer *peer;
1545 	size_t min_req_len = sizeof(struct wpa_tdls_frame) +
1546 		1 /* dialog token */ + sizeof(struct wpa_tdls_lnkid);
1547 	u8 dialog_token;
1548 
1549 	wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from " MACSTR,
1550 		   MAC2STR(addr));
1551 
1552 	if (len < min_req_len) {
1553 		wpa_printf(MSG_DEBUG, "TDLS Discovery Request is too short: "
1554 			   "%d", (int) len);
1555 		return -1;
1556 	}
1557 
1558 	dialog_token = buf[sizeof(struct wpa_tdls_frame)];
1559 
1560 	/*
1561 	 * Some APs will tack on a weird IE to the end of a TDLS
1562 	 * discovery request packet. This needn't fail the response,
1563 	 * since the required IE are verified separately.
1564 	 */
1565 	if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1,
1566 				     len - (sizeof(struct wpa_tdls_frame) + 1),
1567 				     &kde) < 0) {
1568 		wpa_printf(MSG_DEBUG,
1569 			   "TDLS: Failed to parse IEs in Discovery Request - ignore as an interop workaround");
1570 	}
1571 
1572 	if (!kde.lnkid) {
1573 		wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery "
1574 			   "Request");
1575 		return -1;
1576 	}
1577 
1578 	lnkid = (const struct wpa_tdls_lnkid *) kde.lnkid;
1579 
1580 	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1581 		wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from different "
1582 			   " BSS " MACSTR, MAC2STR(lnkid->bssid));
1583 		return -1;
1584 	}
1585 
1586 	peer = wpa_tdls_add_peer(sm, addr, NULL);
1587 	if (peer == NULL)
1588 		return -1;
1589 
1590 	return wpa_tdls_send_discovery_response(sm, peer, dialog_token);
1591 }
1592 
1593 
wpa_tdls_send_discovery_request(struct wpa_sm * sm,const u8 * addr)1594 int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
1595 {
1596 	if (sm->tdls_disabled || !sm->tdls_supported)
1597 		return -1;
1598 
1599 	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
1600 		   MACSTR, MAC2STR(addr));
1601 	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
1602 				 1, 0, 0, 1, NULL, 0);
1603 }
1604 
1605 
copy_supp_rates(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1606 static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
1607 			   struct wpa_tdls_peer *peer)
1608 {
1609 	if (!kde->supp_rates) {
1610 		wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
1611 		return -1;
1612 	}
1613 	peer->supp_rates_len = merge_byte_arrays(
1614 		peer->supp_rates, sizeof(peer->supp_rates),
1615 		kde->supp_rates + 2, kde->supp_rates_len - 2,
1616 		kde->ext_supp_rates ? kde->ext_supp_rates + 2 : NULL,
1617 		kde->ext_supp_rates ? kde->ext_supp_rates_len - 2 : 0);
1618 	return 0;
1619 }
1620 
1621 
copy_peer_ht_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1622 static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde,
1623 			      struct wpa_tdls_peer *peer)
1624 {
1625 	if (!kde->ht_capabilities) {
1626 		wpa_printf(MSG_DEBUG, "TDLS: No supported ht capabilities "
1627 			   "received");
1628 		return 0;
1629 	}
1630 
1631 	if (!peer->ht_capabilities) {
1632 		peer->ht_capabilities =
1633                         os_zalloc(sizeof(struct ieee80211_ht_capabilities));
1634 		if (peer->ht_capabilities == NULL)
1635                         return -1;
1636 	}
1637 
1638 	os_memcpy(peer->ht_capabilities, kde->ht_capabilities,
1639                   sizeof(struct ieee80211_ht_capabilities));
1640 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer HT capabilities",
1641 		    (u8 *) peer->ht_capabilities,
1642 		    sizeof(struct ieee80211_ht_capabilities));
1643 
1644 	return 0;
1645 }
1646 
1647 
copy_peer_vht_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1648 static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
1649 			      struct wpa_tdls_peer *peer)
1650 {
1651 	if (!kde->vht_capabilities) {
1652 		wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
1653 			   "received");
1654 		return 0;
1655 	}
1656 
1657 	if (!peer->vht_capabilities) {
1658 		peer->vht_capabilities =
1659                         os_zalloc(sizeof(struct ieee80211_vht_capabilities));
1660 		if (peer->vht_capabilities == NULL)
1661                         return -1;
1662 	}
1663 
1664 	os_memcpy(peer->vht_capabilities, kde->vht_capabilities,
1665                   sizeof(struct ieee80211_vht_capabilities));
1666 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities",
1667 		    (u8 *) peer->vht_capabilities,
1668 		    sizeof(struct ieee80211_vht_capabilities));
1669 
1670 	return 0;
1671 }
1672 
1673 
copy_peer_he_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1674 static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde,
1675 			      struct wpa_tdls_peer *peer)
1676 {
1677 	if (!kde->he_capabilities) {
1678 		wpa_printf(MSG_DEBUG, "TDLS: No HE capabilities received");
1679 		return 0;
1680 	}
1681 
1682 	os_free(peer->he_capabilities);
1683 	peer->he_capab_len = 0;
1684 	peer->he_capabilities = os_memdup(kde->he_capabilities,
1685 					  kde->he_capab_len);
1686 	if (!peer->he_capabilities)
1687 		return -1;
1688 
1689 	peer->he_capab_len = kde->he_capab_len;
1690 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer HE capabilities",
1691 		    peer->he_capabilities, peer->he_capab_len);
1692 
1693 	return 0;
1694 }
1695 
1696 
copy_peer_he_6ghz_band_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1697 static int copy_peer_he_6ghz_band_capab(const struct wpa_eapol_ie_parse *kde,
1698 					struct wpa_tdls_peer *peer)
1699 {
1700 	if (!kde->he_6ghz_capabilities) {
1701 		wpa_printf(MSG_DEBUG,
1702 			   "TDLS: No HE 6 GHz band capabilities received");
1703 		return 0;
1704 	}
1705 
1706 	if (!peer->he_6ghz_band_capabilities) {
1707 		peer->he_6ghz_band_capabilities =
1708 			os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap));
1709 		if (peer->he_6ghz_band_capabilities == NULL)
1710 			return -1;
1711 	}
1712 
1713 	os_memcpy(peer->he_6ghz_band_capabilities, kde->he_6ghz_capabilities,
1714 		  sizeof(struct ieee80211_he_6ghz_band_cap));
1715 
1716 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer 6 GHz band HE capabilities",
1717 		    peer->he_6ghz_band_capabilities,
1718 		    sizeof(struct ieee80211_he_6ghz_band_cap));
1719 
1720 	return 0;
1721 }
1722 
1723 
copy_peer_ext_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1724 static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
1725 			       struct wpa_tdls_peer *peer)
1726 {
1727 	if (!kde->ext_capab) {
1728 		wpa_printf(MSG_DEBUG, "TDLS: No extended capabilities "
1729 			   "received");
1730 		return 0;
1731 	}
1732 
1733 	if (!peer->ext_capab || peer->ext_capab_len < kde->ext_capab_len - 2) {
1734 		/* Need to allocate buffer to fit the new information */
1735 		os_free(peer->ext_capab);
1736 		peer->ext_capab = os_zalloc(kde->ext_capab_len - 2);
1737 		if (peer->ext_capab == NULL)
1738 			return -1;
1739 	}
1740 
1741 	peer->ext_capab_len = kde->ext_capab_len - 2;
1742 	os_memcpy(peer->ext_capab, kde->ext_capab + 2, peer->ext_capab_len);
1743 
1744 	return 0;
1745 }
1746 
1747 
copy_peer_wmm_capab(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1748 static int copy_peer_wmm_capab(const struct wpa_eapol_ie_parse *kde,
1749 			       struct wpa_tdls_peer *peer)
1750 {
1751 	struct wmm_information_element *wmm;
1752 
1753 	if (!kde->wmm) {
1754 		wpa_printf(MSG_DEBUG, "TDLS: No supported WMM capabilities received");
1755 		return 0;
1756 	}
1757 
1758 	if (kde->wmm_len < sizeof(struct wmm_information_element)) {
1759 		wpa_printf(MSG_DEBUG, "TDLS: Invalid supported WMM capabilities received");
1760 		return -1;
1761 	}
1762 
1763 	wmm = (struct wmm_information_element *) kde->wmm;
1764 	peer->qos_info = wmm->qos_info;
1765 
1766 	peer->wmm_capable = 1;
1767 
1768 	wpa_printf(MSG_DEBUG, "TDLS: Peer WMM QOS Info 0x%x", peer->qos_info);
1769 	return 0;
1770 }
1771 
1772 
copy_peer_supp_channels(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1773 static int copy_peer_supp_channels(const struct wpa_eapol_ie_parse *kde,
1774 				   struct wpa_tdls_peer *peer)
1775 {
1776 	if (!kde->supp_channels) {
1777 		wpa_printf(MSG_DEBUG, "TDLS: No supported channels received");
1778 		return 0;
1779 	}
1780 
1781 	if (!peer->supp_channels ||
1782 	    peer->supp_channels_len < kde->supp_channels_len) {
1783 		os_free(peer->supp_channels);
1784 		peer->supp_channels = os_zalloc(kde->supp_channels_len);
1785 		if (peer->supp_channels == NULL)
1786 			return -1;
1787 	}
1788 
1789 	peer->supp_channels_len = kde->supp_channels_len;
1790 
1791 	os_memcpy(peer->supp_channels, kde->supp_channels,
1792 		  peer->supp_channels_len);
1793 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Channels",
1794 		    (u8 *) peer->supp_channels, peer->supp_channels_len);
1795 	return 0;
1796 }
1797 
1798 
copy_peer_supp_oper_classes(const struct wpa_eapol_ie_parse * kde,struct wpa_tdls_peer * peer)1799 static int copy_peer_supp_oper_classes(const struct wpa_eapol_ie_parse *kde,
1800 				       struct wpa_tdls_peer *peer)
1801 {
1802 	if (!kde->supp_oper_classes) {
1803 		wpa_printf(MSG_DEBUG, "TDLS: No supported operating classes received");
1804 		return 0;
1805 	}
1806 
1807 	if (!peer->supp_oper_classes ||
1808 	    peer->supp_oper_classes_len < kde->supp_oper_classes_len) {
1809 		os_free(peer->supp_oper_classes);
1810 		peer->supp_oper_classes = os_zalloc(kde->supp_oper_classes_len);
1811 		if (peer->supp_oper_classes == NULL)
1812 			return -1;
1813 	}
1814 
1815 	peer->supp_oper_classes_len = kde->supp_oper_classes_len;
1816 	os_memcpy(peer->supp_oper_classes, kde->supp_oper_classes,
1817 		  peer->supp_oper_classes_len);
1818 	wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Operating Classes",
1819 		    (u8 *) peer->supp_oper_classes,
1820 		    peer->supp_oper_classes_len);
1821 	return 0;
1822 }
1823 
1824 
wpa_tdls_addset_peer(struct wpa_sm * sm,struct wpa_tdls_peer * peer,int add)1825 static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
1826 				int add)
1827 {
1828 	return wpa_sm_tdls_peer_addset(sm, peer->addr, add, peer->aid,
1829 				       peer->capability,
1830 				       peer->supp_rates, peer->supp_rates_len,
1831 				       peer->ht_capabilities,
1832 				       peer->vht_capabilities,
1833 				       peer->he_capabilities,
1834 				       peer->he_capab_len,
1835 				       peer->he_6ghz_band_capabilities,
1836 				       peer->qos_info, peer->wmm_capable,
1837 				       peer->ext_capab, peer->ext_capab_len,
1838 				       peer->supp_channels,
1839 				       peer->supp_channels_len,
1840 				       peer->supp_oper_classes,
1841 				       peer->supp_oper_classes_len);
1842 }
1843 
1844 
tdls_nonce_set(const u8 * nonce)1845 static int tdls_nonce_set(const u8 *nonce)
1846 {
1847 	int i;
1848 
1849 	for (i = 0; i < WPA_NONCE_LEN; i++) {
1850 		if (nonce[i])
1851 			return 1;
1852 	}
1853 
1854 	return 0;
1855 }
1856 
1857 
wpa_tdls_process_tpk_m1(struct wpa_sm * sm,const u8 * src_addr,const u8 * buf,size_t len)1858 static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
1859 				   const u8 *buf, size_t len)
1860 {
1861 	struct wpa_tdls_peer *peer;
1862 	struct wpa_eapol_ie_parse kde;
1863 	struct wpa_ie_data ie;
1864 	int cipher;
1865 	const u8 *cpos;
1866 	struct wpa_tdls_ftie *ftie = NULL;
1867 	struct wpa_tdls_timeoutie *timeoutie;
1868 	struct wpa_tdls_lnkid *lnkid;
1869 	u32 lifetime = 0;
1870 #if 0
1871 	struct rsn_ie_hdr *hdr;
1872 	u8 *pos;
1873 	u16 rsn_capab;
1874 	u16 rsn_ver;
1875 #endif
1876 	u8 dtoken;
1877 	u16 ielen;
1878 	u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1879 	int tdls_prohibited = sm->tdls_prohibited;
1880 	int existing_peer = 0;
1881 
1882 	if (len < 3 + 3)
1883 		return -1;
1884 
1885 	cpos = buf;
1886 	cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1887 
1888 	/* driver had already verified the frame format */
1889 	dtoken = *cpos++; /* dialog token */
1890 
1891 	wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
1892 
1893 	peer = wpa_tdls_add_peer(sm, src_addr, &existing_peer);
1894 	if (peer == NULL)
1895 		goto error;
1896 
1897 	/* If found, use existing entry instead of adding a new one;
1898 	 * how to handle the case where both ends initiate at the
1899 	 * same time? */
1900 	if (existing_peer) {
1901 		if (peer->tpk_success) {
1902 			wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
1903 				   "direct link is enabled - tear down the "
1904 				   "old link first");
1905 			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
1906 			wpa_tdls_peer_clear(sm, peer);
1907 		} else if (peer->initiator) {
1908 			/*
1909 			 * An entry is already present, so check if we already
1910 			 * sent a TDLS Setup Request. If so, compare MAC
1911 			 * addresses and let the STA with the lower MAC address
1912 			 * continue as the initiator. The other negotiation is
1913 			 * terminated.
1914 			 */
1915 			if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
1916 				wpa_printf(MSG_DEBUG, "TDLS: Discard request "
1917 					   "from peer with higher address "
1918 					   MACSTR, MAC2STR(src_addr));
1919 				return -1;
1920 			} else {
1921 				wpa_printf(MSG_DEBUG, "TDLS: Accept request "
1922 					   "from peer with lower address "
1923 					   MACSTR " (terminate previously "
1924 					   "initiated negotiation",
1925 					   MAC2STR(src_addr));
1926 				wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
1927 						 peer->addr);
1928 				wpa_tdls_peer_clear(sm, peer);
1929 			}
1930 		}
1931 	}
1932 
1933 	/* capability information */
1934 	peer->capability = WPA_GET_LE16(cpos);
1935 	cpos += 2;
1936 
1937 	ielen = len - (cpos - buf); /* start of IE in buf */
1938 
1939 	/*
1940 	 * Don't reject the message if failing to parse IEs. The IEs we need are
1941 	 * explicitly checked below. Some APs may add arbitrary padding to the
1942 	 * end of short TDLS frames and that would look like invalid IEs.
1943 	 */
1944 	if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0)
1945 		wpa_printf(MSG_DEBUG,
1946 			   "TDLS: Failed to parse IEs in TPK M1 - ignore as an interop workaround");
1947 
1948 	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1949 		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1950 			   "TPK M1");
1951 		goto error;
1952 	}
1953 	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
1954 		    kde.lnkid, kde.lnkid_len);
1955 	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1956 	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1957 		wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
1958 		status = WLAN_STATUS_REQUEST_DECLINED;
1959 		goto error;
1960 	}
1961 
1962 	wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
1963 		   MAC2STR(src_addr));
1964 
1965 	if (copy_supp_rates(&kde, peer) < 0)
1966 		goto error;
1967 
1968 	if (copy_peer_ht_capab(&kde, peer) < 0)
1969 		goto error;
1970 
1971 	if (copy_peer_vht_capab(&kde, peer) < 0 ||
1972 	    copy_peer_he_capab(&kde, peer) < 0 ||
1973 	    copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
1974 		goto error;
1975 
1976 	if (copy_peer_ext_capab(&kde, peer) < 0)
1977 		goto error;
1978 
1979 	if (copy_peer_supp_channels(&kde, peer) < 0)
1980 		goto error;
1981 
1982 	if (copy_peer_supp_oper_classes(&kde, peer) < 0)
1983 		goto error;
1984 
1985 	peer->qos_info = kde.qosinfo;
1986 
1987 	/* Overwrite with the qos_info obtained in WMM IE */
1988 	if (copy_peer_wmm_capab(&kde, peer) < 0)
1989 		goto error;
1990 
1991 	peer->aid = kde.aid;
1992 
1993 #ifdef CONFIG_TDLS_TESTING
1994 	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1995 		peer = wpa_tdls_add_peer(sm, src_addr, NULL);
1996 		if (peer == NULL)
1997 			goto error;
1998 		wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
1999 			   "TDLS setup - send own request");
2000 		peer->initiator = 1;
2001 		wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
2002 					NULL, NULL, 0, NULL, 0, 0, NULL, 0,
2003 					NULL, 0, NULL, 0);
2004 		if (wpa_tdls_send_tpk_m1(sm, peer) == -2) {
2005 			peer = NULL;
2006 			goto error;
2007 		}
2008 	}
2009 
2010 	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2011 	    tdls_prohibited) {
2012 		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2013 			   "on TDLS");
2014 		tdls_prohibited = 0;
2015 	}
2016 #endif /* CONFIG_TDLS_TESTING */
2017 
2018 	if (tdls_prohibited) {
2019 		wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
2020 		status = WLAN_STATUS_REQUEST_DECLINED;
2021 		goto error;
2022 	}
2023 
2024 	if (!wpa_tdls_get_privacy(sm)) {
2025 		if (kde.rsn_ie) {
2026 			wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
2027 				   "security is disabled");
2028 			status = WLAN_STATUS_SECURITY_DISABLED;
2029 			goto error;
2030 		}
2031 		goto skip_rsn;
2032 	}
2033 
2034 	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
2035 	    kde.rsn_ie == NULL) {
2036 		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
2037 		status = WLAN_STATUS_INVALID_PARAMETERS;
2038 		goto error;
2039 	}
2040 
2041 	if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
2042 		wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
2043 			   "TPK M1");
2044 		status = WLAN_STATUS_INVALID_RSNIE;
2045 		goto error;
2046 	}
2047 
2048 	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
2049 		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
2050 		status = WLAN_STATUS_INVALID_RSNIE;
2051 		goto error;
2052 	}
2053 
2054 	cipher = ie.pairwise_cipher;
2055 	if (cipher & WPA_CIPHER_CCMP) {
2056 		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
2057 		cipher = WPA_CIPHER_CCMP;
2058 	} else {
2059 		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
2060 		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2061 		goto error;
2062 	}
2063 
2064 	if ((ie.capabilities &
2065 	     (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
2066 	    WPA_CAPABILITY_PEERKEY_ENABLED) {
2067 		wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
2068 			   "TPK M1");
2069 		status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
2070 		goto error;
2071 	}
2072 
2073 	/* Lifetime */
2074 	if (kde.key_lifetime == NULL) {
2075 		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
2076 		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2077 		goto error;
2078 	}
2079 	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
2080 	lifetime = WPA_GET_LE32(timeoutie->value);
2081 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
2082 	if (lifetime < 300) {
2083 		wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
2084 		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2085 		goto error;
2086 	}
2087 
2088 skip_rsn:
2089 #ifdef CONFIG_TDLS_TESTING
2090 	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
2091 		if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
2092 			/*
2093 			 * The request frame from us is going to win, so do not
2094 			 * replace information based on this request frame from
2095 			 * the peer.
2096 			 */
2097 			goto skip_rsn_check;
2098 		}
2099 	}
2100 #endif /* CONFIG_TDLS_TESTING */
2101 
2102 	peer->initiator = 0; /* Need to check */
2103 	peer->dtoken = dtoken;
2104 
2105 	if (!wpa_tdls_get_privacy(sm)) {
2106 		peer->rsnie_i_len = 0;
2107 		peer->rsnie_p_len = 0;
2108 		peer->cipher = WPA_CIPHER_NONE;
2109 		goto skip_rsn_check;
2110 	}
2111 
2112 	ftie = (struct wpa_tdls_ftie *) kde.ftie;
2113 	os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
2114 	peer->rsnie_i_len = kde.rsn_ie_len;
2115 	peer->cipher = cipher;
2116 
2117 	if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 ||
2118 	    !tdls_nonce_set(peer->inonce)) {
2119 		/*
2120 		 * There is no point in updating the RNonce for every obtained
2121 		 * TPK M1 frame (e.g., retransmission due to timeout) with the
2122 		 * same INonce (SNonce in FTIE). However, if the TPK M1 is
2123 		 * retransmitted with a different INonce, update the RNonce
2124 		 * since this is for a new TDLS session.
2125 		 */
2126 		wpa_printf(MSG_DEBUG,
2127 			   "TDLS: New TPK M1 INonce - generate new RNonce");
2128 		os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
2129 		if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
2130 			wpa_msg(sm->ctx->ctx, MSG_WARNING,
2131 				"TDLS: Failed to get random data for responder nonce");
2132 			goto error;
2133 		}
2134 		peer->tk_set = 0; /* A new nonce results in a new TK */
2135 	}
2136 
2137 #if 0
2138 	/* get version info from RSNIE received from Peer */
2139 	hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
2140 	rsn_ver = WPA_GET_LE16(hdr->version);
2141 
2142 	/* use min(peer's version, out version) */
2143 	if (rsn_ver > RSN_VERSION)
2144 		rsn_ver = RSN_VERSION;
2145 
2146 	hdr = (struct rsn_ie_hdr *) peer->rsnie_p;
2147 
2148 	hdr->elem_id = WLAN_EID_RSN;
2149 	WPA_PUT_LE16(hdr->version, rsn_ver);
2150 	pos = (u8 *) (hdr + 1);
2151 
2152 	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
2153 	pos += RSN_SELECTOR_LEN;
2154 	/* Include only the selected cipher in pairwise cipher suite */
2155 	WPA_PUT_LE16(pos, 1);
2156 	pos += 2;
2157 	if (cipher == WPA_CIPHER_CCMP)
2158 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
2159 	pos += RSN_SELECTOR_LEN;
2160 
2161 	WPA_PUT_LE16(pos, 1);
2162 	pos += 2;
2163 	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
2164 	pos += RSN_SELECTOR_LEN;
2165 
2166 	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
2167 	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
2168 	WPA_PUT_LE16(pos, rsn_capab);
2169 	pos += 2;
2170 
2171 	hdr->len = (pos - peer->rsnie_p) - 2;
2172 	peer->rsnie_p_len = pos - peer->rsnie_p;
2173 #endif
2174 
2175 	/* temp fix: validation of RSNIE later */
2176 	os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
2177 	peer->rsnie_p_len = peer->rsnie_i_len;
2178 
2179 	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
2180 		    peer->rsnie_p, peer->rsnie_p_len);
2181 
2182 	peer->lifetime = lifetime;
2183 
2184 	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
2185 
2186 skip_rsn_check:
2187 #ifdef CONFIG_TDLS_TESTING
2188 	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT)
2189 		goto skip_add_peer;
2190 #endif /* CONFIG_TDLS_TESTING */
2191 
2192 	/* add supported rates, capabilities, and qos_info to the TDLS peer */
2193 	if (wpa_tdls_addset_peer(sm, peer, 1) < 0)
2194 		goto error;
2195 
2196 #ifdef CONFIG_TDLS_TESTING
2197 skip_add_peer:
2198 #endif /* CONFIG_TDLS_TESTING */
2199 	peer->tpk_in_progress = 1;
2200 
2201 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
2202 	if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
2203 		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2204 		goto error;
2205 	}
2206 
2207 #ifdef CONFIG_TDLS_TESTING
2208 	if (tdls_testing & TDLS_TESTING_DOUBLE_TPK_M2) {
2209 		wpa_printf(MSG_INFO, "TDLS: Testing - Send another TPK M2");
2210 		wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer);
2211 	}
2212 #endif /* CONFIG_TDLS_TESTING */
2213 
2214 	return 0;
2215 
2216 error:
2217 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
2218 			    status);
2219 	if (peer)
2220 		wpa_tdls_peer_free(sm, peer);
2221 	return -1;
2222 }
2223 
2224 
wpa_tdls_enable_link(struct wpa_sm * sm,struct wpa_tdls_peer * peer)2225 static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
2226 {
2227 	peer->tpk_success = 1;
2228 	peer->tpk_in_progress = 0;
2229 	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
2230 	if (wpa_tdls_get_privacy(sm)) {
2231 		u32 lifetime = peer->lifetime;
2232 		/*
2233 		 * Start the initiator process a bit earlier to avoid race
2234 		 * condition with the responder sending teardown request.
2235 		 */
2236 		if (lifetime > 3 && peer->initiator)
2237 			lifetime -= 3;
2238 		eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
2239 				       sm, peer);
2240 #ifdef CONFIG_TDLS_TESTING
2241 		if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
2242 			wpa_printf(MSG_DEBUG,
2243 				   "TDLS: Testing - disable TPK expiration");
2244 			eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
2245 		}
2246 #endif /* CONFIG_TDLS_TESTING */
2247 	}
2248 
2249 	if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) {
2250 		wpa_printf(MSG_INFO, "TDLS: Could not configure key to the "
2251 			   "driver");
2252 		return -1;
2253 	}
2254 	peer->reconfig_key = 0;
2255 
2256 	return wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
2257 }
2258 
2259 
wpa_tdls_process_tpk_m2(struct wpa_sm * sm,const u8 * src_addr,const u8 * buf,size_t len)2260 static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
2261 				   const u8 *buf, size_t len)
2262 {
2263 	struct wpa_tdls_peer *peer;
2264 	struct wpa_eapol_ie_parse kde;
2265 	struct wpa_ie_data ie;
2266 	int cipher;
2267 	struct wpa_tdls_ftie *ftie;
2268 	struct wpa_tdls_timeoutie *timeoutie;
2269 	struct wpa_tdls_lnkid *lnkid;
2270 	u32 lifetime;
2271 	u8 dtoken;
2272 	int ielen;
2273 	u16 status;
2274 	const u8 *pos;
2275 	int ret = 0;
2276 
2277 	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
2278 		   "(Peer " MACSTR ")", MAC2STR(src_addr));
2279 	for (peer = sm->tdls; peer; peer = peer->next) {
2280 		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
2281 			break;
2282 	}
2283 	if (peer == NULL) {
2284 		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
2285 			   "TPK M2: " MACSTR, MAC2STR(src_addr));
2286 		return -1;
2287 	}
2288 	if (!peer->initiator) {
2289 		/*
2290 		 * This may happen if both devices try to initiate TDLS at the
2291 		 * same time and we accept the TPK M1 from the peer in
2292 		 * wpa_tdls_process_tpk_m1() and clear our previous state.
2293 		 */
2294 		wpa_printf(MSG_INFO, "TDLS: We were not the initiator, so "
2295 			   "ignore TPK M2 from " MACSTR, MAC2STR(src_addr));
2296 		return -1;
2297 	}
2298 
2299 	if (peer->tpk_success) {
2300 		wpa_printf(MSG_INFO, "TDLS: Ignore incoming TPK M2 retry, from "
2301 			   MACSTR " as TPK M3 was already sent",
2302 			   MAC2STR(src_addr));
2303 		return 0;
2304 	}
2305 
2306 	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
2307 
2308 	if (len < 3 + 2 + 1) {
2309 		wpa_tdls_disable_peer_link(sm, peer);
2310 		return -1;
2311 	}
2312 
2313 	pos = buf;
2314 	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
2315 	status = WPA_GET_LE16(pos);
2316 	pos += 2 /* status code */;
2317 
2318 	if (status != WLAN_STATUS_SUCCESS) {
2319 		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
2320 			   status);
2321 		wpa_tdls_disable_peer_link(sm, peer);
2322 		return -1;
2323 	}
2324 
2325 	status = WLAN_STATUS_UNSPECIFIED_FAILURE;
2326 
2327 	/* TODO: need to verify dialog token matches here or in kernel */
2328 	dtoken = *pos++; /* dialog token */
2329 
2330 	wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
2331 
2332 	if (len < 3 + 2 + 1 + 2) {
2333 		wpa_tdls_disable_peer_link(sm, peer);
2334 		return -1;
2335 	}
2336 
2337 	/* capability information */
2338 	peer->capability = WPA_GET_LE16(pos);
2339 	pos += 2;
2340 
2341 	ielen = len - (pos - buf); /* start of IE in buf */
2342 
2343 	/*
2344 	 * Don't reject the message if failing to parse IEs. The IEs we need are
2345 	 * explicitly checked below. Some APs may add arbitrary padding to the
2346 	 * end of short TDLS frames and that would look like invalid IEs.
2347 	 */
2348 	if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0)
2349 		wpa_printf(MSG_DEBUG,
2350 			   "TDLS: Failed to parse IEs in TPK M2 - ignore as an interop workaround");
2351 
2352 #ifdef CONFIG_TDLS_TESTING
2353 	if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
2354 		wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
2355 		status = WLAN_STATUS_REQUEST_DECLINED;
2356 		goto error;
2357 	}
2358 #endif /* CONFIG_TDLS_TESTING */
2359 
2360 	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
2361 		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
2362 			   "TPK M2");
2363 		goto error;
2364 	}
2365 	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
2366 		    kde.lnkid, kde.lnkid_len);
2367 	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
2368 
2369 	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
2370 		wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
2371 		status = WLAN_STATUS_NOT_IN_SAME_BSS;
2372 		goto error;
2373 	}
2374 
2375 	if (copy_supp_rates(&kde, peer) < 0)
2376 		goto error;
2377 
2378 	if (copy_peer_ht_capab(&kde, peer) < 0)
2379 		goto error;
2380 
2381 	if (copy_peer_vht_capab(&kde, peer) < 0 ||
2382 	    copy_peer_he_capab(&kde, peer) < 0 ||
2383 	    copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
2384 		goto error;
2385 
2386 	if (copy_peer_ext_capab(&kde, peer) < 0)
2387 		goto error;
2388 
2389 	if (copy_peer_supp_channels(&kde, peer) < 0)
2390 		goto error;
2391 
2392 	if (copy_peer_supp_oper_classes(&kde, peer) < 0)
2393 		goto error;
2394 
2395 	peer->qos_info = kde.qosinfo;
2396 
2397 	/* Overwrite with the qos_info obtained in WMM IE */
2398 	if (copy_peer_wmm_capab(&kde, peer) < 0)
2399 		goto error;
2400 
2401 	peer->aid = kde.aid;
2402 
2403 	if (!wpa_tdls_get_privacy(sm)) {
2404 		peer->rsnie_p_len = 0;
2405 		peer->cipher = WPA_CIPHER_NONE;
2406 		goto skip_rsn;
2407 	}
2408 
2409 	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
2410 	    kde.rsn_ie == NULL) {
2411 		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
2412 		status = WLAN_STATUS_INVALID_PARAMETERS;
2413 		goto error;
2414 	}
2415 	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
2416 		    kde.rsn_ie, kde.rsn_ie_len);
2417 
2418 	if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
2419 		wpa_printf(MSG_INFO,
2420 			   "TDLS: Too long Responder RSN IE in TPK M2");
2421 		status = WLAN_STATUS_INVALID_RSNIE;
2422 		goto error;
2423 	}
2424 
2425 	/*
2426 	 * FIX: bitwise comparison of RSN IE is not the correct way of
2427 	 * validation this. It can be different, but certain fields must
2428 	 * match. Since we list only a single pairwise cipher in TPK M1, the
2429 	 * memcmp is likely to work in most cases, though.
2430 	 */
2431 	if (kde.rsn_ie_len != peer->rsnie_i_len ||
2432 	    os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
2433 		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
2434 			   "not match with RSN IE used in TPK M1");
2435 		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
2436 			    peer->rsnie_i, peer->rsnie_i_len);
2437 		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
2438 			    kde.rsn_ie, kde.rsn_ie_len);
2439 		status = WLAN_STATUS_INVALID_RSNIE;
2440 		goto error;
2441 	}
2442 
2443 	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
2444 		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
2445 		status = WLAN_STATUS_INVALID_RSNIE;
2446 		goto error;
2447 	}
2448 
2449 	cipher = ie.pairwise_cipher;
2450 	if (cipher == WPA_CIPHER_CCMP) {
2451 		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
2452 		cipher = WPA_CIPHER_CCMP;
2453 	} else {
2454 		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
2455 		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2456 		goto error;
2457 	}
2458 
2459 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
2460 		    kde.ftie, sizeof(*ftie));
2461 	ftie = (struct wpa_tdls_ftie *) kde.ftie;
2462 
2463 	if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) {
2464 		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
2465 			   "not match with FTIE SNonce used in TPK M1");
2466 		/* Silently discard the frame */
2467 		return -1;
2468 	}
2469 
2470 	/* Responder Nonce and RSN IE */
2471 	os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
2472 	os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
2473 	peer->rsnie_p_len = kde.rsn_ie_len;
2474 	peer->cipher = cipher;
2475 
2476 	/* Lifetime */
2477 	if (kde.key_lifetime == NULL) {
2478 		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
2479 		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2480 		goto error;
2481 	}
2482 	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
2483 	lifetime = WPA_GET_LE32(timeoutie->value);
2484 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
2485 		   lifetime);
2486 	if (lifetime != peer->lifetime) {
2487 		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2488 			   "TPK M2 (expected %u)", lifetime, peer->lifetime);
2489 		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2490 		goto error;
2491 	}
2492 
2493 	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
2494 
2495 	/* Process MIC check to see if TPK M2 is right */
2496 	if (wpa_supplicant_verify_tdls_mic(2, peer, (const u8 *) lnkid,
2497 					   (const u8 *) timeoutie, ftie,
2498 					   kde.ftie_len) < 0) {
2499 		/* Discard the frame */
2500 		wpa_tdls_del_key(sm, peer);
2501 		wpa_tdls_disable_peer_link(sm, peer);
2502 		return -1;
2503 	}
2504 
2505 	if (wpa_tdls_set_key(sm, peer) < 0) {
2506 		/*
2507 		 * Some drivers may not be able to config the key prior to full
2508 		 * STA entry having been configured.
2509 		 */
2510 		wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
2511 			   "STA entry is complete");
2512 		peer->reconfig_key = 1;
2513 	}
2514 
2515 skip_rsn:
2516 	peer->dtoken = dtoken;
2517 
2518 	/* add supported rates, capabilities, and qos_info to the TDLS peer */
2519 	if (wpa_tdls_addset_peer(sm, peer, 0) < 0)
2520 		goto error;
2521 
2522 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
2523 		   "TPK Handshake Message 3");
2524 	if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0)
2525 		goto error_no_msg;
2526 
2527 	if (!peer->tpk_success) {
2528 		/*
2529 		 * Enable Link only when tpk_success is 0, signifying that this
2530 		 * processing of TPK M2 frame is not because of a retransmission
2531 		 * during TDLS setup handshake.
2532 		 */
2533 		ret = wpa_tdls_enable_link(sm, peer);
2534 		if (ret < 0) {
2535 			wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
2536 			wpa_tdls_do_teardown(
2537 				sm, peer,
2538 				WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2539 		}
2540 	}
2541 	return ret;
2542 
2543 error:
2544 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 1,
2545 			    status);
2546 error_no_msg:
2547 	wpa_tdls_disable_peer_link(sm, peer);
2548 	return -1;
2549 }
2550 
2551 
wpa_tdls_process_tpk_m3(struct wpa_sm * sm,const u8 * src_addr,const u8 * buf,size_t len)2552 static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
2553 				   const u8 *buf, size_t len)
2554 {
2555 	struct wpa_tdls_peer *peer;
2556 	struct wpa_eapol_ie_parse kde;
2557 	struct wpa_tdls_ftie *ftie;
2558 	struct wpa_tdls_timeoutie *timeoutie;
2559 	struct wpa_tdls_lnkid *lnkid;
2560 	int ielen;
2561 	u16 status;
2562 	const u8 *pos;
2563 	u32 lifetime;
2564 	int ret = 0;
2565 
2566 	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
2567 		   "(Peer " MACSTR ")", MAC2STR(src_addr));
2568 	for (peer = sm->tdls; peer; peer = peer->next) {
2569 		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
2570 			break;
2571 	}
2572 	if (peer == NULL) {
2573 		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
2574 			   "TPK M3: " MACSTR, MAC2STR(src_addr));
2575 		return -1;
2576 	}
2577 	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
2578 
2579 	if (len < 3 + 3)
2580 		goto error;
2581 	pos = buf;
2582 	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
2583 
2584 	status = WPA_GET_LE16(pos);
2585 
2586 	if (status != 0) {
2587 		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
2588 			   status);
2589 		goto error;
2590 	}
2591 	pos += 2 /* status code */ + 1 /* dialog token */;
2592 
2593 	ielen = len - (pos - buf); /* start of IE in buf */
2594 
2595 	/*
2596 	 * Don't reject the message if failing to parse IEs. The IEs we need are
2597 	 * explicitly checked below. Some APs piggy-back broken IEs to the end
2598 	 * of a TDLS Confirm packet, which will fail the link if we don't ignore
2599 	 * this error.
2600 	 */
2601 	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
2602 		wpa_printf(MSG_DEBUG,
2603 			   "TDLS: Failed to parse KDEs in TPK M3 - ignore as an interop workaround");
2604 	}
2605 
2606 	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
2607 		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
2608 		goto error;
2609 	}
2610 	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
2611 		    (u8 *) kde.lnkid, kde.lnkid_len);
2612 	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
2613 
2614 	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
2615 		wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
2616 		goto error;
2617 	}
2618 
2619 	if (!wpa_tdls_get_privacy(sm))
2620 		goto skip_rsn;
2621 
2622 	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
2623 		wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
2624 		goto error;
2625 	}
2626 	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
2627 		    kde.ftie, sizeof(*ftie));
2628 	ftie = (struct wpa_tdls_ftie *) kde.ftie;
2629 
2630 	if (kde.rsn_ie == NULL) {
2631 		wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
2632 		goto error;
2633 	}
2634 	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
2635 		    kde.rsn_ie, kde.rsn_ie_len);
2636 	if (kde.rsn_ie_len != peer->rsnie_p_len ||
2637 	    os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
2638 		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
2639 			   "with the one sent in TPK M2");
2640 		goto error;
2641 	}
2642 
2643 	if (os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) != 0) {
2644 		wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
2645 			   "not match with FTIE ANonce used in TPK M2");
2646 		goto error;
2647 	}
2648 
2649 	if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) {
2650 		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
2651 			   "match with FTIE SNonce used in TPK M1");
2652 		goto error;
2653 	}
2654 
2655 	if (kde.key_lifetime == NULL) {
2656 		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
2657 		goto error;
2658 	}
2659 	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
2660 	wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
2661 		    (u8 *) timeoutie, sizeof(*timeoutie));
2662 	lifetime = WPA_GET_LE32(timeoutie->value);
2663 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
2664 		   lifetime);
2665 	if (lifetime != peer->lifetime) {
2666 		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2667 			   "TPK M3 (expected %u)", lifetime, peer->lifetime);
2668 		goto error;
2669 	}
2670 
2671 	if (wpa_supplicant_verify_tdls_mic(3, peer, (const u8 *) lnkid,
2672 					   (const u8 *) timeoutie, ftie,
2673 					   kde.ftie_len) < 0) {
2674 		wpa_tdls_del_key(sm, peer);
2675 		goto error;
2676 	}
2677 
2678 	if (wpa_tdls_set_key(sm, peer) < 0) {
2679 		/*
2680 		 * Some drivers may not be able to config the key prior to full
2681 		 * STA entry having been configured.
2682 		 */
2683 		wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
2684 			   "STA entry is complete");
2685 		peer->reconfig_key = 1;
2686 	}
2687 
2688 skip_rsn:
2689 	/* add supported rates, capabilities, and qos_info to the TDLS peer */
2690 	if (wpa_tdls_addset_peer(sm, peer, 0) < 0)
2691 		goto error;
2692 
2693 	if (!peer->tpk_success) {
2694 		/*
2695 		 * Enable Link only when tpk_success is 0, signifying that this
2696 		 * processing of TPK M3 frame is not because of a retransmission
2697 		 * during TDLS setup handshake.
2698 		 */
2699 		ret = wpa_tdls_enable_link(sm, peer);
2700 		if (ret < 0) {
2701 			wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
2702 			goto error;
2703 		}
2704 	}
2705 	return ret;
2706 error:
2707 	wpa_tdls_do_teardown(sm, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2708 	return -1;
2709 }
2710 
2711 
wpa_add_tdls_timeoutie(u8 * pos,u8 * ie,size_t ie_len,u32 tsecs)2712 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
2713 {
2714 	struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;
2715 
2716 	os_memset(lifetime, 0, ie_len);
2717 	lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
2718 	lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
2719 	lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
2720 	WPA_PUT_LE32(lifetime->value, tsecs);
2721 	os_memcpy(pos, ie, ie_len);
2722 	return pos + ie_len;
2723 }
2724 
2725 
2726 /**
2727  * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2728  * @sm: Pointer to WPA state machine data from wpa_sm_init()
2729  * @peer: MAC address of the peer STA
2730  * Returns: 0 on success, or -1 on failure
2731  *
2732  * Send TPK Handshake Message 1 info to driver to start TDLS
2733  * handshake with the peer.
2734  */
wpa_tdls_start(struct wpa_sm * sm,const u8 * addr)2735 int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
2736 {
2737 	struct wpa_tdls_peer *peer;
2738 	int tdls_prohibited = sm->tdls_prohibited;
2739 	int res;
2740 
2741 	if (sm->tdls_disabled || !sm->tdls_supported)
2742 		return -1;
2743 
2744 #ifdef CONFIG_TDLS_TESTING
2745 	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2746 	    tdls_prohibited) {
2747 		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2748 			   "on TDLS");
2749 		tdls_prohibited = 0;
2750 	}
2751 #endif /* CONFIG_TDLS_TESTING */
2752 
2753 	if (tdls_prohibited) {
2754 		wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
2755 			   "reject request to start setup");
2756 		return -1;
2757 	}
2758 
2759 	peer = wpa_tdls_add_peer(sm, addr, NULL);
2760 	if (peer == NULL)
2761 		return -1;
2762 
2763 	if (peer->tpk_in_progress) {
2764 		wpa_printf(MSG_DEBUG, "TDLS: Setup is already in progress with the peer");
2765 		return 0;
2766 	}
2767 
2768 	peer->initiator = 1;
2769 
2770 	/* add the peer to the driver as a "setup in progress" peer */
2771 	if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
2772 				    NULL, NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0,
2773 				    NULL, 0)) {
2774 		wpa_tdls_disable_peer_link(sm, peer);
2775 		return -1;
2776 	}
2777 
2778 	peer->tpk_in_progress = 1;
2779 
2780 	res = wpa_tdls_send_tpk_m1(sm, peer);
2781 	if (res < 0) {
2782 		if (res != -2)
2783 			wpa_tdls_disable_peer_link(sm, peer);
2784 		return -1;
2785 	}
2786 
2787 	return 0;
2788 }
2789 
2790 
wpa_tdls_remove(struct wpa_sm * sm,const u8 * addr)2791 void wpa_tdls_remove(struct wpa_sm *sm, const u8 *addr)
2792 {
2793 	struct wpa_tdls_peer *peer;
2794 
2795 	if (sm->tdls_disabled || !sm->tdls_supported)
2796 		return;
2797 
2798 	for (peer = sm->tdls; peer; peer = peer->next) {
2799 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2800 			break;
2801 	}
2802 
2803 	if (peer == NULL || !peer->tpk_success)
2804 		return;
2805 
2806 	if (sm->tdls_external_setup) {
2807 		/*
2808 		 * Disable previous link to allow renegotiation to be completed
2809 		 * on AP path.
2810 		 */
2811 		wpa_tdls_do_teardown(sm, peer,
2812 				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2813 	}
2814 }
2815 
2816 
2817 /**
2818  * wpa_supplicant_rx_tdls - Receive TDLS data frame
2819  *
2820  * This function is called to receive TDLS (ethertype = 0x890d) data frames.
2821  */
wpa_supplicant_rx_tdls(void * ctx,const u8 * src_addr,const u8 * buf,size_t len)2822 static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
2823 				   const u8 *buf, size_t len)
2824 {
2825 	struct wpa_sm *sm = ctx;
2826 	struct wpa_tdls_frame *tf;
2827 
2828 	wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
2829 		    buf, len);
2830 
2831 	if (sm->tdls_disabled || !sm->tdls_supported) {
2832 		wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
2833 			   "or unsupported by driver");
2834 		return;
2835 	}
2836 
2837 	if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
2838 		wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
2839 		return;
2840 	}
2841 
2842 	if (len < sizeof(*tf)) {
2843 		wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
2844 		return;
2845 	}
2846 
2847 	/* Check to make sure its a valid encapsulated TDLS frame */
2848 	tf = (struct wpa_tdls_frame *) buf;
2849 	if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
2850 	    tf->category != WLAN_ACTION_TDLS) {
2851 		wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
2852 			   "category=%u action=%u",
2853 			   tf->payloadtype, tf->category, tf->action);
2854 		return;
2855 	}
2856 
2857 	switch (tf->action) {
2858 	case WLAN_TDLS_SETUP_REQUEST:
2859 		wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
2860 		break;
2861 	case WLAN_TDLS_SETUP_RESPONSE:
2862 		wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
2863 		break;
2864 	case WLAN_TDLS_SETUP_CONFIRM:
2865 		wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
2866 		break;
2867 	case WLAN_TDLS_TEARDOWN:
2868 		wpa_tdls_recv_teardown(sm, src_addr, buf, len);
2869 		break;
2870 	case WLAN_TDLS_DISCOVERY_REQUEST:
2871 		wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
2872 		break;
2873 	default:
2874 		/* Kernel code will process remaining frames */
2875 		wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
2876 			   tf->action);
2877 		break;
2878 	}
2879 }
2880 
2881 
2882 /**
2883  * wpa_tdls_init - Initialize driver interface parameters for TDLS
2884  * @wpa_s: Pointer to wpa_supplicant data
2885  * Returns: 0 on success, -1 on failure
2886  *
2887  * This function is called to initialize driver interface parameters for TDLS.
2888  * wpa_drv_init() must have been called before this function to initialize the
2889  * driver interface.
2890  */
wpa_tdls_init(struct wpa_sm * sm)2891 int wpa_tdls_init(struct wpa_sm *sm)
2892 {
2893 	if (sm == NULL)
2894 		return -1;
2895 
2896 	if (sm->l2_tdls) {
2897 		l2_packet_deinit(sm->l2_tdls);
2898 		sm->l2_tdls = NULL;
2899 	}
2900 
2901 	sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
2902 				     sm->ifname,
2903 				     sm->own_addr,
2904 				     ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
2905 				     sm, 0);
2906 	if (sm->l2_tdls == NULL) {
2907 		wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
2908 			   "connection");
2909 		return -1;
2910 	}
2911 
2912 	/*
2913 	 * Drivers that support TDLS but don't implement the get_capa callback
2914 	 * are assumed to perform everything internally
2915 	 */
2916 	if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
2917 				 &sm->tdls_external_setup,
2918 				 &sm->tdls_chan_switch) < 0) {
2919 		sm->tdls_supported = 1;
2920 		sm->tdls_external_setup = 0;
2921 	}
2922 
2923 	wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
2924 		   "driver", sm->tdls_supported ? "" : " not");
2925 	wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
2926 		   sm->tdls_external_setup ? "external" : "internal");
2927 	wpa_printf(MSG_DEBUG, "TDLS: Driver %s TDLS channel switching",
2928 		   sm->tdls_chan_switch ? "supports" : "does not support");
2929 
2930 	return 0;
2931 }
2932 
2933 
wpa_tdls_teardown_peers(struct wpa_sm * sm)2934 void wpa_tdls_teardown_peers(struct wpa_sm *sm)
2935 {
2936 	struct wpa_tdls_peer *peer, *tmp;
2937 
2938 	if (!sm)
2939 		return;
2940 	peer = sm->tdls;
2941 
2942 	wpa_printf(MSG_DEBUG, "TDLS: Tear down peers");
2943 
2944 	while (peer) {
2945 		tmp = peer->next;
2946 		wpa_printf(MSG_DEBUG, "TDLS: Tear down peer " MACSTR,
2947 			   MAC2STR(peer->addr));
2948 		if (sm->tdls_external_setup)
2949 			wpa_tdls_do_teardown(sm, peer,
2950 					     WLAN_REASON_DEAUTH_LEAVING);
2951 		else
2952 			wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
2953 
2954 		peer = tmp;
2955 	}
2956 }
2957 
2958 
wpa_tdls_remove_peers(struct wpa_sm * sm)2959 static void wpa_tdls_remove_peers(struct wpa_sm *sm)
2960 {
2961 	struct wpa_tdls_peer *peer, *tmp;
2962 
2963 	peer = sm->tdls;
2964 
2965 	while (peer) {
2966 		int res;
2967 		tmp = peer->next;
2968 		res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2969 		wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
2970 			   MAC2STR(peer->addr), res);
2971 		wpa_tdls_peer_free(sm, peer);
2972 		peer = tmp;
2973 	}
2974 }
2975 
2976 
2977 /**
2978  * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
2979  *
2980  * This function is called to recover driver interface parameters for TDLS
2981  * and frees resources allocated for it.
2982  */
wpa_tdls_deinit(struct wpa_sm * sm)2983 void wpa_tdls_deinit(struct wpa_sm *sm)
2984 {
2985 	if (sm == NULL)
2986 		return;
2987 
2988 	if (sm->l2_tdls)
2989 		l2_packet_deinit(sm->l2_tdls);
2990 	sm->l2_tdls = NULL;
2991 
2992 	wpa_tdls_remove_peers(sm);
2993 }
2994 
2995 
wpa_tdls_assoc(struct wpa_sm * sm)2996 void wpa_tdls_assoc(struct wpa_sm *sm)
2997 {
2998 	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
2999 	wpa_tdls_remove_peers(sm);
3000 }
3001 
3002 
wpa_tdls_disassoc(struct wpa_sm * sm)3003 void wpa_tdls_disassoc(struct wpa_sm *sm)
3004 {
3005 	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
3006 	wpa_tdls_remove_peers(sm);
3007 }
3008 
3009 
wpa_tdls_prohibited(struct ieee802_11_elems * elems)3010 static int wpa_tdls_prohibited(struct ieee802_11_elems *elems)
3011 {
3012 	/* bit 38 - TDLS Prohibited */
3013 	return !!(elems->ext_capab[4] & 0x40);
3014 }
3015 
3016 
wpa_tdls_chan_switch_prohibited(struct ieee802_11_elems * elems)3017 static int wpa_tdls_chan_switch_prohibited(struct ieee802_11_elems *elems)
3018 {
3019 	/* bit 39 - TDLS Channel Switch Prohibited */
3020 	return !!(elems->ext_capab[4] & 0x80);
3021 }
3022 
3023 
wpa_tdls_ap_ies(struct wpa_sm * sm,const u8 * ies,size_t len)3024 void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
3025 {
3026 	struct ieee802_11_elems elems;
3027 
3028 	sm->tdls_prohibited = 0;
3029 	sm->tdls_chan_switch_prohibited = 0;
3030 
3031 	if (ies == NULL ||
3032 	    ieee802_11_parse_elems(ies, len, &elems, 0) == ParseFailed ||
3033 	    elems.ext_capab == NULL || elems.ext_capab_len < 5)
3034 		return;
3035 
3036 	sm->tdls_prohibited = wpa_tdls_prohibited(&elems);
3037 	wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
3038 		   sm->tdls_prohibited ? "prohibited" : "allowed");
3039 	sm->tdls_chan_switch_prohibited =
3040 		wpa_tdls_chan_switch_prohibited(&elems);
3041 	wpa_printf(MSG_DEBUG, "TDLS: TDLS channel switch %s in the target BSS",
3042 		   sm->tdls_chan_switch_prohibited ? "prohibited" : "allowed");
3043 }
3044 
3045 
wpa_tdls_assoc_resp_ies(struct wpa_sm * sm,const u8 * ies,size_t len)3046 void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
3047 {
3048 	struct ieee802_11_elems elems;
3049 
3050 	if (ies == NULL ||
3051 	    ieee802_11_parse_elems(ies, len, &elems, 0) == ParseFailed ||
3052 	    elems.ext_capab == NULL || elems.ext_capab_len < 5)
3053 		return;
3054 
3055 	if (!sm->tdls_prohibited && wpa_tdls_prohibited(&elems)) {
3056 		wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
3057 			   "(Re)Association Response IEs");
3058 		sm->tdls_prohibited = 1;
3059 	}
3060 
3061 	if (!sm->tdls_chan_switch_prohibited &&
3062 	    wpa_tdls_chan_switch_prohibited(&elems)) {
3063 		wpa_printf(MSG_DEBUG,
3064 			   "TDLS: TDLS channel switch prohibited based on (Re)Association Response IEs");
3065 		sm->tdls_chan_switch_prohibited = 1;
3066 	}
3067 }
3068 
3069 
wpa_tdls_enable(struct wpa_sm * sm,int enabled)3070 void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
3071 {
3072 	wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
3073 	sm->tdls_disabled = !enabled;
3074 }
3075 
3076 
wpa_tdls_is_external_setup(struct wpa_sm * sm)3077 int wpa_tdls_is_external_setup(struct wpa_sm *sm)
3078 {
3079 	return sm->tdls_external_setup;
3080 }
3081 
3082 
wpa_tdls_enable_chan_switch(struct wpa_sm * sm,const u8 * addr,u8 oper_class,struct hostapd_freq_params * freq_params)3083 int wpa_tdls_enable_chan_switch(struct wpa_sm *sm, const u8 *addr,
3084 				u8 oper_class,
3085 				struct hostapd_freq_params *freq_params)
3086 {
3087 	struct wpa_tdls_peer *peer;
3088 	int ret;
3089 
3090 	if (sm->tdls_disabled || !sm->tdls_supported)
3091 		return -1;
3092 
3093 	if (!sm->tdls_chan_switch) {
3094 		wpa_printf(MSG_DEBUG,
3095 			   "TDLS: Channel switching not supported by the driver");
3096 		return -1;
3097 	}
3098 
3099 	if (sm->tdls_chan_switch_prohibited) {
3100 		wpa_printf(MSG_DEBUG,
3101 			   "TDLS: Channel switching is prohibited in this BSS - reject request to switch channel");
3102 		return -1;
3103 	}
3104 
3105 	for (peer = sm->tdls; peer; peer = peer->next) {
3106 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
3107 			break;
3108 	}
3109 
3110 	if (peer == NULL || !peer->tpk_success) {
3111 		wpa_printf(MSG_ERROR, "TDLS: Peer " MACSTR
3112 			   " not found for channel switching", MAC2STR(addr));
3113 		return -1;
3114 	}
3115 
3116 	if (peer->chan_switch_enabled) {
3117 		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
3118 			   " already has channel switching enabled",
3119 			   MAC2STR(addr));
3120 		return 0;
3121 	}
3122 
3123 	ret = wpa_sm_tdls_enable_channel_switch(sm, peer->addr,
3124 						oper_class, freq_params);
3125 	if (!ret)
3126 		peer->chan_switch_enabled = 1;
3127 
3128 	return ret;
3129 }
3130 
3131 
wpa_tdls_disable_chan_switch(struct wpa_sm * sm,const u8 * addr)3132 int wpa_tdls_disable_chan_switch(struct wpa_sm *sm, const u8 *addr)
3133 {
3134 	struct wpa_tdls_peer *peer;
3135 
3136 	if (sm->tdls_disabled || !sm->tdls_supported)
3137 		return -1;
3138 
3139 	for (peer = sm->tdls; peer; peer = peer->next) {
3140 		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
3141 			break;
3142 	}
3143 
3144 	if (!peer || !peer->chan_switch_enabled) {
3145 		wpa_printf(MSG_ERROR, "TDLS: Channel switching not enabled for "
3146 			   MACSTR, MAC2STR(addr));
3147 		return -1;
3148 	}
3149 
3150 	/* ignore the return value */
3151 	wpa_sm_tdls_disable_channel_switch(sm, peer->addr);
3152 
3153 	peer->chan_switch_enabled = 0;
3154 	return 0;
3155 }
3156