3 * Copyright (c) 2006 CACE Technologies, Davis (California)
6 * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
9 /****************************************************************************/
13 /* Keep this first after config.h so that WS_LOG_DOMAIN is set correctly. */
14 #include "dot11decrypt_debug.h"
19 #include <wsutil/wsgcrypt.h>
20 #include <wsutil/crc32.h>
21 #include <wsutil/pint.h>
23 #include <epan/proto.h> /* for DISSECTOR_ASSERT. */
24 #include <epan/strutil.h>
26 #include "dot11decrypt_util.h"
27 #include "dot11decrypt_system.h"
28 #include "dot11decrypt_int.h"
30 #include "wep-wpadefs.h"
33 /****************************************************************************/
34 static int Dot11DecryptGetKckLen(int akm
);
35 static int Dot11DecryptGetTkLen(int cipher
);
36 static int Dot11DecryptGetKekLen(int akm
);
37 static int Dot11DecryptGetPtkLen(int akm
, int cipher
);
38 static int Dot11DecryptGetHashAlgoFromAkm(int akm
);
40 /****************************************************************************/
41 /* Constant definitions */
43 /* EAPOL definitions */
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)
48 #define DOT11DECRYPT_WPA_KCK_LEN 16
50 *Offset of the Key MIC in the EAPOL packet body
52 #define DOT11DECRYPT_WPA_MICKEY_OFFSET 77
54 * Maximum length of the EAPOL packet (it depends on the maximum MAC
57 #define DOT11DECRYPT_WPA_MAX_EAPOL_LEN 4095
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
63 * Defined in 802.11i-2004, page 78
65 #define DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP 1
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.
71 * Defined in 802.11i-2004, page 78
73 #define DOT11DECRYPT_WPA_KEY_VER_AES_CCMP 2
75 /** Define EAPOL Key Descriptor type values: use 254 for WPA and 2 for WPA2 **/
76 #define DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR 254
77 #define DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR 2
79 /* PMK to PTK derive functions */
80 #define DOT11DECRYPT_DERIVE_USING_PRF 0
81 #define DOT11DECRYPT_DERIVE_USING_KDF 1
82 /****************************************************************************/
85 /****************************************************************************/
86 /* Macro definitions */
88 extern const uint32_t crc32_table
[256];
89 #define CRC(crc, ch) (crc = (crc >> 8) ^ crc32_table[(crc ^ (ch)) & 0xff])
91 #define KCK_OFFSET(akm) (0)
92 #define KEK_OFFSET(akm) ((KCK_OFFSET(akm) + Dot11DecryptGetKckLen(akm) / 8))
93 #define TK_OFFSET(akm) ((KEK_OFFSET(akm) + Dot11DecryptGetKekLen(akm) / 8))
95 #define DOT11DECRYPT_GET_KCK(ptk, akm) (ptk + KCK_OFFSET(akm))
96 #define DOT11DECRYPT_GET_KEK(ptk, akm) (ptk + KEK_OFFSET(akm))
97 #define DOT11DECRYPT_GET_TK_TKIP(ptk) (ptk + 32)
98 #define DOT11DECRYPT_GET_TK(ptk, akm) (ptk + TK_OFFSET(akm))
100 #define DOT11DECRYPT_IEEE80211_OUI(oui) (pntoh24(oui) == 0x000fac)
102 /****************************************************************************/
104 /****************************************************************************/
105 /* Type definitions */
107 /* Internal function prototype declarations */
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
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
125 static int Dot11DecryptRsnaPwd2PskStep(
126 const uint8_t *ppbytes
,
127 const unsigned passLength
,
129 const size_t ssidLength
,
130 const int iterations
,
132 unsigned char *output
)
136 * It calculates the passphrase-to-PSK mapping reccomanded for use with
137 * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
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)
145 * Described in 802.11i-2004, page 165
147 static int Dot11DecryptRsnaPwd2Psk(
148 const struct DOT11DECRYPT_KEY_ITEMDATA_PWD
*userPwd
,
149 unsigned char *output
)
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
)
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
)
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
);
177 * It checks whether the specified key is corrected or not.
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
183 * - true: the key contains valid fields and values
184 * - false: the key has some invalid field or value
186 static int Dot11DecryptValidateKey(
187 PDOT11DECRYPT_KEY_ITEM key
)
190 static int Dot11DecryptRsnaMicCheck(
191 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
192 unsigned char *eapol
,
193 unsigned short eapol_len
,
195 unsigned short key_ver
,
200 Dot11DecryptFtMicCheck(
201 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
205 static PDOT11DECRYPT_SEC_ASSOCIATION
207 PDOT11DECRYPT_CONTEXT ctx
,
208 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
211 static int Dot11DecryptGetSaAddress(
212 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
,
213 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
216 static const unsigned char * Dot11DecryptGetStaAddress(
217 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
220 static const unsigned char * Dot11DecryptGetBssidAddress(
221 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
225 Dot11DecryptDerivePtk(
226 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
227 const unsigned char *pmk
,
229 const unsigned char snonce
[32],
233 uint8_t *ptk
, size_t *ptk_len
);
236 Dot11DecryptFtDerivePtk(
237 const PDOT11DECRYPT_CONTEXT ctx
,
238 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
239 const PDOT11DECRYPT_KEY_ITEM key
,
240 const uint8_t mdid
[2],
241 const uint8_t *snonce
,
242 const uint8_t *r0kh_id
, size_t r0kh_id_len
,
243 const uint8_t *r1kh_id
, size_t r1kh_id_len _U_
,
245 uint8_t *ptk
, size_t *ptk_len
);
248 * @param sa [IN/OUT] pointer to SA that will hold the key
249 * @param data [IN] Frame
250 * @param offset_rsne [IN] RSNE IE offset in the frame
251 * @param offset_fte [IN] Fast BSS Transition IE offset in the frame
252 * @param offset_timeout [IN] Timeout Interval IE offset in the frame
253 * @param offset_link [IN] Link Identifier IE offset in the frame
254 * @param action [IN] Tdls Action code (response or confirm)
257 * DOT11DECRYPT_RET_SUCCESS if Key has been successfully derived (and MIC verified)
258 * DOT11DECRYPT_RET_UNSUCCESS otherwise
261 Dot11DecryptTDLSDeriveKey(
262 PDOT11DECRYPT_SEC_ASSOCIATION sa
,
264 unsigned offset_rsne
,
266 unsigned offset_timeout
,
267 unsigned offset_link
,
274 /****************************************************************************/
276 /****************************************************************************/
277 /* Exported function definitions */
283 const uint8_t broadcast_mac
[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
285 #define TKIP_GROUP_KEY_LEN 32
286 #define CCMP_GROUP_KEY_LEN 16
288 #define EAPOL_RSN_KEY_LEN 95
290 /* Minimum possible key data size (at least one GTK KDE with CCMP key) */
291 #define GROUP_KEY_MIN_LEN 8 + CCMP_GROUP_KEY_LEN
292 /* Minimum possible group key msg size (group key msg using CCMP as cipher)*/
293 #define GROUP_KEY_PAYLOAD_LEN_MIN \
294 (EAPOL_RSN_KEY_LEN + GROUP_KEY_MIN_LEN)
297 Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa
, PDOT11DECRYPT_KEY_ITEM key
)
301 memcpy(key
, sa
->key
, sizeof(DOT11DECRYPT_KEY_ITEM
));
303 memset(key
, 0, sizeof(DOT11DECRYPT_KEY_ITEM
));
304 key
->KeyData
.Wpa
.PtkLen
= sa
->wpa
.ptk_len
;
305 memcpy(key
->KeyData
.Wpa
.Ptk
, sa
->wpa
.ptk
, sa
->wpa
.ptk_len
);
306 key
->KeyData
.Wpa
.Akm
= sa
->wpa
.akm
;
307 key
->KeyData
.Wpa
.Cipher
= sa
->wpa
.cipher
;
308 if (sa
->wpa
.key_ver
==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
)
309 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_TKIP
;
310 else if (sa
->wpa
.key_ver
== 0 || sa
->wpa
.key_ver
== 3 ||
311 sa
->wpa
.key_ver
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
)
313 switch (sa
->wpa
.cipher
) {
315 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_WEP_40
;
318 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_TKIP
;
321 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_CCMP
;
324 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_WEP_104
;
327 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_GCMP
;
330 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_GCMP_256
;
333 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_CCMP_256
;
336 key
->KeyType
= DOT11DECRYPT_KEY_TYPE_UNKNOWN
;
341 case 7: Group addressed traffic not allowed
342 case 11: BIP-GMAC-128
343 case 12: BIP-GMAC-256
344 case 13: BIP-CMAC-256 */
351 Dot11DecryptRc4KeyData(const uint8_t *decryption_key
, unsigned decryption_key_len
,
352 const uint8_t *encrypted_keydata
, unsigned encrypted_keydata_len
)
354 gcry_cipher_hd_t rc4_handle
;
355 uint8_t dummy
[256] = { 0 };
356 uint8_t *decrypted_key
= NULL
;
358 if (gcry_cipher_open (&rc4_handle
, GCRY_CIPHER_ARCFOUR
, GCRY_CIPHER_MODE_STREAM
, 0)) {
361 if (gcry_cipher_setkey(rc4_handle
, decryption_key
, decryption_key_len
)) {
362 gcry_cipher_close(rc4_handle
);
365 decrypted_key
= (uint8_t *)g_memdup2(encrypted_keydata
, encrypted_keydata_len
);
366 if (!decrypted_key
) {
367 gcry_cipher_close(rc4_handle
);
371 /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
372 gcry_cipher_decrypt(rc4_handle
, dummy
, 256, NULL
, 0);
373 gcry_cipher_decrypt(rc4_handle
, decrypted_key
, encrypted_keydata_len
, NULL
, 0);
374 gcry_cipher_close(rc4_handle
);
375 return decrypted_key
;
382 const uint8_t *cipher_text
,
385 uint16_t *output_len
)
387 gcry_cipher_hd_t handle
;
389 if (kek
== NULL
|| cipher_len
< 16 || cipher_text
== NULL
) {
390 return 1; /* "should not happen" */
392 if (gcry_cipher_open(&handle
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_AESWRAP
, 0)) {
395 if (gcry_cipher_setkey(handle
, kek
, kek_len
)) {
396 gcry_cipher_close(handle
);
399 if (gcry_cipher_decrypt(handle
, output
, cipher_len
- 8, cipher_text
, cipher_len
)) {
400 gcry_cipher_close(handle
);
403 *output_len
= cipher_len
- 8;
404 gcry_cipher_close(handle
);
409 Dot11DecryptDecryptKeyData(PDOT11DECRYPT_CONTEXT ctx
,
410 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
411 const unsigned char bssid
[DOT11DECRYPT_MAC_LEN
],
412 const unsigned char sta
[DOT11DECRYPT_MAC_LEN
],
413 unsigned char *decrypted_data
, unsigned *decrypted_len
,
414 PDOT11DECRYPT_KEY_ITEM key
)
417 const uint8_t *key_data
;
418 uint16_t key_bytes_len
= 0; /* Length of the total key data field */
419 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
420 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
422 /* search for a cached Security Association for current BSSID and AP */
423 memcpy(id
.bssid
, bssid
, DOT11DECRYPT_MAC_LEN
);
424 memcpy(id
.sta
, sta
, DOT11DECRYPT_MAC_LEN
);
425 sa
= Dot11DecryptGetSa(ctx
, &id
);
426 if (sa
== NULL
|| !sa
->validKey
) {
427 ws_debug("No valid SA for BSSID found");
428 return DOT11DECRYPT_RET_UNSUCCESS
;
431 /* Decrypt GTK using KEK portion of PTK */
432 uint8_t *decryption_key
= DOT11DECRYPT_GET_KEK(sa
->wpa
.ptk
, sa
->wpa
.akm
);
433 unsigned decryption_key_len
= Dot11DecryptGetKekLen(sa
->wpa
.akm
) / 8;
435 /* 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 /* Preparation for decrypting the group key - determine group key data length */
438 /* depending on whether the pairwise key is TKIP or AES encryption key */
439 key_version
= eapol_parsed
->key_version
;
440 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
){
442 key_bytes_len
= eapol_parsed
->key_len
;
443 }else if (key_version
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
){
445 key_bytes_len
= eapol_parsed
->key_data_len
;
447 /* AES keys must be at least 128 bits = 16 bytes. */
448 if (key_bytes_len
< 16) {
449 return DOT11DECRYPT_RET_UNSUCCESS
;
452 /* XXX Ideally group cipher suite type from EAPOL message 2 of 4 should be used to */
453 /* determine key size. As we currently have no way to do this lookup check that key */
454 /* is at least 16 bytes (IEEE802.11-2016 Table 12-4 Cipher suite key lengths) */
455 key_bytes_len
= eapol_parsed
->key_data_len
;
457 if (key_bytes_len
< 16) {
458 return DOT11DECRYPT_RET_UNSUCCESS
;
462 if ((key_bytes_len
< GROUP_KEY_MIN_LEN
) ||
463 (eapol_parsed
->len
< EAPOL_RSN_KEY_LEN
) ||
464 (key_bytes_len
> eapol_parsed
->len
- EAPOL_RSN_KEY_LEN
)) {
465 return DOT11DECRYPT_RET_UNSUCCESS
;
468 /* Encrypted key is in the information element field of the EAPOL key packet */
469 key_data
= eapol_parsed
->key_data
;
471 DEBUG_DUMP("Encrypted Broadcast key", key_data
, key_bytes_len
, LOG_LEVEL_DEBUG
);
472 DEBUG_DUMP("KeyIV", eapol_parsed
->key_iv
, 16, LOG_LEVEL_DEBUG
);
473 DEBUG_DUMP("decryption_key", decryption_key
, decryption_key_len
, LOG_LEVEL_DEBUG
);
475 /* As we have no concept of the prior association request at this point, we need to deduce the */
476 /* group key cipher from the length of the key bytes. In WPA this is straightforward as the */
477 /* keybytes just contain the GTK, and the GTK is only in the group handshake, NOT the M3. */
478 /* In WPA2 its a little more tricky as the M3 keybytes contain an RSN_IE, but the group handshake */
479 /* does not. Also there are other (variable length) items in the keybytes which we need to account */
480 /* for to determine the true key length, and thus the group cipher. */
482 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
){
484 /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
485 /* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
489 /* The WPA group key just contains the GTK bytes so deducing the type is straightforward */
490 /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
491 sa
->wpa
.key_ver
= (key_bytes_len
>=TKIP_GROUP_KEY_LEN
)?DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
:DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
;
493 /* Build the full decryption key based on the IV and part of the pairwise key */
494 memcpy(new_key
, eapol_parsed
->key_iv
, 16);
495 memcpy(new_key
+16, decryption_key
, 16);
496 DEBUG_DUMP("FullDecrKey", new_key
, 32, LOG_LEVEL_DEBUG
);
497 data
= Dot11DecryptRc4KeyData(new_key
, 32, key_data
, key_bytes_len
);
499 return DOT11DECRYPT_RET_UNSUCCESS
;
501 memcpy(decrypted_data
, data
, key_bytes_len
);
504 /* Ideally AKM from EAPOL message 2 of 4 should be used to determine Key-wrap algorithm to use */
505 /* Though fortunately IEEE802.11-2016 Table 12-8 state that all AKMs use "NIST AES Key Wrap" */
506 /* algorithm so no AKM lookup is needed. */
508 /* Unwrap the key; the result is key_bytes_len in length */
509 if (AES_unwrap(decryption_key
, decryption_key_len
, key_data
, key_bytes_len
,
510 decrypted_data
, &key_bytes_len
)) {
511 return DOT11DECRYPT_RET_UNSUCCESS
;
515 Dot11DecryptCopyKey(sa
, key
);
516 *decrypted_len
= key_bytes_len
;
517 return DOT11DECRYPT_RET_SUCCESS
;
521 * @param ctx [IN] pointer to the current context
522 * @param id [IN] id of the association (composed by BSSID and MAC of
524 * @return a pointer of the requested SA. NULL if it doesn't exist.
526 static PDOT11DECRYPT_SEC_ASSOCIATION
528 PDOT11DECRYPT_CONTEXT ctx
,
529 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
531 return (DOT11DECRYPT_SEC_ASSOCIATION
*)g_hash_table_lookup(ctx
->sa_hash
, id
);
534 static PDOT11DECRYPT_SEC_ASSOCIATION
535 Dot11DecryptNewSa(const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
537 PDOT11DECRYPT_SEC_ASSOCIATION sa
= g_new0(DOT11DECRYPT_SEC_ASSOCIATION
, 1);
544 static DOT11DECRYPT_SEC_ASSOCIATION
*
545 Dot11DecryptPrependSa(
546 DOT11DECRYPT_SEC_ASSOCIATION
*existing_sa
,
547 DOT11DECRYPT_SEC_ASSOCIATION
*new_sa
)
549 DOT11DECRYPT_SEC_ASSOCIATION tmp_sa
;
551 /* Add new SA first in list, but copy by value into existing record
552 * so that sa_hash need not be updated with new value */
553 tmp_sa
= *existing_sa
;
554 *existing_sa
= *new_sa
;
556 existing_sa
->next
= new_sa
;
560 /* Add SA, keep existing (if any). Return pointer to newly inserted (first) SA */
561 static PDOT11DECRYPT_SEC_ASSOCIATION
563 PDOT11DECRYPT_CONTEXT ctx
,
564 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
565 DOT11DECRYPT_SEC_ASSOCIATION
*sa
)
567 DOT11DECRYPT_SEC_ASSOCIATION
*existing_sa
= Dot11DecryptGetSa(ctx
, id
);
568 if (existing_sa
!= NULL
) {
569 sa
= Dot11DecryptPrependSa(existing_sa
, sa
);
571 void *key
= g_memdup2(id
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
));
572 g_hash_table_insert(ctx
->sa_hash
, key
, sa
);
578 Dot11DecryptGetKCK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **kck
)
583 *kck
= DOT11DECRYPT_GET_KCK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
584 return Dot11DecryptGetKckLen(key
->KeyData
.Wpa
.Akm
) / 8;
588 Dot11DecryptGetKEK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **kek
)
593 *kek
= DOT11DECRYPT_GET_KEK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
594 return Dot11DecryptGetKekLen(key
->KeyData
.Wpa
.Akm
) / 8;
598 Dot11DecryptGetTK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **tk
)
604 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_TKIP
) {
605 *tk
= DOT11DECRYPT_GET_TK_TKIP(key
->KeyData
.Wpa
.Ptk
);
608 *tk
= DOT11DECRYPT_GET_TK(key
->KeyData
.Wpa
.Ptk
, key
->KeyData
.Wpa
.Akm
);
609 len
= Dot11DecryptGetTkLen(key
->KeyData
.Wpa
.Cipher
) / 8;
615 Dot11DecryptGetGTK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **gtk
)
622 /* GTK is stored in PTK at offset 32. See comment in Dot11DecryptCopyBroadcastKey */
623 *gtk
= key
->KeyData
.Wpa
.Ptk
+ 32;
624 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_TKIP
) {
627 len
= Dot11DecryptGetTkLen(key
->KeyData
.Wpa
.Cipher
) / 8;
632 int Dot11DecryptScanTdlsForKeys(
633 PDOT11DECRYPT_CONTEXT ctx
,
635 const unsigned tot_len
)
638 unsigned tot_len_left
= tot_len
;
639 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
640 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
641 const uint8_t *initiator
, *responder
;
643 unsigned status
, offset_rsne
= 0, offset_fte
= 0, offset_link
= 0, offset_timeout
= 0;
644 ws_debug("Authentication: TDLS Action Frame");
646 /* TDLS payload contains a TDLS Action field (802.11-2016 9.6.13) */
648 /* check if the packet is a TDLS response or confirm */
649 if (tot_len_left
< 1) {
650 ws_debug("Not EAPOL-Key");
651 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
653 action
= data
[offset
];
654 if (action
!= 1 && action
!= 2) {
655 ws_debug("Not Response nor confirm");
656 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
661 /* Check for SUCCESS (0) or SUCCESS_POWER_SAVE_MODE (85) Status Code */
662 if (tot_len_left
< 5) {
663 ws_debug("Not EAPOL-Key");
664 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
666 status
=pntoh16(data
+ offset
);
667 if (status
!= 0 && status
!= 85) {
668 ws_debug("TDLS setup not successful");
669 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
672 /* skip Token + capabilities */
675 /* search for RSN, Fast BSS Transition, Link Identifier and Timeout Interval IEs */
677 while(offset
< (tot_len
- 2)) {
678 uint8_t element_id
= data
[offset
];
679 uint8_t length
= data
[offset
+ 1];
680 unsigned min_length
= length
;
681 switch (element_id
) {
682 case 48: /* RSN (802.11-2016 9.4.2.35) */
683 offset_rsne
= offset
;
686 case 55: /* FTE (802.11-2016 9.4.2.48) */
688 /* Plus variable length optional parameter(s) */
689 min_length
= 2 + 16 + 32 + 32;
691 case 56: /* Timeout Interval (802.11-2016 9.4.2.49) */
692 offset_timeout
= offset
;
695 case 101: /* Link Identifier (802.11-2016 9.4.2.62) */
696 offset_link
= offset
;
697 min_length
= 6 + 6 + 6;
701 if (length
< min_length
|| tot_len
< offset
+ 2 + length
) {
702 ws_debug("Invalid length records in IEs");
703 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
705 offset
+= 2 + length
;
708 if (offset_rsne
== 0 || offset_fte
== 0 ||
709 offset_timeout
== 0 || offset_link
== 0)
711 ws_debug("Cannot Find all necessary IEs");
712 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
715 ws_debug("Found RSNE/Fast BSS/Timeout Interval/Link IEs");
717 /* Will create a Security Association between 2 STA. Need to get both MAC address */
718 initiator
= &data
[offset_link
+ 8];
719 responder
= &data
[offset_link
+ 14];
721 if (memcmp(initiator
, responder
, DOT11DECRYPT_MAC_LEN
) < 0) {
722 memcpy(id
.sta
, initiator
, DOT11DECRYPT_MAC_LEN
);
723 memcpy(id
.bssid
, responder
, DOT11DECRYPT_MAC_LEN
);
725 memcpy(id
.sta
, responder
, DOT11DECRYPT_MAC_LEN
);
726 memcpy(id
.bssid
, initiator
, DOT11DECRYPT_MAC_LEN
);
729 /* Check if already derived this key */
730 sa
= Dot11DecryptGetSa(ctx
, &id
);
731 PDOT11DECRYPT_SEC_ASSOCIATION iter_sa
;
732 for (iter_sa
= sa
; iter_sa
!= NULL
; iter_sa
= iter_sa
->next
) {
733 if (iter_sa
->validKey
&&
734 memcmp(iter_sa
->wpa
.nonce
, data
+ offset_fte
+ 52,
735 DOT11DECRYPT_WPA_NONCE_LEN
) == 0)
737 /* Already have valid key for this SA, no need to redo key derivation */
738 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
741 /* We are opening a new session with the same two STA (previous sa will be kept if any) */
742 sa
= Dot11DecryptNewSa(&id
);
744 ws_warning("Failed to alloc new SA entry");
745 return DOT11DECRYPT_RET_REQ_DATA
;
747 if (Dot11DecryptTDLSDeriveKey(sa
, data
, offset_rsne
, offset_fte
,
748 offset_timeout
, offset_link
, action
) == DOT11DECRYPT_RET_SUCCESS
) {
749 Dot11DecryptAddSa(ctx
, &id
, sa
);
750 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
753 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
757 Dot11DecryptCopyBroadcastKey(
758 PDOT11DECRYPT_CONTEXT ctx
,
759 const uint8_t *gtk
, size_t gtk_len
,
760 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
762 DOT11DECRYPT_SEC_ASSOCIATION_ID broadcast_id
;
763 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
764 DOT11DECRYPT_SEC_ASSOCIATION
*broadcast_sa
;
766 if (!gtk
|| gtk_len
== 0) {
767 ws_debug("No broadcast key found");
768 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
770 if (gtk_len
> DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32) {
771 ws_debug("Broadcast key too large");
772 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
775 sa
= Dot11DecryptGetSa(ctx
, id
);
777 ws_debug("No SA for BSSID found");
778 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
781 /* Broadcast SA for the current BSSID */
782 memcpy(broadcast_id
.bssid
, id
->bssid
, DOT11DECRYPT_MAC_LEN
);
783 memcpy(broadcast_id
.sta
, broadcast_mac
, DOT11DECRYPT_MAC_LEN
);
785 broadcast_sa
= Dot11DecryptNewSa(&broadcast_id
);
786 if (broadcast_sa
== NULL
) {
787 ws_warning("Failed to alloc broadcast sa");
788 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
791 /* Retrieve AKMS / cipher etc from handshake message 2 */
793 broadcast_sa
->wpa
.key_ver
= sa
->wpa
.key_ver
;
794 broadcast_sa
->wpa
.akm
= sa
->wpa
.akm
;
795 broadcast_sa
->wpa
.cipher
= sa
->wpa
.tmp_group_cipher
;
796 broadcast_sa
->wpa
.ptk_len
= sa
->wpa
.ptk_len
;
797 broadcast_sa
->validKey
= true;
798 DEBUG_DUMP("Broadcast key", gtk
, gtk_len
, LOG_LEVEL_DEBUG
);
800 /* Since this is a GTK and its size is only 32 bytes (vs. the 64 byte size of a PTK),
801 * we fake it and put it in at a 32-byte offset so the Dot11DecryptRsnaMng() function
802 * will extract the right piece of the GTK for decryption. (The first 16 bytes of the
803 * GTK are used for decryption.) */
804 memset(broadcast_sa
->wpa
.ptk
, 0, sizeof(broadcast_sa
->wpa
.ptk
));
805 memcpy(broadcast_sa
->wpa
.ptk
+ 32, gtk
, gtk_len
);
806 Dot11DecryptAddSa(ctx
, &broadcast_id
, broadcast_sa
);
807 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
811 Dot11DecryptGroupHandshake(
812 PDOT11DECRYPT_CONTEXT ctx
,
813 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
814 const DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
815 const unsigned tot_len
)
818 if (GROUP_KEY_PAYLOAD_LEN_MIN
> tot_len
) {
819 ws_debug("Message too short for Group Key");
820 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
822 if (eapol_parsed
->msg_type
!= DOT11DECRYPT_HS_MSG_TYPE_GHS_1
){
823 ws_warning("Not Group handshake message 1");
824 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
826 return Dot11DecryptCopyBroadcastKey(ctx
, eapol_parsed
->gtk
, eapol_parsed
->gtk_len
, id
);
829 int Dot11DecryptScanEapolForKeys(
830 PDOT11DECRYPT_CONTEXT ctx
,
831 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
832 const uint8_t *eapol_raw
,
833 const unsigned tot_len
,
834 const unsigned char bssid
[DOT11DECRYPT_MAC_LEN
],
835 const unsigned char sta
[DOT11DECRYPT_MAC_LEN
])
837 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
839 /* Callers provide these guarantees, so let's make them explicit. */
840 DISSECTOR_ASSERT(tot_len
<= DOT11DECRYPT_EAPOL_MAX_LEN
);
842 ws_debug("Authentication: EAPOL packet");
844 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
845 if (/*eapol_parsed->key_type != 0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
846 eapol_parsed
->key_type
!= DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR
&& /* IEEE 802.11 Key Descriptor Type (WPA2) */
847 eapol_parsed
->key_type
!= DOT11DECRYPT_RSN_WPA_KEY_DESCRIPTOR
) /* 254 = RSN_KEY_DESCRIPTOR - WPA, */
849 ws_debug("Not valid key descriptor type");
850 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
853 /* search for a cached Security Association for current BSSID and AP */
854 memcpy(id
.bssid
, bssid
, DOT11DECRYPT_MAC_LEN
);
855 memcpy(id
.sta
, sta
, DOT11DECRYPT_MAC_LEN
);
857 switch (eapol_parsed
->msg_type
) {
858 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_1
:
859 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_2
:
860 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_3
:
861 case DOT11DECRYPT_HS_MSG_TYPE_4WHS_4
:
862 return Dot11DecryptRsna4WHandshake(ctx
, eapol_parsed
, eapol_raw
,
864 case DOT11DECRYPT_HS_MSG_TYPE_GHS_1
:
865 return Dot11DecryptGroupHandshake(ctx
, eapol_parsed
, &id
, tot_len
);
866 case DOT11DECRYPT_HS_MSG_TYPE_GHS_2
:
868 case DOT11DECRYPT_HS_MSG_TYPE_INVALID
:
870 ws_warning("Invalid message type");
873 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
877 Dot11DecryptGetNbrOfTkKeys(PDOT11DECRYPT_CONTEXT ctx
)
880 for (size_t i
= 0; i
< ctx
->keys_nr
; i
++) {
881 if (ctx
->keys
[i
].KeyType
== DOT11DECRYPT_KEY_TYPE_TK
) {
889 Dot11DecryptUsingUserTk(
890 PDOT11DECRYPT_CONTEXT ctx
,
891 unsigned char *decrypt_data
,
892 unsigned mac_header_len
,
893 unsigned *decrypt_len
,
894 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
895 DOT11DECRYPT_KEY_ITEM
*used_key
)
897 int ret
= DOT11DECRYPT_RET_REQ_DATA
;
898 DOT11DECRYPT_SEC_ASSOCIATION
*sa
= Dot11DecryptNewSa(id
);
899 DOT11DECRYPT_KEY_ITEM
*key
;
907 /* Try decrypt packet with all user TKs applicable ciphers */
908 for (size_t key_index
= 0; key_index
< ctx
->keys_nr
; key_index
++) {
909 key
= &ctx
->keys
[key_index
];
910 if (key
->KeyType
!= DOT11DECRYPT_KEY_TYPE_TK
) {
913 int ciphers_to_try
[4] = { 0 };
914 switch (key
->Tk
.Len
) {
915 case DOT11DECRYPT_WEP_40_KEY_LEN
:
916 case DOT11DECRYPT_WEP_104_KEY_LEN
:
920 ciphers_to_try
[0] = 9; /* GCMP-256 */
921 ciphers_to_try
[1] = 10; /* CCMP-256 */
924 ciphers_to_try
[0] = 4; /* CCMP-128 */
925 ciphers_to_try
[1] = 8; /* GCMP-128 */
926 ciphers_to_try
[2] = 2; /* TKIP */
934 for (int i
= 0; ciphers_to_try
[i
] != 0; i
++) {
935 sa
->wpa
.cipher
= ciphers_to_try
[i
];
936 if (sa
->wpa
.cipher
== DOT11DECRYPT_CIPHER_TKIP
) {
938 memcpy(DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
),
939 key
->Tk
.Tk
, key
->Tk
.Len
);
943 memcpy(DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
944 key
->Tk
.Tk
, key
->Tk
.Len
);
946 sa
->wpa
.ptk_len
= Dot11DecryptGetPtkLen(sa
->wpa
.akm
, sa
->wpa
.cipher
) / 8;
947 ret
= Dot11DecryptRsnaMng(decrypt_data
, mac_header_len
, decrypt_len
, used_key
, sa
);
948 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
949 /* Successfully decrypted using user TK. Add SA formed from user TK so that
950 * subsequent frames can be decrypted much faster using normal code path
951 * without trying each and every user TK entered.
953 Dot11DecryptAddSa(ctx
, id
, sa
);
962 int Dot11DecryptDecryptPacket(
963 PDOT11DECRYPT_CONTEXT ctx
,
965 const unsigned mac_header_len
,
966 const unsigned tot_len
,
967 unsigned char *decrypt_data
,
968 unsigned *decrypt_len
,
969 PDOT11DECRYPT_KEY_ITEM key
)
971 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
972 DISSECTOR_ASSERT(decrypt_data
);
973 DISSECTOR_ASSERT(decrypt_len
);
979 ws_warning("NULL context");
980 return DOT11DECRYPT_RET_REQ_DATA
;
982 if (data
==NULL
|| tot_len
==0) {
983 ws_debug("NULL data or length=0");
984 return DOT11DECRYPT_RET_REQ_DATA
;
987 /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
988 if (tot_len
< (unsigned)(mac_header_len
+DOT11DECRYPT_CRYPTED_DATA_MINLEN
)) {
989 ws_debug("minimum length violated");
990 return DOT11DECRYPT_RET_WRONG_DATA_SIZE
;
993 /* Assume that the decrypt_data field is no more than this size. */
994 if (tot_len
> DOT11DECRYPT_MAX_CAPLEN
) {
995 ws_debug("length too large");
996 return DOT11DECRYPT_RET_UNSUCCESS
;
999 /* get STA/BSSID address */
1000 if (Dot11DecryptGetSaAddress((const DOT11DECRYPT_MAC_FRAME_ADDR4
*)(data
), &id
) != DOT11DECRYPT_RET_SUCCESS
) {
1001 ws_noisy("STA/BSSID not found");
1002 return DOT11DECRYPT_RET_REQ_DATA
;
1005 /* check if data is encrypted (use the WEP bit in the Frame Control field) */
1006 if (DOT11DECRYPT_WEP(data
[1])==0) {
1007 return DOT11DECRYPT_RET_NO_DATA_ENCRYPTED
;
1009 PDOT11DECRYPT_SEC_ASSOCIATION sa
;
1011 /* create new header and data to modify */
1012 *decrypt_len
= tot_len
;
1013 memcpy(decrypt_data
, data
, *decrypt_len
);
1015 /* encrypted data */
1016 ws_noisy("Encrypted data");
1018 /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
1019 /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP, */
1020 /* IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP, */
1021 /* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
1022 if (DOT11DECRYPT_EXTIV(data
[mac_header_len
+ 3]) == 0) {
1023 ws_noisy("WEP encryption");
1024 return Dot11DecryptWepMng(ctx
, decrypt_data
, mac_header_len
, decrypt_len
, key
, &id
);
1026 ws_noisy("TKIP or CCMP encryption");
1028 /* If the destination is a multicast address use the group key. This will not work if the AP is using
1029 more than one group key simultaneously. I've not seen this in practice, however.
1030 Usually an AP will rotate between the two key index values of 1 and 2 whenever
1031 it needs to change the group key to be used. */
1032 if (((const DOT11DECRYPT_MAC_FRAME_ADDR4
*)(data
))->addr1
[0] & 0x01) {
1033 ws_noisy("Broadcast/Multicast address. This is encrypted with a group key.");
1035 /* force STA address to broadcast MAC so we load the SA for the groupkey */
1036 memcpy(id
.sta
, broadcast_mac
, DOT11DECRYPT_MAC_LEN
);
1038 /* search for a cached Security Association for current BSSID and STA/broadcast MAC */
1039 int ret
= DOT11DECRYPT_RET_REQ_DATA
;
1040 sa
= Dot11DecryptGetSa(ctx
, &id
);
1042 /* Decrypt the packet using the appropriate SA */
1043 ret
= Dot11DecryptRsnaMng(decrypt_data
, mac_header_len
, decrypt_len
, key
, sa
);
1045 if (ret
!= DOT11DECRYPT_RET_SUCCESS
&& Dot11DecryptGetNbrOfTkKeys(ctx
) > 0) {
1046 /* Decryption with known SAs failed. Try decrypt with TK user entries */
1047 ret
= Dot11DecryptUsingUserTk(ctx
, decrypt_data
, mac_header_len
, decrypt_len
, &id
, key
);
1051 return DOT11DECRYPT_RET_UNSUCCESS
;
1054 int Dot11DecryptSetKeys(
1055 PDOT11DECRYPT_CONTEXT ctx
,
1056 DOT11DECRYPT_KEY_ITEM keys
[],
1057 const size_t keys_nr
)
1062 if (ctx
==NULL
|| keys
==NULL
) {
1063 ws_warning("NULL context or NULL keys array");
1067 if (keys_nr
>DOT11DECRYPT_MAX_KEYS_NR
) {
1068 ws_warning("Keys number greater than maximum");
1072 /* clean key and SA collections before setting new ones */
1073 Dot11DecryptInitContext(ctx
);
1075 /* check and insert keys */
1076 for (i
=0, success
=0; i
<(int)keys_nr
; i
++) {
1077 if (Dot11DecryptValidateKey(keys
+i
)==true) {
1078 if (keys
[i
].KeyType
==DOT11DECRYPT_KEY_TYPE_WPA_PWD
) {
1079 Dot11DecryptRsnaPwd2Psk(&keys
[i
].UserPwd
, keys
[i
].KeyData
.Wpa
.Psk
);
1080 keys
[i
].KeyData
.Wpa
.PskLen
= DOT11DECRYPT_WPA_PWD_PSK_LEN
;
1082 memcpy(&ctx
->keys
[success
], &keys
[i
], sizeof(keys
[i
]));
1087 ctx
->keys_nr
=success
;
1092 Dot11DecryptCleanKeys(
1093 PDOT11DECRYPT_CONTEXT ctx
)
1096 ws_warning("NULL context");
1100 memset(ctx
->keys
, 0, sizeof(DOT11DECRYPT_KEY_ITEM
) * DOT11DECRYPT_MAX_KEYS_NR
);
1103 ws_debug("Keys collection cleaned!");
1107 Dot11DecryptCleanSA(
1110 DOT11DECRYPT_SEC_ASSOCIATION
*cur_sa
= (DOT11DECRYPT_SEC_ASSOCIATION
*)first_sa
;
1112 DOT11DECRYPT_SEC_ASSOCIATION
*next_sa
= cur_sa
->next
;
1119 Dot11DecryptCleanSecAssoc(
1120 PDOT11DECRYPT_CONTEXT ctx
)
1122 if (ctx
->sa_hash
!= NULL
) {
1123 g_hash_table_destroy(ctx
->sa_hash
);
1124 ctx
->sa_hash
= NULL
;
1129 * XXX - This won't be reliable if a packet containing SSID "B" shows
1130 * up in the middle of a 4-way handshake for SSID "A".
1131 * We should probably use a small array or hash table to keep multiple
1134 int Dot11DecryptSetLastSSID(
1135 PDOT11DECRYPT_CONTEXT ctx
,
1137 size_t pkt_ssid_len
)
1139 if (!ctx
|| !pkt_ssid
|| pkt_ssid_len
< 1 || pkt_ssid_len
> WPA_SSID_MAX_SIZE
)
1140 return DOT11DECRYPT_RET_UNSUCCESS
;
1142 memcpy(ctx
->pkt_ssid
, pkt_ssid
, pkt_ssid_len
);
1143 ctx
->pkt_ssid_len
= pkt_ssid_len
;
1145 return DOT11DECRYPT_RET_SUCCESS
;
1149 Dot11DecryptSaHash(const void *key
)
1151 GBytes
*bytes
= g_bytes_new_static(key
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
));
1152 unsigned hash
= g_bytes_hash(bytes
);
1153 g_bytes_unref(bytes
);
1158 Dot11DecryptIsSaIdEqual(const void *key1
, const void *key2
)
1160 return memcmp(key1
, key2
, sizeof(DOT11DECRYPT_SEC_ASSOCIATION_ID
)) == 0;
1163 int Dot11DecryptInitContext(
1164 PDOT11DECRYPT_CONTEXT ctx
)
1167 ws_warning("NULL context");
1168 return DOT11DECRYPT_RET_UNSUCCESS
;
1171 Dot11DecryptCleanKeys(ctx
);
1172 Dot11DecryptCleanSecAssoc(ctx
);
1174 ctx
->pkt_ssid_len
= 0;
1175 ctx
->sa_hash
= g_hash_table_new_full(Dot11DecryptSaHash
, Dot11DecryptIsSaIdEqual
,
1176 g_free
, Dot11DecryptCleanSA
);
1177 if (ctx
->sa_hash
== NULL
) {
1178 return DOT11DECRYPT_RET_UNSUCCESS
;
1181 ws_debug("Context initialized!");
1182 return DOT11DECRYPT_RET_SUCCESS
;
1185 int Dot11DecryptDestroyContext(
1186 PDOT11DECRYPT_CONTEXT ctx
)
1189 ws_warning("NULL context");
1190 return DOT11DECRYPT_RET_UNSUCCESS
;
1193 Dot11DecryptCleanKeys(ctx
);
1194 Dot11DecryptCleanSecAssoc(ctx
);
1196 ws_debug("Context destroyed!");
1197 return DOT11DECRYPT_RET_SUCCESS
;
1204 /****************************************************************************/
1206 /****************************************************************************/
1207 /* Internal function definitions */
1214 Dot11DecryptRsnaMng(
1215 unsigned char *decrypt_data
,
1216 unsigned mac_header_len
,
1217 unsigned *decrypt_len
,
1218 PDOT11DECRYPT_KEY_ITEM key
,
1219 DOT11DECRYPT_SEC_ASSOCIATION
*sa
)
1222 unsigned char *try_data
;
1223 unsigned try_data_len
= *decrypt_len
;
1225 if (*decrypt_len
== 0) {
1226 ws_debug("Invalid decryption length");
1227 return DOT11DECRYPT_RET_UNSUCCESS
;
1230 /* allocate a temp buffer for the decryption loop */
1231 try_data
=(unsigned char *)g_malloc(try_data_len
);
1233 /* start of loop added by GCS */
1234 for(/* sa */; sa
!= NULL
;sa
=sa
->next
) {
1236 if (sa
->validKey
==false) {
1237 ws_noisy("Key not yet valid");
1241 /* copy the encrypted data into a temp buffer */
1242 memcpy(try_data
, decrypt_data
, *decrypt_len
);
1244 /* Select decryption method based on EAPOL Key Descriptor Version and negotiated AKM
1245 * with selected cipher suite. Refer to IEEE 802.11-2020:
1246 * 12.7.2 EAPOL-Key frames
1247 * 12.2.4 RSNA establishment
1248 * 12.7 Keys and key distribution
1249 * Table 9-149-Cipher suite selectors
1252 if (sa
->wpa
.key_ver
== 1 || sa
->wpa
.cipher
== DOT11DECRYPT_CIPHER_TKIP
) {
1253 /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
1255 DEBUG_DUMP("ptk", sa
->wpa
.ptk
, 64, LOG_LEVEL_NOISY
);
1256 DEBUG_DUMP("ptk portion used", DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
),
1257 16, LOG_LEVEL_NOISY
);
1259 if (*decrypt_len
< (unsigned)mac_header_len
) {
1260 ws_debug("Invalid decryption length");
1262 return DOT11DECRYPT_RET_UNSUCCESS
;
1264 if (*decrypt_len
< DOT11DECRYPT_TKIP_MICLEN
+ DOT11DECRYPT_WEP_ICV
) {
1265 ws_debug("Invalid decryption length");
1267 return DOT11DECRYPT_RET_UNSUCCESS
;
1270 ret
= Dot11DecryptTkipDecrypt(try_data
+ mac_header_len
, *decrypt_len
- mac_header_len
,
1271 try_data
+ DOT11DECRYPT_TA_OFFSET
,
1272 DOT11DECRYPT_GET_TK_TKIP(sa
->wpa
.ptk
));
1274 ws_noisy("TKIP failed!");
1278 ws_noisy("TKIP DECRYPTED!!!");
1279 /* remove MIC and ICV from the end of packet */
1280 *decrypt_len
-= DOT11DECRYPT_TKIP_MICLEN
+ DOT11DECRYPT_WEP_ICV
;
1282 } else if (sa
->wpa
.cipher
== DOT11DECRYPT_CIPHER_GCMP
||
1283 sa
->wpa
.cipher
== DOT11DECRYPT_CIPHER_GCMP256
)
1287 if (*decrypt_len
< DOT11DECRYPT_GCMP_TRAILER
) {
1288 ws_debug("Invalid decryption length");
1290 return DOT11DECRYPT_RET_UNSUCCESS
;
1292 ret
= Dot11DecryptGcmpDecrypt(try_data
, mac_header_len
, (int)*decrypt_len
,
1293 DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1294 Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8);
1298 ws_noisy("GCMP DECRYPTED!!!");
1299 /* remove MIC from the end of packet */
1300 *decrypt_len
-= DOT11DECRYPT_GCMP_TRAILER
;
1303 /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
1306 unsigned trailer
= sa
->wpa
.cipher
!= 10 ? DOT11DECRYPT_CCMP_TRAILER
: DOT11DECRYPT_CCMP_256_TRAILER
;
1307 if (*decrypt_len
< trailer
) {
1308 ws_debug("Invalid decryption length");
1310 return DOT11DECRYPT_RET_UNSUCCESS
;
1313 ret
= Dot11DecryptCcmpDecrypt(try_data
, mac_header_len
, (int)*decrypt_len
,
1314 DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1315 Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8,
1320 ws_noisy("CCMP DECRYPTED!!!");
1321 /* remove MIC from the end of packet */
1322 *decrypt_len
-= trailer
;
1328 /* none of the keys worked */
1334 if (*decrypt_len
> try_data_len
|| *decrypt_len
< 8) {
1335 ws_debug("Invalid decryption length");
1337 return DOT11DECRYPT_RET_UNSUCCESS
;
1340 /* remove protection bit */
1341 decrypt_data
[1]&=0xBF;
1343 /* remove TKIP/CCMP header */
1346 if (*decrypt_len
< mac_header_len
) {
1347 ws_debug("Invalid decryption length < mac_header_len");
1349 return DOT11DECRYPT_RET_UNSUCCESS
;
1352 /* copy the decrypted data into the decrypt buffer GCS*/
1353 memcpy(decrypt_data
+ mac_header_len
, try_data
+ mac_header_len
+ 8,
1354 *decrypt_len
- mac_header_len
);
1357 Dot11DecryptCopyKey(sa
, key
);
1358 return DOT11DECRYPT_RET_SUCCESS
;
1363 PDOT11DECRYPT_CONTEXT ctx
,
1364 unsigned char *decrypt_data
,
1365 unsigned mac_header_len
,
1366 unsigned *decrypt_len
,
1367 PDOT11DECRYPT_KEY_ITEM key
,
1368 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
1370 unsigned char wep_key
[DOT11DECRYPT_WEP_KEY_MAXLEN
+DOT11DECRYPT_WEP_IVLEN
];
1374 DOT11DECRYPT_KEY_ITEM
*tmp_key
;
1375 uint8_t useCache
=false;
1376 unsigned char *try_data
;
1377 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1378 unsigned try_data_len
= *decrypt_len
;
1380 try_data
= (unsigned char *)g_malloc(try_data_len
);
1382 /* get the Security Association structure for the STA and AP */
1384 /* For WEP the sa is used only for caching. When no sa exists all user
1385 * entered WEP keys are checked and on successful packet decryption an
1386 * sa is formed caching the key used for decryption.
1388 sa
= Dot11DecryptGetSa(ctx
, id
);
1389 if (sa
!= NULL
&& sa
->key
!= NULL
) {
1393 for (key_index
=0; key_index
<(int)ctx
->keys_nr
; key_index
++) {
1394 /* use the cached one, or try all keys */
1396 tmp_key
=&ctx
->keys
[key_index
];
1398 if (sa
->key
!=NULL
&& sa
->key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1399 ws_noisy("Try cached WEP key...");
1402 ws_noisy("Cached key is not valid, try another WEP key...");
1403 tmp_key
=&ctx
->keys
[key_index
];
1407 /* obviously, try only WEP keys... */
1408 if (tmp_key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1409 ws_noisy("Try WEP key...");
1411 memset(wep_key
, 0, sizeof(wep_key
));
1412 memcpy(try_data
, decrypt_data
, *decrypt_len
);
1414 /* 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) */
1415 memcpy(wep_key
, try_data
+mac_header_len
, DOT11DECRYPT_WEP_IVLEN
);
1416 keylen
=tmp_key
->KeyData
.Wep
.WepKeyLen
;
1417 memcpy(wep_key
+DOT11DECRYPT_WEP_IVLEN
, tmp_key
->KeyData
.Wep
.WepKey
, keylen
);
1419 ret_value
=Dot11DecryptWepDecrypt(wep_key
,
1420 keylen
+DOT11DECRYPT_WEP_IVLEN
,
1421 try_data
+ (mac_header_len
+DOT11DECRYPT_WEP_IVLEN
+DOT11DECRYPT_WEP_KIDLEN
),
1422 *decrypt_len
-(mac_header_len
+DOT11DECRYPT_WEP_IVLEN
+DOT11DECRYPT_WEP_KIDLEN
+DOT11DECRYPT_CRC_LEN
));
1424 if (ret_value
== DOT11DECRYPT_RET_SUCCESS
)
1425 memcpy(decrypt_data
, try_data
, *decrypt_len
);
1428 if (!ret_value
&& tmp_key
->KeyType
==DOT11DECRYPT_KEY_TYPE_WEP
) {
1429 /* the tried key is the correct one, cache it in the Security Association */
1431 /* Form an SA if one does not exist already */
1433 sa
= Dot11DecryptNewSa(id
);
1435 ws_warning("Failed to alloc sa for WEP");
1436 ret_value
= DOT11DECRYPT_RET_UNSUCCESS
;
1439 sa
= Dot11DecryptAddSa(ctx
, id
, sa
);
1444 memcpy(key
, sa
->key
, sizeof(DOT11DECRYPT_KEY_ITEM
));
1445 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
1450 /* the cached key was not valid, try other keys */
1452 if (useCache
==true) {
1461 return DOT11DECRYPT_RET_UNSUCCESS
;
1463 ws_noisy("WEP DECRYPTED!!!");
1465 /* remove ICV (4bytes) from the end of packet */
1468 if (*decrypt_len
< 4) {
1469 ws_debug("Decryption length too short");
1470 return DOT11DECRYPT_RET_UNSUCCESS
;
1473 /* remove protection bit */
1474 decrypt_data
[1]&=0xBF;
1476 /* remove IC header */
1478 memmove(decrypt_data
+ mac_header_len
,
1479 decrypt_data
+ mac_header_len
+ DOT11DECRYPT_WEP_IVLEN
+ DOT11DECRYPT_WEP_KIDLEN
,
1480 *decrypt_len
- mac_header_len
);
1482 return DOT11DECRYPT_RET_SUCCESS
;
1485 /* From IEEE 802.11-2016 Table 9-133—AKM suite selectors */
1486 static bool Dot11DecryptIsFtAkm(int akm
)
1498 /* Get xxkey portion of MSK */
1499 /* From IEEE 802.11-2016 12.7.1.7.3 PMK-R0 */
1500 static const uint8_t *
1501 Dot11DecryptGetXXKeyFromMSK(const uint8_t *msk
, size_t msk_len
,
1502 int akm
, size_t *xxkey_len
)
1525 /* From IEEE 802.11-2016 12.7.1.3 Pairwise key hierarchy */
1527 Dot11DecryptDerivePmkFromMsk(const uint8_t *msk
, uint8_t msk_len
, int akm
,
1528 uint8_t *pmk
, uint8_t *pmk_len
)
1530 if (!msk
|| !pmk
|| !pmk_len
) {
1533 // When using AKM suite selector 00-0F-AC:12, the length of the PMK, PMK_bits,
1534 // shall be 384 bits. With all other AKM suite selectors, the length of the PMK,
1535 // PMK_bits, shall be 256 bits.
1541 if ((uint8_t)(msk_len
+ *pmk_len
) < msk_len
) {
1545 // PMK = L(MSK, 0, PMK_bits).
1546 memcpy(pmk
, msk
, *pmk_len
);
1550 Dot11DecryptIsWpaKeyType(uint8_t key_type
)
1553 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
1554 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
1555 case DOT11DECRYPT_KEY_TYPE_WPA_PMK
:
1556 case DOT11DECRYPT_KEY_TYPE_MSK
:
1563 Dot11DecryptIsPwdWildcardSsid(const PDOT11DECRYPT_CONTEXT ctx
,
1564 const DOT11DECRYPT_KEY_ITEM
*key_item
)
1566 if (!ctx
|| !key_item
|| key_item
->KeyType
!= DOT11DECRYPT_KEY_TYPE_WPA_PWD
) {
1569 if (key_item
->UserPwd
.SsidLen
== 0 && ctx
->pkt_ssid_len
> 0 &&
1570 ctx
->pkt_ssid_len
<= DOT11DECRYPT_WPA_SSID_MAX_LEN
) {
1576 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
1578 Dot11DecryptRsna4WHandshake(
1579 PDOT11DECRYPT_CONTEXT ctx
,
1580 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
1581 const uint8_t *eapol_raw
,
1582 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
,
1583 const unsigned tot_len
)
1585 DOT11DECRYPT_KEY_ITEM
*tmp_key
, *tmp_pkt_key
, pkt_key
;
1586 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1589 unsigned char useCache
=false;
1590 unsigned char eapol
[DOT11DECRYPT_EAPOL_MAX_LEN
];
1592 if (eapol_parsed
->len
> DOT11DECRYPT_EAPOL_MAX_LEN
||
1593 eapol_parsed
->key_len
> DOT11DECRYPT_EAPOL_MAX_LEN
||
1594 eapol_parsed
->key_data_len
> DOT11DECRYPT_EAPOL_MAX_LEN
) {
1595 ws_debug("Too large EAPOL frame and/or key data");
1596 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1599 /* TODO timeouts? */
1601 /* TODO consider key-index */
1603 /* TODO consider Deauthentications */
1605 ws_debug("4-way handshake...");
1607 /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
1609 /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
1610 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_1
) {
1611 ws_debug("4-way handshake message 1");
1613 /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been */
1614 /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current */
1615 /* local value, the Supplicant discards the message. */
1616 /* -> not checked, the Authenticator will be send another Message 1 (hopefully!) */
1618 /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
1619 if (!eapol_parsed
->nonce
) {
1620 ws_debug("ANonce missing");
1621 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1624 sa
= Dot11DecryptGetSa(ctx
, id
);
1625 if (sa
== NULL
|| sa
->handshake
>= 2) {
1626 /* Either no SA exists or one exists but we're reauthenticating */
1627 sa
= Dot11DecryptNewSa(id
);
1629 ws_warning("Failed to alloc broadcast sa");
1630 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1632 sa
= Dot11DecryptAddSa(ctx
, id
, sa
);
1634 memcpy(sa
->wpa
.nonce
, eapol_parsed
->nonce
, 32);
1636 /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
1637 sa
->wpa
.key_ver
= eapol_parsed
->key_version
;
1639 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1642 /* 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)) */
1643 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_2
) {
1644 ws_debug("4-way handshake message 2");
1646 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
1647 /* outstanding Message 1. If not, it silently discards the message. */
1648 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, */
1649 /* the Authenticator silently discards Message 2. */
1650 /* -> not checked; the Supplicant will send another message 2 (hopefully!) */
1652 sa
= Dot11DecryptGetSa(ctx
, id
);
1654 ws_debug("No SA for BSSID found");
1655 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1657 if (!eapol_parsed
->nonce
) {
1658 ws_debug("SNonce missing");
1659 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1661 if (sa
->key
!= NULL
) {
1667 int group_cipher
= -1;
1668 uint8_t ptk
[DOT11DECRYPT_WPA_PTK_MAX_LEN
];
1671 /* now you can derive the PTK */
1672 for (key_index
=0; key_index
<(int)ctx
->keys_nr
|| useCache
; key_index
++) {
1673 /* use the cached one, or try all keys */
1674 if (useCache
&& Dot11DecryptIsWpaKeyType(sa
->key
->KeyType
)) {
1675 ws_debug("Try cached WPA key...");
1677 /* Step back loop counter as cached key is used instead */
1680 ws_debug("Try WPA key...");
1681 tmp_key
= &ctx
->keys
[key_index
];
1685 /* obviously, try only WPA keys... */
1686 if (!Dot11DecryptIsWpaKeyType(tmp_key
->KeyType
)) {
1689 if (tmp_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_WPA_PWD
&&
1690 Dot11DecryptIsPwdWildcardSsid(ctx
, tmp_key
))
1692 /* We have a "wildcard" SSID. Use the one from the packet. */
1693 memcpy(&pkt_key
, tmp_key
, sizeof(pkt_key
));
1694 memcpy(&pkt_key
.UserPwd
.Ssid
, ctx
->pkt_ssid
, ctx
->pkt_ssid_len
);
1695 pkt_key
.UserPwd
.SsidLen
= ctx
->pkt_ssid_len
;
1696 Dot11DecryptRsnaPwd2Psk(&pkt_key
.UserPwd
, pkt_key
.KeyData
.Wpa
.Psk
);
1697 tmp_pkt_key
= &pkt_key
;
1699 tmp_pkt_key
= tmp_key
;
1701 memcpy(eapol
, eapol_raw
, tot_len
);
1703 /* From IEEE 802.11-2016 12.7.2 EAPOL-Key frames */
1704 if (eapol_parsed
->key_version
== 0 || eapol_parsed
->key_version
== 3 ||
1705 eapol_parsed
->key_version
== DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
)
1707 /* PTK derivation is based on Authentication Key Management Type */
1708 akm
= eapol_parsed
->akm
;
1709 cipher
= eapol_parsed
->cipher
;
1710 group_cipher
= eapol_parsed
->group_cipher
;
1711 } else if (eapol_parsed
->key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
1717 ws_info("EAPOL key_version not supported");
1718 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1721 if (tmp_pkt_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
1722 Dot11DecryptDerivePmkFromMsk(tmp_pkt_key
->Msk
.Msk
, tmp_pkt_key
->Msk
.Len
, akm
,
1723 tmp_pkt_key
->KeyData
.Wpa
.Psk
,
1724 &tmp_pkt_key
->KeyData
.Wpa
.PskLen
);
1727 if (Dot11DecryptIsFtAkm(akm
)) {
1728 ret
= Dot11DecryptFtDerivePtk(ctx
, sa
, tmp_pkt_key
,
1730 eapol_parsed
->nonce
,
1731 eapol_parsed
->fte
.r0kh_id
,
1732 eapol_parsed
->fte
.r0kh_id_len
,
1733 eapol_parsed
->fte
.r1kh_id
,
1734 eapol_parsed
->fte
.r1kh_id_len
,
1735 akm
, cipher
, ptk
, &ptk_len
);
1737 /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
1738 ret
= Dot11DecryptDerivePtk(sa
, /* authenticator nonce, bssid, station mac */
1739 tmp_pkt_key
->KeyData
.Wpa
.Psk
, /* PSK == PMK */
1740 tmp_pkt_key
->KeyData
.Wpa
.PskLen
,
1741 eapol_parsed
->nonce
, /* supplicant nonce */
1742 eapol_parsed
->key_version
,
1743 akm
, cipher
, ptk
, &ptk_len
);
1746 /* Unsuccessful PTK derivation */
1749 DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk
, akm
), Dot11DecryptGetTkLen(cipher
) / 8,
1752 ret
= Dot11DecryptRsnaMicCheck(eapol_parsed
,
1753 eapol
, /* eapol frame (header also) */
1754 tot_len
, /* eapol frame length */
1755 DOT11DECRYPT_GET_KCK(ptk
, akm
),
1756 eapol_parsed
->key_version
,
1758 /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches */
1759 /* that from the (Re)Association Request message. */
1760 /* i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
1761 /* primitive to terminate the association. */
1762 /* ii) If they do match bit-wise, the Authenticator constructs Message 3. */
1764 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
1765 /* the key is the correct one, cache it in the Security Association */
1772 ws_debug("handshake step failed");
1773 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1775 sa
->wpa
.key_ver
= eapol_parsed
->key_version
;
1777 sa
->wpa
.cipher
= cipher
;
1778 sa
->wpa
.tmp_group_cipher
= group_cipher
;
1779 memcpy(sa
->wpa
.ptk
, ptk
, ptk_len
);
1780 sa
->wpa
.ptk_len
= (int)ptk_len
;
1782 sa
->validKey
= true; /* we can use the key to decode, even if we have not captured the other eapol packets */
1784 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1787 /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
1788 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_3
) {
1789 ws_debug("4-way handshake message 3");
1791 /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field */
1792 /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
1793 /* -> not checked, the Authenticator will send another message 3 (hopefully!) */
1795 /* TODO check page 88 (RNS) */
1797 /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1798 In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */
1799 if (eapol_parsed
->key_type
== DOT11DECRYPT_RSN_WPA2_KEY_DESCRIPTOR
) {
1800 return Dot11DecryptCopyBroadcastKey(ctx
, eapol_parsed
->gtk
, eapol_parsed
->gtk_len
, id
);
1805 if (eapol_parsed
->msg_type
== DOT11DECRYPT_HS_MSG_TYPE_4WHS_4
) {
1806 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1808 /* TODO check MIC and Replay Counter */
1809 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one */
1810 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message. */
1811 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1812 /* Authenticator silently discards Message 4. */
1814 ws_debug("4-way handshake message 4");
1815 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1817 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1820 /* Refer to IEEE 802.11-2016 Chapeter 13.8 FT authentication sequence */
1822 Dot11DecryptScanFtAssocForKeys(
1823 const PDOT11DECRYPT_CONTEXT ctx
,
1824 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
1825 uint8_t *decrypted_gtk
, size_t *decrypted_len
,
1826 DOT11DECRYPT_KEY_ITEM
* used_key
)
1828 DOT11DECRYPT_SEC_ASSOCIATION_ID id
;
1830 ws_debug("(Re)Association packet");
1832 if (!ctx
|| !assoc_parsed
) {
1833 ws_warning("Invalid input parameters");
1834 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1836 if (!Dot11DecryptIsFtAkm(assoc_parsed
->akm
)) {
1837 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1839 if (!assoc_parsed
->fte
.anonce
|| !assoc_parsed
->fte
.snonce
) {
1840 ws_debug("ANonce or SNonce missing");
1841 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1844 switch (assoc_parsed
->frame_subtype
) {
1845 case DOT11DECRYPT_SUBTYPE_ASSOC_REQ
:
1846 case DOT11DECRYPT_SUBTYPE_REASSOC_REQ
:
1847 memcpy(id
.sta
, assoc_parsed
->sa
, DOT11DECRYPT_MAC_LEN
);
1849 case DOT11DECRYPT_SUBTYPE_ASSOC_RESP
:
1850 case DOT11DECRYPT_SUBTYPE_REASSOC_RESP
:
1851 memcpy(id
.sta
, assoc_parsed
->da
, DOT11DECRYPT_MAC_LEN
);
1854 ws_warning("Invalid frame subtype");
1855 return DOT11DECRYPT_RET_UNSUCCESS
;
1857 memcpy(id
.bssid
, assoc_parsed
->bssid
, DOT11DECRYPT_MAC_LEN
);
1859 DOT11DECRYPT_KEY_ITEM
*tmp_key
, *tmp_pkt_key
, pkt_key
;
1860 DOT11DECRYPT_SEC_ASSOCIATION
*sa
;
1863 bool useCache
= false;
1865 sa
= Dot11DecryptNewSa(&id
);
1867 ws_warning("Failed to alloc sa");
1868 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1871 memcpy(sa
->wpa
.nonce
, assoc_parsed
->fte
.anonce
, 32);
1873 if (sa
->key
!= NULL
) {
1877 uint8_t ptk
[DOT11DECRYPT_WPA_PTK_MAX_LEN
];
1880 /* now you can derive the PTK */
1881 for (key_index
= 0; key_index
< ctx
->keys_nr
|| useCache
; key_index
++) {
1882 /* use the cached one, or try all keys */
1883 if (useCache
&& Dot11DecryptIsWpaKeyType(sa
->key
->KeyType
)) {
1884 ws_debug("Try cached WPA key...");
1886 /* Step back loop counter as cached key is used instead */
1889 ws_debug("Try WPA key...");
1890 tmp_key
= &ctx
->keys
[key_index
];
1894 /* Try only WPA keys... */
1895 if (!Dot11DecryptIsWpaKeyType(tmp_key
->KeyType
)) {
1898 if (tmp_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_WPA_PWD
&&
1899 Dot11DecryptIsPwdWildcardSsid(ctx
, tmp_key
))
1901 /* We have a "wildcard" SSID. Use the one from the packet. */
1902 memcpy(&pkt_key
, tmp_key
, sizeof(pkt_key
));
1903 memcpy(&pkt_key
.UserPwd
.Ssid
, ctx
->pkt_ssid
, ctx
->pkt_ssid_len
);
1904 pkt_key
.UserPwd
.SsidLen
= ctx
->pkt_ssid_len
;
1905 Dot11DecryptRsnaPwd2Psk(&pkt_key
.UserPwd
, pkt_key
.KeyData
.Wpa
.Psk
);
1906 tmp_pkt_key
= &pkt_key
;
1908 tmp_pkt_key
= tmp_key
;
1911 if (tmp_pkt_key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
1912 Dot11DecryptDerivePmkFromMsk(tmp_pkt_key
->Msk
.Msk
, tmp_pkt_key
->Msk
.Len
,
1914 tmp_pkt_key
->KeyData
.Wpa
.Psk
,
1915 &tmp_pkt_key
->KeyData
.Wpa
.PskLen
);
1918 ret
= Dot11DecryptFtDerivePtk(ctx
, sa
, tmp_pkt_key
,
1920 assoc_parsed
->fte
.snonce
,
1921 assoc_parsed
->fte
.r0kh_id
,
1922 assoc_parsed
->fte
.r0kh_id_len
,
1923 assoc_parsed
->fte
.r1kh_id
,
1924 assoc_parsed
->fte
.r1kh_id_len
,
1925 assoc_parsed
->akm
, assoc_parsed
->cipher
,
1927 if (ret
!= DOT11DECRYPT_RET_SUCCESS
) {
1930 DEBUG_DUMP("TK", DOT11DECRYPT_GET_TK(ptk
, assoc_parsed
->akm
),
1931 Dot11DecryptGetTkLen(assoc_parsed
->cipher
) / 8,
1934 ret
= Dot11DecryptFtMicCheck(assoc_parsed
,
1935 DOT11DECRYPT_GET_KCK(ptk
, assoc_parsed
->akm
),
1936 Dot11DecryptGetKckLen(assoc_parsed
->akm
) / 8);
1937 if (ret
== DOT11DECRYPT_RET_SUCCESS
) {
1938 /* the key is the correct one, cache it in the Security Association */
1945 ws_debug("handshake step failed");
1947 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
1949 sa
= Dot11DecryptAddSa(ctx
, &id
, sa
);
1951 sa
->wpa
.key_ver
= 0; /* Determine key type from akms and cipher*/
1952 sa
->wpa
.akm
= assoc_parsed
->akm
;
1953 sa
->wpa
.cipher
= assoc_parsed
->cipher
;
1954 sa
->wpa
.tmp_group_cipher
= assoc_parsed
->group_cipher
;
1955 memcpy(sa
->wpa
.ptk
, ptk
, ptk_len
);
1956 sa
->wpa
.ptk_len
= (int)ptk_len
;
1957 sa
->validKey
= true;
1959 if (assoc_parsed
->gtk
&& assoc_parsed
->gtk_len
- 8 <= DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32) {
1960 uint8_t decrypted_key
[DOT11DECRYPT_WPA_PTK_MAX_LEN
- 32];
1961 uint16_t decrypted_key_len
;
1962 if (AES_unwrap(DOT11DECRYPT_GET_KEK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
1963 Dot11DecryptGetKekLen(sa
->wpa
.akm
) / 8,
1964 assoc_parsed
->gtk
, assoc_parsed
->gtk_len
,
1965 decrypted_key
, &decrypted_key_len
)) {
1966 return DOT11DECRYPT_RET_UNSUCCESS
;
1968 if (decrypted_key_len
!= assoc_parsed
->gtk_subelem_key_len
) {
1969 ws_debug("Unexpected GTK length");
1970 return DOT11DECRYPT_RET_UNSUCCESS
;
1972 Dot11DecryptCopyBroadcastKey(ctx
, decrypted_key
, decrypted_key_len
, &id
);
1973 *decrypted_len
= decrypted_key_len
;
1974 memcpy(decrypted_gtk
, decrypted_key
, decrypted_key_len
);
1976 Dot11DecryptCopyKey(sa
, used_key
);
1977 return DOT11DECRYPT_RET_SUCCESS_HANDSHAKE
;
1980 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
1982 Dot11DecryptGetIntegrityAlgoFromAkm(int akm
, int *algo
, bool *hmac
)
1988 *algo
= GCRY_MD_SHA1
;
1999 *algo
= GCRY_MAC_CMAC_AES
;
2004 *algo
= GCRY_MD_SHA256
;
2009 *algo
= GCRY_MD_SHA384
;
2013 /* Unknown / Not supported yet */
2021 Dot11DecryptRsnaMicCheck(
2022 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
2023 unsigned char *eapol
,
2024 unsigned short eapol_len
,
2026 unsigned short key_ver
,
2029 uint8_t *mic
= eapol_parsed
->mic
;
2030 uint16_t mic_len
= eapol_parsed
->mic_len
;
2031 uint16_t kck_len
= Dot11DecryptGetKckLen(akm
) / 8;
2032 /* MIC 16 or 24 bytes, though HMAC-SHA256 / SHA384 algos need 32 / 48 bytes buffer */
2033 unsigned char c_mic
[48] = { 0 };
2037 if (!mic
|| mic_len
> DOT11DECRYPT_WPA_MICKEY_MAX_LEN
) {
2038 ws_debug("Not a valid mic");
2039 return DOT11DECRYPT_RET_UNSUCCESS
;
2042 /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
2043 memset(eapol
+ DOT11DECRYPT_WPA_MICKEY_OFFSET
+ 4, 0, mic_len
);
2045 if (key_ver
==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
2046 /* use HMAC-MD5 for the EAPOL-Key MIC */
2049 } else if (key_ver
==DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
) {
2050 /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
2051 algo
= GCRY_MD_SHA1
;
2054 /* Mic check algorithm determined by AKM type */
2055 if (Dot11DecryptGetIntegrityAlgoFromAkm(akm
, &algo
, &hmac
)) {
2056 ws_warning("Unknown Mic check algo");
2057 return DOT11DECRYPT_RET_UNSUCCESS
;
2061 if (ws_hmac_buffer(algo
, c_mic
, eapol
, eapol_len
, KCK
, kck_len
)) {
2062 ws_debug("HMAC_BUFFER");
2063 return DOT11DECRYPT_RET_UNSUCCESS
;
2066 if (ws_cmac_buffer(algo
, c_mic
, eapol
, eapol_len
, KCK
, kck_len
)) {
2067 ws_debug("HMAC_BUFFER");
2068 return DOT11DECRYPT_RET_UNSUCCESS
;
2072 /* compare calculated MIC with the Key MIC and return result (0 means success) */
2073 DEBUG_DUMP("mic", mic
, mic_len
, LOG_LEVEL_DEBUG
);
2074 DEBUG_DUMP("c_mic", c_mic
, mic_len
, LOG_LEVEL_DEBUG
);
2075 return memcmp(mic
, c_mic
, mic_len
);
2078 /* IEEE 802.11-2020 Chapter 13.8.4 FT authentication sequence: contents of third message
2079 * IEEE 802.11-2020 Chapter 13.8.5 FT authentication sequence: contents of fourth message
2080 * The MIC shall be calculated on the concatenation of the following data, in the order given here:
2082 * — FTO’s MAC address (6 octets)
2083 * — Target AP’s MAC address (6 octets)
2085 * — Transaction sequence number (1 octet), which shall be set to the value 5 if this is a
2086 * Reassociation Request frame and, otherwise, set to the value 3
2087 * If fourth message:
2088 * — Transaction sequence number (1 octet), which shall be set to the value 6 if this is a
2089 * Reassociation Response frame or, otherwise, set to the value 4
2093 * — FTE, with the MIC field of the FTE set to 0
2094 * — Contents of the RIC-Response (if present)
2095 * — RSNXE (if present)
2098 Dot11DecryptFtMicCheck(
2099 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
2107 uint8_t zeros
[16] = { 0 };
2108 gcry_mac_hd_t handle
;
2110 fte_len
= assoc_parsed
->fte_tag
[1] + 2;
2112 ws_debug("FTE too short");
2113 return DOT11DECRYPT_RET_UNSUCCESS
;
2116 switch (assoc_parsed
->frame_subtype
) {
2117 case DOT11DECRYPT_SUBTYPE_ASSOC_REQ
:
2118 sta
= assoc_parsed
->sa
;
2121 case DOT11DECRYPT_SUBTYPE_ASSOC_RESP
:
2122 sta
= assoc_parsed
->da
;
2125 case DOT11DECRYPT_SUBTYPE_REASSOC_REQ
:
2126 sta
= assoc_parsed
->sa
;
2129 case DOT11DECRYPT_SUBTYPE_REASSOC_RESP
:
2130 sta
= assoc_parsed
->da
;
2134 return DOT11DECRYPT_RET_UNSUCCESS
;
2137 if (gcry_mac_open(&handle
, GCRY_MAC_CMAC_AES
, 0, NULL
)) {
2138 ws_warning("gcry_mac_open failed");
2139 return DOT11DECRYPT_RET_UNSUCCESS
;
2141 if (gcry_mac_setkey(handle
, kck
, kck_len
)) {
2142 ws_warning("gcry_mac_setkey failed");
2143 gcry_mac_close(handle
);
2144 return DOT11DECRYPT_RET_UNSUCCESS
;
2146 gcry_mac_write(handle
, sta
, DOT11DECRYPT_MAC_LEN
);
2147 gcry_mac_write(handle
, assoc_parsed
->bssid
, DOT11DECRYPT_MAC_LEN
);
2149 gcry_mac_write(handle
, &seq_num
, 1);
2151 gcry_mac_write(handle
, assoc_parsed
->rsne_tag
, assoc_parsed
->rsne_tag
[1] + 2);
2152 gcry_mac_write(handle
, assoc_parsed
->mde_tag
, assoc_parsed
->mde_tag
[1] + 2);
2154 mic_len
= assoc_parsed
->fte
.mic_len
;
2155 gcry_mac_write(handle
, assoc_parsed
->fte_tag
, 4);
2156 gcry_mac_write(handle
, zeros
, mic_len
); /* MIC zeroed */
2157 gcry_mac_write(handle
, assoc_parsed
->fte_tag
+ 4 + mic_len
, fte_len
- 4 - mic_len
);
2159 if (assoc_parsed
->rde_tag
) {
2160 gcry_mac_write(handle
, assoc_parsed
->rde_tag
, assoc_parsed
->rde_tag
[1] + 2);
2162 if (assoc_parsed
->rsnxe_tag
) {
2163 gcry_mac_write(handle
, assoc_parsed
->rsnxe_tag
, assoc_parsed
->rsnxe_tag
[1] + 2);
2166 if (gcry_mac_verify(handle
, assoc_parsed
->fte
.mic
, mic_len
) != 0) {
2167 DEBUG_DUMP("MIC", assoc_parsed
->fte
.mic
, mic_len
, LOG_LEVEL_DEBUG
);
2168 ws_debug("MIC verification failed");
2169 gcry_mac_close(handle
);
2170 return DOT11DECRYPT_RET_UNSUCCESS
;
2172 DEBUG_DUMP("MIC", assoc_parsed
->fte
.mic
, mic_len
, LOG_LEVEL_DEBUG
);
2173 gcry_mac_close(handle
);
2174 return DOT11DECRYPT_RET_SUCCESS
;
2178 Dot11DecryptValidateKey(
2179 PDOT11DECRYPT_KEY_ITEM key
)
2182 unsigned char ret
=true;
2185 ws_warning("NULL key");
2189 switch (key
->KeyType
) {
2190 case DOT11DECRYPT_KEY_TYPE_WEP
:
2191 /* check key size limits */
2192 len
=key
->KeyData
.Wep
.WepKeyLen
;
2193 if (len
<DOT11DECRYPT_WEP_KEY_MINLEN
|| len
>DOT11DECRYPT_WEP_KEY_MAXLEN
) {
2194 ws_info("WEP key: key length not accepted");
2199 case DOT11DECRYPT_KEY_TYPE_WEP_40
:
2200 /* set the standard length and use a generic WEP key type */
2201 key
->KeyData
.Wep
.WepKeyLen
=DOT11DECRYPT_WEP_40_KEY_LEN
;
2202 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
2205 case DOT11DECRYPT_KEY_TYPE_WEP_104
:
2206 /* set the standard length and use a generic WEP key type */
2207 key
->KeyData
.Wep
.WepKeyLen
=DOT11DECRYPT_WEP_104_KEY_LEN
;
2208 key
->KeyType
=DOT11DECRYPT_KEY_TYPE_WEP
;
2211 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
2212 /* check passphrase and SSID size limits */
2213 len
=strlen(key
->UserPwd
.Passphrase
);
2214 if (len
<DOT11DECRYPT_WPA_PASSPHRASE_MIN_LEN
|| len
>DOT11DECRYPT_WPA_PASSPHRASE_MAX_LEN
) {
2215 ws_info("WPA-PWD key: passphrase length not accepted");
2219 len
=key
->UserPwd
.SsidLen
;
2220 if (len
>DOT11DECRYPT_WPA_SSID_MAX_LEN
) {
2221 ws_info("WPA-PWD key: ssid length not accepted");
2227 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
2230 case DOT11DECRYPT_KEY_TYPE_TK
:
2233 case DOT11DECRYPT_KEY_TYPE_MSK
:
2243 Dot11DecryptGetSaAddress(
2244 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
,
2245 DOT11DECRYPT_SEC_ASSOCIATION_ID
*id
)
2247 if ((DOT11DECRYPT_TYPE(frame
->fc
[0])==DOT11DECRYPT_TYPE_DATA
) &&
2248 (DOT11DECRYPT_DS_BITS(frame
->fc
[1]) == 0) &&
2249 (memcmp(frame
->addr2
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) != 0) &&
2250 (memcmp(frame
->addr1
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) != 0)) {
2251 /* DATA frame with fromDS=0 ToDS=0 and neither RA or SA is BSSID
2252 => TDLS traffic. Use highest MAC address for bssid */
2253 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) < 0) {
2254 memcpy(id
->sta
, frame
->addr1
, DOT11DECRYPT_MAC_LEN
);
2255 memcpy(id
->bssid
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
);
2257 memcpy(id
->sta
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
);
2258 memcpy(id
->bssid
, frame
->addr1
, DOT11DECRYPT_MAC_LEN
);
2261 const unsigned char *addr
;
2263 /* Normal Case: SA between STA and AP */
2264 if ((addr
= Dot11DecryptGetBssidAddress(frame
)) != NULL
) {
2265 memcpy(id
->bssid
, addr
, DOT11DECRYPT_MAC_LEN
);
2267 return DOT11DECRYPT_RET_UNSUCCESS
;
2270 if ((addr
= Dot11DecryptGetStaAddress(frame
)) != NULL
) {
2271 memcpy(id
->sta
, addr
, DOT11DECRYPT_MAC_LEN
);
2273 return DOT11DECRYPT_RET_UNSUCCESS
;
2276 ws_noisy("BSSID_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2277 id
->bssid
[0],id
->bssid
[1],id
->bssid
[2],id
->bssid
[3],id
->bssid
[4],id
->bssid
[5]);
2278 ws_noisy("STA_MAC: %02X.%02X.%02X.%02X.%02X.%02X\t",
2279 id
->sta
[0],id
->sta
[1],id
->sta
[2],id
->sta
[3],id
->sta
[4],id
->sta
[5]);
2281 return DOT11DECRYPT_RET_SUCCESS
;
2285 * Dot11DecryptGetBssidAddress() and Dot11DecryptGetBssidAddress() are used for
2286 * key caching. In each case, it's more important to return a value than
2287 * to return a _correct_ value, so we fudge addresses in some cases, e.g.
2288 * the BSSID in bridged connections.
2289 * FromDS ToDS Sta BSSID
2296 static const unsigned char *
2297 Dot11DecryptGetStaAddress(
2298 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
2300 switch(DOT11DECRYPT_DS_BITS(frame
->fc
[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2302 if (memcmp(frame
->addr2
, frame
->addr3
, DOT11DECRYPT_MAC_LEN
) == 0)
2303 return frame
->addr1
;
2305 return frame
->addr2
;
2307 return frame
->addr2
;
2309 return frame
->addr1
;
2311 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) < 0)
2312 return frame
->addr1
;
2314 return frame
->addr2
;
2321 static const unsigned char *
2322 Dot11DecryptGetBssidAddress(
2323 const DOT11DECRYPT_MAC_FRAME_ADDR4
*frame
)
2325 switch(DOT11DECRYPT_DS_BITS(frame
->fc
[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
2327 return frame
->addr3
;
2329 return frame
->addr1
;
2331 return frame
->addr2
;
2333 if (memcmp(frame
->addr1
, frame
->addr2
, DOT11DECRYPT_MAC_LEN
) > 0)
2334 return frame
->addr1
;
2336 return frame
->addr2
;
2343 /* From IEEE 802.11-2016 Table 9-131 Cipher suite selectors and
2344 * Table 12-4 Cipher suite key lengths */
2345 static int Dot11DecryptGetTkLen(int cipher
)
2348 case 1: return 40; /* WEP-40 */
2349 case 2: return 256; /* TKIP */
2350 case 3: return -1; /* Reserved */
2351 case 4: return 128; /* CCMP-128 */
2352 case 5: return 104; /* WEP-104 */
2353 case 6: return 128; /* BIP-CMAC-128 */
2354 case 7: return -1; /* Group addressed traffic not allowed */
2355 case 8: return 128; /* GCMP-128 */
2356 case 9: return 256; /* GCMP-256 */
2357 case 10: return 256; /* CCMP-256 */
2358 case 11: return 128; /* BIP-GMAC-128 */
2359 case 12: return 256; /* BIP-GMAC-256 */
2360 case 13: return 256; /* BIP-CMAC-256 */
2362 ws_warning("Unknown cipher");
2367 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2368 static int Dot11DecryptGetKckLen(int akm
)
2379 case 11: return 128;
2380 case 12: return 192;
2381 case 13: return 192;
2382 case 18: return 128;
2384 /* Unknown / Not supported */
2385 ws_warning("Unknown akm");
2390 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2391 static int Dot11DecryptGetKekLen(int akm
)
2402 case 11: return 128;
2403 case 12: return 256;
2404 case 13: return 256;
2405 case 18: return 128;
2407 /* Unknown / Not supported */
2408 ws_warning("Unknown akm");
2413 /* From IEEE 802.11-2016 9.4.2.25.3 AKM suites and
2414 * Table 12-8 Integrity and key-wrap algorithms */
2415 static int Dot11DecryptGetPtkLen(int akm
, int cipher
)
2417 int kck_len
= Dot11DecryptGetKckLen(akm
);
2418 int kek_len
= Dot11DecryptGetKekLen(akm
);
2419 int tk_len
= Dot11DecryptGetTkLen(cipher
);
2421 if (kck_len
== -1 || kek_len
== -1 || tk_len
== -1) {
2422 ws_warning("Invalid PTK len");
2425 return kck_len
+ kek_len
+ tk_len
;
2428 /* From IEEE 802.11-2016 12.7.1.2 PRF and Table 9-133 AKM suite selectors */
2430 Dot11DecryptGetDeriveFuncFromAkm(int akm
)
2436 func
= DOT11DECRYPT_DERIVE_USING_PRF
;
2450 func
= DOT11DECRYPT_DERIVE_USING_KDF
;
2453 /* Unknown / Not supported yet */
2459 /* From IEEE 802.11-2016 12.7.1.2 PRF and Table 9-133 AKM suite selectors */
2461 Dot11DecryptGetHashAlgoFromAkm(int akm
)
2467 algo
= GCRY_MD_SHA1
;
2479 algo
= GCRY_MD_SHA256
;
2483 algo
= GCRY_MD_SHA384
;
2486 /* Unknown / Not supported yet */
2492 /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
2493 /** From IEEE 802.11-2016 12.7.1.3 Pairwise key hierarchy:
2494 * PRF-Length(PMK, "Pairwise key expansion",
2495 * Min(AA, SPA) || Max(AA, SPA) ||
2496 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
2499 Dot11DecryptDerivePtk(
2500 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
2501 const unsigned char *pmk
,
2503 const unsigned char snonce
[32],
2507 uint8_t *ptk
, size_t *ptk_len
)
2510 int ptk_len_bits
= -1;
2513 if (!sa
|| !pmk
|| !snonce
|| !ptk
|| !ptk_len
) {
2514 ws_warning("Invalid input for PTK derivation");
2515 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2518 if (key_version
== DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP
) {
2521 derive_func
= DOT11DECRYPT_DERIVE_USING_PRF
;
2522 algo
= GCRY_MD_SHA1
;
2524 /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */
2525 ptk_len_bits
= Dot11DecryptGetPtkLen(akm
, cipher
);
2526 algo
= Dot11DecryptGetHashAlgoFromAkm(akm
);
2527 derive_func
= Dot11DecryptGetDeriveFuncFromAkm(akm
);
2528 ws_debug("ptk_len_bits: %d, algo: %d, cipher: %d", ptk_len_bits
, algo
, cipher
);
2531 if (ptk_len_bits
== -1 || algo
== -1) {
2532 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2534 *ptk_len
= ptk_len_bits
/ 8;
2536 static const char *const label
= "Pairwise key expansion";
2537 uint8_t context
[DOT11DECRYPT_MAC_LEN
* 2 + 32 * 2];
2540 /* Min(AA, SPA) || Max(AA, SPA) */
2541 if (memcmp(sa
->saId
.sta
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
) < 0)
2543 memcpy(context
+ offset
, sa
->saId
.sta
, DOT11DECRYPT_MAC_LEN
);
2544 offset
+= DOT11DECRYPT_MAC_LEN
;
2545 memcpy(context
+ offset
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
);
2546 offset
+= DOT11DECRYPT_MAC_LEN
;
2550 memcpy(context
+ offset
, sa
->saId
.bssid
, DOT11DECRYPT_MAC_LEN
);
2551 offset
+= DOT11DECRYPT_MAC_LEN
;
2552 memcpy(context
+ offset
, sa
->saId
.sta
, DOT11DECRYPT_MAC_LEN
);
2553 offset
+= DOT11DECRYPT_MAC_LEN
;
2556 /* Min(ANonce, SNonce) || Max(ANonce, SNonce) */
2557 if (memcmp(snonce
, sa
->wpa
.nonce
, 32) < 0 )
2559 memcpy(context
+ offset
, snonce
, 32);
2561 memcpy(context
+ offset
, sa
->wpa
.nonce
, 32);
2566 memcpy(context
+ offset
, sa
->wpa
.nonce
, 32);
2568 memcpy(context
+ offset
, snonce
, 32);
2571 if (derive_func
== DOT11DECRYPT_DERIVE_USING_PRF
) {
2572 dot11decrypt_prf(pmk
, pmk_len
, label
, context
, offset
, algo
,
2575 dot11decrypt_kdf(pmk
, pmk_len
, label
, context
, offset
, algo
,
2578 DEBUG_DUMP("PTK", ptk
, *ptk_len
, LOG_LEVEL_DEBUG
);
2579 return DOT11DECRYPT_RET_SUCCESS
;
2583 * For Fast BSS Transition AKMS derive PTK from sa, selected key and various information in
2585 * From IEEE 802.11-2016 12.7.1.7.1
2588 Dot11DecryptFtDerivePtk(
2589 const PDOT11DECRYPT_CONTEXT ctx
,
2590 const DOT11DECRYPT_SEC_ASSOCIATION
*sa
,
2591 const PDOT11DECRYPT_KEY_ITEM key
,
2592 const uint8_t mdid
[2],
2593 const uint8_t *snonce
,
2594 const uint8_t *r0kh_id
, size_t r0kh_id_len
,
2595 const uint8_t *r1kh_id
, size_t r1kh_id_len _U_
,
2596 int akm
, int cipher
,
2597 uint8_t *ptk
, size_t *ptk_len
)
2599 int hash_algo
= Dot11DecryptGetHashAlgoFromAkm(akm
);
2600 uint8_t pmk_r0
[DOT11DECRYPT_WPA_PMK_MAX_LEN
];
2601 uint8_t pmk_r1
[DOT11DECRYPT_WPA_PMK_MAX_LEN
];
2602 uint8_t pmk_r0_name
[16] = {0};
2603 uint8_t pmk_r1_name
[16] = {0};
2604 uint8_t ptk_name
[16];
2605 size_t pmk_r0_len
= 0;
2606 size_t pmk_r1_len
= 0;
2607 const uint8_t *xxkey
= NULL
;
2611 if (!sa
|| !key
|| !mdid
|| !snonce
|| !r0kh_id
|| !r1kh_id
|| !ptk
|| !ptk_len
) {
2612 ws_warning("Invalid input for FT PTK derivation");
2613 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2615 ptk_len_bits
= Dot11DecryptGetPtkLen(akm
, cipher
);
2616 if (ptk_len_bits
== -1) {
2617 ws_warning("Invalid akm or cipher");
2618 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2620 *ptk_len
= ptk_len_bits
/ 8;
2622 if (key
->KeyType
== DOT11DECRYPT_KEY_TYPE_MSK
) {
2623 xxkey
= Dot11DecryptGetXXKeyFromMSK(key
->Msk
.Msk
,
2628 if (!xxkey
&& key
->KeyData
.Wpa
.PskLen
> 0) {
2629 xxkey
= key
->KeyData
.Wpa
.Psk
;
2630 xxkey_len
= key
->KeyData
.Wpa
.PskLen
;
2633 ws_debug("no xxkey. Skipping");
2634 return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE
;
2636 if (!dot11decrypt_derive_pmk_r0(xxkey
, xxkey_len
,
2637 ctx
->pkt_ssid
, ctx
->pkt_ssid_len
,
2639 r0kh_id
, r0kh_id_len
,
2640 sa
->saId
.sta
, hash_algo
,
2641 pmk_r0
, &pmk_r0_len
, pmk_r0_name
)) {
2642 /* This can fail for bad size or a bad SHA256 sum. */
2643 return DOT11DECRYPT_RET_UNSUCCESS
;
2645 DEBUG_DUMP("PMK-R0", pmk_r0
, pmk_r0_len
, LOG_LEVEL_DEBUG
);
2646 DEBUG_DUMP("PMKR0Name", pmk_r0_name
, 16, LOG_LEVEL_DEBUG
);
2648 if (!dot11decrypt_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
,
2649 r1kh_id
, sa
->saId
.sta
, hash_algo
,
2650 pmk_r1
, &pmk_r1_len
, pmk_r1_name
)) {
2651 return DOT11DECRYPT_RET_UNSUCCESS
;
2653 DEBUG_DUMP("PMK-R1", pmk_r1
, pmk_r1_len
, LOG_LEVEL_DEBUG
);
2654 DEBUG_DUMP("PMKR1Name", pmk_r1_name
, 16, LOG_LEVEL_DEBUG
);
2656 if (!dot11decrypt_derive_ft_ptk(pmk_r1
, pmk_r1_len
, pmk_r1_name
,
2657 snonce
, sa
->wpa
.nonce
,
2658 sa
->saId
.bssid
, sa
->saId
.sta
, hash_algo
,
2659 ptk
, *ptk_len
, ptk_name
)) {
2660 return DOT11DECRYPT_RET_UNSUCCESS
;
2662 DEBUG_DUMP("PTK", ptk
, *ptk_len
, LOG_LEVEL_DEBUG
);
2663 return DOT11DECRYPT_RET_SUCCESS
;
2666 #define MAX_SSID_LENGTH 32 /* maximum SSID length */
2669 Dot11DecryptRsnaPwd2PskStep(
2670 const uint8_t *ppBytes
,
2671 const unsigned ppLength
,
2673 const size_t ssidLength
,
2674 const int iterations
,
2676 unsigned char *output
)
2678 unsigned char digest
[MAX_SSID_LENGTH
+4] = { 0 }; /* SSID plus 4 bytes of count */
2681 if (ssidLength
> MAX_SSID_LENGTH
) {
2682 /* This "should not happen" */
2683 return DOT11DECRYPT_RET_UNSUCCESS
;
2686 /* U1 = PRF(P, S || int(i)) */
2687 memcpy(digest
, ssid
, ssidLength
);
2688 digest
[ssidLength
] = (unsigned char)((count
>>24) & 0xff);
2689 digest
[ssidLength
+1] = (unsigned char)((count
>>16) & 0xff);
2690 digest
[ssidLength
+2] = (unsigned char)((count
>>8) & 0xff);
2691 digest
[ssidLength
+3] = (unsigned char)(count
& 0xff);
2692 if (ws_hmac_buffer(GCRY_MD_SHA1
, digest
, digest
, (uint32_t) ssidLength
+ 4, ppBytes
, ppLength
)) {
2693 return DOT11DECRYPT_RET_UNSUCCESS
;
2697 memcpy(output
, digest
, 20);
2698 for (i
= 1; i
< iterations
; i
++) {
2699 /* Un = PRF(P, Un-1) */
2700 if (ws_hmac_buffer(GCRY_MD_SHA1
, digest
, digest
, HASH_SHA1_LENGTH
, ppBytes
, ppLength
)) {
2701 return DOT11DECRYPT_RET_UNSUCCESS
;
2704 /* output = output xor Un */
2705 for (j
= 0; j
< 20; j
++) {
2706 output
[j
] ^= digest
[j
];
2710 return DOT11DECRYPT_RET_SUCCESS
;
2714 Dot11DecryptRsnaPwd2Psk(
2715 const struct DOT11DECRYPT_KEY_ITEMDATA_PWD
*userPwd
,
2716 unsigned char *output
)
2718 unsigned char m_output
[40] = { 0 };
2719 GByteArray
*pp_ba
= g_byte_array_new();
2721 g_byte_array_append(pp_ba
, userPwd
->Passphrase
, (unsigned)userPwd
->PassphraseLen
);
2723 Dot11DecryptRsnaPwd2PskStep(pp_ba
->data
, pp_ba
->len
, userPwd
->Ssid
, userPwd
->SsidLen
, 4096, 1, m_output
);
2724 Dot11DecryptRsnaPwd2PskStep(pp_ba
->data
, pp_ba
->len
, userPwd
->Ssid
, userPwd
->SsidLen
, 4096, 2, &m_output
[20]);
2726 memcpy(output
, m_output
, DOT11DECRYPT_WPA_PWD_PSK_LEN
);
2727 g_byte_array_free(pp_ba
, true);
2733 * Returns the decryption_key_t struct given a string describing the key.
2734 * Returns NULL if the input_string cannot be parsed.
2735 * XXX: Should return an error string explaining why parsing failed
2738 parse_key_string(char* input_string
, uint8_t key_type
, char** error
)
2740 GByteArray
*ssid_ba
= NULL
, *key_ba
;
2744 decryption_key_t
*dk
;
2746 if(input_string
== NULL
|| (strcmp(input_string
, "") == 0)) {
2748 *error
= g_strdup("Key cannot be empty");
2754 * Parse the input_string. WEP and WPA will be just a string
2755 * of hexadecimal characters (if key is wrong, null will be
2757 * WPA-PWD should be in the form
2758 * <key data>[:<ssid>]
2759 * With WPA-PWD, we percent-decode the key data and ssid.
2760 * The percent itself ("%25") and the colon ("%3a") must be
2761 * percent-encoded, the latter so we can distinguish between the
2762 * separator and a colon in the key or ssid. Percent-encoding
2763 * for anything else is optional. (NUL is not allowed, either
2764 * percent-encoded or not.)
2769 case DOT11DECRYPT_KEY_TYPE_WEP
:
2770 case DOT11DECRYPT_KEY_TYPE_WEP_40
:
2771 case DOT11DECRYPT_KEY_TYPE_WEP_104
:
2773 key_ba
= g_byte_array_new();
2775 if (!hex_str_to_bytes(input_string
, key_ba
, false)) {
2777 *error
= g_strdup("WEP key must be a hexadecimal string");
2779 g_byte_array_free(key_ba
, true);
2783 if (key_ba
->len
> 0 && key_ba
->len
<= DOT11DECRYPT_WEP_KEY_MAXLEN
) {
2784 /* Key is correct! It was probably an 'old style' WEP key */
2785 /* Create the decryption_key_t structure, fill it and return it*/
2786 dk
= g_new(decryption_key_t
, 1);
2788 dk
->type
= DOT11DECRYPT_KEY_TYPE_WEP
;
2790 dk
->bits
= key_ba
->len
* 8;
2797 *error
= ws_strdup_printf("WEP key entered is %u bytes, and must be no more than %u", key_ba
->len
, DOT11DECRYPT_WEP_KEY_MAXLEN
);
2799 /* Key doesn't work */
2800 g_byte_array_free(key_ba
, true);
2803 case DOT11DECRYPT_KEY_TYPE_WPA_PWD
:
2805 tokens
= g_strsplit(input_string
,":", 3);
2806 n
= g_strv_length(tokens
);
2810 /* Require either one or two tokens; more, and the user
2811 * may have meant a colon in the passphrase or SSID name
2813 /* Free the array of strings */
2814 /* XXX: Return why parsing failed (":" must be escaped) */
2816 *error
= g_strdup("Only one ':' is allowed, as a separator between passphrase and SSID; others must be percent-encoded as \"%%3a\"");
2823 * The first token is the key
2825 key_ba
= g_byte_array_new();
2826 if (! uri_str_to_bytes(tokens
[0], key_ba
)) {
2827 /* Failed parsing as percent-encoded */
2829 *error
= g_strdup("WPA passphrase is treated as percent-encoded; use \"%%25\" for a literal \"%%\"");
2831 g_byte_array_free(key_ba
, true);
2836 /* key length (after percent-decoding) should be between 8 and 63
2837 * octets (63 to distinguish from a PSK as 64 hex characters.)
2838 * XXX: 802.11-2016 Annex J assumes that each character in the
2839 * pass-phrase is ASCII printable ("has an encoding in the range
2840 * 32 to 126"), though this (and the entire algorithm for that
2841 * matter) is only considered a suggestion.
2842 * It is possible to apply PBKDF2 to any octet string, e.g. UTF-8.
2843 * (wpa_passphrase from wpa_supplicant will do so, for example.)
2845 if( ((key_ba
->len
) > WPA_KEY_MAX_CHAR_SIZE
) || ((key_ba
->len
) < WPA_KEY_MIN_CHAR_SIZE
))
2848 *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
);
2850 g_byte_array_free(key_ba
, true);
2852 /* Free the array of strings */
2858 if (n
>= 2) /* more than two tokens found, means that the user specified the ssid */
2860 ssid_ba
= g_byte_array_new();
2861 if (! uri_str_to_bytes(tokens
[1], ssid_ba
)) {
2863 *error
= g_strdup("WPA SSID is treated as percent-encoded; use \"%%25\" for a literal \"%%\".");
2865 g_byte_array_free(key_ba
, true);
2866 g_byte_array_free(ssid_ba
, true);
2867 /* Free the array of strings */
2872 if(ssid_ba
->len
> WPA_SSID_MAX_CHAR_SIZE
)
2875 *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
);
2877 g_byte_array_free(key_ba
, true);
2878 g_byte_array_free(ssid_ba
, true);
2880 /* Free the array of strings */
2886 /* Key was correct!!! Create the new decryption_key_t ... */
2887 dk
= g_new(decryption_key_t
, 1);
2889 dk
->type
= DOT11DECRYPT_KEY_TYPE_WPA_PWD
;
2891 dk
->bits
= 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
2892 dk
->ssid
= ssid_ba
; /* NULL if ssid_ba is NULL */
2894 /* Free the array of strings */
2898 case DOT11DECRYPT_KEY_TYPE_WPA_PSK
:
2900 key_ba
= g_byte_array_new();
2901 if (!hex_str_to_bytes(input_string
, key_ba
, false)) {
2903 *error
= g_strdup("WPA PSK/PMK must be a hexadecimal string");
2905 g_byte_array_free(key_ba
, true);
2909 /* Two tokens means that the user should have entered a WPA-BIN key ... */
2910 if((key_ba
->len
!= DOT11DECRYPT_WPA_PWD_PSK_LEN
&&
2911 key_ba
->len
!= DOT11DECRYPT_WPA_PMK_MAX_LEN
))
2914 *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
);
2916 g_byte_array_free(key_ba
, true);
2920 /* Key was correct!!! Create the new decryption_key_t ... */
2921 dk
= g_new(decryption_key_t
, 1);
2923 dk
->type
= DOT11DECRYPT_KEY_TYPE_WPA_PSK
;
2925 dk
->bits
= (unsigned) dk
->key
->len
* 8;
2930 case DOT11DECRYPT_KEY_TYPE_TK
:
2932 /* From IEEE 802.11-2016 Table 12-4 Cipher suite key lengths */
2933 static const uint8_t allowed_key_lengths
[] = {
2934 // TBD 40 / 8, /* WEP-40 */
2935 // TBD 104 / 8, /* WEP-104 */
2936 128 / 8, /* CCMP-128, GCMP-128 */
2937 256 / 8, /* TKIP, GCMP-256, CCMP-256 */
2939 bool key_length_ok
= false;
2941 key_ba
= g_byte_array_new();
2942 if (!hex_str_to_bytes(input_string
, key_ba
, false)) {
2944 *error
= g_strdup("Temporal Key must be a hexadecimal string");
2946 g_byte_array_free(key_ba
, true);
2950 for (size_t i
= 0; i
< sizeof(allowed_key_lengths
); i
++) {
2951 if (key_ba
->len
== allowed_key_lengths
[i
]) {
2952 key_length_ok
= true;
2956 if (!key_length_ok
) {
2958 GString
*err_string
= g_string_new("Temporal Keys entered is ");
2959 g_string_append_printf(err_string
, "%u bytes and must be ", key_ba
->len
);
2961 for (; i
+ 1 < sizeof(allowed_key_lengths
); i
++) {
2962 g_string_append_printf(err_string
, "%u, ", allowed_key_lengths
[i
]);
2964 g_string_append_printf(err_string
, "or %u bytes.", allowed_key_lengths
[i
]);
2965 *error
= g_string_free(err_string
, FALSE
);
2967 g_byte_array_free(key_ba
, true);
2970 dk
= g_new(decryption_key_t
, 1);
2971 dk
->type
= DOT11DECRYPT_KEY_TYPE_TK
;
2973 dk
->bits
= (unsigned) dk
->key
->len
* 8;
2978 case DOT11DECRYPT_KEY_TYPE_MSK
:
2980 key_ba
= g_byte_array_new();
2981 if (!hex_str_to_bytes(input_string
, key_ba
, false)) {
2983 *error
= g_strdup("Master Session Key must be a hexadecimal string");
2985 g_byte_array_free(key_ba
, true);
2989 if (key_ba
->len
< DOT11DECRYPT_MSK_MIN_LEN
||
2990 key_ba
->len
> DOT11DECRYPT_MSK_MAX_LEN
)
2993 *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
);
2995 g_byte_array_free(key_ba
, true);
2998 dk
= g_new(decryption_key_t
, 1);
2999 dk
->type
= DOT11DECRYPT_KEY_TYPE_MSK
;
3001 dk
->bits
= (unsigned)dk
->key
->len
* 8;
3007 /* Type not supported */
3009 *error
= g_strdup("Unknown key type not supported");
3015 free_key_string(decryption_key_t
*dk
)
3018 g_byte_array_free(dk
->key
, true);
3020 g_byte_array_free(dk
->ssid
, true);
3025 Dot11DecryptTDLSDeriveKey(
3026 PDOT11DECRYPT_SEC_ASSOCIATION sa
,
3027 const uint8_t *data
,
3028 unsigned offset_rsne
,
3029 unsigned offset_fte
,
3030 unsigned offset_timeout
,
3031 unsigned offset_link
,
3035 gcry_md_hd_t sha256_handle
;
3036 gcry_md_hd_t hmac_handle
;
3037 const uint8_t *snonce
, *anonce
, *initiator
, *responder
, *bssid
;
3038 uint8_t key_input
[32];
3039 uint8_t mic
[16], seq_num
= action
+ 1;
3040 uint8_t zeros
[16] = { 0 };
3041 gcry_mac_hd_t cmac_handle
;
3042 size_t cmac_len
= 16;
3043 size_t cmac_write_len
;
3046 anonce
= &data
[offset_fte
+ 20];
3047 snonce
= &data
[offset_fte
+ 52];
3049 if (gcry_md_open (&sha256_handle
, GCRY_MD_SHA256
, 0)) {
3050 return DOT11DECRYPT_RET_UNSUCCESS
;
3052 if (memcmp(anonce
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
) < 0) {
3053 gcry_md_write(sha256_handle
, anonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3054 gcry_md_write(sha256_handle
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3056 gcry_md_write(sha256_handle
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3057 gcry_md_write(sha256_handle
, anonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3059 memcpy(key_input
, gcry_md_read(sha256_handle
, 0), 32);
3060 gcry_md_close(sha256_handle
);
3063 bssid
= &data
[offset_link
+ 2];
3064 initiator
= &data
[offset_link
+ 8];
3065 responder
= &data
[offset_link
+ 14];
3066 if (gcry_md_open(&hmac_handle
, GCRY_MD_SHA256
, GCRY_MD_FLAG_HMAC
)) {
3067 return DOT11DECRYPT_RET_UNSUCCESS
;
3069 if (gcry_md_setkey(hmac_handle
, key_input
, 32)) {
3070 gcry_md_close(hmac_handle
);
3071 return DOT11DECRYPT_RET_UNSUCCESS
;
3073 gcry_md_putc(hmac_handle
, 1);
3074 gcry_md_putc(hmac_handle
, 0);
3075 gcry_md_write(hmac_handle
, "TDLS PMK", 8);
3076 if (memcmp(initiator
, responder
, DOT11DECRYPT_MAC_LEN
) < 0) {
3077 gcry_md_write(hmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3078 gcry_md_write(hmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3080 gcry_md_write(hmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3081 gcry_md_write(hmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3083 gcry_md_write(hmac_handle
, bssid
, DOT11DECRYPT_MAC_LEN
);
3084 gcry_md_putc(hmac_handle
, 0);
3085 gcry_md_putc(hmac_handle
, 1);
3086 memcpy(key_input
, gcry_md_read(hmac_handle
, 0), 32);
3087 gcry_md_close(hmac_handle
);
3090 if (gcry_mac_open(&cmac_handle
, GCRY_MAC_CMAC_AES
, 0, NULL
)) {
3091 return DOT11DECRYPT_RET_UNSUCCESS
;
3093 if (gcry_mac_setkey(cmac_handle
, key_input
, 16)) {
3094 gcry_mac_close(cmac_handle
);
3095 return DOT11DECRYPT_RET_UNSUCCESS
;
3097 gcry_mac_write(cmac_handle
, initiator
, DOT11DECRYPT_MAC_LEN
);
3098 gcry_mac_write(cmac_handle
, responder
, DOT11DECRYPT_MAC_LEN
);
3099 gcry_mac_write(cmac_handle
, &seq_num
, 1);
3100 gcry_mac_write(cmac_handle
, &data
[offset_link
], data
[offset_link
+ 1] + 2);
3101 gcry_mac_write(cmac_handle
, &data
[offset_rsne
], data
[offset_rsne
+ 1] + 2);
3102 gcry_mac_write(cmac_handle
, &data
[offset_timeout
], data
[offset_timeout
+ 1] + 2);
3103 gcry_mac_write(cmac_handle
, &data
[offset_fte
], 4);
3104 gcry_mac_write(cmac_handle
, zeros
, 16);
3105 cmac_write_len
= data
[offset_fte
+ 1] + 2;
3106 if (cmac_write_len
< 20) {
3107 ws_warning("Bad MAC len");
3108 gcry_mac_close(cmac_handle
);
3109 return DOT11DECRYPT_RET_UNSUCCESS
;
3111 gcry_mac_write(cmac_handle
, &data
[offset_fte
+ 20], cmac_write_len
- 20);
3112 if (gcry_mac_read(cmac_handle
, mic
, &cmac_len
) != GPG_ERR_NO_ERROR
) {
3113 ws_warning("MAC read error");
3114 gcry_mac_close(cmac_handle
);
3115 return DOT11DECRYPT_RET_UNSUCCESS
;
3117 if (memcmp(mic
, &data
[offset_fte
+ 4], 16)) {
3118 ws_debug("MIC verification failed");
3119 gcry_mac_close(cmac_handle
);
3120 return DOT11DECRYPT_RET_UNSUCCESS
;
3122 gcry_mac_close(cmac_handle
);
3123 /* TODO support other akm and ciphers? */
3126 sa
->wpa
.ptk_len
= Dot11DecryptGetPtkLen(sa
->wpa
.akm
, sa
->wpa
.cipher
) / 8;
3127 memcpy(DOT11DECRYPT_GET_TK(sa
->wpa
.ptk
, sa
->wpa
.akm
),
3128 key_input
+ 16, Dot11DecryptGetTkLen(sa
->wpa
.cipher
) / 8);
3129 memcpy(sa
->wpa
.nonce
, snonce
, DOT11DECRYPT_WPA_NONCE_LEN
);
3130 sa
->validKey
= true;
3131 sa
->wpa
.key_ver
= DOT11DECRYPT_WPA_KEY_VER_AES_CCMP
;
3132 ws_debug("MIC verified");
3133 return DOT11DECRYPT_RET_SUCCESS
;
3141 /****************************************************************************/
3149 * indent-tabs-mode: nil
3152 * ex: set shiftwidth=4 tabstop=8 expandtab:
3153 * :indentSize=4:tabSize=8:noTabs=true: