crypto: improve key handling

Change-Id: If96f661d507305da4b96cac7b1a8f14ba90676ad
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c
index 8f41c95..2d2e90a 100644
--- a/src/vnet/ipsec/ipsec_sa.c
+++ b/src/vnet/ipsec/ipsec_sa.c
@@ -100,6 +100,7 @@
   sa->crypto_block_size = im->crypto_algs[crypto_alg].block_size;
   sa->crypto_enc_op_id = im->crypto_algs[crypto_alg].enc_op_id;
   sa->crypto_dec_op_id = im->crypto_algs[crypto_alg].dec_op_id;
+  sa->crypto_calg = im->crypto_algs[crypto_alg].alg;
   ASSERT (sa->crypto_iv_size <= ESP_MAX_IV_SIZE);
   ASSERT (sa->crypto_block_size <= ESP_MAX_BLOCK_SIZE);
   if (IPSEC_CRYPTO_ALG_IS_GCM (crypto_alg))
@@ -116,6 +117,7 @@
   sa->integ_alg = integ_alg;
   sa->integ_icv_size = im->integ_algs[integ_alg].icv_size;
   sa->integ_op_id = im->integ_algs[integ_alg].op_id;
+  sa->integ_calg = im->integ_algs[integ_alg].alg;
   ASSERT (sa->integ_icv_size <= ESP_MAX_ICV_SIZE);
 }
 
@@ -133,6 +135,7 @@
 	      const ip46_address_t * tun_src,
 	      const ip46_address_t * tun_dst, u32 * sa_out_index)
 {
+  vlib_main_t *vm = vlib_get_main ();
   ipsec_main_t *im = &ipsec_main;
   clib_error_t *err;
   ipsec_sa_t *sa;
@@ -164,6 +167,13 @@
   ip46_address_copy (&sa->tunnel_src_addr, tun_src);
   ip46_address_copy (&sa->tunnel_dst_addr, tun_dst);
 
+  sa->crypto_key_index = vnet_crypto_key_add (vm,
+					      im->crypto_algs[crypto_alg].alg,
+					      (u8 *) ck->data, ck->len);
+  sa->integ_key_index = vnet_crypto_key_add (vm,
+					     im->integ_algs[integ_alg].alg,
+					     (u8 *) ik->data, ik->len);
+
   err = ipsec_check_support_cb (im, sa);
   if (err)
     {
@@ -253,6 +263,7 @@
 u32
 ipsec_sa_del (u32 id)
 {
+  vlib_main_t *vm = vlib_get_main ();
   ipsec_main_t *im = &ipsec_main;
   ipsec_sa_t *sa = 0;
   uword *p;
@@ -286,6 +297,8 @@
       dpo_reset (&sa->dpo[IPSEC_PROTOCOL_AH]);
       dpo_reset (&sa->dpo[IPSEC_PROTOCOL_ESP]);
     }
+  vnet_crypto_key_del (vm, sa->crypto_key_index);
+  vnet_crypto_key_del (vm, sa->integ_key_index);
   pool_put (im->sad, sa);
   return 0;
 }
@@ -320,6 +333,7 @@
 int
 ipsec_set_sa_key (u32 id, const ipsec_key_t * ck, const ipsec_key_t * ik)
 {
+  vlib_main_t *vm = vlib_get_main ();
   ipsec_main_t *im = &ipsec_main;
   uword *p;
   u32 sa_index;
@@ -337,12 +351,16 @@
   if (ck)
     {
       clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
+      vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg,
+			      (u8 *) ck->data, ck->len);
     }
 
   /* new integ key */
   if (ik)
     {
       clib_memcpy (&sa->integ_key, 0, sizeof (sa->integ_key));
+      vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg,
+			      (u8 *) ik->data, ik->len);
     }
 
   if (ck || ik)