Coverage Report

Created: 2026-08-14 06:45

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
188
{
512
188
    return (DOT11DECRYPT_SEC_ASSOCIATION *)g_hash_table_lookup(ctx->sa_hash, id);
513
188
}
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
40
{
628
40
    unsigned offset = 0;
629
40
    unsigned tot_len_left = tot_len;
630
40
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
631
40
    PDOT11DECRYPT_SEC_ASSOCIATION sa;
632
40
    const uint8_t *initiator, *responder;
633
40
    uint8_t action;
634
40
    unsigned status, offset_rsne = 0, offset_fte = 0, offset_link = 0, offset_timeout = 0;
635
40
    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
40
    if (tot_len_left < 1) {
641
0
        ws_debug("Not EAPOL-Key");
642
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
643
0
    }
644
40
    action = data[offset];
645
40
    if (action != 1 && action != 2) {
646
14
        ws_debug("Not Response nor confirm");
647
14
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
648
14
    }
649
26
    offset++;
650
26
    tot_len_left--;
651
652
    /* Check for SUCCESS (0) or SUCCESS_POWER_SAVE_MODE (85) Status Code */
653
26
    if (tot_len_left < 5) {
654
1
        ws_debug("Not EAPOL-Key");
655
1
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
656
1
    }
657
25
    status=pntohu16(data + offset);
658
25
    if (status != 0 && status != 85) {
659
2
        ws_debug("TDLS setup not successful");
660
2
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
661
2
    }
662
663
    /* skip Token + capabilities */
664
23
    offset += 5;
665
666
    /* search for RSN, Fast BSS Transition, Link Identifier and Timeout Interval IEs */
667
668
409
    while(offset < (tot_len - 2)) {
669
406
        uint8_t element_id = data[offset];
670
406
        uint8_t length = data[offset + 1];
671
406
        unsigned min_length = length;
672
406
        switch (element_id) {
673
7
        case 48:    /* RSN (802.11-2016 9.4.2.35) */
674
7
            offset_rsne = offset;
675
7
            min_length = 1;
676
7
            break;
677
5
        case 55:    /* FTE (802.11-2016 9.4.2.48) */
678
5
            offset_fte = offset;
679
            /* Plus variable length optional parameter(s) */
680
5
            min_length = 2 + 16 + 32 + 32;
681
5
            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
2
        case 101:   /* Link Identifier (802.11-2016 9.4.2.62) */
687
2
            offset_link = offset;
688
2
            min_length = 6 + 6 + 6;
689
2
            break;
690
406
        }
691
692
406
        if (length < min_length || tot_len < offset + 2 + length) {
693
20
            ws_debug("Invalid length records in IEs");
694
20
            return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
695
20
        }
696
386
        offset += 2 + length;
697
386
    }
698
699
3
    if (offset_rsne == 0 || offset_fte == 0 ||
700
0
        offset_timeout == 0 || offset_link == 0)
701
3
    {
702
3
        ws_debug("Cannot Find all necessary IEs");
703
3
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
704
3
    }
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
83
{
905
83
    int nbr = 0;
906
83
    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
83
    return nbr;
912
83
}
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
280
{
1004
280
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
1005
280
    DISSECTOR_ASSERT(decrypt_data);
1006
280
    DISSECTOR_ASSERT(decrypt_len);
1007
1008
280
    if (decrypt_len) {
1009
280
        *decrypt_len = 0;
1010
280
    }
1011
280
    if (ctx==NULL) {
1012
0
        ws_warning("NULL context");
1013
0
        return DOT11DECRYPT_RET_REQ_DATA;
1014
0
    }
1015
280
    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
280
    if (tot_len < (unsigned)(mac_header_len+DOT11DECRYPT_CRYPTED_DATA_MINLEN)) {
1022
61
        ws_debug("minimum length violated");
1023
61
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
1024
61
    }
1025
1026
    /* Assume that the decrypt_data field is no more than this size. */
1027
219
    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
219
    if (Dot11DecryptGetSaAddress(data, mac_header_len, &id) != DOT11DECRYPT_RET_SUCCESS) {
1034
28
        ws_noisy("STA/BSSID not found");
1035
28
        return DOT11DECRYPT_RET_REQ_DATA;
1036
28
    }
1037
1038
    /* check if data is encrypted (use the WEP bit in the Frame Control field) */
1039
191
    if (DOT11DECRYPT_WEP(data[1])==0) {
1040
3
        return DOT11DECRYPT_RET_NO_DATA_ENCRYPTED;
1041
3
    }
1042
188
    PDOT11DECRYPT_SEC_ASSOCIATION sa;
1043
1044
    /* create new header and data to modify */
1045
188
    *decrypt_len = tot_len;
1046
188
    memcpy(decrypt_data, data, *decrypt_len);
1047
1048
    /* encrypted data */
1049
188
    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
188
    if (DOT11DECRYPT_EXTIV(data[mac_header_len + 3]) == 0) {
1056
105
        ws_noisy("WEP encryption");
1057
105
        return Dot11DecryptWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, &id);
1058
105
    } else {
1059
83
        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
83
        if (((const DOT11DECRYPT_MAC_FRAME_ADDR4 *)(data))->addr1[0] & 0x01) {
1066
49
            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
49
            memcpy(id.sta, broadcast_mac, DOT11DECRYPT_MAC_LEN);
1070
49
        }
1071
        /* search for a cached Security Association for current BSSID and STA/broadcast MAC */
1072
83
        int ret = DOT11DECRYPT_RET_REQ_DATA;
1073
83
        sa = Dot11DecryptGetSa(ctx, &id);
1074
83
        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
83
        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
83
        return ret;
1083
83
     }
1084
0
    return DOT11DECRYPT_RET_UNSUCCESS;
1085
188
}
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
3.05k
{
1172
3.05k
    if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
1173
2.65k
        return DOT11DECRYPT_RET_UNSUCCESS;
1174
1175
408
    memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
1176
408
    ctx->pkt_ssid_len = pkt_ssid_len;
1177
1178
408
    return DOT11DECRYPT_RET_SUCCESS;
1179
3.05k
}
1180
1181
static unsigned
1182
Dot11DecryptSaHash(const void *key)
1183
188
{
1184
188
    GBytes *bytes = g_bytes_new_static(key, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID));
1185
188
    unsigned hash = g_bytes_hash(bytes);
1186
188
    g_bytes_unref(bytes);
1187
188
    return hash;
1188
188
}
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
105
{
1400
105
    unsigned char wep_key[DOT11DECRYPT_WEP_KEY_MAXLEN+DOT11DECRYPT_WEP_IVLEN];
1401
105
    size_t keylen;
1402
105
    int ret_value=1;
1403
105
    int key_index;
1404
105
    DOT11DECRYPT_KEY_ITEM *tmp_key;
1405
105
    uint8_t useCache=false;
1406
105
    unsigned char *try_data;
1407
105
    DOT11DECRYPT_SEC_ASSOCIATION *sa;
1408
105
    unsigned try_data_len = *decrypt_len;
1409
105
    ssize_t ciphertext_len = (ssize_t)*decrypt_len -
1410
105
                             (ssize_t)(mac_header_len + DOT11DECRYPT_WEP_HEADER + DOT11DECRYPT_WEP_TRAILER);
1411
1412
105
    if (ciphertext_len < 1) {
1413
0
        ws_debug("Decryption length too short");
1414
0
        return DOT11DECRYPT_RET_UNSUCCESS;
1415
0
    }
1416
1417
105
    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
105
    sa = Dot11DecryptGetSa(ctx, id);
1426
105
    if (sa != NULL && sa->key != NULL) {
1427
0
        useCache = true;
1428
0
    }
1429
1430
105
    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
105
    g_free(try_data);
1497
105
    if (ret_value)
1498
105
        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
105
}
1514
1515
/* From IEEE 802.11-2024 Table 9-190—AKM suite selectors */
1516
static bool Dot11DecryptIsFtAkm(int akm)
1517
909
{
1518
909
    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
909
    }
1526
909
    return false;
1527
909
}
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
909
{
1931
909
    DOT11DECRYPT_SEC_ASSOCIATION_ID id;
1932
1933
909
    ws_debug("(Re)Association packet");
1934
1935
909
    if (!ctx || !assoc_parsed) {
1936
0
        ws_warning("Invalid input parameters");
1937
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1938
0
    }
1939
909
    if (!Dot11DecryptIsFtAkm(assoc_parsed->akm)) {
1940
909
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
1941
909
    }
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
    fte_len = assoc_parsed->fte_tag[1] + 2;
2229
0
    if (fte_len < 20) {
2230
0
        ws_debug("FTE too short");
2231
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2232
0
    }
2233
2234
0
    mic_len = assoc_parsed->fte.mic_len;
2235
0
    if (mic_len > sizeof(zeros)) {
2236
0
        ws_debug("MIC too long");
2237
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2238
0
    }
2239
2240
0
    switch (assoc_parsed->frame_subtype) {
2241
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_REQ:
2242
0
            sta = assoc_parsed->sa;
2243
0
            seq_num = 3;
2244
0
            break;
2245
0
        case DOT11DECRYPT_SUBTYPE_ASSOC_RESP:
2246
0
            sta = assoc_parsed->da;
2247
0
            seq_num = 4;
2248
0
            break;
2249
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_REQ:
2250
0
            sta = assoc_parsed->sa;
2251
0
            seq_num = 5;
2252
0
            break;
2253
0
        case DOT11DECRYPT_SUBTYPE_REASSOC_RESP:
2254
0
            sta = assoc_parsed->da;
2255
0
            seq_num = 6;
2256
0
            break;
2257
0
        default:
2258
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2259
0
    }
2260
2261
    /* For AKM 25, length of KCK is half of PMK while for other AKMs, pmk_len is not used. */
2262
0
    if (Dot11DecryptGetIntegrityAlgoFromAkm(assoc_parsed->akm, kck_len * 2 * 8, &mic_algo, &hmac)) {
2263
0
        ws_warning("unsupported AKM");
2264
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2265
0
    }
2266
2267
0
    if (mic_algo == GCRY_MAC_CMAC_AES)
2268
0
        /* nothing */;
2269
0
    else if (mic_algo == GCRY_MD_SHA256)
2270
0
        mic_algo = GCRY_MAC_HMAC_SHA256;
2271
0
    else if (mic_algo == GCRY_MD_SHA384)
2272
0
        mic_algo = GCRY_MAC_HMAC_SHA384;
2273
0
    else if (mic_algo == GCRY_MD_SHA512)
2274
0
        mic_algo = GCRY_MAC_HMAC_SHA512;
2275
0
    else
2276
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2277
2278
0
    if (gcry_mac_open(&handle, mic_algo, 0, NULL)) {
2279
0
        ws_warning("gcry_mac_open failed");
2280
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2281
0
    }
2282
0
    if (gcry_mac_setkey(handle, kck, kck_len)) {
2283
0
        ws_warning("gcry_mac_setkey failed");
2284
0
        gcry_mac_close(handle);
2285
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2286
0
    }
2287
0
    gcry_mac_write(handle, sta, DOT11DECRYPT_MAC_LEN);
2288
0
    gcry_mac_write(handle, assoc_parsed->bssid, DOT11DECRYPT_MAC_LEN);
2289
2290
0
    gcry_mac_write(handle, &seq_num, 1);
2291
2292
0
    gcry_mac_write(handle, assoc_parsed->rsne_tag, assoc_parsed->rsne_tag[1] + 2);
2293
0
    gcry_mac_write(handle, assoc_parsed->mde_tag, assoc_parsed->mde_tag[1] + 2);
2294
2295
0
    gcry_mac_write(handle, assoc_parsed->fte_tag, 4);
2296
0
    gcry_mac_write(handle, zeros, mic_len); /* MIC zeroed */
2297
0
    gcry_mac_write(handle, assoc_parsed->fte_tag + 4 + mic_len, fte_len - 4 - mic_len);
2298
2299
0
    if (assoc_parsed->rde_tag) {
2300
0
        gcry_mac_write(handle, assoc_parsed->rde_tag, assoc_parsed->rde_tag[1] + 2);
2301
0
    }
2302
0
    if (assoc_parsed->rsnxe_tag) {
2303
0
        gcry_mac_write(handle, assoc_parsed->rsnxe_tag, assoc_parsed->rsnxe_tag[1] + 2);
2304
0
    }
2305
2306
0
    if (gcry_mac_verify(handle, assoc_parsed->fte.mic, mic_len) != 0) {
2307
0
        DEBUG_DUMP("MIC", assoc_parsed->fte.mic, mic_len, LOG_LEVEL_DEBUG);
2308
0
        ws_debug("MIC verification failed");
2309
0
        gcry_mac_close(handle);
2310
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2311
0
    }
2312
0
    DEBUG_DUMP("MIC", assoc_parsed->fte.mic, mic_len, LOG_LEVEL_DEBUG);
2313
0
    gcry_mac_close(handle);
2314
0
    return DOT11DECRYPT_RET_SUCCESS;
2315
0
}
2316
2317
static int
2318
Dot11DecryptValidateKey(
2319
    PDOT11DECRYPT_KEY_ITEM key)
2320
0
{
2321
0
    size_t len;
2322
0
    unsigned char ret=true;
2323
2324
0
    if (key==NULL) {
2325
0
        ws_warning("NULL key");
2326
0
        return false;
2327
0
    }
2328
2329
0
    switch (key->KeyType) {
2330
0
        case DOT11DECRYPT_KEY_TYPE_WEP:
2331
            /* check key size limits */
2332
0
            len=key->KeyData.Wep.WepKeyLen;
2333
0
            if (len<DOT11DECRYPT_WEP_KEY_MINLEN || len>DOT11DECRYPT_WEP_KEY_MAXLEN) {
2334
0
                ws_info("WEP key: key length not accepted");
2335
0
                ret=false;
2336
0
            }
2337
0
            break;
2338
2339
0
        case DOT11DECRYPT_KEY_TYPE_WEP_40:
2340
            /* set the standard length and use a generic WEP key type */
2341
0
            key->KeyData.Wep.WepKeyLen=DOT11DECRYPT_WEP_40_KEY_LEN;
2342
0
            key->KeyType=DOT11DECRYPT_KEY_TYPE_WEP;
2343
0
            break;
2344
2345
0
        case DOT11DECRYPT_KEY_TYPE_WEP_104:
2346
            /* set the standard length and use a generic WEP key type */
2347
0
            key->KeyData.Wep.WepKeyLen=DOT11DECRYPT_WEP_104_KEY_LEN;
2348
0
            key->KeyType=DOT11DECRYPT_KEY_TYPE_WEP;
2349
0
            break;
2350
2351
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PWD:
2352
            /* check passphrase and SSID size limits */
2353
0
            len=strlen(key->UserPwd.Passphrase);
2354
0
            if (len<DOT11DECRYPT_WPA_PASSPHRASE_MIN_LEN || len>DOT11DECRYPT_WPA_PASSPHRASE_MAX_LEN) {
2355
0
                ws_info("WPA-PWD key: passphrase length not accepted");
2356
0
                ret=false;
2357
0
            }
2358
2359
0
            len=key->UserPwd.SsidLen;
2360
0
            if (len>DOT11DECRYPT_WPA_SSID_MAX_LEN) {
2361
0
                ws_info("WPA-PWD key: ssid length not accepted");
2362
0
                ret=false;
2363
0
            }
2364
2365
0
            break;
2366
2367
0
        case DOT11DECRYPT_KEY_TYPE_WPA_PSK:
2368
0
            break;
2369
2370
0
        case DOT11DECRYPT_KEY_TYPE_TK:
2371
0
            break;
2372
2373
0
        case DOT11DECRYPT_KEY_TYPE_MSK:
2374
0
            break;
2375
2376
0
        default:
2377
0
            ret=false;
2378
0
    }
2379
0
    return ret;
2380
0
}
2381
2382
static int
2383
Dot11DecryptGetSaAddress(
2384
    const uint8_t *mac_header,
2385
    unsigned mac_header_len,
2386
    DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
2387
219
{
2388
219
    const DOT11DECRYPT_MAC_FRAME *frame;
2389
2390
219
    if (mac_header_len < sizeof(DOT11DECRYPT_MAC_FRAME)) {
2391
28
        return DOT11DECRYPT_RET_UNSUCCESS;
2392
28
    }
2393
191
    frame = (const DOT11DECRYPT_MAC_FRAME *)mac_header;
2394
2395
191
    if ((DOT11DECRYPT_TYPE(frame->fc[0])==DOT11DECRYPT_TYPE_DATA) &&
2396
68
        (DOT11DECRYPT_DS_BITS(frame->fc[1]) == 0) &&
2397
49
        (memcmp(frame->addr2, frame->addr3, DOT11DECRYPT_MAC_LEN) != 0) &&
2398
47
        (memcmp(frame->addr1, frame->addr3, DOT11DECRYPT_MAC_LEN) != 0)) {
2399
        /* DATA frame with fromDS=0 ToDS=0 and neither RA or SA is BSSID
2400
           => TDLS traffic. Use highest MAC address for bssid */
2401
32
        if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) < 0) {
2402
8
            memcpy(id->sta, frame->addr1, DOT11DECRYPT_MAC_LEN);
2403
8
            memcpy(id->bssid, frame->addr2, DOT11DECRYPT_MAC_LEN);
2404
24
        } else {
2405
24
            memcpy(id->sta, frame->addr2, DOT11DECRYPT_MAC_LEN);
2406
24
            memcpy(id->bssid, frame->addr1, DOT11DECRYPT_MAC_LEN);
2407
24
        }
2408
159
    } else {
2409
159
        const unsigned char *addr;
2410
2411
        /* Normal Case: SA between STA and AP */
2412
159
        if ((addr = Dot11DecryptGetBssidAddress(frame)) != NULL) {
2413
159
            memcpy(id->bssid, addr, DOT11DECRYPT_MAC_LEN);
2414
159
        } else {
2415
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2416
0
        }
2417
2418
159
        if ((addr = Dot11DecryptGetStaAddress(frame)) != NULL) {
2419
159
            memcpy(id->sta, addr, DOT11DECRYPT_MAC_LEN);
2420
159
        } else {
2421
0
            return DOT11DECRYPT_RET_UNSUCCESS;
2422
0
        }
2423
159
    }
2424
191
    ws_noisy("BSSID_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2425
191
             id->bssid[0],id->bssid[1],id->bssid[2],id->bssid[3],id->bssid[4],id->bssid[5]);
2426
191
    ws_noisy("STA_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2427
191
             id->sta[0],id->sta[1],id->sta[2],id->sta[3],id->sta[4],id->sta[5]);
2428
2429
191
    return DOT11DECRYPT_RET_SUCCESS;
2430
191
}
2431
2432
/*
2433
 * Dot11DecryptGetBssidAddress() and Dot11DecryptGetBssidAddress() are used for
2434
 * key caching.  In each case, it's more important to return a value than
2435
 * to return a _correct_ value, so we fudge addresses in some cases, e.g.
2436
 * the BSSID in bridged connections.
2437
 * FromDS    ToDS   Sta      BSSID
2438
 * 0         0      addr1/2  addr3
2439
 * 0         1      addr2    addr1
2440
 * 1         0      addr1    addr2
2441
 * 1         1      addr2    addr1
2442
 */
2443
2444
static const unsigned char *
2445
Dot11DecryptGetStaAddress(
2446
    const DOT11DECRYPT_MAC_FRAME *frame)
2447
159
{
2448
159
    switch(DOT11DECRYPT_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2449
80
        case 0:
2450
80
            if (memcmp(frame->addr2, frame->addr3, DOT11DECRYPT_MAC_LEN) == 0)
2451
17
                return frame->addr1;
2452
63
            else
2453
63
                return frame->addr2;
2454
11
        case 1:
2455
11
            return frame->addr2;
2456
10
        case 2:
2457
10
            return frame->addr1;
2458
58
        case 3:
2459
58
            if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) < 0)
2460
30
                return frame->addr1;
2461
28
            else
2462
28
                return frame->addr2;
2463
2464
0
        default:
2465
0
            return NULL;
2466
159
    }
2467
159
}
2468
2469
static const unsigned char *
2470
Dot11DecryptGetBssidAddress(
2471
    const DOT11DECRYPT_MAC_FRAME *frame)
2472
159
{
2473
159
    switch(DOT11DECRYPT_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2474
80
        case 0:
2475
80
            return frame->addr3;
2476
11
        case 1:
2477
11
            return frame->addr1;
2478
10
        case 2:
2479
10
            return frame->addr2;
2480
58
        case 3:
2481
58
            if (memcmp(frame->addr1, frame->addr2, DOT11DECRYPT_MAC_LEN) > 0)
2482
22
                return frame->addr1;
2483
36
            else
2484
36
                return frame->addr2;
2485
2486
0
        default:
2487
0
            return NULL;
2488
159
    }
2489
159
}
2490
2491
/* From IEEE 802.11-2024 Table 9-188 Cipher suite selectors and
2492
 * Table 12-8 Cipher suite key lengths */
2493
static int Dot11DecryptGetTkLen(int cipher)
2494
0
{
2495
0
    switch (cipher) {
2496
0
        case 1: return 40;   /* WEP-40 */
2497
0
        case 2: return 256;  /* TKIP */
2498
0
        case 3: return -1;   /* Reserved */
2499
0
        case 4: return 128;  /* CCMP-128 */
2500
0
        case 5: return 104;  /* WEP-104 */
2501
0
        case 6: return 128;  /* BIP-CMAC-128 */
2502
0
        case 7: return -1;   /* Group addressed traffic not allowed */
2503
0
        case 8: return 128;  /* GCMP-128 */
2504
0
        case 9: return 256;  /* GCMP-256 */
2505
0
        case 10: return 256; /* CCMP-256 */
2506
0
        case 11: return 128; /* BIP-GMAC-128 */
2507
0
        case 12: return 256; /* BIP-GMAC-256 */
2508
0
        case 13: return 256; /* BIP-CMAC-256 */
2509
0
        default:
2510
0
            ws_warning("Unknown cipher");
2511
0
            return -1;
2512
0
    }
2513
0
}
2514
2515
/* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2516
static int Dot11DecryptGetKckLen(int akm, size_t pmk_len)
2517
0
{
2518
0
    switch (akm) {
2519
0
        case 1: return 128;
2520
0
        case 2: return 128;
2521
0
        case 3: return 128;
2522
0
        case 4: return 128;
2523
0
        case 5: return 128;
2524
0
        case 6: return 128;
2525
0
        case 8: return 128;
2526
0
        case 9: return 128;
2527
0
        case 11: return 128;
2528
0
        case 12: return 192;
2529
0
        case 13: return 192;
2530
0
        case 18:
2531
0
        case 24:
2532
0
        case 25:
2533
0
            return (int)pmk_len / 2;
2534
0
        default:
2535
            /* Unknown / Not supported */
2536
0
            ws_warning("Unknown akm");
2537
0
            return -1;
2538
0
    }
2539
0
}
2540
2541
/* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2542
static int Dot11DecryptGetKekLen(int akm, size_t pmk_len)
2543
0
{
2544
0
    switch (akm) {
2545
0
        case 1: return 128;
2546
0
        case 2: return 128;
2547
0
        case 3: return 128;
2548
0
        case 4: return 128;
2549
0
        case 5: return 128;
2550
0
        case 6: return 128;
2551
0
        case 8: return 128;
2552
0
        case 9: return 128;
2553
0
        case 11: return 128;
2554
0
        case 12: return 256;
2555
0
        case 13: return 256;
2556
0
        case 18:
2557
0
        case 24:
2558
0
        case 25:
2559
0
            return pmk_len <= 256 ? 128 : 256;
2560
0
        default:
2561
            /* Unknown / Not supported */
2562
0
            ws_warning("Unknown akm");
2563
0
            return -1;
2564
0
    }
2565
0
}
2566
2567
/* From IEEE 802.11-2024 12.7.1.3 Pairwise key hierarchy and
2568
 * Table 12-11 Integrity and key-wrap algorithms */
2569
static int Dot11DecryptGetPtkLen(int akm, int cipher, size_t pmk_len)
2570
0
{
2571
0
    int kck_len = Dot11DecryptGetKckLen(akm, pmk_len);
2572
0
    int kek_len = Dot11DecryptGetKekLen(akm, pmk_len);
2573
0
    int tk_len = Dot11DecryptGetTkLen(cipher);
2574
0
    int ptk_len;
2575
2576
0
    if (kck_len == -1 || kek_len == -1 || tk_len == -1) {
2577
0
        ws_warning("Invalid PTK len");
2578
0
        return -1;
2579
0
    }
2580
0
    ptk_len = kck_len + kek_len + tk_len;
2581
2582
0
    ws_assert(ptk_len <= DOT11DECRYPT_WPA_PTK_MAX_LEN * 8);
2583
2584
0
    return ptk_len;
2585
0
}
2586
2587
/* From IEEE 802.11-2024 12.7.1.2 PRF and Table 9-190 AKM suite selectors */
2588
static int
2589
Dot11DecryptGetDeriveFuncFromAkm(int akm)
2590
0
{
2591
0
    int func = -1;
2592
0
    switch (akm) {
2593
0
        case 1:
2594
0
        case 2:
2595
0
            func = DOT11DECRYPT_DERIVE_USING_PRF;
2596
0
            break;
2597
0
        case 3:
2598
0
        case 4:
2599
0
        case 5:
2600
0
        case 6:
2601
0
        case 7:
2602
0
        case 8:
2603
0
        case 9:
2604
0
        case 10:
2605
0
        case 11:
2606
0
        case 12:
2607
0
        case 13:
2608
0
        case 18:
2609
0
        case 24:
2610
0
        case 25:
2611
0
            func = DOT11DECRYPT_DERIVE_USING_KDF;
2612
0
            break;
2613
0
        default:
2614
            /* Unknown / Not supported yet */
2615
0
            break;
2616
0
    }
2617
0
    return func;
2618
0
}
2619
2620
/* From IEEE 802.11-2024 12.7.1.2 PRF and Table 9-190 AKM suite selectors */
2621
static int
2622
Dot11DecryptGetHashAlgoFromAkm(int akm, size_t pmk_len)
2623
0
{
2624
0
    int algo = -1;
2625
0
    switch (akm) {
2626
0
        case 1:
2627
0
        case 2:
2628
0
            algo = GCRY_MD_SHA1;
2629
0
            break;
2630
0
        case 3:
2631
0
        case 4:
2632
0
        case 5:
2633
0
        case 6:
2634
0
        case 7:
2635
0
        case 8:
2636
0
        case 9:
2637
0
        case 10:
2638
0
        case 11:
2639
0
            algo = GCRY_MD_SHA256;
2640
0
            break;
2641
0
        case 12:
2642
0
        case 13:
2643
0
            algo = GCRY_MD_SHA384;
2644
0
            break;
2645
0
        case 18:
2646
0
        case 24:
2647
0
        case 25:
2648
0
            if (pmk_len == 256)
2649
0
                algo = GCRY_MD_SHA256;
2650
0
            else if (pmk_len == 384)
2651
0
                algo = GCRY_MD_SHA384;
2652
0
            else
2653
0
                algo = GCRY_MD_SHA512;
2654
0
            break;
2655
0
        default:
2656
            /* Unknown / Not supported yet */
2657
0
            break;
2658
0
    }
2659
0
    return algo;
2660
0
}
2661
2662
/* derive the PTK from the AA, SPA, PMK, SNonce, ANonce */
2663
/** From IEEE 802.11-2024 12.7.1.3 Pairwise key hierarchy:
2664
 *  PRF-Length(PMK, "Pairwise key expansion",
2665
 *      Min(AA, SPA) || Max(AA, SPA) ||
2666
 *      Min(ANonce, SNonce) || Max(ANonce, SNonce))
2667
 */
2668
static uint8_t
2669
Dot11DecryptDerivePtk(
2670
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
2671
    const unsigned char *pmk,
2672
    size_t pmk_len,
2673
    const unsigned char snonce[32],
2674
    int key_version,
2675
    int akm,
2676
    int cipher,
2677
    uint8_t *ptk, size_t *ptk_len)
2678
0
{
2679
0
    int algo = -1;
2680
0
    int ptk_len_bits = -1;
2681
0
    int derive_func;
2682
2683
0
    if (!sa || !pmk || !snonce || !ptk || !ptk_len) {
2684
0
        ws_warning("Invalid input for PTK derivation");
2685
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2686
0
    }
2687
2688
0
    if (key_version == DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP) {
2689
        /* TKIP */
2690
0
        ptk_len_bits = 512;
2691
0
        derive_func = DOT11DECRYPT_DERIVE_USING_PRF;
2692
0
        algo = GCRY_MD_SHA1;
2693
0
    } else {
2694
        /* From IEEE 802.11-2024 Table 12-11 Integrity and key-wrap algorithms */
2695
0
        ptk_len_bits = Dot11DecryptGetPtkLen(akm, cipher, pmk_len * 8);
2696
0
        algo = Dot11DecryptGetHashAlgoFromAkm(akm, pmk_len * 8);
2697
0
        derive_func = Dot11DecryptGetDeriveFuncFromAkm(akm);
2698
0
        ws_debug("ptk_len_bits: %d, algo: %d, cipher: %d", ptk_len_bits, algo, cipher);
2699
0
    }
2700
2701
0
    if (ptk_len_bits == -1 || algo == -1) {
2702
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2703
0
    }
2704
0
    if ((size_t)ptk_len_bits / 8 > *ptk_len) {
2705
0
        ws_warning("Provided PTK buffer too small");
2706
0
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
2707
0
    }
2708
0
    *ptk_len = ptk_len_bits / 8;
2709
2710
0
    static const char *const label = "Pairwise key expansion";
2711
0
    uint8_t context[DOT11DECRYPT_MAC_LEN * 2 + 32 * 2];
2712
0
    int offset = 0;
2713
0
    const uint8_t *spa = sa->saId.sta, *aa = sa->saId.bssid;
2714
2715
0
    if (sa->wpa.mld) {
2716
0
        spa = sa->wpa.sta_mld_mac;
2717
0
        aa = sa->wpa.ap_mld_mac;
2718
0
    }
2719
2720
    /* Min(AA, SPA) || Max(AA, SPA) */
2721
0
    if (memcmp(spa, aa, DOT11DECRYPT_MAC_LEN) < 0)
2722
0
    {
2723
0
        memcpy(context + offset, spa, DOT11DECRYPT_MAC_LEN);
2724
0
        offset += DOT11DECRYPT_MAC_LEN;
2725
0
        memcpy(context + offset, aa, DOT11DECRYPT_MAC_LEN);
2726
0
        offset += DOT11DECRYPT_MAC_LEN;
2727
0
    }
2728
0
    else
2729
0
    {
2730
0
        memcpy(context + offset, aa, DOT11DECRYPT_MAC_LEN);
2731
0
        offset += DOT11DECRYPT_MAC_LEN;
2732
0
        memcpy(context + offset, spa, DOT11DECRYPT_MAC_LEN);
2733
0
        offset += DOT11DECRYPT_MAC_LEN;
2734
0
    }
2735
2736
    /* Min(ANonce, SNonce) || Max(ANonce, SNonce) */
2737
0
    if (memcmp(snonce, sa->wpa.nonce, 32) < 0 )
2738
0
    {
2739
0
        memcpy(context + offset, snonce, 32);
2740
0
        offset += 32;
2741
0
        memcpy(context + offset, sa->wpa.nonce, 32);
2742
0
        offset += 32;
2743
0
    }
2744
0
    else
2745
0
    {
2746
0
        memcpy(context + offset, sa->wpa.nonce, 32);
2747
0
        offset += 32;
2748
0
        memcpy(context + offset, snonce, 32);
2749
0
        offset += 32;
2750
0
    }
2751
0
    if (derive_func == DOT11DECRYPT_DERIVE_USING_PRF) {
2752
0
        dot11decrypt_prf(pmk, pmk_len, label, context, offset, algo,
2753
0
                         ptk, *ptk_len);
2754
0
    } else {
2755
0
        dot11decrypt_kdf(pmk, pmk_len, label, context, offset, algo,
2756
0
                         ptk, *ptk_len);
2757
0
    }
2758
0
    DEBUG_DUMP("PTK", ptk, *ptk_len, LOG_LEVEL_DEBUG);
2759
0
    return DOT11DECRYPT_RET_SUCCESS;
2760
0
}
2761
2762
/**
2763
 * For Fast BSS Transition AKMS derive PTK from sa, selected key and various information in
2764
 * eapol key frame.
2765
 * From IEEE 802.11-2016 12.7.1.7.1
2766
 */
2767
static uint8_t
2768
Dot11DecryptFtDerivePtk(
2769
    const PDOT11DECRYPT_CONTEXT ctx,
2770
    const DOT11DECRYPT_SEC_ASSOCIATION *sa,
2771
    const PDOT11DECRYPT_KEY_ITEM key,
2772
    const uint8_t mdid[2],
2773
    const uint8_t *snonce,
2774
    const uint8_t *r0kh_id, size_t r0kh_id_len,
2775
    const uint8_t *r1kh_id, size_t r1kh_id_len _U_,
2776
    int akm, int cipher,
2777
    uint8_t *ptk, size_t *ptk_len)
2778
0
{
2779
0
    int hash_algo;
2780
0
    uint8_t pmk_r0[DOT11DECRYPT_WPA_PMK_MAX_LEN];
2781
0
    uint8_t pmk_r1[DOT11DECRYPT_WPA_PMK_MAX_LEN];
2782
0
    uint8_t pmk_r0_name[16] = {0};
2783
0
    uint8_t pmk_r1_name[16] = {0};
2784
0
    uint8_t ptk_name[16];
2785
0
    size_t pmk_r0_len = 0;
2786
0
    size_t pmk_r1_len = 0;
2787
0
    const uint8_t *xxkey = NULL;
2788
0
    size_t xxkey_len;
2789
0
    int ptk_len_bits;
2790
2791
0
    if (!sa || !key || !mdid || !snonce || !r0kh_id || !r1kh_id || !ptk || !ptk_len) {
2792
0
        ws_warning("Invalid input for FT PTK derivation");
2793
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2794
0
    }
2795
2796
0
    if (key->KeyType == DOT11DECRYPT_KEY_TYPE_MSK) {
2797
0
        xxkey = Dot11DecryptGetXXKeyFromMSK(key->Msk.Msk,
2798
0
                                            key->Msk.Len,
2799
0
                                            akm,
2800
0
                                            &xxkey_len);
2801
0
    }
2802
0
    if (!xxkey && key->KeyData.Wpa.PskLen > 0) {
2803
0
        xxkey = key->KeyData.Wpa.Psk;
2804
0
        xxkey_len = key->KeyData.Wpa.PskLen;
2805
0
    }
2806
0
    if (!xxkey) {
2807
0
        ws_debug("no xxkey. Skipping");
2808
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2809
0
    }
2810
0
    hash_algo = Dot11DecryptGetHashAlgoFromAkm(akm, xxkey_len * 8);
2811
0
    ptk_len_bits = Dot11DecryptGetPtkLen(akm, cipher, xxkey_len * 8);
2812
0
    if (ptk_len_bits == -1) {
2813
0
        ws_warning("Invalid akm or cipher");
2814
0
        return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
2815
0
    }
2816
0
    if ((size_t)ptk_len_bits / 8 > *ptk_len) {
2817
0
        ws_warning("Provided PTK buffer too small");
2818
0
        return DOT11DECRYPT_RET_WRONG_DATA_SIZE;
2819
0
    }
2820
0
    *ptk_len = ptk_len_bits / 8;
2821
0
    if (!dot11decrypt_derive_pmk_r0(xxkey, xxkey_len,
2822
0
                               ctx->pkt_ssid, ctx->pkt_ssid_len,
2823
0
                               mdid,
2824
0
                               r0kh_id, r0kh_id_len,
2825
0
                               sa->saId.sta, hash_algo,
2826
0
                               pmk_r0, &pmk_r0_len, pmk_r0_name)) {
2827
        /* This can fail for bad size or a bad SHA256 sum. */
2828
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2829
0
    }
2830
0
    DEBUG_DUMP("PMK-R0", pmk_r0, pmk_r0_len, LOG_LEVEL_DEBUG);
2831
0
    DEBUG_DUMP("PMKR0Name", pmk_r0_name, 16, LOG_LEVEL_DEBUG);
2832
2833
0
    if (!dot11decrypt_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name,
2834
0
                               r1kh_id, sa->saId.sta, hash_algo,
2835
0
                               pmk_r1, &pmk_r1_len, pmk_r1_name)) {
2836
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2837
0
    }
2838
0
    DEBUG_DUMP("PMK-R1", pmk_r1, pmk_r1_len, LOG_LEVEL_DEBUG);
2839
0
    DEBUG_DUMP("PMKR1Name", pmk_r1_name, 16, LOG_LEVEL_DEBUG);
2840
2841
    // Reference: IEEE 802.11be-2024 12.7.1.6.5
2842
0
    const uint8_t *sta_addr = sa->saId.sta, *bssid = sa->saId.bssid;
2843
0
    if (sa->wpa.mld) {
2844
0
        sta_addr = sa->wpa.sta_mld_mac;
2845
0
        bssid = sa->wpa.ap_mld_mac;
2846
0
    }
2847
2848
0
    if (!dot11decrypt_derive_ft_ptk(pmk_r1, pmk_r1_len, pmk_r1_name,
2849
0
                               snonce, sa->wpa.nonce,
2850
0
                               bssid, sta_addr, hash_algo,
2851
0
                               ptk, *ptk_len, ptk_name)) {
2852
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2853
0
    }
2854
0
    DEBUG_DUMP("PTK", ptk, *ptk_len, LOG_LEVEL_DEBUG);
2855
0
    return DOT11DECRYPT_RET_SUCCESS;
2856
0
}
2857
2858
0
#define MAX_SSID_LENGTH 32 /* maximum SSID length */
2859
2860
static int
2861
Dot11DecryptRsnaPwd2Psk(
2862
    const struct DOT11DECRYPT_KEY_ITEMDATA_PWD *userPwd,
2863
    unsigned char *output)
2864
0
{
2865
0
    if (userPwd->SsidLen> MAX_SSID_LENGTH) {
2866
        /* This "should not happen" */
2867
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2868
0
    }
2869
0
    if (gcry_kdf_derive(userPwd->Passphrase, userPwd->PassphraseLen, GCRY_KDF_PBKDF2,
2870
0
                        GCRY_MD_SHA1, userPwd->Ssid, userPwd->SsidLen, 4096,
2871
0
                        DOT11DECRYPT_WPA_PWD_PSK_LEN, output)) {
2872
0
        return DOT11DECRYPT_RET_UNSUCCESS;
2873
0
    }
2874
2875
0
    return DOT11DECRYPT_RET_SUCCESS;
2876
0
}
2877
2878
/*
2879
 * Returns the decryption_key_t struct given a string describing the key.
2880
 * Returns NULL if the input_string cannot be parsed.
2881
 * XXX: Should return an error string explaining why parsing failed
2882
 */
2883
decryption_key_t*
2884
parse_key_string(char* input_string, uint8_t key_type, char** error)
2885
0
{
2886
0
    GByteArray *ssid_ba = NULL, *key_ba;
2887
2888
0
    char **tokens;
2889
0
    unsigned n = 0;
2890
0
    decryption_key_t *dk;
2891
2892
0
    if(input_string == NULL || (strcmp(input_string, "") == 0)) {
2893
0
        if (error) {
2894
0
            *error = g_strdup("Key cannot be empty");
2895
0
        }
2896
0
        return NULL;
2897
0
    }
2898
2899
    /*
2900
     * Parse the input_string. WEP and WPA will be just a string
2901
     * of hexadecimal characters (if key is wrong, null will be
2902
     * returned...).
2903
     * WPA-PWD should be in the form
2904
     * <key data>[:<ssid>]
2905
     * With WPA-PWD, we percent-decode the key data and ssid.
2906
     * The percent itself ("%25") and the colon ("%3a") must be
2907
     * percent-encoded, the latter so we can distinguish between the
2908
     * separator and a colon in the key or ssid. Percent-encoding
2909
     * for anything else is optional. (NUL is not allowed, either
2910
     * percent-encoded or not.)
2911
     */
2912
2913
0
    switch(key_type)
2914
0
    {
2915
0
    case DOT11DECRYPT_KEY_TYPE_WEP:
2916
0
    case DOT11DECRYPT_KEY_TYPE_WEP_40:
2917
0
    case DOT11DECRYPT_KEY_TYPE_WEP_104:
2918
2919
0
        key_ba = g_byte_array_new();
2920
2921
0
        if (!hex_str_to_bytes(input_string, key_ba, false)) {
2922
0
            if (error) {
2923
0
                *error = g_strdup("WEP key must be a hexadecimal string");
2924
0
            }
2925
0
            g_byte_array_free(key_ba, true);
2926
0
            return NULL;
2927
0
        }
2928
2929
0
        if (key_ba->len > 0 && key_ba->len <= DOT11DECRYPT_WEP_KEY_MAXLEN) {
2930
            /* Key is correct! It was probably an 'old style' WEP key */
2931
            /* Create the decryption_key_t structure, fill it and return it*/
2932
0
            dk = g_new0(decryption_key_t, 1);
2933
2934
0
            dk->type = DOT11DECRYPT_KEY_TYPE_WEP;
2935
0
            dk->key  = key_ba;
2936
0
            dk->bits = key_ba->len * 8;
2937
0
            dk->ssid = NULL;
2938
2939
0
            return dk;
2940
0
        }
2941
2942
0
        if (error) {
2943
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);
2944
0
        }
2945
        /* Key doesn't work */
2946
0
        g_byte_array_free(key_ba, true);
2947
0
        return NULL;
2948
2949
0
    case DOT11DECRYPT_KEY_TYPE_WPA_PWD:
2950
2951
0
        tokens = g_strsplit(input_string,":", 3);
2952
0
        n = g_strv_length(tokens);
2953
2954
0
        if (n < 1 || n > 2)
2955
0
        {
2956
            /* Require either one or two tokens; more, and the user
2957
             * may have meant a colon in the passphrase or SSID name
2958
             */
2959
            /* Free the array of strings */
2960
            /* XXX: Return why parsing failed (":" must be escaped) */
2961
0
            if (error) {
2962
0
                *error = g_strdup("Only one ':' is allowed, as a separator between passphrase and SSID; others must be percent-encoded as \"%%3a\"");
2963
0
            }
2964
0
            g_strfreev(tokens);
2965
0
            return NULL;
2966
0
        }
2967
2968
        /*
2969
         * The first token is the key
2970
         */
2971
0
        key_ba = g_byte_array_new();
2972
0
        if (! uri_str_to_bytes(tokens[0], key_ba)) {
2973
            /* Failed parsing as percent-encoded */
2974
0
            if (error) {
2975
0
                *error = g_strdup("WPA passphrase is treated as percent-encoded; use \"%%25\" for a literal \"%%\"");
2976
0
            }
2977
0
            g_byte_array_free(key_ba, true);
2978
0
            g_strfreev(tokens);
2979
0
            return NULL;
2980
0
        }
2981
2982
        /* key length (after percent-decoding) should be between 8 and 63
2983
         * octets (63 to distinguish from a PSK as 64 hex characters.)
2984
         * XXX: 802.11-2016 Annex J assumes that each character in the
2985
         * pass-phrase is ASCII printable ("has an encoding in the range
2986
         * 32 to 126"), though this (and the entire algorithm for that
2987
         * matter) is only considered a suggestion.
2988
         * It is possible to apply PBKDF2 to any octet string, e.g. UTF-8.
2989
         * (wpa_passphrase from wpa_supplicant will do so, for example.)
2990
         */
2991
0
        if( ((key_ba->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_ba->len) < WPA_KEY_MIN_CHAR_SIZE))
2992
0
        {
2993
0
            if (error) {
2994
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);
2995
0
            }
2996
0
            g_byte_array_free(key_ba, true);
2997
2998
            /* Free the array of strings */
2999
0
            g_strfreev(tokens);
3000
0
            return NULL;
3001
0
        }
3002
3003
0
        ssid_ba = NULL;
3004
0
        if (n >= 2) /* more than two tokens found, means that the user specified the ssid */
3005
0
        {
3006
0
            ssid_ba = g_byte_array_new();
3007
0
            if (! uri_str_to_bytes(tokens[1], ssid_ba)) {
3008
0
                if (error) {
3009
0
                    *error = g_strdup("WPA SSID is treated as percent-encoded; use \"%%25\" for a literal \"%%\".");
3010
0
                }
3011
0
                g_byte_array_free(key_ba, true);
3012
0
                g_byte_array_free(ssid_ba, true);
3013
                /* Free the array of strings */
3014
0
                g_strfreev(tokens);
3015
0
                return NULL;
3016
0
            }
3017
3018
0
            if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
3019
0
            {
3020
0
                if (error) {
3021
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);
3022
0
                }
3023
0
                g_byte_array_free(key_ba, true);
3024
0
                g_byte_array_free(ssid_ba, true);
3025
3026
                /* Free the array of strings */
3027
0
                g_strfreev(tokens);
3028
0
                return NULL;
3029
0
            }
3030
0
        }
3031
3032
        /* Key was correct!!! Create the new decryption_key_t ... */
3033
0
        dk = g_new0(decryption_key_t, 1);
3034
3035
0
        dk->type = DOT11DECRYPT_KEY_TYPE_WPA_PWD;
3036
0
        dk->key  = key_ba;
3037
0
        dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
3038
0
        dk->ssid = ssid_ba; /* NULL if ssid_ba is NULL */
3039
3040
        /* Free the array of strings */
3041
0
        g_strfreev(tokens);
3042
0
        return dk;
3043
3044
0
    case DOT11DECRYPT_KEY_TYPE_WPA_PSK:
3045
3046
0
        key_ba = g_byte_array_new();
3047
0
        if (!hex_str_to_bytes(input_string, key_ba, false)) {
3048
0
            if (error) {
3049
0
                *error = g_strdup("WPA PSK/PMK must be a hexadecimal string");
3050
0
            }
3051
0
            g_byte_array_free(key_ba, true);
3052
0
            return NULL;
3053
0
        }
3054
3055
        /* Two tokens means that the user should have entered a WPA-BIN key ... */
3056
0
        if((key_ba->len != DOT11DECRYPT_WPA_PWD_PSK_LEN &&
3057
0
            key_ba->len != 48 &&
3058
0
            key_ba->len != DOT11DECRYPT_WPA_PMK_MAX_LEN))
3059
0
        {
3060
0
            if (error) {
3061
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);
3062
0
            }
3063
0
            g_byte_array_free(key_ba, true);
3064
0
            return NULL;
3065
0
        }
3066
3067
        /* Key was correct!!! Create the new decryption_key_t ... */
3068
0
        dk = g_new0(decryption_key_t, 1);
3069
3070
0
        dk->type = DOT11DECRYPT_KEY_TYPE_WPA_PSK;
3071
0
        dk->key  = key_ba;
3072
0
        dk->bits = (unsigned) dk->key->len * 8;
3073
0
        dk->ssid = NULL;
3074
3075
0
        return dk;
3076
3077
0
    case DOT11DECRYPT_KEY_TYPE_TK:
3078
0
        {
3079
0
            tokens = g_strsplit(input_string,":", 3);
3080
0
            n = g_strv_length(tokens);
3081
0
            if (!(n == 1 || n == 3))
3082
0
            {
3083
                /* Free the array of strings */
3084
0
                if (error) {
3085
0
                    *error = g_strdup("TK must be in TK[:AP MLD MAC:STA MLD MAC] format");
3086
0
                }
3087
0
                g_strfreev(tokens);
3088
0
                return NULL;
3089
0
            }
3090
            /* From IEEE 802.11-2024 Table 12-8 Cipher suite key lengths */
3091
0
            static const uint8_t allowed_key_lengths[] = {
3092
// TBD          40 / 8,  /* WEP-40 */
3093
// TBD          104 / 8, /* WEP-104 */
3094
0
                128 / 8, /* CCMP-128, GCMP-128 */
3095
0
                256 / 8, /* TKIP, GCMP-256, CCMP-256 */
3096
0
            };
3097
0
            bool key_length_ok = false;
3098
3099
0
            key_ba = g_byte_array_new();
3100
0
            if (!hex_str_to_bytes(tokens[0], key_ba, false)) {
3101
0
                if (error) {
3102
0
                    *error = g_strdup("Temporal Key must be a hexadecimal string");
3103
0
                }
3104
0
                g_byte_array_free(key_ba, true);
3105
0
                g_strfreev(tokens);
3106
0
                return NULL;
3107
0
            }
3108
3109
0
            for (size_t i = 0; i < sizeof(allowed_key_lengths); i++) {
3110
0
                if (key_ba->len == allowed_key_lengths[i]) {
3111
0
                    key_length_ok = true;
3112
0
                    break;
3113
0
                }
3114
0
            }
3115
0
            if (!key_length_ok) {
3116
0
                if (error) {
3117
0
                    GString *err_string = g_string_new("Temporal Keys entered is ");
3118
0
                    g_string_append_printf(err_string, "%u bytes and must be ", key_ba->len);
3119
0
                    size_t i = 0;
3120
0
                    for (; i + 1 < sizeof(allowed_key_lengths); i++) {
3121
0
                        g_string_append_printf(err_string, "%u, ", allowed_key_lengths[i]);
3122
0
                    }
3123
0
                    g_string_append_printf(err_string, "or %u bytes.", allowed_key_lengths[i]);
3124
0
                    *error = g_string_free(err_string, FALSE);
3125
0
                }
3126
0
                g_byte_array_free(key_ba, true);
3127
0
                g_strfreev(tokens);
3128
0
                return NULL;
3129
0
            }
3130
0
            dk = g_new0(decryption_key_t, 1);
3131
3132
0
            if (n == 3) {
3133
0
                dk->tk_mld = true;
3134
0
                GByteArray *mac = g_byte_array_new();
3135
0
                for (size_t i = 1; i <= 2; ++i) {
3136
0
                    if (!hex_str_to_bytes(tokens[i], mac, false) || mac->len != 6) {
3137
0
                        if (error) {
3138
0
                            *error = g_strdup("MAC must be a 6 bytes hexadecimal string");
3139
0
                        }
3140
0
                        g_byte_array_free(mac, true);
3141
0
                        g_free(dk);
3142
0
                        g_byte_array_free(key_ba, true);
3143
0
                        g_strfreev(tokens);
3144
0
                        return NULL;
3145
0
                    }
3146
0
                    if (i == 1)
3147
0
                        memcpy(dk->ap_mld_mac, mac->data, 6);
3148
0
                    else
3149
0
                        memcpy(dk->sta_mld_mac, mac->data, 6);
3150
0
                }
3151
0
                g_byte_array_free(mac, true);
3152
0
            }
3153
3154
0
            dk->type = DOT11DECRYPT_KEY_TYPE_TK;
3155
0
            dk->key  = key_ba;
3156
0
            dk->bits = (unsigned) dk->key->len * 8;
3157
0
            dk->ssid = NULL;
3158
3159
            /* Free the array of strings */
3160
0
            g_strfreev(tokens);
3161
0
            return dk;
3162
0
        }
3163
0
    case DOT11DECRYPT_KEY_TYPE_MSK:
3164
0
        {
3165
0
            key_ba = g_byte_array_new();
3166
0
            if (!hex_str_to_bytes(input_string, key_ba, false)) {
3167
0
                if (error) {
3168
0
                    *error = g_strdup("Master Session Key must be a hexadecimal string");
3169
0
                }
3170
0
                g_byte_array_free(key_ba, true);
3171
0
                return NULL;
3172
0
            }
3173
3174
0
            if (key_ba->len < DOT11DECRYPT_MSK_MIN_LEN ||
3175
0
                key_ba->len > DOT11DECRYPT_MSK_MAX_LEN)
3176
0
            {
3177
0
                if (error) {
3178
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);
3179
0
                }
3180
0
                g_byte_array_free(key_ba, true);
3181
0
                return NULL;
3182
0
            }
3183
0
            dk = g_new0(decryption_key_t, 1);
3184
0
            dk->type = DOT11DECRYPT_KEY_TYPE_MSK;
3185
0
            dk->key  = key_ba;
3186
0
            dk->bits = (unsigned)dk->key->len * 8;
3187
0
            dk->ssid = NULL;
3188
0
            return dk;
3189
0
        }
3190
0
    }
3191
3192
    /* Type not supported */
3193
0
    if (error) {
3194
0
        *error = g_strdup("Unknown key type not supported");
3195
0
    }
3196
0
    return NULL;
3197
0
}
3198
3199
void
3200
free_key_string(decryption_key_t *dk)
3201
0
{
3202
0
    if (dk->key)
3203
0
        g_byte_array_free(dk->key, true);
3204
0
    if (dk->ssid)
3205
0
        g_byte_array_free(dk->ssid, true);
3206
0
    g_free(dk);
3207
0
}
3208
3209
static int
3210
Dot11DecryptTDLSDeriveKey(
3211
    PDOT11DECRYPT_SEC_ASSOCIATION sa,
3212
    const uint8_t *data,
3213
    unsigned offset_rsne,
3214
    unsigned offset_fte,
3215
    unsigned offset_timeout,
3216
    unsigned offset_link,
3217
    uint8_t action)
3218
0
{
3219
3220
0
    gcry_md_hd_t sha256_handle;
3221
0
    gcry_md_hd_t hmac_handle;
3222
0
    const uint8_t *snonce, *anonce, *initiator, *responder, *bssid;
3223
0
    uint8_t key_input[32];
3224
0
    uint8_t mic[16], seq_num = action + 1;
3225
0
    uint8_t zeros[16] = { 0 };
3226
0
    gcry_mac_hd_t cmac_handle;
3227
0
    size_t cmac_len = 16;
3228
0
    size_t cmac_write_len;
3229
3230
    /* Get key input */
3231
0
    anonce = &data[offset_fte + 20];
3232
0
    snonce = &data[offset_fte + 52];
3233
3234
0
    if (gcry_md_open (&sha256_handle, GCRY_MD_SHA256, 0)) {
3235
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3236
0
    }
3237
0
    if (memcmp(anonce, snonce, DOT11DECRYPT_WPA_NONCE_LEN) < 0) {
3238
0
        gcry_md_write(sha256_handle, anonce, DOT11DECRYPT_WPA_NONCE_LEN);
3239
0
        gcry_md_write(sha256_handle, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3240
0
    } else {
3241
0
        gcry_md_write(sha256_handle, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3242
0
        gcry_md_write(sha256_handle, anonce, DOT11DECRYPT_WPA_NONCE_LEN);
3243
0
    }
3244
0
    memcpy(key_input, gcry_md_read(sha256_handle, 0), 32);
3245
0
    gcry_md_close(sha256_handle);
3246
3247
    /* Derive key */
3248
0
    bssid = &data[offset_link + 2];
3249
0
    initiator = &data[offset_link + 8];
3250
0
    responder = &data[offset_link + 14];
3251
0
    if (gcry_md_open(&hmac_handle, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC)) {
3252
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3253
0
    }
3254
0
    if (gcry_md_setkey(hmac_handle, key_input, 32)) {
3255
0
        gcry_md_close(hmac_handle);
3256
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3257
0
    }
3258
0
    gcry_md_putc(hmac_handle, 1);
3259
0
    gcry_md_putc(hmac_handle, 0);
3260
0
    gcry_md_write(hmac_handle, "TDLS PMK", 8);
3261
0
    if (memcmp(initiator, responder, DOT11DECRYPT_MAC_LEN) < 0) {
3262
0
          gcry_md_write(hmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3263
0
          gcry_md_write(hmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3264
0
    } else {
3265
0
          gcry_md_write(hmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3266
0
          gcry_md_write(hmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3267
0
    }
3268
0
    gcry_md_write(hmac_handle, bssid, DOT11DECRYPT_MAC_LEN);
3269
0
    gcry_md_putc(hmac_handle, 0);
3270
0
    gcry_md_putc(hmac_handle, 1);
3271
0
    memcpy(key_input, gcry_md_read(hmac_handle, 0), 32);
3272
0
    gcry_md_close(hmac_handle);
3273
3274
    /* Check MIC */
3275
0
    if (gcry_mac_open(&cmac_handle, GCRY_MAC_CMAC_AES, 0, NULL)) {
3276
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3277
0
    }
3278
0
    if (gcry_mac_setkey(cmac_handle, key_input, 16)) {
3279
0
        gcry_mac_close(cmac_handle);
3280
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3281
0
    }
3282
0
    gcry_mac_write(cmac_handle, initiator, DOT11DECRYPT_MAC_LEN);
3283
0
    gcry_mac_write(cmac_handle, responder, DOT11DECRYPT_MAC_LEN);
3284
0
    gcry_mac_write(cmac_handle, &seq_num, 1);
3285
0
    gcry_mac_write(cmac_handle, &data[offset_link], data[offset_link + 1] + 2);
3286
0
    gcry_mac_write(cmac_handle, &data[offset_rsne], data[offset_rsne + 1] + 2);
3287
0
    gcry_mac_write(cmac_handle, &data[offset_timeout], data[offset_timeout + 1] + 2);
3288
0
    gcry_mac_write(cmac_handle, &data[offset_fte], 4);
3289
0
    gcry_mac_write(cmac_handle, zeros, 16);
3290
0
    cmac_write_len = data[offset_fte + 1] + 2;
3291
0
    if (cmac_write_len < 20) {
3292
0
        ws_warning("Bad MAC len");
3293
0
        gcry_mac_close(cmac_handle);
3294
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3295
0
    }
3296
0
    gcry_mac_write(cmac_handle, &data[offset_fte + 20], cmac_write_len - 20);
3297
0
    if (gcry_mac_read(cmac_handle, mic, &cmac_len) != GPG_ERR_NO_ERROR) {
3298
0
        ws_warning("MAC read error");
3299
0
        gcry_mac_close(cmac_handle);
3300
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3301
0
    }
3302
0
    if (memcmp(mic, &data[offset_fte + 4], 16)) {
3303
0
        ws_debug("MIC verification failed");
3304
0
        gcry_mac_close(cmac_handle);
3305
0
        return DOT11DECRYPT_RET_UNSUCCESS;
3306
0
    }
3307
0
    gcry_mac_close(cmac_handle);
3308
    /* TODO support other akm and ciphers? */
3309
0
    sa->wpa.akm = 2;
3310
0
    sa->wpa.cipher = 4;
3311
0
    sa->wpa.ptk_len = Dot11DecryptGetPtkLen(sa->wpa.akm, sa->wpa.cipher, sa->wpa.pmk_len * 8) / 8;
3312
0
    memcpy(DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm, sa->wpa.pmk_len * 8),
3313
0
           key_input + 16, Dot11DecryptGetTkLen(sa->wpa.cipher) / 8);
3314
0
    memcpy(sa->wpa.nonce, snonce, DOT11DECRYPT_WPA_NONCE_LEN);
3315
0
    sa->validKey = true;
3316
0
    sa->wpa.key_ver = DOT11DECRYPT_WPA_KEY_VER_AES_CCMP;
3317
0
    ws_debug("MIC verified");
3318
0
    return  DOT11DECRYPT_RET_SUCCESS;
3319
0
}
3320
3321
3322
#ifdef __cplusplus
3323
}
3324
#endif
3325
3326
/****************************************************************************/
3327
3328
/*
3329
 * Editor modelines
3330
 *
3331
 * Local Variables:
3332
 * c-basic-offset: 4
3333
 * tab-width: 8
3334
 * indent-tabs-mode: nil
3335
 * End:
3336
 *
3337
 * ex: set shiftwidth=4 tabstop=8 expandtab:
3338
 * :indentSize=4:tabSize=8:noTabs=true:
3339
 */