18 #include <openssl/evp.h> 19 #include <openssl/hmac.h> 20 #include <openssl/rand.h> 25 #include <vpp/app/version.h> 32 #if OPENSSL_VERSION_NUMBER < 0x10100000L 39 #define foreach_openssl_evp_op \ 40 _(cbc, DES_CBC, EVP_des_cbc) \ 41 _(cbc, 3DES_CBC, EVP_des_ede3_cbc) \ 42 _(cbc, AES_128_CBC, EVP_aes_128_cbc) \ 43 _(cbc, AES_192_CBC, EVP_aes_192_cbc) \ 44 _(cbc, AES_256_CBC, EVP_aes_256_cbc) \ 45 _(gcm, AES_128_GCM, EVP_aes_128_gcm) \ 46 _(gcm, AES_192_GCM, EVP_aes_192_gcm) \ 47 _(gcm, AES_256_GCM, EVP_aes_256_gcm) \ 48 _(cbc, AES_128_CTR, EVP_aes_128_ctr) \ 49 _(cbc, AES_192_CTR, EVP_aes_192_ctr) \ 50 _(cbc, AES_256_CTR, EVP_aes_256_ctr) \ 52 #define foreach_openssl_hmac_op \ 55 _(SHA224, EVP_sha224) \ 56 _(SHA256, EVP_sha256) \ 57 _(SHA384, EVP_sha384) \ 63 const EVP_CIPHER * cipher)
69 u32 i, j, curr_len = 0;
72 for (i = 0; i < n_ops; i++)
79 if (op->
op == VNET_CRYPTO_OP_3DES_CBC_ENC
80 || op->
op == VNET_CRYPTO_OP_DES_CBC_ENC)
86 RAND_bytes (op->
iv, iv_len);
88 EVP_EncryptInit_ex (ctx, cipher, NULL, key->
data, op->
iv);
91 EVP_CIPHER_CTX_set_padding (ctx, 0);
99 EVP_EncryptUpdate (ctx, out_buf + offset, &out_len, chp->
src,
105 if (out_len < curr_len)
106 EVP_EncryptFinal_ex (ctx, out_buf + offset, &out_len);
119 EVP_EncryptUpdate (ctx, op->
dst, &out_len, op->
src, op->
len);
120 if (out_len < op->
len)
121 EVP_EncryptFinal_ex (ctx, op->
dst + out_len, &out_len);
123 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
131 const EVP_CIPHER * cipher)
137 u32 i, j, curr_len = 0;
140 for (i = 0; i < n_ops; i++)
146 EVP_DecryptInit_ex (ctx, cipher, NULL, key->
data, op->
iv);
149 EVP_CIPHER_CTX_set_padding (ctx, 0);
157 EVP_DecryptUpdate (ctx, out_buf + offset, &out_len, chp->
src,
163 if (out_len < curr_len)
164 EVP_DecryptFinal_ex (ctx, out_buf + offset, &out_len);
177 EVP_DecryptUpdate (ctx, op->
dst, &out_len, op->
src, op->
len);
178 if (out_len < op->
len)
179 EVP_DecryptFinal_ex (ctx, op->
dst + out_len, &out_len);
181 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
189 const EVP_CIPHER * cipher)
196 for (i = 0; i < n_ops; i++)
203 RAND_bytes (op->
iv, 8);
205 EVP_EncryptInit_ex (ctx, cipher, 0, 0, 0);
206 EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
207 EVP_EncryptInit_ex (ctx, 0, 0, key->
data, op->
iv);
209 EVP_EncryptUpdate (ctx, NULL, &len, op->
aad, op->
aad_len);
215 EVP_EncryptUpdate (ctx, chp->
dst, &len, chp->
src, chp->
len);
220 EVP_EncryptUpdate (ctx, op->
dst, &len, op->
src, op->
len);
221 EVP_EncryptFinal_ex (ctx, op->
dst + len, &len);
222 EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_GET_TAG, op->
tag_len, op->
tag);
223 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
231 const EVP_CIPHER * cipher)
237 u32 i, j, n_fail = 0;
238 for (i = 0; i < n_ops; i++)
244 EVP_DecryptInit_ex (ctx, cipher, 0, 0, 0);
245 EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0);
246 EVP_DecryptInit_ex (ctx, 0, 0, key->
data, op->
iv);
248 EVP_DecryptUpdate (ctx, 0, &len, op->
aad, op->
aad_len);
254 EVP_DecryptUpdate (ctx, chp->
dst, &len, chp->
src, chp->
len);
259 EVP_DecryptUpdate (ctx, op->
dst, &len, op->
src, op->
len);
260 EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_TAG, op->
tag_len, op->
tag);
262 if (EVP_DecryptFinal_ex (ctx, op->
dst + len, &len) > 0)
263 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
267 op->
status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
270 return n_ops - n_fail;
283 u32 i, j, n_fail = 0;
284 for (i = 0; i < n_ops; i++)
288 unsigned int out_len = 0;
297 HMAC_Update (ctx, chp->
src, chp->
len);
302 HMAC_Update (ctx, op->
src, op->
len);
303 HMAC_Final (ctx, buffer, &out_len);
307 if ((memcmp (op->
digest, buffer, sz)))
310 op->
status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
316 op->
status = VNET_CRYPTO_OP_STATUS_COMPLETED;
318 return n_ops - n_fail;
323 openssl_ops_enc_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ 324 { return openssl_ops_enc_##m (vm, ops, 0, n_ops, b ()); } \ 327 openssl_ops_dec_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ 328 { return openssl_ops_dec_##m (vm, ops, 0, n_ops, b ()); } \ 331 openssl_ops_enc_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \ 332 vnet_crypto_op_chunk_t *chunks, u32 n_ops) \ 333 { return openssl_ops_enc_##m (vm, ops, chunks, n_ops, b ()); } \ 336 openssl_ops_dec_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \ 337 vnet_crypto_op_chunk_t *chunks, u32 n_ops) \ 338 { return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b ()); } 345 openssl_ops_hmac_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ 346 { return openssl_ops_hmac (vm, ops, 0, n_ops, b ()); } \ 348 openssl_ops_hmac_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \ 349 vnet_crypto_op_chunk_t *chunks, u32 n_ops) \ 350 { return openssl_ops_hmac (vm, ops, chunks, n_ops, b ()); } \ 368 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \ 369 openssl_ops_enc_##a, \ 370 openssl_ops_enc_chained_##a); \ 371 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \ 372 openssl_ops_dec_##a, \ 373 openssl_ops_dec_chained_##a); \ 379 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \ 380 openssl_ops_hmac_##a, \ 381 openssl_ops_hmac_chained_##a); \ 392 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 395 HMAC_CTX_init (&(ptd->_hmac_ctx));
402 vec_add (seed_data, &t,
sizeof (t));
403 vec_add (seed_data, &pid,
sizeof (pid));
404 vec_add (seed_data, seed_data,
sizeof (seed_data));
406 RAND_seed ((
const void *) seed_data,
vec_len (seed_data));
416 .runs_after =
VLIB_INITS (
"vnet_crypto_init"),
423 .version = VPP_BUILD_VER,
424 .description =
"OpenSSL Crypto Engine",
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
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 clib_memcpy_fast(a, b, c)
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)
#define VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
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)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
#define static_always_inline
#define VLIB_INIT_FUNCTION(x)
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)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
clib_error_t * crypto_openssl_init(vlib_main_t *vm)
#define VNET_CRYPTO_OP_FLAG_HMAC_CHECK
EVP_CIPHER_CTX * evp_cipher_ctx
#define foreach_openssl_hmac_op
#define VNET_CRYPTO_OP_FLAG_INIT_IV
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
template key/value backing page structure
static_always_inline vnet_crypto_key_t * vnet_crypto_get_key(vnet_crypto_key_index_t index)
#define foreach_openssl_evp_op
#define VLIB_BUFFER_DEFAULT_DATA_SIZE
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vnet_crypto_op_status_t status
static vlib_thread_main_t * vlib_get_thread_main()
#define vec_foreach(var, vec)
Vector iterator.
#define CLIB_CACHE_LINE_BYTES
u32 vnet_crypto_register_engine(vlib_main_t *vm, char *name, int prio, char *desc)
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)