openssl-ibmca/openssl-ibmca-2.4.1-fixes.patch
Dan Horák 7ad5497fac - apply post-2.4.1 fixes (RHEL-23702)
- Resolves: RHEL-23702
2024-05-23 10:04:28 +02:00

424 lines
14 KiB
Diff

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