diff -Nru openssl-ibmca-2.4.0/bootstrap.sh openssl-ibmca-2.4.1/bootstrap.sh --- openssl-ibmca-2.4.0/bootstrap.sh 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/bootstrap.sh 2023-09-21 08:52:43.000000000 +0200 @@ -15,4 +15,4 @@ # limitations under the License. # -autoreconf -iv +autoreconf --force --install --verbose --warnings=all diff -Nru openssl-ibmca-2.4.0/ChangeLog openssl-ibmca-2.4.1/ChangeLog --- openssl-ibmca-2.4.0/ChangeLog 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/ChangeLog 2023-09-21 08:52:43.000000000 +0200 @@ -1,3 +1,7 @@ +* openssl-ibmca 2.4.1 +- Provider: Change the default log directory to /tmp +- Bug fixes + * openssl-ibmca 2.4.0 - Provider: Adjustments for OpenSSL versions 3.1 and 3.2 - Provider: Support RSA blinding diff -Nru openssl-ibmca-2.4.0/configure.ac openssl-ibmca-2.4.1/configure.ac --- openssl-ibmca-2.4.0/configure.ac 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/configure.ac 2023-09-21 08:52:43.000000000 +0200 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. # See autoconf and autoscan online documentation for details. -AC_INIT([openssl-ibmca], [2.4.0], [https://github.com/opencryptoki/openssl-ibmca/issues],[],[https://github.com/opencryptoki/openssl-ibmca]) +AC_INIT([openssl-ibmca], [2.4.1], [https://github.com/opencryptoki/openssl-ibmca/issues],[],[https://github.com/opencryptoki/openssl-ibmca]) AC_CONFIG_SRCDIR([src/engine/e_ibmca.c]) # sanity check AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) @@ -10,7 +10,7 @@ AC_PATH_PROG([CHMOD], [chmod], [/bin/chmod]) -logdir=$localstatedir/log/ibmca +logdir=/tmp AC_SUBST(logdir) # Cmdline arguments. @@ -48,6 +48,20 @@ AC_PROG_CC LT_INIT +dnl --- check for perl +AC_PATH_PROG(PERL, perl) +if test -z "$PERL" ; then + AC_MSG_ERROR([Please install perl]) +fi + +AC_MSG_CHECKING([if perl module 'FindBin' is installed]) +(echo "use FindBin;" ; echo "exit(0);") | $PERL > /dev/null 2>&1 +if test $? != 0 ; then + AC_MSG_RESULT(no) + AC_MSG_ERROR([Please install perl-FindBin]) +fi +AC_MSG_RESULT(yes) + # Checks for libraries. AC_CHECK_LIB([crypto], [RAND_add], [], AC_MSG_ERROR([*** openssl >= 1.1.1 is required ***])) AC_CHECK_LIB([crypto], [OSSL_LIB_CTX_new], [openssl_3_0="yes"], [openssl_3_0="no"]) diff -Nru openssl-ibmca-2.4.0/debian/changelog openssl-ibmca-2.4.1/debian/changelog --- openssl-ibmca-2.4.0/debian/changelog 2023-07-27 16:38:43.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/changelog 2024-01-22 19:51:21.000000000 +0100 @@ -1,3 +1,11 @@ +openssl-ibmca (2.4.1-0ubuntu1) noble; urgency=medium + + * New upstream release. LP: #2050025 + - Adjust d/p/testconf-openssl3.patch due to slightly different context. + - Remove 5 patches d/p/lp-2027809-* since they are incl. in upstream 2.4.1. + + -- Frank Heimes Mon, 22 Jan 2024 19:51:21 +0100 + openssl-ibmca (2.4.0-0ubuntu2) mantic; urgency=medium * Add selected commits/patches as requested here: LP: #2027809 diff -Nru openssl-ibmca-2.4.0/debian/patches/lp-2027809-engine-Only-register-those-algos-specified-with-defa.patch openssl-ibmca-2.4.1/debian/patches/lp-2027809-engine-Only-register-those-algos-specified-with-defa.patch --- openssl-ibmca-2.4.0/debian/patches/lp-2027809-engine-Only-register-those-algos-specified-with-defa.patch 2023-07-27 16:38:33.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/lp-2027809-engine-Only-register-those-algos-specified-with-defa.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,48 +0,0 @@ -From 3ea8f4ed58e075e097856437c0732e11771931d0 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Wed, 19 Apr 2023 10:07:01 +0200 -Subject: [PATCH] engine: Only register those algos specified with - default_algorithms - -As part of OpenSSL initialization, the engine(s) configured in the OpenSSL -config file are loaded, and its algorithms (methods) are registered according -to the default_algorithms setting. - -However, later during initialization, ENGINE_register_all_complete() is called -which unconditionally registered all algorithms (methods) of the loaded engines -again, unless the engine flag ENGINE_FLAGS_NO_REGISTER_ALL is set. - -Set the ENGINE_FLAGS_NO_REGISTER_ALL flag during IBMCA engine initialization -to avoid unconditional registration of all algorithms. We only want to register -algorithms specified in the default_algorithms configuration setting. - -Note that if the default_algorithms setting is omitted in the OpenSSL config -file, then no algorithms will be registered. - -Signed-off-by: Ingo Franzki - -Origin: upstream, https://github.com/opencryptoki/openssl-ibmca/3ea8f4ed58e075e097856437c0732e11771931d0 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2027809 -Last-Update: 2023-07-27 - ---- - src/engine/e_ibmca.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/engine/e_ibmca.c b/src/engine/e_ibmca.c -index fe21897..6cbf745 100644 ---- a/src/engine/e_ibmca.c -+++ b/src/engine/e_ibmca.c -@@ -642,6 +642,9 @@ static int set_supported_meths(ENGINE *e) - if (!ENGINE_set_pkey_meths(e, ibmca_engine_pkey_meths)) - goto out; - -+ if (!ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)) -+ goto out; -+ - rc = 1; - out: - free(pmech_list); --- -2.25.1 - diff -Nru openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-Default-debug-directory-to-tmp-but-make-it-.patch openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-Default-debug-directory-to-tmp-but-make-it-.patch --- openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-Default-debug-directory-to-tmp-but-make-it-.patch 2023-07-27 16:38:33.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-Default-debug-directory-to-tmp-but-make-it-.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,226 +0,0 @@ -From 2298d3964f1ce32d35bb7585e4fa224c5bf2c8d4 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Wed, 26 Jul 2023 15:19:55 +0200 -Subject: [PATCH] provider: Default debug directory to /tmp but make it - configurable - -The IBMCA provider debug logs were written to the /var/log/ibmca/ directory, -but this required that directory to be world-writable, because we don't know -under which user an application runs that uses the provider. -A world-writable directory under /var has security implications and should be -avoided. - -Change the default log directory to /tmp which is world-writable anyway. -Additionally the log directory can now be configured via the 'debug-path' -option in the IBMCA provider section of the OpenSSL config file, or via -environment variable 'IBMCA_DEBUG_PATH'. - -Closes: https://github.com/opencryptoki/openssl-ibmca/issues/107 - -Signed-off-by: Ingo Franzki - -Origin: upstream, https://github.com/opencryptoki/openssl-ibmca/2298d3964f1ce32d35bb7585e4fa224c5bf2c8d4 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2027809 -Last-Update: 2023-07-27 - ---- - configure.ac | 2 +- - src/provider/Makefile.am | 4 --- - src/provider/doc/ibmca-provider.man | 38 +++++++++++++++++++++++------ - src/provider/p_ibmca.c | 25 ++++++++++++++++++- - src/provider/p_ibmca.h | 3 +++ - test/provider/openssl-test.cnf | 1 + - 6 files changed, 59 insertions(+), 14 deletions(-) - -diff --git a/configure.ac b/configure.ac -index cea8ce8..57b3205 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -10,7 +10,7 @@ AM_INIT_AUTOMAKE([foreign]) - - AC_PATH_PROG([CHMOD], [chmod], [/bin/chmod]) - --logdir=$localstatedir/log/ibmca -+logdir=/tmp - AC_SUBST(logdir) - - # Cmdline arguments. -diff --git a/src/provider/Makefile.am b/src/provider/Makefile.am -index da45a52..f2d1d50 100644 ---- a/src/provider/Makefile.am -+++ b/src/provider/Makefile.am -@@ -25,7 +25,3 @@ ACLOCAL_AMFLAGS = -I m4 - SUBDIRS = doc - - noinst_SCRIPTS = ibmca-provider-opensslconfig -- --install-data-hook: -- $(MKDIR_P) $(DESTDIR)$(logdir) -- $(CHMOD) 0777 $(DESTDIR)$(logdir) -diff --git a/src/provider/doc/ibmca-provider.man b/src/provider/doc/ibmca-provider.man -index 52350e4..846d607 100644 ---- a/src/provider/doc/ibmca-provider.man -+++ b/src/provider/doc/ibmca-provider.man -@@ -94,13 +94,25 @@ provider if you are on an IBM z15 or later. This would actually make it slower. - .IP "debug = yes | no | stderr" - .RS - Enables debug output for the IBMCA provider. If this option is not specified, --no debuging output is produced. If \fBdebug = stderr\fP is specified, -+no debugging output is produced. If \fBdebug = stderr\fP is specified, - debugging messages are printed to stderr. Otherwise the debug output is written --into a trace file in \fB[/usr/local]/var/log/ibmca/trace-.\fP, --where is the name of the IBMCA provider from the identity --option, and is the process ID of the current process. You can also --enable debugging by setting the environment variable \fBIBMCA_DEBUG\fP to --\fBon\fP or \fBstderr\fP. -+into a trace file in \fB/trace-.\fP, -+where is the path name of a directory to where the debug files are -+written (default: \fB/tmp\fP), is the name of the IBMCA provider -+from the identity option, and is the process ID of the current process. -+You can also enable debugging by setting the environment variable -+\fBIBMCA_DEBUG\fP to \fBon\fP or \fBstderr\fP. -+.RE -+.PP -+.IP "debug-path = /dir/to/debug/directory" -+.RS -+Sets the directory path to where debug files are written when debug is enabled -+via \fBdebug = yes\fP or via environment variable \fBIBMCA_DEBUG=on\fP. -+You can also set the debug path by setting the environment variable -+\fBIBMCA_DEBUG_PATH\fP to the directory path. It must be ensured that the user -+under which the application that uses the IBMCA provider runs has write access -+to that directory. If this option is not specified, the default debug path is -+\fB/tmp\fP. - .RE - .PP - .IP "fips = yes | no" -@@ -153,8 +165,18 @@ If - .B $IBMCA_DEBUG - is set to \fBstderr\fP debug output to stderr for the IBMCA provider is enabled. - If it is set to \fBon\fP the debug output is written into a trace file in --\fB[/usr/local]/var/log/ibmca/trace-.\fP, where is --the process ID of the current process. -+\fB/trace-.\fP, where is the path -+name of a directory to where the debug files are written (default: \fB/tmp\fP), -+ is the name of the IBMCA provider from the identity option, -+and is the process ID of the current process. -+.PP -+.TP -+.BR IBMCA_DEBUG_PATH -+Sets the directory path to where debug files are written when debug is enabled -+via \fBdebug = yes\fP configuration option or via environment variable -+\fBIBMCA_DEBUG=on\fP. It must be ensured that the user under which the -+application that uses the IBMCA provider runs has write access to that -+directory. - .PP - .SH SEE ALSO - .B provider(1) -diff --git a/src/provider/p_ibmca.c b/src/provider/p_ibmca.c -index 80f0368..ffb9b5d 100644 ---- a/src/provider/p_ibmca.c -+++ b/src/provider/p_ibmca.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -58,6 +59,8 @@ struct ibmca_config_item { - - static int ibmca_config_debug(struct ibmca_prov_ctx *provctx, - const char *key, const char *value); -+static int ibmca_config_debug_path(struct ibmca_prov_ctx *provctx, -+ const char *key, const char *value); - static int ibmca_config_fips(struct ibmca_prov_ctx *provctx, - const char *key, const char *value); - static int ibmca_config_algorithms(struct ibmca_prov_ctx *provctx, -@@ -70,6 +73,7 @@ static int ibmca_config_openssl_version(struct ibmca_prov_ctx *provctx, - const char *key, const char *value); - - static const struct ibmca_config_item config_items[] = { -+ { IBMCA_CONF_DEBUG_PATH, ibmca_config_debug_path }, - { IBMCA_CONF_DEBUG, ibmca_config_debug }, - { IBMCA_CONF_FIPS, ibmca_config_fips }, - { IBMCA_CONF_ALGORITHMS, ibmca_config_algorithms }, -@@ -881,7 +885,9 @@ static int ibmca_config_debug(struct ibmca_prov_ctx *provctx, - *p = '_'; - - if (snprintf(debug_file, sizeof(debug_file), "%s/trace-%s.%d", -- IBMCA_LOGDIR, prov_name, provctx->debug_pid) -+ provctx->debug_path != NULL ? provctx->debug_path : -+ IBMCA_LOGDIR, -+ prov_name, provctx->debug_pid) - >= (int)sizeof(debug_file)) { - put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR, - "IBMCA_LOGDIR too long: '%s'", IBMCA_LOGDIR); -@@ -904,6 +910,20 @@ static int ibmca_config_debug(struct ibmca_prov_ctx *provctx, - return 1; - } - -+static int ibmca_config_debug_path(struct ibmca_prov_ctx *provctx, -+ const char *key, const char *value) -+{ -+ /* -+ * If the debug path is already set (e.g. due to IBMCA_DEBUG_PATH -+ * environment variable) do not override the setting. -+ */ -+ if (provctx->debug_path != NULL) -+ return 1; -+ -+ return ibmca_config_const_string(provctx, key, value, -+ &provctx->debug_path); -+} -+ - static int ibmca_config_fips(struct ibmca_prov_ctx *provctx, - const char *key, const char *value) - { -@@ -1302,6 +1322,9 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, - ctx->c_free = c_free; - ctx->ica_adapter = DRIVER_NOT_LOADED; - -+ val = secure_getenv(IBMCA_DEBUG_PATH_ENVVAR); -+ if (val != NULL) -+ ibmca_config_debug_path(ctx, IBMCA_CONF_DEBUG_PATH, val); - val = getenv(IBMCA_DEBUG_ENVVAR); - if (val != NULL) - ibmca_config_debug(ctx, IBMCA_CONF_DEBUG, val); -diff --git a/src/provider/p_ibmca.h b/src/provider/p_ibmca.h -index 3b3d4f0..c47a6aa 100644 ---- a/src/provider/p_ibmca.h -+++ b/src/provider/p_ibmca.h -@@ -27,9 +27,11 @@ - - /* Environment variable name to enable debug */ - #define IBMCA_DEBUG_ENVVAR "IBMCA_DEBUG" -+#define IBMCA_DEBUG_PATH_ENVVAR "IBMCA_DEBUG_PATH" - - /* IBMCA provider configuration key words */ - #define IBMCA_CONF_DEBUG "debug" -+#define IBMCA_CONF_DEBUG_PATH "debug-path" - #define IBMCA_CONF_ALGORITHMS "algorithms" - #define IBMCA_CONF_FIPS "fips" - #define IBMCA_CONF_FALLBACK_PROPS "fallback-properties" -@@ -64,6 +66,7 @@ struct ibmca_prov_ctx { - OSSL_FUNC_CRYPTO_secure_clear_free_fn *c_secure_clear_free; - OSSL_FUNC_OPENSSL_cleanse_fn *c_cleanse; - bool debug; -+ const char *debug_path; - FILE *debug_file; - pid_t debug_pid; - pthread_mutex_t debug_mutex; -diff --git a/test/provider/openssl-test.cnf b/test/provider/openssl-test.cnf -index 7866f4e..e8132a6 100644 ---- a/test/provider/openssl-test.cnf -+++ b/test/provider/openssl-test.cnf -@@ -16,6 +16,7 @@ identity = ibmca - module = ibmca-provider.so - activate = 1 - #debug = yes -+#debug-path = /dir/to/debug/directory - #fips=yes - #algorithms = RSA,EC,DH - algorithms = ALL --- -2.25.1 - diff -Nru openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-rsa-Check-RSA-keys-with-p-q-at-key-generati.patch openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-rsa-Check-RSA-keys-with-p-q-at-key-generati.patch --- openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-rsa-Check-RSA-keys-with-p-q-at-key-generati.patch 2023-07-27 16:38:33.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-rsa-Check-RSA-keys-with-p-q-at-key-generati.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,65 +0,0 @@ -From f8a60b6678b1eb3ccadcb31f36bf7961ed8d5a9a Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Tue, 25 Apr 2023 16:23:52 +0200 -Subject: [PATCH] provider: rsa: Check RSA keys with p < q at key generation - and import - -Since OpenSSL 3.0 the OpenSSL RSA key generation taking place within libica -may generate RSA keys where p < q (privileged form). While such a key is -automatically corrected with the first call to libica's ica_rsa_crt(), such -correction modifies the libica RSA key object and may cause concurrency -problems when the same key object is used by multiple threads. - -Check and correct such keys right after key generation or during import, -so that it is ensured that p > q whenever the key is used afterwards, and -thus no correction is applied by ica_rsa_crt() later on. - -Signed-off-by: Ingo Franzki - -Origin: upstream, https://github.com/opencryptoki/openssl-ibmca/f8a60b6678b1eb3ccadcb31f36bf7961ed8d5a9a -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2027809 -Last-Update: 2023-07-27 - ---- - src/provider/rsa_keymgmt.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/src/provider/rsa_keymgmt.c b/src/provider/rsa_keymgmt.c -index aabf9d2..f83d90a 100644 ---- a/src/provider/rsa_keymgmt.c -+++ b/src/provider/rsa_keymgmt.c -@@ -1203,6 +1203,15 @@ static void *ibmca_keymgmt_rsa_gen(void *vgenctx, OSSL_CALLBACK *osslcb, - } - } - -+ /* If p < q, swap and recalculate now */ -+ rc = ica_rsa_crt_key_check(&key->rsa.private); -+ if (rc > 1) { -+ put_error_op_ctx(genctx, IBMCA_ERR_INTERNAL_ERROR, -+ "ica_rsa_crt_key_check failed"); -+ ibmca_keymgmt_free(key); -+ return NULL; -+ } -+ - p = 3; - n = 0; - if (osslcb != NULL && osslcb(cb_params, cbarg) == 0) { -@@ -1823,6 +1832,15 @@ int ibmca_keymgmt_rsa_import(void *vkey, int selection, - "BN_bn2binpad failed for private qinv"); - goto out; - } -+ -+ /* If p < q, swap and recalculate now */ -+ rc = ica_rsa_crt_key_check(&key->rsa.private); -+ if (rc > 1) { -+ rc = 0; -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "ica_rsa_crt_key_check failed"); -+ goto out; -+ } - } - - if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0 && --- -2.25.1 - diff -Nru openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-RSA-Fix-get_params-to-retrieve-max-size-bit.patch openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-RSA-Fix-get_params-to-retrieve-max-size-bit.patch --- openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-RSA-Fix-get_params-to-retrieve-max-size-bit.patch 2023-07-27 16:38:33.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-RSA-Fix-get_params-to-retrieve-max-size-bit.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,44 +0,0 @@ -From 67efa9ad713e8283cb20111a15629f15a8ea8c86 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Tue, 25 Jul 2023 14:52:49 +0200 -Subject: [PATCH] provider: RSA: Fix get_params to retrieve max-size, bits, and - security-bits - -The RSA key management's get_params() function should be able to return the -values for max-size, bits, and security-bits if at least the public key is -available. - -The detection whether the key is 'empty', i.e. has neither the public nor the -private key components was wrong. This leads to the fact that those parameters -were not returned when only the public key was available. - -Signed-off-by: Ingo Franzki - -Origin: upstream, https://github.com/opencryptoki/openssl-ibmca/67efa9ad713e8283cb20111a15629f15a8ea8c86 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2027809 -Last-Update: 2023-07-27 - ---- - src/provider/rsa_keymgmt.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/provider/rsa_keymgmt.c b/src/provider/rsa_keymgmt.c -index 526f2aa..ce49c88 100644 ---- a/src/provider/rsa_keymgmt.c -+++ b/src/provider/rsa_keymgmt.c -@@ -1512,9 +1512,9 @@ static int ibmca_keymgmt_rsa_get_params(void *vkey, OSSL_PARAM params[]) - for (parm = params; parm != NULL && parm->key != NULL; parm++) - ibmca_debug_key(key, "param: %s", parm->key); - -- empty = (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public) || -- (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) && -- !ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me))); -+ empty = (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public) && -+ !ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) && -+ !ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)); - - if (!empty) { - /* OSSL_PKEY_PARAM_BITS */ --- -2.25.1 - diff -Nru openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-Support-importing-of-RSA-keys-with-just-ME-.patch openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-Support-importing-of-RSA-keys-with-just-ME-.patch --- openssl-ibmca-2.4.0/debian/patches/lp-2027809-provider-Support-importing-of-RSA-keys-with-just-ME-.patch 2023-07-27 16:38:33.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/lp-2027809-provider-Support-importing-of-RSA-keys-with-just-ME-.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,1033 +0,0 @@ -From acba1d936bd84c7090ed7d3849b0bab3c7f18da0 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Fri, 7 Jul 2023 14:55:26 +0200 -Subject: [PATCH] provider: Support importing of RSA keys with just ME - components - -RSA private keys may contain just CRT (p, q, dp, dq, qinv) or ME (d) -components, or all of them. If an application imports a private RSA key -from just the ME components (m, e, and private d), then the IBMCA provider -can not use ica_rsa_crt() to perform private key operations. - -Therefore let an RSA key also contain the private key components in ME -format, and use ica_rsa_mod_expo() if only the ME components are available. -RSA keys are still always generated in CRT format, but it now allows to -import an RSA private key in ME format. - -Signed-off-by: Ingo Franzki - -Origin: upstream, https://github.com/opencryptoki/openssl-ibmca/acba1d936bd84c7090ed7d3849b0bab3c7f18da0 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2027809 -Last-Update: 2023-07-27 - ---- - src/provider/p_ibmca.h | 11 +- - src/provider/rsa_asym_cipher.c | 2 +- - src/provider/rsa_blinding.c | 31 +- - src/provider/rsa_keymgmt.c | 603 +++++++++++++++++++++------------ - src/provider/rsa_signature.c | 2 +- - 5 files changed, 427 insertions(+), 222 deletions(-) - -diff --git a/src/provider/p_ibmca.h b/src/provider/p_ibmca.h -index 58f150f..3b3d4f0 100644 ---- a/src/provider/p_ibmca.h -+++ b/src/provider/p_ibmca.h -@@ -124,7 +124,9 @@ struct ibmca_key { - union { - struct { - size_t bits; -- ica_rsa_key_crt_t private; -+ size_t keylength; -+ ica_rsa_key_crt_t private_crt; -+ ica_rsa_key_mod_expo_t private_me; - ica_rsa_key_mod_expo_t public; - struct ibmca_pss_params pss; /* For type EVP_PKEY_RSA_PSS only */ - BN_BLINDING *blinding; -@@ -176,6 +178,9 @@ struct ibmca_op_ctx *ibmca_keymgmt_gen_init( - int (*dup_cb) - (const struct ibmca_op_ctx *ctx, - struct ibmca_op_ctx *new_ctx)); -+bool ibmca_keymgmt_rsa_pub_valid(const ica_rsa_key_mod_expo_t *public); -+bool ibmca_keymgmt_rsa_priv_crt_valid(const ica_rsa_key_crt_t *private_crt); -+bool ibmca_keymgmt_rsa_priv_me_valid(const ica_rsa_key_mod_expo_t *private_me); - - OSSL_FUNC_keymgmt_free_fn ibmca_keymgmt_free; - OSSL_FUNC_keymgmt_dup_fn ibmca_keymgmt_dup; -@@ -519,8 +524,8 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key, - - int ibmca_keymgmt_rsa_pub_as_bn(struct ibmca_key *key, BIGNUM **n, BIGNUM **e); - --int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, -- unsigned char *out, size_t rsa_size); -+int ibmca_rsa_priv_with_blinding(struct ibmca_key *key, const unsigned char *in, -+ unsigned char *out, size_t rsa_size); - - int ossl_bn_rsa_do_unblind(const unsigned char *intermediate, - const BIGNUM *unblind, -diff --git a/src/provider/rsa_asym_cipher.c b/src/provider/rsa_asym_cipher.c -index 43049ee..624bd60 100644 ---- a/src/provider/rsa_asym_cipher.c -+++ b/src/provider/rsa_asym_cipher.c -@@ -844,7 +844,7 @@ static int ibmca_asym_cipher_rsa_decrypt(void *vctx, - } - - /* Perform private key decrypt */ -- rc = ibmca_rsa_crt_with_blinding(ctx->key, in, dec_data, rsa_size); -+ rc = ibmca_rsa_priv_with_blinding(ctx->key, in, dec_data, rsa_size); - if (rc != 1) { - ibmca_debug_op_ctx(ctx, "ibmca_asym_cipher_rsa_with_blinding failed"); - -diff --git a/src/provider/rsa_blinding.c b/src/provider/rsa_blinding.c -index fc13326..4100065 100644 ---- a/src/provider/rsa_blinding.c -+++ b/src/provider/rsa_blinding.c -@@ -392,8 +392,8 @@ out: - return rc; - } - --int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, -- unsigned char *out, size_t rsa_size) -+int ibmca_rsa_priv_with_blinding(struct ibmca_key *key, const unsigned char *in, -+ unsigned char *out, size_t rsa_size) - { - BN_BLINDING *blinding; - bool local_blinding = false; -@@ -404,7 +404,7 @@ int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, - - ibmca_debug_key(key, "key: %p rsa_size: %lu", key, rsa_size); - -- if (rsa_size != key->rsa.private.key_length) { -+ if (rsa_size != key->rsa.keylength) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "rsa_size is not modulus size"); - goto out; -@@ -445,11 +445,26 @@ int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, - goto out; - } - -- rc = ica_rsa_crt(key->provctx->ica_adapter, buf, -- &key->rsa.private, buf + rsa_size); -- if (rc != 0) { -- ibmca_debug_key(key, "ERROR: ica_rsa_crt failed with: %s", -- strerror(rc)); -+ if (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { -+ rc = ica_rsa_crt(key->provctx->ica_adapter, buf, -+ &key->rsa.private_crt, buf + rsa_size); -+ if (rc != 0) { -+ ibmca_debug_key(key, "ERROR: ica_rsa_crt failed with: %s", -+ strerror(rc)); -+ rc = 0; -+ goto out; -+ } -+ } else if (ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { -+ rc = ica_rsa_mod_expo(key->provctx->ica_adapter, buf, -+ &key->rsa.private_me, buf + rsa_size); -+ if (rc != 0) { -+ ibmca_debug_key(key, "ERROR: ica_rsa_mod_expo failed with: %s", -+ strerror(rc)); -+ rc = 0; -+ goto out; -+ } -+ } else { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "No private key"); - rc = 0; - goto out; - } -diff --git a/src/provider/rsa_keymgmt.c b/src/provider/rsa_keymgmt.c -index f83d90a..526f2aa 100644 ---- a/src/provider/rsa_keymgmt.c -+++ b/src/provider/rsa_keymgmt.c -@@ -241,25 +241,14 @@ static int ibmca_keymgmt_rsa_pub_key_to_data( - return 1; - } - --static int ibmca_keymgmt_rsa_priv_key_from_data( -+static int ibmca_keymgmt_rsa_priv_crt_key_from_data( - const struct ibmca_prov_ctx *provctx, -- const OSSL_PARAM params[], -- BIGNUM **d, BIGNUM **p, -+ const OSSL_PARAM params[], BIGNUM **p, - BIGNUM **q, BIGNUM **dp, - BIGNUM **dq, BIGNUM **qinv) - { - int rc; - -- /* OSSL_PKEY_PARAM_RSA_D */ -- *d = BN_secure_new(); -- if (*d == NULL) { -- put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); -- goto error; -- } -- rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_D, d); -- if (rc <= 0) -- goto error; -- - /* OSSL_PKEY_PARAM_RSA_FACTOR1 */ - *p = BN_secure_new(); - if (*p == NULL) { -@@ -316,8 +305,6 @@ static int ibmca_keymgmt_rsa_priv_key_from_data( - return 1; - - error: -- BN_clear_free(*d); -- *d = NULL; - BN_clear_free(*p); - *p = NULL; - BN_clear_free(*dp); -@@ -330,6 +317,31 @@ error: - return 0; - } - -+static int ibmca_keymgmt_rsa_priv_me_key_from_data( -+ const struct ibmca_prov_ctx *provctx, -+ const OSSL_PARAM params[], BIGNUM **d) -+{ -+ int rc; -+ -+ /* OSSL_PKEY_PARAM_RSA_D */ -+ *d = BN_secure_new(); -+ if (*d == NULL) { -+ put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); -+ goto error; -+ } -+ rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_D, d); -+ if (rc <= 0) -+ goto error; -+ -+ return 1; -+ -+error: -+ BN_clear_free(*d); -+ *d = NULL; -+ -+ return 0; -+} -+ - static int ibmca_keymgmt_rsa_priv_key_to_data( - const struct ibmca_prov_ctx *provctx, - OSSL_PARAM_BLD *bld, -@@ -451,13 +463,14 @@ static void *ibmca_keymgmt_rsa_pss_new(void *vprovctx) - - static int ibmca_keymgmt_rsa_alloc_pub(struct ibmca_key *key) - { -- key->rsa.public.key_length = (key->rsa.bits + 7) / 8; -+ key->rsa.public.key_length = key->rsa.keylength; - - key->rsa.public.modulus = P_ZALLOC(key->provctx, - key->rsa.public.key_length); - key->rsa.public.exponent = P_ZALLOC(key->provctx, - key->rsa.public.key_length); -- if (key->rsa.public.modulus == NULL || key->rsa.public.exponent == NULL) { -+ -+ if (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) { - put_error_key(key, IBMCA_ERR_MALLOC_FAILED, - "Failed to allocate libica public RSA key"); - return 0; -@@ -466,24 +479,42 @@ static int ibmca_keymgmt_rsa_alloc_pub(struct ibmca_key *key) - return 1; - } - --static int ibmca_keymgmt_rsa_alloc_priv(struct ibmca_key *key) -+static int ibmca_keymgmt_rsa_alloc_priv_crt(struct ibmca_key *key) - { -- key->rsa.private.key_length = (key->rsa.bits + 7) / 8; -- key->rsa.private.p = P_SECURE_ZALLOC(key->provctx, -- ICA_P_LEN(key->rsa.private.key_length)); -- key->rsa.private.q = P_SECURE_ZALLOC(key->provctx, -- ICA_Q_LEN(key->rsa.private.key_length)); -- key->rsa.private.dp = P_SECURE_ZALLOC(key->provctx, -- ICA_DP_LEN(key->rsa.private.key_length)); -- key->rsa.private.dq = P_SECURE_ZALLOC(key->provctx, -- ICA_DQ_LEN(key->rsa.private.key_length)); -- key->rsa.private.qInverse = P_SECURE_ZALLOC(key->provctx, -- ICA_QINV_LEN(key->rsa.private.key_length)); -- if (key->rsa.private.p == NULL || key->rsa.private.q == NULL || -- key->rsa.private.dp == NULL || key->rsa.private.dq == NULL || -- key->rsa.private.qInverse == NULL ) { -+ key->rsa.private_crt.key_length = key->rsa.keylength; -+ -+ key->rsa.private_crt.p = P_SECURE_ZALLOC(key->provctx, -+ ICA_P_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.q = P_SECURE_ZALLOC(key->provctx, -+ ICA_Q_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.dp = P_SECURE_ZALLOC(key->provctx, -+ ICA_DP_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.dq = P_SECURE_ZALLOC(key->provctx, -+ ICA_DQ_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.qInverse = P_SECURE_ZALLOC(key->provctx, -+ ICA_QINV_LEN(key->rsa.private_crt.key_length)); -+ -+ if (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { - put_error_key(key, IBMCA_ERR_MALLOC_FAILED, -- "Failed to allocate libica private RSA key"); -+ "Failed to allocate libica private RSA CRT key"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int ibmca_keymgmt_rsa_alloc_priv_me(struct ibmca_key *key) -+{ -+ key->rsa.private_me.key_length = key->rsa.keylength; -+ -+ key->rsa.private_me.modulus = P_ZALLOC(key->provctx, -+ key->rsa.private_me.key_length); -+ key->rsa.private_me.exponent = P_ZALLOC(key->provctx, -+ key->rsa.private_me.key_length); -+ -+ if (!ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { -+ put_error_key(key, IBMCA_ERR_MALLOC_FAILED, -+ "Failed to allocate libica private RSA ME key"); - return 0; - } - -@@ -503,29 +534,42 @@ static void ibmca_keymgmt_rsa_free_pub(struct ibmca_key *key) - key->rsa.public.key_length = 0; - } - --static void ibmca_keymgmt_rsa_free_priv(struct ibmca_key *key) -+static void ibmca_keymgmt_rsa_free_priv_crt(struct ibmca_key *key) -+{ -+ if (key->rsa.private_crt.p != NULL) -+ P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.p, -+ ICA_P_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.p = NULL; -+ if (key->rsa.private_crt.q != NULL) -+ P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.q, -+ ICA_Q_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.q = NULL; -+ if (key->rsa.private_crt.dp != NULL) -+ P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.dp, -+ ICA_DP_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.dp = NULL; -+ if (key->rsa.private_crt.dq != NULL) -+ P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.dq, -+ ICA_DQ_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.dq = NULL; -+ if (key->rsa.private_crt.qInverse != NULL) -+ P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.qInverse, -+ ICA_QINV_LEN(key->rsa.private_crt.key_length)); -+ key->rsa.private_crt.qInverse = NULL; -+ key->rsa.private_crt.key_length = 0; -+} -+ -+static void ibmca_keymgmt_rsa_free_priv_me(struct ibmca_key *key) - { -- if (key->rsa.private.p != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.p, -- ICA_P_LEN(key->rsa.private.key_length)); -- key->rsa.private.p = NULL; -- if (key->rsa.private.q != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.q, -- ICA_Q_LEN(key->rsa.private.key_length)); -- key->rsa.private.q = NULL; -- if (key->rsa.private.dp != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.dp, -- ICA_DP_LEN(key->rsa.private.key_length)); -- key->rsa.private.dp = NULL; -- if (key->rsa.private.dq != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.dq, -- ICA_DQ_LEN(key->rsa.private.key_length)); -- key->rsa.private.dq = NULL; -- if (key->rsa.private.qInverse != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.qInverse, -- ICA_QINV_LEN(key->rsa.private.key_length)); -- key->rsa.private.qInverse = NULL; -- key->rsa.private.key_length = 0; -+ if (key->rsa.private_me.modulus != NULL) -+ P_CLEAR_FREE(key->provctx, key->rsa.private_me.modulus, -+ key->rsa.private_me.key_length); -+ key->rsa.private_me.modulus = NULL; -+ if (key->rsa.private_me.exponent != NULL) -+ P_CLEAR_FREE(key->provctx, key->rsa.private_me.exponent, -+ key->rsa.private_me.key_length); -+ key->rsa.private_me.exponent = NULL; -+ key->rsa.private_me.key_length = 0; - } - - static void ibmca_keymgmt_rsa_clean(struct ibmca_key *key) -@@ -535,7 +579,8 @@ static void ibmca_keymgmt_rsa_clean(struct ibmca_key *key) - - ibmca_debug_key(key, "key: %p", key); - -- ibmca_keymgmt_rsa_free_priv(key); -+ ibmca_keymgmt_rsa_free_priv_crt(key); -+ ibmca_keymgmt_rsa_free_priv_me(key); - ibmca_keymgmt_rsa_free_pub(key); - - if (key->type == EVP_PKEY_RSA_PSS) -@@ -572,6 +617,30 @@ static void ibmca_keymgmt_rsa_free_cb(struct ibmca_key *key) - pthread_rwlock_destroy(&key->rsa.blinding_lock); - } - -+bool ibmca_keymgmt_rsa_pub_valid(const ica_rsa_key_mod_expo_t *public) -+{ -+ return public->key_length != 0 && -+ public->modulus != NULL && -+ public->exponent != NULL; -+} -+ -+bool ibmca_keymgmt_rsa_priv_crt_valid(const ica_rsa_key_crt_t *private_crt) -+{ -+ return private_crt->key_length != 0 && -+ private_crt->p != NULL && -+ private_crt->q != NULL && -+ private_crt->dp != NULL && -+ private_crt->dq != NULL && -+ private_crt->qInverse != NULL; -+} -+ -+bool ibmca_keymgmt_rsa_priv_me_valid(const ica_rsa_key_mod_expo_t *private_me) -+{ -+ return private_me->key_length != 0 && -+ private_me->modulus != NULL && -+ private_me->exponent != NULL; -+} -+ - static int ibmca_keymgmt_rsa_dup_pub(const struct ibmca_key *key, - struct ibmca_key *new_key) - { -@@ -583,8 +652,8 @@ static int ibmca_keymgmt_rsa_dup_pub(const struct ibmca_key *key, - new_key->rsa.public.exponent = P_MEMDUP(key->provctx, - key->rsa.public.exponent, - key->rsa.public.key_length); -- if (new_key->rsa.public.modulus == NULL || -- new_key->rsa.public.exponent == NULL) { -+ -+ if (!ibmca_keymgmt_rsa_pub_valid(&new_key->rsa.public)) { - put_error_key(key, IBMCA_ERR_MALLOC_FAILED, - "Failed to allocate libica RSA key"); - return 0; -@@ -593,29 +662,46 @@ static int ibmca_keymgmt_rsa_dup_pub(const struct ibmca_key *key, - return 1; - } - --static int ibmca_keymgmt_rsa_dup_priv(const struct ibmca_key *key, -- struct ibmca_key *new_key) -+static int ibmca_keymgmt_rsa_dup_priv_crt(const struct ibmca_key *key, -+ struct ibmca_key *new_key) - { -- new_key->rsa.private.key_length = key->rsa.private.key_length; -- -- new_key->rsa.private.p = P_SECURE_MEMDUP(key->provctx, key->rsa.private.p, -- ICA_P_LEN(key->rsa.private.key_length)); -- new_key->rsa.private.q = P_SECURE_MEMDUP(key->provctx, key->rsa.private.q, -- ICA_Q_LEN(key->rsa.private.key_length)); -- new_key->rsa.private.dp = P_SECURE_MEMDUP(key->provctx, key->rsa.private.dp, -- ICA_DP_LEN(key->rsa.private.key_length)); -- new_key->rsa.private.dq = P_SECURE_MEMDUP(key->provctx, key->rsa.private.dq, -- ICA_DQ_LEN(key->rsa.private.key_length)); -- new_key->rsa.private.qInverse = P_SECURE_MEMDUP(key->provctx, -- key->rsa.private.qInverse, -+ new_key->rsa.private_crt.key_length = key->rsa.private_crt.key_length; -+ -+ new_key->rsa.private_crt.p = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.p, -+ ICA_P_LEN(key->rsa.private_crt.key_length)); -+ new_key->rsa.private_crt.q = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.q, -+ ICA_Q_LEN(key->rsa.private_crt.key_length)); -+ new_key->rsa.private_crt.dp = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.dp, -+ ICA_DP_LEN(key->rsa.private_crt.key_length)); -+ new_key->rsa.private_crt.dq = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.dq, -+ ICA_DQ_LEN(key->rsa.private_crt.key_length)); -+ new_key->rsa.private_crt.qInverse = P_SECURE_MEMDUP(key->provctx, -+ key->rsa.private_crt.qInverse, - ICA_QINV_LEN( -- key->rsa.private.key_length)); -+ key->rsa.private_crt.key_length)); - -- if (new_key->rsa.private.p == NULL || -- new_key->rsa.private.q == NULL || -- new_key->rsa.private.dp == NULL || -- new_key->rsa.private.dq == NULL || -- new_key->rsa.private.qInverse == NULL) { -+ if (!ibmca_keymgmt_rsa_priv_crt_valid(&new_key->rsa.private_crt)) { -+ put_error_key(key, IBMCA_ERR_MALLOC_FAILED, -+ "Failed to allocate libica RSA key"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int ibmca_keymgmt_rsa_dup_priv_me(const struct ibmca_key *key, -+ struct ibmca_key *new_key) -+{ -+ new_key->rsa.private_me.key_length = key->rsa.private_me.key_length; -+ -+ new_key->rsa.private_me.modulus = P_MEMDUP(key->provctx, -+ key->rsa.private_me.modulus, -+ key->rsa.private_me.key_length); -+ new_key->rsa.private_me.exponent = P_MEMDUP(key->provctx, -+ key->rsa.private_me.exponent, -+ key->rsa.private_me.key_length); -+ -+ if (!ibmca_keymgmt_rsa_priv_me_valid(&new_key->rsa.private_me)) { - put_error_key(key, IBMCA_ERR_MALLOC_FAILED, - "Failed to allocate libica RSA key"); - return 0; -@@ -639,14 +725,20 @@ static int ibmca_keymgmt_rsa_dup_cb(const struct ibmca_key *key, - } - - new_key->rsa.bits = key->rsa.bits; -+ new_key->rsa.keylength = key->rsa.keylength; - -- if (key->rsa.public.key_length != 0) { -+ if (ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) { - if (ibmca_keymgmt_rsa_dup_pub(key, new_key) == 0) - return 0; - } - -- if (key->rsa.private.key_length != 0) { -- if (ibmca_keymgmt_rsa_dup_priv(key, new_key) == 0) -+ if (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { -+ if (ibmca_keymgmt_rsa_dup_priv_crt(key, new_key) == 0) -+ return 0; -+ } -+ -+ if (ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { -+ if (ibmca_keymgmt_rsa_dup_priv_me(key, new_key) == 0) - return 0; - } - -@@ -667,21 +759,56 @@ static int ibmca_keymgmt_rsa_has(const void *vkey, int selection) - ibmca_debug_key(key, "key: %p selection: 0x%x", key, selection); - - if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) -- ok = ok && (key->rsa.public.key_length != 0 && -- key->rsa.public.modulus != NULL && -- key->rsa.public.exponent != NULL); -+ ok = ok && ibmca_keymgmt_rsa_pub_valid(&key->rsa.public); - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) -- ok = ok && (key->rsa.private.key_length != 0 && -- key->rsa.private.p != NULL && -- key->rsa.private.q != NULL && -- key->rsa.private.dp != NULL && -- key->rsa.private.dq != NULL && -- key->rsa.private.qInverse != NULL); -+ ok = ok && (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) || -+ ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)); - - ibmca_debug_key(key, "ok: %d", ok); - return ok; - } - -+static bool ibmca_keymgmt_rsa_pub_equal(const ica_rsa_key_mod_expo_t *public1, -+ const ica_rsa_key_mod_expo_t *public2) -+{ -+ return public1->key_length > 0 && -+ public1->key_length == public2-> key_length && -+ memcmp(public1->exponent, public2->exponent, -+ public1->key_length) == 0 && -+ memcmp(public1->modulus, public2->modulus, -+ public1->key_length) == 0; -+} -+ -+static bool ibmca_keymgmt_rsa_priv_crt_equal( -+ const ica_rsa_key_crt_t *private_crt1, -+ const ica_rsa_key_crt_t *private_crt2) -+{ -+ return private_crt1->key_length > 0 && -+ private_crt1->key_length == private_crt2->key_length && -+ CRYPTO_memcmp(private_crt1->p, private_crt2->p, -+ ICA_P_LEN(private_crt1->key_length)) == 0 && -+ CRYPTO_memcmp(private_crt1->q, private_crt2->q, -+ ICA_Q_LEN(private_crt1->key_length)) == 0 && -+ CRYPTO_memcmp(private_crt1->dp, private_crt2->dp, -+ ICA_DP_LEN(private_crt1->key_length)) == 0 && -+ CRYPTO_memcmp(private_crt1->dq, private_crt2->dq, -+ ICA_DQ_LEN(private_crt1->key_length)) == 0 && -+ CRYPTO_memcmp(private_crt1->qInverse, private_crt2->qInverse, -+ ICA_QINV_LEN(private_crt1->key_length)) == 0; -+} -+ -+static bool ibmca_keymgmt_rsa_priv_me_equal( -+ const ica_rsa_key_mod_expo_t *private_me1, -+ const ica_rsa_key_mod_expo_t *private_me2) -+{ -+ return private_me1->key_length > 0 && -+ private_me1->key_length == private_me2-> key_length && -+ CRYPTO_memcmp(private_me1->exponent, private_me2->exponent, -+ private_me2->key_length) == 0 && -+ CRYPTO_memcmp(private_me1->modulus, private_me2->modulus, -+ private_me1->key_length) == 0; -+} -+ - static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, - int selection) - { -@@ -699,35 +826,16 @@ static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, - return 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, -- key2->rsa.public.exponent, -- key1->rsa.public.key_length) == 0 && -- memcmp(key1->rsa.public.modulus, -- key2->rsa.public.modulus, -- key1->rsa.public.key_length) == 0); -+ ok = ok && ibmca_keymgmt_rsa_pub_equal(&key1->rsa.public, -+ &key2->rsa.public); - checked = 1; - } - - 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, -- key2->rsa.private.p, -- ICA_P_LEN(key1->rsa.private.key_length)) == 0 && -- CRYPTO_memcmp(key1->rsa.private.q, -- key2->rsa.private.q, -- ICA_Q_LEN(key1->rsa.private.key_length)) == 0 && -- CRYPTO_memcmp(key1->rsa.private.dp, -- key2->rsa.private.dp, -- ICA_DP_LEN(key1->rsa.private.key_length)) == 0 && -- CRYPTO_memcmp(key1->rsa.private.dq, -- key2->rsa.private.dq, -- ICA_DQ_LEN(key1->rsa.private.key_length)) == 0 && -- CRYPTO_memcmp(key1->rsa.private.qInverse, -- key2->rsa.private.qInverse, -- ICA_QINV_LEN(key1->rsa.private.key_length)) == 0); -+ ok = ok && (ibmca_keymgmt_rsa_priv_crt_equal(&key1->rsa.private_crt, -+ &key2->rsa.private_crt) || -+ ibmca_keymgmt_rsa_priv_me_equal(&key1->rsa.private_me, -+ &key2->rsa.private_me)); - - ibmca_debug_key(key1, "ok: %d", ok); - return ok; -@@ -922,7 +1030,7 @@ static int ibmca_keymgmt_rsa_gen_set_template(void *vgenctx, void *vtempl) - ibmca_keymgmt_rsa_gen_free_cb(genctx); - - genctx->rsa.gen.bits = templ->rsa.bits; -- if (templ->rsa.public.exponent != NULL) { -+ if (ibmca_keymgmt_rsa_pub_valid(&templ->rsa.public)) { - genctx->rsa.gen.pub_exp = BN_bin2bn(templ->rsa.public.exponent, - templ->rsa.public.key_length, - NULL); -@@ -1153,6 +1261,7 @@ static void *ibmca_keymgmt_rsa_gen(void *vgenctx, OSSL_CALLBACK *osslcb, - } - - key->rsa.bits = genctx->rsa.gen.bits; -+ key->rsa.keylength = (key->rsa.bits + 7) / 8; - ibmca_debug_op_ctx(genctx, "bits: %lu", key->rsa.bits); - - if (ibmca_keymgmt_rsa_alloc_pub(key) == 0) { -@@ -1160,7 +1269,7 @@ static void *ibmca_keymgmt_rsa_gen(void *vgenctx, OSSL_CALLBACK *osslcb, - return NULL; - } - -- if (ibmca_keymgmt_rsa_alloc_priv(key) == 0) { -+ if (ibmca_keymgmt_rsa_alloc_priv_crt(key) == 0) { - ibmca_keymgmt_free(key); - return NULL; - } -@@ -1189,7 +1298,7 @@ static void *ibmca_keymgmt_rsa_gen(void *vgenctx, OSSL_CALLBACK *osslcb, - } - - rc = ica_rsa_key_generate_crt(genctx->provctx->ica_adapter, key->rsa.bits, -- &key->rsa.public, &key->rsa.private); -+ &key->rsa.public, &key->rsa.private_crt); - if (rc != 0) { - ibmca_debug_op_ctx(genctx, "ica_rsa_key_generate_crt failed with: %s", - strerror(rc)); -@@ -1204,7 +1313,7 @@ static void *ibmca_keymgmt_rsa_gen(void *vgenctx, OSSL_CALLBACK *osslcb, - } - - /* If p < q, swap and recalculate now */ -- rc = ica_rsa_crt_key_check(&key->rsa.private); -+ rc = ica_rsa_crt_key_check(&key->rsa.private_crt); - if (rc > 1) { - put_error_op_ctx(genctx, IBMCA_ERR_INTERNAL_ERROR, - "ica_rsa_crt_key_check failed"); -@@ -1256,7 +1365,7 @@ static int ibmca_keymgmt_rsa_security_bits(size_t bits) - - int ibmca_keymgmt_rsa_pub_as_bn(struct ibmca_key *key, BIGNUM **n, BIGNUM **e) - { -- if (key->rsa.public.modulus == NULL || key->rsa.public.exponent == NULL) -+ if (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) - return 0; - - *n = BN_bin2bn(key->rsa.public.modulus, key->rsa.public.key_length, NULL); -@@ -1277,14 +1386,11 @@ error: - return 0; - } - -- --static int ibmca_keymgmt_rsa_priv_as_bn(struct ibmca_key *key, BIGNUM **p, -- BIGNUM **q, BIGNUM **dp, BIGNUM **dq, -- BIGNUM **qinv) -+static int ibmca_keymgmt_rsa_priv_crt_as_bn(struct ibmca_key *key, BIGNUM **p, -+ BIGNUM **q, BIGNUM **dp, -+ BIGNUM **dq, BIGNUM **qinv) - { -- if (key->rsa.private.p == NULL || key->rsa.private.q == NULL || -- key->rsa.private.dp == NULL || key->rsa.private.dq == NULL || -- key->rsa.private.qInverse == NULL) -+ if (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) - return 0; - - *p = BN_secure_new(); -@@ -1298,17 +1404,17 @@ static int ibmca_keymgmt_rsa_priv_as_bn(struct ibmca_key *key, BIGNUM **p, - goto error; - } - -- *p = BN_bin2bn(key->rsa.private.p, -- ICA_P_LEN(key->rsa.private.key_length), *p); -- *q = BN_bin2bn(key->rsa.private.q, -- ICA_Q_LEN(key->rsa.private.key_length), *q); -- *dp = BN_bin2bn(key->rsa.private.dp, -- ICA_DP_LEN(key->rsa.private.key_length), -+ *p = BN_bin2bn(key->rsa.private_crt.p, -+ ICA_P_LEN(key->rsa.private_crt.key_length), *p); -+ *q = BN_bin2bn(key->rsa.private_crt.q, -+ ICA_Q_LEN(key->rsa.private_crt.key_length), *q); -+ *dp = BN_bin2bn(key->rsa.private_crt.dp, -+ ICA_DP_LEN(key->rsa.private_crt.key_length), - *dp); -- *dq = BN_bin2bn(key->rsa.private.dq, -- ICA_DQ_LEN(key->rsa.private.key_length), *dq); -- *qinv = BN_bin2bn(key->rsa.private.qInverse, -- ICA_QINV_LEN(key->rsa.private.key_length), *qinv); -+ *dq = BN_bin2bn(key->rsa.private_crt.dq, -+ ICA_DQ_LEN(key->rsa.private_crt.key_length), *dq); -+ *qinv = BN_bin2bn(key->rsa.private_crt.qInverse, -+ ICA_QINV_LEN(key->rsa.private_crt.key_length), *qinv); - if (*p == NULL || *q == NULL || *dp == NULL || - *dq == NULL || *qinv == NULL) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "BN_bin2bn failed"); -@@ -1332,6 +1438,33 @@ error: - return 0; - } - -+int ibmca_keymgmt_rsa_priv_me_as_bn(struct ibmca_key *key, BIGNUM **d) -+{ -+ if (!ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) -+ return 0; -+ -+ *d = BN_secure_new(); -+ if (*d == NULL) { -+ put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); -+ goto error; -+ } -+ -+ *d = BN_bin2bn(key->rsa.private_me.exponent, key->rsa.private_me.key_length, -+ *d); -+ if (*d == NULL) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "BN_bin2bn failed"); -+ goto error; -+ } -+ -+ return 1; -+ -+error: -+ BN_clear_free(*d); -+ *d = NULL; -+ -+ return 0; -+} -+ - static int ibmca_keymgmt_rsa_calc_priv_d(struct ibmca_key *key, BIGNUM *n, - BIGNUM *e, BIGNUM *p, BIGNUM *q, - BIGNUM **d) -@@ -1379,8 +1512,9 @@ static int ibmca_keymgmt_rsa_get_params(void *vkey, OSSL_PARAM params[]) - for (parm = params; parm != NULL && parm->key != NULL; parm++) - ibmca_debug_key(key, "param: %s", parm->key); - -- empty = (key->rsa.public.key_length == 0 || -- key->rsa.private.key_length == 0); -+ empty = (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public) || -+ (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) && -+ !ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me))); - - if (!empty) { - /* OSSL_PKEY_PARAM_BITS */ -@@ -1439,16 +1573,30 @@ static int ibmca_keymgmt_rsa_get_params(void *vkey, OSSL_PARAM params[]) - } - - /* Private key parts */ -- rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); -+ rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); - if (rc == 1) { -- rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -- if (rc == 0) -- goto out; -+ /* CRT format */ -+ rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); -+ if (rc == 0) { -+ rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -+ if (rc == 0) -+ goto out; -+ } - - rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, NULL, params, d, - p, q, dp, dq, qinv); - if (rc == 0) - goto out; -+ } else { -+ rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); -+ if (rc == 1) { -+ /* ME format */ -+ rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, NULL, params, -+ d, NULL, NULL, NULL, NULL, -+ NULL); -+ if (rc == 0) -+ goto out; -+ } - } - - /* Return RSA-PSS parameters only for restricted RSA-PSS keys */ -@@ -1684,16 +1832,30 @@ int ibmca_keymgmt_rsa_export(void *vkey, int selection, - - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { - /* Private key parts */ -- rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); -+ rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); - if (rc == 1) { -- rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -- if (rc == 0) -- goto error; -+ /* CRT format */ -+ rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); -+ if (rc == 0) { -+ rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -+ if (rc == 0) -+ goto error; -+ } - - rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, bld, NULL, d, - p, q, dp, dq, qinv); - if (rc == 0) - goto error; -+ } else { -+ rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); -+ if (rc == 1) { -+ /* ME format */ -+ rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, bld, NULL, -+ d, NULL, NULL, NULL, -+ NULL, NULL); -+ if (rc == 0) -+ goto error; -+ } - } - } - -@@ -1773,6 +1935,7 @@ int ibmca_keymgmt_rsa_import(void *vkey, int selection, - return 0; - - key->rsa.bits = BN_num_bits(n); -+ key->rsa.keylength = (key->rsa.bits + 7) / 8; - ibmca_debug_key(key, "key: %p bits: %u", key, key->rsa.bits); - - if (ibmca_keymgmt_rsa_alloc_pub(key) == 0) -@@ -1794,52 +1957,73 @@ int ibmca_keymgmt_rsa_import(void *vkey, int selection, - - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { - /* Import private key parts */ -- if (ibmca_keymgmt_rsa_alloc_priv(key) == 0) -- goto out; -- -- rc = ibmca_keymgmt_rsa_priv_key_from_data(key->provctx, params, &d, -- &p, &q, &dp, &dq, &qinv); -- if (rc == 0) -- goto out; -- -- if (BN_bn2binpad(p, key->rsa.private.p, -- ICA_P_LEN(key->rsa.private.key_length)) <= 0) { -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "BN_bn2binpad failed for private p"); -- goto out; -- } -- if (BN_bn2binpad(q, key->rsa.private.q, -- ICA_Q_LEN(key->rsa.private.key_length)) <= 0) { -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "BN_bn2binpad failed for private q"); -- goto out; -- } -- if (BN_bn2binpad(dp, key->rsa.private.dp, -- ICA_DP_LEN(key->rsa.private.key_length)) <= 0) { -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "BN_bn2binpad failed for private dp"); -- goto out; -- } -- if (BN_bn2binpad(dq, key->rsa.private.dq, -- ICA_DQ_LEN(key->rsa.private.key_length)) <= 0) { -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "BN_bn2binpad failed for private dq"); -- goto out; -- } -- if (BN_bn2binpad(qinv, key->rsa.private.qInverse, -- ICA_QINV_LEN(key->rsa.private.key_length)) <= 0) { -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "BN_bn2binpad failed for private qinv"); -- goto out; -+ rc = ibmca_keymgmt_rsa_priv_crt_key_from_data(key->provctx, params, -+ &p, &q, &dp, &dq, &qinv); -+ if (rc == 1) { -+ /* CRT components */ -+ if (ibmca_keymgmt_rsa_alloc_priv_crt(key) == 0) -+ goto out; -+ -+ if (BN_bn2binpad(p, key->rsa.private_crt.p, -+ ICA_P_LEN(key->rsa.private_crt.key_length)) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private p"); -+ goto out; -+ } -+ if (BN_bn2binpad(q, key->rsa.private_crt.q, -+ ICA_Q_LEN(key->rsa.private_crt.key_length)) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private q"); -+ goto out; -+ } -+ if (BN_bn2binpad(dp, key->rsa.private_crt.dp, -+ ICA_DP_LEN(key->rsa.private_crt.key_length)) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private dp"); -+ goto out; -+ } -+ if (BN_bn2binpad(dq, key->rsa.private_crt.dq, -+ ICA_DQ_LEN(key->rsa.private_crt.key_length)) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private dq"); -+ goto out; -+ } -+ if (BN_bn2binpad(qinv, key->rsa.private_crt.qInverse, -+ ICA_QINV_LEN(key->rsa.private_crt.key_length)) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private qinv"); -+ goto out; -+ } -+ -+ /* If p < q, swap and recalculate now */ -+ rc = ica_rsa_crt_key_check(&key->rsa.private_crt); -+ if (rc > 1) { -+ rc = 0; -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "ica_rsa_crt_key_check failed"); -+ goto out; -+ } - } - -- /* If p < q, swap and recalculate now */ -- rc = ica_rsa_crt_key_check(&key->rsa.private); -- if (rc > 1) { -- rc = 0; -- put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -- "ica_rsa_crt_key_check failed"); -- goto out; -+ rc = ibmca_keymgmt_rsa_priv_me_key_from_data(key->provctx, params, &d); -+ if (rc == 1) { -+ /* ME components */ -+ if (ibmca_keymgmt_rsa_alloc_priv_me(key) == 0) -+ goto out; -+ -+ if (BN_bn2binpad(n, key->rsa.private_me.modulus, -+ key->rsa.private_me.key_length) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for modulus"); -+ goto out; -+ } -+ -+ if (BN_bn2binpad(d, key->rsa.private_me.exponent, -+ key->rsa.private_me.key_length) <= 0) { -+ put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, -+ "BN_bn2binpad failed for private d"); -+ goto out; -+ } - } - } - -@@ -1902,19 +2086,22 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key, - return 0; - } - -- rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); -- if (rc == 0) -- goto out; -+ rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); -+ if (rc == 0) { -+ rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); -+ if (rc == 0) -+ goto out; - -- rc = ibmca_keymgmt_rsa_pub_as_bn(key, &n, &e); -- if (rc == 0) -- goto out; -+ rc = ibmca_keymgmt_rsa_pub_as_bn(key, &n, &e); -+ if (rc == 0) -+ goto out; - -- rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -- if (rc == 0) -- goto out; -+ rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); -+ if (rc == 0) -+ goto out; -+ } - -- buf = P_SECURE_ZALLOC(key->provctx, key->rsa.private.key_length); -+ buf = P_SECURE_ZALLOC(key->provctx, key->rsa.keylength); - if (buf == NULL) { - put_error_key(key, IBMCA_ERR_MALLOC_FAILED, - "Failed to allocate buffer for private key"); -@@ -1922,7 +2109,7 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key, - } - - BN_set_flags(d, BN_FLG_CONSTTIME); -- if (BN_bn2binpad(d, buf, key->rsa.private.key_length) < 0) { -+ if (BN_bn2binpad(d, buf, key->rsa.keylength) < 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed"); - goto out; -@@ -1942,8 +2129,7 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key, - goto out; - } - -- if (EVP_Digest(buf, key->rsa.private.key_length, d_hash, NULL, md, NULL) -- <= 0) { -+ if (EVP_Digest(buf, key->rsa.keylength, d_hash, NULL, md, NULL) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "EVP_Digest failed"); - goto out; - } -@@ -1971,10 +2157,9 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key, - goto out; - } - -- if (inlen < key->rsa.private.key_length) { -- memset(buf, 0, key->rsa.private.key_length - inlen); -- if (EVP_MAC_update(ctx, buf, key->rsa.private.key_length - inlen) -- != 1) { -+ if (inlen < key->rsa.keylength) { -+ memset(buf, 0, key->rsa.keylength - inlen); -+ if (EVP_MAC_update(ctx, buf, key->rsa.keylength - inlen) != 1) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "EVP_MAC_update failed"); - goto out; -@@ -2003,7 +2188,7 @@ out: - BN_free(dq); - BN_free(qinv); - if (buf != NULL) -- P_SECURE_CLEAR_FREE(key->provctx, buf, key->rsa.private.key_length); -+ P_SECURE_CLEAR_FREE(key->provctx, buf, key->rsa.keylength); - EVP_MAC_free(hmac); - EVP_MAC_CTX_free(ctx); - EVP_MD_free(md); -diff --git a/src/provider/rsa_signature.c b/src/provider/rsa_signature.c -index cfc10a1..f7a0a91 100644 ---- a/src/provider/rsa_signature.c -+++ b/src/provider/rsa_signature.c -@@ -719,7 +719,7 @@ static int ibmca_signature_rsa_sign(void *vctx, - goto out; - - /* Perform private key encrypt */ -- rc = ibmca_rsa_crt_with_blinding(ctx->key, enc_data, sig, rsa_size); -+ rc = ibmca_rsa_priv_with_blinding(ctx->key, enc_data, sig, rsa_size); - if (rc != 1) { - ibmca_debug_op_ctx(ctx, "ibmca_asym_cipher_rsa_with_blinding failed"); - --- -2.25.1 - diff -Nru openssl-ibmca-2.4.0/debian/patches/series openssl-ibmca-2.4.1/debian/patches/series --- openssl-ibmca-2.4.0/debian/patches/series 2023-07-27 16:38:24.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/series 2024-01-22 19:51:21.000000000 +0100 @@ -1,7 +1,2 @@ openssl-config.patch testconf-openssl3.patch -lp-2027809-engine-Only-register-those-algos-specified-with-defa.patch -lp-2027809-provider-rsa-Check-RSA-keys-with-p-q-at-key-generati.patch -lp-2027809-provider-Support-importing-of-RSA-keys-with-just-ME-.patch -lp-2027809-provider-RSA-Fix-get_params-to-retrieve-max-size-bit.patch -lp-2027809-provider-Default-debug-directory-to-tmp-but-make-it-.patch diff -Nru openssl-ibmca-2.4.0/debian/patches/testconf-openssl3.patch openssl-ibmca-2.4.1/debian/patches/testconf-openssl3.patch --- openssl-ibmca-2.4.0/debian/patches/testconf-openssl3.patch 2023-07-27 16:13:14.000000000 +0200 +++ openssl-ibmca-2.4.1/debian/patches/testconf-openssl3.patch 2024-01-22 19:51:21.000000000 +0100 @@ -12,9 +12,9 @@ -AM_TESTS_ENVIRONMENT = export IBMCA_TEST_PATH=${top_builddir}/src/engine/.libs/ibmca.so IBMCA_OPENSSL_TEST_CONF=${srcdir}/openssl-test.cnf IBMCA_OPENSSL_TEST_NOINIT_CONF=${srcdir}/openssl-test-noinit.cnf PERL5LIB=${srcdir}; +AM_TESTS_ENVIRONMENT = export IBMCA_TEST_PATH=${top_builddir}/src/engine/.libs/ibmca.so IBMCA_OPENSSL_TEST_CONF=${srcdir}/openssl-test.cnf IBMCA_OPENSSL_WITNESS_CONF=${srcdir}/openssl-witness.cnf IBMCA_OPENSSL_TEST_NOINIT_CONF=${srcdir}/openssl-test-noinit.cnf PERL5LIB=${srcdir}; - EXTRA_DIST = ${TESTS_PERL} ${TESTS_CIPHERS} test.pm openssl-test.cnf \ - dsa2k.key dsa2k_pub.key dsa4k.key dsa4k_pub.key dsa8k.key \ - dsa8k_pub.key dsamax.key dsamax_pub.key rsa2k.key rsa4k.key rsa8k.key + EXTRA_DIST = ${TESTS_PERL} ${TESTS_CIPHERS} test.pm openssl-test.cnf \ + openssl-test-noinit.cnf dsa2k.key dsa2k_pub.key dsa4k.key \ + dsa4k_pub.key dsa8k.key dsa8k_pub.key dsamax.key dsamax_pub.key \ --- /dev/null +++ b/test/engine/openssl-witness.cnf @@ -0,0 +1,14 @@ diff -Nru openssl-ibmca-2.4.0/openssl-ibmca-provider.spec openssl-ibmca-2.4.1/openssl-ibmca-provider.spec --- openssl-ibmca-2.4.0/openssl-ibmca-provider.spec 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/openssl-ibmca-provider.spec 2023-09-21 08:52:43.000000000 +0200 @@ -5,7 +5,7 @@ # %global modulesdir %(pkg-config --variable=modulesdir libcrypto) Name: openssl-ibmca -Version: 2.4.0 +Version: 2.4.1 Release: 1%{?dist} Summary: An IBMCA OpenSSL dynamic provider diff -Nru openssl-ibmca-2.4.0/openssl-ibmca.spec openssl-ibmca-2.4.1/openssl-ibmca.spec --- openssl-ibmca-2.4.0/openssl-ibmca.spec 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/openssl-ibmca.spec 2023-09-21 08:52:43.000000000 +0200 @@ -1,7 +1,7 @@ %global enginesdir %(pkg-config --variable=enginesdir libcrypto) Name: openssl-ibmca -Version: 2.4.0 +Version: 2.4.1 Release: 1%{?dist} Summary: An IBMCA OpenSSL dynamic engine diff -Nru openssl-ibmca-2.4.0/src/engine/e_ibmca.c openssl-ibmca-2.4.1/src/engine/e_ibmca.c --- openssl-ibmca-2.4.0/src/engine/e_ibmca.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/engine/e_ibmca.c 2023-09-21 08:52:43.000000000 +0200 @@ -642,6 +642,9 @@ if (!ENGINE_set_pkey_meths(e, ibmca_engine_pkey_meths)) goto out; + if (!ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)) + goto out; + rc = 1; out: free(pmech_list); diff -Nru openssl-ibmca-2.4.0/src/engine/Makefile.am openssl-ibmca-2.4.1/src/engine/Makefile.am --- openssl-ibmca-2.4.0/src/engine/Makefile.am 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/engine/Makefile.am 2023-09-21 08:52:43.000000000 +0200 @@ -1,4 +1,4 @@ -VERSION = 2:4:0 +VERSION = 2:4:1 lib_LTLIBRARIES=ibmca.la @@ -16,8 +16,8 @@ ibmca_la_LDFLAGS=-module -version-number ${VERSION} -shared -no-undefined \ -avoid-version -Wl,--version-script=${srcdir}/ibmca.map -dist_ibmca_la_SOURCES=ibmca.h e_ibmca_err.h -EXTRA_DIST = openssl.cnf.sample +dist_ibmca_la_SOURCES=ibmca.h e_ibmca_err.h openssl-compat.h +EXTRA_DIST = openssl.cnf.sample ibmca.map test/ibmca_mechaList_test.c ACLOCAL_AMFLAGS = -I m4 SUBDIRS = doc @@ -29,3 +29,5 @@ noinst_SCRIPTS = ibmca-engine-opensslconfig EXTRA_DIST += ibmca-engine-opensslconfig.in + +CLEANFILES = ibmca-engine-opensslconfig diff -Nru openssl-ibmca-2.4.0/src/provider/doc/ibmca-provider.man openssl-ibmca-2.4.1/src/provider/doc/ibmca-provider.man --- openssl-ibmca-2.4.0/src/provider/doc/ibmca-provider.man 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/doc/ibmca-provider.man 2023-09-21 08:52:43.000000000 +0200 @@ -94,13 +94,25 @@ .IP "debug = yes | no | stderr" .RS Enables debug output for the IBMCA provider. If this option is not specified, -no debuging output is produced. If \fBdebug = stderr\fP is specified, +no debugging output is produced. If \fBdebug = stderr\fP is specified, debugging messages are printed to stderr. Otherwise the debug output is written -into a trace file in \fB[/usr/local]/var/log/ibmca/trace-.\fP, -where is the name of the IBMCA provider from the identity -option, and is the process ID of the current process. You can also -enable debugging by setting the environment variable \fBIBMCA_DEBUG\fP to -\fBon\fP or \fBstderr\fP. +into a trace file in \fB/trace-.\fP, +where is the path name of a directory to where the debug files are +written (default: \fB/tmp\fP), is the name of the IBMCA provider +from the identity option, and is the process ID of the current process. +You can also enable debugging by setting the environment variable +\fBIBMCA_DEBUG\fP to \fBon\fP or \fBstderr\fP. +.RE +.PP +.IP "debug-path = /dir/to/debug/directory" +.RS +Sets the directory path to where debug files are written when debug is enabled +via \fBdebug = yes\fP or via environment variable \fBIBMCA_DEBUG=on\fP. +You can also set the debug path by setting the environment variable +\fBIBMCA_DEBUG_PATH\fP to the directory path. It must be ensured that the user +under which the application that uses the IBMCA provider runs has write access +to that directory. If this option is not specified, the default debug path is +\fB/tmp\fP. .RE .PP .IP "fips = yes | no" @@ -153,8 +165,18 @@ .B $IBMCA_DEBUG is set to \fBstderr\fP debug output to stderr for the IBMCA provider is enabled. If it is set to \fBon\fP the debug output is written into a trace file in -\fB[/usr/local]/var/log/ibmca/trace-.\fP, where is -the process ID of the current process. +\fB/trace-.\fP, where is the path +name of a directory to where the debug files are written (default: \fB/tmp\fP), + is the name of the IBMCA provider from the identity option, +and is the process ID of the current process. +.PP +.TP +.BR IBMCA_DEBUG_PATH +Sets the directory path to where debug files are written when debug is enabled +via \fBdebug = yes\fP configuration option or via environment variable +\fBIBMCA_DEBUG=on\fP. It must be ensured that the user under which the +application that uses the IBMCA provider runs has write access to that +directory. .PP .SH SEE ALSO .B provider(1) diff -Nru openssl-ibmca-2.4.0/src/provider/Makefile.am openssl-ibmca-2.4.1/src/provider/Makefile.am --- openssl-ibmca-2.4.0/src/provider/Makefile.am 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/Makefile.am 2023-09-21 08:52:43.000000000 +0200 @@ -1,5 +1,5 @@ -VERSION = 2:4:0 -VERSION_STR = 2.4.0 +VERSION = 2:4:1 +VERSION_STR = 2.4.1 lib_LTLIBRARIES=ibmca-provider.la @@ -8,6 +8,8 @@ rsa_signature.c ec_keymgmt.c ec_signature.c ec_keyexch.c \ dh_keymgmt.c dh_keyexch.c rsa_blinding.c rsa_sup_mul.c +dist_ibmca_provider_la_SOURCES=p_ibmca.h constant_time.h + ibmca_provider_la_CFLAGS=-DIBMCA_VERSION=\"${VERSION_STR}\" -DIBMCA_LOGDIR=\"$(logdir)\" if PROVIDER_FULL_LIBICA @@ -18,14 +20,11 @@ ibmca_provider_la_LDFLAGS=-module -version-number ${VERSION} -shared -no-undefined \ -avoid-version -Wl,--version-script=${srcdir}/ibmca-provider.map -EXTRA_DIST = openssl.cnf.provider.sample ibmca-provider-opensslconfig +EXTRA_DIST = openssl.cnf.provider.sample ibmca-provider-opensslconfig \ + ibmca-provider.map ACLOCAL_AMFLAGS = -I m4 SUBDIRS = doc noinst_SCRIPTS = ibmca-provider-opensslconfig - -install-data-hook: - $(MKDIR_P) $(DESTDIR)$(logdir) - $(CHMOD) 0777 $(DESTDIR)$(logdir) diff -Nru openssl-ibmca-2.4.0/src/provider/p_ibmca.c openssl-ibmca-2.4.1/src/provider/p_ibmca.c --- openssl-ibmca-2.4.0/src/provider/p_ibmca.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/p_ibmca.c 2023-09-21 08:52:43.000000000 +0200 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ static int ibmca_config_debug(struct ibmca_prov_ctx *provctx, const char *key, const char *value); +static int ibmca_config_debug_path(struct ibmca_prov_ctx *provctx, + const char *key, const char *value); static int ibmca_config_fips(struct ibmca_prov_ctx *provctx, const char *key, const char *value); static int ibmca_config_algorithms(struct ibmca_prov_ctx *provctx, @@ -70,6 +73,7 @@ const char *key, const char *value); static const struct ibmca_config_item config_items[] = { + { IBMCA_CONF_DEBUG_PATH, ibmca_config_debug_path }, { IBMCA_CONF_DEBUG, ibmca_config_debug }, { IBMCA_CONF_FIPS, ibmca_config_fips }, { IBMCA_CONF_ALGORITHMS, ibmca_config_algorithms }, @@ -881,7 +885,9 @@ *p = '_'; if (snprintf(debug_file, sizeof(debug_file), "%s/trace-%s.%d", - IBMCA_LOGDIR, prov_name, provctx->debug_pid) + provctx->debug_path != NULL ? provctx->debug_path : + IBMCA_LOGDIR, + prov_name, provctx->debug_pid) >= (int)sizeof(debug_file)) { put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR, "IBMCA_LOGDIR too long: '%s'", IBMCA_LOGDIR); @@ -904,6 +910,20 @@ return 1; } +static int ibmca_config_debug_path(struct ibmca_prov_ctx *provctx, + const char *key, const char *value) +{ + /* + * If the debug path is already set (e.g. due to IBMCA_DEBUG_PATH + * environment variable) do not override the setting. + */ + if (provctx->debug_path != NULL) + return 1; + + return ibmca_config_const_string(provctx, key, value, + &provctx->debug_path); +} + static int ibmca_config_fips(struct ibmca_prov_ctx *provctx, const char *key, const char *value) { @@ -1302,6 +1322,9 @@ ctx->c_free = c_free; ctx->ica_adapter = DRIVER_NOT_LOADED; + val = secure_getenv(IBMCA_DEBUG_PATH_ENVVAR); + if (val != NULL) + ibmca_config_debug_path(ctx, IBMCA_CONF_DEBUG_PATH, val); val = getenv(IBMCA_DEBUG_ENVVAR); if (val != NULL) ibmca_config_debug(ctx, IBMCA_CONF_DEBUG, val); diff -Nru openssl-ibmca-2.4.0/src/provider/p_ibmca.h openssl-ibmca-2.4.1/src/provider/p_ibmca.h --- openssl-ibmca-2.4.0/src/provider/p_ibmca.h 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/p_ibmca.h 2023-09-21 08:52:43.000000000 +0200 @@ -27,9 +27,11 @@ /* Environment variable name to enable debug */ #define IBMCA_DEBUG_ENVVAR "IBMCA_DEBUG" +#define IBMCA_DEBUG_PATH_ENVVAR "IBMCA_DEBUG_PATH" /* IBMCA provider configuration key words */ #define IBMCA_CONF_DEBUG "debug" +#define IBMCA_CONF_DEBUG_PATH "debug-path" #define IBMCA_CONF_ALGORITHMS "algorithms" #define IBMCA_CONF_FIPS "fips" #define IBMCA_CONF_FALLBACK_PROPS "fallback-properties" @@ -64,6 +66,7 @@ OSSL_FUNC_CRYPTO_secure_clear_free_fn *c_secure_clear_free; OSSL_FUNC_OPENSSL_cleanse_fn *c_cleanse; bool debug; + const char *debug_path; FILE *debug_file; pid_t debug_pid; pthread_mutex_t debug_mutex; @@ -124,7 +127,9 @@ union { struct { size_t bits; - ica_rsa_key_crt_t private; + size_t keylength; + ica_rsa_key_crt_t private_crt; + ica_rsa_key_mod_expo_t private_me; ica_rsa_key_mod_expo_t public; struct ibmca_pss_params pss; /* For type EVP_PKEY_RSA_PSS only */ BN_BLINDING *blinding; @@ -176,6 +181,9 @@ int (*dup_cb) (const struct ibmca_op_ctx *ctx, struct ibmca_op_ctx *new_ctx)); +bool ibmca_keymgmt_rsa_pub_valid(const ica_rsa_key_mod_expo_t *public); +bool ibmca_keymgmt_rsa_priv_crt_valid(const ica_rsa_key_crt_t *private_crt); +bool ibmca_keymgmt_rsa_priv_me_valid(const ica_rsa_key_mod_expo_t *private_me); OSSL_FUNC_keymgmt_free_fn ibmca_keymgmt_free; OSSL_FUNC_keymgmt_dup_fn ibmca_keymgmt_dup; @@ -519,8 +527,8 @@ int ibmca_keymgmt_rsa_pub_as_bn(struct ibmca_key *key, BIGNUM **n, BIGNUM **e); -int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, - unsigned char *out, size_t rsa_size); +int ibmca_rsa_priv_with_blinding(struct ibmca_key *key, const unsigned char *in, + unsigned char *out, size_t rsa_size); int ossl_bn_rsa_do_unblind(const unsigned char *intermediate, const BIGNUM *unblind, diff -Nru openssl-ibmca-2.4.0/src/provider/rsa_asym_cipher.c openssl-ibmca-2.4.1/src/provider/rsa_asym_cipher.c --- openssl-ibmca-2.4.0/src/provider/rsa_asym_cipher.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/rsa_asym_cipher.c 2023-09-21 08:52:43.000000000 +0200 @@ -844,7 +844,7 @@ } /* Perform private key decrypt */ - rc = ibmca_rsa_crt_with_blinding(ctx->key, in, dec_data, rsa_size); + rc = ibmca_rsa_priv_with_blinding(ctx->key, in, dec_data, rsa_size); if (rc != 1) { ibmca_debug_op_ctx(ctx, "ibmca_asym_cipher_rsa_with_blinding failed"); diff -Nru openssl-ibmca-2.4.0/src/provider/rsa_blinding.c openssl-ibmca-2.4.1/src/provider/rsa_blinding.c --- openssl-ibmca-2.4.0/src/provider/rsa_blinding.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/rsa_blinding.c 2023-09-21 08:52:43.000000000 +0200 @@ -392,8 +392,8 @@ return rc; } -int ibmca_rsa_crt_with_blinding(struct ibmca_key *key, const unsigned char *in, - unsigned char *out, size_t rsa_size) +int ibmca_rsa_priv_with_blinding(struct ibmca_key *key, const unsigned char *in, + unsigned char *out, size_t rsa_size) { BN_BLINDING *blinding; bool local_blinding = false; @@ -404,7 +404,7 @@ ibmca_debug_key(key, "key: %p rsa_size: %lu", key, rsa_size); - if (rsa_size != key->rsa.private.key_length) { + if (rsa_size != key->rsa.keylength) { put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "rsa_size is not modulus size"); goto out; @@ -445,11 +445,26 @@ goto out; } - rc = ica_rsa_crt(key->provctx->ica_adapter, buf, - &key->rsa.private, buf + rsa_size); - if (rc != 0) { - ibmca_debug_key(key, "ERROR: ica_rsa_crt failed with: %s", - strerror(rc)); + if (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { + rc = ica_rsa_crt(key->provctx->ica_adapter, buf, + &key->rsa.private_crt, buf + rsa_size); + if (rc != 0) { + ibmca_debug_key(key, "ERROR: ica_rsa_crt failed with: %s", + strerror(rc)); + rc = 0; + goto out; + } + } else if (ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { + rc = ica_rsa_mod_expo(key->provctx->ica_adapter, buf, + &key->rsa.private_me, buf + rsa_size); + if (rc != 0) { + ibmca_debug_key(key, "ERROR: ica_rsa_mod_expo failed with: %s", + strerror(rc)); + rc = 0; + goto out; + } + } else { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "No private key"); rc = 0; goto out; } diff -Nru openssl-ibmca-2.4.0/src/provider/rsa_keymgmt.c openssl-ibmca-2.4.1/src/provider/rsa_keymgmt.c --- openssl-ibmca-2.4.0/src/provider/rsa_keymgmt.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/rsa_keymgmt.c 2023-09-21 08:52:43.000000000 +0200 @@ -241,25 +241,14 @@ return 1; } -static int ibmca_keymgmt_rsa_priv_key_from_data( +static int ibmca_keymgmt_rsa_priv_crt_key_from_data( const struct ibmca_prov_ctx *provctx, - const OSSL_PARAM params[], - BIGNUM **d, BIGNUM **p, + const OSSL_PARAM params[], BIGNUM **p, BIGNUM **q, BIGNUM **dp, BIGNUM **dq, BIGNUM **qinv) { int rc; - /* OSSL_PKEY_PARAM_RSA_D */ - *d = BN_secure_new(); - if (*d == NULL) { - put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); - goto error; - } - rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_D, d); - if (rc <= 0) - goto error; - /* OSSL_PKEY_PARAM_RSA_FACTOR1 */ *p = BN_secure_new(); if (*p == NULL) { @@ -316,8 +305,6 @@ return 1; error: - BN_clear_free(*d); - *d = NULL; BN_clear_free(*p); *p = NULL; BN_clear_free(*dp); @@ -330,6 +317,31 @@ return 0; } +static int ibmca_keymgmt_rsa_priv_me_key_from_data( + const struct ibmca_prov_ctx *provctx, + const OSSL_PARAM params[], BIGNUM **d) +{ + int rc; + + /* OSSL_PKEY_PARAM_RSA_D */ + *d = BN_secure_new(); + if (*d == NULL) { + put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); + goto error; + } + rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_D, d); + if (rc <= 0) + goto error; + + return 1; + +error: + BN_clear_free(*d); + *d = NULL; + + return 0; +} + static int ibmca_keymgmt_rsa_priv_key_to_data( const struct ibmca_prov_ctx *provctx, OSSL_PARAM_BLD *bld, @@ -451,13 +463,14 @@ static int ibmca_keymgmt_rsa_alloc_pub(struct ibmca_key *key) { - key->rsa.public.key_length = (key->rsa.bits + 7) / 8; + key->rsa.public.key_length = key->rsa.keylength; key->rsa.public.modulus = P_ZALLOC(key->provctx, key->rsa.public.key_length); key->rsa.public.exponent = P_ZALLOC(key->provctx, key->rsa.public.key_length); - if (key->rsa.public.modulus == NULL || key->rsa.public.exponent == NULL) { + + if (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) { put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "Failed to allocate libica public RSA key"); return 0; @@ -466,24 +479,42 @@ return 1; } -static int ibmca_keymgmt_rsa_alloc_priv(struct ibmca_key *key) +static int ibmca_keymgmt_rsa_alloc_priv_crt(struct ibmca_key *key) { - key->rsa.private.key_length = (key->rsa.bits + 7) / 8; - key->rsa.private.p = P_SECURE_ZALLOC(key->provctx, - ICA_P_LEN(key->rsa.private.key_length)); - key->rsa.private.q = P_SECURE_ZALLOC(key->provctx, - ICA_Q_LEN(key->rsa.private.key_length)); - key->rsa.private.dp = P_SECURE_ZALLOC(key->provctx, - ICA_DP_LEN(key->rsa.private.key_length)); - key->rsa.private.dq = P_SECURE_ZALLOC(key->provctx, - ICA_DQ_LEN(key->rsa.private.key_length)); - key->rsa.private.qInverse = P_SECURE_ZALLOC(key->provctx, - ICA_QINV_LEN(key->rsa.private.key_length)); - if (key->rsa.private.p == NULL || key->rsa.private.q == NULL || - key->rsa.private.dp == NULL || key->rsa.private.dq == NULL || - key->rsa.private.qInverse == NULL ) { + key->rsa.private_crt.key_length = key->rsa.keylength; + + key->rsa.private_crt.p = P_SECURE_ZALLOC(key->provctx, + ICA_P_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.q = P_SECURE_ZALLOC(key->provctx, + ICA_Q_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.dp = P_SECURE_ZALLOC(key->provctx, + ICA_DP_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.dq = P_SECURE_ZALLOC(key->provctx, + ICA_DQ_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.qInverse = P_SECURE_ZALLOC(key->provctx, + ICA_QINV_LEN(key->rsa.private_crt.key_length)); + + if (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { put_error_key(key, IBMCA_ERR_MALLOC_FAILED, - "Failed to allocate libica private RSA key"); + "Failed to allocate libica private RSA CRT key"); + return 0; + } + + return 1; +} + +static int ibmca_keymgmt_rsa_alloc_priv_me(struct ibmca_key *key) +{ + key->rsa.private_me.key_length = key->rsa.keylength; + + key->rsa.private_me.modulus = P_ZALLOC(key->provctx, + key->rsa.private_me.key_length); + key->rsa.private_me.exponent = P_ZALLOC(key->provctx, + key->rsa.private_me.key_length); + + if (!ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { + put_error_key(key, IBMCA_ERR_MALLOC_FAILED, + "Failed to allocate libica private RSA ME key"); return 0; } @@ -503,29 +534,42 @@ key->rsa.public.key_length = 0; } -static void ibmca_keymgmt_rsa_free_priv(struct ibmca_key *key) +static void ibmca_keymgmt_rsa_free_priv_crt(struct ibmca_key *key) { - if (key->rsa.private.p != NULL) - P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.p, - ICA_P_LEN(key->rsa.private.key_length)); - key->rsa.private.p = NULL; - if (key->rsa.private.q != NULL) - P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.q, - ICA_Q_LEN(key->rsa.private.key_length)); - key->rsa.private.q = NULL; - if (key->rsa.private.dp != NULL) - P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.dp, - ICA_DP_LEN(key->rsa.private.key_length)); - key->rsa.private.dp = NULL; - if (key->rsa.private.dq != NULL) - P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.dq, - ICA_DQ_LEN(key->rsa.private.key_length)); - key->rsa.private.dq = NULL; - if (key->rsa.private.qInverse != NULL) - P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private.qInverse, - ICA_QINV_LEN(key->rsa.private.key_length)); - key->rsa.private.qInverse = NULL; - key->rsa.private.key_length = 0; + if (key->rsa.private_crt.p != NULL) + P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.p, + ICA_P_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.p = NULL; + if (key->rsa.private_crt.q != NULL) + P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.q, + ICA_Q_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.q = NULL; + if (key->rsa.private_crt.dp != NULL) + P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.dp, + ICA_DP_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.dp = NULL; + if (key->rsa.private_crt.dq != NULL) + P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.dq, + ICA_DQ_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.dq = NULL; + if (key->rsa.private_crt.qInverse != NULL) + P_SECURE_CLEAR_FREE(key->provctx, key->rsa.private_crt.qInverse, + ICA_QINV_LEN(key->rsa.private_crt.key_length)); + key->rsa.private_crt.qInverse = NULL; + key->rsa.private_crt.key_length = 0; +} + +static void ibmca_keymgmt_rsa_free_priv_me(struct ibmca_key *key) +{ + if (key->rsa.private_me.modulus != NULL) + P_CLEAR_FREE(key->provctx, key->rsa.private_me.modulus, + key->rsa.private_me.key_length); + key->rsa.private_me.modulus = NULL; + if (key->rsa.private_me.exponent != NULL) + P_CLEAR_FREE(key->provctx, key->rsa.private_me.exponent, + key->rsa.private_me.key_length); + key->rsa.private_me.exponent = NULL; + key->rsa.private_me.key_length = 0; } static void ibmca_keymgmt_rsa_clean(struct ibmca_key *key) @@ -535,7 +579,8 @@ ibmca_debug_key(key, "key: %p", key); - ibmca_keymgmt_rsa_free_priv(key); + ibmca_keymgmt_rsa_free_priv_crt(key); + ibmca_keymgmt_rsa_free_priv_me(key); ibmca_keymgmt_rsa_free_pub(key); if (key->type == EVP_PKEY_RSA_PSS) @@ -572,6 +617,30 @@ pthread_rwlock_destroy(&key->rsa.blinding_lock); } +bool ibmca_keymgmt_rsa_pub_valid(const ica_rsa_key_mod_expo_t *public) +{ + return public->key_length != 0 && + public->modulus != NULL && + public->exponent != NULL; +} + +bool ibmca_keymgmt_rsa_priv_crt_valid(const ica_rsa_key_crt_t *private_crt) +{ + return private_crt->key_length != 0 && + private_crt->p != NULL && + private_crt->q != NULL && + private_crt->dp != NULL && + private_crt->dq != NULL && + private_crt->qInverse != NULL; +} + +bool ibmca_keymgmt_rsa_priv_me_valid(const ica_rsa_key_mod_expo_t *private_me) +{ + return private_me->key_length != 0 && + private_me->modulus != NULL && + private_me->exponent != NULL; +} + static int ibmca_keymgmt_rsa_dup_pub(const struct ibmca_key *key, struct ibmca_key *new_key) { @@ -583,8 +652,8 @@ new_key->rsa.public.exponent = P_MEMDUP(key->provctx, key->rsa.public.exponent, key->rsa.public.key_length); - if (new_key->rsa.public.modulus == NULL || - new_key->rsa.public.exponent == NULL) { + + if (!ibmca_keymgmt_rsa_pub_valid(&new_key->rsa.public)) { put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "Failed to allocate libica RSA key"); return 0; @@ -593,29 +662,46 @@ return 1; } -static int ibmca_keymgmt_rsa_dup_priv(const struct ibmca_key *key, - struct ibmca_key *new_key) +static int ibmca_keymgmt_rsa_dup_priv_crt(const struct ibmca_key *key, + struct ibmca_key *new_key) { - new_key->rsa.private.key_length = key->rsa.private.key_length; + new_key->rsa.private_crt.key_length = key->rsa.private_crt.key_length; - new_key->rsa.private.p = P_SECURE_MEMDUP(key->provctx, key->rsa.private.p, - ICA_P_LEN(key->rsa.private.key_length)); - new_key->rsa.private.q = P_SECURE_MEMDUP(key->provctx, key->rsa.private.q, - ICA_Q_LEN(key->rsa.private.key_length)); - new_key->rsa.private.dp = P_SECURE_MEMDUP(key->provctx, key->rsa.private.dp, - ICA_DP_LEN(key->rsa.private.key_length)); - new_key->rsa.private.dq = P_SECURE_MEMDUP(key->provctx, key->rsa.private.dq, - ICA_DQ_LEN(key->rsa.private.key_length)); - new_key->rsa.private.qInverse = P_SECURE_MEMDUP(key->provctx, - key->rsa.private.qInverse, + new_key->rsa.private_crt.p = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.p, + ICA_P_LEN(key->rsa.private_crt.key_length)); + new_key->rsa.private_crt.q = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.q, + ICA_Q_LEN(key->rsa.private_crt.key_length)); + new_key->rsa.private_crt.dp = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.dp, + ICA_DP_LEN(key->rsa.private_crt.key_length)); + new_key->rsa.private_crt.dq = P_SECURE_MEMDUP(key->provctx, key->rsa.private_crt.dq, + ICA_DQ_LEN(key->rsa.private_crt.key_length)); + new_key->rsa.private_crt.qInverse = P_SECURE_MEMDUP(key->provctx, + key->rsa.private_crt.qInverse, ICA_QINV_LEN( - key->rsa.private.key_length)); + key->rsa.private_crt.key_length)); - if (new_key->rsa.private.p == NULL || - new_key->rsa.private.q == NULL || - new_key->rsa.private.dp == NULL || - new_key->rsa.private.dq == NULL || - new_key->rsa.private.qInverse == NULL) { + if (!ibmca_keymgmt_rsa_priv_crt_valid(&new_key->rsa.private_crt)) { + put_error_key(key, IBMCA_ERR_MALLOC_FAILED, + "Failed to allocate libica RSA key"); + return 0; + } + + return 1; +} + +static int ibmca_keymgmt_rsa_dup_priv_me(const struct ibmca_key *key, + struct ibmca_key *new_key) +{ + new_key->rsa.private_me.key_length = key->rsa.private_me.key_length; + + new_key->rsa.private_me.modulus = P_MEMDUP(key->provctx, + key->rsa.private_me.modulus, + key->rsa.private_me.key_length); + new_key->rsa.private_me.exponent = P_MEMDUP(key->provctx, + key->rsa.private_me.exponent, + key->rsa.private_me.key_length); + + if (!ibmca_keymgmt_rsa_priv_me_valid(&new_key->rsa.private_me)) { put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "Failed to allocate libica RSA key"); return 0; @@ -639,14 +725,20 @@ } new_key->rsa.bits = key->rsa.bits; + new_key->rsa.keylength = key->rsa.keylength; - if (key->rsa.public.key_length != 0) { + if (ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) { if (ibmca_keymgmt_rsa_dup_pub(key, new_key) == 0) return 0; } - if (key->rsa.private.key_length != 0) { - if (ibmca_keymgmt_rsa_dup_priv(key, new_key) == 0) + if (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) { + if (ibmca_keymgmt_rsa_dup_priv_crt(key, new_key) == 0) + return 0; + } + + if (ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) { + if (ibmca_keymgmt_rsa_dup_priv_me(key, new_key) == 0) return 0; } @@ -667,21 +759,56 @@ ibmca_debug_key(key, "key: %p selection: 0x%x", key, selection); if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) - ok = ok && (key->rsa.public.key_length != 0 && - key->rsa.public.modulus != NULL && - key->rsa.public.exponent != NULL); + ok = ok && ibmca_keymgmt_rsa_pub_valid(&key->rsa.public); if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) - ok = ok && (key->rsa.private.key_length != 0 && - key->rsa.private.p != NULL && - key->rsa.private.q != NULL && - key->rsa.private.dp != NULL && - key->rsa.private.dq != NULL && - key->rsa.private.qInverse != NULL); + ok = ok && (ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) || + ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)); ibmca_debug_key(key, "ok: %d", ok); return ok; } +static bool ibmca_keymgmt_rsa_pub_equal(const ica_rsa_key_mod_expo_t *public1, + const ica_rsa_key_mod_expo_t *public2) +{ + return public1->key_length > 0 && + public1->key_length == public2-> key_length && + memcmp(public1->exponent, public2->exponent, + public1->key_length) == 0 && + memcmp(public1->modulus, public2->modulus, + public1->key_length) == 0; +} + +static bool ibmca_keymgmt_rsa_priv_crt_equal( + const ica_rsa_key_crt_t *private_crt1, + const ica_rsa_key_crt_t *private_crt2) +{ + return private_crt1->key_length > 0 && + private_crt1->key_length == private_crt2->key_length && + CRYPTO_memcmp(private_crt1->p, private_crt2->p, + ICA_P_LEN(private_crt1->key_length)) == 0 && + CRYPTO_memcmp(private_crt1->q, private_crt2->q, + ICA_Q_LEN(private_crt1->key_length)) == 0 && + CRYPTO_memcmp(private_crt1->dp, private_crt2->dp, + ICA_DP_LEN(private_crt1->key_length)) == 0 && + CRYPTO_memcmp(private_crt1->dq, private_crt2->dq, + ICA_DQ_LEN(private_crt1->key_length)) == 0 && + CRYPTO_memcmp(private_crt1->qInverse, private_crt2->qInverse, + ICA_QINV_LEN(private_crt1->key_length)) == 0; +} + +static bool ibmca_keymgmt_rsa_priv_me_equal( + const ica_rsa_key_mod_expo_t *private_me1, + const ica_rsa_key_mod_expo_t *private_me2) +{ + return private_me1->key_length > 0 && + private_me1->key_length == private_me2-> key_length && + CRYPTO_memcmp(private_me1->exponent, private_me2->exponent, + private_me2->key_length) == 0 && + CRYPTO_memcmp(private_me1->modulus, private_me2->modulus, + private_me1->key_length) == 0; +} + static int ibmca_keymgmt_rsa_match(const void *vkey1, const void *vkey2, int selection) { @@ -699,35 +826,16 @@ return 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, - key2->rsa.public.exponent, - key1->rsa.public.key_length) == 0 && - memcmp(key1->rsa.public.modulus, - key2->rsa.public.modulus, - key1->rsa.public.key_length) == 0); + ok = ok && ibmca_keymgmt_rsa_pub_equal(&key1->rsa.public, + &key2->rsa.public); checked = 1; } 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, - key2->rsa.private.p, - ICA_P_LEN(key1->rsa.private.key_length)) == 0 && - CRYPTO_memcmp(key1->rsa.private.q, - key2->rsa.private.q, - ICA_Q_LEN(key1->rsa.private.key_length)) == 0 && - CRYPTO_memcmp(key1->rsa.private.dp, - key2->rsa.private.dp, - ICA_DP_LEN(key1->rsa.private.key_length)) == 0 && - CRYPTO_memcmp(key1->rsa.private.dq, - key2->rsa.private.dq, - ICA_DQ_LEN(key1->rsa.private.key_length)) == 0 && - CRYPTO_memcmp(key1->rsa.private.qInverse, - key2->rsa.private.qInverse, - ICA_QINV_LEN(key1->rsa.private.key_length)) == 0); + ok = ok && (ibmca_keymgmt_rsa_priv_crt_equal(&key1->rsa.private_crt, + &key2->rsa.private_crt) || + ibmca_keymgmt_rsa_priv_me_equal(&key1->rsa.private_me, + &key2->rsa.private_me)); ibmca_debug_key(key1, "ok: %d", ok); return ok; @@ -922,7 +1030,7 @@ ibmca_keymgmt_rsa_gen_free_cb(genctx); genctx->rsa.gen.bits = templ->rsa.bits; - if (templ->rsa.public.exponent != NULL) { + if (ibmca_keymgmt_rsa_pub_valid(&templ->rsa.public)) { genctx->rsa.gen.pub_exp = BN_bin2bn(templ->rsa.public.exponent, templ->rsa.public.key_length, NULL); @@ -1153,6 +1261,7 @@ } key->rsa.bits = genctx->rsa.gen.bits; + key->rsa.keylength = (key->rsa.bits + 7) / 8; ibmca_debug_op_ctx(genctx, "bits: %lu", key->rsa.bits); if (ibmca_keymgmt_rsa_alloc_pub(key) == 0) { @@ -1160,7 +1269,7 @@ return NULL; } - if (ibmca_keymgmt_rsa_alloc_priv(key) == 0) { + if (ibmca_keymgmt_rsa_alloc_priv_crt(key) == 0) { ibmca_keymgmt_free(key); return NULL; } @@ -1189,7 +1298,7 @@ } rc = ica_rsa_key_generate_crt(genctx->provctx->ica_adapter, key->rsa.bits, - &key->rsa.public, &key->rsa.private); + &key->rsa.public, &key->rsa.private_crt); if (rc != 0) { ibmca_debug_op_ctx(genctx, "ica_rsa_key_generate_crt failed with: %s", strerror(rc)); @@ -1203,6 +1312,15 @@ } } + /* If p < q, swap and recalculate now */ + rc = ica_rsa_crt_key_check(&key->rsa.private_crt); + if (rc > 1) { + put_error_op_ctx(genctx, IBMCA_ERR_INTERNAL_ERROR, + "ica_rsa_crt_key_check failed"); + ibmca_keymgmt_free(key); + return NULL; + } + p = 3; n = 0; if (osslcb != NULL && osslcb(cb_params, cbarg) == 0) { @@ -1247,7 +1365,7 @@ int ibmca_keymgmt_rsa_pub_as_bn(struct ibmca_key *key, BIGNUM **n, BIGNUM **e) { - if (key->rsa.public.modulus == NULL || key->rsa.public.exponent == NULL) + if (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public)) return 0; *n = BN_bin2bn(key->rsa.public.modulus, key->rsa.public.key_length, NULL); @@ -1268,14 +1386,11 @@ return 0; } - -static int ibmca_keymgmt_rsa_priv_as_bn(struct ibmca_key *key, BIGNUM **p, - BIGNUM **q, BIGNUM **dp, BIGNUM **dq, - BIGNUM **qinv) -{ - if (key->rsa.private.p == NULL || key->rsa.private.q == NULL || - key->rsa.private.dp == NULL || key->rsa.private.dq == NULL || - key->rsa.private.qInverse == NULL) +static int ibmca_keymgmt_rsa_priv_crt_as_bn(struct ibmca_key *key, BIGNUM **p, + BIGNUM **q, BIGNUM **dp, + BIGNUM **dq, BIGNUM **qinv) +{ + if (!ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt)) return 0; *p = BN_secure_new(); @@ -1289,17 +1404,17 @@ goto error; } - *p = BN_bin2bn(key->rsa.private.p, - ICA_P_LEN(key->rsa.private.key_length), *p); - *q = BN_bin2bn(key->rsa.private.q, - ICA_Q_LEN(key->rsa.private.key_length), *q); - *dp = BN_bin2bn(key->rsa.private.dp, - ICA_DP_LEN(key->rsa.private.key_length), + *p = BN_bin2bn(key->rsa.private_crt.p, + ICA_P_LEN(key->rsa.private_crt.key_length), *p); + *q = BN_bin2bn(key->rsa.private_crt.q, + ICA_Q_LEN(key->rsa.private_crt.key_length), *q); + *dp = BN_bin2bn(key->rsa.private_crt.dp, + ICA_DP_LEN(key->rsa.private_crt.key_length), *dp); - *dq = BN_bin2bn(key->rsa.private.dq, - ICA_DQ_LEN(key->rsa.private.key_length), *dq); - *qinv = BN_bin2bn(key->rsa.private.qInverse, - ICA_QINV_LEN(key->rsa.private.key_length), *qinv); + *dq = BN_bin2bn(key->rsa.private_crt.dq, + ICA_DQ_LEN(key->rsa.private_crt.key_length), *dq); + *qinv = BN_bin2bn(key->rsa.private_crt.qInverse, + ICA_QINV_LEN(key->rsa.private_crt.key_length), *qinv); if (*p == NULL || *q == NULL || *dp == NULL || *dq == NULL || *qinv == NULL) { put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "BN_bin2bn failed"); @@ -1323,6 +1438,33 @@ return 0; } +int ibmca_keymgmt_rsa_priv_me_as_bn(struct ibmca_key *key, BIGNUM **d) +{ + if (!ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)) + return 0; + + *d = BN_secure_new(); + if (*d == NULL) { + put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed"); + goto error; + } + + *d = BN_bin2bn(key->rsa.private_me.exponent, key->rsa.private_me.key_length, + *d); + if (*d == NULL) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "BN_bin2bn failed"); + goto error; + } + + return 1; + +error: + BN_clear_free(*d); + *d = NULL; + + return 0; +} + static int ibmca_keymgmt_rsa_calc_priv_d(struct ibmca_key *key, BIGNUM *n, BIGNUM *e, BIGNUM *p, BIGNUM *q, BIGNUM **d) @@ -1370,8 +1512,9 @@ for (parm = params; parm != NULL && parm->key != NULL; parm++) ibmca_debug_key(key, "param: %s", parm->key); - empty = (key->rsa.public.key_length == 0 || - key->rsa.private.key_length == 0); + empty = (!ibmca_keymgmt_rsa_pub_valid(&key->rsa.public) && + !ibmca_keymgmt_rsa_priv_crt_valid(&key->rsa.private_crt) && + !ibmca_keymgmt_rsa_priv_me_valid(&key->rsa.private_me)); if (!empty) { /* OSSL_PKEY_PARAM_BITS */ @@ -1430,16 +1573,30 @@ } /* Private key parts */ - rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); + rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); if (rc == 1) { - rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); - if (rc == 0) - goto out; + /* CRT format */ + rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); + if (rc == 0) { + rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); + if (rc == 0) + goto out; + } rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, NULL, params, d, p, q, dp, dq, qinv); if (rc == 0) goto out; + } else { + rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); + if (rc == 1) { + /* ME format */ + rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, NULL, params, + d, NULL, NULL, NULL, NULL, + NULL); + if (rc == 0) + goto out; + } } /* Return RSA-PSS parameters only for restricted RSA-PSS keys */ @@ -1675,16 +1832,30 @@ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { /* Private key parts */ - rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); + rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); if (rc == 1) { - rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); - if (rc == 0) - goto error; + /* CRT format */ + rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); + if (rc == 0) { + rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); + if (rc == 0) + goto error; + } rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, bld, NULL, d, p, q, dp, dq, qinv); if (rc == 0) goto error; + } else { + rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); + if (rc == 1) { + /* ME format */ + rc = ibmca_keymgmt_rsa_priv_key_to_data(key->provctx, bld, NULL, + d, NULL, NULL, NULL, + NULL, NULL); + if (rc == 0) + goto error; + } } } @@ -1764,6 +1935,7 @@ return 0; key->rsa.bits = BN_num_bits(n); + key->rsa.keylength = (key->rsa.bits + 7) / 8; ibmca_debug_key(key, "key: %p bits: %u", key, key->rsa.bits); if (ibmca_keymgmt_rsa_alloc_pub(key) == 0) @@ -1785,43 +1957,73 @@ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { /* Import private key parts */ - if (ibmca_keymgmt_rsa_alloc_priv(key) == 0) - goto out; - - rc = ibmca_keymgmt_rsa_priv_key_from_data(key->provctx, params, &d, - &p, &q, &dp, &dq, &qinv); - if (rc == 0) - goto out; - - if (BN_bn2binpad(p, key->rsa.private.p, - ICA_P_LEN(key->rsa.private.key_length)) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed for private p"); - goto out; - } - if (BN_bn2binpad(q, key->rsa.private.q, - ICA_Q_LEN(key->rsa.private.key_length)) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed for private q"); - goto out; - } - if (BN_bn2binpad(dp, key->rsa.private.dp, - ICA_DP_LEN(key->rsa.private.key_length)) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed for private dp"); - goto out; - } - if (BN_bn2binpad(dq, key->rsa.private.dq, - ICA_DQ_LEN(key->rsa.private.key_length)) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed for private dq"); - goto out; + rc = ibmca_keymgmt_rsa_priv_crt_key_from_data(key->provctx, params, + &p, &q, &dp, &dq, &qinv); + if (rc == 1) { + /* CRT components */ + if (ibmca_keymgmt_rsa_alloc_priv_crt(key) == 0) + goto out; + + if (BN_bn2binpad(p, key->rsa.private_crt.p, + ICA_P_LEN(key->rsa.private_crt.key_length)) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private p"); + goto out; + } + if (BN_bn2binpad(q, key->rsa.private_crt.q, + ICA_Q_LEN(key->rsa.private_crt.key_length)) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private q"); + goto out; + } + if (BN_bn2binpad(dp, key->rsa.private_crt.dp, + ICA_DP_LEN(key->rsa.private_crt.key_length)) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private dp"); + goto out; + } + if (BN_bn2binpad(dq, key->rsa.private_crt.dq, + ICA_DQ_LEN(key->rsa.private_crt.key_length)) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private dq"); + goto out; + } + if (BN_bn2binpad(qinv, key->rsa.private_crt.qInverse, + ICA_QINV_LEN(key->rsa.private_crt.key_length)) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private qinv"); + goto out; + } + + /* If p < q, swap and recalculate now */ + rc = ica_rsa_crt_key_check(&key->rsa.private_crt); + if (rc > 1) { + rc = 0; + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "ica_rsa_crt_key_check failed"); + goto out; + } } - if (BN_bn2binpad(qinv, key->rsa.private.qInverse, - ICA_QINV_LEN(key->rsa.private.key_length)) <= 0) { - put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, - "BN_bn2binpad failed for private qinv"); - goto out; + + rc = ibmca_keymgmt_rsa_priv_me_key_from_data(key->provctx, params, &d); + if (rc == 1) { + /* ME components */ + if (ibmca_keymgmt_rsa_alloc_priv_me(key) == 0) + goto out; + + if (BN_bn2binpad(n, key->rsa.private_me.modulus, + key->rsa.private_me.key_length) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for modulus"); + goto out; + } + + if (BN_bn2binpad(d, key->rsa.private_me.exponent, + key->rsa.private_me.key_length) <= 0) { + put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, + "BN_bn2binpad failed for private d"); + goto out; + } } } @@ -1884,19 +2086,22 @@ return 0; } - rc = ibmca_keymgmt_rsa_priv_as_bn(key, &p, &q, &dp, &dq, &qinv); - if (rc == 0) - goto out; + rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d); + if (rc == 0) { + rc = ibmca_keymgmt_rsa_priv_crt_as_bn(key, &p, &q, &dp, &dq, &qinv); + if (rc == 0) + goto out; - rc = ibmca_keymgmt_rsa_pub_as_bn(key, &n, &e); - if (rc == 0) - goto out; + rc = ibmca_keymgmt_rsa_pub_as_bn(key, &n, &e); + if (rc == 0) + goto out; - rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); - if (rc == 0) - goto out; + rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d); + if (rc == 0) + goto out; + } - buf = P_SECURE_ZALLOC(key->provctx, key->rsa.private.key_length); + buf = P_SECURE_ZALLOC(key->provctx, key->rsa.keylength); if (buf == NULL) { put_error_key(key, IBMCA_ERR_MALLOC_FAILED, "Failed to allocate buffer for private key"); @@ -1904,7 +2109,7 @@ } BN_set_flags(d, BN_FLG_CONSTTIME); - if (BN_bn2binpad(d, buf, key->rsa.private.key_length) < 0) { + if (BN_bn2binpad(d, buf, key->rsa.keylength) < 0) { put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "BN_bn2binpad failed"); goto out; @@ -1924,8 +2129,7 @@ goto out; } - if (EVP_Digest(buf, key->rsa.private.key_length, d_hash, NULL, md, NULL) - <= 0) { + if (EVP_Digest(buf, key->rsa.keylength, d_hash, NULL, md, NULL) <= 0) { put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "EVP_Digest failed"); goto out; } @@ -1953,10 +2157,9 @@ goto out; } - if (inlen < key->rsa.private.key_length) { - memset(buf, 0, key->rsa.private.key_length - inlen); - if (EVP_MAC_update(ctx, buf, key->rsa.private.key_length - inlen) - != 1) { + if (inlen < key->rsa.keylength) { + memset(buf, 0, key->rsa.keylength - inlen); + if (EVP_MAC_update(ctx, buf, key->rsa.keylength - inlen) != 1) { put_error_key(key, IBMCA_ERR_INTERNAL_ERROR, "EVP_MAC_update failed"); goto out; @@ -1985,7 +2188,7 @@ BN_free(dq); BN_free(qinv); if (buf != NULL) - P_SECURE_CLEAR_FREE(key->provctx, buf, key->rsa.private.key_length); + P_SECURE_CLEAR_FREE(key->provctx, buf, key->rsa.keylength); EVP_MAC_free(hmac); EVP_MAC_CTX_free(ctx); EVP_MD_free(md); diff -Nru openssl-ibmca-2.4.0/src/provider/rsa_signature.c openssl-ibmca-2.4.1/src/provider/rsa_signature.c --- openssl-ibmca-2.4.0/src/provider/rsa_signature.c 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/src/provider/rsa_signature.c 2023-09-21 08:52:43.000000000 +0200 @@ -719,7 +719,7 @@ goto out; /* Perform private key encrypt */ - rc = ibmca_rsa_crt_with_blinding(ctx->key, enc_data, sig, rsa_size); + rc = ibmca_rsa_priv_with_blinding(ctx->key, enc_data, sig, rsa_size); if (rc != 1) { ibmca_debug_op_ctx(ctx, "ibmca_asym_cipher_rsa_with_blinding failed"); diff -Nru openssl-ibmca-2.4.0/test/engine/Makefile.am openssl-ibmca-2.4.1/test/engine/Makefile.am --- openssl-ibmca-2.4.0/test/engine/Makefile.am 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/test/engine/Makefile.am 2023-09-21 08:52:43.000000000 +0200 @@ -62,9 +62,11 @@ enginectrl_LDADD = -lcrypto -ldl AM_TESTS_ENVIRONMENT = export IBMCA_TEST_PATH=${top_builddir}/src/engine/.libs/ibmca.so IBMCA_OPENSSL_TEST_CONF=${srcdir}/openssl-test.cnf IBMCA_OPENSSL_TEST_NOINIT_CONF=${srcdir}/openssl-test-noinit.cnf PERL5LIB=${srcdir}; -EXTRA_DIST = ${TESTS_PERL} ${TESTS_CIPHERS} test.pm openssl-test.cnf \ -dsa2k.key dsa2k_pub.key dsa4k.key dsa4k_pub.key dsa8k.key \ -dsa8k_pub.key dsamax.key dsamax_pub.key rsa2k.key rsa4k.key rsa8k.key +EXTRA_DIST = ${TESTS_PERL} ${TESTS_CIPHERS} test.pm openssl-test.cnf \ + openssl-test-noinit.cnf dsa2k.key dsa2k_pub.key dsa4k.key \ + dsa4k_pub.key dsa8k.key dsa8k_pub.key dsamax.key dsamax_pub.key \ + rsa2k.key rsa4k.key rsa8k.key rsa16k.key dsaparam2k.key \ + dsaparam4k.key dsaparam8k.key dsaparammax.key libica-link.sh: @echo '#!/bin/bash' > libica-link.sh @@ -77,3 +79,5 @@ @echo "fi" >> libica-link.sh @echo "exit 0" >> libica-link.sh @chmod u+x libica-link.sh + +CLEANFILES = *.out *.dec libica-link.sh diff -Nru openssl-ibmca-2.4.0/test/provider/Makefile.am openssl-ibmca-2.4.1/test/provider/Makefile.am --- openssl-ibmca-2.4.0/test/provider/Makefile.am 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/test/provider/Makefile.am 2023-09-21 08:52:43.000000000 +0200 @@ -48,4 +48,12 @@ threadtest_LDADD = -lcrypto -lpthread AM_TESTS_ENVIRONMENT = export IBMCA_TEST_PATH=${top_builddir}/src/provider/.libs/ IBMCA_OPENSSL_TEST_CONF=${srcdir}/openssl-test.cnf PERL5LIB=${srcdir}; -EXTRA_DIST = ${TESTS_PERL} test.pm openssl-test.cnf server-cert-rsa.pem server-key-rsa.pem server-cert-ec.pem server-key-ec.pem +EXTRA_DIST = ${TESTS_PERL} test.pm openssl-test.cnf server-cert-rsa.pem \ + server-key-rsa.pem server-cert-ec.pem server-key-ec.pem \ + rsa-implrej-bad-empty-in.bin rsa-implrej-bad-empty-out.bin \ + rsa-implrej-bad-max-in.bin rsa-implrej-bad-max-out.bin \ + rsa-implrej-bad-prf-in.bin rsa-implrej-bad-prf-out.bin \ + rsa-implrej-good-in.bin rsa-implrej-good-out.bin \ + rsa-implrej-key.pem rsa16k.pl + +CLEANFILES = *.out *.dec *.pub *.key diff -Nru openssl-ibmca-2.4.0/test/provider/openssl-test.cnf openssl-ibmca-2.4.1/test/provider/openssl-test.cnf --- openssl-ibmca-2.4.0/test/provider/openssl-test.cnf 2023-03-30 11:12:40.000000000 +0200 +++ openssl-ibmca-2.4.1/test/provider/openssl-test.cnf 2023-09-21 08:52:43.000000000 +0200 @@ -16,6 +16,7 @@ module = ibmca-provider.so activate = 1 #debug = yes +#debug-path = /dir/to/debug/directory #fips=yes #algorithms = RSA,EC,DH algorithms = ALL