From 5527a78ed96043d2c26e3271066c50b44dd7fc0b Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Tue, 18 Jan 2022 15:56:41 +0100 Subject: ipsec: make pre-shared keys harder to misuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using pre-shared keys is usually a bad idea, one should use eg. IKEv2 instead, but one does not always have the choice. For AES-CBC, the IV must be unpredictable (see NIST SP800-38a Appendix C) whereas for AES-CTR or AES-GCM, the IV should never be reused with the same key material (see NIST SP800-38a Appendix B and NIST SP800-38d section 8). If one uses pre-shared keys and VPP is restarted, the IV counter restarts at 0 and the same IVs are generated with the same pre-shared keys materials. To fix those issues we follow the recommendation from NIST SP800-38a and NIST SP800-38d: - we use a PRNG (not cryptographically secured) to generate IVs to avoid generating the same IV sequence between VPP restarts. The PRNG is chosen so that there is a low chance of generating the same sequence - for AES-CBC, the generated IV is encrypted as part of the message. This makes the (predictable) PRNG-generated IV unpredictable as it is encrypted with the secret key - for AES-CTR and GCM, we use the IV as-is as predictable IVs are fine Most of the changes in this patch are caused by the need to shoehorn an additional state of 2 u64 for the PRNG in the 1st cacheline of the SA object. Type: improvement Change-Id: I2af89c21ae4b2c4c33dd21aeffcfb79c13c9d84c Signed-off-by: Benoît Ganne --- src/vnet/ipsec/esp_decrypt.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/vnet/ipsec/esp_decrypt.c') diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c index 1bcc65ca972..827d168f98a 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -603,7 +603,7 @@ esp_decrypt_prepare_async_frame (vlib_main_t *vm, vlib_node_runtime_t *node, esp_decrypt_packet_data_t *async_pd = &(esp_post_data (b))->decrypt_data; esp_decrypt_packet_data2_t *async_pd2 = esp_post_data2 (b); u8 *tag = payload + len, *iv = payload + esp_sz, *aad = 0; - u32 key_index; + const u32 key_index = sa0->crypto_key_index; u32 crypto_len, integ_len = 0; i16 crypto_start_offset, integ_start_offset = 0; u8 flags = 0; @@ -611,7 +611,6 @@ esp_decrypt_prepare_async_frame (vlib_main_t *vm, vlib_node_runtime_t *node, if (!ipsec_sa_is_set_IS_AEAD (sa0)) { /* linked algs */ - key_index = sa0->linked_key_index; integ_start_offset = payload - b->data; integ_len = len; if (PREDICT_TRUE (sa0->integ_op_id != VNET_CRYPTO_OP_NONE)) @@ -664,8 +663,6 @@ esp_decrypt_prepare_async_frame (vlib_main_t *vm, vlib_node_runtime_t *node, else esp_insert_esn (vm, sa0, pd, pd2, &integ_len, &tag, &len, b, payload); } - else - key_index = sa0->crypto_key_index; out: /* crypto */ @@ -1103,7 +1100,7 @@ esp_decrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, is_async = im->async_mode | ipsec_sa_is_set_IS_ASYNC (sa0); } - if (PREDICT_FALSE (~0 == sa0->thread_index)) + if (PREDICT_FALSE ((u16) ~0 == sa0->thread_index)) { /* this is the first packet to use this SA, claim the SA * for this thread. this could happen simultaneously on -- cgit 1.2.3-korg