]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
evp_md: assert digest is provided for algctx reuse
authorBenjamin Kaduk <bkaduk@akamai.com>
Mon, 2 May 2022 17:40:57 +0000 (10:40 -0700)
committerBenjamin Kaduk <kaduk@mit.edu>
Mon, 9 May 2022 06:48:34 +0000 (23:48 -0700)
When reusing an algctx (it was always freed on reinitialization,
prior to #18105), assert that the associated digest is provided.
We implicitly rely on this for algctx reuse to be safe (since
an implicit fetch could potentially change the digest object used,
including provider, which accordingly could change the layout of the
algctx object.

From code inspection, this is currently always the case -- the only
way to set an algctx requires the provider to be set, and the only
ways to change or remove a provider without destroying the entier
EVP_MD_CTX will also free the algctx.  Adding an assertion will help
ensure that this remains true as the code evolves.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18224)

crypto/evp/digest.c

index 02e8c4c47d2f386ad2a258f33f709c04728b0c58..e055c70a5f513f17c9aa42b197fe52651aadd932 100644 (file)
@@ -245,8 +245,15 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
     cleanup_old_md_data(ctx, 1);
 
     /* Start of non-legacy code below */
-    if (ctx->digest != type && !evp_md_ctx_free_algctx(ctx))
-        return 0;
+    if (ctx->digest == type) {
+        if (!ossl_assert(type->prov != NULL)) {
+            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+    } else {
+        if (!evp_md_ctx_free_algctx(ctx))
+            return 0;
+    }
 
     if (type->prov == NULL) {
 #ifdef FIPS_MODULE