diff options
author | Matt Caswell <matt@openssl.org> | 2022-08-10 15:31:00 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2022-10-03 14:57:33 +0100 |
commit | 25d47cccf203c3b71171e78865e48ea061a039a8 (patch) | |
tree | 223a67a30739064a176b4f4eaf756e5ac65ff485 /crypto/evp | |
parent | fcae2ae4f675def607d338b7945b9af1dd9bb746 (diff) |
Fix usage of custom EVP_CIPHER objects
If a custom EVP_CIPHER object has been passed to EVP_CipherInit() then it
should be used in preference to a fetched cipher.
We also fix a possible NULL pointer deref in the same code for digests.
If the custom cipher passed to EVP_CipherInit() happens to use NID_undef
(which should be a discouraged practice), then in the previous
implementation this could result in the NULL cipher being fetched and
hence NULL encryption being unexpectedly used.
CVE-2022-3358
Fixes #18970
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19300)
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/digest.c | 5 | ||||
-rw-r--r-- | crypto/evp/evp_enc.c | 6 |
2 files changed, 7 insertions, 4 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index e055c70a5f..5de5a9014d 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -230,11 +230,12 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, # endif #endif || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0 - || type->origin == EVP_ORIG_METH) { + || (type != NULL && type->origin == EVP_ORIG_METH) + || (type == NULL && ctx->digest != NULL + && ctx->digest->origin == EVP_ORIG_METH)) { /* If we were using provided hash before, cleanup algctx */ if (!evp_md_ctx_free_algctx(ctx)) return 0; - if (ctx->digest == ctx->fetched_digest) ctx->digest = NULL; EVP_MD_free(ctx->fetched_digest); diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 6bb893c4d9..c1f5d2ca54 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -144,7 +144,10 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) || tmpimpl != NULL #endif - || impl != NULL) { + || impl != NULL + || (cipher != NULL && cipher->origin == EVP_ORIG_METH) + || (cipher == NULL && ctx->cipher != NULL + && ctx->cipher->origin == EVP_ORIG_METH)) { if (ctx->cipher == ctx->fetched_cipher) ctx->cipher = NULL; EVP_CIPHER_free(ctx->fetched_cipher); @@ -160,7 +163,6 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, ctx->cipher_data = NULL; } - /* Start of non-legacy code below */ /* Ensure a context left lying around from last time is cleared */ |