|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
18 #include <openssl/evp.h>
19 #include <openssl/hmac.h>
20 #include <openssl/rand.h>
21 #include <openssl/sha.h>
26 #include <vpp/app/version.h>
34 #if OPENSSL_VERSION_NUMBER < 0x10100000L
41 #define foreach_openssl_aes_evp_op \
42 _ (cbc, DES_CBC, EVP_des_cbc, 8) \
43 _ (cbc, 3DES_CBC, EVP_des_ede3_cbc, 8) \
44 _ (cbc, AES_128_CBC, EVP_aes_128_cbc, 16) \
45 _ (cbc, AES_192_CBC, EVP_aes_192_cbc, 16) \
46 _ (cbc, AES_256_CBC, EVP_aes_256_cbc, 16) \
47 _ (gcm, AES_128_GCM, EVP_aes_128_gcm, 8) \
48 _ (gcm, AES_192_GCM, EVP_aes_192_gcm, 8) \
49 _ (gcm, AES_256_GCM, EVP_aes_256_gcm, 8) \
50 _ (cbc, AES_128_CTR, EVP_aes_128_ctr, 8) \
51 _ (cbc, AES_192_CTR, EVP_aes_192_ctr, 8) \
52 _ (cbc, AES_256_CTR, EVP_aes_256_ctr, 8)
54 #define foreach_openssl_chacha20_evp_op \
55 _ (chacha20_poly1305, CHACHA20_POLY1305, EVP_chacha20_poly1305, 8)
57 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
58 #define foreach_openssl_evp_op foreach_openssl_aes_evp_op \
59 foreach_openssl_chacha20_evp_op
61 #define foreach_openssl_evp_op foreach_openssl_aes_evp_op
64 #ifndef EVP_CTRL_AEAD_GET_TAG
65 #define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
68 #ifndef EVP_CTRL_AEAD_SET_TAG
69 #define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
72 #define foreach_openssl_hash_op \
74 _ (SHA224, EVP_sha224) \
75 _ (SHA256, EVP_sha256) \
76 _ (SHA384, EVP_sha384) \
77 _ (SHA512, EVP_sha512)
79 #define foreach_openssl_hmac_op \
82 _(SHA224, EVP_sha224) \
83 _(SHA256, EVP_sha256) \
84 _(SHA384, EVP_sha384) \
90 const EVP_CIPHER *cipher,
const int iv_len)
96 u32 i, j, curr_len = 0;
99 for (
i = 0;
i < n_ops;
i++)
106 RAND_bytes (op->
iv, iv_len);
108 EVP_EncryptInit_ex (
ctx, cipher, NULL,
key->data, op->
iv);
111 EVP_CIPHER_CTX_set_padding (
ctx, 0);
119 EVP_EncryptUpdate (
ctx, out_buf +
offset, &out_len, chp->
src,
125 if (out_len < curr_len)
126 EVP_EncryptFinal_ex (
ctx, out_buf +
offset, &out_len);
139 EVP_EncryptUpdate (
ctx, op->
dst, &out_len, op->
src, op->
len);
140 if (out_len < op->
len)
141 EVP_EncryptFinal_ex (
ctx, op->
dst + out_len, &out_len);
143 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
151 const EVP_CIPHER *cipher,
const int iv_len)
157 u32 i, j, curr_len = 0;
160 for (
i = 0;
i < n_ops;
i++)
166 EVP_DecryptInit_ex (
ctx, cipher, NULL,
key->data, op->
iv);
169 EVP_CIPHER_CTX_set_padding (
ctx, 0);
177 EVP_DecryptUpdate (
ctx, out_buf +
offset, &out_len, chp->
src,
183 if (out_len < curr_len)
184 EVP_DecryptFinal_ex (
ctx, out_buf +
offset, &out_len);
197 EVP_DecryptUpdate (
ctx, op->
dst, &out_len, op->
src, op->
len);
198 if (out_len < op->
len)
199 EVP_DecryptFinal_ex (
ctx, op->
dst + out_len, &out_len);
201 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
209 const EVP_CIPHER *cipher,
int is_gcm,
const int iv_len)
216 for (
i = 0;
i < n_ops;
i++)
223 RAND_bytes (op->
iv, 8);
225 EVP_EncryptInit_ex (
ctx, cipher, 0, 0, 0);
227 EVP_CIPHER_CTX_ctrl (
ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
228 EVP_EncryptInit_ex (
ctx, 0, 0,
key->data, op->
iv);
243 EVP_CIPHER_CTX_ctrl (
ctx, EVP_CTRL_AEAD_GET_TAG, op->
tag_len, op->
tag);
244 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
252 const EVP_CIPHER *cipher,
const int iv_len)
261 const EVP_CIPHER *cipher,
const int iv_len)
270 const EVP_CIPHER *cipher,
int is_gcm,
const int iv_len)
276 u32 i, j, n_fail = 0;
277 for (
i = 0;
i < n_ops;
i++)
283 EVP_DecryptInit_ex (
ctx, cipher, 0, 0, 0);
285 EVP_CIPHER_CTX_ctrl (
ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0);
286 EVP_DecryptInit_ex (
ctx, 0, 0,
key->data, op->
iv);
300 EVP_CIPHER_CTX_ctrl (
ctx, EVP_CTRL_AEAD_SET_TAG, op->
tag_len, op->
tag);
303 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
307 op->
status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
310 return n_ops - n_fail;
316 const EVP_CIPHER *cipher,
const int iv_len)
325 const EVP_CIPHER *cipher,
const int iv_len)
339 u32 md_len,
i, j, n_fail = 0;
341 for (
i = 0;
i < n_ops;
i++)
345 EVP_DigestInit_ex (
ctx, md, NULL);
351 EVP_DigestUpdate (
ctx, chp->
src, chp->
len);
356 EVP_DigestUpdate (
ctx, op->
src, op->
len);
358 EVP_DigestFinal_ex (
ctx, op->
digest, &md_len);
360 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
362 return n_ops - n_fail;
375 u32 i, j, n_fail = 0;
376 for (
i = 0;
i < n_ops;
i++)
380 unsigned int out_len = 0;
402 op->
status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
408 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
410 return n_ops - n_fail;
413 #define _(m, a, b, iv) \
414 static u32 openssl_ops_enc_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
417 return openssl_ops_enc_##m (vm, ops, 0, n_ops, b (), iv); \
420 u32 openssl_ops_dec_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
423 return openssl_ops_dec_##m (vm, ops, 0, n_ops, b (), iv); \
426 static u32 openssl_ops_enc_chained_##a ( \
427 vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
430 return openssl_ops_enc_##m (vm, ops, chunks, n_ops, b (), iv); \
433 static u32 openssl_ops_dec_chained_##a ( \
434 vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
437 return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b (), iv); \
444 static u32 openssl_ops_hash_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
447 return openssl_ops_hash (vm, ops, 0, n_ops, b ()); \
449 static u32 openssl_ops_hash_chained_##a ( \
450 vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
453 return openssl_ops_hash (vm, ops, chunks, n_ops, b ()); \
461 openssl_ops_hmac_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
462 { return openssl_ops_hmac (vm, ops, 0, n_ops, b ()); } \
464 openssl_ops_hmac_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \
465 vnet_crypto_op_chunk_t *chunks, u32 n_ops) \
466 { return openssl_ops_hmac (vm, ops, chunks, n_ops, b ()); } \
483 #define _(m, a, b, iv) \
484 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \
485 openssl_ops_enc_##a, \
486 openssl_ops_enc_chained_##a); \
487 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \
488 openssl_ops_dec_##a, \
489 openssl_ops_dec_chained_##a);
495 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \
496 openssl_ops_hmac_##a, \
497 openssl_ops_hmac_chained_##a); \
503 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HASH, \
504 openssl_ops_hash_##a, \
505 openssl_ops_hash_chained_##a);
516 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
518 ptd->
hash_ctx = EVP_MD_CTX_create ();
520 HMAC_CTX_init (&(ptd->_hmac_ctx));
527 vec_add (seed_data, &t,
sizeof (t));
529 vec_add (seed_data, seed_data,
sizeof (seed_data));
531 RAND_seed ((
const void *) seed_data,
vec_len (seed_data));
541 .runs_after =
VLIB_INITS (
"vnet_crypto_init"),
548 .version = VPP_BUILD_VER,
549 .description =
"OpenSSL Crypto Engine",
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
static_always_inline u32 openssl_ops_enc_aead(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, int is_gcm, const int iv_len)
#define foreach_openssl_evp_op
#define foreach_openssl_hash_op
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
vnet_crypto_op_status_t status
static_always_inline u32 openssl_ops_hash(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_MD *md)
static_always_inline u32 openssl_ops_enc_gcm(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
#define foreach_openssl_hmac_op
clib_error_t * crypto_openssl_init(vlib_main_t *vm)
#define VNET_CRYPTO_OP_FLAG_INIT_IV
#define VLIB_BUFFER_DEFAULT_DATA_SIZE
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
u32 vnet_crypto_register_engine(vlib_main_t *vm, char *name, int prio, char *desc)
static_always_inline u32 openssl_ops_hmac(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_MD *md)
#define VNET_CRYPTO_OP_FLAG_HMAC_CHECK
static_always_inline u32 openssl_ops_enc_cbc(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
EVP_CIPHER_CTX * evp_cipher_ctx
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
#define VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS
#define static_always_inline
static_always_inline __clib_unused u32 openssl_ops_dec_chacha20_poly1305(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)
static_always_inline u32 openssl_ops_dec_gcm(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)
sll srl srl sll sra u16x4 i
static_always_inline vnet_crypto_key_t * vnet_crypto_get_key(vnet_crypto_key_index_t index)
#define CLIB_CACHE_LINE_BYTES
static_always_inline u32 openssl_ops_dec_aead(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, int is_gcm, const int iv_len)
#define vec_free(V)
Free vector's memory (no header).
template key/value backing page structure
#define VLIB_INIT_FUNCTION(x)
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
static vlib_thread_main_t * vlib_get_thread_main()
static_always_inline u32 openssl_ops_dec_cbc(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)
static_always_inline __clib_unused u32 openssl_ops_enc_chacha20_poly1305(vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_CIPHER *cipher, const int iv_len)