ipsec: fix padding/alignment for native IPsec encryption

Not all ESP crypto algorithms require padding/alignment to be the same
as AES block/IV size. CCM, CTR and GCM all have no padding/alignment
requirements, and the RFCs indicate that no padding (beyond ESPs 4 octet
alignment requirement) should be used unless TFC (traffic flow
confidentiality) has been requested.

  CTR: https://tools.ietf.org/html/rfc3686#section-3.2
  GCM: https://tools.ietf.org/html/rfc4106#section-3.2
  CCM: https://tools.ietf.org/html/rfc4309#section-3.2

- VPP is incorrectly using the IV/AES block size to pad CTR and GCM.
These modes do not require padding (beyond ESPs 4 octet requirement), as
a result packets will have unnecessary padding, which will waste
bandwidth at least and possibly fail certain network configurations that
have finely tuned MTU configurations at worst.

Fix this as well as changing the field names from ".*block_size" to
".*block_align" to better represent their actual (and only) use. Rename
"block_sz" in esp_encrypt to "esp_align" and set it correctly as well.

test: ipsec: Add unit-test to test for RFC correct padding/alignment

test: patch scapy to not incorrectly pad ccm, ctr, gcm modes as well

- Scapy is also incorrectly using the AES block size of 16 to pad CCM,
CTR, and GCM cipher modes. A bug report has been opened with the
and acknowledged with the upstream scapy project as well:

  https://github.com/secdev/scapy/issues/2322

Ticket: VPP-1928
Type: fix
Signed-off-by: Christian Hopps <chopps@labn.net>
Change-Id: Iaa4d6a325a2e99fdcb2c375a3395bcfe7947770e
This commit is contained in:
Christian Hopps
2019-11-03 07:02:15 -05:00
committed by Damjan Marion
parent dce44e4e23
commit fb7e7ed2cd
9 changed files with 120 additions and 52 deletions
+6 -6
View File
@@ -112,7 +112,7 @@ format_esp_post_encrypt_trace (u8 * s, va_list * args)
/* pad packet in input buffer */
static_always_inline u8 *
esp_add_footer_and_icv (vlib_main_t * vm, vlib_buffer_t ** last,
u8 block_size, u8 icv_sz,
u8 esp_align, u8 icv_sz,
u16 * next, vlib_node_runtime_t * node,
u16 buffer_data_size, uword total_len)
{
@@ -122,7 +122,7 @@ esp_add_footer_and_icv (vlib_main_t * vm, vlib_buffer_t ** last,
};
u16 min_length = total_len + sizeof (esp_footer_t);
u16 new_length = round_pow2 (min_length, block_size);
u16 new_length = round_pow2 (min_length, esp_align);
u8 pad_bytes = new_length - min_length;
esp_footer_t *f = (esp_footer_t *) (vlib_buffer_get_current (last[0]) +
last[0]->current_length + pad_bytes);
@@ -587,7 +587,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
u16 buffer_data_size = vlib_buffer_get_default_data_size (vm);
u32 current_sa_index = ~0, current_sa_packets = 0;
u32 current_sa_bytes = 0, spi = 0;
u8 block_sz = 0, iv_sz = 0, icv_sz = 0;
u8 esp_align = 4, iv_sz = 0, icv_sz = 0;
ipsec_sa_t *sa0 = 0;
vlib_buffer_t *lb;
vnet_crypto_op_t **crypto_ops = &ptd->crypto_ops;
@@ -648,7 +648,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
sa0 = pool_elt_at_index (im->sad, sa_index0);
current_sa_index = sa_index0;
spi = clib_net_to_host_u32 (sa0->spi);
block_sz = sa0->crypto_block_size;
esp_align = sa0->esp_block_align;
icv_sz = sa0->integ_icv_size;
iv_sz = sa0->crypto_iv_size;
@@ -713,7 +713,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (ipsec_sa_is_set_IS_TUNNEL (sa0))
{
payload = vlib_buffer_get_current (b[0]);
next_hdr_ptr = esp_add_footer_and_icv (vm, &lb, block_sz, icv_sz,
next_hdr_ptr = esp_add_footer_and_icv (vm, &lb, esp_align, icv_sz,
next, node,
buffer_data_size,
vlib_buffer_length_in_chain
@@ -789,7 +789,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_buffer_advance (b[0], ip_len);
payload = vlib_buffer_get_current (b[0]);
next_hdr_ptr = esp_add_footer_and_icv (vm, &lb, block_sz, icv_sz,
next_hdr_ptr = esp_add_footer_and_icv (vm, &lb, esp_align, icv_sz,
next, node,
buffer_data_size,
vlib_buffer_length_in_chain
+9 -9
View File
@@ -450,44 +450,44 @@ ipsec_init (vlib_main_t * vm)
a->dec_op_id = VNET_CRYPTO_OP_NONE;
a->alg = VNET_CRYPTO_ALG_NONE;
a->iv_size = 0;
a->block_size = 1;
a->block_align = 1;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_DES_CBC;
a->enc_op_id = VNET_CRYPTO_OP_DES_CBC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_DES_CBC_DEC;
a->alg = VNET_CRYPTO_ALG_DES_CBC;
a->iv_size = a->block_size = 8;
a->iv_size = a->block_align = 8;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_3DES_CBC;
a->enc_op_id = VNET_CRYPTO_OP_3DES_CBC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_3DES_CBC_DEC;
a->alg = VNET_CRYPTO_ALG_3DES_CBC;
a->iv_size = a->block_size = 8;
a->iv_size = a->block_align = 8;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_128;
a->enc_op_id = VNET_CRYPTO_OP_AES_128_CBC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_128_CBC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_128_CBC;
a->iv_size = a->block_size = 16;
a->iv_size = a->block_align = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_192;
a->enc_op_id = VNET_CRYPTO_OP_AES_192_CBC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_192_CBC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_192_CBC;
a->iv_size = a->block_size = 16;
a->iv_size = a->block_align = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_256;
a->enc_op_id = VNET_CRYPTO_OP_AES_256_CBC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_256_CBC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_256_CBC;
a->iv_size = a->block_size = 16;
a->iv_size = a->block_align = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_128;
a->enc_op_id = VNET_CRYPTO_OP_AES_128_GCM_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
a->alg = VNET_CRYPTO_ALG_AES_128_GCM;
a->iv_size = 8;
a->block_size = 16;
a->block_align = 1;
a->icv_size = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_192;
@@ -495,7 +495,7 @@ ipsec_init (vlib_main_t * vm)
a->dec_op_id = VNET_CRYPTO_OP_AES_192_GCM_DEC;
a->alg = VNET_CRYPTO_ALG_AES_192_GCM;
a->iv_size = 8;
a->block_size = 16;
a->block_align = 1;
a->icv_size = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_256;
@@ -503,7 +503,7 @@ ipsec_init (vlib_main_t * vm)
a->dec_op_id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
a->alg = VNET_CRYPTO_ALG_AES_256_GCM;
a->iv_size = 8;
a->block_size = 16;
a->block_align = 1;
a->icv_size = 16;
vec_validate (im->integ_algs, IPSEC_INTEG_N_ALG - 1);
+1 -1
View File
@@ -78,7 +78,7 @@ typedef struct
vnet_crypto_op_id_t dec_op_id;
vnet_crypto_alg_t alg;
u8 iv_size;
u8 block_size;
u8 block_align;
u8 icv_size;
} ipsec_main_crypto_alg_t;
+2 -2
View File
@@ -99,12 +99,12 @@ ipsec_sa_set_crypto_alg (ipsec_sa_t * sa, ipsec_crypto_alg_t crypto_alg)
ipsec_main_t *im = &ipsec_main;
sa->crypto_alg = crypto_alg;
sa->crypto_iv_size = im->crypto_algs[crypto_alg].iv_size;
sa->crypto_block_size = im->crypto_algs[crypto_alg].block_size;
sa->esp_block_align = clib_max (4, im->crypto_algs[crypto_alg].block_align);
sa->sync_op_data.crypto_enc_op_id = im->crypto_algs[crypto_alg].enc_op_id;
sa->sync_op_data.crypto_dec_op_id = im->crypto_algs[crypto_alg].dec_op_id;
sa->crypto_calg = im->crypto_algs[crypto_alg].alg;
ASSERT (sa->crypto_iv_size <= ESP_MAX_IV_SIZE);
ASSERT (sa->crypto_block_size <= ESP_MAX_BLOCK_SIZE);
ASSERT (sa->esp_block_align <= ESP_MAX_BLOCK_SIZE);
if (IPSEC_CRYPTO_ALG_IS_GCM (crypto_alg))
{
sa->integ_icv_size = im->crypto_algs[crypto_alg].icv_size;
+1 -1
View File
@@ -113,7 +113,7 @@ typedef struct
ipsec_sa_flags_t flags;
u8 crypto_iv_size;
u8 crypto_block_size;
u8 esp_block_align;
u8 integ_icv_size;
u32 encrypt_thread_index;
u32 decrypt_thread_index;
+38 -16
View File
@@ -1,5 +1,5 @@
diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
index f8c601fa..f566d288 100644
index ae057ee1..24a1f6ea 100644
--- a/scapy/layers/ipsec.py
+++ b/scapy/layers/ipsec.py
@@ -138,6 +138,7 @@ bind_layers(IP, ESP, proto=socket.IPPROTO_ESP)
@@ -9,8 +9,8 @@ index f8c601fa..f566d288 100644
+bind_layers(UDP, ESP, dport=4545) # NAT-Traversal encapsulation - random port
###############################################################################
@@ -359,11 +359,8 @@ class CryptAlgo(object):
@@ -359,11 +360,8 @@ class CryptAlgo(object):
encryptor = cipher.encryptor()
if self.is_aead:
@@ -24,7 +24,7 @@ index f8c601fa..f566d288 100644
data = encryptor.update(data) + encryptor.finalize()
data += encryptor.tag[:self.icv_size]
else:
@@ -401,12 +398,7 @@ class CryptAlgo(object):
@@ -400,12 +398,7 @@ class CryptAlgo(object):
if self.is_aead:
# Tag value check is done during the finalize method
@@ -38,7 +38,31 @@ index f8c601fa..f566d288 100644
try:
data = decryptor.update(data) + decryptor.finalize()
except InvalidTag as err:
@@ -545,7 +537,7 @@ class AuthAlgo(object):
@@ -445,6 +438,7 @@ if algorithms:
CRYPT_ALGOS['AES-CTR'] = CryptAlgo('AES-CTR',
cipher=algorithms.AES,
mode=modes.CTR,
+ block_size=1,
iv_size=8,
salt_size=4,
format_mode_iv=_aes_ctr_format_mode_iv)
@@ -452,6 +446,7 @@ if algorithms:
CRYPT_ALGOS['AES-GCM'] = CryptAlgo('AES-GCM',
cipher=algorithms.AES,
mode=modes.GCM,
+ block_size=1,
salt_size=4,
iv_size=8,
icv_size=16,
@@ -460,6 +455,7 @@ if algorithms:
CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM',
cipher=algorithms.AES,
mode=modes.CCM,
+ block_size=1,
iv_size=8,
salt_size=3,
icv_size=16,
@@ -544,7 +540,7 @@ class AuthAlgo(object):
else:
return self.mac(key, self.digestmod(), default_backend())
@@ -47,7 +71,7 @@ index f8c601fa..f566d288 100644
"""
Sign an IPsec (ESP or AH) packet with this algo.
@@ -561,16 +553,20 @@ class AuthAlgo(object):
@@ -560,16 +556,20 @@ class AuthAlgo(object):
if pkt.haslayer(ESP):
mac.update(raw(pkt[ESP]))
@@ -69,7 +93,7 @@ index f8c601fa..f566d288 100644
"""
Check that the integrity check value (icv) of a packet is valid.
@@ -602,6 +598,8 @@ class AuthAlgo(object):
@@ -600,6 +600,8 @@ class AuthAlgo(object):
clone = zero_mutable_fields(pkt.copy(), sending=False)
mac.update(raw(clone))
@@ -78,7 +102,7 @@ index f8c601fa..f566d288 100644
computed_icv = mac.finalize()[:self.icv_size]
# XXX: Cannot use mac.verify because the ICV can be truncated
@@ -864,6 +862,23 @@ class SecurityAssociation(object):
@@ -862,6 +864,23 @@ class SecurityAssociation(object):
raise TypeError('nat_t_header must be %s' % UDP.name)
self.nat_t_header = nat_t_header
@@ -102,7 +126,7 @@ index f8c601fa..f566d288 100644
def check_spi(self, pkt):
if pkt.spi != self.spi:
raise TypeError('packet spi=0x%x does not match the SA spi=0x%x' %
@@ -877,7 +892,8 @@ class SecurityAssociation(object):
@@ -875,7 +894,8 @@ class SecurityAssociation(object):
if len(iv) != self.crypt_algo.iv_size:
raise TypeError('iv length must be %s' % self.crypt_algo.iv_size) # noqa: E501
@@ -112,7 +136,7 @@ index f8c601fa..f566d288 100644
if self.tunnel_header:
tunnel = self.tunnel_header.copy()
@@ -901,7 +917,7 @@ class SecurityAssociation(object):
@@ -899,7 +919,7 @@ class SecurityAssociation(object):
esn_en=esn_en or self.esn_en,
esn=esn or self.esn)
@@ -121,7 +145,7 @@ index f8c601fa..f566d288 100644
if self.nat_t_header:
nat_t_header = self.nat_t_header.copy()
@@ -928,7 +944,8 @@ class SecurityAssociation(object):
@@ -926,7 +946,8 @@ class SecurityAssociation(object):
def _encrypt_ah(self, pkt, seq_num=None):
@@ -131,7 +155,7 @@ index f8c601fa..f566d288 100644
icv=b"\x00" * self.auth_algo.icv_size)
if self.tunnel_header:
@@ -968,7 +985,8 @@ class SecurityAssociation(object):
@@ -966,7 +987,8 @@ class SecurityAssociation(object):
else:
ip_header.plen = len(ip_header.payload) + len(ah) + len(payload)
@@ -141,7 +165,7 @@ index f8c601fa..f566d288 100644
# sequence number must always change, unless specified by the user
if seq_num is None:
@@ -1005,11 +1023,12 @@ class SecurityAssociation(object):
@@ -1003,11 +1025,12 @@ class SecurityAssociation(object):
def _decrypt_esp(self, pkt, verify=True, esn_en=None, esn=None):
@@ -155,7 +179,7 @@ index f8c601fa..f566d288 100644
esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key,
self.crypt_algo.icv_size or
@@ -1050,11 +1069,12 @@ class SecurityAssociation(object):
@@ -1048,9 +1071,10 @@ class SecurityAssociation(object):
def _decrypt_ah(self, pkt, verify=True):
@@ -167,5 +191,3 @@ index f8c601fa..f566d288 100644
ah = pkt[AH]
payload = ah.payload
+38 -14
View File
@@ -1,5 +1,5 @@
diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
index 69e7ae3b..3a1724b2 100644
index 69e7ae3b..d9c1705b 100644
--- a/scapy/layers/ipsec.py
+++ b/scapy/layers/ipsec.py
@@ -344,8 +344,7 @@ class CryptAlgo(object):
@@ -24,7 +24,31 @@ index 69e7ae3b..3a1724b2 100644
try:
data = decryptor.update(data) + decryptor.finalize()
except InvalidTag as err:
@@ -518,12 +514,16 @@ class AuthAlgo(object):
@@ -422,6 +418,7 @@ if algorithms:
CRYPT_ALGOS['AES-CTR'] = CryptAlgo('AES-CTR',
cipher=algorithms.AES,
mode=modes.CTR,
+ block_size=1,
iv_size=8,
salt_size=4,
format_mode_iv=_aes_ctr_format_mode_iv)
@@ -429,6 +426,7 @@ if algorithms:
CRYPT_ALGOS['AES-GCM'] = CryptAlgo('AES-GCM',
cipher=algorithms.AES,
mode=modes.GCM,
+ block_size=1,
salt_size=4,
iv_size=8,
icv_size=16,
@@ -437,6 +435,7 @@ if algorithms:
CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM',
cipher=algorithms.AES,
mode=modes.CCM,
+ block_size=1,
iv_size=8,
salt_size=3,
icv_size=16,
@@ -518,12 +517,16 @@ class AuthAlgo(object):
else:
return self.mac(key, self.digestmod(), default_backend())
@@ -42,7 +66,7 @@ index 69e7ae3b..3a1724b2 100644
@return: the signed packet
"""
@@ -534,16 +534,20 @@ class AuthAlgo(object):
@@ -534,16 +537,20 @@ class AuthAlgo(object):
if pkt.haslayer(ESP):
mac.update(raw(pkt[ESP]))
@@ -64,7 +88,7 @@ index 69e7ae3b..3a1724b2 100644
"""
Check that the integrity check value (icv) of a packet is valid.
@@ -574,6 +578,8 @@ class AuthAlgo(object):
@@ -574,6 +581,8 @@ class AuthAlgo(object):
clone = zero_mutable_fields(pkt.copy(), sending=False)
mac.update(raw(clone))
@@ -73,7 +97,7 @@ index 69e7ae3b..3a1724b2 100644
computed_icv = mac.finalize()[:self.icv_size]
# XXX: Cannot use mac.verify because the ICV can be truncated
@@ -757,7 +763,8 @@ class SecurityAssociation(object):
@@ -757,7 +766,8 @@ class SecurityAssociation(object):
SUPPORTED_PROTOS = (IP, IPv6)
def __init__(self, proto, spi, seq_num=1, crypt_algo=None, crypt_key=None,
@@ -83,7 +107,7 @@ index 69e7ae3b..3a1724b2 100644
"""
@param proto: the IPsec proto to use (ESP or AH)
@param spi: the Security Parameters Index of this SA
@@ -771,6 +778,7 @@ class SecurityAssociation(object):
@@ -771,6 +781,7 @@ class SecurityAssociation(object):
to encapsulate the encrypted packets.
@param nat_t_header: an instance of a UDP header that will be used
for NAT-Traversal.
@@ -91,7 +115,7 @@ index 69e7ae3b..3a1724b2 100644
"""
if proto not in (ESP, AH, ESP.name, AH.name):
@@ -782,6 +790,7 @@ class SecurityAssociation(object):
@@ -782,6 +793,7 @@ class SecurityAssociation(object):
self.spi = spi
self.seq_num = seq_num
@@ -99,7 +123,7 @@ index 69e7ae3b..3a1724b2 100644
if crypt_algo:
if crypt_algo not in CRYPT_ALGOS:
@@ -827,6 +836,23 @@ class SecurityAssociation(object):
@@ -827,6 +839,23 @@ class SecurityAssociation(object):
raise TypeError('packet spi=0x%x does not match the SA spi=0x%x' %
(pkt.spi, self.spi))
@@ -123,7 +147,7 @@ index 69e7ae3b..3a1724b2 100644
def _encrypt_esp(self, pkt, seq_num=None, iv=None):
if iv is None:
@@ -835,7 +861,8 @@ class SecurityAssociation(object):
@@ -835,7 +864,8 @@ class SecurityAssociation(object):
if len(iv) != self.crypt_algo.iv_size:
raise TypeError('iv length must be %s' % self.crypt_algo.iv_size)
@@ -133,7 +157,7 @@ index 69e7ae3b..3a1724b2 100644
if self.tunnel_header:
tunnel = self.tunnel_header.copy()
@@ -857,7 +884,7 @@ class SecurityAssociation(object):
@@ -857,7 +887,7 @@ class SecurityAssociation(object):
esp = self.crypt_algo.pad(esp)
esp = self.crypt_algo.encrypt(self, esp, self.crypt_key)
@@ -142,7 +166,7 @@ index 69e7ae3b..3a1724b2 100644
if self.nat_t_header:
nat_t_header = self.nat_t_header.copy()
@@ -884,7 +911,8 @@ class SecurityAssociation(object):
@@ -884,7 +914,8 @@ class SecurityAssociation(object):
def _encrypt_ah(self, pkt, seq_num=None):
@@ -152,7 +176,7 @@ index 69e7ae3b..3a1724b2 100644
icv = b"\x00" * self.auth_algo.icv_size)
if self.tunnel_header:
@@ -924,7 +952,8 @@ class SecurityAssociation(object):
@@ -924,7 +955,8 @@ class SecurityAssociation(object):
else:
ip_header.plen = len(ip_header.payload) + len(ah) + len(payload)
@@ -162,7 +186,7 @@ index 69e7ae3b..3a1724b2 100644
# sequence number must always change, unless specified by the user
if seq_num is None:
@@ -955,11 +984,12 @@ class SecurityAssociation(object):
@@ -955,11 +987,12 @@ class SecurityAssociation(object):
def _decrypt_esp(self, pkt, verify=True):
@@ -176,7 +200,7 @@ index 69e7ae3b..3a1724b2 100644
esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key,
self.crypt_algo.icv_size or
@@ -998,9 +1028,11 @@ class SecurityAssociation(object):
@@ -998,9 +1031,11 @@ class SecurityAssociation(object):
def _decrypt_ah(self, pkt, verify=True):
+13 -1
View File
@@ -803,6 +803,15 @@ class IpsecTun4(object):
self.assert_equal(rx[IP].dst, self.pg1.remote_ip4)
self.assert_packet_checksums_valid(rx)
def verify_esp_padding(self, sa, esp_payload, decrypt_pkt):
align = sa.crypt_algo.block_size
if align < 4:
align = 4
exp_len = (len(decrypt_pkt) + 2 + (align - 1)) & ~(align - 1)
exp_len += sa.crypt_algo.iv_size
exp_len += sa.crypt_algo.icv_size or sa.auth_algo.icv_size
self.assertEqual(exp_len, len(esp_payload))
def verify_encrypted(self, p, sa, rxs):
decrypt_pkts = []
for rx in rxs:
@@ -811,9 +820,12 @@ class IpsecTun4(object):
self.assert_packet_checksums_valid(rx)
self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
try:
decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IP])
rx_ip = rx[IP]
decrypt_pkt = p.vpp_tun_sa.decrypt(rx_ip)
if not decrypt_pkt.haslayer(IP):
decrypt_pkt = IP(decrypt_pkt[Raw].load)
if rx_ip.proto == socket.IPPROTO_ESP:
self.verify_esp_padding(sa, rx_ip[ESP].data, decrypt_pkt)
decrypt_pkts.append(decrypt_pkt)
self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
+12 -2
View File
@@ -1,7 +1,7 @@
import socket
import unittest
from scapy.layers.ipsec import ESP
from scapy.layers.inet import UDP
from scapy.layers.inet import IP, ICMP, UDP
from parameterized import parameterized
from framework import VppTestRunner
@@ -544,6 +544,8 @@ class RunTestIpsecEspAll(ConfigIpsecESP,
self.run_a_test(self.engine, self.flag, self.algo)
def run_a_test(self, engine, flag, algo, payload_size=None):
if engine == "ia32":
engine = "native"
self.vapi.cli("set crypto handler all %s" % engine)
self.ipv4_params = IPsecIPv4Params()
@@ -579,8 +581,16 @@ class RunTestIpsecEspAll(ConfigIpsecESP,
self.verify_tra_basic4(count=NUM_PKTS)
self.verify_tun_66(self.params[socket.AF_INET6],
count=NUM_PKTS)
#
# Use an odd-byte payload size to check for correct padding.
#
# 49 + 2 == 51 which should pad +1 to 52 for 4 byte alignment, +5
# to 56 for 8 byte alignment, and +13 to 64 for 64 byte alignment.
# This should catch bugs where the code is incorrectly over-padding
# for algorithms that don't require it
psz = 49 - len(IP()/ICMP()) if payload_size is None else payload_size
self.verify_tun_44(self.params[socket.AF_INET],
count=NUM_PKTS)
count=NUM_PKTS, payload_size=psz)
LARGE_PKT_SZ = [
1970, # results in 2 chained buffers entering decrypt node