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