summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2010-06-05 09:22:45 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2010-06-05 09:22:45 +0000
commitf7ed15f39ee45c773762c479ed16589e3f279f35 (patch)
tree25d3c99f1700f64b8a2be2a69a880e45c92f06cd
parent7559d34b7b585d0a691ae8df266902493c8646a7 (diff)
downloadwireshark-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.c37
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,