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 1401264779 Lines: 939 1256 74.8 %
Date: 2014-05-28 Functions: 54 57 94.7 %

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

Generated by: LCOV version 1.10