ipsec: add support for RFC-4543 ENCR_NULL_AUTH_AES_GMAC

Type: improvement

Change-Id: I830f7a2ea3ac0aff5185698b9fa7a278c45116b0
Signed-off-by: Benoît Ganne <bganne@cisco.com>
This commit is contained in:
Benoît Ganne
2023-03-10 17:33:03 +01:00
committed by Beno�t Ganne
parent 96600f9077
commit 84e6658486
16 changed files with 3347 additions and 48 deletions

View File

@ -51,7 +51,10 @@ static openssl_per_thread_data_t *per_thread_data = 0;
_ (gcm, AES_256_GCM, EVP_aes_256_gcm, 8) \
_ (cbc, AES_128_CTR, EVP_aes_128_ctr, 8) \
_ (cbc, AES_192_CTR, EVP_aes_192_ctr, 8) \
_ (cbc, AES_256_CTR, EVP_aes_256_ctr, 8)
_ (cbc, AES_256_CTR, EVP_aes_256_ctr, 8) \
_ (null_gmac, AES_128_NULL_GMAC, EVP_aes_128_gcm, 8) \
_ (null_gmac, AES_192_NULL_GMAC, EVP_aes_192_gcm, 8) \
_ (null_gmac, AES_256_NULL_GMAC, EVP_aes_256_gcm, 8)
#define foreach_openssl_chacha20_evp_op \
_ (chacha20_poly1305, CHACHA20_POLY1305, EVP_chacha20_poly1305, 8)
@ -199,7 +202,8 @@ openssl_ops_dec_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[],
static_always_inline u32
openssl_ops_enc_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, int is_gcm, const int iv_len)
const EVP_CIPHER *cipher, int is_gcm, int is_gmac,
const int iv_len)
{
openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
vm->thread_index);
@ -223,26 +227,36 @@ openssl_ops_enc_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
chp = chunks + op->chunk_index;
for (j = 0; j < op->n_chunks; j++)
{
EVP_EncryptUpdate (ctx, chp->dst, &len, chp->src, chp->len);
EVP_EncryptUpdate (ctx, is_gmac ? 0 : chp->dst, &len, chp->src,
chp->len);
chp += 1;
}
}
else
EVP_EncryptUpdate (ctx, op->dst, &len, op->src, op->len);
EVP_EncryptFinal_ex (ctx, op->dst + len, &len);
EVP_EncryptUpdate (ctx, is_gmac ? 0 : op->dst, &len, op->src, op->len);
EVP_EncryptFinal_ex (ctx, is_gmac ? 0 : op->dst + len, &len);
EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_AEAD_GET_TAG, op->tag_len, op->tag);
op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
}
return n_ops;
}
static_always_inline u32
openssl_ops_enc_null_gmac (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 1, /* is_gmac */ 1, iv_len);
}
static_always_inline u32
openssl_ops_enc_gcm (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 1, iv_len);
/* is_gcm */ 1, /* is_gmac */ 0, iv_len);
}
static_always_inline __clib_unused u32
@ -251,13 +265,14 @@ openssl_ops_enc_chacha20_poly1305 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 0, iv_len);
/* is_gcm */ 0, /* is_gmac */ 0, iv_len);
}
static_always_inline u32
openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, int is_gcm, const int iv_len)
const EVP_CIPHER *cipher, int is_gcm, int is_gmac,
const int iv_len)
{
openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
vm->thread_index);
@ -281,15 +296,19 @@ openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
chp = chunks + op->chunk_index;
for (j = 0; j < op->n_chunks; j++)
{
EVP_DecryptUpdate (ctx, chp->dst, &len, chp->src, chp->len);
EVP_DecryptUpdate (ctx, is_gmac ? 0 : chp->dst, &len, chp->src,
chp->len);
chp += 1;
}
}
else
EVP_DecryptUpdate (ctx, op->dst, &len, op->src, op->len);
{
EVP_DecryptUpdate (ctx, is_gmac ? 0 : op->dst, &len, op->src,
op->len);
}
EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_AEAD_SET_TAG, op->tag_len, op->tag);
if (EVP_DecryptFinal_ex (ctx, op->dst + len, &len) > 0)
if (EVP_DecryptFinal_ex (ctx, is_gmac ? 0 : op->dst + len, &len) > 0)
op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
else
{
@ -300,13 +319,22 @@ openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
return n_ops - n_fail;
}
static_always_inline u32
openssl_ops_dec_null_gmac (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 1, /* is_gmac */ 1, iv_len);
}
static_always_inline u32
openssl_ops_dec_gcm (vlib_main_t *vm, vnet_crypto_op_t *ops[],
vnet_crypto_op_chunk_t *chunks, u32 n_ops,
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 1, iv_len);
/* is_gcm */ 1, /* is_gmac */ 0, iv_len);
}
static_always_inline __clib_unused u32
@ -315,7 +343,7 @@ openssl_ops_dec_chacha20_poly1305 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
const EVP_CIPHER *cipher, const int iv_len)
{
return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
/* is_gcm */ 0, iv_len);
/* is_gcm */ 0, /* is_gmac */ 0, iv_len);
}
static_always_inline u32

View File

@ -26,6 +26,7 @@ add_vpp_plugin(unittest
crypto/aes_cbc.c
crypto/aes_ctr.c
crypto/aes_gcm.c
crypto/aes_gmac.c
${chacha20_poly1305}
crypto/rfc2202_hmac_md5.c
crypto/rfc2202_hmac_sha1.c

File diff suppressed because it is too large Load Diff

View File

@ -61,6 +61,10 @@ typedef struct
extern crypto_test_main_t crypto_test_main;
#define TEST_DATA(n) { .data = (u8 *) n, .length = sizeof (n)}
#define TEST_DATA_STR(n) \
{ \
.data = (u8 *) n, .length = sizeof (n) - 1 \
}
#define TEST_DATA_CHUNK(s,off,n) { .data = (u8 *) s + off, .length = n}
#define UNITTEST_REGISTER_CRYPTO_TEST(x) \

View File

@ -139,8 +139,7 @@ print_results (vlib_main_t * vm, unittest_crypto_test_registration_t ** rv,
if (vec_len (err))
fail = 1;
vlib_cli_output (vm, "%-60v%s%v", s, vec_len (err) ? "FAIL: " : "OK",
err);
vlib_cli_output (vm, "%-65v%s%v", s, vec_len (err) ? "FAIL: " : "OK", err);
if (tm->verbose)
{
if (tm->verbose == 2)

View File

@ -145,7 +145,7 @@ show_crypto_handlers_command_fn (vlib_main_t * vm,
"Chained");
for (i = 0; i < VNET_CRYPTO_N_ALGS; i++)
vlib_cli_output (vm, "%-16U%U", format_vnet_crypto_alg, i,
vlib_cli_output (vm, "%-20U%U", format_vnet_crypto_alg, i,
format_vnet_crypto_handlers, i);
return 0;

View File

@ -33,11 +33,14 @@
_(AES_256_CTR, "aes-256-ctr", 32)
/* CRYPTO_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES */
#define foreach_crypto_aead_alg \
_(AES_128_GCM, "aes-128-gcm", 16) \
_(AES_192_GCM, "aes-192-gcm", 24) \
_(AES_256_GCM, "aes-256-gcm", 32) \
_(CHACHA20_POLY1305, "chacha20-poly1305", 32)
#define foreach_crypto_aead_alg \
_ (AES_128_GCM, "aes-128-gcm", 16) \
_ (AES_192_GCM, "aes-192-gcm", 24) \
_ (AES_256_GCM, "aes-256-gcm", 32) \
_ (AES_128_NULL_GMAC, "aes-128-null-gmac", 16) \
_ (AES_192_NULL_GMAC, "aes-192-null-gmac", 24) \
_ (AES_256_NULL_GMAC, "aes-256-null-gmac", 32) \
_ (CHACHA20_POLY1305, "chacha20-poly1305", 32)
#define foreach_crypto_hash_alg \
_ (SHA1, "sha-1") \
@ -89,6 +92,12 @@ typedef enum
_ (AES_192_GCM, "aes-192-gcm-aad12", 24, 16, 12) \
_ (AES_256_GCM, "aes-256-gcm-aad8", 32, 16, 8) \
_ (AES_256_GCM, "aes-256-gcm-aad12", 32, 16, 12) \
_ (AES_128_NULL_GMAC, "aes-128-null-gmac-aad8", 16, 16, 8) \
_ (AES_128_NULL_GMAC, "aes-128-null-gmac-aad12", 16, 16, 12) \
_ (AES_192_NULL_GMAC, "aes-192-null-gmac-aad8", 24, 16, 8) \
_ (AES_192_NULL_GMAC, "aes-192-null-gmac-aad12", 24, 16, 12) \
_ (AES_256_NULL_GMAC, "aes-256-null-gmac-aad8", 32, 16, 8) \
_ (AES_256_NULL_GMAC, "aes-256-null-gmac-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad8", 32, 16, 8) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305", 32, 16, 0)

View File

@ -562,6 +562,12 @@ esp_decrypt_prepare_sync_op (vlib_main_t * vm, vlib_node_runtime_t * node,
op->aad_len = esp_aad_fill (op->aad, esp0, sa0, pd->seq_hi);
op->tag = payload + len;
op->tag_len = 16;
if (PREDICT_FALSE (ipsec_sa_is_set_IS_NULL_GMAC (sa0)))
{
/* RFC-4543 ENCR_NULL_AUTH_AES_GMAC: IV is part of AAD */
payload -= iv_sz;
len += iv_sz;
}
}
else
{
@ -682,6 +688,12 @@ out:
aad = (u8 *) nonce - sizeof (esp_aead_t);
esp_aad_fill (aad, esp0, sa0, pd->seq_hi);
tag = payload + len;
if (PREDICT_FALSE (ipsec_sa_is_set_IS_NULL_GMAC (sa0)))
{
/* RFC-4543 ENCR_NULL_AUTH_AES_GMAC: IV is part of AAD */
payload -= iv_sz;
len += iv_sz;
}
}
else
{

View File

@ -415,6 +415,12 @@ esp_prepare_sync_op (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
op->aad_len = esp_aad_fill (op->aad, esp, sa0, seq_hi);
op->tag = payload + crypto_len;
op->tag_len = 16;
if (PREDICT_FALSE (ipsec_sa_is_set_IS_NULL_GMAC (sa0)))
{
/* RFC-4543 ENCR_NULL_AUTH_AES_GMAC: IV is part of AAD */
crypto_start -= iv_sz;
crypto_len += iv_sz;
}
}
else
{
@ -522,6 +528,12 @@ esp_prepare_async_frame (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
/* constuct aad in a scratch space in front of the nonce */
aad = (u8 *) nonce - sizeof (esp_aead_t);
esp_aad_fill (aad, esp, sa, sa->seq_hi);
if (PREDICT_FALSE (ipsec_sa_is_set_IS_NULL_GMAC (sa)))
{
/* RFC-4543 ENCR_NULL_AUTH_AES_GMAC: IV is part of AAD */
crypto_start_offset -= iv_sz;
crypto_total_len += iv_sz;
}
}
else
{

View File

@ -562,6 +562,30 @@ ipsec_init (vlib_main_t * vm)
a->iv_size = 8;
a->icv_size = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_NULL_GMAC_128;
a->enc_op_id = VNET_CRYPTO_OP_AES_128_NULL_GMAC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_128_NULL_GMAC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_128_GCM;
a->iv_size = 8;
a->block_align = 1;
a->icv_size = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_NULL_GMAC_192;
a->enc_op_id = VNET_CRYPTO_OP_AES_192_NULL_GMAC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_192_NULL_GMAC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_192_GCM;
a->iv_size = 8;
a->block_align = 1;
a->icv_size = 16;
a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_NULL_GMAC_256;
a->enc_op_id = VNET_CRYPTO_OP_AES_256_NULL_GMAC_ENC;
a->dec_op_id = VNET_CRYPTO_OP_AES_256_NULL_GMAC_DEC;
a->alg = VNET_CRYPTO_ALG_AES_256_GCM;
a->iv_size = 8;
a->block_align = 1;
a->icv_size = 16;
vec_validate (im->integ_algs, IPSEC_INTEG_N_ALG - 1);
ipsec_main_integ_alg_t *i;

View File

@ -136,6 +136,13 @@ ipsec_sa_set_crypto_alg (ipsec_sa_t * sa, ipsec_crypto_alg_t crypto_alg)
{
ipsec_sa_set_IS_CTR (sa);
}
else if (IPSEC_CRYPTO_ALG_IS_NULL_GMAC (crypto_alg))
{
sa->integ_icv_size = im->crypto_algs[crypto_alg].icv_size;
ipsec_sa_set_IS_CTR (sa);
ipsec_sa_set_IS_AEAD (sa);
ipsec_sa_set_IS_NULL_GMAC (sa);
}
}
void
@ -416,7 +423,7 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
err = ipsec_check_support_cb (im, sa);
if (err)
{
clib_warning ("%s", err->what);
clib_warning ("%v", err->what);
pool_put (ipsec_sa_pool, sa);
return VNET_API_ERROR_UNIMPLEMENTED;
}

View File

@ -39,7 +39,10 @@
_ (9, AES_GCM_256, "aes-gcm-256") \
_ (10, DES_CBC, "des-cbc") \
_ (11, 3DES_CBC, "3des-cbc") \
_ (12, CHACHA20_POLY1305, "chacha20-poly1305")
_ (12, CHACHA20_POLY1305, "chacha20-poly1305") \
_ (13, AES_NULL_GMAC_128, "aes-null-gmac-128") \
_ (14, AES_NULL_GMAC_192, "aes-null-gmac-192") \
_ (15, AES_NULL_GMAC_256, "aes-null-gmac-256")
typedef enum
{
@ -49,6 +52,11 @@ typedef enum
IPSEC_CRYPTO_N_ALG,
} __clib_packed ipsec_crypto_alg_t;
#define IPSEC_CRYPTO_ALG_IS_NULL_GMAC(_alg) \
((_alg == IPSEC_CRYPTO_ALG_AES_NULL_GMAC_128) || \
(_alg == IPSEC_CRYPTO_ALG_AES_NULL_GMAC_192) || \
(_alg == IPSEC_CRYPTO_ALG_AES_NULL_GMAC_256))
#define IPSEC_CRYPTO_ALG_IS_GCM(_alg) \
(((_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) || \
(_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) || \
@ -112,7 +120,8 @@ typedef struct ipsec_key_t_
_ (128, IS_AEAD, "aead") \
_ (256, IS_CTR, "ctr") \
_ (512, IS_ASYNC, "async") \
_ (1024, NO_ALGO_NO_DROP, "no-algo-no-drop")
_ (1024, NO_ALGO_NO_DROP, "no-algo-no-drop") \
_ (2048, IS_NULL_GMAC, "null-gmac")
typedef enum ipsec_sad_flags_t_
{

View File

@ -37,6 +37,9 @@ enum ipsec_crypto_alg
IPSEC_API_CRYPTO_ALG_DES_CBC,
IPSEC_API_CRYPTO_ALG_3DES_CBC,
IPSEC_API_CRYPTO_ALG_CHACHA20_POLY1305 [backwards_compatible],
IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_128 [backwards_compatible],
IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_192 [backwards_compatible],
IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_256 [backwards_compatible],
};
/*

View File

@ -1,5 +1,5 @@
diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
index ae057ee1..55d0dd53 100644
index ae057ee1..b6806f71 100644
--- a/scapy/layers/ipsec.py
+++ b/scapy/layers/ipsec.py
@@ -56,6 +56,7 @@ from scapy.fields import ByteEnumField, ByteField, IntField, PacketField, \
@ -10,7 +10,7 @@ index ae057ee1..55d0dd53 100644
import scapy.modules.six as six
from scapy.modules.six.moves import range
from scapy.layers.inet6 import IPv6, IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt, \
@@ -359,11 +360,8 @@ class CryptAlgo(object):
@@ -359,13 +360,17 @@ class CryptAlgo(object):
encryptor = cipher.encryptor()
if self.is_aead:
@ -18,15 +18,29 @@ index ae057ee1..55d0dd53 100644
- aad = struct.pack('!LLL', esp.spi, esn, esp.seq)
- else:
- aad = struct.pack('!LL', esp.spi, esp.seq)
- encryptor.authenticate_additional_data(aad)
+ encryptor.authenticate_additional_data(sa.build_aead(esp))
+ aad = sa.build_aead(esp)
+ if self.name == 'AES-NULL-GMAC':
+ aad = aad + esp.iv + data
+ aes_null_gmac_data = data
+ data = b''
encryptor.authenticate_additional_data(aad)
+
data = encryptor.update(data) + encryptor.finalize()
data += encryptor.tag[:self.icv_size]
+ if self.name == 'AES-NULL-GMAC':
+ data = aes_null_gmac_data + data
else:
@@ -400,12 +398,7 @@ class CryptAlgo(object):
data = encryptor.update(data) + encryptor.finalize()
@@ -399,17 +404,19 @@ class CryptAlgo(object):
decryptor = cipher.decryptor()
if self.is_aead:
+ aad = sa.build_aead(esp)
+ if self.name == 'AES-NULL-GMAC':
+ aad = aad + iv + data
+ aes_null_gmac_data = data
+ data = b''
# Tag value check is done during the finalize method
- if esn_en:
- decryptor.authenticate_additional_data(
@ -34,11 +48,17 @@ index ae057ee1..55d0dd53 100644
- else:
- decryptor.authenticate_additional_data(
- struct.pack('!LL', esp.spi, esp.seq))
+ decryptor.authenticate_additional_data(sa.build_aead(esp))
+ decryptor.authenticate_additional_data(aad)
try:
data = decryptor.update(data) + decryptor.finalize()
except InvalidTag as err:
@@ -445,6 +438,7 @@ if algorithms:
raise IPSecIntegrityError(err)
+ if self.name == 'AES-NULL-GMAC':
+ data = aes_null_gmac_data + data
# extract padlen and nh
padlen = orb(data[-2])
@@ -445,6 +452,7 @@ if algorithms:
CRYPT_ALGOS['AES-CTR'] = CryptAlgo('AES-CTR',
cipher=algorithms.AES,
mode=modes.CTR,
@ -46,7 +66,7 @@ index ae057ee1..55d0dd53 100644
iv_size=8,
salt_size=4,
format_mode_iv=_aes_ctr_format_mode_iv)
@@ -452,6 +446,7 @@ if algorithms:
@@ -452,14 +460,24 @@ if algorithms:
CRYPT_ALGOS['AES-GCM'] = CryptAlgo('AES-GCM',
cipher=algorithms.AES,
mode=modes.GCM,
@ -54,7 +74,16 @@ index ae057ee1..55d0dd53 100644
salt_size=4,
iv_size=8,
icv_size=16,
@@ -460,6 +455,7 @@ if algorithms:
format_mode_iv=_salt_format_mode_iv)
+ CRYPT_ALGOS['AES-NULL-GMAC'] = CryptAlgo('AES-NULL-GMAC',
+ cipher=algorithms.AES,
+ mode=modes.GCM,
+ block_size=1,
+ salt_size=4,
+ iv_size=8,
+ icv_size=16,
+ format_mode_iv=_salt_format_mode_iv)
if hasattr(modes, 'CCM'):
CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM',
cipher=algorithms.AES,
mode=modes.CCM,
@ -62,7 +91,7 @@ index ae057ee1..55d0dd53 100644
iv_size=8,
salt_size=3,
icv_size=16,
@@ -544,7 +540,7 @@ class AuthAlgo(object):
@@ -544,7 +562,7 @@ class AuthAlgo(object):
else:
return self.mac(key, self.digestmod(), default_backend())
@ -71,7 +100,7 @@ index ae057ee1..55d0dd53 100644
"""
Sign an IPsec (ESP or AH) packet with this algo.
@@ -560,16 +556,20 @@ class AuthAlgo(object):
@@ -560,16 +578,20 @@ class AuthAlgo(object):
if pkt.haslayer(ESP):
mac.update(raw(pkt[ESP]))
@ -93,7 +122,7 @@ index ae057ee1..55d0dd53 100644
"""
Check that the integrity check value (icv) of a packet is valid.
@@ -600,6 +600,8 @@ class AuthAlgo(object):
@@ -600,6 +622,8 @@ class AuthAlgo(object):
clone = zero_mutable_fields(pkt.copy(), sending=False)
mac.update(raw(clone))
@ -102,7 +131,7 @@ index ae057ee1..55d0dd53 100644
computed_icv = mac.finalize()[:self.icv_size]
# XXX: Cannot use mac.verify because the ICV can be truncated
@@ -788,7 +790,7 @@ class SecurityAssociation(object):
@@ -788,7 +812,7 @@ class SecurityAssociation(object):
This class is responsible of "encryption" and "decryption" of IPsec packets. # noqa: E501
"""
@ -111,7 +140,7 @@ index ae057ee1..55d0dd53 100644
def __init__(self, proto, spi, seq_num=1, crypt_algo=None, crypt_key=None,
auth_algo=None, auth_key=None, tunnel_header=None, nat_t_header=None, esn_en=False, esn=0): # noqa: E501
@@ -862,6 +864,23 @@ class SecurityAssociation(object):
@@ -862,6 +886,23 @@ class SecurityAssociation(object):
raise TypeError('nat_t_header must be %s' % UDP.name)
self.nat_t_header = nat_t_header
@ -135,7 +164,7 @@ index ae057ee1..55d0dd53 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' %
@@ -875,7 +894,8 @@ class SecurityAssociation(object):
@@ -875,7 +916,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
@ -145,7 +174,7 @@ index ae057ee1..55d0dd53 100644
if self.tunnel_header:
tunnel = self.tunnel_header.copy()
@@ -899,7 +919,7 @@ class SecurityAssociation(object):
@@ -899,7 +941,7 @@ class SecurityAssociation(object):
esn_en=esn_en or self.esn_en,
esn=esn or self.esn)
@ -154,7 +183,7 @@ index ae057ee1..55d0dd53 100644
if self.nat_t_header:
nat_t_header = self.nat_t_header.copy()
@@ -926,7 +946,8 @@ class SecurityAssociation(object):
@@ -926,7 +968,8 @@ class SecurityAssociation(object):
def _encrypt_ah(self, pkt, seq_num=None):
@ -164,7 +193,7 @@ index ae057ee1..55d0dd53 100644
icv=b"\x00" * self.auth_algo.icv_size)
if self.tunnel_header:
@@ -966,7 +987,8 @@ class SecurityAssociation(object):
@@ -966,7 +1009,8 @@ class SecurityAssociation(object):
else:
ip_header.plen = len(ip_header.payload) + len(ah) + len(payload)
@ -174,7 +203,7 @@ index ae057ee1..55d0dd53 100644
# sequence number must always change, unless specified by the user
if seq_num is None:
@@ -1003,11 +1025,12 @@ class SecurityAssociation(object):
@@ -1003,11 +1047,12 @@ class SecurityAssociation(object):
def _decrypt_esp(self, pkt, verify=True, esn_en=None, esn=None):
@ -188,7 +217,7 @@ index ae057ee1..55d0dd53 100644
esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key,
self.crypt_algo.icv_size or
@@ -1048,9 +1071,10 @@ class SecurityAssociation(object):
@@ -1048,9 +1093,10 @@ class SecurityAssociation(object):
def _decrypt_ah(self, pkt, verify=True):

View File

@ -122,7 +122,7 @@ class IPsecIPv6Params:
def mk_scapy_crypt_key(p):
if p.crypt_algo in ("AES-GCM", "AES-CTR"):
if p.crypt_algo in ("AES-GCM", "AES-CTR", "AES-NULL-GMAC"):
return p.crypt_key + struct.pack("!I", p.salt)
else:
return p.crypt_key
@ -342,7 +342,7 @@ class IpsecTra4(object):
return count
def get_hash_failed_counts(self, p):
if ESP == self.encryption_type and p.crypt_algo == "AES-GCM":
if ESP == self.encryption_type and p.crypt_algo in ("AES-GCM", "AES-NULL-GMAC"):
hash_failed_node_name = (
"/err/%s/decryption_failed" % self.tra4_decrypt_node_name[p.async_mode]
)
@ -638,7 +638,7 @@ class IpsecTra4(object):
undersize_node_name = "/err/%s/runt" % self.tra4_decrypt_node_name[0]
undersize_count = self.statistics.get_err_counter(undersize_node_name)
# For AES-GCM an error in the hash is reported as a decryption failure
if p.crypt_algo == "AES-GCM":
if p.crypt_algo in ("AES-GCM", "AES-NULL-GMAC"):
hash_err = "decryption_failed"
# In async mode, we don't report errors in the hash.
if p.async_mode:

View File

@ -1033,6 +1033,42 @@ class MyParameters:
"salt": 2020,
"key": b"JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h",
},
"AES-NULL-GMAC-128/NONE": {
"vpp-crypto": (
VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_128
),
"vpp-integ": (
VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_NONE
),
"scapy-crypto": "AES-NULL-GMAC",
"scapy-integ": "NULL",
"key": b"JPjyOWBeVEQiMe7h",
"salt": 0,
},
"AES-NULL-GMAC-192/NONE": {
"vpp-crypto": (
VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_192
),
"vpp-integ": (
VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_NONE
),
"scapy-crypto": "AES-NULL-GMAC",
"scapy-integ": "NULL",
"key": b"JPjyOWBeVEQiMe7h01234567",
"salt": 1010,
},
"AES-NULL-GMAC-256/NONE": {
"vpp-crypto": (
VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_NULL_GMAC_256
),
"vpp-integ": (
VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_NONE
),
"scapy-crypto": "AES-NULL-GMAC",
"scapy-integ": "NULL",
"key": b"JPjyOWBeVEQiMe7h0123456787654321",
"salt": 2020,
},
}
@ -1182,7 +1218,8 @@ class RunTestIpsecEspAll(ConfigIpsecESP, IpsecTra4, IpsecTra6, IpsecTun4, IpsecT
# GEN AES-GCM-192/NONE AES-GCM-256/NONE AES-CBC-128/MD5-96 \
# GEN AES-CBC-192/SHA1-96 AES-CBC-256/SHA1-96 \
# GEN 3DES-CBC/SHA1-96 NONE/SHA1-96 \
# GEN AES-CTR-128/SHA1-96 AES-CTR-192/SHA1-96 AES-CTR-256/SHA1-96; do \
# GEN AES-CTR-128/SHA1-96 AES-CTR-192/SHA1-96 AES-CTR-256/SHA1-96 \
# GEN AES-NULL-GMAC-128/NONE AES-NULL-GMAC-192/NONE AES-NULL-GMAC-256/NONE; do \
# GEN echo -en "\n\nclass "
# GEN echo -e "Test_${ENG}_${ESN}_${AR}_${ALG}(RunTestIpsecEspAll):" |
# GEN sed -e 's/-/_/g' -e 's#/#_#g' ;
@ -1998,6 +2035,30 @@ class Test_openssl_ESNon_ARon_AES_CTR_256_SHA1_96(RunTestIpsecEspAll):
self.run_test()
class Test_openssl_ESNon_ARon_AES_NULL_GMAC_128_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARon AES-NULL-GMAC-128/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARon AES-NULL-GMAC-128/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNon_ARon_AES_NULL_GMAC_192_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARon AES-NULL-GMAC-192/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARon AES-NULL-GMAC-192/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNon_ARon_AES_NULL_GMAC_256_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARon AES-NULL-GMAC-256/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARon AES-NULL-GMAC-256/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNon_ARoff_AES_GCM_128_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARoff AES-GCM-128/NONE IPSec test"""
@ -2086,6 +2147,30 @@ class Test_openssl_ESNon_ARoff_AES_CTR_256_SHA1_96(RunTestIpsecEspAll):
self.run_test()
class Test_openssl_ESNon_ARoff_AES_NULL_GMAC_128_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARoff AES-NULL-GMAC-128/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARoff AES-NULL-GMAC-128/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNon_ARoff_AES_NULL_GMAC_192_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARoff AES-NULL-GMAC-192/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARoff AES-NULL-GMAC-192/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNon_ARoff_AES_NULL_GMAC_256_NONE(RunTestIpsecEspAll):
"""openssl ESNon ARoff AES-NULL-GMAC-256/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNon ARoff AES-NULL-GMAC-256/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARon_AES_GCM_128_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARon AES-GCM-128/NONE IPSec test"""
@ -2174,6 +2259,30 @@ class Test_openssl_ESNoff_ARon_AES_CTR_256_SHA1_96(RunTestIpsecEspAll):
self.run_test()
class Test_openssl_ESNoff_ARon_AES_NULL_GMAC_128_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARon AES-NULL-GMAC-128/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARon AES-NULL-GMAC-128/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARon_AES_NULL_GMAC_192_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARon AES-NULL-GMAC-192/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARon AES-NULL-GMAC-192/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARon_AES_NULL_GMAC_256_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARon AES-NULL-GMAC-256/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARon AES-NULL-GMAC-256/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARoff_AES_GCM_128_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARoff AES-GCM-128/NONE IPSec test"""
@ -2262,6 +2371,30 @@ class Test_openssl_ESNoff_ARoff_AES_CTR_256_SHA1_96(RunTestIpsecEspAll):
self.run_test()
class Test_openssl_ESNoff_ARoff_AES_NULL_GMAC_128_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARoff AES-NULL-GMAC-128/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARoff AES-NULL-GMAC-128/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARoff_AES_NULL_GMAC_192_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARoff AES-NULL-GMAC-192/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARoff AES-NULL-GMAC-192/NONE IPSec test"""
self.run_test()
class Test_openssl_ESNoff_ARoff_AES_NULL_GMAC_256_NONE(RunTestIpsecEspAll):
"""openssl ESNoff ARoff AES-NULL-GMAC-256/NONE IPSec test"""
def test_ipsec(self):
"""openssl ESNoff ARoff AES-NULL-GMAC-256/NONE IPSec test"""
self.run_test()
class Test_async_ESNon_ARon_AES_GCM_128_NONE(RunTestIpsecEspAll):
"""async ESNon ARon AES-GCM-128/NONE IPSec test"""