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