From 84e665848675afdc8e76fcbfb2bd65bccd4f25a8 Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Fri, 10 Mar 2023 17:33:03 +0100 Subject: ipsec: add support for RFC-4543 ENCR_NULL_AUTH_AES_GMAC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Type: improvement Change-Id: I830f7a2ea3ac0aff5185698b9fa7a278c45116b0 Signed-off-by: Benoît Ganne --- src/vnet/ipsec/esp_decrypt.c | 12 ++++++++++++ src/vnet/ipsec/esp_encrypt.c | 12 ++++++++++++ src/vnet/ipsec/ipsec.c | 24 ++++++++++++++++++++++++ src/vnet/ipsec/ipsec_sa.c | 9 ++++++++- src/vnet/ipsec/ipsec_sa.h | 13 +++++++++++-- src/vnet/ipsec/ipsec_types.api | 3 +++ 6 files changed, 70 insertions(+), 3 deletions(-) (limited to 'src/vnet/ipsec') diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c index 43d292d27e8..2c1efa2f4be 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -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 { diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 86f9094cedc..a836453b58e 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -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 { diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c index 14fc697e2eb..f8c39c327ed 100644 --- a/src/vnet/ipsec/ipsec.c +++ b/src/vnet/ipsec/ipsec.c @@ -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; diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c index 80e61d09247..98160cde389 100644 --- a/src/vnet/ipsec/ipsec_sa.c +++ b/src/vnet/ipsec/ipsec_sa.c @@ -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; } diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index a9abfdb05e2..cd90ef5c441 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -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_ { diff --git a/src/vnet/ipsec/ipsec_types.api b/src/vnet/ipsec/ipsec_types.api index 3f894348bcb..9adcc6aa8eb 100644 --- a/src/vnet/ipsec/ipsec_types.api +++ b/src/vnet/ipsec/ipsec_types.api @@ -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], }; /* -- cgit 1.2.3-korg