diff --git a/openssl-ibmca-2.4.1-fixes.patch b/openssl-ibmca-2.4.1-fixes.patch new file mode 100644 index 0000000..cb1df73 --- /dev/null +++ b/openssl-ibmca-2.4.1-fixes.patch @@ -0,0 +1,423 @@ +From 7186bff3fa2a3dd939e1bc0fed48e733da4477a7 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Mon, 8 Jan 2024 08:52:24 +0100 +Subject: [PATCH 1/4] engine: Enable external AES-GCM IV when libica is in FIPS + mode + +When the system is in FIPS mode, newer libica versions may prevent AES-GCM +from being used with an external IV. FIPS requires that the AES-GCM IV is +created libica internally via an approved random source. + +The IBMCA engine can not support the internal generation of the AES-GCM IV, +because the engine API for AES-GCM does not allow this. Applications using +OpenSSL to perform AES-GCM (e.g. the TLS protocol) may require to provide an +external IV. + +Enable the use of external AES-GCM IVs for libica, if the used libica library +supports this. Newer libica versions support to allow external AES-GCM IVs via +function ica_allow_external_gcm_iv_in_fips_mode(). + +Signed-off-by: Ingo Franzki +--- + src/engine/e_ibmca.c | 12 +++++++++++- + src/engine/ibmca.h | 1 + + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/engine/e_ibmca.c b/src/engine/e_ibmca.c +index 6cbf745..afed3fe 100644 +--- a/src/engine/e_ibmca.c ++++ b/src/engine/e_ibmca.c +@@ -103,6 +103,8 @@ ica_aes_gcm_intermediate_t p_ica_aes_gcm_intermediate; + ica_aes_gcm_last_t p_ica_aes_gcm_last; + #endif + ica_cleanup_t p_ica_cleanup; ++ica_allow_external_gcm_iv_in_fips_mode_t ++ p_ica_allow_external_gcm_iv_in_fips_mode; + + /* save libcrypto's default ec methods */ + #ifndef NO_EC +@@ -825,7 +827,15 @@ static int ibmca_init(ENGINE *e) + BIND(ibmca_dso, ica_ed448_ctx_del); + + /* ica_cleanup is not always present and only needed for newer libraries */ +- p_ica_cleanup = (ica_cleanup_t)dlsym(ibmca_dso, "ica_cleanup"); ++ BIND(ibmca_dso, ica_cleanup); ++ ++ /* ++ * Allow external AES-GCM IV when libica runs in FIPS mode. ++ * ica_allow_external_gcm_iv_in_fips_mode() is not always present and only ++ * available with newer libraries. ++ */ ++ if (BIND(ibmca_dso, ica_allow_external_gcm_iv_in_fips_mode)) ++ p_ica_allow_external_gcm_iv_in_fips_mode(1); + + /* disable fallbacks on Libica */ + if (BIND(ibmca_dso, ica_set_fallback_mode)) +diff --git a/src/engine/ibmca.h b/src/engine/ibmca.h +index 7281a5b..01465eb 100644 +--- a/src/engine/ibmca.h ++++ b/src/engine/ibmca.h +@@ -617,6 +617,7 @@ typedef + int (*ica_ed448_ctx_del_t)(ICA_ED448_CTX **ctx); + + typedef void (*ica_cleanup_t)(void); ++typedef void (*ica_allow_external_gcm_iv_in_fips_mode_t)(int allow); + + /* entry points into libica, filled out at DSO load time */ + extern ica_get_functionlist_t p_ica_get_functionlist; +-- +2.45.1 + + +From 2f420ff28cedfea2ca730d7e54dba39fa4e06cbc Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Wed, 10 Jan 2024 15:08:47 +0100 +Subject: [PATCH 2/4] test/provider: Do not link against libica use dlopen + instead + +When an application links against libica (via -lica), then the libica library +constructor runs before the program's main function. Libica's library +constructor does initialize OpenSSL and thus parses the config file. + +However, the test programs set up some OpenSSL configuration related +environment variables within function check_libica() called from the +main function. If libica has already initialized OpenSSL prior to that, +OpenSSL won't initialize again, and thus these environment variables have +no effect. + +Dynamically load libica (via dlopen) only after setting the environment +variables. + +Signed-off-by: Ingo Franzki +--- + configure.ac | 2 ++ + test/provider/Makefile.am | 15 +++++++++------ + test/provider/dhkey.c | 24 ++++++++++++++++++++++-- + test/provider/eckey.c | 24 ++++++++++++++++++++++-- + test/provider/rsakey.c | 24 ++++++++++++++++++++++-- + 5 files changed, 77 insertions(+), 12 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b43a659..09df230 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -116,6 +116,8 @@ AC_ARG_WITH([provider-libica-full], + []) + AM_CONDITIONAL([PROVIDER_FULL_LIBICA], [test "x$useproviderfulllibica" = xyes]) + ++AC_SUBST(libicaversion, "$libicaversion") ++ + # If compiled against OpenSSL 3.0 or later, build the provider unless + # explicitely disabled. + # If build against OpenSSL 1.1.1, we can not build the provider. +diff --git a/test/provider/Makefile.am b/test/provider/Makefile.am +index 15a5466..fce06b3 100644 +--- a/test/provider/Makefile.am ++++ b/test/provider/Makefile.am +@@ -24,24 +24,27 @@ TESTS = \ + check_PROGRAMS = rsakey eckey dhkey threadtest + + dhkey_SOURCES = dhkey.c ++dhkey_LDADD = -lcrypto -ldl + if PROVIDER_FULL_LIBICA +-dhkey_LDADD = -lcrypto -lica ++dhkey_CFLAGS = -DLIBICA_NAME=\"libica.so.@libicaversion@\" + else +-dhkey_LDADD = -lcrypto -lica-cex ++dhkey_CFLAGS = -DLIBICA_NAME=\"libica-cex.so.@libicaversion@\" + endif + + eckey_SOURCES = eckey.c ++eckey_LDADD = -lcrypto -ldl + if PROVIDER_FULL_LIBICA +-eckey_LDADD = -lcrypto -lica ++eckey_CFLAGS = -DLIBICA_NAME=\"libica.so.@libicaversion@\" + else +-eckey_LDADD = -lcrypto -lica-cex ++eckey_CFLAGS = -DLIBICA_NAME=\"libica-cex.so.@libicaversion@\" + endif + + rsakey_SOURCES = rsakey.c ++rsakey_LDADD = -lcrypto -ldl + if PROVIDER_FULL_LIBICA +-rsakey_LDADD = -lcrypto -lica ++rsakey_CFLAGS = -DLIBICA_NAME=\"libica.so.@libicaversion@\" + else +-rsakey_LDADD = -lcrypto -lica-cex ++rsakey_CFLAGS = -DLIBICA_NAME=\"libica-cex.so.@libicaversion@\" + endif + + threadtest_SOURCES = threadtest.c +diff --git a/test/provider/dhkey.c b/test/provider/dhkey.c +index 8829ecc..0ec2c03 100644 +--- a/test/provider/dhkey.c ++++ b/test/provider/dhkey.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -355,13 +356,32 @@ static const unsigned int required_ica_mechs[] = { RSA_ME }; + static const unsigned int required_ica_mechs_len = + sizeof(required_ica_mechs) / sizeof(unsigned int); + ++typedef unsigned int (*ica_get_functionlist_t)(libica_func_list_element *, ++ unsigned int *); ++ + int check_libica() + { + unsigned int mech_len, i, k, found = 0; + libica_func_list_element *mech_list = NULL; ++ void *ibmca_dso; ++ ica_get_functionlist_t p_ica_get_functionlist; + int rc; + +- rc = ica_get_functionlist(NULL, &mech_len); ++ ibmca_dso = dlopen(LIBICA_NAME, RTLD_NOW); ++ if (ibmca_dso == NULL) { ++ fprintf(stderr, "Failed to load libica '%s'!\n", LIBICA_NAME); ++ return 77; ++ } ++ ++ p_ica_get_functionlist = ++ (ica_get_functionlist_t)dlsym(ibmca_dso, "ica_get_functionlist"); ++ if (p_ica_get_functionlist == NULL) { ++ fprintf(stderr, "Failed to get ica_get_functionlist from '%s'!\n", ++ LIBICA_NAME); ++ return 77; ++ } ++ ++ rc = p_ica_get_functionlist(NULL, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + return 77; +@@ -373,7 +393,7 @@ int check_libica() + return 77; + } + +- rc = ica_get_functionlist(mech_list, &mech_len); ++ rc = p_ica_get_functionlist(mech_list, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + free(mech_list); +diff --git a/test/provider/eckey.c b/test/provider/eckey.c +index b2334d7..b8f47b7 100644 +--- a/test/provider/eckey.c ++++ b/test/provider/eckey.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -788,13 +789,32 @@ static const unsigned int required_ica_mechs[] = { EC_DH, EC_DSA_SIGN, + static const unsigned int required_ica_mechs_len = + sizeof(required_ica_mechs) / sizeof(unsigned int); + ++typedef unsigned int (*ica_get_functionlist_t)(libica_func_list_element *, ++ unsigned int *); ++ + int check_libica() + { + unsigned int mech_len, i, k, found = 0; + libica_func_list_element *mech_list = NULL; ++ void *ibmca_dso; ++ ica_get_functionlist_t p_ica_get_functionlist; + int rc; + +- rc = ica_get_functionlist(NULL, &mech_len); ++ ibmca_dso = dlopen(LIBICA_NAME, RTLD_NOW); ++ if (ibmca_dso == NULL) { ++ fprintf(stderr, "Failed to load libica '%s'!\n", LIBICA_NAME); ++ return 77; ++ } ++ ++ p_ica_get_functionlist = ++ (ica_get_functionlist_t)dlsym(ibmca_dso, "ica_get_functionlist"); ++ if (p_ica_get_functionlist == NULL) { ++ fprintf(stderr, "Failed to get ica_get_functionlist from '%s'!\n", ++ LIBICA_NAME); ++ return 77; ++ } ++ ++ rc = p_ica_get_functionlist(NULL, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + return 77; +@@ -806,7 +826,7 @@ int check_libica() + return 77; + } + +- rc = ica_get_functionlist(mech_list, &mech_len); ++ rc = p_ica_get_functionlist(mech_list, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + free(mech_list); +diff --git a/test/provider/rsakey.c b/test/provider/rsakey.c +index 366b503..9d6a618 100644 +--- a/test/provider/rsakey.c ++++ b/test/provider/rsakey.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -735,13 +736,32 @@ static const unsigned int required_ica_mechs[] = { RSA_ME, RSA_CRT }; + static const unsigned int required_ica_mechs_len = + sizeof(required_ica_mechs) / sizeof(unsigned int); + ++typedef unsigned int (*ica_get_functionlist_t)(libica_func_list_element *, ++ unsigned int *); ++ + int check_libica() + { + unsigned int mech_len, i, k, found = 0; + libica_func_list_element *mech_list = NULL; ++ void *ibmca_dso; ++ ica_get_functionlist_t p_ica_get_functionlist; + int rc; + +- rc = ica_get_functionlist(NULL, &mech_len); ++ ibmca_dso = dlopen(LIBICA_NAME, RTLD_NOW); ++ if (ibmca_dso == NULL) { ++ fprintf(stderr, "Failed to load libica '%s'!\n", LIBICA_NAME); ++ return 77; ++ } ++ ++ p_ica_get_functionlist = ++ (ica_get_functionlist_t)dlsym(ibmca_dso, "ica_get_functionlist"); ++ if (p_ica_get_functionlist == NULL) { ++ fprintf(stderr, "Failed to get ica_get_functionlist from '%s'!\n", ++ LIBICA_NAME); ++ return 77; ++ } ++ ++ rc = p_ica_get_functionlist(NULL, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + return 77; +@@ -753,7 +773,7 @@ int check_libica() + return 77; + } + +- rc = ica_get_functionlist(mech_list, &mech_len); ++ rc = p_ica_get_functionlist(mech_list, &mech_len); + if (rc != 0) { + fprintf(stderr, "Failed to get function list from libica!\n"); + free(mech_list); +-- +2.45.1 + + +From d2254c6641b1cf34d5f735f335edf9a05ddfd67e Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Thu, 18 Jan 2024 16:35:14 +0100 +Subject: [PATCH 3/4] test/provider: Explicitly initialize OpenSSL after + setting env vars. + +When running with a libica version without commit +https://github.com/opencryptoki/libica/commit/42e197f61b298c6e6992b080c1923e7e85edea5a +it is necessary to explicitly initialize OpenSSL before loading libica. Because +otherwise libica's library constructor will initialize OpenSSL the first time, +which in turn will load the IBMCA provider, and it will fall into the same +problem as fixed by above libica commit, i.e. the provider won't be able to +get the supported algorithms from libica an thus will not register any +algorithms. + +Signed-off-by: Ingo Franzki +--- + test/provider/dhkey.c | 2 ++ + test/provider/eckey.c | 2 ++ + test/provider/rsakey.c | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/test/provider/dhkey.c b/test/provider/dhkey.c +index 0ec2c03..b1270f5 100644 +--- a/test/provider/dhkey.c ++++ b/test/provider/dhkey.c +@@ -461,6 +461,8 @@ int main(int argc, char **argv) + return 77; + } + ++ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); ++ + ret = check_libica(); + if (ret != 0) + return ret; +diff --git a/test/provider/eckey.c b/test/provider/eckey.c +index b8f47b7..a65bea5 100644 +--- a/test/provider/eckey.c ++++ b/test/provider/eckey.c +@@ -895,6 +895,8 @@ int main(int argc, char **argv) + return 77; + } + ++ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); ++ + ret = check_libica(); + if (ret != 0) + return ret; +diff --git a/test/provider/rsakey.c b/test/provider/rsakey.c +index 9d6a618..874de6d 100644 +--- a/test/provider/rsakey.c ++++ b/test/provider/rsakey.c +@@ -839,6 +839,8 @@ int main(int argc, char **argv) + return 77; + } + ++ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); ++ + ret = check_libica(); + if (ret != 0) + return ret; +-- +2.45.1 + + +From 4ea48e0682ff9a58340421dc9d896c7ca06a2621 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Mon, 13 May 2024 08:53:56 +0200 +Subject: [PATCH 4/4] engine: Fix compile error on Fedora 40 + +ibmca_pkey.c:627:47: error: passing argument 2 of 'EVP_PKEY_meth_set_copy' +from incompatible pointer type [-Wincompatible-pointer-types] + 627 | EVP_PKEY_meth_set_copy(ibmca_ed448_pmeth, ibmca_ed448_copy); + +Signed-off-by: Ingo Franzki +--- + src/engine/ibmca_pkey.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/engine/ibmca_pkey.c b/src/engine/ibmca_pkey.c +index 9c8de94..6cd8fcd 100644 +--- a/src/engine/ibmca_pkey.c ++++ b/src/engine/ibmca_pkey.c +@@ -258,7 +258,7 @@ ret: + + /* ED25519 */ + +-static int ibmca_ed25519_copy(EVP_PKEY_CTX *to, EVP_PKEY_CTX *from) ++static int ibmca_ed25519_copy(EVP_PKEY_CTX *to, const EVP_PKEY_CTX *from) + { + return 1; + } +@@ -402,7 +402,7 @@ ret: + + /* ED448 */ + +-static int ibmca_ed448_copy(EVP_PKEY_CTX *to, EVP_PKEY_CTX *from) ++static int ibmca_ed448_copy(EVP_PKEY_CTX *to, const EVP_PKEY_CTX *from) + { + return 1; + } +-- +2.45.1 + diff --git a/openssl-ibmca.spec b/openssl-ibmca.spec index 6ec8757..c27643a 100644 --- a/openssl-ibmca.spec +++ b/openssl-ibmca.spec @@ -9,12 +9,14 @@ Summary: OpenSSL engine and provider for IBMCA Name: openssl-ibmca Version: 2.4.1 -Release: 1%{?dist} +Release: 2%{?dist} License: ASL 2.0 URL: https://github.com/opencryptoki Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz # warn the user about engine being deprecated Patch1: %{name}-2.3.1-engine-warning.patch +# post GA fixes +Patch2: %{name}-%{version}-fixes.patch Requires: libica >= 4.0.0 BuildRequires: make BuildRequires: gcc @@ -77,6 +79,10 @@ make check %changelog +* Thu May 23 2024 Dan Horák - 2.4.1-2 +- apply post-2.4.1 fixes (RHEL-23702) +- Resolves: RHEL-23702 + * Fri Oct 27 2023 Dan Horák - 2.4.1-1 - updated to 2.4.1 (RHEL-11414) - Resolves: RHEL-11414