LCOV - code coverage report
Current view: top level - src/rsn_supp - tdls.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1422976643 Lines: 1081 1398 77.3 %
Date: 2015-02-03 Functions: 61 63 96.8 %

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

Generated by: LCOV version 1.10