From: Matt Caswell Date: Wed, 10 Aug 2022 14:31:00 +0000 (+0100) Subject: Fix usage of custom EVP_CIPHER objects X-Git-Tag: openssl-3.0.6~13 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=5485c56679d7c49b96e8fc8ca708b0b7e7c03c4b;ds=sidebyside 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 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/19300) (cherry picked from commit 25d47cccf203c3b71171e78865e48ea061a039a8) --- diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index de9a1dcda5..e6e03eaf34 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -225,7 +225,9 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, || tmpimpl != NULL #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 (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 012422630a..8480a86fab 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -136,7 +136,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); @@ -152,7 +155,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 */