From d1a87553bb9f3ed88e351acbf4cea1199a05f995 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Wed, 31 May 2023 16:21:07 +0200 Subject: [PATCH] Release the DRBG in global default libctx early Resolves: rhbz#2211340 --- 0123-ibmca-atexit-crash.patch | 244 ++++++++++++++++++++++++++++++++++ openssl.spec | 4 + 2 files changed, 248 insertions(+) create mode 100644 0123-ibmca-atexit-crash.patch diff --git a/0123-ibmca-atexit-crash.patch b/0123-ibmca-atexit-crash.patch new file mode 100644 index 0000000..893e598 --- /dev/null +++ b/0123-ibmca-atexit-crash.patch @@ -0,0 +1,244 @@ +diff --git a/crypto/context.c b/crypto/context.c +index bdfc4d02a3f0..548665fba265 100644 +--- a/crypto/context.c ++++ b/crypto/context.c +@@ -15,6 +15,7 @@ + #include "internal/bio.h" + #include "internal/provider.h" + #include "crypto/ctype.h" ++#include "crypto/rand.h" + + # include + # include +@@ -271,6 +272,20 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx) + + return NULL; + } ++ ++void ossl_release_default_drbg_ctx(void) ++{ ++ int dynidx = default_context_int.dyn_indexes[OSSL_LIB_CTX_DRBG_INDEX]; ++ ++ /* early release of the DRBG in global default libctx, no locking */ ++ if (dynidx != -1) { ++ void *data; ++ ++ data = CRYPTO_get_ex_data(&default_context_int.data, dynidx); ++ ossl_rand_ctx_free(data); ++ CRYPTO_set_ex_data(&default_context_int.data, dynidx, NULL); ++ } ++} + #endif + + OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx) +diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c +index c453d3226133..f341d915db76 100644 +--- a/crypto/rand/rand_lib.c ++++ b/crypto/rand/rand_lib.c +@@ -96,6 +96,7 @@ void ossl_rand_cleanup_int(void) + CRYPTO_THREAD_lock_free(rand_meth_lock); + rand_meth_lock = NULL; + # endif ++ ossl_release_default_drbg_ctx(); + rand_inited = 0; + } + +@@ -469,7 +470,7 @@ static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx) + return NULL; + } + +-static void rand_ossl_ctx_free(void *vdgbl) ++void ossl_rand_ctx_free(void *vdgbl) + { + RAND_GLOBAL *dgbl = vdgbl; + +@@ -494,7 +495,7 @@ static void rand_ossl_ctx_free(void *vdgbl) + static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_PRIORITY_2, + rand_ossl_ctx_new, +- rand_ossl_ctx_free, ++ ossl_rand_ctx_free, + }; + + static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) +diff --git a/engines/e_dasync.c b/engines/e_dasync.c +index 5a303a9f8528..7974106ae219 100644 +--- a/engines/e_dasync.c ++++ b/engines/e_dasync.c +@@ -139,6 +139,14 @@ static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); + ++static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, ++ void *ptr); ++static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc); ++static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl); ++static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx); ++ + static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, + int arg, void *ptr); + static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, +@@ -171,6 +179,12 @@ static const EVP_CIPHER *dasync_aes_128_cbc(void) + return _hidden_aes_128_cbc; + } + ++static EVP_CIPHER *_hidden_aes_256_ctr = NULL; ++static const EVP_CIPHER *dasync_aes_256_ctr(void) ++{ ++ return _hidden_aes_256_ctr; ++} ++ + /* + * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up + * once only during engine bind and can then be reused many times. +@@ -192,8 +206,10 @@ static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void) + static void destroy_ciphers(void) + { + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); ++ EVP_CIPHER_meth_free(_hidden_aes_256_ctr); + EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); + _hidden_aes_128_cbc = NULL; ++ _hidden_aes_256_ctr = NULL; + _hidden_aes_128_cbc_hmac_sha1 = NULL; + } + +@@ -202,6 +218,7 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + + static int dasync_cipher_nids[] = { + NID_aes_128_cbc, ++ NID_aes_256_ctr, + NID_aes_128_cbc_hmac_sha1, + 0 + }; +@@ -284,6 +301,30 @@ static int bind_dasync(ENGINE *e) + _hidden_aes_128_cbc = NULL; + } + ++ _hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr, ++ 1 /* block size */, ++ 32 /* key len */); ++ if (_hidden_aes_256_ctr == NULL ++ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr,16) ++ || !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr, ++ EVP_CIPH_FLAG_DEFAULT_ASN1 ++ | EVP_CIPH_CTR_MODE ++ | EVP_CIPH_FLAG_PIPELINE ++ | EVP_CIPH_CUSTOM_COPY) ++ || !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr, ++ dasync_aes256_init_key) ++ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_cipher) ++ || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_cleanup) ++ || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_ctrl) ++ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr, ++ sizeof(struct dasync_pipeline_ctx))) { ++ EVP_CIPHER_meth_free(_hidden_aes_256_ctr); ++ _hidden_aes_256_ctr = NULL; ++ } ++ + _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new( + NID_aes_128_cbc_hmac_sha1, + 16 /* block size */, +@@ -445,6 +486,9 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + case NID_aes_128_cbc: + *cipher = dasync_aes_128_cbc(); + break; ++ case NID_aes_256_ctr: ++ *cipher = dasync_aes_256_ctr(); ++ break; + case NID_aes_128_cbc_hmac_sha1: + *cipher = dasync_aes_128_cbc_hmac_sha1(); + break; +@@ -779,6 +823,29 @@ static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx) + return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc()); + } + ++static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, ++ void *ptr) ++{ ++ return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc) ++{ ++ return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl) ++{ ++ return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx) ++{ ++ return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr()); ++} ++ + + /* + * AES128 CBC HMAC SHA1 Implementation +diff --git a/include/crypto/rand.h b/include/crypto/rand.h +index 6a71a339c812..165deaf95c5e 100644 +--- a/include/crypto/rand.h ++++ b/include/crypto/rand.h +@@ -125,4 +125,5 @@ void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, + size_t ossl_pool_acquire_entropy(RAND_POOL *pool); + int ossl_pool_add_nonce_data(RAND_POOL *pool); + ++void ossl_rand_ctx_free(void *vdgbl); + #endif +diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h +index 1291299b6e50..934d4b089c20 100644 +--- a/include/internal/cryptlib.h ++++ b/include/internal/cryptlib.h +@@ -199,6 +199,8 @@ int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn); + const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx); + ++void ossl_release_default_drbg_ctx(void); ++ + OSSL_LIB_CTX *ossl_crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad); + int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, + CRYPTO_EX_DATA *ad); +diff --git a/test/recipes/05-test_rand.t b/test/recipes/05-test_rand.t +index 4da1e64cb6da..3f352db9df3a 100644 +--- a/test/recipes/05-test_rand.t ++++ b/test/recipes/05-test_rand.t +@@ -11,9 +11,30 @@ use warnings; + use OpenSSL::Test; + use OpenSSL::Test::Utils; + +-plan tests => 3; ++plan tests => 5; + setup("test_rand"); + + ok(run(test(["rand_test"]))); + ok(run(test(["drbgtest"]))); + ok(run(test(["rand_status_test"]))); ++ ++SKIP: { ++ skip "engine is not supported by this OpenSSL build", 2 ++ if disabled("engine") || disabled("dynamic-engine"); ++ ++ my $success; ++ my @randdata; ++ my $expected = '0102030405060708090a0b0c0d0e0f10'; ++ ++ @randdata = run(app(['openssl', 'rand', '-engine', 'ossltest', '-hex', '16' ]), ++ capture => 1, statusvar => \$success); ++ chomp(@randdata); ++ ok($success and $randdata[0] eq $expected, ++ "rand with ossltest: Check rand output is as expected"); ++ ++ @randdata = run(app(['openssl', 'rand', '-engine', 'dasync', '-hex', '16' ]), ++ capture => 1, statusvar => \$success); ++ chomp(@randdata); ++ ok($success and length($randdata[0]) == 32, ++ "rand with dasync: Check rand output is of expected length"); ++} diff --git a/openssl.spec b/openssl.spec index f6889a5..5ca4f1e 100644 --- a/openssl.spec +++ b/openssl.spec @@ -195,6 +195,8 @@ Patch120: 0120-RSA-PKCS15-implicit-rejection.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2160797 Patch121: 0121-FIPS-cms-defaults.patch Patch122: 0122-CVE-2023-2650.patch +# https://github.com/openssl/openssl/pull/19386 +Patch123: 0123-ibmca-atexit-crash.patch License: ASL 2.0 URL: http://www.openssl.org/ @@ -521,6 +523,8 @@ install -m644 %{SOURCE9} \ * Tue May 30 2023 Dmitry Belyavskiy - 1:3.0.7-20 - Fix possible DoS translating ASN.1 object identifiers Resolves: CVE-2023-2650 +- Release the DRBG in global default libctx early + Resolves: rhbz#2211340 * Mon May 22 2023 Clemens Lang - 1:3.0.7-19 - Re-enable DHX keys in FIPS mode, disable FIPS 186-4 parameter validation and generation in FIPS mode