Release the DRBG in global default libctx early

Resolves: rhbz#2211340
This commit is contained in:
Dmitry Belyavskiy 2023-05-31 16:21:07 +02:00
parent df4dd7dd7f
commit d1a87553bb
2 changed files with 248 additions and 0 deletions

View File

@ -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 <sys/types.h>
# include <sys/stat.h>
@@ -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");
+}

View File

@ -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 <dbelyavs@redhat.com> - 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 <cllang@redhat.com> - 1:3.0.7-19
- Re-enable DHX keys in FIPS mode, disable FIPS 186-4 parameter validation and generation in FIPS mode