crypto: improve key handling
[vpp.git] / src / plugins / crypto_ia32 / main.c
index 9b83f89..8dd596b 100644 (file)
 #include <vnet/plugin/plugin.h>
 #include <vnet/crypto/crypto.h>
 #include <crypto_ia32/crypto_ia32.h>
+#include <crypto_ia32/aesni.h>
 
 crypto_ia32_main_t crypto_ia32_main;
 
+static void
+crypto_ia32_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop,
+                        vnet_crypto_key_index_t idx)
+{
+  vnet_crypto_key_t *key = vnet_crypto_get_key (idx);
+  crypto_ia32_main_t *cm = &crypto_ia32_main;
+  aesni_key_data_t *kd;
+
+  switch (key->alg)
+    {
+    case VNET_CRYPTO_ALG_AES_128_CBC:
+    case VNET_CRYPTO_ALG_AES_192_CBC:
+    case VNET_CRYPTO_ALG_AES_256_CBC:
+      break;
+    default:
+      return;
+      break;
+    }
+
+  if (kop == VNET_CRYPTO_KEY_OP_DEL)
+    {
+      if (idx >= vec_len (cm->key_data))
+       return;
+
+      if (cm->key_data[idx] == 0)
+       return;
+
+      clib_memset_u8 (cm->key_data[idx], 0,
+                     clib_mem_size (cm->key_data[idx]));
+      clib_mem_free (cm->key_data[idx]);
+      cm->key_data[idx] = 0;
+      return;
+    }
+
+  vec_validate_aligned (cm->key_data, idx, CLIB_CACHE_LINE_BYTES);
+
+  if (kop == VNET_CRYPTO_KEY_OP_MODIFY && cm->key_data[idx])
+    {
+      clib_memset_u8 (cm->key_data[idx], 0,
+                     clib_mem_size (cm->key_data[idx]));
+      clib_mem_free (cm->key_data[idx]);
+    }
+
+  kd = cm->key_data[idx] = clib_mem_alloc_aligned (sizeof (aesni_key_data_t),
+                                                  CLIB_CACHE_LINE_BYTES);
+
+  /* ADD or MODIFY */
+  switch (key->alg)
+    {
+    case VNET_CRYPTO_ALG_AES_128_CBC:
+      aes_key_expand (kd->encrypt_key, key->data, AESNI_KEY_128);
+      aes_key_expand (kd->decrypt_key, key->data, AESNI_KEY_128);
+      aes_key_enc_to_dec (kd->decrypt_key, AESNI_KEY_128);
+      break;
+    case VNET_CRYPTO_ALG_AES_192_CBC:
+      aes_key_expand (kd->encrypt_key, key->data, AESNI_KEY_192);
+      aes_key_expand (kd->decrypt_key, key->data, AESNI_KEY_192);
+      aes_key_enc_to_dec (kd->decrypt_key, AESNI_KEY_192);
+      break;
+    case VNET_CRYPTO_ALG_AES_256_CBC:
+      aes_key_expand (kd->encrypt_key, key->data, AESNI_KEY_256);
+      aes_key_expand (kd->decrypt_key, key->data, AESNI_KEY_256);
+      aes_key_enc_to_dec (kd->decrypt_key, AESNI_KEY_256);
+      break;
+    default:
+      return;
+      break;
+    }
+}
+
 clib_error_t *
 crypto_ia32_init (vlib_main_t * vm)
 {
@@ -43,6 +114,10 @@ crypto_ia32_init (vlib_main_t * vm)
       (error = crypto_ia32_aesni_cbc_init (vm)))
     goto error;
 
+  vnet_crypto_register_key_handler (vm, cm->crypto_engine_index,
+                                   crypto_ia32_key_handler);
+
+
 error:
   if (error)
     vec_free (cm->per_thread_data);