Coverage Report

Created: 2025-08-28 07:04

/src/hostap/src/common/wpa_common.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * WPA/RSN - Shared functions for supplicant and authenticator
3
 * Copyright (c) 2002-2018, Jouni Malinen <j@w1.fi>
4
 *
5
 * This software may be distributed under the terms of the BSD license.
6
 * See README for more details.
7
 */
8
9
#include "includes.h"
10
11
#include "common.h"
12
#include "crypto/md5.h"
13
#include "crypto/sha1.h"
14
#include "crypto/sha256.h"
15
#include "crypto/sha384.h"
16
#include "crypto/sha512.h"
17
#include "crypto/aes_wrap.h"
18
#include "crypto/crypto.h"
19
#include "ieee802_11_defs.h"
20
#include "ieee802_11_common.h"
21
#include "defs.h"
22
#include "wpa_common.h"
23
24
25
static unsigned int wpa_kck_len(int akmp, size_t pmk_len)
26
0
{
27
0
  switch (akmp) {
28
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
29
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
30
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
31
0
    return 24;
32
0
  case WPA_KEY_MGMT_FILS_SHA256:
33
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
34
0
  case WPA_KEY_MGMT_FILS_SHA384:
35
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
36
0
    return 0;
37
0
  case WPA_KEY_MGMT_DPP:
38
0
    return pmk_len / 2;
39
0
  case WPA_KEY_MGMT_OWE:
40
0
    return pmk_len / 2;
41
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
42
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
43
0
    return pmk_len / 2;
44
0
  default:
45
0
    return 16;
46
0
  }
47
0
}
48
49
50
#ifdef CONFIG_IEEE80211R
51
static unsigned int wpa_kck2_len(int akmp)
52
0
{
53
0
  switch (akmp) {
54
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
55
0
    return 16;
56
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
57
0
    return 24;
58
0
  default:
59
0
    return 0;
60
0
  }
61
0
}
62
#endif /* CONFIG_IEEE80211R */
63
64
65
static unsigned int wpa_kek_len(int akmp, size_t pmk_len)
66
0
{
67
0
  switch (akmp) {
68
0
  case WPA_KEY_MGMT_FILS_SHA384:
69
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
70
0
    return 64;
71
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
72
0
  case WPA_KEY_MGMT_FILS_SHA256:
73
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
74
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
75
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
76
0
    return 32;
77
0
  case WPA_KEY_MGMT_DPP:
78
0
    return pmk_len <= 32 ? 16 : 32;
79
0
  case WPA_KEY_MGMT_OWE:
80
0
    return pmk_len <= 32 ? 16 : 32;
81
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
82
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
83
0
    return pmk_len <= 32 ? 16 : 32;
84
0
  default:
85
0
    return 16;
86
0
  }
87
0
}
88
89
90
#ifdef CONFIG_IEEE80211R
91
static unsigned int wpa_kek2_len(int akmp)
92
0
{
93
0
  switch (akmp) {
94
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
95
0
    return 16;
96
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
97
0
    return 32;
98
0
  default:
99
0
    return 0;
100
0
  }
101
0
}
102
#endif /* CONFIG_IEEE80211R */
103
104
105
unsigned int wpa_mic_len(int akmp, size_t pmk_len)
106
0
{
107
0
  switch (akmp) {
108
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
109
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
110
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
111
0
    return 24;
112
0
  case WPA_KEY_MGMT_FILS_SHA256:
113
0
  case WPA_KEY_MGMT_FILS_SHA384:
114
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
115
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
116
0
    return 0;
117
0
  case WPA_KEY_MGMT_DPP:
118
0
    return pmk_len / 2;
119
0
  case WPA_KEY_MGMT_OWE:
120
0
    return pmk_len / 2;
121
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
122
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
123
0
    return pmk_len / 2;
124
0
  default:
125
0
    return 16;
126
0
  }
127
0
}
128
129
130
int rsn_cipher_suite_to_wpa_cipher(u32 cipher)
131
1.69k
{
132
1.69k
  switch (cipher) {
133
18
  case RSN_CIPHER_SUITE_NONE:
134
18
    return WPA_CIPHER_NONE;
135
40
  case RSN_CIPHER_SUITE_TKIP:
136
40
    return WPA_CIPHER_TKIP;
137
161
  case RSN_CIPHER_SUITE_CCMP:
138
161
    return WPA_CIPHER_CCMP;
139
12
  case RSN_CIPHER_SUITE_AES_128_CMAC:
140
12
    return WPA_CIPHER_AES_128_CMAC;
141
51
  case RSN_CIPHER_SUITE_GCMP:
142
51
    return WPA_CIPHER_GCMP;
143
134
  case RSN_CIPHER_SUITE_CCMP_256:
144
134
    return WPA_CIPHER_CCMP_256;
145
39
  case RSN_CIPHER_SUITE_GCMP_256:
146
39
    return WPA_CIPHER_GCMP_256;
147
25
  case RSN_CIPHER_SUITE_BIP_GMAC_128:
148
25
    return WPA_CIPHER_BIP_GMAC_128;
149
15
  case RSN_CIPHER_SUITE_BIP_GMAC_256:
150
15
    return WPA_CIPHER_BIP_GMAC_256;
151
23
  case RSN_CIPHER_SUITE_BIP_CMAC_256:
152
23
    return WPA_CIPHER_BIP_CMAC_256;
153
602
  case RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED:
154
602
    return WPA_CIPHER_GTK_NOT_USED;
155
571
  default:
156
571
    return 0;
157
1.69k
  }
158
1.69k
}
159
160
161
int rsn_key_mgmt_to_wpa_akm(u32 akm_suite)
162
1.52k
{
163
1.52k
  switch (akm_suite) {
164
56
  case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
165
56
    return WPA_KEY_MGMT_IEEE8021X;
166
60
  case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
167
60
    return WPA_KEY_MGMT_PSK;
168
0
#ifdef CONFIG_IEEE80211R
169
68
  case RSN_AUTH_KEY_MGMT_FT_802_1X:
170
68
    return WPA_KEY_MGMT_FT_IEEE8021X;
171
96
  case RSN_AUTH_KEY_MGMT_FT_PSK:
172
96
    return WPA_KEY_MGMT_FT_PSK;
173
0
#ifdef CONFIG_SHA384
174
59
  case RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384:
175
59
    return WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
176
0
#endif /* CONFIG_SHA384 */
177
0
#endif /* CONFIG_IEEE80211R */
178
0
#ifdef CONFIG_SHA384
179
14
  case RSN_AUTH_KEY_MGMT_802_1X_SHA384:
180
14
    return WPA_KEY_MGMT_IEEE8021X_SHA384;
181
0
#endif /* CONFIG_SHA384 */
182
71
  case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
183
71
    return WPA_KEY_MGMT_IEEE8021X_SHA256;
184
85
  case RSN_AUTH_KEY_MGMT_PSK_SHA256:
185
85
    return WPA_KEY_MGMT_PSK_SHA256;
186
0
#ifdef CONFIG_SAE
187
50
  case RSN_AUTH_KEY_MGMT_SAE:
188
50
    return WPA_KEY_MGMT_SAE;
189
20
  case RSN_AUTH_KEY_MGMT_SAE_EXT_KEY:
190
20
    return WPA_KEY_MGMT_SAE_EXT_KEY;
191
63
  case RSN_AUTH_KEY_MGMT_FT_SAE:
192
63
    return WPA_KEY_MGMT_FT_SAE;
193
25
  case RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY:
194
25
    return WPA_KEY_MGMT_FT_SAE_EXT_KEY;
195
0
#endif /* CONFIG_SAE */
196
64
  case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
197
64
    return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
198
58
  case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
199
58
    return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
200
56
  case RSN_AUTH_KEY_MGMT_FILS_SHA256:
201
56
    return WPA_KEY_MGMT_FILS_SHA256;
202
34
  case RSN_AUTH_KEY_MGMT_FILS_SHA384:
203
34
    return WPA_KEY_MGMT_FILS_SHA384;
204
34
  case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
205
34
    return WPA_KEY_MGMT_FT_FILS_SHA256;
206
34
  case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
207
34
    return WPA_KEY_MGMT_FT_FILS_SHA384;
208
#ifdef CONFIG_OWE
209
  case RSN_AUTH_KEY_MGMT_OWE:
210
    return WPA_KEY_MGMT_OWE;
211
#endif /* CONFIG_OWE */
212
#ifdef CONFIG_DPP
213
  case RSN_AUTH_KEY_MGMT_DPP:
214
    return WPA_KEY_MGMT_DPP;
215
#endif /* CONFIG_DPP */
216
0
#ifdef CONFIG_PASN
217
156
  case RSN_AUTH_KEY_MGMT_PASN:
218
156
    return WPA_KEY_MGMT_PASN;
219
0
#endif /* CONFIG_PASN */
220
423
  default:
221
423
    return 0;
222
1.52k
  }
223
1.52k
}
224
225
226
/**
227
 * wpa_use_akm_defined - Is AKM-defined Key Descriptor Version used
228
 * @akmp: WPA_KEY_MGMT_* used in key derivation
229
 * Returns: 1 if AKM-defined Key Descriptor Version is used; 0 otherwise
230
 */
231
int wpa_use_akm_defined(int akmp)
232
0
{
233
0
  return akmp == WPA_KEY_MGMT_OWE ||
234
0
    akmp == WPA_KEY_MGMT_DPP ||
235
0
    akmp == WPA_KEY_MGMT_FT_IEEE8021X_SHA384 ||
236
0
    akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
237
0
    wpa_key_mgmt_sae(akmp) ||
238
0
    wpa_key_mgmt_suite_b(akmp) ||
239
0
    wpa_key_mgmt_fils(akmp);
240
0
}
241
242
243
/**
244
 * wpa_use_cmac - Is CMAC integrity algorithm used for EAPOL-Key MIC
245
 * @akmp: WPA_KEY_MGMT_* used in key derivation
246
 * Returns: 1 if CMAC is used; 0 otherwise
247
 */
248
int wpa_use_cmac(int akmp)
249
0
{
250
0
  return akmp == WPA_KEY_MGMT_OWE ||
251
0
    akmp == WPA_KEY_MGMT_DPP ||
252
0
    wpa_key_mgmt_ft(akmp) ||
253
0
    wpa_key_mgmt_sha256(akmp) ||
254
0
    (wpa_key_mgmt_sae(akmp) &&
255
0
     !wpa_key_mgmt_sae_ext_key(akmp)) ||
256
0
    wpa_key_mgmt_suite_b(akmp);
257
0
}
258
259
260
/**
261
 * wpa_use_aes_key_wrap - Is AES Keywrap algorithm used for EAPOL-Key Key Data
262
 * @akmp: WPA_KEY_MGMT_* used in key derivation
263
 * Returns: 1 if AES Keywrap is used; 0 otherwise
264
 *
265
 * Note: AKM 00-0F-AC:1 and 00-0F-AC:2 have special rules for selecting whether
266
 * to use AES Keywrap based on the negotiated pairwise cipher. This function
267
 * does not cover those special cases.
268
 */
269
int wpa_use_aes_key_wrap(int akmp)
270
0
{
271
0
  return akmp == WPA_KEY_MGMT_OWE ||
272
0
    akmp == WPA_KEY_MGMT_DPP ||
273
0
    akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
274
0
    wpa_key_mgmt_ft(akmp) ||
275
0
    wpa_key_mgmt_sha256(akmp) ||
276
0
    wpa_key_mgmt_sae(akmp) ||
277
0
    wpa_key_mgmt_suite_b(akmp);
278
0
}
279
280
281
/**
282
 * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
283
 * @key: EAPOL-Key Key Confirmation Key (KCK)
284
 * @key_len: KCK length in octets
285
 * @akmp: WPA_KEY_MGMT_* used in key derivation
286
 * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
287
 * @buf: Pointer to the beginning of the EAPOL header (version field)
288
 * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
289
 * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
290
 * Returns: 0 on success, -1 on failure
291
 *
292
 * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
293
 * to be cleared (all zeroes) when calling this function.
294
 *
295
 * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
296
 * description of the Key MIC calculation. It includes packet data from the
297
 * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
298
 * happened during final editing of the standard and the correct behavior is
299
 * defined in the last draft (IEEE 802.11i/D10).
300
 */
301
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
302
          const u8 *buf, size_t len, u8 *mic)
303
0
{
304
0
  u8 hash[SHA512_MAC_LEN];
305
306
0
  if (key_len == 0) {
307
0
    wpa_printf(MSG_DEBUG,
308
0
         "WPA: KCK not set - cannot calculate MIC");
309
0
    return -1;
310
0
  }
311
312
0
  switch (ver) {
313
0
#ifndef CONFIG_FIPS
314
0
  case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
315
0
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-MD5");
316
0
    return hmac_md5(key, key_len, buf, len, mic);
317
0
#endif /* CONFIG_FIPS */
318
0
  case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
319
0
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-SHA1");
320
0
    if (hmac_sha1(key, key_len, buf, len, hash))
321
0
      return -1;
322
0
    os_memcpy(mic, hash, MD5_MAC_LEN);
323
0
    break;
324
0
  case WPA_KEY_INFO_TYPE_AES_128_CMAC:
325
0
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using AES-CMAC");
326
0
    return omac1_aes_128(key, buf, len, mic);
327
0
  case WPA_KEY_INFO_TYPE_AKM_DEFINED:
328
0
    switch (akmp) {
329
0
#ifdef CONFIG_SAE
330
0
    case WPA_KEY_MGMT_SAE:
331
0
    case WPA_KEY_MGMT_FT_SAE:
332
0
      wpa_printf(MSG_DEBUG,
333
0
           "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - SAE)");
334
0
      return omac1_aes_128(key, buf, len, mic);
335
0
    case WPA_KEY_MGMT_SAE_EXT_KEY:
336
0
    case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
337
0
      wpa_printf(MSG_DEBUG,
338
0
           "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - SAE-EXT-KEY)",
339
0
           (unsigned int) key_len * 8 * 2);
340
0
      if (key_len == 128 / 8) {
341
0
        if (hmac_sha256(key, key_len, buf, len, hash))
342
0
          return -1;
343
0
#ifdef CONFIG_SHA384
344
0
      } else if (key_len == 192 / 8) {
345
0
        if (hmac_sha384(key, key_len, buf, len, hash))
346
0
          return -1;
347
0
#endif /* CONFIG_SHA384 */
348
#ifdef CONFIG_SHA512
349
      } else if (key_len == 256 / 8) {
350
        if (hmac_sha512(key, key_len, buf, len, hash))
351
          return -1;
352
#endif /* CONFIG_SHA512 */
353
0
      } else {
354
0
        wpa_printf(MSG_INFO,
355
0
             "SAE: Unsupported KCK length: %u",
356
0
             (unsigned int) key_len);
357
0
        return -1;
358
0
      }
359
0
      os_memcpy(mic, hash, key_len);
360
0
      break;
361
0
#endif /* CONFIG_SAE */
362
#ifdef CONFIG_SUITEB
363
    case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
364
      wpa_printf(MSG_DEBUG,
365
           "WPA: EAPOL-Key MIC using HMAC-SHA256 (AKM-defined - Suite B)");
366
      if (hmac_sha256(key, key_len, buf, len, hash))
367
        return -1;
368
      os_memcpy(mic, hash, MD5_MAC_LEN);
369
      break;
370
#endif /* CONFIG_SUITEB */
371
#ifdef CONFIG_SUITEB192
372
    case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
373
      wpa_printf(MSG_DEBUG,
374
           "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - Suite B 192-bit)");
375
      if (hmac_sha384(key, key_len, buf, len, hash))
376
        return -1;
377
      os_memcpy(mic, hash, 24);
378
      break;
379
#endif /* CONFIG_SUITEB192 */
380
#ifdef CONFIG_OWE
381
    case WPA_KEY_MGMT_OWE:
382
      wpa_printf(MSG_DEBUG,
383
           "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - OWE)",
384
           (unsigned int) key_len * 8 * 2);
385
      if (key_len == 128 / 8) {
386
        if (hmac_sha256(key, key_len, buf, len, hash))
387
          return -1;
388
      } else if (key_len == 192 / 8) {
389
        if (hmac_sha384(key, key_len, buf, len, hash))
390
          return -1;
391
      } else if (key_len == 256 / 8) {
392
        if (hmac_sha512(key, key_len, buf, len, hash))
393
          return -1;
394
      } else {
395
        wpa_printf(MSG_INFO,
396
             "OWE: Unsupported KCK length: %u",
397
             (unsigned int) key_len);
398
        return -1;
399
      }
400
      os_memcpy(mic, hash, key_len);
401
      break;
402
#endif /* CONFIG_OWE */
403
#ifdef CONFIG_DPP
404
    case WPA_KEY_MGMT_DPP:
405
      wpa_printf(MSG_DEBUG,
406
           "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - DPP)",
407
           (unsigned int) key_len * 8 * 2);
408
      if (key_len == 128 / 8) {
409
        if (hmac_sha256(key, key_len, buf, len, hash))
410
          return -1;
411
      } else if (key_len == 192 / 8) {
412
        if (hmac_sha384(key, key_len, buf, len, hash))
413
          return -1;
414
      } else if (key_len == 256 / 8) {
415
        if (hmac_sha512(key, key_len, buf, len, hash))
416
          return -1;
417
      } else {
418
        wpa_printf(MSG_INFO,
419
             "DPP: Unsupported KCK length: %u",
420
             (unsigned int) key_len);
421
        return -1;
422
      }
423
      os_memcpy(mic, hash, key_len);
424
      break;
425
#endif /* CONFIG_DPP */
426
0
#ifdef CONFIG_SHA384
427
0
    case WPA_KEY_MGMT_IEEE8021X_SHA384:
428
0
#ifdef CONFIG_IEEE80211R
429
0
    case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
430
0
#endif /* CONFIG_IEEE80211R */
431
0
      wpa_printf(MSG_DEBUG,
432
0
           "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - 802.1X SHA384)");
433
0
      if (hmac_sha384(key, key_len, buf, len, hash))
434
0
        return -1;
435
0
      os_memcpy(mic, hash, 24);
436
0
      break;
437
0
#endif /* CONFIG_SHA384 */
438
0
    default:
439
0
      wpa_printf(MSG_DEBUG,
440
0
           "WPA: EAPOL-Key MIC algorithm not known (AKM-defined - akmp=0x%x)",
441
0
           akmp);
442
0
      return -1;
443
0
    }
444
0
    break;
445
0
  default:
446
0
    wpa_printf(MSG_DEBUG,
447
0
         "WPA: EAPOL-Key MIC algorithm not known (ver=%d)",
448
0
         ver);
449
0
    return -1;
450
0
  }
451
452
0
  return 0;
453
0
}
454
455
456
/**
457
 * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
458
 * @pmk: Pairwise master key
459
 * @pmk_len: Length of PMK
460
 * @label: Label to use in derivation
461
 * @addr1: AA or SA
462
 * @addr2: SA or AA
463
 * @nonce1: ANonce or SNonce
464
 * @nonce2: SNonce or ANonce
465
 * @ptk: Buffer for pairwise transient key
466
 * @akmp: Negotiated AKM
467
 * @cipher: Negotiated pairwise cipher
468
 * @kdk_len: The length in octets that should be derived for KDK
469
 * Returns: 0 on success, -1 on failure
470
 *
471
 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
472
 * PTK = PRF-X(PMK, "Pairwise key expansion",
473
 *             Min(AA, SA) || Max(AA, SA) ||
474
 *             Min(ANonce, SNonce) || Max(ANonce, SNonce)
475
 *             [ || Z.x ])
476
 *
477
 * The optional Z.x component is used only with DPP and that part is not defined
478
 * in IEEE 802.11.
479
 */
480
int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
481
       const u8 *addr1, const u8 *addr2,
482
       const u8 *nonce1, const u8 *nonce2,
483
       struct wpa_ptk *ptk, int akmp, int cipher,
484
       const u8 *z, size_t z_len, size_t kdk_len)
485
0
{
486
0
#define MAX_Z_LEN 66 /* with NIST P-521 */
487
0
  u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
488
0
  size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
489
0
  u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
490
0
    WPA_KDK_MAX_LEN];
491
0
  size_t ptk_len;
492
#ifdef CONFIG_OWE
493
  int owe_ptk_workaround = 0;
494
495
  if (akmp == (WPA_KEY_MGMT_OWE | WPA_KEY_MGMT_PSK_SHA256)) {
496
    owe_ptk_workaround = 1;
497
    akmp = WPA_KEY_MGMT_OWE;
498
  }
499
#endif /* CONFIG_OWE */
500
501
0
  if (pmk_len == 0) {
502
0
    wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
503
0
    return -1;
504
0
  }
505
506
0
  if (z_len > MAX_Z_LEN)
507
0
    return -1;
508
509
0
  if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
510
0
    os_memcpy(data, addr1, ETH_ALEN);
511
0
    os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
512
0
  } else {
513
0
    os_memcpy(data, addr2, ETH_ALEN);
514
0
    os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
515
0
  }
516
517
0
  if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
518
0
    os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
519
0
    os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
520
0
        WPA_NONCE_LEN);
521
0
  } else {
522
0
    os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
523
0
    os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
524
0
        WPA_NONCE_LEN);
525
0
  }
526
527
0
  if (z && z_len) {
528
0
    os_memcpy(data + 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, z, z_len);
529
0
    data_len += z_len;
530
0
  }
531
532
0
  if (kdk_len > WPA_KDK_MAX_LEN) {
533
0
    wpa_printf(MSG_ERROR,
534
0
         "WPA: KDK len=%zu exceeds max supported len",
535
0
         kdk_len);
536
0
    return -1;
537
0
  }
538
539
0
  ptk->kck_len = wpa_kck_len(akmp, pmk_len);
540
0
  ptk->kek_len = wpa_kek_len(akmp, pmk_len);
541
0
  ptk->tk_len = wpa_cipher_key_len(cipher);
542
0
  ptk->kdk_len = kdk_len;
543
0
  if (ptk->tk_len == 0) {
544
0
    wpa_printf(MSG_ERROR,
545
0
         "WPA: Unsupported cipher (0x%x) used in PTK derivation",
546
0
         cipher);
547
0
    return -1;
548
0
  }
549
0
  ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
550
551
0
  if (wpa_key_mgmt_sha384(akmp)) {
552
0
#ifdef CONFIG_SHA384
553
0
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
554
0
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
555
0
             tmp, ptk_len) < 0)
556
0
      return -1;
557
#else /* CONFIG_SHA384 */
558
    return -1;
559
#endif /* CONFIG_SHA384 */
560
0
  } else if (wpa_key_mgmt_sha256(akmp)) {
561
0
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
562
0
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
563
0
             tmp, ptk_len) < 0)
564
0
      return -1;
565
#ifdef CONFIG_OWE
566
  } else if (akmp == WPA_KEY_MGMT_OWE && (pmk_len == 32 ||
567
            owe_ptk_workaround)) {
568
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
569
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
570
             tmp, ptk_len) < 0)
571
      return -1;
572
  } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 48) {
573
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
574
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
575
             tmp, ptk_len) < 0)
576
      return -1;
577
  } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 64) {
578
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
579
    if (sha512_prf(pmk, pmk_len, label, data, data_len,
580
             tmp, ptk_len) < 0)
581
      return -1;
582
  } else if (akmp == WPA_KEY_MGMT_OWE) {
583
    wpa_printf(MSG_INFO, "OWE: Unknown PMK length %u",
584
         (unsigned int) pmk_len);
585
    return -1;
586
#endif /* CONFIG_OWE */
587
#ifdef CONFIG_DPP
588
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
589
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
590
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
591
             tmp, ptk_len) < 0)
592
      return -1;
593
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
594
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
595
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
596
             tmp, ptk_len) < 0)
597
      return -1;
598
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
599
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
600
    if (sha512_prf(pmk, pmk_len, label, data, data_len,
601
             tmp, ptk_len) < 0)
602
      return -1;
603
  } else if (akmp == WPA_KEY_MGMT_DPP) {
604
    wpa_printf(MSG_INFO, "DPP: Unknown PMK length %u",
605
         (unsigned int) pmk_len);
606
    return -1;
607
#endif /* CONFIG_DPP */
608
0
#ifdef CONFIG_SAE
609
0
  } else if (wpa_key_mgmt_sae_ext_key(akmp)) {
610
0
    if (pmk_len == 32) {
611
0
      wpa_printf(MSG_DEBUG,
612
0
           "SAE: PTK derivation using PRF(SHA256)");
613
0
      if (sha256_prf(pmk, pmk_len, label, data, data_len,
614
0
               tmp, ptk_len) < 0)
615
0
        return -1;
616
0
#ifdef CONFIG_SHA384
617
0
    } else if (pmk_len == 48) {
618
0
      wpa_printf(MSG_DEBUG,
619
0
           "SAE: PTK derivation using PRF(SHA384)");
620
0
      if (sha384_prf(pmk, pmk_len, label, data, data_len,
621
0
               tmp, ptk_len) < 0)
622
0
        return -1;
623
0
#endif /* CONFIG_SHA384 */
624
#ifdef CONFIG_SHA512
625
    } else if (pmk_len == 64) {
626
      wpa_printf(MSG_DEBUG,
627
           "SAE: PTK derivation using PRF(SHA512)");
628
      if (sha512_prf(pmk, pmk_len, label, data, data_len,
629
               tmp, ptk_len) < 0)
630
        return -1;
631
#endif /* CONFIG_SHA512 */
632
0
    } else {
633
0
      wpa_printf(MSG_INFO, "SAE: Unknown PMK length %u",
634
0
           (unsigned int) pmk_len);
635
0
      return -1;
636
0
    }
637
0
#endif /* CONFIG_SAE */
638
0
  } else {
639
0
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
640
0
    if (sha1_prf(pmk, pmk_len, label, data, data_len, tmp,
641
0
           ptk_len) < 0)
642
0
      return -1;
643
0
  }
644
645
0
  wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
646
0
       MAC2STR(addr1), MAC2STR(addr2));
647
0
  wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
648
0
  wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
649
0
  if (z && z_len)
650
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: Z.x", z, z_len);
651
0
  wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
652
0
  wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
653
654
0
  os_memcpy(ptk->kck, tmp, ptk->kck_len);
655
0
  wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
656
657
0
  os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
658
0
  wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
659
660
0
  os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
661
0
  wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
662
663
0
  if (kdk_len) {
664
0
    os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
665
0
        ptk->tk_len, ptk->kdk_len);
666
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: KDK", ptk->kdk, ptk->kdk_len);
667
0
  }
668
669
0
  ptk->kek2_len = 0;
670
0
  ptk->kck2_len = 0;
671
672
0
  ptk->ptk_len = ptk_len;
673
0
  os_memset(tmp, 0, sizeof(tmp));
674
0
  os_memset(data, 0, data_len);
675
0
  return 0;
676
0
}
677
678
#ifdef CONFIG_FILS
679
680
int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
681
         const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
682
         size_t dh_ss_len, u8 *pmk, size_t *pmk_len)
683
0
{
684
0
  u8 nonces[2 * FILS_NONCE_LEN];
685
0
  const u8 *addr[2];
686
0
  size_t len[2];
687
0
  size_t num_elem;
688
0
  int res;
689
690
  /* PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ]) */
691
0
  wpa_printf(MSG_DEBUG, "FILS: rMSK to PMK derivation");
692
693
0
  if (wpa_key_mgmt_sha384(akmp))
694
0
    *pmk_len = SHA384_MAC_LEN;
695
0
  else if (wpa_key_mgmt_sha256(akmp))
696
0
    *pmk_len = SHA256_MAC_LEN;
697
0
  else
698
0
    return -1;
699
700
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: rMSK", rmsk, rmsk_len);
701
0
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
702
0
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
703
0
  wpa_hexdump(MSG_DEBUG, "FILS: DHss", dh_ss, dh_ss_len);
704
705
0
  os_memcpy(nonces, snonce, FILS_NONCE_LEN);
706
0
  os_memcpy(&nonces[FILS_NONCE_LEN], anonce, FILS_NONCE_LEN);
707
0
  addr[0] = rmsk;
708
0
  len[0] = rmsk_len;
709
0
  num_elem = 1;
710
0
  if (dh_ss) {
711
0
    addr[1] = dh_ss;
712
0
    len[1] = dh_ss_len;
713
0
    num_elem++;
714
0
  }
715
0
  if (wpa_key_mgmt_sha384(akmp))
716
0
    res = hmac_sha384_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
717
0
           addr, len, pmk);
718
0
  else
719
0
    res = hmac_sha256_vector(nonces, 2 * FILS_NONCE_LEN, num_elem,
720
0
           addr, len, pmk);
721
0
  if (res == 0)
722
0
    wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, *pmk_len);
723
0
  else
724
0
    *pmk_len = 0;
725
0
  return res;
726
0
}
727
728
729
int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
730
       u8 *pmkid)
731
0
{
732
0
  const u8 *addr[1];
733
0
  size_t len[1];
734
0
  u8 hash[SHA384_MAC_LEN];
735
0
  int res;
736
737
  /* PMKID = Truncate-128(Hash(EAP-Initiate/Reauth)) */
738
0
  addr[0] = reauth;
739
0
  len[0] = reauth_len;
740
0
  if (wpa_key_mgmt_sha384(akmp))
741
0
    res = sha384_vector(1, addr, len, hash);
742
0
  else if (wpa_key_mgmt_sha256(akmp))
743
0
    res = sha256_vector(1, addr, len, hash);
744
0
  else
745
0
    return -1;
746
0
  if (res)
747
0
    return res;
748
0
  os_memcpy(pmkid, hash, PMKID_LEN);
749
0
  wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
750
0
  return 0;
751
0
}
752
753
754
int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
755
        const u8 *snonce, const u8 *anonce, const u8 *dhss,
756
        size_t dhss_len, struct wpa_ptk *ptk,
757
        u8 *ick, size_t *ick_len, int akmp, int cipher,
758
        u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
759
0
{
760
0
  u8 *data, *pos;
761
0
  size_t data_len;
762
0
  u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
763
0
         FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
764
0
  size_t key_data_len;
765
0
  const char *label = "FILS PTK Derivation";
766
0
  int ret = -1;
767
0
  size_t offset;
768
769
  /*
770
   * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
771
   *                       SPA || AA || SNonce || ANonce [ || DHss ])
772
   * ICK = L(FILS-Key-Data, 0, ICK_bits)
773
   * KEK = L(FILS-Key-Data, ICK_bits, KEK_bits)
774
   * TK = L(FILS-Key-Data, ICK_bits + KEK_bits, TK_bits)
775
   * If doing FT initial mobility domain association:
776
   * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
777
   *             FILS-FT_bits)
778
   * When a KDK is derived:
779
   * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
780
   *     KDK_bits)
781
   */
782
0
  data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
783
0
  data = os_malloc(data_len);
784
0
  if (!data)
785
0
    goto err;
786
0
  pos = data;
787
0
  os_memcpy(pos, spa, ETH_ALEN);
788
0
  pos += ETH_ALEN;
789
0
  os_memcpy(pos, aa, ETH_ALEN);
790
0
  pos += ETH_ALEN;
791
0
  os_memcpy(pos, snonce, FILS_NONCE_LEN);
792
0
  pos += FILS_NONCE_LEN;
793
0
  os_memcpy(pos, anonce, FILS_NONCE_LEN);
794
0
  pos += FILS_NONCE_LEN;
795
0
  if (dhss)
796
0
    os_memcpy(pos, dhss, dhss_len);
797
798
0
  ptk->kck_len = 0;
799
0
  ptk->kek_len = wpa_kek_len(akmp, pmk_len);
800
0
  ptk->tk_len = wpa_cipher_key_len(cipher);
801
0
  if (wpa_key_mgmt_sha384(akmp))
802
0
    *ick_len = 48;
803
0
  else if (wpa_key_mgmt_sha256(akmp))
804
0
    *ick_len = 32;
805
0
  else
806
0
    goto err;
807
0
  key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
808
809
0
  if (kdk_len) {
810
0
    if (kdk_len > WPA_KDK_MAX_LEN) {
811
0
      wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
812
0
           kdk_len);
813
0
      goto err;
814
0
    }
815
816
0
    ptk->kdk_len = kdk_len;
817
0
    key_data_len += kdk_len;
818
0
  } else {
819
0
    ptk->kdk_len = 0;
820
0
  }
821
822
0
  if (fils_ft && fils_ft_len) {
823
0
    if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
824
0
      *fils_ft_len = 32;
825
0
    } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
826
0
      *fils_ft_len = 48;
827
0
    } else {
828
0
      *fils_ft_len = 0;
829
0
      fils_ft = NULL;
830
0
    }
831
0
    key_data_len += *fils_ft_len;
832
0
  }
833
834
0
  if (wpa_key_mgmt_sha384(akmp)) {
835
0
    wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
836
0
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
837
0
             tmp, key_data_len) < 0)
838
0
      goto err;
839
0
  } else {
840
0
    wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA256)");
841
0
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
842
0
             tmp, key_data_len) < 0)
843
0
      goto err;
844
0
  }
845
846
0
  wpa_printf(MSG_DEBUG, "FILS: PTK derivation - SPA=" MACSTR
847
0
       " AA=" MACSTR, MAC2STR(spa), MAC2STR(aa));
848
0
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
849
0
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
850
0
  if (dhss)
851
0
    wpa_hexdump_key(MSG_DEBUG, "FILS: DHss", dhss, dhss_len);
852
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, pmk_len);
853
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
854
855
0
  os_memcpy(ick, tmp, *ick_len);
856
0
  offset = *ick_len;
857
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
858
859
0
  os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
860
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
861
0
  offset += ptk->kek_len;
862
863
0
  os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
864
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
865
0
  offset += ptk->tk_len;
866
867
0
  if (fils_ft && fils_ft_len) {
868
0
    os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
869
0
    wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
870
0
        fils_ft, *fils_ft_len);
871
0
    offset += *fils_ft_len;
872
0
  }
873
874
0
  if (ptk->kdk_len) {
875
0
    os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
876
0
    wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
877
0
  }
878
879
0
  ptk->kek2_len = 0;
880
0
  ptk->kck2_len = 0;
881
882
0
  os_memset(tmp, 0, sizeof(tmp));
883
0
  ret = 0;
884
0
err:
885
0
  bin_clear_free(data, data_len);
886
0
  return ret;
887
0
}
888
889
890
int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
891
         const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
892
         const u8 *g_sta, size_t g_sta_len,
893
         const u8 *g_ap, size_t g_ap_len,
894
         int akmp, u8 *key_auth_sta, u8 *key_auth_ap,
895
         size_t *key_auth_len)
896
0
{
897
0
  const u8 *addr[6];
898
0
  size_t len[6];
899
0
  size_t num_elem = 4;
900
0
  int res;
901
902
0
  wpa_printf(MSG_DEBUG, "FILS: Key-Auth derivation: STA-MAC=" MACSTR
903
0
       " AP-BSSID=" MACSTR, MAC2STR(sta_addr), MAC2STR(bssid));
904
0
  wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, ick_len);
905
0
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, FILS_NONCE_LEN);
906
0
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, FILS_NONCE_LEN);
907
0
  wpa_hexdump(MSG_DEBUG, "FILS: gSTA", g_sta, g_sta_len);
908
0
  wpa_hexdump(MSG_DEBUG, "FILS: gAP", g_ap, g_ap_len);
909
910
  /*
911
   * For (Re)Association Request frame (STA->AP):
912
   * Key-Auth = HMAC-Hash(ICK, SNonce || ANonce || STA-MAC || AP-BSSID
913
   *                      [ || gSTA || gAP ])
914
   */
915
0
  addr[0] = snonce;
916
0
  len[0] = FILS_NONCE_LEN;
917
0
  addr[1] = anonce;
918
0
  len[1] = FILS_NONCE_LEN;
919
0
  addr[2] = sta_addr;
920
0
  len[2] = ETH_ALEN;
921
0
  addr[3] = bssid;
922
0
  len[3] = ETH_ALEN;
923
0
  if (g_sta && g_sta_len && g_ap && g_ap_len) {
924
0
    addr[4] = g_sta;
925
0
    len[4] = g_sta_len;
926
0
    addr[5] = g_ap;
927
0
    len[5] = g_ap_len;
928
0
    num_elem = 6;
929
0
  }
930
931
0
  if (wpa_key_mgmt_sha384(akmp)) {
932
0
    *key_auth_len = 48;
933
0
    res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
934
0
           key_auth_sta);
935
0
  } else if (wpa_key_mgmt_sha256(akmp)) {
936
0
    *key_auth_len = 32;
937
0
    res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
938
0
           key_auth_sta);
939
0
  } else {
940
0
    return -1;
941
0
  }
942
0
  if (res < 0)
943
0
    return res;
944
945
  /*
946
   * For (Re)Association Response frame (AP->STA):
947
   * Key-Auth = HMAC-Hash(ICK, ANonce || SNonce || AP-BSSID || STA-MAC
948
   *                      [ || gAP || gSTA ])
949
   */
950
0
  addr[0] = anonce;
951
0
  addr[1] = snonce;
952
0
  addr[2] = bssid;
953
0
  addr[3] = sta_addr;
954
0
  if (g_sta && g_sta_len && g_ap && g_ap_len) {
955
0
    addr[4] = g_ap;
956
0
    len[4] = g_ap_len;
957
0
    addr[5] = g_sta;
958
0
    len[5] = g_sta_len;
959
0
  }
960
961
0
  if (wpa_key_mgmt_sha384(akmp))
962
0
    res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
963
0
           key_auth_ap);
964
0
  else if (wpa_key_mgmt_sha256(akmp))
965
0
    res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
966
0
           key_auth_ap);
967
0
  if (res < 0)
968
0
    return res;
969
970
0
  wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (STA)",
971
0
        key_auth_sta, *key_auth_len);
972
0
  wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (AP)",
973
0
        key_auth_ap, *key_auth_len);
974
975
0
  return 0;
976
0
}
977
978
#endif /* CONFIG_FILS */
979
980
981
#ifdef CONFIG_IEEE80211R
982
int wpa_ft_mic(int key_mgmt, const u8 *kck, size_t kck_len, const u8 *sta_addr,
983
         const u8 *ap_addr, u8 transaction_seqnum,
984
         const u8 *mdie, size_t mdie_len,
985
         const u8 *ftie, size_t ftie_len,
986
         const u8 *rsnie, size_t rsnie_len,
987
         const u8 *ric, size_t ric_len,
988
         const u8 *rsnxe, size_t rsnxe_len,
989
         const struct wpabuf *extra,
990
         u8 *mic)
991
0
{
992
0
  const u8 *addr[11];
993
0
  size_t len[11];
994
0
  size_t i, num_elem = 0;
995
0
  u8 zero_mic[32];
996
0
  size_t mic_len, fte_fixed_len;
997
0
  int res;
998
999
0
  if (kck_len == 16) {
1000
0
    mic_len = 16;
1001
0
#ifdef CONFIG_SHA384
1002
0
  } else if (kck_len == 24) {
1003
0
    mic_len = 24;
1004
0
#endif /* CONFIG_SHA384 */
1005
#ifdef CONFIG_SHA512
1006
  } else if (kck_len == 32) {
1007
    mic_len = 32;
1008
#endif /* CONFIG_SHA512 */
1009
0
  } else {
1010
0
    wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
1011
0
         (unsigned int) kck_len);
1012
0
    return -1;
1013
0
  }
1014
1015
0
  fte_fixed_len = sizeof(struct rsn_ftie) - 16 + mic_len;
1016
1017
0
  addr[num_elem] = sta_addr;
1018
0
  len[num_elem] = ETH_ALEN;
1019
0
  num_elem++;
1020
1021
0
  addr[num_elem] = ap_addr;
1022
0
  len[num_elem] = ETH_ALEN;
1023
0
  num_elem++;
1024
1025
0
  addr[num_elem] = &transaction_seqnum;
1026
0
  len[num_elem] = 1;
1027
0
  num_elem++;
1028
1029
0
  if (rsnie) {
1030
0
    addr[num_elem] = rsnie;
1031
0
    len[num_elem] = rsnie_len;
1032
0
    num_elem++;
1033
0
  }
1034
0
  if (mdie) {
1035
0
    addr[num_elem] = mdie;
1036
0
    len[num_elem] = mdie_len;
1037
0
    num_elem++;
1038
0
  }
1039
0
  if (ftie) {
1040
0
    if (ftie_len < 2 + fte_fixed_len)
1041
0
      return -1;
1042
1043
    /* IE hdr and mic_control */
1044
0
    addr[num_elem] = ftie;
1045
0
    len[num_elem] = 2 + 2;
1046
0
    num_elem++;
1047
1048
    /* MIC field with all zeros */
1049
0
    os_memset(zero_mic, 0, mic_len);
1050
0
    addr[num_elem] = zero_mic;
1051
0
    len[num_elem] = mic_len;
1052
0
    num_elem++;
1053
1054
    /* Rest of FTIE */
1055
0
    addr[num_elem] = ftie + 2 + 2 + mic_len;
1056
0
    len[num_elem] = ftie_len - (2 + 2 + mic_len);
1057
0
    num_elem++;
1058
0
  }
1059
0
  if (ric) {
1060
0
    addr[num_elem] = ric;
1061
0
    len[num_elem] = ric_len;
1062
0
    num_elem++;
1063
0
  }
1064
1065
0
  if (rsnxe) {
1066
0
    addr[num_elem] = rsnxe;
1067
0
    len[num_elem] = rsnxe_len;
1068
0
    num_elem++;
1069
0
  }
1070
1071
0
  if (extra) {
1072
0
    addr[num_elem] = wpabuf_head(extra);
1073
0
    len[num_elem] = wpabuf_len(extra);
1074
0
    num_elem++;
1075
0
  }
1076
1077
0
  for (i = 0; i < num_elem; i++)
1078
0
    wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
1079
0
  res = -1;
1080
#ifdef CONFIG_SHA512
1081
  if (kck_len == 32) {
1082
    u8 hash[SHA512_MAC_LEN];
1083
1084
    if (hmac_sha512_vector(kck, kck_len, num_elem, addr, len, hash))
1085
      return -1;
1086
    os_memcpy(mic, hash, 32);
1087
    res = 0;
1088
  }
1089
#endif /* CONFIG_SHA384 */
1090
0
#ifdef CONFIG_SHA384
1091
0
  if (kck_len == 24) {
1092
0
    u8 hash[SHA384_MAC_LEN];
1093
1094
0
    if (hmac_sha384_vector(kck, kck_len, num_elem, addr, len, hash))
1095
0
      return -1;
1096
0
    os_memcpy(mic, hash, 24);
1097
0
    res = 0;
1098
0
  }
1099
0
#endif /* CONFIG_SHA384 */
1100
0
  if (kck_len == 16 && key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1101
0
    u8 hash[SHA256_MAC_LEN];
1102
1103
0
    if (hmac_sha256_vector(kck, kck_len, num_elem, addr, len, hash))
1104
0
      return -1;
1105
0
    os_memcpy(mic, hash, 16);
1106
0
    res = 0;
1107
0
  }
1108
0
  if (kck_len == 16 && key_mgmt != WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
1109
0
      omac1_aes_128_vector(kck, num_elem, addr, len, mic) == 0)
1110
0
    res = 0;
1111
1112
0
  return res;
1113
0
}
1114
1115
1116
static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
1117
           struct wpa_ft_ies *parse, const u8 *opt)
1118
0
{
1119
0
  const u8 *end, *pos;
1120
0
  u8 link_id;
1121
1122
0
  pos = opt;
1123
0
  end = ie + ie_len;
1124
0
  wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos);
1125
1126
0
  while (end - pos >= 2) {
1127
0
    u8 id, len;
1128
1129
0
    id = *pos++;
1130
0
    len = *pos++;
1131
0
    if (len > end - pos) {
1132
0
      wpa_printf(MSG_DEBUG, "FT: Truncated subelement");
1133
0
      return -1;
1134
0
    }
1135
1136
0
    switch (id) {
1137
0
    case FTIE_SUBELEM_R1KH_ID:
1138
0
      if (len != FT_R1KH_ID_LEN) {
1139
0
        wpa_printf(MSG_DEBUG,
1140
0
             "FT: Invalid R1KH-ID length in FTIE: %d",
1141
0
             len);
1142
0
        return -1;
1143
0
      }
1144
0
      parse->r1kh_id = pos;
1145
0
      wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID",
1146
0
            parse->r1kh_id, FT_R1KH_ID_LEN);
1147
0
      break;
1148
0
    case FTIE_SUBELEM_GTK:
1149
0
      wpa_printf(MSG_DEBUG, "FT: GTK");
1150
0
      parse->gtk = pos;
1151
0
      parse->gtk_len = len;
1152
0
      break;
1153
0
    case FTIE_SUBELEM_R0KH_ID:
1154
0
      if (len < 1 || len > FT_R0KH_ID_MAX_LEN) {
1155
0
        wpa_printf(MSG_DEBUG,
1156
0
             "FT: Invalid R0KH-ID length in FTIE: %d",
1157
0
             len);
1158
0
        return -1;
1159
0
      }
1160
0
      parse->r0kh_id = pos;
1161
0
      parse->r0kh_id_len = len;
1162
0
      wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
1163
0
            parse->r0kh_id, parse->r0kh_id_len);
1164
0
      break;
1165
0
    case FTIE_SUBELEM_IGTK:
1166
0
      wpa_printf(MSG_DEBUG, "FT: IGTK");
1167
0
      parse->igtk = pos;
1168
0
      parse->igtk_len = len;
1169
0
      break;
1170
#ifdef CONFIG_OCV
1171
    case FTIE_SUBELEM_OCI:
1172
      parse->oci = pos;
1173
      parse->oci_len = len;
1174
      wpa_hexdump(MSG_DEBUG, "FT: OCI",
1175
            parse->oci, parse->oci_len);
1176
      break;
1177
#endif /* CONFIG_OCV */
1178
0
    case FTIE_SUBELEM_BIGTK:
1179
0
      wpa_printf(MSG_DEBUG, "FT: BIGTK");
1180
0
      parse->bigtk = pos;
1181
0
      parse->bigtk_len = len;
1182
0
      break;
1183
0
    case FTIE_SUBELEM_MLO_GTK:
1184
0
      if (len < 2 + 1 + 1 + 8) {
1185
0
        wpa_printf(MSG_DEBUG,
1186
0
             "FT: Too short MLO GTK in FTE");
1187
0
        return -1;
1188
0
      }
1189
0
      link_id = pos[2] & 0x0f;
1190
0
      wpa_printf(MSG_DEBUG, "FT: MLO GTK (Link ID %u)",
1191
0
           link_id);
1192
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1193
0
        break;
1194
0
      parse->valid_mlo_gtks |= BIT(link_id);
1195
0
      parse->mlo_gtk[link_id] = pos;
1196
0
      parse->mlo_gtk_len[link_id] = len;
1197
0
      break;
1198
0
    case FTIE_SUBELEM_MLO_IGTK:
1199
0
      if (len < 2 + 6 + 1 + 1) {
1200
0
        wpa_printf(MSG_DEBUG,
1201
0
             "FT: Too short MLO IGTK in FTE");
1202
0
        return -1;
1203
0
      }
1204
0
      link_id = pos[2 + 6] & 0x0f;
1205
0
      wpa_printf(MSG_DEBUG, "FT: MLO IGTK (Link ID %u)",
1206
0
           link_id);
1207
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1208
0
        break;
1209
0
      parse->valid_mlo_igtks |= BIT(link_id);
1210
0
      parse->mlo_igtk[link_id] = pos;
1211
0
      parse->mlo_igtk_len[link_id] = len;
1212
0
      break;
1213
0
    case FTIE_SUBELEM_MLO_BIGTK:
1214
0
      if (len < 2 + 6 + 1 + 1) {
1215
0
        wpa_printf(MSG_DEBUG,
1216
0
             "FT: Too short MLO BIGTK in FTE");
1217
0
        return -1;
1218
0
      }
1219
0
      link_id = pos[2 + 6] & 0x0f;
1220
0
      wpa_printf(MSG_DEBUG, "FT: MLO BIGTK (Link ID %u)",
1221
0
           link_id);
1222
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1223
0
        break;
1224
0
      parse->valid_mlo_bigtks |= BIT(link_id);
1225
0
      parse->mlo_bigtk[link_id] = pos;
1226
0
      parse->mlo_bigtk_len[link_id] = len;
1227
0
      break;
1228
0
    default:
1229
0
      wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id);
1230
0
      break;
1231
0
    }
1232
1233
0
    pos += len;
1234
0
  }
1235
1236
0
  return 0;
1237
0
}
1238
1239
1240
static int wpa_ft_parse_fte(int key_mgmt, const u8 *ie, size_t len,
1241
          struct wpa_ft_ies *parse)
1242
0
{
1243
0
  size_t mic_len;
1244
0
  u8 mic_len_info;
1245
0
  const u8 *pos = ie;
1246
0
  const u8 *end = pos + len;
1247
1248
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC Control", pos, 2);
1249
0
  parse->fte_rsnxe_used = pos[0] & FTE_MIC_CTRL_RSNXE_USED;
1250
0
  mic_len_info = (pos[0] & FTE_MIC_CTRL_MIC_LEN_MASK) >>
1251
0
    FTE_MIC_CTRL_MIC_LEN_SHIFT;
1252
0
  parse->fte_elem_count = pos[1];
1253
0
  pos += 2;
1254
1255
0
  if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1256
0
    switch (mic_len_info) {
1257
0
    case FTE_MIC_LEN_16:
1258
0
      mic_len = 16;
1259
0
      break;
1260
0
    case FTE_MIC_LEN_24:
1261
0
      mic_len = 24;
1262
0
      break;
1263
0
    case FTE_MIC_LEN_32:
1264
0
      mic_len = 32;
1265
0
      break;
1266
0
    default:
1267
0
      wpa_printf(MSG_DEBUG,
1268
0
           "FT: Unknown MIC Length subfield value %u",
1269
0
           mic_len_info);
1270
0
      return -1;
1271
0
    }
1272
0
  } else {
1273
0
    mic_len = wpa_key_mgmt_sha384(key_mgmt) ? 24 : 16;
1274
0
  }
1275
0
  if (mic_len > (size_t) (end - pos)) {
1276
0
    wpa_printf(MSG_DEBUG, "FT: No room for %zu octet MIC in FTE",
1277
0
         mic_len);
1278
0
    return -1;
1279
0
  }
1280
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC", pos, mic_len);
1281
0
  parse->fte_mic = pos;
1282
0
  parse->fte_mic_len = mic_len;
1283
0
  pos += mic_len;
1284
1285
0
  if (2 * WPA_NONCE_LEN > end - pos)
1286
0
    return -1;
1287
0
  parse->fte_anonce = pos;
1288
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-ANonce",
1289
0
        parse->fte_anonce, WPA_NONCE_LEN);
1290
0
  pos += WPA_NONCE_LEN;
1291
0
  parse->fte_snonce = pos;
1292
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-SNonce",
1293
0
        parse->fte_snonce, WPA_NONCE_LEN);
1294
0
  pos += WPA_NONCE_LEN;
1295
1296
0
  return wpa_ft_parse_ftie(ie, len, parse, pos);
1297
0
}
1298
1299
1300
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
1301
         int key_mgmt, bool reassoc_resp)
1302
0
{
1303
0
  const u8 *end, *pos;
1304
0
  struct wpa_ie_data data;
1305
0
  int ret;
1306
0
  int prot_ie_count = 0;
1307
0
  const u8 *fte = NULL;
1308
0
  size_t fte_len = 0;
1309
0
  bool is_fte = false;
1310
0
  struct ieee802_11_elems elems;
1311
1312
0
  os_memset(parse, 0, sizeof(*parse));
1313
0
  if (ies == NULL)
1314
0
    return 0;
1315
1316
0
  if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
1317
0
    wpa_printf(MSG_DEBUG, "FT: Failed to parse elements");
1318
0
    goto fail;
1319
0
  }
1320
1321
0
  pos = ies;
1322
0
  end = ies + ies_len;
1323
0
  while (end - pos >= 2) {
1324
0
    u8 id, len;
1325
1326
0
    id = *pos++;
1327
0
    len = *pos++;
1328
0
    if (len > end - pos)
1329
0
      break;
1330
1331
0
    if (id != WLAN_EID_FAST_BSS_TRANSITION &&
1332
0
        id != WLAN_EID_FRAGMENT)
1333
0
      is_fte = false;
1334
1335
0
    switch (id) {
1336
0
    case WLAN_EID_RSN:
1337
0
      wpa_hexdump(MSG_DEBUG, "FT: RSNE", pos, len);
1338
0
      parse->rsn = pos;
1339
0
      parse->rsn_len = len;
1340
0
      ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
1341
0
               parse->rsn_len + 2,
1342
0
               &data);
1343
0
      if (ret < 0) {
1344
0
        wpa_printf(MSG_DEBUG, "FT: Failed to parse "
1345
0
             "RSN IE: %d", ret);
1346
0
        goto fail;
1347
0
      }
1348
0
      parse->rsn_capab = data.capabilities;
1349
0
      if (data.num_pmkid == 1 && data.pmkid)
1350
0
        parse->rsn_pmkid = data.pmkid;
1351
0
      parse->key_mgmt = data.key_mgmt;
1352
0
      parse->pairwise_cipher = data.pairwise_cipher;
1353
0
      if (!key_mgmt)
1354
0
        key_mgmt = parse->key_mgmt;
1355
0
      break;
1356
0
    case WLAN_EID_RSNX:
1357
0
      wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len);
1358
0
      if (len < 1)
1359
0
        break;
1360
0
      parse->rsnxe = pos;
1361
0
      parse->rsnxe_len = len;
1362
0
      break;
1363
0
    case WLAN_EID_MOBILITY_DOMAIN:
1364
0
      wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len);
1365
0
      if (len < sizeof(struct rsn_mdie))
1366
0
        goto fail;
1367
0
      parse->mdie = pos;
1368
0
      parse->mdie_len = len;
1369
0
      break;
1370
0
    case WLAN_EID_FAST_BSS_TRANSITION:
1371
0
      wpa_hexdump(MSG_DEBUG, "FT: FTE", pos, len);
1372
      /* The first two octets (MIC Control field) is in the
1373
       * same offset for all cases, but the second field (MIC)
1374
       * has variable length with three different values.
1375
       * In particular the FT-SAE-EXT-KEY is inconvinient to
1376
       * parse, so try to handle this in pieces instead of
1377
       * using the struct rsn_ftie* definitions. */
1378
1379
0
      if (len < 2)
1380
0
        goto fail;
1381
0
      prot_ie_count = pos[1]; /* Element Count field in
1382
             * MIC Control */
1383
0
      is_fte = true;
1384
0
      fte = pos;
1385
0
      fte_len = len;
1386
0
      break;
1387
0
    case WLAN_EID_FRAGMENT:
1388
0
      if (is_fte) {
1389
0
        wpa_hexdump(MSG_DEBUG, "FT: FTE fragment",
1390
0
              pos, len);
1391
0
        fte_len += 2 + len;
1392
0
      }
1393
0
      break;
1394
0
    case WLAN_EID_TIMEOUT_INTERVAL:
1395
0
      wpa_hexdump(MSG_DEBUG, "FT: Timeout Interval",
1396
0
            pos, len);
1397
0
      if (len != 5)
1398
0
        break;
1399
0
      parse->tie = pos;
1400
0
      parse->tie_len = len;
1401
0
      break;
1402
0
    case WLAN_EID_RIC_DATA:
1403
0
      if (parse->ric == NULL)
1404
0
        parse->ric = pos - 2;
1405
0
      break;
1406
0
    }
1407
1408
0
    pos += len;
1409
0
  }
1410
1411
0
  if (fte) {
1412
0
    int res;
1413
1414
0
    if (fte_len < 255) {
1415
0
      res = wpa_ft_parse_fte(key_mgmt, fte, fte_len, parse);
1416
0
    } else {
1417
0
      parse->fte_buf = ieee802_11_defrag(fte, fte_len, false);
1418
0
      if (!parse->fte_buf)
1419
0
        goto fail;
1420
0
      res = wpa_ft_parse_fte(key_mgmt,
1421
0
                 wpabuf_head(parse->fte_buf),
1422
0
                 wpabuf_len(parse->fte_buf),
1423
0
                 parse);
1424
0
    }
1425
0
    if (res < 0)
1426
0
      goto fail;
1427
1428
    /* FTE might be fragmented. If it is, the separate Fragment
1429
     * elements are included in MIC calculation as full elements. */
1430
0
    parse->ftie = fte;
1431
0
    parse->ftie_len = fte_len;
1432
0
  }
1433
1434
0
  if (prot_ie_count == 0)
1435
0
    return 0; /* no MIC */
1436
1437
  /*
1438
   * Check that the protected IE count matches with IEs included in the
1439
   * frame.
1440
   */
1441
0
  if (reassoc_resp && elems.basic_mle) {
1442
0
    unsigned int link_id;
1443
1444
    /* TODO: This count should be done based on all _requested_,
1445
     * not _accepted_ links. */
1446
0
    for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
1447
0
      if (parse->mlo_gtk[link_id]) {
1448
0
        if (parse->rsn)
1449
0
          prot_ie_count--;
1450
0
        if (parse->rsnxe)
1451
0
          prot_ie_count--;
1452
0
      }
1453
0
    }
1454
0
  } else {
1455
0
    if (parse->rsn)
1456
0
      prot_ie_count--;
1457
0
    if (parse->rsnxe)
1458
0
      prot_ie_count--;
1459
0
  }
1460
0
  if (parse->mdie)
1461
0
    prot_ie_count--;
1462
0
  if (parse->ftie)
1463
0
    prot_ie_count--;
1464
0
  if (prot_ie_count < 0) {
1465
0
    wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
1466
0
         "the protected IE count");
1467
0
    goto fail;
1468
0
  }
1469
1470
0
  if (prot_ie_count == 0 && parse->ric) {
1471
0
    wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
1472
0
         "included in protected IE count");
1473
0
    goto fail;
1474
0
  }
1475
1476
  /* Determine the end of the RIC IE(s) */
1477
0
  if (parse->ric) {
1478
0
    pos = parse->ric;
1479
0
    while (end - pos >= 2 && 2 + pos[1] <= end - pos &&
1480
0
           prot_ie_count) {
1481
0
      prot_ie_count--;
1482
0
      pos += 2 + pos[1];
1483
0
    }
1484
0
    parse->ric_len = pos - parse->ric;
1485
0
  }
1486
0
  if (prot_ie_count) {
1487
0
    wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
1488
0
         "frame", (int) prot_ie_count);
1489
0
    goto fail;
1490
0
  }
1491
1492
0
  return 0;
1493
1494
0
fail:
1495
0
  wpa_ft_parse_ies_free(parse);
1496
0
  return -1;
1497
0
}
1498
1499
1500
void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse)
1501
0
{
1502
0
  if (!parse)
1503
0
    return;
1504
0
  wpabuf_free(parse->fte_buf);
1505
0
  parse->fte_buf = NULL;
1506
0
}
1507
1508
#endif /* CONFIG_IEEE80211R */
1509
1510
1511
#ifdef CONFIG_PASN
1512
1513
/*
1514
 * pasn_use_sha384 - Should SHA384 be used or SHA256
1515
 *
1516
 * @akmp: Authentication and key management protocol
1517
 * @cipher: The cipher suite
1518
 *
1519
 * According to IEEE Std 802.11-2024, 12.13.8 (PTKSA derivation with PASN
1520
 * authentication), the hash algorithm to use is the
1521
 * hash algorithm defined for the Base AKM (see Table 9-190 (AKM suite
1522
 * selectors)). When there is no Base AKM, the hash algorithm is selected based
1523
 * on the pairwise cipher suite provided in the RSNE by the AP in the second
1524
 * PASN frame. SHA-256 is used as the hash algorithm, except for the ciphers
1525
 * 00-0F-AC:9 and 00-0F-AC:10 for which SHA-384 is used.
1526
 */
1527
bool pasn_use_sha384(int akmp, int cipher)
1528
3.19k
{
1529
3.19k
  return (akmp == WPA_KEY_MGMT_PASN && (cipher == WPA_CIPHER_CCMP_256 ||
1530
114
                cipher == WPA_CIPHER_GCMP_256)) ||
1531
3.19k
    wpa_key_mgmt_sha384(akmp);
1532
3.19k
}
1533
1534
1535
/**
1536
 * pasn_pmk_to_ptk - Calculate PASN PTK from PMK, addresses, etc.
1537
 * @pmk: Pairwise master key
1538
 * @pmk_len: Length of PMK
1539
 * @spa: Suppplicant address
1540
 * @bssid: AP BSSID
1541
 * @dhss: Is the shared secret (DHss) derived from the PASN ephemeral key
1542
 *  exchange encoded as an octet string
1543
 * @dhss_len: The length of dhss in octets
1544
 * @ptk: Buffer for pairwise transient key
1545
 * @akmp: Negotiated AKM
1546
 * @cipher: Negotiated pairwise cipher
1547
 * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
1548
 * @kek_len: The length in octets that should be derived for KEK. Can be zero.
1549
 * Returns: 0 on success, -1 on failure
1550
 */
1551
int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
1552
        const u8 *spa, const u8 *bssid,
1553
        const u8 *dhss, size_t dhss_len,
1554
        struct wpa_ptk *ptk, int akmp, int cipher,
1555
        size_t kdk_len, size_t kek_len)
1556
0
{
1557
0
  u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
1558
0
         WPA_KDK_MAX_LEN];
1559
0
  const u8 *pos;
1560
0
  u8 *data;
1561
0
  size_t data_len, ptk_len;
1562
0
  int ret = -1;
1563
0
  const char *label = "PASN PTK Derivation";
1564
1565
0
  if (!pmk || !pmk_len) {
1566
0
    wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
1567
0
    return -1;
1568
0
  }
1569
1570
0
  if (!dhss || !dhss_len) {
1571
0
    wpa_printf(MSG_ERROR, "PASN: No DHss set for PTK derivation");
1572
0
    return -1;
1573
0
  }
1574
1575
  /*
1576
   * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
1577
   *
1578
   * KCK = L(PASN-PTK, 0, 256)
1579
   * TK = L(PASN-PTK, 256, TK_bits)
1580
   * KDK = L(PASN-PTK, 256 + TK_bits, kdk_len * 8)
1581
   */
1582
0
  data_len = 2 * ETH_ALEN + dhss_len;
1583
0
  data = os_zalloc(data_len);
1584
0
  if (!data)
1585
0
    return -1;
1586
1587
0
  os_memcpy(data, spa, ETH_ALEN);
1588
0
  os_memcpy(data + ETH_ALEN, bssid, ETH_ALEN);
1589
0
  os_memcpy(data + 2 * ETH_ALEN, dhss, dhss_len);
1590
1591
0
  ptk->kck_len = WPA_PASN_KCK_LEN;
1592
0
  ptk->tk_len = wpa_cipher_key_len(cipher);
1593
0
  ptk->kdk_len = kdk_len;
1594
0
  ptk->kek_len = kek_len;
1595
0
  ptk->kek2_len = 0;
1596
0
  ptk->kck2_len = 0;
1597
1598
0
  if (ptk->tk_len == 0) {
1599
0
    wpa_printf(MSG_ERROR,
1600
0
         "PASN: Unsupported cipher (0x%x) used in PTK derivation",
1601
0
         cipher);
1602
0
    goto err;
1603
0
  }
1604
1605
0
  ptk_len = ptk->kck_len + ptk->tk_len + ptk->kdk_len + ptk->kek_len;
1606
0
  if (ptk_len > sizeof(tmp))
1607
0
    goto err;
1608
1609
0
  if (pasn_use_sha384(akmp, cipher)) {
1610
0
    wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA384");
1611
1612
0
    if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp,
1613
0
             ptk_len) < 0)
1614
0
      goto err;
1615
0
  } else {
1616
0
    wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA256");
1617
1618
0
    if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp,
1619
0
             ptk_len) < 0)
1620
0
      goto err;
1621
0
  }
1622
1623
0
  wpa_printf(MSG_DEBUG,
1624
0
       "PASN: PTK derivation: SPA=" MACSTR " BSSID=" MACSTR,
1625
0
       MAC2STR(spa), MAC2STR(bssid));
1626
1627
0
  wpa_hexdump_key(MSG_DEBUG, "PASN: DHss", dhss, dhss_len);
1628
0
  wpa_hexdump_key(MSG_DEBUG, "PASN: PMK", pmk, pmk_len);
1629
0
  wpa_hexdump_key(MSG_DEBUG, "PASN: PASN-PTK", tmp, ptk_len);
1630
1631
0
  os_memcpy(ptk->kck, tmp, WPA_PASN_KCK_LEN);
1632
0
  wpa_hexdump_key(MSG_DEBUG, "PASN: KCK:", ptk->kck, WPA_PASN_KCK_LEN);
1633
0
  pos = &tmp[WPA_PASN_KCK_LEN];
1634
1635
0
  if (kek_len) {
1636
0
    os_memcpy(ptk->kek, pos, kek_len);
1637
0
    wpa_hexdump_key(MSG_DEBUG, "PASN: KEK:",
1638
0
        ptk->kek, ptk->kek_len);
1639
0
    pos += kek_len;
1640
0
  }
1641
1642
0
  os_memcpy(ptk->tk, pos, ptk->tk_len);
1643
0
  wpa_hexdump_key(MSG_DEBUG, "PASN: TK:", ptk->tk, ptk->tk_len);
1644
0
  pos += ptk->tk_len;
1645
1646
0
  if (kdk_len) {
1647
0
    os_memcpy(ptk->kdk, pos, ptk->kdk_len);
1648
0
    wpa_hexdump_key(MSG_DEBUG, "PASN: KDK:",
1649
0
        ptk->kdk, ptk->kdk_len);
1650
0
  }
1651
1652
0
  ptk->ptk_len = ptk_len;
1653
0
  forced_memzero(tmp, sizeof(tmp));
1654
0
  ret = 0;
1655
0
err:
1656
0
  bin_clear_free(data, data_len);
1657
0
  return ret;
1658
0
}
1659
1660
1661
/*
1662
 * pasn_mic_len - Returns the MIC length for PASN authentication
1663
 */
1664
u8 pasn_mic_len(int akmp, int cipher)
1665
2.62k
{
1666
2.62k
  if (pasn_use_sha384(akmp, cipher))
1667
0
    return 24;
1668
1669
2.62k
  return 16;
1670
2.62k
}
1671
1672
1673
/**
1674
 * wpa_ltf_keyseed - Compute LTF keyseed from KDK
1675
 * @ptk: Buffer that holds pairwise transient key
1676
 * @akmp: Negotiated AKM
1677
 * @cipher: Negotiated pairwise cipher
1678
 * Returns: 0 on success, -1 on failure
1679
 */
1680
int wpa_ltf_keyseed(struct wpa_ptk *ptk, int akmp, int cipher)
1681
0
{
1682
0
  u8 *buf;
1683
0
  size_t buf_len;
1684
0
  u8 hash[SHA384_MAC_LEN];
1685
0
  const u8 *kdk = ptk->kdk;
1686
0
  size_t kdk_len = ptk->kdk_len;
1687
0
  const char *label = "Secure LTF key seed";
1688
1689
0
  if (!kdk || !kdk_len) {
1690
0
    wpa_printf(MSG_ERROR, "WPA: No KDK for LTF keyseed generation");
1691
0
    return -1;
1692
0
  }
1693
1694
0
  buf = (u8 *)label;
1695
0
  buf_len = os_strlen(label);
1696
1697
0
  if (pasn_use_sha384(akmp, cipher)) {
1698
0
    wpa_printf(MSG_DEBUG,
1699
0
         "WPA: Secure LTF keyseed using HMAC-SHA384");
1700
1701
0
    if (hmac_sha384(kdk, kdk_len, buf, buf_len, hash)) {
1702
0
      wpa_printf(MSG_ERROR,
1703
0
           "WPA: HMAC-SHA384 compute failed");
1704
0
      return -1;
1705
0
    }
1706
0
    os_memcpy(ptk->ltf_keyseed, hash, SHA384_MAC_LEN);
1707
0
    ptk->ltf_keyseed_len = SHA384_MAC_LEN;
1708
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
1709
0
        ptk->ltf_keyseed, ptk->ltf_keyseed_len);
1710
1711
0
  } else {
1712
0
    wpa_printf(MSG_DEBUG, "WPA: LTF keyseed using HMAC-SHA256");
1713
1714
0
    if (hmac_sha256(kdk, kdk_len, buf, buf_len, hash)) {
1715
0
      wpa_printf(MSG_ERROR,
1716
0
           "WPA: HMAC-SHA256 compute failed");
1717
0
      return -1;
1718
0
    }
1719
0
    os_memcpy(ptk->ltf_keyseed, hash, SHA256_MAC_LEN);
1720
0
    ptk->ltf_keyseed_len = SHA256_MAC_LEN;
1721
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
1722
0
        ptk->ltf_keyseed, ptk->ltf_keyseed_len);
1723
0
  }
1724
1725
0
  return 0;
1726
0
}
1727
1728
1729
/**
1730
 * pasn_mic - Calculate PASN MIC
1731
 * @kck: The key confirmation key for the PASN PTKSA
1732
 * @akmp: Negotiated AKM
1733
 * @cipher: Negotiated pairwise cipher
1734
 * @addr1: For the 2nd PASN frame supplicant address; for the 3rd frame the
1735
 *  BSSID
1736
 * @addr2: For the 2nd PASN frame the BSSID; for the 3rd frame the supplicant
1737
 *  address
1738
 * @data: For calculating the MIC for the 2nd PASN frame, this should hold the
1739
 *  Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
1740
 *  frame, this should hold the hash of the body of the PASN 1st frame.
1741
 * @data_len: The length of data
1742
 * @frame: The body of the PASN frame including the MIC element with the octets
1743
 *  in the MIC field of the MIC element set to 0.
1744
 * @frame_len: The length of frame
1745
 * @mic: Buffer to hold the MIC on success. Should be big enough to handle the
1746
 *  maximal MIC length
1747
 * Returns: 0 on success, -1 on failure
1748
 */
1749
int pasn_mic(const u8 *kck, int akmp, int cipher,
1750
       const u8 *addr1, const u8 *addr2,
1751
       const u8 *data, size_t data_len,
1752
       const u8 *frame, size_t frame_len, u8 *mic)
1753
576
{
1754
576
  u8 *buf;
1755
576
  u8 hash[SHA384_MAC_LEN];
1756
576
  size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
1757
576
  int ret = -1;
1758
1759
576
  if (!kck) {
1760
0
    wpa_printf(MSG_ERROR, "PASN: No KCK for MIC calculation");
1761
0
    return -1;
1762
0
  }
1763
1764
576
  if (!data || !data_len) {
1765
0
    wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
1766
0
    return -1;
1767
0
  }
1768
1769
576
  if (!frame || !frame_len) {
1770
0
    wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
1771
0
    return -1;
1772
0
  }
1773
1774
576
  buf = os_zalloc(buf_len);
1775
576
  if (!buf)
1776
0
    return -1;
1777
1778
576
  os_memcpy(buf, addr1, ETH_ALEN);
1779
576
  os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
1780
1781
576
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: data", data, data_len);
1782
576
  os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
1783
1784
576
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: frame", frame, frame_len);
1785
576
  os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
1786
1787
576
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: KCK", kck, WPA_PASN_KCK_LEN);
1788
576
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: buf", buf, buf_len);
1789
1790
576
  if (pasn_use_sha384(akmp, cipher)) {
1791
0
    wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA384");
1792
1793
0
    if (hmac_sha384(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
1794
0
      goto err;
1795
1796
0
    os_memcpy(mic, hash, 24);
1797
0
    wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 24);
1798
576
  } else {
1799
576
    wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA256");
1800
1801
576
    if (hmac_sha256(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
1802
0
      goto err;
1803
1804
576
    os_memcpy(mic, hash, 16);
1805
576
    wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 16);
1806
576
  }
1807
1808
576
  ret = 0;
1809
576
err:
1810
576
  bin_clear_free(buf, buf_len);
1811
576
  return ret;
1812
576
}
1813
1814
1815
/**
1816
 * pasn_auth_frame_hash - Computes a hash of an Authentication frame body
1817
 * @akmp: Negotiated AKM
1818
 * @cipher: Negotiated pairwise cipher
1819
 * @data: Pointer to the Authentication frame body
1820
 * @len: Length of the Authentication frame body
1821
 * @hash: On return would hold the computed hash. Should be big enough to handle
1822
 *  SHA384.
1823
 * Returns: 0 on success, -1 on failure
1824
 */
1825
int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
1826
       u8 *hash)
1827
0
{
1828
0
  if (pasn_use_sha384(akmp, cipher)) {
1829
0
    wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-384");
1830
0
    return sha384_vector(1, &data, &len, hash);
1831
0
  } else {
1832
0
    wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-256");
1833
0
    return sha256_vector(1, &data, &len, hash);
1834
0
  }
1835
0
}
1836
1837
#endif /* CONFIG_PASN */
1838
1839
1840
static int rsn_selector_to_bitfield(const u8 *s)
1841
1.69k
{
1842
1.69k
  return rsn_cipher_suite_to_wpa_cipher(RSN_SELECTOR_GET(s));
1843
1.69k
}
1844
1845
1846
static int rsn_key_mgmt_to_bitfield(const u8 *s)
1847
1.52k
{
1848
1.52k
  return rsn_key_mgmt_to_wpa_akm(RSN_SELECTOR_GET(s));
1849
1.52k
}
1850
1851
1852
int wpa_cipher_valid_group(int cipher)
1853
604
{
1854
604
  return wpa_cipher_valid_pairwise(cipher) ||
1855
604
    cipher == WPA_CIPHER_GTK_NOT_USED;
1856
604
}
1857
1858
1859
int wpa_cipher_valid_mgmt_group(int cipher)
1860
134
{
1861
134
  return cipher == WPA_CIPHER_GTK_NOT_USED ||
1862
134
    cipher == WPA_CIPHER_AES_128_CMAC ||
1863
134
    cipher == WPA_CIPHER_BIP_GMAC_128 ||
1864
134
    cipher == WPA_CIPHER_BIP_GMAC_256 ||
1865
134
    cipher == WPA_CIPHER_BIP_CMAC_256;
1866
134
}
1867
1868
1869
/**
1870
 * wpa_parse_wpa_ie_rsn - Parse RSN IE
1871
 * @rsn_ie: Buffer containing RSN IE
1872
 * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
1873
 * @data: Pointer to structure that will be filled in with parsed data
1874
 * Returns: 0 on success, <0 on failure
1875
 */
1876
int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
1877
       struct wpa_ie_data *data)
1878
812
{
1879
812
  const u8 *pos;
1880
812
  int left;
1881
812
  int i, count;
1882
1883
812
  os_memset(data, 0, sizeof(*data));
1884
812
  data->proto = WPA_PROTO_RSN;
1885
812
  data->pairwise_cipher = WPA_CIPHER_CCMP;
1886
812
  data->group_cipher = WPA_CIPHER_CCMP;
1887
812
  data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1888
812
  data->capabilities = 0;
1889
812
  data->pmkid = NULL;
1890
812
  data->num_pmkid = 0;
1891
812
  data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1892
1893
812
  if (rsn_ie_len == 0) {
1894
    /* No RSN IE - fail silently */
1895
0
    return -1;
1896
0
  }
1897
1898
812
  if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
1899
68
    wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
1900
68
         __func__, (unsigned long) rsn_ie_len);
1901
68
    return -1;
1902
68
  }
1903
1904
744
  if (rsn_ie_len >= 2 + 4 + 2 && rsn_ie[1] >= 4 + 2 &&
1905
744
       rsn_ie[1] == rsn_ie_len - 2 &&
1906
744
       (WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE ||
1907
707
        WPA_GET_BE32(&rsn_ie[2]) ==
1908
700
        RSNE_OVERRIDE_2_IE_VENDOR_TYPE) &&
1909
744
       WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) {
1910
2
    pos = rsn_ie + 2 + 4 + 2;
1911
2
    left = rsn_ie_len - 2 - 4 - 2;
1912
742
  } else {
1913
742
    const struct rsn_ie_hdr *hdr;
1914
1915
742
    hdr = (const struct rsn_ie_hdr *) rsn_ie;
1916
1917
742
    if (hdr->elem_id != WLAN_EID_RSN ||
1918
742
        hdr->len != rsn_ie_len - 2 ||
1919
742
        WPA_GET_LE16(hdr->version) != RSN_VERSION) {
1920
134
      wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
1921
134
           __func__);
1922
134
      return -2;
1923
134
    }
1924
1925
608
    pos = (const u8 *) (hdr + 1);
1926
608
    left = rsn_ie_len - sizeof(*hdr);
1927
608
  }
1928
1929
610
  if (left >= RSN_SELECTOR_LEN) {
1930
604
    data->group_cipher = rsn_selector_to_bitfield(pos);
1931
604
    data->has_group = 1;
1932
604
    if (!wpa_cipher_valid_group(data->group_cipher)) {
1933
96
      wpa_printf(MSG_DEBUG,
1934
96
           "%s: invalid group cipher 0x%x (%08x)",
1935
96
           __func__, data->group_cipher,
1936
96
           WPA_GET_BE32(pos));
1937
#ifdef CONFIG_NO_TKIP
1938
      if (RSN_SELECTOR_GET(pos) == RSN_CIPHER_SUITE_TKIP) {
1939
        wpa_printf(MSG_DEBUG,
1940
             "%s: TKIP as group cipher not supported in CONFIG_NO_TKIP=y build",
1941
             __func__);
1942
      }
1943
#endif /* CONFIG_NO_TKIP */
1944
96
      return -1;
1945
96
    }
1946
508
    pos += RSN_SELECTOR_LEN;
1947
508
    left -= RSN_SELECTOR_LEN;
1948
508
  } else if (left > 0) {
1949
4
    wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
1950
4
         __func__, left);
1951
4
    return -3;
1952
4
  }
1953
1954
510
  if (left >= 2) {
1955
501
    data->pairwise_cipher = 0;
1956
501
    count = WPA_GET_LE16(pos);
1957
501
    pos += 2;
1958
501
    left -= 2;
1959
501
    if (count == 0 || count > left / RSN_SELECTOR_LEN) {
1960
19
      wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
1961
19
           "count %u left %u", __func__, count, left);
1962
19
      return -4;
1963
19
    }
1964
482
    if (count)
1965
482
      data->has_pairwise = 1;
1966
1.43k
    for (i = 0; i < count; i++) {
1967
953
      data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
1968
953
      pos += RSN_SELECTOR_LEN;
1969
953
      left -= RSN_SELECTOR_LEN;
1970
953
    }
1971
482
    if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
1972
4
      wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
1973
4
           "pairwise cipher", __func__);
1974
4
      return -1;
1975
4
    }
1976
482
  } else if (left == 1) {
1977
1
    wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
1978
1
         __func__);
1979
1
    return -5;
1980
1
  }
1981
1982
486
  if (left >= 2) {
1983
421
    data->key_mgmt = 0;
1984
421
    count = WPA_GET_LE16(pos);
1985
421
    pos += 2;
1986
421
    left -= 2;
1987
421
    if (count == 0 || count > left / RSN_SELECTOR_LEN) {
1988
23
      wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
1989
23
           "count %u left %u", __func__, count, left);
1990
23
      return -6;
1991
23
    }
1992
1.92k
    for (i = 0; i < count; i++) {
1993
1.52k
      data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
1994
1.52k
      pos += RSN_SELECTOR_LEN;
1995
1.52k
      left -= RSN_SELECTOR_LEN;
1996
1.52k
    }
1997
398
  } else if (left == 1) {
1998
3
    wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
1999
3
         __func__);
2000
3
    return -7;
2001
3
  }
2002
2003
460
  if (left >= 2) {
2004
339
    data->capabilities = WPA_GET_LE16(pos);
2005
339
    pos += 2;
2006
339
    left -= 2;
2007
339
  }
2008
2009
460
  if (left >= 2) {
2010
163
    u16 num_pmkid = WPA_GET_LE16(pos);
2011
163
    pos += 2;
2012
163
    left -= 2;
2013
163
    if (num_pmkid > (unsigned int) left / PMKID_LEN) {
2014
21
      wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
2015
21
           "(num_pmkid=%u left=%d)",
2016
21
           __func__, num_pmkid, left);
2017
21
      data->num_pmkid = 0;
2018
21
      return -9;
2019
142
    } else {
2020
142
      data->num_pmkid = num_pmkid;
2021
142
      data->pmkid = pos;
2022
142
      pos += data->num_pmkid * PMKID_LEN;
2023
142
      left -= data->num_pmkid * PMKID_LEN;
2024
142
    }
2025
163
  }
2026
2027
439
  if (left >= 4) {
2028
134
    data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
2029
134
    if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
2030
16
      wpa_printf(MSG_DEBUG,
2031
16
           "%s: Unsupported management group cipher 0x%x (%08x)",
2032
16
           __func__, data->mgmt_group_cipher,
2033
16
           WPA_GET_BE32(pos));
2034
16
      return -10;
2035
16
    }
2036
118
    pos += RSN_SELECTOR_LEN;
2037
118
    left -= RSN_SELECTOR_LEN;
2038
118
  }
2039
2040
423
  if (left > 0) {
2041
15
    wpa_hexdump(MSG_DEBUG,
2042
15
          "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
2043
15
          pos, left);
2044
15
  }
2045
2046
423
  return 0;
2047
439
}
2048
2049
2050
static int wpa_selector_to_bitfield(const u8 *s)
2051
0
{
2052
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
2053
0
    return WPA_CIPHER_NONE;
2054
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
2055
0
    return WPA_CIPHER_TKIP;
2056
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
2057
0
    return WPA_CIPHER_CCMP;
2058
0
  return 0;
2059
0
}
2060
2061
2062
static int wpa_key_mgmt_to_bitfield(const u8 *s)
2063
0
{
2064
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
2065
0
    return WPA_KEY_MGMT_IEEE8021X;
2066
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
2067
0
    return WPA_KEY_MGMT_PSK;
2068
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
2069
0
    return WPA_KEY_MGMT_WPA_NONE;
2070
0
  return 0;
2071
0
}
2072
2073
2074
int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
2075
       struct wpa_ie_data *data)
2076
0
{
2077
0
  const struct wpa_ie_hdr *hdr;
2078
0
  const u8 *pos;
2079
0
  int left;
2080
0
  int i, count;
2081
2082
0
  os_memset(data, 0, sizeof(*data));
2083
0
  data->proto = WPA_PROTO_WPA;
2084
0
  data->pairwise_cipher = WPA_CIPHER_TKIP;
2085
0
  data->group_cipher = WPA_CIPHER_TKIP;
2086
0
  data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
2087
0
  data->capabilities = 0;
2088
0
  data->pmkid = NULL;
2089
0
  data->num_pmkid = 0;
2090
0
  data->mgmt_group_cipher = 0;
2091
2092
0
  if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
2093
0
    wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
2094
0
         __func__, (unsigned long) wpa_ie_len);
2095
0
    return -1;
2096
0
  }
2097
2098
0
  hdr = (const struct wpa_ie_hdr *) wpa_ie;
2099
2100
0
  if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
2101
0
      hdr->len != wpa_ie_len - 2 ||
2102
0
      RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
2103
0
      WPA_GET_LE16(hdr->version) != WPA_VERSION) {
2104
0
    wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
2105
0
         __func__);
2106
0
    return -2;
2107
0
  }
2108
2109
0
  pos = (const u8 *) (hdr + 1);
2110
0
  left = wpa_ie_len - sizeof(*hdr);
2111
2112
0
  if (left >= WPA_SELECTOR_LEN) {
2113
0
    data->group_cipher = wpa_selector_to_bitfield(pos);
2114
0
    pos += WPA_SELECTOR_LEN;
2115
0
    left -= WPA_SELECTOR_LEN;
2116
0
  } else if (left > 0) {
2117
0
    wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
2118
0
         __func__, left);
2119
0
    return -3;
2120
0
  }
2121
2122
0
  if (left >= 2) {
2123
0
    data->pairwise_cipher = 0;
2124
0
    count = WPA_GET_LE16(pos);
2125
0
    pos += 2;
2126
0
    left -= 2;
2127
0
    if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2128
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
2129
0
           "count %u left %u", __func__, count, left);
2130
0
      return -4;
2131
0
    }
2132
0
    for (i = 0; i < count; i++) {
2133
0
      data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
2134
0
      pos += WPA_SELECTOR_LEN;
2135
0
      left -= WPA_SELECTOR_LEN;
2136
0
    }
2137
0
  } else if (left == 1) {
2138
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
2139
0
         __func__);
2140
0
    return -5;
2141
0
  }
2142
2143
0
  if (left >= 2) {
2144
0
    data->key_mgmt = 0;
2145
0
    count = WPA_GET_LE16(pos);
2146
0
    pos += 2;
2147
0
    left -= 2;
2148
0
    if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2149
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
2150
0
           "count %u left %u", __func__, count, left);
2151
0
      return -6;
2152
0
    }
2153
0
    for (i = 0; i < count; i++) {
2154
0
      data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
2155
0
      pos += WPA_SELECTOR_LEN;
2156
0
      left -= WPA_SELECTOR_LEN;
2157
0
    }
2158
0
  } else if (left == 1) {
2159
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
2160
0
         __func__);
2161
0
    return -7;
2162
0
  }
2163
2164
0
  if (left >= 2) {
2165
0
    data->capabilities = WPA_GET_LE16(pos);
2166
0
    pos += 2;
2167
0
    left -= 2;
2168
0
  }
2169
2170
0
  if (left > 0) {
2171
0
    wpa_hexdump(MSG_DEBUG,
2172
0
          "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
2173
0
          pos, left);
2174
0
  }
2175
2176
0
  return 0;
2177
0
}
2178
2179
2180
int wpa_default_rsn_cipher(int freq)
2181
0
{
2182
0
  if (freq > 56160)
2183
0
    return WPA_CIPHER_GCMP; /* DMG */
2184
2185
0
  return WPA_CIPHER_CCMP;
2186
0
}
2187
2188
2189
#ifdef CONFIG_IEEE80211R
2190
2191
/**
2192
 * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
2193
 *
2194
 * IEEE Std 802.11r-2008 - 8.5.1.5.3
2195
 */
2196
int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
2197
          const u8 *ssid, size_t ssid_len,
2198
          const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
2199
          const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name,
2200
          int key_mgmt)
2201
0
{
2202
0
  u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
2203
0
         FT_R0KH_ID_MAX_LEN + ETH_ALEN];
2204
0
  u8 *pos, r0_key_data[64 + 16], hash[64];
2205
0
  const u8 *addr[2];
2206
0
  size_t len[2];
2207
0
  size_t q, r0_key_data_len;
2208
0
  int res;
2209
2210
0
  if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
2211
0
      (xxkey_len == SHA256_MAC_LEN || xxkey_len == SHA384_MAC_LEN ||
2212
0
       xxkey_len == SHA512_MAC_LEN))
2213
0
    q = xxkey_len;
2214
0
  else if (wpa_key_mgmt_sha384(key_mgmt))
2215
0
    q = SHA384_MAC_LEN;
2216
0
  else
2217
0
    q = SHA256_MAC_LEN;
2218
0
  r0_key_data_len = q + 16;
2219
2220
  /*
2221
   * R0-Key-Data = KDF-Hash-Length(XXKey, "FT-R0",
2222
   *                       SSIDlength || SSID || MDID || R0KHlength ||
2223
   *                       R0KH-ID || S0KH-ID)
2224
   * XXKey is either the second 256 bits of MSK or PSK; or the first
2225
   * 384 bits of MSK for FT-EAP-SHA384; or PMK from SAE.
2226
   * PMK-R0 = L(R0-Key-Data, 0, Q)
2227
   * PMK-R0Name-Salt = L(R0-Key-Data, Q, 128)
2228
   * Q = 384 for FT-EAP-SHA384; the length of the digest generated by H()
2229
   * for FT-SAE-EXT-KEY; or otherwise, 256
2230
   */
2231
0
  if (ssid_len > SSID_MAX_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
2232
0
    return -1;
2233
0
  wpa_printf(MSG_DEBUG, "FT: Derive PMK-R0 using KDF-SHA%zu", q * 8);
2234
0
  wpa_hexdump_key(MSG_DEBUG, "FT: XXKey", xxkey, xxkey_len);
2235
0
  wpa_hexdump_ascii(MSG_DEBUG, "FT: SSID", ssid, ssid_len);
2236
0
  wpa_hexdump(MSG_DEBUG, "FT: MDID", mdid, MOBILITY_DOMAIN_ID_LEN);
2237
0
  wpa_hexdump_ascii(MSG_DEBUG, "FT: R0KH-ID", r0kh_id, r0kh_id_len);
2238
0
  wpa_printf(MSG_DEBUG, "FT: S0KH-ID: " MACSTR, MAC2STR(s0kh_id));
2239
0
  pos = buf;
2240
0
  *pos++ = ssid_len;
2241
0
  os_memcpy(pos, ssid, ssid_len);
2242
0
  pos += ssid_len;
2243
0
  os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
2244
0
  pos += MOBILITY_DOMAIN_ID_LEN;
2245
0
  *pos++ = r0kh_id_len;
2246
0
  os_memcpy(pos, r0kh_id, r0kh_id_len);
2247
0
  pos += r0kh_id_len;
2248
0
  os_memcpy(pos, s0kh_id, ETH_ALEN);
2249
0
  pos += ETH_ALEN;
2250
2251
0
  res = -1;
2252
#ifdef CONFIG_SHA512
2253
  if (q == SHA512_MAC_LEN) {
2254
    if (xxkey_len != SHA512_MAC_LEN) {
2255
      wpa_printf(MSG_ERROR,
2256
           "FT: Unexpected XXKey length %d (expected %d)",
2257
           (int) xxkey_len, SHA512_MAC_LEN);
2258
      return -1;
2259
    }
2260
    res = sha512_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2261
         r0_key_data, r0_key_data_len);
2262
  }
2263
#endif /* CONFIG_SHA512 */
2264
0
#ifdef CONFIG_SHA384
2265
0
  if (q == SHA384_MAC_LEN) {
2266
0
    if (xxkey_len != SHA384_MAC_LEN) {
2267
0
      wpa_printf(MSG_ERROR,
2268
0
           "FT: Unexpected XXKey length %d (expected %d)",
2269
0
           (int) xxkey_len, SHA384_MAC_LEN);
2270
0
      return -1;
2271
0
    }
2272
0
    res = sha384_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2273
0
         r0_key_data, r0_key_data_len);
2274
0
  }
2275
0
#endif /* CONFIG_SHA384 */
2276
0
  if (q == SHA256_MAC_LEN) {
2277
0
    if (xxkey_len != PMK_LEN) {
2278
0
      wpa_printf(MSG_ERROR,
2279
0
           "FT: Unexpected XXKey length %d (expected %d)",
2280
0
           (int) xxkey_len, PMK_LEN);
2281
0
      return -1;
2282
0
    }
2283
0
    res = sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2284
0
         r0_key_data, r0_key_data_len);
2285
0
  }
2286
0
  if (res < 0)
2287
0
    return res;
2288
0
  os_memcpy(pmk_r0, r0_key_data, q);
2289
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, q);
2290
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0Name-Salt", &r0_key_data[q], 16);
2291
2292
  /*
2293
   * PMKR0Name = Truncate-128(Hash("FT-R0N" || PMK-R0Name-Salt)
2294
   */
2295
0
  addr[0] = (const u8 *) "FT-R0N";
2296
0
  len[0] = 6;
2297
0
  addr[1] = &r0_key_data[q];
2298
0
  len[1] = 16;
2299
2300
0
  res = -1;
2301
#ifdef CONFIG_SHA512
2302
  if (q == SHA512_MAC_LEN)
2303
    res = sha512_vector(2, addr, len, hash);
2304
#endif /* CONFIG_SHA512 */
2305
0
#ifdef CONFIG_SHA384
2306
0
  if (q == SHA384_MAC_LEN)
2307
0
    res = sha384_vector(2, addr, len, hash);
2308
0
#endif /* CONFIG_SHA384 */
2309
0
  if (q == SHA256_MAC_LEN)
2310
0
    res = sha256_vector(2, addr, len, hash);
2311
0
  if (res < 0) {
2312
0
    wpa_printf(MSG_DEBUG,
2313
0
         "FT: Failed to derive PMKR0Name (PMK-R0 len %zu)",
2314
0
         q);
2315
0
    return res;
2316
0
  }
2317
0
  os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
2318
0
  wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
2319
0
  forced_memzero(r0_key_data, sizeof(r0_key_data));
2320
0
  return 0;
2321
0
}
2322
2323
2324
/**
2325
 * wpa_derive_pmk_r1_name - Derive PMKR1Name
2326
 *
2327
 * IEEE Std 802.11r-2008 - 8.5.1.5.4
2328
 */
2329
int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
2330
         const u8 *s1kh_id, u8 *pmk_r1_name,
2331
         size_t pmk_r1_len)
2332
0
{
2333
0
  u8 hash[64];
2334
0
  const u8 *addr[4];
2335
0
  size_t len[4];
2336
0
  int res;
2337
0
  const char *title;
2338
2339
  /*
2340
   * PMKR1Name = Truncate-128(Hash("FT-R1N" || PMKR0Name ||
2341
   *                               R1KH-ID || S1KH-ID))
2342
   */
2343
0
  addr[0] = (const u8 *) "FT-R1N";
2344
0
  len[0] = 6;
2345
0
  addr[1] = pmk_r0_name;
2346
0
  len[1] = WPA_PMK_NAME_LEN;
2347
0
  addr[2] = r1kh_id;
2348
0
  len[2] = FT_R1KH_ID_LEN;
2349
0
  addr[3] = s1kh_id;
2350
0
  len[3] = ETH_ALEN;
2351
2352
0
  res = -1;
2353
#ifdef CONFIG_SHA512
2354
  if (pmk_r1_len == SHA512_MAC_LEN) {
2355
    title = "FT: PMKR1Name (using SHA512)";
2356
    res = sha512_vector(4, addr, len, hash);
2357
  }
2358
#endif /* CONFIG_SHA512 */
2359
0
#ifdef CONFIG_SHA384
2360
0
  if (pmk_r1_len == SHA384_MAC_LEN) {
2361
0
    title = "FT: PMKR1Name (using SHA384)";
2362
0
    res = sha384_vector(4, addr, len, hash);
2363
0
  }
2364
0
#endif /* CONFIG_SHA384 */
2365
0
  if (pmk_r1_len == SHA256_MAC_LEN) {
2366
0
    title = "FT: PMKR1Name (using SHA256)";
2367
0
    res = sha256_vector(4, addr, len, hash);
2368
0
  }
2369
0
  if (res < 0) {
2370
0
    wpa_printf(MSG_DEBUG,
2371
0
         "FT: Failed to derive PMKR1Name (PMK-R1 len %zu)",
2372
0
         pmk_r1_len);
2373
0
    return res;
2374
0
  }
2375
0
  os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
2376
0
  wpa_hexdump(MSG_DEBUG, title, pmk_r1_name, WPA_PMK_NAME_LEN);
2377
0
  return 0;
2378
0
}
2379
2380
2381
/**
2382
 * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
2383
 *
2384
 * IEEE Std 802.11r-2008 - 8.5.1.5.4
2385
 */
2386
int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
2387
          const u8 *pmk_r0_name,
2388
          const u8 *r1kh_id, const u8 *s1kh_id,
2389
          u8 *pmk_r1, u8 *pmk_r1_name)
2390
0
{
2391
0
  u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
2392
0
  u8 *pos;
2393
0
  int res;
2394
2395
  /* PMK-R1 = KDF-Hash(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
2396
0
  wpa_printf(MSG_DEBUG, "FT: Derive PMK-R1 using KDF-SHA%zu",
2397
0
       pmk_r0_len * 8);
2398
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len);
2399
0
  wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", r1kh_id, FT_R1KH_ID_LEN);
2400
0
  wpa_printf(MSG_DEBUG, "FT: S1KH-ID: " MACSTR, MAC2STR(s1kh_id));
2401
0
  pos = buf;
2402
0
  os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
2403
0
  pos += FT_R1KH_ID_LEN;
2404
0
  os_memcpy(pos, s1kh_id, ETH_ALEN);
2405
0
  pos += ETH_ALEN;
2406
2407
0
  res = -1;
2408
#ifdef CONFIG_SHA512
2409
  if (pmk_r0_len == SHA512_MAC_LEN)
2410
    res = sha512_prf(pmk_r0, pmk_r0_len, "FT-R1",
2411
         buf, pos - buf, pmk_r1, pmk_r0_len);
2412
#endif /* CONFIG_SHA512 */
2413
0
#ifdef CONFIG_SHA384
2414
0
  if (pmk_r0_len == SHA384_MAC_LEN)
2415
0
    res = sha384_prf(pmk_r0, pmk_r0_len, "FT-R1",
2416
0
         buf, pos - buf, pmk_r1, pmk_r0_len);
2417
0
#endif /* CONFIG_SHA384 */
2418
0
  if (pmk_r0_len == SHA256_MAC_LEN)
2419
0
    res = sha256_prf(pmk_r0, pmk_r0_len, "FT-R1",
2420
0
         buf, pos - buf, pmk_r1, pmk_r0_len);
2421
0
  if (res < 0) {
2422
0
    wpa_printf(MSG_ERROR, "FT: Failed to derive PMK-R1");
2423
0
    return res;
2424
0
  }
2425
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len);
2426
2427
0
  return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
2428
0
              pmk_r1_name, pmk_r0_len);
2429
0
}
2430
2431
2432
/**
2433
 * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
2434
 *
2435
 * IEEE Std 802.11r-2008 - 8.5.1.5.5
2436
 */
2437
int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
2438
          const u8 *snonce, const u8 *anonce,
2439
          const u8 *sta_addr, const u8 *bssid,
2440
          const u8 *pmk_r1_name,
2441
          struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
2442
          size_t kdk_len)
2443
0
{
2444
0
  u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
2445
0
  u8 *pos, hash[32];
2446
0
  const u8 *addr[6];
2447
0
  size_t len[6];
2448
0
  u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
2449
0
         WPA_KDK_MAX_LEN];
2450
0
  size_t ptk_len, offset;
2451
0
  size_t key_len;
2452
0
  int res;
2453
2454
0
  if (kdk_len > WPA_KDK_MAX_LEN) {
2455
0
    wpa_printf(MSG_ERROR,
2456
0
         "FT: KDK len=%zu exceeds max supported len",
2457
0
         kdk_len);
2458
0
    return -1;
2459
0
  }
2460
2461
0
  if (akmp == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
2462
0
      (pmk_r1_len == SHA256_MAC_LEN || pmk_r1_len == SHA384_MAC_LEN ||
2463
0
       pmk_r1_len == SHA512_MAC_LEN))
2464
0
    key_len = pmk_r1_len;
2465
0
  else if (wpa_key_mgmt_sha384(akmp))
2466
0
    key_len = SHA384_MAC_LEN;
2467
0
  else
2468
0
    key_len = SHA256_MAC_LEN;
2469
2470
  /*
2471
   * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
2472
   *                  BSSID || STA-ADDR)
2473
   */
2474
0
  wpa_printf(MSG_DEBUG, "FT: Derive PTK using KDF-SHA%zu", key_len * 8);
2475
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len);
2476
0
  wpa_hexdump(MSG_DEBUG, "FT: SNonce", snonce, WPA_NONCE_LEN);
2477
0
  wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
2478
0
  wpa_printf(MSG_DEBUG, "FT: BSSID=" MACSTR " STA-ADDR=" MACSTR,
2479
0
       MAC2STR(bssid), MAC2STR(sta_addr));
2480
0
  pos = buf;
2481
0
  os_memcpy(pos, snonce, WPA_NONCE_LEN);
2482
0
  pos += WPA_NONCE_LEN;
2483
0
  os_memcpy(pos, anonce, WPA_NONCE_LEN);
2484
0
  pos += WPA_NONCE_LEN;
2485
0
  os_memcpy(pos, bssid, ETH_ALEN);
2486
0
  pos += ETH_ALEN;
2487
0
  os_memcpy(pos, sta_addr, ETH_ALEN);
2488
0
  pos += ETH_ALEN;
2489
2490
0
  ptk->kck_len = wpa_kck_len(akmp, key_len);
2491
0
  ptk->kck2_len = wpa_kck2_len(akmp);
2492
0
  ptk->kek_len = wpa_kek_len(akmp, key_len);
2493
0
  ptk->kek2_len = wpa_kek2_len(akmp);
2494
0
  ptk->tk_len = wpa_cipher_key_len(cipher);
2495
0
  ptk->kdk_len = kdk_len;
2496
0
  ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
2497
0
    ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
2498
2499
0
  res = -1;
2500
#ifdef CONFIG_SHA512
2501
  if (key_len == SHA512_MAC_LEN) {
2502
    if (pmk_r1_len != SHA512_MAC_LEN) {
2503
      wpa_printf(MSG_ERROR,
2504
           "FT: Unexpected PMK-R1 length %d (expected %d)",
2505
           (int) pmk_r1_len, SHA512_MAC_LEN);
2506
      return -1;
2507
    }
2508
    res = sha512_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2509
         buf, pos - buf, tmp, ptk_len);
2510
  }
2511
#endif /* CONFIG_SHA512 */
2512
0
#ifdef CONFIG_SHA384
2513
0
  if (key_len == SHA384_MAC_LEN) {
2514
0
    if (pmk_r1_len != SHA384_MAC_LEN) {
2515
0
      wpa_printf(MSG_ERROR,
2516
0
           "FT: Unexpected PMK-R1 length %d (expected %d)",
2517
0
           (int) pmk_r1_len, SHA384_MAC_LEN);
2518
0
      return -1;
2519
0
    }
2520
0
    res = sha384_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2521
0
         buf, pos - buf, tmp, ptk_len);
2522
0
  }
2523
0
#endif /* CONFIG_SHA384 */
2524
0
  if (key_len == SHA256_MAC_LEN) {
2525
0
    if (pmk_r1_len != PMK_LEN) {
2526
0
      wpa_printf(MSG_ERROR,
2527
0
           "FT: Unexpected PMK-R1 length %d (expected %d)",
2528
0
           (int) pmk_r1_len, PMK_LEN);
2529
0
      return -1;
2530
0
    }
2531
0
    res = sha256_prf(pmk_r1, pmk_r1_len, "FT-PTK",
2532
0
         buf, pos - buf, tmp, ptk_len);
2533
0
  }
2534
0
  if (res < 0)
2535
0
    return -1;
2536
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PTK", tmp, ptk_len);
2537
2538
  /*
2539
   * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
2540
   *                                ANonce || BSSID || STA-ADDR))
2541
   */
2542
0
  wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
2543
0
  addr[0] = pmk_r1_name;
2544
0
  len[0] = WPA_PMK_NAME_LEN;
2545
0
  addr[1] = (const u8 *) "FT-PTKN";
2546
0
  len[1] = 7;
2547
0
  addr[2] = snonce;
2548
0
  len[2] = WPA_NONCE_LEN;
2549
0
  addr[3] = anonce;
2550
0
  len[3] = WPA_NONCE_LEN;
2551
0
  addr[4] = bssid;
2552
0
  len[4] = ETH_ALEN;
2553
0
  addr[5] = sta_addr;
2554
0
  len[5] = ETH_ALEN;
2555
2556
0
  if (sha256_vector(6, addr, len, hash) < 0)
2557
0
    return -1;
2558
0
  os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
2559
2560
0
  os_memcpy(ptk->kck, tmp, ptk->kck_len);
2561
0
  offset = ptk->kck_len;
2562
0
  os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
2563
0
  offset += ptk->kek_len;
2564
0
  os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
2565
0
  offset += ptk->tk_len;
2566
0
  os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
2567
0
  offset += ptk->kck2_len;
2568
0
  os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
2569
0
  offset += ptk->kek2_len;
2570
0
  os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
2571
2572
0
  wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
2573
0
  wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
2574
0
  if (ptk->kck2_len)
2575
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KCK2",
2576
0
        ptk->kck2, ptk->kck2_len);
2577
0
  if (ptk->kek2_len)
2578
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
2579
0
        ptk->kek2, ptk->kek2_len);
2580
0
  if (ptk->kdk_len)
2581
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KDK", ptk->kdk, ptk->kdk_len);
2582
2583
0
  wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
2584
0
  wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
2585
2586
0
  forced_memzero(tmp, sizeof(tmp));
2587
2588
0
  return 0;
2589
0
}
2590
2591
#endif /* CONFIG_IEEE80211R */
2592
2593
2594
/**
2595
 * rsn_pmkid - Calculate PMK identifier
2596
 * @pmk: Pairwise master key
2597
 * @pmk_len: Length of pmk in bytes
2598
 * @aa: Authenticator address
2599
 * @spa: Supplicant address
2600
 * @pmkid: Buffer for PMKID
2601
 * @akmp: Negotiated key management protocol
2602
 *
2603
 * IEEE Std 802.11-2016 - 12.7.1.3 Pairwise key hierarchy
2604
 * AKM: 00-0F-AC:3, 00-0F-AC:5, 00-0F-AC:6, 00-0F-AC:14, 00-0F-AC:16
2605
 * PMKID = Truncate-128(HMAC-SHA-256(PMK, "PMK Name" || AA || SPA))
2606
 * AKM: 00-0F-AC:11
2607
 * See rsn_pmkid_suite_b()
2608
 * AKM: 00-0F-AC:12
2609
 * See rsn_pmkid_suite_b_192()
2610
 * AKM: 00-0F-AC:13, 00-0F-AC:15, 00-0F-AC:17
2611
 * PMKID = Truncate-128(HMAC-SHA-384(PMK, "PMK Name" || AA || SPA))
2612
 * Otherwise:
2613
 * PMKID = Truncate-128(HMAC-SHA-1(PMK, "PMK Name" || AA || SPA))
2614
 */
2615
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
2616
         u8 *pmkid, int akmp)
2617
0
{
2618
0
  char *title = "PMK Name";
2619
0
  const u8 *addr[3];
2620
0
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2621
0
  unsigned char hash[SHA384_MAC_LEN];
2622
2623
0
  addr[0] = (u8 *) title;
2624
0
  addr[1] = aa;
2625
0
  addr[2] = spa;
2626
2627
0
  if (0) {
2628
0
#if defined(CONFIG_FILS) || defined(CONFIG_SHA384)
2629
0
  } else if (wpa_key_mgmt_sha384(akmp)) {
2630
0
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-384");
2631
0
    hmac_sha384_vector(pmk, pmk_len, 3, addr, len, hash);
2632
0
#endif /* CONFIG_FILS || CONFIG_SHA384 */
2633
0
  } else if (wpa_key_mgmt_sha256(akmp)) {
2634
0
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-256");
2635
0
    hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
2636
0
  } else {
2637
0
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-1");
2638
0
    hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
2639
0
  }
2640
0
  wpa_hexdump(MSG_DEBUG, "RSN: Derived PMKID", hash, PMKID_LEN);
2641
0
  os_memcpy(pmkid, hash, PMKID_LEN);
2642
0
}
2643
2644
2645
#ifdef CONFIG_SUITEB
2646
/**
2647
 * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
2648
 * @kck: Key confirmation key
2649
 * @kck_len: Length of kck in bytes
2650
 * @aa: Authenticator address
2651
 * @spa: Supplicant address
2652
 * @pmkid: Buffer for PMKID
2653
 * Returns: 0 on success, -1 on failure
2654
 *
2655
 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
2656
 * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
2657
 */
2658
int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
2659
          const u8 *spa, u8 *pmkid)
2660
{
2661
  char *title = "PMK Name";
2662
  const u8 *addr[3];
2663
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2664
  unsigned char hash[SHA256_MAC_LEN];
2665
2666
  addr[0] = (u8 *) title;
2667
  addr[1] = aa;
2668
  addr[2] = spa;
2669
2670
  if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
2671
    return -1;
2672
  os_memcpy(pmkid, hash, PMKID_LEN);
2673
  return 0;
2674
}
2675
#endif /* CONFIG_SUITEB */
2676
2677
2678
#ifdef CONFIG_SUITEB192
2679
/**
2680
 * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
2681
 * @kck: Key confirmation key
2682
 * @kck_len: Length of kck in bytes
2683
 * @aa: Authenticator address
2684
 * @spa: Supplicant address
2685
 * @pmkid: Buffer for PMKID
2686
 * Returns: 0 on success, -1 on failure
2687
 *
2688
 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
2689
 * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
2690
 */
2691
int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
2692
        const u8 *spa, u8 *pmkid)
2693
{
2694
  char *title = "PMK Name";
2695
  const u8 *addr[3];
2696
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
2697
  unsigned char hash[SHA384_MAC_LEN];
2698
2699
  addr[0] = (u8 *) title;
2700
  addr[1] = aa;
2701
  addr[2] = spa;
2702
2703
  if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
2704
    return -1;
2705
  os_memcpy(pmkid, hash, PMKID_LEN);
2706
  return 0;
2707
}
2708
#endif /* CONFIG_SUITEB192 */
2709
2710
2711
/**
2712
 * wpa_cipher_txt - Convert cipher suite to a text string
2713
 * @cipher: Cipher suite (WPA_CIPHER_* enum)
2714
 * Returns: Pointer to a text string of the cipher suite name
2715
 */
2716
const char * wpa_cipher_txt(int cipher)
2717
0
{
2718
0
  switch (cipher) {
2719
0
  case WPA_CIPHER_NONE:
2720
0
    return "NONE";
2721
#ifdef CONFIG_WEP
2722
  case WPA_CIPHER_WEP40:
2723
    return "WEP-40";
2724
  case WPA_CIPHER_WEP104:
2725
    return "WEP-104";
2726
#endif /* CONFIG_WEP */
2727
0
  case WPA_CIPHER_TKIP:
2728
0
    return "TKIP";
2729
0
  case WPA_CIPHER_CCMP:
2730
0
    return "CCMP";
2731
0
  case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
2732
0
    return "CCMP+TKIP";
2733
0
  case WPA_CIPHER_GCMP:
2734
0
    return "GCMP";
2735
0
  case WPA_CIPHER_GCMP_256:
2736
0
    return "GCMP-256";
2737
0
  case WPA_CIPHER_CCMP_256:
2738
0
    return "CCMP-256";
2739
0
  case WPA_CIPHER_AES_128_CMAC:
2740
0
    return "BIP";
2741
0
  case WPA_CIPHER_BIP_GMAC_128:
2742
0
    return "BIP-GMAC-128";
2743
0
  case WPA_CIPHER_BIP_GMAC_256:
2744
0
    return "BIP-GMAC-256";
2745
0
  case WPA_CIPHER_BIP_CMAC_256:
2746
0
    return "BIP-CMAC-256";
2747
0
  case WPA_CIPHER_GTK_NOT_USED:
2748
0
    return "GTK_NOT_USED";
2749
0
  default:
2750
0
    return "UNKNOWN";
2751
0
  }
2752
0
}
2753
2754
2755
/**
2756
 * wpa_key_mgmt_txt - Convert key management suite to a text string
2757
 * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
2758
 * @proto: WPA/WPA2 version (WPA_PROTO_*)
2759
 * Returns: Pointer to a text string of the key management suite name
2760
 */
2761
const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
2762
0
{
2763
0
  switch (key_mgmt) {
2764
0
  case WPA_KEY_MGMT_IEEE8021X:
2765
0
    if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
2766
0
      return "WPA2+WPA/IEEE 802.1X/EAP";
2767
0
    return proto == WPA_PROTO_RSN ?
2768
0
      "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
2769
0
  case WPA_KEY_MGMT_PSK:
2770
0
    if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
2771
0
      return "WPA2-PSK+WPA-PSK";
2772
0
    return proto == WPA_PROTO_RSN ?
2773
0
      "WPA2-PSK" : "WPA-PSK";
2774
0
  case WPA_KEY_MGMT_NONE:
2775
0
    return "NONE";
2776
0
  case WPA_KEY_MGMT_WPA_NONE:
2777
0
    return "WPA-NONE";
2778
0
  case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
2779
0
    return "IEEE 802.1X (no WPA)";
2780
0
#ifdef CONFIG_IEEE80211R
2781
0
  case WPA_KEY_MGMT_FT_IEEE8021X:
2782
0
    return "FT-EAP";
2783
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
2784
0
    return "FT-EAP-SHA384";
2785
0
  case WPA_KEY_MGMT_FT_PSK:
2786
0
    return "FT-PSK";
2787
0
#endif /* CONFIG_IEEE80211R */
2788
0
  case WPA_KEY_MGMT_IEEE8021X_SHA256:
2789
0
    return "WPA2-EAP-SHA256";
2790
0
  case WPA_KEY_MGMT_PSK_SHA256:
2791
0
    return "WPA2-PSK-SHA256";
2792
0
  case WPA_KEY_MGMT_WPS:
2793
0
    return "WPS";
2794
0
  case WPA_KEY_MGMT_SAE:
2795
0
    return "SAE";
2796
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
2797
0
    return "SAE-EXT-KEY";
2798
0
  case WPA_KEY_MGMT_FT_SAE:
2799
0
    return "FT-SAE";
2800
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
2801
0
    return "FT-SAE-EXT-KEY";
2802
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2803
0
    return "WPA2-EAP-SUITE-B";
2804
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2805
0
    return "WPA2-EAP-SUITE-B-192";
2806
0
  case WPA_KEY_MGMT_FILS_SHA256:
2807
0
    return "FILS-SHA256";
2808
0
  case WPA_KEY_MGMT_FILS_SHA384:
2809
0
    return "FILS-SHA384";
2810
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
2811
0
    return "FT-FILS-SHA256";
2812
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
2813
0
    return "FT-FILS-SHA384";
2814
0
  case WPA_KEY_MGMT_OWE:
2815
0
    return "OWE";
2816
0
  case WPA_KEY_MGMT_DPP:
2817
0
    return "DPP";
2818
0
  case WPA_KEY_MGMT_PASN:
2819
0
    return "PASN";
2820
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
2821
0
    return "WPA2-EAP-SHA384";
2822
0
  default:
2823
0
    return "UNKNOWN";
2824
0
  }
2825
0
}
2826
2827
2828
u32 wpa_akm_to_suite(int akm)
2829
0
{
2830
0
  if (akm & WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
2831
0
    return RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384;
2832
0
  if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
2833
0
    return RSN_AUTH_KEY_MGMT_FT_802_1X;
2834
0
  if (akm & WPA_KEY_MGMT_FT_PSK)
2835
0
    return RSN_AUTH_KEY_MGMT_FT_PSK;
2836
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SHA384)
2837
0
    return RSN_AUTH_KEY_MGMT_802_1X_SHA384;
2838
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
2839
0
    return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2840
0
  if (akm & WPA_KEY_MGMT_IEEE8021X)
2841
0
    return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
2842
0
  if (akm & WPA_KEY_MGMT_PSK_SHA256)
2843
0
    return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2844
0
  if (akm & WPA_KEY_MGMT_PSK)
2845
0
    return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
2846
0
  if (akm & WPA_KEY_MGMT_CCKM)
2847
0
    return RSN_AUTH_KEY_MGMT_CCKM;
2848
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
2849
0
    return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
2850
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
2851
0
    return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
2852
0
  if (akm & WPA_KEY_MGMT_FILS_SHA256)
2853
0
    return RSN_AUTH_KEY_MGMT_FILS_SHA256;
2854
0
  if (akm & WPA_KEY_MGMT_FILS_SHA384)
2855
0
    return RSN_AUTH_KEY_MGMT_FILS_SHA384;
2856
0
  if (akm & WPA_KEY_MGMT_FT_FILS_SHA256)
2857
0
    return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
2858
0
  if (akm & WPA_KEY_MGMT_FT_FILS_SHA384)
2859
0
    return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
2860
0
  if (akm & WPA_KEY_MGMT_SAE)
2861
0
    return RSN_AUTH_KEY_MGMT_SAE;
2862
0
  if (akm & WPA_KEY_MGMT_SAE_EXT_KEY)
2863
0
    return RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
2864
0
  if (akm & WPA_KEY_MGMT_FT_SAE)
2865
0
    return RSN_AUTH_KEY_MGMT_FT_SAE;
2866
0
  if (akm & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
2867
0
    return RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
2868
0
  if (akm & WPA_KEY_MGMT_OWE)
2869
0
    return RSN_AUTH_KEY_MGMT_OWE;
2870
0
  if (akm & WPA_KEY_MGMT_DPP)
2871
0
    return RSN_AUTH_KEY_MGMT_DPP;
2872
0
#ifdef CONFIG_PASN
2873
0
  if (akm & WPA_KEY_MGMT_PASN)
2874
0
    return RSN_AUTH_KEY_MGMT_PASN;
2875
0
#endif /* CONFIG_PASN */
2876
0
  return 0;
2877
0
}
2878
2879
2880
int wpa_compare_rsn_ie(int ft_initial_assoc,
2881
           const u8 *ie1, size_t ie1len,
2882
           const u8 *ie2, size_t ie2len)
2883
0
{
2884
0
  if (ie1 == NULL || ie2 == NULL)
2885
0
    return -1;
2886
2887
0
  if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
2888
0
    return 0; /* identical IEs */
2889
2890
0
#ifdef CONFIG_IEEE80211R
2891
0
  if (ft_initial_assoc) {
2892
0
    struct wpa_ie_data ie1d, ie2d;
2893
    /*
2894
     * The PMKID-List in RSN IE is different between Beacon/Probe
2895
     * Response/(Re)Association Request frames and EAPOL-Key
2896
     * messages in FT initial mobility domain association. Allow
2897
     * for this, but verify that other parts of the RSN IEs are
2898
     * identical.
2899
     */
2900
0
    if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
2901
0
        wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
2902
0
      return -1;
2903
0
    if (ie1d.proto == ie2d.proto &&
2904
0
        ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
2905
0
        ie1d.group_cipher == ie2d.group_cipher &&
2906
0
        ie1d.key_mgmt == ie2d.key_mgmt &&
2907
0
        ie1d.capabilities == ie2d.capabilities &&
2908
0
        ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
2909
0
      return 0;
2910
0
  }
2911
0
#endif /* CONFIG_IEEE80211R */
2912
2913
0
  return -1;
2914
0
}
2915
2916
2917
int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid, bool replace)
2918
0
{
2919
0
  u8 *start, *end, *rpos, *rend;
2920
0
  int added = 0;
2921
2922
0
  start = ies;
2923
0
  end = ies + *ies_len;
2924
2925
0
  while (start < end) {
2926
0
    if (*start == WLAN_EID_RSN)
2927
0
      break;
2928
0
    start += 2 + start[1];
2929
0
  }
2930
0
  if (start >= end) {
2931
0
    wpa_printf(MSG_ERROR, "RSN: Could not find RSNE in IEs data");
2932
0
    return -1;
2933
0
  }
2934
0
  wpa_hexdump(MSG_DEBUG, "RSN: RSNE before modification",
2935
0
        start, 2 + start[1]);
2936
2937
  /* Find start of PMKID-Count */
2938
0
  rpos = start + 2;
2939
0
  rend = rpos + start[1];
2940
2941
  /* Skip Version and Group Data Cipher Suite */
2942
0
  rpos += 2 + 4;
2943
  /* Skip Pairwise Cipher Suite Count and List */
2944
0
  rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
2945
  /* Skip AKM Suite Count and List */
2946
0
  rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
2947
2948
0
  if (rpos == rend) {
2949
    /* Add RSN Capabilities */
2950
0
    os_memmove(rpos + 2, rpos, end - rpos);
2951
0
    *rpos++ = 0;
2952
0
    *rpos++ = 0;
2953
0
    added += 2;
2954
0
    start[1] += 2;
2955
0
    rend = rpos;
2956
0
  } else {
2957
    /* Skip RSN Capabilities */
2958
0
    rpos += 2;
2959
0
    if (rpos > rend) {
2960
0
      wpa_printf(MSG_ERROR,
2961
0
           "RSN: Could not parse RSNE in IEs data");
2962
0
      return -1;
2963
0
    }
2964
0
  }
2965
2966
0
  if (rpos == rend) {
2967
    /* No PMKID-Count field included; add it */
2968
0
    os_memmove(rpos + 2 + PMKID_LEN, rpos, end + added - rpos);
2969
0
    WPA_PUT_LE16(rpos, 1);
2970
0
    rpos += 2;
2971
0
    os_memcpy(rpos, pmkid, PMKID_LEN);
2972
0
    added += 2 + PMKID_LEN;
2973
0
    start[1] += 2 + PMKID_LEN;
2974
0
  } else {
2975
0
    u16 num_pmkid;
2976
2977
0
    if (rend - rpos < 2)
2978
0
      return -1;
2979
0
    num_pmkid = WPA_GET_LE16(rpos);
2980
0
    if (num_pmkid * PMKID_LEN > rend - rpos - 2)
2981
0
      return -1;
2982
    /* PMKID-Count was included; use it */
2983
0
    if (replace && num_pmkid != 0) {
2984
0
      u8 *after;
2985
2986
      /*
2987
       * PMKID may have been included in RSN IE in
2988
       * (Re)Association Request frame, so remove the old
2989
       * PMKID(s) first before adding the new one.
2990
       */
2991
0
      wpa_printf(MSG_DEBUG,
2992
0
           "RSN: Remove %u old PMKID(s) from RSNE",
2993
0
           num_pmkid);
2994
0
      after = rpos + 2 + num_pmkid * PMKID_LEN;
2995
0
      os_memmove(rpos + 2, after, end - after);
2996
0
      start[1] -= num_pmkid * PMKID_LEN;
2997
0
      added -= num_pmkid * PMKID_LEN;
2998
0
      num_pmkid = 0;
2999
0
    }
3000
0
    WPA_PUT_LE16(rpos, num_pmkid + 1);
3001
0
    rpos += 2;
3002
0
    os_memmove(rpos + PMKID_LEN, rpos, end + added - rpos);
3003
0
    os_memcpy(rpos, pmkid, PMKID_LEN);
3004
0
    added += PMKID_LEN;
3005
0
    start[1] += PMKID_LEN;
3006
0
  }
3007
3008
0
  wpa_hexdump(MSG_DEBUG, "RSN: RSNE after modification (PMKID inserted)",
3009
0
        start, 2 + start[1]);
3010
3011
0
  *ies_len += added;
3012
3013
0
  return 0;
3014
0
}
3015
3016
3017
int wpa_cipher_key_len(int cipher)
3018
0
{
3019
0
  switch (cipher) {
3020
0
  case WPA_CIPHER_CCMP_256:
3021
0
  case WPA_CIPHER_GCMP_256:
3022
0
  case WPA_CIPHER_BIP_GMAC_256:
3023
0
  case WPA_CIPHER_BIP_CMAC_256:
3024
0
    return 32;
3025
0
  case WPA_CIPHER_CCMP:
3026
0
  case WPA_CIPHER_GCMP:
3027
0
  case WPA_CIPHER_AES_128_CMAC:
3028
0
  case WPA_CIPHER_BIP_GMAC_128:
3029
0
    return 16;
3030
0
  case WPA_CIPHER_TKIP:
3031
0
    return 32;
3032
0
  default:
3033
0
    return 0;
3034
0
  }
3035
0
}
3036
3037
3038
int wpa_cipher_rsc_len(int cipher)
3039
0
{
3040
0
  switch (cipher) {
3041
0
  case WPA_CIPHER_CCMP_256:
3042
0
  case WPA_CIPHER_GCMP_256:
3043
0
  case WPA_CIPHER_CCMP:
3044
0
  case WPA_CIPHER_GCMP:
3045
0
  case WPA_CIPHER_TKIP:
3046
0
    return 6;
3047
0
  default:
3048
0
    return 0;
3049
0
  }
3050
0
}
3051
3052
3053
enum wpa_alg wpa_cipher_to_alg(int cipher)
3054
0
{
3055
0
  switch (cipher) {
3056
0
  case WPA_CIPHER_CCMP_256:
3057
0
    return WPA_ALG_CCMP_256;
3058
0
  case WPA_CIPHER_GCMP_256:
3059
0
    return WPA_ALG_GCMP_256;
3060
0
  case WPA_CIPHER_CCMP:
3061
0
    return WPA_ALG_CCMP;
3062
0
  case WPA_CIPHER_GCMP:
3063
0
    return WPA_ALG_GCMP;
3064
0
  case WPA_CIPHER_TKIP:
3065
0
    return WPA_ALG_TKIP;
3066
0
  case WPA_CIPHER_AES_128_CMAC:
3067
0
    return WPA_ALG_BIP_CMAC_128;
3068
0
  case WPA_CIPHER_BIP_GMAC_128:
3069
0
    return WPA_ALG_BIP_GMAC_128;
3070
0
  case WPA_CIPHER_BIP_GMAC_256:
3071
0
    return WPA_ALG_BIP_GMAC_256;
3072
0
  case WPA_CIPHER_BIP_CMAC_256:
3073
0
    return WPA_ALG_BIP_CMAC_256;
3074
0
  default:
3075
0
    return WPA_ALG_NONE;
3076
0
  }
3077
0
}
3078
3079
3080
int wpa_cipher_valid_pairwise(int cipher)
3081
604
{
3082
#ifdef CONFIG_NO_TKIP
3083
  return cipher == WPA_CIPHER_CCMP_256 ||
3084
    cipher == WPA_CIPHER_GCMP_256 ||
3085
    cipher == WPA_CIPHER_CCMP ||
3086
    cipher == WPA_CIPHER_GCMP;
3087
#else /* CONFIG_NO_TKIP */
3088
604
  return cipher == WPA_CIPHER_CCMP_256 ||
3089
604
    cipher == WPA_CIPHER_GCMP_256 ||
3090
604
    cipher == WPA_CIPHER_CCMP ||
3091
604
    cipher == WPA_CIPHER_GCMP ||
3092
604
    cipher == WPA_CIPHER_TKIP;
3093
604
#endif /* CONFIG_NO_TKIP */
3094
604
}
3095
3096
3097
u32 wpa_cipher_to_suite(int proto, int cipher)
3098
0
{
3099
0
  if (cipher & WPA_CIPHER_CCMP_256)
3100
0
    return RSN_CIPHER_SUITE_CCMP_256;
3101
0
  if (cipher & WPA_CIPHER_GCMP_256)
3102
0
    return RSN_CIPHER_SUITE_GCMP_256;
3103
0
  if (cipher & WPA_CIPHER_CCMP)
3104
0
    return (proto == WPA_PROTO_RSN ?
3105
0
      RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
3106
0
  if (cipher & WPA_CIPHER_GCMP)
3107
0
    return RSN_CIPHER_SUITE_GCMP;
3108
0
  if (cipher & WPA_CIPHER_TKIP)
3109
0
    return (proto == WPA_PROTO_RSN ?
3110
0
      RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
3111
0
  if (cipher & WPA_CIPHER_NONE)
3112
0
    return (proto == WPA_PROTO_RSN ?
3113
0
      RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
3114
0
  if (cipher & WPA_CIPHER_GTK_NOT_USED)
3115
0
    return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
3116
0
  if (cipher & WPA_CIPHER_AES_128_CMAC)
3117
0
    return RSN_CIPHER_SUITE_AES_128_CMAC;
3118
0
  if (cipher & WPA_CIPHER_BIP_GMAC_128)
3119
0
    return RSN_CIPHER_SUITE_BIP_GMAC_128;
3120
0
  if (cipher & WPA_CIPHER_BIP_GMAC_256)
3121
0
    return RSN_CIPHER_SUITE_BIP_GMAC_256;
3122
0
  if (cipher & WPA_CIPHER_BIP_CMAC_256)
3123
0
    return RSN_CIPHER_SUITE_BIP_CMAC_256;
3124
0
  return 0;
3125
0
}
3126
3127
3128
int rsn_cipher_put_suites(u8 *start, int ciphers)
3129
0
{
3130
0
  u8 *pos = start;
3131
3132
0
  if (ciphers & WPA_CIPHER_CCMP_256) {
3133
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
3134
0
    pos += RSN_SELECTOR_LEN;
3135
0
  }
3136
0
  if (ciphers & WPA_CIPHER_GCMP_256) {
3137
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
3138
0
    pos += RSN_SELECTOR_LEN;
3139
0
  }
3140
0
  if (ciphers & WPA_CIPHER_CCMP) {
3141
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
3142
0
    pos += RSN_SELECTOR_LEN;
3143
0
  }
3144
0
  if (ciphers & WPA_CIPHER_GCMP) {
3145
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
3146
0
    pos += RSN_SELECTOR_LEN;
3147
0
  }
3148
0
  if (ciphers & WPA_CIPHER_TKIP) {
3149
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
3150
0
    pos += RSN_SELECTOR_LEN;
3151
0
  }
3152
0
  if (ciphers & WPA_CIPHER_NONE) {
3153
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
3154
0
    pos += RSN_SELECTOR_LEN;
3155
0
  }
3156
3157
0
  return (pos - start) / RSN_SELECTOR_LEN;
3158
0
}
3159
3160
3161
int wpa_cipher_put_suites(u8 *start, int ciphers)
3162
0
{
3163
0
  u8 *pos = start;
3164
3165
0
  if (ciphers & WPA_CIPHER_CCMP) {
3166
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
3167
0
    pos += WPA_SELECTOR_LEN;
3168
0
  }
3169
0
  if (ciphers & WPA_CIPHER_TKIP) {
3170
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
3171
0
    pos += WPA_SELECTOR_LEN;
3172
0
  }
3173
0
  if (ciphers & WPA_CIPHER_NONE) {
3174
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
3175
0
    pos += WPA_SELECTOR_LEN;
3176
0
  }
3177
3178
0
  return (pos - start) / RSN_SELECTOR_LEN;
3179
0
}
3180
3181
3182
int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
3183
0
{
3184
0
  if (ciphers & WPA_CIPHER_GCMP_256)
3185
0
    return WPA_CIPHER_GCMP_256;
3186
0
  if (ciphers & WPA_CIPHER_CCMP_256)
3187
0
    return WPA_CIPHER_CCMP_256;
3188
0
  if (ciphers & WPA_CIPHER_CCMP)
3189
0
    return WPA_CIPHER_CCMP;
3190
0
  if (ciphers & WPA_CIPHER_GCMP)
3191
0
    return WPA_CIPHER_GCMP;
3192
0
  if (ciphers & WPA_CIPHER_TKIP)
3193
0
    return WPA_CIPHER_TKIP;
3194
0
  if (none_allowed && (ciphers & WPA_CIPHER_NONE))
3195
0
    return WPA_CIPHER_NONE;
3196
0
  return -1;
3197
0
}
3198
3199
3200
int wpa_pick_group_cipher(int ciphers)
3201
0
{
3202
0
  if (ciphers & WPA_CIPHER_GCMP_256)
3203
0
    return WPA_CIPHER_GCMP_256;
3204
0
  if (ciphers & WPA_CIPHER_CCMP_256)
3205
0
    return WPA_CIPHER_CCMP_256;
3206
0
  if (ciphers & WPA_CIPHER_CCMP)
3207
0
    return WPA_CIPHER_CCMP;
3208
0
  if (ciphers & WPA_CIPHER_GCMP)
3209
0
    return WPA_CIPHER_GCMP;
3210
0
  if (ciphers & WPA_CIPHER_GTK_NOT_USED)
3211
0
    return WPA_CIPHER_GTK_NOT_USED;
3212
0
  if (ciphers & WPA_CIPHER_TKIP)
3213
0
    return WPA_CIPHER_TKIP;
3214
0
  return -1;
3215
0
}
3216
3217
3218
int wpa_parse_cipher(const char *value)
3219
0
{
3220
0
  int val = 0, last;
3221
0
  char *start, *end, *buf;
3222
3223
0
  buf = os_strdup(value);
3224
0
  if (buf == NULL)
3225
0
    return -1;
3226
0
  start = buf;
3227
3228
0
  while (*start != '\0') {
3229
0
    while (*start == ' ' || *start == '\t')
3230
0
      start++;
3231
0
    if (*start == '\0')
3232
0
      break;
3233
0
    end = start;
3234
0
    while (*end != ' ' && *end != '\t' && *end != '\0')
3235
0
      end++;
3236
0
    last = *end == '\0';
3237
0
    *end = '\0';
3238
0
    if (os_strcmp(start, "CCMP-256") == 0)
3239
0
      val |= WPA_CIPHER_CCMP_256;
3240
0
    else if (os_strcmp(start, "GCMP-256") == 0)
3241
0
      val |= WPA_CIPHER_GCMP_256;
3242
0
    else if (os_strcmp(start, "CCMP") == 0)
3243
0
      val |= WPA_CIPHER_CCMP;
3244
0
    else if (os_strcmp(start, "GCMP") == 0)
3245
0
      val |= WPA_CIPHER_GCMP;
3246
0
#ifndef CONFIG_NO_TKIP
3247
0
    else if (os_strcmp(start, "TKIP") == 0)
3248
0
      val |= WPA_CIPHER_TKIP;
3249
0
#endif /* CONFIG_NO_TKIP */
3250
#ifdef CONFIG_WEP
3251
    else if (os_strcmp(start, "WEP104") == 0)
3252
      val |= WPA_CIPHER_WEP104;
3253
    else if (os_strcmp(start, "WEP40") == 0)
3254
      val |= WPA_CIPHER_WEP40;
3255
#endif /* CONFIG_WEP */
3256
0
    else if (os_strcmp(start, "NONE") == 0)
3257
0
      val |= WPA_CIPHER_NONE;
3258
0
    else if (os_strcmp(start, "GTK_NOT_USED") == 0)
3259
0
      val |= WPA_CIPHER_GTK_NOT_USED;
3260
0
    else if (os_strcmp(start, "AES-128-CMAC") == 0)
3261
0
      val |= WPA_CIPHER_AES_128_CMAC;
3262
0
    else if (os_strcmp(start, "BIP-GMAC-128") == 0)
3263
0
      val |= WPA_CIPHER_BIP_GMAC_128;
3264
0
    else if (os_strcmp(start, "BIP-GMAC-256") == 0)
3265
0
      val |= WPA_CIPHER_BIP_GMAC_256;
3266
0
    else if (os_strcmp(start, "BIP-CMAC-256") == 0)
3267
0
      val |= WPA_CIPHER_BIP_CMAC_256;
3268
0
    else {
3269
0
      os_free(buf);
3270
0
      return -1;
3271
0
    }
3272
3273
0
    if (last)
3274
0
      break;
3275
0
    start = end + 1;
3276
0
  }
3277
0
  os_free(buf);
3278
3279
0
  return val;
3280
0
}
3281
3282
3283
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
3284
0
{
3285
0
  char *pos = start;
3286
0
  int ret;
3287
3288
0
  if (ciphers & WPA_CIPHER_CCMP_256) {
3289
0
    ret = os_snprintf(pos, end - pos, "%sCCMP-256",
3290
0
          pos == start ? "" : delim);
3291
0
    if (os_snprintf_error(end - pos, ret))
3292
0
      return -1;
3293
0
    pos += ret;
3294
0
  }
3295
0
  if (ciphers & WPA_CIPHER_GCMP_256) {
3296
0
    ret = os_snprintf(pos, end - pos, "%sGCMP-256",
3297
0
          pos == start ? "" : delim);
3298
0
    if (os_snprintf_error(end - pos, ret))
3299
0
      return -1;
3300
0
    pos += ret;
3301
0
  }
3302
0
  if (ciphers & WPA_CIPHER_CCMP) {
3303
0
    ret = os_snprintf(pos, end - pos, "%sCCMP",
3304
0
          pos == start ? "" : delim);
3305
0
    if (os_snprintf_error(end - pos, ret))
3306
0
      return -1;
3307
0
    pos += ret;
3308
0
  }
3309
0
  if (ciphers & WPA_CIPHER_GCMP) {
3310
0
    ret = os_snprintf(pos, end - pos, "%sGCMP",
3311
0
          pos == start ? "" : delim);
3312
0
    if (os_snprintf_error(end - pos, ret))
3313
0
      return -1;
3314
0
    pos += ret;
3315
0
  }
3316
0
  if (ciphers & WPA_CIPHER_TKIP) {
3317
0
    ret = os_snprintf(pos, end - pos, "%sTKIP",
3318
0
          pos == start ? "" : delim);
3319
0
    if (os_snprintf_error(end - pos, ret))
3320
0
      return -1;
3321
0
    pos += ret;
3322
0
  }
3323
0
  if (ciphers & WPA_CIPHER_AES_128_CMAC) {
3324
0
    ret = os_snprintf(pos, end - pos, "%sAES-128-CMAC",
3325
0
          pos == start ? "" : delim);
3326
0
    if (os_snprintf_error(end - pos, ret))
3327
0
      return -1;
3328
0
    pos += ret;
3329
0
  }
3330
0
  if (ciphers & WPA_CIPHER_BIP_GMAC_128) {
3331
0
    ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-128",
3332
0
          pos == start ? "" : delim);
3333
0
    if (os_snprintf_error(end - pos, ret))
3334
0
      return -1;
3335
0
    pos += ret;
3336
0
  }
3337
0
  if (ciphers & WPA_CIPHER_BIP_GMAC_256) {
3338
0
    ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-256",
3339
0
          pos == start ? "" : delim);
3340
0
    if (os_snprintf_error(end - pos, ret))
3341
0
      return -1;
3342
0
    pos += ret;
3343
0
  }
3344
0
  if (ciphers & WPA_CIPHER_BIP_CMAC_256) {
3345
0
    ret = os_snprintf(pos, end - pos, "%sBIP-CMAC-256",
3346
0
          pos == start ? "" : delim);
3347
0
    if (os_snprintf_error(end - pos, ret))
3348
0
      return -1;
3349
0
    pos += ret;
3350
0
  }
3351
0
  if (ciphers & WPA_CIPHER_NONE) {
3352
0
    ret = os_snprintf(pos, end - pos, "%sNONE",
3353
0
          pos == start ? "" : delim);
3354
0
    if (os_snprintf_error(end - pos, ret))
3355
0
      return -1;
3356
0
    pos += ret;
3357
0
  }
3358
3359
0
  return pos - start;
3360
0
}
3361
3362
3363
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
3364
0
{
3365
0
  int pairwise = 0;
3366
3367
  /* Select group cipher based on the enabled pairwise cipher suites */
3368
0
  if (wpa & 1)
3369
0
    pairwise |= wpa_pairwise;
3370
0
  if (wpa & 2)
3371
0
    pairwise |= rsn_pairwise;
3372
3373
0
  if (pairwise & WPA_CIPHER_TKIP)
3374
0
    return WPA_CIPHER_TKIP;
3375
0
  if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
3376
0
    return WPA_CIPHER_GCMP;
3377
0
  if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
3378
0
       WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
3379
0
    return WPA_CIPHER_GCMP_256;
3380
0
  if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
3381
0
       WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
3382
0
    return WPA_CIPHER_CCMP_256;
3383
0
  return WPA_CIPHER_CCMP;
3384
0
}
3385
3386
3387
#ifdef CONFIG_FILS
3388
int fils_domain_name_hash(const char *domain, u8 *hash)
3389
0
{
3390
0
  char buf[255], *wpos = buf;
3391
0
  const char *pos = domain;
3392
0
  size_t len;
3393
0
  const u8 *addr[1];
3394
0
  u8 mac[SHA256_MAC_LEN];
3395
3396
0
  for (len = 0; len < sizeof(buf) && *pos; len++) {
3397
0
    if (isalpha(*pos) && isupper(*pos))
3398
0
      *wpos++ = tolower(*pos);
3399
0
    else
3400
0
      *wpos++ = *pos;
3401
0
    pos++;
3402
0
  }
3403
3404
0
  addr[0] = (const u8 *) buf;
3405
0
  if (sha256_vector(1, addr, &len, mac) < 0)
3406
0
    return -1;
3407
0
  os_memcpy(hash, mac, 2);
3408
0
  return 0;
3409
0
}
3410
#endif /* CONFIG_FILS */
3411
3412
3413
/**
3414
 * wpa_parse_vendor_specific - Parse Vendor Specific IEs
3415
 * @pos: Pointer to the IE header
3416
 * @end: Pointer to the end of the Key Data buffer
3417
 * @ie: Pointer to parsed IE data
3418
 */
3419
static void wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
3420
              struct wpa_eapol_ie_parse *ie)
3421
0
{
3422
0
  unsigned int oui;
3423
3424
0
  if (pos[1] < 4) {
3425
0
    wpa_printf(MSG_MSGDUMP,
3426
0
         "Too short vendor specific IE ignored (len=%u)",
3427
0
         pos[1]);
3428
0
    return;
3429
0
  }
3430
3431
0
  oui = WPA_GET_BE24(&pos[2]);
3432
0
  if (oui == OUI_MICROSOFT && pos[5] == WMM_OUI_TYPE && pos[1] > 4) {
3433
0
    if (pos[6] == WMM_OUI_SUBTYPE_INFORMATION_ELEMENT) {
3434
0
      ie->wmm = &pos[2];
3435
0
      ie->wmm_len = pos[1];
3436
0
      wpa_hexdump(MSG_DEBUG, "WPA: WMM IE",
3437
0
            ie->wmm, ie->wmm_len);
3438
0
    } else if (pos[6] == WMM_OUI_SUBTYPE_PARAMETER_ELEMENT) {
3439
0
      ie->wmm = &pos[2];
3440
0
      ie->wmm_len = pos[1];
3441
0
      wpa_hexdump(MSG_DEBUG, "WPA: WMM Parameter Element",
3442
0
            ie->wmm, ie->wmm_len);
3443
0
    }
3444
0
  }
3445
0
}
3446
3447
3448
/**
3449
 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
3450
 * @pos: Pointer to the IE header
3451
 * @ie: Pointer to parsed IE data
3452
 * Returns: 0 on success, 1 if end mark is found, 2 if KDE is not recognized
3453
 */
3454
static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
3455
0
{
3456
0
  u8 len = pos[1];
3457
0
  size_t dlen = 2 + len;
3458
0
  u32 selector;
3459
0
  const u8 *p;
3460
0
  size_t left;
3461
0
  u8 link_id;
3462
0
  char title[100];
3463
0
  int ret;
3464
3465
0
  if (len == 0)
3466
0
    return 1;
3467
3468
0
  if (len < RSN_SELECTOR_LEN)
3469
0
    return 2;
3470
3471
0
  p = pos + 2;
3472
0
  selector = RSN_SELECTOR_GET(p);
3473
0
  p += RSN_SELECTOR_LEN;
3474
0
  left = len - RSN_SELECTOR_LEN;
3475
3476
0
  if (left >= 2 && selector == WPA_OUI_TYPE && p[0] == 1 && p[1] == 0) {
3477
0
    ie->wpa_ie = pos;
3478
0
    ie->wpa_ie_len = dlen;
3479
0
    wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
3480
0
          ie->wpa_ie, ie->wpa_ie_len);
3481
0
    return 0;
3482
0
  }
3483
3484
0
  if (left >= PMKID_LEN && selector == RSN_KEY_DATA_PMKID) {
3485
0
    ie->pmkid = p;
3486
0
    wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key", pos, dlen);
3487
0
    return 0;
3488
0
  }
3489
3490
0
  if (left >= 2 && selector == RSN_KEY_DATA_KEYID) {
3491
0
    ie->key_id = p;
3492
0
    wpa_hexdump(MSG_DEBUG, "WPA: KeyID in EAPOL-Key", pos, dlen);
3493
0
    return 0;
3494
0
  }
3495
3496
0
  if (left > 2 && selector == RSN_KEY_DATA_GROUPKEY) {
3497
0
    ie->gtk = p;
3498
0
    ie->gtk_len = left;
3499
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key", pos, dlen);
3500
0
    return 0;
3501
0
  }
3502
3503
0
  if (left >= ETH_ALEN && selector == RSN_KEY_DATA_MAC_ADDR) {
3504
0
    ie->mac_addr = p;
3505
0
    wpa_printf(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key: " MACSTR,
3506
0
         MAC2STR(ie->mac_addr));
3507
0
    return 0;
3508
0
  }
3509
3510
0
  if (left > 2 && selector == RSN_KEY_DATA_IGTK) {
3511
0
    ie->igtk = p;
3512
0
    ie->igtk_len = left;
3513
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
3514
0
        pos, dlen);
3515
0
    return 0;
3516
0
  }
3517
3518
0
  if (left > 2 && selector == RSN_KEY_DATA_BIGTK) {
3519
0
    ie->bigtk = p;
3520
0
    ie->bigtk_len = left;
3521
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: BIGTK in EAPOL-Key",
3522
0
        pos, dlen);
3523
0
    return 0;
3524
0
  }
3525
3526
0
  if (left >= 1 && selector == WFA_KEY_DATA_IP_ADDR_REQ) {
3527
0
    ie->ip_addr_req = p;
3528
0
    wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
3529
0
          ie->ip_addr_req, left);
3530
0
    return 0;
3531
0
  }
3532
3533
0
  if (left >= 3 * 4 && selector == WFA_KEY_DATA_IP_ADDR_ALLOC) {
3534
0
    ie->ip_addr_alloc = p;
3535
0
    wpa_hexdump(MSG_DEBUG,
3536
0
          "WPA: IP Address Allocation in EAPOL-Key",
3537
0
          ie->ip_addr_alloc, left);
3538
0
    return 0;
3539
0
  }
3540
3541
0
  if (left > 2 && selector == RSN_KEY_DATA_OCI) {
3542
0
    ie->oci = p;
3543
0
    ie->oci_len = left;
3544
0
    wpa_hexdump(MSG_DEBUG, "WPA: OCI KDE in EAPOL-Key",
3545
0
          pos, dlen);
3546
0
    return 0;
3547
0
  }
3548
3549
0
  if (left >= 1 && selector == WFA_KEY_DATA_TRANSITION_DISABLE) {
3550
0
    ie->transition_disable = p;
3551
0
    ie->transition_disable_len = left;
3552
0
    wpa_hexdump(MSG_DEBUG,
3553
0
          "WPA: Transition Disable KDE in EAPOL-Key",
3554
0
          pos, dlen);
3555
0
    return 0;
3556
0
  }
3557
3558
0
  if (left >= 2 && selector == WFA_KEY_DATA_DPP) {
3559
0
    ie->dpp_kde = p;
3560
0
    ie->dpp_kde_len = left;
3561
0
    wpa_hexdump(MSG_DEBUG, "WPA: DPP KDE in EAPOL-Key", pos, dlen);
3562
0
    return 0;
3563
0
  }
3564
3565
0
  if (left >= RSN_MLO_GTK_KDE_PREFIX_LENGTH &&
3566
0
      selector == RSN_KEY_DATA_MLO_GTK) {
3567
0
    link_id = (p[0] & RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK) >>
3568
0
      RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT;
3569
0
    if (link_id >= MAX_NUM_MLD_LINKS)
3570
0
      return 2;
3571
3572
0
    ie->valid_mlo_gtks |= BIT(link_id);
3573
0
    ie->mlo_gtk[link_id] = p;
3574
0
    ie->mlo_gtk_len[link_id] = left;
3575
0
    ret = os_snprintf(title, sizeof(title),
3576
0
          "RSN: Link ID %u - MLO GTK KDE in EAPOL-Key",
3577
0
          link_id);
3578
0
    if (!os_snprintf_error(sizeof(title), ret))
3579
0
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3580
0
    return 0;
3581
0
  }
3582
3583
0
  if (left >= RSN_MLO_IGTK_KDE_PREFIX_LENGTH &&
3584
0
      selector == RSN_KEY_DATA_MLO_IGTK) {
3585
0
    link_id = (p[8] & RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK) >>
3586
0
        RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT;
3587
0
    if (link_id >= MAX_NUM_MLD_LINKS)
3588
0
      return 2;
3589
3590
0
    ie->valid_mlo_igtks |= BIT(link_id);
3591
0
    ie->mlo_igtk[link_id] = p;
3592
0
    ie->mlo_igtk_len[link_id] = left;
3593
0
    ret = os_snprintf(title, sizeof(title),
3594
0
          "RSN: Link ID %u - MLO IGTK KDE in EAPOL-Key",
3595
0
          link_id);
3596
0
    if (!os_snprintf_error(sizeof(title), ret))
3597
0
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3598
0
    return 0;
3599
0
  }
3600
3601
0
  if (left >= RSN_MLO_BIGTK_KDE_PREFIX_LENGTH &&
3602
0
      selector == RSN_KEY_DATA_MLO_BIGTK) {
3603
0
    link_id = (p[8] & RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK) >>
3604
0
        RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT;
3605
0
    if (link_id >= MAX_NUM_MLD_LINKS)
3606
0
      return 2;
3607
3608
0
    ie->valid_mlo_bigtks |= BIT(link_id);
3609
0
    ie->mlo_bigtk[link_id] = p;
3610
0
    ie->mlo_bigtk_len[link_id] = left;
3611
0
    ret = os_snprintf(title, sizeof(title),
3612
0
          "RSN: Link ID %u - MLO BIGTK KDE in EAPOL-Key",
3613
0
          link_id);
3614
0
    if (!os_snprintf_error(sizeof(title), ret))
3615
0
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
3616
0
    return 0;
3617
0
  }
3618
3619
0
  if (left >= RSN_MLO_LINK_KDE_FIXED_LENGTH &&
3620
0
      selector == RSN_KEY_DATA_MLO_LINK) {
3621
0
    link_id = (p[0] & RSN_MLO_LINK_KDE_LI_LINK_ID_MASK) >>
3622
0
        RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT;
3623
0
    if (link_id >= MAX_NUM_MLD_LINKS)
3624
0
      return 2;
3625
3626
0
    ie->valid_mlo_links |= BIT(link_id);
3627
0
    ie->mlo_link[link_id] = p;
3628
0
    ie->mlo_link_len[link_id] = left;
3629
0
    ret = os_snprintf(title, sizeof(title),
3630
0
          "RSN: Link ID %u - MLO Link KDE in EAPOL-Key",
3631
0
          link_id);
3632
0
    if (!os_snprintf_error(sizeof(title), ret))
3633
0
      wpa_hexdump(MSG_DEBUG, title, pos, dlen);
3634
0
    return 0;
3635
0
  }
3636
3637
0
  if (left >= 1 && selector == WFA_KEY_DATA_RSN_OVERRIDE_LINK) {
3638
0
    link_id = p[0];
3639
0
    if (link_id >= MAX_NUM_MLD_LINKS)
3640
0
      return 2;
3641
3642
0
    ie->rsn_override_link[link_id] = p;
3643
0
    ie->rsn_override_link_len[link_id] = left;
3644
0
    ret = os_snprintf(title, sizeof(title),
3645
0
          "RSN: Link ID %u - RSN Override Link KDE in EAPOL-Key",
3646
0
          link_id);
3647
0
    if (!os_snprintf_error(sizeof(title), ret))
3648
0
      wpa_hexdump(MSG_DEBUG, title, pos, dlen);
3649
0
    return 0;
3650
0
  }
3651
3652
0
  if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
3653
0
    ie->rsne_override = pos;
3654
0
    ie->rsne_override_len = dlen;
3655
0
    wpa_hexdump(MSG_DEBUG,
3656
0
          "RSN: RSNE Override element in EAPOL-Key",
3657
0
          ie->rsne_override, ie->rsne_override_len);
3658
0
    return 0;
3659
0
  }
3660
3661
0
  if (selector == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
3662
0
    ie->rsne_override_2 = pos;
3663
0
    ie->rsne_override_2_len = dlen;
3664
0
    wpa_hexdump(MSG_DEBUG,
3665
0
          "RSN: RSNE Override 2 element in EAPOL-Key",
3666
0
          ie->rsne_override_2, ie->rsne_override_2_len);
3667
0
    return 0;
3668
0
  }
3669
3670
0
  if (selector == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
3671
0
    ie->rsnxe_override = pos;
3672
0
    ie->rsnxe_override_len = dlen;
3673
0
    wpa_hexdump(MSG_DEBUG,
3674
0
          "RSN: RSNXE Override element in EAPOL-Key",
3675
0
          ie->rsnxe_override, ie->rsnxe_override_len);
3676
0
    return 0;
3677
0
  }
3678
3679
0
  if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
3680
0
    ie->rsn_selection = p;
3681
0
    ie->rsn_selection_len = left;
3682
0
    wpa_hexdump(MSG_DEBUG,
3683
0
          "RSN: RSN Selection element in EAPOL-Key",
3684
0
          ie->rsn_selection, ie->rsn_selection_len);
3685
0
    return 0;
3686
0
  }
3687
3688
0
  return 2;
3689
0
}
3690
3691
3692
/**
3693
 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
3694
 * @buf: Pointer to the Key Data buffer
3695
 * @len: Key Data Length
3696
 * @ie: Pointer to parsed IE data
3697
 * Returns: 0 on success, -1 on failure
3698
 */
3699
int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
3700
0
{
3701
0
  const u8 *pos, *end;
3702
0
  int ret = 0;
3703
0
  size_t dlen = 0;
3704
3705
0
  os_memset(ie, 0, sizeof(*ie));
3706
0
  for (pos = buf, end = pos + len; end - pos > 1; pos += dlen) {
3707
0
    if (pos[0] == 0xdd &&
3708
0
        ((pos == buf + len - 1) || pos[1] == 0)) {
3709
      /* Ignore padding */
3710
0
      break;
3711
0
    }
3712
0
    dlen = 2 + pos[1];
3713
0
    if ((int) dlen > end - pos) {
3714
0
      wpa_printf(MSG_DEBUG,
3715
0
           "WPA: EAPOL-Key Key Data underflow (ie=%d len=%d pos=%d)",
3716
0
           pos[0], pos[1], (int) (pos - buf));
3717
0
      wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", buf, len);
3718
0
      ret = -1;
3719
0
      break;
3720
0
    }
3721
0
    if (*pos == WLAN_EID_RSN) {
3722
0
      ie->rsn_ie = pos;
3723
0
      ie->rsn_ie_len = dlen;
3724
0
      wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
3725
0
            ie->rsn_ie, ie->rsn_ie_len);
3726
0
    } else if (*pos == WLAN_EID_RSNX) {
3727
0
      ie->rsnxe = pos;
3728
0
      ie->rsnxe_len = dlen;
3729
0
      wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
3730
0
            ie->rsnxe, ie->rsnxe_len);
3731
0
    } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
3732
0
      ie->mdie = pos;
3733
0
      ie->mdie_len = dlen;
3734
0
      wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
3735
0
            ie->mdie, ie->mdie_len);
3736
0
    } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
3737
0
      ie->ftie = pos;
3738
0
      ie->ftie_len = dlen;
3739
0
      wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
3740
0
            ie->ftie, ie->ftie_len);
3741
0
    } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
3742
0
      if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
3743
0
        ie->reassoc_deadline = pos;
3744
0
        wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
3745
0
              "in EAPOL-Key",
3746
0
              ie->reassoc_deadline, dlen);
3747
0
      } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
3748
0
        ie->key_lifetime = pos;
3749
0
        wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
3750
0
              "in EAPOL-Key",
3751
0
              ie->key_lifetime, dlen);
3752
0
      } else {
3753
0
        wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
3754
0
              "EAPOL-Key Key Data IE",
3755
0
              pos, dlen);
3756
0
      }
3757
0
    } else if (*pos == WLAN_EID_LINK_ID) {
3758
0
      if (pos[1] >= 18) {
3759
0
        ie->lnkid = pos;
3760
0
        ie->lnkid_len = dlen;
3761
0
      }
3762
0
    } else if (*pos == WLAN_EID_EXT_CAPAB) {
3763
0
      ie->ext_capab = pos;
3764
0
      ie->ext_capab_len = dlen;
3765
0
    } else if (*pos == WLAN_EID_SUPP_RATES) {
3766
0
      ie->supp_rates = pos;
3767
0
      ie->supp_rates_len = dlen;
3768
0
    } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
3769
0
      ie->ext_supp_rates = pos;
3770
0
      ie->ext_supp_rates_len = dlen;
3771
0
    } else if (*pos == WLAN_EID_HT_CAP &&
3772
0
         pos[1] >= sizeof(struct ieee80211_ht_capabilities)) {
3773
0
      ie->ht_capabilities = pos + 2;
3774
0
    } else if (*pos == WLAN_EID_AID) {
3775
0
      if (pos[1] >= 2)
3776
0
        ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
3777
0
    } else if (*pos == WLAN_EID_VHT_CAP &&
3778
0
         pos[1] >= sizeof(struct ieee80211_vht_capabilities))
3779
0
    {
3780
0
      ie->vht_capabilities = pos + 2;
3781
0
    } else if (*pos == WLAN_EID_EXTENSION &&
3782
0
         pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN &&
3783
0
         pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) {
3784
0
      ie->he_capabilities = pos + 3;
3785
0
      ie->he_capab_len = pos[1] - 1;
3786
0
    } else if (*pos == WLAN_EID_EXTENSION &&
3787
0
         pos[1] >= 1 +
3788
0
         sizeof(struct ieee80211_he_6ghz_band_cap) &&
3789
0
         pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) {
3790
0
      ie->he_6ghz_capabilities = pos + 3;
3791
0
    } else if (*pos == WLAN_EID_EXTENSION &&
3792
0
         pos[1] >= 1 + IEEE80211_EHT_CAPAB_MIN_LEN &&
3793
0
         pos[2] == WLAN_EID_EXT_EHT_CAPABILITIES) {
3794
0
      ie->eht_capabilities = pos + 3;
3795
0
      ie->eht_capab_len = pos[1] - 1;
3796
0
    } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
3797
0
      ie->qosinfo = pos[2];
3798
0
    } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
3799
0
      ie->supp_channels = pos + 2;
3800
0
      ie->supp_channels_len = pos[1];
3801
0
    } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
3802
      /*
3803
       * The value of the Length field of the Supported
3804
       * Operating Classes element is between 2 and 253.
3805
       * Silently skip invalid elements to avoid interop
3806
       * issues when trying to use the value.
3807
       */
3808
0
      if (pos[1] >= 2 && pos[1] <= 253) {
3809
0
        ie->supp_oper_classes = pos + 2;
3810
0
        ie->supp_oper_classes_len = pos[1];
3811
0
      }
3812
0
    } else if (*pos == WLAN_EID_SSID) {
3813
0
      ie->ssid = pos + 2;
3814
0
      ie->ssid_len = pos[1];
3815
0
      wpa_hexdump_ascii(MSG_DEBUG, "RSN: SSID in EAPOL-Key",
3816
0
            ie->ssid, ie->ssid_len);
3817
0
    } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
3818
0
      ret = wpa_parse_generic(pos, ie);
3819
0
      if (ret == 1) {
3820
        /* end mark found */
3821
0
        ret = 0;
3822
0
        break;
3823
0
      }
3824
3825
0
      if (ret == 2) {
3826
        /* not a known KDE */
3827
0
        wpa_parse_vendor_specific(pos, end, ie);
3828
0
      }
3829
3830
0
      ret = 0;
3831
0
    } else {
3832
0
      wpa_hexdump(MSG_DEBUG,
3833
0
            "WPA: Unrecognized EAPOL-Key Key Data IE",
3834
0
            pos, dlen);
3835
0
    }
3836
0
  }
3837
3838
0
  return ret;
3839
0
}
3840
3841
3842
#ifdef CONFIG_PASN
3843
3844
/*
3845
 * wpa_pasn_build_auth_header - Add the MAC header and initialize Authentication
3846
 * frame for PASN
3847
 *
3848
 * @buf: Buffer in which the header will be added
3849
 * @bssid: The BSSID of the AP
3850
 * @src: Source address
3851
 * @dst: Destination address
3852
 * @trans_seq: Authentication transaction sequence number
3853
 * @status: Authentication status
3854
 */
3855
void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
3856
        const u8 *src, const u8 *dst,
3857
        u8 trans_seq, u16 status)
3858
2.75k
{
3859
2.75k
  struct ieee80211_mgmt *auth;
3860
3861
2.75k
  wpa_printf(MSG_DEBUG, "PASN: Add authentication header. trans_seq=%u",
3862
2.75k
       trans_seq);
3863
3864
2.75k
  auth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
3865
2.75k
          u.auth.variable));
3866
3867
2.75k
  auth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
3868
2.75k
             (WLAN_FC_STYPE_AUTH << 4));
3869
3870
2.75k
  os_memcpy(auth->da, dst, ETH_ALEN);
3871
2.75k
  os_memcpy(auth->sa, src, ETH_ALEN);
3872
2.75k
  os_memcpy(auth->bssid, bssid, ETH_ALEN);
3873
2.75k
  auth->seq_ctrl = 0;
3874
3875
2.75k
  auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_PASN);
3876
2.75k
  auth->u.auth.auth_transaction = host_to_le16(trans_seq);
3877
2.75k
  auth->u.auth.status_code = host_to_le16(status);
3878
2.75k
}
3879
3880
3881
/*
3882
 * wpa_pasn_add_rsne - Add an RSNE for PASN authentication
3883
 * @buf: Buffer in which the IE will be added
3884
 * @pmkid: Optional PMKID. Can be NULL.
3885
 * @akmp: Authentication and key management protocol
3886
 * @cipher: The cipher suite
3887
 */
3888
int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid, int akmp, int cipher)
3889
0
{
3890
0
  struct rsn_ie_hdr *hdr;
3891
0
  u32 suite;
3892
0
  u16 capab;
3893
0
  u8 *pos;
3894
0
  u8 rsne_len;
3895
3896
0
  wpa_printf(MSG_DEBUG, "PASN: Add RSNE");
3897
3898
0
  rsne_len = sizeof(*hdr) + RSN_SELECTOR_LEN +
3899
0
    2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN +
3900
0
    2 + RSN_SELECTOR_LEN + 2 + (pmkid ? PMKID_LEN : 0);
3901
3902
0
  if (wpabuf_tailroom(buf) < rsne_len)
3903
0
    return -1;
3904
0
  hdr = wpabuf_put(buf, rsne_len);
3905
0
  hdr->elem_id = WLAN_EID_RSN;
3906
0
  hdr->len = rsne_len - 2;
3907
0
  WPA_PUT_LE16(hdr->version, RSN_VERSION);
3908
0
  pos = (u8 *) (hdr + 1);
3909
3910
  /* Group addressed data is not allowed */
3911
0
  RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
3912
0
  pos += RSN_SELECTOR_LEN;
3913
3914
  /* Add the pairwise cipher */
3915
0
  WPA_PUT_LE16(pos, 1);
3916
0
  pos += 2;
3917
0
  suite = wpa_cipher_to_suite(WPA_PROTO_RSN, cipher);
3918
0
  RSN_SELECTOR_PUT(pos, suite);
3919
0
  pos += RSN_SELECTOR_LEN;
3920
3921
  /* Add the AKM suite */
3922
0
  WPA_PUT_LE16(pos, 1);
3923
0
  pos += 2;
3924
3925
0
  switch (akmp) {
3926
0
  case WPA_KEY_MGMT_PASN:
3927
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
3928
0
    break;
3929
0
#ifdef CONFIG_SAE
3930
0
  case WPA_KEY_MGMT_SAE:
3931
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
3932
0
    break;
3933
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
3934
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
3935
0
    break;
3936
0
#endif /* CONFIG_SAE */
3937
0
#ifdef CONFIG_FILS
3938
0
  case WPA_KEY_MGMT_FILS_SHA256:
3939
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
3940
0
    break;
3941
0
  case WPA_KEY_MGMT_FILS_SHA384:
3942
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
3943
0
    break;
3944
0
#endif /* CONFIG_FILS */
3945
0
#ifdef CONFIG_IEEE80211R
3946
0
  case WPA_KEY_MGMT_FT_PSK:
3947
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
3948
0
    break;
3949
0
  case WPA_KEY_MGMT_FT_IEEE8021X:
3950
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
3951
0
    break;
3952
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
3953
0
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
3954
0
    break;
3955
0
#endif /* CONFIG_IEEE80211R */
3956
0
  default:
3957
0
    wpa_printf(MSG_ERROR, "PASN: Invalid AKMP=0x%x", akmp);
3958
0
    return -1;
3959
0
  }
3960
0
  pos += RSN_SELECTOR_LEN;
3961
3962
  /* RSN Capabilities: PASN mandates both MFP capable and required */
3963
0
  capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
3964
0
  WPA_PUT_LE16(pos, capab);
3965
0
  pos += 2;
3966
3967
0
  if (pmkid) {
3968
0
    wpa_printf(MSG_DEBUG, "PASN: Adding PMKID");
3969
3970
0
    WPA_PUT_LE16(pos, 1);
3971
0
    pos += 2;
3972
0
    os_memcpy(pos, pmkid, PMKID_LEN);
3973
0
    pos += PMKID_LEN;
3974
0
  } else {
3975
0
    WPA_PUT_LE16(pos, 0);
3976
0
    pos += 2;
3977
0
  }
3978
3979
  /* Group addressed management is not allowed */
3980
0
  RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
3981
3982
0
  return 0;
3983
0
}
3984
3985
3986
/*
3987
 * wpa_pasn_add_parameter_ie - Add PASN Parameters IE for PASN authentication
3988
 * @buf: Buffer in which the IE will be added
3989
 * @pasn_group: Finite Cyclic Group ID for PASN authentication
3990
 * @wrapped_data_format: Format of the data in the Wrapped Data IE
3991
 * @pubkey: A buffer holding the local public key. Can be NULL
3992
 * @compressed: In case pubkey is included, indicates if the public key is
3993
 *     compressed (only x coordinate is included) or not (both x and y
3994
 *     coordinates are included)
3995
 * @comeback: A buffer holding the comeback token. Can be NULL
3996
 * @after: If comeback is set, defined the comeback time in seconds. -1 to not
3997
 *  include the Comeback After field (frames from non-AP STA).
3998
 */
3999
void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
4000
             u8 wrapped_data_format,
4001
             const struct wpabuf *pubkey, bool compressed,
4002
             const struct wpabuf *comeback, int after)
4003
0
{
4004
0
  struct pasn_parameter_ie *params;
4005
4006
0
  wpa_printf(MSG_DEBUG, "PASN: Add PASN Parameters element");
4007
4008
0
  params = wpabuf_put(buf, sizeof(*params));
4009
4010
0
  params->id = WLAN_EID_EXTENSION;
4011
0
  params->len = sizeof(*params) - 2;
4012
0
  params->id_ext = WLAN_EID_EXT_PASN_PARAMS;
4013
0
  params->control = 0;
4014
0
  params->wrapped_data_format = wrapped_data_format;
4015
4016
0
  if (comeback) {
4017
0
    wpa_printf(MSG_DEBUG, "PASN: Adding comeback data");
4018
4019
    /*
4020
     * 2 octets for the 'after' field + 1 octet for the length +
4021
     * actual cookie data
4022
     */
4023
0
    if (after >= 0)
4024
0
      params->len += 2;
4025
0
    params->len += 1 + wpabuf_len(comeback);
4026
0
    params->control |= WPA_PASN_CTRL_COMEBACK_INFO_PRESENT;
4027
4028
0
    if (after >= 0)
4029
0
      wpabuf_put_le16(buf, after);
4030
0
    wpabuf_put_u8(buf, wpabuf_len(comeback));
4031
0
    wpabuf_put_buf(buf, comeback);
4032
0
  }
4033
4034
0
  if (pubkey) {
4035
0
    wpa_printf(MSG_DEBUG,
4036
0
         "PASN: Adding public key and group ID %u",
4037
0
         pasn_group);
4038
4039
    /*
4040
     * 2 octets for the finite cyclic group + 2 octets public key
4041
     * length + 1 octet for the compressed/uncompressed indication +
4042
     * the actual key.
4043
     */
4044
0
    params->len += 2 + 1 + 1 + wpabuf_len(pubkey);
4045
0
    params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
4046
4047
0
    wpabuf_put_le16(buf, pasn_group);
4048
4049
    /*
4050
     * The first octet indicates whether the public key is
4051
     * compressed, as defined in RFC 5480 section 2.2.
4052
     */
4053
0
    wpabuf_put_u8(buf, wpabuf_len(pubkey) + 1);
4054
0
    wpabuf_put_u8(buf, compressed ? WPA_PASN_PUBKEY_COMPRESSED_0 :
4055
0
            WPA_PASN_PUBKEY_UNCOMPRESSED);
4056
4057
0
    wpabuf_put_buf(buf, pubkey);
4058
0
  }
4059
0
}
4060
4061
/*
4062
 * wpa_pasn_add_wrapped_data - Add a Wrapped Data IE to PASN Authentication
4063
 * frame. If needed, the Wrapped Data IE would be fragmented.
4064
 *
4065
 * @buf: Buffer in which the IE will be added
4066
 * @wrapped_data_buf: Buffer holding the wrapped data
4067
 */
4068
int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
4069
            struct wpabuf *wrapped_data_buf)
4070
0
{
4071
0
  const u8 *data;
4072
0
  size_t data_len;
4073
0
  u8 len;
4074
4075
0
  if (!wrapped_data_buf)
4076
0
    return 0;
4077
4078
0
  wpa_printf(MSG_DEBUG, "PASN: Add wrapped data");
4079
4080
0
  data = wpabuf_head_u8(wrapped_data_buf);
4081
0
  data_len = wpabuf_len(wrapped_data_buf);
4082
4083
  /* nothing to add */
4084
0
  if (!data_len)
4085
0
    return 0;
4086
4087
0
  if (data_len <= 254)
4088
0
    len = 1 + data_len;
4089
0
  else
4090
0
    len = 255;
4091
4092
0
  if (wpabuf_tailroom(buf) < 3 + data_len)
4093
0
    return -1;
4094
4095
0
  wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
4096
0
  wpabuf_put_u8(buf, len);
4097
0
  wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
4098
0
  wpabuf_put_data(buf, data, len - 1);
4099
4100
0
  data += len - 1;
4101
0
  data_len -= len - 1;
4102
4103
0
  while (data_len) {
4104
0
    if (wpabuf_tailroom(buf) < 1 + data_len)
4105
0
      return -1;
4106
0
    wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
4107
0
    len = data_len > 255 ? 255 : data_len;
4108
0
    wpabuf_put_u8(buf, len);
4109
0
    wpabuf_put_data(buf, data, len);
4110
0
    data += len;
4111
0
    data_len -= len;
4112
0
  }
4113
4114
0
  return 0;
4115
0
}
4116
4117
4118
/*
4119
 * wpa_pasn_validate_rsne - Validate PSAN specific data of RSNE
4120
 * @data: Parsed representation of an RSNE
4121
 * Returns -1 for invalid data; otherwise 0
4122
 */
4123
int wpa_pasn_validate_rsne(const struct wpa_ie_data *data)
4124
423
{
4125
423
  u16 capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
4126
4127
423
  if (data->proto != WPA_PROTO_RSN)
4128
0
    return -1;
4129
4130
423
  if ((data->capabilities & capab) != capab) {
4131
126
    wpa_printf(MSG_DEBUG, "PASN: Invalid RSNE capabilities");
4132
126
    return -1;
4133
126
  }
4134
4135
297
  if (!data->has_group || data->group_cipher != WPA_CIPHER_GTK_NOT_USED) {
4136
4
    wpa_printf(MSG_DEBUG, "PASN: Invalid group data cipher");
4137
4
    return -1;
4138
4
  }
4139
4140
293
  if (!data->has_pairwise || !data->pairwise_cipher ||
4141
293
      (data->pairwise_cipher & (data->pairwise_cipher - 1))) {
4142
12
    wpa_printf(MSG_DEBUG, "PASN: No valid pairwise suite");
4143
12
    return -1;
4144
12
  }
4145
4146
281
  switch (data->key_mgmt) {
4147
0
#ifdef CONFIG_SAE
4148
1
  case WPA_KEY_MGMT_SAE:
4149
3
  case WPA_KEY_MGMT_SAE_EXT_KEY:
4150
  /* fall through */
4151
3
#endif /* CONFIG_SAE */
4152
3
#ifdef CONFIG_FILS
4153
4
  case WPA_KEY_MGMT_FILS_SHA256:
4154
6
  case WPA_KEY_MGMT_FILS_SHA384:
4155
  /* fall through */
4156
6
#endif /* CONFIG_FILS */
4157
6
#ifdef CONFIG_IEEE80211R
4158
7
  case WPA_KEY_MGMT_FT_PSK:
4159
8
  case WPA_KEY_MGMT_FT_IEEE8021X:
4160
10
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
4161
  /* fall through */
4162
10
#endif /* CONFIG_IEEE80211R */
4163
120
  case WPA_KEY_MGMT_PASN:
4164
120
    break;
4165
161
  default:
4166
161
    wpa_printf(MSG_ERROR, "PASN: invalid key_mgmt: 0x%0x",
4167
161
         data->key_mgmt);
4168
161
    return -1;
4169
281
  }
4170
4171
120
  if (data->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED) {
4172
10
    wpa_printf(MSG_DEBUG, "PASN: Invalid group mgmt cipher");
4173
10
    return -1;
4174
10
  }
4175
4176
110
  if (data->num_pmkid > 1) {
4177
2
    wpa_printf(MSG_DEBUG, "PASN: Invalid number of PMKIDs");
4178
2
    return -1;
4179
2
  }
4180
4181
108
  return 0;
4182
110
}
4183
4184
4185
/*
4186
 * wpa_pasn_parse_parameter_ie - Validates PASN Parameters IE
4187
 * @data: Pointer to the PASN Parameters IE (starting with the EID).
4188
 * @len: Length of the data in the PASN Parameters IE
4189
 * @from_ap: Whether this was received from an AP
4190
 * @pasn_params: On successful return would hold the parsed PASN parameters.
4191
 * Returns: -1 for invalid data; otherwise 0
4192
 *
4193
 * Note: On successful return, the pointers in &pasn_params point to the data in
4194
 * the IE and are not locally allocated (so they should not be freed etc.).
4195
 */
4196
int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
4197
        struct wpa_pasn_params_data *pasn_params)
4198
720
{
4199
720
  struct pasn_parameter_ie *params = (struct pasn_parameter_ie *) data;
4200
720
  const u8 *pos = (const u8 *) (params + 1);
4201
4202
720
  if (!pasn_params) {
4203
0
    wpa_printf(MSG_DEBUG, "PASN: Invalid params");
4204
0
    return -1;
4205
0
  }
4206
4207
720
  if (!params || ((size_t) (params->len + 2) < sizeof(*params)) ||
4208
720
      len < sizeof(*params) || params->len + 2 != len) {
4209
7
    wpa_printf(MSG_DEBUG,
4210
7
         "PASN: Invalid parameters IE. len=(%u, %u)",
4211
7
         params ? params->len : 0, len);
4212
7
    return -1;
4213
7
  }
4214
4215
713
  os_memset(pasn_params, 0, sizeof(*pasn_params));
4216
4217
713
  switch (params->wrapped_data_format) {
4218
412
  case WPA_PASN_WRAPPED_DATA_NO:
4219
474
  case WPA_PASN_WRAPPED_DATA_SAE:
4220
477
  case WPA_PASN_WRAPPED_DATA_FILS_SK:
4221
705
  case WPA_PASN_WRAPPED_DATA_FT:
4222
705
    break;
4223
8
  default:
4224
8
    wpa_printf(MSG_DEBUG, "PASN: Invalid wrapped data format");
4225
8
    return -1;
4226
713
  }
4227
4228
705
  pasn_params->wrapped_data_format = params->wrapped_data_format;
4229
4230
705
  len -= sizeof(*params);
4231
4232
705
  if (params->control & WPA_PASN_CTRL_COMEBACK_INFO_PRESENT) {
4233
76
    if (from_ap) {
4234
0
      if (len < 2) {
4235
0
        wpa_printf(MSG_DEBUG,
4236
0
             "PASN: Invalid Parameters IE: Truncated Comeback After");
4237
0
        return -1;
4238
0
      }
4239
0
      pasn_params->after = WPA_GET_LE16(pos);
4240
0
      pos += 2;
4241
0
      len -= 2;
4242
0
    }
4243
4244
76
    if (len < 1 || len < 1 + *pos) {
4245
20
      wpa_printf(MSG_DEBUG,
4246
20
           "PASN: Invalid Parameters IE: comeback len");
4247
20
      return -1;
4248
20
    }
4249
4250
56
    pasn_params->comeback_len = *pos++;
4251
56
    len--;
4252
56
    pasn_params->comeback = pos;
4253
56
    len -=  pasn_params->comeback_len;
4254
56
    pos += pasn_params->comeback_len;
4255
56
  }
4256
4257
685
  if (params->control & WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT) {
4258
88
    if (len < 3 || len < 3 + pos[2]) {
4259
23
      wpa_printf(MSG_DEBUG,
4260
23
           "PASN: Invalid Parameters IE: group and key");
4261
23
      return -1;
4262
23
    }
4263
4264
65
    pasn_params->group = WPA_GET_LE16(pos);
4265
65
    pos += 2;
4266
65
    len -= 2;
4267
65
    pasn_params->pubkey_len = *pos++;
4268
65
    len--;
4269
65
    pasn_params->pubkey = pos;
4270
65
    len -= pasn_params->pubkey_len;
4271
65
    pos += pasn_params->pubkey_len;
4272
65
  }
4273
4274
662
  if (len) {
4275
21
    wpa_printf(MSG_DEBUG,
4276
21
         "PASN: Invalid Parameters IE. Bytes left=%u", len);
4277
21
    return -1;
4278
21
  }
4279
4280
641
  return 0;
4281
662
}
4282
4283
4284
void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab)
4285
0
{
4286
0
  size_t flen;
4287
4288
0
  flen = (capab & 0xff00) ? 2 : 1;
4289
0
  if (!capab)
4290
0
    return; /* no supported extended RSN capabilities */
4291
0
  if (wpabuf_tailroom(buf) < 2 + flen)
4292
0
    return;
4293
0
  capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
4294
4295
0
  wpabuf_put_u8(buf, WLAN_EID_RSNX);
4296
0
  wpabuf_put_u8(buf, flen);
4297
0
  wpabuf_put_u8(buf, capab & 0x00ff);
4298
0
  capab >>= 8;
4299
0
  if (capab)
4300
0
    wpabuf_put_u8(buf, capab);
4301
0
}
4302
4303
4304
/*
4305
 * wpa_pasn_add_extra_ies - Add protocol specific IEs in Authentication
4306
 * frame for PASN.
4307
 *
4308
 * @buf: Buffer in which the elements will be added
4309
 * @extra_ies: Protocol specific elements to add
4310
 * @len: Length of the elements
4311
 * Returns: 0 on success, -1 on failure
4312
 */
4313
4314
int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len)
4315
0
{
4316
0
  if (!len || !extra_ies || !buf)
4317
0
    return 0;
4318
4319
0
  if (wpabuf_tailroom(buf) < sizeof(len))
4320
0
    return -1;
4321
4322
0
  wpabuf_put_data(buf, extra_ies, len);
4323
0
  return 0;
4324
0
}
4325
4326
#endif /* CONFIG_PASN */
4327
4328
4329
void rsn_set_snonce_cookie(u8 *snonce)
4330
0
{
4331
0
  u8 *pos;
4332
4333
0
  pos = snonce + WPA_NONCE_LEN - 6;
4334
0
  WPA_PUT_BE24(pos, OUI_WFA);
4335
0
  pos += 3;
4336
0
  WPA_PUT_BE24(pos, 0x000029);
4337
0
}
4338
4339
4340
bool rsn_is_snonce_cookie(const u8 *snonce)
4341
0
{
4342
0
  const u8 *pos;
4343
4344
0
  pos = snonce + WPA_NONCE_LEN - 6;
4345
0
  return WPA_GET_BE24(pos) == OUI_WFA &&
4346
0
    WPA_GET_BE24(pos + 3) == 0x000029;
4347
0
}