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		goto skip_ies;
685
686	ftie = (struct wpa_tdls_ftie *) pos;
687	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
688	/* Using the recent nonce which should be for CONFIRM frame */
689	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
690	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
691	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
692	pos = (u8 *) (ftie + 1);
693#ifdef CONFIG_TDLS_TESTING
694	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
695		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
696			   "FTIE");
697		ftie->ie_len += 170;
698		*pos++ = 255; /* FTIE subelem */
699		*pos++ = 168; /* FTIE subelem length */
700		pos += 168;
701	}
702#endif /* CONFIG_TDLS_TESTING */
703	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TDLS Teardown handshake",
704		    (u8 *) ftie, pos - (u8 *) ftie);
705
706	/* compute MIC before sending */
707	wpa_tdls_linkid(sm, peer, &lnkid);
708	wpa_tdls_key_mic_teardown(peer->tpk.kck, 4, reason_code,
709				  dialog_token, (u8 *) &lnkid, (u8 *) ftie,
710				  ftie->mic);
711
712skip_ies:
713	/* TODO: register for a Timeout handler, if Teardown is not received at
714	 * the other end, then try again another time */
715
716	/* request driver to send Teardown using this FTIE */
717	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
718			  WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, rbuf,
719			  pos - rbuf);
720	os_free(rbuf);
721
722	/* clear the Peerkey statemachine */
723	wpa_tdls_peer_free(sm, peer);
724
725	return 0;
726}
727
728
729int wpa_tdls_teardown_link(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
730{
731	struct wpa_tdls_peer *peer;
732
733	if (sm->tdls_disabled || !sm->tdls_supported)
734		return -1;
735
736	for (peer = sm->tdls; peer; peer = peer->next) {
737		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
738			break;
739	}
740
741	if (peer == NULL) {
742		wpa_printf(MSG_DEBUG, "TDLS: Could not find peer " MACSTR
743		   " for link Teardown", MAC2STR(addr));
744		return -1;
745	}
746
747	if (!peer->tpk_success) {
748		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
749		   " not connected - cannot Teardown link", MAC2STR(addr));
750		return -1;
751	}
752
753	return wpa_tdls_do_teardown(sm, peer, reason_code, 0);
754}
755
756
757void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
758{
759	struct wpa_tdls_peer *peer;
760
761	for (peer = sm->tdls; peer; peer = peer->next) {
762		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
763			break;
764	}
765
766	if (peer) {
767		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
768		wpa_tdls_peer_free(sm, peer);
769	}
770}
771
772
773static int wpa_tdls_recv_teardown(struct wpa_sm *sm, const u8 *src_addr,
774				  const u8 *buf, size_t len)
775{
776	struct wpa_tdls_peer *peer = NULL;
777	struct wpa_tdls_ftie *ftie;
778	struct wpa_tdls_lnkid *lnkid;
779	struct wpa_eapol_ie_parse kde;
780	u16 reason_code;
781	const u8 *pos;
782	int ielen;
783
784	/* Find the node and free from the list */
785	for (peer = sm->tdls; peer; peer = peer->next) {
786		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
787			break;
788	}
789
790	if (peer == NULL) {
791		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
792			   "Teardown " MACSTR, MAC2STR(src_addr));
793		return 0;
794	}
795
796	pos = buf;
797	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
798
799	reason_code = WPA_GET_LE16(pos);
800	pos += 2;
801
802	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown Request from " MACSTR
803		   " (reason code %u)", MAC2STR(src_addr), reason_code);
804
805	ielen = len - (pos - buf); /* start of IE in buf */
806	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
807		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in Teardown");
808		return -1;
809	}
810
811	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
812		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TDLS "
813			   "Teardown");
814		return -1;
815	}
816	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
817
818	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
819		goto skip_ftie;
820
821	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
822		wpa_printf(MSG_INFO, "TDLS: No FTIE in TDLS Teardown");
823		return -1;
824	}
825
826	ftie = (struct wpa_tdls_ftie *) kde.ftie;
827
828	/* Process MIC check to see if TDLS Teardown is right */
829	if (wpa_supplicant_verify_tdls_mic_teardown(4, reason_code,
830						    peer->dtoken, peer,
831						    (u8 *) lnkid, ftie) < 0) {
832		wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS "
833			   "Teardown Request from " MACSTR, MAC2STR(src_addr));
834		return -1;
835	}
836
837skip_ftie:
838	/*
839	 * Request the driver to disable the direct link and clear associated
840	 * keys.
841	 */
842	wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
843
844	/* clear the Peerkey statemachine */
845	wpa_tdls_peer_free(sm, peer);
846
847	return 0;
848}
849
850
851/**
852 * wpa_tdls_send_error - To send suitable TDLS status response with
853 *	appropriate status code mentioning reason for error/failure.
854 * @dst 	- MAC addr of Peer station
855 * @tdls_action - TDLS frame type for which error code is sent
856 * @status 	- status code mentioning reason
857 */
858
859static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
860			       u8 tdls_action, u8 dialog_token, u16 status)
861{
862	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
863		   " (action=%u status=%u)",
864		   MAC2STR(dst), tdls_action, status);
865	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
866				 NULL, 0);
867}
868
869
870static struct wpa_tdls_peer *
871wpa_tdls_add_peer(struct wpa_sm *sm, const u8 *addr)
872{
873	struct wpa_tdls_peer *peer;
874
875	wpa_printf(MSG_INFO, "TDLS: Creating peer entry for " MACSTR,
876		   MAC2STR(addr));
877
878	peer = os_zalloc(sizeof(*peer));
879	if (peer == NULL)
880		return NULL;
881
882	os_memcpy(peer->addr, addr, ETH_ALEN);
883	peer->next = sm->tdls;
884	sm->tdls = peer;
885
886	return peer;
887}
888
889
890static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm,
891				struct wpa_tdls_peer *peer)
892{
893	size_t buf_len;
894	struct wpa_tdls_timeoutie timeoutie;
895	u16 rsn_capab;
896	struct wpa_tdls_ftie *ftie;
897	u8 *rbuf, *pos, *count_pos;
898	u16 count;
899	struct rsn_ie_hdr *hdr;
900
901	if (!wpa_tdls_get_privacy(sm)) {
902		wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
903		peer->rsnie_i_len = 0;
904		goto skip_rsnie;
905	}
906
907	/*
908	 * TPK Handshake Message 1:
909	 * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I,
910	 * Timeout Interval IE))
911	 */
912
913	/* Filling RSN IE */
914	hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
915	hdr->elem_id = WLAN_EID_RSN;
916	WPA_PUT_LE16(hdr->version, RSN_VERSION);
917
918	pos = (u8 *) (hdr + 1);
919	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
920	pos += RSN_SELECTOR_LEN;
921	count_pos = pos;
922	pos += 2;
923
924	count = 0;
925
926	/*
927	 * AES-CCMP is the default Encryption preferred for TDLS, so
928	 * RSN IE is filled only with CCMP CIPHER
929	 * Note: TKIP is not used to encrypt TDLS link.
930	 *
931	 * Regardless of the cipher used on the AP connection, select CCMP
932	 * here.
933	 */
934	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
935	pos += RSN_SELECTOR_LEN;
936	count++;
937
938	WPA_PUT_LE16(count_pos, count);
939
940	WPA_PUT_LE16(pos, 1);
941	pos += 2;
942	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
943	pos += RSN_SELECTOR_LEN;
944
945	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
946	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
947#ifdef CONFIG_TDLS_TESTING
948	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
949		wpa_printf(MSG_DEBUG, "TDLS: Use alternative RSN IE for "
950			   "testing");
951		rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
952	}
953#endif /* CONFIG_TDLS_TESTING */
954	WPA_PUT_LE16(pos, rsn_capab);
955	pos += 2;
956#ifdef CONFIG_TDLS_TESTING
957	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
958		/* Number of PMKIDs */
959		*pos++ = 0x00;
960		*pos++ = 0x00;
961	}
962#endif /* CONFIG_TDLS_TESTING */
963
964	hdr->len = (pos - peer->rsnie_i) - 2;
965	peer->rsnie_i_len = pos - peer->rsnie_i;
966	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
967		    peer->rsnie_i, peer->rsnie_i_len);
968
969skip_rsnie:
970	buf_len = 0;
971	if (wpa_tdls_get_privacy(sm))
972		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
973			sizeof(struct wpa_tdls_timeoutie);
974#ifdef CONFIG_TDLS_TESTING
975	if (wpa_tdls_get_privacy(sm) &&
976	    (tdls_testing & TDLS_TESTING_LONG_FRAME))
977		buf_len += 170;
978	if (tdls_testing & TDLS_TESTING_DIFF_BSSID)
979		buf_len += sizeof(struct wpa_tdls_lnkid);
980#endif /* CONFIG_TDLS_TESTING */
981	rbuf = os_zalloc(buf_len + 1);
982	if (rbuf == NULL) {
983		wpa_tdls_peer_free(sm, peer);
984		return -1;
985	}
986	pos = rbuf;
987
988	if (!wpa_tdls_get_privacy(sm))
989		goto skip_ies;
990
991	/* Initiator RSN IE */
992	pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
993
994	ftie = (struct wpa_tdls_ftie *) pos;
995	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
996	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
997
998	if (os_get_random(peer->inonce, WPA_NONCE_LEN)) {
999		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1000			"TDLS: Failed to get random data for initiator Nonce");
1001		os_free(rbuf);
1002		wpa_tdls_peer_free(sm, peer);
1003		return -1;
1004	}
1005	wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
1006		    peer->inonce, WPA_NONCE_LEN);
1007	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1008
1009	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK Handshake M1",
1010		    (u8 *) ftie, sizeof(struct wpa_tdls_ftie));
1011
1012	pos = (u8 *) (ftie + 1);
1013
1014#ifdef CONFIG_TDLS_TESTING
1015	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1016		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1017			   "FTIE");
1018		ftie->ie_len += 170;
1019		*pos++ = 255; /* FTIE subelem */
1020		*pos++ = 168; /* FTIE subelem length */
1021		pos += 168;
1022	}
1023#endif /* CONFIG_TDLS_TESTING */
1024
1025	/* Lifetime */
1026	peer->lifetime = TPK_LIFETIME;
1027#ifdef CONFIG_TDLS_TESTING
1028	if (tdls_testing & TDLS_TESTING_SHORT_LIFETIME) {
1029		wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK "
1030			   "lifetime");
1031		peer->lifetime = 301;
1032	}
1033	if (tdls_testing & TDLS_TESTING_LONG_LIFETIME) {
1034		wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK "
1035			   "lifetime");
1036		peer->lifetime = 0xffffffff;
1037	}
1038#endif /* CONFIG_TDLS_TESTING */
1039	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1040				     sizeof(timeoutie), peer->lifetime);
1041	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1042
1043skip_ies:
1044
1045#ifdef CONFIG_TDLS_TESTING
1046	if (tdls_testing & TDLS_TESTING_DIFF_BSSID) {
1047		wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in "
1048			   "Link Identifier");
1049		struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos;
1050		wpa_tdls_linkid(sm, peer, l);
1051		l->bssid[5] ^= 0x01;
1052		pos += sizeof(*l);
1053	}
1054#endif /* CONFIG_TDLS_TESTING */
1055
1056	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Request / TPK "
1057		   "Handshake Message 1 (peer " MACSTR ")",
1058		   MAC2STR(peer->addr));
1059
1060	wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 1, 0,
1061			  rbuf, pos - rbuf);
1062	os_free(rbuf);
1063
1064	return 0;
1065}
1066
1067
1068static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
1069				const unsigned char *src_addr, u8 dtoken,
1070				struct wpa_tdls_lnkid *lnkid,
1071				const struct wpa_tdls_peer *peer)
1072{
1073	u8 *rbuf, *pos;
1074	size_t buf_len;
1075	u32 lifetime;
1076	struct wpa_tdls_timeoutie timeoutie;
1077	struct wpa_tdls_ftie *ftie;
1078
1079	buf_len = 0;
1080	if (wpa_tdls_get_privacy(sm)) {
1081		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1082		 * Lifetime */
1083		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1084			sizeof(struct wpa_tdls_timeoutie);
1085#ifdef CONFIG_TDLS_TESTING
1086		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1087			buf_len += 170;
1088#endif /* CONFIG_TDLS_TESTING */
1089	}
1090
1091	rbuf = os_zalloc(buf_len + 1);
1092	if (rbuf == NULL)
1093		return -1;
1094	pos = rbuf;
1095
1096	if (!wpa_tdls_get_privacy(sm))
1097		goto skip_ies;
1098
1099	/* Peer RSN IE */
1100	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1101
1102	ftie = (struct wpa_tdls_ftie *) pos;
1103	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1104	/* TODO: ftie->mic_control to set 2-RESPONSE */
1105	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1106	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1107	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1108	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK M2",
1109		    (u8 *) ftie, sizeof(*ftie));
1110
1111	pos = (u8 *) (ftie + 1);
1112
1113#ifdef CONFIG_TDLS_TESTING
1114	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1115		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1116			   "FTIE");
1117		ftie->ie_len += 170;
1118		*pos++ = 255; /* FTIE subelem */
1119		*pos++ = 168; /* FTIE subelem length */
1120		pos += 168;
1121	}
1122#endif /* CONFIG_TDLS_TESTING */
1123
1124	/* Lifetime */
1125	lifetime = peer->lifetime;
1126#ifdef CONFIG_TDLS_TESTING
1127	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_RESP) {
1128		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1129			   "lifetime in response");
1130		lifetime++;
1131	}
1132#endif /* CONFIG_TDLS_TESTING */
1133	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1134				     sizeof(timeoutie), lifetime);
1135	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds from initiator",
1136		   lifetime);
1137
1138	/* compute MIC before sending */
1139	wpa_tdls_ftie_mic(peer->tpk.kck, 2, (u8 *) lnkid, peer->rsnie_p,
1140			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1141
1142skip_ies:
1143	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
1144			  rbuf, pos - rbuf);
1145	os_free(rbuf);
1146
1147	return 0;
1148}
1149
1150
1151static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm,
1152				const unsigned char *src_addr, u8 dtoken,
1153				struct wpa_tdls_lnkid *lnkid,
1154				const struct wpa_tdls_peer *peer)
1155{
1156	u8 *rbuf, *pos;
1157	size_t buf_len;
1158	struct wpa_tdls_ftie *ftie;
1159	struct wpa_tdls_timeoutie timeoutie;
1160	u32 lifetime;
1161
1162	buf_len = 0;
1163	if (wpa_tdls_get_privacy(sm)) {
1164		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1165		 * Lifetime */
1166		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1167			sizeof(struct wpa_tdls_timeoutie);
1168#ifdef CONFIG_TDLS_TESTING
1169		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1170			buf_len += 170;
1171#endif /* CONFIG_TDLS_TESTING */
1172	}
1173
1174	rbuf = os_zalloc(buf_len + 1);
1175	if (rbuf == NULL)
1176		return -1;
1177	pos = rbuf;
1178
1179	if (!wpa_tdls_get_privacy(sm))
1180		goto skip_ies;
1181
1182	/* Peer RSN IE */
1183	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1184
1185	ftie = (struct wpa_tdls_ftie *) pos;
1186	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1187	/*TODO: ftie->mic_control to set 3-CONFIRM */
1188	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1189	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1190	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1191
1192	pos = (u8 *) (ftie + 1);
1193
1194#ifdef CONFIG_TDLS_TESTING
1195	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1196		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1197			   "FTIE");
1198		ftie->ie_len += 170;
1199		*pos++ = 255; /* FTIE subelem */
1200		*pos++ = 168; /* FTIE subelem length */
1201		pos += 168;
1202	}
1203#endif /* CONFIG_TDLS_TESTING */
1204
1205	/* Lifetime */
1206	lifetime = peer->lifetime;
1207#ifdef CONFIG_TDLS_TESTING
1208	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_CONF) {
1209		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1210			   "lifetime in confirm");
1211		lifetime++;
1212	}
1213#endif /* CONFIG_TDLS_TESTING */
1214	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1215				     sizeof(timeoutie), lifetime);
1216	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds",
1217		   lifetime);
1218
1219	/* compute MIC before sending */
1220	wpa_tdls_ftie_mic(peer->tpk.kck, 3, (u8 *) lnkid, peer->rsnie_p,
1221			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1222
1223skip_ies:
1224	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 0,
1225			  rbuf, pos - rbuf);
1226	os_free(rbuf);
1227
1228	return 0;
1229}
1230
1231
1232static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
1233					    struct wpa_tdls_peer *peer,
1234					    u8 dialog_token)
1235{
1236	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Discovery Response "
1237		   "(peer " MACSTR ")", MAC2STR(peer->addr));
1238
1239	return wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
1240				 dialog_token, 0, NULL, 0);
1241}
1242
1243
1244static int
1245wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr,
1246				   const u8 *buf, size_t len)
1247{
1248	struct wpa_eapol_ie_parse kde;
1249	const struct wpa_tdls_lnkid *lnkid;
1250	struct wpa_tdls_peer *peer;
1251	size_t min_req_len = sizeof(struct wpa_tdls_frame) +
1252		1 /* dialog token */ + sizeof(struct wpa_tdls_lnkid);
1253	u8 dialog_token;
1254
1255	wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from " MACSTR,
1256		   MAC2STR(addr));
1257
1258	if (len < min_req_len) {
1259		wpa_printf(MSG_DEBUG, "TDLS Discovery Request is too short: "
1260			   "%d", (int) len);
1261		return -1;
1262	}
1263
1264	dialog_token = buf[sizeof(struct wpa_tdls_frame)];
1265
1266	if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1,
1267				     len - (sizeof(struct wpa_tdls_frame) + 1),
1268				     &kde) < 0)
1269		return -1;
1270
1271	if (!kde.lnkid) {
1272		wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery "
1273			   "Request");
1274		return -1;
1275	}
1276
1277	lnkid = (const struct wpa_tdls_lnkid *) kde.lnkid;
1278
1279	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1280		wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from different "
1281			   " BSS " MACSTR, MAC2STR(lnkid->bssid));
1282		return -1;
1283	}
1284
1285	peer = wpa_tdls_add_peer(sm, addr);
1286	if (peer == NULL)
1287		return -1;
1288
1289	return wpa_tdls_send_discovery_response(sm, peer, dialog_token);
1290}
1291
1292
1293int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
1294{
1295	if (sm->tdls_disabled || !sm->tdls_supported)
1296		return -1;
1297
1298	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
1299		   MACSTR, MAC2STR(addr));
1300	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
1301				 1, 0, NULL, 0);
1302}
1303
1304
1305static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
1306			   struct wpa_tdls_peer *peer)
1307{
1308	if (!kde->supp_rates) {
1309		wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
1310		return -1;
1311	}
1312
1313	peer->supp_rates_len = kde->supp_rates_len - 2;
1314	if (peer->supp_rates_len > IEEE80211_MAX_SUPP_RATES)
1315		peer->supp_rates_len = IEEE80211_MAX_SUPP_RATES;
1316	os_memcpy(peer->supp_rates, kde->supp_rates + 2, peer->supp_rates_len);
1317
1318	if (kde->ext_supp_rates) {
1319		int clen = kde->ext_supp_rates_len - 2;
1320		if (peer->supp_rates_len + clen > IEEE80211_MAX_SUPP_RATES)
1321			clen = IEEE80211_MAX_SUPP_RATES - peer->supp_rates_len;
1322		os_memcpy(peer->supp_rates + peer->supp_rates_len,
1323			  kde->ext_supp_rates + 2, clen);
1324		peer->supp_rates_len += clen;
1325	}
1326
1327	return 0;
1328}
1329
1330
1331static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
1332				   const u8 *buf, size_t len)
1333{
1334	struct wpa_tdls_peer *peer;
1335	struct wpa_eapol_ie_parse kde;
1336	struct wpa_ie_data ie;
1337	int cipher;
1338	const u8 *cpos;
1339	struct wpa_tdls_ftie *ftie = NULL;
1340	struct wpa_tdls_timeoutie *timeoutie;
1341	struct wpa_tdls_lnkid *lnkid;
1342	u32 lifetime = 0;
1343#if 0
1344	struct rsn_ie_hdr *hdr;
1345	u8 *pos;
1346	u16 rsn_capab;
1347	u16 rsn_ver;
1348#endif
1349	u8 dtoken;
1350	u16 ielen;
1351	u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1352	int tdls_prohibited = sm->tdls_prohibited;
1353	int existing_peer = 0;
1354
1355	if (len < 3 + 3)
1356		return -1;
1357
1358	cpos = buf;
1359	cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1360
1361	/* driver had already verified the frame format */
1362	dtoken = *cpos++; /* dialog token */
1363
1364	wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
1365
1366	for (peer = sm->tdls; peer; peer = peer->next) {
1367		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0) {
1368			existing_peer = 1;
1369			break;
1370		}
1371	}
1372
1373	if (peer == NULL) {
1374		peer = wpa_tdls_add_peer(sm, src_addr);
1375		if (peer == NULL)
1376			goto error;
1377	}
1378
1379	/* capability information */
1380	peer->capability = WPA_GET_LE16(cpos);
1381	cpos += 2;
1382
1383	ielen = len - (cpos - buf); /* start of IE in buf */
1384	if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
1385		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M1");
1386		goto error;
1387	}
1388
1389	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1390		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1391			   "TPK M1");
1392		goto error;
1393	}
1394	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
1395		    kde.lnkid, kde.lnkid_len);
1396	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1397	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1398		wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
1399		status = WLAN_STATUS_NOT_IN_SAME_BSS;
1400		goto error;
1401	}
1402
1403	wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
1404		   MAC2STR(src_addr));
1405
1406	if (copy_supp_rates(&kde, peer) < 0)
1407		goto error;
1408
1409#ifdef CONFIG_TDLS_TESTING
1410	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1411		for (peer = sm->tdls; peer; peer = peer->next) {
1412			if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1413				break;
1414		}
1415		if (peer == NULL) {
1416			peer = wpa_tdls_add_peer(sm, src_addr);
1417			if (peer == NULL)
1418				goto error;
1419		}
1420		wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
1421			   "TDLS setup - send own request");
1422		peer->initiator = 1;
1423		wpa_tdls_send_tpk_m1(sm, peer);
1424	}
1425
1426	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
1427	    tdls_prohibited) {
1428		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
1429			   "on TDLS");
1430		tdls_prohibited = 0;
1431	}
1432#endif /* CONFIG_TDLS_TESTING */
1433
1434	if (tdls_prohibited) {
1435		wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
1436		status = WLAN_STATUS_REQUEST_DECLINED;
1437		goto error;
1438	}
1439
1440	if (!wpa_tdls_get_privacy(sm)) {
1441		if (kde.rsn_ie) {
1442			wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
1443				   "security is disabled");
1444			status = WLAN_STATUS_SECURITY_DISABLED;
1445			goto error;
1446		}
1447		goto skip_rsn;
1448	}
1449
1450	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1451	    kde.rsn_ie == NULL) {
1452		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
1453		status = WLAN_STATUS_INVALID_PARAMETERS;
1454		goto error;
1455	}
1456
1457	if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
1458		wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
1459			   "TPK M1");
1460		status = WLAN_STATUS_INVALID_RSNIE;
1461		goto error;
1462	}
1463
1464	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1465		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
1466		status = WLAN_STATUS_INVALID_RSNIE;
1467		goto error;
1468	}
1469
1470	cipher = ie.pairwise_cipher;
1471	if (cipher & WPA_CIPHER_CCMP) {
1472		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1473		cipher = WPA_CIPHER_CCMP;
1474	} else {
1475		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
1476		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1477		goto error;
1478	}
1479
1480	if ((ie.capabilities &
1481	     (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
1482	    WPA_CAPABILITY_PEERKEY_ENABLED) {
1483		wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
1484			   "TPK M1");
1485		status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
1486		goto error;
1487	}
1488
1489	/* Lifetime */
1490	if (kde.key_lifetime == NULL) {
1491		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
1492		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1493		goto error;
1494	}
1495	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1496	lifetime = WPA_GET_LE32(timeoutie->value);
1497	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
1498	if (lifetime < 300) {
1499		wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
1500		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1501		goto error;
1502	}
1503
1504skip_rsn:
1505	/* If found, use existing entry instead of adding a new one;
1506	 * how to handle the case where both ends initiate at the
1507	 * same time? */
1508	if (existing_peer) {
1509		if (peer->tpk_success) {
1510			wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
1511				   "direct link is enabled - tear down the "
1512				   "old link first");
1513#if 0
1514			/* TODO: Disabling the link would be more proper
1515			 * operation here, but it seems to trigger a race with
1516			 * some drivers handling the new request frame. */
1517			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1518#else
1519			if (sm->tdls_external_setup)
1520				wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
1521						 src_addr);
1522			else
1523				wpa_tdls_del_key(sm, peer);
1524#endif
1525			wpa_tdls_peer_free(sm, peer);
1526		}
1527
1528		/*
1529		 * An entry is already present, so check if we already sent a
1530		 * TDLS Setup Request. If so, compare MAC addresses and let the
1531		 * STA with the lower MAC address continue as the initiator.
1532		 * The other negotiation is terminated.
1533		 */
1534		if (peer->initiator) {
1535			if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
1536				wpa_printf(MSG_DEBUG, "TDLS: Discard request "
1537					   "from peer with higher address "
1538					   MACSTR, MAC2STR(src_addr));
1539				return -1;
1540			} else {
1541				wpa_printf(MSG_DEBUG, "TDLS: Accept request "
1542					   "from peer with lower address "
1543					   MACSTR " (terminate previously "
1544					   "initiated negotiation",
1545					   MAC2STR(src_addr));
1546				wpa_tdls_peer_free(sm, peer);
1547			}
1548		}
1549	}
1550
1551#ifdef CONFIG_TDLS_TESTING
1552	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1553		if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
1554			/*
1555			 * The request frame from us is going to win, so do not
1556			 * replace information based on this request frame from
1557			 * the peer.
1558			 */
1559			goto skip_rsn_check;
1560		}
1561	}
1562#endif /* CONFIG_TDLS_TESTING */
1563
1564	peer->initiator = 0; /* Need to check */
1565	peer->dtoken = dtoken;
1566
1567	if (!wpa_tdls_get_privacy(sm)) {
1568		peer->rsnie_i_len = 0;
1569		peer->rsnie_p_len = 0;
1570		peer->cipher = WPA_CIPHER_NONE;
1571		goto skip_rsn_check;
1572	}
1573
1574	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1575	os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
1576	os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
1577	peer->rsnie_i_len = kde.rsn_ie_len;
1578	peer->cipher = cipher;
1579
1580	if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
1581		wpa_msg(sm->ctx->ctx, MSG_WARNING,
1582			"TDLS: Failed to get random data for responder nonce");
1583		wpa_tdls_peer_free(sm, peer);
1584		goto error;
1585	}
1586
1587#if 0
1588	/* get version info from RSNIE received from Peer */
1589	hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
1590	rsn_ver = WPA_GET_LE16(hdr->version);
1591
1592	/* use min(peer's version, out version) */
1593	if (rsn_ver > RSN_VERSION)
1594		rsn_ver = RSN_VERSION;
1595
1596	hdr = (struct rsn_ie_hdr *) peer->rsnie_p;
1597
1598	hdr->elem_id = WLAN_EID_RSN;
1599	WPA_PUT_LE16(hdr->version, rsn_ver);
1600	pos = (u8 *) (hdr + 1);
1601
1602	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1603	pos += RSN_SELECTOR_LEN;
1604	/* Include only the selected cipher in pairwise cipher suite */
1605	WPA_PUT_LE16(pos, 1);
1606	pos += 2;
1607	if (cipher == WPA_CIPHER_CCMP)
1608		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1609	pos += RSN_SELECTOR_LEN;
1610
1611	WPA_PUT_LE16(pos, 1);
1612	pos += 2;
1613	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1614	pos += RSN_SELECTOR_LEN;
1615
1616	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1617	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1618	WPA_PUT_LE16(pos, rsn_capab);
1619	pos += 2;
1620
1621	hdr->len = (pos - peer->rsnie_p) - 2;
1622	peer->rsnie_p_len = pos - peer->rsnie_p;
1623#endif
1624
1625	/* temp fix: validation of RSNIE later */
1626	os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
1627	peer->rsnie_p_len = peer->rsnie_i_len;
1628
1629	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
1630		    peer->rsnie_p, peer->rsnie_p_len);
1631
1632	peer->lifetime = lifetime;
1633
1634	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1635
1636skip_rsn_check:
1637	/* add the peer to the driver as a "setup in progress" peer */
1638	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
1639
1640	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
1641	if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
1642		wpa_tdls_disable_link(sm, peer->addr);
1643		goto error;
1644	}
1645
1646	return 0;
1647
1648error:
1649	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
1650			    status);
1651	return -1;
1652}
1653
1654
1655static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
1656{
1657	peer->tpk_success = 1;
1658	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1659	if (wpa_tdls_get_privacy(sm)) {
1660		u32 lifetime = peer->lifetime;
1661		/*
1662		 * Start the initiator process a bit earlier to avoid race
1663		 * condition with the responder sending teardown request.
1664		 */
1665		if (lifetime > 3 && peer->initiator)
1666			lifetime -= 3;
1667		eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
1668				       sm, peer);
1669#ifdef CONFIG_TDLS_TESTING
1670	if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
1671		wpa_printf(MSG_DEBUG, "TDLS: Testing - disable TPK "
1672			   "expiration");
1673		eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1674	}
1675#endif /* CONFIG_TDLS_TESTING */
1676	}
1677
1678	/* add supported rates and capabilities to the TDLS peer */
1679	wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
1680				peer->supp_rates, peer->supp_rates_len);
1681
1682	wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
1683}
1684
1685
1686static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
1687				   const u8 *buf, size_t len)
1688{
1689	struct wpa_tdls_peer *peer;
1690	struct wpa_eapol_ie_parse kde;
1691	struct wpa_ie_data ie;
1692	int cipher;
1693	struct wpa_tdls_ftie *ftie;
1694	struct wpa_tdls_timeoutie *timeoutie;
1695	struct wpa_tdls_lnkid *lnkid;
1696	u32 lifetime;
1697	u8 dtoken;
1698	int ielen;
1699	u16 status;
1700	const u8 *pos;
1701
1702	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
1703		   "(Peer " MACSTR ")", MAC2STR(src_addr));
1704	for (peer = sm->tdls; peer; peer = peer->next) {
1705		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1706			break;
1707	}
1708	if (peer == NULL) {
1709		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1710			   "TPK M2: " MACSTR, MAC2STR(src_addr));
1711		return -1;
1712	}
1713	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
1714
1715	if (len < 3 + 2 + 1)
1716		return -1;
1717	pos = buf;
1718	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1719	status = WPA_GET_LE16(pos);
1720	pos += 2 /* status code */;
1721
1722	if (status != WLAN_STATUS_SUCCESS) {
1723		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
1724			   status);
1725		if (sm->tdls_external_setup)
1726			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1727		return -1;
1728	}
1729
1730	status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1731
1732	/* TODO: need to verify dialog token matches here or in kernel */
1733	dtoken = *pos++; /* dialog token */
1734
1735	wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
1736
1737	if (len < 3 + 2 + 1 + 2)
1738		return -1;
1739
1740	/* capability information */
1741	peer->capability = WPA_GET_LE16(pos);
1742	pos += 2;
1743
1744	ielen = len - (pos - buf); /* start of IE in buf */
1745	if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
1746		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M2");
1747		goto error;
1748	}
1749
1750#ifdef CONFIG_TDLS_TESTING
1751	if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
1752		wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
1753		status = WLAN_STATUS_REQUEST_DECLINED;
1754		goto error;
1755	}
1756#endif /* CONFIG_TDLS_TESTING */
1757
1758	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1759		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1760			   "TPK M2");
1761		goto error;
1762	}
1763	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
1764		    kde.lnkid, kde.lnkid_len);
1765	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1766
1767	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1768		wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
1769		status = WLAN_STATUS_NOT_IN_SAME_BSS;
1770		goto error;
1771	}
1772
1773	if (copy_supp_rates(&kde, peer) < 0)
1774		goto error;
1775
1776	if (!wpa_tdls_get_privacy(sm)) {
1777		peer->rsnie_p_len = 0;
1778		peer->cipher = WPA_CIPHER_NONE;
1779		goto skip_rsn;
1780	}
1781
1782	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1783	    kde.rsn_ie == NULL) {
1784		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
1785		status = WLAN_STATUS_INVALID_PARAMETERS;
1786		goto error;
1787	}
1788	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1789		    kde.rsn_ie, kde.rsn_ie_len);
1790
1791	/*
1792	 * FIX: bitwise comparison of RSN IE is not the correct way of
1793	 * validation this. It can be different, but certain fields must
1794	 * match. Since we list only a single pairwise cipher in TPK M1, the
1795	 * memcmp is likely to work in most cases, though.
1796	 */
1797	if (kde.rsn_ie_len != peer->rsnie_i_len ||
1798	    os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
1799		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
1800			   "not match with RSN IE used in TPK M1");
1801		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
1802			    peer->rsnie_i, peer->rsnie_i_len);
1803		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1804			    kde.rsn_ie, kde.rsn_ie_len);
1805		status = WLAN_STATUS_INVALID_RSNIE;
1806		goto error;
1807	}
1808
1809	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1810		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
1811		status = WLAN_STATUS_INVALID_RSNIE;
1812		goto error;
1813	}
1814
1815	cipher = ie.pairwise_cipher;
1816	if (cipher == WPA_CIPHER_CCMP) {
1817		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1818		cipher = WPA_CIPHER_CCMP;
1819	} else {
1820		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
1821		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1822		goto error;
1823	}
1824
1825	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
1826		    kde.ftie, sizeof(*ftie));
1827	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1828
1829	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1830		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
1831			   "not match with FTIE SNonce used in TPK M1");
1832		/* Silently discard the frame */
1833		return -1;
1834	}
1835
1836	/* Responder Nonce and RSN IE */
1837	os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
1838	os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
1839	peer->rsnie_p_len = kde.rsn_ie_len;
1840	peer->cipher = cipher;
1841
1842	/* Lifetime */
1843	if (kde.key_lifetime == NULL) {
1844		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
1845		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1846		goto error;
1847	}
1848	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1849	lifetime = WPA_GET_LE32(timeoutie->value);
1850	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
1851		   lifetime);
1852	if (lifetime != peer->lifetime) {
1853		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
1854			   "TPK M2 (expected %u)", lifetime, peer->lifetime);
1855		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1856		goto error;
1857	}
1858
1859	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1860
1861	/* Process MIC check to see if TPK M2 is right */
1862	if (wpa_supplicant_verify_tdls_mic(2, peer, (u8 *) lnkid,
1863					   (u8 *) timeoutie, ftie) < 0) {
1864		/* Discard the frame */
1865		wpa_tdls_del_key(sm, peer);
1866		wpa_tdls_peer_free(sm, peer);
1867		if (sm->tdls_external_setup)
1868			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1869		return -1;
1870	}
1871
1872	wpa_tdls_set_key(sm, peer);
1873
1874skip_rsn:
1875	peer->dtoken = dtoken;
1876
1877	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
1878		   "TPK Handshake Message 3");
1879	wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
1880
1881	wpa_tdls_enable_link(sm, peer);
1882
1883	return 0;
1884
1885error:
1886	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
1887			    status);
1888	if (sm->tdls_external_setup)
1889		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1890	return -1;
1891}
1892
1893
1894static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
1895				   const u8 *buf, size_t len)
1896{
1897	struct wpa_tdls_peer *peer;
1898	struct wpa_eapol_ie_parse kde;
1899	struct wpa_tdls_ftie *ftie;
1900	struct wpa_tdls_timeoutie *timeoutie;
1901	struct wpa_tdls_lnkid *lnkid;
1902	int ielen;
1903	u16 status;
1904	const u8 *pos;
1905	u32 lifetime;
1906
1907	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
1908		   "(Peer " MACSTR ")", MAC2STR(src_addr));
1909	for (peer = sm->tdls; peer; peer = peer->next) {
1910		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1911			break;
1912	}
1913	if (peer == NULL) {
1914		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1915			   "TPK M3: " MACSTR, MAC2STR(src_addr));
1916		return -1;
1917	}
1918	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
1919
1920	if (len < 3 + 3)
1921		return -1;
1922	pos = buf;
1923	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1924
1925	status = WPA_GET_LE16(pos);
1926
1927	if (status != 0) {
1928		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
1929			   status);
1930		if (sm->tdls_external_setup)
1931			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1932		return -1;
1933	}
1934	pos += 2 /* status code */ + 1 /* dialog token */;
1935
1936	ielen = len - (pos - buf); /* start of IE in buf */
1937	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
1938		wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3");
1939		return -1;
1940	}
1941
1942	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1943		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
1944		return -1;
1945	}
1946	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
1947		    (u8 *) kde.lnkid, kde.lnkid_len);
1948	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1949
1950	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1951		wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
1952		return -1;
1953	}
1954
1955	if (!wpa_tdls_get_privacy(sm))
1956		goto skip_rsn;
1957
1958	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
1959		wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
1960		return -1;
1961	}
1962	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
1963		    kde.ftie, sizeof(*ftie));
1964	ftie = (struct wpa_tdls_ftie *) kde.ftie;
1965
1966	if (kde.rsn_ie == NULL) {
1967		wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
1968		return -1;
1969	}
1970	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
1971		    kde.rsn_ie, kde.rsn_ie_len);
1972	if (kde.rsn_ie_len != peer->rsnie_p_len ||
1973	    os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
1974		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
1975			   "with the one sent in TPK M2");
1976		return -1;
1977	}
1978
1979	if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
1980		wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
1981			   "not match with FTIE ANonce used in TPK M2");
1982		return -1;
1983	}
1984
1985	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1986		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
1987			   "match with FTIE SNonce used in TPK M1");
1988		return -1;
1989	}
1990
1991	if (kde.key_lifetime == NULL) {
1992		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
1993		return -1;
1994	}
1995	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1996	wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
1997		    (u8 *) timeoutie, sizeof(*timeoutie));
1998	lifetime = WPA_GET_LE32(timeoutie->value);
1999	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
2000		   lifetime);
2001	if (lifetime != peer->lifetime) {
2002		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2003			   "TPK M3 (expected %u)", lifetime, peer->lifetime);
2004		if (sm->tdls_external_setup)
2005			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
2006		return -1;
2007	}
2008
2009	if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
2010					   (u8 *) timeoutie, ftie) < 0) {
2011		wpa_tdls_del_key(sm, peer);
2012		wpa_tdls_peer_free(sm, peer);
2013		return -1;
2014	}
2015
2016	if (wpa_tdls_set_key(sm, peer) < 0)
2017		return -1;
2018
2019skip_rsn:
2020	wpa_tdls_enable_link(sm, peer);
2021
2022	return 0;
2023}
2024
2025
2026static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
2027{
2028	struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;
2029
2030	os_memset(lifetime, 0, ie_len);
2031	lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
2032	lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
2033	lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
2034	WPA_PUT_LE32(lifetime->value, tsecs);
2035	os_memcpy(pos, ie, ie_len);
2036	return pos + ie_len;
2037}
2038
2039
2040/**
2041 * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2042 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2043 * @peer: MAC address of the peer STA
2044 * Returns: 0 on success, or -1 on failure
2045 *
2046 * Send TPK Handshake Message 1 info to driver to start TDLS
2047 * handshake with the peer.
2048 */
2049int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
2050{
2051	struct wpa_tdls_peer *peer;
2052	int tdls_prohibited = sm->tdls_prohibited;
2053
2054	if (sm->tdls_disabled || !sm->tdls_supported)
2055		return -1;
2056
2057#ifdef CONFIG_TDLS_TESTING
2058	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2059	    tdls_prohibited) {
2060		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2061			   "on TDLS");
2062		tdls_prohibited = 0;
2063	}
2064#endif /* CONFIG_TDLS_TESTING */
2065
2066	if (tdls_prohibited) {
2067		wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
2068			   "reject request to start setup");
2069		return -1;
2070	}
2071
2072	/* Find existing entry and if found, use that instead of adding
2073	 * a new one */
2074	for (peer = sm->tdls; peer; peer = peer->next) {
2075		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2076			break;
2077	}
2078
2079	if (peer == NULL) {
2080		peer = wpa_tdls_add_peer(sm, addr);
2081		if (peer == NULL)
2082			return -1;
2083	}
2084
2085	peer->initiator = 1;
2086
2087	/* add the peer to the driver as a "setup in progress" peer */
2088	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
2089
2090	if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
2091		wpa_tdls_disable_link(sm, peer->addr);
2092		return -1;
2093	}
2094
2095	return 0;
2096}
2097
2098
2099int wpa_tdls_reneg(struct wpa_sm *sm, const u8 *addr)
2100{
2101	struct wpa_tdls_peer *peer;
2102
2103	if (sm->tdls_disabled || !sm->tdls_supported)
2104		return -1;
2105
2106	for (peer = sm->tdls; peer; peer = peer->next) {
2107		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2108			break;
2109	}
2110
2111	if (peer == NULL || !peer->tpk_success)
2112		return -1;
2113
2114	if (sm->tdls_external_setup) {
2115		/*
2116		 * Disable previous link to allow renegotiation to be completed
2117		 * on AP path.
2118		 */
2119		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2120	}
2121
2122	return wpa_tdls_start(sm, addr);
2123}
2124
2125
2126/**
2127 * wpa_supplicant_rx_tdls - Receive TDLS data frame
2128 *
2129 * This function is called to receive TDLS (ethertype = 0x890d) data frames.
2130 */
2131static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
2132				   const u8 *buf, size_t len)
2133{
2134	struct wpa_sm *sm = ctx;
2135	struct wpa_tdls_frame *tf;
2136
2137	wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
2138		    buf, len);
2139
2140	if (sm->tdls_disabled || !sm->tdls_supported) {
2141		wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
2142			   "or unsupported by driver");
2143		return;
2144	}
2145
2146	if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
2147		wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
2148		return;
2149	}
2150
2151	if (len < sizeof(*tf)) {
2152		wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
2153		return;
2154	}
2155
2156	/* Check to make sure its a valid encapsulated TDLS frame */
2157	tf = (struct wpa_tdls_frame *) buf;
2158	if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
2159	    tf->category != WLAN_ACTION_TDLS) {
2160		wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
2161			   "category=%u action=%u",
2162			   tf->payloadtype, tf->category, tf->action);
2163		return;
2164	}
2165
2166	switch (tf->action) {
2167	case WLAN_TDLS_SETUP_REQUEST:
2168		wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
2169		break;
2170	case WLAN_TDLS_SETUP_RESPONSE:
2171		wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
2172		break;
2173	case WLAN_TDLS_SETUP_CONFIRM:
2174		wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
2175		break;
2176	case WLAN_TDLS_TEARDOWN:
2177		wpa_tdls_recv_teardown(sm, src_addr, buf, len);
2178		break;
2179	case WLAN_TDLS_DISCOVERY_REQUEST:
2180		wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
2181		break;
2182	default:
2183		/* Kernel code will process remaining frames */
2184		wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
2185			   tf->action);
2186		break;
2187	}
2188}
2189
2190
2191/**
2192 * wpa_tdls_init - Initialize driver interface parameters for TDLS
2193 * @wpa_s: Pointer to wpa_supplicant data
2194 * Returns: 0 on success, -1 on failure
2195 *
2196 * This function is called to initialize driver interface parameters for TDLS.
2197 * wpa_drv_init() must have been called before this function to initialize the
2198 * driver interface.
2199 */
2200int wpa_tdls_init(struct wpa_sm *sm)
2201{
2202	if (sm == NULL)
2203		return -1;
2204
2205	sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
2206				     sm->ifname,
2207				     sm->own_addr,
2208				     ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
2209				     sm, 0);
2210	if (sm->l2_tdls == NULL) {
2211		wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
2212			   "connection");
2213		return -1;
2214	}
2215
2216	/*
2217	 * Drivers that support TDLS but don't implement the get_capa callback
2218	 * are assumed to perform everything internally
2219	 */
2220	if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
2221				 &sm->tdls_external_setup) < 0) {
2222		sm->tdls_supported = 1;
2223		sm->tdls_external_setup = 0;
2224	}
2225
2226	wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
2227		   "driver", sm->tdls_supported ? "" : " not");
2228	wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
2229		   sm->tdls_external_setup ? "external" : "internal");
2230
2231	return 0;
2232}
2233
2234
2235static void wpa_tdls_remove_peers(struct wpa_sm *sm)
2236{
2237	struct wpa_tdls_peer *peer, *tmp;
2238
2239	peer = sm->tdls;
2240	sm->tdls = NULL;
2241
2242	while (peer) {
2243		int res;
2244		tmp = peer->next;
2245		res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2246		wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
2247			   MAC2STR(peer->addr), res);
2248		wpa_tdls_peer_free(sm, peer);
2249		os_free(peer);
2250		peer = tmp;
2251	}
2252}
2253
2254
2255/**
2256 * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
2257 *
2258 * This function is called to recover driver interface parameters for TDLS
2259 * and frees resources allocated for it.
2260 */
2261void wpa_tdls_deinit(struct wpa_sm *sm)
2262{
2263	if (sm == NULL)
2264		return;
2265
2266	if (sm->l2_tdls)
2267		l2_packet_deinit(sm->l2_tdls);
2268	sm->l2_tdls = NULL;
2269
2270	wpa_tdls_remove_peers(sm);
2271}
2272
2273
2274void wpa_tdls_assoc(struct wpa_sm *sm)
2275{
2276	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
2277	wpa_tdls_remove_peers(sm);
2278}
2279
2280
2281void wpa_tdls_disassoc(struct wpa_sm *sm)
2282{
2283	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
2284	wpa_tdls_remove_peers(sm);
2285}
2286
2287
2288static int wpa_tdls_prohibited(const u8 *ies, size_t len)
2289{
2290	struct wpa_eapol_ie_parse elems;
2291
2292	if (ies == NULL)
2293		return 0;
2294
2295	if (wpa_supplicant_parse_ies(ies, len, &elems) < 0)
2296		return 0;
2297
2298	if (elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
2299		return 0;
2300
2301	 /* bit 38 - TDLS Prohibited */
2302	return !!(elems.ext_capab[2 + 4] & 0x40);
2303}
2304
2305
2306void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2307{
2308	sm->tdls_prohibited = wpa_tdls_prohibited(ies, len);
2309	wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
2310		   sm->tdls_prohibited ? "prohibited" : "allowed");
2311}
2312
2313
2314void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2315{
2316	if (!sm->tdls_prohibited && wpa_tdls_prohibited(ies, len)) {
2317		wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
2318			   "(Re)Association Response IEs");
2319		sm->tdls_prohibited = 1;
2320	}
2321}
2322
2323
2324void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
2325{
2326	wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
2327	sm->tdls_disabled = !enabled;
2328}
2329
2330
2331int wpa_tdls_is_external_setup(struct wpa_sm *sm)
2332{
2333	return sm->tdls_external_setup;
2334}
2335