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