IPSEC: Pass the algorithm salt (used in GCM) over the API 50/18950/2
authorNeale Ranns <nranns@cisco.com>
Tue, 16 Apr 2019 02:41:34 +0000 (02:41 +0000)
committerDamjan Marion <dmarion@me.com>
Wed, 17 Apr 2019 13:05:07 +0000 (13:05 +0000)
Change-Id: Ia8cea13f7b937294e6a080a55fb2ceff30063acf
Signed-off-by: Neale Ranns <nranns@cisco.com>
12 files changed:
src/vnet/ipsec/esp_decrypt.c
src/vnet/ipsec/ipsec.api
src/vnet/ipsec/ipsec_api.c
src/vnet/ipsec/ipsec_cli.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_sa.h
test/template_ipsec.py
test/test_ipsec_esp.py
test/test_ipsec_tun_if_esp.py
test/vpp_ipsec.py
test/vpp_ipsec_tun_interface.py
test/vpp_papi_provider.py

index d2365fc..e74c1bb 100644 (file)
@@ -239,7 +239,6 @@ esp_decrypt_inline (vlib_main_t * vm,
              esp_header_t *esp0;
              esp_aead_t *aad;
              u8 *scratch;
-             u32 salt;
 
              /*
               * construct the AAD and the nonce (Salt || IV) in a scratch
@@ -258,9 +257,8 @@ esp_decrypt_inline (vlib_main_t * vm,
               * can overwrite it with the salt and use the IV where it is
               * to form the nonce = (Salt + IV)
               */
-             salt = clib_host_to_net_u32 (sa0->salt);
              op->iv -= sizeof (sa0->salt);
-             clib_memcpy_fast (op->iv, &salt, sizeof (sa0->salt));
+             clib_memcpy_fast (op->iv, &sa0->salt, sizeof (sa0->salt));
              op->iv_len = cpd.iv_sz + sizeof (sa0->salt);
 
              op->tag = payload + len;
index bc407f1..3a2c993 100644 (file)
@@ -262,6 +262,7 @@ typedef key
     @param tunnel_src_address - IPsec tunnel source address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero
     @param tunnel_dst_address - IPsec tunnel destination address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero
     @param tx_table_id - the FIB id used for encapsulated packets
+    @param salt - for use with counter mode ciphers
  */
 typedef ipsec_sad_entry
 {
@@ -282,6 +283,7 @@ typedef ipsec_sad_entry
   vl_api_address_t tunnel_src;
   vl_api_address_t tunnel_dst;
   u32 tx_table_id;
+  u32 salt;
 };
 
 /** \brief IPsec: Add/delete Security Association Database entry
@@ -374,6 +376,7 @@ define ipsec_spd_interface_details {
     @param show_instance - instance to display for intf if renumber is set
     @param udp_encap - enable UDP encapsulation for NAT traversal
     @param tx_table_id - the FIB id used after packet encap
+    @param salt - for use with counter mode ciphers
 */
 define ipsec_tunnel_if_add_del {
   u32 client_index;
@@ -399,6 +402,7 @@ define ipsec_tunnel_if_add_del {
   u32 show_instance;
   u8 udp_encap;
   u32 tx_table_id;
+  u32 salt;
 };
 
 /** \brief Add/delete IPsec tunnel interface response
index 767cd2f..4a15beb 100644 (file)
@@ -385,12 +385,11 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
   ip_address_decode (&mp->entry.tunnel_src, &tun_src);
   ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
 
-
   if (mp->is_add)
     rv = ipsec_sa_add (id, spi, proto,
                       crypto_alg, &crypto_key,
                       integ_alg, &integ_key, flags,
-                      0, 0, &tun_src, &tun_dst, &sa_index);
+                      0, mp->entry.salt, &tun_src, &tun_dst, &sa_index);
   else
     rv = ipsec_sa_del (id);
 
@@ -644,6 +643,7 @@ vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t *
   tun.remote_integ_key_len = mp->remote_integ_key_len;
   tun.udp_encap = mp->udp_encap;
   tun.tx_table_id = ntohl (mp->tx_table_id);
+  tun.salt = mp->salt;
   itype = ip_address_decode (&mp->local_ip, &tun.local_ip);
   itype = ip_address_decode (&mp->remote_ip, &tun.remote_ip);
   tun.is_ip6 = (IP46_TYPE_IP6 == itype);
index 0960608..b6bdc40 100644 (file)
@@ -84,8 +84,8 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
   clib_error_t *error;
   ipsec_key_t ck = { 0 };
   ipsec_key_t ik = { 0 };
+  u32 id, spi, salt;
   int is_add, rv;
-  u32 id, spi;
 
   error = NULL;
   is_add = 0;
@@ -103,6 +103,8 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
        is_add = 0;
       else if (unformat (line_input, "spi %u", &spi))
        ;
+      else if (unformat (line_input, "salt %u", &salt))
+       ;
       else if (unformat (line_input, "esp"))
        proto = IPSEC_PROTOCOL_ESP;
       else if (unformat (line_input, "ah"))
@@ -141,7 +143,8 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
   if (is_add)
     rv = ipsec_sa_add (id, spi, proto, crypto_alg,
                       &ck, integ_alg, &ik, flags,
-                      0, 0, &tun_src, &tun_dst, NULL);
+                      0, clib_host_to_net_u32 (salt),
+                      &tun_src, &tun_dst, NULL);
   else
     rv = ipsec_sa_del (id);
 
index 93b1efd..44f064d 100644 (file)
@@ -290,7 +290,7 @@ format_ipsec_sa (u8 * s, va_list * args)
   if (!(flags & IPSEC_FORMAT_DETAIL))
     goto done;
 
-  s = format (s, "\n   salt 0x%x", sa->salt);
+  s = format (s, "\n   salt 0x%x", clib_net_to_host_u32 (sa->salt));
   s = format (s, "\n   seq %u seq-hi %u", sa->seq, sa->seq_hi);
   s = format (s, "\n   last-seq %u last-seq-hi %u window %U",
              sa->last_seq, sa->last_seq_hi,
@@ -303,6 +303,7 @@ format_ipsec_sa (u8 * s, va_list * args)
              format_ipsec_integ_alg, sa->integ_alg);
   if (sa->integ_alg)
     s = format (s, " key %U", format_ipsec_key, &sa->integ_key);
+
   vlib_get_combined_counter (&ipsec_sa_counters, sai, &counts);
   s = format (s, "\n   packets %u bytes %u", counts.packets, counts.bytes);
 
index f87e12e..d1b44c3 100644 (file)
@@ -160,9 +160,9 @@ typedef struct
   u32 sibling;
 
   u32 tx_fib_index;
-  u32 salt;
 
-  /* runtime */
+  /* Salt used in GCM modes - stored in network byte order */
+  u32 salt;
 } ipsec_sa_t;
 
 STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline1, CLIB_CACHE_LINE_BYTES);
index 6e42ac7..d6641c4 100644 (file)
@@ -1,5 +1,6 @@
 import unittest
 import socket
+import struct
 
 from scapy.layers.inet import IP, ICMP, TCP, UDP
 from scapy.layers.ipsec import SecurityAssociation
@@ -42,7 +43,7 @@ class IPsecIPv4Params(object):
                                   IPSEC_API_CRYPTO_ALG_AES_CBC_128)
         self.crypt_algo = 'AES-CBC'  # scapy name
         self.crypt_key = 'JPjyOWBeVEQiMe7h'
-        self.crypt_salt = ''
+        self.salt = 0
         self.flags = 0
         self.nat_header = None
 
@@ -78,7 +79,7 @@ class IPsecIPv6Params(object):
                                   IPSEC_API_CRYPTO_ALG_AES_CBC_128)
         self.crypt_algo = 'AES-CBC'  # scapy name
         self.crypt_key = 'JPjyOWBeVEQiMe7h'
-        self.crypt_salt = ''
+        self.salt = 0
         self.flags = 0
         self.nat_header = None
 
@@ -87,9 +88,14 @@ def config_tun_params(p, encryption_type, tun_if):
     ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
     use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
                               IPSEC_API_SAD_FLAG_USE_ESN))
+    if p.crypt_algo == "AES-GCM":
+        crypt_key = p.crypt_key + struct.pack("!I", p.salt)
+    else:
+        crypt_key = p.crypt_key
     p.scapy_tun_sa = SecurityAssociation(
         encryption_type, spi=p.vpp_tun_spi,
-        crypt_algo=p.crypt_algo, crypt_key=p.crypt_key + p.crypt_salt,
+        crypt_algo=p.crypt_algo,
+        crypt_key=crypt_key,
         auth_algo=p.auth_algo, auth_key=p.auth_key,
         tunnel_header=ip_class_by_addr_type[p.addr_type](
             src=tun_if.remote_addr[p.addr_type],
@@ -98,7 +104,8 @@ def config_tun_params(p, encryption_type, tun_if):
         use_esn=use_esn)
     p.vpp_tun_sa = SecurityAssociation(
         encryption_type, spi=p.scapy_tun_spi,
-        crypt_algo=p.crypt_algo, crypt_key=p.crypt_key + p.crypt_salt,
+        crypt_algo=p.crypt_algo,
+        crypt_key=crypt_key,
         auth_algo=p.auth_algo, auth_key=p.auth_key,
         tunnel_header=ip_class_by_addr_type[p.addr_type](
             dst=tun_if.remote_addr[p.addr_type],
@@ -110,11 +117,15 @@ def config_tun_params(p, encryption_type, tun_if):
 def config_tra_params(p, encryption_type):
     use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
                               IPSEC_API_SAD_FLAG_USE_ESN))
+    if p.crypt_algo == "AES-GCM":
+        crypt_key = p.crypt_key + struct.pack("!I", p.salt)
+    else:
+        crypt_key = p.crypt_key
     p.scapy_tra_sa = SecurityAssociation(
         encryption_type,
         spi=p.vpp_tra_spi,
         crypt_algo=p.crypt_algo,
-        crypt_key=p.crypt_key + p.crypt_salt,
+        crypt_key=crypt_key,
         auth_algo=p.auth_algo,
         auth_key=p.auth_key,
         nat_t_header=p.nat_header,
@@ -123,7 +134,7 @@ def config_tra_params(p, encryption_type):
         encryption_type,
         spi=p.scapy_tra_spi,
         crypt_algo=p.crypt_algo,
-        crypt_key=p.crypt_key + p.crypt_salt,
+        crypt_key=crypt_key,
         auth_algo=p.auth_algo,
         auth_key=p.auth_key,
         nat_t_header=p.nat_header,
index 566ed34..eb21c58 100644 (file)
@@ -1,6 +1,5 @@
 import socket
 import unittest
-import struct
 from scapy.layers.ipsec import ESP
 from scapy.layers.inet import UDP
 
@@ -102,6 +101,7 @@ class ConfigIpsecESP(TemplateIpsec):
         addr_bcast = params.addr_bcast
         e = VppEnum.vl_api_ipsec_spd_action_t
         flags = params.flags
+        salt = params.salt
         objs = []
 
         params.tun_sa_in = VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
@@ -110,14 +110,16 @@ class ConfigIpsecESP(TemplateIpsec):
                                       self.vpp_esp_protocol,
                                       self.tun_if.local_addr[addr_type],
                                       self.tun_if.remote_addr[addr_type],
-                                      flags=flags)
+                                      flags=flags,
+                                      salt=salt)
         params.tun_sa_out = VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
                                        auth_algo_vpp_id, auth_key,
                                        crypt_algo_vpp_id, crypt_key,
                                        self.vpp_esp_protocol,
                                        self.tun_if.remote_addr[addr_type],
                                        self.tun_if.local_addr[addr_type],
-                                       flags=flags)
+                                       flags=flags,
+                                       salt=salt)
         objs.append(params.tun_sa_in)
         objs.append(params.tun_sa_out)
 
@@ -185,18 +187,21 @@ class ConfigIpsecESP(TemplateIpsec):
                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
         e = VppEnum.vl_api_ipsec_spd_action_t
         flags = params.flags | flags
+        salt = params.salt
         objs = []
 
         params.tra_sa_in = VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
                                       auth_algo_vpp_id, auth_key,
                                       crypt_algo_vpp_id, crypt_key,
                                       self.vpp_esp_protocol,
-                                      flags=flags)
+                                      flags=flags,
+                                      salt=salt)
         params.tra_sa_out = VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
                                        auth_algo_vpp_id, auth_key,
                                        crypt_algo_vpp_id, crypt_key,
                                        self.vpp_esp_protocol,
-                                       flags=flags)
+                                       flags=flags,
+                                       salt=salt)
         objs.append(params.tra_sa_in)
         objs.append(params.tra_sa_out)
 
@@ -371,7 +376,15 @@ class TestIpsecEspAll(ConfigIpsecESP,
                   'scapy-crypto': "AES-GCM",
                   'scapy-integ': "NULL",
                   'key': "JPjyOWBeVEQiMe7h",
-                  'salt': struct.pack("!L", 0)},
+                  'salt': 0},
+                 {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
+                                 IPSEC_API_CRYPTO_ALG_AES_GCM_192),
+                  'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
+                                IPSEC_API_INTEG_ALG_NONE),
+                  'scapy-crypto': "AES-GCM",
+                  'scapy-integ': "NULL",
+                  'key': "JPjyOWBeVEQiMe7h01234567",
+                  'salt': 1010},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_GCM_256),
                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
@@ -379,14 +392,14 @@ class TestIpsecEspAll(ConfigIpsecESP,
                   'scapy-crypto': "AES-GCM",
                   'scapy-integ': "NULL",
                   'key': "JPjyOWBeVEQiMe7h0123456787654321",
-                  'salt': struct.pack("!L", 0)},
+                  'salt': 2020},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_128),
                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7h"},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_192),
@@ -394,7 +407,7 @@ class TestIpsecEspAll(ConfigIpsecESP,
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBe"},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_256),
@@ -402,7 +415,7 @@ class TestIpsecEspAll(ConfigIpsecESP,
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"}]
 
         # with and without ESN
@@ -437,7 +450,7 @@ class TestIpsecEspAll(ConfigIpsecESP,
                         p.crypt_algo = algo['scapy-crypto']
                         p.auth_algo = algo['scapy-integ']
                         p.crypt_key = algo['key']
-                        p.crypt_salt = algo['salt']
+                        p.salt = algo['salt']
                         p.flags = p.flags | flag
 
                     #
index 833bbd4..018e00b 100644 (file)
@@ -1,7 +1,6 @@
 import unittest
 import socket
 import copy
-import struct
 
 from scapy.layers.ipsec import ESP
 from scapy.layers.l2 import Ether, Raw, GRE
@@ -218,7 +217,8 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                                         p.crypt_algo_vpp_id,
                                         p.crypt_key, p.crypt_key,
                                         p.auth_algo_vpp_id, p.auth_key,
-                                        p.auth_key)
+                                        p.auth_key,
+                                        salt=p.salt)
         p.tun_if.add_vpp_config()
         p.tun_if.admin_up()
         p.tun_if.config_ip4()
@@ -257,7 +257,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                   'scapy-crypto': "AES-GCM",
                   'scapy-integ': "NULL",
                   'key': "JPjyOWBeVEQiMe7h",
-                  'salt': struct.pack("!L", 0)},
+                  'salt': 3333},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_GCM_192),
                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
@@ -265,7 +265,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                   'scapy-crypto': "AES-GCM",
                   'scapy-integ': "NULL",
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBe",
-                  'salt': struct.pack("!L", 0)},
+                  'salt': 0},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_GCM_256),
                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
@@ -273,14 +273,14 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                   'scapy-crypto': "AES-GCM",
                   'scapy-integ': "NULL",
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h",
-                  'salt': struct.pack("!L", 0)},
+                  'salt': 9999},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_128),
                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7h"},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_192),
@@ -288,7 +288,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBe"},
                  {'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_256),
@@ -296,7 +296,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                                 IPSEC_API_INTEG_ALG_SHA1_96),
                   'scapy-crypto': "AES-CBC",
                   'scapy-integ': "HMAC-SHA1-96",
-                  'salt': '',
+                  'salt': 0,
                   'key': "JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"}]
 
         for engine in engines:
@@ -314,7 +314,7 @@ class TestIpsec4TunIfEspAll(TemplateIpsec, IpsecTun4):
                 p.crypt_algo = algo['scapy-crypto']
                 p.auth_algo = algo['scapy-integ']
                 p.crypt_key = algo['key']
-                p.crypt_salt = algo['salt']
+                p.salt = algo['salt']
 
                 self.config_network(p)
 
index 278ff36..77a9d74 100644 (file)
@@ -178,7 +178,7 @@ class VppIpsecSA(VppObject):
                  crypto_alg, crypto_key,
                  proto,
                  tun_src=None, tun_dst=None,
-                 flags=None):
+                 flags=None, salt=0):
         e = VppEnum.vl_api_ipsec_sad_flags_t
         self.test = test
         self.id = id
@@ -188,6 +188,7 @@ class VppIpsecSA(VppObject):
         self.crypto_alg = crypto_alg
         self.crypto_key = crypto_key
         self.proto = proto
+        self.salt = salt
 
         self.tun_src = tun_src
         self.tun_dst = tun_dst
@@ -214,7 +215,8 @@ class VppIpsecSA(VppObject):
             self.proto,
             (self.tun_src if self.tun_src else []),
             (self.tun_dst if self.tun_dst else []),
-            flags=self.flags)
+            flags=self.flags,
+            salt=self.salt)
         self.stat_index = r.stat_index
         self.test.registry.register(self, self.test.logger)
 
index 1a41244..bc689b3 100644 (file)
@@ -8,7 +8,8 @@ class VppIpsecTunInterface(VppTunnelInterface):
 
     def __init__(self, test, parent_if, local_spi,
                  remote_spi, crypto_alg, local_crypto_key, remote_crypto_key,
-                 integ_alg, local_integ_key, remote_integ_key, is_ip6=False):
+                 integ_alg, local_integ_key, remote_integ_key, salt=0,
+                 is_ip6=False):
         super(VppIpsecTunInterface, self).__init__(test, parent_if)
         self.local_spi = local_spi
         self.remote_spi = remote_spi
@@ -18,6 +19,7 @@ class VppIpsecTunInterface(VppTunnelInterface):
         self.integ_alg = integ_alg
         self.local_integ_key = local_integ_key
         self.remote_integ_key = remote_integ_key
+        self.salt = salt
         if is_ip6:
             self.local_ip = self.parent_if.local_ip6
             self.remote_ip = self.parent_if.remote_ip6
@@ -30,7 +32,8 @@ class VppIpsecTunInterface(VppTunnelInterface):
             self.local_ip, self.remote_ip,
             self.remote_spi, self.local_spi,
             self.crypto_alg, self.local_crypto_key, self.remote_crypto_key,
-            self.integ_alg, self.local_integ_key, self.remote_integ_key)
+            self.integ_alg, self.local_integ_key, self.remote_integ_key,
+            salt=self.salt)
         self.set_sw_if_index(r.sw_if_index)
         self.generate_remote_hosts()
         self.test.registry.register(self, self.test.logger)
index 260e6b2..62175e2 100644 (file)
@@ -2357,6 +2357,7 @@ class VppPapiProvider(object):
                                 tunnel_src_address='',
                                 tunnel_dst_address='',
                                 flags=0,
+                                salt=0,
                                 is_add=1):
         """ IPSEC SA add/del
         :param sad_id: security association ID
@@ -2395,6 +2396,7 @@ class VppPapiProvider(object):
                             'data': crypto_key,
                         },
                         'flags': flags,
+                        'salt': salt,
                     }
             })
 
@@ -2472,7 +2474,7 @@ class VppPapiProvider(object):
     def ipsec_tunnel_if_add_del(self, local_ip, remote_ip, local_spi,
                                 remote_spi, crypto_alg, local_crypto_key,
                                 remote_crypto_key, integ_alg, local_integ_key,
-                                remote_integ_key, is_add=1, esn=0,
+                                remote_integ_key, is_add=1, esn=0, salt=0,
                                 anti_replay=1, renumber=0, show_instance=0):
         return self.api(
             self.papi.ipsec_tunnel_if_add_del,
@@ -2495,7 +2497,8 @@ class VppPapiProvider(object):
                 'esn': esn,
                 'anti_replay': anti_replay,
                 'renumber': renumber,
-                'show_instance': show_instance
+                'show_instance': show_instance,
+                'salt': salt
             })
 
     def ipsec_gre_tunnel_add_del(self, local_ip, remote_ip,