2626#include <vnet/plugin/plugin.h>
2727#include <vnet/crypto/crypto.h>
2828#include <vpp/app/version.h>
29+ #include <crypto_openssl/crypto_openssl.h>
2930
3031typedef struct
3132{
3233 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0 );
33- EVP_CIPHER_CTX * evp_cipher_ctx ;
34- HMAC_CTX * hmac_ctx ;
34+ EVP_CIPHER_CTX * * evp_cipher_enc_ctx ;
35+ EVP_CIPHER_CTX * * evp_cipher_dec_ctx ;
36+ HMAC_CTX * * hmac_ctx ;
3537 EVP_MD_CTX * hash_ctx ;
3638#if OPENSSL_VERSION_NUMBER < 0x10100000L
3739 HMAC_CTX _hmac_ctx ;
@@ -89,25 +91,27 @@ static openssl_per_thread_data_t *per_thread_data = 0;
8991 _(SHA384, EVP_sha384) \
9092 _(SHA512, EVP_sha512)
9193
94+ crypto_openssl_main_t crypto_openssl_main ;
95+
9296static_always_inline u32
9397openssl_ops_enc_cbc (vlib_main_t * vm , vnet_crypto_op_t * ops [],
9498 vnet_crypto_op_chunk_t * chunks , u32 n_ops ,
9599 const EVP_CIPHER * cipher , const int iv_len )
96100{
97101 openssl_per_thread_data_t * ptd = vec_elt_at_index (per_thread_data ,
98102 vm -> thread_index );
99- EVP_CIPHER_CTX * ctx = ptd -> evp_cipher_ctx ;
103+ EVP_CIPHER_CTX * ctx ;
100104 vnet_crypto_op_chunk_t * chp ;
101105 u32 i , j , curr_len = 0 ;
102106 u8 out_buf [VLIB_BUFFER_DEFAULT_DATA_SIZE * 5 ];
103107
104108 for (i = 0 ; i < n_ops ; i ++ )
105109 {
106110 vnet_crypto_op_t * op = ops [i ];
107- vnet_crypto_key_t * key = vnet_crypto_get_key (op -> key_index );
108111 int out_len = 0 ;
109112
110- EVP_EncryptInit_ex (ctx , cipher , NULL , key -> data , op -> iv );
113+ ctx = ptd -> evp_cipher_enc_ctx [op -> key_index ];
114+ EVP_EncryptInit_ex (ctx , NULL , NULL , NULL , op -> iv );
111115
112116 if (op -> flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS )
113117 {
@@ -151,18 +155,18 @@ openssl_ops_dec_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[],
151155{
152156 openssl_per_thread_data_t * ptd = vec_elt_at_index (per_thread_data ,
153157 vm -> thread_index );
154- EVP_CIPHER_CTX * ctx = ptd -> evp_cipher_ctx ;
158+ EVP_CIPHER_CTX * ctx ;
155159 vnet_crypto_op_chunk_t * chp ;
156160 u32 i , j , curr_len = 0 ;
157161 u8 out_buf [VLIB_BUFFER_DEFAULT_DATA_SIZE * 5 ];
158162
159163 for (i = 0 ; i < n_ops ; i ++ )
160164 {
161165 vnet_crypto_op_t * op = ops [i ];
162- vnet_crypto_key_t * key = vnet_crypto_get_key (op -> key_index );
163166 int out_len = 0 ;
164167
165- EVP_DecryptInit_ex (ctx , cipher , NULL , key -> data , op -> iv );
168+ ctx = ptd -> evp_cipher_dec_ctx [op -> key_index ];
169+ EVP_DecryptInit_ex (ctx , NULL , NULL , NULL , op -> iv );
166170
167171 if (op -> flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS )
168172 {
@@ -207,19 +211,16 @@ openssl_ops_enc_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
207211{
208212 openssl_per_thread_data_t * ptd = vec_elt_at_index (per_thread_data ,
209213 vm -> thread_index );
210- EVP_CIPHER_CTX * ctx = ptd -> evp_cipher_ctx ;
214+ EVP_CIPHER_CTX * ctx ;
211215 vnet_crypto_op_chunk_t * chp ;
212216 u32 i , j ;
213217 for (i = 0 ; i < n_ops ; i ++ )
214218 {
215219 vnet_crypto_op_t * op = ops [i ];
216- vnet_crypto_key_t * key = vnet_crypto_get_key (op -> key_index );
217220 int len = 0 ;
218221
219- EVP_EncryptInit_ex (ctx , cipher , 0 , 0 , 0 );
220- if (is_gcm )
221- EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , NULL );
222- EVP_EncryptInit_ex (ctx , 0 , 0 , key -> data , op -> iv );
222+ ctx = ptd -> evp_cipher_enc_ctx [op -> key_index ];
223+ EVP_EncryptInit_ex (ctx , 0 , 0 , NULL , op -> iv );
223224 if (op -> aad_len )
224225 EVP_EncryptUpdate (ctx , NULL , & len , op -> aad , op -> aad_len );
225226 if (op -> flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS )
@@ -276,19 +277,16 @@ openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
276277{
277278 openssl_per_thread_data_t * ptd = vec_elt_at_index (per_thread_data ,
278279 vm -> thread_index );
279- EVP_CIPHER_CTX * ctx = ptd -> evp_cipher_ctx ;
280+ EVP_CIPHER_CTX * ctx ;
280281 vnet_crypto_op_chunk_t * chp ;
281282 u32 i , j , n_fail = 0 ;
282283 for (i = 0 ; i < n_ops ; i ++ )
283284 {
284285 vnet_crypto_op_t * op = ops [i ];
285- vnet_crypto_key_t * key = vnet_crypto_get_key (op -> key_index );
286286 int len = 0 ;
287287
288- EVP_DecryptInit_ex (ctx , cipher , 0 , 0 , 0 );
289- if (is_gcm )
290- EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , 0 );
291- EVP_DecryptInit_ex (ctx , 0 , 0 , key -> data , op -> iv );
288+ ctx = ptd -> evp_cipher_dec_ctx [op -> key_index ];
289+ EVP_DecryptInit_ex (ctx , 0 , 0 , NULL , op -> iv );
292290 if (op -> aad_len )
293291 EVP_DecryptUpdate (ctx , 0 , & len , op -> aad , op -> aad_len );
294292 if (op -> flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS )
@@ -388,17 +386,17 @@ openssl_ops_hmac (vlib_main_t * vm, vnet_crypto_op_t * ops[],
388386 u8 buffer [64 ];
389387 openssl_per_thread_data_t * ptd = vec_elt_at_index (per_thread_data ,
390388 vm -> thread_index );
391- HMAC_CTX * ctx = ptd -> hmac_ctx ;
389+ HMAC_CTX * ctx ;
392390 vnet_crypto_op_chunk_t * chp ;
393391 u32 i , j , n_fail = 0 ;
394392 for (i = 0 ; i < n_ops ; i ++ )
395393 {
396394 vnet_crypto_op_t * op = ops [i ];
397- vnet_crypto_key_t * key = vnet_crypto_get_key (op -> key_index );
398395 unsigned int out_len = 0 ;
399396 size_t sz = op -> digest_len ? op -> digest_len : EVP_MD_size (md );
400397
401- HMAC_Init_ex (ctx , key -> data , vec_len (key -> data ), md , NULL );
398+ ctx = ptd -> hmac_ctx [op -> key_index ];
399+ HMAC_Init_ex (ctx , NULL , 0 , NULL , NULL );
402400 if (op -> flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS )
403401 {
404402 chp = chunks + op -> chunk_index ;
@@ -428,6 +426,131 @@ openssl_ops_hmac (vlib_main_t * vm, vnet_crypto_op_t * ops[],
428426 return n_ops - n_fail ;
429427}
430428
429+ static_always_inline void *
430+ openssl_ctx_cipher (vnet_crypto_key_t * key , vnet_crypto_key_op_t kop ,
431+ vnet_crypto_key_index_t idx , const EVP_CIPHER * cipher ,
432+ int is_gcm )
433+ {
434+ EVP_CIPHER_CTX * ctx ;
435+ openssl_per_thread_data_t * ptd ;
436+
437+ if (VNET_CRYPTO_KEY_OP_ADD == kop )
438+ {
439+ vec_foreach (ptd , per_thread_data )
440+ {
441+ vec_validate_aligned (ptd -> evp_cipher_enc_ctx , idx ,
442+ CLIB_CACHE_LINE_BYTES );
443+ vec_validate_aligned (ptd -> evp_cipher_dec_ctx , idx ,
444+ CLIB_CACHE_LINE_BYTES );
445+
446+ ctx = EVP_CIPHER_CTX_new ();
447+ EVP_CIPHER_CTX_set_padding (ctx , 0 );
448+ EVP_EncryptInit_ex (ctx , cipher , NULL , NULL , NULL );
449+ if (is_gcm )
450+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , NULL );
451+ EVP_EncryptInit_ex (ctx , 0 , 0 , key -> data , 0 );
452+ ptd -> evp_cipher_enc_ctx [idx ] = ctx ;
453+
454+ ctx = EVP_CIPHER_CTX_new ();
455+ EVP_CIPHER_CTX_set_padding (ctx , 0 );
456+ EVP_DecryptInit_ex (ctx , cipher , 0 , 0 , 0 );
457+ if (is_gcm )
458+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , 0 );
459+ EVP_DecryptInit_ex (ctx , 0 , 0 , key -> data , 0 );
460+ ptd -> evp_cipher_dec_ctx [idx ] = ctx ;
461+ }
462+ }
463+ else if (VNET_CRYPTO_KEY_OP_MODIFY == kop )
464+ {
465+ vec_foreach (ptd , per_thread_data )
466+ {
467+ ctx = ptd -> evp_cipher_enc_ctx [idx ];
468+ EVP_EncryptInit_ex (ctx , cipher , NULL , NULL , NULL );
469+ if (is_gcm )
470+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , NULL );
471+ EVP_EncryptInit_ex (ctx , 0 , 0 , key -> data , 0 );
472+
473+ ctx = ptd -> evp_cipher_dec_ctx [idx ];
474+ EVP_DecryptInit_ex (ctx , cipher , 0 , 0 , 0 );
475+ if (is_gcm )
476+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IVLEN , 12 , 0 );
477+ EVP_DecryptInit_ex (ctx , 0 , 0 , key -> data , 0 );
478+ }
479+ }
480+ else if (VNET_CRYPTO_KEY_OP_DEL == kop )
481+ {
482+ vec_foreach (ptd , per_thread_data )
483+ {
484+ ctx = ptd -> evp_cipher_enc_ctx [idx ];
485+ EVP_CIPHER_CTX_free (ctx );
486+ ptd -> evp_cipher_enc_ctx [idx ] = NULL ;
487+
488+ ctx = ptd -> evp_cipher_dec_ctx [idx ];
489+ EVP_CIPHER_CTX_free (ctx );
490+ ptd -> evp_cipher_dec_ctx [idx ] = NULL ;
491+ }
492+ }
493+ return NULL ;
494+ }
495+
496+ static_always_inline void *
497+ openssl_ctx_hmac (vnet_crypto_key_t * key , vnet_crypto_key_op_t kop ,
498+ vnet_crypto_key_index_t idx , const EVP_MD * md )
499+ {
500+ HMAC_CTX * ctx ;
501+ openssl_per_thread_data_t * ptd ;
502+ if (VNET_CRYPTO_KEY_OP_ADD == kop )
503+ {
504+ vec_foreach (ptd , per_thread_data )
505+ {
506+ vec_validate_aligned (ptd -> hmac_ctx , idx , CLIB_CACHE_LINE_BYTES );
507+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
508+ ctx = HMAC_CTX_new ();
509+ HMAC_Init_ex (ctx , key -> data , vec_len (key -> data ), md , NULL );
510+ ptd -> hmac_ctx [idx ] = ctx ;
511+ #else
512+ HMAC_CTX_init (& (ptd -> _hmac_ctx ));
513+ ptd -> hmac_ctx [idx ] = & ptd -> _hmac_ctx ;
514+ #endif
515+ }
516+ }
517+ else if (VNET_CRYPTO_KEY_OP_MODIFY == kop )
518+ {
519+ vec_foreach (ptd , per_thread_data )
520+ {
521+ ctx = ptd -> hmac_ctx [idx ];
522+ HMAC_Init_ex (ctx , key -> data , vec_len (key -> data ), md , NULL );
523+ }
524+ }
525+ else if (VNET_CRYPTO_KEY_OP_DEL == kop )
526+ {
527+ vec_foreach (ptd , per_thread_data )
528+ {
529+ ctx = ptd -> hmac_ctx [idx ];
530+ HMAC_CTX_free (ctx );
531+ ptd -> hmac_ctx [idx ] = NULL ;
532+ }
533+ }
534+ return NULL ;
535+ }
536+
537+ static void
538+ crypto_openssl_key_handler (vlib_main_t * vm , vnet_crypto_key_op_t kop ,
539+ vnet_crypto_key_index_t idx )
540+ {
541+ vnet_crypto_key_t * key = vnet_crypto_get_key (idx );
542+ crypto_openssl_main_t * cm = & crypto_openssl_main ;
543+
544+ /** TODO: add linked alg support **/
545+ if (key -> type == VNET_CRYPTO_KEY_TYPE_LINK )
546+ return ;
547+
548+ if (cm -> ctx_fn [key -> alg ] == 0 )
549+ return ;
550+
551+ cm -> ctx_fn [key -> alg ](key , kop , idx );
552+ }
553+
431554#define _ (m , a , b , iv ) \
432555 static u32 openssl_ops_enc_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
433556 u32 n_ops) \
@@ -453,6 +576,16 @@ openssl_ops_hmac (vlib_main_t * vm, vnet_crypto_op_t * ops[],
453576 u32 n_ops) \
454577 { \
455578 return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b (), iv); \
579+ } \
580+ static void *openssl_ctx_##a (vnet_crypto_key_t *key, \
581+ vnet_crypto_key_op_t kop, \
582+ vnet_crypto_key_index_t idx) \
583+ { \
584+ int is_gcm = ((VNET_CRYPTO_ALG_AES_128_GCM <= key->alg) && \
585+ (VNET_CRYPTO_ALG_AES_256_NULL_GMAC >= key->alg)) ? \
586+ 1 : \
587+ 0; \
588+ return openssl_ctx_cipher (key, kop, idx, b (), is_gcm); \
456589 }
457590
458591foreach_openssl_evp_op ;
@@ -474,22 +607,32 @@ foreach_openssl_evp_op;
474607foreach_openssl_hash_op ;
475608#undef _
476609
477- #define _ (a , b ) \
478- static u32 \
479- openssl_ops_hmac_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
480- { return openssl_ops_hmac (vm, ops, 0, n_ops, b ()); } \
481- static u32 \
482- openssl_ops_hmac_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \
483- vnet_crypto_op_chunk_t *chunks, u32 n_ops) \
484- { return openssl_ops_hmac (vm, ops, chunks, n_ops, b ()); } \
610+ #define _ (a , b ) \
611+ static u32 openssl_ops_hmac_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
612+ u32 n_ops) \
613+ { \
614+ return openssl_ops_hmac (vm, ops, 0, n_ops, b ()); \
615+ } \
616+ static u32 openssl_ops_hmac_chained_##a ( \
617+ vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
618+ u32 n_ops) \
619+ { \
620+ return openssl_ops_hmac (vm, ops, chunks, n_ops, b ()); \
621+ } \
622+ static void *openssl_ctx_hmac_##a (vnet_crypto_key_t *key, \
623+ vnet_crypto_key_op_t kop, \
624+ vnet_crypto_key_index_t idx) \
625+ { \
626+ return openssl_ctx_hmac (key, kop, idx, b ()); \
627+ }
485628
486629foreach_openssl_hmac_op ;
487630#undef _
488631
489-
490632clib_error_t *
491633crypto_openssl_init (vlib_main_t * vm )
492634{
635+ crypto_openssl_main_t * cm = & crypto_openssl_main ;
493636 vlib_thread_main_t * tm = vlib_get_thread_main ();
494637 openssl_per_thread_data_t * ptd ;
495638 u8 seed [32 ];
@@ -500,22 +643,25 @@ crypto_openssl_init (vlib_main_t * vm)
500643 RAND_seed (seed , sizeof (seed ));
501644
502645 u32 eidx = vnet_crypto_register_engine (vm , "openssl" , 50 , "OpenSSL" );
646+ cm -> crypto_engine_index = eidx ;
503647
504648#define _ (m , a , b , iv ) \
505649 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \
506650 openssl_ops_enc_##a, \
507651 openssl_ops_enc_chained_##a); \
508652 vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \
509653 openssl_ops_dec_##a, \
510- openssl_ops_dec_chained_##a);
654+ openssl_ops_dec_chained_##a); \
655+ cm->ctx_fn[VNET_CRYPTO_ALG_##a] = openssl_ctx_##a;
511656
512657 foreach_openssl_evp_op ;
513658#undef _
514659
515- #define _ (a , b ) \
516- vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \
517- openssl_ops_hmac_##a, \
518- openssl_ops_hmac_chained_##a); \
660+ #define _ (a , b ) \
661+ vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \
662+ openssl_ops_hmac_##a, \
663+ openssl_ops_hmac_chained_##a); \
664+ cm->ctx_fn[VNET_CRYPTO_ALG_HMAC_##a] = openssl_ctx_hmac_##a;
519665
520666 foreach_openssl_hmac_op ;
521667#undef _
@@ -533,17 +679,12 @@ crypto_openssl_init (vlib_main_t * vm)
533679
534680 vec_foreach (ptd , per_thread_data )
535681 {
536- ptd -> evp_cipher_ctx = EVP_CIPHER_CTX_new ();
537- EVP_CIPHER_CTX_set_padding (ptd -> evp_cipher_ctx , 0 );
538682#if OPENSSL_VERSION_NUMBER >= 0x10100000L
539- ptd -> hmac_ctx = HMAC_CTX_new ();
540683 ptd -> hash_ctx = EVP_MD_CTX_create ();
541- #else
542- HMAC_CTX_init (& (ptd -> _hmac_ctx ));
543- ptd -> hmac_ctx = & ptd -> _hmac_ctx ;
544684#endif
545685 }
546-
686+ vnet_crypto_register_key_handler (vm , cm -> crypto_engine_index ,
687+ crypto_openssl_key_handler );
547688 return 0 ;
548689}
549690
0 commit comments