From 8617aa0a2d8bc7c0e6f1f20466001d4601c126e3 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 28 Mar 2023 09:21:24 +0000 Subject: [PATCH] import openssl-ibmca-2.3.1-2.el9 --- .gitignore | 2 +- .openssl-ibmca.metadata | 2 +- SOURCES/openssl-ibmca-2.3.0-fixes.patch | 689 --------------- .../openssl-ibmca-2.3.1-engine-warning.patch | 27 + SOURCES/openssl-ibmca-2.3.1-fixes.patch | 827 ++++++++++++++++++ SPECS/openssl-ibmca.spec | 22 +- 6 files changed, 870 insertions(+), 699 deletions(-) delete mode 100644 SOURCES/openssl-ibmca-2.3.0-fixes.patch create mode 100644 SOURCES/openssl-ibmca-2.3.1-engine-warning.patch create mode 100644 SOURCES/openssl-ibmca-2.3.1-fixes.patch diff --git a/.gitignore b/.gitignore index 9201c59..be7d21a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/openssl-ibmca-2.3.0.tar.gz +SOURCES/openssl-ibmca-2.3.1.tar.gz diff --git a/.openssl-ibmca.metadata b/.openssl-ibmca.metadata index 1ed5dac..aa192b9 100644 --- a/.openssl-ibmca.metadata +++ b/.openssl-ibmca.metadata @@ -1 +1 @@ -826976fdb0a4de24affe6b7c6678665bea8cdda0 SOURCES/openssl-ibmca-2.3.0.tar.gz +5e5ac182d30787788c94b5dcdf9a3a21d209bbaf SOURCES/openssl-ibmca-2.3.1.tar.gz diff --git a/SOURCES/openssl-ibmca-2.3.0-fixes.patch b/SOURCES/openssl-ibmca-2.3.0-fixes.patch deleted file mode 100644 index 65be671..0000000 --- a/SOURCES/openssl-ibmca-2.3.0-fixes.patch +++ /dev/null @@ -1,689 +0,0 @@ -From 1a75586c2821a55deeaa76861b1fc0539e6a3ca1 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Fri, 1 Apr 2022 10:47:45 +0200 -Subject: [PATCH 1/5] SPEC: Fix version number in provider-spec file - -Signed-off-by: Ingo Franzki ---- - openssl-ibmca-provider.spec | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/openssl-ibmca-provider.spec b/openssl-ibmca-provider.spec -index a3ef1a6..6c95b54 100644 ---- a/openssl-ibmca-provider.spec -+++ b/openssl-ibmca-provider.spec -@@ -5,7 +5,7 @@ - # %global modulesdir %(pkg-config --variable=modulesdir libcrypto) - - Name: openssl-ibmca --Version: 2.2.3 -+Version: 2.3.0 - Release: 1%{?dist} - Summary: An IBMCA OpenSSL dynamic provider - -@@ -45,6 +45,10 @@ mv -f src/provider/openssl.cnf.sample src/provider/openssl.cnf.sample.%{_arch} - %dir %attr(777,root,root) %{_localstatedir}/log/ibmca - - %changelog -+* Fri Mar 25 2022 Juergen Christ 2.3.0 -+- First version including the provider -+- Fix for engine build without OpenSSL 3.0 sources -+ - * Wed March 3 2022 Ingo Franzki - - Add provider support - --- -2.36.1 - - -From 76341149f2102bb628da61c2653e5911ddb81084 Mon Sep 17 00:00:00 2001 -From: Juergen Christ -Date: Thu, 7 Apr 2022 12:32:36 +0200 -Subject: [PATCH 2/5] Adjust to new libica. - -libica recently added function ica_cleanup to be called to free internal -OpenSSL 3.0 resources. This collided with our internal ica_cleanup function. -Rename that and call ica_cleanup if present. - -Signed-off-by: Juergen Christ ---- - configure.ac | 2 ++ - src/engine/e_ibmca.c | 13 ++++++++++--- - src/engine/ibmca.h | 3 +++ - src/provider/p_ibmca.c | 3 +++ - 4 files changed, 18 insertions(+), 3 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 46ad10e..6434056 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -130,6 +130,8 @@ if test "x$enable_provider" = xyes; then - [#include ]) - fi - -+AC_CHECK_DECLS([ica_cleanup],,,[#include ]) -+ - AC_CONFIG_FILES([ - Makefile - src/Makefile -diff --git a/src/engine/e_ibmca.c b/src/engine/e_ibmca.c -index ef17349..7335246 100644 ---- a/src/engine/e_ibmca.c -+++ b/src/engine/e_ibmca.c -@@ -102,6 +102,7 @@ ica_aes_gcm_initialize_t p_ica_aes_gcm_initialize; - 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; - - /* save libcrypto's default ec methods */ - #ifndef NO_EC -@@ -652,8 +653,10 @@ static void ibmca_destructor(void) - free((void *)LIBICA_NAME); - } - --static void ica_cleanup(void) -+static void do_ica_cleanup(void) - { -+ if (p_ica_cleanup) -+ p_ica_cleanup(); - if (ibmca_dso && dlclose(ibmca_dso)) { - IBMCAerr(IBMCA_F_IBMCA_FINISH, IBMCA_R_DSO_FAILURE); - return; -@@ -725,6 +728,7 @@ static void ica_cleanup(void) - p_ica_x448_ctx_del = NULL; - p_ica_ed25519_ctx_del = NULL; - p_ica_ed448_ctx_del = NULL; -+ p_ica_cleanup = NULL; - } - - static int ibmca_init(ENGINE *e) -@@ -806,6 +810,9 @@ static int ibmca_init(ENGINE *e) - BIND(ibmca_dso, ica_ed25519_ctx_del); - 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"); -+ - /* disable fallbacks on Libica */ - if (BIND(ibmca_dso, ica_set_fallback_mode)) - p_ica_set_fallback_mode(0); -@@ -821,7 +828,7 @@ static int ibmca_init(ENGINE *e) - return 1; - - err: -- ica_cleanup(); -+ do_ica_cleanup(); - return 0; - } - -@@ -884,7 +891,7 @@ static int ibmca_finish(ENGINE *e) - if (p_ica_close_adapter) - p_ica_close_adapter(ibmca_handle); - -- ica_cleanup(); -+ do_ica_cleanup(); - memset(&ibmca_registration, 0, sizeof(ibmca_registration)); - return 1; - } -diff --git a/src/engine/ibmca.h b/src/engine/ibmca.h -index 382a45d..53f4ca1 100644 ---- a/src/engine/ibmca.h -+++ b/src/engine/ibmca.h -@@ -616,6 +616,8 @@ int (*ica_ed25519_ctx_del_t)(ICA_ED25519_CTX **ctx); - typedef - int (*ica_ed448_ctx_del_t)(ICA_ED448_CTX **ctx); - -+typedef void (*ica_cleanup_t)(void); -+ - /* entry points into libica, filled out at DSO load time */ - extern ica_get_functionlist_t p_ica_get_functionlist; - extern ica_set_fallback_mode_t p_ica_set_fallback_mode; -@@ -681,3 +683,4 @@ extern ica_x25519_ctx_del_t p_ica_x25519_ctx_del; - extern ica_x448_ctx_del_t p_ica_x448_ctx_del; - extern ica_ed25519_ctx_del_t p_ica_ed25519_ctx_del; - extern ica_ed448_ctx_del_t p_ica_ed448_ctx_del; -+extern ica_cleanup_t p_ica_cleanup; -diff --git a/src/provider/p_ibmca.c b/src/provider/p_ibmca.c -index d8045ba..80f0368 100644 ---- a/src/provider/p_ibmca.c -+++ b/src/provider/p_ibmca.c -@@ -633,6 +633,9 @@ static void ibmca_teardown(void *vprovctx) - pthread_mutex_destroy(&provctx->debug_mutex); - - P_FREE(provctx, provctx); -+#if HAVE_DECL_ICA_CLEANUP == 1 -+ ica_cleanup(); -+#endif - } - - static const OSSL_PARAM ibmca_param_types[] = { --- -2.36.1 - - -From 688273ec77530a44d43ad5133155e646a945bc88 Mon Sep 17 00:00:00 2001 -From: Juergen Christ -Date: Thu, 7 Apr 2022 12:33:44 +0200 -Subject: [PATCH 3/5] Support tests in remote builds. - -If the build is not wihin the source tree, tests failed since they could not -find the key files. Add support for this. - -Signed-off-by: Juergen Christ ---- - test/engine/test.pm | 26 ++++++++++++++------------ - test/provider/tls.pl | 13 +++++++------ - 2 files changed, 21 insertions(+), 18 deletions(-) - -diff --git a/test/engine/test.pm b/test/engine/test.pm -index 8e4b8ab..3a313e1 100644 ---- a/test/engine/test.pm -+++ b/test/engine/test.pm -@@ -3,6 +3,8 @@ - use strict; - use warnings; - -+use FindBin; -+ - package test; - - sub osslversion1 { -@@ -69,16 +71,16 @@ sub rsaencdec { - my $bytes = 1 + int(rand($max_file_size)); - # engine enc, no-engine dec - `openssl rand $bytes > rsaencdec.${i}.${keylen}.data.in`; -- `$eng openssl rsautl -encrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`; -- `openssl rsautl -decrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`; -+ `$eng openssl rsautl -encrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`; -+ `openssl rsautl -decrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`; - `cmp rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.data.dec`; - exit(99) if ($?); - `rm -f rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.out rsaencdec.${i}.${keylen}.dec`; - - # no-engine enc, engine dec - `openssl rand $bytes > rsaencdec.${i}.${keylen}.data.in`; -- `openssl rsautl -encrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`; -- `$eng openssl rsautl -decrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`; -+ `openssl rsautl -encrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`; -+ `$eng openssl rsautl -decrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`; - `cmp rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.data.dec`; - exit(99) if ($?); - `rm -f rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.out rsaencdec.${i}.${keylen}.dec`; -@@ -100,16 +102,16 @@ sub rsasignverify { - $key .= $hex[rand(@hex)] for (1..$keylen); - # engine sign, no-engine verify - `openssl rand $bytes > rsasignverify.${i}.${keylen}.data.in`; -- `$eng openssl rsautl -sign -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`; -- `openssl rsautl -verify -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`; -+ `$eng openssl rsautl -sign -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`; -+ `openssl rsautl -verify -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`; - `cmp rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.rec`; - exit(99) if ($?); - `rm -f rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.out rsasignverify.${i}.${keylen}.data.rec`; - - # no-engine sign, engine verify - `openssl rand $bytes > rsasignverify.${i}.${keylen}.data.in`; -- `openssl rsautl -sign -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`; -- `$eng openssl rsautl -verify -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`; -+ `openssl rsautl -sign -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`; -+ `$eng openssl rsautl -verify -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`; - `cmp rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.rec`; - exit(99) if ($?); - `rm -f rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.out rsasignverify.${i}.${keylen}.data.rec`; -@@ -131,15 +133,15 @@ sub dsasignverify { - my $bytes = 1 + int(rand($max_file_size)); - # engine sign, no-engine verify - `openssl rand $bytes > dsa.${i}.${keylen}.data.in`; -- `$eng openssl dgst -sign dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -- `openssl dgst -verify dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -+ `$eng openssl dgst -sign $FindBin::Bin/dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -+ `openssl dgst -verify $FindBin::Bin/dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; - exit(99) if ($?); - `rm -f dsa.${i}.${keylen}.data.in dsa.${i}.${keylen}.data.out`; - - # no-engine sign, engine verify - `openssl rand $bytes > dsa.${i}.${keylen}.data.in`; -- `openssl dgst -sign dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -- `$eng openssl dgst -verify dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -+ `openssl dgst -sign $FindBin::Bin/dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; -+ `$eng openssl dgst -verify $FindBin::Bin/dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`; - exit(99) if ($?); - `rm -f dsa.${i}.${keylen}.data.in dsa.${i}.${keylen}.data.out`; - } -diff --git a/test/provider/tls.pl b/test/provider/tls.pl -index c8871d4..0d9df6d 100755 ---- a/test/provider/tls.pl -+++ b/test/provider/tls.pl -@@ -19,17 +19,18 @@ - use strict; - use warnings; - use test; -+use FindBin; - - # TLS 1.3 with RSA signatures --test::tls(10001, "server-key-rsa.pem", "server-cert-rsa.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3"); -+test::tls(10001, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3"); - # TLS 1.3 with EC signatures --test::tls(10002, "server-key-ec.pem", "server-cert-ec.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3"); -+test::tls(10002, "$FindBin::Bin/server-key-ec.pem", "$FindBin::Bin/server-cert-ec.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3"); - # TLS 1.2 with RSA signatures and ECDH key exchange --test::tls(10003, "server-key-rsa.pem", "server-cert-rsa.pem", "ECDHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); -+test::tls(10003, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "ECDHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); - # TLS 1.2 with ECDSA signatures and ECDH key exchange --test::tls(10004, "server-key-ec.pem", "server-cert-ec.pem", "ECDHE-ECDSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); -+test::tls(10004, "$FindBin::Bin/server-key-ec.pem", "$FindBin::Bin/server-cert-ec.pem", "ECDHE-ECDSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); - # TLS 1.2 with RSA signatures and DH key exchange --test::tls(10005, "server-key-rsa.pem", "server-cert-rsa.pem", "DHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); -+test::tls(10005, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "DHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); - # TLS 1.2 with RSA signatures and RSA key exchange --test::tls(10006, "server-key-rsa.pem", "server-cert-rsa.pem", "AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); -+test::tls(10006, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "AES256-GCM-SHA384", "\"\"", "-no_tls1_3"); - --- -2.36.1 - - -From c0d384b72f280a4bd1c71407df0583da1847f5cb Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Thu, 12 May 2022 11:20:18 +0200 -Subject: [PATCH 4/5] provider: Adapt keymgmt_match() implementations to - OpenSSL - -OpenSSL commit ee22a3741e3fc27c981e7f7e9bcb8d3342b0c65a changed the -OpenSSL provider's keymgmt_match() function to be not so strict with -the selector bits in regards to matching different key parts. - -Adapt the provider's match functions accordingly. -This means, that if the public key is selected to be matched, and the -public key matches (together with any also selected parameters), -then the private key is no longer checked, although it may also be -selected to be matched. This is according to how the OpenSSL function -EVP_PKEY_eq() is supposed to behave. - -Signed-off-by: Ingo Franzki ---- - src/provider/dh_keymgmt.c | 2 +- - src/provider/ec_keymgmt.c | 5 +++-- - src/provider/rsa_keymgmt.c | 8 +++++--- - 3 files changed, 9 insertions(+), 6 deletions(-) - -diff --git a/src/provider/dh_keymgmt.c b/src/provider/dh_keymgmt.c -index 48ba739..3180158 100644 ---- a/src/provider/dh_keymgmt.c -+++ b/src/provider/dh_keymgmt.c -@@ -1000,7 +1000,7 @@ static int ibmca_keymgmt_dh_match(const void *vkey1, const void *vkey2, - } - } - -- if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { -+ if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { - if (key1->dh.priv != NULL || key2->dh.priv != NULL) { - ok = ok && (BN_cmp(key1->dh.priv, key2->dh.priv) == 0); - checked = 1; -diff --git a/src/provider/ec_keymgmt.c b/src/provider/ec_keymgmt.c -index d898c6a..d39b1e2 100644 ---- a/src/provider/ec_keymgmt.c -+++ b/src/provider/ec_keymgmt.c -@@ -751,7 +751,7 @@ static int ibmca_keymgmt_ec_match(const void *vkey1, const void *vkey2, - const struct ibmca_key *key2 = vkey2; - BIGNUM *x1 = NULL, *y1 = NULL, *d1 = NULL; - BIGNUM *x2 = NULL, *y2 = NULL, *d2 = NULL; -- int ok = 1, rc1, rc2; -+ int ok = 1, rc1, rc2, checked = 0; - - if (key1 == NULL || key2 == NULL) - return 0; -@@ -781,9 +781,10 @@ static int ibmca_keymgmt_ec_match(const void *vkey1, const void *vkey2, - - ok = ok && (rc1 == rc2 && (rc1 == -1 || - (BN_cmp(x1, x2) == 0 && BN_cmp(y1, y2) == 0))); -+ checked = 1; - } - -- if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { -+ if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { - rc1 = ibmca_keymgmt_ec_priv_key_as_bn(key1, &d1); - if (rc1 == 0) { - ok = 0; -diff --git a/src/provider/rsa_keymgmt.c b/src/provider/rsa_keymgmt.c -index 61f7744..9278327 100644 ---- a/src/provider/rsa_keymgmt.c -+++ b/src/provider/rsa_keymgmt.c -@@ -641,7 +641,7 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, - { - const struct ibmca_key *key1 = vkey1; - const struct ibmca_key *key2 = vkey2; -- int ok = 1; -+ int ok = 1, checked = 0; - - if (key1 == NULL || key2 == NULL) - return 0; -@@ -652,7 +652,7 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, - if (ibmca_keymgmt_match(key1, key2) == 0) - return 0; - -- if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) -+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { - ok = ok && (key1->rsa.public.key_length == - key2->rsa.public.key_length && - memcmp(key1->rsa.public.exponent, -@@ -661,8 +661,10 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, - memcmp(key1->rsa.public.modulus, - key2->rsa.public.modulus, - key1->rsa.public.key_length) == 0); -+ checked = 1; -+ } - -- if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) -+ if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) - ok = ok && (key1->rsa.private.key_length == - key2->rsa.private.key_length && - CRYPTO_memcmp(key1->rsa.private.p, --- -2.36.1 - - -From 49be3a5c9c1258e0dc15bbc50d5aa04a0ba4ba66 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Wed, 18 May 2022 15:41:12 +0200 -Subject: [PATCH 5/5] tests: skip tests if libica does not support required - algorithms - -Before actually running the tests, check if libica supports the -required algorithms. Skip the whole test if not. - -This can happen when running the test on a system without appropriate -crypto adapters. This would lead to the situation that the provider would -not register itself for the required algorithms, and thus the OpenSSL -default provider would be used. This would make the tests to fail, because -it is not running with the IBMCA provider as expected by the test. - -Signed-off-by: Ingo Franzki ---- - test/provider/Makefile.am | 18 ++++++++++--- - test/provider/dhkey.c | 56 ++++++++++++++++++++++++++++++++++++++ - test/provider/eckey.c | 57 +++++++++++++++++++++++++++++++++++++++ - test/provider/rsakey.c | 56 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 184 insertions(+), 3 deletions(-) - -diff --git a/test/provider/Makefile.am b/test/provider/Makefile.am -index f5cb97d..b007682 100644 ---- a/test/provider/Makefile.am -+++ b/test/provider/Makefile.am -@@ -20,13 +20,25 @@ TESTS = \ - check_PROGRAMS = rsakey eckey dhkey threadtest - - dhkey_SOURCES = dhkey.c --dhkey_LDADD = -lcrypto -+if PROVIDER_FULL_LIBICA -+dhkey_LDADD = -lcrypto -lica -+else -+dhkey_LDADD = -lcrypto -lica-cex -+endif - - eckey_SOURCES = eckey.c --eckey_LDADD = -lcrypto -+if PROVIDER_FULL_LIBICA -+eckey_LDADD = -lcrypto -lica -+else -+eckey_LDADD = -lcrypto -lica-cex -+endif - - rsakey_SOURCES = rsakey.c --rsakey_LDADD = -lcrypto -+if PROVIDER_FULL_LIBICA -+rsakey_LDADD = -lcrypto -lica -+else -+rsakey_LDADD = -lcrypto -lica-cex -+endif - - threadtest_SOURCES = threadtest.c - threadtest_LDADD = -lcrypto -lpthread -diff --git a/test/provider/dhkey.c b/test/provider/dhkey.c -index a9cea13..8829ecc 100644 ---- a/test/provider/dhkey.c -+++ b/test/provider/dhkey.c -@@ -27,6 +27,8 @@ - #include - #include - -+#include -+ - #define UNUSED(var) ((void)(var)) - - void setup(void) -@@ -349,6 +351,56 @@ int check_dhkey(int nid, const char *name, const char *algo) - return ret; - } - -+static const unsigned int required_ica_mechs[] = { RSA_ME }; -+static const unsigned int required_ica_mechs_len = -+ sizeof(required_ica_mechs) / sizeof(unsigned int); -+ -+int check_libica() -+{ -+ unsigned int mech_len, i, k, found = 0; -+ libica_func_list_element *mech_list = NULL; -+ int rc; -+ -+ rc = ica_get_functionlist(NULL, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ return 77; -+ } -+ -+ mech_list = calloc(sizeof(libica_func_list_element), mech_len); -+ if (mech_list == NULL) { -+ fprintf(stderr, "Failed to allocate memory for function list!\n"); -+ return 77; -+ } -+ -+ rc = ica_get_functionlist(mech_list, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ free(mech_list); -+ return 77; -+ } -+ -+ for (i = 0; i < mech_len; i++) { -+ for (k = 0; k < required_ica_mechs_len; k++) { -+ if (mech_list[i].mech_mode_id == required_ica_mechs[k]) { -+ if (mech_list[i].flags & -+ (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW)) -+ found++; -+ } -+ } -+ } -+ -+ free(mech_list); -+ -+ if (found < required_ica_mechs_len) { -+ fprintf(stderr, -+ "Libica does not support the required algorithms, skipping.\n"); -+ return 77; -+ } -+ -+ return 0; -+} -+ - int main(int argc, char **argv) - { - static const struct testparams { -@@ -389,6 +441,10 @@ int main(int argc, char **argv) - return 77; - } - -+ ret = check_libica(); -+ if (ret != 0) -+ return ret; -+ - setup(); - for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) { - if (!check_dhkey(params[i].nid, params[i].name, "DH")) { -diff --git a/test/provider/eckey.c b/test/provider/eckey.c -index 279b942..b2334d7 100644 ---- a/test/provider/eckey.c -+++ b/test/provider/eckey.c -@@ -27,6 +27,8 @@ - #include - #include - -+#include -+ - #define UNUSED(var) ((void)(var)) - - void setup(void) -@@ -781,6 +783,57 @@ int check_eckey(int nid, const char *name) - return ret; - } - -+static const unsigned int required_ica_mechs[] = { EC_DH, EC_DSA_SIGN, -+ EC_DSA_VERIFY, EC_KGEN, }; -+static const unsigned int required_ica_mechs_len = -+ sizeof(required_ica_mechs) / sizeof(unsigned int); -+ -+int check_libica() -+{ -+ unsigned int mech_len, i, k, found = 0; -+ libica_func_list_element *mech_list = NULL; -+ int rc; -+ -+ rc = ica_get_functionlist(NULL, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ return 77; -+ } -+ -+ mech_list = calloc(sizeof(libica_func_list_element), mech_len); -+ if (mech_list == NULL) { -+ fprintf(stderr, "Failed to allocate memory for function list!\n"); -+ return 77; -+ } -+ -+ rc = ica_get_functionlist(mech_list, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ free(mech_list); -+ return 77; -+ } -+ -+ for (i = 0; i < mech_len; i++) { -+ for (k = 0; k < required_ica_mechs_len; k++) { -+ if (mech_list[i].mech_mode_id == required_ica_mechs[k]) { -+ if (mech_list[i].flags & -+ (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW)) -+ found++; -+ } -+ } -+ } -+ -+ free(mech_list); -+ -+ if (found < required_ica_mechs_len) { -+ fprintf(stderr, -+ "Libica does not support the required algorithms, skipping.\n"); -+ return 77; -+ } -+ -+ return 0; -+} -+ - int main(int argc, char **argv) - { - static const struct testparams { -@@ -822,6 +875,10 @@ int main(int argc, char **argv) - return 77; - } - -+ ret = check_libica(); -+ if (ret != 0) -+ return ret; -+ - setup(); - for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) { - if (!check_eckey(params[i].nid, params[i].name)) { -diff --git a/test/provider/rsakey.c b/test/provider/rsakey.c -index 0adface..366b503 100644 ---- a/test/provider/rsakey.c -+++ b/test/provider/rsakey.c -@@ -26,6 +26,8 @@ - #include - #include - -+#include -+ - #define UNUSED(var) ((void)(var)) - - void setup(void) -@@ -729,6 +731,56 @@ int check_rsakey(int bits, const char *algo, const char *name) - return ret; - } - -+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); -+ -+int check_libica() -+{ -+ unsigned int mech_len, i, k, found = 0; -+ libica_func_list_element *mech_list = NULL; -+ int rc; -+ -+ rc = ica_get_functionlist(NULL, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ return 77; -+ } -+ -+ mech_list = calloc(sizeof(libica_func_list_element), mech_len); -+ if (mech_list == NULL) { -+ fprintf(stderr, "Failed to allocate memory for function list!\n"); -+ return 77; -+ } -+ -+ rc = ica_get_functionlist(mech_list, &mech_len); -+ if (rc != 0) { -+ fprintf(stderr, "Failed to get function list from libica!\n"); -+ free(mech_list); -+ return 77; -+ } -+ -+ for (i = 0; i < mech_len; i++) { -+ for (k = 0; k < required_ica_mechs_len; k++) { -+ if (mech_list[i].mech_mode_id == required_ica_mechs[k]) { -+ if (mech_list[i].flags & -+ (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW)) -+ found++; -+ } -+ } -+ } -+ -+ free(mech_list); -+ -+ if (found < required_ica_mechs_len) { -+ fprintf(stderr, -+ "Libica does not support the required algorithms, skipping.\n"); -+ return 77; -+ } -+ -+ return 0; -+} -+ - int main(int argc, char **argv) - { - static const struct testparams { -@@ -767,6 +819,10 @@ int main(int argc, char **argv) - return 77; - } - -+ ret = check_libica(); -+ if (ret != 0) -+ return ret; -+ - setup(); - for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) { - if (!check_rsakey(params[i].bits, params[i].algo, params[i].name)) { --- -2.36.1 - diff --git a/SOURCES/openssl-ibmca-2.3.1-engine-warning.patch b/SOURCES/openssl-ibmca-2.3.1-engine-warning.patch new file mode 100644 index 0000000..c4d4aec --- /dev/null +++ b/SOURCES/openssl-ibmca-2.3.1-engine-warning.patch @@ -0,0 +1,27 @@ +From b72865d57bf129c058bdb4e7301b9cb7ce16938e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 13 Jan 2023 18:09:49 +0100 +Subject: [ibmca PATCH] warn the user when configuring the engine + +The engine feature is deprecated in OpenSSL 3.0 and will be removed. +Thus warn the user and recommend using the provider instead. +--- + src/engine/ibmca-engine-opensslconfig.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/engine/ibmca-engine-opensslconfig.in b/src/engine/ibmca-engine-opensslconfig.in +index e4b168b..ec7fbfc 100644 +--- a/src/engine/ibmca-engine-opensslconfig.in ++++ b/src/engine/ibmca-engine-opensslconfig.in +@@ -140,4 +140,8 @@ this file. + |; + } + ++print "WARNING: The OpenSSL engine feature is DEPRECATED since OpenSSL 3.0.\n"; ++print "WARNING: It will be removed in the future.\n"; ++print "WARNING: Please use the OpenSSL provider instead.\n"; ++ + generate(); +-- +2.39.0 + diff --git a/SOURCES/openssl-ibmca-2.3.1-fixes.patch b/SOURCES/openssl-ibmca-2.3.1-fixes.patch new file mode 100644 index 0000000..5e63b2e --- /dev/null +++ b/SOURCES/openssl-ibmca-2.3.1-fixes.patch @@ -0,0 +1,827 @@ +From ec926d577754babce01db22274a582988c5c4e44 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Wed, 12 Oct 2022 09:40:27 +0200 +Subject: [PATCH 1/4] provider: Support EC parameter generation with named + curve + +In general the IBMCA provider does not support EC parameter generation, +because libica only supports certain named curves. However, one can +also use EC parameter generation with a named curve, and then use such +parameter key object as template for generating other keys. One example +for this is the openssl speed utility. + +Like for EC key generation, EC parameter generation only supports +parameters 'group', 'point-format', 'encoding', and 'use-cofactor-flag', +where the only accepted value for parameter 'encoding' is 'named_curve', +and the only accepted value for parameter 'use-cofactor-flag' is '0'. + +Signed-off-by: Ingo Franzki +--- + src/provider/ec_keymgmt.c | 10 ++++++++-- + src/provider/p_ibmca.h | 1 + + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/provider/ec_keymgmt.c b/src/provider/ec_keymgmt.c +index d39b1e2..97516f1 100644 +--- a/src/provider/ec_keymgmt.c ++++ b/src/provider/ec_keymgmt.c +@@ -928,9 +928,10 @@ static void *ibmca_keymgmt_ec_gen_init(void *vprovctx, int selection, + for (p = params; p != NULL && p->key != NULL; p++) + ibmca_debug_ctx(provctx, "param: %s", p->key); + +- if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) { ++ if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR | ++ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)) == 0) { + put_error_ctx(provctx, IBMCA_ERR_INVALID_PARAM, +- "selection is not KEYPAIR"); ++ "selection is not KEYPAIR and/or parameters"); + return NULL; + } + +@@ -943,6 +944,7 @@ static void *ibmca_keymgmt_ec_gen_init(void *vprovctx, int selection, + } + + /* set defaults */ ++ ctx->ec.gen.selection = selection; + ctx->ec.gen.curve_nid = NID_undef; + ctx->ec.gen.format = POINT_CONVERSION_UNCOMPRESSED; + +@@ -1223,6 +1225,9 @@ static void *ibmca_keymgmt_ec_gen(void *vgenctx, OSSL_CALLBACK *osslcb, + + ibmca_debug_op_ctx(genctx, "prime_size: %lu", key->ec.prime_size); + ++ if ((genctx->ec.gen.selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) ++ goto out; ++ + key->ec.key = ica_ec_key_new(key->ec.curve_nid, &privlen); + if (key->ec.key == NULL || key->ec.prime_size != privlen) { + ibmca_debug_op_ctx(genctx, "ica_ec_key_new failed"); +@@ -1267,6 +1272,7 @@ static void *ibmca_keymgmt_ec_gen(void *vgenctx, OSSL_CALLBACK *osslcb, + return NULL; + } + ++out: + ibmca_debug_op_ctx(genctx, "key: %p", key); + + return key; +diff --git a/src/provider/p_ibmca.h b/src/provider/p_ibmca.h +index fa0e1ee..2b4ff8e 100644 +--- a/src/provider/p_ibmca.h ++++ b/src/provider/p_ibmca.h +@@ -216,6 +216,7 @@ struct ibmca_op_ctx { + } rsa; /* For type EVP_PKEY_RSA and EVP_PKEY_RSA_PSS */ + union { + struct { ++ int selection; + int curve_nid; + point_conversion_form_t format; + } gen; /* For operation EVP_PKEY_OP_KEYGEN */ +-- +2.39.0 + + +From a462093d2478b287cb9a7a25131788eba16b7640 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Fri, 14 Oct 2022 11:31:16 +0200 +Subject: [PATCH 2/4] engine: EC: Cache ICA key in EC_KEY object + +Creating a new ICA EC key via ica_ec_key_init() is time consuming, because +libica performs EC key checks on the key components. + +Currently every sign, verify or derive operation creates a new ICA key, and +thus suffers from the long taking EC key checks with every operation. + +Change this to create an ICA key on the first usage of an EC key, and attach +the ICA key to the EC_KEY object as ex-data. That way, subsequent operations +using the same key will reuse the attached ICA key and do not have to create +a new ICA key again. + +Signed-off-by: Ingo Franzki +--- + src/engine/e_ibmca.c | 5 + + src/engine/ibmca.h | 1 + + src/engine/ibmca_ec.c | 411 ++++++++++++++++++++++++++++++------------ + 3 files changed, 306 insertions(+), 111 deletions(-) + +diff --git a/src/engine/e_ibmca.c b/src/engine/e_ibmca.c +index d045828..fe21897 100644 +--- a/src/engine/e_ibmca.c ++++ b/src/engine/e_ibmca.c +@@ -833,6 +833,11 @@ static int ibmca_init(ENGINE *e) + goto err; + } + ++#ifndef NO_EC ++ if (!ibmca_ec_init()) ++ goto err; ++#endif ++ + if (!set_supported_meths(e)) + goto err; + +diff --git a/src/engine/ibmca.h b/src/engine/ibmca.h +index 37bdfd8..7281a5b 100644 +--- a/src/engine/ibmca.h ++++ b/src/engine/ibmca.h +@@ -298,6 +298,7 @@ void ibmca_dh_destroy(void); + #define IBMCA_EC_MAX_Z_LEN IBMCA_EC_MAX_D_LEN + + #ifndef OPENSSL_NO_EC ++int ibmca_ec_init(void); + void ibmca_ec_destroy(void); + + int ibmca_ecdh_compute_key(unsigned char **pout, size_t *poutlen, +diff --git a/src/engine/ibmca_ec.c b/src/engine/ibmca_ec.c +index 8bc6cbf..5206ae3 100644 +--- a/src/engine/ibmca_ec.c ++++ b/src/engine/ibmca_ec.c +@@ -16,6 +16,7 @@ + */ + + #include ++#include + #include "ibmca.h" + #include "e_ibmca_err.h" + +@@ -31,6 +32,251 @@ ica_ec_key_get_public_key_t p_ica_ec_key_get_public_key; + ica_ec_key_get_private_key_t p_ica_ec_key_get_private_key; + ica_ec_key_free_t p_ica_ec_key_free; + ++int ec_ex_data_index = -1; ++pthread_mutex_t ec_ex_data_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++struct ibmca_ec_ex_data { ++ ICA_EC_KEY *ica_key; ++ int nid; ++ unsigned int privlen; ++}; ++ ++void ibmca_ec_ex_data_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, ++ int idx, long argl, void *argp) ++{ ++ struct ibmca_ec_ex_data *data = ptr; ++ ++ if (data == NULL) ++ return; ++ ++ p_ica_ec_key_free(data->ica_key); ++ OPENSSL_free(data); ++} ++ ++int ibmca_ec_ex_data_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, ++#ifdef OPENSSL_VERSION_PREREQ ++ void **pptr, int idx, long argl, void *argp) ++#else ++ void *from_d, int idx, long argl, void *argp) ++#endif ++{ ++#ifndef OPENSSL_VERSION_PREREQ ++ void **pptr = (void **)from_d; ++#endif ++ struct ibmca_ec_ex_data *from_data; ++ struct ibmca_ec_ex_data *to_data; ++ unsigned char Q[2 * IBMCA_EC_MAX_D_LEN]; ++ unsigned char D[IBMCA_EC_MAX_D_LEN]; ++ unsigned int len; ++ int rc; ++ ++ if (pptr == NULL) ++ return 0; ++ ++ from_data = (struct ibmca_ec_ex_data *)*pptr; ++ if (from_data == NULL) ++ return 0; ++ ++ to_data = OPENSSL_zalloc(sizeof(*to_data)); ++ if (to_data == NULL) { ++ return 0; ++ } ++ ++ to_data->nid = from_data->nid; ++ to_data->ica_key = p_ica_ec_key_new(to_data->nid, &to_data->privlen); ++ if (to_data->ica_key == NULL) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_ICA_EC_KEY_INIT); ++ goto error; ++ } ++ ++ if (p_ica_ec_key_get_private_key(from_data->ica_key, D, &len) == 0) { ++ rc = p_ica_ec_key_init(NULL, NULL, D, to_data->ica_key); ++ if (rc != 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); ++ goto error; ++ } ++ } ++ ++ if (p_ica_ec_key_get_public_key(from_data->ica_key, Q, &len) == 0) { ++ rc = p_ica_ec_key_init(Q, Q + to_data->privlen, NULL, to_data->ica_key); ++ if (rc != 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); ++ goto error; ++ } ++ } ++ ++ *pptr = to_data; ++ ++ return 1; ++ ++error: ++ if (to_data->ica_key != NULL) ++ p_ica_ec_key_free(to_data->ica_key); ++ OPENSSL_free(to_data); ++ ++ return 0; ++} ++ ++static ICA_EC_KEY *ibmca_ec_make_ica_key(EC_KEY *ec_key, int *nid, ++ unsigned int *privlen) ++{ ++ ICA_EC_KEY *icakey; ++ const EC_GROUP *group; ++ const EC_POINT *q; ++ const BIGNUM *bn_d; ++ BIGNUM *bn_x = NULL, *bn_y = NULL; ++ unsigned char D[IBMCA_EC_MAX_D_LEN]; ++ unsigned char X[IBMCA_EC_MAX_D_LEN]; ++ unsigned char Y[IBMCA_EC_MAX_D_LEN]; ++ int rc, n; ++ ++ /* Get group */ ++ if ((group = EC_KEY_get0_group(ec_key)) == NULL) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_INVALID_PARM); ++ return NULL; ++ } ++ ++ /* Get curve nid */ ++ *nid = EC_GROUP_get_curve_name(group); ++ if (*nid <= 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_UNSUPPORTED_CURVE); ++ return NULL; ++ } ++ ++ /* Create ICA_EC_KEY object */ ++ icakey = p_ica_ec_key_new(*nid, privlen); ++ if (icakey == NULL) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_ICA_EC_KEY_INIT); ++ return NULL; ++ } ++ ++ /* Get private (D) value from EC_KEY (if available) */ ++ bn_d = EC_KEY_get0_private_key(ec_key); ++ if (bn_d != NULL) { ++ /* Format (D) as char array, with leading zeros if necessary */ ++ n = *privlen - BN_num_bytes(bn_d); ++ memset(D, 0, n); ++ BN_bn2bin(bn_d, &(D[n])); ++ ++ /* Initialize private ICA_EC_KEY */ ++ rc = p_ica_ec_key_init(NULL, NULL, D, icakey); ++ if (rc != 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); ++ goto error; ++ } ++ } ++ ++ /* Get public (X and Y) values from EC_KEY (if available) */ ++ q = EC_KEY_get0_public_key(ec_key); ++ if (q != NULL) { ++ /* Provide public key (X,Y) */ ++ bn_x = BN_new(); ++ bn_y = BN_new(); ++ if (!EC_POINT_get_affine_coordinates_GFp(group, q, bn_x, bn_y, NULL)) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_INTERNAL_ERROR); ++ goto error; ++ } ++ ++ /* Format (X) as char array with leading nulls if necessary */ ++ n = *privlen - BN_num_bytes(bn_x); ++ memset(X, 0, n); ++ BN_bn2bin(bn_x, &X[n]); ++ ++ /* Format (Y) as char array with leading nulls if necessary */ ++ n = *privlen - BN_num_bytes(bn_y); ++ memset(Y, 0, n); ++ BN_bn2bin(bn_y, &Y[n]); ++ ++ /* Initialize public ICA_EC_KEY */ ++ rc = p_ica_ec_key_init(X, Y, NULL, icakey); ++ if (rc != 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); ++ goto error; ++ } ++ } ++ ++out: ++ BN_clear_free(bn_x); ++ BN_clear_free(bn_y); ++ ++ return icakey; ++ ++error: ++ p_ica_ec_key_free(icakey); ++ icakey = NULL; ++ goto out; ++} ++ ++static ICA_EC_KEY *ibmca_ec_make_and_cache_ica_key(EC_KEY *ec_key, ++ unsigned int *privlen) ++{ ++ struct ibmca_ec_ex_data *data, *data2; ++ ++ data = OPENSSL_zalloc(sizeof(*data)); ++ if (data == NULL) ++ return NULL; ++ ++ data->ica_key = ibmca_ec_make_ica_key(ec_key, &data->nid, &data->privlen); ++ if (data->ica_key == NULL) { ++ OPENSSL_free(data); ++ return NULL; ++ } ++ ++ /* ++ * Note that another thread could have allocated and set the ex_data for ++ * that key after the caller of this function has checked if there is ++ * already ex_data available for the key. So once we have the lock, we ++ * check again, and if there now is ex_data available, we return the ++ * ICA key from the ex_data, and free the one just created. ++ */ ++ if (pthread_mutex_lock(&ec_ex_data_mutex) != 0) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_INTERNAL_ERROR); ++ return NULL; ++ } ++ ++ data2 = EC_KEY_get_ex_data(ec_key, ec_ex_data_index); ++ if (data2 != NULL) { ++ pthread_mutex_unlock(&ec_ex_data_mutex); ++ ++ p_ica_ec_key_free(data->ica_key); ++ OPENSSL_free(data); ++ ++ *privlen = data2->privlen; ++ ++ return data2->ica_key; ++ } ++ ++ if (EC_KEY_set_ex_data(ec_key, ec_ex_data_index, data) != 1) { ++ IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_INTERNAL_ERROR); ++ pthread_mutex_unlock(&ec_ex_data_mutex); ++ OPENSSL_free(data); ++ return NULL; ++ } ++ ++ pthread_mutex_unlock(&ec_ex_data_mutex); ++ ++ *privlen = data->privlen; ++ ++ return data->ica_key; ++} ++ ++int ibmca_ec_init(void) ++{ ++#ifdef OLDER_OPENSSL ++ return 0; ++#else ++ ec_ex_data_index = EC_KEY_get_ex_new_index(0, NULL, NULL, ++ ibmca_ec_ex_data_dup, ++ ibmca_ec_ex_data_free); ++ if (ec_ex_data_index < 0) { ++ IBMCAerr(IBMCA_F_IBMCA_INIT, IBMCA_R_EC_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ return 1; ++#endif ++} ++ + void ibmca_ec_destroy(void) + { + #ifdef OLDER_OPENSSL +@@ -39,6 +285,10 @@ void ibmca_ec_destroy(void) + if (ibmca_ecdh) + ECDSA_METHOD_free(ibmca_ecdsa); + #else ++ if (ec_ex_data_index >= 0) { ++ CRYPTO_free_ex_index(CRYPTO_EX_INDEX_EC_KEY, ec_ex_data_index); ++ ec_ex_data_index = -1; ++ } + if (ibmca_ec) + EC_KEY_METHOD_free(ibmca_ec); + #endif +@@ -55,17 +305,17 @@ int ibmca_ecdh_compute_key(unsigned char **pout, size_t *poutlen, + { + ICA_EC_KEY *ica_pubkey = NULL, *ica_privkey = NULL; + const EC_GROUP *group; +- BIGNUM *bn_d, *bn_x, *bn_y; ++ BIGNUM *bn_x = NULL, *bn_y = NULL; + unsigned int n, privlen; + unsigned char X[IBMCA_EC_MAX_D_LEN]; + unsigned char Y[IBMCA_EC_MAX_D_LEN]; +- unsigned char D[IBMCA_EC_MAX_D_LEN]; + unsigned char *z_buf = NULL; + int rc, ret = 0, nid; + #ifndef OLDER_OPENSSL + int (*compute_key_sw)(unsigned char **pout, size_t *poutlen, + const EC_POINT *pub_key, const EC_KEY *ecdh) = NULL; + #endif ++ struct ibmca_ec_ex_data *data = EC_KEY_get_ex_data(ecdh, ec_ex_data_index); + + /* Get group from EC_KEY */ + if ((group = EC_KEY_get0_group(ecdh)) == NULL) { +@@ -76,10 +326,40 @@ int ibmca_ecdh_compute_key(unsigned char **pout, size_t *poutlen, + /* Determine curve nid */ + nid = EC_GROUP_get_curve_name(group); + if (nid <= 0) { +- IBMCAerr(IBMCA_F_IBMCA_ECDH_COMPUTE_KEY, IBMCA_R_EC_INTERNAL_ERROR); ++ IBMCAerr(IBMCA_F_IBMCA_ECDH_COMPUTE_KEY, IBMCA_R_EC_UNSUPPORTED_CURVE); ++ return 0; ++ } ++ ++ if (data != NULL) { ++ ica_privkey = data->ica_key; ++ privlen = data->privlen; ++ goto do_derive; ++ } ++ ++ /* Create ICA_EC_KEY object for private key */ ++ ica_privkey = ibmca_ec_make_and_cache_ica_key((EC_KEY*)ecdh, &privlen); ++ if (ica_privkey == NULL) { ++ /* This curve is not supported by libica. */ ++ #ifdef OLDER_OPENSSL + return 0; ++ #else ++ /* ++ * EC_KEY_METHOD_get_compute_key misses the const-qualifier of the ++ * parameter in some openssl versions. ++ */ ++ EC_KEY_METHOD_get_compute_key((EC_KEY_METHOD *)ossl_ec, ++ &compute_key_sw); ++ if (compute_key_sw == NULL) { ++ IBMCAerr(IBMCA_F_IBMCA_ECDH_COMPUTE_KEY, ++ IBMCA_R_EC_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ return compute_key_sw(pout, poutlen, pub_key, ecdh); ++ #endif + } + ++do_derive: + /* Create ICA_EC_KEY object for public key */ + ica_pubkey = p_ica_ec_key_new(nid, &privlen); + if (ica_pubkey == NULL) { +@@ -128,32 +408,6 @@ int ibmca_ecdh_compute_key(unsigned char **pout, size_t *poutlen, + goto end; + } + +- /* Create ICA_EC_KEY object for private key */ +- ica_privkey = p_ica_ec_key_new(nid, &privlen); +- if (!ica_privkey) { +- IBMCAerr(IBMCA_F_ICA_EC_KEY_NEW, IBMCA_R_EC_INTERNAL_ERROR); +- goto end; +- } +- +- /* Get private (D) value from EC_KEY */ +- bn_d = (BIGNUM*)EC_KEY_get0_private_key((EC_KEY*)ecdh); +- if (bn_d == NULL) { +- IBMCAerr(IBMCA_F_IBMCA_ECDH_COMPUTE_KEY, IBMCA_R_EC_INTERNAL_ERROR); +- goto end; +- } +- +- /* Format (D) as char array, with leading zeros if necessary */ +- n = privlen - BN_num_bytes(bn_d); +- memset(D, 0, n); +- BN_bn2bin(bn_d, &(D[n])); +- +- /* Initialize private ICA_EC_KEY with (D) */ +- rc = p_ica_ec_key_init(NULL, NULL, D, ica_privkey); +- if (rc != 0) { +- IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); +- goto end; +- } +- + /* Allocate memory for shared secret z, will be freed by caller */ + if ((z_buf = OPENSSL_malloc(privlen)) == NULL) { + IBMCAerr(IBMCA_F_IBMCA_ECDH_COMPUTE_KEY, IBMCA_R_EC_INTERNAL_ERROR); +@@ -193,7 +447,6 @@ int ibmca_ecdh_compute_key(unsigned char **pout, size_t *poutlen, + + end: + p_ica_ec_key_free(ica_pubkey); +- p_ica_ec_key_free(ica_privkey); + BN_clear_free(bn_x); + BN_clear_free(bn_y); + return ret; +@@ -210,12 +463,10 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + { + ECDSA_SIG *sig = NULL; + ICA_EC_KEY *icakey = NULL; +- const EC_GROUP *group; + unsigned int privlen; +- BIGNUM *r, *s, *bn_d, *kinv; +- unsigned char D[IBMCA_EC_MAX_D_LEN]; ++ BIGNUM *r, *s, *kinv; + unsigned char sigret[IBMCA_EC_MAX_SIG_LEN]; +- int n, nid, rc; ++ int rc; + #ifndef OLDER_OPENSSL + int (*sign_sw)(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, +@@ -227,6 +478,7 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) = NULL; + BN_CTX *ctx; ++ struct ibmca_ec_ex_data *data = EC_KEY_get_ex_data(eckey, ec_ex_data_index); + + /* Check parms: precomputed (k,r) are not supported by ibmca */ + if (in_kinv != NULL || in_r != NULL) { +@@ -234,12 +486,6 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + return NULL; + } + +- /* Get group */ +- if ((group = EC_KEY_get0_group(eckey)) == NULL) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_SIGN_SIG, IBMCA_R_EC_INVALID_PARM); +- return NULL; +- } +- + /* Check if key usable */ + #ifndef OLDER_OPENSSL + if (!EC_KEY_can_sign(eckey)) { +@@ -249,15 +495,14 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + } + #endif + +- /* Get curve nid */ +- nid = EC_GROUP_get_curve_name(group); +- if (nid <= 0) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_SIGN_SIG, IBMCA_R_EC_UNSUPPORTED_CURVE); +- return NULL; ++ if (data != NULL) { ++ icakey = data->ica_key; ++ privlen = data->privlen; ++ goto do_sign; + } + + /* Create ICA_EC_KEY object */ +- icakey = p_ica_ec_key_new(nid, &privlen); ++ icakey = ibmca_ec_make_and_cache_ica_key(eckey, &privlen); + if (icakey == NULL) { + /* This curve is not supported by libica. */ + #ifdef OLDER_OPENSSL +@@ -287,25 +532,7 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + return sig; + } + +- /* Get private (D) value from EC_KEY */ +- bn_d = (BIGNUM*)EC_KEY_get0_private_key(eckey); +- if (bn_d == NULL) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_SIGN_SIG, IBMCA_R_EC_INTERNAL_ERROR); +- goto end; +- } +- +- /* Format (D) as char array, with leading zeros if necessary */ +- n = privlen - BN_num_bytes(bn_d); +- memset(D, 0, n); +- BN_bn2bin(bn_d, &(D[n])); +- +- /* Initialize private ICA_EC_KEY */ +- rc = p_ica_ec_key_init(NULL, NULL, D, icakey); +- if (rc != 0) { +- IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); +- goto end; +- } +- ++do_sign: + /* Call libica signing routine */ + rc = p_ica_ecdsa_sign(ibmca_handle, icakey, dgst, dgst_len, sigret, + sizeof(sigret)); +@@ -343,7 +570,6 @@ ECDSA_SIG *ibmca_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + s = BN_bin2bn(sigret + privlen, privlen, NULL); + sig = ECDSA_SIG_new(); + +-end: + #ifndef OLDER_OPENSSL + if (sig) + ECDSA_SIG_set0(sig, r, s); +@@ -357,7 +583,6 @@ end: + #endif + + end2: +- p_ica_ec_key_free(icakey); + return sig; + } + +@@ -372,16 +597,12 @@ end2: + int ibmca_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) + { +- const EC_GROUP *group; +- const EC_POINT *q; +- unsigned char x_array[IBMCA_EC_MAX_D_LEN]; +- unsigned char y_array[IBMCA_EC_MAX_D_LEN]; + unsigned char sig_array[IBMCA_EC_MAX_Q_LEN]; + BIGNUM *bn_x = NULL, *bn_y = NULL; + const BIGNUM *bn_r, *bn_s; + unsigned int privlen; + ICA_EC_KEY *icakey = NULL; +- int rc, n, nid; ++ int rc, n; + int ret = -1; + #ifndef OLDER_OPENSSL + int (*verify_sw)(int type, const unsigned char *dgst, int dgst_len, +@@ -389,6 +610,7 @@ int ibmca_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + #endif + int (*verify_sig_sw)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) = NULL; ++ struct ibmca_ec_ex_data *data = EC_KEY_get_ex_data(eckey, ec_ex_data_index); + + /* Check parms */ + if (eckey == NULL || sig == NULL) { +@@ -404,21 +626,14 @@ int ibmca_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + } + #endif + +- /* Get group */ +- if ((group = EC_KEY_get0_group(eckey)) == NULL) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_VERIFY_SIG, IBMCA_R_EC_INTERNAL_ERROR); +- return ret; +- } +- +- /* Get curve nid */ +- nid = EC_GROUP_get_curve_name(group); +- if (nid <= 0) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_VERIFY_SIG, IBMCA_R_EC_UNSUPPORTED_CURVE); +- return ret; ++ if (data != NULL) { ++ icakey = data->ica_key; ++ privlen = data->privlen; ++ goto do_verify; + } + + /* Create ICA_EC_KEY object */ +- icakey = p_ica_ec_key_new(nid, &privlen); ++ icakey = ibmca_ec_make_and_cache_ica_key(eckey, &privlen); + if (icakey == NULL) { + /* This curve is not supported by libica. */ + #ifdef OLDER_OPENSSL +@@ -440,32 +655,7 @@ int ibmca_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + return verify_sig_sw(dgst, dgst_len, sig, eckey); + } + +- /* Provide public key (X,Y) */ +- bn_x = BN_new(); +- bn_y = BN_new(); +- q = EC_KEY_get0_public_key(eckey); +- if (!EC_POINT_get_affine_coordinates_GFp(group, q, bn_x, bn_y, NULL)) { +- IBMCAerr(IBMCA_F_IBMCA_ECDSA_VERIFY_SIG, IBMCA_R_EC_INTERNAL_ERROR); +- goto end; +- } +- +- /* Format (X) as char array with leading nulls if necessary */ +- n = privlen - BN_num_bytes(bn_x); +- memset(x_array, 0, n); +- BN_bn2bin(bn_x, &(x_array[n])); +- +- /* Format (Y) as char array with leading nulls if necessary */ +- n = privlen - BN_num_bytes(bn_y); +- memset(y_array, 0, n); +- BN_bn2bin(bn_y, &(y_array[n])); +- +- /* Initialize ICA_EC_KEY */ +- rc = p_ica_ec_key_init(x_array, y_array, NULL, icakey); +- if (rc != 0) { +- IBMCAerr(IBMCA_F_ICA_EC_KEY_INIT, rc); +- goto end; +- } +- ++do_verify: + /* Get (r,s) from ECDSA_SIG */ + #ifdef OLDER_OPENSSL + bn_r = sig->r; +@@ -517,7 +707,6 @@ int ibmca_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + } + + end: +- p_ica_ec_key_free(icakey); + BN_clear_free(bn_x); + BN_clear_free(bn_y); + +-- +2.39.0 + + +From 072e32bb199ff772148f1cbe0b2faadf9ab33c12 Mon Sep 17 00:00:00 2001 +From: Juergen Christ +Date: Thu, 27 Oct 2022 16:13:01 +0200 +Subject: [PATCH 3/4] provider: Fix configuration script + +Small typo in the configuration script created an invalid configuration. + +Signed-off-by: Juergen Christ +--- + src/provider/ibmca-provider-opensslconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/provider/ibmca-provider-opensslconfig b/src/provider/ibmca-provider-opensslconfig +index 21ed6f6..d45428e 100755 +--- a/src/provider/ibmca-provider-opensslconfig ++++ b/src/provider/ibmca-provider-opensslconfig +@@ -83,7 +83,7 @@ sub generate() + } + if ($providersect && $line =~ /\[\s*$providersect\s*\]/) { + print $oh "ibmca_provider = ibmca_provider_section\n"; +- print $oh # Make sure that you have configured and activated at least one other provider!\n"; ++ print $oh "# Make sure that you have configured and activated at least one other provider!\n"; + print "WARNING: The IBMCA provider was added to section [$providersect].\n"; + print "Make sure that you have configured and activated at least one other provider, e.g. the default provider!\n"; + } +-- +2.39.0 + + +From e90203dbc9bf0d9a4488af470adf11852860991a Mon Sep 17 00:00:00 2001 +From: Juergen Christ +Date: Wed, 2 Nov 2022 14:29:35 +0100 +Subject: [PATCH 4/4] provider: Fix order of providers in configuration + +Since libica requires a provider that supports HMAC to be loaded and +available, fix the order of providers loaded by our sample configuration +generator. The "default" provider has to come first such that libica can do +the file integrity test with a HMAC provided by this provider when being +loaded via the ibmca provider. + +Signed-off-by: Juergen Christ +--- + src/provider/ibmca-provider-opensslconfig | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/src/provider/ibmca-provider-opensslconfig b/src/provider/ibmca-provider-opensslconfig +index d45428e..d87fa8e 100755 +--- a/src/provider/ibmca-provider-opensslconfig ++++ b/src/provider/ibmca-provider-opensslconfig +@@ -30,7 +30,7 @@ use warnings; + sub generate() + { + my ($osslconfpath); +- my ($ih, $line, $oh, $defaultcnfsect, $indefaultsect, $providersect); ++ my ($ih, $line, $oh, $defaultcnfsect, $indefaultsect, $providersect, $inprovidersect); + my ($inalgsect, $algsection); + + $osslconfpath = `openssl version -d` || die "Please install openssl binary"; +@@ -43,6 +43,7 @@ sub generate() + $defaultcnfsect = undef; + $indefaultsect = 0; + $providersect = undef; ++ $inprovidersect = 0; + while ($line = <$ih>) { + if ($line =~ /openssl_conf\s*=\s*(.*)/) { + $defaultcnfsect = $1; +@@ -67,13 +68,22 @@ sub generate() + } elsif ($inalgsect) { + if ($line =~ /\[\s*\w+\s*\]/) { + print $oh "default_properties = ?provider=ibmca\n"; ++ $inalgsect = 0; + } elsif ($line =~ /^\s*default_properties\s*=\s*(\w+)\s*/) { + print $oh "default_properties = ?provider=ibmca\n"; + print $oh "# The following was commented out by ibmca-provider-opensslconfig script\n"; + print "WARNING: The default_properties in $algsection was modified by this script.\n"; + $line = "# $line"; + } +- } ++ } elsif ($inprovidersect) { ++ if ($line =~ /\[\s*\w+\s*\]/) { ++ $inprovidersect = 0; ++ print $oh "ibmca_provider = ibmca_provider_section\n"; ++ print $oh "# Make sure that you have configured and activated at least one other provider!\n"; ++ print "WARNING: The IBMCA provider was added to section [$providersect].\n"; ++ print "Make sure that you have configured and activated at least one other provider, e.g. the default provider!\n"; ++ } ++ } + print $oh "$line"; + if ($defaultcnfsect && $line =~ /\[\s*$defaultcnfsect\s*\]/) { + $indefaultsect = 1; +@@ -81,11 +91,8 @@ sub generate() + if ($algsection && $line =~ /\[\s*$algsection\s*\]/) { + $inalgsect = 1; + } +- if ($providersect && $line =~ /\[\s*$providersect\s*\]/) { +- print $oh "ibmca_provider = ibmca_provider_section\n"; +- print $oh "# Make sure that you have configured and activated at least one other provider!\n"; +- print "WARNING: The IBMCA provider was added to section [$providersect].\n"; +- print "Make sure that you have configured and activated at least one other provider, e.g. the default provider!\n"; ++ if ($providersect && $line =~ /\[\s*$providersect\s*\]/) { ++ $inprovidersect = 1; + } + } + +@@ -100,8 +107,8 @@ providers = provider_section + if (!$providersect) { + print $oh qq| + [provider_section] +-ibmca_provider = ibmca_provider_section + default = default_sect ++ibmca_provider = ibmca_provider_section + + [default_sect] + activate = 1 +-- +2.39.0 + diff --git a/SPECS/openssl-ibmca.spec b/SPECS/openssl-ibmca.spec index f401ce3..e6263a6 100644 --- a/SPECS/openssl-ibmca.spec +++ b/SPECS/openssl-ibmca.spec @@ -1,9 +1,5 @@ %global enginesdir %(pkg-config --variable=enginesdir libcrypto) -%global modulesdir %(openssl version -m | grep -o '".*"' | tr -d '"') -# Above can be replaced by the following once OpenSSL commit -# https://github.com/openssl/openssl/commit/7fde39de848f062d6db45bf9e69439db2100b9bb -# has been included into the distribution: -# %%global modulesdir %%(pkg-config --variable=modulesdir libcrypto) +%global modulesdir %(pkg-config --variable=modulesdir libcrypto) %if 0%{?fedora} >= 36 || 0%{?rhel} >= 9 %global with_openssl3 1 @@ -12,19 +8,21 @@ Summary: A dynamic OpenSSL engine for IBMCA Name: openssl-ibmca -Version: 2.3.0 -Release: 1%{?dist} +Version: 2.3.1 +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 # post GA fixes Patch0: %{name}-%{version}-fixes.patch +# warn the user about engine being deprecated +Patch1: %{name}-2.3.1-engine-warning.patch Requires: libica >= 4.0.0 BuildRequires: make BuildRequires: gcc BuildRequires: libica-devel >= 4.0.0 BuildRequires: automake libtool -BuildRequires: openssl +BuildRequires: openssl >= 3.0.5 BuildRequires: perl(FindBin) ExclusiveArch: s390 s390x @@ -80,6 +78,14 @@ make check %changelog +* Fri Jan 13 2023 Dan Horák - 2.3.1-2 +- fix provider configuration script (#2140028) +- Resolves: #2140028 + +* Thu Jan 12 2023 Dan Horák - 2.3.1-1 +- updated to 2.3.1 (#2110378) +- Resolves: #2110378 + * Thu May 19 2022 Dan Horák - 2.3.0-1 - updated to 2.3.0 (#2044177) - add provider for openssl 3.x (#2044185)