3 * Copyright (c) 2006 CACE Technologies, Davis (California)
6 * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
9 /****************************************************************************/
16 #include <wsutil/wsgcrypt.h>
17 #include <wsutil/crc32.h>
18 #include <wsutil/pint.h>
19 #include <wsutil/glib-compat.h>
21 #include <epan/proto.h> /* for DISSECTOR_ASSERT. */
22 #include <epan/tvbuff.h>
23 #include <epan/to_str.h>
24 #include <epan/strutil.h>
26 #include "dot11decrypt_util.h"
27 #include "dot11decrypt_system.h"
28 #include "dot11decrypt_int.h"
30 #include "dot11decrypt_debug.h"
32 #include "wep-wpadefs.h"
35 /****************************************************************************/
36 static int Dot11DecryptGetKckLen(int akm
);
37 static int Dot11DecryptGetTkLen(int cipher
);
38 static int Dot11DecryptGetKekLen(int akm
);
39 static int Dot11DecryptGetPtkLen(int akm
, int cipher
);
40 static int Dot11DecryptGetHashAlgoFromAkm(int akm
);
42 /****************************************************************************/
43 /* Constant definitions */
45 /* EAPOL definitions */
47 * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
48 * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
50 #define DOT11DECRYPT_WPA_KCK_LEN 16
52 *Offset of the Key MIC in the EAPOL packet body
54 #define DOT11DECRYPT_WPA_MICKEY_OFFSET 77
56 * Maximum length of the EAPOL packet (it depends on the maximum MAC
59 #define DOT11DECRYPT_WPA_MAX_EAPOL_LEN 4095
61 * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
62 * from a STA when neither the group nor pairwise ciphers are CCMP for
65 * Defined in 802.11i-2004, page 78
67 #define DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP 1
69 * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
70 * from a STA when either the pairwise or the group cipher is AES-CCMP
71 * for Key Descriptor 2.
73 * Defined in 802.11i-2004, page 78
75 #define DOT11DECRYPT_WPA_KEY_VER_AES_CCMP 2
77 /** Define EAPOL Key Descriptor type values: use 254 for WPA and 2 for WPA2 **/
78 #define DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR 254
79 #define DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR 2
81 /* PMK to PTK derive functions */
82 #define DOT11DECRYPT_DERIVE_USING_PRF 0
83 #define DOT11DECRYPT_DERIVE_USING_KDF 1
84 /****************************************************************************/
87 /****************************************************************************/
88 /* Macro definitions */
90 extern const UINT32 crc32_table
[256];
91 #define CRC(crc, ch) (crc = (crc >> 8) ^ crc32_table[(crc ^ (ch)) & 0xff])
93 #define KCK_OFFSET(akm) (0)
94 #define KEK_OFFSET(akm) ((KCK_OFFSET(akm) + Dot11DecryptGetKckLen(akm) / 8))
95 #define TK_OFFSET(akm) ((KEK_OFFSET(akm) + Dot11DecryptGetKekLen(akm) / 8))
97 #define DOT11DECRYPT_GET_KCK(ptk, akm) (ptk + KCK_OFFSET(akm))
98 #define DOT11DECRYPT_GET_KEK(ptk, akm) (ptk + KEK_OFFSET(akm))
99 #define DOT11DECRYPT_GET_TK_TKIP(ptk) (ptk + 32)
100 #define DOT11DECRYPT_GET_TK(ptk, akm) (ptk + TK_OFFSET(akm))
102 #define DOT11DECRYPT_IEEE80211_OUI(oui) (pntoh24(oui) == 0x000fac)
104 /****************************************************************************/
106 /****************************************************************************/
107 /* Type definitions */
109 /* Internal function prototype declarations */
116 * It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in
117 * the RFC 2898 to derive a key (used as PMK in WPA)
118 * @param ppbytes [IN] pointer to a password (sequence of between 8 and
119 * 63 ASCII encoded characters)
120 * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
122 * @param iterations [IN] times to hash the password (4096 for WPA)
123 * @param count [IN] ???
124 * @param output [OUT] pointer to a preallocated buffer of
125 * SHA1_DIGEST_LEN characters that will contain a part of the key
127 static INT
Dot11DecryptRsnaPwd2PskStep(
128 const guint8
*ppbytes
,
129 const guint passLength
,
131 const size_t ssidLength
,
132 const INT iterations
,
138 * It calculates the passphrase-to-PSK mapping reccomanded for use with
139 * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
141 * @param passphrase [IN] pointer to a password (sequence of between 8 and
142 * 63 ASCII encoded characters)
143 * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
145 * @param output [OUT] calculated PSK (to use as PMK in WPA)
147 * Described in 802.11i-2004, page 165
149 static INT
Dot11DecryptRsnaPwd2Psk(
150 const CHAR
*passphrase
,
152 const size_t ssidLength
,
156 static INT
Dot11DecryptRsnaMng(
158 guint mac_header_len
,
160 PDOT11DECRYPT_KEY_ITEM key
,
161 DOT11DECRYPT_SEC_ASSOCIATION
*sa
)
164 static INT
Dot11DecryptWepMng(
165 PDOT11DECRYPT_CONTEXT ctx
,
167 guint mac_header_len
,
169 PDOT11DECRYPT_KEY_ITEM key
,
170 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
173 static INT
Dot11DecryptRsna4WHandshake(
174 PDOT11DECRYPT_CONTEXT ctx
,
175 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
176 const guint8
*eapol_raw
,
177 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
178 const guint tot_len
);
181 * It checks whether the specified key is corrected or not.
183 * For a standard WEP key the length will be changed to the standard
184 * length, and the type changed in a generic WEP key.
185 * @param key [IN] pointer to the key to validate
187 * - TRUE: the key contains valid fields and values
188 * - FALSE: the key has some invalid field or value
190 static INT
Dot11DecryptValidateKey(
191 PDOT11DECRYPT_KEY_ITEM key
)
194 static INT
Dot11DecryptRsnaMicCheck(
195 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
203 #if GCRYPT_VERSION_NUMBER >= 0x010600
205 Dot11DecryptFtMicCheck(
206 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
211 static PDOT11DECRYPT_SEC_ASSOCIATION
213 PDOT11DECRYPT_CONTEXT ctx
,
214 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
217 static INT
Dot11DecryptGetSaAddress(
218 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
,
219 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
222 static const UCHAR
* Dot11DecryptGetStaAddress(
223 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
226 static const UCHAR
* Dot11DecryptGetBssidAddress(
227 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
231 Dot11DecryptDerivePtk(
232 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
235 const UCHAR snonce
[32],
239 guint8
*ptk
, size_t *ptk_len
);
242 Dot11DecryptFtDerivePtk(
243 const PDOT11DECRYPT_CONTEXT ctx
,
244 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
245 const PDOT11DECRYPT_KEY_ITEM key
,
246 const guint8 mdid
[2],
247 const guint8
*snonce
,
248 const guint8
*r0kh_id
, size_t r0kh_id_len
,
249 const guint8
*r1kh_id
, size_t r1kh_id_len _U_
,
251 guint8
*ptk
, size_t *ptk_len
);
254 * @param sa [IN/OUT] pointer to SA that will hold the key
255 * @param data [IN] Frame
256 * @param offset_rsne [IN] RSNE IE offset in the frame
257 * @param offset_fte [IN] Fast BSS Transition IE offset in the frame
258 * @param offset_timeout [IN] Timeout Interval IE offset in the frame
259 * @param offset_link [IN] Link Identifier IE offset in the frame
260 * @param action [IN] Tdls Action code (response or confirm)
263 * DOT11DECRYPT_RET_SUCCESS if Key has been sucessfully derived (and MIC verified)
264 * DOT11DECRYPT_RET_UNSUCCESS otherwise
267 Dot11DecryptTDLSDeriveKey(
268 PDOT11DECRYPT_SEC_ASSOCIATION sa
,
272 guint offset_timeout
,
280 /****************************************************************************/
282 /****************************************************************************/
283 /* Exported function definitions */
289 const guint8 broadcast_mac
[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
291 #define TKIP_GROUP_KEY_LEN 32
292 #define CCMP_GROUP_KEY_LEN 16
294 #define EAPOL_RSN_KEY_LEN 95
296 /* Minimum possible key data size (at least one GTK KDE with CCMP key) */
297 #define GROUP_KEY_MIN_LEN 8 + CCMP_GROUP_KEY_LEN
298 /* Minimum possible group key msg size (group key msg using CCMP as cipher)*/
299 #define GROUP_KEY_PAYLOAD_LEN_MIN \
300 (EAPOL_RSN_KEY_LEN + GROUP_KEY_MIN_LEN)
303 Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa
, PDOT11DECRYPT_KEY_ITEM key
)
307 memcpy(key
, sa
->key
, sizeof(DOT11DECRYPT_KEY_ITEM
));
309 memset(key
, 0, sizeof(DOT11DECRYPT_KEY_ITEM
));
310 key
->KeyData
.Wpa
.PtkLen
= sa
->wpa
.ptk_len
;
311 memcpy(key
->KeyData
.Wpa
.Ptk
, sa
->wpa
.ptk
, sa
->wpa
.ptk_len
);
312 key
->KeyData
.Wpa
.Akm
= sa
->wpa
.akm
;
313 key
->KeyData
.Wpa
.Cipher
= sa
->wpa
.cipher
;
314 if (sa
->wpa
.key_ver
==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
)
315 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_TKIP
;
316 else if (sa
->wpa
.key_ver
== 0 || sa
->wpa
.key_ver
== 3 ||
317 sa
->wpa
.key_ver
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
)
319 switch (sa
->wpa
.cipher
) {
321 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_WEP_40
;
324 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_TKIP
;
327 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_CCMP
;
330 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_WEP_104
;
333 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_GCMP
;
336 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_GCMP_256
;
339 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_CCMP_256
;
342 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_UNKNOWN
;
347 case 7: Group addressed traffic not allowed
348 case 11: BIP-GMAC-128
349 case 12: BIP-GMAC-256
350 case 13: BIP-CMAC-256 */
357 Dot11DecryptRc4KeyData(const guint8
*decryption_key
, guint decryption_key_len
,
358 const guint8
*encrypted_keydata
, guint encrypted_keydata_len
)
360 gcry_cipher_hd_t rc4_handle
;
361 guint8 dummy
[256] = { 0 };
362 guint8
*decrypted_key
= NULL
;
364 if (gcry_cipher_open (&rc4_handle
, GCRY_CIPHER_ARCFOUR
, GCRY_CIPHER_MODE_STREAM
, 0)) {
367 if (gcry_cipher_setkey(rc4_handle
, decryption_key
, decryption_key_len
)) {
368 gcry_cipher_close(rc4_handle
);
371 decrypted_key
= (guint8
*)g_memdup2(encrypted_keydata
, encrypted_keydata_len
);
372 if (!decrypted_key
) {
373 gcry_cipher_close(rc4_handle
);
377 /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
378 gcry_cipher_decrypt(rc4_handle
, dummy
, 256, NULL
, 0);
379 gcry_cipher_decrypt(rc4_handle
, decrypted_key
, encrypted_keydata_len
, NULL
, 0);
380 gcry_cipher_close(rc4_handle
);
381 return decrypted_key
;
388 const guint8
*cipher_text
,
393 gcry_cipher_hd_t handle
;
395 if (kek
== NULL
|| cipher_len
< 16 || cipher_text
== NULL
) {
396 return 1; /* "should not happen" */
398 if (gcry_cipher_open(&handle
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_AESWRAP
, 0)) {
401 if (gcry_cipher_setkey(handle
, kek
, kek_len
)) {
402 gcry_cipher_close(handle
);
405 if (gcry_cipher_decrypt(handle
, output
, cipher_len
- 8, cipher_text
, cipher_len
)) {
406 gcry_cipher_close(handle
);
409 *output_len
= cipher_len
- 8;
410 gcry_cipher_close(handle
);
415 Dot11DecryptDecryptKeyData(PDOT11DECRYPT_CONTEXT ctx
,
416 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
417 const UCHAR bssid
[DOT11DECRYPT_MAC_LEN
],
418 const UCHAR sta
[DOT11DECRYPT_MAC_LEN
],
419 UCHAR
*decrypted_data
, guint
*decrypted_len
,
420 PDOT11DECRYPT_KEY_ITEM key
)
423 const guint8
*key_data
;
424 guint16 key_bytes_len
= 0; /* Length of the total key data field */
425 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
426 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
428 /* search for a cached Security Association for current BSSID and AP */
429 memcpy(id
.bssid
, bssid
, DOT11DECRYPT_MAC_LEN
);
430 memcpy(id
.sta
, sta
, DOT11DECRYPT_MAC_LEN
);
431 sa
= Dot11DecryptGetSa(ctx
, &id
);
432 if (sa
== NULL
|| !sa
->validKey
) {
433 DEBUG_PRINT_LINE("No valid SA for BSSID found", DEBUG_LEVEL_3
);
434 return DOT11DECRYPT_RET_UNSUCCESS
;
437 /* Decrypt GTK using KEK portion of PTK */
438 guint8
*decryption_key
= DOT11DECRYPT_GET_KEK(sa
->wpa
.ptk
, sa
->wpa
.akm
);
439 guint decryption_key_len
= Dot11DecryptGetKekLen(sa
->wpa
.akm
) / 8;
441 /* 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. */
443 /* Preparation for decrypting the group key - determine group key data length */
444 /* depending on whether the pairwise key is TKIP or AES encryption key */
445 key_version
= eapol_parsed
->key_version
;
446 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
){
448 key_bytes_len
= eapol_parsed
->key_len
;
449 }else if (key_version
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
){
451 key_bytes_len
= eapol_parsed
->key_data_len
;
453 /* AES keys must be at least 128 bits = 16 bytes. */
454 if (key_bytes_len
< 16) {
455 return DOT11DECRYPT_RET_UNSUCCESS
;
458 /* XXX Ideally group cipher suite type from EAPOL message 2 of 4 should be used to */
459 /* determine key size. As we currently have no way to do this lookup check that key */
460 /* is at least 16 bytes (IEEE802.11-2016 Table 12-4 Cipher suite key lengths) */
461 key_bytes_len
= eapol_parsed
->key_data_len
;
463 if (key_bytes_len
< 16) {
464 return DOT11DECRYPT_RET_UNSUCCESS
;
468 if ((key_bytes_len
< GROUP_KEY_MIN_LEN
) ||
469 (eapol_parsed
->len
< EAPOL_RSN_KEY_LEN
) ||
470 (key_bytes_len
> eapol_parsed
->len
- EAPOL_RSN_KEY_LEN
)) {
471 return DOT11DECRYPT_RET_UNSUCCESS
;
474 /* Encrypted key is in the information element field of the EAPOL key packet */
475 key_data
= eapol_parsed
->key_data
;
477 DEBUG_DUMP("Encrypted Broadcast key:", key_data
, key_bytes_len
);
478 DEBUG_DUMP("KeyIV:", eapol_parsed
->key_iv
, 16);
479 DEBUG_DUMP("decryption_key:", decryption_key
, decryption_key_len
);
481 /* As we have no concept of the prior association request at this point, we need to deduce the */
482 /* group key cipher from the length of the key bytes. In WPA this is straightforward as the */
483 /* keybytes just contain the GTK, and the GTK is only in the group handshake, NOT the M3. */
484 /* In WPA2 its a little more tricky as the M3 keybytes contain an RSN_IE, but the group handshake */
485 /* does not. Also there are other (variable length) items in the keybytes which we need to account */
486 /* for to determine the true key length, and thus the group cipher. */
488 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
){
490 /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
491 /* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
495 /* The WPA group key just contains the GTK bytes so deducing the type is straightforward */
496 /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
497 sa
->wpa
.key_ver
= (key_bytes_len
>=TKIP_GROUP_KEY_LEN
)?DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
:DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
;
499 /* Build the full decryption key based on the IV and part of the pairwise key */
500 memcpy(new_key
, eapol_parsed
->key_iv
, 16);
501 memcpy(new_key
+16, decryption_key
, 16);
502 DEBUG_DUMP("FullDecrKey:", new_key
, 32);
503 data
= Dot11DecryptRc4KeyData(new_key
, 32, key_data
, key_bytes_len
);
505 return DOT11DECRYPT_RET_UNSUCCESS
;
507 memcpy(decrypted_data
, data
, key_bytes_len
);
510 /* Ideally AKM from EAPOL message 2 of 4 should be used to determine Key-wrap algoritm to use */
511 /* Though fortunately IEEE802.11-2016 Table 12-8 state that all AKMs use "NIST AES Key Wrap" */
512 /* algorithm so no AKM lookup is needed. */
514 /* Unwrap the key; the result is key_bytes_len in length */
515 if (AES_unwrap(decryption_key
, decryption_key_len
, key_data
, key_bytes_len
,
516 decrypted_data
, &key_bytes_len
)) {
517 return DOT11DECRYPT_RET_UNSUCCESS
;
521 Dot11DecryptCopyKey(sa
, key
);
522 *decrypted_len
= key_bytes_len
;
523 return DOT11DECRYPT_RET_SUCCESS
;
527 * @param ctx [IN] pointer to the current context
528 * @param id [IN] id of the association (composed by BSSID and MAC of
530 * @return a pointer the the requested SA. NULL if it doesn't exist.
532 static PDOT11DECRYPT_SEC_ASSOCIATION
534 PDOT11DECRYPT_CONTEXT ctx
,
535 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
537 return (DOT11DECRYPT_SEC_ASSOCIATION
*)g_hash_table_lookup(ctx
->sa_hash
, id
);
540 static PDOT11DECRYPT_SEC_ASSOCIATION
541 Dot11DecryptNewSa(const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
543 PDOT11DECRYPT_SEC_ASSOCIATION sa
= g_new0(DOT11DECRYPT_SEC_ASSOCIATION
, 1);
550 static DOT11DECRYPT_SEC_ASSOCIATION
*
551 Dot11DecryptPrependSa(
552 DOT11DECRYPT_SEC_ASSOCIATION
*existing_sa
,
553 DOT11DECRYPT_SEC_ASSOCIATION
*new_sa
)
555 DOT11DECRYPT_SEC_ASSOCIATION tmp_sa
;
557 /* Add new SA first in list, but copy by value into existing record
558 * so that sa_hash need not be updated with new value */
559 tmp_sa
= *existing_sa
;
560 *existing_sa
= *new_sa
;
562 existing_sa
->next
= new_sa
;
566 /* Add SA, keep existing (if any). Return pointer to newly inserted (first) SA */
567 static PDOT11DECRYPT_SEC_ASSOCIATION
569 PDOT11DECRYPT_CONTEXT ctx
,
570 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
571 DOT11DECRYPT_SEC_ASSOCIATION
*sa
)
573 DOT11DECRYPT_SEC_ASSOCIATION
*existing_sa
= Dot11DecryptGetSa(ctx
, id
);
574 if (existing_sa
!= NULL
) {
575 sa
= Dot11DecryptPrependSa(existing_sa
, sa
);
577 void *key
= g_memdup2(id
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
));
578 g_hash_table_insert(ctx
->sa_hash
, key
, sa
);
584 Dot11DecryptGetKCK(const PDOT11DECRYPT_KEY_ITEM key
, const guint8
**kck
)
589 *kck
= DOT11DECRYPT_GET_KCK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
590 return Dot11DecryptGetKckLen(key
->KeyData
.Wpa
.Akm
) / 8;
594 Dot11DecryptGetKEK(const PDOT11DECRYPT_KEY_ITEM key
, const guint8
**kek
)
599 *kek
= DOT11DECRYPT_GET_KEK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
600 return Dot11DecryptGetKekLen(key
->KeyData
.Wpa
.Akm
) / 8;
604 Dot11DecryptGetTK(const PDOT11DECRYPT_KEY_ITEM key
, const guint8
**tk
)
610 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_TKIP
) {
611 *tk
= DOT11DECRYPT_GET_TK_TKIP(key
->KeyData
.Wpa
.Ptk
);
614 *tk
= DOT11DECRYPT_GET_TK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
615 len
= Dot11DecryptGetTkLen(key
->KeyData
.Wpa
.Cipher
) / 8;
621 Dot11DecryptGetGTK(const PDOT11DECRYPT_KEY_ITEM key
, const guint8
**gtk
)
628 /* GTK is stored in PTK at offset 32. See comment in Dot11DecryptCopyBroadcastKey */
629 *gtk
= key
->KeyData
.Wpa
.Ptk
+ 32;
630 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_TKIP
) {
633 len
= Dot11DecryptGetTkLen(key
->KeyData
.Wpa
.Cipher
) / 8;
638 INT
Dot11DecryptScanTdlsForKeys(
639 PDOT11DECRYPT_CONTEXT ctx
,
644 guint tot_len_left
= tot_len
;
645 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
646 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
647 const guint8
*initiator
, *responder
;
649 guint status
, offset_rsne
= 0, offset_fte
= 0, offset_link
= 0, offset_timeout
= 0;
650 DEBUG_PRINT_LINE("Authentication: TDLS Action Frame", DEBUG_LEVEL_3
);
652 /* TDLS payload contains a TDLS Action field (802.11-2016 9.6.13) */
654 /* check if the packet is a TDLS response or confirm */
655 if (tot_len_left
< 1) {
656 DEBUG_PRINT_LINE("Not EAPOL-Key", DEBUG_LEVEL_3
);
657 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
659 action
= data
[offset
];
660 if (action
!= 1 && action
!= 2) {
661 DEBUG_PRINT_LINE("Not Response nor confirm", DEBUG_LEVEL_3
);
662 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
667 /* Check for SUCCESS (0) or SUCCESS_POWER_SAVE_MODE (85) Status Code */
668 if (tot_len_left
< 5) {
669 DEBUG_PRINT_LINE("Not EAPOL-Key", DEBUG_LEVEL_3
);
670 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
672 status
=pntoh16(data
+ offset
);
673 if (status
!= 0 && status
!= 85) {
674 DEBUG_PRINT_LINE("TDLS setup not successful", DEBUG_LEVEL_3
);
675 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
678 /* skip Token + capabilities */
681 /* search for RSN, Fast BSS Transition, Link Identifier and Timeout Interval IEs */
683 while(offset
< (tot_len
- 2)) {
684 guint8 element_id
= data
[offset
];
685 guint8 length
= data
[offset
+ 1];
686 guint min_length
= length
;
687 switch (element_id
) {
688 case 48: /* RSN (802.11-2016 9.4.2.35) */
689 offset_rsne
= offset
;
692 case 55: /* FTE (802.11-2016 9.4.2.48) */
694 /* Plus variable length optional parameter(s) */
695 min_length
= 2 + 16 + 32 + 32;
697 case 56: /* Timeout Interval (802.11-2016 9.4.2.49) */
698 offset_timeout
= offset
;
701 case 101: /* Link Identifier (802.11-2016 9.4.2.62) */
702 offset_link
= offset
;
703 min_length
= 6 + 6 + 6;
707 if (length
< min_length
|| tot_len
< offset
+ 2 + length
) {
708 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
710 offset
+= 2 + length
;
713 if (offset_rsne
== 0 || offset_fte
== 0 ||
714 offset_timeout
== 0 || offset_link
== 0)
716 DEBUG_PRINT_LINE("Cannot Find all necessary IEs", DEBUG_LEVEL_3
);
717 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
720 DEBUG_PRINT_LINE("Found RSNE/Fast BSS/Timeout Interval/Link IEs", DEBUG_LEVEL_3
);
722 /* Will create a Security Association between 2 STA. Need to get both MAC address */
723 initiator
= &data
[offset_link
+ 8];
724 responder
= &data
[offset_link
+ 14];
726 if (memcmp(initiator
, responder
, DOT11DECRYPT_MAC_LEN
) < 0) {
727 memcpy(id
.sta
, initiator
, DOT11DECRYPT_MAC_LEN
);
728 memcpy(id
.bssid
, responder
, DOT11DECRYPT_MAC_LEN
);
730 memcpy(id
.sta
, responder
, DOT11DECRYPT_MAC_LEN
);
731 memcpy(id
.bssid
, initiator
, DOT11DECRYPT_MAC_LEN
);
734 /* Check if already derived this key */
735 sa
= Dot11DecryptGetSa(ctx
, &id
);
736 PDOT11DECRYPT_SEC_ASSOCIATION iter_sa
;
737 for (iter_sa
= sa
; iter_sa
!= NULL
; iter_sa
= iter_sa
->next
) {
738 if (iter_sa
->validKey
&&
739 memcmp(iter_sa
->wpa
.nonce
, data
+ offset_fte
+ 52,
740 DOT11DECRYPT_WPA_NONCE_LEN
) == 0)
742 /* Already have valid key for this SA, no need to redo key derivation */
743 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
746 /* We are opening a new session with the same two STA (previous sa will be kept if any) */
747 sa
= Dot11DecryptNewSa(&id
);
749 return DOT11DECRYPT_RET_REQ_DATA
;
751 if (Dot11DecryptTDLSDeriveKey(sa
, data
, offset_rsne
, offset_fte
,
752 offset_timeout
, offset_link
, action
) == DOT11DECRYPT_RET_SUCCESS
) {
753 Dot11DecryptAddSa(ctx
, &id
, sa
);
754 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
757 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
761 Dot11DecryptCopyBroadcastKey(
762 PDOT11DECRYPT_CONTEXT ctx
,
763 const guint8
*gtk
, size_t gtk_len
,
764 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
766 DOT11DECRYPT_SEC_ASSOCIATION_ID broadcast_id
;
767 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
768 DOT11DECRYPT_SEC_ASSOCIATION
*broadcast_sa
;
770 if (!gtk
|| gtk_len
== 0) {
771 DEBUG_PRINT_LINE("No broadcast key found", DEBUG_LEVEL_3
);
772 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
774 if (gtk_len
> DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32) {
775 DEBUG_PRINT_LINE("Broadcast key too large", DEBUG_LEVEL_3
);
776 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
779 sa
= Dot11DecryptGetSa(ctx
, id
);
781 DEBUG_PRINT_LINE("No SA for BSSID found", DEBUG_LEVEL_3
);
782 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
785 /* Broadcast SA for the current BSSID */
786 memcpy(broadcast_id
.bssid
, id
->bssid
, DOT11DECRYPT_MAC_LEN
);
787 memcpy(broadcast_id
.sta
, broadcast_mac
, DOT11DECRYPT_MAC_LEN
);
789 broadcast_sa
= Dot11DecryptNewSa(&broadcast_id
);
790 if (broadcast_sa
== NULL
) {
791 DEBUG_PRINT_LINE("Failed to alloc broadcast sa", DEBUG_LEVEL_3
);
792 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
795 /* Retrieve AKMS / cipher etc from handshake message 2 */
797 broadcast_sa
->wpa
.key_ver
= sa
->wpa
.key_ver
;
798 broadcast_sa
->wpa
.akm
= sa
->wpa
.akm
;
799 broadcast_sa
->wpa
.cipher
= sa
->wpa
.tmp_group_cipher
;
800 broadcast_sa
->wpa
.ptk_len
= sa
->wpa
.ptk_len
;
801 broadcast_sa
->validKey
= TRUE
;
802 DEBUG_DUMP("Broadcast key:", gtk
, gtk_len
);
804 /* Since this is a GTK and its size is only 32 bytes (vs. the 64 byte size of a PTK),
805 * we fake it and put it in at a 32-byte offset so the Dot11DecryptRsnaMng() function
806 * will extract the right piece of the GTK for decryption. (The first 16 bytes of the
807 * GTK are used for decryption.) */
808 memset(broadcast_sa
->wpa
.ptk
, 0, sizeof(broadcast_sa
->wpa
.ptk
));
809 memcpy(broadcast_sa
->wpa
.ptk
+ 32, gtk
, gtk_len
);
810 Dot11DecryptAddSa(ctx
, &broadcast_id
, broadcast_sa
);
811 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
815 Dot11DecryptGroupHandshake(
816 PDOT11DECRYPT_CONTEXT ctx
,
817 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
818 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
822 if (GROUP_KEY_PAYLOAD_LEN_MIN
> tot_len
) {
823 DEBUG_PRINT_LINE("Message too short for Group Key", DEBUG_LEVEL_3
);
824 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
826 if (eapol_parsed
->msg_type
!= DOT11DECRYPT_HS_MSG_TYPE_GHS_1
){
828 DEBUG_PRINT_LINE("Not Group handshake message 1", DEBUG_LEVEL_3
);
829 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
831 return Dot11DecryptCopyBroadcastKey(ctx
, eapol_parsed
->gtk
, eapol_parsed
->gtk_len
, id
);
834 INT
Dot11DecryptScanEapolForKeys(
835 PDOT11DECRYPT_CONTEXT ctx
,
836 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
837 const guint8
*eapol_raw
,
839 const UCHAR bssid
[DOT11DECRYPT_MAC_LEN
],
840 const UCHAR sta
[DOT11DECRYPT_MAC_LEN
])
842 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
844 /* Callers provide these guarantees, so let's make them explicit. */
845 DISSECTOR_ASSERT(tot_len
<= DOT11DECRYPT_EAPOL_MAX_LEN
);
847 DEBUG_PRINT_LINE("Authentication: EAPOL packet", DEBUG_LEVEL_3
);
849 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
850 if (/*eapol_parsed->key_type != 0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
851 eapol_parsed
->key_type
!= DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR
&& /* IEEE 802.11 Key Descriptor Type (WPA2) */
852 eapol_parsed
->key_type
!= DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR
) /* 254 = RSN_KEY_DESCRIPTOR - WPA, */
854 DEBUG_PRINT_LINE("Not valid key descriptor type", DEBUG_LEVEL_3
);
855 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
858 /* search for a cached Security Association for current BSSID and AP */
859 memcpy(id
.bssid
, bssid
, DOT11DECRYPT_MAC_LEN
);
860 memcpy(id
.sta
, sta
, DOT11DECRYPT_MAC_LEN
);
862 switch (eapol_parsed
->msg_type
) {
863 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_1
:
864 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_2
:
865 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_3
:
866 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_4
:
867 return Dot11DecryptRsna4WHandshake(ctx
, eapol_parsed
, eapol_raw
,
869 case DOT11DECRYPT_HS_MSG_TYPE_GHS_1
:
870 return Dot11DecryptGroupHandshake(ctx
, eapol_parsed
, &id
, tot_len
);
871 case DOT11DECRYPT_HS_MSG_TYPE_INVALID
:
873 DEBUG_PRINT_LINE("Invalid message type", DEBUG_LEVEL_3
);
876 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
880 Dot11DecryptGetNbrOfTkKeys(PDOT11DECRYPT_CONTEXT ctx
)
883 for (size_t i
= 0; i
< ctx
->keys_nr
; i
++) {
884 if (ctx
->keys
[i
].KeyType
== DOT11DECRYPT_KEY_TYPE_TK
) {
892 Dot11DecryptUsingUserTk(
893 PDOT11DECRYPT_CONTEXT ctx
,
895 guint mac_header_len
,
897 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
898 DOT11DECRYPT_KEY_ITEM
*used_key
)
900 int ret
= DOT11DECRYPT_RET_REQ_DATA
;
901 DOT11DECRYPT_SEC_ASSOCIATION
*sa
= Dot11DecryptNewSa(id
);
902 DOT11DECRYPT_KEY_ITEM
*key
;
910 /* Try decrypt packet with all user TKs applicable ciphers */
911 for (size_t key_index
= 0; key_index
< ctx
->keys_nr
; key_index
++) {
912 key
= &ctx
->keys
[key_index
];
913 if (key
->KeyType
!= DOT11DECRYPT_KEY_TYPE_TK
) {
916 int ciphers_to_try
[4] = { 0 };
917 switch (key
->Tk
.Len
) {
918 case DOT11DECRYPT_WEP_40_KEY_LEN
:
919 case DOT11DECRYPT_WEP_104_KEY_LEN
:
923 ciphers_to_try
[0] = 9; /* GCMP-256 */
924 ciphers_to_try
[1] = 10; /* CCMP-256 */
927 ciphers_to_try
[0] = 4; /* CCMP-128 */
928 ciphers_to_try
[1] = 8; /* GCMP-128 */
929 ciphers_to_try
[2] = 2; /* TKIP */
937 for (int i
= 0; ciphers_to_try
[i
] != 0; i
++) {
938 sa
->wpa
.cipher
= ciphers_to_try
[i
];
939 if (sa
->wpa
.cipher
== 2 /* TKIP */) {
941 memcpy(DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
),
942 key
->Tk
.Tk
, key
->Tk
.Len
);
946 memcpy(DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
947 key
->Tk
.Tk
, key
->Tk
.Len
);
949 sa
->wpa
.ptk_len
= Dot11DecryptGetPtkLen(sa
->wpa
.akm
, sa
->wpa
.cipher
) / 8;
950 ret
= Dot11DecryptRsnaMng(decrypt_data
, mac_header_len
, decrypt_len
, used_key
, sa
);
951 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
952 /* Successfully decrypted using user TK. Add SA formed from user TK so that
953 * subsequent frames can be decrypted much faster using normal code path
954 * without trying each and every user TK entered.
956 Dot11DecryptAddSa(ctx
, id
, sa
);
965 INT
Dot11DecryptDecryptPacket(
966 PDOT11DECRYPT_CONTEXT ctx
,
968 const guint mac_header_len
,
972 PDOT11DECRYPT_KEY_ITEM key
)
974 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
975 DISSECTOR_ASSERT(decrypt_data
);
976 DISSECTOR_ASSERT(decrypt_len
);
978 #ifdef DOT11DECRYPT_DEBUG
979 #define MSGBUF_LEN 255
980 CHAR msgbuf
[MSGBUF_LEN
];
987 DEBUG_PRINT_LINE("NULL context", DEBUG_LEVEL_5
);
988 return DOT11DECRYPT_RET_REQ_DATA
;
990 if (data
==NULL
|| tot_len
==0) {
991 DEBUG_PRINT_LINE("NULL data or length=0", DEBUG_LEVEL_5
);
992 return DOT11DECRYPT_RET_REQ_DATA
;
995 /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
996 if (tot_len
< (UINT
)(mac_header_len
+DOT11DECRYPT_CRYPTED_DATA_MINLEN
)) {
997 DEBUG_PRINT_LINE("minimum length violated", DEBUG_LEVEL_5
);
998 return DOT11DECRYPT_RET_WRONG_DATA_SIZE
;
1001 /* Assume that the decrypt_data field is no more than this size. */
1002 if (tot_len
> DOT11DECRYPT_MAX_CAPLEN
) {
1003 DEBUG_PRINT_LINE("length too large", DEBUG_LEVEL_3
);
1004 return DOT11DECRYPT_RET_UNSUCCESS
;
1007 /* get STA/BSSID address */
1008 if (Dot11DecryptGetSaAddress((const DOT11DECRYPT_MAC_FRAME_ADDR4
*)(data
), &id
) != DOT11DECRYPT_RET_SUCCESS
) {
1009 DEBUG_PRINT_LINE("STA/BSSID not found", DEBUG_LEVEL_5
);
1010 return DOT11DECRYPT_RET_REQ_DATA
;
1013 /* check if data is encrypted (use the WEP bit in the Frame Control field) */
1014 if (DOT11DECRYPT_WEP(data
[1])==0) {
1015 return DOT11DECRYPT_RET_NO_DATA_ENCRYPTED
;
1017 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
1019 /* create new header and data to modify */
1020 *decrypt_len
= tot_len
;
1021 memcpy(decrypt_data
, data
, *decrypt_len
);
1023 /* encrypted data */
1024 DEBUG_PRINT_LINE("Encrypted data", DEBUG_LEVEL_3
);
1026 /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
1027 /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */
1028 /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */
1029 /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
1030 if (DOT11DECRYPT_EXTIV(data
[mac_header_len
+ 3]) == 0) {
1031 DEBUG_PRINT_LINE("WEP encryption", DEBUG_LEVEL_3
);
1032 return Dot11DecryptWepMng(ctx
, decrypt_data
, mac_header_len
, decrypt_len
, key
, &id
);
1034 DEBUG_PRINT_LINE("TKIP or CCMP encryption", DEBUG_LEVEL_3
);
1036 /* If the destination is a multicast address use the group key. This will not work if the AP is using
1037 more than one group key simultaneously. I've not seen this in practice, however.
1038 Usually an AP will rotate between the two key index values of 1 and 2 whenever
1039 it needs to change the group key to be used. */
1040 if (((const DOT11DECRYPT_MAC_FRAME_ADDR4
*)(data
))->addr1
[0] & 0x01) {
1041 DEBUG_PRINT_LINE("Broadcast/Multicast address. This is encrypted with a group key.", DEBUG_LEVEL_3
);
1043 /* force STA address to broadcast MAC so we load the SA for the groupkey */
1044 memcpy(id
.sta
, broadcast_mac
, DOT11DECRYPT_MAC_LEN
);
1046 #ifdef DOT11DECRYPT_DEBUG
1047 g_snprintf(msgbuf
, MSGBUF_LEN
, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id
.sta
[0],id
.sta
[1],id
.sta
[2],id
.sta
[3],id
.sta
[4],id
.sta
[5]);
1048 DEBUG_PRINT_LINE(msgbuf
, DEBUG_LEVEL_3
);
1051 /* search for a cached Security Association for current BSSID and STA/broadcast MAC */
1052 int ret
= DOT11DECRYPT_RET_REQ_DATA
;
1053 sa
= Dot11DecryptGetSa(ctx
, &id
);
1055 /* Decrypt the packet using the appropriate SA */
1056 ret
= Dot11DecryptRsnaMng(decrypt_data
, mac_header_len
, decrypt_len
, key
, sa
);
1058 if (ret
!= DOT11DECRYPT_RET_SUCCESS
&& Dot11DecryptGetNbrOfTkKeys(ctx
) > 0) {
1059 /* Decryption with known SAs failed. Try decrypt with TK user entries */
1060 ret
= Dot11DecryptUsingUserTk(ctx
, decrypt_data
, mac_header_len
, decrypt_len
, &id
, key
);
1064 return DOT11DECRYPT_RET_UNSUCCESS
;
1067 INT
Dot11DecryptSetKeys(
1068 PDOT11DECRYPT_CONTEXT ctx
,
1069 DOT11DECRYPT_KEY_ITEM keys
[],
1070 const size_t keys_nr
)
1075 if (ctx
==NULL
|| keys
==NULL
) {
1076 DEBUG_PRINT_LINE("NULL context or NULL keys array", DEBUG_LEVEL_3
);
1080 if (keys_nr
>DOT11DECRYPT_MAX_KEYS_NR
) {
1081 DEBUG_PRINT_LINE("Keys number greater than maximum", DEBUG_LEVEL_3
);
1085 /* clean key and SA collections before setting new ones */
1086 Dot11DecryptInitContext(ctx
);
1088 /* check and insert keys */
1089 for (i
=0, success
=0; i
<(INT
)keys_nr
; i
++) {
1090 if (Dot11DecryptValidateKey(keys
+i
)==TRUE
) {
1091 if (keys
[i
].KeyType
==DOT11DECRYPT_KEY_TYPE_WPA_PWD
) {
1092 DEBUG_PRINT_LINE("Set a WPA-PWD key", DEBUG_LEVEL_4
);
1093 Dot11DecryptRsnaPwd2Psk(keys
[i
].UserPwd
.Passphrase
, keys
[i
].UserPwd
.Ssid
, keys
[i
].UserPwd
.SsidLen
, keys
[i
].KeyData
.Wpa
.Psk
);
1094 keys
[i
].KeyData
.Wpa
.PskLen
= DOT11DECRYPT_WPA_PWD_PSK_LEN
;
1096 #ifdef DOT11DECRYPT_DEBUG
1097 else if (keys
[i
].KeyType
==DOT11DECRYPT_KEY_TYPE_WPA_PMK
) {
1098 DEBUG_PRINT_LINE("Set a WPA-PMK key", DEBUG_LEVEL_4
);
1099 } else if (keys
[i
].KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1100 DEBUG_PRINT_LINE("Set a WEP key", DEBUG_LEVEL_4
);
1102 DEBUG_PRINT_LINE("Set a key", DEBUG_LEVEL_4
);
1105 memcpy(&ctx
->keys
[success
], &keys
[i
], sizeof(keys
[i
]));
1110 ctx
->keys_nr
=success
;
1115 Dot11DecryptCleanKeys(
1116 PDOT11DECRYPT_CONTEXT ctx
)
1119 DEBUG_PRINT_LINE("NULL context", DEBUG_LEVEL_5
);
1123 memset(ctx
->keys
, 0, sizeof(DOT11DECRYPT_KEY_ITEM
) * DOT11DECRYPT_MAX_KEYS_NR
);
1127 DEBUG_PRINT_LINE("Keys collection cleaned!", DEBUG_LEVEL_5
);
1131 Dot11DecryptRecurseCleanSA(
1134 DOT11DECRYPT_SEC_ASSOCIATION
*sa
= (DOT11DECRYPT_SEC_ASSOCIATION
*)first_sa
;
1136 Dot11DecryptRecurseCleanSA((gpointer
)sa
->next
);
1142 Dot11DecryptCleanSecAssoc(
1143 PDOT11DECRYPT_CONTEXT ctx
)
1145 if (ctx
->sa_hash
!= NULL
) {
1146 g_hash_table_destroy(ctx
->sa_hash
);
1147 ctx
->sa_hash
= NULL
;
1152 * XXX - This won't be reliable if a packet containing SSID "B" shows
1153 * up in the middle of a 4-way handshake for SSID "A".
1154 * We should probably use a small array or hash table to keep multiple
1157 INT
Dot11DecryptSetLastSSID(
1158 PDOT11DECRYPT_CONTEXT ctx
,
1160 size_t pkt_ssid_len
)
1162 if (!ctx
|| !pkt_ssid
|| pkt_ssid_len
< 1 || pkt_ssid_len
> WPA_SSID_MAX_SIZE
)
1163 return DOT11DECRYPT_RET_UNSUCCESS
;
1165 memcpy(ctx
->pkt_ssid
, pkt_ssid
, pkt_ssid_len
);
1166 ctx
->pkt_ssid_len
= pkt_ssid_len
;
1168 return DOT11DECRYPT_RET_SUCCESS
;
1172 Dot11DecryptSaHash(gconstpointer key
)
1174 GBytes
*bytes
= g_bytes_new_static(key
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
));
1175 guint hash
= g_bytes_hash(bytes
);
1176 g_bytes_unref(bytes
);
1181 Dot11DecryptIsSaIdEqual(gconstpointer key1
, gconstpointer key2
)
1183 return memcmp(key1
, key2
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
)) == 0;
1186 INT
Dot11DecryptInitContext(
1187 PDOT11DECRYPT_CONTEXT ctx
)
1190 DEBUG_PRINT_LINE("NULL context", DEBUG_LEVEL_5
);
1191 return DOT11DECRYPT_RET_UNSUCCESS
;
1194 Dot11DecryptCleanKeys(ctx
);
1195 Dot11DecryptCleanSecAssoc(ctx
);
1197 ctx
->pkt_ssid_len
= 0;
1198 ctx
->sa_hash
= g_hash_table_new_full(Dot11DecryptSaHash
, Dot11DecryptIsSaIdEqual
,
1199 g_free
, Dot11DecryptRecurseCleanSA
);
1200 if (ctx
->sa_hash
== NULL
) {
1201 return DOT11DECRYPT_RET_UNSUCCESS
;
1204 DEBUG_PRINT_LINE("Context initialized!", DEBUG_LEVEL_5
);
1205 return DOT11DECRYPT_RET_SUCCESS
;
1208 INT
Dot11DecryptDestroyContext(
1209 PDOT11DECRYPT_CONTEXT ctx
)
1212 DEBUG_PRINT_LINE("NULL context", DEBUG_LEVEL_5
);
1213 return DOT11DECRYPT_RET_UNSUCCESS
;
1216 Dot11DecryptCleanKeys(ctx
);
1217 Dot11DecryptCleanSecAssoc(ctx
);
1219 DEBUG_PRINT_LINE("Context destroyed!", DEBUG_LEVEL_5
);
1220 return DOT11DECRYPT_RET_SUCCESS
;
1227 /****************************************************************************/
1229 /****************************************************************************/
1230 /* Internal function definitions */
1237 Dot11DecryptRsnaMng(
1238 UCHAR
*decrypt_data
,
1239 guint mac_header_len
,
1241 PDOT11DECRYPT_KEY_ITEM key
,
1242 DOT11DECRYPT_SEC_ASSOCIATION
*sa
)
1246 guint try_data_len
= *decrypt_len
;
1248 if (*decrypt_len
== 0) {
1249 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1250 return DOT11DECRYPT_RET_UNSUCCESS
;
1253 /* allocate a temp buffer for the decryption loop */
1254 try_data
=(UCHAR
*)g_malloc(try_data_len
);
1256 /* start of loop added by GCS */
1257 for(/* sa */; sa
!= NULL
;sa
=sa
->next
) {
1259 if (sa
->validKey
==FALSE
) {
1260 DEBUG_PRINT_LINE("Key not yet valid", DEBUG_LEVEL_3
);
1264 /* copy the encrypted data into a temp buffer */
1265 memcpy(try_data
, decrypt_data
, *decrypt_len
);
1267 if (sa
->wpa
.key_ver
==1) {
1268 /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
1269 DEBUG_PRINT_LINE("TKIP", DEBUG_LEVEL_3
);
1270 DEBUG_DUMP("ptk", sa
->wpa
.ptk
, 64);
1271 DEBUG_DUMP("ptk portion used", DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
), 16);
1273 if (*decrypt_len
< (guint
)mac_header_len
) {
1274 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1276 return DOT11DECRYPT_RET_UNSUCCESS
;
1278 if (*decrypt_len
< DOT11DECRYPT_TKIP_MICLEN
+ DOT11DECRYPT_WEP_ICV
) {
1279 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1281 return DOT11DECRYPT_RET_UNSUCCESS
;
1284 ret
= Dot11DecryptTkipDecrypt(try_data
+ mac_header_len
, *decrypt_len
- mac_header_len
,
1285 try_data
+ DOT11DECRYPT_TA_OFFSET
,
1286 DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
));
1288 DEBUG_PRINT_LINE("TKIP failed!", DEBUG_LEVEL_3
);
1292 DEBUG_PRINT_LINE("TKIP DECRYPTED!!!", DEBUG_LEVEL_3
);
1293 /* remove MIC and ICV from the end of packet */
1294 *decrypt_len
-= DOT11DECRYPT_TKIP_MICLEN
+ DOT11DECRYPT_WEP_ICV
;
1296 } else if (sa
->wpa
.cipher
== 8 || sa
->wpa
.cipher
== 9) {
1297 DEBUG_PRINT_LINE("GCMP", DEBUG_LEVEL_3
);
1299 if (*decrypt_len
< DOT11DECRYPT_GCMP_TRAILER
) {
1300 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1302 return DOT11DECRYPT_RET_UNSUCCESS
;
1304 ret
= Dot11DecryptGcmpDecrypt(try_data
, mac_header_len
, (INT
)*decrypt_len
,
1305 DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1306 Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8);
1310 DEBUG_PRINT_LINE("GCMP DECRYPTED!!!", DEBUG_LEVEL_3
);
1311 /* remove MIC from the end of packet */
1312 *decrypt_len
-= DOT11DECRYPT_GCMP_TRAILER
;
1315 /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
1316 DEBUG_PRINT_LINE("CCMP", DEBUG_LEVEL_3
);
1318 guint trailer
= sa
->wpa
.cipher
!= 10 ? DOT11DECRYPT_CCMP_TRAILER
: DOT11DECRYPT_CCMP_256_TRAILER
;
1319 if (*decrypt_len
< trailer
) {
1320 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1322 return DOT11DECRYPT_RET_UNSUCCESS
;
1325 ret
= Dot11DecryptCcmpDecrypt(try_data
, mac_header_len
, (INT
)*decrypt_len
,
1326 DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1327 Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8,
1332 DEBUG_PRINT_LINE("CCMP DECRYPTED!!!", DEBUG_LEVEL_3
);
1333 /* remove MIC from the end of packet */
1334 *decrypt_len
-= trailer
;
1340 /* none of the keys worked */
1346 if (*decrypt_len
> try_data_len
|| *decrypt_len
< 8) {
1347 DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3
);
1349 return DOT11DECRYPT_RET_UNSUCCESS
;
1352 /* remove protection bit */
1353 decrypt_data
[1]&=0xBF;
1355 /* remove TKIP/CCMP header */
1358 if (*decrypt_len
< mac_header_len
) {
1359 DEBUG_PRINT_LINE("Invalid decryption length < mac_header_len", DEBUG_LEVEL_3
);
1361 return DOT11DECRYPT_RET_UNSUCCESS
;
1364 /* copy the decrypted data into the decrypt buffer GCS*/
1365 memcpy(decrypt_data
+ mac_header_len
, try_data
+ mac_header_len
+ 8,
1366 *decrypt_len
- mac_header_len
);
1369 Dot11DecryptCopyKey(sa
, key
);
1370 return DOT11DECRYPT_RET_SUCCESS
;
1375 PDOT11DECRYPT_CONTEXT ctx
,
1376 UCHAR
*decrypt_data
,
1377 guint mac_header_len
,
1379 PDOT11DECRYPT_KEY_ITEM key
,
1380 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
1382 UCHAR wep_key
[DOT11DECRYPT_WEP_KEY_MAXLEN
+DOT11DECRYPT_WEP_IVLEN
];
1386 DOT11DECRYPT_KEY_ITEM
*tmp_key
;
1387 UINT8 useCache
=FALSE
;
1389 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1390 guint try_data_len
= *decrypt_len
;
1392 try_data
= (UCHAR
*)g_malloc(try_data_len
);
1394 /* get the Security Association structure for the STA and AP */
1396 /* For WEP the sa is used only for caching. When no sa exists all user
1397 * entered WEP keys are checked and on successful packet decryption an
1398 * sa is formed caching the key used for decryption.
1400 sa
= Dot11DecryptGetSa(ctx
, id
);
1401 if (sa
!= NULL
&& sa
->key
!= NULL
) {
1405 for (key_index
=0; key_index
<(INT
)ctx
->keys_nr
; key_index
++) {
1406 /* use the cached one, or try all keys */
1408 tmp_key
=&ctx
->keys
[key_index
];
1410 if (sa
->key
!=NULL
&& sa
->key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1411 DEBUG_PRINT_LINE("Try cached WEP key...", DEBUG_LEVEL_3
);
1414 DEBUG_PRINT_LINE("Cached key is not valid, try another WEP key...", DEBUG_LEVEL_3
);
1415 tmp_key
=&ctx
->keys
[key_index
];
1419 /* obviously, try only WEP keys... */
1420 if (tmp_key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1421 DEBUG_PRINT_LINE("Try WEP key...", DEBUG_LEVEL_3
);
1423 memset(wep_key
, 0, sizeof(wep_key
));
1424 memcpy(try_data
, decrypt_data
, *decrypt_len
);
1426 /* Costruct 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) */
1427 memcpy(wep_key
, try_data
+mac_header_len
, DOT11DECRYPT_WEP_IVLEN
);
1428 keylen
=tmp_key
->KeyData
.Wep
.WepKeyLen
;
1429 memcpy(wep_key
+DOT11DECRYPT_WEP_IVLEN
, tmp_key
->KeyData
.Wep
.WepKey
, keylen
);
1431 ret_value
=Dot11DecryptWepDecrypt(wep_key
,
1432 keylen
+DOT11DECRYPT_WEP_IVLEN
,
1433 try_data
+ (mac_header_len
+DOT11DECRYPT_WEP_IVLEN
+DOT11DECRYPT_WEP_KIDLEN
),
1434 *decrypt_len
-(mac_header_len
+DOT11DECRYPT_WEP_IVLEN
+DOT11DECRYPT_WEP_KIDLEN
+DOT11DECRYPT_CRC_LEN
));
1436 if (ret_value
== DOT11DECRYPT_RET_SUCCESS
)
1437 memcpy(decrypt_data
, try_data
, *decrypt_len
);
1440 if (!ret_value
&& tmp_key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1441 /* the tried key is the correct one, cache it in the Security Association */
1443 /* Form an SA if one does not exist already */
1445 sa
= Dot11DecryptNewSa(id
);
1447 DEBUG_PRINT_LINE("Failed to alloc sa for WEP", DEBUG_LEVEL_3
);
1448 ret_value
= DOT11DECRYPT_RET_UNSUCCESS
;
1451 sa
= Dot11DecryptAddSa(ctx
, id
, sa
);
1456 memcpy(key
, sa
->key
, sizeof(DOT11DECRYPT_KEY_ITEM
));
1457 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
1462 /* the cached key was not valid, try other keys */
1464 if (useCache
==TRUE
) {
1473 return DOT11DECRYPT_RET_UNSUCCESS
;
1475 DEBUG_PRINT_LINE("WEP DECRYPTED!!!", DEBUG_LEVEL_3
);
1477 /* remove ICV (4bytes) from the end of packet */
1480 if (*decrypt_len
< 4) {
1481 DEBUG_PRINT_LINE("Decryption length too short", DEBUG_LEVEL_3
);
1482 return DOT11DECRYPT_RET_UNSUCCESS
;
1485 /* remove protection bit */
1486 decrypt_data
[1]&=0xBF;
1488 /* remove IC header */
1490 memmove(decrypt_data
+ mac_header_len
,
1491 decrypt_data
+ mac_header_len
+ DOT11DECRYPT_WEP_IVLEN
+ DOT11DECRYPT_WEP_KIDLEN
,
1492 *decrypt_len
- mac_header_len
);
1494 return DOT11DECRYPT_RET_SUCCESS
;
1497 /* From IEEE 802.11-2016 Table 9-133—AKM suite selectors */
1498 static gboolean
Dot11DecryptIsFtAkm(int akm
)
1510 /* Get xxkey portion of MSK */
1511 /* From IEEE 802.11-2016 12.7.1.7.3 PMK-R0 */
1512 static const guint8
*
1513 Dot11DecryptGetXXKeyFromMSK(const guint8
*msk
, size_t msk_len
,
1514 int akm
, size_t *xxkey_len
)
1537 /* From IEEE 802.11-2016 12.7.1.3 Pairwise key hierarchy */
1539 Dot11DecryptDerivePmkFromMsk(const guint8
*msk
, guint8 msk_len
, int akm
,
1540 guint8
*pmk
, guint8
*pmk_len
)
1542 if (!msk
|| !pmk
|| !pmk_len
) {
1545 // When using AKM suite selector 00-0F-AC:12, the length of the PMK, PMK_bits,
1546 // shall be 384 bits. With all other AKM suite selectors, the length of the PMK,
1547 // PMK_bits, shall be 256 bits.
1553 if (msk_len
+ *pmk_len
< msk_len
) {
1557 // PMK = L(MSK, 0, PMK_bits).
1558 memcpy(pmk
, msk
, *pmk_len
);
1562 Dot11DecryptIsWpaKeyType(guint8 key_type
)
1565 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
1566 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
1567 case DOT11DECRYPT_KEY_TYPE_WPA_PMK
:
1568 case DOT11DECRYPT_KEY_TYPE_MSK
:
1575 Dot11DecryptIsPwdWildcardSsid(const PDOT11DECRYPT_CONTEXT ctx
,
1576 const DOT11DECRYPT_KEY_ITEM
*key_item
)
1578 if (!ctx
|| !key_item
|| key_item
->KeyType
!= DOT11DECRYPT_KEY_TYPE_WPA_PWD
) {
1581 if (key_item
->UserPwd
.SsidLen
== 0 && ctx
->pkt_ssid_len
> 0 &&
1582 ctx
->pkt_ssid_len
<= DOT11DECRYPT_WPA_SSID_MAX_LEN
) {
1588 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
1590 Dot11DecryptRsna4WHandshake(
1591 PDOT11DECRYPT_CONTEXT ctx
,
1592 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
1593 const guint8
*eapol_raw
,
1594 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
1595 const guint tot_len
)
1597 DOT11DECRYPT_KEY_ITEM
*tmp_key
, *tmp_pkt_key
, pkt_key
;
1598 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1601 UCHAR useCache
=FALSE
;
1602 UCHAR eapol
[DOT11DECRYPT_EAPOL_MAX_LEN
];
1604 if (eapol_parsed
->len
> DOT11DECRYPT_EAPOL_MAX_LEN
||
1605 eapol_parsed
->key_len
> DOT11DECRYPT_EAPOL_MAX_LEN
||
1606 eapol_parsed
->key_data_len
> DOT11DECRYPT_EAPOL_MAX_LEN
) {
1607 DEBUG_PRINT_LINE("Too large EAPOL frame and/or key data", DEBUG_LEVEL_5
);
1608 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1611 /* TODO timeouts? */
1613 /* TODO consider key-index */
1615 /* TODO considera Deauthentications */
1617 DEBUG_PRINT_LINE("4-way handshake...", DEBUG_LEVEL_5
);
1619 /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
1621 /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
1622 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_1
) {
1623 DEBUG_PRINT_LINE("4-way handshake message 1", DEBUG_LEVEL_3
);
1625 /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been */
1626 /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current */
1627 /* local value, the Supplicant discards the message. */
1628 /* -> not checked, the Authenticator will be send another Message 1 (hopefully!) */
1630 /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
1631 if (!eapol_parsed
->nonce
) {
1632 DEBUG_PRINT_LINE("ANonce missing", DEBUG_LEVEL_5
);
1633 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1636 sa
= Dot11DecryptGetSa(ctx
, id
);
1637 if (sa
== NULL
|| sa
->handshake
>= 2) {
1638 /* Either no SA exists or one exists but we're reauthenticating */
1639 sa
= Dot11DecryptNewSa(id
);
1641 DEBUG_PRINT_LINE("Failed to alloc broadcast sa", DEBUG_LEVEL_3
);
1642 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1644 sa
= Dot11DecryptAddSa(ctx
, id
, sa
);
1646 memcpy(sa
->wpa
.nonce
, eapol_parsed
->nonce
, 32);
1648 /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
1649 sa
->wpa
.key_ver
= eapol_parsed
->key_version
;
1651 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1654 /* 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)) */
1655 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_2
) {
1656 DEBUG_PRINT_LINE("4-way handshake message 2", DEBUG_LEVEL_3
);
1658 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
1659 /* outstanding Message 1. If not, it silently discards the message. */
1660 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, */
1661 /* the Authenticator silently discards Message 2. */
1662 /* -> not checked; the Supplicant will send another message 2 (hopefully!) */
1664 sa
= Dot11DecryptGetSa(ctx
, id
);
1666 DEBUG_PRINT_LINE("No SA for BSSID found", DEBUG_LEVEL_3
);
1667 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1669 if (!eapol_parsed
->nonce
) {
1670 DEBUG_PRINT_LINE("SNonce missing", DEBUG_LEVEL_5
);
1671 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1673 if (sa
->key
!= NULL
) {
1679 int group_cipher
= -1;
1680 guint8 ptk
[DOT11DECRYPT_WPA_PTK_MAX_LEN
];
1683 /* now you can derive the PTK */
1684 for (key_index
=0; key_index
<(INT
)ctx
->keys_nr
|| useCache
; key_index
++) {
1685 /* use the cached one, or try all keys */
1686 if (useCache
&& Dot11DecryptIsWpaKeyType(sa
->key
->KeyType
)) {
1687 DEBUG_PRINT_LINE("Try cached WPA key...", DEBUG_LEVEL_3
);
1689 /* Step back loop counter as cached key is used instead */
1692 DEBUG_PRINT_LINE("Try WPA key...", DEBUG_LEVEL_3
);
1693 tmp_key
= &ctx
->keys
[key_index
];
1697 /* obviously, try only WPA keys... */
1698 if (!Dot11DecryptIsWpaKeyType(tmp_key
->KeyType
)) {
1701 if (tmp_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_WPA_PWD
&&
1702 Dot11DecryptIsPwdWildcardSsid(ctx
, tmp_key
))
1704 /* We have a "wildcard" SSID. Use the one from the packet. */
1705 memcpy(&pkt_key
, tmp_key
, sizeof(pkt_key
));
1706 memcpy(&pkt_key
.UserPwd
.Ssid
, ctx
->pkt_ssid
, ctx
->pkt_ssid_len
);
1707 pkt_key
.UserPwd
.SsidLen
= ctx
->pkt_ssid_len
;
1708 Dot11DecryptRsnaPwd2Psk(pkt_key
.UserPwd
.Passphrase
, pkt_key
.UserPwd
.Ssid
,
1709 pkt_key
.UserPwd
.SsidLen
, pkt_key
.KeyData
.Wpa
.Psk
);
1710 tmp_pkt_key
= &pkt_key
;
1712 tmp_pkt_key
= tmp_key
;
1714 memcpy(eapol
, eapol_raw
, tot_len
);
1716 /* From IEEE 802.11-2016 12.7.2 EAPOL-Key frames */
1717 if (eapol_parsed
->key_version
== 0 || eapol_parsed
->key_version
== 3 ||
1718 eapol_parsed
->key_version
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
)
1720 /* PTK derivation is based on Authentication Key Management Type */
1721 akm
= eapol_parsed
->akm
;
1722 cipher
= eapol_parsed
->cipher
;
1723 group_cipher
= eapol_parsed
->group_cipher
;
1724 } else if (eapol_parsed
->key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
1730 DEBUG_PRINT_LINE("EAPOL key_version not supported", DEBUG_LEVEL_3
);
1731 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1734 if (tmp_pkt_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
1735 Dot11DecryptDerivePmkFromMsk(tmp_pkt_key
->Msk
.Msk
, tmp_pkt_key
->Msk
.Len
, akm
,
1736 tmp_pkt_key
->KeyData
.Wpa
.Psk
,
1737 &tmp_pkt_key
->KeyData
.Wpa
.PskLen
);
1740 if (Dot11DecryptIsFtAkm(akm
)) {
1741 ret
= Dot11DecryptFtDerivePtk(ctx
, sa
, tmp_pkt_key
,
1743 eapol_parsed
->nonce
,
1744 eapol_parsed
->fte
.r0kh_id
,
1745 eapol_parsed
->fte
.r0kh_id_len
,
1746 eapol_parsed
->fte
.r1kh_id
,
1747 eapol_parsed
->fte
.r1kh_id_len
,
1748 akm
, cipher
, ptk
, &ptk_len
);
1750 /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
1751 ret
= Dot11DecryptDerivePtk(sa
, /* authenticator nonce, bssid, station mac */
1752 tmp_pkt_key
->KeyData
.Wpa
.Psk
, /* PSK == PMK */
1753 tmp_pkt_key
->KeyData
.Wpa
.PskLen
,
1754 eapol_parsed
->nonce
, /* supplicant nonce */
1755 eapol_parsed
->key_version
,
1756 akm
, cipher
, ptk
, &ptk_len
);
1759 /* Unsuccessful PTK derivation */
1762 DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk
, akm
), Dot11DecryptGetTkLen(cipher
) / 8);
1764 ret
= Dot11DecryptRsnaMicCheck(eapol_parsed
,
1765 eapol
, /* eapol frame (header also) */
1766 tot_len
, /* eapol frame length */
1767 DOT11DECRYPT_GET_KCK(ptk
, akm
),
1768 eapol_parsed
->key_version
,
1770 /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches */
1771 /* that from the (Re)Association Request message. */
1772 /* i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
1773 /* primitive to terminate the association. */
1774 /* ii) If they do match bit-wise, the Authenticator constructs Message 3. */
1776 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
1777 /* the key is the correct one, cache it in the Security Association */
1784 DEBUG_PRINT_LINE("handshake step failed", DEBUG_LEVEL_3
);
1785 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1787 sa
->wpa
.key_ver
= eapol_parsed
->key_version
;
1789 sa
->wpa
.cipher
= cipher
;
1790 sa
->wpa
.tmp_group_cipher
= group_cipher
;
1791 memcpy(sa
->wpa
.ptk
, ptk
, ptk_len
);
1792 sa
->wpa
.ptk_len
= (INT
)ptk_len
;
1794 sa
->validKey
= TRUE
; /* we can use the key to decode, even if we have not captured the other eapol packets */
1796 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1799 /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
1800 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_3
) {
1801 DEBUG_PRINT_LINE("4-way handshake message 3", DEBUG_LEVEL_3
);
1803 /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field */
1804 /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
1805 /* -> not checked, the Authenticator will send another message 3 (hopefully!) */
1807 /* TODO check page 88 (RNS) */
1809 /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1810 In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */
1811 if (eapol_parsed
->key_type
== DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR
) {
1812 return Dot11DecryptCopyBroadcastKey(ctx
, eapol_parsed
->gtk
, eapol_parsed
->gtk_len
, id
);
1817 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_4
) {
1818 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1820 /* TODO check MIC and Replay Counter */
1821 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1822 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
1823 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1824 /* Authenticator silently discards Message 4. */
1826 DEBUG_PRINT_LINE("4-way handshake message 4", DEBUG_LEVEL_3
);
1827 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1829 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1832 /* Refer to IEEE 802.11-2016 Chapeter 13.8 FT authentication sequence */
1833 #if GCRYPT_VERSION_NUMBER >= 0x010600
1835 Dot11DecryptScanFtAssocForKeys(
1836 const PDOT11DECRYPT_CONTEXT ctx
,
1837 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
1838 guint8
*decrypted_gtk
, size_t *decrypted_len
,
1839 DOT11DECRYPT_KEY_ITEM
* used_key
)
1841 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
1843 DEBUG_PRINT_LINE("(Re)Association packet", DEBUG_LEVEL_3
);
1845 if (!ctx
|| !assoc_parsed
) {
1846 DEBUG_PRINT_LINE("Invalid input parameters", DEBUG_LEVEL_3
);
1847 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1849 if (!Dot11DecryptIsFtAkm(assoc_parsed
->akm
)) {
1850 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1852 if (!assoc_parsed
->fte
.anonce
|| !assoc_parsed
->fte
.snonce
) {
1853 DEBUG_PRINT_LINE("ANonce or SNonce missing", DEBUG_LEVEL_5
);
1854 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1857 switch (assoc_parsed
->frame_subtype
) {
1858 case DOT11DECRYPT_SUBTYPE_ASSOC_REQ
:
1859 case DOT11DECRYPT_SUBTYPE_REASSOC_REQ
:
1860 memcpy(id
.sta
, assoc_parsed
->sa
, DOT11DECRYPT_MAC_LEN
);
1862 case DOT11DECRYPT_SUBTYPE_ASSOC_RESP
:
1863 case DOT11DECRYPT_SUBTYPE_REASSOC_RESP
:
1864 memcpy(id
.sta
, assoc_parsed
->da
, DOT11DECRYPT_MAC_LEN
);
1867 DEBUG_PRINT_LINE("Invalid frame subtype", DEBUG_LEVEL_3
);
1868 return DOT11DECRYPT_RET_UNSUCCESS
;
1870 memcpy(id
.bssid
, assoc_parsed
->bssid
, DOT11DECRYPT_MAC_LEN
);
1872 DOT11DECRYPT_KEY_ITEM
*tmp_key
, *tmp_pkt_key
, pkt_key
;
1873 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1876 gboolean useCache
= FALSE
;
1878 sa
= Dot11DecryptNewSa(&id
);
1880 DEBUG_PRINT_LINE("Failed to alloc sa", DEBUG_LEVEL_3
);
1881 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1884 memcpy(sa
->wpa
.nonce
, assoc_parsed
->fte
.anonce
, 32);
1886 if (sa
->key
!= NULL
) {
1890 guint8 ptk
[DOT11DECRYPT_WPA_PTK_MAX_LEN
];
1893 /* now you can derive the PTK */
1894 for (key_index
= 0; key_index
< ctx
->keys_nr
|| useCache
; key_index
++) {
1895 /* use the cached one, or try all keys */
1896 if (useCache
&& Dot11DecryptIsWpaKeyType(sa
->key
->KeyType
)) {
1897 DEBUG_PRINT_LINE("Try cached WPA key...", DEBUG_LEVEL_3
);
1899 /* Step back loop counter as cached key is used instead */
1902 DEBUG_PRINT_LINE("Try WPA key...", DEBUG_LEVEL_3
);
1903 tmp_key
= &ctx
->keys
[key_index
];
1907 /* Try only WPA keys... */
1908 if (!Dot11DecryptIsWpaKeyType(tmp_key
->KeyType
)) {
1911 if (tmp_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_WPA_PWD
&&
1912 Dot11DecryptIsPwdWildcardSsid(ctx
, tmp_key
))
1914 /* We have a "wildcard" SSID. Use the one from the packet. */
1915 memcpy(&pkt_key
, tmp_key
, sizeof(pkt_key
));
1916 memcpy(&pkt_key
.UserPwd
.Ssid
, ctx
->pkt_ssid
, ctx
->pkt_ssid_len
);
1917 pkt_key
.UserPwd
.SsidLen
= ctx
->pkt_ssid_len
;
1918 Dot11DecryptRsnaPwd2Psk(pkt_key
.UserPwd
.Passphrase
, pkt_key
.UserPwd
.Ssid
,
1919 pkt_key
.UserPwd
.SsidLen
, pkt_key
.KeyData
.Wpa
.Psk
);
1920 tmp_pkt_key
= &pkt_key
;
1922 tmp_pkt_key
= tmp_key
;
1925 if (tmp_pkt_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
1926 Dot11DecryptDerivePmkFromMsk(tmp_pkt_key
->Msk
.Msk
, tmp_pkt_key
->Msk
.Len
,
1928 tmp_pkt_key
->KeyData
.Wpa
.Psk
,
1929 &tmp_pkt_key
->KeyData
.Wpa
.PskLen
);
1932 ret
= Dot11DecryptFtDerivePtk(ctx
, sa
, tmp_pkt_key
,
1934 assoc_parsed
->fte
.snonce
,
1935 assoc_parsed
->fte
.r0kh_id
,
1936 assoc_parsed
->fte
.r0kh_id_len
,
1937 assoc_parsed
->fte
.r1kh_id
,
1938 assoc_parsed
->fte
.r1kh_id_len
,
1939 assoc_parsed
->akm
, assoc_parsed
->cipher
,
1941 if (ret
!= DOT11DECRYPT_RET_SUCCESS
) {
1944 DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk
, assoc_parsed
->akm
),
1945 Dot11DecryptGetTkLen(assoc_parsed
->cipher
) / 8);
1947 ret
= Dot11DecryptFtMicCheck(assoc_parsed
,
1948 DOT11DECRYPT_GET_KCK(ptk
, assoc_parsed
->akm
),
1949 Dot11DecryptGetKckLen(assoc_parsed
->akm
) / 8);
1950 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
1951 /* the key is the correct one, cache it in the Security Association */
1958 DEBUG_PRINT_LINE("handshake step failed", DEBUG_LEVEL_3
);
1960 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1962 sa
= Dot11DecryptAddSa(ctx
, &id
, sa
);
1964 sa
->wpa
.key_ver
= 0; /* Determine key type from akms and cipher*/
1965 sa
->wpa
.akm
= assoc_parsed
->akm
;
1966 sa
->wpa
.cipher
= assoc_parsed
->cipher
;
1967 sa
->wpa
.tmp_group_cipher
= assoc_parsed
->group_cipher
;
1968 memcpy(sa
->wpa
.ptk
, ptk
, ptk_len
);
1969 sa
->wpa
.ptk_len
= (INT
)ptk_len
;
1970 sa
->validKey
= TRUE
;
1972 if (assoc_parsed
->gtk
&& assoc_parsed
->gtk_len
- 8 <= DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32) {
1973 guint8 decrypted_key
[DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32];
1974 guint16 decrypted_key_len
;
1975 if (AES_unwrap(DOT11DECRYPT_GET_KEK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1976 Dot11DecryptGetKekLen(sa
->wpa
.akm
) / 8,
1977 assoc_parsed
->gtk
, assoc_parsed
->gtk_len
,
1978 decrypted_key
, &decrypted_key_len
)) {
1979 return DOT11DECRYPT_RET_UNSUCCESS
;
1981 if (decrypted_key_len
!= assoc_parsed
->gtk_subelem_key_len
) {
1982 DEBUG_PRINT_LINE("Unexpected GTK length", DEBUG_LEVEL_3
);
1983 return DOT11DECRYPT_RET_UNSUCCESS
;
1985 Dot11DecryptCopyBroadcastKey(ctx
, decrypted_key
, decrypted_key_len
, &id
);
1986 *decrypted_len
= decrypted_key_len
;
1987 memcpy(decrypted_gtk
, decrypted_key
, decrypted_key_len
);
1989 Dot11DecryptCopyKey(sa
, used_key
);
1990 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1994 Dot11DecryptScanFtAssocForKeys(
1995 const PDOT11DECRYPT_CONTEXT ctx _U_
,
1996 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed _U_
,
1997 guint8
*decrypted_gtk _U_
, size_t *decrypted_len _U_
,
1998 DOT11DECRYPT_KEY_ITEM
* used_item _U_
)
2000 DEBUG_PRINT_LINE("Skipped Dot11DecryptScanFtAssocForKeys, libgcrypt >= 1.6", DEBUG_LEVEL_3
);
2001 return DOT11DECRYPT_RET_UNSUCCESS
;
2005 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2007 Dot11DecryptGetIntegrityAlgoFromAkm(int akm
, int *algo
, gboolean
*hmac
)
2013 *algo
= GCRY_MD_SHA1
;
2016 #if GCRYPT_VERSION_NUMBER >= 0x010600
2025 *algo
= GCRY_MAC_CMAC_AES
;
2031 *algo
= GCRY_MD_SHA256
;
2036 *algo
= GCRY_MD_SHA384
;
2040 /* Unknown / Not supported yet */
2048 Dot11DecryptRsnaMicCheck(
2049 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
2056 guint8
*mic
= eapol_parsed
->mic
;
2057 guint16 mic_len
= eapol_parsed
->mic_len
;
2058 guint16 kck_len
= Dot11DecryptGetKckLen(akm
) / 8;
2059 /* MIC 16 or 24 bytes, though HMAC-SHA256 / SHA384 algos need 32 / 48 bytes buffer */
2060 UCHAR c_mic
[48] = { 0 };
2062 gboolean hmac
= TRUE
;
2064 if (!mic
|| mic_len
> DOT11DECRYPT_WPA_MICKEY_MAX_LEN
) {
2065 DEBUG_PRINT_LINE("Not a valid mic", DEBUG_LEVEL_3
);
2066 return DOT11DECRYPT_RET_UNSUCCESS
;
2069 /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
2070 memset(eapol
+ DOT11DECRYPT_WPA_MICKEY_OFFSET
+ 4, 0, mic_len
);
2072 if (key_ver
==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
2073 /* use HMAC-MD5 for the EAPOL-Key MIC */
2076 } else if (key_ver
==DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
) {
2077 /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
2078 algo
= GCRY_MD_SHA1
;
2081 /* Mic check algoritm determined by AKM type */
2082 if (Dot11DecryptGetIntegrityAlgoFromAkm(akm
, &algo
, &hmac
)) {
2083 DEBUG_PRINT_LINE("Unknown Mic check algo", DEBUG_LEVEL_3
);
2084 return DOT11DECRYPT_RET_UNSUCCESS
;
2088 if (ws_hmac_buffer(algo
, c_mic
, eapol
, eapol_len
, KCK
, kck_len
)) {
2089 DEBUG_PRINT_LINE("HMAC_BUFFER", DEBUG_LEVEL_3
);
2090 return DOT11DECRYPT_RET_UNSUCCESS
;
2093 if (ws_cmac_buffer(algo
, c_mic
, eapol
, eapol_len
, KCK
, kck_len
)) {
2094 DEBUG_PRINT_LINE("HMAC_BUFFER", DEBUG_LEVEL_3
);
2095 return DOT11DECRYPT_RET_UNSUCCESS
;
2099 /* compare calculated MIC with the Key MIC and return result (0 means success) */
2100 DEBUG_DUMP("mic", mic
, mic_len
);
2101 DEBUG_DUMP("c_mic", c_mic
, mic_len
);
2102 return memcmp(mic
, c_mic
, mic_len
);
2105 /* IEEE 802.11-2016 Chapter 13.8.4 FT authentication sequence: contents of third message
2106 * IEEE 802.11-2016 Chapter 13.8.5 FT authentication sequence: contents of fourth message
2107 * The MIC shall be calculated on the concatenation of the following data, in the order given here:
2109 * — FTO’s MAC address (6 octets)
2110 * — Target AP’s MAC address (6 octets)
2112 * — Transaction sequence number (1 octet), which shall be set to the value 5 if this is a
2113 * Reassociation Request frame and, otherwise, set to the value 3
2114 * If fourth message:
2115 * — Transaction sequence number (1 octet), which shall be set to the value 6 if this is a
2116 * Reassociation Response frame or, otherwise, set to the value 4
2120 * — FTE, with the MIC field of the FTE set to 0
2121 * — Contents of the RIC-Response (if present)
2123 #if GCRYPT_VERSION_NUMBER >= 0x010600
2125 Dot11DecryptFtMicCheck(
2126 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
2134 guint8 zeros
[16] = { 0 };
2135 gcry_mac_hd_t handle
;
2137 fte_len
= assoc_parsed
->fte_tag
[1] + 2;
2139 DEBUG_PRINT_LINE("FTE too short", DEBUG_LEVEL_3
);
2140 return DOT11DECRYPT_RET_UNSUCCESS
;
2143 switch (assoc_parsed
->frame_subtype
) {
2144 case DOT11DECRYPT_SUBTYPE_ASSOC_REQ
:
2145 sta
= assoc_parsed
->sa
;
2148 case DOT11DECRYPT_SUBTYPE_ASSOC_RESP
:
2149 sta
= assoc_parsed
->da
;
2152 case DOT11DECRYPT_SUBTYPE_REASSOC_REQ
:
2153 sta
= assoc_parsed
->sa
;
2156 case DOT11DECRYPT_SUBTYPE_REASSOC_RESP
:
2157 sta
= assoc_parsed
->da
;
2161 return DOT11DECRYPT_RET_UNSUCCESS
;
2164 if (gcry_mac_open(&handle
, GCRY_MAC_CMAC_AES
, 0, NULL
)) {
2165 DEBUG_PRINT_LINE("gcry_mac_open failed", DEBUG_LEVEL_3
);
2166 return DOT11DECRYPT_RET_UNSUCCESS
;
2168 if (gcry_mac_setkey(handle
, kck
, kck_len
)) {
2169 DEBUG_PRINT_LINE("gcry_mac_setkey failed", DEBUG_LEVEL_3
);
2170 gcry_mac_close(handle
);
2171 return DOT11DECRYPT_RET_UNSUCCESS
;
2173 gcry_mac_write(handle
, sta
, DOT11DECRYPT_MAC_LEN
);
2174 gcry_mac_write(handle
, assoc_parsed
->bssid
, DOT11DECRYPT_MAC_LEN
);
2176 gcry_mac_write(handle
, &seq_num
, 1);
2178 gcry_mac_write(handle
, assoc_parsed
->rsne_tag
, assoc_parsed
->rsne_tag
[1] + 2);
2179 gcry_mac_write(handle
, assoc_parsed
->mde_tag
, assoc_parsed
->mde_tag
[1] + 2);
2181 mic_len
= assoc_parsed
->fte
.mic_len
;
2182 gcry_mac_write(handle
, assoc_parsed
->fte_tag
, 4);
2183 gcry_mac_write(handle
, zeros
, mic_len
); /* MIC zeroed */
2184 gcry_mac_write(handle
, assoc_parsed
->fte_tag
+ 4 + mic_len
, fte_len
- 4 - mic_len
);
2186 if (assoc_parsed
->rde_tag
) {
2187 gcry_mac_write(handle
, assoc_parsed
->rde_tag
, assoc_parsed
->rde_tag
[1] + 2);
2190 if (gcry_mac_verify(handle
, assoc_parsed
->fte
.mic
, mic_len
) != 0) {
2191 DEBUG_DUMP("MIC", assoc_parsed
->fte
.mic
, mic_len
);
2192 DEBUG_PRINT_LINE("MIC verification failed", DEBUG_LEVEL_3
);
2193 gcry_mac_close(handle
);
2194 return DOT11DECRYPT_RET_UNSUCCESS
;
2196 DEBUG_DUMP("MIC", assoc_parsed
->fte
.mic
, mic_len
);
2197 gcry_mac_close(handle
);
2198 return DOT11DECRYPT_RET_SUCCESS
;
2203 Dot11DecryptValidateKey(
2204 PDOT11DECRYPT_KEY_ITEM key
)
2210 DEBUG_PRINT_LINE("NULL key", DEBUG_LEVEL_5
);
2214 switch (key
->KeyType
) {
2215 case DOT11DECRYPT_KEY_TYPE_WEP
:
2216 /* check key size limits */
2217 len
=key
->KeyData
.Wep
.WepKeyLen
;
2218 if (len
<DOT11DECRYPT_WEP_KEY_MINLEN
|| len
>DOT11DECRYPT_WEP_KEY_MAXLEN
) {
2219 DEBUG_PRINT_LINE("WEP key: key length not accepted", DEBUG_LEVEL_5
);
2224 case DOT11DECRYPT_KEY_TYPE_WEP_40
:
2225 /* set the standard length and use a generic WEP key type */
2226 key
->KeyData
.Wep
.WepKeyLen
=DOT11DECRYPT_WEP_40_KEY_LEN
;
2227 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
2230 case DOT11DECRYPT_KEY_TYPE_WEP_104
:
2231 /* set the standard length and use a generic WEP key type */
2232 key
->KeyData
.Wep
.WepKeyLen
=DOT11DECRYPT_WEP_104_KEY_LEN
;
2233 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
2236 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
2237 /* check passphrase and SSID size limits */
2238 len
=strlen(key
->UserPwd
.Passphrase
);
2239 if (len
<DOT11DECRYPT_WPA_PASSPHRASE_MIN_LEN
|| len
>DOT11DECRYPT_WPA_PASSPHRASE_MAX_LEN
) {
2240 DEBUG_PRINT_LINE("WPA-PWD key: passphrase length not accepted", DEBUG_LEVEL_5
);
2244 len
=key
->UserPwd
.SsidLen
;
2245 if (len
>DOT11DECRYPT_WPA_SSID_MAX_LEN
) {
2246 DEBUG_PRINT_LINE("WPA-PWD key: ssid length not accepted", DEBUG_LEVEL_5
);
2252 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
2255 case DOT11DECRYPT_KEY_TYPE_TK
:
2258 case DOT11DECRYPT_KEY_TYPE_MSK
:
2268 Dot11DecryptGetSaAddress(
2269 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
,
2270 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
2272 #ifdef DOT11DECRYPT_DEBUG
2273 #define MSGBUF_LEN 255
2274 CHAR msgbuf
[MSGBUF_LEN
];
2277 if ((DOT11DECRYPT_TYPE(frame
->fc
[0])==DOT11DECRYPT_TYPE_DATA
) &&
2278 (DOT11DECRYPT_DS_BITS(frame
->fc
[1]) == 0) &&
2279 (memcmp(frame
->addr2
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) != 0) &&
2280 (memcmp(frame
->addr1
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) != 0)) {
2281 /* DATA frame with fromDS=0 ToDS=0 and neither RA or SA is BSSID
2282 => TDLS traffic. Use highest MAC address for bssid */
2283 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) < 0) {
2284 memcpy(id
->sta
, frame
->addr1
, DOT11DECRYPT_MAC_LEN
);
2285 memcpy(id
->bssid
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
);
2287 memcpy(id
->sta
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
);
2288 memcpy(id
->bssid
, frame
->addr1
, DOT11DECRYPT_MAC_LEN
);
2293 /* Normal Case: SA between STA and AP */
2294 if ((addr
= Dot11DecryptGetBssidAddress(frame
)) != NULL
) {
2295 memcpy(id
->bssid
, addr
, DOT11DECRYPT_MAC_LEN
);
2297 return DOT11DECRYPT_RET_UNSUCCESS
;
2300 if ((addr
= Dot11DecryptGetStaAddress(frame
)) != NULL
) {
2301 memcpy(id
->sta
, addr
, DOT11DECRYPT_MAC_LEN
);
2303 return DOT11DECRYPT_RET_UNSUCCESS
;
2307 #ifdef DOT11DECRYPT_DEBUG
2308 g_snprintf(msgbuf
, MSGBUF_LEN
, "BSSID_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2309 id
->bssid
[0],id
->bssid
[1],id
->bssid
[2],id
->bssid
[3],id
->bssid
[4],id
->bssid
[5]);
2310 DEBUG_PRINT_LINE(msgbuf
, DEBUG_LEVEL_3
);
2311 g_snprintf(msgbuf
, MSGBUF_LEN
, "STA_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2312 id
->sta
[0],id
->sta
[1],id
->sta
[2],id
->sta
[3],id
->sta
[4],id
->sta
[5]);
2313 DEBUG_PRINT_LINE(msgbuf
, DEBUG_LEVEL_3
);
2316 return DOT11DECRYPT_RET_SUCCESS
;
2320 * Dot11DecryptGetBssidAddress() and Dot11DecryptGetBssidAddress() are used for
2321 * key caching. In each case, it's more important to return a value than
2322 * to return a _correct_ value, so we fudge addresses in some cases, e.g.
2323 * the BSSID in bridged connections.
2324 * FromDS ToDS Sta BSSID
2331 static const UCHAR
*
2332 Dot11DecryptGetStaAddress(
2333 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
2335 switch(DOT11DECRYPT_DS_BITS(frame
->fc
[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2337 if (memcmp(frame
->addr2
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) == 0)
2338 return frame
->addr1
;
2340 return frame
->addr2
;
2342 return frame
->addr2
;
2344 return frame
->addr1
;
2346 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) < 0)
2347 return frame
->addr1
;
2349 return frame
->addr2
;
2356 static const UCHAR
*
2357 Dot11DecryptGetBssidAddress(
2358 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
2360 switch(DOT11DECRYPT_DS_BITS(frame
->fc
[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2362 return frame
->addr3
;
2364 return frame
->addr1
;
2366 return frame
->addr2
;
2368 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) > 0)
2369 return frame
->addr1
;
2371 return frame
->addr2
;
2378 /* From IEEE 802.11-2016 Table 9-131 Cipher suite selectors and
2379 * Table 12-4 Cipher suite key lengths */
2380 static int Dot11DecryptGetTkLen(int cipher
)
2383 case 1: return 40; /* WEP-40 */
2384 case 2: return 256; /* TKIP */
2385 case 3: return -1; /* Reserved */
2386 case 4: return 128; /* CCMP-128 */
2387 case 5: return 104; /* WEP-104 */
2388 case 6: return 128; /* BIP-CMAC-128 */
2389 case 7: return -1; /* Group addressed traffic not allowed */
2390 case 8: return 128; /* GCMP-128 */
2391 case 9: return 256; /* GCMP-256 */
2392 case 10: return 256; /* CCMP-256 */
2393 case 11: return 128; /* BIP-GMAC-128 */
2394 case 12: return 256; /* BIP-GMAC-256 */
2395 case 13: return 256; /* BIP-CMAC-256 */
2397 DEBUG_PRINT_LINE("Unknown cipher", DEBUG_LEVEL_3
);
2402 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2403 static int Dot11DecryptGetKckLen(int akm
)
2414 case 11: return 128;
2415 case 12: return 192;
2416 case 13: return 192;
2417 case 18: return 128;
2419 /* Unknown / Not supported */
2420 DEBUG_PRINT_LINE("Unknown akm", DEBUG_LEVEL_3
);
2425 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2426 static int Dot11DecryptGetKekLen(int akm
)
2437 case 11: return 128;
2438 case 12: return 256;
2439 case 13: return 256;
2440 case 18: return 128;
2442 /* Unknown / Not supported */
2443 DEBUG_PRINT_LINE("Unknown akm", DEBUG_LEVEL_3
);
2448 /* From IEEE 802.11-2016 9.4.2.25.3 AKM suites and
2449 * Table 12-8 Integrity and key-wrap algorithms */
2450 static int Dot11DecryptGetPtkLen(int akm
, int cipher
)
2452 int kck_len
= Dot11DecryptGetKckLen(akm
);
2453 int kek_len
= Dot11DecryptGetKekLen(akm
);
2454 int tk_len
= Dot11DecryptGetTkLen(cipher
);
2456 if (kck_len
== -1 || kek_len
== -1 || tk_len
== -1) {
2457 DEBUG_PRINT_LINE("Invalid PTK len", DEBUG_LEVEL_3
);
2460 return kck_len
+ kek_len
+ tk_len
;
2463 /* From IEEE 802.11-2016 12.7.1.2 PRF and Table 9-133 AKM suite selectors */
2465 Dot11DecryptGetDeriveFuncFromAkm(int akm
)
2471 func
= DOT11DECRYPT_DERIVE_USING_PRF
;
2485 func
= DOT11DECRYPT_DERIVE_USING_KDF
;
2488 /* Unknown / Not supported yet */
2494 /* From IEEE 802.11-2016 12.7.1.2 PRF and Table 9-133 AKM suite selectors */
2496 Dot11DecryptGetHashAlgoFromAkm(int akm
)
2502 algo
= GCRY_MD_SHA1
;
2514 algo
= GCRY_MD_SHA256
;
2518 algo
= GCRY_MD_SHA384
;
2521 /* Unknown / Not supported yet */
2527 /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
2528 /** From IEEE 802.11-2016 12.7.1.3 Pairwise key hierarchy:
2529 * PRF-Length(PMK, “Pairwise key expansion”,
2530 * Min(AA, SPA) || Max(AA, SPA) ||
2531 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
2534 Dot11DecryptDerivePtk(
2535 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
2538 const UCHAR snonce
[32],
2542 guint8
*ptk
, size_t *ptk_len
)
2544 #ifdef DOT11DECRYPT_DEBUG
2545 #define MSGBUF_LEN 255
2546 CHAR msgbuf
[MSGBUF_LEN
];
2549 int ptk_len_bits
= -1;
2552 if (!sa
|| !pmk
|| !snonce
|| !ptk
|| !ptk_len
) {
2553 DEBUG_PRINT_LINE("Invalid input for PTK derivation", DEBUG_LEVEL_3
);
2554 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2557 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
2560 derive_func
= DOT11DECRYPT_DERIVE_USING_PRF
;
2561 algo
= GCRY_MD_SHA1
;
2563 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2564 ptk_len_bits
= Dot11DecryptGetPtkLen(akm
, cipher
);
2565 algo
= Dot11DecryptGetHashAlgoFromAkm(akm
);
2566 derive_func
= Dot11DecryptGetDeriveFuncFromAkm(akm
);
2568 #ifdef DOT11DECRYPT_DEBUG
2569 g_snprintf(msgbuf
, MSGBUF_LEN
, "ptk_len_bits: %d, algo: %d, cipher: %d", ptk_len_bits
, algo
, cipher
);
2570 DEBUG_PRINT_LINE(msgbuf
, DEBUG_LEVEL_3
);
2571 #endif /* DOT11DECRYPT_DEBUG */
2574 if (ptk_len_bits
== -1 || algo
== -1) {
2575 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2577 *ptk_len
= ptk_len_bits
/ 8;
2579 static const char *const label
= "Pairwise key expansion";
2580 guint8 context
[DOT11DECRYPT_MAC_LEN
* 2 + 32 * 2];
2583 /* Min(AA, SPA) || Max(AA, SPA) */
2584 if (memcmp(sa
->saId
.sta
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
) < 0)
2586 memcpy(context
+ offset
, sa
->saId
.sta
, DOT11DECRYPT_MAC_LEN
);
2587 offset
+= DOT11DECRYPT_MAC_LEN
;
2588 memcpy(context
+ offset
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
);
2589 offset
+= DOT11DECRYPT_MAC_LEN
;
2593 memcpy(context
+ offset
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
);
2594 offset
+= DOT11DECRYPT_MAC_LEN
;
2595 memcpy(context
+ offset
, sa
->saId
.sta
, DOT11DECRYPT_MAC_LEN
);
2596 offset
+= DOT11DECRYPT_MAC_LEN
;
2599 /* Min(ANonce, SNonce) || Max(ANonce, SNonce) */
2600 if (memcmp(snonce
, sa
->wpa
.nonce
, 32) < 0 )
2602 memcpy(context
+ offset
, snonce
, 32);
2604 memcpy(context
+ offset
, sa
->wpa
.nonce
, 32);
2609 memcpy(context
+ offset
, sa
->wpa
.nonce
, 32);
2611 memcpy(context
+ offset
, snonce
, 32);
2614 if (derive_func
== DOT11DECRYPT_DERIVE_USING_PRF
) {
2615 dot11decrypt_prf(pmk
, pmk_len
, label
, context
, offset
, algo
,
2618 dot11decrypt_kdf(pmk
, pmk_len
, label
, context
, offset
, algo
,
2621 DEBUG_DUMP("PTK", ptk
, *ptk_len
);
2622 return DOT11DECRYPT_RET_SUCCESS
;
2626 * For Fast BSS Transition AKMS derive PTK from sa, selected key and various information in
2628 * From IEEE 802.11-2016 12.7.1.7.1
2631 Dot11DecryptFtDerivePtk(
2632 const PDOT11DECRYPT_CONTEXT ctx
,
2633 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
2634 const PDOT11DECRYPT_KEY_ITEM key
,
2635 const guint8 mdid
[2],
2636 const guint8
*snonce
,
2637 const guint8
*r0kh_id
, size_t r0kh_id_len
,
2638 const guint8
*r1kh_id
, size_t r1kh_id_len _U_
,
2639 int akm
, int cipher
,
2640 guint8
*ptk
, size_t *ptk_len
)
2642 int hash_algo
= Dot11DecryptGetHashAlgoFromAkm(akm
);
2643 guint8 pmk_r0
[DOT11DECRYPT_WPA_PMK_MAX_LEN
];
2644 guint8 pmk_r1
[DOT11DECRYPT_WPA_PMK_MAX_LEN
];
2645 guint8 pmk_r0_name
[16];
2646 guint8 pmk_r1_name
[16];
2647 guint8 ptk_name
[16];
2650 const guint8
*xxkey
= NULL
;
2654 if (!sa
|| !key
|| !mdid
|| !snonce
|| !r0kh_id
|| !r1kh_id
|| !ptk
|| !ptk_len
) {
2655 DEBUG_PRINT_LINE("Invalid input for FT PTK derivation", DEBUG_LEVEL_3
);
2656 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2658 ptk_len_bits
= Dot11DecryptGetPtkLen(akm
, cipher
);
2659 if (ptk_len_bits
== -1) {
2660 DEBUG_PRINT_LINE("Invalid akm or cipher", DEBUG_LEVEL_3
);
2661 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2663 *ptk_len
= ptk_len_bits
/ 8;
2665 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
2666 xxkey
= Dot11DecryptGetXXKeyFromMSK(key
->Msk
.Msk
,
2671 if (!xxkey
&& key
->KeyData
.Wpa
.PskLen
> 0) {
2672 xxkey
= key
->KeyData
.Wpa
.Psk
;
2673 xxkey_len
= key
->KeyData
.Wpa
.PskLen
;
2676 DEBUG_PRINT_LINE("no xxkey. Skipping", DEBUG_LEVEL_3
);
2677 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2679 dot11decrypt_derive_pmk_r0(xxkey
, xxkey_len
,
2680 ctx
->pkt_ssid
, ctx
->pkt_ssid_len
,
2682 r0kh_id
, r0kh_id_len
,
2683 sa
->saId
.sta
, hash_algo
,
2684 pmk_r0
, &pmk_r0_len
, pmk_r0_name
);
2685 DEBUG_DUMP("PMK-R0", pmk_r0
, (int)pmk_r0_len
);
2686 DEBUG_DUMP("PMKR0Name", pmk_r0_name
, 16);
2688 dot11decrypt_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
,
2689 r1kh_id
, sa
->saId
.sta
, hash_algo
,
2690 pmk_r1
, &pmk_r1_len
, pmk_r1_name
);
2691 DEBUG_DUMP("PMK-R1", pmk_r1
, (int)pmk_r1_len
);
2692 DEBUG_DUMP("PMKR1Name", pmk_r1_name
, 16);
2694 dot11decrypt_derive_ft_ptk(pmk_r1
, pmk_r1_len
, pmk_r1_name
,
2695 snonce
, sa
->wpa
.nonce
,
2696 sa
->saId
.bssid
, sa
->saId
.sta
, hash_algo
,
2697 ptk
, *ptk_len
, ptk_name
);
2698 DEBUG_DUMP("PTK", ptk
, (int)*ptk_len
);
2699 return DOT11DECRYPT_RET_SUCCESS
;
2702 #define MAX_SSID_LENGTH 32 /* maximum SSID length */
2705 Dot11DecryptRsnaPwd2PskStep(
2706 const guint8
*ppBytes
,
2707 const guint ppLength
,
2709 const size_t ssidLength
,
2710 const INT iterations
,
2714 UCHAR digest
[MAX_SSID_LENGTH
+4] = { 0 }; /* SSID plus 4 bytes of count */
2717 if (ssidLength
> MAX_SSID_LENGTH
) {
2718 /* This "should not happen" */
2719 return DOT11DECRYPT_RET_UNSUCCESS
;
2722 /* U1 = PRF(P, S || INT(i)) */
2723 memcpy(digest
, ssid
, ssidLength
);
2724 digest
[ssidLength
] = (UCHAR
)((count
>>24) & 0xff);
2725 digest
[ssidLength
+1] = (UCHAR
)((count
>>16) & 0xff);
2726 digest
[ssidLength
+2] = (UCHAR
)((count
>>8) & 0xff);
2727 digest
[ssidLength
+3] = (UCHAR
)(count
& 0xff);
2728 if (ws_hmac_buffer(GCRY_MD_SHA1
, digest
, digest
, (guint32
) ssidLength
+ 4, ppBytes
, ppLength
)) {
2729 return DOT11DECRYPT_RET_UNSUCCESS
;
2733 memcpy(output
, digest
, 20);
2734 for (i
= 1; i
< iterations
; i
++) {
2735 /* Un = PRF(P, Un-1) */
2736 if (ws_hmac_buffer(GCRY_MD_SHA1
, digest
, digest
, HASH_SHA1_LENGTH
, ppBytes
, ppLength
)) {
2737 return DOT11DECRYPT_RET_UNSUCCESS
;
2740 /* output = output xor Un */
2741 for (j
= 0; j
< 20; j
++) {
2742 output
[j
] ^= digest
[j
];
2746 return DOT11DECRYPT_RET_SUCCESS
;
2750 Dot11DecryptRsnaPwd2Psk(
2751 const CHAR
*passphrase
,
2753 const size_t ssidLength
,
2756 UCHAR m_output
[40] = { 0 };
2757 GByteArray
*pp_ba
= g_byte_array_new();
2759 if (!uri_str_to_bytes(passphrase
, pp_ba
)) {
2760 g_byte_array_free(pp_ba
, TRUE
);
2764 Dot11DecryptRsnaPwd2PskStep(pp_ba
->data
, pp_ba
->len
, ssid
, ssidLength
, 4096, 1, m_output
);
2765 Dot11DecryptRsnaPwd2PskStep(pp_ba
->data
, pp_ba
->len
, ssid
, ssidLength
, 4096, 2, &m_output
[20]);
2767 memcpy(output
, m_output
, DOT11DECRYPT_WPA_PWD_PSK_LEN
);
2768 g_byte_array_free(pp_ba
, TRUE
);
2774 * Returns the decryption_key_t struct given a string describing the key.
2775 * Returns NULL if the input_string cannot be parsed.
2778 parse_key_string(gchar
* input_string
, guint8 key_type
)
2780 gchar
*key
, *tmp_str
;
2783 GString
*key_string
= NULL
;
2784 GByteArray
*ssid_ba
= NULL
, *key_ba
;
2789 decryption_key_t
*dk
;
2791 if(input_string
== NULL
)
2795 * Parse the input_string. WEP and WPA will be just a string
2796 * of hexadecimal characters (if key is wrong, null will be
2798 * WPA-PWD should be in the form
2799 * <key data>[:<ssid>]
2804 case DOT11DECRYPT_KEY_TYPE_WEP
:
2805 case DOT11DECRYPT_KEY_TYPE_WEP_40
:
2806 case DOT11DECRYPT_KEY_TYPE_WEP_104
:
2808 key_ba
= g_byte_array_new();
2809 res
= hex_str_to_bytes(input_string
, key_ba
, FALSE
);
2811 if (res
&& key_ba
->len
> 0) {
2812 /* Key is correct! It was probably an 'old style' WEP key */
2813 /* Create the decryption_key_t structure, fill it and return it*/
2814 dk
= g_new(decryption_key_t
, 1);
2816 dk
->type
= DOT11DECRYPT_KEY_TYPE_WEP
;
2817 /* XXX - The current key handling code in the GUI requires
2818 * no separators and lower case */
2819 tmp_str
= bytes_to_str(NULL
, key_ba
->data
, key_ba
->len
);
2820 dk
->key
= g_string_new(tmp_str
);
2821 g_string_ascii_down(dk
->key
);
2822 dk
->bits
= key_ba
->len
* 8;
2825 wmem_free(NULL
, tmp_str
);
2826 g_byte_array_free(key_ba
, TRUE
);
2830 /* Key doesn't work */
2831 g_byte_array_free(key_ba
, TRUE
);
2834 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
2836 tokens
= g_strsplit(input_string
,":",0);
2838 /* Tokens is a null termiated array of strings ... */
2839 while(tokens
[n
] != NULL
)
2844 /* Free the array of strings */
2850 * The first token is the key
2852 key
= g_strdup(tokens
[0]);
2855 /* Maybe there is a second token (an ssid, if everything else is ok) */
2858 ssid
= g_strdup(tokens
[1]);
2861 /* Create a new string */
2862 key_string
= g_string_new(key
);
2865 /* Two (or more) tokens mean that the user entered a WPA-PWD key ... */
2866 if( ((key_string
->len
) > WPA_KEY_MAX_CHAR_SIZE
) || ((key_string
->len
) < WPA_KEY_MIN_CHAR_SIZE
))
2868 g_string_free(key_string
, TRUE
);
2873 /* Free the array of strings */
2878 if(ssid
!= NULL
) /* more than two tokens found, means that the user specified the ssid */
2880 ssid_ba
= g_byte_array_new();
2881 if (! uri_str_to_bytes(ssid
, ssid_ba
)) {
2882 g_string_free(key_string
, TRUE
);
2883 g_byte_array_free(ssid_ba
, TRUE
);
2886 /* Free the array of strings */
2891 if(ssid_ba
->len
> WPA_SSID_MAX_CHAR_SIZE
)
2893 g_string_free(key_string
, TRUE
);
2894 g_byte_array_free(ssid_ba
, TRUE
);
2899 /* Free the array of strings */
2905 /* Key was correct!!! Create the new decryption_key_t ... */
2906 dk
= g_new(decryption_key_t
, 1);
2908 dk
->type
= DOT11DECRYPT_KEY_TYPE_WPA_PWD
;
2909 dk
->key
= g_string_new(key
);
2910 dk
->bits
= 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
2911 dk
->ssid
= byte_array_dup(ssid_ba
); /* NULL if ssid_ba is NULL */
2913 g_string_free(key_string
, TRUE
);
2914 if (ssid_ba
!= NULL
)
2915 g_byte_array_free(ssid_ba
, TRUE
);
2920 /* Free the array of strings */
2924 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
2926 key_ba
= g_byte_array_new();
2927 res
= hex_str_to_bytes(input_string
, key_ba
, FALSE
);
2929 /* Two tokens means that the user should have entered a WPA-BIN key ... */
2930 if(!res
|| (key_ba
->len
!= DOT11DECRYPT_WPA_PWD_PSK_LEN
&&
2931 key_ba
->len
!= DOT11DECRYPT_WPA_PMK_MAX_LEN
))
2933 g_byte_array_free(key_ba
, TRUE
);
2935 /* No ssid has been created ... */
2939 /* Key was correct!!! Create the new decryption_key_t ... */
2940 dk
= g_new(decryption_key_t
, 1);
2942 dk
->type
= DOT11DECRYPT_KEY_TYPE_WPA_PSK
;
2943 dk
->key
= g_string_new(input_string
);
2944 dk
->bits
= (guint
) dk
->key
->len
* 4;
2947 g_byte_array_free(key_ba
, TRUE
);
2950 case DOT11DECRYPT_KEY_TYPE_TK
:
2952 /* From IEEE 802.11-2016 Table 12-4 Cipher suite key lengths */
2953 static const guint8 allowed_key_lengths
[] = {
2954 // TBD 40 / 8, /* WEP-40 */
2955 // TBD 104 / 8, /* WEP-104 */
2956 256 / 8, /* TKIP, GCMP-256, CCMP-256 */
2957 128 / 8, /* CCMP-128, GCMP-128 */
2959 gboolean key_length_ok
= FALSE
;
2961 key_ba
= g_byte_array_new();
2962 res
= hex_str_to_bytes(input_string
, key_ba
, FALSE
);
2964 for (size_t i
= 0; i
< sizeof(allowed_key_lengths
); i
++) {
2965 if (key_ba
->len
== allowed_key_lengths
[i
]) {
2966 key_length_ok
= TRUE
;
2970 if (!res
|| !key_length_ok
) {
2971 g_byte_array_free(key_ba
, TRUE
);
2974 dk
= g_new(decryption_key_t
, 1);
2975 dk
->type
= DOT11DECRYPT_KEY_TYPE_TK
;
2976 dk
->key
= g_string_new(input_string
);
2977 dk
->bits
= (guint
) dk
->key
->len
* 4;
2980 g_byte_array_free(key_ba
, TRUE
);
2983 case DOT11DECRYPT_KEY_TYPE_MSK
:
2985 key_ba
= g_byte_array_new();
2986 res
= hex_str_to_bytes(input_string
, key_ba
, FALSE
);
2988 if (!res
|| key_ba
->len
< DOT11DECRYPT_MSK_MIN_LEN
||
2989 key_ba
->len
> DOT11DECRYPT_MSK_MAX_LEN
)
2991 g_byte_array_free(key_ba
, TRUE
);
2994 dk
= g_new(decryption_key_t
, 1);
2995 dk
->type
= DOT11DECRYPT_KEY_TYPE_MSK
;
2996 dk
->key
= g_string_new(input_string
);
2997 dk
->bits
= (guint
)dk
->key
->len
* 4;
2999 g_byte_array_free(key_ba
, TRUE
);
3004 /* Type not supported */
3009 free_key_string(decryption_key_t
*dk
)
3012 g_string_free(dk
->key
, TRUE
);
3014 g_byte_array_free(dk
->ssid
, TRUE
);
3019 Dot11DecryptTDLSDeriveKey(
3020 PDOT11DECRYPT_SEC_ASSOCIATION sa
,
3022 #if GCRYPT_VERSION_NUMBER >= 0x010600
3025 guint offset_rsne _U_
,
3028 #if GCRYPT_VERSION_NUMBER >= 0x010600
3029 guint offset_timeout
,
3031 guint offset_timeout _U_
,
3034 #if GCRYPT_VERSION_NUMBER >= 0x010600
3041 gcry_md_hd_t sha256_handle
;
3042 gcry_md_hd_t hmac_handle
;
3043 const guint8
*snonce
, *anonce
, *initiator
, *responder
, *bssid
;
3044 guint8 key_input
[32];
3045 #if GCRYPT_VERSION_NUMBER >= 0x010600
3046 guint8 mic
[16], seq_num
= action
+ 1;
3047 guint8 zeros
[16] = { 0 };
3048 gcry_mac_hd_t cmac_handle
;
3049 size_t cmac_len
= 16;
3050 size_t cmac_write_len
;
3054 anonce
= &data
[offset_fte
+ 20];
3055 snonce
= &data
[offset_fte
+ 52];
3057 gcry_md_open (&sha256_handle
, GCRY_MD_SHA256
, 0);
3058 if (memcmp(anonce
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
) < 0) {
3059 gcry_md_write(sha256_handle
, anonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3060 gcry_md_write(sha256_handle
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3062 gcry_md_write(sha256_handle
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3063 gcry_md_write(sha256_handle
, anonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3065 memcpy(key_input
, gcry_md_read(sha256_handle
, 0), 32);
3066 gcry_md_close(sha256_handle
);
3069 bssid
= &data
[offset_link
+ 2];
3070 initiator
= &data
[offset_link
+ 8];
3071 responder
= &data
[offset_link
+ 14];
3072 if (gcry_md_open(&hmac_handle
, GCRY_MD_SHA256
, GCRY_MD_FLAG_HMAC
)) {
3073 return DOT11DECRYPT_RET_UNSUCCESS
;
3075 if (gcry_md_setkey(hmac_handle
, key_input
, 32)) {
3076 gcry_md_close(hmac_handle
);
3077 return DOT11DECRYPT_RET_UNSUCCESS
;
3079 gcry_md_putc(hmac_handle
, 1);
3080 gcry_md_putc(hmac_handle
, 0);
3081 gcry_md_write(hmac_handle
, "TDLS PMK", 8);
3082 if (memcmp(initiator
, responder
, DOT11DECRYPT_MAC_LEN
) < 0) {
3083 gcry_md_write(hmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3084 gcry_md_write(hmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3086 gcry_md_write(hmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3087 gcry_md_write(hmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3089 gcry_md_write(hmac_handle
, bssid
, DOT11DECRYPT_MAC_LEN
);
3090 gcry_md_putc(hmac_handle
, 0);
3091 gcry_md_putc(hmac_handle
, 1);
3092 memcpy(key_input
, gcry_md_read(hmac_handle
, 0), 32);
3093 gcry_md_close(hmac_handle
);
3096 #if GCRYPT_VERSION_NUMBER >= 0x010600
3097 if (gcry_mac_open(&cmac_handle
, GCRY_MAC_CMAC_AES
, 0, NULL
)) {
3098 return DOT11DECRYPT_RET_UNSUCCESS
;
3100 if (gcry_mac_setkey(cmac_handle
, key_input
, 16)) {
3101 gcry_mac_close(cmac_handle
);
3102 return DOT11DECRYPT_RET_UNSUCCESS
;
3104 gcry_mac_write(cmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3105 gcry_mac_write(cmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3106 gcry_mac_write(cmac_handle
, &seq_num
, 1);
3107 gcry_mac_write(cmac_handle
, &data
[offset_link
], data
[offset_link
+ 1] + 2);
3108 gcry_mac_write(cmac_handle
, &data
[offset_rsne
], data
[offset_rsne
+ 1] + 2);
3109 gcry_mac_write(cmac_handle
, &data
[offset_timeout
], data
[offset_timeout
+ 1] + 2);
3110 gcry_mac_write(cmac_handle
, &data
[offset_fte
], 4);
3111 gcry_mac_write(cmac_handle
, zeros
, 16);
3112 cmac_write_len
= data
[offset_fte
+ 1] + 2;
3113 if (cmac_write_len
< 20) {
3114 DEBUG_PRINT_LINE("Bad MAC len", DEBUG_LEVEL_3
);
3115 gcry_mac_close(cmac_handle
);
3116 return DOT11DECRYPT_RET_UNSUCCESS
;
3118 gcry_mac_write(cmac_handle
, &data
[offset_fte
+ 20], cmac_write_len
- 20);
3119 if (gcry_mac_read(cmac_handle
, mic
, &cmac_len
) != GPG_ERR_NO_ERROR
) {
3120 DEBUG_PRINT_LINE("MAC read error", DEBUG_LEVEL_3
);
3121 gcry_mac_close(cmac_handle
);
3122 return DOT11DECRYPT_RET_UNSUCCESS
;
3124 if (memcmp(mic
, &data
[offset_fte
+ 4], 16)) {
3125 DEBUG_PRINT_LINE("MIC verification failed", DEBUG_LEVEL_3
);
3126 gcry_mac_close(cmac_handle
);
3127 return DOT11DECRYPT_RET_UNSUCCESS
;
3129 gcry_mac_close(cmac_handle
);
3131 DEBUG_PRINT_LINE("MIC verification failed, need libgcrypt >= 1.6", DEBUG_LEVEL_3
);
3132 return DOT11DECRYPT_RET_UNSUCCESS
;
3134 /* TODO support other akm and ciphers? */
3137 sa
->wpa
.ptk_len
= Dot11DecryptGetPtkLen(sa
->wpa
.akm
, sa
->wpa
.cipher
) / 8;
3138 memcpy(DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
3139 key_input
+ 16, Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8);
3140 memcpy(sa
->wpa
.nonce
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3141 sa
->validKey
= TRUE
;
3142 sa
->wpa
.key_ver
= DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
;
3143 DEBUG_PRINT_LINE("MIC verified", DEBUG_LEVEL_3
);
3144 return DOT11DECRYPT_RET_SUCCESS
;
3152 /****************************************************************************/
3160 * indent-tabs-mode: nil
3163 * ex: set shiftwidth=4 tabstop=8 expandtab:
3164 * :indentSize=4:tabSize=8:noTabs=true: