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