aboutsummaryrefslogtreecommitdiffstats
path: root/epan/crypt/airpdcap.c
diff options
context:
space:
mode:
authorDom Gifford <Dominic.Gifford@atmel.com>2014-08-11 14:53:04 +0100
committerEvan Huus <eapache@gmail.com>2014-08-11 16:50:36 +0000
commitf022e1549479e7468cf29deeba6032af4f535c3e (patch)
tree2976dc639df24c8a14d335dcb1ada1021910ce93 /epan/crypt/airpdcap.c
parentcb44442dfcaf94a1806b3559773e9fc4739f09f2 (diff)
Guard against buffer overflow when copying group key bytes into
security association structure. Change-Id: I2f573a0626bab44aaca1ac6716bf5ac3d6a9b7ed Reviewed-on: https://code.wireshark.org/review/3553 Petri-Dish: Evan Huus <eapache@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan/crypt/airpdcap.c')
-rw-r--r--epan/crypt/airpdcap.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/epan/crypt/airpdcap.c b/epan/crypt/airpdcap.c
index 1d920c6ff3..deef466ee8 100644
--- a/epan/crypt/airpdcap.c
+++ b/epan/crypt/airpdcap.c
@@ -350,7 +350,8 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
guint8 new_key[32];
guint8 key_version;
guint8 *szEncryptedKey;
- guint16 key_len = 0;
+ guint16 key_bytes_len = 0; /* Length of the total key data field */
+ guint16 key_len = 0; /* Actual group key length */
static AIRPDCAP_KEY_ITEM dummy_key; /* needed in case AirPDcapRsnaMng() wants the key structure */
/* 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. */
@@ -360,20 +361,20 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
key_version = AIRPDCAP_EAP_KEY_DESCR_VER(pEAPKey->key_information[1]);
if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
/* TKIP */
- key_len = pntoh16(pEAPKey->key_length);
+ key_bytes_len = pntoh16(pEAPKey->key_length);
}else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
/* AES */
- key_len = pntoh16(pEAPKey->key_data_len);
+ key_bytes_len = pntoh16(pEAPKey->key_data_len);
}
- if (key_len > TKIP_GROUP_KEYBYTES_LEN_MAX || key_len == 0) { /* Don't read past the end of pEAPKey->ie */
+ if (key_bytes_len > TKIP_GROUP_KEYBYTES_LEN_MAX || key_bytes_len == 0) { /* Don't read past the end of pEAPKey->ie */
return;
}
/* Encrypted key is in the information element field of the EAPOL key packet */
- szEncryptedKey = (guint8 *)g_memdup(pEAPKey->ie, key_len);
+ szEncryptedKey = (guint8 *)g_memdup(pEAPKey->ie, key_bytes_len);
- DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_len);
+ DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_bytes_len);
DEBUG_DUMP("KeyIV:", pEAPKey->key_iv, 16);
DEBUG_DUMP("decryption_key:", decryption_key, 16);
@@ -399,13 +400,13 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
/* The WPA group key just contains the GTK bytes so deducing the type is straightforward */
/* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
- sa->wpa.key_ver = (key_len >=TKIP_GROUP_KEY_LEN)?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
+ sa->wpa.key_ver = (key_bytes_len >=TKIP_GROUP_KEY_LEN)?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
crypt_rc4_init(&rc4_state, new_key, sizeof(new_key));
/* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
crypt_rc4(&rc4_state, dummy, 256);
- crypt_rc4(&rc4_state, szEncryptedKey, key_len);
+ crypt_rc4(&rc4_state, szEncryptedKey, key_bytes_len);
} else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
/* AES CCMP key */
@@ -417,14 +418,14 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
/* If this EAPOL frame is part of a separate group key handshake then this contains no */
/* RSN IE, so we can deduct that from the calculation. */
if (group_hshake)
- sa->wpa.key_ver = (key_len >= (TKIP_GROUP_KEYBYTES_LEN_GKEY))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
+ sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN_GKEY))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
else
- sa->wpa.key_ver = (key_len >= (TKIP_GROUP_KEYBYTES_LEN))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
+ sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
/* This storage is needed for the AES_unwrap function */
- decrypted_data = (guint8 *) g_malloc(key_len);
+ decrypted_data = (guint8 *) g_malloc(key_bytes_len);
- AES_unwrap(decryption_key, 16, szEncryptedKey, key_len, decrypted_data);
+ AES_unwrap(decryption_key, 16, szEncryptedKey, key_bytes_len, decrypted_data);
/* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
The key itself is stored as a GTK KDE
@@ -433,7 +434,7 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
key_found = FALSE;
key_index = 0;
- while(key_index < key_len && !key_found){
+ while(key_index < key_bytes_len && !key_found){
guint8 rsn_id;
/* Get RSN ID */
@@ -448,12 +449,14 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption
if (key_found){
/* Skip over the GTK header info, and don't copy past the end of the encrypted data */
- memcpy(szEncryptedKey, decrypted_data+key_index+8, key_len-key_index-8);
+ memcpy(szEncryptedKey, decrypted_data+key_index+8, key_bytes_len-key_index-8);
}
g_free(decrypted_data);
}
+ key_len = (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)?TKIP_GROUP_KEY_LEN:CCMP_GROUP_KEY_LEN;
+
/* Decrypted key is now in szEncryptedKey with len of key_len */
DEBUG_DUMP("Broadcast key:", szEncryptedKey, key_len);