Home | History | Annotate | Download | only in rsn_supp
      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)
     42 unsigned 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 
     53 struct 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 
     63 struct 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 
     70 struct 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 */
     79 struct 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 
     85 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
     86 static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx);
     87 static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
     88 
     89 
     90 #define TDLS_MAX_IE_LEN 80
     91 struct 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 
    125 static 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 
    136 static 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 
    143 static 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 
    156 static 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 
    189 static 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 
    198 static 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 
    256 static 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 
    307 static 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 
    333 static 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  */
    398 static 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  */
    460 static 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 
    507 static 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 
    536 static 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 
    559 static 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 
    584 static 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 
    602 static 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 
    618 int 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 
    691 skip_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 
    708 static 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 
    772 skip_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 
    794 static 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 
    805 static 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 
    884 skip_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 
    958 skip_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 
    983 static 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 
   1057 skip_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 
   1066 static 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 
   1138 skip_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 
   1147 static 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 
   1304 skip_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 
   1435 skip_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 
   1441 error:
   1442 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
   1443 			    status);
   1444 	return -1;
   1445 }
   1446 
   1447 
   1448 static 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 
   1474 static 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 
   1652 skip_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 
   1663 error:
   1664 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
   1665 			    status);
   1666 	return -1;
   1667 }
   1668 
   1669 
   1670 static 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 
   1791 skip_rsn:
   1792 	wpa_tdls_enable_link(sm, peer);
   1793 
   1794 	return 0;
   1795 }
   1796 
   1797 
   1798 static 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  */
   1821 int 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 
   1869 int 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  */
   1893 static 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  */
   1958 int 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 
   1976 static 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  */
   2002 void 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 
   2015 void 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 
   2022 void 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 
   2029 static 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 
   2047 void 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 
   2055 void 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 
   2065 void 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