diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2010-06-05 09:22:45 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2010-06-05 09:22:45 +0000 |
commit | f7ed15f39ee45c773762c479ed16589e3f279f35 (patch) | |
tree | 25d3c99f1700f64b8a2be2a69a880e45c92f06cd | |
parent | 7559d34b7b585d0a691ae8df266902493c8646a7 (diff) | |
download | wireshark-f7ed15f39ee45c773762c479ed16589e3f279f35.tar.gz |
From John Fitzgibbon:
When specifying SA keys for AES-CTR, Wireshark expects a key length of 160, 224
or 288 bits, (i.e. 128, 192 or 256 bits, followed by the 32 bit nonce value),
but gcry_cipher_setkey() in packet_ipsec.c fails, as it expects 128, 192 or 256
bits.
Omitting the nonce won't work -- even if Wireshark liked those key lengths,
gcrypt wouldn't be able to decrypt without it.
svn path=/trunk/; revision=33105
-rw-r--r-- | epan/dissectors/packet-ipsec.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/epan/dissectors/packet-ipsec.c b/epan/dissectors/packet-ipsec.c index 5fc37b98c0..59853d7ab7 100644 --- a/epan/dissectors/packet-ipsec.c +++ b/epan/dissectors/packet-ipsec.c @@ -1582,6 +1582,7 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) unsigned char *authenticator_data_computed = NULL; unsigned char *authenticator_data_computed_md; + unsigned char ctr_block[16]; /* * load the top pane info. This should be overwritten by @@ -2389,12 +2390,20 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) else { - err = gcry_cipher_setkey (cypher_hd, esp_crypt_key, esp_crypt_key_len); + if (crypt_mode_libgcrypt == GCRY_CIPHER_MODE_CTR) + { + /* Counter mode key includes a 4 byte, (32 bit), nonce following the key */ + err = gcry_cipher_setkey (cypher_hd, esp_crypt_key, esp_crypt_key_len - 4); + } + else + { + err = gcry_cipher_setkey (cypher_hd, esp_crypt_key, esp_crypt_key_len); + } if (err) { fprintf(stderr, - "<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_setkey failed: %s\n", - gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err)); + "<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_setkey(key_len=%d) failed: %s\n", + gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, esp_crypt_key_len, gpg_strerror (err)); gcry_cipher_close (cypher_hd); g_free(encrypted_data); g_free(decrypted_data); @@ -2402,9 +2411,25 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } else { - err = gcry_cipher_decrypt (cypher_hd, - decrypted_data, - decrypted_len_alloc + esp_iv_len, encrypted_data, decrypted_len_alloc); + if (crypt_mode_libgcrypt == GCRY_CIPHER_MODE_CTR) + { + memset(ctr_block, 0, 16); + memcpy(ctr_block, esp_crypt_key + esp_crypt_key_len - 4, 4); + memcpy(ctr_block + 4, encrypted_data, 8); + ctr_block[15] = 1; + err = gcry_cipher_setctr (cypher_hd, ctr_block, 16); + if (!err) + { + memcpy(decrypted_data, encrypted_data, esp_iv_len); + err = gcry_cipher_decrypt (cypher_hd, decrypted_data + esp_iv_len, decrypted_len_alloc, + encrypted_data + esp_iv_len, decrypted_len_alloc - esp_iv_len); + } + } + else + { + err = gcry_cipher_decrypt (cypher_hd, decrypted_data, decrypted_len_alloc + esp_iv_len, + encrypted_data, decrypted_len_alloc); + } if (err) { fprintf(stderr, |