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 25 : nonce[0] = peer->inonce;
404 25 : nonce[1] = peer->rnonce;
405 : } else {
406 17 : nonce[0] = peer->rnonce;
407 17 : 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 25 : if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
943 0 : wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in Teardown");
944 0 : return -1;
945 : }
946 :
947 25 : if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
948 0 : wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TDLS "
949 : "Teardown");
950 0 : return -1;
951 : }
952 25 : lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
953 :
954 25 : if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
955 : goto skip_ftie;
956 :
957 19 : if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
958 1 : wpa_printf(MSG_INFO, "TDLS: No FTIE in TDLS Teardown");
959 1 : return -1;
960 : }
961 :
962 18 : ftie = (struct wpa_tdls_ftie *) kde.ftie;
963 :
964 : /* Process MIC check to see if TDLS Teardown is right */
965 18 : if (wpa_supplicant_verify_tdls_mic_teardown(4, reason_code,
966 18 : peer->dtoken, peer,
967 : (u8 *) lnkid, ftie) < 0) {
968 0 : wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS "
969 0 : "Teardown Request from " MACSTR, MAC2STR(src_addr));
970 0 : return -1;
971 : }
972 :
973 : skip_ftie:
974 : /*
975 : * Request the driver to disable the direct link and clear associated
976 : * keys.
977 : */
978 24 : wpa_tdls_disable_peer_link(sm, peer);
979 24 : return 0;
980 : }
981 :
982 :
983 : /**
984 : * wpa_tdls_send_error - To send suitable TDLS status response with
985 : * appropriate status code mentioning reason for error/failure.
986 : * @dst - MAC addr of Peer station
987 : * @tdls_action - TDLS frame type for which error code is sent
988 : * @initiator - was this end the initiator of the connection
989 : * @status - status code mentioning reason
990 : */
991 :
992 3 : static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
993 : u8 tdls_action, u8 dialog_token, int initiator,
994 : u16 status)
995 : {
996 21 : wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
997 : " (action=%u status=%u)",
998 18 : MAC2STR(dst), tdls_action, status);
999 3 : return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
1000 : 0, initiator, NULL, 0);
1001 : }
1002 :
1003 :
1004 : static struct wpa_tdls_peer *
1005 65 : wpa_tdls_add_peer(struct wpa_sm *sm, const u8 *addr, int *existing)
1006 : {
1007 : struct wpa_tdls_peer *peer;
1008 :
1009 65 : if (existing)
1010 31 : *existing = 0;
1011 65 : for (peer = sm->tdls; peer; peer = peer->next) {
1012 5 : if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) {
1013 5 : if (existing)
1014 3 : *existing = 1;
1015 5 : return peer; /* re-use existing entry */
1016 : }
1017 : }
1018 :
1019 360 : wpa_printf(MSG_INFO, "TDLS: Creating peer entry for " MACSTR,
1020 360 : MAC2STR(addr));
1021 :
1022 60 : peer = os_zalloc(sizeof(*peer));
1023 60 : if (peer == NULL)
1024 1 : return NULL;
1025 :
1026 59 : os_memcpy(peer->addr, addr, ETH_ALEN);
1027 59 : peer->next = sm->tdls;
1028 59 : sm->tdls = peer;
1029 :
1030 59 : return peer;
1031 : }
1032 :
1033 :
1034 31 : static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm,
1035 : struct wpa_tdls_peer *peer)
1036 : {
1037 : size_t buf_len;
1038 : struct wpa_tdls_timeoutie timeoutie;
1039 : u16 rsn_capab;
1040 : struct wpa_tdls_ftie *ftie;
1041 : u8 *rbuf, *pos, *count_pos;
1042 : u16 count;
1043 : struct rsn_ie_hdr *hdr;
1044 : int status;
1045 :
1046 31 : if (!wpa_tdls_get_privacy(sm)) {
1047 6 : wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
1048 6 : peer->rsnie_i_len = 0;
1049 6 : goto skip_rsnie;
1050 : }
1051 :
1052 : /*
1053 : * TPK Handshake Message 1:
1054 : * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I,
1055 : * Timeout Interval IE))
1056 : */
1057 :
1058 : /* Filling RSN IE */
1059 25 : hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
1060 25 : hdr->elem_id = WLAN_EID_RSN;
1061 25 : WPA_PUT_LE16(hdr->version, RSN_VERSION);
1062 :
1063 25 : pos = (u8 *) (hdr + 1);
1064 25 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1065 25 : pos += RSN_SELECTOR_LEN;
1066 25 : count_pos = pos;
1067 25 : pos += 2;
1068 :
1069 25 : count = 0;
1070 :
1071 : /*
1072 : * AES-CCMP is the default Encryption preferred for TDLS, so
1073 : * RSN IE is filled only with CCMP CIPHER
1074 : * Note: TKIP is not used to encrypt TDLS link.
1075 : *
1076 : * Regardless of the cipher used on the AP connection, select CCMP
1077 : * here.
1078 : */
1079 25 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1080 25 : pos += RSN_SELECTOR_LEN;
1081 25 : count++;
1082 :
1083 25 : WPA_PUT_LE16(count_pos, count);
1084 :
1085 25 : WPA_PUT_LE16(pos, 1);
1086 25 : pos += 2;
1087 25 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1088 25 : pos += RSN_SELECTOR_LEN;
1089 :
1090 25 : rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1091 25 : rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1092 : #ifdef CONFIG_TDLS_TESTING
1093 25 : if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
1094 1 : wpa_printf(MSG_DEBUG, "TDLS: Use alternative RSN IE for "
1095 : "testing");
1096 1 : rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1097 : }
1098 : #endif /* CONFIG_TDLS_TESTING */
1099 25 : WPA_PUT_LE16(pos, rsn_capab);
1100 25 : pos += 2;
1101 : #ifdef CONFIG_TDLS_TESTING
1102 25 : if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
1103 : /* Number of PMKIDs */
1104 1 : *pos++ = 0x00;
1105 1 : *pos++ = 0x00;
1106 : }
1107 : #endif /* CONFIG_TDLS_TESTING */
1108 :
1109 25 : hdr->len = (pos - peer->rsnie_i) - 2;
1110 25 : peer->rsnie_i_len = pos - peer->rsnie_i;
1111 50 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
1112 25 : peer->rsnie_i, peer->rsnie_i_len);
1113 :
1114 : skip_rsnie:
1115 31 : buf_len = 0;
1116 31 : if (wpa_tdls_get_privacy(sm))
1117 25 : buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1118 : sizeof(struct wpa_tdls_timeoutie);
1119 : #ifdef CONFIG_TDLS_TESTING
1120 56 : if (wpa_tdls_get_privacy(sm) &&
1121 25 : (tdls_testing & TDLS_TESTING_LONG_FRAME))
1122 2 : buf_len += 170;
1123 31 : if (tdls_testing & TDLS_TESTING_DIFF_BSSID)
1124 0 : buf_len += sizeof(struct wpa_tdls_lnkid);
1125 : #endif /* CONFIG_TDLS_TESTING */
1126 31 : rbuf = os_zalloc(buf_len + 1);
1127 31 : if (rbuf == NULL) {
1128 0 : wpa_tdls_peer_free(sm, peer);
1129 0 : return -1;
1130 : }
1131 31 : pos = rbuf;
1132 :
1133 31 : if (!wpa_tdls_get_privacy(sm))
1134 6 : goto skip_ies;
1135 :
1136 : /* Initiator RSN IE */
1137 25 : pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
1138 :
1139 25 : ftie = (struct wpa_tdls_ftie *) pos;
1140 25 : ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1141 25 : ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1142 :
1143 25 : if (os_get_random(peer->inonce, WPA_NONCE_LEN)) {
1144 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1145 : "TDLS: Failed to get random data for initiator Nonce");
1146 0 : os_free(rbuf);
1147 0 : wpa_tdls_peer_free(sm, peer);
1148 0 : return -1;
1149 : }
1150 25 : wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
1151 25 : peer->inonce, WPA_NONCE_LEN);
1152 25 : os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1153 :
1154 25 : wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK Handshake M1",
1155 : (u8 *) ftie, sizeof(struct wpa_tdls_ftie));
1156 :
1157 25 : pos = (u8 *) (ftie + 1);
1158 :
1159 : #ifdef CONFIG_TDLS_TESTING
1160 25 : if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1161 2 : wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1162 : "FTIE");
1163 2 : ftie->ie_len += 170;
1164 2 : *pos++ = 255; /* FTIE subelem */
1165 2 : *pos++ = 168; /* FTIE subelem length */
1166 2 : pos += 168;
1167 : }
1168 : #endif /* CONFIG_TDLS_TESTING */
1169 :
1170 : /* Lifetime */
1171 25 : peer->lifetime = TPK_LIFETIME;
1172 : #ifdef CONFIG_TDLS_TESTING
1173 25 : if (tdls_testing & TDLS_TESTING_SHORT_LIFETIME) {
1174 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK "
1175 : "lifetime");
1176 0 : peer->lifetime = 301;
1177 : }
1178 25 : if (tdls_testing & TDLS_TESTING_LONG_LIFETIME) {
1179 1 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK "
1180 : "lifetime");
1181 1 : peer->lifetime = 0xffffffff;
1182 : }
1183 : #endif /* CONFIG_TDLS_TESTING */
1184 25 : pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1185 : sizeof(timeoutie), peer->lifetime);
1186 25 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1187 :
1188 : skip_ies:
1189 :
1190 : #ifdef CONFIG_TDLS_TESTING
1191 31 : if (tdls_testing & TDLS_TESTING_DIFF_BSSID) {
1192 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in "
1193 : "Link Identifier");
1194 0 : struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos;
1195 0 : wpa_tdls_linkid(sm, peer, l);
1196 0 : l->bssid[5] ^= 0x01;
1197 0 : pos += sizeof(*l);
1198 : }
1199 : #endif /* CONFIG_TDLS_TESTING */
1200 :
1201 186 : wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Request / TPK "
1202 : "Handshake Message 1 (peer " MACSTR ")",
1203 186 : MAC2STR(peer->addr));
1204 :
1205 31 : status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
1206 31 : 1, 0, 0, peer->initiator, rbuf, pos - rbuf);
1207 31 : os_free(rbuf);
1208 :
1209 31 : return status;
1210 : }
1211 :
1212 :
1213 29 : static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
1214 : const unsigned char *src_addr, u8 dtoken,
1215 : struct wpa_tdls_lnkid *lnkid,
1216 : const struct wpa_tdls_peer *peer)
1217 : {
1218 : u8 *rbuf, *pos;
1219 : size_t buf_len;
1220 : u32 lifetime;
1221 : struct wpa_tdls_timeoutie timeoutie;
1222 : struct wpa_tdls_ftie *ftie;
1223 : int status;
1224 :
1225 29 : buf_len = 0;
1226 29 : if (wpa_tdls_get_privacy(sm)) {
1227 : /* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1228 : * Lifetime */
1229 23 : buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1230 : sizeof(struct wpa_tdls_timeoutie);
1231 : #ifdef CONFIG_TDLS_TESTING
1232 23 : if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1233 2 : buf_len += 170;
1234 : #endif /* CONFIG_TDLS_TESTING */
1235 : }
1236 :
1237 29 : rbuf = os_zalloc(buf_len + 1);
1238 29 : if (rbuf == NULL)
1239 0 : return -1;
1240 29 : pos = rbuf;
1241 :
1242 29 : if (!wpa_tdls_get_privacy(sm))
1243 6 : goto skip_ies;
1244 :
1245 : /* Peer RSN IE */
1246 23 : pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1247 :
1248 23 : ftie = (struct wpa_tdls_ftie *) pos;
1249 23 : ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1250 : /* TODO: ftie->mic_control to set 2-RESPONSE */
1251 23 : os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1252 23 : os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1253 23 : ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1254 23 : wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK M2",
1255 : (u8 *) ftie, sizeof(*ftie));
1256 :
1257 23 : pos = (u8 *) (ftie + 1);
1258 :
1259 : #ifdef CONFIG_TDLS_TESTING
1260 23 : if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1261 2 : wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1262 : "FTIE");
1263 2 : ftie->ie_len += 170;
1264 2 : *pos++ = 255; /* FTIE subelem */
1265 2 : *pos++ = 168; /* FTIE subelem length */
1266 2 : pos += 168;
1267 : }
1268 : #endif /* CONFIG_TDLS_TESTING */
1269 :
1270 : /* Lifetime */
1271 23 : lifetime = peer->lifetime;
1272 : #ifdef CONFIG_TDLS_TESTING
1273 23 : if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_RESP) {
1274 1 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1275 : "lifetime in response");
1276 1 : lifetime++;
1277 : }
1278 : #endif /* CONFIG_TDLS_TESTING */
1279 23 : pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1280 : sizeof(timeoutie), lifetime);
1281 23 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds from initiator",
1282 : lifetime);
1283 :
1284 : /* compute MIC before sending */
1285 23 : wpa_tdls_ftie_mic(peer->tpk.kck, 2, (u8 *) lnkid, peer->rsnie_p,
1286 23 : (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1287 : #ifdef CONFIG_TDLS_TESTING
1288 23 : if (tdls_testing & TDLS_TESTING_WRONG_MIC) {
1289 1 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC");
1290 1 : ftie->mic[0] ^= 0x01;
1291 : }
1292 : #endif /* CONFIG_TDLS_TESTING */
1293 :
1294 : skip_ies:
1295 29 : status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
1296 : dtoken, 0, 0, peer->initiator, rbuf,
1297 29 : pos - rbuf);
1298 29 : os_free(rbuf);
1299 :
1300 29 : return status;
1301 : }
1302 :
1303 :
1304 25 : static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm,
1305 : const unsigned char *src_addr, u8 dtoken,
1306 : struct wpa_tdls_lnkid *lnkid,
1307 : const struct wpa_tdls_peer *peer)
1308 : {
1309 : u8 *rbuf, *pos;
1310 : size_t buf_len;
1311 : struct wpa_tdls_ftie *ftie;
1312 : struct wpa_tdls_timeoutie timeoutie;
1313 : u32 lifetime;
1314 : int status;
1315 25 : u32 peer_capab = 0;
1316 :
1317 25 : buf_len = 0;
1318 25 : if (wpa_tdls_get_privacy(sm)) {
1319 : /* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
1320 : * Lifetime */
1321 19 : buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
1322 : sizeof(struct wpa_tdls_timeoutie);
1323 : #ifdef CONFIG_TDLS_TESTING
1324 19 : if (tdls_testing & TDLS_TESTING_LONG_FRAME)
1325 2 : buf_len += 170;
1326 : #endif /* CONFIG_TDLS_TESTING */
1327 : }
1328 :
1329 25 : rbuf = os_zalloc(buf_len + 1);
1330 25 : if (rbuf == NULL)
1331 0 : return -1;
1332 25 : pos = rbuf;
1333 :
1334 25 : if (!wpa_tdls_get_privacy(sm))
1335 6 : goto skip_ies;
1336 :
1337 : /* Peer RSN IE */
1338 19 : pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);
1339 :
1340 19 : ftie = (struct wpa_tdls_ftie *) pos;
1341 19 : ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
1342 : /*TODO: ftie->mic_control to set 3-CONFIRM */
1343 19 : os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
1344 19 : os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
1345 19 : ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
1346 :
1347 19 : pos = (u8 *) (ftie + 1);
1348 :
1349 : #ifdef CONFIG_TDLS_TESTING
1350 19 : if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
1351 2 : wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
1352 : "FTIE");
1353 2 : ftie->ie_len += 170;
1354 2 : *pos++ = 255; /* FTIE subelem */
1355 2 : *pos++ = 168; /* FTIE subelem length */
1356 2 : pos += 168;
1357 : }
1358 : #endif /* CONFIG_TDLS_TESTING */
1359 :
1360 : /* Lifetime */
1361 19 : lifetime = peer->lifetime;
1362 : #ifdef CONFIG_TDLS_TESTING
1363 19 : if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_CONF) {
1364 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
1365 : "lifetime in confirm");
1366 0 : lifetime++;
1367 : }
1368 : #endif /* CONFIG_TDLS_TESTING */
1369 19 : pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1370 : sizeof(timeoutie), lifetime);
1371 19 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds",
1372 : lifetime);
1373 :
1374 : /* compute MIC before sending */
1375 19 : wpa_tdls_ftie_mic(peer->tpk.kck, 3, (u8 *) lnkid, peer->rsnie_p,
1376 19 : (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
1377 : #ifdef CONFIG_TDLS_TESTING
1378 19 : if (tdls_testing & TDLS_TESTING_WRONG_MIC) {
1379 1 : wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC");
1380 1 : ftie->mic[0] ^= 0x01;
1381 : }
1382 : #endif /* CONFIG_TDLS_TESTING */
1383 :
1384 : skip_ies:
1385 :
1386 25 : if (peer->vht_capabilities)
1387 0 : peer_capab |= TDLS_PEER_VHT;
1388 25 : if (peer->ht_capabilities)
1389 24 : peer_capab |= TDLS_PEER_HT;
1390 25 : if (peer->wmm_capable)
1391 25 : peer_capab |= TDLS_PEER_WMM;
1392 :
1393 25 : status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
1394 : dtoken, 0, peer_capab, peer->initiator,
1395 25 : rbuf, pos - rbuf);
1396 25 : os_free(rbuf);
1397 :
1398 25 : return status;
1399 : }
1400 :
1401 :
1402 2 : static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
1403 : struct wpa_tdls_peer *peer,
1404 : u8 dialog_token)
1405 : {
1406 2 : size_t buf_len = 0;
1407 : struct wpa_tdls_timeoutie timeoutie;
1408 : u16 rsn_capab;
1409 : u8 *rbuf, *pos, *count_pos;
1410 : u16 count;
1411 : struct rsn_ie_hdr *hdr;
1412 : int status;
1413 :
1414 12 : wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Discovery Response "
1415 12 : "(peer " MACSTR ")", MAC2STR(peer->addr));
1416 2 : if (!wpa_tdls_get_privacy(sm))
1417 1 : goto skip_rsn_ies;
1418 :
1419 : /* Filling RSN IE */
1420 1 : hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
1421 1 : hdr->elem_id = WLAN_EID_RSN;
1422 1 : WPA_PUT_LE16(hdr->version, RSN_VERSION);
1423 1 : pos = (u8 *) (hdr + 1);
1424 1 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1425 1 : pos += RSN_SELECTOR_LEN;
1426 1 : count_pos = pos;
1427 1 : pos += 2;
1428 1 : count = 0;
1429 :
1430 : /*
1431 : * AES-CCMP is the default encryption preferred for TDLS, so
1432 : * RSN IE is filled only with CCMP cipher suite.
1433 : * Note: TKIP is not used to encrypt TDLS link.
1434 : *
1435 : * Regardless of the cipher used on the AP connection, select CCMP
1436 : * here.
1437 : */
1438 1 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1439 1 : pos += RSN_SELECTOR_LEN;
1440 1 : count++;
1441 1 : WPA_PUT_LE16(count_pos, count);
1442 1 : WPA_PUT_LE16(pos, 1);
1443 1 : pos += 2;
1444 1 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1445 1 : pos += RSN_SELECTOR_LEN;
1446 :
1447 1 : rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1448 1 : rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1449 1 : WPA_PUT_LE16(pos, rsn_capab);
1450 1 : pos += 2;
1451 1 : hdr->len = (pos - (u8 *) hdr) - 2;
1452 1 : peer->rsnie_i_len = pos - peer->rsnie_i;
1453 :
1454 1 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for Discovery Response",
1455 1 : (u8 *) hdr, hdr->len + 2);
1456 : skip_rsn_ies:
1457 2 : buf_len = 0;
1458 2 : if (wpa_tdls_get_privacy(sm)) {
1459 : /* Peer RSN IE, Lifetime */
1460 1 : buf_len += peer->rsnie_i_len +
1461 : sizeof(struct wpa_tdls_timeoutie);
1462 : }
1463 2 : rbuf = os_zalloc(buf_len + 1);
1464 2 : if (rbuf == NULL) {
1465 0 : wpa_tdls_peer_free(sm, peer);
1466 0 : return -1;
1467 : }
1468 2 : pos = rbuf;
1469 :
1470 2 : if (!wpa_tdls_get_privacy(sm))
1471 1 : goto skip_ies;
1472 : /* Initiator RSN IE */
1473 1 : pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);
1474 : /* Lifetime */
1475 1 : peer->lifetime = TPK_LIFETIME;
1476 1 : pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
1477 : sizeof(timeoutie), peer->lifetime);
1478 1 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
1479 : skip_ies:
1480 2 : status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
1481 2 : dialog_token, 0, 0, 0, rbuf, pos - rbuf);
1482 2 : os_free(rbuf);
1483 :
1484 2 : return status;
1485 : }
1486 :
1487 :
1488 : static int
1489 2 : wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr,
1490 : const u8 *buf, size_t len)
1491 : {
1492 : struct wpa_eapol_ie_parse kde;
1493 : const struct wpa_tdls_lnkid *lnkid;
1494 : struct wpa_tdls_peer *peer;
1495 2 : size_t min_req_len = sizeof(struct wpa_tdls_frame) +
1496 : 1 /* dialog token */ + sizeof(struct wpa_tdls_lnkid);
1497 : u8 dialog_token;
1498 :
1499 12 : wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from " MACSTR,
1500 12 : MAC2STR(addr));
1501 :
1502 2 : if (len < min_req_len) {
1503 0 : wpa_printf(MSG_DEBUG, "TDLS Discovery Request is too short: "
1504 : "%d", (int) len);
1505 0 : return -1;
1506 : }
1507 :
1508 2 : dialog_token = buf[sizeof(struct wpa_tdls_frame)];
1509 :
1510 : /*
1511 : * Some APs will tack on a weird IE to the end of a TDLS
1512 : * discovery request packet. This needn't fail the response,
1513 : * since the required IE are verified separately.
1514 : */
1515 2 : if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1,
1516 : len - (sizeof(struct wpa_tdls_frame) + 1),
1517 : &kde) < 0) {
1518 0 : wpa_printf(MSG_DEBUG,
1519 : "TDLS: Failed to parse IEs in Discovery Request - ignore as an interop workaround");
1520 : }
1521 :
1522 2 : if (!kde.lnkid) {
1523 0 : wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery "
1524 : "Request");
1525 0 : return -1;
1526 : }
1527 :
1528 2 : lnkid = (const struct wpa_tdls_lnkid *) kde.lnkid;
1529 :
1530 2 : if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1531 0 : wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from different "
1532 0 : " BSS " MACSTR, MAC2STR(lnkid->bssid));
1533 0 : return -1;
1534 : }
1535 :
1536 2 : peer = wpa_tdls_add_peer(sm, addr, NULL);
1537 2 : if (peer == NULL)
1538 0 : return -1;
1539 :
1540 2 : return wpa_tdls_send_discovery_response(sm, peer, dialog_token);
1541 : }
1542 :
1543 :
1544 3 : int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
1545 : {
1546 3 : if (sm->tdls_disabled || !sm->tdls_supported)
1547 0 : return -1;
1548 :
1549 18 : wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
1550 18 : MACSTR, MAC2STR(addr));
1551 3 : return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
1552 : 1, 0, 0, 1, NULL, 0);
1553 : }
1554 :
1555 :
1556 56 : static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
1557 : struct wpa_tdls_peer *peer)
1558 : {
1559 56 : if (!kde->supp_rates) {
1560 0 : wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
1561 0 : return -1;
1562 : }
1563 332 : peer->supp_rates_len = merge_byte_arrays(
1564 56 : peer->supp_rates, sizeof(peer->supp_rates),
1565 112 : kde->supp_rates + 2, kde->supp_rates_len - 2,
1566 108 : kde->ext_supp_rates ? kde->ext_supp_rates + 2 : NULL,
1567 56 : kde->ext_supp_rates_len - 2);
1568 56 : return 0;
1569 : }
1570 :
1571 :
1572 56 : static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde,
1573 : struct wpa_tdls_peer *peer)
1574 : {
1575 111 : if (!kde->ht_capabilities ||
1576 55 : kde->ht_capabilities_len <
1577 : sizeof(struct ieee80211_ht_capabilities) ) {
1578 1 : wpa_printf(MSG_DEBUG, "TDLS: No supported ht capabilities "
1579 : "received");
1580 1 : return 0;
1581 : }
1582 :
1583 55 : if (!peer->ht_capabilities) {
1584 54 : peer->ht_capabilities =
1585 54 : os_zalloc(sizeof(struct ieee80211_ht_capabilities));
1586 54 : if (peer->ht_capabilities == NULL)
1587 0 : return -1;
1588 : }
1589 :
1590 55 : os_memcpy(peer->ht_capabilities, kde->ht_capabilities,
1591 : sizeof(struct ieee80211_ht_capabilities));
1592 55 : wpa_hexdump(MSG_DEBUG, "TDLS: Peer HT capabilities",
1593 55 : (u8 *) peer->ht_capabilities,
1594 : sizeof(struct ieee80211_ht_capabilities));
1595 :
1596 55 : return 0;
1597 : }
1598 :
1599 :
1600 56 : static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
1601 : struct wpa_tdls_peer *peer)
1602 : {
1603 56 : if (!kde->vht_capabilities ||
1604 0 : kde->vht_capabilities_len <
1605 : sizeof(struct ieee80211_vht_capabilities) ) {
1606 56 : wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
1607 : "received");
1608 56 : return 0;
1609 : }
1610 :
1611 0 : if (!peer->vht_capabilities) {
1612 0 : peer->vht_capabilities =
1613 0 : os_zalloc(sizeof(struct ieee80211_vht_capabilities));
1614 0 : if (peer->vht_capabilities == NULL)
1615 0 : return -1;
1616 : }
1617 :
1618 0 : os_memcpy(peer->vht_capabilities, kde->vht_capabilities,
1619 : sizeof(struct ieee80211_vht_capabilities));
1620 0 : wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities",
1621 0 : (u8 *) peer->vht_capabilities,
1622 : sizeof(struct ieee80211_vht_capabilities));
1623 :
1624 0 : return 0;
1625 : }
1626 :
1627 :
1628 56 : static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
1629 : struct wpa_tdls_peer *peer)
1630 : {
1631 56 : if (!kde->ext_capab) {
1632 0 : wpa_printf(MSG_DEBUG, "TDLS: No extended capabilities "
1633 : "received");
1634 0 : return 0;
1635 : }
1636 :
1637 56 : if (!peer->ext_capab || peer->ext_capab_len < kde->ext_capab_len - 2) {
1638 : /* Need to allocate buffer to fit the new information */
1639 55 : os_free(peer->ext_capab);
1640 55 : peer->ext_capab = os_zalloc(kde->ext_capab_len - 2);
1641 55 : if (peer->ext_capab == NULL)
1642 0 : return -1;
1643 : }
1644 :
1645 56 : peer->ext_capab_len = kde->ext_capab_len - 2;
1646 56 : os_memcpy(peer->ext_capab, kde->ext_capab + 2, peer->ext_capab_len);
1647 :
1648 56 : return 0;
1649 : }
1650 :
1651 :
1652 56 : static int copy_peer_wmm_capab(const struct wpa_eapol_ie_parse *kde,
1653 : struct wpa_tdls_peer *peer)
1654 : {
1655 : struct wmm_information_element *wmm;
1656 :
1657 56 : if (!kde->wmm) {
1658 0 : wpa_printf(MSG_DEBUG, "TDLS: No supported WMM capabilities received");
1659 0 : return 0;
1660 : }
1661 :
1662 56 : if (kde->wmm_len < sizeof(struct wmm_information_element)) {
1663 0 : wpa_printf(MSG_DEBUG, "TDLS: Invalid supported WMM capabilities received");
1664 0 : return -1;
1665 : }
1666 :
1667 56 : wmm = (struct wmm_information_element *) kde->wmm;
1668 56 : peer->qos_info = wmm->qos_info;
1669 :
1670 56 : peer->wmm_capable = 1;
1671 :
1672 56 : wpa_printf(MSG_DEBUG, "TDLS: Peer WMM QOS Info 0x%x", peer->qos_info);
1673 56 : return 0;
1674 : }
1675 :
1676 :
1677 56 : static int copy_peer_supp_channels(const struct wpa_eapol_ie_parse *kde,
1678 : struct wpa_tdls_peer *peer)
1679 : {
1680 56 : if (!kde->supp_channels) {
1681 0 : wpa_printf(MSG_DEBUG, "TDLS: No supported channels received");
1682 0 : return 0;
1683 : }
1684 :
1685 57 : if (!peer->supp_channels ||
1686 1 : peer->supp_channels_len < kde->supp_channels_len) {
1687 55 : os_free(peer->supp_channels);
1688 55 : peer->supp_channels = os_zalloc(kde->supp_channels_len);
1689 55 : if (peer->supp_channels == NULL)
1690 0 : return -1;
1691 : }
1692 :
1693 56 : peer->supp_channels_len = kde->supp_channels_len;
1694 :
1695 56 : os_memcpy(peer->supp_channels, kde->supp_channels,
1696 : peer->supp_channels_len);
1697 112 : wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Channels",
1698 56 : (u8 *) peer->supp_channels, peer->supp_channels_len);
1699 56 : return 0;
1700 : }
1701 :
1702 :
1703 56 : static int copy_peer_supp_oper_classes(const struct wpa_eapol_ie_parse *kde,
1704 : struct wpa_tdls_peer *peer)
1705 : {
1706 56 : if (!kde->supp_oper_classes) {
1707 56 : wpa_printf(MSG_DEBUG, "TDLS: No supported operating classes received");
1708 56 : return 0;
1709 : }
1710 :
1711 0 : if (!peer->supp_oper_classes ||
1712 0 : peer->supp_oper_classes_len < kde->supp_oper_classes_len) {
1713 0 : os_free(peer->supp_oper_classes);
1714 0 : peer->supp_oper_classes = os_zalloc(kde->supp_oper_classes_len);
1715 0 : if (peer->supp_oper_classes == NULL)
1716 0 : return -1;
1717 : }
1718 :
1719 0 : peer->supp_oper_classes_len = kde->supp_oper_classes_len;
1720 0 : os_memcpy(peer->supp_oper_classes, kde->supp_oper_classes,
1721 : peer->supp_oper_classes_len);
1722 0 : wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Operating Classes",
1723 0 : (u8 *) peer->supp_oper_classes,
1724 : peer->supp_oper_classes_len);
1725 0 : return 0;
1726 : }
1727 :
1728 :
1729 76 : static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
1730 : int add)
1731 : {
1732 532 : return wpa_sm_tdls_peer_addset(sm, peer->addr, add, peer->aid,
1733 76 : peer->capability,
1734 76 : peer->supp_rates, peer->supp_rates_len,
1735 76 : peer->ht_capabilities,
1736 76 : peer->vht_capabilities,
1737 152 : peer->qos_info, peer->wmm_capable,
1738 76 : peer->ext_capab, peer->ext_capab_len,
1739 76 : peer->supp_channels,
1740 : peer->supp_channels_len,
1741 76 : peer->supp_oper_classes,
1742 : peer->supp_oper_classes_len);
1743 : }
1744 :
1745 :
1746 31 : static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
1747 : const u8 *buf, size_t len)
1748 : {
1749 : struct wpa_tdls_peer *peer;
1750 : struct wpa_eapol_ie_parse kde;
1751 : struct wpa_ie_data ie;
1752 : int cipher;
1753 : const u8 *cpos;
1754 31 : struct wpa_tdls_ftie *ftie = NULL;
1755 : struct wpa_tdls_timeoutie *timeoutie;
1756 : struct wpa_tdls_lnkid *lnkid;
1757 31 : u32 lifetime = 0;
1758 : #if 0
1759 : struct rsn_ie_hdr *hdr;
1760 : u8 *pos;
1761 : u16 rsn_capab;
1762 : u16 rsn_ver;
1763 : #endif
1764 : u8 dtoken;
1765 : u16 ielen;
1766 31 : u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1767 31 : int tdls_prohibited = sm->tdls_prohibited;
1768 31 : int existing_peer = 0;
1769 :
1770 31 : if (len < 3 + 3)
1771 0 : return -1;
1772 :
1773 31 : cpos = buf;
1774 31 : cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1775 :
1776 : /* driver had already verified the frame format */
1777 31 : dtoken = *cpos++; /* dialog token */
1778 :
1779 31 : wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
1780 :
1781 31 : peer = wpa_tdls_add_peer(sm, src_addr, &existing_peer);
1782 31 : if (peer == NULL)
1783 0 : goto error;
1784 :
1785 : /* If found, use existing entry instead of adding a new one;
1786 : * how to handle the case where both ends initiate at the
1787 : * same time? */
1788 31 : if (existing_peer) {
1789 3 : if (peer->tpk_success) {
1790 0 : wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
1791 : "direct link is enabled - tear down the "
1792 : "old link first");
1793 0 : wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
1794 0 : wpa_tdls_peer_clear(sm, peer);
1795 3 : } else if (peer->initiator) {
1796 : /*
1797 : * An entry is already present, so check if we already
1798 : * sent a TDLS Setup Request. If so, compare MAC
1799 : * addresses and let the STA with the lower MAC address
1800 : * continue as the initiator. The other negotiation is
1801 : * terminated.
1802 : */
1803 2 : if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
1804 6 : wpa_printf(MSG_DEBUG, "TDLS: Discard request "
1805 : "from peer with higher address "
1806 6 : MACSTR, MAC2STR(src_addr));
1807 1 : return -1;
1808 : } else {
1809 6 : wpa_printf(MSG_DEBUG, "TDLS: Accept request "
1810 : "from peer with lower address "
1811 : MACSTR " (terminate previously "
1812 : "initiated negotiation",
1813 6 : MAC2STR(src_addr));
1814 1 : wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
1815 1 : peer->addr);
1816 1 : wpa_tdls_peer_clear(sm, peer);
1817 : }
1818 : }
1819 : }
1820 :
1821 : /* capability information */
1822 30 : peer->capability = WPA_GET_LE16(cpos);
1823 30 : cpos += 2;
1824 :
1825 30 : ielen = len - (cpos - buf); /* start of IE in buf */
1826 30 : if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
1827 0 : wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M1");
1828 0 : goto error;
1829 : }
1830 :
1831 30 : if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1832 0 : wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1833 : "TPK M1");
1834 0 : goto error;
1835 : }
1836 60 : wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
1837 30 : kde.lnkid, kde.lnkid_len);
1838 30 : lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1839 30 : if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1840 1 : wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
1841 1 : status = WLAN_STATUS_REQUEST_DECLINED;
1842 1 : goto error;
1843 : }
1844 :
1845 174 : wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
1846 174 : MAC2STR(src_addr));
1847 :
1848 29 : if (copy_supp_rates(&kde, peer) < 0)
1849 0 : goto error;
1850 :
1851 29 : if (copy_peer_ht_capab(&kde, peer) < 0)
1852 0 : goto error;
1853 :
1854 29 : if (copy_peer_vht_capab(&kde, peer) < 0)
1855 0 : goto error;
1856 :
1857 29 : if (copy_peer_ext_capab(&kde, peer) < 0)
1858 0 : goto error;
1859 :
1860 29 : if (copy_peer_supp_channels(&kde, peer) < 0)
1861 0 : goto error;
1862 :
1863 29 : if (copy_peer_supp_oper_classes(&kde, peer) < 0)
1864 0 : goto error;
1865 :
1866 29 : peer->qos_info = kde.qosinfo;
1867 :
1868 : /* Overwrite with the qos_info obtained in WMM IE */
1869 29 : if (copy_peer_wmm_capab(&kde, peer) < 0)
1870 0 : goto error;
1871 :
1872 29 : peer->aid = kde.aid;
1873 :
1874 : #ifdef CONFIG_TDLS_TESTING
1875 29 : if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1876 2 : peer = wpa_tdls_add_peer(sm, src_addr, NULL);
1877 2 : if (peer == NULL)
1878 0 : goto error;
1879 2 : wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
1880 : "TDLS setup - send own request");
1881 2 : peer->initiator = 1;
1882 2 : wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
1883 : NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0);
1884 2 : wpa_tdls_send_tpk_m1(sm, peer);
1885 : }
1886 :
1887 29 : if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
1888 : tdls_prohibited) {
1889 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
1890 : "on TDLS");
1891 0 : tdls_prohibited = 0;
1892 : }
1893 : #endif /* CONFIG_TDLS_TESTING */
1894 :
1895 29 : if (tdls_prohibited) {
1896 0 : wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
1897 0 : status = WLAN_STATUS_REQUEST_DECLINED;
1898 0 : goto error;
1899 : }
1900 :
1901 29 : if (!wpa_tdls_get_privacy(sm)) {
1902 6 : if (kde.rsn_ie) {
1903 0 : wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
1904 : "security is disabled");
1905 0 : status = WLAN_STATUS_SECURITY_DISABLED;
1906 0 : goto error;
1907 : }
1908 6 : goto skip_rsn;
1909 : }
1910 :
1911 46 : if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1912 23 : kde.rsn_ie == NULL) {
1913 0 : wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
1914 0 : status = WLAN_STATUS_INVALID_PARAMETERS;
1915 0 : goto error;
1916 : }
1917 :
1918 23 : if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
1919 0 : wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
1920 : "TPK M1");
1921 0 : status = WLAN_STATUS_INVALID_RSNIE;
1922 0 : goto error;
1923 : }
1924 :
1925 23 : if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1926 0 : wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
1927 0 : status = WLAN_STATUS_INVALID_RSNIE;
1928 0 : goto error;
1929 : }
1930 :
1931 23 : cipher = ie.pairwise_cipher;
1932 23 : if (cipher & WPA_CIPHER_CCMP) {
1933 23 : wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1934 23 : cipher = WPA_CIPHER_CCMP;
1935 : } else {
1936 0 : wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
1937 0 : status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1938 0 : goto error;
1939 : }
1940 :
1941 23 : if ((ie.capabilities &
1942 : (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
1943 : WPA_CAPABILITY_PEERKEY_ENABLED) {
1944 0 : wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
1945 : "TPK M1");
1946 0 : status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
1947 0 : goto error;
1948 : }
1949 :
1950 : /* Lifetime */
1951 23 : if (kde.key_lifetime == NULL) {
1952 0 : wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
1953 0 : status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1954 0 : goto error;
1955 : }
1956 23 : timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1957 23 : lifetime = WPA_GET_LE32(timeoutie->value);
1958 23 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
1959 23 : if (lifetime < 300) {
1960 0 : wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
1961 0 : status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1962 0 : goto error;
1963 : }
1964 :
1965 : skip_rsn:
1966 : #ifdef CONFIG_TDLS_TESTING
1967 29 : if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1968 2 : if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
1969 : /*
1970 : * The request frame from us is going to win, so do not
1971 : * replace information based on this request frame from
1972 : * the peer.
1973 : */
1974 1 : goto skip_rsn_check;
1975 : }
1976 : }
1977 : #endif /* CONFIG_TDLS_TESTING */
1978 :
1979 28 : peer->initiator = 0; /* Need to check */
1980 28 : peer->dtoken = dtoken;
1981 :
1982 28 : if (!wpa_tdls_get_privacy(sm)) {
1983 6 : peer->rsnie_i_len = 0;
1984 6 : peer->rsnie_p_len = 0;
1985 6 : peer->cipher = WPA_CIPHER_NONE;
1986 6 : goto skip_rsn_check;
1987 : }
1988 :
1989 22 : ftie = (struct wpa_tdls_ftie *) kde.ftie;
1990 22 : os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
1991 22 : peer->rsnie_i_len = kde.rsn_ie_len;
1992 22 : peer->cipher = cipher;
1993 :
1994 22 : if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) {
1995 : /*
1996 : * There is no point in updating the RNonce for every obtained
1997 : * TPK M1 frame (e.g., retransmission due to timeout) with the
1998 : * same INonce (SNonce in FTIE). However, if the TPK M1 is
1999 : * retransmitted with a different INonce, update the RNonce
2000 : * since this is for a new TDLS session.
2001 : */
2002 22 : wpa_printf(MSG_DEBUG,
2003 : "TDLS: New TPK M1 INonce - generate new RNonce");
2004 22 : os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
2005 22 : if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
2006 0 : wpa_msg(sm->ctx->ctx, MSG_WARNING,
2007 : "TDLS: Failed to get random data for responder nonce");
2008 0 : goto error;
2009 : }
2010 : }
2011 :
2012 : #if 0
2013 : /* get version info from RSNIE received from Peer */
2014 : hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
2015 : rsn_ver = WPA_GET_LE16(hdr->version);
2016 :
2017 : /* use min(peer's version, out version) */
2018 : if (rsn_ver > RSN_VERSION)
2019 : rsn_ver = RSN_VERSION;
2020 :
2021 : hdr = (struct rsn_ie_hdr *) peer->rsnie_p;
2022 :
2023 : hdr->elem_id = WLAN_EID_RSN;
2024 : WPA_PUT_LE16(hdr->version, rsn_ver);
2025 : pos = (u8 *) (hdr + 1);
2026 :
2027 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
2028 : pos += RSN_SELECTOR_LEN;
2029 : /* Include only the selected cipher in pairwise cipher suite */
2030 : WPA_PUT_LE16(pos, 1);
2031 : pos += 2;
2032 : if (cipher == WPA_CIPHER_CCMP)
2033 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
2034 : pos += RSN_SELECTOR_LEN;
2035 :
2036 : WPA_PUT_LE16(pos, 1);
2037 : pos += 2;
2038 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
2039 : pos += RSN_SELECTOR_LEN;
2040 :
2041 : rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
2042 : rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
2043 : WPA_PUT_LE16(pos, rsn_capab);
2044 : pos += 2;
2045 :
2046 : hdr->len = (pos - peer->rsnie_p) - 2;
2047 : peer->rsnie_p_len = pos - peer->rsnie_p;
2048 : #endif
2049 :
2050 : /* temp fix: validation of RSNIE later */
2051 22 : os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
2052 22 : peer->rsnie_p_len = peer->rsnie_i_len;
2053 :
2054 44 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
2055 22 : peer->rsnie_p, peer->rsnie_p_len);
2056 :
2057 22 : peer->lifetime = lifetime;
2058 :
2059 22 : wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
2060 :
2061 : skip_rsn_check:
2062 : #ifdef CONFIG_TDLS_TESTING
2063 29 : if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT)
2064 2 : goto skip_add_peer;
2065 : #endif /* CONFIG_TDLS_TESTING */
2066 :
2067 : /* add supported rates, capabilities, and qos_info to the TDLS peer */
2068 27 : if (wpa_tdls_addset_peer(sm, peer, 1) < 0)
2069 0 : goto error;
2070 :
2071 : #ifdef CONFIG_TDLS_TESTING
2072 : skip_add_peer:
2073 : #endif /* CONFIG_TDLS_TESTING */
2074 29 : peer->tpk_in_progress = 1;
2075 :
2076 29 : wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
2077 29 : if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
2078 0 : wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2079 0 : goto error;
2080 : }
2081 :
2082 29 : return 0;
2083 :
2084 : error:
2085 1 : wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
2086 : status);
2087 1 : if (peer)
2088 1 : wpa_tdls_peer_free(sm, peer);
2089 1 : return -1;
2090 : }
2091 :
2092 :
2093 49 : static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
2094 : {
2095 49 : peer->tpk_success = 1;
2096 49 : peer->tpk_in_progress = 0;
2097 49 : eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
2098 49 : if (wpa_tdls_get_privacy(sm)) {
2099 37 : u32 lifetime = peer->lifetime;
2100 : /*
2101 : * Start the initiator process a bit earlier to avoid race
2102 : * condition with the responder sending teardown request.
2103 : */
2104 37 : if (lifetime > 3 && peer->initiator)
2105 19 : lifetime -= 3;
2106 37 : eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
2107 : sm, peer);
2108 : #ifdef CONFIG_TDLS_TESTING
2109 37 : if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
2110 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - disable TPK "
2111 : "expiration");
2112 0 : eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
2113 : }
2114 : #endif /* CONFIG_TDLS_TESTING */
2115 : }
2116 :
2117 49 : if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) {
2118 0 : wpa_printf(MSG_INFO, "TDLS: Could not configure key to the "
2119 : "driver");
2120 0 : return -1;
2121 : }
2122 49 : peer->reconfig_key = 0;
2123 :
2124 49 : return wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
2125 : }
2126 :
2127 :
2128 35 : static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
2129 : const u8 *buf, size_t len)
2130 : {
2131 : struct wpa_tdls_peer *peer;
2132 : struct wpa_eapol_ie_parse kde;
2133 : struct wpa_ie_data ie;
2134 : int cipher;
2135 : struct wpa_tdls_ftie *ftie;
2136 : struct wpa_tdls_timeoutie *timeoutie;
2137 : struct wpa_tdls_lnkid *lnkid;
2138 : u32 lifetime;
2139 : u8 dtoken;
2140 : int ielen;
2141 : u16 status;
2142 : const u8 *pos;
2143 35 : int ret = 0;
2144 :
2145 210 : wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
2146 210 : "(Peer " MACSTR ")", MAC2STR(src_addr));
2147 35 : for (peer = sm->tdls; peer; peer = peer->next) {
2148 33 : if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
2149 33 : break;
2150 : }
2151 35 : if (peer == NULL) {
2152 12 : wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
2153 12 : "TPK M2: " MACSTR, MAC2STR(src_addr));
2154 2 : return -1;
2155 : }
2156 33 : if (!peer->initiator) {
2157 : /*
2158 : * This may happen if both devices try to initiate TDLS at the
2159 : * same time and we accept the TPK M1 from the peer in
2160 : * wpa_tdls_process_tpk_m1() and clear our previous state.
2161 : */
2162 24 : wpa_printf(MSG_INFO, "TDLS: We were not the initiator, so "
2163 24 : "ignore TPK M2 from " MACSTR, MAC2STR(src_addr));
2164 4 : return -1;
2165 : }
2166 29 : wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
2167 :
2168 29 : if (len < 3 + 2 + 1) {
2169 0 : wpa_tdls_disable_peer_link(sm, peer);
2170 0 : return -1;
2171 : }
2172 :
2173 29 : pos = buf;
2174 29 : pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
2175 29 : status = WPA_GET_LE16(pos);
2176 29 : pos += 2 /* status code */;
2177 :
2178 29 : if (status != WLAN_STATUS_SUCCESS) {
2179 1 : wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
2180 : status);
2181 1 : wpa_tdls_disable_peer_link(sm, peer);
2182 1 : return -1;
2183 : }
2184 :
2185 28 : status = WLAN_STATUS_UNSPECIFIED_FAILURE;
2186 :
2187 : /* TODO: need to verify dialog token matches here or in kernel */
2188 28 : dtoken = *pos++; /* dialog token */
2189 :
2190 28 : wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
2191 :
2192 28 : if (len < 3 + 2 + 1 + 2) {
2193 0 : wpa_tdls_disable_peer_link(sm, peer);
2194 0 : return -1;
2195 : }
2196 :
2197 : /* capability information */
2198 28 : peer->capability = WPA_GET_LE16(pos);
2199 28 : pos += 2;
2200 :
2201 28 : ielen = len - (pos - buf); /* start of IE in buf */
2202 28 : if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
2203 0 : wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M2");
2204 0 : goto error;
2205 : }
2206 :
2207 : #ifdef CONFIG_TDLS_TESTING
2208 28 : if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
2209 1 : wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
2210 1 : status = WLAN_STATUS_REQUEST_DECLINED;
2211 1 : goto error;
2212 : }
2213 : #endif /* CONFIG_TDLS_TESTING */
2214 :
2215 27 : if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
2216 0 : wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
2217 : "TPK M2");
2218 0 : goto error;
2219 : }
2220 54 : wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
2221 27 : kde.lnkid, kde.lnkid_len);
2222 27 : lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
2223 :
2224 27 : if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
2225 0 : wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
2226 0 : status = WLAN_STATUS_NOT_IN_SAME_BSS;
2227 0 : goto error;
2228 : }
2229 :
2230 27 : if (copy_supp_rates(&kde, peer) < 0)
2231 0 : goto error;
2232 :
2233 27 : if (copy_peer_ht_capab(&kde, peer) < 0)
2234 0 : goto error;
2235 :
2236 27 : if (copy_peer_vht_capab(&kde, peer) < 0)
2237 0 : goto error;
2238 :
2239 27 : if (copy_peer_ext_capab(&kde, peer) < 0)
2240 0 : goto error;
2241 :
2242 27 : if (copy_peer_supp_channels(&kde, peer) < 0)
2243 0 : goto error;
2244 :
2245 27 : if (copy_peer_supp_oper_classes(&kde, peer) < 0)
2246 0 : goto error;
2247 :
2248 27 : peer->qos_info = kde.qosinfo;
2249 :
2250 : /* Overwrite with the qos_info obtained in WMM IE */
2251 27 : if (copy_peer_wmm_capab(&kde, peer) < 0)
2252 0 : goto error;
2253 :
2254 27 : peer->aid = kde.aid;
2255 :
2256 27 : if (!wpa_tdls_get_privacy(sm)) {
2257 6 : peer->rsnie_p_len = 0;
2258 6 : peer->cipher = WPA_CIPHER_NONE;
2259 6 : goto skip_rsn;
2260 : }
2261 :
2262 42 : if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
2263 21 : kde.rsn_ie == NULL) {
2264 0 : wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
2265 0 : status = WLAN_STATUS_INVALID_PARAMETERS;
2266 0 : goto error;
2267 : }
2268 42 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
2269 21 : kde.rsn_ie, kde.rsn_ie_len);
2270 :
2271 21 : if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
2272 0 : wpa_printf(MSG_INFO,
2273 : "TDLS: Too long Responder RSN IE in TPK M2");
2274 0 : status = WLAN_STATUS_INVALID_RSNIE;
2275 0 : goto error;
2276 : }
2277 :
2278 : /*
2279 : * FIX: bitwise comparison of RSN IE is not the correct way of
2280 : * validation this. It can be different, but certain fields must
2281 : * match. Since we list only a single pairwise cipher in TPK M1, the
2282 : * memcmp is likely to work in most cases, though.
2283 : */
2284 42 : if (kde.rsn_ie_len != peer->rsnie_i_len ||
2285 21 : os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
2286 0 : wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
2287 : "not match with RSN IE used in TPK M1");
2288 0 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
2289 0 : peer->rsnie_i, peer->rsnie_i_len);
2290 0 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
2291 0 : kde.rsn_ie, kde.rsn_ie_len);
2292 0 : status = WLAN_STATUS_INVALID_RSNIE;
2293 0 : goto error;
2294 : }
2295 :
2296 21 : if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
2297 0 : wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
2298 0 : status = WLAN_STATUS_INVALID_RSNIE;
2299 0 : goto error;
2300 : }
2301 :
2302 21 : cipher = ie.pairwise_cipher;
2303 21 : if (cipher == WPA_CIPHER_CCMP) {
2304 21 : wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
2305 21 : cipher = WPA_CIPHER_CCMP;
2306 : } else {
2307 0 : wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
2308 0 : status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2309 0 : goto error;
2310 : }
2311 :
2312 21 : wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
2313 21 : kde.ftie, sizeof(*ftie));
2314 21 : ftie = (struct wpa_tdls_ftie *) kde.ftie;
2315 :
2316 21 : if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
2317 0 : wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
2318 : "not match with FTIE SNonce used in TPK M1");
2319 : /* Silently discard the frame */
2320 0 : return -1;
2321 : }
2322 :
2323 : /* Responder Nonce and RSN IE */
2324 21 : os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
2325 21 : os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
2326 21 : peer->rsnie_p_len = kde.rsn_ie_len;
2327 21 : peer->cipher = cipher;
2328 :
2329 : /* Lifetime */
2330 21 : if (kde.key_lifetime == NULL) {
2331 0 : wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
2332 0 : status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2333 0 : goto error;
2334 : }
2335 21 : timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
2336 21 : lifetime = WPA_GET_LE32(timeoutie->value);
2337 21 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
2338 : lifetime);
2339 21 : if (lifetime != peer->lifetime) {
2340 1 : wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2341 : "TPK M2 (expected %u)", lifetime, peer->lifetime);
2342 1 : status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
2343 1 : goto error;
2344 : }
2345 :
2346 20 : wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
2347 :
2348 : /* Process MIC check to see if TPK M2 is right */
2349 20 : if (wpa_supplicant_verify_tdls_mic(2, peer, (u8 *) lnkid,
2350 : (u8 *) timeoutie, ftie) < 0) {
2351 : /* Discard the frame */
2352 1 : wpa_tdls_del_key(sm, peer);
2353 1 : wpa_tdls_disable_peer_link(sm, peer);
2354 1 : return -1;
2355 : }
2356 :
2357 19 : if (wpa_tdls_set_key(sm, peer) < 0) {
2358 : /*
2359 : * Some drivers may not be able to config the key prior to full
2360 : * STA entry having been configured.
2361 : */
2362 19 : wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
2363 : "STA entry is complete");
2364 19 : peer->reconfig_key = 1;
2365 : }
2366 :
2367 : skip_rsn:
2368 25 : peer->dtoken = dtoken;
2369 :
2370 : /* add supported rates, capabilities, and qos_info to the TDLS peer */
2371 25 : if (wpa_tdls_addset_peer(sm, peer, 0) < 0)
2372 0 : goto error;
2373 :
2374 25 : wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
2375 : "TPK Handshake Message 3");
2376 25 : if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0)
2377 0 : goto error;
2378 :
2379 25 : if (!peer->tpk_success) {
2380 : /*
2381 : * Enable Link only when tpk_success is 0, signifying that this
2382 : * processing of TPK M2 frame is not because of a retransmission
2383 : * during TDLS setup handshake.
2384 : */
2385 25 : ret = wpa_tdls_enable_link(sm, peer);
2386 25 : if (ret < 0) {
2387 0 : wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
2388 0 : wpa_tdls_do_teardown(
2389 : sm, peer,
2390 : WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2391 : }
2392 : }
2393 25 : return ret;
2394 :
2395 : error:
2396 2 : wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 1,
2397 : status);
2398 2 : wpa_tdls_disable_peer_link(sm, peer);
2399 2 : return -1;
2400 : }
2401 :
2402 :
2403 27 : static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
2404 : const u8 *buf, size_t len)
2405 : {
2406 : struct wpa_tdls_peer *peer;
2407 : struct wpa_eapol_ie_parse kde;
2408 : struct wpa_tdls_ftie *ftie;
2409 : struct wpa_tdls_timeoutie *timeoutie;
2410 : struct wpa_tdls_lnkid *lnkid;
2411 : int ielen;
2412 : u16 status;
2413 : const u8 *pos;
2414 : u32 lifetime;
2415 27 : int ret = 0;
2416 :
2417 162 : wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
2418 162 : "(Peer " MACSTR ")", MAC2STR(src_addr));
2419 27 : for (peer = sm->tdls; peer; peer = peer->next) {
2420 27 : if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
2421 27 : break;
2422 : }
2423 27 : if (peer == NULL) {
2424 0 : wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
2425 0 : "TPK M3: " MACSTR, MAC2STR(src_addr));
2426 0 : return -1;
2427 : }
2428 27 : wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
2429 :
2430 27 : if (len < 3 + 3)
2431 0 : goto error;
2432 27 : pos = buf;
2433 27 : pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
2434 :
2435 27 : status = WPA_GET_LE16(pos);
2436 :
2437 27 : if (status != 0) {
2438 2 : wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
2439 : status);
2440 2 : goto error;
2441 : }
2442 25 : pos += 2 /* status code */ + 1 /* dialog token */;
2443 :
2444 25 : ielen = len - (pos - buf); /* start of IE in buf */
2445 :
2446 : /*
2447 : * Don't reject the message if failing to parse IEs. The IEs we need are
2448 : * explicitly checked below. Some APs piggy-back broken IEs to the end
2449 : * of a TDLS Confirm packet, which will fail the link if we don't ignore
2450 : * this error.
2451 : */
2452 25 : if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
2453 0 : wpa_printf(MSG_DEBUG,
2454 : "TDLS: Failed to parse KDEs in TPK M3 - ignore as an interop workaround");
2455 : }
2456 :
2457 25 : if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
2458 0 : wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
2459 0 : goto error;
2460 : }
2461 50 : wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
2462 25 : (u8 *) kde.lnkid, kde.lnkid_len);
2463 25 : lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
2464 :
2465 25 : if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
2466 0 : wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
2467 0 : goto error;
2468 : }
2469 :
2470 25 : if (!wpa_tdls_get_privacy(sm))
2471 6 : goto skip_rsn;
2472 :
2473 19 : if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
2474 0 : wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
2475 0 : goto error;
2476 : }
2477 19 : wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
2478 19 : kde.ftie, sizeof(*ftie));
2479 19 : ftie = (struct wpa_tdls_ftie *) kde.ftie;
2480 :
2481 19 : if (kde.rsn_ie == NULL) {
2482 0 : wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
2483 0 : goto error;
2484 : }
2485 38 : wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
2486 19 : kde.rsn_ie, kde.rsn_ie_len);
2487 38 : if (kde.rsn_ie_len != peer->rsnie_p_len ||
2488 19 : os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
2489 0 : wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
2490 : "with the one sent in TPK M2");
2491 0 : goto error;
2492 : }
2493 :
2494 19 : if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
2495 0 : wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
2496 : "not match with FTIE ANonce used in TPK M2");
2497 0 : goto error;
2498 : }
2499 :
2500 19 : if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
2501 0 : wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
2502 : "match with FTIE SNonce used in TPK M1");
2503 0 : goto error;
2504 : }
2505 :
2506 19 : if (kde.key_lifetime == NULL) {
2507 0 : wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
2508 0 : goto error;
2509 : }
2510 19 : timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
2511 19 : wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
2512 : (u8 *) timeoutie, sizeof(*timeoutie));
2513 19 : lifetime = WPA_GET_LE32(timeoutie->value);
2514 19 : wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
2515 : lifetime);
2516 19 : if (lifetime != peer->lifetime) {
2517 0 : wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2518 : "TPK M3 (expected %u)", lifetime, peer->lifetime);
2519 0 : goto error;
2520 : }
2521 :
2522 19 : if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
2523 : (u8 *) timeoutie, ftie) < 0) {
2524 1 : wpa_tdls_del_key(sm, peer);
2525 1 : goto error;
2526 : }
2527 :
2528 18 : if (wpa_tdls_set_key(sm, peer) < 0) {
2529 : /*
2530 : * Some drivers may not be able to config the key prior to full
2531 : * STA entry having been configured.
2532 : */
2533 18 : wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
2534 : "STA entry is complete");
2535 18 : peer->reconfig_key = 1;
2536 : }
2537 :
2538 : skip_rsn:
2539 : /* add supported rates, capabilities, and qos_info to the TDLS peer */
2540 24 : if (wpa_tdls_addset_peer(sm, peer, 0) < 0)
2541 0 : goto error;
2542 :
2543 24 : if (!peer->tpk_success) {
2544 : /*
2545 : * Enable Link only when tpk_success is 0, signifying that this
2546 : * processing of TPK M3 frame is not because of a retransmission
2547 : * during TDLS setup handshake.
2548 : */
2549 24 : ret = wpa_tdls_enable_link(sm, peer);
2550 24 : if (ret < 0) {
2551 0 : wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
2552 0 : goto error;
2553 : }
2554 : }
2555 24 : return ret;
2556 : error:
2557 3 : wpa_tdls_do_teardown(sm, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2558 3 : return -1;
2559 : }
2560 :
2561 :
2562 68 : static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
2563 : {
2564 68 : struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;
2565 :
2566 68 : os_memset(lifetime, 0, ie_len);
2567 68 : lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
2568 68 : lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
2569 68 : lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
2570 68 : WPA_PUT_LE32(lifetime->value, tsecs);
2571 68 : os_memcpy(pos, ie, ie_len);
2572 68 : return pos + ie_len;
2573 : }
2574 :
2575 :
2576 : /**
2577 : * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2578 : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2579 : * @peer: MAC address of the peer STA
2580 : * Returns: 0 on success, or -1 on failure
2581 : *
2582 : * Send TPK Handshake Message 1 info to driver to start TDLS
2583 : * handshake with the peer.
2584 : */
2585 30 : int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
2586 : {
2587 : struct wpa_tdls_peer *peer;
2588 30 : int tdls_prohibited = sm->tdls_prohibited;
2589 :
2590 30 : if (sm->tdls_disabled || !sm->tdls_supported)
2591 0 : return -1;
2592 :
2593 : #ifdef CONFIG_TDLS_TESTING
2594 30 : if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2595 : tdls_prohibited) {
2596 0 : wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2597 : "on TDLS");
2598 0 : tdls_prohibited = 0;
2599 : }
2600 : #endif /* CONFIG_TDLS_TESTING */
2601 :
2602 30 : if (tdls_prohibited) {
2603 0 : wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
2604 : "reject request to start setup");
2605 0 : return -1;
2606 : }
2607 :
2608 30 : peer = wpa_tdls_add_peer(sm, addr, NULL);
2609 30 : if (peer == NULL)
2610 1 : return -1;
2611 :
2612 29 : if (peer->tpk_in_progress) {
2613 0 : wpa_printf(MSG_DEBUG, "TDLS: Setup is already in progress with the peer");
2614 0 : return 0;
2615 : }
2616 :
2617 29 : peer->initiator = 1;
2618 :
2619 : /* add the peer to the driver as a "setup in progress" peer */
2620 29 : if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
2621 : NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
2622 0 : wpa_tdls_disable_peer_link(sm, peer);
2623 0 : return -1;
2624 : }
2625 :
2626 29 : peer->tpk_in_progress = 1;
2627 :
2628 29 : if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
2629 0 : wpa_tdls_disable_peer_link(sm, peer);
2630 0 : return -1;
2631 : }
2632 :
2633 29 : return 0;
2634 : }
2635 :
2636 :
2637 30 : void wpa_tdls_remove(struct wpa_sm *sm, const u8 *addr)
2638 : {
2639 : struct wpa_tdls_peer *peer;
2640 :
2641 30 : if (sm->tdls_disabled || !sm->tdls_supported)
2642 0 : return;
2643 :
2644 30 : for (peer = sm->tdls; peer; peer = peer->next) {
2645 1 : if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2646 1 : break;
2647 : }
2648 :
2649 30 : if (peer == NULL || !peer->tpk_success)
2650 29 : return;
2651 :
2652 1 : if (sm->tdls_external_setup) {
2653 : /*
2654 : * Disable previous link to allow renegotiation to be completed
2655 : * on AP path.
2656 : */
2657 1 : wpa_tdls_do_teardown(sm, peer,
2658 : WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2659 : }
2660 : }
2661 :
2662 :
2663 : /**
2664 : * wpa_supplicant_rx_tdls - Receive TDLS data frame
2665 : *
2666 : * This function is called to receive TDLS (ethertype = 0x890d) data frames.
2667 : */
2668 123 : static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
2669 : const u8 *buf, size_t len)
2670 : {
2671 123 : struct wpa_sm *sm = ctx;
2672 : struct wpa_tdls_frame *tf;
2673 :
2674 123 : wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
2675 : buf, len);
2676 :
2677 123 : if (sm->tdls_disabled || !sm->tdls_supported) {
2678 0 : wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
2679 : "or unsupported by driver");
2680 0 : return;
2681 : }
2682 :
2683 123 : if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
2684 0 : wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
2685 0 : return;
2686 : }
2687 :
2688 123 : if (len < sizeof(*tf)) {
2689 0 : wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
2690 0 : return;
2691 : }
2692 :
2693 : /* Check to make sure its a valid encapsulated TDLS frame */
2694 123 : tf = (struct wpa_tdls_frame *) buf;
2695 246 : if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
2696 123 : tf->category != WLAN_ACTION_TDLS) {
2697 0 : wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
2698 : "category=%u action=%u",
2699 0 : tf->payloadtype, tf->category, tf->action);
2700 0 : return;
2701 : }
2702 :
2703 123 : switch (tf->action) {
2704 : case WLAN_TDLS_SETUP_REQUEST:
2705 31 : wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
2706 31 : break;
2707 : case WLAN_TDLS_SETUP_RESPONSE:
2708 35 : wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
2709 35 : break;
2710 : case WLAN_TDLS_SETUP_CONFIRM:
2711 27 : wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
2712 27 : break;
2713 : case WLAN_TDLS_TEARDOWN:
2714 28 : wpa_tdls_recv_teardown(sm, src_addr, buf, len);
2715 28 : break;
2716 : case WLAN_TDLS_DISCOVERY_REQUEST:
2717 2 : wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
2718 2 : break;
2719 : default:
2720 : /* Kernel code will process remaining frames */
2721 0 : wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
2722 0 : tf->action);
2723 0 : break;
2724 : }
2725 : }
2726 :
2727 :
2728 : /**
2729 : * wpa_tdls_init - Initialize driver interface parameters for TDLS
2730 : * @wpa_s: Pointer to wpa_supplicant data
2731 : * Returns: 0 on success, -1 on failure
2732 : *
2733 : * This function is called to initialize driver interface parameters for TDLS.
2734 : * wpa_drv_init() must have been called before this function to initialize the
2735 : * driver interface.
2736 : */
2737 188 : int wpa_tdls_init(struct wpa_sm *sm)
2738 : {
2739 188 : if (sm == NULL)
2740 0 : return -1;
2741 :
2742 188 : sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
2743 : sm->ifname,
2744 188 : sm->own_addr,
2745 : ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
2746 : sm, 0);
2747 188 : if (sm->l2_tdls == NULL) {
2748 1 : wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
2749 : "connection");
2750 1 : return -1;
2751 : }
2752 :
2753 : /*
2754 : * Drivers that support TDLS but don't implement the get_capa callback
2755 : * are assumed to perform everything internally
2756 : */
2757 187 : if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
2758 : &sm->tdls_external_setup,
2759 : &sm->tdls_chan_switch) < 0) {
2760 31 : sm->tdls_supported = 1;
2761 31 : sm->tdls_external_setup = 0;
2762 : }
2763 :
2764 187 : wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
2765 187 : "driver", sm->tdls_supported ? "" : " not");
2766 187 : wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
2767 187 : sm->tdls_external_setup ? "external" : "internal");
2768 187 : wpa_printf(MSG_DEBUG, "TDLS: Driver %s TDLS channel switching",
2769 187 : sm->tdls_chan_switch ? "supports" : "does not support");
2770 :
2771 187 : return 0;
2772 : }
2773 :
2774 :
2775 2345 : void wpa_tdls_teardown_peers(struct wpa_sm *sm)
2776 : {
2777 : struct wpa_tdls_peer *peer, *tmp;
2778 :
2779 2345 : if (!sm)
2780 2349 : return;
2781 2341 : peer = sm->tdls;
2782 :
2783 2341 : wpa_printf(MSG_DEBUG, "TDLS: Tear down peers");
2784 :
2785 4697 : while (peer) {
2786 15 : tmp = peer->next;
2787 90 : wpa_printf(MSG_DEBUG, "TDLS: Tear down peer " MACSTR,
2788 90 : MAC2STR(peer->addr));
2789 15 : if (sm->tdls_external_setup)
2790 15 : wpa_tdls_do_teardown(sm, peer,
2791 : WLAN_REASON_DEAUTH_LEAVING);
2792 : else
2793 0 : wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
2794 :
2795 15 : peer = tmp;
2796 : }
2797 : }
2798 :
2799 :
2800 5008 : static void wpa_tdls_remove_peers(struct wpa_sm *sm)
2801 : {
2802 : struct wpa_tdls_peer *peer, *tmp;
2803 :
2804 5008 : peer = sm->tdls;
2805 :
2806 10016 : while (peer) {
2807 : int res;
2808 0 : tmp = peer->next;
2809 0 : res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2810 0 : wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
2811 0 : MAC2STR(peer->addr), res);
2812 0 : wpa_tdls_peer_free(sm, peer);
2813 0 : peer = tmp;
2814 : }
2815 5008 : }
2816 :
2817 :
2818 : /**
2819 : * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
2820 : *
2821 : * This function is called to recover driver interface parameters for TDLS
2822 : * and frees resources allocated for it.
2823 : */
2824 212 : void wpa_tdls_deinit(struct wpa_sm *sm)
2825 : {
2826 212 : if (sm == NULL)
2827 229 : return;
2828 :
2829 195 : if (sm->l2_tdls)
2830 187 : l2_packet_deinit(sm->l2_tdls);
2831 195 : sm->l2_tdls = NULL;
2832 :
2833 195 : wpa_tdls_remove_peers(sm);
2834 : }
2835 :
2836 :
2837 2484 : void wpa_tdls_assoc(struct wpa_sm *sm)
2838 : {
2839 2484 : wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
2840 2484 : wpa_tdls_remove_peers(sm);
2841 2484 : }
2842 :
2843 :
2844 2329 : void wpa_tdls_disassoc(struct wpa_sm *sm)
2845 : {
2846 2329 : wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
2847 2329 : wpa_tdls_remove_peers(sm);
2848 2329 : }
2849 :
2850 :
2851 4875 : static int wpa_tdls_prohibited(struct wpa_eapol_ie_parse *elems)
2852 : {
2853 : /* bit 38 - TDLS Prohibited */
2854 4875 : return !!(elems->ext_capab[2 + 4] & 0x40);
2855 : }
2856 :
2857 :
2858 4875 : static int wpa_tdls_chan_switch_prohibited(struct wpa_eapol_ie_parse *elems)
2859 : {
2860 : /* bit 39 - TDLS Channel Switch Prohibited */
2861 4875 : return !!(elems->ext_capab[2 + 4] & 0x80);
2862 : }
2863 :
2864 :
2865 2414 : void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2866 : {
2867 : struct wpa_eapol_ie_parse elems;
2868 :
2869 2414 : sm->tdls_prohibited = 0;
2870 2414 : sm->tdls_chan_switch_prohibited = 0;
2871 :
2872 4828 : if (ies == NULL || wpa_supplicant_parse_ies(ies, len, &elems) < 0 ||
2873 4828 : elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
2874 2414 : return;
2875 :
2876 2414 : sm->tdls_prohibited = wpa_tdls_prohibited(&elems);
2877 2414 : wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
2878 2414 : sm->tdls_prohibited ? "prohibited" : "allowed");
2879 2414 : sm->tdls_chan_switch_prohibited =
2880 2414 : wpa_tdls_chan_switch_prohibited(&elems);
2881 2414 : wpa_printf(MSG_DEBUG, "TDLS: TDLS channel switch %s in the target BSS",
2882 2414 : sm->tdls_chan_switch_prohibited ? "prohibited" : "allowed");
2883 : }
2884 :
2885 :
2886 2461 : void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2887 : {
2888 : struct wpa_eapol_ie_parse elems;
2889 :
2890 4922 : if (ies == NULL || wpa_supplicant_parse_ies(ies, len, &elems) < 0 ||
2891 4922 : elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
2892 2461 : return;
2893 :
2894 2461 : if (!sm->tdls_prohibited && wpa_tdls_prohibited(&elems)) {
2895 0 : wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
2896 : "(Re)Association Response IEs");
2897 0 : sm->tdls_prohibited = 1;
2898 : }
2899 :
2900 4922 : if (!sm->tdls_chan_switch_prohibited &&
2901 2461 : wpa_tdls_chan_switch_prohibited(&elems)) {
2902 0 : wpa_printf(MSG_DEBUG,
2903 : "TDLS: TDLS channel switch prohibited based on (Re)Association Response IEs");
2904 0 : sm->tdls_chan_switch_prohibited = 1;
2905 : }
2906 : }
2907 :
2908 :
2909 3173 : void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
2910 : {
2911 3173 : wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
2912 3173 : sm->tdls_disabled = !enabled;
2913 3173 : }
2914 :
2915 :
2916 57 : int wpa_tdls_is_external_setup(struct wpa_sm *sm)
2917 : {
2918 57 : return sm->tdls_external_setup;
2919 : }
2920 :
2921 :
2922 3 : int wpa_tdls_enable_chan_switch(struct wpa_sm *sm, const u8 *addr,
2923 : u8 oper_class,
2924 : struct hostapd_freq_params *freq_params)
2925 : {
2926 : struct wpa_tdls_peer *peer;
2927 : int ret;
2928 :
2929 3 : if (sm->tdls_disabled || !sm->tdls_supported)
2930 0 : return -1;
2931 :
2932 3 : if (!sm->tdls_chan_switch) {
2933 0 : wpa_printf(MSG_DEBUG,
2934 : "TDLS: Channel switching not supported by the driver");
2935 0 : return -1;
2936 : }
2937 :
2938 3 : if (sm->tdls_chan_switch_prohibited) {
2939 0 : wpa_printf(MSG_DEBUG,
2940 : "TDLS: Channel switching is prohibited in this BSS - reject request to switch channel");
2941 0 : return -1;
2942 : }
2943 :
2944 3 : for (peer = sm->tdls; peer; peer = peer->next) {
2945 1 : if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2946 1 : break;
2947 : }
2948 :
2949 3 : if (peer == NULL || !peer->tpk_success) {
2950 12 : wpa_printf(MSG_ERROR, "TDLS: Peer " MACSTR
2951 12 : " not found for channel switching", MAC2STR(addr));
2952 2 : return -1;
2953 : }
2954 :
2955 1 : if (peer->chan_switch_enabled) {
2956 0 : wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
2957 : " already has channel switching enabled",
2958 0 : MAC2STR(addr));
2959 0 : return 0;
2960 : }
2961 :
2962 1 : ret = wpa_sm_tdls_enable_channel_switch(sm, peer->addr,
2963 : oper_class, freq_params);
2964 1 : if (!ret)
2965 1 : peer->chan_switch_enabled = 1;
2966 :
2967 1 : return ret;
2968 : }
2969 :
2970 :
2971 3 : int wpa_tdls_disable_chan_switch(struct wpa_sm *sm, const u8 *addr)
2972 : {
2973 : struct wpa_tdls_peer *peer;
2974 :
2975 3 : if (sm->tdls_disabled || !sm->tdls_supported)
2976 0 : return -1;
2977 :
2978 3 : for (peer = sm->tdls; peer; peer = peer->next) {
2979 2 : if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2980 2 : break;
2981 : }
2982 :
2983 3 : if (!peer || !peer->chan_switch_enabled) {
2984 12 : wpa_printf(MSG_ERROR, "TDLS: Channel switching not enabled for "
2985 12 : MACSTR, MAC2STR(addr));
2986 2 : return -1;
2987 : }
2988 :
2989 : /* ignore the return value */
2990 1 : wpa_sm_tdls_disable_channel_switch(sm, peer->addr);
2991 :
2992 1 : peer->chan_switch_enabled = 0;
2993 1 : return 0;
2994 : }
|