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