diff --git a/.github/workflows/static-wolfssl.yml b/.github/workflows/static-wolfssl.yml new file mode 100644 index 00000000..11bc1709 --- /dev/null +++ b/.github/workflows/static-wolfssl.yml @@ -0,0 +1,136 @@ +name: wolfPKCS11 static wolfSSL tests + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +permissions: + contents: read + +jobs: + autotools: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: +#pull wolfPKCS11 + - uses: actions/checkout@v4 + with: + submodules: true + persist-credentials: false + +#setup wolfssl + - uses: actions/checkout@v4 + with: + repository: wolfssl/wolfssl + path: wolfssl + persist-credentials: false + - name: Build static wolfSSL + working-directory: ./wolfssl + run: | + ./autogen.sh + ./configure --prefix=$GITHUB_WORKSPACE/wolfssl-install \ + --enable-static --disable-shared --with-pic --enable-cryptonly \ + --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --enable-md5 \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" + make + make install + +#setup wolfPKCS11 + - name: Build wolfPKCS11 + run: | + ./autogen.sh + ./configure CPPFLAGS=-I$GITHUB_WORKSPACE/wolfssl-install/include \ + --with-static-wolfssl=$GITHUB_WORKSPACE/wolfssl-install/lib/libwolfssl.a + make + - name: Check the library is self-contained + run: | + lib=$(readlink -f src/.libs/libwolfpkcs11.so) + dyn=$(readelf -d "$lib") + syms=$(nm -D --defined-only "$lib") + if grep -E 'NEEDED.*libwolfssl|TEXTREL' <<<"$dyn"; then exit 1; fi + if grep -v ' C_' <<<"$syms"; then exit 1; fi + for f in C_GetFunctionList C_GetInterface C_LoginUser; do + grep -qw "$f" <<<"$syms" + done + - name: wolfpkcs11 make check + run: make check + - name: Run the wolfSSL interoperability test against the library + run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/src/.libs/libwolfpkcs11.so + - name: Install wolfPKCS11 + run: | + sudo make install + sudo ldconfig + - name: Build a find_package consumer without wolfSSL + run: | + libs=$(wolfpkcs11-config --libs) + if grep wolfssl <<<"$libs"; then exit 1; fi + cmake -S cmake/consumer -B consumer-build + cmake --build consumer-build + ./consumer-build/wolfpkcs11_consumer + +# capture logs on failure + - name: Upload failure logs + if: failure() || cancelled() + uses: actions/upload-artifact@v4 + with: + name: wolfpkcs11-static-wolfssl-logs + path: | + test-suite.log + tests/*.log + retention-days: 5 + + cmake: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: +#pull wolfPKCS11 + - uses: actions/checkout@v4 + with: + submodules: true + persist-credentials: false + +#setup wolfssl + - uses: actions/checkout@v4 + with: + repository: wolfssl/wolfssl + path: wolfssl + persist-credentials: false + - name: Build static wolfSSL + working-directory: ./wolfssl + run: | + cmake -B build -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/wolfssl-install \ + -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release \ + -DWOLFSSL_CRYPT_ONLY=yes -DWOLFSSL_AESCFB=yes -DWOLFSSL_AESECB=yes -DWOLFSSL_AESCTR=yes \ + -DWOLFSSL_AESKEYWRAP=yes -DWOLFSSL_RSA_PSS=yes -DWOLFSSL_KEYGEN=yes -DWOLFSSL_PWDBASED=yes \ + -DWOLFSSL_MD5=yes -DWOLFSSL_SHA224=yes -DWOLFSSL_HKDF=yes -DWOLFSSL_PUBLIC_MP=yes \ + -DWOLFSSL_WC_RSA_DIRECT=yes -DWOLFSSL_EXAMPLES=no -DWOLFSSL_CRYPT_TESTS=no + cmake --build build + cmake --install build + +#setup wolfPKCS11 + - name: Build and test wolfPKCS11 + run: | + cmake -B build -DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/wolfssl-install \ + -DWOLFPKCS11_STATIC_WOLFSSL=yes -DWOLFPKCS11_PBKDF2=yes + cmake --build build + ctest --test-dir build --output-on-failure + - name: Check the library is self-contained + run: | + lib=$(readlink -f build/libwolfpkcs11.so) + dyn=$(readelf -d "$lib") + syms=$(nm -D --defined-only "$lib") + if grep -E 'NEEDED.*libwolfssl|TEXTREL' <<<"$dyn"; then exit 1; fi + if grep -v ' C_' <<<"$syms"; then exit 1; fi + for f in C_GetFunctionList C_GetInterface C_LoginUser; do + grep -qw "$f" <<<"$syms" + done + - name: Run the wolfSSL interoperability test against the library + run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/build/libwolfpkcs11.so + - name: Build a find_package consumer without wolfSSL + run: | + cmake --install build --prefix $RUNNER_TEMP/wolfpkcs11 + cmake -S cmake/consumer -B consumer-build -DCMAKE_PREFIX_PATH=$RUNNER_TEMP/wolfpkcs11 + cmake --build consumer-build + LD_LIBRARY_PATH=$RUNNER_TEMP/wolfpkcs11/lib ./consumer-build/wolfpkcs11_consumer diff --git a/CMakeLists.txt b/CMakeLists.txt index 3989eaad..897bf2a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -599,6 +599,11 @@ set(LIB_SOURCES src/slot.c src/crypto.c ) + +add_option("WOLFPKCS11_STATIC_WOLFSSL" + "Link a static wolfSSL into the shared library and hide its symbols (default: disabled)" + "no" "yes;no") + if(BUILD_SHARED_LIBS) message(STATUS "BUILD_SHARED_LIBS enabled: ${LIB_SOURCES}") add_library(wolfpkcs11 SHARED ${LIB_SOURCES}) @@ -631,6 +636,10 @@ set_target_properties(wolfpkcs11 ) target_compile_definitions(wolfpkcs11 PRIVATE "BUILDING_WOLFPKCS11") +if(NOT WIN32 AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + set_target_properties(wolfpkcs11 PROPERTIES C_VISIBILITY_PRESET hidden) + target_compile_definitions(wolfpkcs11 PRIVATE "HAVE_VISIBILITY=1") +endif() target_compile_definitions(wolfpkcs11 PRIVATE ${WOLFPKCS11_DEFINITIONS}) # Determine library filename for WOLFPKCS11_DLL_FILENAME @@ -728,7 +737,33 @@ else() # Try to find wolfSSL as an installed package find_package(wolfssl REQUIRED) endif() -list(APPEND WOLFPKCS11_LINK_LIBS wolfssl::wolfssl) + +if(WOLFPKCS11_STATIC_WOLFSSL) + get_target_property(WOLFSSL_LIB_TYPE wolfssl::wolfssl TYPE) + if(WOLFSSL_LIB_TYPE STREQUAL "UNKNOWN_LIBRARY") + get_target_property(WOLFSSL_LIB_PATH wolfssl::wolfssl IMPORTED_LOCATION) + if(WOLFSSL_LIB_PATH MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") + set(WOLFSSL_LIB_TYPE "STATIC_LIBRARY") + endif() + endif() + + if(NOT BUILD_SHARED_LIBS) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs BUILD_SHARED_LIBS") + elseif(APPLE OR WIN32) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs an ELF linker") + elseif(WOLFPKCS11_TPM) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL cannot be combined with WOLFPKCS11_TPM") + elseif(NOT WOLFSSL_LIB_TYPE STREQUAL "STATIC_LIBRARY") + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs a static wolfSSL library") + endif() + + target_link_libraries(wolfpkcs11 PRIVATE wolfssl::wolfssl) + target_link_options(wolfpkcs11 PRIVATE + "LINKER:--exclude-libs,ALL" "LINKER:-Bsymbolic" "LINKER:-z,text" + "LINKER:-z,defs") +else() + list(APPEND WOLFPKCS11_LINK_LIBS wolfssl::wolfssl) +endif() # Other libraries target_link_libraries(wolfpkcs11 PUBLIC ${WOLFPKCS11_LINK_LIBS}) @@ -775,6 +810,7 @@ if(WOLFPKCS11_TESTS) add_wpkcs11_test(${test_target} ${CMAKE_CURRENT_SOURCE_DIR}/tests/${test_target}.c) endforeach() + set_tests_properties(debug_test PROPERTIES SKIP_RETURN_CODE 77) # HBS (LMS/HSS, XMSS/XMSS^MT) public-key persistence test. Only built when # the feature is enabled; the test exits 77 (skip) when no token store is diff --git a/README.md b/README.md index dc44f1a6..f9a1e02d 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,39 @@ As ML-KEM is a feature of PKCS#11 version 3.2, support for that is required, too. Hence, to enable all in wolfPKCS11, add `--enable-pkcs11v32 --enable-mlkem` during the configure step. +### Optional: Self-contained library with static wolfSSL + +By default libwolfpkcs11 loads libwolfssl at run time. To ship a single +library instead, build wolfSSL as a static library with position independent +code and link it into libwolfpkcs11: + +```sh +cd wolfssl +./configure --enable-static --disable-shared --with-pic --enable-cryptonly \ + --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased \ + --enable-scrypt \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" +make +sudo make install + +cd ../wolfPKCS11 +./configure --with-static-wolfssl=/usr/local/lib/libwolfssl.a +make +``` + +The wolfSSL symbols stay hidden inside libwolfpkcs11, so an application using +its own wolfSSL, even with a different configuration, can load the module with +`dlopen()` or `wc_Pkcs11_Initialize()`. Settings the application makes on its +own wolfSSL, such as `wolfSSL_SetAllocators()`, do not reach the module. A +wolfSSL update requires rebuilding libwolfpkcs11. This option needs an ELF +linker (GNU ld, gold or lld) and cannot be combined with wolfTPM support. If +the static wolfSSL needs other libraries, such as zlib, pass them in `LIBS`: +the ones `pkg-config --static --libs wolfssl` lists after `-lwolfssl`. + +With CMake, build wolfSSL with `-DBUILD_SHARED_LIBS=OFF` and +`-DCMAKE_POSITION_INDEPENDENT_CODE=ON`, then configure wolfPKCS11 with +`-DWOLFPKCS11_STATIC_WOLFSSL=yes`. + ### Build options and defines #### Define WOLFPKCS11_TPM_STORE @@ -295,6 +328,7 @@ cmake -DCMAKE_PREFIX_PATH=/path/to/wolfssl/install .. | `WOLFPKCS11_DEFAULT_TOKEN_PATH` | `""` | Default token storage path compiled into library | | `WOLFPKCS11_BUILD_OUT_OF_TREE` | `yes` | Generate build artifacts outside source tree | | `BUILD_SHARED_LIBS` | `ON` | Build shared (`ON`) or static (`OFF`) library | +| `WOLFPKCS11_STATIC_WOLFSSL` | `no` | Link a static wolfSSL into the shared library and hide its symbols | Note: wolfSSL must be built with the corresponding features enabled for the options above to work (e.g. enabling `WOLFPKCS11_AESCCM` requires wolfSSL built diff --git a/cmake/consumer/CMakeLists.txt b/cmake/consumer/CMakeLists.txt new file mode 100644 index 00000000..a4c2d040 --- /dev/null +++ b/cmake/consumer/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +project(wolfpkcs11_consumer C) + +find_package(wolfpkcs11 REQUIRED) + +add_executable(wolfpkcs11_consumer main.c) +target_link_libraries(wolfpkcs11_consumer PRIVATE wolfpkcs11::wolfpkcs11) diff --git a/cmake/consumer/main.c b/cmake/consumer/main.c new file mode 100644 index 00000000..9db6b98a --- /dev/null +++ b/cmake/consumer/main.c @@ -0,0 +1,32 @@ +/* main.c + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfPKCS11. + * + * wolfPKCS11 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfPKCS11 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +int main(void) +{ + CK_FUNCTION_LIST_PTR funcList = NULL; + + if (C_GetFunctionList(&funcList) != CKR_OK || funcList == NULL) { + return 1; + } + return 0; +} diff --git a/cmake/wolfpkcs11Config.cmake.in b/cmake/wolfpkcs11Config.cmake.in index ca33f0c0..57da0aae 100644 --- a/cmake/wolfpkcs11Config.cmake.in +++ b/cmake/wolfpkcs11Config.cmake.in @@ -5,7 +5,9 @@ if("@HAVE_PTHREAD@" STREQUAL "1") endif() include(CMakeFindDependencyMacro) -find_dependency(wolfssl) +if(NOT "@WOLFPKCS11_STATIC_WOLFSSL@" STREQUAL "yes") + find_dependency(wolfssl) +endif() if (_wolfpkcs11_needs_threads) find_dependency(Threads) endif() diff --git a/cmake/wolfpkcs11Targets.cmake.in b/cmake/wolfpkcs11Targets.cmake.in index dcd83dcb..21b8b556 100644 --- a/cmake/wolfpkcs11Targets.cmake.in +++ b/cmake/wolfpkcs11Targets.cmake.in @@ -19,9 +19,11 @@ if (NOT TARGET wolfpkcs11::wolfpkcs11) INTERFACE_INCLUDE_DIRECTORIES "${_wolfpkcs11_includedir}" ) - set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY - INTERFACE_LINK_LIBRARIES wolfssl::wolfssl - ) + if (NOT "@WOLFPKCS11_STATIC_WOLFSSL@" STREQUAL "yes") + set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY + INTERFACE_LINK_LIBRARIES wolfssl::wolfssl + ) + endif() if (@HAVE_PTHREAD@) set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY diff --git a/configure.ac b/configure.ac index 24ea49bc..44950f26 100644 --- a/configure.ac +++ b/configure.ac @@ -629,13 +629,46 @@ fi AM_CONDITIONAL([BUILD_STATIC],[test "x$enable_shared" = "xno"]) +# STATIC WOLFSSL +AC_ARG_WITH([static-wolfssl], + [AS_HELP_STRING([--with-static-wolfssl=FILE],[Link the wolfSSL static library FILE into the shared library and hide its symbols (default: disabled)])], + [ STATIC_WOLFSSL=$withval ], + [ STATIC_WOLFSSL=no ]) + +WOLFPKCS11_STATIC_WOLFSSL=no +STATIC_WOLFSSL_DEP= +AS_IF([test "x$STATIC_WOLFSSL" != "xno"],[ + AS_CASE([$STATIC_WOLFSSL], + [*.a],[AS_IF([test ! -f "$STATIC_WOLFSSL"], + [AC_MSG_ERROR([--with-static-wolfssl: $STATIC_WOLFSSL not found])])], + [AC_MSG_ERROR([--with-static-wolfssl needs the path to libwolfssl.a])]) + AS_IF([test "x$enable_shared" = "xno"], + [AC_MSG_ERROR([--with-static-wolfssl needs a shared library build])]) + AS_IF([test "x$enable_static" = "xyes"], + [AC_MSG_ERROR([--with-static-wolfssl cannot be combined with --enable-static])]) + AS_IF([test "x$ENABLED_TPM" = "xyes"], + [AC_MSG_ERROR([--with-static-wolfssl cannot be combined with --enable-wolftpm])]) + AX_CHECK_LINK_FLAG([-Wl,--exclude-libs,ALL -Wl,-Bsymbolic -Wl,-z,text -Wl,-z,defs],[], + [AC_MSG_ERROR([--with-static-wolfssl needs a linker supporting --exclude-libs, -Bsymbolic, -z text and -z defs])]) + WOLFPKCS11_STATIC_WOLFSSL=yes + STATIC_WOLFSSL_DEP="$STATIC_WOLFSSL" + ]) +AM_CONDITIONAL([BUILD_STATIC_WOLFSSL],[test "x$WOLFPKCS11_STATIC_WOLFSSL" = "xyes"]) +AC_SUBST([WOLFPKCS11_STATIC_WOLFSSL]) +AC_SUBST([STATIC_WOLFSSL_DEP]) + + # HARDEN FLAGS AX_HARDEN_CC_COMPILER_FLAGS OPTION_FLAGS="$CFLAGS $CPPFLAGS $AM_CFLAGS" -LIBS="$LIBS -lwolfssl -lm" +AS_IF([test "x$WOLFPKCS11_STATIC_WOLFSSL" = "xyes"], + [WOLFPKCS11_CONFIG_LIBS="$LIBS -lm" + LIBS="$STATIC_WOLFSSL $LIBS -lm"], + [LIBS="$LIBS -lwolfssl -lm" + WOLFPKCS11_CONFIG_LIBS="$LIBS"]) CREATE_HEX_VERSION AC_SUBST([AM_CPPFLAGS]) @@ -645,8 +678,14 @@ AC_SUBST([AM_LDFLAGS]) PACKAGE_INIT='get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)' AC_SUBST([PACKAGE_INIT]) +wolfpkcs11_save_prefix=$prefix +wolfpkcs11_save_exec_prefix=$exec_prefix +test "x$prefix" = "xNONE" && prefix=$ac_default_prefix +test "x$exec_prefix" = "xNONE" && exec_prefix=$prefix WOLFPKCS11_LIBDIR_ABS=`eval echo "$libdir"` WOLFPKCS11_INCLUDEDIR_ABS=`eval echo "$includedir"` +prefix=$wolfpkcs11_save_prefix +exec_prefix=$wolfpkcs11_save_exec_prefix AC_SUBST([WOLFPKCS11_LIBDIR_ABS]) AC_SUBST([WOLFPKCS11_INCLUDEDIR_ABS]) @@ -660,7 +699,7 @@ AS_IF([test "x$ENABLED_CMAKE_INSTALL" = "xyes"],[ AC_CONFIG_FILES([cmake/wolfpkcs11ConfigVersion.cmake:cmake/wolfpkcs11ConfigVersion.cmake.in]) ]) -AX_CREATE_GENERIC_CONFIG +AX_CREATE_GENERIC_CONFIG([$PACKAGE $WOLFPKCS11_CONFIG_LIBS]) AX_AM_JOBSERVER([yes]) AC_OUTPUT diff --git a/src/include.am b/src/include.am index f54ea410..2c5d4e50 100644 --- a/src/include.am +++ b/src/include.am @@ -13,6 +13,9 @@ src_libwolfpkcs11_la_SOURCES = \ src_libwolfpkcs11_la_CFLAGS = -DBUILDING_WOLFPKCS11 $(AM_CFLAGS) src_libwolfpkcs11_la_CPPFLAGS = -DBUILDING_WOLFPKCS11 $(AM_CPPFLAGS) src_libwolfpkcs11_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-number ${WOLFPKCS11_LIBRARY_VERSION} +if BUILD_STATIC_WOLFSSL +src_libwolfpkcs11_la_LDFLAGS += -Wl,--exclude-libs,ALL -Wl,-Bsymbolic -Wl,-z,text -Wl,-z,defs +endif -#src_libwolfpkcs11_la_DEPENDENCIES = +src_libwolfpkcs11_la_DEPENDENCIES = $(STATIC_WOLFSSL_DEP) #EXTRA_DIST += diff --git a/tests/include.am b/tests/include.am index 8d234f41..6227e4f4 100644 --- a/tests/include.am +++ b/tests/include.am @@ -240,7 +240,6 @@ noinst_PROGRAMS += tests/aes_keywrap_pad_test tests_aes_keywrap_pad_test_SOURCES = tests/aes_keywrap_pad_test.c tests_aes_keywrap_pad_test_LDADD = -check_PROGRAMS += tests/mlkem_secret_scrub_test noinst_PROGRAMS += tests/mlkem_secret_scrub_test tests_mlkem_secret_scrub_test_SOURCES = tests/mlkem_secret_scrub_test.c tests_mlkem_secret_scrub_test_LDADD = @@ -285,11 +284,9 @@ noinst_PROGRAMS += tests/unique_id_test tests_unique_id_test_SOURCES = tests/unique_id_test.c tests_unique_id_test_LDADD = -check_PROGRAMS += tests/token_reset_fail_test noinst_PROGRAMS += tests/token_reset_fail_test tests_token_reset_fail_test_SOURCES = tests/token_reset_fail_test.c tests_token_reset_fail_test_LDADD = -check_PROGRAMS += tests/token_store_test noinst_PROGRAMS += tests/token_store_test tests_token_store_test_SOURCES = tests/token_store_test.c tests_token_store_test_LDADD = @@ -339,7 +336,6 @@ noinst_PROGRAMS += tests/nss_configdir_prefix_test tests_nss_configdir_prefix_test_SOURCES = tests/nss_configdir_prefix_test.c tests_nss_configdir_prefix_test_LDADD = -check_PROGRAMS += tests/logout_retire_test noinst_PROGRAMS += tests/logout_retire_test tests_logout_retire_test_SOURCES = tests/logout_retire_test.c tests_logout_retire_test_LDADD = @@ -349,7 +345,6 @@ noinst_PROGRAMS += tests/login_pin_state_test tests_login_pin_state_test_SOURCES = tests/login_pin_state_test.c tests_login_pin_state_test_LDADD = -check_PROGRAMS += tests/object_store_decode_test noinst_PROGRAMS += tests/object_store_decode_test tests_object_store_decode_test_SOURCES = tests/object_store_decode_test.c tests_object_store_decode_test_LDADD = @@ -360,22 +355,18 @@ tests_object_policy_integrity_test_SOURCES = \ tests/object_policy_integrity_test.c tests_object_policy_integrity_test_LDADD = -check_PROGRAMS += tests/session_op_lifecycle_test noinst_PROGRAMS += tests/session_op_lifecycle_test tests_session_op_lifecycle_test_SOURCES = tests/session_op_lifecycle_test.c tests_session_op_lifecycle_test_LDADD = -check_PROGRAMS += tests/info_mech_table_test noinst_PROGRAMS += tests/info_mech_table_test tests_info_mech_table_test_SOURCES = tests/info_mech_table_test.c tests_info_mech_table_test_LDADD = -check_PROGRAMS += tests/attribute_validation_test noinst_PROGRAMS += tests/attribute_validation_test tests_attribute_validation_test_SOURCES = tests/attribute_validation_test.c tests_attribute_validation_test_LDADD = -check_PROGRAMS += tests/key_material_update_test noinst_PROGRAMS += tests/key_material_update_test tests_key_material_update_test_SOURCES = tests/key_material_update_test.c tests_key_material_update_test_LDADD = @@ -400,12 +391,10 @@ noinst_PROGRAMS += tests/digest_length_test tests_digest_length_test_SOURCES = tests/digest_length_test.c tests_digest_length_test_LDADD = -check_PROGRAMS += tests/secret_scrub_test noinst_PROGRAMS += tests/secret_scrub_test tests_secret_scrub_test_SOURCES = tests/secret_scrub_test.c tests_secret_scrub_test_LDADD = -check_PROGRAMS += tests/unwrap_keygen_test noinst_PROGRAMS += tests/unwrap_keygen_test tests_unwrap_keygen_test_SOURCES = tests/unwrap_keygen_test.c tests_unwrap_keygen_test_LDADD = @@ -415,6 +404,20 @@ noinst_PROGRAMS += tests/token_partial_store_test tests_token_partial_store_test_SOURCES = tests/token_partial_store_test.c tests_token_partial_store_test_LDADD = +if !BUILD_STATIC_WOLFSSL +check_PROGRAMS += tests/token_store_test +check_PROGRAMS += tests/logout_retire_test +check_PROGRAMS += tests/session_op_lifecycle_test +check_PROGRAMS += tests/info_mech_table_test +check_PROGRAMS += tests/attribute_validation_test +check_PROGRAMS += tests/key_material_update_test +check_PROGRAMS += tests/secret_scrub_test +check_PROGRAMS += tests/object_store_decode_test +check_PROGRAMS += tests/mlkem_secret_scrub_test +check_PROGRAMS += tests/token_reset_fail_test +check_PROGRAMS += tests/unwrap_keygen_test +endif + if BUILD_STATIC tests_pkcs11test_LDADD += src/libwolfpkcs11.la tests_pkcs11mtt_LDADD += src/libwolfpkcs11.la diff --git a/tests/wolfssl-interoperability/Makefile b/tests/wolfssl-interoperability/Makefile index 06bc49fb..85316aaf 100644 --- a/tests/wolfssl-interoperability/Makefile +++ b/tests/wolfssl-interoperability/Makefile @@ -9,6 +9,8 @@ WOLFSSL_DIR ?= ../../wolfssl WOLFPKCS11_DIR ?= ../.. BUILD_DIR := build +INTEROP_MODULE := $(BUILD_DIR)/libwolfpkcs11-interop.so +WOLFPKCS11_MODULE ?= $(INTEROP_MODULE) COMMON_CPPFLAGS := -DWOLFSSL_USER_SETTINGS -DWOLFPKCS11_USER_SETTINGS -I. -I.. \ -I$(WOLFSSL_DIR) -I$(WOLFSSL_DIR)/wolfssl -I$(WOLFSSL_DIR)/wolfssl/wolfcrypt \ @@ -64,7 +66,7 @@ TEST_OBJS := $(patsubst %.c,$(BUILD_DIR)/interop-test/%.o,$(TEST_SRCS)) all: test -interop: $(BUILD_DIR)/pkcs11_interop +interop: $(BUILD_DIR)/pkcs11_interop check-module $(BUILD_DIR)/wolfssl/%.o: $(WOLFSSL_DIR)/%.c @mkdir -p $(dir $@) @@ -86,14 +88,24 @@ $(BUILD_DIR)/libwolfpkcs11-interop.so: $(ENGINE_OBJS) $(BUILD_DIR)/libwolfcrypt- @mkdir -p $(dir $@) $(CC) -shared -o $@ $(ENGINE_OBJS) -L$(BUILD_DIR) -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) -$(BUILD_DIR)/pkcs11_interop: $(TEST_OBJS) $(BUILD_DIR)/libwolfpkcs11-interop.so $(BUILD_DIR)/libwolfcrypt-interop.so - $(CC) -o $@ $(TEST_OBJS) -L$(BUILD_DIR) -lwolfpkcs11-interop -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) +$(BUILD_DIR)/pkcs11_interop: $(TEST_OBJS) $(BUILD_DIR)/libwolfcrypt-interop.so + $(CC) -o $@ $(TEST_OBJS) -L$(BUILD_DIR) -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) + +.PHONY: check-module +check-module: $(WOLFPKCS11_MODULE) +ifneq ($(WOLFPKCS11_MODULE),$(INTEROP_MODULE)) + @dyn=$$(readelf -d $(WOLFPKCS11_MODULE)) || exit 1; \ + if echo "$$dyn" | grep -q 'NEEDED.*libwolfssl'; then \ + echo "$(WOLFPKCS11_MODULE) depends on libwolfssl; use the interop module or a --with-static-wolfssl build"; \ + exit 1; \ + fi +endif .PHONY: test -test: $(BUILD_DIR)/pkcs11_interop - WOLFPKCS11_MODULE=$(BUILD_DIR)/libwolfpkcs11-interop.so LD_LIBRARY_PATH=$(BUILD_DIR) $(BUILD_DIR)/pkcs11_interop -debug: $(BUILD_DIR)/pkcs11_interop - WOLFPKCS11_MODULE=$(BUILD_DIR)/libwolfpkcs11-interop.so LD_LIBRARY_PATH=$(BUILD_DIR) gdb $(BUILD_DIR)/pkcs11_interop +test: $(BUILD_DIR)/pkcs11_interop check-module + WOLFPKCS11_MODULE=$(WOLFPKCS11_MODULE) LD_LIBRARY_PATH=$(BUILD_DIR) $(BUILD_DIR)/pkcs11_interop +debug: $(BUILD_DIR)/pkcs11_interop check-module + WOLFPKCS11_MODULE=$(WOLFPKCS11_MODULE) LD_LIBRARY_PATH=$(BUILD_DIR) gdb $(BUILD_DIR)/pkcs11_interop .PHONY: clean clean: diff --git a/tests/wolfssl-interoperability/pkcs11_interop.c b/tests/wolfssl-interoperability/pkcs11_interop.c index 8cff984f..8bf71e39 100644 --- a/tests/wolfssl-interoperability/pkcs11_interop.c +++ b/tests/wolfssl-interoperability/pkcs11_interop.c @@ -1141,6 +1141,8 @@ int main(int argc, char** argv) int dev_id = 23; int ret; int failures = 0; + void* probe; + void (*debug_on)(void); if (module_path == NULL) { module_path = (argc > 1) ? argv[1] : "./build/libwolfpkcs11-interop.so"; @@ -1155,22 +1157,28 @@ int main(int argc, char** argv) memset(&dev, 0, sizeof(dev)); memset(&token, 0, sizeof(token)); - { - void* probe = dlopen(module_path, RTLD_NOW | RTLD_LOCAL); - if (probe == NULL) { - fprintf(stderr, "dlopen failed for %s: %s\n", module_path, dlerror()); - return EXIT_FAILURE; - } - void (*debug_on)(void) = (void (*)(void))dlsym(probe, - "wolfPKCS11_Debugging_On"); - if (debug_on != NULL) - debug_on(); + probe = dlopen(module_path, RTLD_NOW | RTLD_LOCAL); + if (probe == NULL) { + fprintf(stderr, "dlopen failed for %s: %s\n", module_path, dlerror()); + return EXIT_FAILURE; + } + debug_on = (void (*)(void))dlsym(probe, "wolfPKCS11_Debugging_On"); + if (debug_on != NULL) + debug_on(); + + ret = wolfCrypt_Init(); + if (ret != 0) { + fprintf(stderr, "wolfCrypt_Init failed: %d\n", ret); dlclose(probe); + return EXIT_FAILURE; } ret = init_token(module_path, &dev, &token, &slot_id); - if (ret != 0) + if (ret != 0) { + wolfCrypt_Cleanup(); + dlclose(probe); return EXIT_FAILURE; + } ret = wc_CryptoCb_RegisterDevice(dev_id, wc_Pkcs11_CryptoDevCb, &token); if (ret != 0) { @@ -1366,6 +1374,8 @@ int main(int argc, char** argv) wc_Pkcs11Token_Close(&token); wc_Pkcs11Token_Final(&token); wc_Pkcs11_Finalize(&dev); + wolfCrypt_Cleanup(); + dlclose(probe); if (failures == 0) { printf("All wolfPKCS11 interoperability tests passed.\n"); diff --git a/wolfpkcs11/pkcs11.h b/wolfpkcs11/pkcs11.h index 03bd305e..94f3c389 100644 --- a/wolfpkcs11/pkcs11.h +++ b/wolfpkcs11/pkcs11.h @@ -1149,92 +1149,92 @@ WP11_API CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags); -CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, +WP11_API CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen); -CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags); -CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, +WP11_API CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags); +WP11_API CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen); -CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen); -CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags); -CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, CK_ULONG_PTR pulPlaintextLen); -CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen); -CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags); -CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); -CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen); -CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); -CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen); -CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession); /* PKCS#11 V 3.2 functions */ -CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey); -CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPrivateKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, CK_ULONG ulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey); -CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, +WP11_API CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen); -CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, +WP11_API CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen); -CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession); -CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, +WP11_API CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, CK_FLAGS * pFlags); -CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ASYNC_DATA_PTR pResult); -CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ULONG_PTR pulID); -CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData);