diff options
author | Damjan Marion <dmarion@me.com> | 2024-12-16 09:06:42 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2024-12-18 12:34:55 +0000 |
commit | 0cf4eef73a4c1bd2831a4618af50939a2aab01c6 (patch) | |
tree | 809caae588fa1e12556cb180bc4b253120627134 /src | |
parent | 4358a18dea319b590da5b64e263439136bd8f806 (diff) |
crypto: move crypto engines outside of plugins
This is first step in process of making crypto engine binaries
less dependant on specific VPP version.
Type: improvement
Change-Id: Ib08135688be409049b660e2b2ac435578b63be65
Signed-off-by: Damjan Marion <dmarion@me.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/cmake/crypto_engines.cmake | 76 | ||||
-rw-r--r-- | src/crypto_engines/CMakeLists.txt | 30 | ||||
-rw-r--r-- | src/crypto_engines/ipsecmb/CMakeLists.txt (renamed from src/plugins/crypto_ipsecmb/CMakeLists.txt) | 4 | ||||
-rw-r--r-- | src/crypto_engines/ipsecmb/FEATURE.yaml (renamed from src/plugins/crypto_ipsecmb/FEATURE.yaml) | 0 | ||||
-rw-r--r-- | src/crypto_engines/ipsecmb/ipsecmb.c (renamed from src/plugins/crypto_ipsecmb/ipsecmb.c) | 186 | ||||
-rw-r--r-- | src/crypto_engines/native/CMakeLists.txt (renamed from src/plugins/crypto_native/CMakeLists.txt) | 6 | ||||
-rw-r--r-- | src/crypto_engines/native/FEATURE.yaml (renamed from src/plugins/crypto_native/FEATURE.yaml) | 0 | ||||
-rw-r--r-- | src/crypto_engines/native/aes_cbc.c (renamed from src/plugins/crypto_native/aes_cbc.c) | 2 | ||||
-rw-r--r-- | src/crypto_engines/native/aes_ctr.c (renamed from src/plugins/crypto_native/aes_ctr.c) | 2 | ||||
-rw-r--r-- | src/crypto_engines/native/aes_gcm.c (renamed from src/plugins/crypto_native/aes_gcm.c) | 2 | ||||
-rw-r--r-- | src/crypto_engines/native/crypto_native.h (renamed from src/plugins/crypto_native/crypto_native.h) | 1 | ||||
-rw-r--r-- | src/crypto_engines/native/main.c (renamed from src/plugins/crypto_native/main.c) | 59 | ||||
-rw-r--r-- | src/crypto_engines/native/sha2.c (renamed from src/plugins/crypto_native/sha2.c) | 2 | ||||
-rw-r--r-- | src/crypto_engines/openssl/CMakeLists.txt (renamed from src/plugins/crypto_openssl/CMakeLists.txt) | 2 | ||||
-rw-r--r-- | src/crypto_engines/openssl/FEATURE.yaml (renamed from src/plugins/crypto_openssl/FEATURE.yaml) | 0 | ||||
-rw-r--r-- | src/crypto_engines/openssl/crypto_openssl.h (renamed from src/plugins/crypto_openssl/crypto_openssl.h) | 1 | ||||
-rw-r--r-- | src/crypto_engines/openssl/main.c (renamed from src/plugins/crypto_openssl/main.c) | 234 | ||||
-rw-r--r-- | src/plugins/crypto_sw_scheduler/main.c | 2 | ||||
-rw-r--r-- | src/plugins/dpdk/cryptodev/cryptodev.c | 5 | ||||
-rw-r--r-- | src/plugins/quic/quic_crypto.c | 5 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.c | 136 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.h | 3 | ||||
-rw-r--r-- | src/vnet/crypto/engine.h | 41 |
24 files changed, 497 insertions, 305 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1fbb624b972..f6d07be0b79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -244,6 +244,7 @@ include(cmake/api.cmake) include(cmake/library.cmake) include(cmake/exec.cmake) include(cmake/plugin.cmake) +include(cmake/crypto_engines.cmake) ############################################################################## # FreeBSD - use epoll-shim @@ -278,7 +279,7 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD") find_package(OpenSSL) set(SUBDIRS vppinfra svm vlib vlibmemory vlibapi vnet vpp vat vat2 vcl vpp-api - plugins tools/vppapigen tools/g2 tools/perftool cmake pkg + plugins crypto_engines tools/vppapigen tools/g2 tools/perftool cmake pkg tools/appimage ) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") diff --git a/src/cmake/crypto_engines.cmake b/src/cmake/crypto_engines.cmake new file mode 100644 index 00000000000..ae8214621b1 --- /dev/null +++ b/src/cmake/crypto_engines.cmake @@ -0,0 +1,76 @@ +# Copyright (c) 2018 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +macro(add_vpp_crypto_engine name) + cmake_parse_arguments(CRYPTO_ENGINE + "" + "LINK_FLAGS;COMPONENT;DEV_COMPONENT" + "SOURCES;LINK_LIBRARIES;SUPPORTED_OS_LIST" + ${ARGN} + ) + if (CRYPTO_ENGINE_SUPPORTED_OS_LIST AND NOT ${CMAKE_SYSTEM_NAME} IN_LIST CRYPTO_ENGINE_SUPPORTED_OS_LIST) + message(WARNING "unsupported OS - ${name} crypto engine disabled") + return() + endif() + set(crypto_engine_name ${name}_crypto_engine) + if(NOT CRYPTO_ENGINE_COMPONENT) + set(CRYPTO_ENGINE_COMPONENT vpp-crypto-engines) + endif() + if(NOT CRYPTO_ENGINE_DEV_COMPONENT) + if(NOT VPP_EXTERNAL_PROJECT) + set(CRYPTO_ENGINE_DEV_COMPONENT vpp-dev) + else() + set(CRYPTO_ENGINE_DEV_COMPONENT ${CRYPTO_ENGINE_COMPONENT}-dev) + endif() + endif() + + add_library(${crypto_engine_name} SHARED ${CRYPTO_ENGINE_SOURCES}) + target_compile_options(${crypto_engine_name} PUBLIC ${VPP_DEFAULT_MARCH_FLAGS}) + set_target_properties(${crypto_engine_name} PROPERTIES NO_SONAME 1) + target_compile_options(${crypto_engine_name} PRIVATE "-fvisibility=hidden") + target_compile_options (${crypto_engine_name} PRIVATE "-ffunction-sections") + target_compile_options (${crypto_engine_name} PRIVATE "-fdata-sections") + target_link_libraries (${crypto_engine_name} "-Wl,--gc-sections") + set(deps "") + if(NOT VPP_EXTERNAL_PROJECT) + list(APPEND deps vpp_version_h) + endif() + if(deps) + add_dependencies(${crypto_engine_name} ${deps}) + endif() + set_target_properties(${crypto_engine_name} PROPERTIES + PREFIX "" + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/vpp_crypto_engines) + if(CRYPTO_ENGINE_LINK_LIBRARIES) + target_link_libraries(${crypto_engine_name} ${CRYPTO_ENGINE_LINK_LIBRARIES}) + endif() + if(CRYPTO_ENGINE_LINK_FLAGS) + set_target_properties(${crypto_engine_name} PROPERTIES LINK_FLAGS "${CRYPTO_ENGINE_LINK_FLAGS}") + endif() + + install( + TARGETS ${crypto_engine_name} + DESTINATION ${VPP_LIBRARY_DIR}/vpp_crypto_engines + COMPONENT ${CRYPTO_ENGINE_COMPONENT} + ) +endmacro() + +macro(vpp_crypto_engine_find_library n var name) + find_library(${var} NAMES ${name} ${ARGN}) + mark_as_advanced(${var}) +if (NOT ${var}) + message(WARNING "-- ${name} library not found - ${n} crypto engine disabled") + return() +endif() + message(STATUS "${n} crypto engine needs ${name} library - found at ${${var}}") +endmacro() diff --git a/src/crypto_engines/CMakeLists.txt b/src/crypto_engines/CMakeLists.txt new file mode 100644 index 00000000000..8c4d930c08c --- /dev/null +++ b/src/crypto_engines/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (c) 2018 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +############################################################################## +# find and add all crypto engine subdirs +############################################################################## +FILE(GLOB files RELATIVE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/*/CMakeLists.txt +) + +foreach (f ${files}) + get_filename_component(dir ${f} DIRECTORY) + add_subdirectory(${dir}) +endforeach() diff --git a/src/plugins/crypto_ipsecmb/CMakeLists.txt b/src/crypto_engines/ipsecmb/CMakeLists.txt index 429343a9f3b..738bc05b0f5 100644 --- a/src/plugins/crypto_ipsecmb/CMakeLists.txt +++ b/src/crypto_engines/ipsecmb/CMakeLists.txt @@ -25,7 +25,7 @@ if(IPSECMB_INCLUDE_DIR AND IPSECMB_LIB) set(IPSECMB_LINK_FLAGS "${IPSECMB_LINK_FLAGS} -L${IPSECMB_LIB_DIR} -Wl,--whole-archive ${IPSECMB_LIB} -Wl,--no-whole-archive") set(IPSECMB_LINK_FLAGS "${IPSECMB_LINK_FLAGS} -Wl,--exclude-libs,libIPSec_MB.a,-l:libIPSec_MB.a") include_directories(${IPSECMB_INCLUDE_DIR}) - add_vpp_plugin(crypto_ipsecmb + add_vpp_crypto_engine(ipsecmb SOURCES ipsecmb.c @@ -43,7 +43,7 @@ if(IPSECMB_INCLUDE_DIR AND IPSECMB_LIB) message(STATUS "Intel IPSecMB ${IPSECMB_VERSION} does not support chacha20-poly1305. Disabled") endif() - target_compile_options(crypto_ipsecmb_plugin PRIVATE "-march=silvermont" "-maes") + target_compile_options(ipsecmb_crypto_engine PRIVATE "-march=silvermont" "-maes") message(STATUS "Intel IPSecMB found: ${IPSECMB_INCLUDE_DIR}") else() message(STATUS "Intel IPSecMB not found") diff --git a/src/plugins/crypto_ipsecmb/FEATURE.yaml b/src/crypto_engines/ipsecmb/FEATURE.yaml index 3ca03bf5515..3ca03bf5515 100644 --- a/src/plugins/crypto_ipsecmb/FEATURE.yaml +++ b/src/crypto_engines/ipsecmb/FEATURE.yaml diff --git a/src/plugins/crypto_ipsecmb/ipsecmb.c b/src/crypto_engines/ipsecmb/ipsecmb.c index 064c129ba12..256856bed8c 100644 --- a/src/plugins/crypto_ipsecmb/ipsecmb.c +++ b/src/crypto_engines/ipsecmb/ipsecmb.c @@ -1,18 +1,5 @@ -/* - * ipsecmb.c - Intel IPSec Multi-buffer library Crypto Engine - * - * Copyright (c) 2019 Cisco Systemss - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. */ #include <fcntl.h> @@ -23,6 +10,7 @@ #include <vnet/plugin/plugin.h> #include <vpp/app/version.h> #include <vnet/crypto/crypto.h> +#include <vnet/crypto/engine.h> #include <vppinfra/cpu.h> #define HMAC_MAX_BLOCK_SIZE IMB_SHA_512_BLOCK_SIZE @@ -149,8 +137,7 @@ ipsecmb_ops_hmac_inline (vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops, IMB_HASH_ALG alg) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; IMB_JOB *job; u32 i, n_fail = 0, ops_index = 0; u8 scratch[n_ops][digest_size]; @@ -204,8 +191,7 @@ ipsecmb_ops_hmac_inline (vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops, JOB_HASH_ALG alg) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; IMB_JOB *job; u32 i, n_fail = 0; u8 scratch[n_ops][digest_size]; @@ -283,8 +269,7 @@ ipsecmb_ops_aes_cipher_inline (vlib_main_t *vm, vnet_crypto_op_t *ops[], IMB_CIPHER_MODE cipher_mode) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; IMB_JOB *job; u32 i, n_fail = 0, ops_index = 0; const u32 burst_sz = @@ -338,8 +323,7 @@ ipsecmb_ops_aes_cipher_inline (vlib_main_t *vm, vnet_crypto_op_t *ops[], JOB_CIPHER_MODE cipher_mode) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; IMB_JOB *job; u32 i, n_fail = 0; @@ -409,8 +393,8 @@ ipsecmb_ops_gcm_cipher_enc_##a##_chained (vlib_main_t * vm, \ vnet_crypto_op_t * ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops) \ { \ ipsecmb_main_t *imbm = &ipsecmb_main; \ - ipsecmb_per_thread_data_t *ptd = vec_elt_at_index (imbm->per_thread_data, \ - vm->thread_index); \ + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + \ + vm->thread_index; \ IMB_MGR *m = ptd->mgr; \ vnet_crypto_op_chunk_t *chp; \ u32 i, j; \ @@ -444,8 +428,8 @@ ipsecmb_ops_gcm_cipher_enc_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \ u32 n_ops) \ { \ ipsecmb_main_t *imbm = &ipsecmb_main; \ - ipsecmb_per_thread_data_t *ptd = vec_elt_at_index (imbm->per_thread_data, \ - vm->thread_index); \ + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + \ + vm->thread_index; \ IMB_MGR *m = ptd->mgr; \ u32 i; \ \ @@ -470,8 +454,8 @@ ipsecmb_ops_gcm_cipher_dec_##a##_chained (vlib_main_t * vm, \ vnet_crypto_op_t * ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops) \ { \ ipsecmb_main_t *imbm = &ipsecmb_main; \ - ipsecmb_per_thread_data_t *ptd = vec_elt_at_index (imbm->per_thread_data, \ - vm->thread_index); \ + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + \ + vm->thread_index; \ IMB_MGR *m = ptd->mgr; \ vnet_crypto_op_chunk_t *chp; \ u32 i, j, n_failed = 0; \ @@ -512,8 +496,8 @@ ipsecmb_ops_gcm_cipher_dec_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \ u32 n_ops) \ { \ ipsecmb_main_t *imbm = &ipsecmb_main; \ - ipsecmb_per_thread_data_t *ptd = vec_elt_at_index (imbm->per_thread_data, \ - vm->thread_index); \ + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + \ + vm->thread_index; \ IMB_MGR *m = ptd->mgr; \ u32 i, n_failed = 0; \ \ @@ -577,8 +561,7 @@ ipsecmb_ops_chacha_poly (vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops, IMB_CIPHER_DIRECTION dir) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; struct IMB_JOB *job; IMB_MGR *m = ptd->mgr; u32 i, n_fail = 0, last_key_index = ~0; @@ -655,8 +638,7 @@ ipsecmb_ops_chacha_poly_chained (vlib_main_t *vm, vnet_crypto_op_t *ops[], IMB_CIPHER_DIRECTION dir) { ipsecmb_main_t *imbm = &ipsecmb_main; - ipsecmb_per_thread_data_t *ptd = - vec_elt_at_index (imbm->per_thread_data, vm->thread_index); + ipsecmb_per_thread_data_t *ptd = imbm->per_thread_data + vm->thread_index; IMB_MGR *m = ptd->mgr; u32 i, n_fail = 0, last_key_index = ~0; u8 *key = 0; @@ -762,7 +744,7 @@ ipsec_mb_ops_chacha_poly_dec_chained (vlib_main_t *vm, vnet_crypto_op_t *ops[], #endif static void -crypto_ipsecmb_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop, +crypto_ipsecmb_key_handler (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx) { ipsecmb_main_t *imbm = &ipsecmb_main; @@ -840,33 +822,23 @@ crypto_ipsecmb_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop, } } -static clib_error_t * -crypto_ipsecmb_init (vlib_main_t * vm) +static char * +crypto_ipsecmb_init (vnet_crypto_engine_registration_t *r) { ipsecmb_main_t *imbm = &ipsecmb_main; ipsecmb_alg_data_t *ad; ipsecmb_per_thread_data_t *ptd; - vlib_thread_main_t *tm = vlib_get_thread_main (); IMB_MGR *m = 0; - u32 eidx; - u8 *name; if (!clib_cpu_supports_aes ()) - return 0; + return "AES ISA not available on this CPU"; - /* - * A priority that is better than OpenSSL but worse than VPP natvie - */ - name = format (0, "Intel(R) Multi-Buffer Crypto for IPsec Library %s%c", - IMB_VERSION_STR, 0); - eidx = vnet_crypto_register_engine (vm, "ipsecmb", 80, (char *) name); + imbm->per_thread_data = r->per_thread_data; - vec_validate_aligned (imbm->per_thread_data, tm->n_vlib_mains - 1, - CLIB_CACHE_LINE_BYTES); - - vec_foreach (ptd, imbm->per_thread_data) + for (u32 i = 0; i < r->num_threads; i++) { - ptd->mgr = alloc_mb_mgr (0); + ptd = imbm->per_thread_data + i; + ptd->mgr = alloc_mb_mgr (0); #if IMB_VERSION_NUM >= IMB_VERSION(1, 3, 0) clib_memset_u8 (ptd->burst_jobs, 0, sizeof (IMB_JOB) * IMB_MAX_BURST_SIZE); @@ -882,82 +854,80 @@ crypto_ipsecmb_init (vlib_main_t * vm) m = ptd->mgr; } -#define _(a, b, c, d, e, f) \ - vnet_crypto_register_ops_handler (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \ - ipsecmb_ops_hmac_##a); \ - ad = imbm->alg_data + VNET_CRYPTO_ALG_HMAC_##a; \ - ad->block_size = d; \ - ad->data_size = e * 2; \ - ad->hash_one_block = m-> c##_one_block; \ - ad->hash_fn = m-> c; \ +#define _(a, b, c, d, e, f) \ + ad = imbm->alg_data + VNET_CRYPTO_ALG_HMAC_##a; \ + ad->block_size = d; \ + ad->data_size = e * 2; \ + ad->hash_one_block = m->c##_one_block; \ + ad->hash_fn = m->c; foreach_ipsecmb_hmac_op; #undef _ #define _(a, b, c) \ - vnet_crypto_register_ops_handler (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \ - ipsecmb_ops_cipher_enc_##a); \ - vnet_crypto_register_ops_handler (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \ - ipsecmb_ops_cipher_dec_##a); \ ad = imbm->alg_data + VNET_CRYPTO_ALG_##a; \ ad->data_size = sizeof (ipsecmb_aes_key_data_t); \ ad->keyexp = m->keyexp_##b; foreach_ipsecmb_cipher_op; #undef _ -#define _(a, b) \ - vnet_crypto_register_ops_handler (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \ - ipsecmb_ops_gcm_cipher_enc_##a); \ - vnet_crypto_register_ops_handler (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \ - ipsecmb_ops_gcm_cipher_dec_##a); \ - vnet_crypto_register_chained_ops_handler \ - (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \ - ipsecmb_ops_gcm_cipher_enc_##a##_chained); \ - vnet_crypto_register_chained_ops_handler \ - (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \ - ipsecmb_ops_gcm_cipher_dec_##a##_chained); \ - ad = imbm->alg_data + VNET_CRYPTO_ALG_##a; \ - ad->data_size = sizeof (struct gcm_key_data); \ - ad->aes_gcm_pre = m->gcm##b##_pre; \ +#define _(a, b) \ + ad = imbm->alg_data + VNET_CRYPTO_ALG_##a; \ + ad->data_size = sizeof (struct gcm_key_data); \ + ad->aes_gcm_pre = m->gcm##b##_pre; foreach_ipsecmb_gcm_cipher_op; #undef _ #ifdef HAVE_IPSECMB_CHACHA_POLY - vnet_crypto_register_ops_handler (vm, eidx, - VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, - ipsecmb_ops_chacha_poly_enc); - vnet_crypto_register_ops_handler (vm, eidx, - VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, - ipsecmb_ops_chacha_poly_dec); - vnet_crypto_register_chained_ops_handler ( - vm, eidx, VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, - ipsec_mb_ops_chacha_poly_enc_chained); - vnet_crypto_register_chained_ops_handler ( - vm, eidx, VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, - ipsec_mb_ops_chacha_poly_dec_chained); ad = imbm->alg_data + VNET_CRYPTO_ALG_CHACHA20_POLY1305; ad->data_size = 0; #endif - vnet_crypto_register_key_handler (vm, eidx, crypto_ipsecmb_key_handler); - return (NULL); + return 0; } -VLIB_INIT_FUNCTION (crypto_ipsecmb_init) = -{ - .runs_after = VLIB_INITS ("vnet_crypto_init"), -}; +vnet_crypto_engine_op_handlers_t op_handlers[] = { +#define _(a, b) \ + { \ + .opt = VNET_CRYPTO_OP_##a##_ENC, \ + .fn = ipsecmb_ops_gcm_cipher_enc_##a, \ + .cfn = ipsecmb_ops_gcm_cipher_enc_##a##_chained, \ + }, \ + { \ + .opt = VNET_CRYPTO_OP_##a##_DEC, \ + .fn = ipsecmb_ops_gcm_cipher_dec_##a, \ + .cfn = ipsecmb_ops_gcm_cipher_dec_##a##_chained, \ + }, + foreach_ipsecmb_gcm_cipher_op +#undef _ +#define _(a, b, c, d, e, f) \ + { .opt = VNET_CRYPTO_OP_##a##_HMAC, .fn = ipsecmb_ops_hmac_##a }, -VLIB_PLUGIN_REGISTER () = -{ - .version = VPP_BUILD_VER, - .description = "Intel IPSEC Multi-buffer Crypto Engine", + foreach_ipsecmb_hmac_op +#undef _ +#define _(a, b, c) \ + { .opt = VNET_CRYPTO_OP_##a##_ENC, .fn = ipsecmb_ops_cipher_enc_##a }, \ + { .opt = VNET_CRYPTO_OP_##a##_DEC, .fn = ipsecmb_ops_cipher_dec_##a }, + + foreach_ipsecmb_cipher_op +#undef _ +#ifdef HAVE_IPSECMB_CHACHA_POLY + { .opt = VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, + .fn = ipsecmb_ops_chacha_poly_enc, + .cfn = ipsec_mb_ops_chacha_poly_enc_chained }, + { .opt = VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, + .fn = ipsecmb_ops_chacha_poly_dec, + .cfn = ipsec_mb_ops_chacha_poly_dec_chained }, +#endif + {} }; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ +VNET_CRYPTO_ENGINE_REGISTRATION () = { + .name = "ipsecmb", + .desc = "Intel(R) Multi-Buffer Crypto for IPsec Library" IMB_VERSION_STR, + .prio = 80, + .per_thread_data_sz = sizeof (ipsecmb_per_thread_data_t), + .init_fn = crypto_ipsecmb_init, + .key_handler = crypto_ipsecmb_key_handler, + .op_handlers = op_handlers, +}; diff --git a/src/plugins/crypto_native/CMakeLists.txt b/src/crypto_engines/native/CMakeLists.txt index 5499ed4608a..d9d72aff58e 100644 --- a/src/plugins/crypto_native/CMakeLists.txt +++ b/src/crypto_engines/native/CMakeLists.txt @@ -36,15 +36,15 @@ if (NOT VARIANTS) return() endif() -add_vpp_plugin(crypto_native SOURCES main.c) +add_vpp_crypto_engine(native SOURCES main.c) foreach(VARIANT ${VARIANTS}) list(GET VARIANT 0 v) list(GET VARIANT 1 f) - set(l crypto_native_${v}) + set(l native_crypto_engine_${v}) add_library(${l} OBJECT ${COMPILE_FILES}) set_target_properties(${l} PROPERTIES POSITION_INDEPENDENT_CODE ON) separate_arguments(f) target_compile_options(${l} PUBLIC ${f} ${COMPILE_OPTS}) - target_sources(crypto_native_plugin PRIVATE $<TARGET_OBJECTS:${l}>) + target_sources(native_crypto_engine PRIVATE $<TARGET_OBJECTS:${l}>) endforeach() diff --git a/src/plugins/crypto_native/FEATURE.yaml b/src/crypto_engines/native/FEATURE.yaml index d54816d673f..d54816d673f 100644 --- a/src/plugins/crypto_native/FEATURE.yaml +++ b/src/crypto_engines/native/FEATURE.yaml diff --git a/src/plugins/crypto_native/aes_cbc.c b/src/crypto_engines/native/aes_cbc.c index c981897783f..b4ed2b3493d 100644 --- a/src/plugins/crypto_native/aes_cbc.c +++ b/src/crypto_engines/native/aes_cbc.c @@ -18,7 +18,7 @@ #include <vlib/vlib.h> #include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <crypto_native/crypto_native.h> +#include <native/crypto_native.h> #include <vppinfra/crypto/aes_cbc.h> #if __GNUC__ > 4 && !__clang__ && CLIB_DEBUG == 0 diff --git a/src/plugins/crypto_native/aes_ctr.c b/src/crypto_engines/native/aes_ctr.c index d02a7b69b9d..d39b1c83842 100644 --- a/src/plugins/crypto_native/aes_ctr.c +++ b/src/crypto_engines/native/aes_ctr.c @@ -5,7 +5,7 @@ #include <vlib/vlib.h> #include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <crypto_native/crypto_native.h> +#include <native/crypto_native.h> #include <vppinfra/crypto/aes_ctr.h> #if __GNUC__ > 4 && !__clang__ && CLIB_DEBUG == 0 diff --git a/src/plugins/crypto_native/aes_gcm.c b/src/crypto_engines/native/aes_gcm.c index 220788d4e97..57eee17f3d0 100644 --- a/src/plugins/crypto_native/aes_gcm.c +++ b/src/crypto_engines/native/aes_gcm.c @@ -18,7 +18,7 @@ #include <vlib/vlib.h> #include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <crypto_native/crypto_native.h> +#include <native/crypto_native.h> #include <vppinfra/crypto/aes_gcm.h> #if __GNUC__ > 4 && !__clang__ && CLIB_DEBUG == 0 diff --git a/src/plugins/crypto_native/crypto_native.h b/src/crypto_engines/native/crypto_native.h index 3d18e8cabd0..0fcb6a99524 100644 --- a/src/plugins/crypto_native/crypto_native.h +++ b/src/crypto_engines/native/crypto_native.h @@ -42,7 +42,6 @@ typedef struct crypto_native_key_handler typedef struct { - u32 crypto_engine_index; crypto_native_key_fn_t *key_fn[VNET_CRYPTO_N_ALGS]; void **key_data; crypto_native_op_handler_t *op_handlers; diff --git a/src/plugins/crypto_native/main.c b/src/crypto_engines/native/main.c index 2bc0d98f196..e9e71b6fb6d 100644 --- a/src/plugins/crypto_native/main.c +++ b/src/crypto_engines/native/main.c @@ -1,29 +1,18 @@ -/* - *------------------------------------------------------------------ - * Copyright (c) 2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. */ #include <vlib/vlib.h> #include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <crypto_native/crypto_native.h> +#include <vnet/crypto/engine.h> +#include <native/crypto_native.h> crypto_native_main_t crypto_native_main; +vnet_crypto_engine_op_handlers_t op_handlers[24], *ophp = op_handlers; static void -crypto_native_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop, +crypto_native_key_handler (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx) { vnet_crypto_key_t *key = vnet_crypto_get_key (idx); @@ -59,18 +48,14 @@ crypto_native_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop, cm->key_data[idx] = cm->key_fn[key->alg] (key); } -clib_error_t * -crypto_native_init (vlib_main_t * vm) +static char * +crypto_native_init (vnet_crypto_engine_registration_t *r) { crypto_native_main_t *cm = &crypto_native_main; if (cm->op_handlers == 0) return 0; - cm->crypto_engine_index = - vnet_crypto_register_engine (vm, "native", 100, - "Native ISA Optimized Crypto"); - crypto_native_op_handler_t *oh = cm->op_handlers; crypto_native_key_handler_t *kh = cm->key_handlers; crypto_native_op_handler_t **best_by_op_id = 0; @@ -100,8 +85,13 @@ crypto_native_init (vlib_main_t * vm) vec_foreach_pointer (oh, best_by_op_id) if (oh) - vnet_crypto_register_ops_handlers (vm, cm->crypto_engine_index, - oh->op_id, oh->fn, oh->cfn); + { + *ophp = (vnet_crypto_engine_op_handlers_t){ .opt = oh->op_id, + .fn = oh->fn, + .cfn = oh->cfn }; + ophp++; + ASSERT ((ophp - op_handlers) < ARRAY_LEN (op_handlers)); + } vec_foreach_pointer (kh, best_by_alg_id) if (kh) @@ -110,19 +100,14 @@ crypto_native_init (vlib_main_t * vm) vec_free (best_by_op_id); vec_free (best_by_alg_id); - vnet_crypto_register_key_handler (vm, cm->crypto_engine_index, - crypto_native_key_handler); return 0; } -VLIB_INIT_FUNCTION (crypto_native_init) = -{ - .runs_after = VLIB_INITS ("vnet_crypto_init"), -}; - -#include <vpp/app/version.h> - -VLIB_PLUGIN_REGISTER () = { - .version = VPP_BUILD_VER, - .description = "Native Crypto Engine", +VNET_CRYPTO_ENGINE_REGISTRATION () = { + .name = "native", + .desc = "Native ISA Optimized Crypto", + .prio = 100, + .init_fn = crypto_native_init, + .key_handler = crypto_native_key_handler, + .op_handlers = op_handlers, }; diff --git a/src/plugins/crypto_native/sha2.c b/src/crypto_engines/native/sha2.c index 6787f629104..b61a5f08060 100644 --- a/src/plugins/crypto_native/sha2.c +++ b/src/crypto_engines/native/sha2.c @@ -5,7 +5,7 @@ #include <vlib/vlib.h> #include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <crypto_native/crypto_native.h> +#include <native/crypto_native.h> #include <vppinfra/crypto/sha2.h> static_always_inline u32 diff --git a/src/plugins/crypto_openssl/CMakeLists.txt b/src/crypto_engines/openssl/CMakeLists.txt index 472b0ef3243..01f00a01a74 100644 --- a/src/plugins/crypto_openssl/CMakeLists.txt +++ b/src/crypto_engines/openssl/CMakeLists.txt @@ -18,7 +18,7 @@ endif() include_directories(${OPENSSL_INCLUDE_DIR}) add_compile_definitions(OPENSSL_SUPPRESS_DEPRECATED) -add_vpp_plugin(crypto_openssl +add_vpp_crypto_engine(openssl SOURCES main.c diff --git a/src/plugins/crypto_openssl/FEATURE.yaml b/src/crypto_engines/openssl/FEATURE.yaml index da0a0812595..da0a0812595 100644 --- a/src/plugins/crypto_openssl/FEATURE.yaml +++ b/src/crypto_engines/openssl/FEATURE.yaml diff --git a/src/plugins/crypto_openssl/crypto_openssl.h b/src/crypto_engines/openssl/crypto_openssl.h index e16429fb5dd..cff9820fe99 100644 --- a/src/plugins/crypto_openssl/crypto_openssl.h +++ b/src/crypto_engines/openssl/crypto_openssl.h @@ -11,7 +11,6 @@ typedef void *(crypto_openssl_ctx_fn_t) (vnet_crypto_key_t *key, typedef struct { - u32 crypto_engine_index; crypto_openssl_ctx_fn_t *ctx_fn[VNET_CRYPTO_N_ALGS]; } crypto_openssl_main_t; diff --git a/src/plugins/crypto_openssl/main.c b/src/crypto_engines/openssl/main.c index c59b5d34a29..c5636add266 100644 --- a/src/plugins/crypto_openssl/main.c +++ b/src/crypto_engines/openssl/main.c @@ -1,32 +1,16 @@ -/* - *------------------------------------------------------------------ - * Copyright (c) 2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. */ -#include <sys/syscall.h> - #include <openssl/evp.h> #include <openssl/hmac.h> #include <openssl/rand.h> #include <openssl/sha.h> #include <vlib/vlib.h> -#include <vnet/plugin/plugin.h> #include <vnet/crypto/crypto.h> -#include <vpp/app/version.h> -#include <crypto_openssl/crypto_openssl.h> +#include <vnet/crypto/engine.h> +#include <openssl/crypto_openssl.h> typedef struct { @@ -40,26 +24,27 @@ typedef struct #endif } openssl_per_thread_data_t; -static openssl_per_thread_data_t *per_thread_data = 0; +static openssl_per_thread_data_t *per_thread_data; +static u32 num_threads; #define foreach_openssl_aes_evp_op \ - _ (cbc, DES_CBC, EVP_des_cbc, 8) \ - _ (cbc, 3DES_CBC, EVP_des_ede3_cbc, 8) \ - _ (cbc, AES_128_CBC, EVP_aes_128_cbc, 16) \ - _ (cbc, AES_192_CBC, EVP_aes_192_cbc, 16) \ - _ (cbc, AES_256_CBC, EVP_aes_256_cbc, 16) \ - _ (gcm, AES_128_GCM, EVP_aes_128_gcm, 8) \ - _ (gcm, AES_192_GCM, EVP_aes_192_gcm, 8) \ - _ (gcm, AES_256_GCM, EVP_aes_256_gcm, 8) \ - _ (cbc, AES_128_CTR, EVP_aes_128_ctr, 8) \ - _ (cbc, AES_192_CTR, EVP_aes_192_ctr, 8) \ - _ (cbc, AES_256_CTR, EVP_aes_256_ctr, 8) \ - _ (null_gmac, AES_128_NULL_GMAC, EVP_aes_128_gcm, 8) \ - _ (null_gmac, AES_192_NULL_GMAC, EVP_aes_192_gcm, 8) \ - _ (null_gmac, AES_256_NULL_GMAC, EVP_aes_256_gcm, 8) + _ (cbc, DES_CBC, EVP_des_cbc) \ + _ (cbc, 3DES_CBC, EVP_des_ede3_cbc) \ + _ (cbc, AES_128_CBC, EVP_aes_128_cbc) \ + _ (cbc, AES_192_CBC, EVP_aes_192_cbc) \ + _ (cbc, AES_256_CBC, EVP_aes_256_cbc) \ + _ (gcm, AES_128_GCM, EVP_aes_128_gcm) \ + _ (gcm, AES_192_GCM, EVP_aes_192_gcm) \ + _ (gcm, AES_256_GCM, EVP_aes_256_gcm) \ + _ (cbc, AES_128_CTR, EVP_aes_128_ctr) \ + _ (cbc, AES_192_CTR, EVP_aes_192_ctr) \ + _ (cbc, AES_256_CTR, EVP_aes_256_ctr) \ + _ (null_gmac, AES_128_NULL_GMAC, EVP_aes_128_gcm) \ + _ (null_gmac, AES_192_NULL_GMAC, EVP_aes_192_gcm) \ + _ (null_gmac, AES_256_NULL_GMAC, EVP_aes_256_gcm) #define foreach_openssl_chacha20_evp_op \ - _ (chacha20_poly1305, CHACHA20_POLY1305, EVP_chacha20_poly1305, 8) + _ (chacha20_poly1305, CHACHA20_POLY1305, EVP_chacha20_poly1305) #if OPENSSL_VERSION_NUMBER >= 0x10100000L #define foreach_openssl_evp_op foreach_openssl_aes_evp_op \ @@ -96,10 +81,9 @@ crypto_openssl_main_t crypto_openssl_main; 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) + const EVP_CIPHER *cipher) { - openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data, - vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; EVP_CIPHER_CTX *ctx; vnet_crypto_op_chunk_t *chp; u32 i, j, curr_len = 0; @@ -151,10 +135,9 @@ openssl_ops_enc_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[], 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) + const EVP_CIPHER *cipher) { - openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data, - vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; EVP_CIPHER_CTX *ctx; vnet_crypto_op_chunk_t *chp; u32 i, j, curr_len = 0; @@ -206,11 +189,9 @@ openssl_ops_dec_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[], 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, int is_gmac, - const int iv_len) + const EVP_CIPHER *cipher, int is_gcm, int is_gmac) { - openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data, - vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; EVP_CIPHER_CTX *ctx; vnet_crypto_op_chunk_t *chp; u32 i, j; @@ -256,38 +237,36 @@ openssl_ops_enc_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[], static_always_inline u32 openssl_ops_enc_null_gmac (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) + const EVP_CIPHER *cipher) { return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 1, /* is_gmac */ 1, iv_len); + /* is_gcm */ 1, /* is_gmac */ 1); } 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) + const EVP_CIPHER *cipher) { return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 1, /* is_gmac */ 0, iv_len); + /* is_gcm */ 1, /* is_gmac */ 0); } 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) + const EVP_CIPHER *cipher) { return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 0, /* is_gmac */ 0, iv_len); + /* is_gcm */ 0, /* is_gmac */ 0); } 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, int is_gmac, - const int iv_len) + const EVP_CIPHER *cipher, int is_gcm, int is_gmac) { - openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data, - vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; EVP_CIPHER_CTX *ctx; vnet_crypto_op_chunk_t *chp; u32 i, j, n_fail = 0; @@ -331,36 +310,35 @@ openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[], static_always_inline u32 openssl_ops_dec_null_gmac (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) + const EVP_CIPHER *cipher) { return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 1, /* is_gmac */ 1, iv_len); + /* is_gcm */ 1, /* is_gmac */ 1); } 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) + const EVP_CIPHER *cipher) { return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 1, /* is_gmac */ 0, iv_len); + /* is_gcm */ 1, /* is_gmac */ 0); } 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) + const EVP_CIPHER *cipher) { return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher, - /* is_gcm */ 0, /* is_gmac */ 0, iv_len); + /* is_gcm */ 0, /* is_gmac */ 0); } 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) { - openssl_per_thread_data_t *ptd = - vec_elt_at_index (per_thread_data, vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; EVP_MD_CTX *ctx = ptd->hash_ctx; vnet_crypto_op_chunk_t *chp; u32 md_len, i, j, n_fail = 0; @@ -395,8 +373,7 @@ openssl_ops_hmac (vlib_main_t * vm, vnet_crypto_op_t * ops[], const EVP_MD * md) { u8 buffer[64]; - openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data, - vm->thread_index); + openssl_per_thread_data_t *ptd = per_thread_data + vm->thread_index; HMAC_CTX *ctx; vnet_crypto_op_chunk_t *chp; u32 i, j, n_fail = 0; @@ -447,7 +424,7 @@ openssl_ctx_cipher (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, if (VNET_CRYPTO_KEY_OP_ADD == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { vec_validate_aligned (ptd->evp_cipher_enc_ctx, idx, CLIB_CACHE_LINE_BYTES); @@ -473,7 +450,7 @@ openssl_ctx_cipher (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, } else if (VNET_CRYPTO_KEY_OP_MODIFY == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { ctx = ptd->evp_cipher_enc_ctx[idx]; EVP_EncryptInit_ex (ctx, cipher, NULL, NULL, NULL); @@ -490,7 +467,7 @@ openssl_ctx_cipher (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, } else if (VNET_CRYPTO_KEY_OP_DEL == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { ctx = ptd->evp_cipher_enc_ctx[idx]; EVP_CIPHER_CTX_free (ctx); @@ -512,7 +489,7 @@ openssl_ctx_hmac (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, openssl_per_thread_data_t *ptd; if (VNET_CRYPTO_KEY_OP_ADD == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { vec_validate_aligned (ptd->hmac_ctx, idx, CLIB_CACHE_LINE_BYTES); #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -527,7 +504,7 @@ openssl_ctx_hmac (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, } else if (VNET_CRYPTO_KEY_OP_MODIFY == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { ctx = ptd->hmac_ctx[idx]; HMAC_Init_ex (ctx, key->data, vec_len (key->data), md, NULL); @@ -535,7 +512,7 @@ openssl_ctx_hmac (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, } else if (VNET_CRYPTO_KEY_OP_DEL == kop) { - vec_foreach (ptd, per_thread_data) + for (ptd = per_thread_data; ptd - per_thread_data < num_threads; ptd++) { ctx = ptd->hmac_ctx[idx]; HMAC_CTX_free (ctx); @@ -546,7 +523,7 @@ openssl_ctx_hmac (vnet_crypto_key_t *key, vnet_crypto_key_op_t kop, } static void -crypto_openssl_key_handler (vlib_main_t *vm, vnet_crypto_key_op_t kop, +crypto_openssl_key_handler (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx) { vnet_crypto_key_t *key = vnet_crypto_get_key (idx); @@ -562,31 +539,31 @@ crypto_openssl_key_handler (vlib_main_t *vm, vnet_crypto_key_op_t kop, cm->ctx_fn[key->alg](key, kop, idx); } -#define _(m, a, b, iv) \ +#define _(m, a, b) \ static u32 openssl_ops_enc_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \ u32 n_ops) \ { \ - return openssl_ops_enc_##m (vm, ops, 0, n_ops, b (), iv); \ + return openssl_ops_enc_##m (vm, ops, 0, n_ops, b ()); \ } \ \ u32 openssl_ops_dec_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \ u32 n_ops) \ { \ - return openssl_ops_dec_##m (vm, ops, 0, n_ops, b (), iv); \ + return openssl_ops_dec_##m (vm, ops, 0, n_ops, b ()); \ } \ \ static u32 openssl_ops_enc_chained_##a ( \ vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \ u32 n_ops) \ { \ - return openssl_ops_enc_##m (vm, ops, chunks, n_ops, b (), iv); \ + return openssl_ops_enc_##m (vm, ops, chunks, n_ops, b ()); \ } \ \ static u32 openssl_ops_dec_chained_##a ( \ vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \ u32 n_ops) \ { \ - return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b (), iv); \ + return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b ()); \ } \ static void *openssl_ctx_##a (vnet_crypto_key_t *key, \ vnet_crypto_key_op_t kop, \ @@ -594,8 +571,8 @@ crypto_openssl_key_handler (vlib_main_t *vm, vnet_crypto_key_op_t kop, { \ int is_gcm = ((VNET_CRYPTO_ALG_AES_128_GCM <= key->alg) && \ (VNET_CRYPTO_ALG_AES_256_NULL_GMAC >= key->alg)) ? \ - 1 : \ - 0; \ + 1 : \ + 0; \ return openssl_ctx_cipher (key, kop, idx, b (), is_gcm); \ } @@ -640,80 +617,69 @@ foreach_openssl_hash_op; foreach_openssl_hmac_op; #undef _ -clib_error_t * -crypto_openssl_init (vlib_main_t * vm) +static char * +crypto_openssl_init (vnet_crypto_engine_registration_t *r) { crypto_openssl_main_t *cm = &crypto_openssl_main; - vlib_thread_main_t *tm = vlib_get_thread_main (); - openssl_per_thread_data_t *ptd; u8 seed[32]; if (syscall (SYS_getrandom, &seed, sizeof (seed), 0) != sizeof (seed)) - return clib_error_return_unix (0, "getrandom() failed"); - - RAND_seed (seed, sizeof (seed)); + return "getrandom() failed"; - u32 eidx = vnet_crypto_register_engine (vm, "openssl", 50, "OpenSSL"); - cm->crypto_engine_index = eidx; + num_threads = r->num_threads; -#define _(m, a, b, iv) \ - vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \ - openssl_ops_enc_##a, \ - openssl_ops_enc_chained_##a); \ - vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \ - openssl_ops_dec_##a, \ - openssl_ops_dec_chained_##a); \ - cm->ctx_fn[VNET_CRYPTO_ALG_##a] = openssl_ctx_##a; + RAND_seed (seed, sizeof (seed)); +#define _(m, a, b) cm->ctx_fn[VNET_CRYPTO_ALG_##a] = openssl_ctx_##a; foreach_openssl_evp_op; #undef _ -#define _(a, b) \ - vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \ - openssl_ops_hmac_##a, \ - openssl_ops_hmac_chained_##a); \ - cm->ctx_fn[VNET_CRYPTO_ALG_HMAC_##a] = openssl_ctx_hmac_##a; - +#define _(a, b) cm->ctx_fn[VNET_CRYPTO_ALG_HMAC_##a] = openssl_ctx_hmac_##a; foreach_openssl_hmac_op; #undef _ -#define _(a, b) \ - vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HASH, \ - openssl_ops_hash_##a, \ - openssl_ops_hash_chained_##a); - - foreach_openssl_hash_op; -#undef _ - - vec_validate_aligned (per_thread_data, tm->n_vlib_mains - 1, - CLIB_CACHE_LINE_BYTES); + per_thread_data = r->per_thread_data; - vec_foreach (ptd, per_thread_data) - { #if OPENSSL_VERSION_NUMBER >= 0x10100000L - ptd->hash_ctx = EVP_MD_CTX_create (); + for (u32 i = 0; i < r->num_threads; i++) + per_thread_data[i].hash_ctx = EVP_MD_CTX_create (); #endif - } - vnet_crypto_register_key_handler (vm, cm->crypto_engine_index, - crypto_openssl_key_handler); return 0; } -VLIB_INIT_FUNCTION (crypto_openssl_init) = -{ - .runs_after = VLIB_INITS ("vnet_crypto_init"), +vnet_crypto_engine_op_handlers_t op_handlers[] = { +#define _(m, a, b) \ + { \ + .opt = VNET_CRYPTO_OP_##a##_ENC, \ + .fn = openssl_ops_enc_##a, \ + .cfn = openssl_ops_enc_chained_##a, \ + }, \ + { .opt = VNET_CRYPTO_OP_##a##_DEC, \ + .fn = openssl_ops_dec_##a, \ + .cfn = openssl_ops_dec_chained_##a }, + foreach_openssl_evp_op +#undef _ +#define _(a, b) \ + { .opt = VNET_CRYPTO_OP_##a##_HMAC, \ + .fn = openssl_ops_hmac_##a, \ + .cfn = openssl_ops_hmac_chained_##a }, + foreach_openssl_hmac_op +#undef _ +#define _(a, b) \ + { .opt = VNET_CRYPTO_OP_##a##_HASH, \ + .fn = openssl_ops_hash_##a, \ + .cfn = openssl_ops_hash_chained_##a }, + foreach_openssl_hash_op +#undef _ + {} }; - -VLIB_PLUGIN_REGISTER () = { - .version = VPP_BUILD_VER, - .description = "OpenSSL Crypto Engine", +VNET_CRYPTO_ENGINE_REGISTRATION () = { + .name = "openssl", + .desc = "OpenSSL", + .prio = 50, + .per_thread_data_sz = sizeof (openssl_per_thread_data_t), + .init_fn = crypto_openssl_init, + .key_handler = crypto_openssl_key_handler, + .op_handlers = op_handlers, }; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/plugins/crypto_sw_scheduler/main.c b/src/plugins/crypto_sw_scheduler/main.c index 8d0430ab2f6..a594f30f823 100644 --- a/src/plugins/crypto_sw_scheduler/main.c +++ b/src/plugins/crypto_sw_scheduler/main.c @@ -51,7 +51,7 @@ crypto_sw_scheduler_set_worker_crypto (u32 worker_idx, u8 enabled) } static void -crypto_sw_scheduler_key_handler (vlib_main_t * vm, vnet_crypto_key_op_t kop, +crypto_sw_scheduler_key_handler (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx) { crypto_sw_scheduler_main_t *cm = &crypto_sw_scheduler_main; diff --git a/src/plugins/dpdk/cryptodev/cryptodev.c b/src/plugins/dpdk/cryptodev/cryptodev.c index 43c2c879aab..0250da7cda3 100644 --- a/src/plugins/dpdk/cryptodev/cryptodev.c +++ b/src/plugins/dpdk/cryptodev/cryptodev.c @@ -327,10 +327,9 @@ cryptodev_sess_handler (vlib_main_t *vm, vnet_crypto_key_op_t kop, } /*static*/ void -cryptodev_key_handler (vlib_main_t *vm, vnet_crypto_key_op_t kop, - vnet_crypto_key_index_t idx) +cryptodev_key_handler (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx) { - cryptodev_sess_handler (vm, kop, idx, 8); + cryptodev_sess_handler (vlib_get_main (), kop, idx, 8); } clib_error_t * diff --git a/src/plugins/quic/quic_crypto.c b/src/plugins/quic/quic_crypto.c index c5cc5a4a714..9e2c915daaa 100644 --- a/src/plugins/quic/quic_crypto.c +++ b/src/plugins/quic/quic_crypto.c @@ -130,19 +130,18 @@ quic_crypto_set_key (crypto_key_t *key) u8 thread_index = vlib_get_thread_index (); u32 key_id = quic_main.per_thread_crypto_key_indices[thread_index]; vnet_crypto_key_t *vnet_key = vnet_crypto_get_key (key_id); - vlib_main_t *vm = vlib_get_main (); vnet_crypto_engine_t *engine; vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, key_id); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_DEL, key_id); vnet_key->alg = key->algo; clib_memcpy (vnet_key->data, key->key, key->key_len); vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, key_id); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, key_id); return key_id; } diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c index c8e7ca90c9d..f46e307af89 100644 --- a/src/vnet/crypto/crypto.c +++ b/src/vnet/crypto/crypto.c @@ -16,9 +16,24 @@ #include <stdbool.h> #include <vlib/vlib.h> #include <vnet/crypto/crypto.h> +#include <vnet/crypto/engine.h> +#include <vppinfra/unix.h> +#include <vlib/log.h> +#include <dlfcn.h> +#include <dirent.h> vnet_crypto_main_t crypto_main; +VLIB_REGISTER_LOG_CLASS (crypto_main_log, static) = { + .class_name = "crypto", + .subclass_name = "main", +}; + +#define log_debug(f, ...) \ + vlib_log (VLIB_LOG_LEVEL_DEBUG, crypto_main_log.class, f, ##__VA_ARGS__) +#define log_err(f, ...) \ + vlib_log (VLIB_LOG_LEVEL_ERR, crypto_main_log.class, f, ##__VA_ARGS__) + static_always_inline void crypto_set_op_status (vnet_crypto_op_t * ops[], u32 n_ops, int status) { @@ -451,7 +466,7 @@ vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data, clib_memcpy (key->data, data, length); vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index); return index; } @@ -464,7 +479,7 @@ vnet_crypto_key_del (vlib_main_t * vm, vnet_crypto_key_index_t index) vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_DEL, index); if (key->type == VNET_CRYPTO_KEY_TYPE_DATA) { @@ -487,7 +502,7 @@ vnet_crypto_key_update (vlib_main_t *vm, vnet_crypto_key_index_t index) vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_MODIFY, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_MODIFY, index); } vnet_crypto_async_alg_t @@ -530,7 +545,7 @@ vnet_crypto_key_add_linked (vlib_main_t * vm, vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index); return index; } @@ -716,6 +731,117 @@ vnet_crypto_init_async_data (vnet_crypto_async_alg_t alg, hash_set_mem (cm->async_alg_index_by_name, name, alg); } +static void +vnet_crypto_load_engines (vlib_main_t *vm) +{ + vlib_thread_main_t *tm = vlib_get_thread_main (); + u8 *path; + char *p; + u32 path_len; + struct dirent *entry; + DIR *dp; + + path = os_get_exec_path (); + log_debug ("exec path is %s", path); + + vec_add1 (path, 0); + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; + *p = 0; + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; + + vec_set_len (path, (u8 *) p - path); + + path = format (path, "/" CLIB_LIB_DIR "/vpp_crypto_engines"); + path_len = vec_len (path); + vec_add1 (path, 0); + + log_debug ("libpath is %s", path); + + dp = opendir ((char *) path); + + if (dp) + { + while ((entry = readdir (dp))) + { + void *handle; + + if (entry->d_type != DT_REG) + continue; + + char *ext = strrchr (entry->d_name, '.'); + if (!ext || strncmp (ext, ".so", 3) != 0) + { + log_debug ("skipping %s, not .so", entry->d_name); + } + vec_set_len (path, path_len); + path = format (path, "/%s%c", entry->d_name, 0); + + handle = dlopen ((char *) path, RTLD_LAZY); + if (!handle) + { + log_err ("failed to dlopen %s", path); + continue; + } + + vnet_crypto_engine_registration_t *r = + dlsym (handle, "__vnet_crypto_engine"); + if (!r) + { + log_err ("%s is not a crypto engine", entry->d_name); + dlclose (handle); + continue; + } + + if (r->per_thread_data_sz) + { + u64 sz = + round_pow2 (r->per_thread_data_sz, CLIB_CACHE_LINE_BYTES); + u64 alloc = sz * tm->n_vlib_mains; + r->per_thread_data = + clib_mem_alloc_aligned (alloc, CLIB_CACHE_LINE_BYTES); + clib_memset (r->per_thread_data, 0, alloc); + log_debug ("%s: allocated %u bytes per thread", r->name, sz); + } + + r->num_threads = tm->n_vlib_mains; + + if (r->init_fn) + { + char *rv = r->init_fn (r); + if (rv) + { + log_err ("%s crypto engine init failed: %s", r->name, rv); + if (r->per_thread_data) + clib_mem_free (r->per_thread_data); + dlclose (handle); + continue; + } + log_debug ("%s crypto engine initialized", r->name); + } + u32 eidx = + vnet_crypto_register_engine (vm, r->name, r->prio, r->desc); + log_debug ("%s crypto engine registered with id %u", r->name, eidx); + typeof (r->op_handlers) oh = r->op_handlers; + + while (oh->opt != VNET_CRYPTO_OP_NONE) + { + vnet_crypto_register_ops_handlers (vm, eidx, oh->opt, oh->fn, + oh->cfn); + oh++; + } + + if (r->key_handler) + vnet_crypto_register_key_handler (vm, eidx, r->key_handler); + } + closedir (dp); + } + +done: + vec_free (path); +} + clib_error_t * vnet_crypto_init (vlib_main_t * vm) { @@ -772,6 +898,8 @@ vnet_crypto_init (vlib_main_t * vm) cm->crypto_node_index = vlib_get_node_by_name (vm, (u8 *) "crypto-dispatch")->index; + vnet_crypto_load_engines (vm); + return 0; } diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h index 89cf70d19e3..13d08756109 100644 --- a/src/vnet/crypto/crypto.h +++ b/src/vnet/crypto/crypto.h @@ -392,8 +392,7 @@ typedef u32 (vnet_crypto_chained_ops_handler_t) (vlib_main_t * vm, typedef u32 (vnet_crypto_ops_handler_t) (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops); -typedef void (vnet_crypto_key_handler_t) (vlib_main_t * vm, - vnet_crypto_key_op_t kop, +typedef void (vnet_crypto_key_handler_t) (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx); /** async crypto function handlers **/ diff --git a/src/vnet/crypto/engine.h b/src/vnet/crypto/engine.h new file mode 100644 index 00000000000..993befb393a --- /dev/null +++ b/src/vnet/crypto/engine.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. + */ + +#ifndef included_vnet_crypto_engine_h +#define included_vnet_crypto_engine_h + +#ifndef included_clib_types_h +typedef unsigned int u32; +#endif + +typedef struct +{ + vnet_crypto_op_id_t opt; + vnet_crypto_ops_handler_t *fn; + vnet_crypto_chained_ops_handler_t *cfn; +} vnet_crypto_engine_op_handlers_t; + +struct vnet_crypto_engine_registration; + +typedef char *( + vnet_crypto_engine_init_fn_t) (struct vnet_crypto_engine_registration *); + +typedef struct vnet_crypto_engine_registration +{ + char name[32]; /* backend name */ + char desc[128]; /* backend name */ + int prio; + u32 version; + u32 per_thread_data_sz; + u32 num_threads; + void *per_thread_data; + vnet_crypto_engine_init_fn_t *init_fn; + vnet_crypto_key_handler_t *key_handler; + vnet_crypto_engine_op_handlers_t *op_handlers; +} vnet_crypto_engine_registration_t; + +#define VNET_CRYPTO_ENGINE_REGISTRATION() \ + __clib_export vnet_crypto_engine_registration_t __vnet_crypto_engine + +#endif |