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