2 *------------------------------------------------------------------
3 * Copyright (c) 2019 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
18 #include <vlib/vlib.h>
19 #include <vnet/plugin/plugin.h>
20 #include <vnet/crypto/crypto.h>
21 #include <crypto_native/crypto_native.h>
22 #include <crypto_native/aes.h>
24 #if __GNUC__ > 4 && !__clang__ && CLIB_DEBUG == 0
25 #pragma GCC optimize ("O3")
30 u8x16 encrypt_key[15];
32 __m512i decrypt_key[15];
34 u8x16 decrypt_key[15];
38 #include <crypto_native/aes_cbc_aesni.h>
39 #include <crypto_native/aes_cbc_neon.h>
41 static_always_inline void *
42 aesni_cbc_key_exp (vnet_crypto_key_t * key, aes_key_size_t ks)
45 aes_cbc_key_data_t *kd;
46 kd = clib_mem_alloc_aligned (sizeof (*kd), CLIB_CACHE_LINE_BYTES);
47 aes_key_expand (e, key->data, ks);
48 aes_key_enc_to_dec (e, d, ks);
49 for (int i = 0; i < AES_KEY_ROUNDS (ks) + 1; i++)
52 kd->decrypt_key[i] = _mm512_broadcast_i64x2 ((__m128i) d[i]);
54 kd->decrypt_key[i] = d[i];
56 kd->encrypt_key[i] = e[i];
61 #define foreach_aesni_cbc_handler_type _(128) _(192) _(256)
64 static u32 aesni_ops_dec_aes_cbc_##x \
65 (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
66 { return aesni_ops_dec_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \
67 static u32 aesni_ops_enc_aes_cbc_##x \
68 (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
69 { return aesni_ops_enc_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \
70 static void * aesni_cbc_key_exp_##x (vnet_crypto_key_t *key) \
71 { return aesni_cbc_key_exp (key, AES_KEY_##x); }
73 foreach_aesni_cbc_handler_type;
80 crypto_native_aes_cbc_init_vaes (vlib_main_t * vm)
82 crypto_native_aes_cbc_init_avx512 (vlib_main_t * vm)
84 crypto_native_aes_cbc_init_neon (vlib_main_t * vm)
86 crypto_native_aes_cbc_init_avx2 (vlib_main_t * vm)
88 crypto_native_aes_cbc_init_sse42 (vlib_main_t * vm)
91 crypto_native_main_t *cm = &crypto_native_main;
92 crypto_native_per_thread_data_t *ptd;
93 clib_error_t *err = 0;
96 if ((fd = open ("/dev/urandom", O_RDONLY)) < 0)
97 return clib_error_return_unix (0, "failed to open '/dev/urandom'");
100 vec_foreach (ptd, cm->per_thread_data)
102 for (int i = 0; i < 4; i++)
104 if (read(fd, ptd->cbc_iv, sizeof (ptd->cbc_iv)) !=
105 sizeof (ptd->cbc_iv))
107 err = clib_error_return_unix (0, "'/dev/urandom' read failure");
115 vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \
116 VNET_CRYPTO_OP_AES_##x##_CBC_ENC, \
117 aesni_ops_enc_aes_cbc_##x); \
118 vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \
119 VNET_CRYPTO_OP_AES_##x##_CBC_DEC, \
120 aesni_ops_dec_aes_cbc_##x); \
121 cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_CBC] = aesni_cbc_key_exp_##x;
122 foreach_aesni_cbc_handler_type;
131 * fd.io coding-style-patch-verification: ON
134 * eval: (c-set-style "gnu")