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