ipsec: keep crypto data inside SA 37/18437/2
authorDamjan Marion <damarion@cisco.com>
Wed, 20 Mar 2019 15:07:09 +0000 (16:07 +0100)
committerNeale Ranns <nranns@cisco.com>
Wed, 20 Mar 2019 17:23:04 +0000 (17:23 +0000)
Change-Id: Ie8986bd3652d25c4befe681cea77df95aba37ebc
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vnet/ipsec/ah_decrypt.c
src/vnet/ipsec/ah_encrypt.c
src/vnet/ipsec/esp.h
src/vnet/ipsec/esp_decrypt.c
src/vnet/ipsec/esp_encrypt.c
src/vnet/ipsec/ipsec_if.c
src/vnet/ipsec/ipsec_sa.c
src/vnet/ipsec/ipsec_sa.h

index 2488fa9..b128dfa 100644 (file)
@@ -172,7 +172,7 @@ ah_decrypt_inline (vlib_main_t * vm,
            (&ipsec_sa_counters, thread_index, sa_index0,
             1, i_b0->current_length);
 
-         icv_size = im->integ_algs[sa0->integ_alg].trunc_size;
+         icv_size = sa0->integ_trunc_size;
          if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
            {
              u8 sig[64];
@@ -203,9 +203,7 @@ ah_decrypt_inline (vlib_main_t * vm,
                  icv_padding_len =
                    ah_calc_icv_padding_len (icv_size, 0 /* is_ipv6 */ );
                }
-             hmac_calc (vm, sa0->integ_alg, sa0->integ_key.data,
-                        sa0->integ_key.len, (u8 *) ih4, i_b0->current_length,
-                        sig, sa0->use_esn, sa0->seq_hi);
+             hmac_calc (vm, sa0, (u8 *) ih4, i_b0->current_length, sig);
 
              if (PREDICT_FALSE (memcmp (digest, sig, icv_size)))
                {
index ce930bd..c6dbe57 100644 (file)
@@ -152,7 +152,7 @@ ah_encrypt_inline (vlib_main_t * vm,
              adv = -sizeof (ah_header_t);
            }
 
-         icv_size = im->integ_algs[sa0->integ_alg].trunc_size;
+         icv_size = sa0->integ_trunc_size;
          const u8 padding_len = ah_calc_icv_padding_len (icv_size, is_ip6);
          adv -= padding_len;
          /* transport mode save the eth header before it is overwritten */
@@ -265,11 +265,8 @@ ah_encrypt_inline (vlib_main_t * vm,
            sizeof (ah_header_t);
          clib_memset (digest, 0, icv_size);
 
-         unsigned size = hmac_calc (vm, sa0->integ_alg, sa0->integ_key.data,
-                                    sa0->integ_key.len,
-                                    vlib_buffer_get_current (i_b0),
-                                    i_b0->current_length, sig, sa0->use_esn,
-                                    sa0->seq_hi);
+         unsigned size = hmac_calc (vm, sa0, vlib_buffer_get_current (i_b0),
+                                    i_b0->current_length, sig);
 
          memcpy (digest, sig, size);
          if (is_ip6)
index 1730038..74ab1f0 100644 (file)
@@ -205,19 +205,17 @@ esp_seq_advance (ipsec_sa_t * sa)
 
 
 always_inline unsigned int
-hmac_calc (vlib_main_t * vm, ipsec_integ_alg_t alg, u8 * key, int key_len,
-          u8 * data, int data_len, u8 * signature, u8 use_esn, u32 seq_hi)
+hmac_calc (vlib_main_t * vm, ipsec_sa_t * sa, u8 * data, int data_len,
+          u8 * signature)
 {
-  ipsec_main_t *im = &ipsec_main;
   vnet_crypto_op_t _op, *op = &_op;
-  ASSERT (alg < IPSEC_INTEG_N_ALG);
 
-  if (PREDICT_FALSE (im->integ_algs[alg].op_type == 0))
+  if (PREDICT_FALSE (sa->integ_op_type == 0))
     return 0;
 
-  op->op = im->integ_algs[alg].op_type;
-  op->key = key;
-  op->key_len = key_len;
+  op->op = sa->integ_op_type;
+  op->key = sa->integ_key.data;
+  op->key_len = sa->integ_key.len;
   op->src = data;
   op->len = data_len;
   op->dst = signature;
@@ -233,7 +231,7 @@ hmac_calc (vlib_main_t * vm, ipsec_integ_alg_t alg, u8 * key, int key_len,
 
 #endif
   vnet_crypto_process_ops (vm, op, 1);
-  return im->integ_algs[alg].trunc_size;
+  return sa->integ_trunc_size;
 }
 
 #endif /* __ESP_H__ */
index 1ee7ce8..7860ca3 100644 (file)
@@ -82,21 +82,16 @@ format_esp_decrypt_trace (u8 * s, va_list * args)
 }
 
 always_inline void
-esp_decrypt_cbc (vlib_main_t * vm, ipsec_crypto_alg_t alg,
+esp_decrypt_cbc (vlib_main_t * vm, ipsec_sa_t * sa,
                 u8 * in, u8 * out, size_t in_len, u8 * key, u8 * iv)
 {
-  ipsec_main_t *im = &ipsec_main;
-  ipsec_main_crypto_alg_t *a;
   vnet_crypto_op_t _op, *op = &_op;
 
-  ASSERT (alg < IPSEC_CRYPTO_N_ALG);
-
-  a = &im->crypto_algs[alg];
 
-  if (PREDICT_FALSE (a->dec_op_type == VNET_CRYPTO_OP_NONE))
+  if (PREDICT_FALSE (sa->crypto_dec_op_type == VNET_CRYPTO_OP_NONE))
     return;
 
-  op->op = a->dec_op_type;
+  op->op = sa->crypto_dec_op_type;
   op->iv = iv;
   op->src = in;
   op->dst = out;
@@ -181,15 +176,13 @@ esp_decrypt_inline (vlib_main_t * vm,
       if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
        {
          u8 sig[64];
-         int icv_size = im->integ_algs[sa0->integ_alg].trunc_size;
+         int icv_size = sa0->integ_trunc_size;
          clib_memset (sig, 0, sizeof (sig));
          u8 *icv = vlib_buffer_get_current (ib[0]) + ib[0]->current_length -
            icv_size;
          ib[0]->current_length -= icv_size;
 
-         hmac_calc (vm, sa0->integ_alg, sa0->integ_key.data,
-                    sa0->integ_key.len, (u8 *) esp0,
-                    ib[0]->current_length, sig, sa0->use_esn, sa0->seq_hi);
+         hmac_calc (vm, sa0, (u8 *) esp0, ib[0]->current_length, sig);
 
          if (PREDICT_FALSE (memcmp (icv, sig, icv_size)))
            {
@@ -217,8 +210,8 @@ esp_decrypt_inline (vlib_main_t * vm,
          (sa0->crypto_alg >= IPSEC_CRYPTO_ALG_DES_CBC &&
           sa0->crypto_alg <= IPSEC_CRYPTO_ALG_3DES_CBC))
        {
-         const int BLOCK_SIZE = im->crypto_algs[sa0->crypto_alg].block_size;
-         const int IV_SIZE = im->crypto_algs[sa0->crypto_alg].iv_size;
+         const int BLOCK_SIZE = sa0->crypto_block_size;
+         const int IV_SIZE = sa0->crypto_block_size;
          esp_footer_t *f0;
          u8 ip_hdr_size = 0;
 
@@ -251,8 +244,7 @@ esp_decrypt_inline (vlib_main_t * vm,
                }
            }
 
-         esp_decrypt_cbc (vm, sa0->crypto_alg,
-                          esp0->data + IV_SIZE,
+         esp_decrypt_cbc (vm, sa0, esp0->data + IV_SIZE,
                           (u8 *) vlib_buffer_get_current (ob[0]) +
                           ip_hdr_size, BLOCK_SIZE * blocks,
                           sa0->crypto_key.data, esp0->data);
index 37c2c95..1e29ee3 100644 (file)
@@ -87,21 +87,16 @@ format_esp_encrypt_trace (u8 * s, va_list * args)
 }
 
 always_inline void
-esp_encrypt_cbc (vlib_main_t * vm, ipsec_crypto_alg_t alg,
+esp_encrypt_cbc (vlib_main_t * vm, ipsec_sa_t * sa,
                 u8 * in, u8 * out, size_t in_len, u8 * key, u8 * iv)
 {
-  ipsec_main_t *im = &ipsec_main;
-  ipsec_main_crypto_alg_t *a;
   vnet_crypto_op_t _op, *op = &_op;
 
-  ASSERT (alg < IPSEC_CRYPTO_N_ALG);
-
-  a = &im->crypto_algs[alg];
 
-  if (PREDICT_FALSE (a->enc_op_type == VNET_CRYPTO_OP_NONE))
+  if (PREDICT_FALSE (sa->crypto_enc_op_type == VNET_CRYPTO_OP_NONE))
     return;
 
-  op->op = a->enc_op_type;
+  op->op = sa->crypto_enc_op_type;
   op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV;
   op->iv = iv;
   op->src = in;
@@ -282,8 +277,8 @@ esp_encrypt_inline (vlib_main_t * vm,
       if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE))
        {
 
-         const int BLOCK_SIZE = im->crypto_algs[sa0->crypto_alg].block_size;
-         const int IV_SIZE = im->crypto_algs[sa0->crypto_alg].iv_size;
+         const int BLOCK_SIZE = sa0->crypto_block_size;
+         const int IV_SIZE = sa0->crypto_iv_size;
          int blocks = 1 + (ib[0]->current_length + 1) / BLOCK_SIZE;
 
          /* pad packet in input buffer */
@@ -311,10 +306,9 @@ esp_encrypt_inline (vlib_main_t * vm,
 
          clib_memcpy_fast ((u8 *) vlib_buffer_get_current (ob[0]) +
                            ip_udp_hdr_size + sizeof (esp_header_t), iv,
-                           im->crypto_algs[sa0->crypto_alg].iv_size);
+                           IV_SIZE);
 
-         esp_encrypt_cbc (vm, sa0->crypto_alg,
-                          (u8 *) vlib_buffer_get_current (ib[0]),
+         esp_encrypt_cbc (vm, sa0, (u8 *) vlib_buffer_get_current (ib[0]),
                           (u8 *) vlib_buffer_get_current (ob[0]) +
                           ip_udp_hdr_size + sizeof (esp_header_t) +
                           IV_SIZE, BLOCK_SIZE * blocks,
@@ -322,11 +316,9 @@ esp_encrypt_inline (vlib_main_t * vm,
        }
 
       ob[0]->current_length +=
-       hmac_calc (vm, sa0->integ_alg, sa0->integ_key.data,
-                  sa0->integ_key.len, (u8 *) o_esp0,
+       hmac_calc (vm, sa0, (u8 *) o_esp0,
                   ob[0]->current_length - ip_udp_hdr_size,
-                  vlib_buffer_get_current (ob[0]) + ob[0]->current_length,
-                  sa0->use_esn, sa0->seq_hi);
+                  vlib_buffer_get_current (ob[0]) + ob[0]->current_length);
 
 
       if (is_ip6)
index f40e94d..33cac4c 100644 (file)
@@ -493,25 +493,25 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index,
   if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO)
     {
       sa = pool_elt_at_index (im->sad, t->output_sa_index);
-      sa->crypto_alg = alg;
+      ipsec_sa_set_crypto_alg (sa, alg);
       ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
     }
   else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG)
     {
       sa = pool_elt_at_index (im->sad, t->output_sa_index);
-      sa->integ_alg = alg;
+      ipsec_sa_set_integ_alg (sa, alg);
       ipsec_mk_key (&sa->integ_key, key, vec_len (key));
     }
   else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO)
     {
       sa = pool_elt_at_index (im->sad, t->input_sa_index);
-      sa->crypto_alg = alg;
+      ipsec_sa_set_crypto_alg (sa, alg);
       ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
     }
   else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG)
     {
       sa = pool_elt_at_index (im->sad, t->input_sa_index);
-      sa->integ_alg = alg;
+      ipsec_sa_set_integ_alg (sa, alg);
       ipsec_mk_key (&sa->integ_key, key, vec_len (key));
     }
   else
index fc8520d..337ca34 100644 (file)
@@ -88,6 +88,26 @@ ipsec_sa_stack (ipsec_sa_t * sa)
   dpo_reset (&tmp);
 }
 
+void
+ipsec_sa_set_crypto_alg (ipsec_sa_t * sa, ipsec_crypto_alg_t crypto_alg)
+{
+  ipsec_main_t *im = &ipsec_main;
+  sa->crypto_alg = crypto_alg;
+  sa->crypto_iv_size = im->crypto_algs[crypto_alg].iv_size;
+  sa->crypto_block_size = im->crypto_algs[crypto_alg].block_size;
+  sa->crypto_enc_op_type = im->crypto_algs[crypto_alg].enc_op_type;
+  sa->crypto_dec_op_type = im->crypto_algs[crypto_alg].dec_op_type;
+}
+
+void
+ipsec_sa_set_integ_alg (ipsec_sa_t * sa, ipsec_integ_alg_t integ_alg)
+{
+  ipsec_main_t *im = &ipsec_main;
+  sa->integ_alg = integ_alg;
+  sa->integ_trunc_size = im->integ_algs[integ_alg].trunc_size;
+  sa->integ_op_type = im->integ_algs[integ_alg].op_type;
+}
+
 int
 ipsec_sa_add (u32 id,
              u32 spi,
@@ -123,9 +143,9 @@ ipsec_sa_add (u32 id,
   sa->spi = spi;
   sa->stat_index = sa_index;
   sa->protocol = proto;
-  sa->crypto_alg = crypto_alg;
+  ipsec_sa_set_crypto_alg (sa, crypto_alg);
   clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
-  sa->integ_alg = integ_alg;
+  ipsec_sa_set_integ_alg (sa, integ_alg);
   clib_memcpy (&sa->integ_key, ik, sizeof (sa->integ_key));
   ip46_address_copy (&sa->tunnel_src_addr, tun_src);
   ip46_address_copy (&sa->tunnel_dst_addr, tun_dst);
index 2601f51..a6ade60 100644 (file)
@@ -106,9 +106,15 @@ typedef struct
 
   ipsec_crypto_alg_t crypto_alg;
   ipsec_key_t crypto_key;
+  u8 crypto_iv_size;
+  u8 crypto_block_size;
+  vnet_crypto_op_type_t crypto_enc_op_type;
+  vnet_crypto_op_type_t crypto_dec_op_type;
 
   ipsec_integ_alg_t integ_alg;
   ipsec_key_t integ_key;
+  vnet_crypto_op_type_t integ_op_type;
+  u8 integ_trunc_size;
 
   u8 use_esn;
   u8 use_anti_replay;
@@ -156,6 +162,10 @@ extern int ipsec_sa_add (u32 id,
                         u32 * sa_index);
 extern u32 ipsec_sa_del (u32 id);
 extern void ipsec_sa_stack (ipsec_sa_t * sa);
+extern void ipsec_sa_set_crypto_alg (ipsec_sa_t * sa,
+                                    ipsec_crypto_alg_t crypto_alg);
+extern void ipsec_sa_set_integ_alg (ipsec_sa_t * sa,
+                                   ipsec_integ_alg_t integ_alg);
 
 extern u8 ipsec_is_sa_used (u32 sa_index);
 extern int ipsec_set_sa_key (u32 id,