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