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