IPSEC: support GCM in ESP
[vpp.git] / src / vnet / ipsec / ipsec.c
index 0ad11ba..73c5cf4 100644 (file)
 #include <vnet/udp/udp.h>
 
 #include <vnet/ipsec/ipsec.h>
-#include <vnet/ipsec/ikev2.h>
 #include <vnet/ipsec/esp.h>
 #include <vnet/ipsec/ah.h>
 
 ipsec_main_t ipsec_main;
 
-static void
-ipsec_rand_seed (void)
-{
-  struct
-  {
-    time_t time;
-    pid_t pid;
-    void *p;
-  } seed_data;
-
-  seed_data.time = time (NULL);
-  seed_data.pid = getpid ();
-  seed_data.p = (void *) &seed_data;
-
-  RAND_seed ((const void *) &seed_data, sizeof (seed_data));
-}
-
 static clib_error_t *
 ipsec_check_ah_support (ipsec_sa_t * sa)
 {
@@ -56,13 +38,6 @@ ipsec_check_ah_support (ipsec_sa_t * sa)
 static clib_error_t *
 ipsec_check_esp_support (ipsec_sa_t * sa)
 {
-  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
-    return clib_error_return (0, "unsupported aes-gcm-128 crypto-alg");
-  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_192)
-    return clib_error_return (0, "unsupported aes-gcm-192 crypto-alg");
-  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_256)
-    return clib_error_return (0, "unsupported aes-gcm-256 crypto-alg");
-
   return 0;
 }
 
@@ -137,7 +112,7 @@ ipsec_register_ah_backend (vlib_main_t * vm, ipsec_main_t * im,
 {
   ipsec_ah_backend_t *b;
   pool_get (im->ah_backends, b);
-  b->name = format (NULL, "%s", name);
+  b->name = format (0, "%s%c", name, 0);
 
   ipsec_add_node (vm, ah4_encrypt_node_name, "ipsec4-output-feature",
                  &b->ah4_encrypt_node_index, &b->ah4_encrypt_next_index);
@@ -165,7 +140,7 @@ ipsec_register_esp_backend (vlib_main_t * vm, ipsec_main_t * im,
 {
   ipsec_esp_backend_t *b;
   pool_get (im->esp_backends, b);
-  b->name = format (NULL, "%s", name);
+  b->name = format (0, "%s%c", name, 0);
 
   ipsec_add_node (vm, esp4_encrypt_node_name, "ipsec4-output-feature",
                  &b->esp4_encrypt_node_index, &b->esp4_encrypt_next_index);
@@ -240,11 +215,7 @@ ipsec_init (vlib_main_t * vm)
 {
   clib_error_t *error;
   ipsec_main_t *im = &ipsec_main;
-  vlib_thread_main_t *tm = vlib_get_thread_main ();
-
-  ipsec_rand_seed ();
-
-  clib_memset (im, 0, sizeof (im[0]));
+  ipsec_main_crypto_alg_t *a;
 
   im->vnet_main = vnet_get_main ();
   im->vlib_main = vm;
@@ -253,9 +224,6 @@ ipsec_init (vlib_main_t * vm)
   im->sa_index_by_sa_id = hash_create (0, sizeof (uword));
   im->spd_index_by_sw_if_index = hash_create (0, sizeof (uword));
 
-  vec_validate_aligned (im->empty_buffers, tm->n_vlib_mains - 1,
-                       CLIB_CACHE_LINE_BYTES);
-
   vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
   ASSERT (node);
   im->error_drop_node_index = node->index;
@@ -291,10 +259,75 @@ ipsec_init (vlib_main_t * vm)
   if ((error = vlib_call_init_function (vm, ipsec_tunnel_if_init)))
     return error;
 
-  ipsec_proto_init ();
-
-  if ((error = ikev2_init (vm)))
-    return error;
+  vec_validate (im->crypto_algs, IPSEC_CRYPTO_N_ALG - 1);
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_DES_CBC;
+  a->enc_op_id = VNET_CRYPTO_OP_DES_CBC_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_DES_CBC_DEC;
+  a->iv_size = a->block_size = 8;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_3DES_CBC;
+  a->enc_op_id = VNET_CRYPTO_OP_3DES_CBC_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_3DES_CBC_DEC;
+  a->iv_size = a->block_size = 8;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_128;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_128_CBC_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_128_CBC_DEC;
+  a->iv_size = a->block_size = 16;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_192;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_192_CBC_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_192_CBC_DEC;
+  a->iv_size = a->block_size = 16;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_256;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_256_CBC_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_256_CBC_DEC;
+  a->iv_size = a->block_size = 16;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_128;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_128_GCM_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
+  a->iv_size = a->block_size = 8;
+  a->icv_size = 16;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_192;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_192_GCM_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_192_GCM_DEC;
+  a->iv_size = a->block_size = 8;
+  a->icv_size = 16;
+
+  a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_256;
+  a->enc_op_id = VNET_CRYPTO_OP_AES_256_GCM_ENC;
+  a->dec_op_id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
+  a->iv_size = a->block_size = 8;
+  a->icv_size = 16;
+
+  vec_validate (im->integ_algs, IPSEC_INTEG_N_ALG - 1);
+  ipsec_main_integ_alg_t *i;
+
+  i = &im->integ_algs[IPSEC_INTEG_ALG_SHA1_96];
+  i->op_id = VNET_CRYPTO_OP_SHA1_HMAC;
+  i->icv_size = 12;
+
+  i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_256_96];
+  i->op_id = VNET_CRYPTO_OP_SHA1_HMAC;
+  i->icv_size = 12;
+
+  i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_256_128];
+  i->op_id = VNET_CRYPTO_OP_SHA256_HMAC;
+  i->icv_size = 16;
+
+  i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_384_192];
+  i->op_id = VNET_CRYPTO_OP_SHA384_HMAC;
+  i->icv_size = 24;
+
+  i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_512_256];
+  i->op_id = VNET_CRYPTO_OP_SHA512_HMAC;
+  i->icv_size = 32;
+
+  vec_validate_aligned (im->ptd, vlib_num_workers (), CLIB_CACHE_LINE_BYTES);
 
   return 0;
 }