/*
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/* We need to use some engine deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED

#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#ifndef FIPS_MODULE
# include <openssl/engine.h>
#endif
#include <openssl/params.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/provider.h"
#include "internal/core.h"
#include "crypto/evp.h"
#include "evp_local.h"

static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
{
    if (ctx->digest != NULL) {
        if (ctx->digest->cleanup != NULL
                && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
            ctx->digest->cleanup(ctx);
        if (ctx->md_data != NULL && ctx->digest->ctx_size > 0
                && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)
                    || force)) {
            OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
            ctx->md_data = NULL;
        }
    }
}

void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force, int keep_fetched)
{
    if (ctx->algctx != NULL) {
        if (ctx->digest != NULL && ctx->digest->freectx != NULL)
            ctx->digest->freectx(ctx->algctx);
        ctx->algctx = NULL;
        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
    }

    /* Code below to be removed when legacy support is dropped. */

    /*
     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
     * sometimes only copies of the context are ever finalised.
     */
    cleanup_old_md_data(ctx, force);
    if (force)
        ctx->digest = NULL;

#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
    ENGINE_finish(ctx->engine);
    ctx->engine = NULL;
#endif

    /* Non legacy code, this has to be later than the ctx->digest cleaning */
    if (!keep_fetched) {
        EVP_MD_free(ctx->fetched_digest);
        ctx->fetched_digest = NULL;
        ctx->reqdigest = NULL;
    }
}

static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched)
{
    if (ctx == NULL)
        return 1;

#ifndef FIPS_MODULE
    /*
     * pctx should be freed by the user of EVP_MD_CTX
     * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
     */
    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
        EVP_PKEY_CTX_free(ctx->pctx);
        ctx->pctx = NULL;
    }
#endif

    evp_md_ctx_clear_digest(ctx, 0, keep_fetched);
    if (!keep_fetched)
        OPENSSL_cleanse(ctx, sizeof(*ctx));

    return 1;
}

/* This call frees resources associated with the context */
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
{
    return evp_md_ctx_reset_ex(ctx, 0);
}

#ifndef FIPS_MODULE
EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id,
                              OSSL_LIB_CTX *libctx, const char *propq)
{
    EVP_MD_CTX *ctx;
    EVP_PKEY_CTX *pctx = NULL;

    if ((ctx = EVP_MD_CTX_new()) == NULL
        || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (id != NULL && EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0)
        goto err;

    EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
    return ctx;

 err:
    EVP_PKEY_CTX_free(pctx);
    EVP_MD_CTX_free(ctx);
    return NULL;
}
#endif

EVP_MD_CTX *EVP_MD_CTX_new(void)
{
    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}

void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
    if (ctx == NULL)
        return;

    EVP_MD_CTX_reset(ctx);
    OPENSSL_free(ctx);
}

int evp_md_ctx_free_algctx(EVP_MD_CTX *ctx)
{
    if (ctx->algctx != NULL) {
        if (!ossl_assert(ctx->digest != NULL)) {
            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
            return 0;
        }
        if (ctx->digest->freectx != NULL)
            ctx->digest->freectx(ctx->algctx);
        ctx->algctx = NULL;
    }
    return 1;
}

static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
                                const OSSL_PARAM params[], ENGINE *impl)
{
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    ENGINE *tmpimpl = NULL;
#endif

#if !defined(FIPS_MODULE)
    if (ctx->pctx != NULL
            && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
            && ctx->pctx->op.sig.algctx != NULL) {
        /*
         * Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx
         * previously initialised with EVP_DigestSignInit() would retain
         * information about the key, and re-initialise for another sign
         * operation. So in that case we redirect to EVP_DigestSignInit()
         */
        if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX)
            return EVP_DigestSignInit(ctx, NULL, type, impl, NULL);
        if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
            return EVP_DigestVerifyInit(ctx, NULL, type, impl, NULL);
        ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
        return 0;
    }
#endif

    EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);

    if (type != NULL) {
        ctx->reqdigest = type;
    } else {
        if (ctx->digest == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_NO_DIGEST_SET);
            return 0;
        }
        type = ctx->digest;
    }

    /* Code below to be removed when legacy support is dropped. */
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    /*
     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
     * this context may already have an ENGINE! Try to avoid releasing the
     * previous handle, re-querying for an ENGINE, and having a
     * reinitialisation, when it may all be unnecessary.
     */
    if (ctx->engine != NULL
            && ctx->digest != NULL
            && type->type == ctx->digest->type)
        goto skip_to_init;

    /*
     * Ensure an ENGINE left lying around from last time is cleared (the
     * previous check attempted to avoid this if the same ENGINE and
     * EVP_MD could be used).
     */
    ENGINE_finish(ctx->engine);
    ctx->engine = NULL;

    if (impl == NULL)
        tmpimpl = ENGINE_get_digest_engine(type->type);
#endif

    /*
     * If there are engines involved or EVP_MD_CTX_FLAG_NO_INIT is set then we
     * should use legacy handling for now.
     */
    if (impl != NULL
#if !defined(OPENSSL_NO_ENGINE)
            || ctx->engine != NULL
# if !defined(FIPS_MODULE)
            || tmpimpl != NULL
# endif
#endif
            || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0
            || type->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);
        ctx->fetched_digest = NULL;
        goto legacy;
    }

    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 (type->prov == NULL) {
#ifdef FIPS_MODULE
        /* We only do explicit fetches inside the FIPS module */
        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
        return 0;
#else
        /* The NULL digest is a special case */
        EVP_MD *provmd = EVP_MD_fetch(NULL,
                                      type->type != NID_undef ? OBJ_nid2sn(type->type)
                                                              : "NULL", "");

        if (provmd == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
            return 0;
        }
        type = provmd;
        EVP_MD_free(ctx->fetched_digest);
        ctx->fetched_digest = provmd;
#endif
    }

    if (type->prov != NULL && ctx->fetched_digest != type) {
        if (!EVP_MD_up_ref((EVP_MD *)type)) {
            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
            return 0;
        }
        EVP_MD_free(ctx->fetched_digest);
        ctx->fetched_digest = (EVP_MD *)type;
    }
    ctx->digest = type;
    if (ctx->algctx == NULL) {
        ctx->algctx = ctx->digest->newctx(ossl_provider_ctx(type->prov));
        if (ctx->algctx == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
            return 0;
        }
    }

    if (ctx->digest->dinit == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
        return 0;
    }

    return ctx->digest->dinit(ctx->algctx, params);

    /* Code below to be removed when legacy support is dropped. */
 legacy:

#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    if (type) {
        if (impl != NULL) {
            if (!ENGINE_init(impl)) {
                ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
                return 0;
            }
        } else {
            /* Ask if an ENGINE is reserved for this job */
            impl = tmpimpl;
        }
        if (impl != NULL) {
            /* There's an ENGINE for this job ... (apparently) */
            const EVP_MD *d = ENGINE_get_digest(impl, type->type);

            if (d == NULL) {
                ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
                ENGINE_finish(impl);
                return 0;
            }
            /* We'll use the ENGINE's private digest definition */
            type = d;
            /*
             * Store the ENGINE functional reference so we know 'type' came
             * from an ENGINE and we need to release it when done.
             */
            ctx->engine = impl;
        } else
            ctx->engine = NULL;
    }
#endif
    if (ctx->digest != type) {
        cleanup_old_md_data(ctx, 1);

        ctx->digest = type;
        if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
            ctx->update = type->update;
            ctx->md_data = OPENSSL_zalloc(type->ctx_size);
            if (ctx->md_data == NULL) {
                ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
                return 0;
            }
        }
    }
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
 skip_to_init:
#endif
#ifndef FIPS_MODULE
    if (ctx->pctx != NULL
            && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
                 || ctx->pctx->op.sig.signature == NULL)) {
        int r;
        r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
                              EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
        if (r <= 0 && (r != -2))
            return 0;
    }
#endif
    if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
        return 1;
    return ctx->digest->init(ctx);
}

int EVP_DigestInit_ex2(EVP_MD_CTX *ctx, const EVP_MD *type,
                       const OSSL_PARAM params[])
{
    return evp_md_init_internal(ctx, type, params, NULL);
}

int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
{
    EVP_MD_CTX_reset(ctx);
    return evp_md_init_internal(ctx, type, NULL, NULL);
}

int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
{
    return evp_md_init_internal(ctx, type, NULL, impl);
}

int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
    if (count == 0)
        return 1;

    if (ctx->pctx != NULL
            && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
            && ctx->pctx->op.sig.algctx != NULL) {
        /*
         * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and
         * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate().
         * Some code calls EVP_DigestUpdate() directly even when initialised
         * with EVP_DigestSignInit_ex() or
         * EVP_DigestVerifyInit_ex(), so we detect that and redirect to
         * the correct EVP_Digest*Update() function
         */
        if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX)
            return EVP_DigestSignUpdate(ctx, data, count);
        if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
            return EVP_DigestVerifyUpdate(ctx, data, count);
        ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
        return 0;
    }

    if (ctx->digest == NULL
            || ctx->digest->prov == NULL
            || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
        goto legacy;

    if (ctx->digest->dupdate == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
        return 0;
    }
    return ctx->digest->dupdate(ctx->algctx, data, count);

    /* Code below to be removed when legacy support is dropped. */
 legacy:
    return ctx->update(ctx, data, count);
}

/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
    int ret;
    ret = EVP_DigestFinal_ex(ctx, md, size);
    EVP_MD_CTX_reset(ctx);
    return ret;
}

/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
{
    int ret, sz;
    size_t size = 0;
    size_t mdsize = 0;

    if (ctx->digest == NULL)
        return 0;

    sz = EVP_MD_get_size(ctx->digest);
    if (sz < 0)
        return 0;
    mdsize = sz;
    if (ctx->digest->prov == NULL)
        goto legacy;

    if (ctx->digest->dfinal == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
        return 0;
    }

    ret = ctx->digest->dfinal(ctx->algctx, md, &size, mdsize);

    if (isize != NULL) {
        if (size <= UINT_MAX) {
            *isize = (int)size;
        } else {
            ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
            ret = 0;
        }
    }

    return ret;

    /* Code below to be removed when legacy support is dropped. */
 legacy:
    OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE);
    ret = ctx->digest->final(ctx, md);
    if (isize != NULL)
        *isize = mdsize;
    if (ctx->digest->cleanup) {
        ctx->digest->cleanup(ctx);
        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
    }
    OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
    return ret;
}

int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
{
    int ret = 0;
    OSSL_PARAM params[2];
    size_t i = 0;

    if (ctx->digest == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM);
        return 0;
    }

    if (ctx->digest->prov == NULL)
        goto legacy;

    if (ctx->digest->dfinal == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
        return 0;
    }

    params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size);
    params[i++] = OSSL_PARAM_construct_end();

    if (EVP_MD_CTX_set_params(ctx, params) > 0)
        ret = ctx->digest->dfinal(ctx->algctx, md, &size, size);

    return ret;

legacy:
    if (ctx->digest->flags & EVP_MD_FLAG_XOF
        && size <= INT_MAX
        && ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) {
        ret = ctx->digest->final(ctx, md);
        if (ctx->digest->cleanup != NULL) {
            ctx->digest->cleanup(ctx);
            EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
        }
        OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
    } else {
        ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
    }

    return ret;
}

EVP_MD_CTX *EVP_MD_CTX_dup(const EVP_MD_CTX *in)
{
    EVP_MD_CTX *out = EVP_MD_CTX_new();

    if (out != NULL && !EVP_MD_CTX_copy_ex(out, in)) {
        EVP_MD_CTX_free(out);
        out = NULL;
    }
    return out;
}

int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
{
    EVP_MD_CTX_reset(out);
    return EVP_MD_CTX_copy_ex(out, in);
}

int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
{
    int digest_change = 0;
    unsigned char *tmp_buf;

    if (in == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (in->digest == NULL) {
        /* copying uninitialized digest context */
        EVP_MD_CTX_reset(out);
        if (out->fetched_digest != NULL)
            EVP_MD_free(out->fetched_digest);
        *out = *in;
        goto clone_pkey;
    }

    if (in->digest->prov == NULL
            || (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
        goto legacy;

    if (in->digest->dupctx == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
        return 0;
    }

    evp_md_ctx_reset_ex(out, 1);
    digest_change = (out->fetched_digest != in->fetched_digest);
    if (digest_change && out->fetched_digest != NULL)
        EVP_MD_free(out->fetched_digest);
    *out = *in;
    /* NULL out pointers in case of error */
    out->pctx = NULL;
    out->algctx = NULL;

    if (digest_change && in->fetched_digest != NULL)
        EVP_MD_up_ref(in->fetched_digest);

    if (in->algctx != NULL) {
        out->algctx = in->digest->dupctx(in->algctx);
        if (out->algctx == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
            return 0;
        }
    }

 clone_pkey:
    /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
    EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
#ifndef FIPS_MODULE
    if (in->pctx != NULL) {
        out->pctx = EVP_PKEY_CTX_dup(in->pctx);
        if (out->pctx == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
            EVP_MD_CTX_reset(out);
            return 0;
        }
    }
#endif

    return 1;

    /* Code below to be removed when legacy support is dropped. */
 legacy:
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    /* Make sure it's safe to copy a digest context using an ENGINE */
    if (in->engine && !ENGINE_init(in->engine)) {
        ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB);
        return 0;
    }
#endif

    if (out->digest == in->digest) {
        tmp_buf = out->md_data;
        EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
    } else
        tmp_buf = NULL;
    EVP_MD_CTX_reset(out);
    memcpy(out, in, sizeof(*out));

    /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
    EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);

    /* Null these variables, since they are getting fixed up
     * properly below.  Anything else may cause a memleak and/or
     * double free if any of the memory allocations below fail
     */
    out->md_data = NULL;
    out->pctx = NULL;

    if (in->md_data && out->digest->ctx_size) {
        if (tmp_buf)
            out->md_data = tmp_buf;
        else {
            out->md_data = OPENSSL_malloc(out->digest->ctx_size);
            if (out->md_data == NULL) {
                ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
                return 0;
            }
        }
        memcpy(out->md_data, in->md_data, out->digest->ctx_size);
    }

    out->update = in->update;

#ifndef FIPS_MODULE
    if (in->pctx) {
        out->pctx = EVP_PKEY_CTX_dup(in->pctx);
        if (!out->pctx) {
            EVP_MD_CTX_reset(out);
            return 0;
        }
    }
#endif

    if (out->digest->copy)
        return out->digest->copy(out, in);

    return 1;
}

int EVP_Digest(const void *data, size_t count,
               unsigned char *md, unsigned int *size, const EVP_MD *type,
               ENGINE *impl)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    int ret;

    if (ctx == NULL)
        return 0;
    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
    ret = EVP_DigestInit_ex(ctx, type, impl)
        && EVP_DigestUpdate(ctx, data, count)
        && EVP_DigestFinal_ex(ctx, md, size);
    EVP_MD_CTX_free(ctx);

    return ret;
}

int EVP_Q_digest(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
                 const void *data, size_t datalen,
                 unsigned char *md, size_t *mdlen)
{
    EVP_MD *digest = EVP_MD_fetch(libctx, name, propq);
    unsigned int temp = 0;
    int ret = 0;

    if (digest != NULL) {
        ret = EVP_Digest(data, datalen, md, &temp, digest, NULL);
        EVP_MD_free(digest);
    }
    if (mdlen != NULL)
        *mdlen = temp;
    return ret;
}

int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[])
{
    if (digest != NULL && digest->get_params != NULL)
        return digest->get_params(params);
    return 0;
}

const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest)
{
    if (digest != NULL && digest->gettable_params != NULL)
        return digest->gettable_params(
                           ossl_provider_ctx(EVP_MD_get0_provider(digest)));
    return NULL;
}

int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
{
    EVP_PKEY_CTX *pctx = ctx->pctx;

    /* If we have a pctx then we should try that first */
    if (pctx != NULL
            && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                || pctx->operation == EVP_PKEY_OP_SIGNCTX)
            && pctx->op.sig.algctx != NULL
            && pctx->op.sig.signature->set_ctx_md_params != NULL)
        return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.algctx,
                                                         params);

    if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL)
        return ctx->digest->set_ctx_params(ctx->algctx, params);

    return 0;
}

const OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md)
{
    void *provctx;

    if (md != NULL && md->settable_ctx_params != NULL) {
        provctx = ossl_provider_ctx(EVP_MD_get0_provider(md));
        return md->settable_ctx_params(NULL, provctx);
    }
    return NULL;
}

const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx)
{
    EVP_PKEY_CTX *pctx;
    void *alg;

    if (ctx == NULL)
        return NULL;

    /* If we have a pctx then we should try that first */
    pctx = ctx->pctx;
    if (pctx != NULL
            && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                || pctx->operation == EVP_PKEY_OP_SIGNCTX)
            && pctx->op.sig.algctx != NULL
            && pctx->op.sig.signature->settable_ctx_md_params != NULL)
        return pctx->op.sig.signature->settable_ctx_md_params(
                   pctx->op.sig.algctx);

    if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL) {
        alg = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest));
        return ctx->digest->settable_ctx_params(ctx->algctx, alg);
    }

    return NULL;
}

int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
{
    EVP_PKEY_CTX *pctx = ctx->pctx;

    /* If we have a pctx then we should try that first */
    if (pctx != NULL
            && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                || pctx->operation == EVP_PKEY_OP_SIGNCTX)
            && pctx->op.sig.algctx != NULL
            && pctx->op.sig.signature->get_ctx_md_params != NULL)
        return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.algctx,
                                                         params);

    if (ctx->digest != NULL && ctx->digest->get_params != NULL)
        return ctx->digest->get_ctx_params(ctx->algctx, params);

    return 0;
}

const OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md)
{
    void *provctx;

    if (md != NULL && md->gettable_ctx_params != NULL) {
        provctx = ossl_provider_ctx(EVP_MD_get0_provider(md));
        return md->gettable_ctx_params(NULL, provctx);
    }
    return NULL;
}

const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx)
{
    EVP_PKEY_CTX *pctx;
    void *provctx;

    if (ctx == NULL)
        return NULL;

    /* If we have a pctx then we should try that first */
    pctx = ctx->pctx;
    if (pctx != NULL
            && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                || pctx->operation == EVP_PKEY_OP_SIGNCTX)
            && pctx->op.sig.algctx != NULL
            && pctx->op.sig.signature->gettable_ctx_md_params != NULL)
        return pctx->op.sig.signature->gettable_ctx_md_params(
                    pctx->op.sig.algctx);

    if (ctx->digest != NULL && ctx->digest->gettable_ctx_params != NULL) {
        provctx = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest));
        return ctx->digest->gettable_ctx_params(ctx->algctx, provctx);
    }
    return NULL;
}

int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
{
    int ret = EVP_CTRL_RET_UNSUPPORTED;
    int set_params = 1;
    size_t sz;
    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };

    if (ctx == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ctx->digest != NULL && ctx->digest->prov == NULL)
        goto legacy;

    switch (cmd) {
    case EVP_MD_CTRL_XOF_LEN:
        sz = (size_t)p1;
        params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
        break;
    case EVP_MD_CTRL_MICALG:
        set_params = 0;
        params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG,
                                                     p2, p1 ? p1 : 9999);
        break;
    case EVP_CTRL_SSL3_MASTER_SECRET:
        params[0] = OSSL_PARAM_construct_octet_string(OSSL_DIGEST_PARAM_SSL3_MS,
                                                      p2, p1);
        break;
    default:
        goto conclude;
    }

    if (set_params)
        ret = EVP_MD_CTX_set_params(ctx, params);
    else
        ret = EVP_MD_CTX_get_params(ctx, params);
    goto conclude;


    /* Code below to be removed when legacy support is dropped. */
 legacy:
    if (ctx->digest->md_ctrl == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED);
        return 0;
    }

    ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
 conclude:
    if (ret <= 0)
        return 0;
    return ret;
}

EVP_MD *evp_md_new(void)
{
    EVP_MD *md = OPENSSL_zalloc(sizeof(*md));

    if (md != NULL) {
        md->lock = CRYPTO_THREAD_lock_new();
        if (md->lock == NULL) {
            OPENSSL_free(md);
            return NULL;
        }
        md->refcnt = 1;
    }
    return md;
}

/*
 * FIPS module note: since internal fetches will be entirely
 * provider based, we know that none of its code depends on legacy
 * NIDs or any functionality that use them.
 */
#ifndef FIPS_MODULE
static void set_legacy_nid(const char *name, void *vlegacy_nid)
{
    int nid;
    int *legacy_nid = vlegacy_nid;
    /*
     * We use lowest level function to get the associated method, because
     * higher level functions such as EVP_get_digestbyname() have changed
     * to look at providers too.
     */
    const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);

    if (*legacy_nid == -1)       /* We found a clash already */
        return;

    if (legacy_method == NULL)
        return;
    nid = EVP_MD_nid(legacy_method);
    if (*legacy_nid != NID_undef && *legacy_nid != nid) {
        *legacy_nid = -1;
        return;
    }
    *legacy_nid = nid;
}
#endif

static int evp_md_cache_constants(EVP_MD *md)
{
    int ok, xof = 0, algid_absent = 0;
    size_t blksz = 0;
    size_t mdsize = 0;
    OSSL_PARAM params[5];

    params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &blksz);
    params[1] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &mdsize);
    params[2] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_XOF, &xof);
    params[3] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_ALGID_ABSENT,
                                         &algid_absent);
    params[4] = OSSL_PARAM_construct_end();
    ok = evp_do_md_getparams(md, params) > 0;
    if (mdsize > INT_MAX || blksz > INT_MAX)
        ok = 0;
    if (ok) {
        md->block_size = (int)blksz;
        md->md_size = (int)mdsize;
        if (xof)
            md->flags |= EVP_MD_FLAG_XOF;
        if (algid_absent)
            md->flags |= EVP_MD_FLAG_DIGALGID_ABSENT;
    }
    return ok;
}

static void *evp_md_from_algorithm(int name_id,
                                   const OSSL_ALGORITHM *algodef,
                                   OSSL_PROVIDER *prov)
{
    const OSSL_DISPATCH *fns = algodef->implementation;
    EVP_MD *md = NULL;
    int fncnt = 0;

    /* EVP_MD_fetch() will set the legacy NID if available */
    if ((md = evp_md_new()) == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

#ifndef FIPS_MODULE
    md->type = NID_undef;
    if (!evp_names_do_all(prov, name_id, set_legacy_nid, &md->type)
            || md->type == -1) {
        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
        EVP_MD_free(md);
        return NULL;
    }
#endif

    md->name_id = name_id;
    if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
        EVP_MD_free(md);
        return NULL;
    }
    md->description = algodef->algorithm_description;

    for (; fns->function_id != 0; fns++) {
        switch (fns->function_id) {
        case OSSL_FUNC_DIGEST_NEWCTX:
            if (md->newctx == NULL) {
                md->newctx = OSSL_FUNC_digest_newctx(fns);
                fncnt++;
            }
            break;
        case OSSL_FUNC_DIGEST_INIT:
            if (md->dinit == NULL) {
                md->dinit = OSSL_FUNC_digest_init(fns);
                fncnt++;
            }
            break;
        case OSSL_FUNC_DIGEST_UPDATE:
            if (md->dupdate == NULL) {
                md->dupdate = OSSL_FUNC_digest_update(fns);
                fncnt++;
            }
            break;
        case OSSL_FUNC_DIGEST_FINAL:
            if (md->dfinal == NULL) {
                md->dfinal = OSSL_FUNC_digest_final(fns);
                fncnt++;
            }
            break;
        case OSSL_FUNC_DIGEST_DIGEST:
            if (md->digest == NULL)
                md->digest = OSSL_FUNC_digest_digest(fns);
            /* We don't increment fnct for this as it is stand alone */
            break;
        case OSSL_FUNC_DIGEST_FREECTX:
            if (md->freectx == NULL) {
                md->freectx = OSSL_FUNC_digest_freectx(fns);
                fncnt++;
            }
            break;
        case OSSL_FUNC_DIGEST_DUPCTX:
            if (md->dupctx == NULL)
                md->dupctx = OSSL_FUNC_digest_dupctx(fns);
            break;
        case OSSL_FUNC_DIGEST_GET_PARAMS:
            if (md->get_params == NULL)
                md->get_params = OSSL_FUNC_digest_get_params(fns);
            break;
        case OSSL_FUNC_DIGEST_SET_CTX_PARAMS:
            if (md->set_ctx_params == NULL)
                md->set_ctx_params = OSSL_FUNC_digest_set_ctx_params(fns);
            break;
        case OSSL_FUNC_DIGEST_GET_CTX_PARAMS:
            if (md->get_ctx_params == NULL)
                md->get_ctx_params = OSSL_FUNC_digest_get_ctx_params(fns);
            break;
        case OSSL_FUNC_DIGEST_GETTABLE_PARAMS:
            if (md->gettable_params == NULL)
                md->gettable_params = OSSL_FUNC_digest_gettable_params(fns);
            break;
        case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS:
            if (md->settable_ctx_params == NULL)
                md->settable_ctx_params =
                    OSSL_FUNC_digest_settable_ctx_params(fns);
            break;
        case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS:
            if (md->gettable_ctx_params == NULL)
                md->gettable_ctx_params =
                    OSSL_FUNC_digest_gettable_ctx_params(fns);
            break;
        }
    }
    if ((fncnt != 0 && fncnt != 5)
        || (fncnt == 0 && md->digest == NULL)) {
        /*
         * In order to be a consistent set of functions we either need the
         * whole set of init/update/final etc functions or none of them.
         * The "digest" function can standalone. We at least need one way to
         * generate digests.
         */
        EVP_MD_free(md);
        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
        return NULL;
    }
    md->prov = prov;
    if (prov != NULL)
        ossl_provider_up_ref(prov);

    if (!evp_md_cache_constants(md)) {
        EVP_MD_free(md);
        ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
        md = NULL;
    }

    return md;
}

static int evp_md_up_ref(void *md)
{
    return EVP_MD_up_ref(md);
}

static void evp_md_free(void *md)
{
    EVP_MD_free(md);
}

EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                     const char *properties)
{
    EVP_MD *md =
        evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
                          evp_md_from_algorithm, evp_md_up_ref, evp_md_free);

    return md;
}

int EVP_MD_up_ref(EVP_MD *md)
{
    int ref = 0;

    if (md->origin == EVP_ORIG_DYNAMIC)
        CRYPTO_UP_REF(&md->refcnt, &ref, md->lock);
    return 1;
}

void EVP_MD_free(EVP_MD *md)
{
    int i;

    if (md == NULL || md->origin != EVP_ORIG_DYNAMIC)
        return;

    CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock);
    if (i > 0)
        return;
    evp_md_free_int(md);
}

void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx,
                            void (*fn)(EVP_MD *mac, void *arg),
                            void *arg)
{
    evp_generic_do_all(libctx, OSSL_OP_DIGEST,
                       (void (*)(void *, void *))fn, arg,
                       evp_md_from_algorithm, evp_md_up_ref, evp_md_free);
}
