Coverage Report

Created: 2025-08-04 07:15

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