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