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