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