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