diff options
author | Mikael Kanstrup <mikael.kanstrup@sony.com> | 2020-01-12 23:28:37 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2020-03-14 06:53:13 +0000 |
commit | eed31f13be8da5bb80d2fde68a67696e8b2da41e (patch) | |
tree | 05742d2e2be94d1103c6d96c2b781674cb63ceaa /epan/crypt | |
parent | 14bc684b18e775b9a18aef8c095bc2aaf1e8f877 (diff) |
ieee80211: Add CCMP-256 decryption support
Add support for decrypting CCMP-256 encrypted IEEE 802.11 traffic
Bug: 16197
Change-Id: I0c9ee09e5b71cb02e6d2381049fd5bbb02686f7f
Reviewed-on: https://code.wireshark.org/review/36344
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/crypt')
-rw-r--r-- | epan/crypt/dot11decrypt.c | 42 | ||||
-rw-r--r-- | epan/crypt/dot11decrypt_ccmp.c | 16 | ||||
-rw-r--r-- | epan/crypt/dot11decrypt_ccmp_compat.c | 9 | ||||
-rw-r--r-- | epan/crypt/dot11decrypt_system.h | 13 | ||||
-rw-r--r-- | epan/crypt/dot11decrypt_user.h | 1 |
5 files changed, 50 insertions, 31 deletions
diff --git a/epan/crypt/dot11decrypt.c b/epan/crypt/dot11decrypt.c index 60d69327ad..9db5db5744 100644 --- a/epan/crypt/dot11decrypt.c +++ b/epan/crypt/dot11decrypt.c @@ -329,9 +329,9 @@ Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa, PDOT11DECRYPT_KEY_ITEM key key->KeyData.Wpa.Cipher = sa->wpa.cipher; if (sa->wpa.key_ver==DOT11DECRYPT_WPA_KEY_VER_NOT_CCMP) key->KeyType=DOT11DECRYPT_KEY_TYPE_TKIP; - else if (sa->wpa.key_ver==DOT11DECRYPT_WPA_KEY_VER_AES_CCMP) - key->KeyType=DOT11DECRYPT_KEY_TYPE_CCMP; - else if (sa->wpa.key_ver==0) { + else if (sa->wpa.key_ver == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP || + sa->wpa.key_ver == 0) + { switch (sa->wpa.cipher) { case 1: key->KeyType = DOT11DECRYPT_KEY_TYPE_WEP_40; @@ -345,6 +345,9 @@ Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa, PDOT11DECRYPT_KEY_ITEM key case 5: key->KeyType = DOT11DECRYPT_KEY_TYPE_WEP_104; break; + case 10: + key->KeyType = DOT11DECRYPT_KEY_TYPE_CCMP_256; + break; default: key->KeyType = DOT11DECRYPT_KEY_TYPE_UNKNOWN; break; @@ -354,7 +357,6 @@ Dot11DecryptCopyKey(PDOT11DECRYPT_SEC_ASSOCIATION sa, PDOT11DECRYPT_KEY_ITEM key case 7: Group addressed traffic not allowed case 8: GCMP-128 case 9: GCMP-256 - case 10: CCMP-256 case 11: BIP-GMAC-128 case 12: BIP-GMAC-256 case 13: BIP-CMAC-256 */ @@ -568,13 +570,19 @@ Dot11DecryptGetTK(const PDOT11DECRYPT_KEY_ITEM key, const guint8 **tk) int Dot11DecryptGetGTK(const PDOT11DECRYPT_KEY_ITEM key, const guint8 **gtk) { + int len; if (!key || !gtk) { return 0; } /* GTK is stored in PTK at offset 32. See comment in Dot11DecryptCopyBroadcastKey */ *gtk = key->KeyData.Wpa.Ptk + 32; - return 16; + if (key->KeyType == DOT11DECRYPT_KEY_TYPE_TKIP) { + len = 16; + } else { + len = Dot11DecryptGetTkLen(key->KeyData.Wpa.Cipher) / 8; + } + return len; } INT Dot11DecryptScanTdlsForKeys( @@ -1178,7 +1186,7 @@ Dot11DecryptRsnaMng( g_free(try_data); return DOT11DECRYPT_RET_UNSUCCESS; } - if (*decrypt_len < DOT11DECRYPT_RSNA_MICLEN+DOT11DECRYPT_WEP_ICV) { + if (*decrypt_len < DOT11DECRYPT_TKIP_MICLEN + DOT11DECRYPT_WEP_ICV) { DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3); g_free(try_data); return DOT11DECRYPT_RET_UNSUCCESS; @@ -1194,26 +1202,29 @@ Dot11DecryptRsnaMng( DEBUG_PRINT_LINE("TKIP DECRYPTED!!!", DEBUG_LEVEL_3); /* remove MIC and ICV from the end of packet */ - *decrypt_len-=DOT11DECRYPT_RSNA_MICLEN+DOT11DECRYPT_WEP_ICV; + *decrypt_len -= DOT11DECRYPT_TKIP_MICLEN + DOT11DECRYPT_WEP_ICV; break; } else { /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */ DEBUG_PRINT_LINE("CCMP", DEBUG_LEVEL_3); - if (*decrypt_len < DOT11DECRYPT_RSNA_MICLEN) { + guint trailer = sa->wpa.cipher != 10 ? DOT11DECRYPT_CCMP_TRAILER : DOT11DECRYPT_CCMP_256_TRAILER; + if (*decrypt_len < trailer) { DEBUG_PRINT_LINE("Invalid decryption length", DEBUG_LEVEL_3); g_free(try_data); return DOT11DECRYPT_RET_UNSUCCESS; } ret = Dot11DecryptCcmpDecrypt(try_data, mac_header_len, (INT)*decrypt_len, - DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm)); + DOT11DECRYPT_GET_TK(sa->wpa.ptk, sa->wpa.akm), + Dot11DecryptGetTkLen(sa->wpa.cipher) / 8, + trailer); if (ret) { continue; } DEBUG_PRINT_LINE("CCMP DECRYPTED!!!", DEBUG_LEVEL_3); /* remove MIC from the end of packet */ - *decrypt_len-=DOT11DECRYPT_RSNA_MICLEN; + *decrypt_len -= trailer; break; } } @@ -1488,9 +1499,9 @@ Dot11DecryptRsna4WHandshake( group_cipher = 2; } else if (eapol_parsed->key_version == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP) { /* CCMP-128 */ - akm = 2; - cipher = 4; - group_cipher = 4; + akm = eapol_parsed->akm; + cipher = eapol_parsed->cipher; + group_cipher = eapol_parsed->group_cipher; } /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */ @@ -2128,11 +2139,6 @@ Dot11DecryptDerivePtk( ptk_len_bits = 512; DerivePtk = Dot11DecryptRsnaPrfX; algo = GCRY_MD_SHA1; - } else if (key_version == DOT11DECRYPT_WPA_KEY_VER_AES_CCMP) { - /* CCMP-128 */ - ptk_len_bits = 384; - DerivePtk = Dot11DecryptRsnaPrfX; - algo = GCRY_MD_SHA1; } else { /* From IEEE 802.11-2016 Table 12-8 Integrity and key-wrap algorithms */ ptk_len_bits = Dot11DecryptGetPtkLen(akm, cipher); diff --git a/epan/crypt/dot11decrypt_ccmp.c b/epan/crypt/dot11decrypt_ccmp.c index d283a647a2..f5bc664901 100644 --- a/epan/crypt/dot11decrypt_ccmp.c +++ b/epan/crypt/dot11decrypt_ccmp.c @@ -133,12 +133,14 @@ int Dot11DecryptCcmpDecrypt( guint8 *m, int mac_header_len, int len, - guint8 *TK1) + guint8 *TK1, + int tk_len, + int mic_len) { PDOT11DECRYPT_MAC_FRAME wh; guint8 aad[30]; /* Max aad_len. See Table 12-1 IEEE 802.11 2016 */ guint8 nonce[13]; - guint8 mic[8]; + guint8 mic[16]; /* Big enough for CCMP-256 */ ssize_t data_len; size_t aad_len; int z = mac_header_len; @@ -147,12 +149,12 @@ int Dot11DecryptCcmpDecrypt( guint8 *ivp = m + z; wh = (PDOT11DECRYPT_MAC_FRAME )m; - data_len = len - (z + DOT11DECRYPT_CCMP_HEADER + DOT11DECRYPT_CCMP_TRAILER); + data_len = len - (z + DOT11DECRYPT_CCMP_HEADER + mic_len); if (data_len < 1) { return 0; } - memcpy(mic, m + len - DOT11DECRYPT_CCMP_TRAILER, DOT11DECRYPT_CCMP_TRAILER); + memcpy(mic, m + len - mic_len, mic_len); pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]); ccmp_construct_nonce(wh, pn, nonce); ccmp_construct_aad(wh, aad, &aad_len); @@ -160,7 +162,7 @@ int Dot11DecryptCcmpDecrypt( if (gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0)) { return 1; } - if (gcry_cipher_setkey(handle, TK1, 16)) { + if (gcry_cipher_setkey(handle, TK1, tk_len)) { goto err_out; } if (gcry_cipher_setiv(handle, nonce, sizeof(nonce))) { @@ -170,7 +172,7 @@ int Dot11DecryptCcmpDecrypt( guint64 ccm_lengths[3]; ccm_lengths[0] = data_len; ccm_lengths[1] = aad_len; - ccm_lengths[2] = DOT11DECRYPT_CCMP_TRAILER; + ccm_lengths[2] = mic_len; if (gcry_cipher_ctl(handle, GCRYCTL_SET_CCM_LENGTHS, ccm_lengths, sizeof(ccm_lengths))) { goto err_out; } @@ -180,7 +182,7 @@ int Dot11DecryptCcmpDecrypt( if (gcry_cipher_decrypt(handle, m + z + DOT11DECRYPT_CCMP_HEADER, data_len, NULL, 0)) { goto err_out; } - if (gcry_cipher_checktag(handle, mic, DOT11DECRYPT_CCMP_TRAILER)) { + if (gcry_cipher_checktag(handle, mic, mic_len)) { goto err_out; } diff --git a/epan/crypt/dot11decrypt_ccmp_compat.c b/epan/crypt/dot11decrypt_ccmp_compat.c index 1912caf40c..29f75b741e 100644 --- a/epan/crypt/dot11decrypt_ccmp_compat.c +++ b/epan/crypt/dot11decrypt_ccmp_compat.c @@ -185,7 +185,9 @@ int Dot11DecryptCcmpDecrypt( guint8 *m, int mac_header_len, int len, - guint8 *TK1) + guint8 *TK1, + int tk_len, + int mic_len) { PDOT11DECRYPT_MAC_FRAME wh; UINT8 aad[2 * AES_BLOCK_LEN]; @@ -200,6 +202,11 @@ int Dot11DecryptCcmpDecrypt( UINT64 PN; UINT8 *ivp=m+z; + if (tk_len > 16 || mic_len > 8) { + /* NOT SUPPORTED*/ + return 1; + } + PN = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]); if (gcry_cipher_open(&rijndael_handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)) { diff --git a/epan/crypt/dot11decrypt_system.h b/epan/crypt/dot11decrypt_system.h index 36531d3fe8..2e6af3e6da 100644 --- a/epan/crypt/dot11decrypt_system.h +++ b/epan/crypt/dot11decrypt_system.h @@ -67,15 +67,16 @@ */ #define DOT11DECRYPT_RSNA_EXTIV 0x20 #define DOT11DECRYPT_RSNA_EXTIVLEN 4 /* extended IV length */ -#define DOT11DECRYPT_RSNA_MICLEN 8 /* trailing MIC */ +#define DOT11DECRYPT_TKIP_MICLEN 8 /* trailing MIC */ #define DOT11DECRYPT_RSNA_HEADER DOT11DECRYPT_WEP_HEADER + DOT11DECRYPT_RSNA_EXTIVLEN -#define DOT11DECRYPT_CCMP_HEADER DOT11DECRYPT_RSNA_HEADER -#define DOT11DECRYPT_CCMP_TRAILER DOT11DECRYPT_RSNA_MICLEN +#define DOT11DECRYPT_CCMP_HEADER DOT11DECRYPT_RSNA_HEADER +#define DOT11DECRYPT_CCMP_TRAILER 8 /* IEEE 802.11-2016 12.5.3.2 CCMP MPDU format */ +#define DOT11DECRYPT_CCMP_256_TRAILER 16 /* IEEE 802.11-2016 12.5.3.2 CCMP MPDU format */ #define DOT11DECRYPT_TKIP_HEADER DOT11DECRYPT_RSNA_HEADER -#define DOT11DECRYPT_TKIP_TRAILER DOT11DECRYPT_RSNA_MICLEN + DOT11DECRYPT_WEP_ICV +#define DOT11DECRYPT_TKIP_TRAILER DOT11DECRYPT_TKIP_MICLEN + DOT11DECRYPT_WEP_ICV #define DOT11DECRYPT_CRC_LEN 4 @@ -440,7 +441,9 @@ int Dot11DecryptCcmpDecrypt( guint8 *m, int mac_header_len, int len, - guint8 *TK1); + guint8 *TK1, + int tk_len, + int mic_len); extern INT Dot11DecryptTkipDecrypt( UCHAR *tkip_mpdu, diff --git a/epan/crypt/dot11decrypt_user.h b/epan/crypt/dot11decrypt_user.h index 6d06926bda..c8fa1f36f7 100644 --- a/epan/crypt/dot11decrypt_user.h +++ b/epan/crypt/dot11decrypt_user.h @@ -31,6 +31,7 @@ #define DOT11DECRYPT_KEY_TYPE_WPA_PMK 5 #define DOT11DECRYPT_KEY_TYPE_TKIP 6 #define DOT11DECRYPT_KEY_TYPE_CCMP 7 +#define DOT11DECRYPT_KEY_TYPE_CCMP_256 8 #define DOT11DECRYPT_KEY_TYPE_UNKNOWN -1 /* Decryption algorithms fields size definition (bytes) */ |