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