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)
(cherry picked from commit
25d47cccf203c3b71171e78865e48ea061a039a8)
|| tmpimpl != NULL
#endif
|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0
|| 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);
if (ctx->digest == ctx->fetched_digest)
ctx->digest = NULL;
EVP_MD_free(ctx->fetched_digest);
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|| tmpimpl != NULL
#endif
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|| tmpimpl != NULL
#endif
+ || 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);
if (ctx->cipher == ctx->fetched_cipher)
ctx->cipher = NULL;
EVP_CIPHER_free(ctx->fetched_cipher);
ctx->cipher_data = NULL;
}
ctx->cipher_data = NULL;
}
/* Start of non-legacy code below */
/* Ensure a context left lying around from last time is cleared */
/* Start of non-legacy code below */
/* Ensure a context left lying around from last time is cleared */