Coverage Report

Created: 2026-10-28 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hostap/src/common/wpa_common.c
Line
Count
Source
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 "crypto/random.h"
20
#include "ieee802_11_defs.h"
21
#include "ieee802_11_common.h"
22
#include "defs.h"
23
#include "common/nan_defs.h"
24
#include "wpa_common.h"
25
26
27
static unsigned int wpa_kck_len(int akmp, size_t pmk_len)
28
1.22k
{
29
1.22k
  switch (akmp) {
30
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
31
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
32
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
33
0
    return 24;
34
0
  case WPA_KEY_MGMT_FILS_SHA256:
35
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
36
0
  case WPA_KEY_MGMT_FILS_SHA384:
37
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
38
0
    return 0;
39
0
  case WPA_KEY_MGMT_DPP:
40
0
    return pmk_len / 2;
41
0
  case WPA_KEY_MGMT_OWE:
42
0
    return pmk_len / 2;
43
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
44
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
45
0
    return pmk_len / 2;
46
#ifdef CONFIG_ENC_ASSOC
47
  case WPA_KEY_MGMT_EPPKE:
48
    return 32;
49
#endif /* CONFIG_ENC_ASSOC */
50
1.22k
  default:
51
1.22k
    return 16;
52
1.22k
  }
53
1.22k
}
54
55
56
#ifdef CONFIG_IEEE80211R
57
static unsigned int wpa_kck2_len(int akmp)
58
0
{
59
0
  switch (akmp) {
60
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
61
0
    return 16;
62
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
63
0
    return 24;
64
0
  default:
65
0
    return 0;
66
0
  }
67
0
}
68
#endif /* CONFIG_IEEE80211R */
69
70
71
unsigned int wpa_kek_len(int akmp, size_t pmk_len, u16 pasn_group)
72
1.22k
{
73
1.22k
  switch (akmp) {
74
0
  case WPA_KEY_MGMT_FILS_SHA384:
75
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
76
0
    return 64;
77
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
78
0
  case WPA_KEY_MGMT_FILS_SHA256:
79
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
80
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
81
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
82
0
    return 32;
83
0
  case WPA_KEY_MGMT_DPP:
84
0
    return pmk_len <= 32 ? 16 : 32;
85
0
  case WPA_KEY_MGMT_OWE:
86
0
    return pmk_len <= 32 ? 16 : 32;
87
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
88
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
89
0
    return pmk_len <= 32 ? 16 : 32;
90
#ifdef CONFIG_ENC_ASSOC
91
  case WPA_KEY_MGMT_EPPKE:
92
    if (pasn_group == 21 || pasn_group == 20)
93
      return 32;
94
    return 16;
95
#endif /* CONFIG_ENC_ASSOC */
96
1.22k
  default:
97
1.22k
    return 16;
98
1.22k
  }
99
1.22k
}
100
101
102
#ifdef CONFIG_IEEE80211R
103
static unsigned int wpa_kek2_len(int akmp)
104
0
{
105
0
  switch (akmp) {
106
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
107
0
    return 16;
108
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
109
0
    return 32;
110
0
  default:
111
0
    return 0;
112
0
  }
113
0
}
114
#endif /* CONFIG_IEEE80211R */
115
116
117
#ifdef CONFIG_ENC_ASSOC
118
static int rsn_eppke_mic_len(u16 pasn_group)
119
{
120
  /* MIC length is half of the output length of the hash algorithm */
121
  switch (pasn_group) {
122
  case 21:
123
    return 32;
124
  case 20:
125
    return 24;
126
  default:
127
    return 16;
128
  }
129
}
130
#endif /* CONFIG_ENC_ASSOC */
131
132
133
static int rsn_mic_len_hash(size_t pmk_len, enum rsn_hash_alg hash)
134
0
{
135
0
  switch (hash) {
136
0
  case RSN_HASH_SHA256:
137
0
    return 16;
138
0
  case RSN_HASH_SHA384:
139
0
    return 24;
140
0
  case RSN_HASH_SHA512:
141
0
    return 32;
142
0
  default:
143
0
    return pmk_len / 2;
144
0
  }
145
0
}
146
147
unsigned int wpa_mic_len(int akmp, size_t pmk_len, enum rsn_hash_alg hash,
148
       u16 pasn_group)
149
4.20k
{
150
4.20k
  switch (akmp) {
151
0
  case WPA_KEY_MGMT_PQC_8021X:
152
0
  case WPA_KEY_MGMT_FT_PQC_8021X:
153
0
    return rsn_mic_len_hash(pmk_len, hash);
154
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
155
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
156
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
157
0
    return 24;
158
0
  case WPA_KEY_MGMT_FILS_SHA256:
159
0
  case WPA_KEY_MGMT_FILS_SHA384:
160
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
161
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
162
0
    return 0;
163
0
  case WPA_KEY_MGMT_DPP:
164
0
    return rsn_mic_len_hash(pmk_len, hash);
165
0
  case WPA_KEY_MGMT_OWE:
166
0
    return rsn_mic_len_hash(pmk_len, hash);
167
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
168
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
169
0
    return rsn_mic_len_hash(pmk_len, hash);
170
#ifdef CONFIG_ENC_ASSOC
171
  case WPA_KEY_MGMT_EPPKE:
172
    return rsn_eppke_mic_len(pasn_group);
173
#endif /* CONFIG_ENC_ASSOC */
174
4.20k
  default:
175
4.20k
    return 16;
176
4.20k
  }
177
4.20k
}
178
179
180
int rsn_cipher_suite_to_wpa_cipher(u32 cipher)
181
0
{
182
0
  switch (cipher) {
183
0
  case RSN_CIPHER_SUITE_NONE:
184
0
    return WPA_CIPHER_NONE;
185
0
  case RSN_CIPHER_SUITE_TKIP:
186
0
    return WPA_CIPHER_TKIP;
187
0
  case RSN_CIPHER_SUITE_CCMP:
188
0
    return WPA_CIPHER_CCMP;
189
0
  case RSN_CIPHER_SUITE_AES_128_CMAC:
190
0
    return WPA_CIPHER_AES_128_CMAC;
191
0
  case RSN_CIPHER_SUITE_GCMP:
192
0
    return WPA_CIPHER_GCMP;
193
0
  case RSN_CIPHER_SUITE_CCMP_256:
194
0
    return WPA_CIPHER_CCMP_256;
195
0
  case RSN_CIPHER_SUITE_GCMP_256:
196
0
    return WPA_CIPHER_GCMP_256;
197
0
  case RSN_CIPHER_SUITE_BIP_GMAC_128:
198
0
    return WPA_CIPHER_BIP_GMAC_128;
199
0
  case RSN_CIPHER_SUITE_BIP_GMAC_256:
200
0
    return WPA_CIPHER_BIP_GMAC_256;
201
0
  case RSN_CIPHER_SUITE_BIP_CMAC_256:
202
0
    return WPA_CIPHER_BIP_CMAC_256;
203
0
  case RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED:
204
0
    return WPA_CIPHER_GTK_NOT_USED;
205
0
  default:
206
0
    return 0;
207
0
  }
208
0
}
209
210
211
int rsn_key_mgmt_to_wpa_akm(u32 akm_suite)
212
0
{
213
0
  switch (akm_suite) {
214
0
  case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
215
0
    return WPA_KEY_MGMT_IEEE8021X;
216
0
  case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
217
0
    return WPA_KEY_MGMT_PSK;
218
0
#ifdef CONFIG_IEEE80211R
219
0
  case RSN_AUTH_KEY_MGMT_FT_802_1X:
220
0
    return WPA_KEY_MGMT_FT_IEEE8021X;
221
0
  case RSN_AUTH_KEY_MGMT_FT_PSK:
222
0
    return WPA_KEY_MGMT_FT_PSK;
223
#ifdef CONFIG_SHA384
224
  case RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384:
225
    return WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
226
#endif /* CONFIG_SHA384 */
227
0
#endif /* CONFIG_IEEE80211R */
228
#ifdef CONFIG_SHA384
229
  case RSN_AUTH_KEY_MGMT_802_1X_SHA384:
230
    return WPA_KEY_MGMT_IEEE8021X_SHA384;
231
#endif /* CONFIG_SHA384 */
232
0
  case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
233
0
    return WPA_KEY_MGMT_IEEE8021X_SHA256;
234
0
  case RSN_AUTH_KEY_MGMT_PSK_SHA256:
235
0
    return WPA_KEY_MGMT_PSK_SHA256;
236
0
#ifdef CONFIG_SAE
237
0
  case RSN_AUTH_KEY_MGMT_SAE:
238
0
    return WPA_KEY_MGMT_SAE;
239
0
  case RSN_AUTH_KEY_MGMT_SAE_EXT_KEY:
240
0
    return WPA_KEY_MGMT_SAE_EXT_KEY;
241
0
  case RSN_AUTH_KEY_MGMT_FT_SAE:
242
0
    return WPA_KEY_MGMT_FT_SAE;
243
0
  case RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY:
244
0
    return WPA_KEY_MGMT_FT_SAE_EXT_KEY;
245
0
#endif /* CONFIG_SAE */
246
0
  case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
247
0
    return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
248
0
  case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
249
0
    return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
250
0
  case RSN_AUTH_KEY_MGMT_FILS_SHA256:
251
0
    return WPA_KEY_MGMT_FILS_SHA256;
252
0
  case RSN_AUTH_KEY_MGMT_FILS_SHA384:
253
0
    return WPA_KEY_MGMT_FILS_SHA384;
254
0
  case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
255
0
    return WPA_KEY_MGMT_FT_FILS_SHA256;
256
0
  case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
257
0
    return WPA_KEY_MGMT_FT_FILS_SHA384;
258
#ifdef CONFIG_OWE
259
  case RSN_AUTH_KEY_MGMT_OWE:
260
    return WPA_KEY_MGMT_OWE;
261
#endif /* CONFIG_OWE */
262
#ifdef CONFIG_DPP
263
  case RSN_AUTH_KEY_MGMT_DPP:
264
    return WPA_KEY_MGMT_DPP;
265
#endif /* CONFIG_DPP */
266
#ifdef CONFIG_PASN
267
  case RSN_AUTH_KEY_MGMT_PASN:
268
    return WPA_KEY_MGMT_PASN;
269
#endif /* CONFIG_PASN */
270
0
  case RSN_AUTH_KEY_MGMT_EPPKE:
271
0
    return WPA_KEY_MGMT_EPPKE;
272
#ifdef CONFIG_PQC
273
  case RSN_AUTH_KEY_MGMT_802_1X_PQC:
274
    return WPA_KEY_MGMT_PQC_8021X;
275
  case RSN_AUTH_KEY_MGMT_FT_802_1X_PQC:
276
    return WPA_KEY_MGMT_FT_PQC_8021X;
277
#endif /* CONFIG_PQC */
278
0
  default:
279
0
    return 0;
280
0
  }
281
0
}
282
283
284
/**
285
 * wpa_use_akm_defined - Is AKM-defined Key Descriptor Version used
286
 * @akmp: WPA_KEY_MGMT_* used in key derivation
287
 * Returns: 1 if AKM-defined Key Descriptor Version is used; 0 otherwise
288
 */
289
int wpa_use_akm_defined(int akmp)
290
3.22k
{
291
3.22k
  return akmp == WPA_KEY_MGMT_OWE ||
292
3.22k
    akmp == WPA_KEY_MGMT_DPP ||
293
3.22k
    akmp == WPA_KEY_MGMT_FT_IEEE8021X_SHA384 ||
294
3.22k
    akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
295
3.22k
    akmp == WPA_KEY_MGMT_EPPKE ||
296
3.22k
    wpa_key_mgmt_sae(akmp) ||
297
3.22k
    wpa_key_mgmt_pqc(akmp) ||
298
3.22k
    wpa_key_mgmt_suite_b(akmp) ||
299
3.22k
    wpa_key_mgmt_fils(akmp);
300
3.22k
}
301
302
303
/**
304
 * wpa_use_cmac - Is CMAC integrity algorithm used for EAPOL-Key MIC
305
 * @akmp: WPA_KEY_MGMT_* used in key derivation
306
 * Returns: 1 if CMAC is used; 0 otherwise
307
 */
308
int wpa_use_cmac(int akmp)
309
0
{
310
0
  return akmp == WPA_KEY_MGMT_OWE ||
311
0
    akmp == WPA_KEY_MGMT_DPP ||
312
0
    wpa_key_mgmt_ft(akmp) ||
313
0
    wpa_key_mgmt_sha256(akmp) ||
314
0
    (wpa_key_mgmt_sae(akmp) &&
315
0
     !wpa_key_mgmt_sae_ext_key(akmp)) ||
316
0
    wpa_key_mgmt_suite_b(akmp);
317
0
}
318
319
320
/**
321
 * wpa_use_aes_key_wrap - Is AES Keywrap algorithm used for EAPOL-Key Key Data
322
 * @akmp: WPA_KEY_MGMT_* used in key derivation
323
 * Returns: 1 if AES Keywrap is used; 0 otherwise
324
 *
325
 * Note: AKM 00-0F-AC:1 and 00-0F-AC:2 have special rules for selecting whether
326
 * to use AES Keywrap based on the negotiated pairwise cipher. This function
327
 * does not cover those special cases.
328
 */
329
int wpa_use_aes_key_wrap(int akmp)
330
0
{
331
0
  return akmp == WPA_KEY_MGMT_OWE ||
332
0
    akmp == WPA_KEY_MGMT_DPP ||
333
0
    akmp == WPA_KEY_MGMT_IEEE8021X_SHA384 ||
334
0
    akmp == WPA_KEY_MGMT_EPPKE ||
335
0
    wpa_key_mgmt_ft(akmp) ||
336
0
    wpa_key_mgmt_sha256(akmp) ||
337
0
    wpa_key_mgmt_sae(akmp) ||
338
0
    wpa_key_mgmt_pqc(akmp) ||
339
0
    wpa_key_mgmt_suite_b(akmp);
340
0
}
341
342
343
#ifdef CONFIG_ENC_ASSOC
344
static int rsn_eapol_key_eppke_mic(const u8 *key, size_t key_len,
345
           u16 pasn_group, const u8 *buf,
346
           size_t len, u8 *mic)
347
{
348
  u8 hash[SHA512_MAC_LEN];
349
  size_t mic_len;
350
351
  switch (pasn_group) {
352
  case 19:
353
    wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key MIC using HMAC-SHA256");
354
    if (hmac_sha256(key, key_len, buf, len, hash))
355
      return -1;
356
    mic_len = 16;
357
    break;
358
#ifdef CONFIG_SHA384
359
  case 20:
360
    wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key MIC using HMAC-SHA384");
361
    if (hmac_sha384(key, key_len, buf, len, hash))
362
      return -1;
363
    mic_len = 24;
364
    break;
365
#endif /* CONFIG_SHA384 */
366
#ifdef CONFIG_SHA512
367
  case 21:
368
    wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key MIC using HMAC-SHA512");
369
    if (hmac_sha512(key, key_len, buf, len, hash))
370
      return -1;
371
    mic_len = 32;
372
    break;
373
#endif /* CONFIG_SHA512 */
374
  default:
375
    wpa_printf(MSG_INFO, "EPPKE: Unsupported group: %u",
376
         pasn_group);
377
    return -1;
378
  }
379
  os_memcpy(mic, hash, mic_len);
380
  wpa_hexdump(MSG_DEBUG, "RSN: EAPOL-Key MIC", mic, mic_len);
381
  return 0;
382
}
383
#endif /* CONFIG_ENC_ASSOC */
384
385
386
#if defined(CONFIG_SAE) || defined(CONFIG_OWE) || defined(CONFIG_DPP)
387
static int rsn_eapol_key_mic_hash(const u8 *key, size_t key_len, int akmp,
388
          enum rsn_hash_alg hash_alg, int ver,
389
          const u8 *buf, size_t len, u8 *mic)
390
0
{
391
0
  u8 hash[SHA512_MAC_LEN];
392
0
  size_t mic_len;
393
394
0
  if (hash_alg == RSN_HASH_NOT_SPECIFIED) {
395
0
    if (key_len == 128 / 8)
396
0
      hash_alg = RSN_HASH_SHA256;
397
0
    else if (key_len == 192 / 8)
398
0
      hash_alg = RSN_HASH_SHA384;
399
0
    else if (key_len == 256 / 8)
400
0
      hash_alg = RSN_HASH_SHA512;
401
0
    else
402
0
      return -1;
403
0
  }
404
405
0
  wpa_printf(MSG_DEBUG,
406
0
       "RSN: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - %s)",
407
0
       hash_alg == RSN_HASH_SHA512 ? 512 :
408
0
       hash_alg == RSN_HASH_SHA384 ? 384 : 256,
409
0
       wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN));
410
0
  wpa_hexdump(MSG_DEBUG, "RSN: KCK", key, key_len);
411
412
0
  if (hash_alg == RSN_HASH_SHA256) {
413
0
    if (hmac_sha256(key, key_len, buf, len, hash))
414
0
      return -1;
415
0
    mic_len = 16;
416
#ifdef CONFIG_SHA384
417
  } else if (hash_alg == RSN_HASH_SHA384) {
418
    if (hmac_sha384(key, key_len, buf, len, hash))
419
      return -1;
420
    mic_len = 24;
421
#endif /* CONFIG_SHA384 */
422
#ifdef CONFIG_SHA512
423
  } else if (hash_alg == RSN_HASH_SHA512) {
424
    if (hmac_sha512(key, key_len, buf, len, hash))
425
      return -1;
426
    mic_len = 32;
427
#endif /* CONFIG_SHA512 */
428
0
  } else {
429
0
    wpa_printf(MSG_INFO,
430
0
         "RSN: Unsupported KCK length: %u (hash_alg=%d)",
431
0
         (unsigned int) key_len, hash_alg);
432
0
    return -1;
433
0
  }
434
435
0
  os_memcpy(mic, hash, mic_len);
436
0
  wpa_hexdump(MSG_DEBUG, "RSN: EAPOL-Key MIC", mic, mic_len);
437
0
  return 0;
438
0
}
439
#endif /* CONFIG_SAE || CONFIG_OWE || CONFIG_DPP */
440
441
442
/**
443
 * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
444
 * @key: EAPOL-Key Key Confirmation Key (KCK)
445
 * @key_len: KCK length in octets
446
 * @akmp: WPA_KEY_MGMT_* used in key derivation
447
 * @hash_alg: Hash algorithm
448
 * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
449
 * @buf: Pointer to the beginning of the EAPOL header (version field)
450
 * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
451
 * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
452
 * Returns: 0 on success, -1 on failure
453
 *
454
 * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
455
 * to be cleared (all zeroes) when calling this function.
456
 *
457
 * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
458
 * description of the Key MIC calculation. It includes packet data from the
459
 * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
460
 * happened during final editing of the standard and the correct behavior is
461
 * defined in the last draft (IEEE 802.11i/D10).
462
 */
463
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp,
464
          enum rsn_hash_alg hash_alg, int ver,
465
          const u8 *buf, size_t len, u8 *mic, u16 pasn_group)
466
1.22k
{
467
1.22k
  u8 hash[SHA512_MAC_LEN];
468
469
1.22k
  if (key_len == 0) {
470
0
    wpa_printf(MSG_DEBUG,
471
0
         "WPA: KCK not set - cannot calculate MIC");
472
0
    return -1;
473
0
  }
474
475
1.22k
  switch (ver) {
476
0
#ifndef CONFIG_FIPS
477
0
  case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
478
0
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-MD5");
479
0
    return hmac_md5(key, key_len, buf, len, mic);
480
0
#endif /* CONFIG_FIPS */
481
522
  case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
482
522
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using HMAC-SHA1");
483
522
    if (hmac_sha1(key, key_len, buf, len, hash))
484
0
      return -1;
485
522
    os_memcpy(mic, hash, MD5_MAC_LEN);
486
522
    break;
487
703
  case WPA_KEY_INFO_TYPE_AES_128_CMAC:
488
703
    wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key MIC using AES-CMAC");
489
703
    return omac1_aes_128(key, buf, len, mic);
490
0
  case WPA_KEY_INFO_TYPE_AKM_DEFINED:
491
0
    switch (akmp) {
492
0
#ifdef CONFIG_SAE
493
0
    case WPA_KEY_MGMT_SAE:
494
0
    case WPA_KEY_MGMT_FT_SAE:
495
0
      wpa_printf(MSG_DEBUG,
496
0
           "WPA: EAPOL-Key MIC using AES-CMAC (AKM-defined - SAE)");
497
0
      return omac1_aes_128(key, buf, len, mic);
498
0
    case WPA_KEY_MGMT_SAE_EXT_KEY:
499
0
    case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
500
0
      if (rsn_eapol_key_mic_hash(key, key_len, akmp, hash_alg,
501
0
               ver, buf, len, mic) < 0)
502
0
        return -1;
503
0
      break;
504
0
#endif /* CONFIG_SAE */
505
#ifdef CONFIG_ENC_ASSOC
506
    case WPA_KEY_MGMT_EPPKE:
507
      if (rsn_eapol_key_eppke_mic(key, key_len, pasn_group,
508
                buf, len, mic) < 0)
509
        return -1;
510
      break;
511
#endif /* CONFIG_ENC_ASSOC */
512
0
#ifdef CONFIG_SUITEB
513
0
    case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
514
0
      wpa_printf(MSG_DEBUG,
515
0
           "WPA: EAPOL-Key MIC using HMAC-SHA256 (AKM-defined - Suite B)");
516
0
      if (hmac_sha256(key, key_len, buf, len, hash))
517
0
        return -1;
518
0
      os_memcpy(mic, hash, MD5_MAC_LEN);
519
0
      break;
520
0
#endif /* CONFIG_SUITEB */
521
#ifdef CONFIG_SUITEB192
522
    case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
523
      wpa_printf(MSG_DEBUG,
524
           "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - Suite B 192-bit)");
525
      if (hmac_sha384(key, key_len, buf, len, hash))
526
        return -1;
527
      os_memcpy(mic, hash, 24);
528
      break;
529
#endif /* CONFIG_SUITEB192 */
530
#ifdef CONFIG_OWE
531
    case WPA_KEY_MGMT_OWE:
532
      if (rsn_eapol_key_mic_hash(key, key_len, akmp, hash_alg,
533
               ver, buf, len, mic) < 0)
534
        return -1;
535
      break;
536
#endif /* CONFIG_OWE */
537
#ifdef CONFIG_DPP
538
    case WPA_KEY_MGMT_DPP:
539
      if (rsn_eapol_key_mic_hash(key, key_len, akmp, hash_alg,
540
               ver, buf, len, mic) < 0)
541
        return -1;
542
      break;
543
#endif /* CONFIG_DPP */
544
#ifdef CONFIG_PQC
545
    case WPA_KEY_MGMT_PQC_8021X:
546
#ifdef CONFIG_IEEE80211R
547
    case WPA_KEY_MGMT_FT_PQC_8021X:
548
#endif /* CONFIG_IEEE80211R */
549
      if (rsn_eapol_key_mic_hash(key, key_len, akmp, hash_alg,
550
               ver, buf, len, mic) < 0)
551
        return -1;
552
      break;
553
#endif /* CONFIG_PQC */
554
#ifdef CONFIG_SHA384
555
    case WPA_KEY_MGMT_IEEE8021X_SHA384:
556
#ifdef CONFIG_IEEE80211R
557
    case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
558
#endif /* CONFIG_IEEE80211R */
559
      wpa_printf(MSG_DEBUG,
560
           "WPA: EAPOL-Key MIC using HMAC-SHA384 (AKM-defined - 802.1X SHA384)");
561
      if (hmac_sha384(key, key_len, buf, len, hash))
562
        return -1;
563
      os_memcpy(mic, hash, 24);
564
      break;
565
#endif /* CONFIG_SHA384 */
566
0
    default:
567
0
      wpa_printf(MSG_DEBUG,
568
0
           "WPA: EAPOL-Key MIC algorithm not known (AKM-defined - akmp=0x%x)",
569
0
           akmp);
570
0
      return -1;
571
0
    }
572
0
    break;
573
0
  default:
574
0
    wpa_printf(MSG_DEBUG,
575
0
         "WPA: EAPOL-Key MIC algorithm not known (ver=%d)",
576
0
         ver);
577
0
    return -1;
578
1.22k
  }
579
580
522
  return 0;
581
1.22k
}
582
583
584
/**
585
 * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
586
 * @pmk: Pairwise master key
587
 * @pmk_len: Length of PMK
588
 * @label: Label to use in derivation
589
 * @addr1: AA or SA
590
 * @addr2: SA or AA
591
 * @nonce1: ANonce or SNonce
592
 * @nonce2: SNonce or ANonce
593
 * @ptk: Buffer for pairwise transient key
594
 * @akmp: Negotiated AKM
595
 * @cipher: Negotiated pairwise cipher
596
 * @z: Additional context data
597
 * @z_len: Length of additional context data
598
 * @kdk_len: The length in octets that should be derived for KDK
599
 * Returns: 0 on success, -1 on failure
600
 *
601
 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
602
 * PTK = PRF-X(PMK, "Pairwise key expansion",
603
 *             Min(AA, SA) || Max(AA, SA) ||
604
 *             Min(ANonce, SNonce) || Max(ANonce, SNonce)
605
 *             [ || Z.x ])
606
 *
607
 * The optional Z.x component is used only with DPP and that part is not defined
608
 * in IEEE 802.11. The additional context data is also used to carry the DHss
609
 * (Diffie-Hellman shared secret) when IEEE 802.1X authentication in
610
 * Authentication frames is  used.
611
 */
612
int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
613
       const u8 *addr1, const u8 *addr2,
614
       const u8 *nonce1, const u8 *nonce2,
615
       struct wpa_ptk *ptk, int akmp, int cipher,
616
       const u8 *z, size_t z_len, size_t kdk_len, u16 pasn_group)
617
1.22k
{
618
1.22k
#define MAX_Z_LEN 66 /* with NIST P-521 */
619
1.22k
  u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
620
1.22k
  size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
621
1.22k
  u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
622
1.22k
    WPA_KDK_MAX_LEN];
623
1.22k
  size_t ptk_len;
624
#ifdef CONFIG_OWE
625
  int owe_ptk_workaround = 0;
626
627
  if (akmp == (WPA_KEY_MGMT_OWE | WPA_KEY_MGMT_PSK_SHA256)) {
628
    owe_ptk_workaround = 1;
629
    akmp = WPA_KEY_MGMT_OWE;
630
  }
631
#endif /* CONFIG_OWE */
632
633
1.22k
  if (pmk_len == 0) {
634
0
    wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
635
0
    return -1;
636
0
  }
637
638
1.22k
  if (z_len > MAX_Z_LEN)
639
0
    return -1;
640
641
1.22k
  if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
642
0
    os_memcpy(data, addr1, ETH_ALEN);
643
0
    os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
644
1.22k
  } else {
645
1.22k
    os_memcpy(data, addr2, ETH_ALEN);
646
1.22k
    os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
647
1.22k
  }
648
649
1.22k
  if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
650
772
    os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
651
772
    os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
652
772
        WPA_NONCE_LEN);
653
772
  } else {
654
453
    os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
655
453
    os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
656
453
        WPA_NONCE_LEN);
657
453
  }
658
659
1.22k
  if (z && z_len) {
660
0
    os_memcpy(data + 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, z, z_len);
661
0
    data_len += z_len;
662
0
  }
663
664
1.22k
  if (kdk_len > WPA_KDK_MAX_LEN) {
665
0
    wpa_printf(MSG_ERROR,
666
0
         "WPA: KDK len=%zu exceeds max supported len",
667
0
         kdk_len);
668
0
    return -1;
669
0
  }
670
671
1.22k
  ptk->kck_len = wpa_kck_len(akmp, pmk_len);
672
1.22k
  ptk->kek_len = wpa_kek_len(akmp, pmk_len, pasn_group);
673
1.22k
  ptk->tk_len = wpa_cipher_key_len(cipher);
674
1.22k
  ptk->kdk_len = kdk_len;
675
1.22k
  if (ptk->tk_len == 0) {
676
0
    wpa_printf(MSG_ERROR,
677
0
         "WPA: Unsupported cipher (0x%x) used in PTK derivation",
678
0
         cipher);
679
0
    return -1;
680
0
  }
681
1.22k
  ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
682
683
1.22k
  if (wpa_key_mgmt_sha384(akmp)) {
684
#ifdef CONFIG_SHA384
685
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
686
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
687
             tmp, ptk_len) < 0)
688
      return -1;
689
    ptk->hash_alg = RSN_HASH_SHA384;
690
#else /* CONFIG_SHA384 */
691
0
    return -1;
692
0
#endif /* CONFIG_SHA384 */
693
1.22k
  } else if (wpa_key_mgmt_sha256(akmp)) {
694
0
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
695
0
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
696
0
             tmp, ptk_len) < 0)
697
0
      return -1;
698
0
    ptk->hash_alg = RSN_HASH_SHA256;
699
#ifdef CONFIG_OWE
700
  } else if (akmp == WPA_KEY_MGMT_OWE && (pmk_len == 32 ||
701
            owe_ptk_workaround)) {
702
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
703
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
704
             tmp, ptk_len) < 0)
705
      return -1;
706
    if (owe_ptk_workaround && pmk_len == 64)
707
      ptk->hash_alg = RSN_HASH_SHA512;
708
    else if (owe_ptk_workaround && pmk_len == 48)
709
      ptk->hash_alg = RSN_HASH_SHA384;
710
    else
711
      ptk->hash_alg = RSN_HASH_SHA256;
712
  } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 48) {
713
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
714
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
715
             tmp, ptk_len) < 0)
716
      return -1;
717
    ptk->hash_alg = RSN_HASH_SHA384;
718
  } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 64) {
719
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
720
    if (sha512_prf(pmk, pmk_len, label, data, data_len,
721
             tmp, ptk_len) < 0)
722
      return -1;
723
    ptk->hash_alg = RSN_HASH_SHA512;
724
  } else if (akmp == WPA_KEY_MGMT_OWE) {
725
    wpa_printf(MSG_INFO, "OWE: Unknown PMK length %u",
726
         (unsigned int) pmk_len);
727
    return -1;
728
#endif /* CONFIG_OWE */
729
#ifdef CONFIG_DPP
730
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
731
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
732
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
733
             tmp, ptk_len) < 0)
734
      return -1;
735
    ptk->hash_alg = RSN_HASH_SHA256;
736
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
737
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
738
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
739
             tmp, ptk_len) < 0)
740
      return -1;
741
    ptk->hash_alg = RSN_HASH_SHA384;
742
  } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
743
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
744
    if (sha512_prf(pmk, pmk_len, label, data, data_len,
745
             tmp, ptk_len) < 0)
746
      return -1;
747
    ptk->hash_alg = RSN_HASH_SHA512;
748
  } else if (akmp == WPA_KEY_MGMT_DPP) {
749
    wpa_printf(MSG_INFO, "DPP: Unknown PMK length %u",
750
         (unsigned int) pmk_len);
751
    return -1;
752
#endif /* CONFIG_DPP */
753
0
#ifdef CONFIG_SAE
754
1.22k
  } else if (wpa_key_mgmt_sae_ext_key(akmp)) {
755
0
    if (pmk_len == 32) {
756
0
      wpa_printf(MSG_DEBUG,
757
0
           "SAE: PTK derivation using PRF(SHA256)");
758
0
      if (sha256_prf(pmk, pmk_len, label, data, data_len,
759
0
               tmp, ptk_len) < 0)
760
0
        return -1;
761
0
    ptk->hash_alg = RSN_HASH_SHA256;
762
#ifdef CONFIG_SHA384
763
    } else if (pmk_len == 48) {
764
      wpa_printf(MSG_DEBUG,
765
           "SAE: PTK derivation using PRF(SHA384)");
766
      if (sha384_prf(pmk, pmk_len, label, data, data_len,
767
               tmp, ptk_len) < 0)
768
        return -1;
769
    ptk->hash_alg = RSN_HASH_SHA384;
770
#endif /* CONFIG_SHA384 */
771
#ifdef CONFIG_SHA512
772
    } else if (pmk_len == 64) {
773
      wpa_printf(MSG_DEBUG,
774
           "SAE: PTK derivation using PRF(SHA512)");
775
      if (sha512_prf(pmk, pmk_len, label, data, data_len,
776
               tmp, ptk_len) < 0)
777
        return -1;
778
    ptk->hash_alg = RSN_HASH_SHA512;
779
#endif /* CONFIG_SHA512 */
780
0
    } else {
781
0
      wpa_printf(MSG_INFO, "SAE: Unknown PMK length %u",
782
0
           (unsigned int) pmk_len);
783
0
      return -1;
784
0
    }
785
0
#endif /* CONFIG_SAE */
786
1.22k
  } else {
787
1.22k
    wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
788
1.22k
    if (sha1_prf(pmk, pmk_len, label, data, data_len, tmp,
789
1.22k
           ptk_len) < 0)
790
0
      return -1;
791
1.22k
    ptk->hash_alg = RSN_HASH_SHA1;
792
1.22k
  }
793
794
1.22k
  wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
795
1.22k
       MAC2STR(addr1), MAC2STR(addr2));
796
1.22k
  wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
797
1.22k
  wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
798
1.22k
  if (z && z_len)
799
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: Z.x", z, z_len);
800
1.22k
  wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
801
1.22k
  wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
802
803
1.22k
  os_memcpy(ptk->kck, tmp, ptk->kck_len);
804
1.22k
  wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
805
806
1.22k
  os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
807
1.22k
  wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
808
809
1.22k
  os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
810
1.22k
  wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
811
812
1.22k
  if (kdk_len) {
813
0
    os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
814
0
        ptk->tk_len, ptk->kdk_len);
815
0
    wpa_hexdump_key(MSG_DEBUG, "WPA: KDK", ptk->kdk, ptk->kdk_len);
816
0
  }
817
818
1.22k
  ptk->kek2_len = 0;
819
1.22k
  ptk->kck2_len = 0;
820
821
1.22k
  ptk->ptk_len = ptk_len;
822
1.22k
  os_memset(tmp, 0, sizeof(tmp));
823
1.22k
  os_memset(data, 0, data_len);
824
1.22k
  return 0;
825
1.22k
}
826
827
#ifdef CONFIG_FILS
828
829
int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
830
         const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
831
         size_t dh_ss_len, u8 *pmk, size_t *pmk_len)
832
{
833
  u8 nonces[2 * NONCE_LEN];
834
  const u8 *addr[2];
835
  size_t len[2];
836
  size_t num_elem;
837
  int res;
838
839
  /* PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ]) */
840
  wpa_printf(MSG_DEBUG, "FILS: rMSK to PMK derivation");
841
842
  if (wpa_key_mgmt_sha384(akmp))
843
    *pmk_len = SHA384_MAC_LEN;
844
  else if (wpa_key_mgmt_sha256(akmp))
845
    *pmk_len = SHA256_MAC_LEN;
846
  else
847
    return -1;
848
849
  wpa_hexdump_key(MSG_DEBUG, "FILS: rMSK", rmsk, rmsk_len);
850
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, NONCE_LEN);
851
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, NONCE_LEN);
852
  wpa_hexdump(MSG_DEBUG, "FILS: DHss", dh_ss, dh_ss_len);
853
854
  os_memcpy(nonces, snonce, NONCE_LEN);
855
  os_memcpy(&nonces[NONCE_LEN], anonce, NONCE_LEN);
856
  addr[0] = rmsk;
857
  len[0] = rmsk_len;
858
  num_elem = 1;
859
  if (dh_ss) {
860
    addr[1] = dh_ss;
861
    len[1] = dh_ss_len;
862
    num_elem++;
863
  }
864
  if (wpa_key_mgmt_sha384(akmp))
865
    res = hmac_sha384_vector(nonces, 2 * NONCE_LEN, num_elem,
866
           addr, len, pmk);
867
  else
868
    res = hmac_sha256_vector(nonces, 2 * NONCE_LEN, num_elem,
869
           addr, len, pmk);
870
  if (res == 0)
871
    wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, *pmk_len);
872
  else
873
    *pmk_len = 0;
874
  return res;
875
}
876
877
878
int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
879
       u8 *pmkid)
880
{
881
  const u8 *addr[1];
882
  size_t len[1];
883
  u8 hash[SHA384_MAC_LEN];
884
  int res;
885
886
  /* PMKID = Truncate-128(Hash(EAP-Initiate/Reauth)) */
887
  addr[0] = reauth;
888
  len[0] = reauth_len;
889
  if (wpa_key_mgmt_sha384(akmp))
890
    res = sha384_vector(1, addr, len, hash);
891
  else if (wpa_key_mgmt_sha256(akmp))
892
    res = sha256_vector(1, addr, len, hash);
893
  else
894
    return -1;
895
  if (res)
896
    return res;
897
  os_memcpy(pmkid, hash, PMKID_LEN);
898
  wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
899
  return 0;
900
}
901
902
903
int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
904
        const u8 *snonce, const u8 *anonce, const u8 *dhss,
905
        size_t dhss_len, struct wpa_ptk *ptk,
906
        u8 *ick, size_t *ick_len, int akmp, int cipher,
907
        u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
908
{
909
  u8 *data, *pos;
910
  size_t data_len;
911
  u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
912
         FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
913
  size_t key_data_len;
914
  const char *label = "FILS PTK Derivation";
915
  int ret = -1;
916
  size_t offset;
917
918
  /*
919
   * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
920
   *                       SPA || AA || SNonce || ANonce [ || DHss ])
921
   * ICK = L(FILS-Key-Data, 0, ICK_bits)
922
   * KEK = L(FILS-Key-Data, ICK_bits, KEK_bits)
923
   * TK = L(FILS-Key-Data, ICK_bits + KEK_bits, TK_bits)
924
   * If doing FT initial mobility domain association:
925
   * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
926
   *             FILS-FT_bits)
927
   * When a KDK is derived:
928
   * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
929
   *     KDK_bits)
930
   */
931
  data_len = 2 * ETH_ALEN + 2 * NONCE_LEN + dhss_len;
932
  data = os_malloc(data_len);
933
  if (!data)
934
    goto err;
935
  pos = data;
936
  os_memcpy(pos, spa, ETH_ALEN);
937
  pos += ETH_ALEN;
938
  os_memcpy(pos, aa, ETH_ALEN);
939
  pos += ETH_ALEN;
940
  os_memcpy(pos, snonce, NONCE_LEN);
941
  pos += NONCE_LEN;
942
  os_memcpy(pos, anonce, NONCE_LEN);
943
  pos += NONCE_LEN;
944
  if (dhss)
945
    os_memcpy(pos, dhss, dhss_len);
946
947
  ptk->kck_len = 0;
948
  ptk->kek_len = wpa_kek_len(akmp, pmk_len, PASN_GROUP_NOT_SPECIFIED);
949
  ptk->tk_len = wpa_cipher_key_len(cipher);
950
  if (wpa_key_mgmt_sha384(akmp))
951
    *ick_len = 48;
952
  else if (wpa_key_mgmt_sha256(akmp))
953
    *ick_len = 32;
954
  else
955
    goto err;
956
  key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
957
958
  if (kdk_len) {
959
    if (kdk_len > WPA_KDK_MAX_LEN) {
960
      wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
961
           kdk_len);
962
      goto err;
963
    }
964
965
    ptk->kdk_len = kdk_len;
966
    key_data_len += kdk_len;
967
  } else {
968
    ptk->kdk_len = 0;
969
  }
970
971
  if (fils_ft && fils_ft_len) {
972
    if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
973
      *fils_ft_len = 32;
974
    } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
975
      *fils_ft_len = 48;
976
    } else {
977
      *fils_ft_len = 0;
978
      fils_ft = NULL;
979
    }
980
    key_data_len += *fils_ft_len;
981
  }
982
983
  if (wpa_key_mgmt_sha384(akmp)) {
984
    wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
985
    if (sha384_prf(pmk, pmk_len, label, data, data_len,
986
             tmp, key_data_len) < 0)
987
      goto err;
988
  } else {
989
    wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA256)");
990
    if (sha256_prf(pmk, pmk_len, label, data, data_len,
991
             tmp, key_data_len) < 0)
992
      goto err;
993
  }
994
995
  wpa_printf(MSG_DEBUG, "FILS: PTK derivation - SPA=" MACSTR
996
       " AA=" MACSTR, MAC2STR(spa), MAC2STR(aa));
997
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, NONCE_LEN);
998
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, NONCE_LEN);
999
  if (dhss)
1000
    wpa_hexdump_key(MSG_DEBUG, "FILS: DHss", dhss, dhss_len);
1001
  wpa_hexdump_key(MSG_DEBUG, "FILS: PMK", pmk, pmk_len);
1002
  wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
1003
1004
  os_memcpy(ick, tmp, *ick_len);
1005
  offset = *ick_len;
1006
  wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
1007
1008
  os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
1009
  wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
1010
  offset += ptk->kek_len;
1011
1012
  os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
1013
  wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
1014
  offset += ptk->tk_len;
1015
1016
  if (fils_ft && fils_ft_len) {
1017
    os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
1018
    wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
1019
        fils_ft, *fils_ft_len);
1020
    offset += *fils_ft_len;
1021
  }
1022
1023
  if (ptk->kdk_len) {
1024
    os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
1025
    wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
1026
  }
1027
1028
  ptk->kek2_len = 0;
1029
  ptk->kck2_len = 0;
1030
1031
  os_memset(tmp, 0, sizeof(tmp));
1032
  ret = 0;
1033
err:
1034
  bin_clear_free(data, data_len);
1035
  return ret;
1036
}
1037
1038
1039
int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
1040
         const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
1041
         const u8 *g_sta, size_t g_sta_len,
1042
         const u8 *g_ap, size_t g_ap_len,
1043
         int akmp, u8 *key_auth_sta, u8 *key_auth_ap,
1044
         size_t *key_auth_len)
1045
{
1046
  const u8 *addr[6];
1047
  size_t len[6];
1048
  size_t num_elem = 4;
1049
  int res;
1050
1051
  wpa_printf(MSG_DEBUG, "FILS: Key-Auth derivation: STA-MAC=" MACSTR
1052
       " AP-BSSID=" MACSTR, MAC2STR(sta_addr), MAC2STR(bssid));
1053
  wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, ick_len);
1054
  wpa_hexdump(MSG_DEBUG, "FILS: SNonce", snonce, NONCE_LEN);
1055
  wpa_hexdump(MSG_DEBUG, "FILS: ANonce", anonce, NONCE_LEN);
1056
  wpa_hexdump(MSG_DEBUG, "FILS: gSTA", g_sta, g_sta_len);
1057
  wpa_hexdump(MSG_DEBUG, "FILS: gAP", g_ap, g_ap_len);
1058
1059
  /*
1060
   * For (Re)Association Request frame (STA->AP):
1061
   * Key-Auth = HMAC-Hash(ICK, SNonce || ANonce || STA-MAC || AP-BSSID
1062
   *                      [ || gSTA || gAP ])
1063
   */
1064
  addr[0] = snonce;
1065
  len[0] = NONCE_LEN;
1066
  addr[1] = anonce;
1067
  len[1] = NONCE_LEN;
1068
  addr[2] = sta_addr;
1069
  len[2] = ETH_ALEN;
1070
  addr[3] = bssid;
1071
  len[3] = ETH_ALEN;
1072
  if (g_sta && g_sta_len && g_ap && g_ap_len) {
1073
    addr[4] = g_sta;
1074
    len[4] = g_sta_len;
1075
    addr[5] = g_ap;
1076
    len[5] = g_ap_len;
1077
    num_elem = 6;
1078
  }
1079
1080
  if (wpa_key_mgmt_sha384(akmp)) {
1081
    *key_auth_len = 48;
1082
    res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
1083
           key_auth_sta);
1084
  } else if (wpa_key_mgmt_sha256(akmp)) {
1085
    *key_auth_len = 32;
1086
    res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
1087
           key_auth_sta);
1088
  } else {
1089
    return -1;
1090
  }
1091
  if (res < 0)
1092
    return res;
1093
1094
  /*
1095
   * For (Re)Association Response frame (AP->STA):
1096
   * Key-Auth = HMAC-Hash(ICK, ANonce || SNonce || AP-BSSID || STA-MAC
1097
   *                      [ || gAP || gSTA ])
1098
   */
1099
  addr[0] = anonce;
1100
  addr[1] = snonce;
1101
  addr[2] = bssid;
1102
  addr[3] = sta_addr;
1103
  if (g_sta && g_sta_len && g_ap && g_ap_len) {
1104
    addr[4] = g_ap;
1105
    len[4] = g_ap_len;
1106
    addr[5] = g_sta;
1107
    len[5] = g_sta_len;
1108
  }
1109
1110
  if (wpa_key_mgmt_sha384(akmp))
1111
    res = hmac_sha384_vector(ick, ick_len, num_elem, addr, len,
1112
           key_auth_ap);
1113
  else if (wpa_key_mgmt_sha256(akmp))
1114
    res = hmac_sha256_vector(ick, ick_len, num_elem, addr, len,
1115
           key_auth_ap);
1116
  if (res < 0)
1117
    return res;
1118
1119
  wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (STA)",
1120
        key_auth_sta, *key_auth_len);
1121
  wpa_hexdump(MSG_DEBUG, "FILS: Key-Auth (AP)",
1122
        key_auth_ap, *key_auth_len);
1123
1124
  return 0;
1125
}
1126
1127
#endif /* CONFIG_FILS */
1128
1129
1130
#ifdef CONFIG_IEEE80211R
1131
int wpa_ft_mic(int key_mgmt, const u8 *kck, size_t kck_len, const u8 *sta_addr,
1132
         const u8 *ap_addr, u8 transaction_seqnum,
1133
         const u8 *mdie, size_t mdie_len,
1134
         const u8 *ftie, size_t ftie_len,
1135
         const u8 *rsnie, size_t rsnie_len,
1136
         const u8 *ric, size_t ric_len,
1137
         const u8 *rsnxe, size_t rsnxe_len,
1138
         const struct wpabuf *extra,
1139
         u8 *mic)
1140
0
{
1141
0
  const u8 *addr[11];
1142
0
  size_t len[11];
1143
0
  size_t i, num_elem = 0;
1144
0
  u8 zero_mic[32];
1145
0
  size_t mic_len, fte_fixed_len;
1146
0
  int res;
1147
1148
0
  if (kck_len == 16) {
1149
0
    mic_len = 16;
1150
#ifdef CONFIG_SHA384
1151
  } else if (kck_len == 24) {
1152
    mic_len = 24;
1153
#endif /* CONFIG_SHA384 */
1154
#ifdef CONFIG_SHA512
1155
  } else if (kck_len == 32) {
1156
    mic_len = 32;
1157
#endif /* CONFIG_SHA512 */
1158
0
  } else {
1159
0
    wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
1160
0
         (unsigned int) kck_len);
1161
0
    return -1;
1162
0
  }
1163
1164
0
  fte_fixed_len = sizeof(struct rsn_ftie) - 16 + mic_len;
1165
1166
0
  addr[num_elem] = sta_addr;
1167
0
  len[num_elem] = ETH_ALEN;
1168
0
  num_elem++;
1169
1170
0
  addr[num_elem] = ap_addr;
1171
0
  len[num_elem] = ETH_ALEN;
1172
0
  num_elem++;
1173
1174
0
  addr[num_elem] = &transaction_seqnum;
1175
0
  len[num_elem] = 1;
1176
0
  num_elem++;
1177
1178
0
  if (rsnie) {
1179
0
    addr[num_elem] = rsnie;
1180
0
    len[num_elem] = rsnie_len;
1181
0
    num_elem++;
1182
0
  }
1183
0
  if (mdie) {
1184
0
    addr[num_elem] = mdie;
1185
0
    len[num_elem] = mdie_len;
1186
0
    num_elem++;
1187
0
  }
1188
0
  if (ftie) {
1189
0
    if (ftie_len < 2 + fte_fixed_len)
1190
0
      return -1;
1191
1192
    /* IE hdr and mic_control */
1193
0
    addr[num_elem] = ftie;
1194
0
    len[num_elem] = 2 + 2;
1195
0
    num_elem++;
1196
1197
    /* MIC field with all zeros */
1198
0
    os_memset(zero_mic, 0, mic_len);
1199
0
    addr[num_elem] = zero_mic;
1200
0
    len[num_elem] = mic_len;
1201
0
    num_elem++;
1202
1203
    /* Rest of FTIE */
1204
0
    addr[num_elem] = ftie + 2 + 2 + mic_len;
1205
0
    len[num_elem] = ftie_len - (2 + 2 + mic_len);
1206
0
    num_elem++;
1207
0
  }
1208
0
  if (ric) {
1209
0
    addr[num_elem] = ric;
1210
0
    len[num_elem] = ric_len;
1211
0
    num_elem++;
1212
0
  }
1213
1214
0
  if (rsnxe) {
1215
0
    addr[num_elem] = rsnxe;
1216
0
    len[num_elem] = rsnxe_len;
1217
0
    num_elem++;
1218
0
  }
1219
1220
0
  if (extra) {
1221
0
    addr[num_elem] = wpabuf_head(extra);
1222
0
    len[num_elem] = wpabuf_len(extra);
1223
0
    num_elem++;
1224
0
  }
1225
1226
0
  for (i = 0; i < num_elem; i++)
1227
0
    wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
1228
0
  res = -1;
1229
#ifdef CONFIG_SHA512
1230
  if (kck_len == 32) {
1231
    u8 hash[SHA512_MAC_LEN];
1232
1233
    if (hmac_sha512_vector(kck, kck_len, num_elem, addr, len, hash))
1234
      return -1;
1235
    os_memcpy(mic, hash, 32);
1236
    res = 0;
1237
  }
1238
#endif /* CONFIG_SHA384 */
1239
#ifdef CONFIG_SHA384
1240
  if (kck_len == 24) {
1241
    u8 hash[SHA384_MAC_LEN];
1242
1243
    if (hmac_sha384_vector(kck, kck_len, num_elem, addr, len, hash))
1244
      return -1;
1245
    os_memcpy(mic, hash, 24);
1246
    res = 0;
1247
  }
1248
#endif /* CONFIG_SHA384 */
1249
0
  if (kck_len == 16 && key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1250
0
    u8 hash[SHA256_MAC_LEN];
1251
1252
0
    if (hmac_sha256_vector(kck, kck_len, num_elem, addr, len, hash))
1253
0
      return -1;
1254
0
    os_memcpy(mic, hash, 16);
1255
0
    res = 0;
1256
0
  }
1257
0
  if (kck_len == 16 && key_mgmt != WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
1258
0
      omac1_aes_128_vector(kck, num_elem, addr, len, mic) == 0)
1259
0
    res = 0;
1260
1261
0
  return res;
1262
0
}
1263
1264
1265
static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
1266
           struct wpa_ft_ies *parse, const u8 *opt)
1267
0
{
1268
0
  const u8 *end, *pos;
1269
0
  u8 link_id;
1270
1271
0
  pos = opt;
1272
0
  end = ie + ie_len;
1273
0
  wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos);
1274
1275
0
  while (end - pos >= 2) {
1276
0
    u8 id, len;
1277
1278
0
    id = *pos++;
1279
0
    len = *pos++;
1280
0
    if (len > end - pos) {
1281
0
      wpa_printf(MSG_DEBUG, "FT: Truncated subelement");
1282
0
      return -1;
1283
0
    }
1284
1285
0
    switch (id) {
1286
0
    case FTIE_SUBELEM_R1KH_ID:
1287
0
      if (len != FT_R1KH_ID_LEN) {
1288
0
        wpa_printf(MSG_DEBUG,
1289
0
             "FT: Invalid R1KH-ID length in FTIE: %d",
1290
0
             len);
1291
0
        return -1;
1292
0
      }
1293
0
      parse->r1kh_id = pos;
1294
0
      wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID",
1295
0
            parse->r1kh_id, FT_R1KH_ID_LEN);
1296
0
      break;
1297
0
    case FTIE_SUBELEM_GTK:
1298
0
      wpa_printf(MSG_DEBUG, "FT: GTK");
1299
0
      parse->gtk = pos;
1300
0
      parse->gtk_len = len;
1301
0
      break;
1302
0
    case FTIE_SUBELEM_R0KH_ID:
1303
0
      if (len < 1 || len > FT_R0KH_ID_MAX_LEN) {
1304
0
        wpa_printf(MSG_DEBUG,
1305
0
             "FT: Invalid R0KH-ID length in FTIE: %d",
1306
0
             len);
1307
0
        return -1;
1308
0
      }
1309
0
      parse->r0kh_id = pos;
1310
0
      parse->r0kh_id_len = len;
1311
0
      wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
1312
0
            parse->r0kh_id, parse->r0kh_id_len);
1313
0
      break;
1314
0
    case FTIE_SUBELEM_IGTK:
1315
0
      wpa_printf(MSG_DEBUG, "FT: IGTK");
1316
0
      parse->igtk = pos;
1317
0
      parse->igtk_len = len;
1318
0
      break;
1319
#ifdef CONFIG_OCV
1320
    case FTIE_SUBELEM_OCI:
1321
      parse->oci = pos;
1322
      parse->oci_len = len;
1323
      wpa_hexdump(MSG_DEBUG, "FT: OCI",
1324
            parse->oci, parse->oci_len);
1325
      break;
1326
#endif /* CONFIG_OCV */
1327
0
    case FTIE_SUBELEM_BIGTK:
1328
0
      wpa_printf(MSG_DEBUG, "FT: BIGTK");
1329
0
      parse->bigtk = pos;
1330
0
      parse->bigtk_len = len;
1331
0
      break;
1332
0
    case FTIE_SUBELEM_MLO_GTK:
1333
0
      if (len < 2 + 1 + 1 + 8) {
1334
0
        wpa_printf(MSG_DEBUG,
1335
0
             "FT: Too short MLO GTK in FTE");
1336
0
        return -1;
1337
0
      }
1338
0
      link_id = pos[2] & 0x0f;
1339
0
      wpa_printf(MSG_DEBUG, "FT: MLO GTK (Link ID %u)",
1340
0
           link_id);
1341
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1342
0
        break;
1343
0
      parse->valid_mlo_gtks |= BIT(link_id);
1344
0
      parse->mlo_gtk[link_id] = pos;
1345
0
      parse->mlo_gtk_len[link_id] = len;
1346
0
      break;
1347
0
    case FTIE_SUBELEM_MLO_IGTK:
1348
0
      if (len < 2 + 6 + 1 + 1) {
1349
0
        wpa_printf(MSG_DEBUG,
1350
0
             "FT: Too short MLO IGTK in FTE");
1351
0
        return -1;
1352
0
      }
1353
0
      link_id = pos[2 + 6] & 0x0f;
1354
0
      wpa_printf(MSG_DEBUG, "FT: MLO IGTK (Link ID %u)",
1355
0
           link_id);
1356
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1357
0
        break;
1358
0
      parse->valid_mlo_igtks |= BIT(link_id);
1359
0
      parse->mlo_igtk[link_id] = pos;
1360
0
      parse->mlo_igtk_len[link_id] = len;
1361
0
      break;
1362
0
    case FTIE_SUBELEM_MLO_BIGTK:
1363
0
      if (len < 2 + 6 + 1 + 1) {
1364
0
        wpa_printf(MSG_DEBUG,
1365
0
             "FT: Too short MLO BIGTK in FTE");
1366
0
        return -1;
1367
0
      }
1368
0
      link_id = pos[2 + 6] & 0x0f;
1369
0
      wpa_printf(MSG_DEBUG, "FT: MLO BIGTK (Link ID %u)",
1370
0
           link_id);
1371
0
      if (link_id >= MAX_NUM_MLD_LINKS)
1372
0
        break;
1373
0
      parse->valid_mlo_bigtks |= BIT(link_id);
1374
0
      parse->mlo_bigtk[link_id] = pos;
1375
0
      parse->mlo_bigtk_len[link_id] = len;
1376
0
      break;
1377
0
    default:
1378
0
      wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id);
1379
0
      break;
1380
0
    }
1381
1382
0
    pos += len;
1383
0
  }
1384
1385
0
  return 0;
1386
0
}
1387
1388
1389
static int wpa_ft_parse_fte(int key_mgmt, const u8 *ie, size_t len,
1390
          struct wpa_ft_ies *parse)
1391
0
{
1392
0
  size_t mic_len;
1393
0
  u8 mic_len_info;
1394
0
  const u8 *pos = ie;
1395
0
  const u8 *end = pos + len;
1396
1397
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC Control", pos, 2);
1398
0
  parse->fte_rsnxe_used = pos[0] & FTE_MIC_CTRL_RSNXE_USED;
1399
0
  mic_len_info = (pos[0] & FTE_MIC_CTRL_MIC_LEN_MASK) >>
1400
0
    FTE_MIC_CTRL_MIC_LEN_SHIFT;
1401
0
  parse->fte_elem_count = pos[1];
1402
0
  pos += 2;
1403
1404
0
  if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1405
0
    switch (mic_len_info) {
1406
0
    case FTE_MIC_LEN_16:
1407
0
      mic_len = 16;
1408
0
      break;
1409
0
    case FTE_MIC_LEN_24:
1410
0
      mic_len = 24;
1411
0
      break;
1412
0
    case FTE_MIC_LEN_32:
1413
0
      mic_len = 32;
1414
0
      break;
1415
0
    default:
1416
0
      wpa_printf(MSG_DEBUG,
1417
0
           "FT: Unknown MIC Length subfield value %u",
1418
0
           mic_len_info);
1419
0
      return -1;
1420
0
    }
1421
0
  } else {
1422
0
    mic_len = wpa_key_mgmt_sha384(key_mgmt) ? 24 : 16;
1423
0
  }
1424
0
  if (mic_len > (size_t) (end - pos)) {
1425
0
    wpa_printf(MSG_DEBUG, "FT: No room for %zu octet MIC in FTE",
1426
0
         mic_len);
1427
0
    return -1;
1428
0
  }
1429
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-MIC", pos, mic_len);
1430
0
  parse->fte_mic = pos;
1431
0
  parse->fte_mic_len = mic_len;
1432
0
  pos += mic_len;
1433
1434
0
  if (2 * WPA_NONCE_LEN > end - pos)
1435
0
    return -1;
1436
0
  parse->fte_anonce = pos;
1437
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-ANonce",
1438
0
        parse->fte_anonce, WPA_NONCE_LEN);
1439
0
  pos += WPA_NONCE_LEN;
1440
0
  parse->fte_snonce = pos;
1441
0
  wpa_hexdump(MSG_DEBUG, "FT: FTE-SNonce",
1442
0
        parse->fte_snonce, WPA_NONCE_LEN);
1443
0
  pos += WPA_NONCE_LEN;
1444
1445
0
  return wpa_ft_parse_ftie(ie, len, parse, pos);
1446
0
}
1447
1448
1449
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
1450
         int key_mgmt, bool reassoc_resp)
1451
0
{
1452
0
  const u8 *end, *pos;
1453
0
  struct wpa_ie_data data;
1454
0
  int ret;
1455
0
  int prot_ie_count = 0;
1456
0
  const u8 *fte = NULL;
1457
0
  size_t fte_len = 0;
1458
0
  bool is_fte = false;
1459
0
  struct ieee802_11_elems elems;
1460
1461
0
  os_memset(parse, 0, sizeof(*parse));
1462
0
  if (ies == NULL)
1463
0
    return 0;
1464
1465
0
  if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
1466
0
    wpa_printf(MSG_DEBUG, "FT: Failed to parse elements");
1467
0
    goto fail;
1468
0
  }
1469
1470
0
  pos = ies;
1471
0
  end = ies + ies_len;
1472
0
  while (end - pos >= 2) {
1473
0
    u8 id, len;
1474
1475
0
    id = *pos++;
1476
0
    len = *pos++;
1477
0
    if (len > end - pos)
1478
0
      break;
1479
1480
0
    if (id != WLAN_EID_FAST_BSS_TRANSITION &&
1481
0
        id != WLAN_EID_FRAGMENT)
1482
0
      is_fte = false;
1483
1484
0
    switch (id) {
1485
0
    case WLAN_EID_RSN:
1486
0
      wpa_hexdump(MSG_DEBUG, "FT: RSNE", pos, len);
1487
0
      parse->rsn = pos;
1488
0
      parse->rsn_len = len;
1489
0
      ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
1490
0
               parse->rsn_len + 2,
1491
0
               &data);
1492
0
      if (ret < 0) {
1493
0
        wpa_printf(MSG_DEBUG, "FT: Failed to parse "
1494
0
             "RSN IE: %d", ret);
1495
0
        goto fail;
1496
0
      }
1497
0
      parse->rsn_capab = data.capabilities;
1498
0
      if (data.num_pmkid == 1 && data.pmkid)
1499
0
        parse->rsn_pmkid = data.pmkid;
1500
0
      parse->key_mgmt = data.key_mgmt;
1501
0
      parse->pairwise_cipher = data.pairwise_cipher;
1502
0
      if (!key_mgmt)
1503
0
        key_mgmt = parse->key_mgmt;
1504
0
      break;
1505
0
    case WLAN_EID_RSNX:
1506
0
      wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len);
1507
0
      if (len < 1)
1508
0
        break;
1509
0
      parse->rsnxe = pos;
1510
0
      parse->rsnxe_len = len;
1511
0
      break;
1512
0
    case WLAN_EID_MOBILITY_DOMAIN:
1513
0
      wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len);
1514
0
      if (len < sizeof(struct rsn_mdie))
1515
0
        goto fail;
1516
0
      parse->mdie = pos;
1517
0
      parse->mdie_len = len;
1518
0
      break;
1519
0
    case WLAN_EID_FAST_BSS_TRANSITION:
1520
0
      wpa_hexdump(MSG_DEBUG, "FT: FTE", pos, len);
1521
      /* The first two octets (MIC Control field) is in the
1522
       * same offset for all cases, but the second field (MIC)
1523
       * has variable length with three different values.
1524
       * In particular the FT-SAE-EXT-KEY is inconvinient to
1525
       * parse, so try to handle this in pieces instead of
1526
       * using the struct rsn_ftie* definitions. */
1527
1528
0
      if (len < 2)
1529
0
        goto fail;
1530
0
      prot_ie_count = pos[1]; /* Element Count field in
1531
             * MIC Control */
1532
0
      is_fte = true;
1533
0
      fte = pos;
1534
0
      fte_len = len;
1535
0
      break;
1536
0
    case WLAN_EID_FRAGMENT:
1537
0
      if (is_fte) {
1538
0
        wpa_hexdump(MSG_DEBUG, "FT: FTE fragment",
1539
0
              pos, len);
1540
0
        fte_len += 2 + len;
1541
0
      }
1542
0
      break;
1543
0
    case WLAN_EID_TIMEOUT_INTERVAL:
1544
0
      wpa_hexdump(MSG_DEBUG, "FT: Timeout Interval",
1545
0
            pos, len);
1546
0
      if (len != 5)
1547
0
        break;
1548
0
      parse->tie = pos;
1549
0
      parse->tie_len = len;
1550
0
      break;
1551
0
    case WLAN_EID_RIC_DATA:
1552
0
      if (parse->ric == NULL)
1553
0
        parse->ric = pos - 2;
1554
0
      break;
1555
0
    }
1556
1557
0
    pos += len;
1558
0
  }
1559
1560
0
  if (fte) {
1561
0
    int res;
1562
1563
0
    if (fte_len < 255) {
1564
0
      res = wpa_ft_parse_fte(key_mgmt, fte, fte_len, parse);
1565
0
    } else {
1566
0
      parse->fte_buf = ieee802_11_defrag(fte, fte_len, false);
1567
0
      if (!parse->fte_buf)
1568
0
        goto fail;
1569
0
      res = wpa_ft_parse_fte(key_mgmt,
1570
0
                 wpabuf_head(parse->fte_buf),
1571
0
                 wpabuf_len(parse->fte_buf),
1572
0
                 parse);
1573
0
    }
1574
0
    if (res < 0)
1575
0
      goto fail;
1576
1577
    /* FTE might be fragmented. If it is, the separate Fragment
1578
     * elements are included in MIC calculation as full elements. */
1579
0
    parse->ftie = fte;
1580
0
    parse->ftie_len = fte_len;
1581
0
  }
1582
1583
0
  if (prot_ie_count == 0)
1584
0
    return 0; /* no MIC */
1585
1586
  /*
1587
   * Check that the protected IE count matches with IEs included in the
1588
   * frame.
1589
   */
1590
0
  if (reassoc_resp && elems.basic_mle) {
1591
0
    unsigned int link_id;
1592
1593
    /* TODO: This count should be done based on all _requested_,
1594
     * not _accepted_ links. */
1595
0
    for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
1596
0
      if (parse->mlo_gtk[link_id]) {
1597
0
        if (parse->rsn)
1598
0
          prot_ie_count--;
1599
0
        if (parse->rsnxe)
1600
0
          prot_ie_count--;
1601
0
      }
1602
0
    }
1603
0
  } else {
1604
0
    if (parse->rsn)
1605
0
      prot_ie_count--;
1606
0
    if (parse->rsnxe)
1607
0
      prot_ie_count--;
1608
0
  }
1609
0
  if (parse->mdie)
1610
0
    prot_ie_count--;
1611
0
  if (parse->ftie)
1612
0
    prot_ie_count--;
1613
0
  if (prot_ie_count < 0) {
1614
0
    wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
1615
0
         "the protected IE count");
1616
0
    goto fail;
1617
0
  }
1618
1619
0
  if (prot_ie_count == 0 && parse->ric) {
1620
0
    wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
1621
0
         "included in protected IE count");
1622
0
    goto fail;
1623
0
  }
1624
1625
  /* Determine the end of the RIC IE(s) */
1626
0
  if (parse->ric) {
1627
0
    pos = parse->ric;
1628
0
    while (end - pos >= 2 && 2 + pos[1] <= end - pos &&
1629
0
           prot_ie_count) {
1630
0
      prot_ie_count--;
1631
0
      pos += 2 + pos[1];
1632
0
    }
1633
0
    parse->ric_len = pos - parse->ric;
1634
0
  }
1635
0
  if (prot_ie_count) {
1636
0
    wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
1637
0
         "frame", (int) prot_ie_count);
1638
0
    goto fail;
1639
0
  }
1640
1641
0
  return 0;
1642
1643
0
fail:
1644
0
  wpa_ft_parse_ies_free(parse);
1645
0
  return -1;
1646
0
}
1647
1648
1649
void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse)
1650
0
{
1651
0
  if (!parse)
1652
0
    return;
1653
0
  wpabuf_free(parse->fte_buf);
1654
0
  parse->fte_buf = NULL;
1655
0
}
1656
1657
#endif /* CONFIG_IEEE80211R */
1658
1659
1660
#ifdef CONFIG_PASN
1661
1662
/*
1663
 * pasn_use_sha384 - Should SHA384 be used or SHA256
1664
 *
1665
 * @akmp: Authentication and key management protocol
1666
 * @cipher: The cipher suite
1667
 *
1668
 * According to IEEE Std 802.11-2024, 12.13.8 (PTKSA derivation with PASN
1669
 * authentication), the hash algorithm to use is the
1670
 * hash algorithm defined for the Base AKM (see Table 9-190 (AKM suite
1671
 * selectors)). When there is no Base AKM, the hash algorithm is selected based
1672
 * on the pairwise cipher suite provided in the RSNE by the AP in the second
1673
 * PASN frame. SHA-256 is used as the hash algorithm, except for the ciphers
1674
 * 00-0F-AC:9 and 00-0F-AC:10 for which SHA-384 is used.
1675
 */
1676
static bool pasn_use_sha384(int akmp, int cipher)
1677
{
1678
  return ((akmp == WPA_KEY_MGMT_PASN || akmp == WPA_KEY_MGMT_EPPKE) &&
1679
    (cipher == WPA_CIPHER_CCMP_256 ||
1680
     cipher == WPA_CIPHER_GCMP_256)) ||
1681
    wpa_key_mgmt_sha384(akmp);
1682
}
1683
1684
1685
/**
1686
 * pasn_select_hash_alg - Select hash algorithm for PTK derivation
1687
 * @akmp: Authentication and key management protocol
1688
 * @cipher: The cipher suite
1689
 * @pmk_len: PMK length in octets
1690
 *
1691
 * According to IEEE Std 802.11-2024, Table 9-190 (AKM suite selectors), AKMs
1692
 * 00-0F-AC:24 and 00-0F-AC:25 have the length of the PMK, the length
1693
 * of the SAE key confirmation key, SAE-KCK, and PTK-KCK, and the length of
1694
 * PTK-KEK depending on the hash algorithm specified in 12.4.2 (see 12.7.1.3
1695
 * and 12.7.3), i.e, the hash algorithm depends on the prime length associated
1696
 * with the selected group per Table 12-1 (Hash algorithm based on length of
1697
 * prime).
1698
 */
1699
static enum rsn_hash_alg pasn_select_hash_alg(int akmp, int cipher,
1700
                size_t pmk_len)
1701
{
1702
#ifdef CONFIG_SAE
1703
  if (wpa_key_mgmt_sae_ext_key(akmp)) {
1704
    if (pmk_len == 64)
1705
      return RSN_HASH_SHA512;
1706
    if (pmk_len == 48)
1707
      return RSN_HASH_SHA384;
1708
  }
1709
#endif /* CONFIG_SAE */
1710
1711
  if (pasn_use_sha384(akmp, cipher))
1712
    return RSN_HASH_SHA384;
1713
1714
  return RSN_HASH_SHA256;
1715
}
1716
1717
1718
/**
1719
 * pasn_pmk_to_ptk - Calculate PASN/EPPKE PTK from PMK, addresses, etc.
1720
 * @pmk: Pairwise master key
1721
 * @pmk_len: Length of PMK
1722
 * @spa: For EPPKE authentication, non-AP MLD MAC address is used for MLO. For
1723
 *  PASN authentication or EPPKE authentication for non-MLO, non-AP STA link
1724
 *  MAC address is used.
1725
 * @bssid: For EPPKE authentication, AP MLD MAC address is used for MLO. For
1726
 *  PASN authentication or EPPKE authentication for non-MLO, AP BSSID is
1727
 *  used.
1728
 * @dhss: Is the shared secret (DHss) derived from the PASN ephemeral key
1729
 *  exchange encoded as an octet string
1730
 * @dhss_len: The length of dhss in octets
1731
 * @ptk: Buffer for pairwise transient key
1732
 * @akmp: Negotiated AKM
1733
 * @cipher: Negotiated pairwise cipher
1734
 * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
1735
 * @kek_len: The length in octets that should be derived for KEK. Can be zero.
1736
 * @alg: Output variable for indicating the selected hash algorithm
1737
 * @is_eppke: EPPKE authentication
1738
 * Returns: 0 on success, -1 on failure
1739
 */
1740
int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
1741
        const u8 *spa, const u8 *bssid,
1742
        const u8 *dhss, size_t dhss_len,
1743
        struct wpa_ptk *ptk, int akmp, int cipher,
1744
        size_t kdk_len, size_t kek_len, enum rsn_hash_alg *alg,
1745
        bool is_eppke)
1746
{
1747
  u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
1748
         WPA_KDK_MAX_LEN];
1749
  const u8 *pos;
1750
  u8 *data;
1751
  size_t data_len, ptk_len;
1752
  int ret = -1;
1753
  const char *label = is_eppke ? "EPPKE PTK Derivation" :
1754
    "PASN PTK Derivation";
1755
1756
  if (!pmk || !pmk_len) {
1757
    wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
1758
    return -1;
1759
  }
1760
1761
  if (!dhss || !dhss_len) {
1762
    wpa_printf(MSG_ERROR, "PASN: No DHss set for PTK derivation");
1763
    return -1;
1764
  }
1765
1766
  /*
1767
   * Use "EPPKE PTK Derivation" instead of “PASN PTK Derivation” for
1768
   * EPPKE Authentication per IEEE P802.11bi/D4.0, 12.16.9.3.4 (PTKSA
1769
   * derivation and MIC computation with EPPKE authentication). For EPPKE
1770
   * MLO, the non-AP MLD MAC address is used instead of the SPA and the
1771
   * AP MLD MAC address instead of the BSSID.
1772
   *
1773
   * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
1774
   *
1775
   * KCK = L(PASN-PTK, 0, 256)
1776
   * TK = L(PASN-PTK, 256, TK_bits)
1777
   * KDK = L(PASN-PTK, 256 + TK_bits, kdk_len * 8)
1778
   */
1779
  data_len = 2 * ETH_ALEN + dhss_len;
1780
  data = os_zalloc(data_len);
1781
  if (!data)
1782
    return -1;
1783
1784
  os_memcpy(data, spa, ETH_ALEN);
1785
  os_memcpy(data + ETH_ALEN, bssid, ETH_ALEN);
1786
  os_memcpy(data + 2 * ETH_ALEN, dhss, dhss_len);
1787
1788
  ptk->kck_len = WPA_PASN_KCK_LEN;
1789
  ptk->tk_len = wpa_cipher_key_len(cipher);
1790
  ptk->kdk_len = kdk_len;
1791
  ptk->kek_len = kek_len;
1792
  ptk->kek2_len = 0;
1793
  ptk->kck2_len = 0;
1794
1795
  if (ptk->tk_len == 0) {
1796
    wpa_printf(MSG_ERROR,
1797
         "PASN: Unsupported cipher (0x%x) used in PTK derivation",
1798
         cipher);
1799
    goto err;
1800
  }
1801
1802
  ptk_len = ptk->kck_len + ptk->tk_len + ptk->kdk_len + ptk->kek_len;
1803
  if (ptk_len > sizeof(tmp))
1804
    goto err;
1805
1806
  *alg = pasn_select_hash_alg(akmp, cipher, pmk_len);
1807
1808
  switch (*alg) {
1809
  case RSN_HASH_SHA512:
1810
#ifdef CONFIG_SHA512
1811
    wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA512");
1812
1813
    if (sha512_prf(pmk, pmk_len, label, data, data_len, tmp,
1814
             ptk_len) < 0)
1815
      goto err;
1816
    break;
1817
#endif
1818
  case RSN_HASH_SHA384:
1819
#ifdef CONFIG_SHA384
1820
    wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA384");
1821
1822
    if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp,
1823
             ptk_len) < 0)
1824
      goto err;
1825
    break;
1826
#endif
1827
  case RSN_HASH_SHA256:
1828
    wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA256");
1829
1830
    if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp,
1831
             ptk_len) < 0)
1832
      goto err;
1833
    break;
1834
  default:
1835
    wpa_printf(MSG_DEBUG, "PASN: Unsupported hash algorithm %d",
1836
         *alg);
1837
    goto err;
1838
  }
1839
1840
  wpa_printf(MSG_DEBUG,
1841
       "PASN: PTK derivation: SPA=" MACSTR " BSSID=" MACSTR,
1842
       MAC2STR(spa), MAC2STR(bssid));
1843
1844
  wpa_hexdump_key(MSG_DEBUG, "PASN: DHss", dhss, dhss_len);
1845
  wpa_hexdump_key(MSG_DEBUG, "PASN: PMK", pmk, pmk_len);
1846
  wpa_hexdump_key(MSG_DEBUG, "PASN: PASN-PTK", tmp, ptk_len);
1847
1848
  os_memcpy(ptk->kck, tmp, WPA_PASN_KCK_LEN);
1849
  wpa_hexdump_key(MSG_DEBUG, "PASN: KCK:", ptk->kck, WPA_PASN_KCK_LEN);
1850
  pos = &tmp[WPA_PASN_KCK_LEN];
1851
1852
  if (kek_len) {
1853
    os_memcpy(ptk->kek, pos, kek_len);
1854
    wpa_hexdump_key(MSG_DEBUG, "PASN: KEK:",
1855
        ptk->kek, ptk->kek_len);
1856
    pos += kek_len;
1857
  }
1858
1859
  os_memcpy(ptk->tk, pos, ptk->tk_len);
1860
  wpa_hexdump_key(MSG_DEBUG, "PASN: TK:", ptk->tk, ptk->tk_len);
1861
  pos += ptk->tk_len;
1862
1863
  if (kdk_len) {
1864
    os_memcpy(ptk->kdk, pos, ptk->kdk_len);
1865
    wpa_hexdump_key(MSG_DEBUG, "PASN: KDK:",
1866
        ptk->kdk, ptk->kdk_len);
1867
  }
1868
1869
  ptk->ptk_len = ptk_len;
1870
  ptk->hash_alg = *alg;
1871
  forced_memzero(tmp, sizeof(tmp));
1872
  ret = 0;
1873
err:
1874
  bin_clear_free(data, data_len);
1875
  return ret;
1876
}
1877
1878
1879
size_t wpa_hash_len(enum rsn_hash_alg hash)
1880
{
1881
  switch (hash) {
1882
  case RSN_HASH_SHA256:
1883
    return SHA256_MAC_LEN;
1884
  case RSN_HASH_SHA384:
1885
    return SHA384_MAC_LEN;
1886
  case RSN_HASH_SHA512:
1887
    return SHA512_MAC_LEN;
1888
  default:
1889
    return 0;
1890
  }
1891
}
1892
1893
1894
#ifdef CONFIG_PQC
1895
/**
1896
 * pqc_pmk_to_ptk - Derive PTK from PMK for PQC cases
1897
 * @pmk: PMK buffer
1898
 * @pmk_len: Length of PMK in octets
1899
 * @spa: Supplicant address
1900
 * @aa: Authenticator address
1901
 * @hash: Selected hash algorithm
1902
 * @cipher: Negotiated pairwise cipher
1903
 * @dhss: Diffie-Hellman shared secret. NULL, if not used.
1904
 * @dhss_len: Length of dhss in octets. Zero, if dhss is NULL.
1905
 * @ml_kem_ss: ML-KEM shared secret (32 octets)
1906
 * @transcript: Transcript hash of the authentication exchange
1907
 * @transcript_len: Length of the transcript hash in octets
1908
 * @ptk: Buffer for PTK
1909
 * @kdk_len: Length in octets that should be derived for KDK. Can be zero.
1910
 * Returns: 0 on success, -1 on failure
1911
 */
1912
int pqc_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
1913
       enum rsn_hash_alg hash, int cipher,
1914
       const u8 *dhss, size_t dhss_len, const u8 *ml_kem_ss,
1915
       const u8 *transcript, size_t transcript_len,
1916
       struct wpa_ptk *ptk, size_t kdk_len)
1917
{
1918
  static const char *label = "Pairwise key expansion";
1919
  size_t label_len = os_strlen(label);
1920
  u8 data[os_strlen(label) + 2 * ETH_ALEN];
1921
  u8 prk[SHA512_MAC_LEN];
1922
  u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
1923
         WPA_KDK_MAX_LEN];
1924
  size_t hash_len;
1925
  const u8 *addrs[3];
1926
  size_t addrs_len[3];
1927
  unsigned int idx = 0;
1928
  size_t ptk_len;
1929
  int ret = -1;
1930
1931
  wpa_printf(MSG_DEBUG, "PQC PMK to PTK: hash=%d", hash);
1932
1933
  hash_len = wpa_hash_len(hash);
1934
  if (!hash_len) {
1935
    wpa_printf(MSG_DEBUG,
1936
         "RSN: Unsupported hash algorithm %d for PQC PTK derivation",
1937
         hash);
1938
    return -1;
1939
  }
1940
1941
  if (!pmk || !pmk_len) {
1942
    wpa_printf(MSG_DEBUG, "RSN: No PMK for PTK derivation");
1943
    return -1;
1944
  }
1945
1946
  /* IEEE P802.11bt/D1.0, 12.7.1.3: PMK_bits is the hash output length */
1947
  if (pmk_len != hash_len) {
1948
    wpa_printf(MSG_DEBUG,
1949
         "RSN: Unexpected PMK length %zu for PQC PTK derivation (expected %zu)",
1950
         pmk_len, hash_len);
1951
    return -1;
1952
  }
1953
1954
  if (kdk_len > WPA_KDK_MAX_LEN) {
1955
    wpa_printf(MSG_DEBUG,
1956
         "RSN: KDK len=%zu exceeds max supported length",
1957
         kdk_len);
1958
    return -1;
1959
  }
1960
1961
  if (!transcript || !transcript_len) {
1962
    wpa_printf(MSG_DEBUG,
1963
         "RSN: No transcript hash for PQC PTK derivation");
1964
    return -1;
1965
  }
1966
1967
  /* IEEE P802.11bt/D1.0, Table 12-13: KCK_bits is 128/192/256 */
1968
  ptk->kck_len = pmk_len / 2;
1969
  /* IEEE P802.11bt/D1.0, Table 12-13: KEK_bits is 128/256/256 */
1970
  ptk->kek_len = hash == RSN_HASH_SHA256 ? 16 : 32;
1971
  ptk->tk_len = wpa_cipher_key_len(cipher);
1972
  ptk->kdk_len = kdk_len;
1973
  ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
1974
  ptk->hash_alg = hash;
1975
1976
  /*
1977
   * PRK = HKDF-Extract(T, EPHss || IKM)
1978
   * Where EPHss is:
1979
   * - MLKEMss for PQC profile 0
1980
   * - DHss || MLKEMss for PQC profile 1, 2 and 3
1981
   * Where IKM is:
1982
   * - PMK-R1 for FT
1983
   * - PMK otherwise
1984
   */
1985
  if (dhss && dhss_len) {
1986
    addrs[idx] = dhss;
1987
    addrs_len[idx] = dhss_len;
1988
    idx++;
1989
  }
1990
1991
  if (!ml_kem_ss) {
1992
    wpa_printf(MSG_DEBUG, "RSN: No MLKEMss for PQC PTK derivation");
1993
    return -1;
1994
  }
1995
  addrs[idx] = ml_kem_ss;
1996
  addrs_len[idx] = CRYPTO_ML_KEM_SS_LEN;
1997
  idx++;
1998
1999
  addrs[idx] = pmk;
2000
  addrs_len[idx] = pmk_len;
2001
  idx++;
2002
2003
  if (hkdf_extract(hash_len, transcript, transcript_len,
2004
       idx, addrs, addrs_len, prk) < 0) {
2005
    wpa_printf(MSG_DEBUG,
2006
         "RSN: HKDF-Extract failed for PQC PMK to PTK");
2007
    goto err;
2008
  }
2009
2010
2011
  /*
2012
   * PTK = HKDF-Expand(PRK, Pairwise key expansion" || SPA || AA,
2013
   *         Length)
2014
   */
2015
  os_memcpy(data, label, label_len);
2016
  os_memcpy(data + label_len, spa, ETH_ALEN);
2017
  os_memcpy(data + label_len + ETH_ALEN, aa, ETH_ALEN);
2018
2019
  if (hkdf_expand_bin(hash_len, prk, hash_len, data, sizeof(data),
2020
          tmp, ptk_len) < 0) {
2021
    wpa_printf(MSG_DEBUG,
2022
         "RSN: HKDF-Expand failed for PQC PMK to PTK");
2023
    goto err;
2024
  }
2025
2026
  wpa_printf(MSG_DEBUG,
2027
       "RSN: PQC: PTK derivation - SPA=" MACSTR " AA=" MACSTR,
2028
       MAC2STR(spa), MAC2STR(aa));
2029
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: PMK", pmk, pmk_len);
2030
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: T", transcript, transcript_len);
2031
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: PTK", tmp, ptk_len);
2032
2033
  os_memcpy(ptk->kck, tmp, ptk->kck_len);
2034
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: KCK", ptk->kck, ptk->kck_len);
2035
2036
  os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
2037
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: KEK", ptk->kek, ptk->kek_len);
2038
2039
  os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
2040
  wpa_hexdump_key(MSG_DEBUG, "RSN: PQC: TK", ptk->tk, ptk->tk_len);
2041
2042
  if (kdk_len) {
2043
    os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
2044
        ptk->tk_len, ptk->kdk_len);
2045
    wpa_hexdump_key(MSG_DEBUG,
2046
        "RSN: PQC: KDK", ptk->kdk, ptk->kdk_len);
2047
  }
2048
2049
  ptk->kek2_len = 0;
2050
  ptk->kck2_len = 0;
2051
2052
  ptk->ptk_len = ptk_len;
2053
  ret = 0;
2054
2055
err:
2056
  forced_memzero(tmp, sizeof(tmp));
2057
  forced_memzero(prk, sizeof(prk));
2058
2059
  return ret;
2060
}
2061
#endif /* CONFIG_PQC */
2062
2063
/*
2064
 * pasn_mic_len - Returns the MIC length for PASN authentication
2065
 * @alg: Selected hash algorithm from pasn_pmk_to_ptk()
2066
 */
2067
size_t pasn_mic_len(enum rsn_hash_alg alg)
2068
{
2069
  switch (alg) {
2070
  case RSN_HASH_SHA512:
2071
    return 32;
2072
  case RSN_HASH_SHA384:
2073
    return 24;
2074
  case RSN_HASH_SHA256:
2075
  default:
2076
    return 16;
2077
  }
2078
}
2079
2080
2081
/**
2082
 * wpa_ltf_keyseed - Compute LTF keyseed from KDK
2083
 * @ptk: Buffer that holds pairwise transient key
2084
 * @akmp: Negotiated AKM
2085
 * @cipher: Negotiated pairwise cipher
2086
 * Returns: 0 on success, -1 on failure
2087
 */
2088
int wpa_ltf_keyseed(struct wpa_ptk *ptk, int akmp, int cipher)
2089
{
2090
  u8 *buf;
2091
  size_t buf_len;
2092
  u8 hash[SHA384_MAC_LEN];
2093
  const u8 *kdk = ptk->kdk;
2094
  size_t kdk_len = ptk->kdk_len;
2095
  const char *label = "Secure LTF key seed";
2096
2097
  if (!kdk || !kdk_len) {
2098
    wpa_printf(MSG_ERROR, "WPA: No KDK for LTF keyseed generation");
2099
    return -1;
2100
  }
2101
2102
  buf = (u8 *)label;
2103
  buf_len = os_strlen(label);
2104
2105
  if (pasn_use_sha384(akmp, cipher)) {
2106
    wpa_printf(MSG_DEBUG,
2107
         "WPA: Secure LTF keyseed using HMAC-SHA384");
2108
2109
    if (hmac_sha384(kdk, kdk_len, buf, buf_len, hash)) {
2110
      wpa_printf(MSG_ERROR,
2111
           "WPA: HMAC-SHA384 compute failed");
2112
      return -1;
2113
    }
2114
    os_memcpy(ptk->ltf_keyseed, hash, SHA384_MAC_LEN);
2115
    ptk->ltf_keyseed_len = SHA384_MAC_LEN;
2116
    wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
2117
        ptk->ltf_keyseed, ptk->ltf_keyseed_len);
2118
2119
  } else {
2120
    wpa_printf(MSG_DEBUG, "WPA: LTF keyseed using HMAC-SHA256");
2121
2122
    if (hmac_sha256(kdk, kdk_len, buf, buf_len, hash)) {
2123
      wpa_printf(MSG_ERROR,
2124
           "WPA: HMAC-SHA256 compute failed");
2125
      return -1;
2126
    }
2127
    os_memcpy(ptk->ltf_keyseed, hash, SHA256_MAC_LEN);
2128
    ptk->ltf_keyseed_len = SHA256_MAC_LEN;
2129
    wpa_hexdump_key(MSG_DEBUG, "WPA: Secure LTF keyseed: ",
2130
        ptk->ltf_keyseed, ptk->ltf_keyseed_len);
2131
  }
2132
2133
  return 0;
2134
}
2135
2136
2137
#ifdef CONFIG_IEEE8021X_AUTH
2138
2139
int wpa_auth_802_1x_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa,
2140
             const u8 *aa, const u8 *snonce, const u8 *anonce,
2141
             int akmp, int cipher, const u8 *dhss,
2142
             size_t dhss_len, struct wpa_ptk *ptk,
2143
             size_t kdk_len)
2144
{
2145
  return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
2146
            spa, aa, snonce, anonce, ptk, akmp,
2147
            cipher, dhss, dhss_len, kdk_len,
2148
            PASN_GROUP_NOT_SPECIFIED);
2149
}
2150
2151
2152
/**
2153
 * wpa_auth_8021x_mic - Calculate IEEE 802.1X in Authentication frames  MIC
2154
 * @akmp: Negotiated key management protocol
2155
 * @hash_alg: Hash algorithm to use for MIC calculation
2156
 * @kck: The key confirmation key from 802.1X exchange
2157
 * @kck_len: KCK length in octets
2158
 * @addr1: Authenticator address
2159
 * @addr2: Supplicant address
2160
 * @data: This should hold the RSNE + RSNXE.
2161
 *  For a MIC included by the AP with EAP-Success and the second
2162
 *  Authentication frame if a PMKSA was identified via a PMKID included in
2163
 *  the first Authentication frame, this holds the Beacon frame RSNE+RSNXE.
2164
 *  For a MIC included by the non-AP STA in the (Re)Association Request
2165
 *  frame, this holds the RSNE and RSNXE sent by the non-AP STA.
2166
 * @data_len: The length of data
2167
 * @frame: For a MIC included by the AP in EAP-Success and the second
2168
 *  Authentication frame if a PMKSA was identified via a PMKID included in
2169
 *  the first Authentication frame, this holds the body of the
2170
 *  Authentication frame including the MIC element with the octets in the
2171
 *  MIC field of the MIC element set to 0, else NULL
2172
 * @frame_len: The length of frame
2173
 * @mic: Buffer to hold the MIC on success. Must be large enough to handle the
2174
 *  maximal MIC length.
2175
 * Returns: 0 on success, -1 on failure
2176
 *
2177
 * HMAC-HASH (PTK-KCK, AA || SPA || RSNE || RSNXE || Frame Data)
2178
 */
2179
int wpa_auth_8021x_mic(int akmp, enum rsn_hash_alg hash_alg,
2180
           const u8 *kck, size_t kck_len, const u8 *addr1,
2181
           const u8 *addr2, const u8 *data, size_t data_len,
2182
           const u8 *frame, size_t frame_len, u8 *mic)
2183
{
2184
  size_t mic_len;
2185
  u8 *buf;
2186
  int ret = -1;
2187
  size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
2188
2189
  if (!kck) {
2190
    wpa_printf(MSG_INFO, "802.1X: No KCK for MIC calculation");
2191
    return -1;
2192
  }
2193
2194
  if (!data || !data_len) {
2195
    wpa_printf(MSG_INFO,
2196
         "802.1X: Invalid data for MIC calculation");
2197
    return -1;
2198
  }
2199
2200
  buf = os_zalloc(buf_len);
2201
  if (!buf)
2202
    return -1;
2203
2204
  wpa_printf(MSG_DEBUG, "802.1X MIC calculation");
2205
  wpa_printf(MSG_DEBUG, "addr1: " MACSTR, MAC2STR(addr1));
2206
  wpa_printf(MSG_DEBUG, "addr2: " MACSTR, MAC2STR(addr2));
2207
2208
  os_memcpy(buf, addr1, ETH_ALEN);
2209
  os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
2210
2211
  wpa_hexdump_key(MSG_DEBUG, "MIC: data", data, data_len);
2212
  os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
2213
2214
  wpa_hexdump_key(MSG_DEBUG, "MIC: KCK", kck, kck_len);
2215
2216
  if (frame) {
2217
    wpa_hexdump_key(MSG_MSGDUMP, "802.1X: MIC: frame",
2218
        frame, frame_len);
2219
    os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
2220
  }
2221
2222
  wpa_hexdump_key(MSG_DEBUG, "MIC: buf", buf, buf_len);
2223
2224
  if (hash_alg == RSN_HASH_SHA512) {
2225
    wpa_printf(MSG_DEBUG, "MIC: HMAC-SHA512");
2226
    mic_len = 32;
2227
2228
    if (hmac_sha512(kck, kck_len, buf, buf_len, mic) < 0)
2229
      goto out;
2230
  } else if (hash_alg == RSN_HASH_SHA384 ||
2231
       wpa_key_mgmt_sha384(akmp)) {
2232
    wpa_printf(MSG_DEBUG, "MIC: HMAC-SHA384");
2233
    mic_len = 24;
2234
2235
    if (hmac_sha384(kck, kck_len, buf, buf_len, mic) < 0)
2236
      goto out;
2237
  } else {
2238
    wpa_printf(MSG_DEBUG, "MIC: HMAC-SHA256");
2239
    mic_len = 16;
2240
2241
    if (hmac_sha256(kck, kck_len, buf, buf_len, mic) < 0)
2242
      goto out;
2243
  }
2244
2245
  wpa_hexdump_key(MSG_DEBUG, "802.1X: Calculated MIC", mic, mic_len);
2246
  ret = 0;
2247
out:
2248
  bin_clear_free(buf, buf_len);
2249
  return ret;
2250
}
2251
2252
#endif /* CONFIG_IEEE8021X_AUTH */
2253
2254
2255
/**
2256
 * pasn_mic - Calculate PASN MIC
2257
 * @alg: Selected hash algorithm from pasn_pmk_to_ptk()
2258
 * @kck: The key confirmation key for the PASN PTKSA
2259
 * @kck_len: KCK length in octets
2260
 * @addr1: For the 2nd PASN/EPPKE frame supplicant address is used for non-MLO;
2261
 *  for MLO, 2nd EPPKE authentication to use non-AP MLD MAC address.
2262
 *  For the 3rd PASN/EPPKE frame BSSID is used for non-MLO; for MLO, 3rd
2263
 *  EPPKE authentication to use AP MLD MAC address as per
2264
 * @addr2: For the 2nd PASN/EPPKE frame BSSID is used for non-MLO; for MLO, 2nd
2265
 *  EPPKE authentication to use AP MLD MAC address. For the 3rd PASN/EPPKE
2266
 *  frame supplicant address is used for non-MLO; for MLO, 3rd EPPKE
2267
 *  Authentication frame to use non-AP MLD MAC address.
2268
 * @data: For calculating the MIC for the 2nd PASN frame, this should hold the
2269
 *  Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
2270
 *  frame, this should hold the hash of the body of the PASN 1st frame.
2271
 * @data_len: The length of data
2272
 * @frame: The body of the PASN frame including the MIC element with the octets
2273
 *  in the MIC field of the MIC element set to 0.
2274
 * @frame_len: The length of frame
2275
 * @mic: Buffer to hold the MIC on success. Should be big enough to handle the
2276
 *  maximal MIC length
2277
 * Returns: 0 on success, -1 on failure
2278
 */
2279
int pasn_mic(enum rsn_hash_alg alg, const u8 *kck, size_t kck_len,
2280
       const u8 *addr1, const u8 *addr2,
2281
       const u8 *data, size_t data_len,
2282
       const u8 *frame, size_t frame_len, u8 *mic)
2283
{
2284
  u8 *buf;
2285
  u8 hash[SHA512_MAC_LEN];
2286
  size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
2287
  int ret = -1;
2288
  size_t mic_len;
2289
2290
  if (!kck) {
2291
    wpa_printf(MSG_ERROR, "PASN: No KCK for MIC calculation");
2292
    return -1;
2293
  }
2294
2295
  if (kck_len != WPA_PASN_KCK_LEN) {
2296
    wpa_printf(MSG_ERROR,
2297
         "PASN: Unexpected KCK length %zu for MIC calculation",
2298
         kck_len);
2299
    return -1;
2300
  }
2301
2302
  if (!data || !data_len) {
2303
    wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
2304
    return -1;
2305
  }
2306
2307
  if (!frame || !frame_len) {
2308
    wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
2309
    return -1;
2310
  }
2311
2312
  buf = os_zalloc(buf_len);
2313
  if (!buf)
2314
    return -1;
2315
2316
  os_memcpy(buf, addr1, ETH_ALEN);
2317
  os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
2318
2319
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: data", data, data_len);
2320
  os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
2321
2322
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: frame", frame, frame_len);
2323
  os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
2324
2325
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: KCK", kck, kck_len);
2326
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: buf", buf, buf_len);
2327
2328
  mic_len = pasn_mic_len(alg);
2329
2330
  switch (alg) {
2331
#ifdef CONFIG_SHA512
2332
  case RSN_HASH_SHA512:
2333
    wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA512");
2334
    if (hmac_sha512(kck, kck_len, buf, buf_len, hash))
2335
      goto err;
2336
    break;
2337
#endif /* CONFIG_SHA512 */
2338
#ifdef CONFIG_SHA384
2339
  case RSN_HASH_SHA384:
2340
    wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA384");
2341
    if (hmac_sha384(kck, kck_len, buf, buf_len, hash))
2342
      goto err;
2343
    break;
2344
#endif /* CONFIG_SHA384 */
2345
  case RSN_HASH_SHA256:
2346
    wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA256");
2347
    if (hmac_sha256(kck, kck_len, buf, buf_len, hash))
2348
      goto err;
2349
    break;
2350
  default:
2351
    wpa_printf(MSG_ERROR,
2352
         "PASN: Unsupported alg=%d for MIC calculation", alg);
2353
    goto err;
2354
  }
2355
2356
  os_memcpy(mic, hash, mic_len);
2357
  wpa_hexdump_key(MSG_DEBUG, "PASN: MIC", mic, mic_len);
2358
2359
  ret = 0;
2360
err:
2361
  bin_clear_free(buf, buf_len);
2362
  return ret;
2363
}
2364
2365
2366
/**
2367
 * pasn_auth_frame_hash - Computes a hash of an Authentication frame body
2368
 * @alg: Selected hash algorithm from pasn_pmk_to_ptk()
2369
 * @data: Pointer to the Authentication frame body
2370
 * @len: Length of the Authentication frame body
2371
 * @hash: On return would hold the computed hash. Should be big enough to handle
2372
 *  SHA512.
2373
 * Returns: 0 on success, -1 on failure
2374
 */
2375
int pasn_auth_frame_hash(enum rsn_hash_alg alg, const u8 *data, size_t len,
2376
       u8 *hash)
2377
{
2378
  switch (alg) {
2379
#ifdef CONFIG_SHA512
2380
  case RSN_HASH_SHA512:
2381
    wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-512");
2382
    return sha512_vector(1, &data, &len, hash);
2383
#endif /* CONFIG_SHA512 */
2384
#ifdef CONFIG_SHA384
2385
  case RSN_HASH_SHA384:
2386
    wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-384");
2387
    return sha384_vector(1, &data, &len, hash);
2388
#endif /* CONFIG_SHA384 */
2389
  case RSN_HASH_SHA256:
2390
    wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-256");
2391
    return sha256_vector(1, &data, &len, hash);
2392
  default:
2393
    wpa_printf(MSG_ERROR, "PASN: Unsupported alg=%d", alg);
2394
    return -1;
2395
  }
2396
}
2397
2398
#endif /* CONFIG_PASN */
2399
2400
2401
static int rsn_selector_to_bitfield(const u8 *s)
2402
0
{
2403
0
  return rsn_cipher_suite_to_wpa_cipher(RSN_SELECTOR_GET(s));
2404
0
}
2405
2406
2407
static int rsn_key_mgmt_to_bitfield(const u8 *s)
2408
0
{
2409
0
  return rsn_key_mgmt_to_wpa_akm(RSN_SELECTOR_GET(s));
2410
0
}
2411
2412
2413
int wpa_cipher_valid_group(int cipher)
2414
0
{
2415
0
  return wpa_cipher_valid_pairwise(cipher) ||
2416
0
    cipher == WPA_CIPHER_GTK_NOT_USED;
2417
0
}
2418
2419
2420
int wpa_cipher_valid_mgmt_group(int cipher)
2421
1.98k
{
2422
1.98k
  return cipher == WPA_CIPHER_GTK_NOT_USED ||
2423
1.98k
    cipher == WPA_CIPHER_AES_128_CMAC ||
2424
1.98k
    cipher == WPA_CIPHER_BIP_GMAC_128 ||
2425
1.98k
    cipher == WPA_CIPHER_BIP_GMAC_256 ||
2426
1.98k
    cipher == WPA_CIPHER_BIP_CMAC_256;
2427
1.98k
}
2428
2429
2430
/**
2431
 * wpa_parse_wpa_ie_rsn - Parse RSN IE
2432
 * @rsn_ie: Buffer containing RSN IE
2433
 * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
2434
 * @data: Pointer to structure that will be filled in with parsed data
2435
 * Returns: 0 on success, <0 on failure
2436
 */
2437
int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
2438
       struct wpa_ie_data *data)
2439
0
{
2440
0
  const u8 *pos;
2441
0
  int left;
2442
0
  int i, count;
2443
2444
0
  os_memset(data, 0, sizeof(*data));
2445
0
  data->proto = WPA_PROTO_RSN;
2446
0
  data->pairwise_cipher = WPA_CIPHER_CCMP;
2447
0
  data->group_cipher = WPA_CIPHER_CCMP;
2448
0
  data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
2449
0
  data->capabilities = 0;
2450
0
  data->pmkid = NULL;
2451
0
  data->num_pmkid = 0;
2452
0
  data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
2453
2454
0
  if (rsn_ie_len == 0) {
2455
    /* No RSN IE - fail silently */
2456
0
    return -1;
2457
0
  }
2458
2459
0
  if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
2460
0
    wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
2461
0
         __func__, (unsigned long) rsn_ie_len);
2462
0
    return -1;
2463
0
  }
2464
2465
0
  if (rsn_ie_len >= 2 + 4 + 2 && rsn_ie[1] >= 4 + 2 &&
2466
0
       rsn_ie[1] == rsn_ie_len - 2 &&
2467
0
       (WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE ||
2468
0
        WPA_GET_BE32(&rsn_ie[2]) ==
2469
0
        RSNE_OVERRIDE_2_IE_VENDOR_TYPE) &&
2470
0
       WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) {
2471
0
    pos = rsn_ie + 2 + 4 + 2;
2472
0
    left = rsn_ie_len - 2 - 4 - 2;
2473
0
  } else {
2474
0
    const struct rsn_ie_hdr *hdr;
2475
2476
0
    hdr = (const struct rsn_ie_hdr *) rsn_ie;
2477
2478
0
    if (hdr->elem_id != WLAN_EID_RSN ||
2479
0
        hdr->len != rsn_ie_len - 2 ||
2480
0
        WPA_GET_LE16(hdr->version) != RSN_VERSION) {
2481
0
      wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
2482
0
           __func__);
2483
0
      return -2;
2484
0
    }
2485
2486
0
    pos = (const u8 *) (hdr + 1);
2487
0
    left = rsn_ie_len - sizeof(*hdr);
2488
0
  }
2489
2490
0
  if (left >= RSN_SELECTOR_LEN) {
2491
0
    data->group_cipher = rsn_selector_to_bitfield(pos);
2492
0
    data->has_group = 1;
2493
0
    if (!wpa_cipher_valid_group(data->group_cipher)) {
2494
0
      wpa_printf(MSG_DEBUG,
2495
0
           "%s: invalid group cipher 0x%x (%08x)",
2496
0
           __func__, data->group_cipher,
2497
0
           WPA_GET_BE32(pos));
2498
#ifdef CONFIG_NO_TKIP
2499
      if (RSN_SELECTOR_GET(pos) == RSN_CIPHER_SUITE_TKIP) {
2500
        wpa_printf(MSG_DEBUG,
2501
             "%s: TKIP as group cipher not supported in CONFIG_NO_TKIP=y build",
2502
             __func__);
2503
      }
2504
#endif /* CONFIG_NO_TKIP */
2505
0
      return -1;
2506
0
    }
2507
0
    pos += RSN_SELECTOR_LEN;
2508
0
    left -= RSN_SELECTOR_LEN;
2509
0
  } else if (left > 0) {
2510
0
    wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
2511
0
         __func__, left);
2512
0
    return -3;
2513
0
  }
2514
2515
0
  if (left >= 2) {
2516
0
    data->pairwise_cipher = 0;
2517
0
    count = WPA_GET_LE16(pos);
2518
0
    pos += 2;
2519
0
    left -= 2;
2520
0
    if (count == 0 || count > left / RSN_SELECTOR_LEN) {
2521
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
2522
0
           "count %u left %u", __func__, count, left);
2523
0
      return -4;
2524
0
    }
2525
0
    if (count)
2526
0
      data->has_pairwise = 1;
2527
0
    for (i = 0; i < count; i++) {
2528
0
      data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
2529
0
      pos += RSN_SELECTOR_LEN;
2530
0
      left -= RSN_SELECTOR_LEN;
2531
0
    }
2532
0
    if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
2533
0
      wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
2534
0
           "pairwise cipher", __func__);
2535
0
      return -1;
2536
0
    }
2537
0
  } else if (left == 1) {
2538
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
2539
0
         __func__);
2540
0
    return -5;
2541
0
  }
2542
2543
0
  if (left >= 2) {
2544
0
    data->key_mgmt = 0;
2545
0
    count = WPA_GET_LE16(pos);
2546
0
    pos += 2;
2547
0
    left -= 2;
2548
0
    if (count > left / RSN_SELECTOR_LEN) {
2549
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
2550
0
           "count %u left %u", __func__, count, left);
2551
0
      return -6;
2552
0
    }
2553
0
    for (i = 0; i < count; i++) {
2554
0
      data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
2555
0
      pos += RSN_SELECTOR_LEN;
2556
0
      left -= RSN_SELECTOR_LEN;
2557
0
    }
2558
0
  } else if (left == 1) {
2559
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
2560
0
         __func__);
2561
0
    return -7;
2562
0
  }
2563
2564
0
  if (left >= 2) {
2565
0
    data->capabilities = WPA_GET_LE16(pos);
2566
0
    pos += 2;
2567
0
    left -= 2;
2568
0
  }
2569
2570
0
  if (left >= 2) {
2571
0
    u16 num_pmkid = WPA_GET_LE16(pos);
2572
0
    pos += 2;
2573
0
    left -= 2;
2574
0
    if (num_pmkid > (unsigned int) left / PMKID_LEN) {
2575
0
      wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
2576
0
           "(num_pmkid=%u left=%d)",
2577
0
           __func__, num_pmkid, left);
2578
0
      data->num_pmkid = 0;
2579
0
      return -9;
2580
0
    } else {
2581
0
      data->num_pmkid = num_pmkid;
2582
0
      data->pmkid = pos;
2583
0
      pos += data->num_pmkid * PMKID_LEN;
2584
0
      left -= data->num_pmkid * PMKID_LEN;
2585
0
    }
2586
0
  }
2587
2588
0
  if (left >= 4) {
2589
0
    data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
2590
0
    if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
2591
0
      wpa_printf(MSG_DEBUG,
2592
0
           "%s: Unsupported management group cipher 0x%x (%08x)",
2593
0
           __func__, data->mgmt_group_cipher,
2594
0
           WPA_GET_BE32(pos));
2595
0
      return -10;
2596
0
    }
2597
0
    pos += RSN_SELECTOR_LEN;
2598
0
    left -= RSN_SELECTOR_LEN;
2599
0
  }
2600
2601
0
  if (left > 0) {
2602
0
    wpa_hexdump(MSG_DEBUG,
2603
0
          "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
2604
0
          pos, left);
2605
0
  }
2606
2607
0
  return 0;
2608
0
}
2609
2610
2611
static int wpa_selector_to_bitfield(const u8 *s)
2612
0
{
2613
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
2614
0
    return WPA_CIPHER_NONE;
2615
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
2616
0
    return WPA_CIPHER_TKIP;
2617
0
  if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
2618
0
    return WPA_CIPHER_CCMP;
2619
0
  return 0;
2620
0
}
2621
2622
2623
static int wpa_key_mgmt_to_bitfield(const u8 *s)
2624
0
{
2625
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
2626
0
    return WPA_KEY_MGMT_IEEE8021X;
2627
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
2628
0
    return WPA_KEY_MGMT_PSK;
2629
0
  if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
2630
0
    return WPA_KEY_MGMT_WPA_NONE;
2631
0
  return 0;
2632
0
}
2633
2634
2635
int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
2636
       struct wpa_ie_data *data)
2637
0
{
2638
0
  const struct wpa_ie_hdr *hdr;
2639
0
  const u8 *pos;
2640
0
  int left;
2641
0
  int i, count;
2642
2643
0
  os_memset(data, 0, sizeof(*data));
2644
0
  data->proto = WPA_PROTO_WPA;
2645
0
  data->pairwise_cipher = WPA_CIPHER_TKIP;
2646
0
  data->group_cipher = WPA_CIPHER_TKIP;
2647
0
  data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
2648
0
  data->capabilities = 0;
2649
0
  data->pmkid = NULL;
2650
0
  data->num_pmkid = 0;
2651
0
  data->mgmt_group_cipher = 0;
2652
2653
0
  if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
2654
0
    wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
2655
0
         __func__, (unsigned long) wpa_ie_len);
2656
0
    return -1;
2657
0
  }
2658
2659
0
  hdr = (const struct wpa_ie_hdr *) wpa_ie;
2660
2661
0
  if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
2662
0
      hdr->len != wpa_ie_len - 2 ||
2663
0
      RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
2664
0
      WPA_GET_LE16(hdr->version) != WPA_VERSION) {
2665
0
    wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
2666
0
         __func__);
2667
0
    return -2;
2668
0
  }
2669
2670
0
  pos = (const u8 *) (hdr + 1);
2671
0
  left = wpa_ie_len - sizeof(*hdr);
2672
2673
0
  if (left >= WPA_SELECTOR_LEN) {
2674
0
    data->group_cipher = wpa_selector_to_bitfield(pos);
2675
0
    pos += WPA_SELECTOR_LEN;
2676
0
    left -= WPA_SELECTOR_LEN;
2677
0
  } else if (left > 0) {
2678
0
    wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
2679
0
         __func__, left);
2680
0
    return -3;
2681
0
  }
2682
2683
0
  if (left >= 2) {
2684
0
    data->pairwise_cipher = 0;
2685
0
    count = WPA_GET_LE16(pos);
2686
0
    pos += 2;
2687
0
    left -= 2;
2688
0
    if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2689
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
2690
0
           "count %u left %u", __func__, count, left);
2691
0
      return -4;
2692
0
    }
2693
0
    for (i = 0; i < count; i++) {
2694
0
      data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
2695
0
      pos += WPA_SELECTOR_LEN;
2696
0
      left -= WPA_SELECTOR_LEN;
2697
0
    }
2698
0
  } else if (left == 1) {
2699
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
2700
0
         __func__);
2701
0
    return -5;
2702
0
  }
2703
2704
0
  if (left >= 2) {
2705
0
    data->key_mgmt = 0;
2706
0
    count = WPA_GET_LE16(pos);
2707
0
    pos += 2;
2708
0
    left -= 2;
2709
0
    if (count == 0 || count > left / WPA_SELECTOR_LEN) {
2710
0
      wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
2711
0
           "count %u left %u", __func__, count, left);
2712
0
      return -6;
2713
0
    }
2714
0
    for (i = 0; i < count; i++) {
2715
0
      data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
2716
0
      pos += WPA_SELECTOR_LEN;
2717
0
      left -= WPA_SELECTOR_LEN;
2718
0
    }
2719
0
  } else if (left == 1) {
2720
0
    wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
2721
0
         __func__);
2722
0
    return -7;
2723
0
  }
2724
2725
0
  if (left >= 2) {
2726
0
    data->capabilities = WPA_GET_LE16(pos);
2727
0
    pos += 2;
2728
0
    left -= 2;
2729
0
  }
2730
2731
0
  if (left > 0) {
2732
0
    wpa_hexdump(MSG_DEBUG,
2733
0
          "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
2734
0
          pos, left);
2735
0
  }
2736
2737
0
  return 0;
2738
0
}
2739
2740
2741
int wpa_default_rsn_cipher(int freq)
2742
0
{
2743
0
  if (freq > 56160)
2744
0
    return WPA_CIPHER_GCMP; /* DMG */
2745
2746
0
  return WPA_CIPHER_CCMP;
2747
0
}
2748
2749
2750
#ifdef CONFIG_IEEE80211R
2751
2752
/**
2753
 * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
2754
 *
2755
 * IEEE Std 802.11r-2008 - 8.5.1.5.3
2756
 */
2757
int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
2758
          const u8 *ssid, size_t ssid_len,
2759
          const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
2760
          const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name,
2761
          int key_mgmt)
2762
0
{
2763
0
  u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
2764
0
         FT_R0KH_ID_MAX_LEN + ETH_ALEN];
2765
0
  u8 *pos, r0_key_data[64 + 16], hash[64];
2766
0
  const u8 *addr[2];
2767
0
  size_t len[2];
2768
0
  size_t q, r0_key_data_len;
2769
0
  int res;
2770
2771
0
  if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
2772
0
      (xxkey_len == SHA256_MAC_LEN || xxkey_len == SHA384_MAC_LEN ||
2773
0
       xxkey_len == SHA512_MAC_LEN))
2774
0
    q = xxkey_len;
2775
0
  else if (wpa_key_mgmt_sha384(key_mgmt))
2776
0
    q = SHA384_MAC_LEN;
2777
0
  else
2778
0
    q = SHA256_MAC_LEN;
2779
0
  r0_key_data_len = q + 16;
2780
2781
  /*
2782
   * R0-Key-Data = KDF-Hash-Length(XXKey, "FT-R0",
2783
   *                       SSIDlength || SSID || MDID || R0KHlength ||
2784
   *                       R0KH-ID || S0KH-ID)
2785
   * XXKey is either the second 256 bits of MSK or PSK; or the first
2786
   * 384 bits of MSK for FT-EAP-SHA384; or PMK from SAE.
2787
   * PMK-R0 = L(R0-Key-Data, 0, Q)
2788
   * PMK-R0Name-Salt = L(R0-Key-Data, Q, 128)
2789
   * Q = 384 for FT-EAP-SHA384; the length of the digest generated by H()
2790
   * for FT-SAE-EXT-KEY; or otherwise, 256
2791
   */
2792
0
  if (ssid_len > SSID_MAX_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
2793
0
    return -1;
2794
0
  wpa_printf(MSG_DEBUG, "FT: Derive PMK-R0 using KDF-SHA%zu", q * 8);
2795
0
  wpa_hexdump_key(MSG_DEBUG, "FT: XXKey", xxkey, xxkey_len);
2796
0
  wpa_hexdump_ascii(MSG_DEBUG, "FT: SSID", ssid, ssid_len);
2797
0
  wpa_hexdump(MSG_DEBUG, "FT: MDID", mdid, MOBILITY_DOMAIN_ID_LEN);
2798
0
  wpa_hexdump_ascii(MSG_DEBUG, "FT: R0KH-ID", r0kh_id, r0kh_id_len);
2799
0
  wpa_printf(MSG_DEBUG, "FT: S0KH-ID: " MACSTR, MAC2STR(s0kh_id));
2800
0
  pos = buf;
2801
0
  *pos++ = ssid_len;
2802
0
  os_memcpy(pos, ssid, ssid_len);
2803
0
  pos += ssid_len;
2804
0
  os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
2805
0
  pos += MOBILITY_DOMAIN_ID_LEN;
2806
0
  *pos++ = r0kh_id_len;
2807
0
  os_memcpy(pos, r0kh_id, r0kh_id_len);
2808
0
  pos += r0kh_id_len;
2809
0
  os_memcpy(pos, s0kh_id, ETH_ALEN);
2810
0
  pos += ETH_ALEN;
2811
2812
0
  res = -1;
2813
#ifdef CONFIG_SHA512
2814
  if (q == SHA512_MAC_LEN) {
2815
    if (xxkey_len != SHA512_MAC_LEN) {
2816
      wpa_printf(MSG_ERROR,
2817
           "FT: Unexpected XXKey length %d (expected %d)",
2818
           (int) xxkey_len, SHA512_MAC_LEN);
2819
      return -1;
2820
    }
2821
    res = sha512_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2822
         r0_key_data, r0_key_data_len);
2823
  }
2824
#endif /* CONFIG_SHA512 */
2825
#ifdef CONFIG_SHA384
2826
  if (q == SHA384_MAC_LEN) {
2827
    if (xxkey_len != SHA384_MAC_LEN) {
2828
      wpa_printf(MSG_ERROR,
2829
           "FT: Unexpected XXKey length %d (expected %d)",
2830
           (int) xxkey_len, SHA384_MAC_LEN);
2831
      return -1;
2832
    }
2833
    res = sha384_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2834
         r0_key_data, r0_key_data_len);
2835
  }
2836
#endif /* CONFIG_SHA384 */
2837
0
  if (q == SHA256_MAC_LEN) {
2838
0
    if (xxkey_len != PMK_LEN) {
2839
0
      wpa_printf(MSG_ERROR,
2840
0
           "FT: Unexpected XXKey length %d (expected %d)",
2841
0
           (int) xxkey_len, PMK_LEN);
2842
0
      return -1;
2843
0
    }
2844
0
    res = sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
2845
0
         r0_key_data, r0_key_data_len);
2846
0
  }
2847
0
  if (res < 0)
2848
0
    return res;
2849
0
  os_memcpy(pmk_r0, r0_key_data, q);
2850
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, q);
2851
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0Name-Salt", &r0_key_data[q], 16);
2852
2853
  /*
2854
   * PMKR0Name = Truncate-128(Hash("FT-R0N" || PMK-R0Name-Salt)
2855
   */
2856
0
  addr[0] = (const u8 *) "FT-R0N";
2857
0
  len[0] = 6;
2858
0
  addr[1] = &r0_key_data[q];
2859
0
  len[1] = 16;
2860
2861
0
  res = -1;
2862
#ifdef CONFIG_SHA512
2863
  if (q == SHA512_MAC_LEN)
2864
    res = sha512_vector(2, addr, len, hash);
2865
#endif /* CONFIG_SHA512 */
2866
#ifdef CONFIG_SHA384
2867
  if (q == SHA384_MAC_LEN)
2868
    res = sha384_vector(2, addr, len, hash);
2869
#endif /* CONFIG_SHA384 */
2870
0
  if (q == SHA256_MAC_LEN)
2871
0
    res = sha256_vector(2, addr, len, hash);
2872
0
  if (res < 0) {
2873
0
    wpa_printf(MSG_DEBUG,
2874
0
         "FT: Failed to derive PMKR0Name (PMK-R0 len %zu)",
2875
0
         q);
2876
0
    return res;
2877
0
  }
2878
0
  os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
2879
0
  wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
2880
0
  forced_memzero(r0_key_data, sizeof(r0_key_data));
2881
0
  return 0;
2882
0
}
2883
2884
2885
/**
2886
 * wpa_derive_pmk_r1_name - Derive PMKR1Name
2887
 *
2888
 * IEEE Std 802.11r-2008 - 8.5.1.5.4
2889
 */
2890
int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
2891
         const u8 *s1kh_id, u8 *pmk_r1_name,
2892
         size_t pmk_r1_len)
2893
0
{
2894
0
  u8 hash[64];
2895
0
  const u8 *addr[4];
2896
0
  size_t len[4];
2897
0
  int res;
2898
0
  const char *title;
2899
2900
  /*
2901
   * PMKR1Name = Truncate-128(Hash("FT-R1N" || PMKR0Name ||
2902
   *                               R1KH-ID || S1KH-ID))
2903
   */
2904
0
  addr[0] = (const u8 *) "FT-R1N";
2905
0
  len[0] = 6;
2906
0
  addr[1] = pmk_r0_name;
2907
0
  len[1] = WPA_PMK_NAME_LEN;
2908
0
  addr[2] = r1kh_id;
2909
0
  len[2] = FT_R1KH_ID_LEN;
2910
0
  addr[3] = s1kh_id;
2911
0
  len[3] = ETH_ALEN;
2912
2913
0
  res = -1;
2914
#ifdef CONFIG_SHA512
2915
  if (pmk_r1_len == SHA512_MAC_LEN) {
2916
    title = "FT: PMKR1Name (using SHA512)";
2917
    res = sha512_vector(4, addr, len, hash);
2918
  }
2919
#endif /* CONFIG_SHA512 */
2920
#ifdef CONFIG_SHA384
2921
  if (pmk_r1_len == SHA384_MAC_LEN) {
2922
    title = "FT: PMKR1Name (using SHA384)";
2923
    res = sha384_vector(4, addr, len, hash);
2924
  }
2925
#endif /* CONFIG_SHA384 */
2926
0
  if (pmk_r1_len == SHA256_MAC_LEN) {
2927
0
    title = "FT: PMKR1Name (using SHA256)";
2928
0
    res = sha256_vector(4, addr, len, hash);
2929
0
  }
2930
0
  if (res < 0) {
2931
0
    wpa_printf(MSG_DEBUG,
2932
0
         "FT: Failed to derive PMKR1Name (PMK-R1 len %zu)",
2933
0
         pmk_r1_len);
2934
0
    return res;
2935
0
  }
2936
0
  os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
2937
0
  wpa_hexdump(MSG_DEBUG, title, pmk_r1_name, WPA_PMK_NAME_LEN);
2938
0
  return 0;
2939
0
}
2940
2941
2942
/**
2943
 * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
2944
 *
2945
 * IEEE Std 802.11r-2008 - 8.5.1.5.4
2946
 */
2947
int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
2948
          const u8 *pmk_r0_name,
2949
          const u8 *r1kh_id, const u8 *s1kh_id,
2950
          u8 *pmk_r1, u8 *pmk_r1_name)
2951
0
{
2952
0
  u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
2953
0
  u8 *pos;
2954
0
  int res;
2955
2956
  /* PMK-R1 = KDF-Hash(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
2957
0
  wpa_printf(MSG_DEBUG, "FT: Derive PMK-R1 using KDF-SHA%zu",
2958
0
       pmk_r0_len * 8);
2959
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len);
2960
0
  wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", r1kh_id, FT_R1KH_ID_LEN);
2961
0
  wpa_printf(MSG_DEBUG, "FT: S1KH-ID: " MACSTR, MAC2STR(s1kh_id));
2962
0
  pos = buf;
2963
0
  os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
2964
0
  pos += FT_R1KH_ID_LEN;
2965
0
  os_memcpy(pos, s1kh_id, ETH_ALEN);
2966
0
  pos += ETH_ALEN;
2967
2968
0
  res = -1;
2969
#ifdef CONFIG_SHA512
2970
  if (pmk_r0_len == SHA512_MAC_LEN)
2971
    res = sha512_prf(pmk_r0, pmk_r0_len, "FT-R1",
2972
         buf, pos - buf, pmk_r1, pmk_r0_len);
2973
#endif /* CONFIG_SHA512 */
2974
#ifdef CONFIG_SHA384
2975
  if (pmk_r0_len == SHA384_MAC_LEN)
2976
    res = sha384_prf(pmk_r0, pmk_r0_len, "FT-R1",
2977
         buf, pos - buf, pmk_r1, pmk_r0_len);
2978
#endif /* CONFIG_SHA384 */
2979
0
  if (pmk_r0_len == SHA256_MAC_LEN)
2980
0
    res = sha256_prf(pmk_r0, pmk_r0_len, "FT-R1",
2981
0
         buf, pos - buf, pmk_r1, pmk_r0_len);
2982
0
  if (res < 0) {
2983
0
    wpa_printf(MSG_ERROR, "FT: Failed to derive PMK-R1");
2984
0
    return res;
2985
0
  }
2986
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len);
2987
2988
0
  return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
2989
0
              pmk_r1_name, pmk_r0_len);
2990
0
}
2991
2992
2993
/**
2994
 * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
2995
 *
2996
 * IEEE Std 802.11r-2008 - 8.5.1.5.5
2997
 */
2998
int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
2999
          const u8 *snonce, const u8 *anonce,
3000
          const u8 *sta_addr, const u8 *bssid,
3001
          const u8 *pmk_r1_name,
3002
          struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
3003
          size_t kdk_len)
3004
0
{
3005
0
  u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
3006
0
  u8 *pos, hash[32];
3007
0
  const u8 *addr[6];
3008
0
  size_t len[6];
3009
0
  u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
3010
0
         WPA_KDK_MAX_LEN];
3011
0
  size_t ptk_len, offset;
3012
0
  size_t key_len;
3013
0
  int res;
3014
3015
0
  if (kdk_len > WPA_KDK_MAX_LEN) {
3016
0
    wpa_printf(MSG_ERROR,
3017
0
         "FT: KDK len=%zu exceeds max supported len",
3018
0
         kdk_len);
3019
0
    return -1;
3020
0
  }
3021
3022
0
  if (akmp == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
3023
0
      (pmk_r1_len == SHA256_MAC_LEN || pmk_r1_len == SHA384_MAC_LEN ||
3024
0
       pmk_r1_len == SHA512_MAC_LEN))
3025
0
    key_len = pmk_r1_len;
3026
0
  else if (wpa_key_mgmt_sha384(akmp))
3027
0
    key_len = SHA384_MAC_LEN;
3028
0
  else
3029
0
    key_len = SHA256_MAC_LEN;
3030
3031
  /*
3032
   * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
3033
   *                  BSSID || STA-ADDR)
3034
   */
3035
0
  wpa_printf(MSG_DEBUG, "FT: Derive PTK using KDF-SHA%zu", key_len * 8);
3036
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len);
3037
0
  wpa_hexdump(MSG_DEBUG, "FT: SNonce", snonce, WPA_NONCE_LEN);
3038
0
  wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
3039
0
  wpa_printf(MSG_DEBUG, "FT: BSSID=" MACSTR " STA-ADDR=" MACSTR,
3040
0
       MAC2STR(bssid), MAC2STR(sta_addr));
3041
0
  pos = buf;
3042
0
  os_memcpy(pos, snonce, WPA_NONCE_LEN);
3043
0
  pos += WPA_NONCE_LEN;
3044
0
  os_memcpy(pos, anonce, WPA_NONCE_LEN);
3045
0
  pos += WPA_NONCE_LEN;
3046
0
  os_memcpy(pos, bssid, ETH_ALEN);
3047
0
  pos += ETH_ALEN;
3048
0
  os_memcpy(pos, sta_addr, ETH_ALEN);
3049
0
  pos += ETH_ALEN;
3050
3051
0
  ptk->kck_len = wpa_kck_len(akmp, key_len);
3052
0
  ptk->kck2_len = wpa_kck2_len(akmp);
3053
0
  ptk->kek_len = wpa_kek_len(akmp, key_len, PASN_GROUP_NOT_SPECIFIED);
3054
0
  ptk->kek2_len = wpa_kek2_len(akmp);
3055
0
  ptk->tk_len = wpa_cipher_key_len(cipher);
3056
0
  ptk->kdk_len = kdk_len;
3057
0
  ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
3058
0
    ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
3059
3060
0
  res = -1;
3061
#ifdef CONFIG_SHA512
3062
  if (key_len == SHA512_MAC_LEN) {
3063
    if (pmk_r1_len != SHA512_MAC_LEN) {
3064
      wpa_printf(MSG_ERROR,
3065
           "FT: Unexpected PMK-R1 length %d (expected %d)",
3066
           (int) pmk_r1_len, SHA512_MAC_LEN);
3067
      return -1;
3068
    }
3069
    res = sha512_prf(pmk_r1, pmk_r1_len, "FT-PTK",
3070
         buf, pos - buf, tmp, ptk_len);
3071
  }
3072
#endif /* CONFIG_SHA512 */
3073
#ifdef CONFIG_SHA384
3074
  if (key_len == SHA384_MAC_LEN) {
3075
    if (pmk_r1_len != SHA384_MAC_LEN) {
3076
      wpa_printf(MSG_ERROR,
3077
           "FT: Unexpected PMK-R1 length %d (expected %d)",
3078
           (int) pmk_r1_len, SHA384_MAC_LEN);
3079
      return -1;
3080
    }
3081
    res = sha384_prf(pmk_r1, pmk_r1_len, "FT-PTK",
3082
         buf, pos - buf, tmp, ptk_len);
3083
  }
3084
#endif /* CONFIG_SHA384 */
3085
0
  if (key_len == SHA256_MAC_LEN) {
3086
0
    if (pmk_r1_len != PMK_LEN) {
3087
0
      wpa_printf(MSG_ERROR,
3088
0
           "FT: Unexpected PMK-R1 length %d (expected %d)",
3089
0
           (int) pmk_r1_len, PMK_LEN);
3090
0
      return -1;
3091
0
    }
3092
0
    res = sha256_prf(pmk_r1, pmk_r1_len, "FT-PTK",
3093
0
         buf, pos - buf, tmp, ptk_len);
3094
0
  }
3095
0
  if (res < 0)
3096
0
    return -1;
3097
0
  wpa_hexdump_key(MSG_DEBUG, "FT: PTK", tmp, ptk_len);
3098
3099
  /*
3100
   * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
3101
   *                                ANonce || BSSID || STA-ADDR))
3102
   */
3103
0
  wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
3104
0
  addr[0] = pmk_r1_name;
3105
0
  len[0] = WPA_PMK_NAME_LEN;
3106
0
  addr[1] = (const u8 *) "FT-PTKN";
3107
0
  len[1] = 7;
3108
0
  addr[2] = snonce;
3109
0
  len[2] = WPA_NONCE_LEN;
3110
0
  addr[3] = anonce;
3111
0
  len[3] = WPA_NONCE_LEN;
3112
0
  addr[4] = bssid;
3113
0
  len[4] = ETH_ALEN;
3114
0
  addr[5] = sta_addr;
3115
0
  len[5] = ETH_ALEN;
3116
3117
0
  if (sha256_vector(6, addr, len, hash) < 0)
3118
0
    return -1;
3119
0
  os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
3120
3121
0
  os_memcpy(ptk->kck, tmp, ptk->kck_len);
3122
0
  offset = ptk->kck_len;
3123
0
  os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
3124
0
  offset += ptk->kek_len;
3125
0
  os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
3126
0
  offset += ptk->tk_len;
3127
0
  os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
3128
0
  offset += ptk->kck2_len;
3129
0
  os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
3130
0
  offset += ptk->kek2_len;
3131
0
  os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
3132
3133
0
  wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
3134
0
  wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
3135
0
  if (ptk->kck2_len)
3136
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KCK2",
3137
0
        ptk->kck2, ptk->kck2_len);
3138
0
  if (ptk->kek2_len)
3139
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
3140
0
        ptk->kek2, ptk->kek2_len);
3141
0
  if (ptk->kdk_len)
3142
0
    wpa_hexdump_key(MSG_DEBUG, "FT: KDK", ptk->kdk, ptk->kdk_len);
3143
3144
0
  wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
3145
0
  wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
3146
3147
0
  forced_memzero(tmp, sizeof(tmp));
3148
3149
0
  return 0;
3150
0
}
3151
3152
#endif /* CONFIG_IEEE80211R */
3153
3154
3155
/**
3156
 * rsn_pmkid - Calculate PMK identifier
3157
 * @pmk: Pairwise master key
3158
 * @pmk_len: Length of pmk in bytes
3159
 * @aa: Authenticator address
3160
 * @spa: Supplicant address
3161
 * @pmkid: Buffer for PMKID
3162
 * @akmp: Negotiated key management protocol
3163
 * @alg: Hash algorithm
3164
 *
3165
 * IEEE Std 802.11-2016 - 12.7.1.3 Pairwise key hierarchy
3166
 * AKM: 00-0F-AC:3, 00-0F-AC:5, 00-0F-AC:6, 00-0F-AC:14, 00-0F-AC:16
3167
 * PMKID = Truncate-128(HMAC-SHA-256(PMK, "PMK Name" || AA || SPA))
3168
 * AKM: 00-0F-AC:11
3169
 * See rsn_pmkid_suite_b()
3170
 * AKM: 00-0F-AC:12
3171
 * See rsn_pmkid_suite_b_192()
3172
 * AKM: 00-0F-AC:13, 00-0F-AC:15, 00-0F-AC:17
3173
 * PMKID = Truncate-128(HMAC-SHA-384(PMK, "PMK Name" || AA || SPA))
3174
 * Otherwise:
3175
 * PMKID = Truncate-128(HMAC-SHA-1(PMK, "PMK Name" || AA || SPA))
3176
 */
3177
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
3178
         u8 *pmkid, int akmp, enum rsn_hash_alg alg)
3179
0
{
3180
0
  char *title = "PMK Name";
3181
0
  const u8 *addr[3];
3182
0
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
3183
0
  unsigned char hash[SHA512_MAC_LEN];
3184
3185
0
  addr[0] = (u8 *) title;
3186
0
  addr[1] = aa;
3187
0
  addr[2] = spa;
3188
3189
0
  if (0) {
3190
#ifdef CONFIG_SHA512
3191
  } else if (alg == RSN_HASH_SHA512) {
3192
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-512");
3193
    hmac_sha512_vector(pmk, pmk_len, 3, addr, len, hash);
3194
#endif /* CONFIG_SHA512 */
3195
#if defined(CONFIG_FILS) || defined(CONFIG_SHA384)
3196
  } else if (alg == RSN_HASH_SHA384 || wpa_key_mgmt_sha384(akmp)) {
3197
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-384");
3198
    hmac_sha384_vector(pmk, pmk_len, 3, addr, len, hash);
3199
#endif /* CONFIG_FILS || CONFIG_SHA384 */
3200
0
  } else if (alg == RSN_HASH_SHA256 || wpa_key_mgmt_sha256(akmp)) {
3201
0
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-256");
3202
0
    hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
3203
0
  } else {
3204
0
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-1");
3205
0
    hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
3206
0
  }
3207
0
  wpa_hexdump(MSG_DEBUG, "RSN: Derived PMKID", hash, PMKID_LEN);
3208
0
  os_memcpy(pmkid, hash, PMKID_LEN);
3209
0
}
3210
3211
3212
#ifdef CONFIG_SUITEB
3213
/**
3214
 * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
3215
 * @kck: Key confirmation key
3216
 * @kck_len: Length of kck in bytes
3217
 * @aa: Authenticator address
3218
 * @spa: Supplicant address
3219
 * @pmkid: Buffer for PMKID
3220
 * Returns: 0 on success, -1 on failure
3221
 *
3222
 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
3223
 * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
3224
 */
3225
int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
3226
          const u8 *spa, u8 *pmkid)
3227
0
{
3228
0
  char *title = "PMK Name";
3229
0
  const u8 *addr[3];
3230
0
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
3231
0
  unsigned char hash[SHA256_MAC_LEN];
3232
3233
0
  addr[0] = (u8 *) title;
3234
0
  addr[1] = aa;
3235
0
  addr[2] = spa;
3236
3237
0
  if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
3238
0
    return -1;
3239
0
  os_memcpy(pmkid, hash, PMKID_LEN);
3240
0
  return 0;
3241
0
}
3242
#endif /* CONFIG_SUITEB */
3243
3244
3245
#ifdef CONFIG_SUITEB192
3246
/**
3247
 * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
3248
 * @kck: Key confirmation key
3249
 * @kck_len: Length of kck in bytes
3250
 * @aa: Authenticator address
3251
 * @spa: Supplicant address
3252
 * @pmkid: Buffer for PMKID
3253
 * Returns: 0 on success, -1 on failure
3254
 *
3255
 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
3256
 * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
3257
 */
3258
int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
3259
        const u8 *spa, u8 *pmkid)
3260
{
3261
  char *title = "PMK Name";
3262
  const u8 *addr[3];
3263
  const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
3264
  unsigned char hash[SHA384_MAC_LEN];
3265
3266
  addr[0] = (u8 *) title;
3267
  addr[1] = aa;
3268
  addr[2] = spa;
3269
3270
  if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
3271
    return -1;
3272
  os_memcpy(pmkid, hash, PMKID_LEN);
3273
  return 0;
3274
}
3275
#endif /* CONFIG_SUITEB192 */
3276
3277
3278
#ifdef CONFIG_PMKSA_PRIVACY
3279
/**
3280
 * rsn_pmkid_privacy - Calculate a new PMKID for PMKSA caching privacy
3281
 * @pmkid_anonce: Authenticator nonce (ANonce)
3282
 * @pmkid_snonce: Supplicant nonce (SNonce)
3283
 * @akmp: Negotiated key management protocol
3284
 * @pmk_len: PMK length in bytes
3285
 * @pmkid: Buffer for returning PMKID
3286
 * Returns: 0 on success, -1 on failure
3287
 *
3288
 * IEEE P802.11bi/D4.0, 12.16.7.2 (PMKID privacy)
3289
 * PMKID = Truncate-128(Hash("PMK Name" || PMKIDANonce || PMKIDSNonce))
3290
 */
3291
int rsn_pmkid_privacy(const u8 *pmkid_anonce, const u8 *pmkid_snonce,
3292
          int akmp, size_t pmk_len, u8 *pmkid)
3293
{
3294
  const char *label = "PMK Name";
3295
  const u8 *addr[3];
3296
  const size_t len[3] = { 8, NONCE_LEN, NONCE_LEN };
3297
  unsigned char hash[SHA512_MAC_LEN];
3298
3299
  wpa_hexdump(MSG_DEBUG, "PMKID privacy: PMKIDANonce",
3300
        pmkid_anonce, NONCE_LEN);
3301
  wpa_hexdump(MSG_DEBUG, "PMKID privacy: PMKIDSNonce",
3302
        pmkid_snonce, NONCE_LEN);
3303
3304
  addr[0] = (const u8 *) label;
3305
  addr[1] = pmkid_anonce;
3306
  addr[2] = pmkid_snonce;
3307
3308
  if (0) {
3309
#if defined(CONFIG_FILS) || defined(CONFIG_SHA384)
3310
  } else if (wpa_key_mgmt_sha384(akmp)) {
3311
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using SHA-384");
3312
    if (sha384_vector(3, addr, len, hash) < 0)
3313
      return -1;
3314
#endif /* CONFIG_FILS || CONFIG_SHA384 */
3315
#ifdef CONFIG_SAE
3316
  } else if (wpa_key_mgmt_sae_ext_key(akmp)) {
3317
    if (pmk_len == 64) {
3318
      if (sha512_vector(3, addr, len, hash) < 0)
3319
        return -1;
3320
    } else if (pmk_len == 48) {
3321
      if (sha384_vector(3, addr, len, hash) < 0)
3322
        return -1;
3323
    } else {
3324
      if (sha256_vector(3, addr, len, hash) < 0)
3325
        return -1;
3326
    }
3327
#endif /* CONFIG_SAE */
3328
  } else {
3329
    wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using SHA-256");
3330
    if (sha256_vector(3, addr, len, hash) < 0)
3331
      return -1;
3332
  }
3333
3334
  wpa_hexdump(MSG_DEBUG, "PMKID privacy: new PMKID", hash, PMKID_LEN);
3335
  os_memcpy(pmkid, hash, PMKID_LEN);
3336
3337
  return 0;
3338
}
3339
#endif /* CONFIG_PMKSA_PRIVACY */
3340
3341
3342
/**
3343
 * wpa_cipher_txt - Convert cipher suite to a text string
3344
 * @cipher: Cipher suite (WPA_CIPHER_* enum)
3345
 * Returns: Pointer to a text string of the cipher suite name
3346
 */
3347
const char * wpa_cipher_txt(int cipher)
3348
0
{
3349
0
  switch (cipher) {
3350
0
  case WPA_CIPHER_NONE:
3351
0
    return "NONE";
3352
#ifdef CONFIG_WEP
3353
  case WPA_CIPHER_WEP40:
3354
    return "WEP-40";
3355
  case WPA_CIPHER_WEP104:
3356
    return "WEP-104";
3357
#endif /* CONFIG_WEP */
3358
0
  case WPA_CIPHER_TKIP:
3359
0
    return "TKIP";
3360
0
  case WPA_CIPHER_CCMP:
3361
0
    return "CCMP";
3362
0
  case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
3363
0
    return "CCMP+TKIP";
3364
0
  case WPA_CIPHER_GCMP:
3365
0
    return "GCMP";
3366
0
  case WPA_CIPHER_GCMP_256:
3367
0
    return "GCMP-256";
3368
0
  case WPA_CIPHER_CCMP_256:
3369
0
    return "CCMP-256";
3370
0
  case WPA_CIPHER_AES_128_CMAC:
3371
0
    return "BIP";
3372
0
  case WPA_CIPHER_BIP_GMAC_128:
3373
0
    return "BIP-GMAC-128";
3374
0
  case WPA_CIPHER_BIP_GMAC_256:
3375
0
    return "BIP-GMAC-256";
3376
0
  case WPA_CIPHER_BIP_CMAC_256:
3377
0
    return "BIP-CMAC-256";
3378
0
  case WPA_CIPHER_GTK_NOT_USED:
3379
0
    return "GTK_NOT_USED";
3380
0
  default:
3381
0
    return "UNKNOWN";
3382
0
  }
3383
0
}
3384
3385
3386
/**
3387
 * wpa_key_mgmt_txt - Convert key management suite to a text string
3388
 * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
3389
 * @proto: WPA/WPA2 version (WPA_PROTO_*)
3390
 * Returns: Pointer to a text string of the key management suite name
3391
 */
3392
const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
3393
0
{
3394
0
  switch (key_mgmt) {
3395
0
  case WPA_KEY_MGMT_IEEE8021X:
3396
0
    if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
3397
0
      return "WPA2+WPA/IEEE 802.1X/EAP";
3398
0
    return proto == WPA_PROTO_RSN ?
3399
0
      "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
3400
0
  case WPA_KEY_MGMT_PSK:
3401
0
    if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
3402
0
      return "WPA2-PSK+WPA-PSK";
3403
0
    return proto == WPA_PROTO_RSN ?
3404
0
      "WPA2-PSK" : "WPA-PSK";
3405
0
  case WPA_KEY_MGMT_NONE:
3406
0
    return "NONE";
3407
0
  case WPA_KEY_MGMT_WPA_NONE:
3408
0
    return "WPA-NONE";
3409
0
  case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
3410
0
    return "IEEE 802.1X (no WPA)";
3411
0
#ifdef CONFIG_IEEE80211R
3412
0
  case WPA_KEY_MGMT_FT_IEEE8021X:
3413
0
    return "FT-EAP";
3414
0
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
3415
0
    return "FT-EAP-SHA384";
3416
0
  case WPA_KEY_MGMT_FT_PSK:
3417
0
    return "FT-PSK";
3418
0
#endif /* CONFIG_IEEE80211R */
3419
0
  case WPA_KEY_MGMT_IEEE8021X_SHA256:
3420
0
    return "WPA2-EAP-SHA256";
3421
0
  case WPA_KEY_MGMT_PSK_SHA256:
3422
0
    return "WPA2-PSK-SHA256";
3423
0
  case WPA_KEY_MGMT_WPS:
3424
0
    return "WPS";
3425
0
  case WPA_KEY_MGMT_SAE:
3426
0
    return "SAE";
3427
0
  case WPA_KEY_MGMT_SAE_EXT_KEY:
3428
0
    return "SAE-EXT-KEY";
3429
0
  case WPA_KEY_MGMT_FT_SAE:
3430
0
    return "FT-SAE";
3431
0
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
3432
0
    return "FT-SAE-EXT-KEY";
3433
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
3434
0
    return "WPA2-EAP-SUITE-B";
3435
0
  case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
3436
0
    return "WPA2-EAP-SUITE-B-192";
3437
0
  case WPA_KEY_MGMT_FILS_SHA256:
3438
0
    return "FILS-SHA256";
3439
0
  case WPA_KEY_MGMT_FILS_SHA384:
3440
0
    return "FILS-SHA384";
3441
0
  case WPA_KEY_MGMT_FT_FILS_SHA256:
3442
0
    return "FT-FILS-SHA256";
3443
0
  case WPA_KEY_MGMT_FT_FILS_SHA384:
3444
0
    return "FT-FILS-SHA384";
3445
0
  case WPA_KEY_MGMT_OWE:
3446
0
    return "OWE";
3447
0
  case WPA_KEY_MGMT_DPP:
3448
0
    return "DPP";
3449
0
  case WPA_KEY_MGMT_PASN:
3450
0
    return "PASN";
3451
0
  case WPA_KEY_MGMT_IEEE8021X_SHA384:
3452
0
    return "WPA2-EAP-SHA384";
3453
0
  case WPA_KEY_MGMT_EPPKE:
3454
0
    return "EPPKE";
3455
0
  case WPA_KEY_MGMT_PQC_8021X:
3456
0
    return "EAP-PQC";
3457
0
  case WPA_KEY_MGMT_FT_PQC_8021X:
3458
0
    return "FT-EAP-PQC";
3459
0
  default:
3460
0
    return "UNKNOWN";
3461
0
  }
3462
0
}
3463
3464
3465
u32 wpa_akm_to_suite(int akm)
3466
0
{
3467
0
  if (akm & WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
3468
0
    return RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384;
3469
0
  if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
3470
0
    return RSN_AUTH_KEY_MGMT_FT_802_1X;
3471
0
  if (akm & WPA_KEY_MGMT_FT_PSK)
3472
0
    return RSN_AUTH_KEY_MGMT_FT_PSK;
3473
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SHA384)
3474
0
    return RSN_AUTH_KEY_MGMT_802_1X_SHA384;
3475
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
3476
0
    return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
3477
0
  if (akm & WPA_KEY_MGMT_IEEE8021X)
3478
0
    return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
3479
0
  if (akm & WPA_KEY_MGMT_PSK_SHA256)
3480
0
    return RSN_AUTH_KEY_MGMT_PSK_SHA256;
3481
0
  if (akm & WPA_KEY_MGMT_PSK)
3482
0
    return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
3483
0
  if (akm & WPA_KEY_MGMT_CCKM)
3484
0
    return RSN_AUTH_KEY_MGMT_CCKM;
3485
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
3486
0
    return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
3487
0
  if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
3488
0
    return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
3489
0
  if (akm & WPA_KEY_MGMT_FILS_SHA256)
3490
0
    return RSN_AUTH_KEY_MGMT_FILS_SHA256;
3491
0
  if (akm & WPA_KEY_MGMT_FILS_SHA384)
3492
0
    return RSN_AUTH_KEY_MGMT_FILS_SHA384;
3493
0
  if (akm & WPA_KEY_MGMT_FT_FILS_SHA256)
3494
0
    return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
3495
0
  if (akm & WPA_KEY_MGMT_FT_FILS_SHA384)
3496
0
    return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
3497
0
  if (akm & WPA_KEY_MGMT_SAE)
3498
0
    return RSN_AUTH_KEY_MGMT_SAE;
3499
0
  if (akm & WPA_KEY_MGMT_SAE_EXT_KEY)
3500
0
    return RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
3501
0
  if (akm & WPA_KEY_MGMT_FT_SAE)
3502
0
    return RSN_AUTH_KEY_MGMT_FT_SAE;
3503
0
  if (akm & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
3504
0
    return RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
3505
0
  if (akm & WPA_KEY_MGMT_OWE)
3506
0
    return RSN_AUTH_KEY_MGMT_OWE;
3507
0
  if (akm & WPA_KEY_MGMT_DPP)
3508
0
    return RSN_AUTH_KEY_MGMT_DPP;
3509
#ifdef CONFIG_PASN
3510
  if (akm & WPA_KEY_MGMT_PASN)
3511
    return RSN_AUTH_KEY_MGMT_PASN;
3512
#endif /* CONFIG_PASN */
3513
0
  if (akm & WPA_KEY_MGMT_EPPKE)
3514
0
    return RSN_AUTH_KEY_MGMT_EPPKE;
3515
0
  if (akm & WPA_KEY_MGMT_FT_PQC_8021X)
3516
0
    return RSN_AUTH_KEY_MGMT_FT_802_1X_PQC;
3517
0
  if (akm & WPA_KEY_MGMT_PQC_8021X)
3518
0
    return RSN_AUTH_KEY_MGMT_802_1X_PQC;
3519
0
  return 0;
3520
0
}
3521
3522
3523
int wpa_compare_rsn_ie(int ft_initial_assoc,
3524
           const u8 *ie1, size_t ie1len,
3525
           const u8 *ie2, size_t ie2len)
3526
0
{
3527
0
  if (ie1 == NULL || ie2 == NULL)
3528
0
    return -1;
3529
3530
0
  if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
3531
0
    return 0; /* identical IEs */
3532
3533
0
#ifdef CONFIG_IEEE80211R
3534
0
  if (ft_initial_assoc) {
3535
0
    struct wpa_ie_data ie1d, ie2d;
3536
    /*
3537
     * The PMKID-List in RSN IE is different between Beacon/Probe
3538
     * Response/(Re)Association Request frames and EAPOL-Key
3539
     * messages in FT initial mobility domain association. Allow
3540
     * for this, but verify that other parts of the RSN IEs are
3541
     * identical.
3542
     */
3543
0
    if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
3544
0
        wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
3545
0
      return -1;
3546
0
    if (ie1d.proto == ie2d.proto &&
3547
0
        ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
3548
0
        ie1d.group_cipher == ie2d.group_cipher &&
3549
0
        ie1d.key_mgmt == ie2d.key_mgmt &&
3550
0
        ie1d.capabilities == ie2d.capabilities &&
3551
0
        ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
3552
0
      return 0;
3553
0
  }
3554
0
#endif /* CONFIG_IEEE80211R */
3555
3556
0
  return -1;
3557
0
}
3558
3559
3560
/**
3561
 * wpa_compare_rsn_ie_params - Compare RSN IE parameters
3562
 * @rsne1: Pointer to first RSNE (with element ID and length)
3563
 * @rsne1_len: Length of the first RSNE
3564
 * @rsnee2: Pointer to second RSNE (with element ID and length)
3565
 * @rsne2_len: Length of the second RSNE
3566
 * @pqc_sec_prof: Whether a PQC security profile is being used
3567
 * Returns: 0 if parameters match, -1 otherwise
3568
 *
3569
 * Compare the security parameters (proto, ciphers, key_mgmt)
3570
 * of two RSN IEs.
3571
 */
3572
int wpa_compare_rsne_params(const u8 *rsne1, size_t rsne1_len,
3573
          const u8 *rsne2, size_t rsne2_len,
3574
          bool pqc_sec_prof)
3575
0
{
3576
0
  struct wpa_ie_data rsn1, rsn2;
3577
3578
0
  if (!rsne1 || !rsne2)
3579
0
    return -1;
3580
3581
0
  if (wpa_parse_wpa_ie_rsn(rsne1, rsne1_len, &rsn1) < 0 ||
3582
0
      wpa_parse_wpa_ie_rsn(rsne2, rsne2_len, &rsn2) < 0)
3583
0
    return -1;
3584
3585
0
  if (pqc_sec_prof) {
3586
    /* PQC AKMs are not required to be included in the RSNE, so mask
3587
     * them out from the comparison below.*/
3588
0
    rsn1.key_mgmt &= ~(WPA_KEY_MGMT_PQC_8021X |
3589
0
           WPA_KEY_MGMT_FT_PQC_8021X);
3590
0
    rsn2.key_mgmt &= ~(WPA_KEY_MGMT_PQC_8021X |
3591
0
           WPA_KEY_MGMT_FT_PQC_8021X);
3592
0
  }
3593
3594
0
  if (rsn1.proto == rsn2.proto &&
3595
0
      rsn1.pairwise_cipher == rsn2.pairwise_cipher &&
3596
0
      rsn1.key_mgmt == rsn2.key_mgmt)
3597
0
    return 0;
3598
3599
0
  return -1;
3600
0
}
3601
3602
3603
int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid, bool replace)
3604
0
{
3605
0
  u8 *start, *end, *rpos, *rend;
3606
0
  int added = 0;
3607
3608
0
  start = ies;
3609
0
  end = ies + *ies_len;
3610
3611
0
  while (start < end) {
3612
0
    if (*start == WLAN_EID_RSN)
3613
0
      break;
3614
0
    start += 2 + start[1];
3615
0
  }
3616
0
  if (start >= end) {
3617
0
    wpa_printf(MSG_ERROR, "RSN: Could not find RSNE in IEs data");
3618
0
    return -1;
3619
0
  }
3620
0
  wpa_hexdump(MSG_DEBUG, "RSN: RSNE before modification",
3621
0
        start, 2 + start[1]);
3622
3623
  /* Find start of PMKID-Count */
3624
0
  rpos = start + 2;
3625
0
  rend = rpos + start[1];
3626
3627
  /* Skip Version and Group Data Cipher Suite */
3628
0
  rpos += 2 + 4;
3629
  /* Skip Pairwise Cipher Suite Count and List */
3630
0
  rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
3631
  /* Skip AKM Suite Count and List */
3632
0
  rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
3633
3634
0
  if (rpos == rend) {
3635
    /* Add RSN Capabilities */
3636
0
    os_memmove(rpos + 2, rpos, end - rpos);
3637
0
    *rpos++ = 0;
3638
0
    *rpos++ = 0;
3639
0
    added += 2;
3640
0
    start[1] += 2;
3641
0
    rend = rpos;
3642
0
  } else {
3643
    /* Skip RSN Capabilities */
3644
0
    rpos += 2;
3645
0
    if (rpos > rend) {
3646
0
      wpa_printf(MSG_ERROR,
3647
0
           "RSN: Could not parse RSNE in IEs data");
3648
0
      return -1;
3649
0
    }
3650
0
  }
3651
3652
0
  if (rpos == rend) {
3653
    /* No PMKID-Count field included; add it */
3654
0
    os_memmove(rpos + 2 + PMKID_LEN, rpos, end + added - rpos);
3655
0
    WPA_PUT_LE16(rpos, 1);
3656
0
    rpos += 2;
3657
0
    os_memcpy(rpos, pmkid, PMKID_LEN);
3658
0
    added += 2 + PMKID_LEN;
3659
0
    start[1] += 2 + PMKID_LEN;
3660
0
  } else {
3661
0
    u16 num_pmkid;
3662
3663
0
    if (rend - rpos < 2)
3664
0
      return -1;
3665
0
    num_pmkid = WPA_GET_LE16(rpos);
3666
0
    if (num_pmkid * PMKID_LEN > rend - rpos - 2)
3667
0
      return -1;
3668
    /* PMKID-Count was included; use it */
3669
0
    if (replace && num_pmkid != 0) {
3670
0
      u8 *after;
3671
3672
      /*
3673
       * PMKID may have been included in RSN IE in
3674
       * (Re)Association Request frame, so remove the old
3675
       * PMKID(s) first before adding the new one.
3676
       */
3677
0
      wpa_printf(MSG_DEBUG,
3678
0
           "RSN: Remove %u old PMKID(s) from RSNE",
3679
0
           num_pmkid);
3680
0
      after = rpos + 2 + num_pmkid * PMKID_LEN;
3681
0
      os_memmove(rpos + 2, after, end - after);
3682
0
      start[1] -= num_pmkid * PMKID_LEN;
3683
0
      added -= num_pmkid * PMKID_LEN;
3684
0
      num_pmkid = 0;
3685
0
    }
3686
0
    WPA_PUT_LE16(rpos, num_pmkid + 1);
3687
0
    rpos += 2;
3688
0
    os_memmove(rpos + PMKID_LEN, rpos, end + added - rpos);
3689
0
    os_memcpy(rpos, pmkid, PMKID_LEN);
3690
0
    added += PMKID_LEN;
3691
0
    start[1] += PMKID_LEN;
3692
0
  }
3693
3694
0
  wpa_hexdump(MSG_DEBUG, "RSN: RSNE after modification (PMKID inserted)",
3695
0
        start, 2 + start[1]);
3696
3697
0
  *ies_len += added;
3698
3699
0
  return 0;
3700
0
}
3701
3702
3703
int wpa_cipher_key_len(int cipher)
3704
1.22k
{
3705
1.22k
  switch (cipher) {
3706
0
  case WPA_CIPHER_CCMP_256:
3707
0
  case WPA_CIPHER_GCMP_256:
3708
0
  case WPA_CIPHER_BIP_GMAC_256:
3709
0
  case WPA_CIPHER_BIP_CMAC_256:
3710
0
    return 32;
3711
1.22k
  case WPA_CIPHER_CCMP:
3712
1.22k
  case WPA_CIPHER_GCMP:
3713
1.22k
  case WPA_CIPHER_AES_128_CMAC:
3714
1.22k
  case WPA_CIPHER_BIP_GMAC_128:
3715
1.22k
    return 16;
3716
0
  case WPA_CIPHER_TKIP:
3717
0
    return 32;
3718
0
  default:
3719
0
    return 0;
3720
1.22k
  }
3721
1.22k
}
3722
3723
3724
int wpa_cipher_rsc_len(int cipher)
3725
0
{
3726
0
  switch (cipher) {
3727
0
  case WPA_CIPHER_CCMP_256:
3728
0
  case WPA_CIPHER_GCMP_256:
3729
0
  case WPA_CIPHER_CCMP:
3730
0
  case WPA_CIPHER_GCMP:
3731
0
  case WPA_CIPHER_TKIP:
3732
0
    return 6;
3733
0
  default:
3734
0
    return 0;
3735
0
  }
3736
0
}
3737
3738
3739
enum wpa_alg wpa_cipher_to_alg(int cipher)
3740
0
{
3741
0
  switch (cipher) {
3742
0
  case WPA_CIPHER_CCMP_256:
3743
0
    return WPA_ALG_CCMP_256;
3744
0
  case WPA_CIPHER_GCMP_256:
3745
0
    return WPA_ALG_GCMP_256;
3746
0
  case WPA_CIPHER_CCMP:
3747
0
    return WPA_ALG_CCMP;
3748
0
  case WPA_CIPHER_GCMP:
3749
0
    return WPA_ALG_GCMP;
3750
0
  case WPA_CIPHER_TKIP:
3751
0
    return WPA_ALG_TKIP;
3752
0
  case WPA_CIPHER_AES_128_CMAC:
3753
0
    return WPA_ALG_BIP_CMAC_128;
3754
0
  case WPA_CIPHER_BIP_GMAC_128:
3755
0
    return WPA_ALG_BIP_GMAC_128;
3756
0
  case WPA_CIPHER_BIP_GMAC_256:
3757
0
    return WPA_ALG_BIP_GMAC_256;
3758
0
  case WPA_CIPHER_BIP_CMAC_256:
3759
0
    return WPA_ALG_BIP_CMAC_256;
3760
0
  default:
3761
0
    return WPA_ALG_NONE;
3762
0
  }
3763
0
}
3764
3765
3766
int wpa_cipher_valid_pairwise(int cipher)
3767
1.98k
{
3768
#ifdef CONFIG_NO_TKIP
3769
  return cipher == WPA_CIPHER_CCMP_256 ||
3770
    cipher == WPA_CIPHER_GCMP_256 ||
3771
    cipher == WPA_CIPHER_CCMP ||
3772
    cipher == WPA_CIPHER_GCMP;
3773
#else /* CONFIG_NO_TKIP */
3774
1.98k
  return cipher == WPA_CIPHER_CCMP_256 ||
3775
1.98k
    cipher == WPA_CIPHER_GCMP_256 ||
3776
1.98k
    cipher == WPA_CIPHER_CCMP ||
3777
1.98k
    cipher == WPA_CIPHER_GCMP ||
3778
0
    cipher == WPA_CIPHER_TKIP;
3779
1.98k
#endif /* CONFIG_NO_TKIP */
3780
1.98k
}
3781
3782
3783
u32 wpa_cipher_to_suite(int proto, int cipher)
3784
3.97k
{
3785
3.97k
  if (cipher & WPA_CIPHER_CCMP_256)
3786
0
    return RSN_CIPHER_SUITE_CCMP_256;
3787
3.97k
  if (cipher & WPA_CIPHER_GCMP_256)
3788
0
    return RSN_CIPHER_SUITE_GCMP_256;
3789
3.97k
  if (cipher & WPA_CIPHER_CCMP)
3790
3.97k
    return (proto == WPA_PROTO_RSN ?
3791
3.97k
      RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
3792
0
  if (cipher & WPA_CIPHER_GCMP)
3793
0
    return RSN_CIPHER_SUITE_GCMP;
3794
0
  if (cipher & WPA_CIPHER_TKIP)
3795
0
    return (proto == WPA_PROTO_RSN ?
3796
0
      RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
3797
0
  if (cipher & WPA_CIPHER_NONE)
3798
0
    return (proto == WPA_PROTO_RSN ?
3799
0
      RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
3800
0
  if (cipher & WPA_CIPHER_GTK_NOT_USED)
3801
0
    return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
3802
0
  if (cipher & WPA_CIPHER_AES_128_CMAC)
3803
0
    return RSN_CIPHER_SUITE_AES_128_CMAC;
3804
0
  if (cipher & WPA_CIPHER_BIP_GMAC_128)
3805
0
    return RSN_CIPHER_SUITE_BIP_GMAC_128;
3806
0
  if (cipher & WPA_CIPHER_BIP_GMAC_256)
3807
0
    return RSN_CIPHER_SUITE_BIP_GMAC_256;
3808
0
  if (cipher & WPA_CIPHER_BIP_CMAC_256)
3809
0
    return RSN_CIPHER_SUITE_BIP_CMAC_256;
3810
0
  return 0;
3811
0
}
3812
3813
3814
int rsn_cipher_put_suites(u8 *start, int ciphers)
3815
0
{
3816
0
  u8 *pos = start;
3817
3818
0
  if (ciphers & WPA_CIPHER_CCMP_256) {
3819
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
3820
0
    pos += RSN_SELECTOR_LEN;
3821
0
  }
3822
0
  if (ciphers & WPA_CIPHER_GCMP_256) {
3823
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
3824
0
    pos += RSN_SELECTOR_LEN;
3825
0
  }
3826
0
  if (ciphers & WPA_CIPHER_CCMP) {
3827
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
3828
0
    pos += RSN_SELECTOR_LEN;
3829
0
  }
3830
0
  if (ciphers & WPA_CIPHER_GCMP) {
3831
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
3832
0
    pos += RSN_SELECTOR_LEN;
3833
0
  }
3834
0
  if (ciphers & WPA_CIPHER_TKIP) {
3835
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
3836
0
    pos += RSN_SELECTOR_LEN;
3837
0
  }
3838
0
  if (ciphers & WPA_CIPHER_NONE) {
3839
0
    RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
3840
0
    pos += RSN_SELECTOR_LEN;
3841
0
  }
3842
3843
0
  return (pos - start) / RSN_SELECTOR_LEN;
3844
0
}
3845
3846
3847
int wpa_cipher_put_suites(u8 *start, int ciphers)
3848
0
{
3849
0
  u8 *pos = start;
3850
3851
0
  if (ciphers & WPA_CIPHER_CCMP) {
3852
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
3853
0
    pos += WPA_SELECTOR_LEN;
3854
0
  }
3855
0
  if (ciphers & WPA_CIPHER_TKIP) {
3856
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
3857
0
    pos += WPA_SELECTOR_LEN;
3858
0
  }
3859
0
  if (ciphers & WPA_CIPHER_NONE) {
3860
0
    RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
3861
0
    pos += WPA_SELECTOR_LEN;
3862
0
  }
3863
3864
0
  return (pos - start) / RSN_SELECTOR_LEN;
3865
0
}
3866
3867
3868
int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
3869
0
{
3870
0
  if (ciphers & WPA_CIPHER_GCMP_256)
3871
0
    return WPA_CIPHER_GCMP_256;
3872
0
  if (ciphers & WPA_CIPHER_CCMP_256)
3873
0
    return WPA_CIPHER_CCMP_256;
3874
0
  if (ciphers & WPA_CIPHER_CCMP)
3875
0
    return WPA_CIPHER_CCMP;
3876
0
  if (ciphers & WPA_CIPHER_GCMP)
3877
0
    return WPA_CIPHER_GCMP;
3878
0
  if (ciphers & WPA_CIPHER_TKIP)
3879
0
    return WPA_CIPHER_TKIP;
3880
0
  if (none_allowed && (ciphers & WPA_CIPHER_NONE))
3881
0
    return WPA_CIPHER_NONE;
3882
0
  return -1;
3883
0
}
3884
3885
3886
int wpa_pick_group_cipher(int ciphers)
3887
0
{
3888
0
  if (ciphers & WPA_CIPHER_GCMP_256)
3889
0
    return WPA_CIPHER_GCMP_256;
3890
0
  if (ciphers & WPA_CIPHER_CCMP_256)
3891
0
    return WPA_CIPHER_CCMP_256;
3892
0
  if (ciphers & WPA_CIPHER_CCMP)
3893
0
    return WPA_CIPHER_CCMP;
3894
0
  if (ciphers & WPA_CIPHER_GCMP)
3895
0
    return WPA_CIPHER_GCMP;
3896
0
  if (ciphers & WPA_CIPHER_GTK_NOT_USED)
3897
0
    return WPA_CIPHER_GTK_NOT_USED;
3898
0
  if (ciphers & WPA_CIPHER_TKIP)
3899
0
    return WPA_CIPHER_TKIP;
3900
0
  return -1;
3901
0
}
3902
3903
3904
int wpa_parse_cipher(const char *value)
3905
0
{
3906
0
  int val = 0, last;
3907
0
  char *start, *end, *buf;
3908
3909
0
  buf = os_strdup(value);
3910
0
  if (buf == NULL)
3911
0
    return -1;
3912
0
  start = buf;
3913
3914
0
  while (*start != '\0') {
3915
0
    while (*start == ' ' || *start == '\t')
3916
0
      start++;
3917
0
    if (*start == '\0')
3918
0
      break;
3919
0
    end = start;
3920
0
    while (*end != ' ' && *end != '\t' && *end != '\0')
3921
0
      end++;
3922
0
    last = *end == '\0';
3923
0
    *end = '\0';
3924
0
    if (os_strcmp(start, "CCMP-256") == 0)
3925
0
      val |= WPA_CIPHER_CCMP_256;
3926
0
    else if (os_strcmp(start, "GCMP-256") == 0)
3927
0
      val |= WPA_CIPHER_GCMP_256;
3928
0
    else if (os_strcmp(start, "CCMP") == 0)
3929
0
      val |= WPA_CIPHER_CCMP;
3930
0
    else if (os_strcmp(start, "GCMP") == 0)
3931
0
      val |= WPA_CIPHER_GCMP;
3932
0
#ifndef CONFIG_NO_TKIP
3933
0
    else if (os_strcmp(start, "TKIP") == 0)
3934
0
      val |= WPA_CIPHER_TKIP;
3935
0
#endif /* CONFIG_NO_TKIP */
3936
#ifdef CONFIG_WEP
3937
    else if (os_strcmp(start, "WEP104") == 0)
3938
      val |= WPA_CIPHER_WEP104;
3939
    else if (os_strcmp(start, "WEP40") == 0)
3940
      val |= WPA_CIPHER_WEP40;
3941
#endif /* CONFIG_WEP */
3942
0
    else if (os_strcmp(start, "NONE") == 0)
3943
0
      val |= WPA_CIPHER_NONE;
3944
0
    else if (os_strcmp(start, "GTK_NOT_USED") == 0)
3945
0
      val |= WPA_CIPHER_GTK_NOT_USED;
3946
0
    else if (os_strcmp(start, "AES-128-CMAC") == 0)
3947
0
      val |= WPA_CIPHER_AES_128_CMAC;
3948
0
    else if (os_strcmp(start, "BIP-GMAC-128") == 0)
3949
0
      val |= WPA_CIPHER_BIP_GMAC_128;
3950
0
    else if (os_strcmp(start, "BIP-GMAC-256") == 0)
3951
0
      val |= WPA_CIPHER_BIP_GMAC_256;
3952
0
    else if (os_strcmp(start, "BIP-CMAC-256") == 0)
3953
0
      val |= WPA_CIPHER_BIP_CMAC_256;
3954
0
    else {
3955
0
      os_free(buf);
3956
0
      return -1;
3957
0
    }
3958
3959
0
    if (last)
3960
0
      break;
3961
0
    start = end + 1;
3962
0
  }
3963
0
  os_free(buf);
3964
3965
0
  return val;
3966
0
}
3967
3968
3969
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
3970
0
{
3971
0
  char *pos = start;
3972
0
  int ret;
3973
3974
0
  if (ciphers & WPA_CIPHER_CCMP_256) {
3975
0
    ret = os_snprintf(pos, end - pos, "%sCCMP-256",
3976
0
          pos == start ? "" : delim);
3977
0
    if (os_snprintf_error(end - pos, ret))
3978
0
      return -1;
3979
0
    pos += ret;
3980
0
  }
3981
0
  if (ciphers & WPA_CIPHER_GCMP_256) {
3982
0
    ret = os_snprintf(pos, end - pos, "%sGCMP-256",
3983
0
          pos == start ? "" : delim);
3984
0
    if (os_snprintf_error(end - pos, ret))
3985
0
      return -1;
3986
0
    pos += ret;
3987
0
  }
3988
0
  if (ciphers & WPA_CIPHER_CCMP) {
3989
0
    ret = os_snprintf(pos, end - pos, "%sCCMP",
3990
0
          pos == start ? "" : delim);
3991
0
    if (os_snprintf_error(end - pos, ret))
3992
0
      return -1;
3993
0
    pos += ret;
3994
0
  }
3995
0
  if (ciphers & WPA_CIPHER_GCMP) {
3996
0
    ret = os_snprintf(pos, end - pos, "%sGCMP",
3997
0
          pos == start ? "" : delim);
3998
0
    if (os_snprintf_error(end - pos, ret))
3999
0
      return -1;
4000
0
    pos += ret;
4001
0
  }
4002
0
  if (ciphers & WPA_CIPHER_TKIP) {
4003
0
    ret = os_snprintf(pos, end - pos, "%sTKIP",
4004
0
          pos == start ? "" : delim);
4005
0
    if (os_snprintf_error(end - pos, ret))
4006
0
      return -1;
4007
0
    pos += ret;
4008
0
  }
4009
0
  if (ciphers & WPA_CIPHER_AES_128_CMAC) {
4010
0
    ret = os_snprintf(pos, end - pos, "%sAES-128-CMAC",
4011
0
          pos == start ? "" : delim);
4012
0
    if (os_snprintf_error(end - pos, ret))
4013
0
      return -1;
4014
0
    pos += ret;
4015
0
  }
4016
0
  if (ciphers & WPA_CIPHER_BIP_GMAC_128) {
4017
0
    ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-128",
4018
0
          pos == start ? "" : delim);
4019
0
    if (os_snprintf_error(end - pos, ret))
4020
0
      return -1;
4021
0
    pos += ret;
4022
0
  }
4023
0
  if (ciphers & WPA_CIPHER_BIP_GMAC_256) {
4024
0
    ret = os_snprintf(pos, end - pos, "%sBIP-GMAC-256",
4025
0
          pos == start ? "" : delim);
4026
0
    if (os_snprintf_error(end - pos, ret))
4027
0
      return -1;
4028
0
    pos += ret;
4029
0
  }
4030
0
  if (ciphers & WPA_CIPHER_BIP_CMAC_256) {
4031
0
    ret = os_snprintf(pos, end - pos, "%sBIP-CMAC-256",
4032
0
          pos == start ? "" : delim);
4033
0
    if (os_snprintf_error(end - pos, ret))
4034
0
      return -1;
4035
0
    pos += ret;
4036
0
  }
4037
0
  if (ciphers & WPA_CIPHER_NONE) {
4038
0
    ret = os_snprintf(pos, end - pos, "%sNONE",
4039
0
          pos == start ? "" : delim);
4040
0
    if (os_snprintf_error(end - pos, ret))
4041
0
      return -1;
4042
0
    pos += ret;
4043
0
  }
4044
4045
0
  return pos - start;
4046
0
}
4047
4048
4049
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
4050
0
{
4051
0
  int pairwise = 0;
4052
4053
  /* Select group cipher based on the enabled pairwise cipher suites */
4054
0
  if (wpa & 1)
4055
0
    pairwise |= wpa_pairwise;
4056
0
  if (wpa & 2)
4057
0
    pairwise |= rsn_pairwise;
4058
4059
0
  if (pairwise & WPA_CIPHER_TKIP)
4060
0
    return WPA_CIPHER_TKIP;
4061
0
  if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
4062
0
    return WPA_CIPHER_GCMP;
4063
0
  if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
4064
0
       WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
4065
0
    return WPA_CIPHER_GCMP_256;
4066
0
  if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
4067
0
       WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
4068
0
    return WPA_CIPHER_CCMP_256;
4069
0
  return WPA_CIPHER_CCMP;
4070
0
}
4071
4072
4073
#ifdef CONFIG_FILS
4074
int fils_domain_name_hash(const char *domain, u8 *hash)
4075
{
4076
  char buf[255], *wpos = buf;
4077
  const char *pos = domain;
4078
  size_t len;
4079
  const u8 *addr[1];
4080
  u8 mac[SHA256_MAC_LEN];
4081
4082
  for (len = 0; len < sizeof(buf) && *pos; len++) {
4083
    if (isalpha(*pos) && isupper(*pos))
4084
      *wpos++ = tolower(*pos);
4085
    else
4086
      *wpos++ = *pos;
4087
    pos++;
4088
  }
4089
4090
  addr[0] = (const u8 *) buf;
4091
  if (sha256_vector(1, addr, &len, mac) < 0)
4092
    return -1;
4093
  os_memcpy(hash, mac, 2);
4094
  return 0;
4095
}
4096
#endif /* CONFIG_FILS */
4097
4098
4099
/**
4100
 * wpa_parse_vendor_specific - Parse Vendor Specific IEs
4101
 * @pos: Pointer to the IE header
4102
 * @end: Pointer to the end of the Key Data buffer
4103
 * @ie: Pointer to parsed IE data
4104
 */
4105
static void wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
4106
              struct wpa_eapol_ie_parse *ie)
4107
13.8k
{
4108
13.8k
  unsigned int oui;
4109
4110
13.8k
  if (pos[1] < 4) {
4111
3.90k
    wpa_printf(MSG_MSGDUMP,
4112
3.90k
         "Too short vendor specific IE ignored (len=%u)",
4113
3.90k
         pos[1]);
4114
3.90k
    return;
4115
3.90k
  }
4116
4117
9.91k
  oui = WPA_GET_BE24(&pos[2]);
4118
9.91k
  if (oui == OUI_MICROSOFT && pos[5] == WMM_OUI_TYPE && pos[1] > 4) {
4119
823
    if (pos[6] == WMM_OUI_SUBTYPE_INFORMATION_ELEMENT) {
4120
261
      ie->wmm = &pos[2];
4121
261
      ie->wmm_len = pos[1];
4122
261
      wpa_hexdump(MSG_DEBUG, "WPA: WMM IE",
4123
261
            ie->wmm, ie->wmm_len);
4124
562
    } else if (pos[6] == WMM_OUI_SUBTYPE_PARAMETER_ELEMENT) {
4125
312
      ie->wmm = &pos[2];
4126
312
      ie->wmm_len = pos[1];
4127
312
      wpa_hexdump(MSG_DEBUG, "WPA: WMM Parameter Element",
4128
312
            ie->wmm, ie->wmm_len);
4129
312
    }
4130
823
  }
4131
9.91k
}
4132
4133
4134
/**
4135
 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
4136
 * @pos: Pointer to the IE header
4137
 * @ie: Pointer to parsed IE data
4138
 * Returns: 0 on success, 1 if end mark is found, 2 if KDE is not recognized
4139
 */
4140
static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
4141
23.7k
{
4142
23.7k
  u8 len = pos[1];
4143
23.7k
  size_t dlen = 2 + len;
4144
23.7k
  u32 selector;
4145
23.7k
  const u8 *p;
4146
23.7k
  size_t left;
4147
23.7k
  u8 link_id;
4148
23.7k
  char title[100];
4149
23.7k
  int ret;
4150
4151
23.7k
  if (len == 0)
4152
0
    return 1;
4153
4154
23.7k
  if (len < RSN_SELECTOR_LEN)
4155
3.90k
    return 2;
4156
4157
19.8k
  p = pos + 2;
4158
19.8k
  selector = RSN_SELECTOR_GET(p);
4159
19.8k
  p += RSN_SELECTOR_LEN;
4160
19.8k
  left = len - RSN_SELECTOR_LEN;
4161
4162
19.8k
  if (left >= 2 && selector == WPA_OUI_TYPE && p[0] == 1 && p[1] == 0) {
4163
620
    ie->wpa_ie = pos;
4164
620
    ie->wpa_ie_len = dlen;
4165
620
    wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
4166
620
          ie->wpa_ie, ie->wpa_ie_len);
4167
620
    return 0;
4168
620
  }
4169
4170
19.2k
  if (left >= PMKID_LEN && selector == RSN_KEY_DATA_PMKID) {
4171
1.11k
    ie->pmkid = p;
4172
1.11k
    wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key", pos, dlen);
4173
1.11k
    return 0;
4174
1.11k
  }
4175
4176
18.0k
  if (left >= 2 && selector == RSN_KEY_DATA_KEYID) {
4177
238
    ie->key_id = p;
4178
238
    wpa_hexdump(MSG_DEBUG, "WPA: KeyID in EAPOL-Key", pos, dlen);
4179
238
    return 0;
4180
238
  }
4181
4182
17.8k
  if (left > 2 && selector == RSN_KEY_DATA_GROUPKEY) {
4183
337
    ie->gtk = p;
4184
337
    ie->gtk_len = left;
4185
337
    wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key", pos, dlen);
4186
337
    return 0;
4187
337
  }
4188
4189
17.5k
  if (left >= ETH_ALEN && selector == RSN_KEY_DATA_MAC_ADDR) {
4190
435
    ie->mac_addr = p;
4191
435
    wpa_printf(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key: " MACSTR,
4192
435
         MAC2STR(ie->mac_addr));
4193
435
    return 0;
4194
435
  }
4195
4196
17.0k
  if (left > 2 && selector == RSN_KEY_DATA_IGTK) {
4197
1.02k
    ie->igtk = p;
4198
1.02k
    ie->igtk_len = left;
4199
1.02k
    wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
4200
1.02k
        pos, dlen);
4201
1.02k
    return 0;
4202
1.02k
  }
4203
4204
16.0k
  if (left > 2 && selector == RSN_KEY_DATA_BIGTK) {
4205
292
    ie->bigtk = p;
4206
292
    ie->bigtk_len = left;
4207
292
    wpa_hexdump_key(MSG_DEBUG, "WPA: BIGTK in EAPOL-Key",
4208
292
        pos, dlen);
4209
292
    return 0;
4210
292
  }
4211
4212
15.7k
  if (left > 2 && selector == RSN_KEY_DATA_SAE_PW_IDS) {
4213
353
    ie->sae_pw_ids = p;
4214
353
    ie->sae_pw_ids_len = left;
4215
353
    wpa_hexdump_key(MSG_DEBUG,
4216
353
        "RSN: SAE Password Identifiers in EAPOL-Key",
4217
353
        pos, dlen);
4218
353
    return 0;
4219
353
  }
4220
4221
15.4k
  if (left >= 1 && selector == WFA_KEY_DATA_IP_ADDR_REQ) {
4222
348
    ie->ip_addr_req = p;
4223
348
    wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
4224
348
          ie->ip_addr_req, left);
4225
348
    return 0;
4226
348
  }
4227
4228
15.0k
  if (left >= 3 * 4 && selector == WFA_KEY_DATA_IP_ADDR_ALLOC) {
4229
232
    ie->ip_addr_alloc = p;
4230
232
    wpa_hexdump(MSG_DEBUG,
4231
232
          "WPA: IP Address Allocation in EAPOL-Key",
4232
232
          ie->ip_addr_alloc, left);
4233
232
    return 0;
4234
232
  }
4235
4236
14.8k
  if (left > 2 && selector == RSN_KEY_DATA_OCI) {
4237
356
    ie->oci = p;
4238
356
    ie->oci_len = left;
4239
356
    wpa_hexdump(MSG_DEBUG, "WPA: OCI KDE in EAPOL-Key",
4240
356
          pos, dlen);
4241
356
    return 0;
4242
356
  }
4243
4244
14.4k
  if (left >= 1 && selector == WFA_KEY_DATA_TRANSITION_DISABLE) {
4245
289
    ie->transition_disable = p;
4246
289
    ie->transition_disable_len = left;
4247
289
    wpa_hexdump(MSG_DEBUG,
4248
289
          "WPA: Transition Disable KDE in EAPOL-Key",
4249
289
          pos, dlen);
4250
289
    return 0;
4251
289
  }
4252
4253
14.1k
  if (left >= 2 && selector == WFA_KEY_DATA_DPP) {
4254
387
    ie->dpp_kde = p;
4255
387
    ie->dpp_kde_len = left;
4256
387
    wpa_hexdump(MSG_DEBUG, "WPA: DPP KDE in EAPOL-Key", pos, dlen);
4257
387
    return 0;
4258
387
  }
4259
4260
13.8k
  if (left >= RSN_MLO_GTK_KDE_PREFIX_LENGTH &&
4261
5.06k
      selector == RSN_KEY_DATA_MLO_GTK) {
4262
641
    link_id = (p[0] & RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK) >>
4263
641
      RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT;
4264
641
    if (link_id >= MAX_NUM_MLD_LINKS)
4265
358
      return 2;
4266
4267
283
    ie->valid_mlo_gtks |= BIT(link_id);
4268
283
    ie->mlo_gtk[link_id] = p;
4269
283
    ie->mlo_gtk_len[link_id] = left;
4270
283
    ret = os_snprintf(title, sizeof(title),
4271
283
          "RSN: Link ID %u - MLO GTK KDE in EAPOL-Key",
4272
283
          link_id);
4273
283
    if (!os_snprintf_error(sizeof(title), ret))
4274
283
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
4275
283
    return 0;
4276
641
  }
4277
4278
13.1k
  if (left >= RSN_MLO_IGTK_KDE_PREFIX_LENGTH &&
4279
3.06k
      selector == RSN_KEY_DATA_MLO_IGTK) {
4280
639
    link_id = (p[8] & RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK) >>
4281
639
        RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT;
4282
639
    if (link_id >= MAX_NUM_MLD_LINKS)
4283
335
      return 2;
4284
4285
304
    ie->valid_mlo_igtks |= BIT(link_id);
4286
304
    ie->mlo_igtk[link_id] = p;
4287
304
    ie->mlo_igtk_len[link_id] = left;
4288
304
    ret = os_snprintf(title, sizeof(title),
4289
304
          "RSN: Link ID %u - MLO IGTK KDE in EAPOL-Key",
4290
304
          link_id);
4291
304
    if (!os_snprintf_error(sizeof(title), ret))
4292
304
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
4293
304
    return 0;
4294
639
  }
4295
4296
12.5k
  if (left >= RSN_MLO_BIGTK_KDE_PREFIX_LENGTH &&
4297
2.42k
      selector == RSN_KEY_DATA_MLO_BIGTK) {
4298
890
    link_id = (p[8] & RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK) >>
4299
890
        RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT;
4300
890
    if (link_id >= MAX_NUM_MLD_LINKS)
4301
292
      return 2;
4302
4303
598
    ie->valid_mlo_bigtks |= BIT(link_id);
4304
598
    ie->mlo_bigtk[link_id] = p;
4305
598
    ie->mlo_bigtk_len[link_id] = left;
4306
598
    ret = os_snprintf(title, sizeof(title),
4307
598
          "RSN: Link ID %u - MLO BIGTK KDE in EAPOL-Key",
4308
598
          link_id);
4309
598
    if (!os_snprintf_error(sizeof(title), ret))
4310
598
      wpa_hexdump_key(MSG_DEBUG, title, pos, dlen);
4311
598
    return 0;
4312
890
  }
4313
4314
11.6k
  if (left >= RSN_MLO_LINK_KDE_FIXED_LENGTH &&
4315
2.89k
      selector == RSN_KEY_DATA_MLO_LINK) {
4316
540
    link_id = (p[0] & RSN_MLO_LINK_KDE_LI_LINK_ID_MASK) >>
4317
540
        RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT;
4318
540
    if (link_id >= MAX_NUM_MLD_LINKS)
4319
208
      return 2;
4320
4321
332
    ie->valid_mlo_links |= BIT(link_id);
4322
332
    ie->mlo_link[link_id] = p;
4323
332
    ie->mlo_link_len[link_id] = left;
4324
332
    ret = os_snprintf(title, sizeof(title),
4325
332
          "RSN: Link ID %u - MLO Link KDE in EAPOL-Key",
4326
332
          link_id);
4327
332
    if (!os_snprintf_error(sizeof(title), ret))
4328
332
      wpa_hexdump(MSG_DEBUG, title, pos, dlen);
4329
332
    return 0;
4330
540
  }
4331
4332
11.0k
  if (left >= 1 && selector == WFA_KEY_DATA_RSN_OVERRIDE_LINK) {
4333
861
    link_id = p[0];
4334
861
    if (link_id >= MAX_NUM_MLD_LINKS)
4335
436
      return 2;
4336
4337
425
    ie->rsn_override_link[link_id] = p;
4338
425
    ie->rsn_override_link_len[link_id] = left;
4339
425
    ret = os_snprintf(title, sizeof(title),
4340
425
          "RSN: Link ID %u - RSN Override Link KDE in EAPOL-Key",
4341
425
          link_id);
4342
425
    if (!os_snprintf_error(sizeof(title), ret))
4343
425
      wpa_hexdump(MSG_DEBUG, title, pos, dlen);
4344
425
    return 0;
4345
861
  }
4346
4347
10.2k
  if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
4348
915
    ie->rsne_override = pos;
4349
915
    ie->rsne_override_len = dlen;
4350
915
    wpa_hexdump(MSG_DEBUG,
4351
915
          "RSN: RSNE Override element in EAPOL-Key",
4352
915
          ie->rsne_override, ie->rsne_override_len);
4353
915
    return 0;
4354
915
  }
4355
4356
9.31k
  if (selector == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
4357
368
    ie->rsne_override_2 = pos;
4358
368
    ie->rsne_override_2_len = dlen;
4359
368
    wpa_hexdump(MSG_DEBUG,
4360
368
          "RSN: RSNE Override 2 element in EAPOL-Key",
4361
368
          ie->rsne_override_2, ie->rsne_override_2_len);
4362
368
    return 0;
4363
368
  }
4364
4365
8.94k
  if (selector == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
4366
277
    ie->rsnxe_override = pos;
4367
277
    ie->rsnxe_override_len = dlen;
4368
277
    wpa_hexdump(MSG_DEBUG,
4369
277
          "RSN: RSNXE Override element in EAPOL-Key",
4370
277
          ie->rsnxe_override, ie->rsnxe_override_len);
4371
277
    return 0;
4372
277
  }
4373
4374
8.67k
  if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
4375
385
    ie->rsn_selection = p;
4376
385
    ie->rsn_selection_len = left;
4377
385
    wpa_hexdump(MSG_DEBUG,
4378
385
          "RSN: RSN Selection element in EAPOL-Key",
4379
385
          ie->rsn_selection, ie->rsn_selection_len);
4380
385
    return 0;
4381
385
  }
4382
4383
#if defined(CONFIG_NAN) || defined(CONFIG_PASN)
4384
  if (left >= sizeof(struct nan_nik_kde) &&
4385
      selector == NAN_KEY_DATA_NIK) {
4386
    ie->nan_nik = p;
4387
    ie->nan_nik_len = left;
4388
    wpa_hexdump_key(MSG_DEBUG, "RSN: NAN NIK KDE in EAPOL-Key",
4389
        ie->nan_nik, ie->nan_nik_len);
4390
    return 0;
4391
  }
4392
4393
  if (left >= sizeof(struct nan_key_lifetime_kde) &&
4394
      selector == NAN_KEY_DATA_LIFETIME) {
4395
    ie->nan_key_lifetime = p;
4396
    ie->nan_key_lifetime_len = left;
4397
    wpa_hexdump(MSG_DEBUG,
4398
          "RSN: NAN Key Lifetime KDE in EAPOL-Key",
4399
          ie->nan_key_lifetime, ie->nan_key_lifetime_len);
4400
    return 0;
4401
  }
4402
#endif /* CONFIG_NAN || CONFIG_PASN */
4403
4404
8.28k
  return 2;
4405
8.67k
}
4406
4407
4408
/**
4409
 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
4410
 * @buf: Pointer to the Key Data buffer
4411
 * @len: Key Data Length
4412
 * @ie: Pointer to parsed IE data
4413
 * Returns: 0 on success, -1 on failure
4414
 */
4415
int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
4416
1.60k
{
4417
1.60k
  const u8 *pos, *end;
4418
1.60k
  int ret = 0;
4419
1.60k
  size_t dlen = 0;
4420
4421
1.60k
  os_memset(ie, 0, sizeof(*ie));
4422
93.5k
  for (pos = buf, end = pos + len; end - pos > 1; pos += dlen) {
4423
92.3k
    if (pos[0] == 0xdd &&
4424
23.7k
        ((pos == buf + len - 1) || pos[1] == 0)) {
4425
      /* Ignore padding */
4426
17
      break;
4427
17
    }
4428
92.3k
    dlen = 2 + pos[1];
4429
92.3k
    if ((int) dlen > end - pos) {
4430
376
      wpa_printf(MSG_DEBUG,
4431
376
           "WPA: EAPOL-Key Key Data underflow (ie=%d len=%d pos=%d)",
4432
376
           pos[0], pos[1], (int) (pos - buf));
4433
376
      wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", buf, len);
4434
376
      ret = -1;
4435
376
      break;
4436
376
    }
4437
91.9k
    if (*pos == WLAN_EID_RSN) {
4438
1.70k
      ie->rsn_ie = pos;
4439
1.70k
      ie->rsn_ie_len = dlen;
4440
1.70k
      wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
4441
1.70k
            ie->rsn_ie, ie->rsn_ie_len);
4442
90.2k
    } else if (*pos == WLAN_EID_RSNX) {
4443
592
      ie->rsnxe = pos;
4444
592
      ie->rsnxe_len = dlen;
4445
592
      wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
4446
592
            ie->rsnxe, ie->rsnxe_len);
4447
89.6k
    } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
4448
1.21k
      ie->mdie = pos;
4449
1.21k
      ie->mdie_len = dlen;
4450
1.21k
      wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
4451
1.21k
            ie->mdie, ie->mdie_len);
4452
88.4k
    } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
4453
769
      ie->ftie = pos;
4454
769
      ie->ftie_len = dlen;
4455
769
      wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
4456
769
            ie->ftie, ie->ftie_len);
4457
87.6k
    } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
4458
1.49k
      if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
4459
236
        ie->reassoc_deadline = pos;
4460
236
        wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
4461
236
              "in EAPOL-Key",
4462
236
              ie->reassoc_deadline, dlen);
4463
1.26k
      } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
4464
432
        ie->key_lifetime = pos;
4465
432
        wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
4466
432
              "in EAPOL-Key",
4467
432
              ie->key_lifetime, dlen);
4468
831
      } else {
4469
831
        wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
4470
831
              "EAPOL-Key Key Data IE",
4471
831
              pos, dlen);
4472
831
      }
4473
86.1k
    } else if (*pos == WLAN_EID_LINK_ID) {
4474
726
      if (pos[1] >= 18) {
4475
224
        ie->lnkid = pos;
4476
224
        ie->lnkid_len = dlen;
4477
224
      }
4478
85.4k
    } else if (*pos == WLAN_EID_EXT_CAPAB) {
4479
462
      ie->ext_capab = pos;
4480
462
      ie->ext_capab_len = dlen;
4481
84.9k
    } else if (*pos == WLAN_EID_SUPP_RATES) {
4482
2.83k
      ie->supp_rates = pos;
4483
2.83k
      ie->supp_rates_len = dlen;
4484
82.1k
    } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
4485
600
      ie->ext_supp_rates = pos;
4486
600
      ie->ext_supp_rates_len = dlen;
4487
81.5k
    } else if (*pos == WLAN_EID_HT_CAP &&
4488
2.25k
         pos[1] >= sizeof(struct ieee80211_ht_capabilities)) {
4489
372
      ie->ht_capabilities = pos + 2;
4490
81.1k
    } else if (*pos == WLAN_EID_AID) {
4491
790
      if (pos[1] >= 2)
4492
298
        ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
4493
80.3k
    } else if (*pos == WLAN_EID_VHT_CAP &&
4494
1.20k
         pos[1] >= sizeof(struct ieee80211_vht_capabilities))
4495
368
    {
4496
368
      ie->vht_capabilities = pos + 2;
4497
80.0k
    } else if (*pos == WLAN_EID_EXTENSION &&
4498
5.12k
         pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN &&
4499
1.36k
         pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) {
4500
424
      ie->he_capabilities = pos + 3;
4501
424
      ie->he_capab_len = pos[1] - 1;
4502
79.6k
    } else if (*pos == WLAN_EID_EXTENSION &&
4503
4.69k
         pos[1] >= 1 +
4504
4.69k
         sizeof(struct ieee80211_he_6ghz_band_cap) &&
4505
2.86k
         pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) {
4506
376
      ie->he_6ghz_capabilities = pos + 3;
4507
79.2k
    } else if (*pos == WLAN_EID_EXTENSION &&
4508
4.32k
         pos[1] >= 1 + IEEE80211_EHT_CAPAB_MIN_LEN &&
4509
1.44k
         pos[2] == WLAN_EID_EXT_EHT_CAPABILITIES) {
4510
276
      ie->eht_capabilities = pos + 3;
4511
276
      ie->eht_capab_len = pos[1] - 1;
4512
78.9k
    } else if (*pos == WLAN_EID_EXTENSION &&
4513
4.04k
         pos[1] >= 3 &&
4514
2.20k
         pos[2] == WLAN_EID_EXT_SECURITY_PROFILE) {
4515
682
      ie->security_profile = pos;
4516
682
      ie->security_profile_len = dlen;
4517
682
      wpa_hexdump(MSG_DEBUG,
4518
682
            "WPA: Security Profile element in EAPOL-Key",
4519
682
            ie->security_profile,
4520
682
            ie->security_profile_len);
4521
78.2k
    } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
4522
582
      ie->qosinfo = pos[2];
4523
77.6k
    } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
4524
589
      ie->supp_channels = pos + 2;
4525
589
      ie->supp_channels_len = pos[1];
4526
77.1k
    } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
4527
      /*
4528
       * The value of the Length field of the Supported
4529
       * Operating Classes element is between 2 and 253.
4530
       * Silently skip invalid elements to avoid interop
4531
       * issues when trying to use the value.
4532
       */
4533
1.85k
      if (pos[1] >= 2 && pos[1] <= 253) {
4534
393
        ie->supp_oper_classes = pos + 2;
4535
393
        ie->supp_oper_classes_len = pos[1];
4536
393
      }
4537
75.2k
    } else if (*pos == WLAN_EID_SSID) {
4538
22.8k
      ie->ssid = pos + 2;
4539
22.8k
      ie->ssid_len = pos[1];
4540
22.8k
      wpa_hexdump_ascii(MSG_DEBUG, "RSN: SSID in EAPOL-Key",
4541
22.8k
            ie->ssid, ie->ssid_len);
4542
52.3k
    } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
4543
23.7k
      ret = wpa_parse_generic(pos, ie);
4544
23.7k
      if (ret == 1) {
4545
        /* end mark found */
4546
0
        ret = 0;
4547
0
        break;
4548
0
      }
4549
4550
23.7k
      if (ret == 2) {
4551
        /* not a known KDE */
4552
13.8k
        wpa_parse_vendor_specific(pos, end, ie);
4553
13.8k
      }
4554
4555
23.7k
      ret = 0;
4556
28.6k
    } else {
4557
28.6k
      wpa_hexdump(MSG_DEBUG,
4558
28.6k
            "WPA: Unrecognized EAPOL-Key Key Data IE",
4559
28.6k
            pos, dlen);
4560
28.6k
    }
4561
91.9k
  }
4562
4563
1.60k
  return ret;
4564
1.60k
}
4565
4566
4567
#ifdef CONFIG_TESTING_OPTIONS
4568
int wpa_rsne_inject_random_pmkids(u8 **pos, unsigned int count)
4569
{
4570
  unsigned int i;
4571
4572
  wpa_printf(MSG_INFO, "TESTING: Inject %u random PMKID(s) into RSNE",
4573
       count);
4574
  WPA_PUT_LE16(*pos, count);
4575
  *pos += 2;
4576
  for (i = 0; i < count; i++) {
4577
    if (random_get_bytes(*pos, PMKID_LEN) < 0) {
4578
      wpa_printf(MSG_WARNING,
4579
           "TESTING: Failed to generate random PMKID");
4580
      return -1;
4581
    }
4582
    wpa_hexdump(MSG_DEBUG, "TESTING: Random PMKID",
4583
          *pos, PMKID_LEN);
4584
    *pos += PMKID_LEN;
4585
  }
4586
  return 0;
4587
}
4588
#endif /* CONFIG_TESTING_OPTIONS */
4589
4590
4591
#ifdef CONFIG_PASN
4592
4593
/*
4594
 * wpa_pasn_build_auth_header - Add the MAC header and initialize Authentication
4595
 * frame for PASN/EPPKE
4596
 *
4597
 * @buf: Buffer in which the header will be added
4598
 * @bssid: The BSSID of the AP
4599
 * @src: Source address
4600
 * @dst: Destination address
4601
 * @trans_seq: Authentication transaction sequence number
4602
 * @status: Authentication status
4603
 * @is_eppke: EPPKE authentication
4604
 */
4605
void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
4606
        const u8 *src, const u8 *dst,
4607
        u8 trans_seq, u16 status, bool is_eppke)
4608
{
4609
  struct ieee80211_mgmt *auth;
4610
  u16 auth_alg = is_eppke ? WLAN_AUTH_EPPKE : WLAN_AUTH_PASN;
4611
4612
  wpa_printf(MSG_DEBUG, "%s: Add authentication header trans_seq=%u",
4613
       is_eppke ? "EPPKE" : "PASN", trans_seq);
4614
4615
  auth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
4616
          u.auth.variable));
4617
4618
  auth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
4619
             (WLAN_FC_STYPE_AUTH << 4));
4620
4621
  os_memcpy(auth->da, dst, ETH_ALEN);
4622
  os_memcpy(auth->sa, src, ETH_ALEN);
4623
  os_memcpy(auth->bssid, bssid, ETH_ALEN);
4624
  auth->seq_ctrl = 0;
4625
4626
  auth->u.auth.auth_alg = host_to_le16(auth_alg);
4627
  auth->u.auth.auth_transaction = host_to_le16(trans_seq);
4628
  auth->u.auth.status_code = host_to_le16(status);
4629
}
4630
4631
4632
/*
4633
 * wpa_pasn_add_rsne - Add an RSNE for PASN authentication
4634
 * @buf: Buffer in which the IE will be added
4635
 * @pmkid: Optional PMKID. Can be NULL.
4636
 * @akmp: Authentication and key management protocol
4637
 * @cipher: The cipher suite
4638
 * @random_pmkid_count: Number of random PMKIDs to add; only for testing
4639
 * purposes
4640
 */
4641
int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid, int akmp, int cipher,
4642
          unsigned int random_pmkid_count)
4643
{
4644
  struct rsn_ie_hdr *hdr;
4645
  u32 suite;
4646
  u16 capab;
4647
  u8 *pos;
4648
  u8 rsne_len;
4649
4650
  wpa_printf(MSG_DEBUG, "PASN: Add RSNE");
4651
4652
  rsne_len = sizeof(*hdr) + RSN_SELECTOR_LEN +
4653
    2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN +
4654
    2 + RSN_SELECTOR_LEN + 2 + (pmkid ? PMKID_LEN : 0);
4655
  if (!pmkid && random_pmkid_count > 0)
4656
    rsne_len += 2 + random_pmkid_count * PMKID_LEN;
4657
4658
  if (wpabuf_tailroom(buf) < rsne_len)
4659
    return -1;
4660
  hdr = wpabuf_put(buf, rsne_len);
4661
  hdr->elem_id = WLAN_EID_RSN;
4662
  hdr->len = rsne_len - 2;
4663
  WPA_PUT_LE16(hdr->version, RSN_VERSION);
4664
  pos = (u8 *) (hdr + 1);
4665
4666
  /* Group addressed data is not allowed */
4667
  RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
4668
  pos += RSN_SELECTOR_LEN;
4669
4670
  /* Add the pairwise cipher */
4671
  WPA_PUT_LE16(pos, 1);
4672
  pos += 2;
4673
  suite = wpa_cipher_to_suite(WPA_PROTO_RSN, cipher);
4674
  RSN_SELECTOR_PUT(pos, suite);
4675
  pos += RSN_SELECTOR_LEN;
4676
4677
  /* Add the AKM suite */
4678
  WPA_PUT_LE16(pos, 1);
4679
  pos += 2;
4680
4681
  switch (akmp) {
4682
  case WPA_KEY_MGMT_PASN:
4683
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
4684
    break;
4685
#ifdef CONFIG_ENC_ASSOC
4686
  case WPA_KEY_MGMT_EPPKE:
4687
    /* EPPKE without base AKM: EPPKE AKMP is used as the selected
4688
     * AKMP per IEEE P802.11bi/D4.0, 12.16.9.1. */
4689
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_EPPKE);
4690
    break;
4691
#endif /* CONFIG_ENC_ASSOC */
4692
#ifdef CONFIG_SAE
4693
  case WPA_KEY_MGMT_SAE:
4694
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
4695
    break;
4696
  case WPA_KEY_MGMT_SAE_EXT_KEY:
4697
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
4698
    break;
4699
#endif /* CONFIG_SAE */
4700
#ifdef CONFIG_FILS
4701
  case WPA_KEY_MGMT_FILS_SHA256:
4702
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
4703
    break;
4704
  case WPA_KEY_MGMT_FILS_SHA384:
4705
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
4706
    break;
4707
#endif /* CONFIG_FILS */
4708
#ifdef CONFIG_IEEE80211R
4709
  case WPA_KEY_MGMT_FT_PSK:
4710
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
4711
    break;
4712
  case WPA_KEY_MGMT_FT_IEEE8021X:
4713
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
4714
    break;
4715
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
4716
    RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
4717
    break;
4718
#endif /* CONFIG_IEEE80211R */
4719
  default:
4720
    wpa_printf(MSG_ERROR, "PASN: Invalid AKMP=0x%x", akmp);
4721
    return -1;
4722
  }
4723
  pos += RSN_SELECTOR_LEN;
4724
4725
  /* RSN Capabilities: PASN mandates both MFP capable and required */
4726
  capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
4727
  WPA_PUT_LE16(pos, capab);
4728
  pos += 2;
4729
4730
#ifdef CONFIG_TESTING_OPTIONS
4731
  if (!pmkid && random_pmkid_count > 0) {
4732
    if (wpa_rsne_inject_random_pmkids(&pos, random_pmkid_count) < 0)
4733
      return -1;
4734
  } else
4735
#endif /* CONFIG_TESTING_OPTIONS */
4736
  if (pmkid) {
4737
    wpa_printf(MSG_DEBUG, "PASN: Adding PMKID");
4738
4739
    WPA_PUT_LE16(pos, 1);
4740
    pos += 2;
4741
    os_memcpy(pos, pmkid, PMKID_LEN);
4742
    pos += PMKID_LEN;
4743
  } else {
4744
    WPA_PUT_LE16(pos, 0);
4745
    pos += 2;
4746
  }
4747
4748
  /* Group addressed management is not allowed */
4749
  RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
4750
4751
  return 0;
4752
}
4753
4754
4755
/*
4756
 * wpa_pasn_add_parameter_ie - Add PASN Parameters IE for PASN authentication
4757
 * @buf: Buffer in which the IE will be added
4758
 * @pasn_group: Finite Cyclic Group ID for PASN authentication
4759
 * @wrapped_data_format: Format of the data in the Wrapped Data IE
4760
 * @pubkey: A buffer holding the local public key. Can be NULL
4761
 * @compressed: In case pubkey is included, indicates if the public key is
4762
 *     compressed (only x coordinate is included) or not (both x and y
4763
 *     coordinates are included)
4764
 * @comeback: A buffer holding the comeback token. Can be NULL
4765
 * @after: If comeback is set, defined the comeback time in seconds. -1 to not
4766
 *  include the Comeback After field (frames from non-AP STA).
4767
 */
4768
void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
4769
             u8 wrapped_data_format,
4770
             const struct wpabuf *pubkey, bool compressed,
4771
             const struct wpabuf *comeback, int after)
4772
{
4773
  struct pasn_parameter_ie *params;
4774
4775
  wpa_printf(MSG_DEBUG, "PASN: Add PASN Parameters element");
4776
4777
  params = wpabuf_put(buf, sizeof(*params));
4778
4779
  params->id = WLAN_EID_EXTENSION;
4780
  params->len = sizeof(*params) - 2;
4781
  params->id_ext = WLAN_EID_EXT_PASN_PARAMS;
4782
  params->control = 0;
4783
  params->wrapped_data_format = wrapped_data_format;
4784
4785
  if (comeback) {
4786
    wpa_printf(MSG_DEBUG, "PASN: Adding comeback data");
4787
4788
    /*
4789
     * 2 octets for the 'after' field + 1 octet for the length +
4790
     * actual cookie data
4791
     */
4792
    if (after >= 0)
4793
      params->len += 2;
4794
    params->len += 1 + wpabuf_len(comeback);
4795
    params->control |= WPA_PASN_CTRL_COMEBACK_INFO_PRESENT;
4796
4797
    if (after >= 0)
4798
      wpabuf_put_le16(buf, after);
4799
    wpabuf_put_u8(buf, wpabuf_len(comeback));
4800
    wpabuf_put_buf(buf, comeback);
4801
  }
4802
4803
  if (pubkey) {
4804
    wpa_printf(MSG_DEBUG,
4805
         "PASN: Adding public key and group ID %u",
4806
         pasn_group);
4807
4808
    /*
4809
     * 2 octets for the finite cyclic group + 2 octets public key
4810
     * length + 1 octet for the compressed/uncompressed indication +
4811
     * the actual key.
4812
     */
4813
    params->len += 2 + 1 + 1 + wpabuf_len(pubkey);
4814
    params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
4815
4816
    wpabuf_put_le16(buf, pasn_group);
4817
4818
    /*
4819
     * The first octet indicates whether the public key is
4820
     * compressed, as defined in RFC 5480 section 2.2.
4821
     */
4822
    wpabuf_put_u8(buf, wpabuf_len(pubkey) + 1);
4823
    wpabuf_put_u8(buf, compressed ? WPA_PASN_PUBKEY_COMPRESSED_0 :
4824
            WPA_PASN_PUBKEY_UNCOMPRESSED);
4825
4826
    wpabuf_put_buf(buf, pubkey);
4827
  }
4828
}
4829
4830
/*
4831
 * wpa_pasn_add_wrapped_data - Add a Wrapped Data IE to PASN Authentication
4832
 * frame. If needed, the Wrapped Data IE would be fragmented.
4833
 *
4834
 * @buf: Buffer in which the IE will be added
4835
 * @wrapped_data_buf: Buffer holding the wrapped data
4836
 */
4837
int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
4838
            struct wpabuf *wrapped_data_buf)
4839
{
4840
  const u8 *data;
4841
  size_t data_len;
4842
  u8 len;
4843
4844
  if (!wrapped_data_buf)
4845
    return 0;
4846
4847
  wpa_printf(MSG_DEBUG, "PASN: Add wrapped data");
4848
4849
  data = wpabuf_head_u8(wrapped_data_buf);
4850
  data_len = wpabuf_len(wrapped_data_buf);
4851
4852
  /* nothing to add */
4853
  if (!data_len)
4854
    return 0;
4855
4856
  if (data_len <= 254)
4857
    len = 1 + data_len;
4858
  else
4859
    len = 255;
4860
4861
  if (wpabuf_tailroom(buf) < 3 + data_len)
4862
    return -1;
4863
4864
  wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
4865
  wpabuf_put_u8(buf, len);
4866
  wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
4867
  wpabuf_put_data(buf, data, len - 1);
4868
4869
  data += len - 1;
4870
  data_len -= len - 1;
4871
4872
  while (data_len) {
4873
    if (wpabuf_tailroom(buf) < 2 + data_len)
4874
      return -1;
4875
    wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
4876
    len = data_len > 255 ? 255 : data_len;
4877
    wpabuf_put_u8(buf, len);
4878
    wpabuf_put_data(buf, data, len);
4879
    data += len;
4880
    data_len -= len;
4881
  }
4882
4883
  return 0;
4884
}
4885
4886
4887
/*
4888
 * wpa_pasn_validate_rsne - Validate PASN/EPPKE specific data of RSNE
4889
 * @data: Parsed representation of an RSNE
4890
 * @is_eppke: EPPKE Authentication
4891
 * Returns -1 for invalid data; otherwise 0
4892
 */
4893
int wpa_pasn_validate_rsne(const struct wpa_ie_data *data, bool is_eppke)
4894
{
4895
  u16 capab = WPA_CAPABILITY_MFPC;
4896
4897
  if (!is_eppke)
4898
    capab |= WPA_CAPABILITY_MFPR;
4899
4900
  if (data->proto != WPA_PROTO_RSN)
4901
    return -1;
4902
4903
  if ((data->capabilities & capab) != capab) {
4904
    wpa_printf(MSG_DEBUG, "%s: Invalid RSNE capabilities",
4905
         is_eppke ? "EPPKE" : "PASN");
4906
    return -1;
4907
  }
4908
4909
  if (!data->has_group ||
4910
      (!is_eppke && data->group_cipher != WPA_CIPHER_GTK_NOT_USED)) {
4911
    wpa_printf(MSG_DEBUG, "PASN: Invalid group data cipher");
4912
    return -1;
4913
  }
4914
4915
  if (!data->has_pairwise || !data->pairwise_cipher ||
4916
      (data->pairwise_cipher & (data->pairwise_cipher - 1))) {
4917
    wpa_printf(MSG_DEBUG, "PASN: No valid pairwise suite");
4918
    return -1;
4919
  }
4920
4921
  switch (data->key_mgmt) {
4922
#ifdef CONFIG_SAE
4923
  case WPA_KEY_MGMT_SAE:
4924
  case WPA_KEY_MGMT_SAE_EXT_KEY:
4925
  case WPA_KEY_MGMT_FT_SAE_EXT_KEY:
4926
  /* fall through */
4927
#endif /* CONFIG_SAE */
4928
#ifdef CONFIG_FILS
4929
  case WPA_KEY_MGMT_FILS_SHA256:
4930
  case WPA_KEY_MGMT_FILS_SHA384:
4931
  /* fall through */
4932
#endif /* CONFIG_FILS */
4933
#ifdef CONFIG_IEEE80211R
4934
  case WPA_KEY_MGMT_FT_PSK:
4935
  case WPA_KEY_MGMT_FT_IEEE8021X:
4936
  case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
4937
  /* fall through */
4938
#endif /* CONFIG_IEEE80211R */
4939
  case WPA_KEY_MGMT_PASN:
4940
    break;
4941
#ifdef CONFIG_ENC_ASSOC
4942
  case WPA_KEY_MGMT_EPPKE:
4943
    /* EPPKE AKMP is used when EPPKE is performed without a base
4944
     * AKM (no mutual authentication). This is only valid for EPPKE
4945
     * authentication per IEEE P802.11bi/D4.0, 12.16.9.1. */
4946
    if (!is_eppke) {
4947
      wpa_printf(MSG_INFO,
4948
           "PASN: EPPKE AKM not allowed for PASN");
4949
      return -1;
4950
    }
4951
    break;
4952
#endif /* CONFIG_ENC_ASSOC */
4953
  default:
4954
    wpa_printf(MSG_ERROR, "%s: invalid key_mgmt: 0x%0x",
4955
         is_eppke ? "EPPKE" : "PASN", data->key_mgmt);
4956
    return -1;
4957
  }
4958
4959
  if (!is_eppke && (data->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED)) {
4960
    wpa_printf(MSG_DEBUG, "PASN: Invalid group mgmt cipher");
4961
    return -1;
4962
  }
4963
4964
  if (data->num_pmkid > 1) {
4965
    wpa_printf(MSG_DEBUG, "PASN: Invalid number of PMKIDs");
4966
    return -1;
4967
  }
4968
4969
  return 0;
4970
}
4971
4972
4973
/*
4974
 * wpa_pasn_parse_parameter_ie - Validates PASN Parameters IE
4975
 * @data: Pointer to the PASN Parameters IE (starting with the EID).
4976
 * @len: Length of the data in the PASN Parameters IE
4977
 * @from_ap: Whether this was received from an AP
4978
 * @pasn_params: On successful return would hold the parsed PASN parameters.
4979
 * Returns: -1 for invalid data; otherwise 0
4980
 *
4981
 * Note: On successful return, the pointers in &pasn_params point to the data in
4982
 * the IE and are not locally allocated (so they should not be freed etc.).
4983
 */
4984
int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
4985
        struct wpa_pasn_params_data *pasn_params)
4986
{
4987
  struct pasn_parameter_ie *params = (struct pasn_parameter_ie *) data;
4988
  const u8 *pos = (const u8 *) (params + 1);
4989
4990
  if (!pasn_params) {
4991
    wpa_printf(MSG_DEBUG, "PASN: Invalid params");
4992
    return -1;
4993
  }
4994
4995
  if (!params || ((size_t) (params->len + 2) < sizeof(*params)) ||
4996
      len < sizeof(*params) || params->len + 2 != len) {
4997
    wpa_printf(MSG_DEBUG,
4998
         "PASN: Invalid parameters IE. len=(%u, %u)",
4999
         params ? params->len : 0, len);
5000
    return -1;
5001
  }
5002
5003
  os_memset(pasn_params, 0, sizeof(*pasn_params));
5004
5005
  switch (params->wrapped_data_format) {
5006
  case WPA_PASN_WRAPPED_DATA_NO:
5007
  case WPA_PASN_WRAPPED_DATA_SAE:
5008
  case WPA_PASN_WRAPPED_DATA_FILS_SK:
5009
  case WPA_PASN_WRAPPED_DATA_FT:
5010
    break;
5011
  default:
5012
    wpa_printf(MSG_DEBUG, "PASN: Invalid wrapped data format");
5013
    return -1;
5014
  }
5015
5016
  pasn_params->wrapped_data_format = params->wrapped_data_format;
5017
5018
  len -= sizeof(*params);
5019
5020
  if (params->control & WPA_PASN_CTRL_COMEBACK_INFO_PRESENT) {
5021
    if (from_ap) {
5022
      if (len < 2) {
5023
        wpa_printf(MSG_DEBUG,
5024
             "PASN: Invalid Parameters IE: Truncated Comeback After");
5025
        return -1;
5026
      }
5027
      pasn_params->after = WPA_GET_LE16(pos);
5028
      pos += 2;
5029
      len -= 2;
5030
    }
5031
5032
    if (len < 1 || len < 1 + *pos) {
5033
      wpa_printf(MSG_DEBUG,
5034
           "PASN: Invalid Parameters IE: comeback len");
5035
      return -1;
5036
    }
5037
5038
    pasn_params->comeback_len = *pos++;
5039
    len--;
5040
    pasn_params->comeback = pos;
5041
    len -=  pasn_params->comeback_len;
5042
    pos += pasn_params->comeback_len;
5043
  }
5044
5045
  if (params->control & WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT) {
5046
    if (len < 3 || len < 3 + pos[2]) {
5047
      wpa_printf(MSG_DEBUG,
5048
           "PASN: Invalid Parameters IE: group and key");
5049
      return -1;
5050
    }
5051
5052
    pasn_params->group = WPA_GET_LE16(pos);
5053
    pos += 2;
5054
    len -= 2;
5055
    pasn_params->pubkey_len = *pos++;
5056
    len--;
5057
    pasn_params->pubkey = pos;
5058
    len -= pasn_params->pubkey_len;
5059
    pos += pasn_params->pubkey_len;
5060
  }
5061
5062
  if (len) {
5063
    wpa_printf(MSG_DEBUG,
5064
         "PASN: Invalid Parameters IE. Bytes left=%u", len);
5065
    return -1;
5066
  }
5067
5068
  return 0;
5069
}
5070
5071
5072
void wpa_pasn_add_rsnxe(struct wpabuf *buf, u64 capab)
5073
{
5074
  size_t flen;
5075
5076
  if (!capab)
5077
    return; /* no supported extended RSN capabilities */
5078
5079
  /* Determine how many octets are needed to represent capab */
5080
  if (capab & 0xFF00000000000000ULL)
5081
    flen = 8;
5082
  else if (capab & 0x00FF000000000000ULL)
5083
    flen = 7;
5084
  else if (capab & 0x0000FF0000000000ULL)
5085
    flen = 6;
5086
  else if (capab & 0x000000FF00000000ULL)
5087
    flen = 5;
5088
  else if (capab & 0xFF000000)
5089
    flen = 4;
5090
  else if (capab & 0x00FF0000)
5091
    flen = 3;
5092
  else if (capab & 0x0000FF00)
5093
    flen = 2;
5094
  else
5095
    flen = 1;
5096
5097
  if (wpabuf_tailroom(buf) < 2 + flen)
5098
    return;
5099
  capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
5100
5101
  wpabuf_put_u8(buf, WLAN_EID_RSNX);
5102
  wpabuf_put_u8(buf, flen);
5103
5104
  /* Write the little endian capability field octet-by-octet */
5105
  wpabuf_put_u8(buf, capab & 0x000000FF);
5106
  if (flen > 1)
5107
    wpabuf_put_u8(buf, (capab >> 8) & 0x000000FF);
5108
  if (flen > 2)
5109
    wpabuf_put_u8(buf, (capab >> 16) & 0x000000FF);
5110
  if (flen > 3)
5111
    wpabuf_put_u8(buf, (capab >> 24) & 0x000000FF);
5112
  if (flen > 4)
5113
    wpabuf_put_u8(buf, (capab >> 32) & 0x000000FF);
5114
  if (flen > 5)
5115
    wpabuf_put_u8(buf, (capab >> 40) & 0x000000FF);
5116
  if (flen > 6)
5117
    wpabuf_put_u8(buf, (capab >> 48) & 0x000000FF);
5118
  if (flen > 7)
5119
    wpabuf_put_u8(buf, (capab >> 56) & 0x000000FF);
5120
}
5121
5122
5123
/*
5124
 * wpa_pasn_add_extra_ies - Add protocol specific IEs in Authentication
5125
 * frame for PASN.
5126
 *
5127
 * @buf: Buffer in which the elements will be added
5128
 * @extra_ies: Protocol specific elements to add
5129
 * @len: Length of the elements
5130
 * Returns: 0 on success, -1 on failure
5131
 */
5132
5133
int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len)
5134
{
5135
  if (!len || !extra_ies || !buf)
5136
    return 0;
5137
5138
  if (wpabuf_tailroom(buf) < len)
5139
    return -1;
5140
5141
  wpabuf_put_data(buf, extra_ies, len);
5142
  return 0;
5143
}
5144
5145
#endif /* CONFIG_PASN */
5146
5147
5148
void rsn_set_snonce_cookie(u8 *snonce)
5149
0
{
5150
0
  u8 *pos;
5151
5152
0
  pos = snonce + WPA_NONCE_LEN - 6;
5153
0
  WPA_PUT_BE24(pos, OUI_WFA);
5154
0
  pos += 3;
5155
0
  WPA_PUT_BE24(pos, 0x000029);
5156
0
}
5157
5158
5159
bool rsn_is_snonce_cookie(const u8 *snonce)
5160
0
{
5161
0
  const u8 *pos;
5162
5163
0
  pos = snonce + WPA_NONCE_LEN - 6;
5164
0
  return WPA_GET_BE24(pos) == OUI_WFA &&
5165
0
    WPA_GET_BE24(pos + 3) == 0x000029;
5166
0
}
5167
5168
5169
void wpa_add_supported_groups(struct wpabuf *buf, const int *groups)
5170
0
{
5171
0
  unsigned int count, i;
5172
0
  static const int default_groups[] = { 19, 0 };
5173
5174
0
  if (!buf)
5175
0
    return;
5176
5177
0
  if (!groups)
5178
0
    groups = default_groups;
5179
5180
0
  count = int_array_len(groups);
5181
0
  if (wpabuf_tailroom(buf) < 2 + 1 + count * 2)
5182
0
    return;
5183
5184
0
  wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
5185
0
  wpabuf_put_u8(buf, 1 + count * 2);
5186
0
  wpabuf_put_u8(buf, WLAN_EID_EXT_SUPPORTED_GROUPS);
5187
0
  for (i = 0; i < count; i++)
5188
0
    wpabuf_put_le16(buf, groups[i]);
5189
0
}
5190
5191
5192
static const struct security_profile_entry
5193
security_profile_table[] = {
5194
  /* number, key_mgmt, pairwise_cipher, ieee8021x_auth_frame,
5195
   * assoc_frame_encrypt, pmksa_caching_privacy */
5196
5197
  /* 0: EPPKE (AKM 29), unauth‑EPPKE allowed */
5198
  { 0, WPA_KEY_MGMT_EPPKE, WPA_CIPHER_GCMP_256, false, true, true, -1 },
5199
5200
  /* 1: EPPKE + SAE (AKM 29+24) */
5201
  { 1, WPA_KEY_MGMT_EPPKE | WPA_KEY_MGMT_SAE_EXT_KEY,
5202
    WPA_CIPHER_GCMP_256, false, true, true, -1 },
5203
5204
  /* 2: EPPKE + FT‑SAE (AKM 29+25) */
5205
  { 2, WPA_KEY_MGMT_EPPKE | WPA_KEY_MGMT_FT_SAE_EXT_KEY,
5206
    WPA_CIPHER_GCMP_256, false, true, true, -1 },
5207
5208
  /* 3: EPP 802.1X (AKM 5) */
5209
  { 3, WPA_KEY_MGMT_IEEE8021X_SHA256, WPA_CIPHER_GCMP_256,
5210
    true, true, true, -1 },
5211
5212
  /* 4: EPP FT‑802.1X (AKM 3) */
5213
  { 4, WPA_KEY_MGMT_FT_IEEE8021X, WPA_CIPHER_GCMP_256, true, true, true,
5214
    -1 },
5215
5216
  /* 5: EPP 802.1X (AKM 23) */
5217
  { 5, WPA_KEY_MGMT_IEEE8021X_SHA384, WPA_CIPHER_GCMP_256,
5218
    true, true, true, -1 },
5219
5220
  /* 6: EPP FT‑802.1X (AKM 22) */
5221
  { 6, WPA_KEY_MGMT_FT_IEEE8021X_SHA384, WPA_CIPHER_GCMP_256,
5222
    true, true, true, -1 },
5223
5224
  /* 7: EPP 802.1X (AKM 12) */
5225
  { 7, WPA_KEY_MGMT_IEEE8021X_SUITE_B_192,  WPA_CIPHER_GCMP_256,
5226
    true, true, true, -1 },
5227
5228
  /* 8: OWE (AKM 18) */
5229
  { 8, WPA_KEY_MGMT_OWE, WPA_CIPHER_GCMP_256, false, false, false, -1 },
5230
5231
  /* 9: SAE (AKM 24) */
5232
  { 9, WPA_KEY_MGMT_SAE_EXT_KEY, WPA_CIPHER_GCMP_256,
5233
    false, false, false, -1 },
5234
5235
#ifdef CONFIG_PQC
5236
  /* 16: PQC 802.1X (AKM 31), no ECP, SHA-512, ML-KEM-1024 */
5237
  { SEC_PROF_8021X_PQC_0, WPA_KEY_MGMT_PQC_8021X, WPA_CIPHER_GCMP_256,
5238
    true, true, true, PQC_PROFILE_ML_KEM_1024 },
5239
5240
  /* 17: PQC 802.1X (AKM 31), P-256, SHA-256, ML-KEM-512 */
5241
  { SEC_PROF_8021X_PQC_1, WPA_KEY_MGMT_PQC_8021X, WPA_CIPHER_GCMP_256,
5242
    true, true, true, PQC_PROFILE_ECP_19_ML_KEM_512 },
5243
5244
  /* 18: PQC 802.1X (AKM 31), P-384, SHA-384, ML-KEM-768 */
5245
  { SEC_PROF_8021X_PQC_2, WPA_KEY_MGMT_PQC_8021X, WPA_CIPHER_GCMP_256,
5246
    true, true, true, PQC_PROFILE_ECP_20_ML_KEM_768 },
5247
5248
  /* 19: PQC 802.1X (AKM 31), P-521, SHA-512, ML-KEM-1024 */
5249
  { SEC_PROF_8021X_PQC_3, WPA_KEY_MGMT_PQC_8021X, WPA_CIPHER_GCMP_256,
5250
    true, true, true, PQC_PROFILE_ECP_21_ML_KEM_1024 },
5251
5252
  /* 20: FT PQC 802.1X (AKM 32), no ECP, SHA-512, ML-KEM-1024 */
5253
  { SEC_PROF_8021X_FT_PQC_0, WPA_KEY_MGMT_FT_PQC_8021X,
5254
    WPA_CIPHER_GCMP_256, true, true, true, PQC_PROFILE_ML_KEM_1024 },
5255
5256
  /* 21: FT PQC 802.1X (AKM 32), P-256, SHA-256, ML-KEM-512 */
5257
  { SEC_PROF_8021X_FT_PQC_1, WPA_KEY_MGMT_FT_PQC_8021X,
5258
    WPA_CIPHER_GCMP_256, true, true, true,
5259
    PQC_PROFILE_ECP_19_ML_KEM_512 },
5260
5261
  /* 22: FT PQC 802.1X (AKM 32), P-384, SHA-384, ML-KEM-768 */
5262
  { SEC_PROF_8021X_FT_PQC_2, WPA_KEY_MGMT_FT_PQC_8021X,
5263
    WPA_CIPHER_GCMP_256, true, true, true,
5264
    PQC_PROFILE_ECP_20_ML_KEM_768 },
5265
5266
  /* 23: FT PQC 802.1X (AKM 32), P-521, SHA-512, ML-KEM-1024 */
5267
  { SEC_PROF_8021X_FT_PQC_3, WPA_KEY_MGMT_FT_PQC_8021X,
5268
    WPA_CIPHER_GCMP_256, true, true, true,
5269
    PQC_PROFILE_ECP_21_ML_KEM_1024 },
5270
#endif /* CONFIG_PQC */
5271
};
5272
5273
5274
/**
5275
 * sec_prof_implied_key_mgmt - Derive implied key_mgmt from security profiles
5276
 * @profiles: -1 terminated int array of enabled security profile numbers
5277
 * Returns: Union of all AKMs defined by the enabled security profiles
5278
 */
5279
int sec_prof_implied_key_mgmt(const int *profiles)
5280
0
{
5281
0
  int i, implied = 0;
5282
5283
0
  if (!profiles)
5284
0
    return 0;
5285
5286
0
  for (i = 0; profiles[i] >= 0; i++) {
5287
0
    const struct security_profile_entry *sp;
5288
5289
0
    sp = sec_prof_get(profiles[i]);
5290
0
    if (sp)
5291
0
      implied |= sp->key_mgmt;
5292
0
  }
5293
5294
0
  return implied;
5295
0
}
5296
5297
5298
const struct security_profile_entry * sec_prof_get(int p)
5299
0
{
5300
0
  unsigned int i;
5301
5302
0
  for (i = 0; i < ARRAY_SIZE(security_profile_table); i++) {
5303
0
    const struct security_profile_entry *sp;
5304
5305
0
    sp = &security_profile_table[i];
5306
0
    if (sp->number == p)
5307
0
      return sp;
5308
0
  }
5309
5310
0
  return NULL;
5311
0
}
5312
5313
5314
#ifdef CONFIG_PQC
5315
5316
/*
5317
 * Global table of PQC profiles as defined in IEEE P802.11bt/D1.0,
5318
 * Table 12-aa1 (PQC profiles).
5319
 */
5320
static const struct ieee80211_pqc_profile g_pqc_profiles[] = {
5321
  { PQC_PROFILE_ML_KEM_1024, 0, RSN_HASH_SHA512, CRYPTO_ML_KEM_1024 },
5322
  { PQC_PROFILE_ECP_19_ML_KEM_512, 19, RSN_HASH_SHA256,
5323
    CRYPTO_ML_KEM_512 },
5324
  { PQC_PROFILE_ECP_20_ML_KEM_768, 20, RSN_HASH_SHA384,
5325
    CRYPTO_ML_KEM_768 },
5326
  { PQC_PROFILE_ECP_21_ML_KEM_1024, 21, RSN_HASH_SHA512,
5327
    CRYPTO_ML_KEM_1024 },
5328
  { PQC_PROFILE_NONE, 0, 0, 0 }
5329
};
5330
5331
5332
const struct ieee80211_pqc_profile *
5333
pqc_profile_get(int security_profile_num)
5334
{
5335
  const struct security_profile_entry *sp =
5336
    sec_prof_get(security_profile_num);
5337
  int i;
5338
5339
  if (!sp || sp->pqc_profile < 0) {
5340
    wpa_printf(MSG_ERROR,
5341
         "Invalid PQC security profile number: %u",
5342
         security_profile_num);
5343
    return NULL;
5344
  }
5345
5346
  for (i = 0; g_pqc_profiles[i].number != PQC_PROFILE_NONE; i++) {
5347
    if (g_pqc_profiles[i].number == sp->pqc_profile)
5348
      return &g_pqc_profiles[i];
5349
  }
5350
5351
  return NULL;
5352
}
5353
5354
#endif /* CONFIG_PQC */
5355
5356
5357
#if defined(CONFIG_SAE) || defined(CONFIG_PQC)
5358
5359
int hkdf_extract(size_t hash_len, const u8 *salt, size_t salt_len,
5360
     size_t num_elem, const u8 *addr[], const size_t len[],
5361
     u8 *prk)
5362
0
{
5363
#ifdef CONFIG_SHA256
5364
  if (hash_len == 32)
5365
    return hmac_sha256_vector(salt, salt_len, num_elem, addr, len,
5366
            prk);
5367
#endif /* CONFIG_SHA256 */
5368
#ifdef CONFIG_SHA384
5369
  if (hash_len == 48)
5370
    return hmac_sha384_vector(salt, salt_len, num_elem, addr, len,
5371
            prk);
5372
#endif /* CONFIG_SHA384 */
5373
#ifdef CONFIG_SHA512
5374
  if (hash_len == 64)
5375
    return hmac_sha512_vector(salt, salt_len, num_elem, addr, len,
5376
            prk);
5377
#endif /* CONFIG_SHA512 */
5378
0
  return -1;
5379
0
}
5380
5381
5382
int hkdf_expand_bin(size_t hash_len, const u8 *prk, size_t prk_len,
5383
        const u8 *info, size_t info_len, u8 *okm, size_t okm_len)
5384
0
{
5385
#ifdef CONFIG_SHA256
5386
  if (hash_len == 32)
5387
    return hmac_sha256_kdf(prk, prk_len, NULL,
5388
               (const u8 *) info, info_len,
5389
               okm, okm_len);
5390
#endif /* CONFIG_SHA256 */
5391
#ifdef CONFIG_SHA384
5392
  if (hash_len == 48)
5393
    return hmac_sha384_kdf(prk, prk_len, NULL,
5394
               (const u8 *) info, info_len,
5395
               okm, okm_len);
5396
#endif /* CONFIG_SHA384 */
5397
#ifdef CONFIG_SHA512
5398
  if (hash_len == 64)
5399
    return hmac_sha512_kdf(prk, prk_len, NULL,
5400
               (const u8 *) info, info_len,
5401
               okm, okm_len);
5402
#endif /* CONFIG_SHA512 */
5403
0
  return -1;
5404
0
}
5405
5406
5407
int hkdf_expand(size_t hash_len, const u8 *prk, size_t prk_len,
5408
    const char *info, u8 *okm, size_t okm_len)
5409
0
{
5410
0
  return hkdf_expand_bin(hash_len, prk, prk_len, (const u8 *) info,
5411
0
             os_strlen(info), okm, okm_len);
5412
0
}
5413
5414
#endif /* CONFIG_SAE || CONFIG_PQC */