dot11decrypt: Fix WEP decryption

For WPA security association (SA) entries are created on sucessful
PTK derivation from 4-way handshake frames. WEP though don't use
4-way handshake frames for key derivation and therefore no SA entry
is created. Still WEP decryption implementaton expects to find
an SA otherwise the decryption is skipped.

Fix broken WEP decryption by removing the check for an existing SA
entry and instead form the SA on first successful decryption.

Add also a test for WEP decryption.

Fixes: v3.3.0rc0-1263-g099d241046 ("dot11decrypt: Avoid allocating SA on packet decryption")
This commit is contained in:
Mikael Kanstrup 2020-10-20 21:34:22 +02:00 committed by AndersBroman
parent e814fe0c9b
commit ad69ec2e11
4 changed files with 36 additions and 11 deletions

View File

@ -161,7 +161,7 @@ static INT Dot11DecryptWepMng(
guint mac_header_len,
guint *decrypt_len,
PDOT11DECRYPT_KEY_ITEM key,
DOT11DECRYPT_SEC_ASSOCIATION *sa)
DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
;
static INT Dot11DecryptRsna4WHandshake(
@ -1082,12 +1082,7 @@ INT Dot11DecryptDecryptPacket(
/* IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP */
if (DOT11DECRYPT_EXTIV(data[mac_header_len + 3]) == 0) {
DEBUG_PRINT_LINE("WEP encryption", DEBUG_LEVEL_3);
/* get the Security Association structure for the STA and AP */
sa = Dot11DecryptGetSa(ctx, &id);
if (sa == NULL) {
return DOT11DECRYPT_RET_REQ_DATA;
}
return Dot11DecryptWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa);
return Dot11DecryptWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, &id);
} else {
DEBUG_PRINT_LINE("TKIP or CCMP encryption", DEBUG_LEVEL_3);
@ -1435,7 +1430,7 @@ Dot11DecryptWepMng(
guint mac_header_len,
guint *decrypt_len,
PDOT11DECRYPT_KEY_ITEM key,
DOT11DECRYPT_SEC_ASSOCIATION *sa)
DOT11DECRYPT_SEC_ASSOCIATION_ID *id)
{
UCHAR wep_key[DOT11DECRYPT_WEP_KEY_MAXLEN+DOT11DECRYPT_WEP_IVLEN];
size_t keylen;
@ -1444,12 +1439,21 @@ Dot11DecryptWepMng(
DOT11DECRYPT_KEY_ITEM *tmp_key;
UINT8 useCache=FALSE;
UCHAR *try_data;
DOT11DECRYPT_SEC_ASSOCIATION *sa;
guint try_data_len = *decrypt_len;
try_data = (UCHAR *)g_malloc(try_data_len);
if (sa->key!=NULL)
useCache=TRUE;
/* get the Security Association structure for the STA and AP */
/* For WEP the sa is used only for caching. When no sa exists all user
* entered WEP keys are checked and on successful packet decryption an
* sa is formed caching the key used for decryption.
*/
sa = Dot11DecryptGetSa(ctx, id);
if (sa != NULL && sa->key != NULL) {
useCache = TRUE;
}
for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
/* use the cached one, or try all keys */
@ -1487,8 +1491,18 @@ Dot11DecryptWepMng(
}
if (!ret_value && tmp_key->KeyType==DOT11DECRYPT_KEY_TYPE_WEP) {
/* the tried key is the correct one, cached in the Security Association */
/* the tried key is the correct one, cache it in the Security Association */
/* Form an SA if one does not exist already */
if (sa == NULL) {
sa = Dot11DecryptNewSa(id);
if (sa == NULL) {
DEBUG_PRINT_LINE("Failed to alloc sa for WEP", DEBUG_LEVEL_3);
ret_value = DOT11DECRYPT_RET_UNSUCCESS;
break;
}
sa = Dot11DecryptAddSa(ctx, id, sa);
}
sa->key=tmp_key;
if (key!=NULL) {

BIN
test/captures/wep.pcapng.gz Normal file

Binary file not shown.

View File

@ -1,4 +1,5 @@
# Keys needed for the decryption test suite
"wep","1234567890"
"wpa-pwd","Induction"
"wpa-pwd","test0815"
"wpa-pwd","12345678"

View File

@ -23,6 +23,16 @@ import fixtures
@fixtures.mark_usefixtures('test_env')
@fixtures.uses_fixtures
class case_decrypt_80211(subprocesstest.SubprocessTestCase):
def test_80211_wep(self, cmd_tshark, capture_file):
'''IEEE 802.11 WEP'''
# Included in git sources test/captures/wep.pcapng.gz
self.assertRun((cmd_tshark,
'-o', 'wlan.enable_decryption: TRUE',
'-r', capture_file('wep.pcapng.gz'),
))
self.assertTrue(self.grepOutput('Who has 192.168.5.1'))
self.assertTrue(self.grepOutput('Echo \(ping\) request'))
def test_80211_wpa_psk(self, cmd_tshark, capture_file):
'''IEEE 802.11 WPA PSK'''
# https://gitlab.com/wireshark/wireshark/-/wikis/SampleCaptures?action=AttachFile&do=view&target=wpa-Induction.pcap