Coverage Report

Created: 2025-04-24 06:18

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