]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix usage of custom EVP_CIPHER objects
authorMatt Caswell <matt@openssl.org>
Wed, 10 Aug 2022 14:31:00 +0000 (15:31 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 3 Oct 2022 13:57:33 +0000 (14:57 +0100)
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)

crypto/evp/digest.c
crypto/evp/evp_enc.c

index e055c70a5f513f17c9aa42b197fe52651aadd932..5de5a9014d18e03c4969032dd2ed34809e3d0593 100644 (file)
@@ -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);
index 6bb893c4d9990bc394af6098cdd387b9c9a3ceec..c1f5d2ca54073d27040e58ca965c839a41ec5425 100644 (file)
@@ -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 */