Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/crypt/dot11decrypt.c
Line
Count
Source
1
/* dot11decrypt.c
2
 *
3
 * Copyright (c) 2006 CACE Technologies, Davis (California)
4
 * All rights reserved.
5
 *
6
 * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
7
 */
8
9
/****************************************************************************/
10
/*      File includes                                                       */
11
12
#include "config.h"
13
/* Keep this first after config.h so that WS_LOG_DOMAIN is set correctly. */
14
#include "dot11decrypt_debug.h"
15
16
#include <stdint.h>
17
#include <glib.h>
18
19
#include <wsutil/wsgcrypt.h>
20
#include <wsutil/pint.h>
21
22
#include <epan/proto.h> /* for DISSECTOR_ASSERT. */
23
#include <epan/strutil.h>
24
25
#include "dot11decrypt_util.h"
26
#include "dot11decrypt_system.h"
27
#include "dot11decrypt_int.h"
28
29
#include "wep-wpadefs.h"
30
31
32
/****************************************************************************/
33
static int Dot11DecryptGetKckLen(int akm, size_t pmk_len);
34
static int Dot11DecryptGetTkLen(int cipher);
35
static int Dot11DecryptGetKekLen(int akm, size_t pmk_len);
36
static int Dot11DecryptGetPtkLen(int akm, int cipher, size_t pmk_len);
37
static int Dot11DecryptGetHashAlgoFromAkm(int akm, size_t pmk_len);
38
39
/****************************************************************************/
40
/*      Constant definitions                                                    */
41
42
/*      EAPOL definitions                                                       */
43
/**
44
 * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
45
 * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
46
 */
47
#define DOT11DECRYPT_WPA_KCK_LEN    16
48
/**
49
 *Offset of the Key MIC in the EAPOL packet body
50
 */
51
0
#define DOT11DECRYPT_WPA_MICKEY_OFFSET      77
52
/**
53
 * Maximum length of the EAPOL packet (it depends on the maximum MAC
54
 * frame size)
55
 */
56
#define DOT11DECRYPT_WPA_MAX_EAPOL_LEN      4095
57
/**
58
 * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
59
 * from a STA when neither the group nor pairwise ciphers are CCMP for
60
 * Key Descriptor 1.
61
 * @note
62
 * Defined in 802.11i-2004, page 78
63
 */
64
0
#define DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP   1
65
/**
66
 * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
67
 * from a STA when either the pairwise or the group cipher is AES-CCMP
68
 * for Key Descriptor 2.
69
 * /note
70
 * Defined in 802.11i-2004, page 78
71
 */
72
0
#define DOT11DECRYPT_WPA_KEY_VER_AES_CCMP   2
73
74
/** Define EAPOL Key Descriptor type values:  use 254 for WPA and 2 for WPA2 **/
75
0
#define DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR 254
76
0
#define DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR 2
77
78
/* PMK to PTK derive functions */
79
0
#define DOT11DECRYPT_DERIVE_USING_PRF 0
80
0
#define DOT11DECRYPT_DERIVE_USING_KDF 1
81
/****************************************************************************/
82
83
84
/****************************************************************************/
85
/*      Macro definitions                                                       */
86
87
0
#define KCK_OFFSET(akm) (0)
88
0
#define KEK_OFFSET(akm, pmk_len) ((KCK_OFFSET(akm) + Dot11DecryptGetKckLen(akm, pmk_len) / 8))
89
0
#define TK_OFFSET(akm, pmk_len)  ((KEK_OFFSET(akm, pmk_len) + Dot11DecryptGetKekLen(akm, pmk_len) / 8))
90
91
0
#define DOT11DECRYPT_GET_KCK(ptk, akm)           (ptk + KCK_OFFSET(akm))
92
0
#define DOT11DECRYPT_GET_KEK(ptk, akm, pmk_len)  (ptk + KEK_OFFSET(akm, pmk_len))
93
0
#define DOT11DECRYPT_GET_TK_TKIP(ptk)            (ptk + 32)
94
0
#define DOT11DECRYPT_GET_TK(ptk, akm, pmk_len)   (ptk + TK_OFFSET(akm, pmk_len))
95
96
#define DOT11DECRYPT_IEEE80211_OUI(oui) (pntohu24(oui) == 0x000fac)
97
98
/****************************************************************************/
99
100
/****************************************************************************/
101
/*      Type definitions                                                        */
102
103
/*      Internal function prototype declarations                                */
104
105
#ifdef  __cplusplus
106
extern "C" {
107
#endif
108
109
/**
110
 * It calculates the passphrase-to-PSK mapping recommended for use with
111
 * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
112
 * 2898.
113
 * @param userPwd [IN] pointer to the struct containing a password
114
 * (octet string between 8 and 63 octets) and optional SSID octet
115
 * string of up to 32 octets (both are usually ASCII but in fact
116
 * opaque and can be any encoding.)
117
 * @param output [OUT] calculated PSK (to use as PMK in WPA)
118
 * @note
119
 * Described in 802.11i-2004, page 165
120
 */
121
static int Dot11DecryptRsnaPwd2Psk(
122
    const struct DOT11DECRYPT_KEY_ITEMDATA_PWD *userPwd,
123
    unsigned char *output)
124
    ;
125
126
static int Dot11DecryptRsnaMng(
127
    unsigned char *decrypt_data,
128
    unsigned mac_header_len,
129
    unsigned *decrypt_len,
130
    PDOT11DECRYPT_KEY_ITEM key,
131
    DOT11DECRYPT_SEC_ASSOCIATION *sa)
132
    ;
133
134
static int Dot11DecryptWepMng(
135
    PDOT11DECRYPT_CONTEXT ctx,
136
    unsigned char *decrypt_data,
137
    unsigned mac_header_len,
138
    unsigned *decrypt_len,
139
    PDOT11DECRYPT_KEY_ITEM key,
140
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
141
    ;
142
143
static int Dot11DecryptRsna4WHandshake(
144
    PDOT11DECRYPT_CONTEXT ctx,
145
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
146
    const uint8_t *eapol_raw,
147
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id,
148
    const unsigned tot_len);
149
150
/**
151
 * It checks whether the specified key is corrected or not.
152
 * @note
153
 * For a standard WEP key the length will be changed to the standard
154
 * length, and the type changed in a generic WEP key.
155
 * @param key [IN] pointer to the key to validate
156
 * @return
157
 * - true: the key contains valid fields and values
158
 * - false: the key has some invalid field or value
159
 */
160
static int Dot11DecryptValidateKey(
161
    PDOT11DECRYPT_KEY_ITEM key)
162
    ;
163
164
static int Dot11DecryptRsnaMicCheck(
165
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
166
    unsigned char *eapol,
167
    unsigned short eapol_len,
168
    unsigned char *KCK,
169
    unsigned short key_ver,
170
    int akm,
171
    int pmk_len)
172
    ;
173
174
static int
175
Dot11DecryptFtMicCheck(
176
    const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed,
177
    const uint8_t *kck,
178
    size_t kck_len);
179
180
static PDOT11DECRYPT_SEC_ASSOCIATION
181
Dot11DecryptGetSa(
182
    PDOT11DECRYPT_CONTEXT ctx,
183
    const DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
184
    ;
185
186
static int Dot11DecryptGetSaAddress(
187
    const uint8_t *mac_header,
188
    unsigned mac_header_len,
189
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
190
    ;
191
192
static const unsigned char * Dot11DecryptGetStaAddress(
193
    const DOT11DECRYPT_MAC_FRAME *frame)
194
    ;
195
196
static const unsigned char * Dot11DecryptGetBssidAddress(
197
    const DOT11DECRYPT_MAC_FRAME *frame)
198
    ;
199
200
static uint8_t
201
Dot11DecryptDerivePtk(
202
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
203
    const unsigned char *pmk,
204
    size_t pmk_len,
205
    const unsigned char snonce[32],
206
    int key_version,
207
    int akm,
208
    int cipher,
209
    uint8_t *ptk, size_t *ptk_len);
210
211
static uint8_t
212
Dot11DecryptFtDerivePtk(
213
    const PDOT11DECRYPT_CONTEXT ctx,
214
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
215
    const PDOT11DECRYPT_KEY_ITEM key,
216
    const uint8_t mdid[2],
217
    const uint8_t *snonce,
218
    const uint8_t *r0kh_id, size_t r0kh_id_len,
219
    const uint8_t *r1kh_id, size_t r1kh_id_len _U_,
220
    int akm, int cipher,
221
    uint8_t *ptk, size_t *ptk_len);
222
223
/**
224
 * @param sa  [IN/OUT] pointer to SA that will hold the key
225
 * @param data [IN] Frame
226
 * @param offset_rsne [IN] RSNE IE offset in the frame
227
 * @param offset_fte [IN] Fast BSS Transition IE offset in the frame
228
 * @param offset_timeout [IN] Timeout Interval IE offset in the frame
229
 * @param offset_link [IN] Link Identifier IE offset in the frame
230
 * @param action [IN] Tdls Action code (response or confirm)
231
 *
232
 * @return
233
 *  DOT11DECRYPT_RET_SUCCESS if Key has been successfully derived (and MIC verified)
234
 *  DOT11DECRYPT_RET_UNSUCCESS otherwise
235
 */
236
static int
237
Dot11DecryptTDLSDeriveKey(
238
    PDOT11DECRYPT_SEC_ASSOCIATION sa,
239
    const uint8_t *data,
240
    unsigned offset_rsne,
241
    unsigned offset_fte,
242
    unsigned offset_timeout,
243
    unsigned offset_link,
244
    uint8_t action)
245
    ;
246
#ifdef  __cplusplus
247
}
248
#endif
249
250
/****************************************************************************/
251
252
/****************************************************************************/
253
/* Exported function definitions                                                */
254
255
#ifdef  __cplusplus
256
extern "C" {
257
#endif
258
259
static const uint8_t broadcast_mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
260
261
0
#define TKIP_GROUP_KEY_LEN 32
262
0
#define CCMP_GROUP_KEY_LEN 16
263
264
0
#define EAPOL_RSN_KEY_LEN 95
265
266
/* Minimum possible key data size (at least one GTK KDE with CCMP key) */
267
0
#define GROUP_KEY_MIN_LEN 8 + CCMP_GROUP_KEY_LEN
268
/* Minimum possible group key msg size (group key msg using CCMP as cipher)*/
269
#define GROUP_KEY_PAYLOAD_LEN_MIN \
270
0
    (EAPOL_RSN_KEY_LEN + GROUP_KEY_MIN_LEN)
271
272
static void
273
Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa, PDOT11DECRYPT_KEY_ITEM key)
274
0
{
275
0
    if (key!=NULL) {
276
0
        if (sa->key!=NULL)
277
0
            memcpy(key, sa->key, sizeof(DOT11DECRYPT_KEY_ITEM));
278
0
        else
279
0
            memset(key, 0, sizeof(DOT11DECRYPT_KEY_ITEM));
280
0
        key->KeyData.Wpa.PtkLen = sa->wpa.ptk_len;
281
0
        memcpy(key->KeyData.Wpa.Ptk, sa->wpa.ptk, sa->wpa.ptk_len);
282
0
        key->KeyData.Wpa.Akm = sa->wpa.akm;
283
0
        key->KeyData.Wpa.Cipher = sa->wpa.cipher;
284
0
        if (sa->wpa.key_ver==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP)
285
0
            key->KeyType=DOT11DECRYPT_KEY_TYPE_TKIP;
286
0
        else if (sa->wpa.key_ver == 0 || sa->wpa.key_ver == 3 ||
287
0
                 sa->wpa.key_ver == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP)
288
0
        {
289
0
            switch (sa->wpa.cipher) {
290
0
                case 1:
291
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_WEP_40;
292
0
                    break;
293
0
                case 2:
294
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_TKIP;
295
0
                    break;
296
0
                case 4:
297
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_CCMP;
298
0
                    break;
299
0
                case 5:
300
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_WEP_104;
301
0
                    break;
302
0
                case 8:
303
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_GCMP;
304
0
                    break;
305
0
                case 9:
306
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_GCMP_256;
307
0
                    break;
308
0
                case 10:
309
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_CCMP_256;
310
0
                    break;
311
0
                default:
312
0
                    key->KeyType = DOT11DECRYPT_KEY_TYPE_UNKNOWN;
313
0
                    break;
314
                /* NOT SUPPORTED YET
315
                case 3:  Reserved
316
                case 6:  BIP-CMAC-128
317
                case 7:  Group addressed traffic not allowed
318
                case 11: BIP-GMAC-128
319
                case 12: BIP-GMAC-256
320
                case 13: BIP-CMAC-256 */
321
0
            }
322
0
        }
323
0
    }
324
0
}
325
326
static uint8_t*
327
Dot11DecryptRc4KeyData(const uint8_t *decryption_key, unsigned decryption_key_len,
328
                       const uint8_t *encrypted_keydata, unsigned encrypted_keydata_len)
329
0
{
330
0
    gcry_cipher_hd_t  rc4_handle;
331
0
    uint8_t dummy[256] = { 0 };
332
0
    uint8_t *decrypted_key = NULL;
333
334
0
    if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) {
335
0
        return NULL;
336
0
    }
337
0
    if (gcry_cipher_setkey(rc4_handle, decryption_key, decryption_key_len)) {
338
0
        gcry_cipher_close(rc4_handle);
339
0
        return NULL;
340
0
    }
341
0
    decrypted_key = (uint8_t *)g_memdup2(encrypted_keydata, encrypted_keydata_len);
342
0
    if (!decrypted_key) {
343
0
        gcry_cipher_close(rc4_handle);
344
0
        return NULL;
345
0
    }
346
347
    /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
348
0
    gcry_cipher_decrypt(rc4_handle, dummy, 256, NULL, 0);
349
0
    gcry_cipher_decrypt(rc4_handle, decrypted_key, encrypted_keydata_len, NULL, 0);
350
0
    gcry_cipher_close(rc4_handle);
351
0
    return decrypted_key;
352
0
}
353
354
static int
355
AES_unwrap(
356
    const uint8_t *kek,
357
    uint16_t kek_len,
358
    const uint8_t *cipher_text,
359
    uint16_t cipher_len,
360
    uint8_t *output,
361
    uint16_t *output_len)
362
0
{
363
0
    gcry_cipher_hd_t handle;
364
365
0
    if (kek == NULL || cipher_len < 16 || cipher_text == NULL) {
366
0
        return 1; /* "should not happen" */
367
0
    }
368
0
    if (gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_AESWRAP, 0)) {
369
0
        return 1;
370
0
    }
371
0
    if (gcry_cipher_setkey(handle, kek, kek_len)) {
372
0
        gcry_cipher_close(handle);
373
0
        return 1;
374
0
    }
375
0
    if (gcry_cipher_decrypt(handle, output, cipher_len - 8, cipher_text, cipher_len)) {
376
0
        gcry_cipher_close(handle);
377
0
        return 1;
378
0
    }
379
0
    *output_len = cipher_len - 8;
380
0
    gcry_cipher_close(handle);
381
0
    return 0;
382
0
}
383
384
int
385
Dot11DecryptDecryptKeyData(PDOT11DECRYPT_CONTEXT ctx,
386
                           PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
387
                           const unsigned char bssid[DOT11DECRYPT_MAC_LEN],
388
                           const unsigned char sta[DOT11DECRYPT_MAC_LEN],
389
                           unsigned char *decrypted_data, unsigned *decrypted_len,
390
                           PDOT11DECRYPT_KEY_ITEM key)
391
0
{
392
0
    uint8_t key_version;
393
0
    const uint8_t *key_data;
394
0
    uint16_t key_bytes_len = 0; /* Length of the total key data field */
395
0
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
396
0
    PDOT11DECRYPT_SEC_ASSOCIATION sa;
397
398
    /* search for a cached Security Association for current BSSID and AP */
399
0
    memcpy(id.bssid, bssid, DOT11DECRYPT_MAC_LEN);
400
0
    memcpy(id.sta, sta, DOT11DECRYPT_MAC_LEN);
401
0
    sa = Dot11DecryptGetSa(ctx, &id);
402
0
    if (sa == NULL || !sa->validKey) {
403
0
        ws_debug("No valid SA for BSSID found");
404
0
        return DOT11DECRYPT_RET_UNSUCCESS;
405
0
    }
406
407
    /* Decrypt GTK using KEK portion of PTK */
408
0
    uint8_t *decryption_key = DOT11DECRYPT_GET_KEK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8);
409
0
    unsigned decryption_key_len = Dot11DecryptGetKekLen(sa->wpa.akm, sa->wpa.pmk_len * 8) / 8;
410
411
    /* We skip verifying the MIC of the key. If we were implementing a WPA supplicant we'd want to verify, but for a sniffer it's not needed. */
412
413
    /* Preparation for decrypting the group key -  determine group key data length */
414
    /* depending on whether the pairwise key is TKIP or AES encryption key */
415
0
    key_version = eapol_parsed->key_version;
416
0
    if (key_version == DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP){
417
        /* TKIP */
418
0
        key_bytes_len = eapol_parsed->key_len;
419
0
    }else if (key_version == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP){
420
        /* AES */
421
0
        key_bytes_len = eapol_parsed->key_data_len;
422
423
        /* AES keys must be at least 128 bits = 16 bytes. */
424
0
        if (key_bytes_len < 16) {
425
0
            return DOT11DECRYPT_RET_UNSUCCESS;
426
0
        }
427
0
    } else {
428
        /* XXX Ideally group cipher suite type from EAPOL message 2 of 4 should be used to  */
429
        /* determine key size. As we currently have no way to do this lookup check that key */
430
        /* is at least 16 bytes (IEEE802.11-2024 Table 12-8 Cipher suite key lengths)       */
431
0
        key_bytes_len = eapol_parsed->key_data_len;
432
433
0
        if (key_bytes_len < 16) {
434
0
            return DOT11DECRYPT_RET_UNSUCCESS;
435
0
        }
436
0
    }
437
438
0
    if (key_bytes_len > *decrypted_len) {
439
0
        ws_debug("Too large EAPOL key data");
440
0
        return DOT11DECRYPT_RET_UNSUCCESS;
441
0
    }
442
443
0
    if ((key_bytes_len < GROUP_KEY_MIN_LEN) ||
444
0
        (eapol_parsed->len < EAPOL_RSN_KEY_LEN) ||
445
0
        (key_bytes_len > eapol_parsed->len - EAPOL_RSN_KEY_LEN)) {
446
0
        return DOT11DECRYPT_RET_UNSUCCESS;
447
0
    }
448
449
    /* Encrypted key is in the information element field of the EAPOL key packet */
450
0
    key_data = eapol_parsed->key_data;
451
452
0
    DEBUG_DUMP("Encrypted Broadcast key", key_data, key_bytes_len, LOG_LEVEL_DEBUG);
453
0
    DEBUG_DUMP("KeyIV", eapol_parsed->key_iv, 16, LOG_LEVEL_DEBUG);
454
0
    DEBUG_DUMP("decryption_key", decryption_key, decryption_key_len, LOG_LEVEL_DEBUG);
455
456
    /* As we have no concept of the prior association request at this point, we need to deduce the     */
457
    /* group key cipher from the length of the key bytes. In WPA this is straightforward as the        */
458
    /* keybytes just contain the GTK, and the GTK is only in the group handshake, NOT the M3.          */
459
    /* In WPA2 its a little more tricky as the M3 keybytes contain an RSN_IE, but the group handshake  */
460
    /* does not. Also there are other (variable length) items in the keybytes which we need to account */
461
    /* for to determine the true key length, and thus the group cipher.                                */
462
463
0
    if (key_version == DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP){
464
        /* TKIP key */
465
        /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
466
        /* group key is decrypted using RC4.  Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
467
0
        uint8_t new_key[32];
468
0
        uint8_t *data;
469
470
        /* The WPA group key just contains the GTK bytes so deducing the type is straightforward   */
471
        /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
472
0
        sa->wpa.key_ver = (key_bytes_len >=TKIP_GROUP_KEY_LEN)?DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP:DOT11DECRYPT_WPA_KEY_VER_AES_CCMP;
473
474
        /* Build the full decryption key based on the IV and part of the pairwise key */
475
0
        memcpy(new_key, eapol_parsed->key_iv, 16);
476
0
        memcpy(new_key+16, decryption_key, 16);
477
0
        DEBUG_DUMP("FullDecrKey", new_key, 32, LOG_LEVEL_DEBUG);
478
0
        data = Dot11DecryptRc4KeyData(new_key, 32, key_data, key_bytes_len);
479
0
        if (!data) {
480
0
            return DOT11DECRYPT_RET_UNSUCCESS;
481
0
        }
482
0
        memcpy(decrypted_data, data, key_bytes_len);
483
0
        g_free(data);
484
0
    } else {
485
        /* Ideally AKM from EAPOL message 2 of 4 should be used to determine Key-wrap algorithm to use */
486
        /* Though fortunately IEEE802.11-2024 Table 12-11 state that all AKMs use "NIST AES Key Wrap"  */
487
        /* algorithm so no AKM lookup is needed. */
488
489
        /* Unwrap the key; the result is key_bytes_len in length */
490
0
        if (AES_unwrap(decryption_key, decryption_key_len, key_data, key_bytes_len,
491
0
                       decrypted_data, &key_bytes_len)) {
492
0
            return DOT11DECRYPT_RET_UNSUCCESS;
493
0
        }
494
0
    }
495
496
0
    Dot11DecryptCopyKey(sa, key);
497
0
    *decrypted_len = key_bytes_len;
498
0
    return DOT11DECRYPT_RET_SUCCESS;
499
0
}
500
501
/**
502
 * @param ctx [IN] pointer to the current context
503
 * @param id [IN] id of the association (composed by BSSID and MAC of
504
 * the station)
505
 * @return a pointer of the requested SA. NULL if it doesn't exist.
506
 */
507
static PDOT11DECRYPT_SEC_ASSOCIATION
508
Dot11DecryptGetSa(
509
    PDOT11DECRYPT_CONTEXT ctx,
510
    const DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
511
97
{
512
97
    return (DOT11DECRYPT_SEC_ASSOCIATION *)g_hash_table_lookup(ctx->sa_hash, id);
513
97
}
514
515
static PDOT11DECRYPT_SEC_ASSOCIATION
516
Dot11DecryptNewSa(const DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
517
0
{
518
0
    PDOT11DECRYPT_SEC_ASSOCIATION sa = g_new0(DOT11DECRYPT_SEC_ASSOCIATION, 1);
519
0
    if (sa != NULL) {
520
0
        sa->saId = *id;
521
0
    }
522
0
    return sa;
523
0
}
524
525
static PDOT11DECRYPT_SEC_ASSOCIATION
526
Dot11DecryptDupSa(const DOT11DECRYPT_SEC_ASSOCIATION *sa)
527
0
{
528
0
    PDOT11DECRYPT_SEC_ASSOCIATION new_sa = g_memdup2(sa, sizeof(*sa));
529
0
    if (new_sa != NULL) {
530
0
        new_sa->next = NULL;
531
0
    }
532
0
    return new_sa;
533
0
}
534
535
static DOT11DECRYPT_SEC_ASSOCIATION *
536
Dot11DecryptPrependSa(
537
    DOT11DECRYPT_SEC_ASSOCIATION *existing_sa,
538
    DOT11DECRYPT_SEC_ASSOCIATION *new_sa)
539
0
{
540
0
    DOT11DECRYPT_SEC_ASSOCIATION tmp_sa;
541
542
    /* Add new SA first in list, but copy by value into existing record
543
     * so that sa_hash need not be updated with new value */
544
0
    tmp_sa = *existing_sa;
545
0
    *existing_sa = *new_sa;
546
0
    *new_sa = tmp_sa;
547
0
    existing_sa->next = new_sa;
548
0
    return existing_sa;
549
0
}
550
551
/* Add SA, keep existing (if any). Return pointer to newly inserted (first) SA */
552
static PDOT11DECRYPT_SEC_ASSOCIATION
553
Dot11DecryptAddSa(
554
    PDOT11DECRYPT_CONTEXT ctx,
555
    const DOT11DECRYPT_SEC_ASSOCIATION_ID *id,
556
    DOT11DECRYPT_SEC_ASSOCIATION *sa)
557
0
{
558
0
    DOT11DECRYPT_SEC_ASSOCIATION *existing_sa = Dot11DecryptGetSa(ctx, id);
559
0
    if (existing_sa != NULL) {
560
0
        sa = Dot11DecryptPrependSa(existing_sa, sa);
561
0
    } else {
562
0
        void *key = g_memdup2(id, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID));
563
0
        g_hash_table_insert(ctx->sa_hash, key, sa);
564
0
    }
565
0
    return sa;
566
0
}
567
568
int
569
Dot11DecryptGetKCK(const PDOT11DECRYPT_KEY_ITEM key, const uint8_t **kck)
570
0
{
571
0
    if (!key || !kck) {
572
0
        return 0;
573
0
    }
574
0
    *kck = DOT11DECRYPT_GET_KCK(key->KeyData.Wpa.Ptk, key->KeyData.Wpa.Akm);
575
0
    return Dot11DecryptGetKckLen(key->KeyData.Wpa.Akm, key->KeyData.Wpa.PskLen * 8) / 8;
576
0
}
577
578
int
579
Dot11DecryptGetKEK(const PDOT11DECRYPT_KEY_ITEM key, const uint8_t **kek)
580
0
{
581
0
    if (!key || !kek) {
582
0
        return 0;
583
0
    }
584
0
    *kek = DOT11DECRYPT_GET_KEK(key->KeyData.Wpa.Ptk, key->KeyData.Wpa.Akm, key->KeyData.Wpa.PskLen * 8);
585
0
    return Dot11DecryptGetKekLen(key->KeyData.Wpa.Akm, key->KeyData.Wpa.PskLen * 8) / 8;
586
0
}
587
588
int
589
Dot11DecryptGetTK(const PDOT11DECRYPT_KEY_ITEM key, const uint8_t **tk)
590
0
{
591
0
    int len;
592
0
    if (!key || !tk) {
593
0
        return 0;
594
0
    }
595
0
    if (key->KeyType == DOT11DECRYPT_KEY_TYPE_TKIP) {
596
0
        *tk = DOT11DECRYPT_GET_TK_TKIP(key->KeyData.Wpa.Ptk);
597
0
        len = 16;
598
0
    } else {
599
0
        *tk = DOT11DECRYPT_GET_TK(key->KeyData.Wpa.Ptk, key->KeyData.Wpa.Akm, key->KeyData.Wpa.PskLen * 8);
600
0
        len = Dot11DecryptGetTkLen(key->KeyData.Wpa.Cipher) / 8;
601
0
    }
602
0
    return len;
603
0
}
604
605
int
606
Dot11DecryptGetGTK(const PDOT11DECRYPT_KEY_ITEM key, const uint8_t **gtk)
607
0
{
608
0
    int len;
609
0
    if (!key || !gtk) {
610
0
        return 0;
611
0
    }
612
613
    /* GTK is stored just as PTK. See comment in Dot11DecryptCopyBroadcastKey */
614
0
    *gtk = DOT11DECRYPT_GET_TK(key->KeyData.Wpa.Ptk, key->KeyData.Wpa.Akm, key->KeyData.Wpa.PskLen);
615
0
    if (key->KeyType == DOT11DECRYPT_KEY_TYPE_TKIP) {
616
0
        len = 16;
617
0
    } else {
618
0
        len = Dot11DecryptGetTkLen(key->KeyData.Wpa.Cipher) / 8;
619
0
    }
620
0
    return len;
621
0
}
622
623
int Dot11DecryptScanTdlsForKeys(
624
    PDOT11DECRYPT_CONTEXT ctx,
625
    const uint8_t *data,
626
    const unsigned tot_len)
627
27
{
628
27
    unsigned offset = 0;
629
27
    unsigned tot_len_left = tot_len;
630
27
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
631
27
    PDOT11DECRYPT_SEC_ASSOCIATION sa;
632
27
    const uint8_t *initiator, *responder;
633
27
    uint8_t action;
634
27
    unsigned status, offset_rsne = 0, offset_fte = 0, offset_link = 0, offset_timeout = 0;
635
27
    ws_debug("Authentication: TDLS Action Frame");
636
637
    /* TDLS payload contains a TDLS Action field (802.11-2016 9.6.13) */
638
639
    /* check if the packet is a TDLS response or confirm */
640
27
    if (tot_len_left < 1) {
641
0
        ws_debug("Not EAPOL-Key");
642
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
643
0
    }
644
27
    action = data[offset];
645
27
    if (action != 1 && action != 2) {
646
8
        ws_debug("Not Response nor confirm");
647
8
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
648
8
    }
649
19
    offset++;
650
19
    tot_len_left--;
651
652
    /* Check for SUCCESS (0) or SUCCESS_POWER_SAVE_MODE (85) Status Code */
653
19
    if (tot_len_left < 5) {
654
1
        ws_debug("Not EAPOL-Key");
655
1
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
656
1
    }
657
18
    status=pntohu16(data + offset);
658
18
    if (status != 0 && status != 85) {
659
1
        ws_debug("TDLS setup not successful");
660
1
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
661
1
    }
662
663
    /* skip Token + capabilities */
664
17
    offset += 5;
665
666
    /* search for RSN, Fast BSS Transition, Link Identifier and Timeout Interval IEs */
667
668
354
    while(offset < (tot_len - 2)) {
669
353
        uint8_t element_id = data[offset];
670
353
        uint8_t length = data[offset + 1];
671
353
        unsigned min_length = length;
672
353
        switch (element_id) {
673
3
        case 48:    /* RSN (802.11-2016 9.4.2.35) */
674
3
            offset_rsne = offset;
675
3
            min_length = 1;
676
3
            break;
677
4
        case 55:    /* FTE (802.11-2016 9.4.2.48) */
678
4
            offset_fte = offset;
679
            /* Plus variable length optional parameter(s) */
680
4
            min_length = 2 + 16 + 32 + 32;
681
4
            break;
682
3
        case 56:    /* Timeout Interval (802.11-2016 9.4.2.49) */
683
3
            offset_timeout = offset;
684
3
            min_length = 1 + 4;
685
3
            break;
686
1
        case 101:   /* Link Identifier (802.11-2016 9.4.2.62) */
687
1
            offset_link = offset;
688
1
            min_length = 6 + 6 + 6;
689
1
            break;
690
353
        }
691
692
353
        if (length < min_length || tot_len < offset + 2 + length) {
693
16
            ws_debug("Invalid length records in IEs");
694
16
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
695
16
        }
696
337
        offset += 2 + length;
697
337
    }
698
699
1
    if (offset_rsne == 0 || offset_fte == 0 ||
700
0
        offset_timeout == 0 || offset_link == 0)
701
1
    {
702
1
        ws_debug("Cannot Find all necessary IEs");
703
1
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
704
1
    }
705
706
0
    ws_debug("Found RSNE/Fast BSS/Timeout Interval/Link IEs");
707
708
    /* Will create a Security Association between 2 STA. Need to get both MAC address */
709
0
    initiator = &data[offset_link + 8];
710
0
    responder = &data[offset_link + 14];
711
712
0
    if (memcmp(initiator, responder, DOT11DECRYPT_MAC_LEN) < 0) {
713
0
        memcpy(id.sta, initiator, DOT11DECRYPT_MAC_LEN);
714
0
        memcpy(id.bssid, responder, DOT11DECRYPT_MAC_LEN);
715
0
    } else {
716
0
        memcpy(id.sta, responder, DOT11DECRYPT_MAC_LEN);
717
0
        memcpy(id.bssid, initiator, DOT11DECRYPT_MAC_LEN);
718
0
    }
719
720
    /* Check if already derived this key */
721
0
    sa = Dot11DecryptGetSa(ctx, &id);
722
0
    PDOT11DECRYPT_SEC_ASSOCIATION iter_sa;
723
0
    for (iter_sa = sa; iter_sa != NULL; iter_sa = iter_sa->next) {
724
0
        if (iter_sa->validKey &&
725
0
            memcmp(iter_sa->wpa.nonce, data + offset_fte + 52,
726
0
                   DOT11DECRYPT_WPA_NONCE_LEN) == 0)
727
0
        {
728
            /* Already have valid key for this SA, no need to redo key derivation */
729
0
            return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
730
0
        }
731
0
    }
732
    /* We are opening a new session with the same two STA (previous sa will be kept if any) */
733
0
    sa = Dot11DecryptNewSa(&id);
734
0
    if (sa == NULL) {
735
0
        ws_warning("Failed to alloc new SA entry");
736
0
        return DOT11DECRYPT_RET_REQ_DATA;
737
0
    }
738
0
    if (Dot11DecryptTDLSDeriveKey(sa, data, offset_rsne, offset_fte,
739
0
            offset_timeout, offset_link, action) == DOT11DECRYPT_RET_SUCCESS) {
740
0
        Dot11DecryptAddSa(ctx, &id, sa);
741
0
        return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
742
0
    }
743
0
    g_free(sa);
744
0
    return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
745
0
}
746
747
static int
748
Dot11DecryptCopyBroadcastKey(
749
    PDOT11DECRYPT_CONTEXT ctx,
750
    const uint8_t *gtk, size_t gtk_len,
751
    const DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
752
0
{
753
0
    DOT11DECRYPT_SEC_ASSOCIATION_ID broadcast_id;
754
0
    DOT11DECRYPT_SEC_ASSOCIATION *sa;
755
0
    DOT11DECRYPT_SEC_ASSOCIATION *broadcast_sa;
756
0
    int tk_len;
757
758
0
    if (!gtk || gtk_len == 0) {
759
0
        ws_debug("No broadcast key found");
760
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
761
0
    }
762
0
    sa = Dot11DecryptGetSa(ctx, id);
763
0
    if (sa == NULL) {
764
0
        ws_debug("No SA for BSSID found");
765
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
766
0
    }
767
768
0
    tk_len = Dot11DecryptGetTkLen(sa->wpa.tmp_group_cipher);
769
0
    if (tk_len < 0 || gtk_len !=  (size_t)tk_len / 8) {
770
0
        ws_debug("Broadcast key with incorrect length");
771
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
772
0
    }
773
774
    /* Broadcast SA for the current BSSID */
775
0
    memcpy(broadcast_id.bssid, id->bssid, DOT11DECRYPT_MAC_LEN);
776
0
    memcpy(broadcast_id.sta, broadcast_mac, DOT11DECRYPT_MAC_LEN);
777
778
0
    broadcast_sa = Dot11DecryptNewSa(&broadcast_id);
779
0
    if (broadcast_sa == NULL) {
780
0
        ws_warning("Failed to alloc broadcast sa");
781
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
782
0
    }
783
784
    /* Retrieve AKMS / cipher etc from handshake message 2 */
785
786
0
    broadcast_sa->wpa.key_ver = sa->wpa.key_ver;
787
0
    broadcast_sa->wpa.akm = sa->wpa.akm;
788
0
    broadcast_sa->wpa.cipher = sa->wpa.tmp_group_cipher;
789
0
    broadcast_sa->wpa.ptk_len = sa->wpa.ptk_len;
790
0
    broadcast_sa->validKey = true;
791
0
    DEBUG_DUMP("Broadcast key", gtk, gtk_len, LOG_LEVEL_DEBUG);
792
793
    /* Since this is a GTK we fake it and put it just as PTK so the
794
     * Dot11DecryptRsnaMng() function will extract the right piece of
795
     * the GTK for decryption. */
796
0
    memset(broadcast_sa->wpa.ptk, 0, sizeof(broadcast_sa->wpa.ptk));
797
0
    memcpy(DOT11DECRYPT_GET_TK(broadcast_sa->wpa.ptk, broadcast_sa->wpa.akm,
798
0
                               broadcast_sa->wpa.pmk_len * 8), gtk, gtk_len);
799
0
    Dot11DecryptAddSa(ctx, &broadcast_id, broadcast_sa);
800
0
    return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
801
0
}
802
803
static void Dot11DecryptCreateMloGtkSa(
804
    PDOT11DECRYPT_CONTEXT ctx,
805
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
806
    DOT11DECRYPT_SEC_ASSOCIATION *ptk_sa
807
)
808
0
{
809
0
    if (ptk_sa == NULL || !ptk_sa->validKey || !ptk_sa->wpa.mld) {
810
0
        return;
811
0
    }
812
0
    for (int i = 0; i < eapol_parsed->mlo_gtk_count; ++i) {
813
0
        struct DOT11DECRYPT_EAPOL_PARSED_MLO_GTK *gtk = &eapol_parsed->mlo_gtk[i];
814
815
0
        for (struct DOT11DECRYPT_MLO_LINK_INFO *link = ptk_sa->wpa.mlo_links;
816
0
             link < &ptk_sa->wpa.mlo_links[DOT11DECRYPT_MAX_MLO_LINKS];
817
0
             ++link) {
818
0
            if (!(link->id_set && link->ap_mac_set && link->sta_mac_set))
819
0
                continue;
820
0
            if (link->id == gtk->link_id) {
821
0
                DOT11DECRYPT_SEC_ASSOCIATION_ID saId;
822
0
                memcpy(&saId.bssid, link->ap_mac, DOT11DECRYPT_MAC_LEN);
823
0
                memcpy(&saId.sta, link->sta_mac, DOT11DECRYPT_MAC_LEN);
824
0
                ws_debug("Create GTKSA for LinkID %d", link->id);
825
0
                Dot11DecryptCopyBroadcastKey(ctx, gtk->key, gtk->len, &saId);
826
0
            }
827
0
        }
828
0
    }
829
0
}
830
831
static int
832
Dot11DecryptGroupHandshake(
833
    PDOT11DECRYPT_CONTEXT ctx,
834
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
835
    const DOT11DECRYPT_SEC_ASSOCIATION_ID *id,
836
    const unsigned tot_len)
837
0
{
838
839
0
    if (GROUP_KEY_PAYLOAD_LEN_MIN > tot_len) {
840
0
        ws_debug("Message too short for Group Key");
841
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
842
0
    }
843
0
    if (eapol_parsed->msg_type != DOT11DECRYPT_HS_MSG_TYPE_GHS_1){
844
0
        ws_warning("Not Group handshake message 1");
845
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
846
0
    }
847
848
0
    Dot11DecryptCopyBroadcastKey(ctx, eapol_parsed->gtk, eapol_parsed->gtk_len, id);
849
850
0
    Dot11DecryptCreateMloGtkSa(ctx, eapol_parsed, Dot11DecryptGetSa(ctx, id));
851
852
0
    return DOT11DECRYPT_RET_SUCCESS;
853
0
}
854
855
int Dot11DecryptScanEapolForKeys(
856
    PDOT11DECRYPT_CONTEXT ctx,
857
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
858
    const uint8_t *eapol_raw,
859
    const unsigned tot_len,
860
    const unsigned char bssid[DOT11DECRYPT_MAC_LEN],
861
    const unsigned char sta[DOT11DECRYPT_MAC_LEN])
862
0
{
863
0
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
864
865
    /* Callers provide these guarantees, so let's make them explicit. */
866
0
    DISSECTOR_ASSERT(tot_len <= DOT11DECRYPT_EAPOL_MAX_LEN);
867
868
0
    ws_debug("Authentication: EAPOL packet");
869
870
    /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
871
0
    if (/*eapol_parsed->key_type != 0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
872
0
        eapol_parsed->key_type != DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR &&  /* IEEE 802.11 Key Descriptor Type  (WPA2) */
873
0
        eapol_parsed->key_type != DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR)     /* 254 = RSN_KEY_DESCRIPTOR - WPA,         */
874
0
    {
875
0
        ws_debug("Not valid key descriptor type");
876
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
877
0
    }
878
879
    /* search for a cached Security Association for current BSSID and AP */
880
0
    memcpy(id.bssid, bssid, DOT11DECRYPT_MAC_LEN);
881
0
    memcpy(id.sta, sta, DOT11DECRYPT_MAC_LEN);
882
883
0
    switch (eapol_parsed->msg_type) {
884
0
        case DOT11DECRYPT_HS_MSG_TYPE_4WHS_1:
885
0
        case DOT11DECRYPT_HS_MSG_TYPE_4WHS_2:
886
0
        case DOT11DECRYPT_HS_MSG_TYPE_4WHS_3:
887
0
        case DOT11DECRYPT_HS_MSG_TYPE_4WHS_4:
888
0
            return Dot11DecryptRsna4WHandshake(ctx, eapol_parsed, eapol_raw,
889
0
                                               &id, tot_len);
890
0
        case DOT11DECRYPT_HS_MSG_TYPE_GHS_1:
891
0
            return Dot11DecryptGroupHandshake(ctx, eapol_parsed, &id, tot_len);
892
0
        case DOT11DECRYPT_HS_MSG_TYPE_GHS_2:
893
0
            break;
894
0
        case DOT11DECRYPT_HS_MSG_TYPE_INVALID:
895
0
        default:
896
0
            ws_warning("Invalid message type");
897
0
            break;
898
0
    }
899
0
    return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
900
0
}
901
902
static int
903
Dot11DecryptGetNbrOfTkKeys(PDOT11DECRYPT_CONTEXT ctx)
904
44
{
905
44
    int nbr = 0;
906
44
    for (size_t i = 0; i < ctx->keys_nr; i++) {
907
0
        if (ctx->keys[i].KeyType == DOT11DECRYPT_KEY_TYPE_TK) {
908
0
            nbr++;
909
0
        }
910
0
    }
911
44
    return nbr;
912
44
}
913
914
static int
915
Dot11DecryptUsingUserTk(
916
    PDOT11DECRYPT_CONTEXT ctx,
917
    unsigned char *decrypt_data,
918
    unsigned mac_header_len,
919
    unsigned *decrypt_len,
920
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id,
921
    DOT11DECRYPT_KEY_ITEM *used_key)
922
0
{
923
0
    int ret = DOT11DECRYPT_RET_REQ_DATA;
924
0
    DOT11DECRYPT_SEC_ASSOCIATION *sa = Dot11DecryptNewSa(id);
925
0
    DOT11DECRYPT_KEY_ITEM *key;
926
0
    if (sa == NULL) {
927
0
        return ret;
928
0
    }
929
930
0
    sa->wpa.akm = 2;
931
0
    sa->validKey = true;
932
933
    /* Try decrypt packet with all user TKs applicable ciphers */
934
0
    for (size_t key_index = 0; key_index < ctx->keys_nr; key_index++) {
935
0
        key = &ctx->keys[key_index];
936
0
        if (key->KeyType != DOT11DECRYPT_KEY_TYPE_TK) {
937
0
            continue;
938
0
        }
939
0
        int ciphers_to_try[4] = { 0 };
940
0
        switch (key->Tk.Len) {
941
0
            case DOT11DECRYPT_WEP_40_KEY_LEN:
942
0
            case DOT11DECRYPT_WEP_104_KEY_LEN:
943
                /* TBD implement */
944
0
                continue;
945
0
            case 256 / 8:
946
0
                ciphers_to_try[0] = 9; /* GCMP-256 */
947
0
                ciphers_to_try[1] = 10; /* CCMP-256 */
948
0
                break;
949
0
            case 128 / 8:
950
0
                ciphers_to_try[0] = 4; /* CCMP-128 */
951
0
                ciphers_to_try[1] = 8; /* GCMP-128 */
952
                /* MLO does not allow TKIP */
953
0
                if (!key->Tk.mld)
954
0
                    ciphers_to_try[2] = 2; /* TKIP */
955
0
                break;
956
0
            default:
957
0
                continue;
958
0
        }
959
960
0
        sa->key = key;
961
962
0
        for (int i = 0; ciphers_to_try[i] != 0; i++) {
963
0
            sa->wpa.cipher = ciphers_to_try[i];
964
0
            if (sa->wpa.cipher == DOT11DECRYPT_CIPHER_TKIP) {
965
0
                sa->wpa.key_ver = 1;
966
0
                memcpy(DOT11DECRYPT_GET_TK_TKIP(sa->wpa.ptk),
967
0
                       key->Tk.Tk, key->Tk.Len);
968
0
            } else {
969
0
                sa->wpa.key_ver = 2;
970
0
                sa->wpa.akm = 2;
971
0
                memcpy(DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
972
0
                       key->Tk.Tk, key->Tk.Len);
973
0
                sa->wpa.mld = key->Tk.mld;
974
0
                if (key->Tk.mld) {
975
0
                    memcpy(sa->wpa.ap_mld_mac, key->Tk.ap_mld_mac, DOT11DECRYPT_MAC_LEN);
976
0
                    memcpy(sa->wpa.sta_mld_mac, key->Tk.sta_mld_mac, DOT11DECRYPT_MAC_LEN);
977
0
                }
978
0
            }
979
0
            sa->wpa.ptk_len = Dot11DecryptGetPtkLen(sa->wpa.akm, sa->wpa.cipher, sa->wpa.pmk_len * 8) / 8;
980
0
            ret = Dot11DecryptRsnaMng(decrypt_data, mac_header_len, decrypt_len, used_key, sa);
981
0
            if (ret == DOT11DECRYPT_RET_SUCCESS) {
982
                /* Successfully decrypted using user TK. Add SA formed from user TK so that
983
                 * subsequent frames can be decrypted much faster using normal code path
984
                 * without trying each and every user TK entered.
985
                 */
986
0
                Dot11DecryptAddSa(ctx, id, sa);
987
0
                return ret;
988
0
            }
989
0
        }
990
0
    }
991
0
    g_free(sa);
992
0
    return ret;
993
0
}
994
995
int Dot11DecryptDecryptPacket(
996
    PDOT11DECRYPT_CONTEXT ctx,
997
    const uint8_t *data,
998
    const unsigned mac_header_len,
999
    const unsigned tot_len,
1000
    unsigned char *decrypt_data,
1001
    unsigned *decrypt_len,
1002
    PDOT11DECRYPT_KEY_ITEM key)
1003
133
{
1004
133
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
1005
133
    DISSECTOR_ASSERT(decrypt_data);
1006
133
    DISSECTOR_ASSERT(decrypt_len);
1007
1008
133
    if (decrypt_len) {
1009
133
        *decrypt_len = 0;
1010
133
    }
1011
133
    if (ctx==NULL) {
1012
0
        ws_warning("NULL context");
1013
0
        return DOT11DECRYPT_RET_REQ_DATA;
1014
0
    }
1015
133
    if (data==NULL || tot_len==0) {
1016
0
        ws_debug("NULL data or length=0");
1017
0
        return DOT11DECRYPT_RET_REQ_DATA;
1018
0
    }
1019
1020
    /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
1021
133
    if (tot_len < (unsigned)(mac_header_len+DOT11DECRYPT_CRYPTED_DATA_MINLEN)) {
1022
16
        ws_debug("minimum length violated");
1023
16
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
1024
16
    }
1025
1026
    /* Assume that the decrypt_data field is no more than this size. */
1027
117
    if (tot_len > DOT11DECRYPT_MAX_CAPLEN) {
1028
0
        ws_debug("length too large");
1029
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1030
0
    }
1031
1032
    /* get STA/BSSID address */
1033
117
    if (Dot11DecryptGetSaAddress(data, mac_header_len, &id) != DOT11DECRYPT_RET_SUCCESS) {
1034
20
        ws_noisy("STA/BSSID not found");
1035
20
        return DOT11DECRYPT_RET_REQ_DATA;
1036
20
    }
1037
1038
    /* check if data is encrypted (use the WEP bit in the Frame Control field) */
1039
97
    if (DOT11DECRYPT_WEP(data[1])==0) {
1040
0
        return DOT11DECRYPT_RET_NO_DATA_ENCRYPTED;
1041
0
    }
1042
97
    PDOT11DECRYPT_SEC_ASSOCIATION sa;
1043
1044
    /* create new header and data to modify */
1045
97
    *decrypt_len = tot_len;
1046
97
    memcpy(decrypt_data, data, *decrypt_len);
1047
1048
    /* encrypted data */
1049
97
    ws_noisy("Encrypted data");
1050
1051
    /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
1052
    /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP,    */
1053
    /*          IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP,  */
1054
    /*          IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP   */
1055
97
    if (DOT11DECRYPT_EXTIV(data[mac_header_len + 3]) == 0) {
1056
53
        ws_noisy("WEP encryption");
1057
53
        return Dot11DecryptWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, &id);
1058
53
    } else {
1059
44
        ws_noisy("TKIP or CCMP encryption");
1060
1061
        /* If the destination is a multicast address use the group key. This will not work if the AP is using
1062
            more than one group key simultaneously.  I've not seen this in practice, however.
1063
            Usually an AP will rotate between the two key index values of 1 and 2 whenever
1064
            it needs to change the group key to be used. */
1065
44
        if (((const DOT11DECRYPT_MAC_FRAME_ADDR4 *)(data))->addr1[0] & 0x01) {
1066
23
            ws_noisy("Broadcast/Multicast address. This is encrypted with a group key.");
1067
1068
            /* force STA address to broadcast MAC so we load the SA for the groupkey */
1069
23
            memcpy(id.sta, broadcast_mac, DOT11DECRYPT_MAC_LEN);
1070
23
        }
1071
        /* search for a cached Security Association for current BSSID and STA/broadcast MAC */
1072
44
        int ret = DOT11DECRYPT_RET_REQ_DATA;
1073
44
        sa = Dot11DecryptGetSa(ctx, &id);
1074
44
        if (sa != NULL) {
1075
            /* Decrypt the packet using the appropriate SA */
1076
0
            ret = Dot11DecryptRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa);
1077
0
        }
1078
44
        if (ret != DOT11DECRYPT_RET_SUCCESS && Dot11DecryptGetNbrOfTkKeys(ctx) > 0) {
1079
            /* Decryption with known SAs failed. Try decrypt with TK user entries */
1080
0
            ret = Dot11DecryptUsingUserTk(ctx, decrypt_data, mac_header_len, decrypt_len, &id, key);
1081
0
        }
1082
44
        return ret;
1083
44
     }
1084
0
    return DOT11DECRYPT_RET_UNSUCCESS;
1085
97
}
1086
1087
int Dot11DecryptSetKeys(
1088
    PDOT11DECRYPT_CONTEXT ctx,
1089
    DOT11DECRYPT_KEY_ITEM keys[],
1090
    const size_t keys_nr)
1091
32
{
1092
32
    int i;
1093
32
    int success;
1094
1095
32
    if (ctx==NULL || keys==NULL) {
1096
0
        ws_warning("NULL context or NULL keys array");
1097
0
        return 0;
1098
0
    }
1099
1100
32
    if (keys_nr>DOT11DECRYPT_MAX_KEYS_NR) {
1101
0
        ws_warning("Keys number greater than maximum");
1102
0
        return 0;
1103
0
    }
1104
1105
    /* clean key and SA collections before setting new ones */
1106
32
    Dot11DecryptInitContext(ctx);
1107
1108
    /* check and insert keys */
1109
32
    for (i=0, success=0; i<(int)keys_nr; i++) {
1110
0
        if (Dot11DecryptValidateKey(keys+i)==true) {
1111
0
            if (keys[i].KeyType==DOT11DECRYPT_KEY_TYPE_WPA_PWD && keys[i].UserPwd.SsidLen > 0) {
1112
0
                Dot11DecryptRsnaPwd2Psk(&keys[i].UserPwd, keys[i].KeyData.Wpa.Psk);
1113
0
                keys[i].KeyData.Wpa.PskLen = DOT11DECRYPT_WPA_PWD_PSK_LEN;
1114
0
            }
1115
0
            memcpy(&ctx->keys[success], &keys[i], sizeof(keys[i]));
1116
0
            success++;
1117
0
        }
1118
0
    }
1119
1120
32
    ctx->keys_nr=success;
1121
32
    return success;
1122
32
}
1123
1124
static void
1125
Dot11DecryptCleanKeys(
1126
    PDOT11DECRYPT_CONTEXT ctx)
1127
32
{
1128
32
    if (ctx==NULL) {
1129
0
        ws_warning("NULL context");
1130
0
        return;
1131
0
    }
1132
1133
32
    memset(ctx->keys, 0, sizeof(DOT11DECRYPT_KEY_ITEM) * DOT11DECRYPT_MAX_KEYS_NR);
1134
1135
32
    ctx->keys_nr=0;
1136
32
    ws_debug("Keys collection cleaned!");
1137
32
}
1138
1139
static void
1140
Dot11DecryptCleanSA(
1141
    void * first_sa)
1142
0
{
1143
0
    DOT11DECRYPT_SEC_ASSOCIATION *cur_sa = (DOT11DECRYPT_SEC_ASSOCIATION *)first_sa;
1144
0
    while (cur_sa) {
1145
0
        DOT11DECRYPT_SEC_ASSOCIATION *next_sa = cur_sa->next;
1146
0
        g_free(cur_sa);
1147
0
        cur_sa = next_sa;
1148
0
    }
1149
0
}
1150
1151
static void
1152
Dot11DecryptCleanSecAssoc(
1153
    PDOT11DECRYPT_CONTEXT ctx)
1154
32
{
1155
32
    if (ctx->sa_hash != NULL) {
1156
16
        g_hash_table_destroy(ctx->sa_hash);
1157
16
        ctx->sa_hash = NULL;
1158
16
    }
1159
32
}
1160
1161
/*
1162
 * XXX - This won't be reliable if a packet containing SSID "B" shows
1163
 * up in the middle of a 4-way handshake for SSID "A".
1164
 * We should probably use a small array or hash table to keep multiple
1165
 * SSIDs.
1166
 */
1167
int Dot11DecryptSetLastSSID(
1168
    PDOT11DECRYPT_CONTEXT ctx,
1169
    char *pkt_ssid,
1170
    size_t pkt_ssid_len)
1171
1.56k
{
1172
1.56k
    if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
1173
1.37k
        return DOT11DECRYPT_RET_UNSUCCESS;
1174
1175
186
    memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
1176
186
    ctx->pkt_ssid_len = pkt_ssid_len;
1177
1178
186
    return DOT11DECRYPT_RET_SUCCESS;
1179
1.56k
}
1180
1181
static unsigned
1182
Dot11DecryptSaHash(const void *key)
1183
97
{
1184
97
    GBytes *bytes = g_bytes_new_static(key, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID));
1185
97
    unsigned hash = g_bytes_hash(bytes);
1186
97
    g_bytes_unref(bytes);
1187
97
    return hash;
1188
97
}
1189
1190
static gboolean
1191
Dot11DecryptIsSaIdEqual(const void *key1, const void *key2)
1192
0
{
1193
0
    return memcmp(key1, key2, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID)) == 0;
1194
0
}
1195
1196
int Dot11DecryptInitContext(
1197
    PDOT11DECRYPT_CONTEXT ctx)
1198
32
{
1199
32
    if (ctx==NULL) {
1200
0
        ws_warning("NULL context");
1201
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1202
0
    }
1203
1204
32
    Dot11DecryptCleanKeys(ctx);
1205
32
    Dot11DecryptCleanSecAssoc(ctx);
1206
1207
32
    ctx->pkt_ssid_len = 0;
1208
32
    ctx->sa_hash = g_hash_table_new_full(Dot11DecryptSaHash, Dot11DecryptIsSaIdEqual,
1209
32
                                         g_free, Dot11DecryptCleanSA);
1210
32
    if (ctx->sa_hash == NULL) {
1211
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1212
0
    }
1213
1214
32
    ws_debug("Context initialized!");
1215
32
    return DOT11DECRYPT_RET_SUCCESS;
1216
32
}
1217
1218
int Dot11DecryptDestroyContext(
1219
    PDOT11DECRYPT_CONTEXT ctx)
1220
0
{
1221
0
    if (ctx==NULL) {
1222
0
        ws_warning("NULL context");
1223
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1224
0
    }
1225
1226
0
    Dot11DecryptCleanKeys(ctx);
1227
0
    Dot11DecryptCleanSecAssoc(ctx);
1228
1229
0
    ws_debug("Context destroyed!");
1230
0
    return DOT11DECRYPT_RET_SUCCESS;
1231
0
}
1232
1233
#ifdef __cplusplus
1234
}
1235
#endif
1236
1237
/****************************************************************************/
1238
1239
/****************************************************************************/
1240
/* Internal function definitions                                         */
1241
1242
#ifdef __cplusplus
1243
extern "C" {
1244
#endif
1245
1246
static int
1247
Dot11DecryptRsnaMng(
1248
    unsigned char *decrypt_data,
1249
    unsigned mac_header_len,
1250
    unsigned *decrypt_len,
1251
    PDOT11DECRYPT_KEY_ITEM key,
1252
    DOT11DECRYPT_SEC_ASSOCIATION *sa)
1253
0
{
1254
0
    int ret = 1;
1255
0
    unsigned char *try_data;
1256
0
    unsigned try_data_len = *decrypt_len;
1257
1258
    /* There should be at least 1 byte encrypted and TKIP/CCMP/GCMP header
1259
       should be present. Trailer is at least 8 bytes and it's precisely checked
1260
       afterwards. */
1261
0
    if (*decrypt_len < mac_header_len + DOT11DECRYPT_RSNA_HEADER + 1 +
1262
0
                       DOT11DECRYPT_RSNA_MIN_TRAILER) {
1263
0
        ws_debug("Invalid decryption length");
1264
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1265
0
    }
1266
1267
    /* allocate a temp buffer for the decryption loop */
1268
0
    try_data=(unsigned char *)g_malloc(try_data_len);
1269
1270
    /* start of loop added by GCS */
1271
0
    for(/* sa */; sa != NULL ;sa=sa->next) {
1272
0
       const uint8_t *ap_mld_mac = NULL, *sta_mld_mac = NULL;
1273
1274
0
       if (sa->validKey==false) {
1275
0
           ws_noisy("Key not yet valid");
1276
0
           continue;
1277
0
       }
1278
1279
       /* copy the encrypted data into a temp buffer */
1280
0
       memcpy(try_data, decrypt_data, *decrypt_len);
1281
1282
0
       if (sa->wpa.mld) {
1283
0
           ap_mld_mac = sa->wpa.ap_mld_mac;
1284
0
           sta_mld_mac = sa->wpa.sta_mld_mac;
1285
0
       }
1286
       /* Select decryption method based on EAPOL Key Descriptor Version and negotiated AKM
1287
        * with selected cipher suite. Refer to IEEE 802.11-2020:
1288
        * 12.7.2 EAPOL-Key frames
1289
        * 12.2.4 RSNA establishment
1290
        * 12.7 Keys and key distribution
1291
        * Table 9-149-Cipher suite selectors
1292
        */
1293
1294
0
       if (sa->wpa.key_ver == 1 || sa->wpa.cipher == DOT11DECRYPT_CIPHER_TKIP) {
1295
           /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
1296
0
           ws_noisy("TKIP");
1297
0
           DEBUG_DUMP("ptk", sa->wpa.ptk, 64, LOG_LEVEL_NOISY);
1298
0
           DEBUG_DUMP("ptk portion used", DOT11DECRYPT_GET_TK_TKIP(sa->wpa.ptk),
1299
0
                      16, LOG_LEVEL_NOISY);
1300
1301
0
           ret = Dot11DecryptTkipDecrypt(try_data, mac_header_len, *decrypt_len,
1302
0
                                         DOT11DECRYPT_GET_TK_TKIP(sa->wpa.ptk));
1303
0
           if (ret) {
1304
0
               if (ret < 0) {
1305
0
                   ws_debug("Invalid decryption length");
1306
0
                   g_free(try_data);
1307
0
                   return DOT11DECRYPT_RET_UNSUCCESS;
1308
0
               }
1309
0
               ws_noisy("TKIP failed!");
1310
0
               continue;
1311
0
           }
1312
1313
0
           ws_noisy("TKIP DECRYPTED!!!");
1314
           /* remove MIC and ICV from the end of packet */
1315
0
           *decrypt_len -= DOT11DECRYPT_TKIP_MICLEN + DOT11DECRYPT_WEP_ICV;
1316
0
           break;
1317
0
       } else if (sa->wpa.cipher == DOT11DECRYPT_CIPHER_GCMP ||
1318
0
                  sa->wpa.cipher == DOT11DECRYPT_CIPHER_GCMP256)
1319
0
       {
1320
0
           ws_noisy("GCMP");
1321
1322
0
           ret = Dot11DecryptGcmpDecrypt(try_data, mac_header_len, (int)*decrypt_len,
1323
0
                                         DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
1324
0
                                         Dot11DecryptGetTkLen(sa->wpa.cipher) / 8,
1325
0
                                         ap_mld_mac, sta_mld_mac);
1326
0
           if (ret) {
1327
0
               if (ret < 0) {
1328
0
                   ws_debug("Invalid decryption length");
1329
0
                   g_free(try_data);
1330
0
                   return DOT11DECRYPT_RET_UNSUCCESS;
1331
0
               }
1332
0
               continue;
1333
0
           }
1334
0
           ws_noisy("GCMP DECRYPTED!!!");
1335
           /* remove MIC from the end of packet */
1336
0
           *decrypt_len -= DOT11DECRYPT_GCMP_TRAILER;
1337
0
           break;
1338
0
       } else {
1339
           /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
1340
0
           ws_noisy("CCMP");
1341
1342
0
           unsigned trailer = sa->wpa.cipher != 10 ? DOT11DECRYPT_CCMP_TRAILER : DOT11DECRYPT_CCMP_256_TRAILER;
1343
1344
0
           ret = Dot11DecryptCcmpDecrypt(try_data, mac_header_len, (int)*decrypt_len,
1345
0
                                         DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
1346
0
                                         Dot11DecryptGetTkLen(sa->wpa.cipher) / 8,
1347
0
                                         trailer, ap_mld_mac, sta_mld_mac);
1348
0
           if (ret) {
1349
0
               if (ret < 0) {
1350
0
                   ws_debug("Invalid decryption length");
1351
0
                   g_free(try_data);
1352
0
                   return DOT11DECRYPT_RET_UNSUCCESS;
1353
0
               }
1354
0
               continue;
1355
0
           }
1356
0
           ws_noisy("CCMP DECRYPTED!!!");
1357
           /* remove MIC from the end of packet */
1358
0
           *decrypt_len -= trailer;
1359
0
           break;
1360
0
       }
1361
0
    }
1362
    /* end of loop */
1363
1364
    /* none of the keys worked */
1365
0
    if(sa == NULL) {
1366
0
        g_free(try_data);
1367
0
        return ret;
1368
0
    }
1369
1370
    /* We should have decrypted at least 1 byte successfully and
1371
       subtracted security trailer.  */
1372
0
    ws_assert(*decrypt_len > mac_header_len + DOT11DECRYPT_RSNA_HEADER &&
1373
0
              *decrypt_len < try_data_len);
1374
1375
    /* remove protection bit */
1376
0
    decrypt_data[1]&=0xBF;
1377
1378
    /* remove TKIP/CCMP/GCMP header */
1379
0
    *decrypt_len -= DOT11DECRYPT_RSNA_HEADER;
1380
1381
    /* copy the decrypted data into the decrypt buffer GCS*/
1382
0
    memcpy(decrypt_data + mac_header_len,
1383
0
           try_data + mac_header_len + DOT11DECRYPT_RSNA_HEADER,
1384
0
           *decrypt_len - mac_header_len);
1385
0
    g_free(try_data);
1386
1387
0
    Dot11DecryptCopyKey(sa, key);
1388
0
    return DOT11DECRYPT_RET_SUCCESS;
1389
0
}
1390
1391
static int
1392
Dot11DecryptWepMng(
1393
    PDOT11DECRYPT_CONTEXT ctx,
1394
    unsigned char *decrypt_data,
1395
    unsigned mac_header_len,
1396
    unsigned *decrypt_len,
1397
    PDOT11DECRYPT_KEY_ITEM key,
1398
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
1399
53
{
1400
53
    unsigned char wep_key[DOT11DECRYPT_WEP_KEY_MAXLEN+DOT11DECRYPT_WEP_IVLEN];
1401
53
    size_t keylen;
1402
53
    int ret_value=1;
1403
53
    int key_index;
1404
53
    DOT11DECRYPT_KEY_ITEM *tmp_key;
1405
53
    uint8_t useCache=false;
1406
53
    unsigned char *try_data;
1407
53
    DOT11DECRYPT_SEC_ASSOCIATION *sa;
1408
53
    unsigned try_data_len = *decrypt_len;
1409
53
    ssize_t ciphertext_len = (ssize_t)*decrypt_len -
1410
53
                             (ssize_t)(mac_header_len + DOT11DECRYPT_WEP_HEADER + DOT11DECRYPT_WEP_TRAILER);
1411
1412
53
    if (ciphertext_len < 1) {
1413
0
        ws_debug("Decryption length too short");
1414
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1415
0
    }
1416
1417
53
    try_data = (unsigned char *)g_malloc(try_data_len);
1418
1419
    /* get the Security Association structure for the STA and AP */
1420
1421
    /* For WEP the sa is used only for caching. When no sa exists all user
1422
     * entered WEP keys are checked and on successful packet decryption an
1423
     * sa is formed caching the key used for decryption.
1424
     */
1425
53
    sa = Dot11DecryptGetSa(ctx, id);
1426
53
    if (sa != NULL && sa->key != NULL) {
1427
0
        useCache = true;
1428
0
    }
1429
1430
53
    for (key_index=0; key_index<(int)ctx->keys_nr; key_index++) {
1431
        /* use the cached one, or try all keys */
1432
0
        if (!useCache) {
1433
0
            tmp_key=&ctx->keys[key_index];
1434
0
        } else {
1435
0
            if (sa->key!=NULL && sa->key->KeyType==DOT11DECRYPT_KEY_TYPE_WEP) {
1436
0
                ws_noisy("Try cached WEP key...");
1437
0
                tmp_key=sa->key;
1438
0
            } else {
1439
0
                ws_noisy("Cached key is not valid, try another WEP key...");
1440
0
                tmp_key=&ctx->keys[key_index];
1441
0
            }
1442
0
        }
1443
1444
        /* obviously, try only WEP keys... */
1445
0
        if (tmp_key->KeyType==DOT11DECRYPT_KEY_TYPE_WEP) {
1446
0
            ws_noisy("Try WEP key...");
1447
1448
0
            memset(wep_key, 0, sizeof(wep_key));
1449
0
            memcpy(try_data, decrypt_data, *decrypt_len);
1450
1451
            /* Construct the WEP seed: copy the IV in first 3 bytes and then the WEP key (refer to 802-11i-2004, 8.2.1.4.3, pag. 36) */
1452
0
            memcpy(wep_key, try_data+mac_header_len, DOT11DECRYPT_WEP_IVLEN);
1453
0
            keylen=tmp_key->KeyData.Wep.WepKeyLen;
1454
0
            memcpy(wep_key+DOT11DECRYPT_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
1455
1456
0
            ret_value=Dot11DecryptWepDecrypt(wep_key,
1457
0
                keylen+DOT11DECRYPT_WEP_IVLEN,
1458
0
                try_data + (mac_header_len + DOT11DECRYPT_WEP_HEADER),
1459
0
                ciphertext_len);
1460
1461
0
            if (ret_value == DOT11DECRYPT_RET_SUCCESS)
1462
0
                memcpy(decrypt_data, try_data, *decrypt_len);
1463
0
        }
1464
1465
0
        if (!ret_value && tmp_key->KeyType==DOT11DECRYPT_KEY_TYPE_WEP) {
1466
            /* the tried key is the correct one, cache it in the Security Association */
1467
1468
            /* Form an SA if one does not exist already */
1469
0
            if (sa == NULL) {
1470
0
                sa = Dot11DecryptNewSa(id);
1471
0
                if (sa == NULL) {
1472
0
                    ws_warning("Failed to alloc sa for WEP");
1473
0
                    ret_value = DOT11DECRYPT_RET_UNSUCCESS;
1474
0
                    break;
1475
0
                }
1476
0
                sa = Dot11DecryptAddSa(ctx, id, sa);
1477
0
            }
1478
0
            sa->key=tmp_key;
1479
1480
0
            if (key!=NULL) {
1481
0
                memcpy(key, sa->key, sizeof(DOT11DECRYPT_KEY_ITEM));
1482
0
                key->KeyType=DOT11DECRYPT_KEY_TYPE_WEP;
1483
0
            }
1484
1485
0
            break;
1486
0
        } else {
1487
            /* the cached key was not valid, try other keys */
1488
1489
0
            if (useCache==true) {
1490
0
                useCache=false;
1491
0
                key_index--;
1492
0
            }
1493
0
        }
1494
0
    }
1495
1496
53
    g_free(try_data);
1497
53
    if (ret_value)
1498
53
        return DOT11DECRYPT_RET_UNSUCCESS;
1499
1500
0
    ws_noisy("WEP DECRYPTED!!!");
1501
1502
    /* remove IV(4bytes) and ICV (4bytes) from the packet */
1503
0
    *decrypt_len -= 4 + 4;
1504
1505
    /* remove protection bit */
1506
0
    decrypt_data[1]&=0xBF;
1507
1508
0
    memmove(decrypt_data + mac_header_len,
1509
0
            decrypt_data + mac_header_len + DOT11DECRYPT_WEP_IVLEN + DOT11DECRYPT_WEP_KIDLEN,
1510
0
            *decrypt_len - mac_header_len);
1511
1512
0
    return DOT11DECRYPT_RET_SUCCESS;
1513
53
}
1514
1515
/* From IEEE 802.11-2024 Table 9-190—AKM suite selectors */
1516
static bool Dot11DecryptIsFtAkm(int akm)
1517
387
{
1518
387
    switch (akm) {
1519
0
        case 3:
1520
0
        case 4:
1521
0
        case 9:
1522
0
        case 13:
1523
0
        case 25: /* FT SAE EXT KEY */
1524
0
            return true;
1525
387
    }
1526
387
    return false;
1527
387
}
1528
1529
/* Get xxkey portion of MSK */
1530
/* From IEEE 802.11-2016 12.7.1.7.3 PMK-R0 */
1531
static const uint8_t *
1532
Dot11DecryptGetXXKeyFromMSK(const uint8_t *msk, size_t msk_len,
1533
                            int akm, size_t *xxkey_len)
1534
0
{
1535
0
    if (!xxkey_len) {
1536
0
        return NULL;
1537
0
    }
1538
0
    switch (akm) {
1539
0
    case 3:
1540
0
        if (msk_len < 64) {
1541
0
            return NULL;
1542
0
        }
1543
0
        *xxkey_len = 32;
1544
0
        return msk + 32;
1545
0
    case 13:
1546
0
        if (msk_len < 48) {
1547
0
            return NULL;
1548
0
        }
1549
0
        *xxkey_len = 48;
1550
0
        return msk;
1551
0
    default:
1552
0
        return NULL;
1553
0
    }
1554
0
}
1555
1556
/* From IEEE 802.11-2024 12.7.1.3 Pairwise key hierarchy */
1557
static void
1558
Dot11DecryptDerivePmkFromMsk(const uint8_t *msk, uint8_t msk_len, int akm,
1559
                             uint8_t *pmk, uint8_t *pmk_len)
1560
0
{
1561
0
    if (!msk || !pmk || !pmk_len) {
1562
0
        return;
1563
0
    }
1564
    // When using AKM suite selector 00-0F-AC:12, the length of the PMK, PMK_bits,
1565
    // shall be 384 bits. With all other AKM suite selectors, the length of the PMK,
1566
    // PMK_bits, shall be 256 bits.
1567
0
    if (akm == 12) {
1568
0
        *pmk_len = 384 / 8;
1569
0
    } else {
1570
0
        *pmk_len = 256 / 8;
1571
0
    }
1572
0
    if ((uint8_t)(msk_len + *pmk_len) < msk_len) {
1573
0
        *pmk_len = 0;
1574
0
        return;
1575
0
    }
1576
    // PMK = L(MSK, 0, PMK_bits).
1577
0
    memcpy(pmk, msk, *pmk_len);
1578
0
}
1579
1580
static bool
1581
Dot11DecryptIsWpaKeyType(uint8_t key_type)
1582
0
{
1583
0
    switch (key_type) {
1584
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PWD:
1585
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PSK:
1586
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PMK:
1587
0
        case DOT11DECRYPT_KEY_TYPE_MSK:
1588
0
            return true;
1589
0
    }
1590
0
    return false;
1591
0
}
1592
1593
static bool
1594
Dot11DecryptIsPwdWildcardSsid(const PDOT11DECRYPT_CONTEXT ctx,
1595
                              const DOT11DECRYPT_KEY_ITEM *key_item)
1596
0
{
1597
0
    if (!ctx || !key_item || key_item->KeyType != DOT11DECRYPT_KEY_TYPE_WPA_PWD) {
1598
0
        return false;
1599
0
    }
1600
0
    if (key_item->UserPwd.SsidLen == 0 && ctx->pkt_ssid_len > 0 &&
1601
0
        ctx->pkt_ssid_len <= DOT11DECRYPT_WPA_SSID_MAX_LEN) {
1602
0
        return true;
1603
0
    }
1604
0
    return false;
1605
0
}
1606
1607
/* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
1608
static int
1609
Dot11DecryptRsna4WHandshake(
1610
    PDOT11DECRYPT_CONTEXT ctx,
1611
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
1612
    const uint8_t *eapol_raw,
1613
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id,
1614
    const unsigned tot_len)
1615
0
{
1616
0
    DOT11DECRYPT_KEY_ITEM *tmp_key, *tmp_pkt_key, pkt_key;
1617
0
    DOT11DECRYPT_SEC_ASSOCIATION *sa;
1618
0
    int key_index;
1619
0
    int ret = 1;
1620
0
    unsigned char useCache=false;
1621
0
    unsigned char eapol[DOT11DECRYPT_EAPOL_MAX_LEN];
1622
1623
0
    if (eapol_parsed->len > DOT11DECRYPT_EAPOL_MAX_LEN ||
1624
0
        eapol_parsed->key_len > DOT11DECRYPT_EAPOL_MAX_LEN ||
1625
0
        eapol_parsed->key_data_len > DOT11DECRYPT_EAPOL_MAX_LEN) {
1626
0
        ws_debug("Too large EAPOL frame and/or key data");
1627
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1628
0
    }
1629
1630
    /* TODO timeouts? */
1631
1632
    /* TODO consider key-index */
1633
1634
    /* TODO consider Deauthentications */
1635
1636
0
    ws_debug("4-way handshake...");
1637
1638
    /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
1639
1640
    /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
1641
0
    if (eapol_parsed->msg_type == DOT11DECRYPT_HS_MSG_TYPE_4WHS_1) {
1642
0
        ws_debug("4-way handshake message 1");
1643
1644
        /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been        */
1645
        /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current  */
1646
        /* local value, the Supplicant discards the message.                                                               */
1647
        /* -> not checked, the Authenticator will be send another Message 1 (hopefully!)                                   */
1648
1649
        /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
1650
0
        if (!eapol_parsed->nonce) {
1651
0
            ws_debug("ANonce missing");
1652
0
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1653
0
        }
1654
1655
0
        sa = Dot11DecryptGetSa(ctx, id);
1656
0
        if (sa == NULL || sa->handshake >= 2) {
1657
            /* Either no SA exists or one exists but we're reauthenticating */
1658
0
            sa = Dot11DecryptNewSa(id);
1659
0
            if (sa == NULL) {
1660
0
                ws_warning("Failed to alloc broadcast sa");
1661
0
                return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1662
0
            }
1663
0
            sa = Dot11DecryptAddSa(ctx, id, sa);
1664
0
        }
1665
0
        memcpy(sa->wpa.nonce, eapol_parsed->nonce, 32);
1666
1667
0
        if (eapol_parsed->mld_mac) {
1668
0
            memcpy(sa->wpa.ap_mld_mac, eapol_parsed->mld_mac, 6);
1669
0
            sa->wpa.ap_mld_mac_set = 1;
1670
0
        }
1671
        /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
1672
0
        sa->wpa.key_ver = eapol_parsed->key_version;
1673
0
        sa->handshake=1;
1674
0
        return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
1675
0
    }
1676
1677
    /* message 2|4: Supplicant->Authenticator (Sec=0|1, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=SNonce|0, MIC=MIC(KCK,EAPOL)) */
1678
0
    if (eapol_parsed->msg_type == DOT11DECRYPT_HS_MSG_TYPE_4WHS_2) {
1679
0
        ws_debug("4-way handshake message 2");
1680
1681
        /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
1682
        /* outstanding Message 1. If not, it silently discards the message.                                   */
1683
        /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame,  */
1684
        /* the Authenticator silently discards Message 2.                                                     */
1685
        /* -> not checked; the Supplicant will send another message 2 (hopefully!)                            */
1686
1687
0
        sa = Dot11DecryptGetSa(ctx, id);
1688
0
        if (sa == NULL) {
1689
0
            ws_debug("No SA for BSSID found");
1690
0
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1691
0
        }
1692
0
        if (!eapol_parsed->nonce) {
1693
0
            ws_debug("SNonce missing");
1694
0
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1695
0
        }
1696
0
        if (sa->key != NULL) {
1697
0
            useCache = true;
1698
0
        }
1699
1700
        // Save partial MLO link info using association link info and MLO Link KDEs
1701
0
        if (sa->wpa.ap_mld_mac_set && eapol_parsed->mld_mac) {
1702
0
            memcpy(sa->wpa.sta_mld_mac, eapol_parsed->mld_mac, DOT11DECRYPT_MAC_LEN);
1703
0
            sa->wpa.sta_mld_mac_set = 1;
1704
0
            sa->wpa.mld = 1;
1705
0
            memcpy(sa->wpa.mlo_links[0].sta_mac, id->sta, DOT11DECRYPT_MAC_LEN);
1706
0
            memcpy(sa->wpa.mlo_links[0].ap_mac, id->bssid, DOT11DECRYPT_MAC_LEN);
1707
0
            sa->wpa.mlo_links[0].sta_mac_set = 1;
1708
0
            sa->wpa.mlo_links[0].ap_mac_set = 1;
1709
1710
0
            int links = 1;
1711
0
            for (int i = 0; i < eapol_parsed->mlo_link_count && links < DOT11DECRYPT_MAX_MLO_LINKS; ++i) {
1712
0
                if (!memcmp(eapol_parsed->mlo_link[i].mac, id->sta, DOT11DECRYPT_MAC_LEN))
1713
0
                    continue;
1714
0
                sa->wpa.mlo_links[links].id = eapol_parsed->mlo_link[i].id;
1715
0
                memcpy(sa->wpa.mlo_links[links].sta_mac, eapol_parsed->mlo_link[i].mac, DOT11DECRYPT_MAC_LEN);
1716
0
                sa->wpa.mlo_links[links].id_set = 1;
1717
0
                sa->wpa.mlo_links[links].sta_mac_set = 1;
1718
0
                links++;
1719
0
            }
1720
0
        }
1721
1722
0
        int akm = -1;
1723
0
        int cipher = -1;
1724
0
        int group_cipher = -1;
1725
0
        uint8_t ptk[DOT11DECRYPT_WPA_PTK_MAX_LEN];
1726
0
        size_t ptk_len;
1727
1728
        /* now you can derive the PTK */
1729
0
        for (key_index=0; key_index<(int)ctx->keys_nr || useCache; key_index++) {
1730
            /* use the cached one, or try all keys */
1731
0
            if (useCache && Dot11DecryptIsWpaKeyType(sa->key->KeyType)) {
1732
0
                ws_debug("Try cached WPA key...");
1733
0
                tmp_key = sa->key;
1734
                /* Step back loop counter as cached key is used instead */
1735
0
                key_index--;
1736
0
            } else {
1737
0
                ws_debug("Try WPA key...");
1738
0
                tmp_key = &ctx->keys[key_index];
1739
0
            }
1740
0
            useCache = false;
1741
1742
            /* obviously, try only WPA keys... */
1743
0
            if (!Dot11DecryptIsWpaKeyType(tmp_key->KeyType)) {
1744
0
                continue;
1745
0
            }
1746
0
            if (Dot11DecryptIsPwdWildcardSsid(ctx, tmp_key))
1747
0
            {
1748
                /* We have a "wildcard" SSID.  Use the one from the packet. */
1749
0
                memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
1750
0
                memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
1751
0
                pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
1752
0
                Dot11DecryptRsnaPwd2Psk(&pkt_key.UserPwd, pkt_key.KeyData.Wpa.Psk);
1753
0
                pkt_key.KeyData.Wpa.PskLen = DOT11DECRYPT_WPA_PWD_PSK_LEN;
1754
0
                tmp_pkt_key = &pkt_key;
1755
0
            } else {
1756
0
                tmp_pkt_key = tmp_key;
1757
0
            }
1758
0
            memcpy(eapol, eapol_raw, tot_len);
1759
1760
            /* From IEEE 802.11-2024 12.7.2 EAPOL-Key frames */
1761
0
            if (eapol_parsed->key_version == 0 || eapol_parsed->key_version == 3 ||
1762
0
                eapol_parsed->key_version == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP)
1763
0
            {
1764
                /* PTK derivation is based on Authentication Key Management Type */
1765
0
                akm = eapol_parsed->akm;
1766
0
                cipher = eapol_parsed->cipher;
1767
0
                group_cipher = eapol_parsed->group_cipher;
1768
0
            } else if (eapol_parsed->key_version == DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP) {
1769
                /* TKIP */
1770
0
                akm = 2;
1771
0
                cipher = 2;
1772
0
                group_cipher = 2;
1773
0
            } else {
1774
0
                ws_info("EAPOL key_version not supported");
1775
0
                return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1776
0
            }
1777
1778
0
            if (tmp_pkt_key->KeyType == DOT11DECRYPT_KEY_TYPE_MSK) {
1779
0
                Dot11DecryptDerivePmkFromMsk(tmp_pkt_key->Msk.Msk, tmp_pkt_key->Msk.Len, akm,
1780
0
                                             tmp_pkt_key->KeyData.Wpa.Psk,
1781
0
                                             &tmp_pkt_key->KeyData.Wpa.PskLen);
1782
0
            }
1783
1784
0
            ptk_len = DOT11DECRYPT_WPA_PTK_MAX_LEN;
1785
1786
0
            if (Dot11DecryptIsFtAkm(akm)) {
1787
0
                ret = Dot11DecryptFtDerivePtk(ctx, sa, tmp_pkt_key,
1788
0
                                              eapol_parsed->mdid,
1789
0
                                              eapol_parsed->nonce,
1790
0
                                              eapol_parsed->fte.r0kh_id,
1791
0
                                              eapol_parsed->fte.r0kh_id_len,
1792
0
                                              eapol_parsed->fte.r1kh_id,
1793
0
                                              eapol_parsed->fte.r1kh_id_len,
1794
0
                                              akm, cipher, ptk, &ptk_len);
1795
0
            } else {
1796
                /* derive the PTK from the AA, SPA, PMK, SNonce, ANonce */
1797
0
                ret = Dot11DecryptDerivePtk(sa, /* authenticator nonce, AA, SPA */
1798
0
                                            tmp_pkt_key->KeyData.Wpa.Psk, /* PSK == PMK */
1799
0
                                            tmp_pkt_key->KeyData.Wpa.PskLen,
1800
0
                                            eapol_parsed->nonce, /* supplicant nonce */
1801
0
                                            eapol_parsed->key_version,
1802
0
                                            akm, cipher, ptk, &ptk_len);
1803
0
            }
1804
0
            if (ret) {
1805
                /* Unsuccessful PTK derivation */
1806
0
                continue;
1807
0
            }
1808
0
            DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk, akm, tmp_pkt_key->KeyData.Wpa.PskLen * 8), Dot11DecryptGetTkLen(cipher) / 8,
1809
0
                       LOG_LEVEL_DEBUG);
1810
1811
0
            ret = Dot11DecryptRsnaMicCheck(eapol_parsed,
1812
0
                                           eapol, /* eapol frame (header also) */
1813
0
                                           tot_len, /* eapol frame length */
1814
0
                                           DOT11DECRYPT_GET_KCK(ptk, akm),
1815
0
                                           eapol_parsed->key_version,
1816
0
                                           akm, tmp_pkt_key->KeyData.Wpa.PskLen);
1817
            /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches   */
1818
            /* that from the (Re)Association Request message.                                                    */
1819
            /*     i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
1820
            /* primitive to terminate the association.                                                           */
1821
            /*     ii) If they do match bit-wise, the Authenticator constructs Message 3.                        */
1822
1823
0
            if (ret == DOT11DECRYPT_RET_SUCCESS) {
1824
                /* the key is the correct one, cache it in the Security Association */
1825
0
                sa->key = tmp_key;
1826
0
                break;
1827
0
            }
1828
0
        }
1829
1830
0
        if (ret) {
1831
0
            ws_debug("handshake step failed");
1832
0
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1833
0
        }
1834
0
        sa->wpa.key_ver = eapol_parsed->key_version;
1835
0
        sa->wpa.akm = akm;
1836
0
        sa->wpa.cipher = cipher;
1837
0
        sa->wpa.tmp_group_cipher = group_cipher;
1838
0
        memcpy(sa->wpa.ptk, ptk, ptk_len);
1839
0
        sa->wpa.ptk_len = (int)ptk_len;
1840
0
        sa->wpa.pmk_len = tmp_pkt_key->KeyData.Wpa.PskLen;
1841
0
        sa->handshake = 2;
1842
0
        sa->validKey = true; /* we can use the key to decode, even if we have not captured the other eapol packets */
1843
1844
0
        return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
1845
0
    }
1846
1847
    /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
1848
0
    if (eapol_parsed->msg_type == DOT11DECRYPT_HS_MSG_TYPE_4WHS_3) {
1849
0
        ws_debug("4-way handshake message 3");
1850
1851
        /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field     */
1852
        /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
1853
        /* -> not checked, the Authenticator will send another message 3 (hopefully!)                                  */
1854
1855
        /* TODO check page 88 (RNS) */
1856
1857
        /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1858
           In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */
1859
0
        if (eapol_parsed->key_type == DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR) {
1860
0
            Dot11DecryptCopyBroadcastKey(ctx, eapol_parsed->gtk, eapol_parsed->gtk_len, id);
1861
1862
0
            sa = Dot11DecryptGetSa(ctx, id);
1863
0
            if (sa == NULL || sa->handshake != 2 || !sa->validKey || !sa->wpa.mld) {
1864
0
                ws_debug("No MLD SA for BSSID found");
1865
0
                return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
1866
0
            }
1867
1868
            // Build complete MLO link info using MLO Link KDEs
1869
0
            for (int i = 0; i < eapol_parsed->mlo_link_count; ++i) {
1870
0
                struct DOT11DECRYPT_EAPOL_PARSED_MLO_LINK *parsed = &eapol_parsed->mlo_link[i];
1871
1872
0
                for (struct DOT11DECRYPT_MLO_LINK_INFO *link = sa->wpa.mlo_links;
1873
0
                     link < &sa->wpa.mlo_links[DOT11DECRYPT_MAX_MLO_LINKS];
1874
0
                     ++link) {
1875
0
                    if (link->ap_mac_set && !memcmp(parsed->mac, link->ap_mac, DOT11DECRYPT_MAC_LEN)) {
1876
0
                        link->id = parsed->id;
1877
0
                        link->id_set = 1;
1878
0
                    } else if (link->id_set && link->id == parsed->id) {
1879
0
                        memcpy(link->ap_mac, parsed->mac, DOT11DECRYPT_MAC_LEN);
1880
0
                        link->ap_mac_set = 1;
1881
0
                    }
1882
0
                }
1883
0
            }
1884
1885
            // Create PTKSA for non-association links
1886
0
            for (struct DOT11DECRYPT_MLO_LINK_INFO *link = sa->wpa.mlo_links;
1887
0
                 link < &sa->wpa.mlo_links[DOT11DECRYPT_MAX_MLO_LINKS];
1888
0
                 ++link) {
1889
0
                if (!(link->id_set && link->ap_mac_set && link->sta_mac_set))
1890
0
                    continue;
1891
0
                if (!memcmp(link->ap_mac, id->bssid, DOT11DECRYPT_MAC_LEN))
1892
0
                    continue;
1893
0
                ws_debug("Create PTKSA for LinkID %d", link->id);
1894
0
                DOT11DECRYPT_SEC_ASSOCIATION *new_sa = Dot11DecryptDupSa(sa);
1895
0
                DOT11DECRYPT_SEC_ASSOCIATION_ID saId;
1896
0
                memcpy(&saId.bssid, link->ap_mac, DOT11DECRYPT_MAC_LEN);
1897
0
                memcpy(&saId.sta, link->sta_mac, DOT11DECRYPT_MAC_LEN);
1898
0
                memcpy(&new_sa->saId, &saId, sizeof(saId));
1899
0
                Dot11DecryptAddSa(ctx, &saId, new_sa);
1900
0
            }
1901
1902
            // Create GTKSA for all MLO links
1903
0
            Dot11DecryptCreateMloGtkSa(ctx, eapol_parsed, sa);
1904
0
       }
1905
0
    }
1906
1907
    /* message 4 */
1908
0
    if (eapol_parsed->msg_type == DOT11DECRYPT_HS_MSG_TYPE_4WHS_4) {
1909
        /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1910
1911
        /* TODO check MIC and Replay Counter                                                                     */
1912
        /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one  */
1913
        /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                 */
1914
        /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1915
        /* Authenticator silently discards Message 4.                                                            */
1916
1917
0
        ws_debug("4-way handshake message 4");
1918
0
        return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
1919
0
    }
1920
0
    return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1921
0
}
1922
1923
/* Refer to IEEE 802.11-2016 Chapeter 13.8 FT authentication sequence */
1924
int
1925
Dot11DecryptScanFtAssocForKeys(
1926
    const PDOT11DECRYPT_CONTEXT ctx,
1927
    const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed,
1928
    uint8_t *decrypted_gtk, size_t *decrypted_len,
1929
    DOT11DECRYPT_KEY_ITEM* used_key)
1930
387
{
1931
387
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
1932
1933
387
    ws_debug("(Re)Association packet");
1934
1935
387
    if (!ctx || !assoc_parsed) {
1936
0
        ws_warning("Invalid input parameters");
1937
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1938
0
    }
1939
387
    if (!Dot11DecryptIsFtAkm(assoc_parsed->akm)) {
1940
387
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1941
387
    }
1942
0
    if (!assoc_parsed->fte.anonce || !assoc_parsed->fte.snonce) {
1943
0
        ws_debug("ANonce or SNonce missing");
1944
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1945
0
    }
1946
1947
0
    switch (assoc_parsed->frame_subtype) {
1948
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_REQ:
1949
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_REQ:
1950
0
            memcpy(id.sta, assoc_parsed->sa, DOT11DECRYPT_MAC_LEN);
1951
0
            break;
1952
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_RESP:
1953
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_RESP:
1954
0
            memcpy(id.sta, assoc_parsed->da, DOT11DECRYPT_MAC_LEN);
1955
0
            break;
1956
0
        default:
1957
0
            ws_warning("Invalid frame subtype");
1958
0
            return DOT11DECRYPT_RET_UNSUCCESS;
1959
0
    }
1960
0
    memcpy(id.bssid, assoc_parsed->bssid, DOT11DECRYPT_MAC_LEN);
1961
1962
0
    DOT11DECRYPT_KEY_ITEM *tmp_key, *tmp_pkt_key, pkt_key;
1963
0
    DOT11DECRYPT_SEC_ASSOCIATION *sa;
1964
0
    size_t key_index;
1965
0
    unsigned ret = 1;
1966
0
    bool useCache = false;
1967
1968
0
    sa = Dot11DecryptNewSa(&id);
1969
0
    if (sa == NULL) {
1970
0
        ws_warning("Failed to alloc sa");
1971
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1972
0
    }
1973
1974
0
    memcpy(sa->wpa.nonce, assoc_parsed->fte.anonce, 32);
1975
1976
0
    if (sa->key != NULL) {
1977
0
        useCache = true;
1978
0
    }
1979
1980
0
    uint8_t ptk[DOT11DECRYPT_WPA_PTK_MAX_LEN];
1981
0
    size_t ptk_len;
1982
1983
    /* now you can derive the PTK */
1984
0
    for (key_index = 0; key_index < ctx->keys_nr || useCache; key_index++) {
1985
        /* use the cached one, or try all keys */
1986
0
        if (useCache && Dot11DecryptIsWpaKeyType(sa->key->KeyType)) {
1987
0
            ws_debug("Try cached WPA key...");
1988
0
            tmp_key = sa->key;
1989
            /* Step back loop counter as cached key is used instead */
1990
0
            key_index--;
1991
0
        } else {
1992
0
            ws_debug("Try WPA key...");
1993
0
            tmp_key = &ctx->keys[key_index];
1994
0
        }
1995
0
        useCache = false;
1996
1997
        /* Try only WPA keys... */
1998
0
        if (!Dot11DecryptIsWpaKeyType(tmp_key->KeyType)) {
1999
0
            continue;
2000
0
        }
2001
0
        if (Dot11DecryptIsPwdWildcardSsid(ctx, tmp_key))
2002
0
        {
2003
            /* We have a "wildcard" SSID.  Use the one from the packet. */
2004
0
            memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
2005
0
            memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
2006
0
            pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
2007
0
            Dot11DecryptRsnaPwd2Psk(&pkt_key.UserPwd, pkt_key.KeyData.Wpa.Psk);
2008
0
            pkt_key.KeyData.Wpa.PskLen = DOT11DECRYPT_WPA_PWD_PSK_LEN;
2009
0
            tmp_pkt_key = &pkt_key;
2010
0
        } else {
2011
0
            tmp_pkt_key = tmp_key;
2012
0
        }
2013
2014
0
        if (tmp_pkt_key->KeyType == DOT11DECRYPT_KEY_TYPE_MSK) {
2015
0
            Dot11DecryptDerivePmkFromMsk(tmp_pkt_key->Msk.Msk, tmp_pkt_key->Msk.Len,
2016
0
                                         assoc_parsed->akm,
2017
0
                                         tmp_pkt_key->KeyData.Wpa.Psk,
2018
0
                                         &tmp_pkt_key->KeyData.Wpa.PskLen);
2019
0
        }
2020
2021
0
        ptk_len = DOT11DECRYPT_WPA_PTK_MAX_LEN;
2022
0
        ret = Dot11DecryptFtDerivePtk(ctx, sa, tmp_pkt_key,
2023
0
                                      assoc_parsed->mdid,
2024
0
                                      assoc_parsed->fte.snonce,
2025
0
                                      assoc_parsed->fte.r0kh_id,
2026
0
                                      assoc_parsed->fte.r0kh_id_len,
2027
0
                                      assoc_parsed->fte.r1kh_id,
2028
0
                                      assoc_parsed->fte.r1kh_id_len,
2029
0
                                      assoc_parsed->akm, assoc_parsed->cipher,
2030
0
                                      ptk, &ptk_len);
2031
0
        if (ret != DOT11DECRYPT_RET_SUCCESS) {
2032
0
            continue;
2033
0
        }
2034
0
        DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk, assoc_parsed->akm, tmp_pkt_key->KeyData.Wpa.PskLen * 8),
2035
0
                   Dot11DecryptGetTkLen(assoc_parsed->cipher) / 8,
2036
0
                   LOG_LEVEL_DEBUG);
2037
2038
0
        ret = Dot11DecryptFtMicCheck(assoc_parsed,
2039
0
                                     DOT11DECRYPT_GET_KCK(ptk, assoc_parsed->akm),
2040
0
                                     Dot11DecryptGetKckLen(assoc_parsed->akm, tmp_pkt_key->KeyData.Wpa.PskLen * 8) / 8);
2041
0
        if (ret == DOT11DECRYPT_RET_SUCCESS) {
2042
            /* the key is the correct one, cache it in the Security Association */
2043
0
            sa->key = tmp_key;
2044
0
            break;
2045
0
        }
2046
0
    }
2047
2048
0
    if (ret) {
2049
0
        ws_debug("handshake step failed");
2050
0
        g_free(sa);
2051
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2052
0
    }
2053
0
    sa = Dot11DecryptAddSa(ctx, &id, sa);
2054
2055
0
    sa->wpa.key_ver = 0; /* Determine key type from akms and cipher*/
2056
0
    sa->wpa.akm = assoc_parsed->akm;
2057
0
    sa->wpa.cipher = assoc_parsed->cipher;
2058
0
    sa->wpa.tmp_group_cipher = assoc_parsed->group_cipher;
2059
0
    sa->wpa.pmk_len = tmp_pkt_key->KeyData.Wpa.PskLen;
2060
0
    memcpy(sa->wpa.ptk, ptk, ptk_len);
2061
0
    sa->wpa.ptk_len = (int)ptk_len;
2062
0
    sa->validKey = true;
2063
2064
0
    if (assoc_parsed->gtk && assoc_parsed->gtk_len - 8 <= 32) {
2065
0
        uint8_t decrypted_key[32];
2066
0
        uint16_t decrypted_key_len;
2067
0
        if (AES_unwrap(DOT11DECRYPT_GET_KEK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
2068
0
                       Dot11DecryptGetKekLen(sa->wpa.akm, sa->wpa.pmk_len * 8) / 8,
2069
0
                       assoc_parsed->gtk, assoc_parsed->gtk_len,
2070
0
                       decrypted_key, &decrypted_key_len)) {
2071
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2072
0
        }
2073
0
        if (decrypted_key_len != assoc_parsed->gtk_subelem_key_len) {
2074
0
            ws_debug("Unexpected GTK length");
2075
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2076
0
        }
2077
0
        Dot11DecryptCopyBroadcastKey(ctx, decrypted_key, decrypted_key_len, &id);
2078
0
        *decrypted_len = decrypted_key_len;
2079
0
        memcpy(decrypted_gtk, decrypted_key, decrypted_key_len);
2080
0
    }
2081
0
    Dot11DecryptCopyKey(sa, used_key);
2082
0
    return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE;
2083
0
}
2084
2085
/* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2086
static int
2087
Dot11DecryptGetIntegrityAlgoFromAkm(int akm, size_t pmk_len, int *algo, bool *hmac)
2088
0
{
2089
0
    int res = 0;
2090
0
    switch (akm) {
2091
0
        case 1:
2092
0
        case 2:
2093
0
            *algo = GCRY_MD_SHA1;
2094
0
            *hmac = true;
2095
0
            break;
2096
0
        case 3:
2097
0
        case 4:
2098
0
        case 5:
2099
0
        case 6:
2100
0
        case 8:
2101
0
        case 9:
2102
0
            *algo = GCRY_MAC_CMAC_AES;
2103
0
            *hmac = false;
2104
0
            break;
2105
0
        case 11:
2106
0
            *algo = GCRY_MD_SHA256;
2107
0
            *hmac = true;
2108
0
            break;
2109
0
        case 12:
2110
0
        case 13:
2111
0
            *algo = GCRY_MD_SHA384;
2112
0
            *hmac = true;
2113
0
            break;
2114
0
        case 18:
2115
0
        case 24:
2116
0
        case 25:
2117
0
            if (pmk_len == 256)
2118
0
                *algo = GCRY_MD_SHA256;
2119
0
            else if (pmk_len == 384)
2120
0
                *algo = GCRY_MD_SHA384;
2121
0
            else if (pmk_len == 512)
2122
0
                *algo = GCRY_MD_SHA512;
2123
0
            else
2124
0
                res = -1;
2125
0
            *hmac = true;
2126
0
            break;
2127
0
        default:
2128
            /* Unknown / Not supported yet */
2129
0
            res = -1;
2130
0
            break;
2131
0
    }
2132
0
    return res;
2133
0
}
2134
2135
static int
2136
Dot11DecryptRsnaMicCheck(
2137
    PDOT11DECRYPT_EAPOL_PARSED eapol_parsed,
2138
    unsigned char *eapol,
2139
    unsigned short eapol_len,
2140
    unsigned char *KCK,
2141
    unsigned short key_ver,
2142
    int akm,
2143
    int pmk_len)
2144
0
{
2145
0
    uint8_t *mic = eapol_parsed->mic;
2146
0
    uint16_t mic_len = eapol_parsed->mic_len;
2147
0
    uint16_t kck_len = Dot11DecryptGetKckLen(akm, pmk_len * 8) / 8;
2148
    /* MIC 16, 24 or 32 bytes, though HMAC-SHA256 / SHA384 / SHA512 algos need 32 / 48 / 64 bytes buffer */
2149
0
    unsigned char c_mic[64] = { 0 };
2150
0
    int algo = -1;
2151
0
    bool hmac = true;
2152
2153
0
    if (!mic || mic_len > DOT11DECRYPT_WPA_MICKEY_MAX_LEN) {
2154
0
        ws_debug("Not a valid mic");
2155
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2156
0
    }
2157
2158
    /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
2159
0
    memset(eapol + DOT11DECRYPT_WPA_MICKEY_OFFSET + 4, 0, mic_len);
2160
2161
0
    if (key_ver==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP) {
2162
        /* use HMAC-MD5 for the EAPOL-Key MIC */
2163
0
        algo = GCRY_MD_MD5;
2164
0
        hmac = true;
2165
0
    } else if (key_ver==DOT11DECRYPT_WPA_KEY_VER_AES_CCMP) {
2166
        /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
2167
0
        algo = GCRY_MD_SHA1;
2168
0
        hmac = true;
2169
0
    } else {
2170
        /* Mic check algorithm determined by AKM type */
2171
0
        if (Dot11DecryptGetIntegrityAlgoFromAkm(akm, pmk_len * 8, &algo, &hmac)) {
2172
0
            ws_warning("Unknown Mic check algo");
2173
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2174
0
        };
2175
0
    }
2176
0
    if (hmac) {
2177
0
        if (ws_hmac_buffer(algo, c_mic, eapol, eapol_len, KCK, kck_len)) {
2178
0
            ws_debug("HMAC_BUFFER");
2179
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2180
0
        }
2181
0
    } else {
2182
0
        if (ws_cmac_buffer(algo, c_mic, eapol, eapol_len, KCK, kck_len)) {
2183
0
            ws_debug("HMAC_BUFFER");
2184
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2185
0
        }
2186
0
    }
2187
2188
    /* compare calculated MIC with the Key MIC and return result (0 means success) */
2189
0
    DEBUG_DUMP("mic",  mic, mic_len, LOG_LEVEL_DEBUG);
2190
0
    DEBUG_DUMP("c_mic", c_mic, mic_len, LOG_LEVEL_DEBUG);
2191
0
    return memcmp(mic, c_mic, mic_len);
2192
0
}
2193
2194
/* IEEE 802.11-2020 Chapter 13.8.4 FT authentication sequence: contents of third message
2195
 * IEEE 802.11-2020 Chapter 13.8.5 FT authentication sequence: contents of fourth message
2196
 * The MIC shall be calculated on the concatenation of the following data, in the order given here:
2197
 * —
2198
 * — FTO’s MAC address (6 octets)
2199
 * — Target AP’s MAC address (6 octets)
2200
 * If third message:
2201
 * — Transaction sequence number (1 octet), which shall be set to the value 5 if this is a
2202
 *   Reassociation Request frame and, otherwise, set to the value 3
2203
 * If fourth message:
2204
 * — Transaction sequence number (1 octet), which shall be set to the value 6 if this is a
2205
 *   Reassociation Response frame or, otherwise, set to the value 4
2206
 *
2207
 * — RSNE
2208
 * — MDE
2209
 * — FTE, with the MIC field of the FTE set to 0
2210
 * — Contents of the RIC-Response (if present)
2211
 * — RSNXE (if present)
2212
 */
2213
static int
2214
Dot11DecryptFtMicCheck(
2215
    const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed,
2216
    const uint8_t *kck,
2217
    size_t kck_len)
2218
0
{
2219
0
    uint8_t *sta;
2220
0
    uint8_t seq_num;
2221
0
    uint8_t fte_len;
2222
0
    uint16_t mic_len;
2223
0
    uint8_t zeros[32] = { 0 };
2224
0
    gcry_mac_hd_t handle;
2225
0
    int mic_algo;
2226
0
    bool hmac;
2227
2228
0
    if (!assoc_parsed->rsne_tag || !assoc_parsed->mde_tag ||
2229
0
        !assoc_parsed->fte_tag) {
2230
0
        ws_debug("RSNE, MDE, or FTE not present");
2231
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2232
0
    }
2233
2234
0
    fte_len = assoc_parsed->fte_tag[1] + 2;
2235
0
    if (fte_len < 20) {
2236
0
        ws_debug("FTE too short");
2237
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2238
0
    }
2239
2240
0
    mic_len = assoc_parsed->fte.mic_len;
2241
0
    if (mic_len > sizeof(zeros)) {
2242
0
        ws_debug("MIC too long");
2243
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2244
0
    }
2245
2246
0
    switch (assoc_parsed->frame_subtype) {
2247
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_REQ:
2248
0
            sta = assoc_parsed->sa;
2249
0
            seq_num = 3;
2250
0
            break;
2251
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_RESP:
2252
0
            sta = assoc_parsed->da;
2253
0
            seq_num = 4;
2254
0
            break;
2255
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_REQ:
2256
0
            sta = assoc_parsed->sa;
2257
0
            seq_num = 5;
2258
0
            break;
2259
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_RESP:
2260
0
            sta = assoc_parsed->da;
2261
0
            seq_num = 6;
2262
0
            break;
2263
0
        default:
2264
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2265
0
    }
2266
2267
    /* For AKM 25, length of KCK is half of PMK while for other AKMs, pmk_len is not used. */
2268
0
    if (Dot11DecryptGetIntegrityAlgoFromAkm(assoc_parsed->akm, kck_len * 2 * 8, &mic_algo, &hmac)) {
2269
0
        ws_warning("unsupported AKM");
2270
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2271
0
    }
2272
2273
0
    if (mic_algo == GCRY_MAC_CMAC_AES)
2274
0
        /* nothing */;
2275
0
    else if (mic_algo == GCRY_MD_SHA256)
2276
0
        mic_algo = GCRY_MAC_HMAC_SHA256;
2277
0
    else if (mic_algo == GCRY_MD_SHA384)
2278
0
        mic_algo = GCRY_MAC_HMAC_SHA384;
2279
0
    else if (mic_algo == GCRY_MD_SHA512)
2280
0
        mic_algo = GCRY_MAC_HMAC_SHA512;
2281
0
    else
2282
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2283
2284
0
    if (gcry_mac_open(&handle, mic_algo, 0, NULL)) {
2285
0
        ws_warning("gcry_mac_open failed");
2286
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2287
0
    }
2288
0
    if (gcry_mac_setkey(handle, kck, kck_len)) {
2289
0
        ws_warning("gcry_mac_setkey failed");
2290
0
        gcry_mac_close(handle);
2291
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2292
0
    }
2293
0
    gcry_mac_write(handle, sta, DOT11DECRYPT_MAC_LEN);
2294
0
    gcry_mac_write(handle, assoc_parsed->bssid, DOT11DECRYPT_MAC_LEN);
2295
2296
0
    gcry_mac_write(handle, &seq_num, 1);
2297
2298
0
    gcry_mac_write(handle, assoc_parsed->rsne_tag, assoc_parsed->rsne_tag[1] + 2);
2299
0
    gcry_mac_write(handle, assoc_parsed->mde_tag, assoc_parsed->mde_tag[1] + 2);
2300
2301
0
    gcry_mac_write(handle, assoc_parsed->fte_tag, 4);
2302
0
    gcry_mac_write(handle, zeros, mic_len); /* MIC zeroed */
2303
0
    gcry_mac_write(handle, assoc_parsed->fte_tag + 4 + mic_len, fte_len - 4 - mic_len);
2304
2305
0
    if (assoc_parsed->rde_tag) {
2306
0
        gcry_mac_write(handle, assoc_parsed->rde_tag, assoc_parsed->rde_tag[1] + 2);
2307
0
    }
2308
0
    if (assoc_parsed->rsnxe_tag) {
2309
0
        gcry_mac_write(handle, assoc_parsed->rsnxe_tag, assoc_parsed->rsnxe_tag[1] + 2);
2310
0
    }
2311
2312
0
    if (gcry_mac_verify(handle, assoc_parsed->fte.mic, mic_len) != 0) {
2313
0
        DEBUG_DUMP("MIC", assoc_parsed->fte.mic, mic_len, LOG_LEVEL_DEBUG);
2314
0
        ws_debug("MIC verification failed");
2315
0
        gcry_mac_close(handle);
2316
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2317
0
    }
2318
0
    DEBUG_DUMP("MIC", assoc_parsed->fte.mic, mic_len, LOG_LEVEL_DEBUG);
2319
0
    gcry_mac_close(handle);
2320
0
    return DOT11DECRYPT_RET_SUCCESS;
2321
0
}
2322
2323
static int
2324
Dot11DecryptValidateKey(
2325
    PDOT11DECRYPT_KEY_ITEM key)
2326
0
{
2327
0
    size_t len;
2328
0
    unsigned char ret=true;
2329
2330
0
    if (key==NULL) {
2331
0
        ws_warning("NULL key");
2332
0
        return false;
2333
0
    }
2334
2335
0
    switch (key->KeyType) {
2336
0
        case DOT11DECRYPT_KEY_TYPE_WEP:
2337
            /* check key size limits */
2338
0
            len=key->KeyData.Wep.WepKeyLen;
2339
0
            if (len<DOT11DECRYPT_WEP_KEY_MINLEN || len>DOT11DECRYPT_WEP_KEY_MAXLEN) {
2340
0
                ws_info("WEP key: key length not accepted");
2341
0
                ret=false;
2342
0
            }
2343
0
            break;
2344
2345
0
        case DOT11DECRYPT_KEY_TYPE_WEP_40:
2346
            /* set the standard length and use a generic WEP key type */
2347
0
            key->KeyData.Wep.WepKeyLen=DOT11DECRYPT_WEP_40_KEY_LEN;
2348
0
            key->KeyType=DOT11DECRYPT_KEY_TYPE_WEP;
2349
0
            break;
2350
2351
0
        case DOT11DECRYPT_KEY_TYPE_WEP_104:
2352
            /* set the standard length and use a generic WEP key type */
2353
0
            key->KeyData.Wep.WepKeyLen=DOT11DECRYPT_WEP_104_KEY_LEN;
2354
0
            key->KeyType=DOT11DECRYPT_KEY_TYPE_WEP;
2355
0
            break;
2356
2357
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PWD:
2358
            /* check passphrase and SSID size limits */
2359
0
            len=strlen(key->UserPwd.Passphrase);
2360
0
            if (len<DOT11DECRYPT_WPA_PASSPHRASE_MIN_LEN || len>DOT11DECRYPT_WPA_PASSPHRASE_MAX_LEN) {
2361
0
                ws_info("WPA-PWD key: passphrase length not accepted");
2362
0
                ret=false;
2363
0
            }
2364
2365
0
            len=key->UserPwd.SsidLen;
2366
0
            if (len>DOT11DECRYPT_WPA_SSID_MAX_LEN) {
2367
0
                ws_info("WPA-PWD key: ssid length not accepted");
2368
0
                ret=false;
2369
0
            }
2370
2371
0
            break;
2372
2373
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PSK:
2374
0
            break;
2375
2376
0
        case DOT11DECRYPT_KEY_TYPE_TK:
2377
0
            break;
2378
2379
0
        case DOT11DECRYPT_KEY_TYPE_MSK:
2380
0
            break;
2381
2382
0
        default:
2383
0
            ret=false;
2384
0
    }
2385
0
    return ret;
2386
0
}
2387
2388
static int
2389
Dot11DecryptGetSaAddress(
2390
    const uint8_t *mac_header,
2391
    unsigned mac_header_len,
2392
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
2393
117
{
2394
117
    const DOT11DECRYPT_MAC_FRAME *frame;
2395
2396
117
    if (mac_header_len < sizeof(DOT11DECRYPT_MAC_FRAME)) {
2397
20
        return DOT11DECRYPT_RET_UNSUCCESS;
2398
20
    }
2399
97
    frame = (const DOT11DECRYPT_MAC_FRAME *)mac_header;
2400
2401
97
    if ((DOT11DECRYPT_TYPE(frame->fc[0])==DOT11DECRYPT_TYPE_DATA) &&
2402
39
        (DOT11DECRYPT_DS_BITS(frame->fc[1]) == 0) &&
2403
23
        (memcmp(frame->addr2, frame->addr3, DOT11DECRYPT_MAC_LEN) != 0) &&
2404
22
        (memcmp(frame->addr1, frame->addr3, DOT11DECRYPT_MAC_LEN) != 0)) {
2405
        /* DATA frame with fromDS=0 ToDS=0 and neither RA or SA is BSSID
2406
           => TDLS traffic. Use highest MAC address for bssid */
2407
19
        if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) < 0) {
2408
3
            memcpy(id->sta, frame->addr1, DOT11DECRYPT_MAC_LEN);
2409
3
            memcpy(id->bssid, frame->addr2, DOT11DECRYPT_MAC_LEN);
2410
16
        } else {
2411
16
            memcpy(id->sta, frame->addr2, DOT11DECRYPT_MAC_LEN);
2412
16
            memcpy(id->bssid, frame->addr1, DOT11DECRYPT_MAC_LEN);
2413
16
        }
2414
78
    } else {
2415
78
        const unsigned char *addr;
2416
2417
        /* Normal Case: SA between STA and AP */
2418
78
        if ((addr = Dot11DecryptGetBssidAddress(frame)) != NULL) {
2419
78
            memcpy(id->bssid, addr, DOT11DECRYPT_MAC_LEN);
2420
78
        } else {
2421
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2422
0
        }
2423
2424
78
        if ((addr = Dot11DecryptGetStaAddress(frame)) != NULL) {
2425
78
            memcpy(id->sta, addr, DOT11DECRYPT_MAC_LEN);
2426
78
        } else {
2427
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2428
0
        }
2429
78
    }
2430
97
    ws_noisy("BSSID_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2431
97
             id->bssid[0],id->bssid[1],id->bssid[2],id->bssid[3],id->bssid[4],id->bssid[5]);
2432
97
    ws_noisy("STA_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2433
97
             id->sta[0],id->sta[1],id->sta[2],id->sta[3],id->sta[4],id->sta[5]);
2434
2435
97
    return DOT11DECRYPT_RET_SUCCESS;
2436
97
}
2437
2438
/*
2439
 * Dot11DecryptGetBssidAddress() and Dot11DecryptGetBssidAddress() are used for
2440
 * key caching.  In each case, it's more important to return a value than
2441
 * to return a _correct_ value, so we fudge addresses in some cases, e.g.
2442
 * the BSSID in bridged connections.
2443
 * FromDS    ToDS   Sta      BSSID
2444
 * 0         0      addr1/2  addr3
2445
 * 0         1      addr2    addr1
2446
 * 1         0      addr1    addr2
2447
 * 1         1      addr2    addr1
2448
 */
2449
2450
static const unsigned char *
2451
Dot11DecryptGetStaAddress(
2452
    const DOT11DECRYPT_MAC_FRAME *frame)
2453
78
{
2454
78
    switch(DOT11DECRYPT_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2455
20
        case 0:
2456
20
            if (memcmp(frame->addr2, frame->addr3, DOT11DECRYPT_MAC_LEN) == 0)
2457
1
                return frame->addr1;
2458
19
            else
2459
19
                return frame->addr2;
2460
7
        case 1:
2461
7
            return frame->addr2;
2462
8
        case 2:
2463
8
            return frame->addr1;
2464
43
        case 3:
2465
43
            if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) < 0)
2466
20
                return frame->addr1;
2467
23
            else
2468
23
                return frame->addr2;
2469
2470
0
        default:
2471
0
            return NULL;
2472
78
    }
2473
78
}
2474
2475
static const unsigned char *
2476
Dot11DecryptGetBssidAddress(
2477
    const DOT11DECRYPT_MAC_FRAME *frame)
2478
78
{
2479
78
    switch(DOT11DECRYPT_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2480
20
        case 0:
2481
20
            return frame->addr3;
2482
7
        case 1:
2483
7
            return frame->addr1;
2484
8
        case 2:
2485
8
            return frame->addr2;
2486
43
        case 3:
2487
43
            if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) > 0)
2488
17
                return frame->addr1;
2489
26
            else
2490
26
                return frame->addr2;
2491
2492
0
        default:
2493
0
            return NULL;
2494
78
    }
2495
78
}
2496
2497
/* From IEEE 802.11-2024 Table 9-188 Cipher suite selectors and
2498
 * Table 12-8 Cipher suite key lengths */
2499
static int Dot11DecryptGetTkLen(int cipher)
2500
0
{
2501
0
    switch (cipher) {
2502
0
        case 1: return 40;   /* WEP-40 */
2503
0
        case 2: return 256;  /* TKIP */
2504
0
        case 3: return -1;   /* Reserved */
2505
0
        case 4: return 128;  /* CCMP-128 */
2506
0
        case 5: return 104;  /* WEP-104 */
2507
0
        case 6: return 128;  /* BIP-CMAC-128 */
2508
0
        case 7: return -1;   /* Group addressed traffic not allowed */
2509
0
        case 8: return 128;  /* GCMP-128 */
2510
0
        case 9: return 256;  /* GCMP-256 */
2511
0
        case 10: return 256; /* CCMP-256 */
2512
0
        case 11: return 128; /* BIP-GMAC-128 */
2513
0
        case 12: return 256; /* BIP-GMAC-256 */
2514
0
        case 13: return 256; /* BIP-CMAC-256 */
2515
0
        default:
2516
0
            ws_warning("Unknown cipher");
2517
0
            return -1;
2518
0
    }
2519
0
}
2520
2521
/* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2522
static int Dot11DecryptGetKckLen(int akm, size_t pmk_len)
2523
0
{
2524
0
    switch (akm) {
2525
0
        case 1: return 128;
2526
0
        case 2: return 128;
2527
0
        case 3: return 128;
2528
0
        case 4: return 128;
2529
0
        case 5: return 128;
2530
0
        case 6: return 128;
2531
0
        case 8: return 128;
2532
0
        case 9: return 128;
2533
0
        case 11: return 128;
2534
0
        case 12: return 192;
2535
0
        case 13: return 192;
2536
0
        case 18:
2537
0
        case 24:
2538
0
        case 25:
2539
0
            return (int)pmk_len / 2;
2540
0
        default:
2541
            /* Unknown / Not supported */
2542
0
            ws_warning("Unknown akm");
2543
0
            return -1;
2544
0
    }
2545
0
}
2546
2547
/* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2548
static int Dot11DecryptGetKekLen(int akm, size_t pmk_len)
2549
0
{
2550
0
    switch (akm) {
2551
0
        case 1: return 128;
2552
0
        case 2: return 128;
2553
0
        case 3: return 128;
2554
0
        case 4: return 128;
2555
0
        case 5: return 128;
2556
0
        case 6: return 128;
2557
0
        case 8: return 128;
2558
0
        case 9: return 128;
2559
0
        case 11: return 128;
2560
0
        case 12: return 256;
2561
0
        case 13: return 256;
2562
0
        case 18:
2563
0
        case 24:
2564
0
        case 25:
2565
0
            return pmk_len <= 256 ? 128 : 256;
2566
0
        default:
2567
            /* Unknown / Not supported */
2568
0
            ws_warning("Unknown akm");
2569
0
            return -1;
2570
0
    }
2571
0
}
2572
2573
/* From IEEE 802.11-2024 12.7.1.3 Pairwise key hierarchy and
2574
 * Table 12-11 Integrity and key-wrap algorithms */
2575
static int Dot11DecryptGetPtkLen(int akm, int cipher, size_t pmk_len)
2576
0
{
2577
0
    int kck_len = Dot11DecryptGetKckLen(akm, pmk_len);
2578
0
    int kek_len = Dot11DecryptGetKekLen(akm, pmk_len);
2579
0
    int tk_len = Dot11DecryptGetTkLen(cipher);
2580
0
    int ptk_len;
2581
2582
0
    if (kck_len == -1 || kek_len == -1 || tk_len == -1) {
2583
0
        ws_warning("Invalid PTK len");
2584
0
        return -1;
2585
0
    }
2586
0
    ptk_len = kck_len + kek_len + tk_len;
2587
2588
0
    ws_assert(ptk_len <= DOT11DECRYPT_WPA_PTK_MAX_LEN * 8);
2589
2590
0
    return ptk_len;
2591
0
}
2592
2593
/* From IEEE 802.11-2024 12.7.1.2 PRF and Table 9-190 AKM suite selectors */
2594
static int
2595
Dot11DecryptGetDeriveFuncFromAkm(int akm)
2596
0
{
2597
0
    int func = -1;
2598
0
    switch (akm) {
2599
0
        case 1:
2600
0
        case 2:
2601
0
            func = DOT11DECRYPT_DERIVE_USING_PRF;
2602
0
            break;
2603
0
        case 3:
2604
0
        case 4:
2605
0
        case 5:
2606
0
        case 6:
2607
0
        case 7:
2608
0
        case 8:
2609
0
        case 9:
2610
0
        case 10:
2611
0
        case 11:
2612
0
        case 12:
2613
0
        case 13:
2614
0
        case 18:
2615
0
        case 24:
2616
0
        case 25:
2617
0
            func = DOT11DECRYPT_DERIVE_USING_KDF;
2618
0
            break;
2619
0
        default:
2620
            /* Unknown / Not supported yet */
2621
0
            break;
2622
0
    }
2623
0
    return func;
2624
0
}
2625
2626
/* From IEEE 802.11-2024 12.7.1.2 PRF and Table 9-190 AKM suite selectors */
2627
static int
2628
Dot11DecryptGetHashAlgoFromAkm(int akm, size_t pmk_len)
2629
0
{
2630
0
    int algo = -1;
2631
0
    switch (akm) {
2632
0
        case 1:
2633
0
        case 2:
2634
0
            algo = GCRY_MD_SHA1;
2635
0
            break;
2636
0
        case 3:
2637
0
        case 4:
2638
0
        case 5:
2639
0
        case 6:
2640
0
        case 7:
2641
0
        case 8:
2642
0
        case 9:
2643
0
        case 10:
2644
0
        case 11:
2645
0
            algo = GCRY_MD_SHA256;
2646
0
            break;
2647
0
        case 12:
2648
0
        case 13:
2649
0
            algo = GCRY_MD_SHA384;
2650
0
            break;
2651
0
        case 18:
2652
0
        case 24:
2653
0
        case 25:
2654
0
            if (pmk_len == 256)
2655
0
                algo = GCRY_MD_SHA256;
2656
0
            else if (pmk_len == 384)
2657
0
                algo = GCRY_MD_SHA384;
2658
0
            else
2659
0
                algo = GCRY_MD_SHA512;
2660
0
            break;
2661
0
        default:
2662
            /* Unknown / Not supported yet */
2663
0
            break;
2664
0
    }
2665
0
    return algo;
2666
0
}
2667
2668
/* derive the PTK from the AA, SPA, PMK, SNonce, ANonce */
2669
/** From IEEE 802.11-2024 12.7.1.3 Pairwise key hierarchy:
2670
 *  PRF-Length(PMK, "Pairwise key expansion",
2671
 *      Min(AA, SPA) || Max(AA, SPA) ||
2672
 *      Min(ANonce, SNonce) || Max(ANonce, SNonce))
2673
 */
2674
static uint8_t
2675
Dot11DecryptDerivePtk(
2676
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
2677
    const unsigned char *pmk,
2678
    size_t pmk_len,
2679
    const unsigned char snonce[32],
2680
    int key_version,
2681
    int akm,
2682
    int cipher,
2683
    uint8_t *ptk, size_t *ptk_len)
2684
0
{
2685
0
    int algo = -1;
2686
0
    int ptk_len_bits = -1;
2687
0
    int derive_func;
2688
2689
0
    if (!sa || !pmk || !snonce || !ptk || !ptk_len) {
2690
0
        ws_warning("Invalid input for PTK derivation");
2691
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2692
0
    }
2693
2694
0
    if (key_version == DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP) {
2695
        /* TKIP */
2696
0
        ptk_len_bits = 512;
2697
0
        derive_func = DOT11DECRYPT_DERIVE_USING_PRF;
2698
0
        algo = GCRY_MD_SHA1;
2699
0
    } else {
2700
        /* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2701
0
        ptk_len_bits = Dot11DecryptGetPtkLen(akm, cipher, pmk_len * 8);
2702
0
        algo = Dot11DecryptGetHashAlgoFromAkm(akm, pmk_len * 8);
2703
0
        derive_func = Dot11DecryptGetDeriveFuncFromAkm(akm);
2704
0
        ws_debug("ptk_len_bits: %d, algo: %d, cipher: %d", ptk_len_bits, algo, cipher);
2705
0
    }
2706
2707
0
    if (ptk_len_bits == -1 || algo == -1) {
2708
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2709
0
    }
2710
0
    if ((size_t)ptk_len_bits / 8 > *ptk_len) {
2711
0
        ws_warning("Provided PTK buffer too small");
2712
0
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
2713
0
    }
2714
0
    *ptk_len = ptk_len_bits / 8;
2715
2716
0
    static const char *const label = "Pairwise key expansion";
2717
0
    uint8_t context[DOT11DECRYPT_MAC_LEN * 2 + 32 * 2];
2718
0
    int offset = 0;
2719
0
    const uint8_t *spa = sa->saId.sta, *aa = sa->saId.bssid;
2720
2721
0
    if (sa->wpa.mld) {
2722
0
        spa = sa->wpa.sta_mld_mac;
2723
0
        aa = sa->wpa.ap_mld_mac;
2724
0
    }
2725
2726
    /* Min(AA, SPA) || Max(AA, SPA) */
2727
0
    if (memcmp(spa, aa, DOT11DECRYPT_MAC_LEN) < 0)
2728
0
    {
2729
0
        memcpy(context + offset, spa, DOT11DECRYPT_MAC_LEN);
2730
0
        offset += DOT11DECRYPT_MAC_LEN;
2731
0
        memcpy(context + offset, aa, DOT11DECRYPT_MAC_LEN);
2732
0
        offset += DOT11DECRYPT_MAC_LEN;
2733
0
    }
2734
0
    else
2735
0
    {
2736
0
        memcpy(context + offset, aa, DOT11DECRYPT_MAC_LEN);
2737
0
        offset += DOT11DECRYPT_MAC_LEN;
2738
0
        memcpy(context + offset, spa, DOT11DECRYPT_MAC_LEN);
2739
0
        offset += DOT11DECRYPT_MAC_LEN;
2740
0
    }
2741
2742
    /* Min(ANonce, SNonce) || Max(ANonce, SNonce) */
2743
0
    if (memcmp(snonce, sa->wpa.nonce, 32) < 0 )
2744
0
    {
2745
0
        memcpy(context + offset, snonce, 32);
2746
0
        offset += 32;
2747
0
        memcpy(context + offset, sa->wpa.nonce, 32);
2748
0
        offset += 32;
2749
0
    }
2750
0
    else
2751
0
    {
2752
0
        memcpy(context + offset, sa->wpa.nonce, 32);
2753
0
        offset += 32;
2754
0
        memcpy(context + offset, snonce, 32);
2755
0
        offset += 32;
2756
0
    }
2757
0
    if (derive_func == DOT11DECRYPT_DERIVE_USING_PRF) {
2758
0
        dot11decrypt_prf(pmk, pmk_len, label, context, offset, algo,
2759
0
                         ptk, *ptk_len);
2760
0
    } else {
2761
0
        dot11decrypt_kdf(pmk, pmk_len, label, context, offset, algo,
2762
0
                         ptk, *ptk_len);
2763
0
    }
2764
0
    DEBUG_DUMP("PTK", ptk, *ptk_len, LOG_LEVEL_DEBUG);
2765
0
    return DOT11DECRYPT_RET_SUCCESS;
2766
0
}
2767
2768
/**
2769
 * For Fast BSS Transition AKMS derive PTK from sa, selected key and various information in
2770
 * eapol key frame.
2771
 * From IEEE 802.11-2016 12.7.1.7.1
2772
 */
2773
static uint8_t
2774
Dot11DecryptFtDerivePtk(
2775
    const PDOT11DECRYPT_CONTEXT ctx,
2776
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
2777
    const PDOT11DECRYPT_KEY_ITEM key,
2778
    const uint8_t mdid[2],
2779
    const uint8_t *snonce,
2780
    const uint8_t *r0kh_id, size_t r0kh_id_len,
2781
    const uint8_t *r1kh_id, size_t r1kh_id_len _U_,
2782
    int akm, int cipher,
2783
    uint8_t *ptk, size_t *ptk_len)
2784
0
{
2785
0
    int hash_algo;
2786
0
    uint8_t pmk_r0[DOT11DECRYPT_WPA_PMK_MAX_LEN];
2787
0
    uint8_t pmk_r1[DOT11DECRYPT_WPA_PMK_MAX_LEN];
2788
0
    uint8_t pmk_r0_name[16] = {0};
2789
0
    uint8_t pmk_r1_name[16] = {0};
2790
0
    uint8_t ptk_name[16];
2791
0
    size_t pmk_r0_len = 0;
2792
0
    size_t pmk_r1_len = 0;
2793
0
    const uint8_t *xxkey = NULL;
2794
0
    size_t xxkey_len;
2795
0
    int ptk_len_bits;
2796
2797
0
    if (!sa || !key || !mdid || !snonce || !r0kh_id || !r1kh_id || !ptk || !ptk_len) {
2798
0
        ws_warning("Invalid input for FT PTK derivation");
2799
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2800
0
    }
2801
2802
0
    if (key->KeyType == DOT11DECRYPT_KEY_TYPE_MSK) {
2803
0
        xxkey = Dot11DecryptGetXXKeyFromMSK(key->Msk.Msk,
2804
0
                                            key->Msk.Len,
2805
0
                                            akm,
2806
0
                                            &xxkey_len);
2807
0
    }
2808
0
    if (!xxkey && key->KeyData.Wpa.PskLen > 0) {
2809
0
        xxkey = key->KeyData.Wpa.Psk;
2810
0
        xxkey_len = key->KeyData.Wpa.PskLen;
2811
0
    }
2812
0
    if (!xxkey) {
2813
0
        ws_debug("no xxkey. Skipping");
2814
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2815
0
    }
2816
0
    hash_algo = Dot11DecryptGetHashAlgoFromAkm(akm, xxkey_len * 8);
2817
0
    ptk_len_bits = Dot11DecryptGetPtkLen(akm, cipher, xxkey_len * 8);
2818
0
    if (ptk_len_bits == -1) {
2819
0
        ws_warning("Invalid akm or cipher");
2820
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2821
0
    }
2822
0
    if ((size_t)ptk_len_bits / 8 > *ptk_len) {
2823
0
        ws_warning("Provided PTK buffer too small");
2824
0
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
2825
0
    }
2826
0
    *ptk_len = ptk_len_bits / 8;
2827
0
    if (!dot11decrypt_derive_pmk_r0(xxkey, xxkey_len,
2828
0
                               ctx->pkt_ssid, ctx->pkt_ssid_len,
2829
0
                               mdid,
2830
0
                               r0kh_id, r0kh_id_len,
2831
0
                               sa->saId.sta, hash_algo,
2832
0
                               pmk_r0, &pmk_r0_len, pmk_r0_name)) {
2833
        /* This can fail for bad size or a bad SHA256 sum. */
2834
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2835
0
    }
2836
0
    DEBUG_DUMP("PMK-R0", pmk_r0, pmk_r0_len, LOG_LEVEL_DEBUG);
2837
0
    DEBUG_DUMP("PMKR0Name", pmk_r0_name, 16, LOG_LEVEL_DEBUG);
2838
2839
0
    if (!dot11decrypt_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name,
2840
0
                               r1kh_id, sa->saId.sta, hash_algo,
2841
0
                               pmk_r1, &pmk_r1_len, pmk_r1_name)) {
2842
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2843
0
    }
2844
0
    DEBUG_DUMP("PMK-R1", pmk_r1, pmk_r1_len, LOG_LEVEL_DEBUG);
2845
0
    DEBUG_DUMP("PMKR1Name", pmk_r1_name, 16, LOG_LEVEL_DEBUG);
2846
2847
    // Reference: IEEE 802.11be-2024 12.7.1.6.5
2848
0
    const uint8_t *sta_addr = sa->saId.sta, *bssid = sa->saId.bssid;
2849
0
    if (sa->wpa.mld) {
2850
0
        sta_addr = sa->wpa.sta_mld_mac;
2851
0
        bssid = sa->wpa.ap_mld_mac;
2852
0
    }
2853
2854
0
    if (!dot11decrypt_derive_ft_ptk(pmk_r1, pmk_r1_len, pmk_r1_name,
2855
0
                               snonce, sa->wpa.nonce,
2856
0
                               bssid, sta_addr, hash_algo,
2857
0
                               ptk, *ptk_len, ptk_name)) {
2858
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2859
0
    }
2860
0
    DEBUG_DUMP("PTK", ptk, *ptk_len, LOG_LEVEL_DEBUG);
2861
0
    return DOT11DECRYPT_RET_SUCCESS;
2862
0
}
2863
2864
0
#define MAX_SSID_LENGTH 32 /* maximum SSID length */
2865
2866
static int
2867
Dot11DecryptRsnaPwd2Psk(
2868
    const struct DOT11DECRYPT_KEY_ITEMDATA_PWD *userPwd,
2869
    unsigned char *output)
2870
0
{
2871
0
    if (userPwd->SsidLen> MAX_SSID_LENGTH) {
2872
        /* This "should not happen" */
2873
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2874
0
    }
2875
0
    if (gcry_kdf_derive(userPwd->Passphrase, userPwd->PassphraseLen, GCRY_KDF_PBKDF2,
2876
0
                        GCRY_MD_SHA1, userPwd->Ssid, userPwd->SsidLen, 4096,
2877
0
                        DOT11DECRYPT_WPA_PWD_PSK_LEN, output)) {
2878
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2879
0
    }
2880
2881
0
    return DOT11DECRYPT_RET_SUCCESS;
2882
0
}
2883
2884
/*
2885
 * Returns the decryption_key_t struct given a string describing the key.
2886
 * Returns NULL if the input_string cannot be parsed.
2887
 * XXX: Should return an error string explaining why parsing failed
2888
 */
2889
decryption_key_t*
2890
parse_key_string(char* input_string, uint8_t key_type, char** error)
2891
0
{
2892
0
    GByteArray *ssid_ba = NULL, *key_ba;
2893
2894
0
    char **tokens;
2895
0
    unsigned n = 0;
2896
0
    decryption_key_t *dk;
2897
2898
0
    if(input_string == NULL || (strcmp(input_string, "") == 0)) {
2899
0
        if (error) {
2900
0
            *error = g_strdup("Key cannot be empty");
2901
0
        }
2902
0
        return NULL;
2903
0
    }
2904
2905
    /*
2906
     * Parse the input_string. WEP and WPA will be just a string
2907
     * of hexadecimal characters (if key is wrong, null will be
2908
     * returned...).
2909
     * WPA-PWD should be in the form
2910
     * <key data>[:<ssid>]
2911
     * With WPA-PWD, we percent-decode the key data and ssid.
2912
     * The percent itself ("%25") and the colon ("%3a") must be
2913
     * percent-encoded, the latter so we can distinguish between the
2914
     * separator and a colon in the key or ssid. Percent-encoding
2915
     * for anything else is optional. (NUL is not allowed, either
2916
     * percent-encoded or not.)
2917
     */
2918
2919
0
    switch(key_type)
2920
0
    {
2921
0
    case DOT11DECRYPT_KEY_TYPE_WEP:
2922
0
    case DOT11DECRYPT_KEY_TYPE_WEP_40:
2923
0
    case DOT11DECRYPT_KEY_TYPE_WEP_104:
2924
2925
0
        key_ba = g_byte_array_new();
2926
2927
0
        if (!hex_str_to_bytes(input_string, key_ba, false)) {
2928
0
            if (error) {
2929
0
                *error = g_strdup("WEP key must be a hexadecimal string");
2930
0
            }
2931
0
            g_byte_array_free(key_ba, true);
2932
0
            return NULL;
2933
0
        }
2934
2935
0
        if (key_ba->len > 0 && key_ba->len <= DOT11DECRYPT_WEP_KEY_MAXLEN) {
2936
            /* Key is correct! It was probably an 'old style' WEP key */
2937
            /* Create the decryption_key_t structure, fill it and return it*/
2938
0
            dk = g_new0(decryption_key_t, 1);
2939
2940
0
            dk->type = DOT11DECRYPT_KEY_TYPE_WEP;
2941
0
            dk->key  = key_ba;
2942
0
            dk->bits = key_ba->len * 8;
2943
0
            dk->ssid = NULL;
2944
2945
0
            return dk;
2946
0
        }
2947
2948
0
        if (error) {
2949
0
            *error = ws_strdup_printf("WEP key entered is %u bytes, and must be no more than %u", key_ba->len, DOT11DECRYPT_WEP_KEY_MAXLEN);
2950
0
        }
2951
        /* Key doesn't work */
2952
0
        g_byte_array_free(key_ba, true);
2953
0
        return NULL;
2954
2955
0
    case DOT11DECRYPT_KEY_TYPE_WPA_PWD:
2956
2957
0
        tokens = g_strsplit(input_string,":", 3);
2958
0
        n = g_strv_length(tokens);
2959
2960
0
        if (n < 1 || n > 2)
2961
0
        {
2962
            /* Require either one or two tokens; more, and the user
2963
             * may have meant a colon in the passphrase or SSID name
2964
             */
2965
            /* Free the array of strings */
2966
            /* XXX: Return why parsing failed (":" must be escaped) */
2967
0
            if (error) {
2968
0
                *error = g_strdup("Only one ':' is allowed, as a separator between passphrase and SSID; others must be percent-encoded as \"%%3a\"");
2969
0
            }
2970
0
            g_strfreev(tokens);
2971
0
            return NULL;
2972
0
        }
2973
2974
        /*
2975
         * The first token is the key
2976
         */
2977
0
        key_ba = g_byte_array_new();
2978
0
        if (! uri_str_to_bytes(tokens[0], key_ba)) {
2979
            /* Failed parsing as percent-encoded */
2980
0
            if (error) {
2981
0
                *error = g_strdup("WPA passphrase is treated as percent-encoded; use \"%%25\" for a literal \"%%\"");
2982
0
            }
2983
0
            g_byte_array_free(key_ba, true);
2984
0
            g_strfreev(tokens);
2985
0
            return NULL;
2986
0
        }
2987
2988
        /* key length (after percent-decoding) should be between 8 and 63
2989
         * octets (63 to distinguish from a PSK as 64 hex characters.)
2990
         * XXX: 802.11-2016 Annex J assumes that each character in the
2991
         * pass-phrase is ASCII printable ("has an encoding in the range
2992
         * 32 to 126"), though this (and the entire algorithm for that
2993
         * matter) is only considered a suggestion.
2994
         * It is possible to apply PBKDF2 to any octet string, e.g. UTF-8.
2995
         * (wpa_passphrase from wpa_supplicant will do so, for example.)
2996
         */
2997
0
        if( ((key_ba->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_ba->len) < WPA_KEY_MIN_CHAR_SIZE))
2998
0
        {
2999
0
            if (error) {
3000
0
                *error = ws_strdup_printf("WPA passphrase entered is %u characters after percent-decoding and must be between %u and %u", key_ba->len, WPA_KEY_MIN_CHAR_SIZE, WPA_KEY_MAX_CHAR_SIZE);
3001
0
            }
3002
0
            g_byte_array_free(key_ba, true);
3003
3004
            /* Free the array of strings */
3005
0
            g_strfreev(tokens);
3006
0
            return NULL;
3007
0
        }
3008
3009
0
        ssid_ba = NULL;
3010
0
        if (n >= 2) /* more than two tokens found, means that the user specified the ssid */
3011
0
        {
3012
0
            ssid_ba = g_byte_array_new();
3013
0
            if (! uri_str_to_bytes(tokens[1], ssid_ba)) {
3014
0
                if (error) {
3015
0
                    *error = g_strdup("WPA SSID is treated as percent-encoded; use \"%%25\" for a literal \"%%\".");
3016
0
                }
3017
0
                g_byte_array_free(key_ba, true);
3018
0
                g_byte_array_free(ssid_ba, true);
3019
                /* Free the array of strings */
3020
0
                g_strfreev(tokens);
3021
0
                return NULL;
3022
0
            }
3023
3024
0
            if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
3025
0
            {
3026
0
                if (error) {
3027
0
                    *error = ws_strdup_printf("WPA SSID entered is %u characters after percent-decoding and must be no more than %u", ssid_ba->len, WPA_SSID_MAX_CHAR_SIZE);
3028
0
                }
3029
0
                g_byte_array_free(key_ba, true);
3030
0
                g_byte_array_free(ssid_ba, true);
3031
3032
                /* Free the array of strings */
3033
0
                g_strfreev(tokens);
3034
0
                return NULL;
3035
0
            }
3036
0
        }
3037
3038
        /* Key was correct!!! Create the new decryption_key_t ... */
3039
0
        dk = g_new0(decryption_key_t, 1);
3040
3041
0
        dk->type = DOT11DECRYPT_KEY_TYPE_WPA_PWD;
3042
0
        dk->key  = key_ba;
3043
0
        dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
3044
0
        dk->ssid = ssid_ba; /* NULL if ssid_ba is NULL */
3045
3046
        /* Free the array of strings */
3047
0
        g_strfreev(tokens);
3048
0
        return dk;
3049
3050
0
    case DOT11DECRYPT_KEY_TYPE_WPA_PSK:
3051
3052
0
        key_ba = g_byte_array_new();
3053
0
        if (!hex_str_to_bytes(input_string, key_ba, false)) {
3054
0
            if (error) {
3055
0
                *error = g_strdup("WPA PSK/PMK must be a hexadecimal string");
3056
0
            }
3057
0
            g_byte_array_free(key_ba, true);
3058
0
            return NULL;
3059
0
        }
3060
3061
        /* Two tokens means that the user should have entered a WPA-BIN key ... */
3062
0
        if((key_ba->len != DOT11DECRYPT_WPA_PWD_PSK_LEN &&
3063
0
            key_ba->len != 48 &&
3064
0
            key_ba->len != DOT11DECRYPT_WPA_PMK_MAX_LEN))
3065
0
        {
3066
0
            if (error) {
3067
0
                *error = ws_strdup_printf("WPA Pre-Master Key/Pairwise Master Key entered is %u bytes and must be 32, 48 or 64", key_ba->len);
3068
0
            }
3069
0
            g_byte_array_free(key_ba, true);
3070
0
            return NULL;
3071
0
        }
3072
3073
        /* Key was correct!!! Create the new decryption_key_t ... */
3074
0
        dk = g_new0(decryption_key_t, 1);
3075
3076
0
        dk->type = DOT11DECRYPT_KEY_TYPE_WPA_PSK;
3077
0
        dk->key  = key_ba;
3078
0
        dk->bits = (unsigned) dk->key->len * 8;
3079
0
        dk->ssid = NULL;
3080
3081
0
        return dk;
3082
3083
0
    case DOT11DECRYPT_KEY_TYPE_TK:
3084
0
        {
3085
0
            tokens = g_strsplit(input_string,":", 3);
3086
0
            n = g_strv_length(tokens);
3087
0
            if (!(n == 1 || n == 3))
3088
0
            {
3089
                /* Free the array of strings */
3090
0
                if (error) {
3091
0
                    *error = g_strdup("TK must be in TK[:AP MLD MAC:STA MLD MAC] format");
3092
0
                }
3093
0
                g_strfreev(tokens);
3094
0
                return NULL;
3095
0
            }
3096
            /* From IEEE 802.11-2024 Table 12-8 Cipher suite key lengths */
3097
0
            static const uint8_t allowed_key_lengths[] = {
3098
// TBD          40 / 8,  /* WEP-40 */
3099
// TBD          104 / 8, /* WEP-104 */
3100
0
                128 / 8, /* CCMP-128, GCMP-128 */
3101
0
                256 / 8, /* TKIP, GCMP-256, CCMP-256 */
3102
0
            };
3103
0
            bool key_length_ok = false;
3104
3105
0
            key_ba = g_byte_array_new();
3106
0
            if (!hex_str_to_bytes(tokens[0], key_ba, false)) {
3107
0
                if (error) {
3108
0
                    *error = g_strdup("Temporal Key must be a hexadecimal string");
3109
0
                }
3110
0
                g_byte_array_free(key_ba, true);
3111
0
                g_strfreev(tokens);
3112
0
                return NULL;
3113
0
            }
3114
3115
0
            for (size_t i = 0; i < sizeof(allowed_key_lengths); i++) {
3116
0
                if (key_ba->len == allowed_key_lengths[i]) {
3117
0
                    key_length_ok = true;
3118
0
                    break;
3119
0
                }
3120
0
            }
3121
0
            if (!key_length_ok) {
3122
0
                if (error) {
3123
0
                    GString *err_string = g_string_new("Temporal Keys entered is ");
3124
0
                    g_string_append_printf(err_string, "%u bytes and must be ", key_ba->len);
3125
0
                    size_t i = 0;
3126
0
                    for (; i + 1 < sizeof(allowed_key_lengths); i++) {
3127
0
                        g_string_append_printf(err_string, "%u, ", allowed_key_lengths[i]);
3128
0
                    }
3129
0
                    g_string_append_printf(err_string, "or %u bytes.", allowed_key_lengths[i]);
3130
0
                    *error = g_string_free(err_string, FALSE);
3131
0
                }
3132
0
                g_byte_array_free(key_ba, true);
3133
0
                g_strfreev(tokens);
3134
0
                return NULL;
3135
0
            }
3136
0
            dk = g_new0(decryption_key_t, 1);
3137
3138
0
            if (n == 3) {
3139
0
                dk->tk_mld = true;
3140
0
                GByteArray *mac = g_byte_array_new();
3141
0
                for (size_t i = 1; i <= 2; ++i) {
3142
0
                    if (!hex_str_to_bytes(tokens[i], mac, false) || mac->len != 6) {
3143
0
                        if (error) {
3144
0
                            *error = g_strdup("MAC must be a 6 bytes hexadecimal string");
3145
0
                        }
3146
0
                        g_byte_array_free(mac, true);
3147
0
                        g_free(dk);
3148
0
                        g_byte_array_free(key_ba, true);
3149
0
                        g_strfreev(tokens);
3150
0
                        return NULL;
3151
0
                    }
3152
0
                    if (i == 1)
3153
0
                        memcpy(dk->ap_mld_mac, mac->data, 6);
3154
0
                    else
3155
0
                        memcpy(dk->sta_mld_mac, mac->data, 6);
3156
0
                }
3157
0
                g_byte_array_free(mac, true);
3158
0
            }
3159
3160
0
            dk->type = DOT11DECRYPT_KEY_TYPE_TK;
3161
0
            dk->key  = key_ba;
3162
0
            dk->bits = (unsigned) dk->key->len * 8;
3163
0
            dk->ssid = NULL;
3164
3165
            /* Free the array of strings */
3166
0
            g_strfreev(tokens);
3167
0
            return dk;
3168
0
        }
3169
0
    case DOT11DECRYPT_KEY_TYPE_MSK:
3170
0
        {
3171
0
            key_ba = g_byte_array_new();
3172
0
            if (!hex_str_to_bytes(input_string, key_ba, false)) {
3173
0
                if (error) {
3174
0
                    *error = g_strdup("Master Session Key must be a hexadecimal string");
3175
0
                }
3176
0
                g_byte_array_free(key_ba, true);
3177
0
                return NULL;
3178
0
            }
3179
3180
0
            if (key_ba->len < DOT11DECRYPT_MSK_MIN_LEN ||
3181
0
                key_ba->len > DOT11DECRYPT_MSK_MAX_LEN)
3182
0
            {
3183
0
                if (error) {
3184
0
                    *error = ws_strdup_printf("Master Session Key entered is %u bytes and must be between %u and %u", key_ba->len, DOT11DECRYPT_MSK_MIN_LEN, DOT11DECRYPT_MSK_MAX_LEN);
3185
0
                }
3186
0
                g_byte_array_free(key_ba, true);
3187
0
                return NULL;
3188
0
            }
3189
0
            dk = g_new0(decryption_key_t, 1);
3190
0
            dk->type = DOT11DECRYPT_KEY_TYPE_MSK;
3191
0
            dk->key  = key_ba;
3192
0
            dk->bits = (unsigned)dk->key->len * 8;
3193
0
            dk->ssid = NULL;
3194
0
            return dk;
3195
0
        }
3196
0
    }
3197
3198
    /* Type not supported */
3199
0
    if (error) {
3200
0
        *error = g_strdup("Unknown key type not supported");
3201
0
    }
3202
0
    return NULL;
3203
0
}
3204
3205
void
3206
free_key_string(decryption_key_t *dk)
3207
0
{
3208
0
    if (dk->key)
3209
0
        g_byte_array_free(dk->key, true);
3210
0
    if (dk->ssid)
3211
0
        g_byte_array_free(dk->ssid, true);
3212
0
    g_free(dk);
3213
0
}
3214
3215
static int
3216
Dot11DecryptTDLSDeriveKey(
3217
    PDOT11DECRYPT_SEC_ASSOCIATION sa,
3218
    const uint8_t *data,
3219
    unsigned offset_rsne,
3220
    unsigned offset_fte,
3221
    unsigned offset_timeout,
3222
    unsigned offset_link,
3223
    uint8_t action)
3224
0
{
3225
3226
0
    gcry_md_hd_t sha256_handle;
3227
0
    gcry_md_hd_t hmac_handle;
3228
0
    const uint8_t *snonce, *anonce, *initiator, *responder, *bssid;
3229
0
    uint8_t key_input[32];
3230
0
    uint8_t mic[16], seq_num = action + 1;
3231
0
    uint8_t zeros[16] = { 0 };
3232
0
    gcry_mac_hd_t cmac_handle;
3233
0
    size_t cmac_len = 16;
3234
0
    size_t cmac_write_len;
3235
3236
    /* Get key input */
3237
0
    anonce = &data[offset_fte + 20];
3238
0
    snonce = &data[offset_fte + 52];
3239
3240
0
    if (gcry_md_open (&sha256_handle, GCRY_MD_SHA256, 0)) {
3241
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3242
0
    }
3243
0
    if (memcmp(anonce, snonce, DOT11DECRYPT_WPA_NONCE_LEN) < 0) {
3244
0
        gcry_md_write(sha256_handle, anonce, DOT11DECRYPT_WPA_NONCE_LEN);
3245
0
        gcry_md_write(sha256_handle, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3246
0
    } else {
3247
0
        gcry_md_write(sha256_handle, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3248
0
        gcry_md_write(sha256_handle, anonce, DOT11DECRYPT_WPA_NONCE_LEN);
3249
0
    }
3250
0
    memcpy(key_input, gcry_md_read(sha256_handle, 0), 32);
3251
0
    gcry_md_close(sha256_handle);
3252
3253
    /* Derive key */
3254
0
    bssid = &data[offset_link + 2];
3255
0
    initiator = &data[offset_link + 8];
3256
0
    responder = &data[offset_link + 14];
3257
0
    if (gcry_md_open(&hmac_handle, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC)) {
3258
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3259
0
    }
3260
0
    if (gcry_md_setkey(hmac_handle, key_input, 32)) {
3261
0
        gcry_md_close(hmac_handle);
3262
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3263
0
    }
3264
0
    gcry_md_putc(hmac_handle, 1);
3265
0
    gcry_md_putc(hmac_handle, 0);
3266
0
    gcry_md_write(hmac_handle, "TDLS PMK", 8);
3267
0
    if (memcmp(initiator, responder, DOT11DECRYPT_MAC_LEN) < 0) {
3268
0
          gcry_md_write(hmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3269
0
          gcry_md_write(hmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3270
0
    } else {
3271
0
          gcry_md_write(hmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3272
0
          gcry_md_write(hmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3273
0
    }
3274
0
    gcry_md_write(hmac_handle, bssid, DOT11DECRYPT_MAC_LEN);
3275
0
    gcry_md_putc(hmac_handle, 0);
3276
0
    gcry_md_putc(hmac_handle, 1);
3277
0
    memcpy(key_input, gcry_md_read(hmac_handle, 0), 32);
3278
0
    gcry_md_close(hmac_handle);
3279
3280
    /* Check MIC */
3281
0
    if (gcry_mac_open(&cmac_handle, GCRY_MAC_CMAC_AES, 0, NULL)) {
3282
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3283
0
    }
3284
0
    if (gcry_mac_setkey(cmac_handle, key_input, 16)) {
3285
0
        gcry_mac_close(cmac_handle);
3286
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3287
0
    }
3288
0
    gcry_mac_write(cmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3289
0
    gcry_mac_write(cmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3290
0
    gcry_mac_write(cmac_handle, &seq_num, 1);
3291
0
    gcry_mac_write(cmac_handle, &data[offset_link], data[offset_link + 1] + 2);
3292
0
    gcry_mac_write(cmac_handle, &data[offset_rsne], data[offset_rsne + 1] + 2);
3293
0
    gcry_mac_write(cmac_handle, &data[offset_timeout], data[offset_timeout + 1] + 2);
3294
0
    gcry_mac_write(cmac_handle, &data[offset_fte], 4);
3295
0
    gcry_mac_write(cmac_handle, zeros, 16);
3296
0
    cmac_write_len = data[offset_fte + 1] + 2;
3297
0
    if (cmac_write_len < 20) {
3298
0
        ws_warning("Bad MAC len");
3299
0
        gcry_mac_close(cmac_handle);
3300
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3301
0
    }
3302
0
    gcry_mac_write(cmac_handle, &data[offset_fte + 20], cmac_write_len - 20);
3303
0
    if (gcry_mac_read(cmac_handle, mic, &cmac_len) != GPG_ERR_NO_ERROR) {
3304
0
        ws_warning("MAC read error");
3305
0
        gcry_mac_close(cmac_handle);
3306
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3307
0
    }
3308
0
    if (memcmp(mic, &data[offset_fte + 4], 16)) {
3309
0
        ws_debug("MIC verification failed");
3310
0
        gcry_mac_close(cmac_handle);
3311
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3312
0
    }
3313
0
    gcry_mac_close(cmac_handle);
3314
    /* TODO support other akm and ciphers? */
3315
0
    sa->wpa.akm = 2;
3316
0
    sa->wpa.cipher = 4;
3317
0
    sa->wpa.ptk_len = Dot11DecryptGetPtkLen(sa->wpa.akm, sa->wpa.cipher, sa->wpa.pmk_len * 8) / 8;
3318
0
    memcpy(DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
3319
0
           key_input + 16, Dot11DecryptGetTkLen(sa->wpa.cipher) / 8);
3320
0
    memcpy(sa->wpa.nonce, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3321
0
    sa->validKey = true;
3322
0
    sa->wpa.key_ver = DOT11DECRYPT_WPA_KEY_VER_AES_CCMP;
3323
0
    ws_debug("MIC verified");
3324
0
    return  DOT11DECRYPT_RET_SUCCESS;
3325
0
}
3326
3327
3328
#ifdef __cplusplus
3329
}
3330
#endif
3331
3332
/****************************************************************************/
3333
3334
/*
3335
 * Editor modelines
3336
 *
3337
 * Local Variables:
3338
 * c-basic-offset: 4
3339
 * tab-width: 8
3340
 * indent-tabs-mode: nil
3341
 * End:
3342
 *
3343
 * ex: set shiftwidth=4 tabstop=8 expandtab:
3344
 * :indentSize=4:tabSize=8:noTabs=true:
3345
 */