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
committed by
Beno�t Ganne
parent
96600f9077
commit
84e6658486
@ -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
|
||||
|
@ -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
|
||||
|
3029
src/plugins/unittest/crypto/aes_gmac.c
Normal file
3029
src/plugins/unittest/crypto/aes_gmac.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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) \
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_
|
||||
{
|
||||
|
@ -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],
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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"""
|
||||
|
||||
|
Reference in New Issue
Block a user