aboutsummaryrefslogtreecommitdiffstats
path: root/epan/crypt
diff options
context:
space:
mode:
authorMikael Kanstrup <mikael.kanstrup@sony.com>2020-01-12 23:28:37 +0100
committerAnders Broman <a.broman58@gmail.com>2020-03-14 06:53:13 +0000
commiteed31f13be8da5bb80d2fde68a67696e8b2da41e (patch)
tree05742d2e2be94d1103c6d96c2b781674cb63ceaa /epan/crypt
parent14bc684b18e775b9a18aef8c095bc2aaf1e8f877 (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.c42
-rw-r--r--epan/crypt/dot11decrypt_ccmp.c16
-rw-r--r--epan/crypt/dot11decrypt_ccmp_compat.c9
-rw-r--r--epan/crypt/dot11decrypt_system.h13
-rw-r--r--epan/crypt/dot11decrypt_user.h1
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) */