esp_header_t *esp0;
esp_aead_t *aad;
u8 *scratch;
- u32 salt;
/*
* construct the AAD and the nonce (Salt || IV) in a scratch
* 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;
@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
{
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
@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;
u32 show_instance;
u8 udp_encap;
u32 tx_table_id;
+ u32 salt;
};
/** \brief Add/delete IPsec tunnel interface response
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);
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);
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;
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"))
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);
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,
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);
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);
import unittest
import socket
+import struct
from scapy.layers.inet import IP, ICMP, TCP, UDP
from scapy.layers.ipsec import SecurityAssociation
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
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
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],
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],
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,
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,
import socket
import unittest
-import struct
from scapy.layers.ipsec import ESP
from scapy.layers.inet import UDP
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,
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)
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)
'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.
'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),
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),
IPSEC_API_INTEG_ALG_SHA1_96),
'scapy-crypto': "AES-CBC",
'scapy-integ': "HMAC-SHA1-96",
- 'salt': '',
+ 'salt': 0,
'key': "JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"}]
# with and without ESN
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
#
import unittest
import socket
import copy
-import struct
from scapy.layers.ipsec import ESP
from scapy.layers.l2 import Ether, Raw, GRE
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()
'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.
'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.
'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),
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),
IPSEC_API_INTEG_ALG_SHA1_96),
'scapy-crypto': "AES-CBC",
'scapy-integ': "HMAC-SHA1-96",
- 'salt': '',
+ 'salt': 0,
'key': "JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"}]
for engine in engines:
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)
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
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
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)
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
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
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)
tunnel_src_address='',
tunnel_dst_address='',
flags=0,
+ salt=0,
is_add=1):
""" IPSEC SA add/del
:param sad_id: security association ID
'data': crypto_key,
},
'flags': flags,
+ 'salt': salt,
}
})
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,
'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,