Ethereal-dev: [Ethereal-dev] IPsec ESP Authentication checking
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Frederic Roudaut <frederic.roudaut@xxxxxxxx>
Date: Fri, 07 Apr 2006 15:08:13 +0200
Hi all, I updated my previous patch of ESP : * It now check authentication for (similar to the ICMP checksum): - NULL Authentication - HMAC-SHA1-96 [RFC2404] - HMAC-SHA256 - HMAC-MD5-96 [RFC2403] (2)I put aside AES-XCBC-MAC-96 [RFC3566] because I did not succeed to have a working implementation. I added a field for any authenticator of 12bytes length (without authentication process)
* I also correct the printing of this authenticator field which was decrypted :-[ .
Thus, with this patch if libgcrypt is linked withe ethereal you should have the availability to :
- decrypt packets - check authentication at the same time or not.If noone of these options are set (or libgcrypt is not available) you also may use the previous heuristic.
I hope it will be helpful,ps: in attachment, you'll get the patch, the previous README I wrote and that I have updated, some capture examples.
Best Regards, ---- Fr�d�ric Roudaut
--- packet-ipsec.c 2006-04-07 15:03:29.486608123 +0200 +++ packet-ipsec.c_new 2006-04-07 15:02:37.223020918 +0200 @@ -26,12 +26,12 @@ /* -Addon: +Addon: ESP Decryption and Authentication Checking Frederic ROUDAUT (frederic.roudaut@xxxxxxx) Copyright 2006 Frederic ROUDAUT -- Decrypt ESP Payload with the following Algorithms defined in RFC 4305: +- Decrypt ESP Payload for the following Algorithms defined in RFC 4305: Encryption Algorithm -------------------- @@ -41,20 +41,26 @@ AES-CTR [RFC3686] : keylen 160/224/288 bits. The remaining 32 bits will be used as nonce. DES-CBC [RFC2405] : keylen 64 bits -Authentication Algorithm (in fact all Algorithms since it uses 12 bytes in the Auth field) +- Add ESP Payload Decryption support for the following Encryption Algorithms : +BLOWFISH-CBC : keylen 128 bits. +TWOFISH-CBC : keylen 128/256 bits. + +- Check ESP Authentication for the following Algorithms defined in RFC 4305: + +Authentication Algorithm ------------------------ -HMAC-SHA1-96 [RFC2404] -NULL -AES-XCBC-MAC-96 [RFC3566] -HMAC-MD5-96 [RFC2403] +NULL +HMAC-SHA1-96 [RFC2404] : any keylen +HMAC-MD5-96 [RFC2403] : any keylen +AES-XCBC-MAC-96 [RFC3566] : Not available because no implementation found. -- Add ESP Payload Decryption support for the following Encryption Algorithms : -[BLOWFISH-CBC] : keylen 128 bits. -[TWOFISH-CBC] : keylen 128/256 bits. +- Add ESP Authentication checking for the following Authentication Algorithm : +HMAC-SHA256 : any keylen */ -/* If you want to be able to decrypt ESP packets you MUST define this : */ +/* If you want to be able to decrypt or Check Authentication of ESP packets you MUST define this : */ + #ifdef HAVE_LIBCRYPT #define __USE_LIBGCRYPT__ #endif @@ -79,13 +85,13 @@ #include <gcrypt.h> #endif - static int proto_ah = -1; +static int proto_ah = -1; static int hf_ah_spi = -1; static int hf_ah_sequence = -1; static int proto_esp = -1; static int hf_esp_spi = -1; static int hf_esp_sequence = -1; -static int hf_esp_pad = -1; +static int hf_esp_pad_len = -1; static int hf_esp_protocol = -1; static int proto_ipcomp = -1; static int hf_ipcomp_flags = -1; @@ -112,8 +118,10 @@ /* Authentication algorithms defined in RFC 4305 */ #define IPSEC_AUTH_NULL 0 #define IPSEC_AUTH_HMAC_SHA1_96 1 -#define IPSEC_AUTH_AES_XCBC_MAC_96 2 +#define IPSEC_AUTH_HMAC_SHA256 2 #define IPSEC_AUTH_HMAC_MD5_96 3 +#define IPSEC_AUTH_ANY_12BYTES 5 +/* define IPSEC_AUTH_AES_XCBC_MAC_96 6 */ #endif /* well-known algorithm number (in CPI), from RFC2409 */ @@ -135,7 +143,7 @@ #define IPSEC_SA_ADDR_LEN_SEPARATOR '/' /* Number of Security Associations */ -#define IPSEC_NB_SA 5 +#define IPSEC_NB_SA 4 #endif static const value_string cpi2val[] = { @@ -188,11 +196,7 @@ gint encryption_algo; gint authentication_algo; const gchar *encryption_key; - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - const gchar *authentication_key; - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ + const gchar *authentication_key; gboolean is_valid; } g_esp_sa; @@ -206,7 +210,11 @@ /* Default ESP payload decode to off */ static gboolean g_esp_enable_encryption_decode = FALSE; + +/* Default ESP payload Authentication Checking to off */ +static gboolean g_esp_enable_authentication_check = FALSE; #endif + /* Default ESP payload heuristic decode to off (only works if payload is NULL encrypted and ESP payload decode is off or payload is NULL encrypted @@ -264,7 +272,7 @@ cpt_suffix ++; } cpt_seg = 0; - + if(ipv6_len - cpt - 1 == 0) { /* Found a suffix */ @@ -733,7 +741,7 @@ */ #ifdef __USE_LIBGCRYPT__ static gboolean -esp_sa_parse_addr_len(const gchar *sa, guint index_start, guint *len, guint *index_end) +esp_sa_parse_addr_len(const gchar *sa, guint index_start, gint *len, guint *index_end) { guint cpt = 0; guint strlen_max = 3; @@ -872,8 +880,8 @@ gchar *src_string; gchar *dst_string; gchar *spi_string; - guint src_len = 0; - guint dst_len = 0; + gint src_len = 0; + gint dst_len = 0; gchar *src; gchar *dst; gchar *sa; @@ -1149,14 +1157,8 @@ get_esp_sa(g_esp_sa_database *sad, gint protocol_typ, gchar *src, gchar *dst, gint spi, gint *entry_index, gint *encryption_algo, gint *authentication_algo, - gchar **encryption_key - - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - ,gchar **authentication_key - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - + gchar **encryption_key, + gchar **authentication_key ) { @@ -1188,14 +1190,8 @@ { *entry_index = i; *encryption_algo = sad -> table[i].encryption_algo; - *authentication_algo = sad -> table[i].authentication_algo; - - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - *authentication_key = (gchar *)sad -> table[i].authentication_key; - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - + *authentication_algo = sad -> table[i].authentication_algo; + *authentication_key = (gchar *)sad -> table[i].authentication_key; *encryption_key = (gchar *)sad -> table[i].encryption_key; found = TRUE; @@ -1318,6 +1314,62 @@ return advance; } + +/* + Name : dissect_esp_authentication(proto_tree *tree, tvbuff_t *tvb, gint len, gint esp_auth_len, guint8 *authenticator_data_computed, + gboolean authentication_ok, gboolean authentication_checking_ok) + Description : used to print Authenticator field when linked with libgcrypt. Print the expected authenticator value + if requested and if it is wrong. + Return : void + Params: + - proto_tree *tree : the current tree + - tvbuff_t *tvb : the tvbuffer + - gint len : length of the data availabale in tvbuff + - gint esp_auth_len : size of authenticator field + - guint8 *authenticator_data_computed : give the authenticator computed (only needed when authentication_ok and !authentication_checking_ok + - gboolean authentication_ok : set to true if the authentication checking has been run successfully + - gboolean authentication_checking_ok : set to true if the authentication was the one expected +*/ +#ifdef __USE_LIBGCRYPT__ +static void +dissect_esp_authentication(proto_tree *tree, tvbuff_t *tvb, gint len, gint esp_auth_len, guint8 *authenticator_data_computed, + gboolean authentication_ok, gboolean authentication_checking_ok) +{ + if(esp_auth_len == 0) + { + proto_tree_add_text(tree, tvb, len, 0, + "NULL Authentication"); + } + + /* Make sure we have the auth trailer data */ + else if(tvb_bytes_exist(tvb, len - esp_auth_len, esp_auth_len)) + { + if((authentication_ok) && (authentication_checking_ok)) + { + proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len, + "Authentication Data [correct]"); + } + + else if((authentication_ok) && (!authentication_checking_ok)) + { + proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len, + "Authentication Data [incorrect, should be 0x%s]", authenticator_data_computed); + + g_free(authenticator_data_computed); + } + + else proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len, + "Authentication Data"); + } + else + { + /* Truncated so just display what we have */ + proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len - (len - tvb_length(tvb)), + "Authentication Data (truncated)"); + } +} +#endif + static void dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -1338,13 +1390,15 @@ #endif guint encapsulated_protocol = 0; - gboolean auth_decode_ok = FALSE; + gboolean decrypt_dissect_ok = FALSE; #ifdef __USE_LIBGCRYPT__ gboolean get_address_ok = FALSE; gboolean null_encryption_decode_heuristic = FALSE; guint8 *decrypted_data = NULL; guint8 *encrypted_data = NULL; + guint8 *authenticator_data = NULL; + guint8 *esp_data = NULL; tvbuff_t *tvb_decrypted; gint entry_index; @@ -1353,28 +1407,33 @@ gint esp_crypt_algo = IPSEC_ENCRYPT_NULL; gint esp_auth_algo = IPSEC_AUTH_NULL; gchar *esp_crypt_key; + gchar *esp_auth_key; gint esp_iv_len = 0; gint esp_auth_len = 0; gint decrypted_len = 0; gboolean decrypt_ok = FALSE; gboolean decrypt_using_libgcrypt = FALSE; + gboolean authentication_check_using_hmac_libgcrypt = FALSE; + gboolean authentication_ok = FALSE; + gboolean authentication_checking_ok = FALSE; + gboolean sad_is_present = FALSE; #endif gint esp_pad_len = 0; #ifdef __USE_LIBGCRYPT__ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - gchar *esp_auth_key; - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - - /* Variables for decryption used for libgrypt */ + + /* Variables for decryption and authentication checking used for libgrypt */ int decrypted_len_alloc = 0; - gcry_cipher_hd_t hd; + gcry_cipher_hd_t cypher_hd; + gcry_md_hd_t md_hd; + int md_len = 0; gcry_error_t err = 0; int crypt_algo_libgcrypt = 0; int crypt_mode_libgcrypt = 0; - + int auth_algo_libgcrypt = 0; + unsigned char *authenticator_data_computed = NULL; + unsigned char *authenticator_data_computed_md; + /* * load the top pane info. This should be overwritten by @@ -1403,7 +1462,7 @@ if(tree) { len = 0, encapsulated_protocol = 0; - auth_decode_ok = FALSE; + decrypt_dissect_ok = FALSE; i = 0; ti = proto_tree_add_item(tree, proto_esp, tvb, 0, -1, FALSE); @@ -1420,7 +1479,7 @@ /* The SAD is not activated */ if(g_esp_enable_null_encryption_decode_heuristic && !g_esp_enable_encryption_decode) null_encryption_decode_heuristic = TRUE; - if(g_esp_enable_encryption_decode) + if(g_esp_enable_encryption_decode || g_esp_enable_authentication_check) { /* Get Dource & Destination Addresses in gchar * with all the bytes available. */ switch (pinfo -> src.type) @@ -1455,14 +1514,14 @@ else { g_snprintf(res,3,"%X ", (pinfo -> dst.data)[i]); - } + } memcpy(ip_dst + i*2, res, 2); } ip_dst[IPSEC_STRLEN_IPV4] = '\0'; - - get_address_ok = TRUE; + + get_address_ok = TRUE; break; - } + } case AT_IPv6 : { @@ -1526,16 +1585,8 @@ It would have been better to do it in the proto registration, but because there is no way to add a crossbar, you have to do a parsing and have a SA Rule. */ - if(get_esp_sa(&g_esp_sad, protocol_typ, ip_src, ip_dst, spi, &entry_index, &esp_crypt_algo, &esp_auth_algo, &esp_crypt_key - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - , &esp_auth_key - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - )) - { - /* Desactivation of the Heuristic to decrypt using the NULL encryption algorithm since the packet is matching a SA */ - null_encryption_decode_heuristic = FALSE; + if((sad_is_present = get_esp_sa(&g_esp_sad, protocol_typ, ip_src, ip_dst, spi, &entry_index, &esp_crypt_algo, &esp_auth_algo, &esp_crypt_key, &esp_auth_key))) + { /* Get length of whole ESP packet. */ len = tvb_reported_length(tvb); @@ -1548,464 +1599,651 @@ esp_auth_len = 12; break; } - + + case IPSEC_AUTH_HMAC_SHA256: + { + esp_auth_len = 12; + break; + } + case IPSEC_AUTH_NULL: { esp_auth_len = 0; break; } - - case IPSEC_AUTH_AES_XCBC_MAC_96: + + /* + case IPSEC_AUTH_AES_XCBC_MAC_96: + { + esp_auth_len = 12; + break; + } + */ + + case IPSEC_AUTH_HMAC_MD5_96: { esp_auth_len = 12; break; } - - case IPSEC_AUTH_HMAC_MD5_96: + + case IPSEC_AUTH_ANY_12BYTES: + default: { esp_auth_len = 12; break; } - + } - - switch(esp_crypt_algo) + + if(g_esp_enable_authentication_check) { + switch(esp_auth_algo) + { + + case IPSEC_AUTH_HMAC_SHA1_96: + /* + RFC 2404 : HMAC-SHA-1-96 is a secret key algorithm. While no fixed + key length is specified in [RFC-2104], for use with either ESP + or AH a fixed key length of 160-bits MUST be supported. Key + lengths other than 160-bits MUST NOT be supported (i.e. only 160-bit keys + are to be used by HMAC-SHA-1-96). A key length of 160-bits was chosen + based on the recommendations in [RFC-2104] (i.e. key lengths less + than the authenticator length decrease security strength and keys + longer than the authenticator length do not significantly increase security + strength). + */ + { + auth_algo_libgcrypt = GCRY_MD_SHA1; + authentication_check_using_hmac_libgcrypt = TRUE; + break; + } + + case IPSEC_AUTH_NULL: + { + authentication_check_using_hmac_libgcrypt = FALSE; + authentication_checking_ok = TRUE; + authentication_ok = TRUE; + break; + } + + /* + case IPSEC_AUTH_AES_XCBC_MAC_96: + { + auth_algo_libgcrypt = + authentication_check_using_libgcrypt = TRUE; + break; + } + */ + + case IPSEC_AUTH_HMAC_SHA256: + { + auth_algo_libgcrypt = GCRY_MD_SHA256; + authentication_check_using_hmac_libgcrypt = TRUE; + break; + } + + case IPSEC_AUTH_HMAC_MD5_96: + /* + RFC 2403 : HMAC-MD5-96 is a secret key algorithm. While no fixed key length is + specified in [RFC-2104], for use with either ESP or AH a fixed key + length of 128-bits MUST be supported. Key lengths other than 128- + bits MUST NOT be supported (i.e. only 128-bit keys are to be used by + HMAC-MD5-96). A key length of 128-bits was chosen based on the + recommendations in [RFC-2104] (i.e. key lengths less than the + authenticator length decrease security strength and keys longer than + the authenticator length do not significantly increase security + strength). + */ + { + auth_algo_libgcrypt = GCRY_MD_MD5; + authentication_check_using_hmac_libgcrypt = TRUE; + break; + } + + case IPSEC_AUTH_ANY_12BYTES: + default: + { + authentication_ok = FALSE; + authentication_check_using_hmac_libgcrypt = FALSE; + break; + } + + } + + if((authentication_check_using_hmac_libgcrypt) && (!authentication_ok)) + { + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + /* Allocate Buffers for Authenticator Field */ + authenticator_data = (guint8 *) g_malloc (( esp_auth_len + 1) * sizeof(guint8)); + memset(authenticator_data,0, esp_auth_len + 1); + tvb_memcpy(tvb, authenticator_data, len - esp_auth_len, esp_auth_len); + + esp_data = (guint8 *) g_malloc (( len - esp_auth_len + 1) * sizeof(guint8)); + memset(esp_data,0, len - esp_auth_len + 1); + tvb_memcpy(tvb, esp_data, 0, len - esp_auth_len); - case IPSEC_ENCRYPT_3DES_CBC : - { - /* RFC 2451 says : - 3DES CBC uses a key of 192 bits. - The first 3DES key is taken from the first 64 bits, the second - from the next 64 bits, and the third from the last 64 bits. - Implementations MUST take into consideration the parity bits when - initially accepting a new set of keys. Each of the three keys is - really 56 bits in length with the extra 8 bits used for parity. */ - - /* Fix parameters for 3DES-CBC */ - esp_iv_len = 8; - crypt_algo_libgcrypt = GCRY_CIPHER_3DES; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; + err = gcry_md_open (&md_hd, auth_algo_libgcrypt, GCRY_MD_FLAG_HMAC); + if (err) + { + fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_open failed: %s\n", gcry_md_algo_name(auth_algo_libgcrypt), gpg_strerror (err)); + authentication_ok = FALSE; + g_free(authenticator_data); + g_free(esp_data); + } + + else + { + md_len = gcry_md_get_algo_dlen (auth_algo_libgcrypt); + if (md_len < 1 || md_len < esp_auth_len) + { + fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, grcy_md_get_algo_dlen failed: %d\n", gcry_md_algo_name(auth_algo_libgcrypt), md_len); + authentication_ok = FALSE; + } + + else + { + gcry_md_setkey( md_hd, esp_auth_key, strlen(esp_auth_key) ); + + gcry_md_write (md_hd, esp_data, len - esp_auth_len); + + authenticator_data_computed_md = gcry_md_read (md_hd, auth_algo_libgcrypt); + if (authenticator_data_computed_md == 0) + { + fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_read failed\n", gcry_md_algo_name(auth_algo_libgcrypt)); + authentication_ok = FALSE; + } + else + { + if(memcmp (authenticator_data_computed_md, authenticator_data, esp_auth_len)) + { + authenticator_data_computed = (guint8 *) g_malloc (( esp_auth_len * 2 + 1) * sizeof(guint8)); + unsigned char authenticator_data_computed_car[3]; + for (i = 0; i < esp_auth_len; i++) + { + g_snprintf((char *)authenticator_data_computed_car, 3, "%02X", authenticator_data_computed_md[i] & 0xFF); + authenticator_data_computed[i*2] = authenticator_data_computed_car[0]; + authenticator_data_computed[i*2 + 1] = authenticator_data_computed_car[1]; + } + + authenticator_data_computed[esp_auth_len * 2] ='\0'; + + authentication_ok = TRUE; + authentication_checking_ok = FALSE; + } + else + { + + authentication_ok = TRUE; + authentication_checking_ok = TRUE; + } + } + } + + gcry_md_close (md_hd); + g_free(authenticator_data); + g_free(esp_data); + } + } + } + + if(g_esp_enable_encryption_decode) + { + /* Desactivation of the Heuristic to decrypt using the NULL encryption algorithm since the packet is matching a SA */ + null_encryption_decode_heuristic = FALSE; + + switch(esp_crypt_algo) + { + + case IPSEC_ENCRYPT_3DES_CBC : + { + /* RFC 2451 says : + 3DES CBC uses a key of 192 bits. + The first 3DES key is taken from the first 64 bits, the second + from the next 64 bits, and the third from the last 64 bits. + Implementations MUST take into consideration the parity bits when + initially accepting a new set of keys. Each of the three keys is + really 56 bits in length with the extra 8 bits used for parity. */ - decrypted_len = len - sizeof(struct newesp); + /* Fix parameters for 3DES-CBC */ + esp_iv_len = 8; + crypt_algo_libgcrypt = GCRY_CIPHER_3DES; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; + + decrypted_len = len - sizeof(struct newesp); - if (decrypted_len <= 0) decrypt_ok = FALSE; - else - { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; - - if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm 3DES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm 3DES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + else decrypt_using_libgcrypt = TRUE; } - else decrypt_using_libgcrypt = TRUE; - } - - break; - } - - case IPSEC_ENCRYPT_AES_CBC : - { - /* RFC 3602 says : - AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The - default key size is 128 bits, and all implementations MUST support - this key size. Implementations MAY also support key sizes of 192 - bits and 256 bits. */ - - /* Fix parameters for AES-CBC */ - esp_iv_len = 16; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + break; + } + + case IPSEC_ENCRYPT_AES_CBC : { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; - - switch(strlen(esp_crypt_key) * 8) + /* RFC 3602 says : + AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The + default key size is 128 bits, and all implementations MUST support + this key size. Implementations MAY also support key sizes of 192 + bits and 256 bits. */ + + /* Fix parameters for AES-CBC */ + esp_iv_len = 16; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; + + decrypted_len = len - sizeof(struct newesp); + + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - case 128: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES128; - decrypt_using_libgcrypt = TRUE; - break; - } - case 192: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES192; - decrypt_using_libgcrypt = TRUE; - break; - } - case 256: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES256; - decrypt_using_libgcrypt = TRUE; - break; - } - default: - { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm AES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; - } + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + switch(strlen(esp_crypt_key) * 8) + { + case 128: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES128; + decrypt_using_libgcrypt = TRUE; + break; + } + case 192: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES192; + decrypt_using_libgcrypt = TRUE; + break; + } + case 256: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES256; + decrypt_using_libgcrypt = TRUE; + break; + } + default: + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm AES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + } } - } - break; - } - - - case IPSEC_ENCRYPT_DES_CBC : - { - /* RFC 2405 says : - DES-CBC is a symmetric secret key algorithm. The key size is 64-bits. - [It is commonly known as a 56-bit key as the key has 56 significant - bits; the least significant bit in every byte is the parity bit.] */ - - /* Fix parameters for DES-CBC */ - esp_iv_len = 8; - crypt_algo_libgcrypt = GCRY_CIPHER_DES; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + break; + } + + + case IPSEC_ENCRYPT_DES_CBC : { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; - - if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + /* RFC 2405 says : + DES-CBC is a symmetric secret key algorithm. The key size is 64-bits. + [It is commonly known as a 56-bit key as the key has 56 significant + bits; the least significant bit in every byte is the parity bit.] */ + + /* Fix parameters for DES-CBC */ + esp_iv_len = 8; + crypt_algo_libgcrypt = GCRY_CIPHER_DES; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; + decrypted_len = len - sizeof(struct newesp); + + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm DES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm DES-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + else decrypt_using_libgcrypt = TRUE; } - else decrypt_using_libgcrypt = TRUE; - } - - break; - } - - - case IPSEC_ENCRYPT_AES_CTR : - { - /* RFC 3686 says : - AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The - default key size is 128 bits, and all implementations MUST support - this key size. Implementations MAY also support key sizes of 192 - bits and 256 bits. The remaining 32 bits will be used as nonce. */ - - /* Fix parameters for AES-CTR */ - esp_iv_len = 8; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CTR; - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + break; + } + + + case IPSEC_ENCRYPT_AES_CTR : { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; - - switch(strlen(esp_crypt_key) * 8) + /* RFC 3686 says : + AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The + default key size is 128 bits, and all implementations MUST support + this key size. Implementations MAY also support key sizes of 192 + bits and 256 bits. The remaining 32 bits will be used as nonce. */ + + /* Fix parameters for AES-CTR */ + esp_iv_len = 8; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CTR; + + decrypted_len = len - sizeof(struct newesp); + + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - case 160: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES128; - decrypt_using_libgcrypt = TRUE; - break; - } - case 224: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES192; - decrypt_using_libgcrypt = TRUE; - break; - } - case 288: - { - crypt_algo_libgcrypt = GCRY_CIPHER_AES256; - decrypt_using_libgcrypt = TRUE; - break; - } - default: - { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm AES-CTR : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; - } + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + switch(strlen(esp_crypt_key) * 8) + { + case 160: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES128; + decrypt_using_libgcrypt = TRUE; + break; + } + case 224: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES192; + decrypt_using_libgcrypt = TRUE; + break; + } + case 288: + { + crypt_algo_libgcrypt = GCRY_CIPHER_AES256; + decrypt_using_libgcrypt = TRUE; + break; + } + default: + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm AES-CTR : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + } } + + break; } - - break; - } - - case IPSEC_ENCRYPT_TWOFISH_CBC : - { - /* Twofish is a 128-bit block cipher developed by Counterpane Labs - that accepts a variable-length key up to 256 bits . - We will only accept key sizes of 128 and 256 bits. - */ - - /* Fix parameters for TWOFISH-CBC */ - esp_iv_len = 16; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; - - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + + case IPSEC_ENCRYPT_TWOFISH_CBC : { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + /* Twofish is a 128-bit block cipher developed by Counterpane Labs + that accepts a variable-length key up to 256 bits . + We will only accept key sizes of 128 and 256 bits. + */ + + /* Fix parameters for TWOFISH-CBC */ + esp_iv_len = 16; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; + + decrypted_len = len - sizeof(struct newesp); - switch(strlen(esp_crypt_key) * 8) + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - case 128: - { - crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH128; - decrypt_using_libgcrypt = TRUE; - break; - } - case 256: - { - crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH; - decrypt_using_libgcrypt = TRUE; - break; - } - default: - { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm TWOFISH-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; - } + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + switch(strlen(esp_crypt_key) * 8) + { + case 128: + { + crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH128; + decrypt_using_libgcrypt = TRUE; + break; + } + case 256: + { + crypt_algo_libgcrypt = GCRY_CIPHER_TWOFISH; + decrypt_using_libgcrypt = TRUE; + break; + } + default: + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm TWOFISH-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + } } - } - - break; - } - - - case IPSEC_ENCRYPT_BLOWFISH_CBC : - { - /* Bruce Schneier of Counterpane Systems developed the Blowfish block - cipher algorithm. - RFC 2451 shows that Blowfish uses key sizes from 40 to 448 bits. The Default size is 128 bits. - We will only accept key sizes of 128 bits, because libgrypt only accept this key size. - */ - - /* Fix parameters for BLOWFISH-CBC */ - esp_iv_len = 8; - crypt_algo_libgcrypt = GCRY_CIPHER_BLOWFISH; - crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + break; + } + + + case IPSEC_ENCRYPT_BLOWFISH_CBC : { - if(decrypted_len % esp_iv_len == 0) - decrypted_len_alloc = decrypted_len; - else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + /* Bruce Schneier of Counterpane Systems developed the Blowfish block + cipher algorithm. + RFC 2451 shows that Blowfish uses key sizes from 40 to 448 bits. The Default size is 128 bits. + We will only accept key sizes of 128 bits, because libgrypt only accept this key size. + */ + + /* Fix parameters for BLOWFISH-CBC */ + esp_iv_len = 8; + crypt_algo_libgcrypt = GCRY_CIPHER_BLOWFISH; + crypt_mode_libgcrypt = GCRY_CIPHER_MODE_CBC; - if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + decrypted_len = len - sizeof(struct newesp); + + if (decrypted_len <= 0) decrypt_ok = FALSE; + else { - fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm BLOWFISH-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); - decrypt_ok = FALSE; + if(decrypted_len % esp_iv_len == 0) + decrypted_len_alloc = decrypted_len; + else decrypted_len_alloc = (decrypted_len / esp_iv_len) * esp_iv_len + esp_iv_len; + + if (strlen(esp_crypt_key) != gcry_cipher_get_algo_keylen (crypt_algo_libgcrypt)) + { + fprintf (stderr,"<ESP Preferences> Error in Encryption Algorithm BLOWFISH-CBC : Bad Keylen (%i Bits)\n",strlen(esp_crypt_key) * 8); + decrypt_ok = FALSE; + } + else + decrypt_using_libgcrypt = TRUE; } - else - decrypt_using_libgcrypt = TRUE; + + break; + } - - break; - } - - - case IPSEC_ENCRYPT_NULL : - default : - { - /* Fix parameters */ - esp_iv_len = 0; - decrypted_len = len - sizeof(struct newesp); - - if (decrypted_len <= 0) decrypt_ok = FALSE; - else + + case IPSEC_ENCRYPT_NULL : + default : { - /* Allocate Buffers for Encrypted and Decrypted data */ - decrypted_data = (guint8 *) g_malloc ((decrypted_len + 1)* sizeof(guint8)); - tvb_memcpy(tvb, decrypted_data , sizeof(struct newesp), decrypted_len); + /* Fix parameters */ + esp_iv_len = 0; + decrypted_len = len - sizeof(struct newesp); - decrypt_ok = TRUE; + if (decrypted_len <= 0) decrypt_ok = FALSE; + else + { + /* Allocate Buffers for Encrypted and Decrypted data */ + decrypted_data = (guint8 *) g_malloc ((decrypted_len + 1)* sizeof(guint8)); + tvb_memcpy(tvb, decrypted_data , sizeof(struct newesp), decrypted_len); + + decrypt_ok = TRUE; + } + + break; } - - break; - } - } - - if(decrypt_using_libgcrypt) - { - /* Allocate Buffers for Encrypted and Decrypted data */ - encrypted_data = (guint8 *) g_malloc ((decrypted_len_alloc) * sizeof(guint8)); - memset(encrypted_data,0,decrypted_len_alloc); - decrypted_data = (guint8 *) g_malloc ((decrypted_len_alloc + esp_iv_len)* sizeof(guint8)); - tvb_memcpy(tvb, encrypted_data , sizeof(struct newesp), decrypted_len); - - err = gcry_cipher_open (&hd, crypt_algo_libgcrypt, crypt_mode_libgcrypt, 0); - if (err) - { - fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, grcy_open_cipher failed: %s\n", - gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err)); - g_free(encrypted_data); - g_free(decrypted_data); - decrypt_ok = FALSE; } - - else + + if(decrypt_using_libgcrypt) { - err = gcry_cipher_setkey (hd, esp_crypt_key, strlen(esp_crypt_key)); + /* Allocate Buffers for Encrypted and Decrypted data */ + encrypted_data = (guint8 *) g_malloc ((decrypted_len_alloc) * sizeof(guint8)); + memset(encrypted_data,0,decrypted_len_alloc); + decrypted_data = (guint8 *) g_malloc ((decrypted_len_alloc + esp_iv_len)* sizeof(guint8)); + tvb_memcpy(tvb, encrypted_data , sizeof(struct newesp), decrypted_len); + + err = gcry_cipher_open (&cypher_hd, crypt_algo_libgcrypt, crypt_mode_libgcrypt, 0); if (err) { - fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_setkey failed: %s\n", + fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, grcy_open_cipher failed: %s\n", gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err)); - gcry_cipher_close (hd); g_free(encrypted_data); g_free(decrypted_data); - decrypt_ok = FALSE; + decrypt_ok = FALSE; } + else - { - err = gcry_cipher_decrypt (hd, decrypted_data, decrypted_len_alloc + esp_iv_len, encrypted_data, decrypted_len_alloc); + { + err = gcry_cipher_setkey (cypher_hd, esp_crypt_key, strlen(esp_crypt_key)); if (err) { - fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, Mode %d, gcry_cipher_decrypt failed: %s\n", + 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)); - gcry_cipher_close (hd); + gcry_cipher_close (cypher_hd); g_free(encrypted_data); g_free(decrypted_data); - decrypt_ok = FALSE; + decrypt_ok = FALSE; } else - { - gcry_cipher_close (hd); - g_free(encrypted_data); - decrypt_ok = TRUE; + { + err = gcry_cipher_decrypt (cypher_hd, decrypted_data, decrypted_len_alloc + esp_iv_len, encrypted_data, decrypted_len_alloc); + if (err) + { + fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, Mode %d, gcry_cipher_decrypt failed: %s\n", + gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err)); + gcry_cipher_close (cypher_hd); + g_free(encrypted_data); + g_free(decrypted_data); + decrypt_ok = FALSE; + } + else + { + gcry_cipher_close (cypher_hd); + + /* Add the Authentication which was not encrypted */ + if(decrypted_len >= esp_auth_len) + { + for(i = 0; i < esp_auth_len; i++) + { + decrypted_data[i + decrypted_len -esp_auth_len] = encrypted_data[i + decrypted_len - esp_auth_len]; + } + } + + fprintf(stderr,"\n\n "); + g_free(encrypted_data); + decrypt_ok = TRUE; + } } } } - } - - if(decrypt_ok) - { - tvb_decrypted = tvb_new_real_data(decrypted_data, decrypted_len, decrypted_len); - tvb_set_child_real_data_tvbuff(tvb, tvb_decrypted); - add_new_data_source(pinfo, - tvb_decrypted, - "Decrypted Data"); - - /* Handler to free the Decrypted Data Buffer. */ - tvb_set_free_cb(tvb_decrypted,g_free); - - if(tvb_bytes_exist(tvb_decrypted, 0, esp_iv_len)) + if(decrypt_ok) { - if(esp_iv_len > 0) - proto_tree_add_text(esp_tree, tvb_decrypted, - 0, esp_iv_len, - "IV"); - } - - else proto_tree_add_text(esp_tree, tvb_decrypted, - 0, -1, - "IV (truncated)"); - - /* Make sure the packet is not truncated before the fields - * we need to read to determine the encapsulated protocol */ - if(tvb_bytes_exist(tvb_decrypted, decrypted_len - esp_auth_len - 2, 2)) - { - esp_pad_len = tvb_get_guint8(tvb_decrypted, decrypted_len - esp_auth_len - 2); + tvb_decrypted = tvb_new_real_data(decrypted_data, decrypted_len, decrypted_len); + tvb_set_child_real_data_tvbuff(tvb, tvb_decrypted); - if(decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2 >= esp_iv_len) - { - /* Get the encapsulated protocol */ - encapsulated_protocol = tvb_get_guint8(tvb_decrypted, decrypted_len - esp_auth_len - 1); - - if(dissector_try_port(ip_dissector_table, - encapsulated_protocol, - tvb_new_subset(tvb_decrypted, esp_iv_len, - decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2, - decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2), - pinfo, - esp_tree)) /*tree))*/ - { - auth_decode_ok = TRUE; - } - } + add_new_data_source(pinfo, + tvb_decrypted, + "Decrypted Data"); - } - - if(auth_decode_ok) - { - if(esp_pad_len !=0) + /* Handler to free the Decrypted Data Buffer. */ + tvb_set_free_cb(tvb_decrypted,g_free); + + if(tvb_bytes_exist(tvb_decrypted, 0, esp_iv_len)) { - proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len - 2 - esp_pad_len, esp_pad_len,"PAD"); + if(esp_iv_len > 0) + proto_tree_add_text(esp_tree, tvb_decrypted, + 0, esp_iv_len, + "IV"); } - proto_tree_add_uint(esp_tree, hf_esp_pad, tvb_decrypted, - decrypted_len - esp_auth_len - 2, 1, - esp_pad_len); - proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb_decrypted, - decrypted_len - esp_auth_len - 1, 1, - encapsulated_protocol); - if(esp_auth_len == 0) + else proto_tree_add_text(esp_tree, tvb_decrypted, + 0, -1, + "IV (truncated)"); + + /* Make sure the packet is not truncated before the fields + * we need to read to determine the encapsulated protocol */ + if(tvb_bytes_exist(tvb_decrypted, decrypted_len - esp_auth_len - 2, 2)) { - proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len, decrypted_len, - "NULL Authentication"); + esp_pad_len = tvb_get_guint8(tvb_decrypted, decrypted_len - esp_auth_len - 2); + + if(decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2 >= esp_iv_len) + { + /* Get the encapsulated protocol */ + encapsulated_protocol = tvb_get_guint8(tvb_decrypted, decrypted_len - esp_auth_len - 1); + + if(dissector_try_port(ip_dissector_table, + encapsulated_protocol, + tvb_new_subset(tvb_decrypted, esp_iv_len, + decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2, + decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2), + pinfo, + esp_tree)) /*tree))*/ + { + decrypt_dissect_ok = TRUE; + } + } + } - /* Make sure we have the auth trailer data */ - else if(tvb_bytes_exist(tvb, decrypted_len - esp_auth_len, esp_auth_len)) - { - proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len, esp_auth_len, - "Authentication Data"); + if(decrypt_dissect_ok) + { + if(esp_pad_len !=0) + { + proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len - 2 - esp_pad_len, esp_pad_len,"Pad"); + } + + proto_tree_add_uint(esp_tree, hf_esp_pad_len, tvb_decrypted, + decrypted_len - esp_auth_len - 2, 1, + esp_pad_len); + proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb_decrypted, + decrypted_len - esp_auth_len - 1, 1, + encapsulated_protocol); + + dissect_esp_authentication(esp_tree, tvb_decrypted, decrypted_len, esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok ); + } else { - /* Truncated so just display what we have */ - proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len, esp_auth_len - (decrypted_len - tvb_length(tvb_decrypted)), - "Authentication Data (truncated)"); + call_dissector(data_handle, + tvb_new_subset(tvb_decrypted, 0, decrypted_len - esp_auth_len, decrypted_len - esp_auth_len), + pinfo, esp_tree); + + dissect_esp_authentication(esp_tree, tvb_decrypted, decrypted_len, esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok ); + } } - else - { - call_dissector(data_handle, - tvb_new_subset(tvb_decrypted, 0, -1, -1), - pinfo, esp_tree); - } + } + else + { + /* The packet does not belong to a security Association */ + null_encryption_decode_heuristic = g_esp_enable_null_encryption_decode_heuristic; + } + + g_free(ip_src); + g_free(ip_dst); + } - - else - { - /* The packet does not belong to a security Association */ - null_encryption_decode_heuristic = g_esp_enable_null_encryption_decode_heuristic; - } - - g_free(ip_src); - g_free(ip_dst); - } } - - if(null_encryption_decode_heuristic) + /* + If the packet is present in the security association database and the field g_esp_enable_authentication_check set. + */ + if(!g_esp_enable_encryption_decode && g_esp_enable_authentication_check && sad_is_present) { -#endif + sad_is_present = FALSE; + call_dissector(data_handle, + tvb_new_subset(tvb, sizeof(struct newesp), len - sizeof(struct newesp) - esp_auth_len, -1), + pinfo, esp_tree); + dissect_esp_authentication(esp_tree, tvb, len , esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok ); + + } + + + /* The packet does not belong to a security association and the field g_esp_enable_null_encryption_decode_heuristic is set */ + else if(null_encryption_decode_heuristic) + { +#endif if(g_esp_enable_null_encryption_decode_heuristic) { /* Get length of whole ESP packet. */ @@ -2026,25 +2264,27 @@ pinfo, esp_tree)) { - auth_decode_ok = TRUE; + decrypt_dissect_ok = TRUE; } } } - if(auth_decode_ok) + if(decrypt_dissect_ok) { - proto_tree_add_uint(esp_tree, hf_esp_pad, tvb, + proto_tree_add_uint(esp_tree, hf_esp_pad_len, tvb, len - 14, 1, esp_pad_len); proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb, len - 13, 1, encapsulated_protocol); + /* Make sure we have the auth trailer data */ if(tvb_bytes_exist(tvb, len - 12, 12)) { proto_tree_add_text(esp_tree, tvb, len - 12, 12, "Authentication Data"); - } + } + else { /* Truncated so just display what we have */ @@ -2052,14 +2292,9 @@ "Authentication Data (truncated)"); } } - else - { - call_dissector(data_handle, - tvb_new_subset(tvb, sizeof(struct newesp), -1, -1), - pinfo, esp_tree); - } } #ifdef __USE_LIBGCRYPT__ + } #endif @@ -2142,8 +2377,8 @@ { &hf_esp_sequence, { "Sequence", "esp.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, - { &hf_esp_pad, - { "Pad Length", "esp.pad", FT_UINT8, BASE_DEC, NULL, 0x0, + { &hf_esp_pad_len, + { "Pad Length", "esp.pad_len", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_esp_protocol, { "Next Header", "esp.protocol", FT_UINT8, BASE_HEX, NULL, 0x0, @@ -2204,8 +2439,10 @@ {"null", "NULL", IPSEC_AUTH_NULL}, {"hmacsha196", "HMAC-SHA1-96 [RFC2404]", IPSEC_AUTH_HMAC_SHA1_96}, - {"aesxcbcmac96", "AES-XCBC-MAC-96 [RFC3566]", IPSEC_AUTH_AES_XCBC_MAC_96}, + {"hmacsha256", "HMAC-SHA256", IPSEC_AUTH_HMAC_SHA256}, {"hmacmd596", "HMAC-MD5-96 [RFC2403]", IPSEC_AUTH_HMAC_MD5_96}, + /* {"aesxcbcmac96", "AES-XCBC-MAC-96 [RFC3566]", IPSEC_AUTH_AES_XCBC_MAC_96}, */ + {"any12bytes", "ANY 12-bytes of Authentication [No Checking]", IPSEC_AUTH_ANY_12BYTES}, {NULL,NULL,0} }; #endif @@ -2227,11 +2464,7 @@ g_esp_sad.table[i].encryption_algo = IPSEC_ENCRYPT_NULL; g_esp_sad.table[i].authentication_algo = IPSEC_AUTH_NULL; g_esp_sad.table[i].encryption_key = NULL; - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - g_esp_sad.table[i].authentication_key = NULL; - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ + g_esp_sad.table[i].authentication_key = NULL; g_esp_sad.table[i].is_valid = FALSE; } #endif @@ -2248,6 +2481,11 @@ "Attempt to decode based on the SAD described hereafter.", &g_esp_enable_encryption_decode); + prefs_register_bool_preference(esp_module, "enable_authentication_check", + "Attempt to Check ESP Authentication", + "Attempt to Check ESP Authentication based on the SAD described hereafter.", + &g_esp_enable_authentication_check); + /* prefs_register_uint_preference(esp_module, "nb_sa", "Number of Security Associations", @@ -2271,7 +2509,7 @@ prefs_register_string_preference(esp_module, str_sa, str_sa_comment, - "This field uses the following syntax : \042<Protocol|Source Address|Destination Adress|SPI\042. " + "This field uses the following syntax : \042Protocol|Source Address|Destination Adress|SPI\042. " "<Protocol>: either IPv4, IPv6 (upper and/or lowercase letters). <SPI> : the Security Parameter Index " "of the Security Association. You may indicate it in decimal (ex: 123) or in hexadecimal (ex: 0x45). " "The special keywords '*' may be used to match any SPI.Nevertheless, if you use more than one '*', " @@ -2313,7 +2551,7 @@ prefs_register_enum_preference(esp_module, str_authentication_algorithm, str_authentication_algorithm_comment, - "According to RFC 4305 Authentication Algorithms Requirements are the following : HMAC-SHA1-96 [RFC2404] (MUST), NULL (MUST), AES-XCBC-MAC-96 [RFC3566] (SHOULD+), HMAC-MD5-96 [RFC2403] (MAY).", + "According to RFC 4305 Authentication Algorithms Requirements are the following : HMAC-SHA1-96 [RFC2404] (MUST), NULL (MUST), AES-XCBC-MAC-96 [RFC3566] (SHOULD+/Not Available), HMAC-MD5-96 [RFC2403] (MAY). It will also Check authentication for HMAC-SHA256", &g_esp_sad.table[i].authentication_algo, esp_authentication_algo, FALSE); @@ -2329,21 +2567,17 @@ &g_esp_sad.table[i].encryption_key); - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ - /* - char *str_authentication_key = (char *) g_malloc(19 + g_max_esp_size_nb_sa + 2); - g_snprintf(str_authentication_key,19 + g_max_esp_size_nb_sa + 2,"%s%s","authentication_key_",str_sa_num); - - char *str_authentication_key_comment = (char *)g_malloc(20 + g_max_esp_size_nb_sa + 2); - g_snprintf(str_authentication_key_comment,21 + g_max_esp_size_nb_sa + 2,"%s%s","Authentication Key #",str_sa_num); - - prefs_register_string_preference(esp_module, str_authentication_key, - str_authentication_key_comment, - "Authentication Key" - , - &g_esp_sad.table[i].authentication_key); - */ - /************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/ + char *str_authentication_key = (char *) g_malloc(19 + g_max_esp_size_nb_sa + 2); + g_snprintf(str_authentication_key,19 + g_max_esp_size_nb_sa + 2,"%s%s","authentication_key_",str_sa_num); + + char *str_authentication_key_comment = (char *)g_malloc(20 + g_max_esp_size_nb_sa + 2); + g_snprintf(str_authentication_key_comment,21 + g_max_esp_size_nb_sa + 2,"%s%s","Authentication Key #",str_sa_num); + + prefs_register_string_preference(esp_module, str_authentication_key, + str_authentication_key_comment, + "The key sizes supported are the following : [HMAC-SHA1-96] : Any. [HMAC-SHA256] : Any. [HMAC-MD5] : Any." + , + &g_esp_sad.table[i].authentication_key); }
README : IPSEC Dissector to decrypt ESP Payload and to check Authentication(v1.4) ================================================================================= Author: Frederic ROUDAUT (frederic.roudaut@xxxxxxx) Date : April 2006 1 - INTRODUCTION 2 - NEEDS AND INSTALLATION 3 - IPSEC ALGORITHMS AND KEYS 3.1 - ESP ALGORITHMS 3.1.1 - REQUIREMENTS 3.1.2 : TripleDES-CBC [RFC2451] 3.1.3 : AES-CBC with 128-bit keys [RFC3602] 3.1.4 : AES-CTR [RFC3686] 3.1.5 : DES-CBC [RFC2405] 3.1.6 : BLOWFISH-CBC [RFC2451] 3.1.7 : TWOFISH-CBC 3.1.8 : HMAC-MD5-96 [RFC2403] 3.1.9 : HMAC-SHA1-96 [RFC2404] 3.1.10 : AES-XCBC-MAC-96 [RFC3566] 3.1.11 : HMAC-SHA256 3.2 - AH ALGORITHMS 3.2.1 - REQUIREMENTS 4 - IPSEC MODES 5 - ESP PREFERENCES 5.1 - FIELD: Attempt to detect/decode NULL encrypted ESP payloads 5.2 - FIELD: Attempt to detect/decode encrypted ESP payloads 5.3 - FIELD: Attempt to check ESP Authentication 5.4 - SECURITY ASSOCIATIONS AND SA FILTERS 5.5 - ENCRYPTION, AUTHENTICATION ALGORITHMS & KEYS 6 - POSSIBLE EXTENSIONS 7 - CREDITS AND LICENCE 8 - BUGS 1 - INTRODUCTION ---------------- The goal of this README is to provide information for the evolutions that I have made to the existing IPsec dissector of Ethereal (www.ethereal.org). The goal is not to explain IPsec or Cyphers, but just to give a few elements on the content of this dissector. The current IPsec dissector was suffering from the two followings points: - It was not possible to decrypt ESP (Encapsulating Security Payload) Payload. We nevertheless remind that this is possible to do this using tcpdump. - There was no checking of ESP (Encapsulating Security Payload) and AH (Authentication Header) Authenticators. The Dissector given with this README tries to solve both points. This Dissector uses libgcrypt. 2 - NEEDS AND INSTALLATION -------------------------- Ethereal runs on many platforms, and can be compiled with a number of different compilers. This dissector has not been tested against a lot of implementations but I have tried to respect the README.developer of Ethereal. Nevertheless, here are what I have used to develop it : - OS : Linux (mandrake 10.1, mandriva 2006, Kernel: 2.6), Freebsd 5.3 - gcc version 3.4.1, 3.4.2 - libgcrypt 1.1 & 1.2.2 - Ethereal 0.10.11 to 0.10.14 and current source available in subversion in February, March, April 2006. In order to use this dissector, you only need to have Ethereal sources and libgcrypt installed. Copy packet-ipsec.c in ethereal/epan/dissector. If you want to be able to decrypt ESP packets or check ESP Authenticator you MUST define HAVE_LIBCRYPT If you use current version of ethereal available on subversion, Ethereal should already be linked against libgcrypt, then it will be very easy to install, just go into Ethereal root and do : make distclean && ./configure && make. If you use version 0.10.14 (or older) you have to do : make distclean && LDFLAGS=-lgcrypt ./configure && make. 3 - IPSEC ALGORITHMS AND KEYS ----------------------------- Currently IPsec is mainly described by the three followings RFCs: - RFC4301, Security Architecture for the Internet Protocol, S. Kent, K. Seo, December 2005, PROPOSED STANDARD. - RFC4302, IP Authentication Header, S. Kent, December 2005, PROPOSED STANDARD. - RFC4303, IP Encapsulating Security Payload (ESP), S. Kent, December 2005, PROPOSED STANDARD. The Algorithms to use and their requirements are described in RFC4305: Cryptographic Algorithm Implementation Requirements for Encapsulating Security Payload (ESP) and Authentication Header (AH), D. Eastlake 3rd, December 2005, PROPOSED STANDARD. You also may use some others Cryptographic Algorithm (have a look at the IANA for some other examples). 3.1 - ESP ALGORITHMS (RFC 4305) ------------------------------ The ESP Format is the following: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Security Parameters Index (SPI) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Data (variable) | ~ ~ | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Padding (0-255 bytes) | +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Pad Length | Next Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Authentication Data (variable) | ~ ~ | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3.1.1 - REQUIREMENTS -------------------- The followings tables (RFC 4305) list Encryption and Authentication algorithms for the IPsec Encapsulating Security Payload protocol. Requirement Encryption Algorithm (notes) ----------- -------------------- MUST NULL (1) MUST- TripleDES-CBC [RFC2451] SHOULD+ AES-CBC with 128-bit keys [RFC3602] SHOULD AES-CTR [RFC3686] SHOULD NOT DES-CBC [RFC2405] (3) Requirement Authentication Algorithm (notes) ----------- ------------------------ MUST HMAC-SHA1-96 [RFC2404] MUST NULL (1) SHOULD+ AES-XCBC-MAC-96 [RFC3566] MAY HMAC-MD5-96 [RFC2403] (2) Notes: (1) Since ESP Encryption and Authentication are optional, support for the two "NULL" algorithms is required to maintain consistency with the way these services are negotiated. Note that while Authentication and Encryption can each be "NULL", they MUST NOT both be "NULL". (2) Weaknesses have become apparent in MD5; however, these should not affect the use of MD5 with HMAC. (3) DES, with its small key size and publicly demonstrated and open- design special-purpose cracking hardware, is of questionable security for general use. This dissector takes into account all these Encryption Algorithms defined in RFC 4305. I also have adapted the dissector for : - BLOWFISH-CBC [RFC2451] with key size of only 128 bits. - TWOFISH-CBC with key of 128 or 256 bits only. These 2 Algorithms have been developed by Counterpane Labs. Have a look to http://www.schneier.com for more information. This dissector is also able to check authentication for all these previous Authentication algorithm (except AES-XCBC-MAC-96 since I had no working implementation). I also have adapted the dissector to check the following Authentication Mechanism : - HMAC-SHA256 with any key size 3.1.2 : TripleDES-CBC [RFC2451] ------------------------------- According to RFC 2451, 3DES CBC uses a key of 192 bits. The first 3DES key is taken from the first 64 bits, the second from the next 64 bits, and the third from the last 64 bits. Implementations MUST take into consideration the parity bits when initially accepting a new set of keys. Each of the three keys is really 56 bits in length with the extra 8 bits used for parity. 3DES CBC uses an IV of 8 octets. 3.1.3 : AES-CBC with 128-bit keys [RFC3602] ------------------------------------------- According to RFC 3602, AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The default key size is 128 bits, and all implementations MUST support this key size. Implementations MAY also support key sizes of 192 bits and 256 bits. AES-CBC uses an IV of 16 octets. 3.1.4 : AES-CTR [RFC3686] ------------------------- According to RFC 3686, AES supports three key sizes: 128 bits, 192 bits, and 256 bits. The default key size is 128 bits, and all implementations MUST support this key size. Implementations MAY also support key sizes of 192 bits and 256 bits. AES-CTR uses an IV of 8 octets. 3.1.5 : DES-CBC [RFC2405] ------------------------- According to RFC 2405, DES-CBC is a symmetric secret key algorithm. The key size is 64-bits. It is commonly known as a 56-bit key as the key has 56 significant bits; the least significant bit in every byte is the parity bit. DES-CBC uses an IV of 8 octets. 3.1.6 : BLOWFISH-CBC [RFC2451] ------------------------------ Bruce Schneier of Counterpane Systems developed the Blowfish cipher algorithm. RFC 2451 shows that Blowfish uses key sizes from 40 to 448 bits. The Default size is 128 bits. We will only accept key sizes of 128 bits, because libgrypt only accept this key size. Have a look to http://www.schneier.com for more information. BLOWFISH-CBC uses an IV of 8 octets. 3.1.7 : TWOFISH-CBC ------------------- Twofish is a 128-bit block cipher developed by Counterpane Labs that accepts a variable-length key up to 256 bits. We will only accept key sizes of 128 and 256 bits. Have a look to http://www.schneier.com for more information. TWOFISH-CBC uses an IV of 16 octets. 3.1.8 : HMAC-MD5-96 [RFC2403] ----------------------------- HMAC with MD5 provides data origin Authentication and integrity protection. While no fixed key length is specified in [RFC2104], for use with either ESP or AH a fixed key length of 128-bits MUST be supported. Key lengths other than 128-bits MUST NOT be supported (i.e. only 128-bit keys are to be used by HMAC-MD5-96). A key length of 128-bits was chosen based on the recommendations in [RFC-2104] (i.e. key lengths less than the authenticator length decrease security strength and keys longer than the authenticator length do not significantly increase security strength). Nevertheless, our implementation will support any key length. HMAC-MD5-96 produces a 128-bit authenticator value. For use with either ESP or AH, a truncated value using the first 96 bits MUST be supported. Upon sending, the truncated value is stored within the authenticator field. Upon receipt, the entire 128-bit value is computed and the first 96 bits are compared to the value stored in the authenticator field. No other authenticator value lengths are supported by HMAC-MD5-96. 3.1.9 : HMAC-SHA1-96 [RFC2404] ------------------------------ SHA-1 combined with HMAC [RFC2104] provides a keyed Authentication mechanism. While no fixed key length is specified in [RFC2104], for use with either ESP or AH a fixed key length of 160-bits MUST be supported. Key lengths other than 160-bits MUST NOT be supported (i.e. only 160-bit keys are to be used by HMAC-SHA-1-96). A key length of 160-bits was chosen based on the recommendations in [RFC2104] (i.e. key lengths less than the authenticator length decrease security strength and keys longer than the authenticator length do not significantly increase security strength). Nevertheless, our implementation will support any key length. HMAC-SHA-1-96 produces a 160-bit authenticator value. For use with either ESP or AH, a truncated value using the first 96 bits MUST be supported. Upon sending, the truncated value is stored within the authenticator field. Upon receipt, the entire 160-bit value is computed and the first 96 bits are compared to the value stored in the authenticator field. No other authenticator value lengths are supported by HMAC-SHA-1-96. 3.1.10 : AES-XCBC-MAC-96 [RFC3566] ---------------------------------- AES-XCBC-MAC-96 is a secret key algorithm. For use with either ESP or AH a fixed key length of 128-bits MUST be supported. Key lengths other than 128-bits MUST NOT be supported (i.e., only 128-bit keys are to be used by AES-XCBC-MAC-96). AES-XCBC-MAC produces a 128-bit authenticator value. For use with either ESP or AH, a truncated value using the first 96 bits MUST be supported. Upon sending, the truncated value is stored within the authenticator field. Upon receipt, the entire 128-bit value is computed and the first 96 bits are compared to the value stored in the authenticator field. No other authenticator value lengths are supported by AES-XCBC-MAC-96. This dissector is currently not able to check Authentication of AES-XCBC-MAC-96 because I found no working implementation. 3.1.11 : HMAC-SHA256 -------------------- This is the SHA-256 algorithm which yields a message digest of 32 bytes. For use with either ESP or AH, a truncated value using the first 96 bits MUST be supported. Upon sending, the truncated value is stored within the authenticator field. Upon receipt, the entire 128-bit value is computed and the first 96 bits are compared to the value stored in the authenticator field. Our implementation will support any key length. 3.2 - AH ALGORITHMS (RFC 4305) ------------------------------ The AH Header described in [RFC4302] is the following: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Header | Payload Len | RESERVED | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Security Parameters Index (SPI) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number Field | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Authentication Data (variable) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3.2.1 - REQUIREMENTS -------------------- The implementation conformance requirements for security algorithms for AH are given below (RFC4305). As you would suspect, all of these algorithms are authentication algorithms. Requirement Algorithm (notes) ----------- --------- MUST HMAC-SHA1-96 [RFC2404] SHOULD+ AES-XCBC-MAC-96 [RFC3566] MAY HMAC-MD5-96 [RFC2403] (1) Note: (1) Weaknesses have become apparent in MD5; however, these should not affect the use of MD5 with HMAC. 4 - IPSEC MODES --------------- IPsec may be used in two Modes : tunnel or transport and concerns two kinds of nodes : End Nodes and Secure Gateways. Each kind of node may use IPsec using these two Modes. This dissector aim is to decrypt the whole packet if you have enough information concerning the different Security Associations. Here is one of the more complex tology (if you have ESP in tunnel Mode in ESP in tunnel Mode ... it should work the same). DUMP | N1 SGW1 | N2 [192.168.0.3] -------[192.168.0.2][10.0.0.1]--------[10.0.0.2] default route for 192.168.0.3 is 192.168.0.2 default route for 10.0.0.2 is 10.0.0.1 We define the following policies with the setkey syntax : <SA1> ########## For 192.168.0.2 (SGW1) spdadd 192.168.0.3 10.0.0.2 any -P out ipsec esp/tunnel/10.0.0.1-10.0.0.2/use; add 10.0.0.1 10.0.0.2 esp 10 -m tunnel -E aes-cbc "aescbcencryption" -A hmac-sha1 "hmacsha1authenticati"; <SA2> ########## For 192.168.0.3 (N1) spdadd 192.168.0.3 10.0.0.2 any -P out ipsec esp/transport//require; add 192.168.0.3 10.0.0.2 esp 15 -E des-cbc "descbte" -A hmac-sha1 "hmacsha1authenticati"; It means that packets coming from N1 to N2 will be encrypted with des-cbc and tunneled from SGW1 with ESP encryption aes-cbc to N2. If we have a look at the DUMP host, we have only two SAs to decrypt the entire packet. If we have a look at the different Layers it will be : [IP1][ESP1][ENCRYPTION1] with [ENCRYPTION1]=[IP2][ESP2][ENCRYPTION2] and [ENCRYPTION2]=ICMP IP1 is IP header from SGW1 to N2 ENCRYPTION2 is aes-cbc IP2 is IP header from N1 to N2 ENCRYPTION2 is des-cbc Thus, the IPsec dissector knowing these two SAs, will decrypt first ENCRYPTION1 using SA1, will dissect it, will get ENCRYPTION2, will decrypt it using SA2 and will dissect it getting the full decrypted packet. If you have a look at the Authentication field, you will notice, that 2 fields are available. The inner one is available only if ENCRYPTION1 is decrypted. 5 - ESP PREFERENCES ------------------- In order to decrypt ESP Payload or to check ESP Authenticator, you need to give some elements of the known Security Associations (SA). I.e : - The Source Address of the SA. Either IPv6, either IPv4. - The Destination Address of the SA. Either IPv6, either IPv4. - The SPI (Security Parameter Index). - The Encryption algorithm and the associated key. - The Authentication algorithm; even if you do not want to check Authentication, it has some impact on the bytes alignment. We do not need to indicate the operation Mode (transport, tunnel), the decryption will be done iteratively. These differents elements have to be indicated in The ESP Preferences Menu of Ethereal. Indeed, it would perhaps have been better to set it in a separate file, but I wanted to have at least a few rules in the Preferences Box. Moreover the parsing is quite basic, without the use of any library/tool such as Lex/yacc for example. I did not wanted to add some other requierements to Ethereal. Because I had no way to add a crossbar and dynamic adding of SA in Ethereal, the number of Security Associations Max is fixed to 4 by default. If you need to modify this value, because the window is too large for example, you have to do it in the dissector by modifying the value of "IPSEC_NB_SA". 5.1 - FIELD: Attempt to detect/decode NULL encrypted ESP payloads ----------------------------------------------------------------- This field is an heuristic in order to decrypt packet. It assumes that packet are encrypted using the NULL algorithm and the Authentication uses 12 bytes as with hmac-sha1-96/aes-xcbc-mac-96/hmac-md5-96. This field Should be the only one available if Ethereal is not linked with libgcrypt. Otherwise, if set, all packets that are not catched by the Security Associations are decrypted using this heuristic. No authentication Checking will be done on these packets. 5.2 - FIELD: Attempt to detect/decode encrypted ESP payloads ------------------------------------------------------------ This field Should be available only if Ethereal is linked with libgcrypt. When an IPsec ESP packet will be catched by a Security Assciation (Source/Destination/SPI) it will be decrypted using the specified Encryption/Authentication Algorithm and the associated Encryption Key. This checking will be done iteratively as described in [Part 4]. 5.3 - FIELD: Attempt to check ESP Authentication ------------------------------------------------ This field Should be available only if Ethereal is linked with libgcrypt. When an IPsec ESP packet will be catched by a Security Assciation (Source/Destination/SPI) the Authentication will be checked using the specified Authentication Algorithm and the associated Authentication Key. This checking will be done iteratively as described in [Part 4]. 5.4 - SECURITY ASSOCIATIONS AND SA FILTERS ------------------------------------------ This field uses the following syntax (with spaces or not): Protocol|Source Address|Destination Adress|SPI Where : - Protocol: either IPv4, IPv6 (upper and/or lowercase letters) - SPI : the Security Parameter Index of the Security Association. You may indicate it in decimal (ex: 123) or in hexadecimal (ex: 0x45). The special keywords '*' may be used to match any SPI. Nevertheless, if you use more than one '*', it will restrict the length of the SPI in decimal to as many '*' as indicated. For example '**' will match 23 but not 234. 234 will be match by '***'. No checking will be done on the SPI value. Thus you have to take into account that the SPI is 4 bytes length. - Addresses : In this field we may have IPv6 or IPv4 address. Any address is a combination of an address or a prefix and a Prefixlen/Netmask separated by '/'. You may omit the Prefixlen/Netmask, assuming that the Adress is 128 bits length for IPv6 and 32 bits length for IPv4. The character '*' used at the Prefixlen/Netmask position will be as if you had omit it. * IPv6 Addresses : Any valid IPv6 address is accepted. ex: 3FFE::1/128, 3FFE:4:5:6666::/64, ::1/128, 3FFE:4::5 If your address is incorrect and longer than 16 bytes, only the last 16 bytes will be taken into account. You also may use the special character '*' to indicate any 4 bits block. ie : 3ffe::45*6. If you use only one '*' in the Address field it will accept any IPv6 address. * IPv4 Addresses : Any valid IPv4 address is accepted. ex : 190.0.0.1/24, 10.0.0.2. You also may use the special character '*' to indicate any 8 bits block. ie : 190.*.*.3. If you use only one '*' in the Address field it will accept any IPv4 address. No checking of correct IPv4 address will be done. For example 456.345.567.890 will be accepted. Thus you have to take care about what you write. Nevertheless only 3 characters will be taken into account for one byte. Ex : 190.0.0.0184 will not be considered correct. (Instead a kind of LRU Mechanism will be used and the address taken into account will be 190.0.0.418). Moreover only the four first values will be used (Ie 190.0.0.12.13 will be considered as 190.0.0.12). 5.5 - ENCRYPTION, AUTHENTICATION ALGORITHMS & KEYS --------------------------------------------------- In these fields you have to describe the Authentication, Encryption Algorithms and the Authentication, Encryption Keys for the SA. The key sizes should be conformant with what is specified in the Algorithms otherwise it will not work. We may notice that if we only care about decryption, choosing one of hmac-sha1-96/aes-xcbc-mac-96/hmac-md5-96 for Authentication will have no impact on the decryption since all this algorithm will give a 12-bytes authenticator field. Thus either we choose one of it without the "FIELD: Attempt to check ESP Authentication" set or we may use the Authentication algorithm "Any 12 Byte Of authentication [No checking]". In this case, the "FIELD: Attempt to check ESP Authentication" has no impact on the decision. 6 - POSSIBLE EXTENSIONS ----------------------- For sure, you may use some others ESP Encryption algorithms. I only have done the work for Algorithms specified in RFC4305, blowfish-cbc with keys of 128 bits and twofish-cbc with key sizes of 128/256 bits. Nevertheless, it should not be very difficult to add some other ones. Moreover, you may also add some other Authentication Algorithms. AES-XCBC-MAC-96 has not been added because i had trouble to get a working implementation. It also should be possible to adapt this to check AH Authentication and why not to do things for IPComp. If the maximum number of Security Associations fixed is a problem for you, you may modify this value in the dissector "IPSEC_NB_SA". It could also be interesting to keep a few SAs in the Preferences Box and have a way to add some more in a separate file. 7 - CREDITS AND LICENCE ----------------------- The Original Dissector was developed by Gerald Combs <gerald@xxxxxxxxxxxx> under the GNU General Public License. This dissector is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 8 - BUGS -------- This dissector has been tested using the script "fuzz-test.sh" available on the Ethereal web pages. If you find any bug you may send me the capture file with associated keys and algorithms at : frederic.roudaut@xxxxxxx
Attachment:
dumps.tgz
Description: application/compressed-tar
- Follow-Ups:
- SV: [Ethereal-dev] IPsec ESP Authentication checking
- From: Anders Broman
- SV: [Ethereal-dev] IPsec ESP Authentication checking
- Prev by Date: [Ethereal-dev] Re: increasing number of bytes printed from "proto_tree_add_bytes" function
- Next by Date: Re: [Ethereal-dev] Ethereal capture for long period
- Previous by thread: Re: [Ethereal-dev] Ethereal capture for long period
- Next by thread: SV: [Ethereal-dev] IPsec ESP Authentication checking
- Index(es):