tdls.c revision 4b9d52f502481b258fec743c03a5e957e5605afc
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 "crypto/sha256.h"
16#include "crypto/crypto.h"
17#include "crypto/aes_wrap.h"
18#include "rsn_supp/wpa.h"
19#include "rsn_supp/wpa_ie.h"
20#include "rsn_supp/wpa_i.h"
21#include "drivers/driver.h"
22#include "l2_packet/l2_packet.h"
23
24#ifdef CONFIG_TDLS_TESTING
25#define TDLS_TESTING_LONG_FRAME BIT(0)
26#define TDLS_TESTING_ALT_RSN_IE BIT(1)
27#define TDLS_TESTING_DIFF_BSSID BIT(2)
28#define TDLS_TESTING_SHORT_LIFETIME BIT(3)
29#define TDLS_TESTING_WRONG_LIFETIME_RESP BIT(4)
30#define TDLS_TESTING_WRONG_LIFETIME_CONF BIT(5)
31#define TDLS_TESTING_LONG_LIFETIME BIT(6)
32#define TDLS_TESTING_CONCURRENT_INIT BIT(7)
33#define TDLS_TESTING_NO_TPK_EXPIRATION BIT(8)
34#define TDLS_TESTING_DECLINE_RESP BIT(9)
35#define TDLS_TESTING_IGNORE_AP_PROHIBIT BIT(10)
36unsigned int tdls_testing = 0;
37#endif /* CONFIG_TDLS_TESTING */
38
39#define TPK_LIFETIME 43200 /* 12 hours */
40#define TPK_RETRY_COUNT 3
41#define TPK_TIMEOUT 5000 /* in milliseconds */
42
43#define TDLS_MIC_LEN		16
44
45#define TDLS_TIMEOUT_LEN	4
46
47struct wpa_tdls_ftie {
48	u8 ie_type; /* FTIE */
49	u8 ie_len;
50	u8 mic_ctrl[2];
51	u8 mic[TDLS_MIC_LEN];
52	u8 Anonce[WPA_NONCE_LEN]; /* Responder Nonce in TDLS */
53	u8 Snonce[WPA_NONCE_LEN]; /* Initiator Nonce in TDLS */
54	/* followed by optional elements */
55} STRUCT_PACKED;
56
57struct wpa_tdls_timeoutie {
58	u8 ie_type; /* Timeout IE */
59	u8 ie_len;
60	u8 interval_type;
61	u8 value[TDLS_TIMEOUT_LEN];
62} STRUCT_PACKED;
63
64struct wpa_tdls_lnkid {
65	u8 ie_type; /* Link Identifier IE */
66	u8 ie_len;
67	u8 bssid[ETH_ALEN];
68	u8 init_sta[ETH_ALEN];
69	u8 resp_sta[ETH_ALEN];
70} STRUCT_PACKED;
71
72/* TDLS frame headers as per IEEE Std 802.11z-2010 */
73struct wpa_tdls_frame {
74	u8 payloadtype; /* IEEE80211_TDLS_RFTYPE */
75	u8 category; /* Category */
76	u8 action; /* Action (enum tdls_frame_type) */
77} STRUCT_PACKED;
78
79static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
80static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx);
81static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
82
83
84#define TDLS_MAX_IE_LEN 80
85#define IEEE80211_MAX_SUPP_RATES 32
86
87struct wpa_tdls_peer {
88	struct wpa_tdls_peer *next;
89	int initiator; /* whether this end was initiator for TDLS setup */
90	u8 addr[ETH_ALEN]; /* other end MAC address */
91	u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
92	u8 rnonce[WPA_NONCE_LEN]; /* Responder Nonce */
93	u8 rsnie_i[TDLS_MAX_IE_LEN]; /* Initiator RSN IE */
94	size_t rsnie_i_len;
95	u8 rsnie_p[TDLS_MAX_IE_LEN]; /* Peer RSN IE */
96	size_t rsnie_p_len;
97	u32 lifetime;
98	int cipher; /* Selected cipher (WPA_CIPHER_*) */
99	u8 dtoken;
100
101	struct tpk {
102		u8 kck[16]; /* TPK-KCK */
103		u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
104	} tpk;
105	int tpk_set;
106	int tpk_success;
107
108	struct tpk_timer {
109		u8 dest[ETH_ALEN];
110		int count;      /* Retry Count */
111		int timer;      /* Timeout in milliseconds */
112		u8 action_code; /* TDLS frame type */
113		u8 dialog_token;
114		u16 status_code;
115		int buf_len;    /* length of TPK message for retransmission */
116		u8 *buf;        /* buffer for TPK message */
117	} sm_tmr;
118
119	u16 capability;
120
121	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
122	size_t supp_rates_len;
123};
124
125
126static int wpa_tdls_get_privacy(struct wpa_sm *sm)
127{
128	/*
129	 * Get info needed from supplicant to check if the current BSS supports
130	 * security. Other than OPEN mode, rest are considered secured
131	 * WEP/WPA/WPA2 hence TDLS frames are processed for TPK handshake.
132	 */
133	return sm->pairwise_cipher != WPA_CIPHER_NONE;
134}
135
136
137static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
138{
139	os_memcpy(pos, ie, ie_len);
140	return pos + ie_len;
141}
142
143
144static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
145{
146	if (wpa_sm_set_key(sm, WPA_ALG_NONE, peer->addr,
147			   0, 0, NULL, 0, NULL, 0) < 0) {
148		wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from "
149			   "the driver");
150		return -1;
151	}
152
153	return 0;
154}
155
156
157static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
158{
159	u8 key_len;
160	u8 rsc[6];
161	enum wpa_alg alg;
162
163	os_memset(rsc, 0, 6);
164
165	switch (peer->cipher) {
166	case WPA_CIPHER_CCMP:
167		alg = WPA_ALG_CCMP;
168		key_len = 16;
169		break;
170	case WPA_CIPHER_NONE:
171		wpa_printf(MSG_DEBUG, "TDLS: Pairwise Cipher Suite: "
172			   "NONE - do not use pairwise keys");
173		return -1;
174	default:
175		wpa_printf(MSG_WARNING, "TDLS: Unsupported pairwise cipher %d",
176			   sm->pairwise_cipher);
177		return -1;
178	}
179
180	if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
181			   rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
182		wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
183			   "driver");
184		return -1;
185	}
186	return 0;
187}
188
189
190static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
191				 u8 action_code, u8 dialog_token,
192				 u16 status_code, const u8 *buf, size_t len)
193{
194	return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
195				     status_code, buf, len);
196}
197
198
199static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
200			     u8 dialog_token, u16 status_code,
201			     const u8 *msg, size_t msg_len)
202{
203	struct wpa_tdls_peer *peer;
204
205	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
206		   "dialog_token=%u status_code=%u msg_len=%u",
207		   MAC2STR(dest), action_code, dialog_token, status_code,
208		   (unsigned int) msg_len);
209
210	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
211				  status_code, msg, msg_len)) {
212		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
213			   "(action_code=%u)", action_code);
214		return -1;
215	}
216
217	if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
218	    action_code == WLAN_TDLS_TEARDOWN ||
219	    action_code == WLAN_TDLS_DISCOVERY_REQUEST ||
220	    action_code == WLAN_TDLS_DISCOVERY_RESPONSE)
221		return 0; /* No retries */
222
223	for (peer = sm->tdls; peer; peer = peer->next) {
224		if (os_memcmp(peer->addr, dest, ETH_ALEN) == 0)
225			break;
226	}
227
228	if (peer == NULL) {
229		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
230			   "retry " MACSTR, MAC2STR(dest));
231		return 0;
232	}
233
234	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
235
236	peer->sm_tmr.count = TPK_RETRY_COUNT;
237	peer->sm_tmr.timer = TPK_TIMEOUT;
238
239	/* Copy message to resend on timeout */
240	os_memcpy(peer->sm_tmr.dest, dest, ETH_ALEN);
241	peer->sm_tmr.action_code = action_code;
242	peer->sm_tmr.dialog_token = dialog_token;
243	peer->sm_tmr.status_code = status_code;
244	peer->sm_tmr.buf_len = msg_len;
245	os_free(peer->sm_tmr.buf);
246	peer->sm_tmr.buf = os_malloc(msg_len);
247	if (peer->sm_tmr.buf == NULL)
248		return -1;
249	os_memcpy(peer->sm_tmr.buf, msg, msg_len);
250
251	wpa_printf(MSG_DEBUG, "TDLS: Retry timeout registered "
252		   "(action_code=%u)", action_code);
253	eloop_register_timeout(peer->sm_tmr.timer / 1000, 0,
254			       wpa_tdls_tpk_retry_timeout, sm, peer);
255	return 0;
256}
257
258
259static int wpa_tdls_do_teardown(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
260				u16 reason_code, int free_peer)
261{
262	int ret;
263
264	if (sm->tdls_external_setup) {
265		ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code);
266
267		/* disable the link after teardown was sent */
268		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
269	} else {
270		ret = wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
271	}
272
273	if (sm->tdls_external_setup || free_peer)
274		wpa_tdls_peer_free(sm, peer);
275
276	return ret;
277}
278
279
280static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx)
281{
282
283	struct wpa_sm *sm = eloop_ctx;
284	struct wpa_tdls_peer *peer = timeout_ctx;
285
286	if (peer->sm_tmr.count) {
287		peer->sm_tmr.count--;
288		peer->sm_tmr.timer = TPK_TIMEOUT;
289
290		wpa_printf(MSG_INFO, "TDLS: Retrying sending of message "
291			   "(action_code=%u)",
292			   peer->sm_tmr.action_code);
293
294		if (peer->sm_tmr.buf == NULL) {
295			wpa_printf(MSG_INFO, "TDLS: No retry buffer available "
296				   "for action_code=%u",
297				   peer->sm_tmr.action_code);
298			eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm,
299					     peer);
300			return;
301		}
302
303		/* resend TPK Handshake Message to Peer */
304		if (wpa_tdls_send_tpk_msg(sm, peer->sm_tmr.dest,
305					  peer->sm_tmr.action_code,
306					  peer->sm_tmr.dialog_token,
307					  peer->sm_tmr.status_code,
308					  peer->sm_tmr.buf,
309					  peer->sm_tmr.buf_len)) {
310			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
311				   "transmission");
312		}
313
314		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
315		eloop_register_timeout(peer->sm_tmr.timer / 1000, 0,
316				       wpa_tdls_tpk_retry_timeout, sm, peer);
317	} else {
318		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
319
320		wpa_printf(MSG_DEBUG, "TDLS: Sending Teardown Request");
321		wpa_tdls_do_teardown(sm, peer,
322				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
323	}
324}
325
326
327static void wpa_tdls_tpk_retry_timeout_cancel(struct wpa_sm *sm,
328					      struct wpa_tdls_peer *peer,
329					      u8 action_code)
330{
331	if (action_code == peer->sm_tmr.action_code) {
332		wpa_printf(MSG_DEBUG, "TDLS: Retry timeout cancelled for "
333			   "action_code=%u", action_code);
334
335		/* Cancel Timeout registered */
336		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
337
338		/* free all resources meant for retry */
339		os_free(peer->sm_tmr.buf);
340		peer->sm_tmr.buf = NULL;
341
342		peer->sm_tmr.count = 0;
343		peer->sm_tmr.timer = 0;
344		peer->sm_tmr.buf_len = 0;
345		peer->sm_tmr.action_code = 0xff;
346	} else {
347		wpa_printf(MSG_INFO, "TDLS: Error in cancelling retry timeout "
348			   "(Unknown action_code=%u)", action_code);
349	}
350}
351
352
353static void wpa_tdls_generate_tpk(struct wpa_tdls_peer *peer,
354				  const u8 *own_addr, const u8 *bssid)
355{
356	u8 key_input[SHA256_MAC_LEN];
357	const u8 *nonce[2];
358	size_t len[2];
359	u8 data[3 * ETH_ALEN];
360
361	/* IEEE Std 802.11z-2010 8.5.9.1:
362	 * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce))
363	 */
364	len[0] = WPA_NONCE_LEN;
365	len[1] = WPA_NONCE_LEN;
366	if (os_memcmp(peer->inonce, peer->rnonce, WPA_NONCE_LEN) < 0) {
367		nonce[0] = peer->inonce;
368		nonce[1] = peer->rnonce;
369	} else {
370		nonce[0] = peer->rnonce;
371		nonce[1] = peer->inonce;
372	}
373	wpa_hexdump(MSG_DEBUG, "TDLS: min(Nonce)", nonce[0], WPA_NONCE_LEN);
374	wpa_hexdump(MSG_DEBUG, "TDLS: max(Nonce)", nonce[1], WPA_NONCE_LEN);
375	sha256_vector(2, nonce, len, key_input);
376	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input",
377			key_input, SHA256_MAC_LEN);
378
379	/*
380	 * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK",
381	 *	min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY)
382	 * TODO: is N_KEY really included in KDF Context and if so, in which
383	 * presentation format (little endian 16-bit?) is it used? It gets
384	 * added by the KDF anyway..
385	 */
386
387	if (os_memcmp(own_addr, peer->addr, ETH_ALEN) < 0) {
388		os_memcpy(data, own_addr, ETH_ALEN);
389		os_memcpy(data + ETH_ALEN, peer->addr, ETH_ALEN);
390	} else {
391		os_memcpy(data, peer->addr, ETH_ALEN);
392		os_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN);
393	}
394	os_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN);
395	wpa_hexdump(MSG_DEBUG, "TDLS: KDF Context", data, sizeof(data));
396
397	sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data),
398		   (u8 *) &peer->tpk, sizeof(peer->tpk));
399	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK",
400			peer->tpk.kck, sizeof(peer->tpk.kck));
401	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK",
402			peer->tpk.tk, sizeof(peer->tpk.tk));
403	peer->tpk_set = 1;
404}
405
406
407/**
408 * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC
409 * @kck: TPK-KCK
410 * @lnkid: Pointer to the beginning of Link Identifier IE
411 * @rsnie: Pointer to the beginning of RSN IE used for handshake
412 * @timeoutie: Pointer to the beginning of Timeout IE used for handshake
413 * @ftie: Pointer to the beginning of FT IE
414 * @mic: Pointer for writing MIC
415 *
416 * Calculate MIC for TDLS frame.
417 */
418static int wpa_tdls_ftie_mic(const u8 *kck, u8 trans_seq, const u8 *lnkid,
419			     const u8 *rsnie, const u8 *timeoutie,
420			     const u8 *ftie, u8 *mic)
421{
422	u8 *buf, *pos;
423	struct wpa_tdls_ftie *_ftie;
424	const struct wpa_tdls_lnkid *_lnkid;
425	int ret;
426	int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + 2 + rsnie[1] +
427		2 + timeoutie[1] + 2 + ftie[1];
428	buf = os_zalloc(len);
429	if (!buf) {
430		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
431		return -1;
432	}
433
434	pos = buf;
435	_lnkid = (const struct wpa_tdls_lnkid *) lnkid;
436	/* 1) TDLS initiator STA MAC address */
437	os_memcpy(pos, _lnkid->init_sta, ETH_ALEN);
438	pos += ETH_ALEN;
439	/* 2) TDLS responder STA MAC address */
440	os_memcpy(pos, _lnkid->resp_sta, ETH_ALEN);
441	pos += ETH_ALEN;
442	/* 3) Transaction Sequence number */
443	*pos++ = trans_seq;
444	/* 4) Link Identifier IE */
445	os_memcpy(pos, lnkid, 2 + lnkid[1]);
446	pos += 2 + lnkid[1];
447	/* 5) RSN IE */
448	os_memcpy(pos, rsnie, 2 + rsnie[1]);
449	pos += 2 + rsnie[1];
450	/* 6) Timeout Interval IE */
451	os_memcpy(pos, timeoutie, 2 + timeoutie[1]);
452	pos += 2 + timeoutie[1];
453	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
454	os_memcpy(pos, ftie, 2 + ftie[1]);
455	_ftie = (struct wpa_tdls_ftie *) pos;
456	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
457	pos += 2 + ftie[1];
458
459	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
460	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
461	ret = omac1_aes_128(kck, buf, pos - buf, mic);
462	os_free(buf);
463	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
464	return ret;
465}
466
467
468/**
469 * wpa_tdls_key_mic_teardown - Calculate TDLS FTIE MIC for Teardown frame
470 * @kck: TPK-KCK
471 * @trans_seq: Transaction Sequence Number (4 - Teardown)
472 * @rcode: Reason code for Teardown
473 * @dtoken: Dialog Token used for that particular link
474 * @lnkid: Pointer to the beginning of Link Identifier IE
475 * @ftie: Pointer to the beginning of FT IE
476 * @mic: Pointer for writing MIC
477 *
478 * Calculate MIC for TDLS frame.
479 */
480static int wpa_tdls_key_mic_teardown(const u8 *kck, u8 trans_seq, u16 rcode,
481				     u8 dtoken, const u8 *lnkid,
482				     const u8 *ftie, u8 *mic)
483{
484	u8 *buf, *pos;
485	struct wpa_tdls_ftie *_ftie;
486	int ret;
487	int len;
488
489	if (lnkid == NULL)
490		return -1;
491
492	len = 2 + lnkid[1] + sizeof(rcode) + sizeof(dtoken) +
493		sizeof(trans_seq) + 2 + ftie[1];
494
495	buf = os_zalloc(len);
496	if (!buf) {
497		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
498		return -1;
499	}
500
501	pos = buf;
502	/* 1) Link Identifier IE */
503	os_memcpy(pos, lnkid, 2 + lnkid[1]);
504	pos += 2 + lnkid[1];
505	/* 2) Reason Code */
506	WPA_PUT_LE16(pos, rcode);
507	pos += sizeof(rcode);
508	/* 3) Dialog token */
509	*pos++ = dtoken;
510	/* 4) Transaction Sequence number */
511	*pos++ = trans_seq;
512	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
513	os_memcpy(pos, ftie, 2 + ftie[1]);
514	_ftie = (struct wpa_tdls_ftie *) pos;
515	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
516	pos += 2 + ftie[1];
517
518	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
519	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
520	ret = omac1_aes_128(kck, buf, pos - buf, mic);
521	os_free(buf);
522	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
523	return ret;
524}
525
526
527static int wpa_supplicant_verify_tdls_mic(u8 trans_seq,
528					  struct wpa_tdls_peer *peer,
529					  const u8 *lnkid, const u8 *timeoutie,
530					  const struct wpa_tdls_ftie *ftie)
531{
532	u8 mic[16];
533
534	if (peer->tpk_set) {
535		wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid,
536				  peer->rsnie_p, timeoutie, (u8 *) ftie,
537				  mic);
538		if (os_memcmp(mic, ftie->mic, 16) != 0) {
539			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - "
540				   "dropping packet");
541			wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC",
542				    ftie->mic, 16);
543			wpa_hexdump(MSG_DEBUG, "TDLS: Calculated MIC",
544				    mic, 16);
545			return -1;
546		}
547	} else {
548		wpa_printf(MSG_WARNING, "TDLS: Could not verify TDLS MIC, "
549			   "TPK not set - dropping packet");
550		return -1;
551	}
552	return 0;
553}
554
555
556static int wpa_supplicant_verify_tdls_mic_teardown(
557	u8 trans_seq, u16 rcode, u8 dtoken, struct wpa_tdls_peer *peer,
558	const u8 *lnkid, const struct wpa_tdls_ftie *ftie)
559{
560	u8 mic[16];
561
562	if (peer->tpk_set) {
563		wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode,
564					  dtoken, lnkid, (u8 *) ftie, mic);
565		if (os_memcmp(mic, ftie->mic, 16) != 0) {
566			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - "
567				   "dropping packet");
568			return -1;
569		}
570	} else {
571		wpa_printf(MSG_INFO, "TDLS: Could not verify TDLS Teardown "
572			   "MIC, TPK not set - dropping packet");
573		return -1;
574	}
575	return 0;
576}
577
578
579static void wpa_tdls_tpk_timeout(void *eloop_ctx, void *timeout_ctx)
580{
581	struct wpa_sm *sm = eloop_ctx;
582	struct wpa_tdls_peer *peer = timeout_ctx;
583
584	/*
585	 * On TPK lifetime expiration, we have an option of either tearing down
586	 * the direct link or trying to re-initiate it. The selection of what
587	 * to do is not strictly speaking controlled by our role in the expired
588	 * link, but for now, use that to select whether to renew or tear down
589	 * the link.
590	 */
591
592	if (peer->initiator) {
593		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
594			   " - try to renew", MAC2STR(peer->addr));
595		wpa_tdls_start(sm, peer->addr);
596	} else {
597		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
598			   " - tear down", MAC2STR(peer->addr));
599		wpa_tdls_do_teardown(sm, peer,
600				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
601	}
602}
603
604
605static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
606{
607	wpa_printf(MSG_DEBUG, "TDLS: Clear state for peer " MACSTR,
608		   MAC2STR(peer->addr));
609	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
610	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
611	peer->initiator = 0;
612	os_free(peer->sm_tmr.buf);
613	peer->sm_tmr.buf = NULL;
614	peer->rsnie_i_len = peer->rsnie_p_len = 0;
615	peer->cipher = 0;
616	peer->tpk_set = peer->tpk_success = 0;
617	os_memset(&peer->tpk, 0, sizeof(peer->tpk));
618	os_memset(peer->inonce, 0, WPA_NONCE_LEN);
619	os_memset(peer->rnonce, 0, WPA_NONCE_LEN);
620}
621
622
623static void wpa_tdls_linkid(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
624			    struct wpa_tdls_lnkid *lnkid)
625{
626	lnkid->ie_type = WLAN_EID_LINK_ID;
627	lnkid->ie_len = 3 * ETH_ALEN;
628	os_memcpy(lnkid->bssid, sm->bssid, ETH_ALEN);
629	if (peer->initiator) {
630		os_memcpy(lnkid->init_sta, sm->own_addr, ETH_ALEN);
631		os_memcpy(lnkid->resp_sta, peer->addr, ETH_ALEN);
632	} else {
633		os_memcpy(lnkid->init_sta, peer->addr, ETH_ALEN);
634		os_memcpy(lnkid->resp_sta, sm->own_addr, ETH_ALEN);
635	}
636}
637
638
639int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
640{
641	struct wpa_tdls_peer *peer;
642	struct wpa_tdls_ftie *ftie;
643	struct wpa_tdls_lnkid lnkid;
644	u8 dialog_token;
645	u8 *rbuf, *pos;
646	int ielen;
647
648	if (sm->tdls_disabled || !sm->tdls_supported)
649		return -1;
650
651	/* Find the node and free from the list */
652	for (peer = sm->tdls; peer; peer = peer->next) {
653		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
654			break;
655	}
656
657	if (peer == NULL) {
658		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
659			   "Teardown " MACSTR, MAC2STR(addr));
660		return 0;
661	}
662
663	dialog_token = peer->dtoken;
664
665	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown for " MACSTR,
666		   MAC2STR(addr));
667
668	ielen = 0;
669	if (wpa_tdls_get_privacy(sm) && peer->tpk_set && peer->tpk_success) {
670		/* To add FTIE for Teardown request and compute MIC */
671		ielen += sizeof(*ftie);
672#ifdef CONFIG_TDLS_TESTING
673		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
674			ielen += 170;
675#endif /* CONFIG_TDLS_TESTING */
676	}
677
678	rbuf = os_zalloc(ielen + 1);
679	if (rbuf == NULL)
680		return -1;
681	pos = rbuf;
682
683	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) {
684		/* Overwrite the reason code */
685		reason_code = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
686		goto skip_ies;
687	}
688
689	ftie = (struct wpa_tdls_ftie *) pos;
690	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
691	/* Using the recent nonce which should be for CONFIRM frame */
692	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
693	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
694	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
695	pos = (u8 *) (ftie + 1);
696#ifdef CONFIG_TDLS_TESTING
697	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
698		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
699			   "FTIE");
700		ftie->ie_len += 170;
701		*pos++ = 255; /* FTIE subelem */
702		*pos++ = 168; /* FTIE subelem length */
703		pos += 168;
704	}
705#endif /* CONFIG_TDLS_TESTING */
706	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TDLS Teardown handshake",
707		    (u8 *) ftie, pos - (u8 *) ftie);
708
709	/* compute MIC before sending */
710	wpa_tdls_linkid(sm, peer, &lnkid);
711	wpa_tdls_key_mic_teardown(peer->tpk.kck, 4, reason_code,
712				  dialog_token, (u8 *) &lnkid, (u8 *) ftie,
713				  ftie->mic);
714
715skip_ies:
716	/* TODO: register for a Timeout handler, if Teardown is not received at
717	 * the other end, then try again another time */
718
719	/* request driver to send Teardown using this FTIE */
720	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
721			  reason_code, rbuf, pos - rbuf);
722	os_free(rbuf);
723
724	/* clear the Peerkey statemachine */
725	wpa_tdls_peer_free(sm, peer);
726
727	return 0;
728}
729
730
731int wpa_tdls_teardown_link(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
732{
733	struct wpa_tdls_peer *peer;
734
735	if (sm->tdls_disabled || !sm->tdls_supported)
736		return -1;
737
738	for (peer = sm->tdls; peer; peer = peer->next) {
739		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
740			break;
741	}
742
743	if (peer == NULL) {
744		wpa_printf(MSG_DEBUG, "TDLS: Could not find peer " MACSTR
745		   " for link Teardown", MAC2STR(addr));
746		return -1;
747	}
748
749	if (!peer->tpk_success) {
750		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
751		   " not connected - cannot Teardown link", MAC2STR(addr));
752		return -1;
753	}
754
755	return wpa_tdls_do_teardown(sm, peer, reason_code, 0);
756}
757
758
759void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
760{
761	struct wpa_tdls_peer *peer;
762
763	for (peer = sm->tdls; peer; peer = peer->next) {
764		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
765			break;
766	}
767
768	if (peer) {
769		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
770		wpa_tdls_peer_free(sm, peer);
771	}
772}
773
774
775static int wpa_tdls_recv_teardown(struct wpa_sm *sm, const u8 *src_addr,
776				  const u8 *buf, size_t len)
777{
778	struct wpa_tdls_peer *peer = NULL;
779	struct wpa_tdls_ftie *ftie;
780	struct wpa_tdls_lnkid *lnkid;
781	struct wpa_eapol_ie_parse kde;
782	u16 reason_code;
783	const u8 *pos;
784	int ielen;
785
786	/* Find the node and free from the list */
787	for (peer = sm->tdls; peer; peer = peer->next) {
788		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
789			break;
790	}
791
792	if (peer == NULL) {
793		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
794			   "Teardown " MACSTR, MAC2STR(src_addr));
795		return 0;
796	}
797
798	pos = buf;
799	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
800
801	reason_code = WPA_GET_LE16(pos);
802	pos += 2;
803
804	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown Request from " MACSTR
805		   " (reason code %u)", MAC2STR(src_addr), reason_code);
806
807	ielen = len - (pos - buf); /* start of IE in buf */
808	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
809		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in Teardown");
810		return -1;
811	}
812
813	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
814		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TDLS "
815			   "Teardown");
816		return -1;
817	}
818	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
819
820	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
821		goto skip_ftie;
822
823	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
824		wpa_printf(MSG_INFO, "TDLS: No FTIE in TDLS Teardown");
825		return -1;
826	}
827
828	ftie = (struct wpa_tdls_ftie *) kde.ftie;
829
830	/* Process MIC check to see if TDLS Teardown is right */
831	if (wpa_supplicant_verify_tdls_mic_teardown(4, reason_code,
832						    peer->dtoken, peer,
833						    (u8 *) lnkid, ftie) < 0) {
834		wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS "
835			   "Teardown Request from " MACSTR, MAC2STR(src_addr));
836		return -1;
837	}
838
839skip_ftie:
840	/*
841	 * Request the driver to disable the direct link and clear associated
842	 * keys.
843	 */
844	wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
845
846	/* clear the Peerkey statemachine */
847	wpa_tdls_peer_free(sm, peer);
848
849	return 0;
850}
851
852
853/**
854 * wpa_tdls_send_error - To send suitable TDLS status response with
855 *	appropriate status code mentioning reason for error/failure.
856 * @dst 	- MAC addr of Peer station
857 * @tdls_action - TDLS frame type for which error code is sent
858 * @status 	- status code mentioning reason
859 */
860
861static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
862			       u8 tdls_action, u8 dialog_token, u16 status)
863{
864	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
865		   " (action=%u status=%u)",
866		   MAC2STR(dst), tdls_action, status);
867	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
868				 NULL, 0);
869}
870
871
872static struct wpa_tdls_peer *
873wpa_tdls_add_peer(struct wpa_sm *sm, const u8 *addr, int *existing)
874{
875	struct wpa_tdls_peer *peer;
876
877	if (existing)
878		*existing = 0;
879	for (peer = sm->tdls; peer; peer = peer->next) {
880		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) {
881			if (existing)
882				*existing = 1;
883			return peer; /* re-use existing entry */
884		}
885	}
886
887	wpa_printf(MSG_INFO, "TDLS: Creating peer entry for " MACSTR,
888		   MAC2STR(addr));
889
890	peer = os_zalloc(sizeof(*peer));
891	if (peer == NULL)
892		return NULL;
893
894	os_memcpy(peer->addr, addr, ETH_ALEN);
895	peer->next = sm->tdls;
896	sm->tdls = peer;
897
898	return peer;
899}
900
901
902static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm,
903				struct wpa_tdls_peer *peer)
904{
905	size_t buf_len;
906	struct wpa_tdls_timeoutie timeoutie;
907	u16 rsn_capab;
908	struct wpa_tdls_ftie *ftie;
909	u8 *rbuf, *pos, *count_pos;
910	u16 count;
911	struct rsn_ie_hdr *hdr;
912
913	if (!wpa_tdls_get_privacy(sm)) {
914		wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
915		peer->rsnie_i_len = 0;
916		goto skip_rsnie;
917	}
918
919	/*
920	 * TPK Handshake Message 1:
921	 * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I,
922	 * Timeout Interval IE))
923	 */
924
925	/* Filling RSN IE */
926	hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
927	hdr->elem_id = WLAN_EID_RSN;
928	WPA_PUT_LE16(hdr->version, RSN_VERSION);
929
930	pos = (u8 *) (hdr + 1);
931	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
932	pos += RSN_SELECTOR_LEN;
933	count_pos = pos;
934	pos += 2;
935
936	count = 0;
937
938	/*
939	 * AES-CCMP is the default Encryption preferred for TDLS, so
940	 * RSN IE is filled only with CCMP CIPHER
941	 * Note: TKIP is not used to encrypt TDLS link.
942	 *
943	 * Regardless of the cipher used on the AP connection, select CCMP
944	 * here.
945	 */
946	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
947	pos += RSN_SELECTOR_LEN;
948	count++;
949
950	WPA_PUT_LE16(count_pos, count);
951
952	WPA_PUT_LE16(pos, 1);
953	pos += 2;
954	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
955	pos += RSN_SELECTOR_LEN;
956
957	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
958	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
959#ifdef CONFIG_TDLS_TESTING
960	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
961		wpa_printf(MSG_DEBUG, "TDLS: Use alternative RSN IE for "
962			   "testing");
963		rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
964	}
965#endif /* CONFIG_TDLS_TESTING */
966	WPA_PUT_LE16(pos, rsn_capab);
967	pos += 2;
968#ifdef CONFIG_TDLS_TESTING
969	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
970		/* Number of PMKIDs */
971		*pos++ = 0x00;
972		*pos++ = 0x00;
973	}
974#endif /* CONFIG_TDLS_TESTING */
975
976	hdr->len = (pos - peer->rsnie_i) - 2;
977	peer->rsnie_i_len = pos - peer->rsnie_i;
978	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
979		    peer->rsnie_i, peer->rsnie_i_len);
980
981skip_rsnie:
982	buf_len = 0;
983	if (wpa_tdls_get_privacy(sm))
984		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
985			sizeof(struct wpa_tdls_timeoutie);
986#ifdef CONFIG_TDLS_TESTING
987	if (wpa_tdls_get_privacy(sm) &&
988	    (tdls_testing & TDLS_TESTING_LONG_FRAME))
989		buf_len += 170;
990	if (tdls_testing & TDLS_TESTING_DIFF_BSSID)
991		buf_len += sizeof(struct wpa_tdls_lnkid);
992#endif /* CONFIG_TDLS_TESTING */
993	rbuf = os_zalloc(buf_len + 1);
994	if (rbuf == NULL) {
995		wpa_tdls_peer_free(sm, peer);
996		return -1;
997	}
998	pos = rbuf;
999
1000	if (!wpa_tdls_get_privacy(sm))
1001		goto skip_ies;
1002
1003	/* Initiator RSN IE */
1004	pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
1005
1006	ftie = (struct wpa_tdls_ftie *) pos;
1007	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1008	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1009
1010	if (os_get_random(peer->inonce, WPA_NONCE_LEN)) {
1011		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1012			"TDLS: Failed to get random data for initiator Nonce");
1013		os_free(rbuf);
1014		wpa_tdls_peer_free(sm, peer);
1015		return -1;
1016	}
1017	wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
1018		    peer->inonce, WPA_NONCE_LEN);
1019	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1020
1021	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK Handshake M1",
1022		    (u8 *) ftie, sizeof(struct wpa_tdls_ftie));
1023
1024	pos = (u8 *) (ftie + 1);
1025
1026#ifdef CONFIG_TDLS_TESTING
1027	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1028		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1029			   "FTIE");
1030		ftie->ie_len += 170;
1031		*pos++ = 255; /* FTIE subelem */
1032		*pos++ = 168; /* FTIE subelem length */
1033		pos += 168;
1034	}
1035#endif /* CONFIG_TDLS_TESTING */
1036
1037	/* Lifetime */
1038	peer->lifetime = TPK_LIFETIME;
1039#ifdef CONFIG_TDLS_TESTING
1040	if (tdls_testing & TDLS_TESTING_SHORT_LIFETIME) {
1041		wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK "
1042			   "lifetime");
1043		peer->lifetime = 301;
1044	}
1045	if (tdls_testing & TDLS_TESTING_LONG_LIFETIME) {
1046		wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK "
1047			   "lifetime");
1048		peer->lifetime = 0xffffffff;
1049	}
1050#endif /* CONFIG_TDLS_TESTING */
1051	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1052				     sizeof(timeoutie), peer->lifetime);
1053	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1054
1055skip_ies:
1056
1057#ifdef CONFIG_TDLS_TESTING
1058	if (tdls_testing & TDLS_TESTING_DIFF_BSSID) {
1059		wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in "
1060			   "Link Identifier");
1061		struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos;
1062		wpa_tdls_linkid(sm, peer, l);
1063		l->bssid[5] ^= 0x01;
1064		pos += sizeof(*l);
1065	}
1066#endif /* CONFIG_TDLS_TESTING */
1067
1068	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Request / TPK "
1069		   "Handshake Message 1 (peer " MACSTR ")",
1070		   MAC2STR(peer->addr));
1071
1072	wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 1, 0,
1073			  rbuf, pos - rbuf);
1074	os_free(rbuf);
1075
1076	return 0;
1077}
1078
1079
1080static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
1081				const unsigned char *src_addr, u8 dtoken,
1082				struct wpa_tdls_lnkid *lnkid,
1083				const struct wpa_tdls_peer *peer)
1084{
1085	u8 *rbuf, *pos;
1086	size_t buf_len;
1087	u32 lifetime;
1088	struct wpa_tdls_timeoutie timeoutie;
1089	struct wpa_tdls_ftie *ftie;
1090
1091	buf_len = 0;
1092	if (wpa_tdls_get_privacy(sm)) {
1093		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1094		 * Lifetime */
1095		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1096			sizeof(struct wpa_tdls_timeoutie);
1097#ifdef CONFIG_TDLS_TESTING
1098		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1099			buf_len += 170;
1100#endif /* CONFIG_TDLS_TESTING */
1101	}
1102
1103	rbuf = os_zalloc(buf_len + 1);
1104	if (rbuf == NULL)
1105		return -1;
1106	pos = rbuf;
1107
1108	if (!wpa_tdls_get_privacy(sm))
1109		goto skip_ies;
1110
1111	/* Peer RSN IE */
1112	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1113
1114	ftie = (struct wpa_tdls_ftie *) pos;
1115	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1116	/* TODO: ftie->mic_control to set 2-RESPONSE */
1117	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1118	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1119	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1120	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK M2",
1121		    (u8 *) ftie, sizeof(*ftie));
1122
1123	pos = (u8 *) (ftie + 1);
1124
1125#ifdef CONFIG_TDLS_TESTING
1126	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1127		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1128			   "FTIE");
1129		ftie->ie_len += 170;
1130		*pos++ = 255; /* FTIE subelem */
1131		*pos++ = 168; /* FTIE subelem length */
1132		pos += 168;
1133	}
1134#endif /* CONFIG_TDLS_TESTING */
1135
1136	/* Lifetime */
1137	lifetime = peer->lifetime;
1138#ifdef CONFIG_TDLS_TESTING
1139	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_RESP) {
1140		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1141			   "lifetime in response");
1142		lifetime++;
1143	}
1144#endif /* CONFIG_TDLS_TESTING */
1145	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1146				     sizeof(timeoutie), lifetime);
1147	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds from initiator",
1148		   lifetime);
1149
1150	/* compute MIC before sending */
1151	wpa_tdls_ftie_mic(peer->tpk.kck, 2, (u8 *) lnkid, peer->rsnie_p,
1152			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1153
1154skip_ies:
1155	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
1156			  rbuf, pos - rbuf);
1157	os_free(rbuf);
1158
1159	return 0;
1160}
1161
1162
1163static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm,
1164				const unsigned char *src_addr, u8 dtoken,
1165				struct wpa_tdls_lnkid *lnkid,
1166				const struct wpa_tdls_peer *peer)
1167{
1168	u8 *rbuf, *pos;
1169	size_t buf_len;
1170	struct wpa_tdls_ftie *ftie;
1171	struct wpa_tdls_timeoutie timeoutie;
1172	u32 lifetime;
1173
1174	buf_len = 0;
1175	if (wpa_tdls_get_privacy(sm)) {
1176		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1177		 * Lifetime */
1178		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1179			sizeof(struct wpa_tdls_timeoutie);
1180#ifdef CONFIG_TDLS_TESTING
1181		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1182			buf_len += 170;
1183#endif /* CONFIG_TDLS_TESTING */
1184	}
1185
1186	rbuf = os_zalloc(buf_len + 1);
1187	if (rbuf == NULL)
1188		return -1;
1189	pos = rbuf;
1190
1191	if (!wpa_tdls_get_privacy(sm))
1192		goto skip_ies;
1193
1194	/* Peer RSN IE */
1195	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1196
1197	ftie = (struct wpa_tdls_ftie *) pos;
1198	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1199	/*TODO: ftie->mic_control to set 3-CONFIRM */
1200	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1201	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1202	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1203
1204	pos = (u8 *) (ftie + 1);
1205
1206#ifdef CONFIG_TDLS_TESTING
1207	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1208		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1209			   "FTIE");
1210		ftie->ie_len += 170;
1211		*pos++ = 255; /* FTIE subelem */
1212		*pos++ = 168; /* FTIE subelem length */
1213		pos += 168;
1214	}
1215#endif /* CONFIG_TDLS_TESTING */
1216
1217	/* Lifetime */
1218	lifetime = peer->lifetime;
1219#ifdef CONFIG_TDLS_TESTING
1220	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_CONF) {
1221		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1222			   "lifetime in confirm");
1223		lifetime++;
1224	}
1225#endif /* CONFIG_TDLS_TESTING */
1226	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1227				     sizeof(timeoutie), lifetime);
1228	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds",
1229		   lifetime);
1230
1231	/* compute MIC before sending */
1232	wpa_tdls_ftie_mic(peer->tpk.kck, 3, (u8 *) lnkid, peer->rsnie_p,
1233			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1234
1235skip_ies:
1236	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 0,
1237			  rbuf, pos - rbuf);
1238	os_free(rbuf);
1239
1240	return 0;
1241}
1242
1243
1244static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
1245					    struct wpa_tdls_peer *peer,
1246					    u8 dialog_token)
1247{
1248	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Discovery Response "
1249		   "(peer " MACSTR ")", MAC2STR(peer->addr));
1250
1251	return wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
1252				 dialog_token, 0, NULL, 0);
1253}
1254
1255
1256static int
1257wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr,
1258				   const u8 *buf, size_t len)
1259{
1260	struct wpa_eapol_ie_parse kde;
1261	const struct wpa_tdls_lnkid *lnkid;
1262	struct wpa_tdls_peer *peer;
1263	size_t min_req_len = sizeof(struct wpa_tdls_frame) +
1264		1 /* dialog token */ + sizeof(struct wpa_tdls_lnkid);
1265	u8 dialog_token;
1266
1267	wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from " MACSTR,
1268		   MAC2STR(addr));
1269
1270	if (len < min_req_len) {
1271		wpa_printf(MSG_DEBUG, "TDLS Discovery Request is too short: "
1272			   "%d", (int) len);
1273		return -1;
1274	}
1275
1276	dialog_token = buf[sizeof(struct wpa_tdls_frame)];
1277
1278	if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1,
1279				     len - (sizeof(struct wpa_tdls_frame) + 1),
1280				     &kde) < 0)
1281		return -1;
1282
1283	if (!kde.lnkid) {
1284		wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery "
1285			   "Request");
1286		return -1;
1287	}
1288
1289	lnkid = (const struct wpa_tdls_lnkid *) kde.lnkid;
1290
1291	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1292		wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from different "
1293			   " BSS " MACSTR, MAC2STR(lnkid->bssid));
1294		return -1;
1295	}
1296
1297	peer = wpa_tdls_add_peer(sm, addr, NULL);
1298	if (peer == NULL)
1299		return -1;
1300
1301	return wpa_tdls_send_discovery_response(sm, peer, dialog_token);
1302}
1303
1304
1305int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
1306{
1307	if (sm->tdls_disabled || !sm->tdls_supported)
1308		return -1;
1309
1310	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
1311		   MACSTR, MAC2STR(addr));
1312	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
1313				 1, 0, NULL, 0);
1314}
1315
1316
1317static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
1318			   struct wpa_tdls_peer *peer)
1319{
1320	if (!kde->supp_rates) {
1321		wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
1322		return -1;
1323	}
1324	peer->supp_rates_len = merge_byte_arrays(
1325		peer->supp_rates, sizeof(peer->supp_rates),
1326		kde->supp_rates + 2, kde->supp_rates_len - 2,
1327		kde->ext_supp_rates + 2, kde->ext_supp_rates_len - 2);
1328	return 0;
1329}
1330
1331
1332static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
1333				   const u8 *buf, size_t len)
1334{
1335	struct wpa_tdls_peer *peer;
1336	struct wpa_eapol_ie_parse kde;
1337	struct wpa_ie_data ie;
1338	int cipher;
1339	const u8 *cpos;
1340	struct wpa_tdls_ftie *ftie = NULL;
1341	struct wpa_tdls_timeoutie *timeoutie;
1342	struct wpa_tdls_lnkid *lnkid;
1343	u32 lifetime = 0;
1344#if 0
1345	struct rsn_ie_hdr *hdr;
1346	u8 *pos;
1347	u16 rsn_capab;
1348	u16 rsn_ver;
1349#endif
1350	u8 dtoken;
1351	u16 ielen;
1352	u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1353	int tdls_prohibited = sm->tdls_prohibited;
1354	int existing_peer = 0;
1355
1356	if (len < 3 + 3)
1357		return -1;
1358
1359	cpos = buf;
1360	cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1361
1362	/* driver had already verified the frame format */
1363	dtoken = *cpos++; /* dialog token */
1364
1365	wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
1366
1367	peer = wpa_tdls_add_peer(sm, src_addr, &existing_peer);
1368	if (peer == NULL)
1369		goto error;
1370
1371	/* capability information */
1372	peer->capability = WPA_GET_LE16(cpos);
1373	cpos += 2;
1374
1375	ielen = len - (cpos - buf); /* start of IE in buf */
1376	if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
1377		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M1");
1378		goto error;
1379	}
1380
1381	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1382		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1383			   "TPK M1");
1384		goto error;
1385	}
1386	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
1387		    kde.lnkid, kde.lnkid_len);
1388	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1389	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1390		wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
1391		status = WLAN_STATUS_NOT_IN_SAME_BSS;
1392		goto error;
1393	}
1394
1395	wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
1396		   MAC2STR(src_addr));
1397
1398	if (copy_supp_rates(&kde, peer) < 0)
1399		goto error;
1400
1401#ifdef CONFIG_TDLS_TESTING
1402	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1403		peer = wpa_tdls_add_peer(sm, src_addr, NULL);
1404		if (peer == NULL)
1405			goto error;
1406		wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
1407			   "TDLS setup - send own request");
1408		peer->initiator = 1;
1409		wpa_tdls_send_tpk_m1(sm, peer);
1410	}
1411
1412	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
1413	    tdls_prohibited) {
1414		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
1415			   "on TDLS");
1416		tdls_prohibited = 0;
1417	}
1418#endif /* CONFIG_TDLS_TESTING */
1419
1420	if (tdls_prohibited) {
1421		wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
1422		status = WLAN_STATUS_REQUEST_DECLINED;
1423		goto error;
1424	}
1425
1426	if (!wpa_tdls_get_privacy(sm)) {
1427		if (kde.rsn_ie) {
1428			wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
1429				   "security is disabled");
1430			status = WLAN_STATUS_SECURITY_DISABLED;
1431			goto error;
1432		}
1433		goto skip_rsn;
1434	}
1435
1436	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1437	    kde.rsn_ie == NULL) {
1438		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
1439		status = WLAN_STATUS_INVALID_PARAMETERS;
1440		goto error;
1441	}
1442
1443	if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
1444		wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
1445			   "TPK M1");
1446		status = WLAN_STATUS_INVALID_RSNIE;
1447		goto error;
1448	}
1449
1450	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1451		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
1452		status = WLAN_STATUS_INVALID_RSNIE;
1453		goto error;
1454	}
1455
1456	cipher = ie.pairwise_cipher;
1457	if (cipher & WPA_CIPHER_CCMP) {
1458		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1459		cipher = WPA_CIPHER_CCMP;
1460	} else {
1461		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
1462		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1463		goto error;
1464	}
1465
1466	if ((ie.capabilities &
1467	     (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
1468	    WPA_CAPABILITY_PEERKEY_ENABLED) {
1469		wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
1470			   "TPK M1");
1471		status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
1472		goto error;
1473	}
1474
1475	/* Lifetime */
1476	if (kde.key_lifetime == NULL) {
1477		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
1478		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1479		goto error;
1480	}
1481	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1482	lifetime = WPA_GET_LE32(timeoutie->value);
1483	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
1484	if (lifetime < 300) {
1485		wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
1486		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1487		goto error;
1488	}
1489
1490skip_rsn:
1491	/* If found, use existing entry instead of adding a new one;
1492	 * how to handle the case where both ends initiate at the
1493	 * same time? */
1494	if (existing_peer) {
1495		if (peer->tpk_success) {
1496			wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
1497				   "direct link is enabled - tear down the "
1498				   "old link first");
1499#if 0
1500			/* TODO: Disabling the link would be more proper
1501			 * operation here, but it seems to trigger a race with
1502			 * some drivers handling the new request frame. */
1503			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1504#else
1505			if (sm->tdls_external_setup)
1506				wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
1507						 src_addr);
1508			else
1509				wpa_tdls_del_key(sm, peer);
1510#endif
1511			wpa_tdls_peer_free(sm, peer);
1512		}
1513
1514		/*
1515		 * An entry is already present, so check if we already sent a
1516		 * TDLS Setup Request. If so, compare MAC addresses and let the
1517		 * STA with the lower MAC address continue as the initiator.
1518		 * The other negotiation is terminated.
1519		 */
1520		if (peer->initiator) {
1521			if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
1522				wpa_printf(MSG_DEBUG, "TDLS: Discard request "
1523					   "from peer with higher address "
1524					   MACSTR, MAC2STR(src_addr));
1525				return -1;
1526			} else {
1527				wpa_printf(MSG_DEBUG, "TDLS: Accept request "
1528					   "from peer with lower address "
1529					   MACSTR " (terminate previously "
1530					   "initiated negotiation",
1531					   MAC2STR(src_addr));
1532				wpa_tdls_peer_free(sm, peer);
1533			}
1534		}
1535	}
1536
1537#ifdef CONFIG_TDLS_TESTING
1538	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1539		if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
1540			/*
1541			 * The request frame from us is going to win, so do not
1542			 * replace information based on this request frame from
1543			 * the peer.
1544			 */
1545			goto skip_rsn_check;
1546		}
1547	}
1548#endif /* CONFIG_TDLS_TESTING */
1549
1550	peer->initiator = 0; /* Need to check */
1551	peer->dtoken = dtoken;
1552
1553	if (!wpa_tdls_get_privacy(sm)) {
1554		peer->rsnie_i_len = 0;
1555		peer->rsnie_p_len = 0;
1556		peer->cipher = WPA_CIPHER_NONE;
1557		goto skip_rsn_check;
1558	}
1559
1560	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1561	os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
1562	os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
1563	peer->rsnie_i_len = kde.rsn_ie_len;
1564	peer->cipher = cipher;
1565
1566	if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
1567		wpa_msg(sm->ctx->ctx, MSG_WARNING,
1568			"TDLS: Failed to get random data for responder nonce");
1569		wpa_tdls_peer_free(sm, peer);
1570		goto error;
1571	}
1572
1573#if 0
1574	/* get version info from RSNIE received from Peer */
1575	hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
1576	rsn_ver = WPA_GET_LE16(hdr->version);
1577
1578	/* use min(peer's version, out version) */
1579	if (rsn_ver > RSN_VERSION)
1580		rsn_ver = RSN_VERSION;
1581
1582	hdr = (struct rsn_ie_hdr *) peer->rsnie_p;
1583
1584	hdr->elem_id = WLAN_EID_RSN;
1585	WPA_PUT_LE16(hdr->version, rsn_ver);
1586	pos = (u8 *) (hdr + 1);
1587
1588	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1589	pos += RSN_SELECTOR_LEN;
1590	/* Include only the selected cipher in pairwise cipher suite */
1591	WPA_PUT_LE16(pos, 1);
1592	pos += 2;
1593	if (cipher == WPA_CIPHER_CCMP)
1594		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1595	pos += RSN_SELECTOR_LEN;
1596
1597	WPA_PUT_LE16(pos, 1);
1598	pos += 2;
1599	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1600	pos += RSN_SELECTOR_LEN;
1601
1602	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1603	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1604	WPA_PUT_LE16(pos, rsn_capab);
1605	pos += 2;
1606
1607	hdr->len = (pos - peer->rsnie_p) - 2;
1608	peer->rsnie_p_len = pos - peer->rsnie_p;
1609#endif
1610
1611	/* temp fix: validation of RSNIE later */
1612	os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
1613	peer->rsnie_p_len = peer->rsnie_i_len;
1614
1615	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
1616		    peer->rsnie_p, peer->rsnie_p_len);
1617
1618	peer->lifetime = lifetime;
1619
1620	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1621
1622skip_rsn_check:
1623	/* add the peer to the driver as a "setup in progress" peer */
1624	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
1625
1626	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
1627	if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
1628		wpa_tdls_disable_link(sm, peer->addr);
1629		goto error;
1630	}
1631
1632	return 0;
1633
1634error:
1635	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
1636			    status);
1637	return -1;
1638}
1639
1640
1641static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
1642{
1643	peer->tpk_success = 1;
1644	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1645	if (wpa_tdls_get_privacy(sm)) {
1646		u32 lifetime = peer->lifetime;
1647		/*
1648		 * Start the initiator process a bit earlier to avoid race
1649		 * condition with the responder sending teardown request.
1650		 */
1651		if (lifetime > 3 && peer->initiator)
1652			lifetime -= 3;
1653		eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
1654				       sm, peer);
1655#ifdef CONFIG_TDLS_TESTING
1656	if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
1657		wpa_printf(MSG_DEBUG, "TDLS: Testing - disable TPK "
1658			   "expiration");
1659		eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1660	}
1661#endif /* CONFIG_TDLS_TESTING */
1662	}
1663
1664	/* add supported rates and capabilities to the TDLS peer */
1665	wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
1666				peer->supp_rates, peer->supp_rates_len);
1667
1668	wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
1669}
1670
1671
1672static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
1673				   const u8 *buf, size_t len)
1674{
1675	struct wpa_tdls_peer *peer;
1676	struct wpa_eapol_ie_parse kde;
1677	struct wpa_ie_data ie;
1678	int cipher;
1679	struct wpa_tdls_ftie *ftie;
1680	struct wpa_tdls_timeoutie *timeoutie;
1681	struct wpa_tdls_lnkid *lnkid;
1682	u32 lifetime;
1683	u8 dtoken;
1684	int ielen;
1685	u16 status;
1686	const u8 *pos;
1687
1688	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
1689		   "(Peer " MACSTR ")", MAC2STR(src_addr));
1690	for (peer = sm->tdls; peer; peer = peer->next) {
1691		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1692			break;
1693	}
1694	if (peer == NULL) {
1695		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1696			   "TPK M2: " MACSTR, MAC2STR(src_addr));
1697		return -1;
1698	}
1699	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
1700
1701	if (len < 3 + 2 + 1)
1702		return -1;
1703	pos = buf;
1704	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1705	status = WPA_GET_LE16(pos);
1706	pos += 2 /* status code */;
1707
1708	if (status != WLAN_STATUS_SUCCESS) {
1709		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
1710			   status);
1711		if (sm->tdls_external_setup)
1712			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1713		return -1;
1714	}
1715
1716	status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1717
1718	/* TODO: need to verify dialog token matches here or in kernel */
1719	dtoken = *pos++; /* dialog token */
1720
1721	wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
1722
1723	if (len < 3 + 2 + 1 + 2)
1724		return -1;
1725
1726	/* capability information */
1727	peer->capability = WPA_GET_LE16(pos);
1728	pos += 2;
1729
1730	ielen = len - (pos - buf); /* start of IE in buf */
1731	if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
1732		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M2");
1733		goto error;
1734	}
1735
1736#ifdef CONFIG_TDLS_TESTING
1737	if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
1738		wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
1739		status = WLAN_STATUS_REQUEST_DECLINED;
1740		goto error;
1741	}
1742#endif /* CONFIG_TDLS_TESTING */
1743
1744	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1745		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1746			   "TPK M2");
1747		goto error;
1748	}
1749	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
1750		    kde.lnkid, kde.lnkid_len);
1751	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1752
1753	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1754		wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
1755		status = WLAN_STATUS_NOT_IN_SAME_BSS;
1756		goto error;
1757	}
1758
1759	if (copy_supp_rates(&kde, peer) < 0)
1760		goto error;
1761
1762	if (!wpa_tdls_get_privacy(sm)) {
1763		peer->rsnie_p_len = 0;
1764		peer->cipher = WPA_CIPHER_NONE;
1765		goto skip_rsn;
1766	}
1767
1768	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1769	    kde.rsn_ie == NULL) {
1770		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
1771		status = WLAN_STATUS_INVALID_PARAMETERS;
1772		goto error;
1773	}
1774	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1775		    kde.rsn_ie, kde.rsn_ie_len);
1776
1777	/*
1778	 * FIX: bitwise comparison of RSN IE is not the correct way of
1779	 * validation this. It can be different, but certain fields must
1780	 * match. Since we list only a single pairwise cipher in TPK M1, the
1781	 * memcmp is likely to work in most cases, though.
1782	 */
1783	if (kde.rsn_ie_len != peer->rsnie_i_len ||
1784	    os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
1785		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
1786			   "not match with RSN IE used in TPK M1");
1787		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
1788			    peer->rsnie_i, peer->rsnie_i_len);
1789		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1790			    kde.rsn_ie, kde.rsn_ie_len);
1791		status = WLAN_STATUS_INVALID_RSNIE;
1792		goto error;
1793	}
1794
1795	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1796		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
1797		status = WLAN_STATUS_INVALID_RSNIE;
1798		goto error;
1799	}
1800
1801	cipher = ie.pairwise_cipher;
1802	if (cipher == WPA_CIPHER_CCMP) {
1803		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1804		cipher = WPA_CIPHER_CCMP;
1805	} else {
1806		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
1807		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1808		goto error;
1809	}
1810
1811	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
1812		    kde.ftie, sizeof(*ftie));
1813	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1814
1815	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1816		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
1817			   "not match with FTIE SNonce used in TPK M1");
1818		/* Silently discard the frame */
1819		return -1;
1820	}
1821
1822	/* Responder Nonce and RSN IE */
1823	os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
1824	os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
1825	peer->rsnie_p_len = kde.rsn_ie_len;
1826	peer->cipher = cipher;
1827
1828	/* Lifetime */
1829	if (kde.key_lifetime == NULL) {
1830		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
1831		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1832		goto error;
1833	}
1834	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1835	lifetime = WPA_GET_LE32(timeoutie->value);
1836	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
1837		   lifetime);
1838	if (lifetime != peer->lifetime) {
1839		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
1840			   "TPK M2 (expected %u)", lifetime, peer->lifetime);
1841		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1842		goto error;
1843	}
1844
1845	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1846
1847	/* Process MIC check to see if TPK M2 is right */
1848	if (wpa_supplicant_verify_tdls_mic(2, peer, (u8 *) lnkid,
1849					   (u8 *) timeoutie, ftie) < 0) {
1850		/* Discard the frame */
1851		wpa_tdls_del_key(sm, peer);
1852		wpa_tdls_peer_free(sm, peer);
1853		if (sm->tdls_external_setup)
1854			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1855		return -1;
1856	}
1857
1858	wpa_tdls_set_key(sm, peer);
1859
1860skip_rsn:
1861	peer->dtoken = dtoken;
1862
1863	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
1864		   "TPK Handshake Message 3");
1865	wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
1866
1867	wpa_tdls_enable_link(sm, peer);
1868
1869	return 0;
1870
1871error:
1872	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
1873			    status);
1874	if (sm->tdls_external_setup)
1875		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1876	return -1;
1877}
1878
1879
1880static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
1881				   const u8 *buf, size_t len)
1882{
1883	struct wpa_tdls_peer *peer;
1884	struct wpa_eapol_ie_parse kde;
1885	struct wpa_tdls_ftie *ftie;
1886	struct wpa_tdls_timeoutie *timeoutie;
1887	struct wpa_tdls_lnkid *lnkid;
1888	int ielen;
1889	u16 status;
1890	const u8 *pos;
1891	u32 lifetime;
1892
1893	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
1894		   "(Peer " MACSTR ")", MAC2STR(src_addr));
1895	for (peer = sm->tdls; peer; peer = peer->next) {
1896		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1897			break;
1898	}
1899	if (peer == NULL) {
1900		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1901			   "TPK M3: " MACSTR, MAC2STR(src_addr));
1902		return -1;
1903	}
1904	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
1905
1906	if (len < 3 + 3)
1907		return -1;
1908	pos = buf;
1909	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1910
1911	status = WPA_GET_LE16(pos);
1912
1913	if (status != 0) {
1914		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
1915			   status);
1916		if (sm->tdls_external_setup)
1917			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1918		return -1;
1919	}
1920	pos += 2 /* status code */ + 1 /* dialog token */;
1921
1922	ielen = len - (pos - buf); /* start of IE in buf */
1923	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
1924		wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3");
1925		return -1;
1926	}
1927
1928	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1929		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
1930		return -1;
1931	}
1932	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
1933		    (u8 *) kde.lnkid, kde.lnkid_len);
1934	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1935
1936	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1937		wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
1938		return -1;
1939	}
1940
1941	if (!wpa_tdls_get_privacy(sm))
1942		goto skip_rsn;
1943
1944	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
1945		wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
1946		return -1;
1947	}
1948	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
1949		    kde.ftie, sizeof(*ftie));
1950	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1951
1952	if (kde.rsn_ie == NULL) {
1953		wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
1954		return -1;
1955	}
1956	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
1957		    kde.rsn_ie, kde.rsn_ie_len);
1958	if (kde.rsn_ie_len != peer->rsnie_p_len ||
1959	    os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
1960		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
1961			   "with the one sent in TPK M2");
1962		return -1;
1963	}
1964
1965	if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
1966		wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
1967			   "not match with FTIE ANonce used in TPK M2");
1968		return -1;
1969	}
1970
1971	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1972		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
1973			   "match with FTIE SNonce used in TPK M1");
1974		return -1;
1975	}
1976
1977	if (kde.key_lifetime == NULL) {
1978		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
1979		return -1;
1980	}
1981	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1982	wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
1983		    (u8 *) timeoutie, sizeof(*timeoutie));
1984	lifetime = WPA_GET_LE32(timeoutie->value);
1985	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
1986		   lifetime);
1987	if (lifetime != peer->lifetime) {
1988		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
1989			   "TPK M3 (expected %u)", lifetime, peer->lifetime);
1990		if (sm->tdls_external_setup)
1991			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1992		return -1;
1993	}
1994
1995	if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
1996					   (u8 *) timeoutie, ftie) < 0) {
1997		wpa_tdls_del_key(sm, peer);
1998		wpa_tdls_peer_free(sm, peer);
1999		return -1;
2000	}
2001
2002	if (wpa_tdls_set_key(sm, peer) < 0)
2003		return -1;
2004
2005skip_rsn:
2006	wpa_tdls_enable_link(sm, peer);
2007
2008	return 0;
2009}
2010
2011
2012static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
2013{
2014	struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;
2015
2016	os_memset(lifetime, 0, ie_len);
2017	lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
2018	lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
2019	lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
2020	WPA_PUT_LE32(lifetime->value, tsecs);
2021	os_memcpy(pos, ie, ie_len);
2022	return pos + ie_len;
2023}
2024
2025
2026/**
2027 * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2028 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2029 * @peer: MAC address of the peer STA
2030 * Returns: 0 on success, or -1 on failure
2031 *
2032 * Send TPK Handshake Message 1 info to driver to start TDLS
2033 * handshake with the peer.
2034 */
2035int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
2036{
2037	struct wpa_tdls_peer *peer;
2038	int tdls_prohibited = sm->tdls_prohibited;
2039
2040	if (sm->tdls_disabled || !sm->tdls_supported)
2041		return -1;
2042
2043#ifdef CONFIG_TDLS_TESTING
2044	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2045	    tdls_prohibited) {
2046		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2047			   "on TDLS");
2048		tdls_prohibited = 0;
2049	}
2050#endif /* CONFIG_TDLS_TESTING */
2051
2052	if (tdls_prohibited) {
2053		wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
2054			   "reject request to start setup");
2055		return -1;
2056	}
2057
2058	peer = wpa_tdls_add_peer(sm, addr, NULL);
2059	if (peer == NULL)
2060		return -1;
2061
2062	peer->initiator = 1;
2063
2064	/* add the peer to the driver as a "setup in progress" peer */
2065	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
2066
2067	if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
2068		wpa_tdls_disable_link(sm, peer->addr);
2069		return -1;
2070	}
2071
2072	return 0;
2073}
2074
2075
2076void wpa_tdls_remove(struct wpa_sm *sm, const u8 *addr)
2077{
2078	struct wpa_tdls_peer *peer;
2079
2080	if (sm->tdls_disabled || !sm->tdls_supported)
2081		return;
2082
2083	for (peer = sm->tdls; peer; peer = peer->next) {
2084		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2085			break;
2086	}
2087
2088	if (peer == NULL || !peer->tpk_success)
2089		return;
2090
2091	if (sm->tdls_external_setup) {
2092		/*
2093		 * Disable previous link to allow renegotiation to be completed
2094		 * on AP path.
2095		 */
2096		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2097	}
2098}
2099
2100
2101/**
2102 * wpa_supplicant_rx_tdls - Receive TDLS data frame
2103 *
2104 * This function is called to receive TDLS (ethertype = 0x890d) data frames.
2105 */
2106static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
2107				   const u8 *buf, size_t len)
2108{
2109	struct wpa_sm *sm = ctx;
2110	struct wpa_tdls_frame *tf;
2111
2112	wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
2113		    buf, len);
2114
2115	if (sm->tdls_disabled || !sm->tdls_supported) {
2116		wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
2117			   "or unsupported by driver");
2118		return;
2119	}
2120
2121	if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
2122		wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
2123		return;
2124	}
2125
2126	if (len < sizeof(*tf)) {
2127		wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
2128		return;
2129	}
2130
2131	/* Check to make sure its a valid encapsulated TDLS frame */
2132	tf = (struct wpa_tdls_frame *) buf;
2133	if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
2134	    tf->category != WLAN_ACTION_TDLS) {
2135		wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
2136			   "category=%u action=%u",
2137			   tf->payloadtype, tf->category, tf->action);
2138		return;
2139	}
2140
2141	switch (tf->action) {
2142	case WLAN_TDLS_SETUP_REQUEST:
2143		wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
2144		break;
2145	case WLAN_TDLS_SETUP_RESPONSE:
2146		wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
2147		break;
2148	case WLAN_TDLS_SETUP_CONFIRM:
2149		wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
2150		break;
2151	case WLAN_TDLS_TEARDOWN:
2152		wpa_tdls_recv_teardown(sm, src_addr, buf, len);
2153		break;
2154	case WLAN_TDLS_DISCOVERY_REQUEST:
2155		wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
2156		break;
2157	default:
2158		/* Kernel code will process remaining frames */
2159		wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
2160			   tf->action);
2161		break;
2162	}
2163}
2164
2165
2166/**
2167 * wpa_tdls_init - Initialize driver interface parameters for TDLS
2168 * @wpa_s: Pointer to wpa_supplicant data
2169 * Returns: 0 on success, -1 on failure
2170 *
2171 * This function is called to initialize driver interface parameters for TDLS.
2172 * wpa_drv_init() must have been called before this function to initialize the
2173 * driver interface.
2174 */
2175int wpa_tdls_init(struct wpa_sm *sm)
2176{
2177	if (sm == NULL)
2178		return -1;
2179
2180	sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
2181				     sm->ifname,
2182				     sm->own_addr,
2183				     ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
2184				     sm, 0);
2185	if (sm->l2_tdls == NULL) {
2186		wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
2187			   "connection");
2188		return -1;
2189	}
2190
2191	/*
2192	 * Drivers that support TDLS but don't implement the get_capa callback
2193	 * are assumed to perform everything internally
2194	 */
2195	if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
2196				 &sm->tdls_external_setup) < 0) {
2197		sm->tdls_supported = 1;
2198		sm->tdls_external_setup = 0;
2199	}
2200
2201	wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
2202		   "driver", sm->tdls_supported ? "" : " not");
2203	wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
2204		   sm->tdls_external_setup ? "external" : "internal");
2205
2206	return 0;
2207}
2208
2209
2210static void wpa_tdls_remove_peers(struct wpa_sm *sm)
2211{
2212	struct wpa_tdls_peer *peer, *tmp;
2213
2214	peer = sm->tdls;
2215	sm->tdls = NULL;
2216
2217	while (peer) {
2218		int res;
2219		tmp = peer->next;
2220		res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2221		wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
2222			   MAC2STR(peer->addr), res);
2223		wpa_tdls_peer_free(sm, peer);
2224		os_free(peer);
2225		peer = tmp;
2226	}
2227}
2228
2229
2230/**
2231 * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
2232 *
2233 * This function is called to recover driver interface parameters for TDLS
2234 * and frees resources allocated for it.
2235 */
2236void wpa_tdls_deinit(struct wpa_sm *sm)
2237{
2238	if (sm == NULL)
2239		return;
2240
2241	if (sm->l2_tdls)
2242		l2_packet_deinit(sm->l2_tdls);
2243	sm->l2_tdls = NULL;
2244
2245	wpa_tdls_remove_peers(sm);
2246}
2247
2248
2249void wpa_tdls_assoc(struct wpa_sm *sm)
2250{
2251	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
2252	wpa_tdls_remove_peers(sm);
2253}
2254
2255
2256void wpa_tdls_disassoc(struct wpa_sm *sm)
2257{
2258	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
2259	wpa_tdls_remove_peers(sm);
2260}
2261
2262
2263static int wpa_tdls_prohibited(const u8 *ies, size_t len)
2264{
2265	struct wpa_eapol_ie_parse elems;
2266
2267	if (ies == NULL)
2268		return 0;
2269
2270	if (wpa_supplicant_parse_ies(ies, len, &elems) < 0)
2271		return 0;
2272
2273	if (elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
2274		return 0;
2275
2276	 /* bit 38 - TDLS Prohibited */
2277	return !!(elems.ext_capab[2 + 4] & 0x40);
2278}
2279
2280
2281void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2282{
2283	sm->tdls_prohibited = wpa_tdls_prohibited(ies, len);
2284	wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
2285		   sm->tdls_prohibited ? "prohibited" : "allowed");
2286}
2287
2288
2289void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2290{
2291	if (!sm->tdls_prohibited && wpa_tdls_prohibited(ies, len)) {
2292		wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
2293			   "(Re)Association Response IEs");
2294		sm->tdls_prohibited = 1;
2295	}
2296}
2297
2298
2299void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
2300{
2301	wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
2302	sm->tdls_disabled = !enabled;
2303}
2304
2305
2306int wpa_tdls_is_external_setup(struct wpa_sm *sm)
2307{
2308	return sm->tdls_external_setup;
2309}
2310