21 #include <x86intrin.h> 29 __m128i r0, r1, r2, r3, c0, c1, c2, c3, f;
32 f = _mm_loadu_si128 ((__m128i *) iv);
36 _mm_prefetch (src + 128, _MM_HINT_T0);
37 _mm_prefetch (dst + 128, _MM_HINT_T0);
39 c0 = _mm_loadu_si128 (((__m128i *) src + 0));
40 c1 = _mm_loadu_si128 (((__m128i *) src + 1));
41 c2 = _mm_loadu_si128 (((__m128i *) src + 2));
42 c3 = _mm_loadu_si128 (((__m128i *) src + 3));
49 for (i = 1; i < rounds; i++)
51 r0 = _mm_aesdec_si128 (r0, k[i]);
52 r1 = _mm_aesdec_si128 (r1, k[i]);
53 r2 = _mm_aesdec_si128 (r2, k[i]);
54 r3 = _mm_aesdec_si128 (r3, k[i]);
57 r0 = _mm_aesdeclast_si128 (r0, k[i]);
58 r1 = _mm_aesdeclast_si128 (r1, k[i]);
59 r2 = _mm_aesdeclast_si128 (r2, k[i]);
60 r3 = _mm_aesdeclast_si128 (r3, k[i]);
62 _mm_storeu_si128 ((__m128i *) dst + 0, r0 ^ f);
63 _mm_storeu_si128 ((__m128i *) dst + 1, r1 ^ c0);
64 _mm_storeu_si128 ((__m128i *) dst + 2, r2 ^ c1);
65 _mm_storeu_si128 ((__m128i *) dst + 3, r3 ^ c2);
76 c0 = _mm_loadu_si128 (((__m128i *) src));
78 for (i = 1; i < rounds; i++)
79 r0 = _mm_aesdec_si128 (r0, k[i]);
80 r0 = _mm_aesdeclast_si128 (r0, k[i]);
81 _mm_storeu_si128 ((__m128i *) dst, r0 ^ f);
103 __m128i r[4] = { }, k[4][rounds + 1];
106 for (i = 0; i < 4; i++)
112 src[
i] = dst[
i] = dummy;
113 len[
i] =
sizeof (dummy);
121 _mm_storeu_si128 ((__m128i *) ops[0]->
iv, r[i]);
122 ptd->
cbc_iv[
i] = _mm_aesenc_si128 (r[i], r[i]);
125 r[
i] = _mm_loadu_si128 ((__m128i *) ops[0]->
iv);
126 src[
i] = ops[0]->
src;
127 dst[
i] = ops[0]->
dst;
128 len[
i] = ops[0]->
len;
130 if (key[i] != ops[0]->key)
133 key[
i] = ops[0]->
key;
135 ops[0]->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
145 for (i = 0; i <
count; i += 16)
147 r[0] ^= _mm_loadu_si128 ((__m128i *) (src[0] + i)) ^ k[0][0];
148 r[1] ^= _mm_loadu_si128 ((__m128i *) (src[1] + i)) ^ k[1][0];
149 r[2] ^= _mm_loadu_si128 ((__m128i *) (src[2] + i)) ^ k[2][0];
150 r[3] ^= _mm_loadu_si128 ((__m128i *) (src[3] + i)) ^ k[3][0];
152 for (j = 1; j < rounds; j++)
154 r[0] = _mm_aesenc_si128 (r[0], k[0][j]);
155 r[1] = _mm_aesenc_si128 (r[1], k[1][j]);
156 r[2] = _mm_aesenc_si128 (r[2], k[2][j]);
157 r[3] = _mm_aesenc_si128 (r[3], k[3][j]);
160 r[0] = _mm_aesenclast_si128 (r[0], k[0][j]);
161 r[1] = _mm_aesenclast_si128 (r[1], k[1][j]);
162 r[2] = _mm_aesenclast_si128 (r[2], k[2][j]);
163 r[3] = _mm_aesenclast_si128 (r[3], k[3][j]);
165 _mm_storeu_si128 ((__m128i *) (dst[0] + i), r[0]);
166 _mm_storeu_si128 ((__m128i *) (dst[1] + i), r[1]);
167 _mm_storeu_si128 ((__m128i *) (dst[2] + i), r[2]);
168 _mm_storeu_si128 ((__m128i *) (dst[3] + i), r[3]);
171 for (i = 0; i < 4; i++)
181 if (!u32x4_is_all_zero (len & dummy_mask))
195 __m128i k[rounds + 1];
206 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
211 if (last_key != op->
key)
219 #define foreach_aesni_cbc_handler_type _(128) _(192) _(256) 222 static u32 aesni_ops_dec_aes_cbc_##x \ 223 (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ 224 { return aesni_ops_dec_aes_cbc (vm, ops, n_ops, AESNI_KEY_##x); } \ 225 static u32 aesni_ops_enc_aes_cbc_##x \ 226 (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ 227 { return aesni_ops_enc_aes_cbc (vm, ops, n_ops, AESNI_KEY_##x); } \ 242 if ((fd = open (
"/dev/urandom", O_RDONLY)) < 0)
248 for (
int i = 0;
i < 4;
i++)
261 vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ 262 VNET_CRYPTO_OP_AES_##x##_CBC_ENC, \ 263 aesni_ops_enc_aes_cbc_##x); \ 264 vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ 265 VNET_CRYPTO_OP_AES_##x##_CBC_DEC, \ 266 aesni_ops_dec_aes_cbc_##x);
crypto_ia32_main_t crypto_ia32_main
static_always_inline u32 u32x4_min_scalar(u32x4 v)
#define AESNI_KEY_ROUNDS(x)
static_always_inline void aes_key_expand(__m128i *k, u8 *key, aesni_key_size_t ks)
#define static_always_inline
static_always_inline u32 aesni_ops_dec_aes_cbc(vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops, aesni_key_size_t ks)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return_unix(e, args...)
#define VNET_CRYPTO_OP_FLAG_INIT_IV
crypto_ia32_per_thread_data_t * per_thread_data
static_always_inline void aes_cbc_dec(__m128i *k, u8 *src, u8 *dst, u8 *iv, int count, aesni_key_size_t rounds)
static_always_inline u32 aesni_ops_enc_aes_cbc(vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops, aesni_key_size_t ks)
static_always_inline void aes_key_enc_to_dec(__m128i *k, aesni_key_size_t ks)
clib_error_t * crypto_ia32_aesni_cbc_init(vlib_main_t *vm)
vnet_crypto_op_status_t status
#define vec_foreach(var, vec)
Vector iterator.
#define foreach_aesni_cbc_handler_type