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