From d97918ec678c4086001840e7263ba9ac3504ce24 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Thu, 25 Apr 2019 18:28:31 +0200 Subject: crypto, ipsec: change GCM IV handling - nonce construction out of salt and iv is ipsec specific so it should be handled in ipsec code - fixes GCM unit tests - GCM IV is constructed out of simple counter, per RFC4106 section 3.1 Change-Id: Ib7712cc9612830daa737f5171d8384f1d361bb61 Signed-off-by: Damjan Marion --- src/vnet/ipsec/esp_encrypt.c | 23 ++++++++++++++++++++--- src/vnet/ipsec/ipsec_sa.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'src/vnet/ipsec') diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index af56302bafb..3aafaffe3b5 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -225,6 +225,14 @@ esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node, } } +typedef struct +{ + u32 salt; + u64 iv; +} __clib_packed esp_gcm_nonce_t; + +STATIC_ASSERT_SIZEOF (esp_gcm_nonce_t, 12); + always_inline uword esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, int is_ip6, int is_tun) @@ -235,6 +243,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u32 n_left = frame->n_vectors; vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs; u16 nexts[VLIB_FRAME_SIZE], *next = nexts; + esp_gcm_nonce_t nonces[VLIB_FRAME_SIZE], *nonce = nonces; u32 thread_index = vm->thread_index; u16 buffer_data_size = vlib_buffer_get_default_data_size (vm); u32 current_sa_index = ~0, current_sa_packets = 0; @@ -439,13 +448,10 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_t *op; vec_add2_aligned (ptd->crypto_ops, op, 1, CLIB_CACHE_LINE_BYTES); vnet_crypto_op_init (op, sa0->crypto_enc_op_id); - op->iv = payload - iv_sz; op->src = op->dst = payload; op->key_index = sa0->crypto_key_index; op->len = payload_len - icv_sz; - op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV; op->user_data = b - bufs; - op->salt = sa0->salt; if (ipsec_sa_is_set_IS_AEAD (sa0)) { @@ -459,6 +465,17 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, op->tag = payload + op->len; op->tag_len = 16; + + u64 *iv = (u64 *) (payload - iv_sz); + nonce->salt = sa0->salt; + nonce->iv = *iv = clib_host_to_net_u64 (sa0->gcm_iv_counter++); + op->iv = (u8 *) nonce; + nonce++; + } + else + { + op->iv = payload - iv_sz; + op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV; } } diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index bde09589672..661b54a6ce9 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -167,6 +167,7 @@ typedef struct /* Salt used in GCM modes - stored in network byte order */ u32 salt; + u64 gcm_iv_counter; } ipsec_sa_t; STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline1, CLIB_CACHE_LINE_BYTES); -- cgit 1.2.3-korg