diff --git a/openssl-ibmca-2.4.0-fixes.patch b/openssl-ibmca-2.4.0-fixes.patch deleted file mode 100644 index 1d3ac73..0000000 --- a/openssl-ibmca-2.4.0-fixes.patch +++ /dev/null @@ -1,1463 +0,0 @@ -From 2d9f0222076f6e243e68238c533b6bf0b6073138 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Mon, 17 Apr 2023 13:38:36 +0200 -Subject: [PATCH 1/7] configure: check for perl and perl-FindBin - -Perl as well as the perl module FindBin are required to run the IBMCA tests. -Check for it during configuration and fail if it is not available. - -Signed-off-by: Ingo Franzki ---- - configure.ac | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/configure.ac b/configure.ac -index 39317c7..cea8ce8 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -48,6 +48,20 @@ AC_DISABLE_STATIC - 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"]) --- -2.41.0 - - -From e8983a442f53e56e49c9143babeacb5c0206c1bd Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Mon, 17 Apr 2023 13:43:59 +0200 -Subject: [PATCH 2/7] bootstrap: add --force option to autoreconf - -Consider all files as obsolete and make all of them new. - -Signed-off-by: Ingo Franzki ---- - bootstrap.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/bootstrap.sh b/bootstrap.sh -index 7800f7f..e60cda5 100755 ---- a/bootstrap.sh -+++ b/bootstrap.sh -@@ -15,4 +15,4 @@ - # limitations under the License. - # - --autoreconf -iv -+autoreconf --force --install --verbose --warnings=all --- -2.41.0 - - -From 3ea8f4ed58e075e097856437c0732e11771931d0 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Wed, 19 Apr 2023 10:07:01 +0200 -Subject: [PATCH 3/7] 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 ---- - 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.41.0 - - -From f8a60b6678b1eb3ccadcb31f36bf7961ed8d5a9a Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Tue, 25 Apr 2023 16:23:52 +0200 -Subject: [PATCH 4/7] 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 ---- - 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.41.0 - - -From acba1d936bd84c7090ed7d3849b0bab3c7f18da0 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Fri, 7 Jul 2023 14:55:26 +0200 -Subject: [PATCH 5/7] 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 ---- - 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.41.0 - - -From 67efa9ad713e8283cb20111a15629f15a8ea8c86 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Tue, 25 Jul 2023 14:52:49 +0200 -Subject: [PATCH 6/7] 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 ---- - 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.41.0 - - -From 2298d3964f1ce32d35bb7585e4fa224c5bf2c8d4 Mon Sep 17 00:00:00 2001 -From: Ingo Franzki -Date: Wed, 26 Jul 2023 15:19:55 +0200 -Subject: [PATCH 7/7] 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 ---- - 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.41.0 - diff --git a/openssl-ibmca-2.4.1-fixes.patch b/openssl-ibmca-2.4.1-fixes.patch new file mode 100644 index 0000000..e69de29 diff --git a/openssl-ibmca.spec b/openssl-ibmca.spec index e00c0e1..cc1480c 100644 --- a/openssl-ibmca.spec +++ b/openssl-ibmca.spec @@ -2,8 +2,8 @@ Summary: OpenSSL provider for IBMCA Name: openssl-ibmca -Version: 2.4.0 -Release: 5%{?dist} +Version: 2.4.1 +Release: 1%{?dist} License: Apache-2.0 URL: https://github.com/opencryptoki Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz @@ -56,6 +56,9 @@ make check %changelog +* Thu Sep 21 2023 Dan Horák - 2.4.1-1 +- updated to 2.4.1 + * Thu Jul 27 2023 Dan Horák - 2.4.0-5 - switch to upstream fix for logging into /tmp diff --git a/sources b/sources index eee921f..c808dc2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (openssl-ibmca-2.4.0.tar.gz) = ec886a89e6537bcda5f40c96dd66a6b3e19563c006434e65e5da7b3bdf7526a1cca7b454d3da1df2455625ffd970a9093ca4a0c7deb5e32e69bed9575f20f811 +SHA512 (openssl-ibmca-2.4.1.tar.gz) = e48b3fae04b0169001c52b1b959a855314f2e7314c6bd9df5ae31dc4a23525619ccca8c3465bad2966a63e32e3fe2c8f05ede84f8bf3d08386c7898d238331a6