32d8188
From 1a75586c2821a55deeaa76861b1fc0539e6a3ca1 Mon Sep 17 00:00:00 2001
32d8188
From: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
Date: Fri, 1 Apr 2022 10:47:45 +0200
32d8188
Subject: [PATCH 1/5] SPEC: Fix version number in provider-spec file
32d8188
32d8188
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
---
32d8188
 openssl-ibmca-provider.spec | 6 +++++-
32d8188
 1 file changed, 5 insertions(+), 1 deletion(-)
32d8188
32d8188
diff --git a/openssl-ibmca-provider.spec b/openssl-ibmca-provider.spec
32d8188
index a3ef1a6..6c95b54 100644
32d8188
--- a/openssl-ibmca-provider.spec
32d8188
+++ b/openssl-ibmca-provider.spec
32d8188
@@ -5,7 +5,7 @@
32d8188
 # %global modulesdir %(pkg-config --variable=modulesdir libcrypto)
32d8188
 
32d8188
 Name:       openssl-ibmca
32d8188
-Version:    2.2.3
32d8188
+Version:    2.3.0
32d8188
 Release:    1%{?dist}
32d8188
 Summary:    An IBMCA OpenSSL dynamic provider
32d8188
 
32d8188
@@ -45,6 +45,10 @@ mv -f src/provider/openssl.cnf.sample src/provider/openssl.cnf.sample.%{_arch}
32d8188
 %dir %attr(777,root,root) %{_localstatedir}/log/ibmca
32d8188
 
32d8188
 %changelog
32d8188
+* Fri Mar 25 2022 Juergen Christ <jchrist@linux.ibm.com> 2.3.0
32d8188
+- First version including the provider
32d8188
+- Fix for engine build without OpenSSL 3.0 sources
32d8188
+
32d8188
 * Wed March 3 2022 Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
 - Add provider support
32d8188
 
32d8188
-- 
32d8188
2.36.1
32d8188
32d8188
32d8188
From 76341149f2102bb628da61c2653e5911ddb81084 Mon Sep 17 00:00:00 2001
32d8188
From: Juergen Christ <jchrist@linux.ibm.com>
32d8188
Date: Thu, 7 Apr 2022 12:32:36 +0200
32d8188
Subject: [PATCH 2/5] Adjust to new libica.
32d8188
32d8188
libica recently added function ica_cleanup to be called to free internal
32d8188
OpenSSL 3.0 resources.  This collided with our internal ica_cleanup function.
32d8188
Rename that and call ica_cleanup if present.
32d8188
32d8188
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
32d8188
---
32d8188
 configure.ac           |  2 ++
32d8188
 src/engine/e_ibmca.c   | 13 ++++++++++---
32d8188
 src/engine/ibmca.h     |  3 +++
32d8188
 src/provider/p_ibmca.c |  3 +++
32d8188
 4 files changed, 18 insertions(+), 3 deletions(-)
32d8188
32d8188
diff --git a/configure.ac b/configure.ac
32d8188
index 46ad10e..6434056 100644
32d8188
--- a/configure.ac
32d8188
+++ b/configure.ac
32d8188
@@ -130,6 +130,8 @@ if test "x$enable_provider" = xyes; then
32d8188
 		[#include <ica_api.h>])
32d8188
 fi
32d8188
 
32d8188
+AC_CHECK_DECLS([ica_cleanup],,,[#include <ica_api.h>])
32d8188
+
32d8188
 AC_CONFIG_FILES([
32d8188
 	Makefile
32d8188
 	src/Makefile
32d8188
diff --git a/src/engine/e_ibmca.c b/src/engine/e_ibmca.c
32d8188
index ef17349..7335246 100644
32d8188
--- a/src/engine/e_ibmca.c
32d8188
+++ b/src/engine/e_ibmca.c
32d8188
@@ -102,6 +102,7 @@ ica_aes_gcm_initialize_t        p_ica_aes_gcm_initialize;
32d8188
 ica_aes_gcm_intermediate_t      p_ica_aes_gcm_intermediate;
32d8188
 ica_aes_gcm_last_t              p_ica_aes_gcm_last;
32d8188
 #endif
32d8188
+ica_cleanup_t                   p_ica_cleanup;
32d8188
 
32d8188
 /* save libcrypto's default ec methods */
32d8188
 #ifndef NO_EC
32d8188
@@ -652,8 +653,10 @@ static void ibmca_destructor(void)
32d8188
         free((void *)LIBICA_NAME);
32d8188
 }
32d8188
 
32d8188
-static void ica_cleanup(void)
32d8188
+static void do_ica_cleanup(void)
32d8188
 {
32d8188
+    if (p_ica_cleanup)
32d8188
+        p_ica_cleanup();
32d8188
     if (ibmca_dso && dlclose(ibmca_dso)) {
32d8188
         IBMCAerr(IBMCA_F_IBMCA_FINISH, IBMCA_R_DSO_FAILURE);
32d8188
         return;
32d8188
@@ -725,6 +728,7 @@ static void ica_cleanup(void)
32d8188
     p_ica_x448_ctx_del = NULL;
32d8188
     p_ica_ed25519_ctx_del = NULL;
32d8188
     p_ica_ed448_ctx_del = NULL;
32d8188
+    p_ica_cleanup = NULL;
32d8188
 }
32d8188
 
32d8188
 static int ibmca_init(ENGINE *e)
32d8188
@@ -806,6 +810,9 @@ static int ibmca_init(ENGINE *e)
32d8188
     BIND(ibmca_dso, ica_ed25519_ctx_del);
32d8188
     BIND(ibmca_dso, ica_ed448_ctx_del);
32d8188
 
32d8188
+    /* ica_cleanup is not always present and only needed for newer libraries */
32d8188
+    p_ica_cleanup = (ica_cleanup_t)dlsym(ibmca_dso, "ica_cleanup");
32d8188
+
32d8188
     /* disable fallbacks on Libica */
32d8188
     if (BIND(ibmca_dso, ica_set_fallback_mode))
32d8188
         p_ica_set_fallback_mode(0);
32d8188
@@ -821,7 +828,7 @@ static int ibmca_init(ENGINE *e)
32d8188
     return 1;
32d8188
 
32d8188
 err:
32d8188
-    ica_cleanup();
32d8188
+    do_ica_cleanup();
32d8188
     return 0;
32d8188
 }
32d8188
 
32d8188
@@ -884,7 +891,7 @@ static int ibmca_finish(ENGINE *e)
32d8188
     if (p_ica_close_adapter)
32d8188
         p_ica_close_adapter(ibmca_handle);
32d8188
 
32d8188
-    ica_cleanup();
32d8188
+    do_ica_cleanup();
32d8188
     memset(&ibmca_registration, 0, sizeof(ibmca_registration));
32d8188
     return 1;
32d8188
 }
32d8188
diff --git a/src/engine/ibmca.h b/src/engine/ibmca.h
32d8188
index 382a45d..53f4ca1 100644
32d8188
--- a/src/engine/ibmca.h
32d8188
+++ b/src/engine/ibmca.h
32d8188
@@ -616,6 +616,8 @@ int (*ica_ed25519_ctx_del_t)(ICA_ED25519_CTX **ctx);
32d8188
 typedef
32d8188
 int (*ica_ed448_ctx_del_t)(ICA_ED448_CTX **ctx);
32d8188
 
32d8188
+typedef void (*ica_cleanup_t)(void);
32d8188
+
32d8188
 /* entry points into libica, filled out at DSO load time */
32d8188
 extern ica_get_functionlist_t           p_ica_get_functionlist;
32d8188
 extern ica_set_fallback_mode_t          p_ica_set_fallback_mode;
32d8188
@@ -681,3 +683,4 @@ extern ica_x25519_ctx_del_t		p_ica_x25519_ctx_del;
32d8188
 extern ica_x448_ctx_del_t		p_ica_x448_ctx_del;
32d8188
 extern ica_ed25519_ctx_del_t		p_ica_ed25519_ctx_del;
32d8188
 extern ica_ed448_ctx_del_t		p_ica_ed448_ctx_del;
32d8188
+extern ica_cleanup_t            p_ica_cleanup;
32d8188
diff --git a/src/provider/p_ibmca.c b/src/provider/p_ibmca.c
32d8188
index d8045ba..80f0368 100644
32d8188
--- a/src/provider/p_ibmca.c
32d8188
+++ b/src/provider/p_ibmca.c
32d8188
@@ -633,6 +633,9 @@ static void ibmca_teardown(void *vprovctx)
32d8188
     pthread_mutex_destroy(&provctx->debug_mutex);
32d8188
 
32d8188
     P_FREE(provctx, provctx);
32d8188
+#if HAVE_DECL_ICA_CLEANUP == 1
32d8188
+    ica_cleanup();
32d8188
+#endif
32d8188
 }
32d8188
 
32d8188
 static const OSSL_PARAM ibmca_param_types[] = {
32d8188
-- 
32d8188
2.36.1
32d8188
32d8188
32d8188
From 688273ec77530a44d43ad5133155e646a945bc88 Mon Sep 17 00:00:00 2001
32d8188
From: Juergen Christ <jchrist@linux.ibm.com>
32d8188
Date: Thu, 7 Apr 2022 12:33:44 +0200
32d8188
Subject: [PATCH 3/5] Support tests in remote builds.
32d8188
32d8188
If the build is not wihin the source tree, tests failed since they could not
32d8188
find the key files.  Add support for this.
32d8188
32d8188
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
32d8188
---
32d8188
 test/engine/test.pm  | 26 ++++++++++++++------------
32d8188
 test/provider/tls.pl | 13 +++++++------
32d8188
 2 files changed, 21 insertions(+), 18 deletions(-)
32d8188
32d8188
diff --git a/test/engine/test.pm b/test/engine/test.pm
32d8188
index 8e4b8ab..3a313e1 100644
32d8188
--- a/test/engine/test.pm
32d8188
+++ b/test/engine/test.pm
32d8188
@@ -3,6 +3,8 @@
32d8188
 use strict;
32d8188
 use warnings;
32d8188
 
32d8188
+use FindBin;
32d8188
+
32d8188
 package test;
32d8188
 
32d8188
 sub osslversion1 {
32d8188
@@ -69,16 +71,16 @@ sub rsaencdec {
32d8188
 		my $bytes = 1 + int(rand($max_file_size));
32d8188
 		# engine enc, no-engine dec
32d8188
 		`openssl rand $bytes > rsaencdec.${i}.${keylen}.data.in`;
32d8188
-		`$eng openssl rsautl -encrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`;
32d8188
-		`openssl rsautl -decrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`;
32d8188
+		`$eng openssl rsautl -encrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`;
32d8188
+		`openssl rsautl -decrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`;
32d8188
 		`cmp rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.data.dec`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.out rsaencdec.${i}.${keylen}.dec`;
32d8188
 
32d8188
 		# no-engine enc, engine dec
32d8188
 		`openssl rand $bytes > rsaencdec.${i}.${keylen}.data.in`;
32d8188
-		`openssl rsautl -encrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`;
32d8188
-		`$eng openssl rsautl -decrypt -inkey rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`;
32d8188
+		`openssl rsautl -encrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.in -out rsaencdec.${i}.${keylen}.data.out`;
32d8188
+		`$eng openssl rsautl -decrypt -inkey $FindBin::Bin/rsa$keylen.key -in rsaencdec.${i}.${keylen}.data.out -out rsaencdec.${i}.${keylen}.data.dec`;
32d8188
 		`cmp rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.data.dec`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f rsaencdec.${i}.${keylen}.data.in rsaencdec.${i}.${keylen}.out rsaencdec.${i}.${keylen}.dec`;
32d8188
@@ -100,16 +102,16 @@ sub rsasignverify {
32d8188
 		$key .= $hex[rand(@hex)] for (1..$keylen);
32d8188
 		# engine sign, no-engine verify
32d8188
 		`openssl rand $bytes > rsasignverify.${i}.${keylen}.data.in`;
32d8188
-		`$eng openssl rsautl -sign -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`;
32d8188
-		`openssl rsautl -verify -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
+		`$eng openssl rsautl -sign -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`;
32d8188
+		`openssl rsautl -verify -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
 		`cmp rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.rec`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
 
32d8188
 		# no-engine sign, engine verify
32d8188
 		`openssl rand $bytes > rsasignverify.${i}.${keylen}.data.in`;
32d8188
-		`openssl rsautl -sign -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`;
32d8188
-		`$eng openssl rsautl -verify -inkey rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
+		`openssl rsautl -sign -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.in -out rsasignverify.${i}.${keylen}.data.out`;
32d8188
+		`$eng openssl rsautl -verify -inkey $FindBin::Bin/rsa$keylen.key -in rsasignverify.${i}.${keylen}.data.out -out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
 		`cmp rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.rec`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f rsasignverify.${i}.${keylen}.data.in rsasignverify.${i}.${keylen}.data.out rsasignverify.${i}.${keylen}.data.rec`;
32d8188
@@ -131,15 +133,15 @@ sub dsasignverify {
32d8188
 		my $bytes = 1 + int(rand($max_file_size));
32d8188
 		# engine sign, no-engine verify
32d8188
 		`openssl rand $bytes > dsa.${i}.${keylen}.data.in`;
32d8188
-		`$eng openssl dgst -sign dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
-		`openssl dgst -verify dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
+		`$eng openssl dgst -sign $FindBin::Bin/dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
+		`openssl dgst -verify $FindBin::Bin/dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f dsa.${i}.${keylen}.data.in dsa.${i}.${keylen}.data.out`;
32d8188
 
32d8188
 		# no-engine sign, engine verify
32d8188
 		`openssl rand $bytes > dsa.${i}.${keylen}.data.in`;
32d8188
-		`openssl dgst -sign dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
-		`$eng openssl dgst -verify dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
+		`openssl dgst -sign $FindBin::Bin/dsa$keylen.key -out dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
+		`$eng openssl dgst -verify $FindBin::Bin/dsa${keylen}_pub.key -signature dsa.${i}.${keylen}.data.out dsa.${i}.${keylen}.data.in`;
32d8188
 		exit(99) if ($?);
32d8188
 		`rm -f dsa.${i}.${keylen}.data.in dsa.${i}.${keylen}.data.out`;
32d8188
 	}
32d8188
diff --git a/test/provider/tls.pl b/test/provider/tls.pl
32d8188
index c8871d4..0d9df6d 100755
32d8188
--- a/test/provider/tls.pl
32d8188
+++ b/test/provider/tls.pl
32d8188
@@ -19,17 +19,18 @@
32d8188
 use strict;
32d8188
 use warnings;
32d8188
 use test;
32d8188
+use FindBin;
32d8188
 
32d8188
 # TLS 1.3 with RSA signatures
32d8188
-test::tls(10001, "server-key-rsa.pem", "server-cert-rsa.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3");
32d8188
+test::tls(10001, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3");
32d8188
 # TLS 1.3 with EC signatures
32d8188
-test::tls(10002, "server-key-ec.pem", "server-cert-ec.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3");
32d8188
+test::tls(10002, "$FindBin::Bin/server-key-ec.pem", "$FindBin::Bin/server-cert-ec.pem", "ALL", "TLS_AES_256_GCM_SHA384", "-tls1_3");
32d8188
 # TLS 1.2 with RSA signatures and ECDH key exchange
32d8188
-test::tls(10003, "server-key-rsa.pem", "server-cert-rsa.pem", "ECDHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
+test::tls(10003, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "ECDHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
 # TLS 1.2 with ECDSA signatures and ECDH key exchange
32d8188
-test::tls(10004, "server-key-ec.pem", "server-cert-ec.pem", "ECDHE-ECDSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
+test::tls(10004, "$FindBin::Bin/server-key-ec.pem", "$FindBin::Bin/server-cert-ec.pem", "ECDHE-ECDSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
 # TLS 1.2 with RSA signatures and DH key exchange
32d8188
-test::tls(10005, "server-key-rsa.pem", "server-cert-rsa.pem", "DHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
+test::tls(10005, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "DHE-RSA-AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
 # TLS 1.2 with RSA signatures and RSA key exchange
32d8188
-test::tls(10006, "server-key-rsa.pem", "server-cert-rsa.pem", "AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
+test::tls(10006, "$FindBin::Bin/server-key-rsa.pem", "$FindBin::Bin/server-cert-rsa.pem", "AES256-GCM-SHA384", "\"\"", "-no_tls1_3");
32d8188
 
32d8188
-- 
32d8188
2.36.1
32d8188
32d8188
32d8188
From c0d384b72f280a4bd1c71407df0583da1847f5cb Mon Sep 17 00:00:00 2001
32d8188
From: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
Date: Thu, 12 May 2022 11:20:18 +0200
32d8188
Subject: [PATCH 4/5] provider: Adapt keymgmt_match() implementations to
32d8188
 OpenSSL
32d8188
32d8188
OpenSSL commit ee22a3741e3fc27c981e7f7e9bcb8d3342b0c65a changed the
32d8188
OpenSSL provider's keymgmt_match() function to be not so strict with
32d8188
the selector bits in regards to matching different key parts.
32d8188
32d8188
Adapt the provider's match functions accordingly.
32d8188
This means, that if the public key is selected to be matched, and the
32d8188
public key matches (together with any also selected parameters),
32d8188
then the private key is no longer checked, although it may also be
32d8188
selected to be matched. This is according to how the OpenSSL function
32d8188
EVP_PKEY_eq() is supposed to behave.
32d8188
32d8188
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
---
32d8188
 src/provider/dh_keymgmt.c  | 2 +-
32d8188
 src/provider/ec_keymgmt.c  | 5 +++--
32d8188
 src/provider/rsa_keymgmt.c | 8 +++++---
32d8188
 3 files changed, 9 insertions(+), 6 deletions(-)
32d8188
32d8188
diff --git a/src/provider/dh_keymgmt.c b/src/provider/dh_keymgmt.c
32d8188
index 48ba739..3180158 100644
32d8188
--- a/src/provider/dh_keymgmt.c
32d8188
+++ b/src/provider/dh_keymgmt.c
32d8188
@@ -1000,7 +1000,7 @@ static int ibmca_keymgmt_dh_match(const void *vkey1, const void *vkey2,
32d8188
             }
32d8188
         }
32d8188
 
32d8188
-        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
32d8188
+        if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
32d8188
             if (key1->dh.priv != NULL || key2->dh.priv != NULL) {
32d8188
                 ok = ok && (BN_cmp(key1->dh.priv, key2->dh.priv) == 0);
32d8188
                 checked = 1;
32d8188
diff --git a/src/provider/ec_keymgmt.c b/src/provider/ec_keymgmt.c
32d8188
index d898c6a..d39b1e2 100644
32d8188
--- a/src/provider/ec_keymgmt.c
32d8188
+++ b/src/provider/ec_keymgmt.c
32d8188
@@ -751,7 +751,7 @@ static int ibmca_keymgmt_ec_match(const void *vkey1, const void *vkey2,
32d8188
     const struct ibmca_key *key2 = vkey2;
32d8188
     BIGNUM *x1 = NULL, *y1 = NULL, *d1 = NULL;
32d8188
     BIGNUM *x2 = NULL, *y2 = NULL, *d2 = NULL;
32d8188
-    int ok = 1, rc1, rc2;
32d8188
+    int ok = 1, rc1, rc2, checked = 0;
32d8188
 
32d8188
     if (key1 == NULL || key2 == NULL)
32d8188
         return 0;
32d8188
@@ -781,9 +781,10 @@ static int ibmca_keymgmt_ec_match(const void *vkey1, const void *vkey2,
32d8188
 
32d8188
         ok = ok && (rc1 == rc2 && (rc1 == -1 ||
32d8188
                     (BN_cmp(x1, x2) == 0 && BN_cmp(y1, y2) == 0)));
32d8188
+        checked = 1;
32d8188
     }
32d8188
 
32d8188
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
32d8188
+    if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
32d8188
         rc1 = ibmca_keymgmt_ec_priv_key_as_bn(key1, &d1;;
32d8188
         if (rc1 == 0) {
32d8188
             ok = 0;
32d8188
diff --git a/src/provider/rsa_keymgmt.c b/src/provider/rsa_keymgmt.c
32d8188
index 61f7744..9278327 100644
32d8188
--- a/src/provider/rsa_keymgmt.c
32d8188
+++ b/src/provider/rsa_keymgmt.c
32d8188
@@ -641,7 +641,7 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2,
32d8188
 {
32d8188
     const struct ibmca_key *key1 = vkey1;
32d8188
     const struct ibmca_key *key2 = vkey2;
32d8188
-    int ok = 1;
32d8188
+    int ok = 1, checked = 0;
32d8188
 
32d8188
     if (key1 == NULL || key2 == NULL)
32d8188
         return 0;
32d8188
@@ -652,7 +652,7 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2,
32d8188
     if (ibmca_keymgmt_match(key1, key2) == 0)
32d8188
         return 0;
32d8188
 
32d8188
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
32d8188
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
32d8188
         ok = ok && (key1->rsa.public.key_length ==
32d8188
                            key2->rsa.public.key_length &&
32d8188
                     memcmp(key1->rsa.public.exponent,
32d8188
@@ -661,8 +661,10 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2,
32d8188
                     memcmp(key1->rsa.public.modulus,
32d8188
                            key2->rsa.public.modulus,
32d8188
                            key1->rsa.public.key_length) == 0);
32d8188
+        checked = 1;
32d8188
+    }
32d8188
 
32d8188
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
32d8188
+    if (!checked && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
32d8188
         ok = ok && (key1->rsa.private.key_length ==
32d8188
                            key2->rsa.private.key_length &&
32d8188
                     CRYPTO_memcmp(key1->rsa.private.p,
32d8188
-- 
32d8188
2.36.1
32d8188
32d8188
32d8188
From 49be3a5c9c1258e0dc15bbc50d5aa04a0ba4ba66 Mon Sep 17 00:00:00 2001
32d8188
From: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
Date: Wed, 18 May 2022 15:41:12 +0200
32d8188
Subject: [PATCH 5/5] tests: skip tests if libica does not support required
32d8188
 algorithms
32d8188
32d8188
Before actually running the tests, check if libica supports the
32d8188
required algorithms. Skip the whole test if not.
32d8188
32d8188
This can happen when running the test on a system without appropriate
32d8188
crypto adapters. This would lead to the situation that the provider would
32d8188
not register itself for the required algorithms, and thus the OpenSSL
32d8188
default provider would be used. This would make the tests to fail, because
32d8188
it is not running with the IBMCA provider as expected by the test.
32d8188
32d8188
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
32d8188
---
32d8188
 test/provider/Makefile.am | 18 ++++++++++---
32d8188
 test/provider/dhkey.c     | 56 ++++++++++++++++++++++++++++++++++++++
32d8188
 test/provider/eckey.c     | 57 +++++++++++++++++++++++++++++++++++++++
32d8188
 test/provider/rsakey.c    | 56 ++++++++++++++++++++++++++++++++++++++
32d8188
 4 files changed, 184 insertions(+), 3 deletions(-)
32d8188
32d8188
diff --git a/test/provider/Makefile.am b/test/provider/Makefile.am
32d8188
index f5cb97d..b007682 100644
32d8188
--- a/test/provider/Makefile.am
32d8188
+++ b/test/provider/Makefile.am
32d8188
@@ -20,13 +20,25 @@ TESTS = \
32d8188
 check_PROGRAMS = rsakey eckey dhkey threadtest
32d8188
 
32d8188
 dhkey_SOURCES = dhkey.c
32d8188
-dhkey_LDADD = -lcrypto
32d8188
+if PROVIDER_FULL_LIBICA
32d8188
+dhkey_LDADD = -lcrypto -lica
32d8188
+else
32d8188
+dhkey_LDADD = -lcrypto -lica-cex
32d8188
+endif
32d8188
 
32d8188
 eckey_SOURCES = eckey.c
32d8188
-eckey_LDADD = -lcrypto
32d8188
+if PROVIDER_FULL_LIBICA
32d8188
+eckey_LDADD = -lcrypto -lica
32d8188
+else
32d8188
+eckey_LDADD = -lcrypto -lica-cex
32d8188
+endif
32d8188
 
32d8188
 rsakey_SOURCES = rsakey.c
32d8188
-rsakey_LDADD = -lcrypto
32d8188
+if PROVIDER_FULL_LIBICA
32d8188
+rsakey_LDADD = -lcrypto -lica
32d8188
+else
32d8188
+rsakey_LDADD = -lcrypto -lica-cex
32d8188
+endif
32d8188
 
32d8188
 threadtest_SOURCES = threadtest.c
32d8188
 threadtest_LDADD = -lcrypto -lpthread
32d8188
diff --git a/test/provider/dhkey.c b/test/provider/dhkey.c
32d8188
index a9cea13..8829ecc 100644
32d8188
--- a/test/provider/dhkey.c
32d8188
+++ b/test/provider/dhkey.c
32d8188
@@ -27,6 +27,8 @@
32d8188
 #include <openssl/core_names.h>
32d8188
 #include <openssl/err.h>
32d8188
 
32d8188
+#include <ica_api.h>
32d8188
+
32d8188
 #define UNUSED(var)                             ((void)(var))
32d8188
 
32d8188
 void setup(void)
32d8188
@@ -349,6 +351,56 @@ int check_dhkey(int nid, const char *name, const char *algo)
32d8188
     return ret;
32d8188
 }
32d8188
 
32d8188
+static const unsigned int required_ica_mechs[] = { RSA_ME };
32d8188
+static const unsigned int required_ica_mechs_len =
32d8188
+                        sizeof(required_ica_mechs) / sizeof(unsigned int);
32d8188
+
32d8188
+int check_libica()
32d8188
+{
32d8188
+    unsigned int mech_len, i, k, found = 0;
32d8188
+    libica_func_list_element *mech_list = NULL;
32d8188
+    int rc;
32d8188
+
32d8188
+    rc = ica_get_functionlist(NULL, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    mech_list = calloc(sizeof(libica_func_list_element), mech_len);
32d8188
+    if (mech_list == NULL) {
32d8188
+        fprintf(stderr, "Failed to allocate memory for function list!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    rc = ica_get_functionlist(mech_list, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        free(mech_list);
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    for (i = 0; i < mech_len; i++) {
32d8188
+        for (k = 0; k < required_ica_mechs_len; k++) {
32d8188
+            if (mech_list[i].mech_mode_id == required_ica_mechs[k]) {
32d8188
+                if (mech_list[i].flags &
32d8188
+                    (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW))
32d8188
+                    found++;
32d8188
+            }
32d8188
+        }
32d8188
+    }
32d8188
+
32d8188
+    free(mech_list);
32d8188
+
32d8188
+    if (found < required_ica_mechs_len) {
32d8188
+        fprintf(stderr,
32d8188
+               "Libica does not support the required algorithms, skipping.\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    return 0;
32d8188
+}
32d8188
+
32d8188
 int main(int argc, char **argv)
32d8188
 {
32d8188
     static const struct testparams {
32d8188
@@ -389,6 +441,10 @@ int main(int argc, char **argv)
32d8188
         return 77;
32d8188
     }
32d8188
 
32d8188
+    ret = check_libica();
32d8188
+    if (ret != 0)
32d8188
+        return ret;
32d8188
+
32d8188
     setup();
32d8188
     for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) {
32d8188
         if (!check_dhkey(params[i].nid, params[i].name, "DH")) {
32d8188
diff --git a/test/provider/eckey.c b/test/provider/eckey.c
32d8188
index 279b942..b2334d7 100644
32d8188
--- a/test/provider/eckey.c
32d8188
+++ b/test/provider/eckey.c
32d8188
@@ -27,6 +27,8 @@
32d8188
 #include <openssl/core_names.h>
32d8188
 #include <openssl/err.h>
32d8188
 
32d8188
+#include <ica_api.h>
32d8188
+
32d8188
 #define UNUSED(var)                             ((void)(var))
32d8188
 
32d8188
 void setup(void)
32d8188
@@ -781,6 +783,57 @@ int check_eckey(int nid, const char *name)
32d8188
     return ret;
32d8188
 }
32d8188
 
32d8188
+static const unsigned int required_ica_mechs[] = { EC_DH, EC_DSA_SIGN,
32d8188
+                                                   EC_DSA_VERIFY, EC_KGEN, };
32d8188
+static const unsigned int required_ica_mechs_len =
32d8188
+                        sizeof(required_ica_mechs) / sizeof(unsigned int);
32d8188
+
32d8188
+int check_libica()
32d8188
+{
32d8188
+    unsigned int mech_len, i, k, found = 0;
32d8188
+    libica_func_list_element *mech_list = NULL;
32d8188
+    int rc;
32d8188
+
32d8188
+    rc = ica_get_functionlist(NULL, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    mech_list = calloc(sizeof(libica_func_list_element), mech_len);
32d8188
+    if (mech_list == NULL) {
32d8188
+        fprintf(stderr, "Failed to allocate memory for function list!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    rc = ica_get_functionlist(mech_list, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        free(mech_list);
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    for (i = 0; i < mech_len; i++) {
32d8188
+        for (k = 0; k < required_ica_mechs_len; k++) {
32d8188
+            if (mech_list[i].mech_mode_id == required_ica_mechs[k]) {
32d8188
+                if (mech_list[i].flags &
32d8188
+                    (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW))
32d8188
+                    found++;
32d8188
+            }
32d8188
+        }
32d8188
+    }
32d8188
+
32d8188
+    free(mech_list);
32d8188
+
32d8188
+    if (found < required_ica_mechs_len) {
32d8188
+        fprintf(stderr,
32d8188
+               "Libica does not support the required algorithms, skipping.\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    return 0;
32d8188
+}
32d8188
+
32d8188
 int main(int argc, char **argv)
32d8188
 {
32d8188
     static const struct testparams {
32d8188
@@ -822,6 +875,10 @@ int main(int argc, char **argv)
32d8188
         return 77;
32d8188
     }
32d8188
 
32d8188
+    ret = check_libica();
32d8188
+    if (ret != 0)
32d8188
+        return ret;
32d8188
+
32d8188
     setup();
32d8188
     for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) {
32d8188
         if (!check_eckey(params[i].nid, params[i].name)) {
32d8188
diff --git a/test/provider/rsakey.c b/test/provider/rsakey.c
32d8188
index 0adface..366b503 100644
32d8188
--- a/test/provider/rsakey.c
32d8188
+++ b/test/provider/rsakey.c
32d8188
@@ -26,6 +26,8 @@
32d8188
 #include <openssl/provider.h>
32d8188
 #include <openssl/err.h>
32d8188
 
32d8188
+#include <ica_api.h>
32d8188
+
32d8188
 #define UNUSED(var)                             ((void)(var))
32d8188
 
32d8188
 void setup(void)
32d8188
@@ -729,6 +731,56 @@ int check_rsakey(int bits, const char *algo, const char *name)
32d8188
     return ret;
32d8188
 }
32d8188
 
32d8188
+static const unsigned int required_ica_mechs[] = { RSA_ME,  RSA_CRT };
32d8188
+static const unsigned int required_ica_mechs_len =
32d8188
+                        sizeof(required_ica_mechs) / sizeof(unsigned int);
32d8188
+
32d8188
+int check_libica()
32d8188
+{
32d8188
+    unsigned int mech_len, i, k, found = 0;
32d8188
+    libica_func_list_element *mech_list = NULL;
32d8188
+    int rc;
32d8188
+
32d8188
+    rc = ica_get_functionlist(NULL, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    mech_list = calloc(sizeof(libica_func_list_element), mech_len);
32d8188
+    if (mech_list == NULL) {
32d8188
+        fprintf(stderr, "Failed to allocate memory for function list!\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    rc = ica_get_functionlist(mech_list, &mech_len);
32d8188
+    if (rc != 0) {
32d8188
+        fprintf(stderr, "Failed to get function list from libica!\n");
32d8188
+        free(mech_list);
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    for (i = 0; i < mech_len; i++) {
32d8188
+        for (k = 0; k < required_ica_mechs_len; k++) {
32d8188
+            if (mech_list[i].mech_mode_id == required_ica_mechs[k]) {
32d8188
+                if (mech_list[i].flags &
32d8188
+                    (ICA_FLAG_SW | ICA_FLAG_SHW | ICA_FLAG_DHW))
32d8188
+                    found++;
32d8188
+            }
32d8188
+        }
32d8188
+    }
32d8188
+
32d8188
+    free(mech_list);
32d8188
+
32d8188
+    if (found < required_ica_mechs_len) {
32d8188
+        fprintf(stderr,
32d8188
+               "Libica does not support the required algorithms, skipping.\n");
32d8188
+        return 77;
32d8188
+    }
32d8188
+
32d8188
+    return 0;
32d8188
+}
32d8188
+
32d8188
 int main(int argc, char **argv)
32d8188
 {
32d8188
     static const struct testparams {
32d8188
@@ -767,6 +819,10 @@ int main(int argc, char **argv)
32d8188
         return 77;
32d8188
     }
32d8188
 
32d8188
+    ret = check_libica();
32d8188
+    if (ret != 0)
32d8188
+        return ret;
32d8188
+
32d8188
     setup();
32d8188
     for (i = 0; i < (int)(sizeof(params) / sizeof(struct testparams)); ++i) {
32d8188
         if (!check_rsakey(params[i].bits, params[i].algo, params[i].name)) {
32d8188
-- 
32d8188
2.36.1
32d8188