OSDN Git Service

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