diff options
author | Damjan Marion <damarion@cisco.com> | 2019-04-25 18:28:31 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-04-26 14:13:00 +0000 |
commit | d97918ec678c4086001840e7263ba9ac3504ce24 (patch) | |
tree | b490f0318dc8bae6b7d8f90f789c416414bf0b17 /src/vnet/ipsec | |
parent | aaed170828dfdb3d62295b76fd617f794dc76b3f (diff) |
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 <damarion@cisco.com>
Diffstat (limited to 'src/vnet/ipsec')
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 23 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.h | 1 |
2 files changed, 21 insertions, 3 deletions
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); |