diff options
author | Dom Gifford <Dominic.Gifford@atmel.com> | 2014-08-11 14:53:04 +0100 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-08-11 16:50:36 +0000 |
commit | f022e1549479e7468cf29deeba6032af4f535c3e (patch) | |
tree | 2976dc639df24c8a14d335dcb1ada1021910ce93 /epan/crypt/airpdcap.c | |
parent | cb44442dfcaf94a1806b3559773e9fc4739f09f2 (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.c | 31 |
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); |