]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/wpa/src/rsn_supp/tdls.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / wpa / 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
1313         peer->supp_rates_len = kde->supp_rates_len - 2;
1314         if (peer->supp_rates_len > IEEE80211_MAX_SUPP_RATES)
1315                 peer->supp_rates_len = IEEE80211_MAX_SUPP_RATES;
1316         os_memcpy(peer->supp_rates, kde->supp_rates + 2, peer->supp_rates_len);
1317
1318         if (kde->ext_supp_rates) {
1319                 int clen = kde->ext_supp_rates_len - 2;
1320                 if (peer->supp_rates_len + clen > IEEE80211_MAX_SUPP_RATES)
1321                         clen = IEEE80211_MAX_SUPP_RATES - peer->supp_rates_len;
1322                 os_memcpy(peer->supp_rates + peer->supp_rates_len,
1323                           kde->ext_supp_rates + 2, clen);
1324                 peer->supp_rates_len += clen;
1325         }
1326
1327         return 0;
1328 }
1329
1330
1331 static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
1332                                    const u8 *buf, size_t len)
1333 {
1334         struct wpa_tdls_peer *peer;
1335         struct wpa_eapol_ie_parse kde;
1336         struct wpa_ie_data ie;
1337         int cipher;
1338         const u8 *cpos;
1339         struct wpa_tdls_ftie *ftie = NULL;
1340         struct wpa_tdls_timeoutie *timeoutie;
1341         struct wpa_tdls_lnkid *lnkid;
1342         u32 lifetime = 0;
1343 #if 0
1344         struct rsn_ie_hdr *hdr;
1345         u8 *pos;
1346         u16 rsn_capab;
1347         u16 rsn_ver;
1348 #endif
1349         u8 dtoken;
1350         u16 ielen;
1351         u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1352         int tdls_prohibited = sm->tdls_prohibited;
1353         int existing_peer = 0;
1354
1355         if (len < 3 + 3)
1356                 return -1;
1357
1358         cpos = buf;
1359         cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1360
1361         /* driver had already verified the frame format */
1362         dtoken = *cpos++; /* dialog token */
1363
1364         wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
1365
1366         for (peer = sm->tdls; peer; peer = peer->next) {
1367                 if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0) {
1368                         existing_peer = 1;
1369                         break;
1370                 }
1371         }
1372
1373         if (peer == NULL) {
1374                 peer = wpa_tdls_add_peer(sm, src_addr);
1375                 if (peer == NULL)
1376                         goto error;
1377         }
1378
1379         /* capability information */
1380         peer->capability = WPA_GET_LE16(cpos);
1381         cpos += 2;
1382
1383         ielen = len - (cpos - buf); /* start of IE in buf */
1384         if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
1385                 wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M1");
1386                 goto error;
1387         }
1388
1389         if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1390                 wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1391                            "TPK M1");
1392                 goto error;
1393         }
1394         wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
1395                     kde.lnkid, kde.lnkid_len);
1396         lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1397         if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1398                 wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
1399                 status = WLAN_STATUS_NOT_IN_SAME_BSS;
1400                 goto error;
1401         }
1402
1403         wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
1404                    MAC2STR(src_addr));
1405
1406         if (copy_supp_rates(&kde, peer) < 0)
1407                 goto error;
1408
1409 #ifdef CONFIG_TDLS_TESTING
1410         if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1411                 for (peer = sm->tdls; peer; peer = peer->next) {
1412                         if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1413                                 break;
1414                 }
1415                 if (peer == NULL) {
1416                         peer = wpa_tdls_add_peer(sm, src_addr);
1417                         if (peer == NULL)
1418                                 goto error;
1419                 }
1420                 wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
1421                            "TDLS setup - send own request");
1422                 peer->initiator = 1;
1423                 wpa_tdls_send_tpk_m1(sm, peer);
1424         }
1425
1426         if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
1427             tdls_prohibited) {
1428                 wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
1429                            "on TDLS");
1430                 tdls_prohibited = 0;
1431         }
1432 #endif /* CONFIG_TDLS_TESTING */
1433
1434         if (tdls_prohibited) {
1435                 wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
1436                 status = WLAN_STATUS_REQUEST_DECLINED;
1437                 goto error;
1438         }
1439
1440         if (!wpa_tdls_get_privacy(sm)) {
1441                 if (kde.rsn_ie) {
1442                         wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
1443                                    "security is disabled");
1444                         status = WLAN_STATUS_SECURITY_DISABLED;
1445                         goto error;
1446                 }
1447                 goto skip_rsn;
1448         }
1449
1450         if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1451             kde.rsn_ie == NULL) {
1452                 wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
1453                 status = WLAN_STATUS_INVALID_PARAMETERS;
1454                 goto error;
1455         }
1456
1457         if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
1458                 wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
1459                            "TPK M1");
1460                 status = WLAN_STATUS_INVALID_RSNIE;
1461                 goto error;
1462         }
1463
1464         if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1465                 wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
1466                 status = WLAN_STATUS_INVALID_RSNIE;
1467                 goto error;
1468         }
1469
1470         cipher = ie.pairwise_cipher;
1471         if (cipher & WPA_CIPHER_CCMP) {
1472                 wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1473                 cipher = WPA_CIPHER_CCMP;
1474         } else {
1475                 wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
1476                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1477                 goto error;
1478         }
1479
1480         if ((ie.capabilities &
1481              (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
1482             WPA_CAPABILITY_PEERKEY_ENABLED) {
1483                 wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
1484                            "TPK M1");
1485                 status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
1486                 goto error;
1487         }
1488
1489         /* Lifetime */
1490         if (kde.key_lifetime == NULL) {
1491                 wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
1492                 status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1493                 goto error;
1494         }
1495         timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1496         lifetime = WPA_GET_LE32(timeoutie->value);
1497         wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
1498         if (lifetime < 300) {
1499                 wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
1500                 status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1501                 goto error;
1502         }
1503
1504 skip_rsn:
1505         /* If found, use existing entry instead of adding a new one;
1506          * how to handle the case where both ends initiate at the
1507          * same time? */
1508         if (existing_peer) {
1509                 if (peer->tpk_success) {
1510                         wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
1511                                    "direct link is enabled - tear down the "
1512                                    "old link first");
1513 #if 0
1514                         /* TODO: Disabling the link would be more proper
1515                          * operation here, but it seems to trigger a race with
1516                          * some drivers handling the new request frame. */
1517                         wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1518 #else
1519                         if (sm->tdls_external_setup)
1520                                 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
1521                                                  src_addr);
1522                         else
1523                                 wpa_tdls_del_key(sm, peer);
1524 #endif
1525                         wpa_tdls_peer_free(sm, peer);
1526                 }
1527
1528                 /*
1529                  * An entry is already present, so check if we already sent a
1530                  * TDLS Setup Request. If so, compare MAC addresses and let the
1531                  * STA with the lower MAC address continue as the initiator.
1532                  * The other negotiation is terminated.
1533                  */
1534                 if (peer->initiator) {
1535                         if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
1536                                 wpa_printf(MSG_DEBUG, "TDLS: Discard request "
1537                                            "from peer with higher address "
1538                                            MACSTR, MAC2STR(src_addr));
1539                                 return -1;
1540                         } else {
1541                                 wpa_printf(MSG_DEBUG, "TDLS: Accept request "
1542                                            "from peer with lower address "
1543                                            MACSTR " (terminate previously "
1544                                            "initiated negotiation",
1545                                            MAC2STR(src_addr));
1546                                 wpa_tdls_peer_free(sm, peer);
1547                         }
1548                 }
1549         }
1550
1551 #ifdef CONFIG_TDLS_TESTING
1552         if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
1553                 if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
1554                         /*
1555                          * The request frame from us is going to win, so do not
1556                          * replace information based on this request frame from
1557                          * the peer.
1558                          */
1559                         goto skip_rsn_check;
1560                 }
1561         }
1562 #endif /* CONFIG_TDLS_TESTING */
1563
1564         peer->initiator = 0; /* Need to check */
1565         peer->dtoken = dtoken;
1566
1567         if (!wpa_tdls_get_privacy(sm)) {
1568                 peer->rsnie_i_len = 0;
1569                 peer->rsnie_p_len = 0;
1570                 peer->cipher = WPA_CIPHER_NONE;
1571                 goto skip_rsn_check;
1572         }
1573
1574         ftie = (struct wpa_tdls_ftie *) kde.ftie;
1575         os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
1576         os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
1577         peer->rsnie_i_len = kde.rsn_ie_len;
1578         peer->cipher = cipher;
1579
1580         if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
1581                 wpa_msg(sm->ctx->ctx, MSG_WARNING,
1582                         "TDLS: Failed to get random data for responder nonce");
1583                 wpa_tdls_peer_free(sm, peer);
1584                 goto error;
1585         }
1586
1587 #if 0
1588         /* get version info from RSNIE received from Peer */
1589         hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
1590         rsn_ver = WPA_GET_LE16(hdr->version);
1591
1592         /* use min(peer's version, out version) */
1593         if (rsn_ver > RSN_VERSION)
1594                 rsn_ver = RSN_VERSION;
1595
1596         hdr = (struct rsn_ie_hdr *) peer->rsnie_p;
1597
1598         hdr->elem_id = WLAN_EID_RSN;
1599         WPA_PUT_LE16(hdr->version, rsn_ver);
1600         pos = (u8 *) (hdr + 1);
1601
1602         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
1603         pos += RSN_SELECTOR_LEN;
1604         /* Include only the selected cipher in pairwise cipher suite */
1605         WPA_PUT_LE16(pos, 1);
1606         pos += 2;
1607         if (cipher == WPA_CIPHER_CCMP)
1608                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1609         pos += RSN_SELECTOR_LEN;
1610
1611         WPA_PUT_LE16(pos, 1);
1612         pos += 2;
1613         RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
1614         pos += RSN_SELECTOR_LEN;
1615
1616         rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
1617         rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
1618         WPA_PUT_LE16(pos, rsn_capab);
1619         pos += 2;
1620
1621         hdr->len = (pos - peer->rsnie_p) - 2;
1622         peer->rsnie_p_len = pos - peer->rsnie_p;
1623 #endif
1624
1625         /* temp fix: validation of RSNIE later */
1626         os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
1627         peer->rsnie_p_len = peer->rsnie_i_len;
1628
1629         wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
1630                     peer->rsnie_p, peer->rsnie_p_len);
1631
1632         peer->lifetime = lifetime;
1633
1634         wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1635
1636 skip_rsn_check:
1637         /* add the peer to the driver as a "setup in progress" peer */
1638         wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
1639
1640         wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
1641         if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
1642                 wpa_tdls_disable_link(sm, peer->addr);
1643                 goto error;
1644         }
1645
1646         return 0;
1647
1648 error:
1649         wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
1650                             status);
1651         return -1;
1652 }
1653
1654
1655 static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
1656 {
1657         peer->tpk_success = 1;
1658         eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1659         if (wpa_tdls_get_privacy(sm)) {
1660                 u32 lifetime = peer->lifetime;
1661                 /*
1662                  * Start the initiator process a bit earlier to avoid race
1663                  * condition with the responder sending teardown request.
1664                  */
1665                 if (lifetime > 3 && peer->initiator)
1666                         lifetime -= 3;
1667                 eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
1668                                        sm, peer);
1669 #ifdef CONFIG_TDLS_TESTING
1670         if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
1671                 wpa_printf(MSG_DEBUG, "TDLS: Testing - disable TPK "
1672                            "expiration");
1673                 eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
1674         }
1675 #endif /* CONFIG_TDLS_TESTING */
1676         }
1677
1678         /* add supported rates and capabilities to the TDLS peer */
1679         wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
1680                                 peer->supp_rates, peer->supp_rates_len);
1681
1682         wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
1683 }
1684
1685
1686 static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
1687                                    const u8 *buf, size_t len)
1688 {
1689         struct wpa_tdls_peer *peer;
1690         struct wpa_eapol_ie_parse kde;
1691         struct wpa_ie_data ie;
1692         int cipher;
1693         struct wpa_tdls_ftie *ftie;
1694         struct wpa_tdls_timeoutie *timeoutie;
1695         struct wpa_tdls_lnkid *lnkid;
1696         u32 lifetime;
1697         u8 dtoken;
1698         int ielen;
1699         u16 status;
1700         const u8 *pos;
1701
1702         wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
1703                    "(Peer " MACSTR ")", MAC2STR(src_addr));
1704         for (peer = sm->tdls; peer; peer = peer->next) {
1705                 if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1706                         break;
1707         }
1708         if (peer == NULL) {
1709                 wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1710                            "TPK M2: " MACSTR, MAC2STR(src_addr));
1711                 return -1;
1712         }
1713         wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
1714
1715         if (len < 3 + 2 + 1)
1716                 return -1;
1717         pos = buf;
1718         pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1719         status = WPA_GET_LE16(pos);
1720         pos += 2 /* status code */;
1721
1722         if (status != WLAN_STATUS_SUCCESS) {
1723                 wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
1724                            status);
1725                 if (sm->tdls_external_setup)
1726                         wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1727                 return -1;
1728         }
1729
1730         status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1731
1732         /* TODO: need to verify dialog token matches here or in kernel */
1733         dtoken = *pos++; /* dialog token */
1734
1735         wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
1736
1737         if (len < 3 + 2 + 1 + 2)
1738                 return -1;
1739
1740         /* capability information */
1741         peer->capability = WPA_GET_LE16(pos);
1742         pos += 2;
1743
1744         ielen = len - (pos - buf); /* start of IE in buf */
1745         if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
1746                 wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M2");
1747                 goto error;
1748         }
1749
1750 #ifdef CONFIG_TDLS_TESTING
1751         if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
1752                 wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
1753                 status = WLAN_STATUS_REQUEST_DECLINED;
1754                 goto error;
1755         }
1756 #endif /* CONFIG_TDLS_TESTING */
1757
1758         if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1759                 wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
1760                            "TPK M2");
1761                 goto error;
1762         }
1763         wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
1764                     kde.lnkid, kde.lnkid_len);
1765         lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1766
1767         if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1768                 wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
1769                 status = WLAN_STATUS_NOT_IN_SAME_BSS;
1770                 goto error;
1771         }
1772
1773         if (copy_supp_rates(&kde, peer) < 0)
1774                 goto error;
1775
1776         if (!wpa_tdls_get_privacy(sm)) {
1777                 peer->rsnie_p_len = 0;
1778                 peer->cipher = WPA_CIPHER_NONE;
1779                 goto skip_rsn;
1780         }
1781
1782         if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
1783             kde.rsn_ie == NULL) {
1784                 wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
1785                 status = WLAN_STATUS_INVALID_PARAMETERS;
1786                 goto error;
1787         }
1788         wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1789                     kde.rsn_ie, kde.rsn_ie_len);
1790
1791         /*
1792          * FIX: bitwise comparison of RSN IE is not the correct way of
1793          * validation this. It can be different, but certain fields must
1794          * match. Since we list only a single pairwise cipher in TPK M1, the
1795          * memcmp is likely to work in most cases, though.
1796          */
1797         if (kde.rsn_ie_len != peer->rsnie_i_len ||
1798             os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
1799                 wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
1800                            "not match with RSN IE used in TPK M1");
1801                 wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
1802                             peer->rsnie_i, peer->rsnie_i_len);
1803                 wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
1804                             kde.rsn_ie, kde.rsn_ie_len);
1805                 status = WLAN_STATUS_INVALID_RSNIE;
1806                 goto error;
1807         }
1808
1809         if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
1810                 wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
1811                 status = WLAN_STATUS_INVALID_RSNIE;
1812                 goto error;
1813         }
1814
1815         cipher = ie.pairwise_cipher;
1816         if (cipher == WPA_CIPHER_CCMP) {
1817                 wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
1818                 cipher = WPA_CIPHER_CCMP;
1819         } else {
1820                 wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
1821                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1822                 goto error;
1823         }
1824
1825         wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
1826                     kde.ftie, sizeof(*ftie));
1827         ftie = (struct wpa_tdls_ftie *) kde.ftie;
1828
1829         if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1830                 wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
1831                            "not match with FTIE SNonce used in TPK M1");
1832                 /* Silently discard the frame */
1833                 return -1;
1834         }
1835
1836         /* Responder Nonce and RSN IE */
1837         os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
1838         os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
1839         peer->rsnie_p_len = kde.rsn_ie_len;
1840         peer->cipher = cipher;
1841
1842         /* Lifetime */
1843         if (kde.key_lifetime == NULL) {
1844                 wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
1845                 status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1846                 goto error;
1847         }
1848         timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1849         lifetime = WPA_GET_LE32(timeoutie->value);
1850         wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
1851                    lifetime);
1852         if (lifetime != peer->lifetime) {
1853                 wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
1854                            "TPK M2 (expected %u)", lifetime, peer->lifetime);
1855                 status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
1856                 goto error;
1857         }
1858
1859         wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
1860
1861         /* Process MIC check to see if TPK M2 is right */
1862         if (wpa_supplicant_verify_tdls_mic(2, peer, (u8 *) lnkid,
1863                                            (u8 *) timeoutie, ftie) < 0) {
1864                 /* Discard the frame */
1865                 wpa_tdls_del_key(sm, peer);
1866                 wpa_tdls_peer_free(sm, peer);
1867                 if (sm->tdls_external_setup)
1868                         wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1869                 return -1;
1870         }
1871
1872         wpa_tdls_set_key(sm, peer);
1873
1874 skip_rsn:
1875         peer->dtoken = dtoken;
1876
1877         wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
1878                    "TPK Handshake Message 3");
1879         wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
1880
1881         wpa_tdls_enable_link(sm, peer);
1882
1883         return 0;
1884
1885 error:
1886         wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
1887                             status);
1888         if (sm->tdls_external_setup)
1889                 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1890         return -1;
1891 }
1892
1893
1894 static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
1895                                    const u8 *buf, size_t len)
1896 {
1897         struct wpa_tdls_peer *peer;
1898         struct wpa_eapol_ie_parse kde;
1899         struct wpa_tdls_ftie *ftie;
1900         struct wpa_tdls_timeoutie *timeoutie;
1901         struct wpa_tdls_lnkid *lnkid;
1902         int ielen;
1903         u16 status;
1904         const u8 *pos;
1905         u32 lifetime;
1906
1907         wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
1908                    "(Peer " MACSTR ")", MAC2STR(src_addr));
1909         for (peer = sm->tdls; peer; peer = peer->next) {
1910                 if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
1911                         break;
1912         }
1913         if (peer == NULL) {
1914                 wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
1915                            "TPK M3: " MACSTR, MAC2STR(src_addr));
1916                 return -1;
1917         }
1918         wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
1919
1920         if (len < 3 + 3)
1921                 return -1;
1922         pos = buf;
1923         pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
1924
1925         status = WPA_GET_LE16(pos);
1926
1927         if (status != 0) {
1928                 wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
1929                            status);
1930                 if (sm->tdls_external_setup)
1931                         wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
1932                 return -1;
1933         }
1934         pos += 2 /* status code */ + 1 /* dialog token */;
1935
1936         ielen = len - (pos - buf); /* start of IE in buf */
1937         if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
1938                 wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3");
1939                 return -1;
1940         }
1941
1942         if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
1943                 wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
1944                 return -1;
1945         }
1946         wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
1947                     (u8 *) kde.lnkid, kde.lnkid_len);
1948         lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
1949
1950         if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
1951                 wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
1952                 return -1;
1953         }
1954
1955         if (!wpa_tdls_get_privacy(sm))
1956                 goto skip_rsn;
1957
1958         if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
1959                 wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
1960                 return -1;
1961         }
1962         wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
1963                     kde.ftie, sizeof(*ftie));
1964         ftie = (struct wpa_tdls_ftie *) kde.ftie;
1965
1966         if (kde.rsn_ie == NULL) {
1967                 wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
1968                 return -1;
1969         }
1970         wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
1971                     kde.rsn_ie, kde.rsn_ie_len);
1972         if (kde.rsn_ie_len != peer->rsnie_p_len ||
1973             os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
1974                 wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
1975                            "with the one sent in TPK M2");
1976                 return -1;
1977         }
1978
1979         if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
1980                 wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
1981                            "not match with FTIE ANonce used in TPK M2");
1982                 return -1;
1983         }
1984
1985         if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
1986                 wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
1987                            "match with FTIE SNonce used in TPK M1");
1988                 return -1;
1989         }
1990
1991         if (kde.key_lifetime == NULL) {
1992                 wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
1993                 return -1;
1994         }
1995         timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
1996         wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
1997                     (u8 *) timeoutie, sizeof(*timeoutie));
1998         lifetime = WPA_GET_LE32(timeoutie->value);
1999         wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
2000                    lifetime);
2001         if (lifetime != peer->lifetime) {
2002                 wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
2003                            "TPK M3 (expected %u)", lifetime, peer->lifetime);
2004                 if (sm->tdls_external_setup)
2005                         wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
2006                 return -1;
2007         }
2008
2009         if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
2010                                            (u8 *) timeoutie, ftie) < 0) {
2011                 wpa_tdls_del_key(sm, peer);
2012                 wpa_tdls_peer_free(sm, peer);
2013                 return -1;
2014         }
2015
2016         if (wpa_tdls_set_key(sm, peer) < 0)
2017                 return -1;
2018
2019 skip_rsn:
2020         wpa_tdls_enable_link(sm, peer);
2021
2022         return 0;
2023 }
2024
2025
2026 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
2027 {
2028         struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;
2029
2030         os_memset(lifetime, 0, ie_len);
2031         lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
2032         lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
2033         lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
2034         WPA_PUT_LE32(lifetime->value, tsecs);
2035         os_memcpy(pos, ie, ie_len);
2036         return pos + ie_len;
2037 }
2038
2039
2040 /**
2041  * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2042  * @sm: Pointer to WPA state machine data from wpa_sm_init()
2043  * @peer: MAC address of the peer STA
2044  * Returns: 0 on success, or -1 on failure
2045  *
2046  * Send TPK Handshake Message 1 info to driver to start TDLS
2047  * handshake with the peer.
2048  */
2049 int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
2050 {
2051         struct wpa_tdls_peer *peer;
2052         int tdls_prohibited = sm->tdls_prohibited;
2053
2054         if (sm->tdls_disabled || !sm->tdls_supported)
2055                 return -1;
2056
2057 #ifdef CONFIG_TDLS_TESTING
2058         if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
2059             tdls_prohibited) {
2060                 wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
2061                            "on TDLS");
2062                 tdls_prohibited = 0;
2063         }
2064 #endif /* CONFIG_TDLS_TESTING */
2065
2066         if (tdls_prohibited) {
2067                 wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
2068                            "reject request to start setup");
2069                 return -1;
2070         }
2071
2072         /* Find existing entry and if found, use that instead of adding
2073          * a new one */
2074         for (peer = sm->tdls; peer; peer = peer->next) {
2075                 if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2076                         break;
2077         }
2078
2079         if (peer == NULL) {
2080                 peer = wpa_tdls_add_peer(sm, addr);
2081                 if (peer == NULL)
2082                         return -1;
2083         }
2084
2085         peer->initiator = 1;
2086
2087         /* add the peer to the driver as a "setup in progress" peer */
2088         wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0);
2089
2090         if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
2091                 wpa_tdls_disable_link(sm, peer->addr);
2092                 return -1;
2093         }
2094
2095         return 0;
2096 }
2097
2098
2099 int wpa_tdls_reneg(struct wpa_sm *sm, const u8 *addr)
2100 {
2101         struct wpa_tdls_peer *peer;
2102
2103         if (sm->tdls_disabled || !sm->tdls_supported)
2104                 return -1;
2105
2106         for (peer = sm->tdls; peer; peer = peer->next) {
2107                 if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
2108                         break;
2109         }
2110
2111         if (peer == NULL || !peer->tpk_success)
2112                 return -1;
2113
2114         if (sm->tdls_external_setup) {
2115                 /*
2116                  * Disable previous link to allow renegotiation to be completed
2117                  * on AP path.
2118                  */
2119                 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2120         }
2121
2122         return wpa_tdls_start(sm, addr);
2123 }
2124
2125
2126 /**
2127  * wpa_supplicant_rx_tdls - Receive TDLS data frame
2128  *
2129  * This function is called to receive TDLS (ethertype = 0x890d) data frames.
2130  */
2131 static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
2132                                    const u8 *buf, size_t len)
2133 {
2134         struct wpa_sm *sm = ctx;
2135         struct wpa_tdls_frame *tf;
2136
2137         wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
2138                     buf, len);
2139
2140         if (sm->tdls_disabled || !sm->tdls_supported) {
2141                 wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
2142                            "or unsupported by driver");
2143                 return;
2144         }
2145
2146         if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
2147                 wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
2148                 return;
2149         }
2150
2151         if (len < sizeof(*tf)) {
2152                 wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
2153                 return;
2154         }
2155
2156         /* Check to make sure its a valid encapsulated TDLS frame */
2157         tf = (struct wpa_tdls_frame *) buf;
2158         if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
2159             tf->category != WLAN_ACTION_TDLS) {
2160                 wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
2161                            "category=%u action=%u",
2162                            tf->payloadtype, tf->category, tf->action);
2163                 return;
2164         }
2165
2166         switch (tf->action) {
2167         case WLAN_TDLS_SETUP_REQUEST:
2168                 wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
2169                 break;
2170         case WLAN_TDLS_SETUP_RESPONSE:
2171                 wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
2172                 break;
2173         case WLAN_TDLS_SETUP_CONFIRM:
2174                 wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
2175                 break;
2176         case WLAN_TDLS_TEARDOWN:
2177                 wpa_tdls_recv_teardown(sm, src_addr, buf, len);
2178                 break;
2179         case WLAN_TDLS_DISCOVERY_REQUEST:
2180                 wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
2181                 break;
2182         default:
2183                 /* Kernel code will process remaining frames */
2184                 wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
2185                            tf->action);
2186                 break;
2187         }
2188 }
2189
2190
2191 /**
2192  * wpa_tdls_init - Initialize driver interface parameters for TDLS
2193  * @wpa_s: Pointer to wpa_supplicant data
2194  * Returns: 0 on success, -1 on failure
2195  *
2196  * This function is called to initialize driver interface parameters for TDLS.
2197  * wpa_drv_init() must have been called before this function to initialize the
2198  * driver interface.
2199  */
2200 int wpa_tdls_init(struct wpa_sm *sm)
2201 {
2202         if (sm == NULL)
2203                 return -1;
2204
2205         sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
2206                                      sm->ifname,
2207                                      sm->own_addr,
2208                                      ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
2209                                      sm, 0);
2210         if (sm->l2_tdls == NULL) {
2211                 wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
2212                            "connection");
2213                 return -1;
2214         }
2215
2216         /*
2217          * Drivers that support TDLS but don't implement the get_capa callback
2218          * are assumed to perform everything internally
2219          */
2220         if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
2221                                  &sm->tdls_external_setup) < 0) {
2222                 sm->tdls_supported = 1;
2223                 sm->tdls_external_setup = 0;
2224         }
2225
2226         wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
2227                    "driver", sm->tdls_supported ? "" : " not");
2228         wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
2229                    sm->tdls_external_setup ? "external" : "internal");
2230
2231         return 0;
2232 }
2233
2234
2235 static void wpa_tdls_remove_peers(struct wpa_sm *sm)
2236 {
2237         struct wpa_tdls_peer *peer, *tmp;
2238
2239         peer = sm->tdls;
2240         sm->tdls = NULL;
2241
2242         while (peer) {
2243                 int res;
2244                 tmp = peer->next;
2245                 res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
2246                 wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
2247                            MAC2STR(peer->addr), res);
2248                 wpa_tdls_peer_free(sm, peer);
2249                 os_free(peer);
2250                 peer = tmp;
2251         }
2252 }
2253
2254
2255 /**
2256  * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
2257  *
2258  * This function is called to recover driver interface parameters for TDLS
2259  * and frees resources allocated for it.
2260  */
2261 void wpa_tdls_deinit(struct wpa_sm *sm)
2262 {
2263         if (sm == NULL)
2264                 return;
2265
2266         if (sm->l2_tdls)
2267                 l2_packet_deinit(sm->l2_tdls);
2268         sm->l2_tdls = NULL;
2269
2270         wpa_tdls_remove_peers(sm);
2271 }
2272
2273
2274 void wpa_tdls_assoc(struct wpa_sm *sm)
2275 {
2276         wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
2277         wpa_tdls_remove_peers(sm);
2278 }
2279
2280
2281 void wpa_tdls_disassoc(struct wpa_sm *sm)
2282 {
2283         wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
2284         wpa_tdls_remove_peers(sm);
2285 }
2286
2287
2288 static int wpa_tdls_prohibited(const u8 *ies, size_t len)
2289 {
2290         struct wpa_eapol_ie_parse elems;
2291
2292         if (ies == NULL)
2293                 return 0;
2294
2295         if (wpa_supplicant_parse_ies(ies, len, &elems) < 0)
2296                 return 0;
2297
2298         if (elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
2299                 return 0;
2300
2301          /* bit 38 - TDLS Prohibited */
2302         return !!(elems.ext_capab[2 + 4] & 0x40);
2303 }
2304
2305
2306 void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2307 {
2308         sm->tdls_prohibited = wpa_tdls_prohibited(ies, len);
2309         wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
2310                    sm->tdls_prohibited ? "prohibited" : "allowed");
2311 }
2312
2313
2314 void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
2315 {
2316         if (!sm->tdls_prohibited && wpa_tdls_prohibited(ies, len)) {
2317                 wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
2318                            "(Re)Association Response IEs");
2319                 sm->tdls_prohibited = 1;
2320         }
2321 }
2322
2323
2324 void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
2325 {
2326         wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
2327         sm->tdls_disabled = !enabled;
2328 }
2329
2330
2331 int wpa_tdls_is_external_setup(struct wpa_sm *sm)
2332 {
2333         return sm->tdls_external_setup;
2334 }