1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* We need to use some engine deprecated APIs */ 11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci#include <stdio.h> 14e1051a39Sopenharmony_ci#include <openssl/objects.h> 15e1051a39Sopenharmony_ci#include <openssl/evp.h> 16e1051a39Sopenharmony_ci#include <openssl/ec.h> 17e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 18e1051a39Sopenharmony_ci# include <openssl/engine.h> 19e1051a39Sopenharmony_ci#endif 20e1051a39Sopenharmony_ci#include <openssl/params.h> 21e1051a39Sopenharmony_ci#include <openssl/core_names.h> 22e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 23e1051a39Sopenharmony_ci#include "internal/provider.h" 24e1051a39Sopenharmony_ci#include "internal/core.h" 25e1051a39Sopenharmony_ci#include "crypto/evp.h" 26e1051a39Sopenharmony_ci#include "evp_local.h" 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_cistatic void cleanup_old_md_data(EVP_MD_CTX *ctx, int force) 29e1051a39Sopenharmony_ci{ 30e1051a39Sopenharmony_ci if (ctx->digest != NULL) { 31e1051a39Sopenharmony_ci if (ctx->digest->cleanup != NULL 32e1051a39Sopenharmony_ci && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) 33e1051a39Sopenharmony_ci ctx->digest->cleanup(ctx); 34e1051a39Sopenharmony_ci if (ctx->md_data != NULL && ctx->digest->ctx_size > 0 35e1051a39Sopenharmony_ci && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) 36e1051a39Sopenharmony_ci || force)) { 37e1051a39Sopenharmony_ci OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); 38e1051a39Sopenharmony_ci ctx->md_data = NULL; 39e1051a39Sopenharmony_ci } 40e1051a39Sopenharmony_ci } 41e1051a39Sopenharmony_ci} 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_civoid evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force, int keep_fetched) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci if (ctx->algctx != NULL) { 46e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->freectx != NULL) 47e1051a39Sopenharmony_ci ctx->digest->freectx(ctx->algctx); 48e1051a39Sopenharmony_ci ctx->algctx = NULL; 49e1051a39Sopenharmony_ci EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 50e1051a39Sopenharmony_ci } 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci /* 55e1051a39Sopenharmony_ci * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because 56e1051a39Sopenharmony_ci * sometimes only copies of the context are ever finalised. 57e1051a39Sopenharmony_ci */ 58e1051a39Sopenharmony_ci cleanup_old_md_data(ctx, force); 59e1051a39Sopenharmony_ci if (force) 60e1051a39Sopenharmony_ci ctx->digest = NULL; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) 63e1051a39Sopenharmony_ci ENGINE_finish(ctx->engine); 64e1051a39Sopenharmony_ci ctx->engine = NULL; 65e1051a39Sopenharmony_ci#endif 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci /* Non legacy code, this has to be later than the ctx->digest cleaning */ 68e1051a39Sopenharmony_ci if (!keep_fetched) { 69e1051a39Sopenharmony_ci EVP_MD_free(ctx->fetched_digest); 70e1051a39Sopenharmony_ci ctx->fetched_digest = NULL; 71e1051a39Sopenharmony_ci ctx->reqdigest = NULL; 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_cistatic int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci if (ctx == NULL) 78e1051a39Sopenharmony_ci return 1; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 81e1051a39Sopenharmony_ci /* 82e1051a39Sopenharmony_ci * pctx should be freed by the user of EVP_MD_CTX 83e1051a39Sopenharmony_ci * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set 84e1051a39Sopenharmony_ci */ 85e1051a39Sopenharmony_ci if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { 86e1051a39Sopenharmony_ci EVP_PKEY_CTX_free(ctx->pctx); 87e1051a39Sopenharmony_ci ctx->pctx = NULL; 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci#endif 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci evp_md_ctx_clear_digest(ctx, 0, keep_fetched); 92e1051a39Sopenharmony_ci if (!keep_fetched) 93e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx, sizeof(*ctx)); 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ci return 1; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci/* This call frees resources associated with the context */ 99e1051a39Sopenharmony_ciint EVP_MD_CTX_reset(EVP_MD_CTX *ctx) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci return evp_md_ctx_reset_ex(ctx, 0); 102e1051a39Sopenharmony_ci} 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 105e1051a39Sopenharmony_ciEVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, 106e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 107e1051a39Sopenharmony_ci{ 108e1051a39Sopenharmony_ci EVP_MD_CTX *ctx; 109e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = NULL; 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci if ((ctx = EVP_MD_CTX_new()) == NULL 112e1051a39Sopenharmony_ci || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) { 113e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 114e1051a39Sopenharmony_ci goto err; 115e1051a39Sopenharmony_ci } 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci if (id != NULL && EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) 118e1051a39Sopenharmony_ci goto err; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci EVP_MD_CTX_set_pkey_ctx(ctx, pctx); 121e1051a39Sopenharmony_ci return ctx; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci err: 124e1051a39Sopenharmony_ci EVP_PKEY_CTX_free(pctx); 125e1051a39Sopenharmony_ci EVP_MD_CTX_free(ctx); 126e1051a39Sopenharmony_ci return NULL; 127e1051a39Sopenharmony_ci} 128e1051a39Sopenharmony_ci#endif 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ciEVP_MD_CTX *EVP_MD_CTX_new(void) 131e1051a39Sopenharmony_ci{ 132e1051a39Sopenharmony_ci return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); 133e1051a39Sopenharmony_ci} 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_civoid EVP_MD_CTX_free(EVP_MD_CTX *ctx) 136e1051a39Sopenharmony_ci{ 137e1051a39Sopenharmony_ci if (ctx == NULL) 138e1051a39Sopenharmony_ci return; 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ci EVP_MD_CTX_reset(ctx); 141e1051a39Sopenharmony_ci OPENSSL_free(ctx); 142e1051a39Sopenharmony_ci} 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_cistatic int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, 145e1051a39Sopenharmony_ci const OSSL_PARAM params[], ENGINE *impl) 146e1051a39Sopenharmony_ci{ 147e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 148e1051a39Sopenharmony_ci ENGINE *tmpimpl = NULL; 149e1051a39Sopenharmony_ci#endif 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ci#if !defined(FIPS_MODULE) 152e1051a39Sopenharmony_ci if (ctx->pctx != NULL 153e1051a39Sopenharmony_ci && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) 154e1051a39Sopenharmony_ci && ctx->pctx->op.sig.algctx != NULL) { 155e1051a39Sopenharmony_ci /* 156e1051a39Sopenharmony_ci * Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx 157e1051a39Sopenharmony_ci * previously initialised with EVP_DigestSignInit() would retain 158e1051a39Sopenharmony_ci * information about the key, and re-initialise for another sign 159e1051a39Sopenharmony_ci * operation. So in that case we redirect to EVP_DigestSignInit() 160e1051a39Sopenharmony_ci */ 161e1051a39Sopenharmony_ci if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) 162e1051a39Sopenharmony_ci return EVP_DigestSignInit(ctx, NULL, type, impl, NULL); 163e1051a39Sopenharmony_ci if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX) 164e1051a39Sopenharmony_ci return EVP_DigestVerifyInit(ctx, NULL, type, impl, NULL); 165e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); 166e1051a39Sopenharmony_ci return 0; 167e1051a39Sopenharmony_ci } 168e1051a39Sopenharmony_ci#endif 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci if (ctx->algctx != NULL) { 173e1051a39Sopenharmony_ci if (!ossl_assert(ctx->digest != NULL)) { 174e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 175e1051a39Sopenharmony_ci return 0; 176e1051a39Sopenharmony_ci } 177e1051a39Sopenharmony_ci if (ctx->digest->freectx != NULL) 178e1051a39Sopenharmony_ci ctx->digest->freectx(ctx->algctx); 179e1051a39Sopenharmony_ci ctx->algctx = NULL; 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci if (type != NULL) { 183e1051a39Sopenharmony_ci ctx->reqdigest = type; 184e1051a39Sopenharmony_ci } else { 185e1051a39Sopenharmony_ci if (ctx->digest == NULL) { 186e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_NO_DIGEST_SET); 187e1051a39Sopenharmony_ci return 0; 188e1051a39Sopenharmony_ci } 189e1051a39Sopenharmony_ci type = ctx->digest; 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 193e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 194e1051a39Sopenharmony_ci /* 195e1051a39Sopenharmony_ci * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so 196e1051a39Sopenharmony_ci * this context may already have an ENGINE! Try to avoid releasing the 197e1051a39Sopenharmony_ci * previous handle, re-querying for an ENGINE, and having a 198e1051a39Sopenharmony_ci * reinitialisation, when it may all be unnecessary. 199e1051a39Sopenharmony_ci */ 200e1051a39Sopenharmony_ci if (ctx->engine && ctx->digest && 201e1051a39Sopenharmony_ci (type == NULL || (type->type == ctx->digest->type))) 202e1051a39Sopenharmony_ci goto skip_to_init; 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ci if (type != NULL) { 205e1051a39Sopenharmony_ci /* 206e1051a39Sopenharmony_ci * Ensure an ENGINE left lying around from last time is cleared (the 207e1051a39Sopenharmony_ci * previous check attempted to avoid this if the same ENGINE and 208e1051a39Sopenharmony_ci * EVP_MD could be used). 209e1051a39Sopenharmony_ci */ 210e1051a39Sopenharmony_ci ENGINE_finish(ctx->engine); 211e1051a39Sopenharmony_ci ctx->engine = NULL; 212e1051a39Sopenharmony_ci } 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci if (type != NULL && impl == NULL) 215e1051a39Sopenharmony_ci tmpimpl = ENGINE_get_digest_engine(type->type); 216e1051a39Sopenharmony_ci#endif 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci /* 219e1051a39Sopenharmony_ci * If there are engines involved or EVP_MD_CTX_FLAG_NO_INIT is set then we 220e1051a39Sopenharmony_ci * should use legacy handling for now. 221e1051a39Sopenharmony_ci */ 222e1051a39Sopenharmony_ci if (ctx->engine != NULL 223e1051a39Sopenharmony_ci || impl != NULL 224e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 225e1051a39Sopenharmony_ci || tmpimpl != NULL 226e1051a39Sopenharmony_ci#endif 227e1051a39Sopenharmony_ci || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0 228e1051a39Sopenharmony_ci || (type != NULL && type->origin == EVP_ORIG_METH) 229e1051a39Sopenharmony_ci || (type == NULL && ctx->digest != NULL 230e1051a39Sopenharmony_ci && ctx->digest->origin == EVP_ORIG_METH)) { 231e1051a39Sopenharmony_ci if (ctx->digest == ctx->fetched_digest) 232e1051a39Sopenharmony_ci ctx->digest = NULL; 233e1051a39Sopenharmony_ci EVP_MD_free(ctx->fetched_digest); 234e1051a39Sopenharmony_ci ctx->fetched_digest = NULL; 235e1051a39Sopenharmony_ci goto legacy; 236e1051a39Sopenharmony_ci } 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci cleanup_old_md_data(ctx, 1); 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci /* Start of non-legacy code below */ 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci if (type->prov == NULL) { 243e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 244e1051a39Sopenharmony_ci /* We only do explicit fetches inside the FIPS module */ 245e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 246e1051a39Sopenharmony_ci return 0; 247e1051a39Sopenharmony_ci#else 248e1051a39Sopenharmony_ci /* The NULL digest is a special case */ 249e1051a39Sopenharmony_ci EVP_MD *provmd = EVP_MD_fetch(NULL, 250e1051a39Sopenharmony_ci type->type != NID_undef ? OBJ_nid2sn(type->type) 251e1051a39Sopenharmony_ci : "NULL", ""); 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci if (provmd == NULL) { 254e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 255e1051a39Sopenharmony_ci return 0; 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci type = provmd; 258e1051a39Sopenharmony_ci EVP_MD_free(ctx->fetched_digest); 259e1051a39Sopenharmony_ci ctx->fetched_digest = provmd; 260e1051a39Sopenharmony_ci#endif 261e1051a39Sopenharmony_ci } 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci if (ctx->algctx != NULL && ctx->digest != NULL && ctx->digest != type) { 264e1051a39Sopenharmony_ci if (ctx->digest->freectx != NULL) 265e1051a39Sopenharmony_ci ctx->digest->freectx(ctx->algctx); 266e1051a39Sopenharmony_ci ctx->algctx = NULL; 267e1051a39Sopenharmony_ci } 268e1051a39Sopenharmony_ci if (type->prov != NULL && ctx->fetched_digest != type) { 269e1051a39Sopenharmony_ci if (!EVP_MD_up_ref((EVP_MD *)type)) { 270e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 271e1051a39Sopenharmony_ci return 0; 272e1051a39Sopenharmony_ci } 273e1051a39Sopenharmony_ci EVP_MD_free(ctx->fetched_digest); 274e1051a39Sopenharmony_ci ctx->fetched_digest = (EVP_MD *)type; 275e1051a39Sopenharmony_ci } 276e1051a39Sopenharmony_ci ctx->digest = type; 277e1051a39Sopenharmony_ci if (ctx->algctx == NULL) { 278e1051a39Sopenharmony_ci ctx->algctx = ctx->digest->newctx(ossl_provider_ctx(type->prov)); 279e1051a39Sopenharmony_ci if (ctx->algctx == NULL) { 280e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 281e1051a39Sopenharmony_ci return 0; 282e1051a39Sopenharmony_ci } 283e1051a39Sopenharmony_ci } 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci if (ctx->digest->dinit == NULL) { 286e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 287e1051a39Sopenharmony_ci return 0; 288e1051a39Sopenharmony_ci } 289e1051a39Sopenharmony_ci 290e1051a39Sopenharmony_ci return ctx->digest->dinit(ctx->algctx, params); 291e1051a39Sopenharmony_ci 292e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 293e1051a39Sopenharmony_ci legacy: 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 296e1051a39Sopenharmony_ci if (type) { 297e1051a39Sopenharmony_ci if (impl != NULL) { 298e1051a39Sopenharmony_ci if (!ENGINE_init(impl)) { 299e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 300e1051a39Sopenharmony_ci return 0; 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci } else { 303e1051a39Sopenharmony_ci /* Ask if an ENGINE is reserved for this job */ 304e1051a39Sopenharmony_ci impl = tmpimpl; 305e1051a39Sopenharmony_ci } 306e1051a39Sopenharmony_ci if (impl != NULL) { 307e1051a39Sopenharmony_ci /* There's an ENGINE for this job ... (apparently) */ 308e1051a39Sopenharmony_ci const EVP_MD *d = ENGINE_get_digest(impl, type->type); 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci if (d == NULL) { 311e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); 312e1051a39Sopenharmony_ci ENGINE_finish(impl); 313e1051a39Sopenharmony_ci return 0; 314e1051a39Sopenharmony_ci } 315e1051a39Sopenharmony_ci /* We'll use the ENGINE's private digest definition */ 316e1051a39Sopenharmony_ci type = d; 317e1051a39Sopenharmony_ci /* 318e1051a39Sopenharmony_ci * Store the ENGINE functional reference so we know 'type' came 319e1051a39Sopenharmony_ci * from an ENGINE and we need to release it when done. 320e1051a39Sopenharmony_ci */ 321e1051a39Sopenharmony_ci ctx->engine = impl; 322e1051a39Sopenharmony_ci } else 323e1051a39Sopenharmony_ci ctx->engine = NULL; 324e1051a39Sopenharmony_ci } 325e1051a39Sopenharmony_ci#endif 326e1051a39Sopenharmony_ci if (ctx->digest != type) { 327e1051a39Sopenharmony_ci cleanup_old_md_data(ctx, 1); 328e1051a39Sopenharmony_ci 329e1051a39Sopenharmony_ci ctx->digest = type; 330e1051a39Sopenharmony_ci if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { 331e1051a39Sopenharmony_ci ctx->update = type->update; 332e1051a39Sopenharmony_ci ctx->md_data = OPENSSL_zalloc(type->ctx_size); 333e1051a39Sopenharmony_ci if (ctx->md_data == NULL) { 334e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 335e1051a39Sopenharmony_ci return 0; 336e1051a39Sopenharmony_ci } 337e1051a39Sopenharmony_ci } 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 340e1051a39Sopenharmony_ci skip_to_init: 341e1051a39Sopenharmony_ci#endif 342e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 343e1051a39Sopenharmony_ci if (ctx->pctx != NULL 344e1051a39Sopenharmony_ci && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) 345e1051a39Sopenharmony_ci || ctx->pctx->op.sig.signature == NULL)) { 346e1051a39Sopenharmony_ci int r; 347e1051a39Sopenharmony_ci r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, 348e1051a39Sopenharmony_ci EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); 349e1051a39Sopenharmony_ci if (r <= 0 && (r != -2)) 350e1051a39Sopenharmony_ci return 0; 351e1051a39Sopenharmony_ci } 352e1051a39Sopenharmony_ci#endif 353e1051a39Sopenharmony_ci if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) 354e1051a39Sopenharmony_ci return 1; 355e1051a39Sopenharmony_ci return ctx->digest->init(ctx); 356e1051a39Sopenharmony_ci} 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ciint EVP_DigestInit_ex2(EVP_MD_CTX *ctx, const EVP_MD *type, 359e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 360e1051a39Sopenharmony_ci{ 361e1051a39Sopenharmony_ci return evp_md_init_internal(ctx, type, params, NULL); 362e1051a39Sopenharmony_ci} 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ciint EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) 365e1051a39Sopenharmony_ci{ 366e1051a39Sopenharmony_ci EVP_MD_CTX_reset(ctx); 367e1051a39Sopenharmony_ci return evp_md_init_internal(ctx, type, NULL, NULL); 368e1051a39Sopenharmony_ci} 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ciint EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) 371e1051a39Sopenharmony_ci{ 372e1051a39Sopenharmony_ci return evp_md_init_internal(ctx, type, NULL, impl); 373e1051a39Sopenharmony_ci} 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ciint EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) 376e1051a39Sopenharmony_ci{ 377e1051a39Sopenharmony_ci if (count == 0) 378e1051a39Sopenharmony_ci return 1; 379e1051a39Sopenharmony_ci 380e1051a39Sopenharmony_ci if (ctx->pctx != NULL 381e1051a39Sopenharmony_ci && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) 382e1051a39Sopenharmony_ci && ctx->pctx->op.sig.algctx != NULL) { 383e1051a39Sopenharmony_ci /* 384e1051a39Sopenharmony_ci * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and 385e1051a39Sopenharmony_ci * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate(). 386e1051a39Sopenharmony_ci * Some code calls EVP_DigestUpdate() directly even when initialised 387e1051a39Sopenharmony_ci * with EVP_DigestSignInit_ex() or 388e1051a39Sopenharmony_ci * EVP_DigestVerifyInit_ex(), so we detect that and redirect to 389e1051a39Sopenharmony_ci * the correct EVP_Digest*Update() function 390e1051a39Sopenharmony_ci */ 391e1051a39Sopenharmony_ci if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) 392e1051a39Sopenharmony_ci return EVP_DigestSignUpdate(ctx, data, count); 393e1051a39Sopenharmony_ci if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX) 394e1051a39Sopenharmony_ci return EVP_DigestVerifyUpdate(ctx, data, count); 395e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); 396e1051a39Sopenharmony_ci return 0; 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci if (ctx->digest == NULL 400e1051a39Sopenharmony_ci || ctx->digest->prov == NULL 401e1051a39Sopenharmony_ci || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) 402e1051a39Sopenharmony_ci goto legacy; 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci if (ctx->digest->dupdate == NULL) { 405e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); 406e1051a39Sopenharmony_ci return 0; 407e1051a39Sopenharmony_ci } 408e1051a39Sopenharmony_ci return ctx->digest->dupdate(ctx->algctx, data, count); 409e1051a39Sopenharmony_ci 410e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 411e1051a39Sopenharmony_ci legacy: 412e1051a39Sopenharmony_ci return ctx->update(ctx, data, count); 413e1051a39Sopenharmony_ci} 414e1051a39Sopenharmony_ci 415e1051a39Sopenharmony_ci/* The caller can assume that this removes any secret data from the context */ 416e1051a39Sopenharmony_ciint EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 417e1051a39Sopenharmony_ci{ 418e1051a39Sopenharmony_ci int ret; 419e1051a39Sopenharmony_ci ret = EVP_DigestFinal_ex(ctx, md, size); 420e1051a39Sopenharmony_ci EVP_MD_CTX_reset(ctx); 421e1051a39Sopenharmony_ci return ret; 422e1051a39Sopenharmony_ci} 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci/* The caller can assume that this removes any secret data from the context */ 425e1051a39Sopenharmony_ciint EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) 426e1051a39Sopenharmony_ci{ 427e1051a39Sopenharmony_ci int ret, sz; 428e1051a39Sopenharmony_ci size_t size = 0; 429e1051a39Sopenharmony_ci size_t mdsize = 0; 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci if (ctx->digest == NULL) 432e1051a39Sopenharmony_ci return 0; 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci sz = EVP_MD_get_size(ctx->digest); 435e1051a39Sopenharmony_ci if (sz < 0) 436e1051a39Sopenharmony_ci return 0; 437e1051a39Sopenharmony_ci mdsize = sz; 438e1051a39Sopenharmony_ci if (ctx->digest->prov == NULL) 439e1051a39Sopenharmony_ci goto legacy; 440e1051a39Sopenharmony_ci 441e1051a39Sopenharmony_ci if (ctx->digest->dfinal == NULL) { 442e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); 443e1051a39Sopenharmony_ci return 0; 444e1051a39Sopenharmony_ci } 445e1051a39Sopenharmony_ci 446e1051a39Sopenharmony_ci ret = ctx->digest->dfinal(ctx->algctx, md, &size, mdsize); 447e1051a39Sopenharmony_ci 448e1051a39Sopenharmony_ci if (isize != NULL) { 449e1051a39Sopenharmony_ci if (size <= UINT_MAX) { 450e1051a39Sopenharmony_ci *isize = (unsigned int)size; 451e1051a39Sopenharmony_ci } else { 452e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); 453e1051a39Sopenharmony_ci ret = 0; 454e1051a39Sopenharmony_ci } 455e1051a39Sopenharmony_ci } 456e1051a39Sopenharmony_ci 457e1051a39Sopenharmony_ci return ret; 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 460e1051a39Sopenharmony_ci legacy: 461e1051a39Sopenharmony_ci OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE); 462e1051a39Sopenharmony_ci ret = ctx->digest->final(ctx, md); 463e1051a39Sopenharmony_ci if (isize != NULL) 464e1051a39Sopenharmony_ci *isize = mdsize; 465e1051a39Sopenharmony_ci if (ctx->digest->cleanup) { 466e1051a39Sopenharmony_ci ctx->digest->cleanup(ctx); 467e1051a39Sopenharmony_ci EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 468e1051a39Sopenharmony_ci } 469e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); 470e1051a39Sopenharmony_ci return ret; 471e1051a39Sopenharmony_ci} 472e1051a39Sopenharmony_ci 473e1051a39Sopenharmony_ciint EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) 474e1051a39Sopenharmony_ci{ 475e1051a39Sopenharmony_ci int ret = 0; 476e1051a39Sopenharmony_ci OSSL_PARAM params[2]; 477e1051a39Sopenharmony_ci size_t i = 0; 478e1051a39Sopenharmony_ci 479e1051a39Sopenharmony_ci if (ctx->digest == NULL) { 480e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); 481e1051a39Sopenharmony_ci return 0; 482e1051a39Sopenharmony_ci } 483e1051a39Sopenharmony_ci 484e1051a39Sopenharmony_ci if (ctx->digest->prov == NULL) 485e1051a39Sopenharmony_ci goto legacy; 486e1051a39Sopenharmony_ci 487e1051a39Sopenharmony_ci if (ctx->digest->dfinal == NULL) { 488e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); 489e1051a39Sopenharmony_ci return 0; 490e1051a39Sopenharmony_ci } 491e1051a39Sopenharmony_ci 492e1051a39Sopenharmony_ci params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size); 493e1051a39Sopenharmony_ci params[i++] = OSSL_PARAM_construct_end(); 494e1051a39Sopenharmony_ci 495e1051a39Sopenharmony_ci if (EVP_MD_CTX_set_params(ctx, params) > 0) 496e1051a39Sopenharmony_ci ret = ctx->digest->dfinal(ctx->algctx, md, &size, size); 497e1051a39Sopenharmony_ci 498e1051a39Sopenharmony_ci return ret; 499e1051a39Sopenharmony_ci 500e1051a39Sopenharmony_cilegacy: 501e1051a39Sopenharmony_ci if (ctx->digest->flags & EVP_MD_FLAG_XOF 502e1051a39Sopenharmony_ci && size <= INT_MAX 503e1051a39Sopenharmony_ci && ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) { 504e1051a39Sopenharmony_ci ret = ctx->digest->final(ctx, md); 505e1051a39Sopenharmony_ci if (ctx->digest->cleanup != NULL) { 506e1051a39Sopenharmony_ci ctx->digest->cleanup(ctx); 507e1051a39Sopenharmony_ci EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 508e1051a39Sopenharmony_ci } 509e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); 510e1051a39Sopenharmony_ci } else { 511e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH); 512e1051a39Sopenharmony_ci } 513e1051a39Sopenharmony_ci 514e1051a39Sopenharmony_ci return ret; 515e1051a39Sopenharmony_ci} 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_ciint EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) 518e1051a39Sopenharmony_ci{ 519e1051a39Sopenharmony_ci EVP_MD_CTX_reset(out); 520e1051a39Sopenharmony_ci return EVP_MD_CTX_copy_ex(out, in); 521e1051a39Sopenharmony_ci} 522e1051a39Sopenharmony_ci 523e1051a39Sopenharmony_ciint EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) 524e1051a39Sopenharmony_ci{ 525e1051a39Sopenharmony_ci int digest_change = 0; 526e1051a39Sopenharmony_ci unsigned char *tmp_buf; 527e1051a39Sopenharmony_ci 528e1051a39Sopenharmony_ci if (in == NULL) { 529e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); 530e1051a39Sopenharmony_ci return 0; 531e1051a39Sopenharmony_ci } 532e1051a39Sopenharmony_ci 533e1051a39Sopenharmony_ci if (in->digest == NULL) { 534e1051a39Sopenharmony_ci /* copying uninitialized digest context */ 535e1051a39Sopenharmony_ci EVP_MD_CTX_reset(out); 536e1051a39Sopenharmony_ci if (out->fetched_digest != NULL) 537e1051a39Sopenharmony_ci EVP_MD_free(out->fetched_digest); 538e1051a39Sopenharmony_ci *out = *in; 539e1051a39Sopenharmony_ci goto clone_pkey; 540e1051a39Sopenharmony_ci } 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ci if (in->digest->prov == NULL 543e1051a39Sopenharmony_ci || (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) 544e1051a39Sopenharmony_ci goto legacy; 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_ci if (in->digest->dupctx == NULL) { 547e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); 548e1051a39Sopenharmony_ci return 0; 549e1051a39Sopenharmony_ci } 550e1051a39Sopenharmony_ci 551e1051a39Sopenharmony_ci evp_md_ctx_reset_ex(out, 1); 552e1051a39Sopenharmony_ci digest_change = (out->fetched_digest != in->fetched_digest); 553e1051a39Sopenharmony_ci if (digest_change && out->fetched_digest != NULL) 554e1051a39Sopenharmony_ci EVP_MD_free(out->fetched_digest); 555e1051a39Sopenharmony_ci *out = *in; 556e1051a39Sopenharmony_ci /* NULL out pointers in case of error */ 557e1051a39Sopenharmony_ci out->pctx = NULL; 558e1051a39Sopenharmony_ci out->algctx = NULL; 559e1051a39Sopenharmony_ci 560e1051a39Sopenharmony_ci if (digest_change && in->fetched_digest != NULL) 561e1051a39Sopenharmony_ci EVP_MD_up_ref(in->fetched_digest); 562e1051a39Sopenharmony_ci 563e1051a39Sopenharmony_ci if (in->algctx != NULL) { 564e1051a39Sopenharmony_ci out->algctx = in->digest->dupctx(in->algctx); 565e1051a39Sopenharmony_ci if (out->algctx == NULL) { 566e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); 567e1051a39Sopenharmony_ci return 0; 568e1051a39Sopenharmony_ci } 569e1051a39Sopenharmony_ci } 570e1051a39Sopenharmony_ci 571e1051a39Sopenharmony_ci clone_pkey: 572e1051a39Sopenharmony_ci /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */ 573e1051a39Sopenharmony_ci EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 574e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 575e1051a39Sopenharmony_ci if (in->pctx != NULL) { 576e1051a39Sopenharmony_ci out->pctx = EVP_PKEY_CTX_dup(in->pctx); 577e1051a39Sopenharmony_ci if (out->pctx == NULL) { 578e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); 579e1051a39Sopenharmony_ci EVP_MD_CTX_reset(out); 580e1051a39Sopenharmony_ci return 0; 581e1051a39Sopenharmony_ci } 582e1051a39Sopenharmony_ci } 583e1051a39Sopenharmony_ci#endif 584e1051a39Sopenharmony_ci 585e1051a39Sopenharmony_ci return 1; 586e1051a39Sopenharmony_ci 587e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 588e1051a39Sopenharmony_ci legacy: 589e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 590e1051a39Sopenharmony_ci /* Make sure it's safe to copy a digest context using an ENGINE */ 591e1051a39Sopenharmony_ci if (in->engine && !ENGINE_init(in->engine)) { 592e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); 593e1051a39Sopenharmony_ci return 0; 594e1051a39Sopenharmony_ci } 595e1051a39Sopenharmony_ci#endif 596e1051a39Sopenharmony_ci 597e1051a39Sopenharmony_ci if (out->digest == in->digest) { 598e1051a39Sopenharmony_ci tmp_buf = out->md_data; 599e1051a39Sopenharmony_ci EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); 600e1051a39Sopenharmony_ci } else 601e1051a39Sopenharmony_ci tmp_buf = NULL; 602e1051a39Sopenharmony_ci EVP_MD_CTX_reset(out); 603e1051a39Sopenharmony_ci memcpy(out, in, sizeof(*out)); 604e1051a39Sopenharmony_ci 605e1051a39Sopenharmony_ci /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */ 606e1051a39Sopenharmony_ci EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 607e1051a39Sopenharmony_ci 608e1051a39Sopenharmony_ci /* Null these variables, since they are getting fixed up 609e1051a39Sopenharmony_ci * properly below. Anything else may cause a memleak and/or 610e1051a39Sopenharmony_ci * double free if any of the memory allocations below fail 611e1051a39Sopenharmony_ci */ 612e1051a39Sopenharmony_ci out->md_data = NULL; 613e1051a39Sopenharmony_ci out->pctx = NULL; 614e1051a39Sopenharmony_ci 615e1051a39Sopenharmony_ci if (in->md_data && out->digest->ctx_size) { 616e1051a39Sopenharmony_ci if (tmp_buf) 617e1051a39Sopenharmony_ci out->md_data = tmp_buf; 618e1051a39Sopenharmony_ci else { 619e1051a39Sopenharmony_ci out->md_data = OPENSSL_malloc(out->digest->ctx_size); 620e1051a39Sopenharmony_ci if (out->md_data == NULL) { 621e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 622e1051a39Sopenharmony_ci return 0; 623e1051a39Sopenharmony_ci } 624e1051a39Sopenharmony_ci } 625e1051a39Sopenharmony_ci memcpy(out->md_data, in->md_data, out->digest->ctx_size); 626e1051a39Sopenharmony_ci } 627e1051a39Sopenharmony_ci 628e1051a39Sopenharmony_ci out->update = in->update; 629e1051a39Sopenharmony_ci 630e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 631e1051a39Sopenharmony_ci if (in->pctx) { 632e1051a39Sopenharmony_ci out->pctx = EVP_PKEY_CTX_dup(in->pctx); 633e1051a39Sopenharmony_ci if (!out->pctx) { 634e1051a39Sopenharmony_ci EVP_MD_CTX_reset(out); 635e1051a39Sopenharmony_ci return 0; 636e1051a39Sopenharmony_ci } 637e1051a39Sopenharmony_ci } 638e1051a39Sopenharmony_ci#endif 639e1051a39Sopenharmony_ci 640e1051a39Sopenharmony_ci if (out->digest->copy) 641e1051a39Sopenharmony_ci return out->digest->copy(out, in); 642e1051a39Sopenharmony_ci 643e1051a39Sopenharmony_ci return 1; 644e1051a39Sopenharmony_ci} 645e1051a39Sopenharmony_ci 646e1051a39Sopenharmony_ciint EVP_Digest(const void *data, size_t count, 647e1051a39Sopenharmony_ci unsigned char *md, unsigned int *size, const EVP_MD *type, 648e1051a39Sopenharmony_ci ENGINE *impl) 649e1051a39Sopenharmony_ci{ 650e1051a39Sopenharmony_ci EVP_MD_CTX *ctx = EVP_MD_CTX_new(); 651e1051a39Sopenharmony_ci int ret; 652e1051a39Sopenharmony_ci 653e1051a39Sopenharmony_ci if (ctx == NULL) 654e1051a39Sopenharmony_ci return 0; 655e1051a39Sopenharmony_ci EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT); 656e1051a39Sopenharmony_ci ret = EVP_DigestInit_ex(ctx, type, impl) 657e1051a39Sopenharmony_ci && EVP_DigestUpdate(ctx, data, count) 658e1051a39Sopenharmony_ci && EVP_DigestFinal_ex(ctx, md, size); 659e1051a39Sopenharmony_ci EVP_MD_CTX_free(ctx); 660e1051a39Sopenharmony_ci 661e1051a39Sopenharmony_ci return ret; 662e1051a39Sopenharmony_ci} 663e1051a39Sopenharmony_ci 664e1051a39Sopenharmony_ciint EVP_Q_digest(OSSL_LIB_CTX *libctx, const char *name, const char *propq, 665e1051a39Sopenharmony_ci const void *data, size_t datalen, 666e1051a39Sopenharmony_ci unsigned char *md, size_t *mdlen) 667e1051a39Sopenharmony_ci{ 668e1051a39Sopenharmony_ci EVP_MD *digest = EVP_MD_fetch(libctx, name, propq); 669e1051a39Sopenharmony_ci unsigned int temp = 0; 670e1051a39Sopenharmony_ci int ret = 0; 671e1051a39Sopenharmony_ci 672e1051a39Sopenharmony_ci if (digest != NULL) { 673e1051a39Sopenharmony_ci ret = EVP_Digest(data, datalen, md, &temp, digest, NULL); 674e1051a39Sopenharmony_ci EVP_MD_free(digest); 675e1051a39Sopenharmony_ci } 676e1051a39Sopenharmony_ci if (mdlen != NULL) 677e1051a39Sopenharmony_ci *mdlen = temp; 678e1051a39Sopenharmony_ci return ret; 679e1051a39Sopenharmony_ci} 680e1051a39Sopenharmony_ci 681e1051a39Sopenharmony_ciint EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]) 682e1051a39Sopenharmony_ci{ 683e1051a39Sopenharmony_ci if (digest != NULL && digest->get_params != NULL) 684e1051a39Sopenharmony_ci return digest->get_params(params); 685e1051a39Sopenharmony_ci return 0; 686e1051a39Sopenharmony_ci} 687e1051a39Sopenharmony_ci 688e1051a39Sopenharmony_ciconst OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest) 689e1051a39Sopenharmony_ci{ 690e1051a39Sopenharmony_ci if (digest != NULL && digest->gettable_params != NULL) 691e1051a39Sopenharmony_ci return digest->gettable_params( 692e1051a39Sopenharmony_ci ossl_provider_ctx(EVP_MD_get0_provider(digest))); 693e1051a39Sopenharmony_ci return NULL; 694e1051a39Sopenharmony_ci} 695e1051a39Sopenharmony_ci 696e1051a39Sopenharmony_ciint EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]) 697e1051a39Sopenharmony_ci{ 698e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = ctx->pctx; 699e1051a39Sopenharmony_ci 700e1051a39Sopenharmony_ci /* If we have a pctx then we should try that first */ 701e1051a39Sopenharmony_ci if (pctx != NULL 702e1051a39Sopenharmony_ci && (pctx->operation == EVP_PKEY_OP_VERIFYCTX 703e1051a39Sopenharmony_ci || pctx->operation == EVP_PKEY_OP_SIGNCTX) 704e1051a39Sopenharmony_ci && pctx->op.sig.algctx != NULL 705e1051a39Sopenharmony_ci && pctx->op.sig.signature->set_ctx_md_params != NULL) 706e1051a39Sopenharmony_ci return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.algctx, 707e1051a39Sopenharmony_ci params); 708e1051a39Sopenharmony_ci 709e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL) 710e1051a39Sopenharmony_ci return ctx->digest->set_ctx_params(ctx->algctx, params); 711e1051a39Sopenharmony_ci 712e1051a39Sopenharmony_ci return 0; 713e1051a39Sopenharmony_ci} 714e1051a39Sopenharmony_ci 715e1051a39Sopenharmony_ciconst OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md) 716e1051a39Sopenharmony_ci{ 717e1051a39Sopenharmony_ci void *provctx; 718e1051a39Sopenharmony_ci 719e1051a39Sopenharmony_ci if (md != NULL && md->settable_ctx_params != NULL) { 720e1051a39Sopenharmony_ci provctx = ossl_provider_ctx(EVP_MD_get0_provider(md)); 721e1051a39Sopenharmony_ci return md->settable_ctx_params(NULL, provctx); 722e1051a39Sopenharmony_ci } 723e1051a39Sopenharmony_ci return NULL; 724e1051a39Sopenharmony_ci} 725e1051a39Sopenharmony_ci 726e1051a39Sopenharmony_ciconst OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx) 727e1051a39Sopenharmony_ci{ 728e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx; 729e1051a39Sopenharmony_ci void *alg; 730e1051a39Sopenharmony_ci 731e1051a39Sopenharmony_ci if (ctx == NULL) 732e1051a39Sopenharmony_ci return NULL; 733e1051a39Sopenharmony_ci 734e1051a39Sopenharmony_ci /* If we have a pctx then we should try that first */ 735e1051a39Sopenharmony_ci pctx = ctx->pctx; 736e1051a39Sopenharmony_ci if (pctx != NULL 737e1051a39Sopenharmony_ci && (pctx->operation == EVP_PKEY_OP_VERIFYCTX 738e1051a39Sopenharmony_ci || pctx->operation == EVP_PKEY_OP_SIGNCTX) 739e1051a39Sopenharmony_ci && pctx->op.sig.algctx != NULL 740e1051a39Sopenharmony_ci && pctx->op.sig.signature->settable_ctx_md_params != NULL) 741e1051a39Sopenharmony_ci return pctx->op.sig.signature->settable_ctx_md_params( 742e1051a39Sopenharmony_ci pctx->op.sig.algctx); 743e1051a39Sopenharmony_ci 744e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL) { 745e1051a39Sopenharmony_ci alg = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest)); 746e1051a39Sopenharmony_ci return ctx->digest->settable_ctx_params(ctx->algctx, alg); 747e1051a39Sopenharmony_ci } 748e1051a39Sopenharmony_ci 749e1051a39Sopenharmony_ci return NULL; 750e1051a39Sopenharmony_ci} 751e1051a39Sopenharmony_ci 752e1051a39Sopenharmony_ciint EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]) 753e1051a39Sopenharmony_ci{ 754e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = ctx->pctx; 755e1051a39Sopenharmony_ci 756e1051a39Sopenharmony_ci /* If we have a pctx then we should try that first */ 757e1051a39Sopenharmony_ci if (pctx != NULL 758e1051a39Sopenharmony_ci && (pctx->operation == EVP_PKEY_OP_VERIFYCTX 759e1051a39Sopenharmony_ci || pctx->operation == EVP_PKEY_OP_SIGNCTX) 760e1051a39Sopenharmony_ci && pctx->op.sig.algctx != NULL 761e1051a39Sopenharmony_ci && pctx->op.sig.signature->get_ctx_md_params != NULL) 762e1051a39Sopenharmony_ci return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.algctx, 763e1051a39Sopenharmony_ci params); 764e1051a39Sopenharmony_ci 765e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->get_ctx_params != NULL) 766e1051a39Sopenharmony_ci return ctx->digest->get_ctx_params(ctx->algctx, params); 767e1051a39Sopenharmony_ci 768e1051a39Sopenharmony_ci return 0; 769e1051a39Sopenharmony_ci} 770e1051a39Sopenharmony_ci 771e1051a39Sopenharmony_ciconst OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md) 772e1051a39Sopenharmony_ci{ 773e1051a39Sopenharmony_ci void *provctx; 774e1051a39Sopenharmony_ci 775e1051a39Sopenharmony_ci if (md != NULL && md->gettable_ctx_params != NULL) { 776e1051a39Sopenharmony_ci provctx = ossl_provider_ctx(EVP_MD_get0_provider(md)); 777e1051a39Sopenharmony_ci return md->gettable_ctx_params(NULL, provctx); 778e1051a39Sopenharmony_ci } 779e1051a39Sopenharmony_ci return NULL; 780e1051a39Sopenharmony_ci} 781e1051a39Sopenharmony_ci 782e1051a39Sopenharmony_ciconst OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx) 783e1051a39Sopenharmony_ci{ 784e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx; 785e1051a39Sopenharmony_ci void *provctx; 786e1051a39Sopenharmony_ci 787e1051a39Sopenharmony_ci if (ctx == NULL) 788e1051a39Sopenharmony_ci return NULL; 789e1051a39Sopenharmony_ci 790e1051a39Sopenharmony_ci /* If we have a pctx then we should try that first */ 791e1051a39Sopenharmony_ci pctx = ctx->pctx; 792e1051a39Sopenharmony_ci if (pctx != NULL 793e1051a39Sopenharmony_ci && (pctx->operation == EVP_PKEY_OP_VERIFYCTX 794e1051a39Sopenharmony_ci || pctx->operation == EVP_PKEY_OP_SIGNCTX) 795e1051a39Sopenharmony_ci && pctx->op.sig.algctx != NULL 796e1051a39Sopenharmony_ci && pctx->op.sig.signature->gettable_ctx_md_params != NULL) 797e1051a39Sopenharmony_ci return pctx->op.sig.signature->gettable_ctx_md_params( 798e1051a39Sopenharmony_ci pctx->op.sig.algctx); 799e1051a39Sopenharmony_ci 800e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->gettable_ctx_params != NULL) { 801e1051a39Sopenharmony_ci provctx = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest)); 802e1051a39Sopenharmony_ci return ctx->digest->gettable_ctx_params(ctx->algctx, provctx); 803e1051a39Sopenharmony_ci } 804e1051a39Sopenharmony_ci return NULL; 805e1051a39Sopenharmony_ci} 806e1051a39Sopenharmony_ci 807e1051a39Sopenharmony_ciint EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) 808e1051a39Sopenharmony_ci{ 809e1051a39Sopenharmony_ci int ret = EVP_CTRL_RET_UNSUPPORTED; 810e1051a39Sopenharmony_ci int set_params = 1; 811e1051a39Sopenharmony_ci size_t sz; 812e1051a39Sopenharmony_ci OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 813e1051a39Sopenharmony_ci 814e1051a39Sopenharmony_ci if (ctx == NULL) { 815e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); 816e1051a39Sopenharmony_ci return 0; 817e1051a39Sopenharmony_ci } 818e1051a39Sopenharmony_ci 819e1051a39Sopenharmony_ci if (ctx->digest != NULL && ctx->digest->prov == NULL) 820e1051a39Sopenharmony_ci goto legacy; 821e1051a39Sopenharmony_ci 822e1051a39Sopenharmony_ci switch (cmd) { 823e1051a39Sopenharmony_ci case EVP_MD_CTRL_XOF_LEN: 824e1051a39Sopenharmony_ci sz = (size_t)p1; 825e1051a39Sopenharmony_ci params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz); 826e1051a39Sopenharmony_ci break; 827e1051a39Sopenharmony_ci case EVP_MD_CTRL_MICALG: 828e1051a39Sopenharmony_ci set_params = 0; 829e1051a39Sopenharmony_ci params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG, 830e1051a39Sopenharmony_ci p2, p1 ? p1 : 9999); 831e1051a39Sopenharmony_ci break; 832e1051a39Sopenharmony_ci case EVP_CTRL_SSL3_MASTER_SECRET: 833e1051a39Sopenharmony_ci params[0] = OSSL_PARAM_construct_octet_string(OSSL_DIGEST_PARAM_SSL3_MS, 834e1051a39Sopenharmony_ci p2, p1); 835e1051a39Sopenharmony_ci break; 836e1051a39Sopenharmony_ci default: 837e1051a39Sopenharmony_ci goto conclude; 838e1051a39Sopenharmony_ci } 839e1051a39Sopenharmony_ci 840e1051a39Sopenharmony_ci if (set_params) 841e1051a39Sopenharmony_ci ret = EVP_MD_CTX_set_params(ctx, params); 842e1051a39Sopenharmony_ci else 843e1051a39Sopenharmony_ci ret = EVP_MD_CTX_get_params(ctx, params); 844e1051a39Sopenharmony_ci goto conclude; 845e1051a39Sopenharmony_ci 846e1051a39Sopenharmony_ci 847e1051a39Sopenharmony_ci /* Code below to be removed when legacy support is dropped. */ 848e1051a39Sopenharmony_ci legacy: 849e1051a39Sopenharmony_ci if (ctx->digest->md_ctrl == NULL) { 850e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED); 851e1051a39Sopenharmony_ci return 0; 852e1051a39Sopenharmony_ci } 853e1051a39Sopenharmony_ci 854e1051a39Sopenharmony_ci ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2); 855e1051a39Sopenharmony_ci conclude: 856e1051a39Sopenharmony_ci if (ret <= 0) 857e1051a39Sopenharmony_ci return 0; 858e1051a39Sopenharmony_ci return ret; 859e1051a39Sopenharmony_ci} 860e1051a39Sopenharmony_ci 861e1051a39Sopenharmony_ciEVP_MD *evp_md_new(void) 862e1051a39Sopenharmony_ci{ 863e1051a39Sopenharmony_ci EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); 864e1051a39Sopenharmony_ci 865e1051a39Sopenharmony_ci if (md != NULL) { 866e1051a39Sopenharmony_ci md->lock = CRYPTO_THREAD_lock_new(); 867e1051a39Sopenharmony_ci if (md->lock == NULL) { 868e1051a39Sopenharmony_ci OPENSSL_free(md); 869e1051a39Sopenharmony_ci return NULL; 870e1051a39Sopenharmony_ci } 871e1051a39Sopenharmony_ci md->refcnt = 1; 872e1051a39Sopenharmony_ci } 873e1051a39Sopenharmony_ci return md; 874e1051a39Sopenharmony_ci} 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci/* 877e1051a39Sopenharmony_ci * FIPS module note: since internal fetches will be entirely 878e1051a39Sopenharmony_ci * provider based, we know that none of its code depends on legacy 879e1051a39Sopenharmony_ci * NIDs or any functionality that use them. 880e1051a39Sopenharmony_ci */ 881e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 882e1051a39Sopenharmony_cistatic void set_legacy_nid(const char *name, void *vlegacy_nid) 883e1051a39Sopenharmony_ci{ 884e1051a39Sopenharmony_ci int nid; 885e1051a39Sopenharmony_ci int *legacy_nid = vlegacy_nid; 886e1051a39Sopenharmony_ci /* 887e1051a39Sopenharmony_ci * We use lowest level function to get the associated method, because 888e1051a39Sopenharmony_ci * higher level functions such as EVP_get_digestbyname() have changed 889e1051a39Sopenharmony_ci * to look at providers too. 890e1051a39Sopenharmony_ci */ 891e1051a39Sopenharmony_ci const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); 892e1051a39Sopenharmony_ci 893e1051a39Sopenharmony_ci if (*legacy_nid == -1) /* We found a clash already */ 894e1051a39Sopenharmony_ci return; 895e1051a39Sopenharmony_ci 896e1051a39Sopenharmony_ci if (legacy_method == NULL) 897e1051a39Sopenharmony_ci return; 898e1051a39Sopenharmony_ci nid = EVP_MD_nid(legacy_method); 899e1051a39Sopenharmony_ci if (*legacy_nid != NID_undef && *legacy_nid != nid) { 900e1051a39Sopenharmony_ci *legacy_nid = -1; 901e1051a39Sopenharmony_ci return; 902e1051a39Sopenharmony_ci } 903e1051a39Sopenharmony_ci *legacy_nid = nid; 904e1051a39Sopenharmony_ci} 905e1051a39Sopenharmony_ci#endif 906e1051a39Sopenharmony_ci 907e1051a39Sopenharmony_cistatic int evp_md_cache_constants(EVP_MD *md) 908e1051a39Sopenharmony_ci{ 909e1051a39Sopenharmony_ci int ok, xof = 0, algid_absent = 0; 910e1051a39Sopenharmony_ci size_t blksz = 0; 911e1051a39Sopenharmony_ci size_t mdsize = 0; 912e1051a39Sopenharmony_ci OSSL_PARAM params[5]; 913e1051a39Sopenharmony_ci 914e1051a39Sopenharmony_ci params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &blksz); 915e1051a39Sopenharmony_ci params[1] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &mdsize); 916e1051a39Sopenharmony_ci params[2] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_XOF, &xof); 917e1051a39Sopenharmony_ci params[3] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, 918e1051a39Sopenharmony_ci &algid_absent); 919e1051a39Sopenharmony_ci params[4] = OSSL_PARAM_construct_end(); 920e1051a39Sopenharmony_ci ok = evp_do_md_getparams(md, params) > 0; 921e1051a39Sopenharmony_ci if (mdsize > INT_MAX || blksz > INT_MAX) 922e1051a39Sopenharmony_ci ok = 0; 923e1051a39Sopenharmony_ci if (ok) { 924e1051a39Sopenharmony_ci md->block_size = (int)blksz; 925e1051a39Sopenharmony_ci md->md_size = (int)mdsize; 926e1051a39Sopenharmony_ci if (xof) 927e1051a39Sopenharmony_ci md->flags |= EVP_MD_FLAG_XOF; 928e1051a39Sopenharmony_ci if (algid_absent) 929e1051a39Sopenharmony_ci md->flags |= EVP_MD_FLAG_DIGALGID_ABSENT; 930e1051a39Sopenharmony_ci } 931e1051a39Sopenharmony_ci return ok; 932e1051a39Sopenharmony_ci} 933e1051a39Sopenharmony_ci 934e1051a39Sopenharmony_cistatic void *evp_md_from_algorithm(int name_id, 935e1051a39Sopenharmony_ci const OSSL_ALGORITHM *algodef, 936e1051a39Sopenharmony_ci OSSL_PROVIDER *prov) 937e1051a39Sopenharmony_ci{ 938e1051a39Sopenharmony_ci const OSSL_DISPATCH *fns = algodef->implementation; 939e1051a39Sopenharmony_ci EVP_MD *md = NULL; 940e1051a39Sopenharmony_ci int fncnt = 0; 941e1051a39Sopenharmony_ci 942e1051a39Sopenharmony_ci /* EVP_MD_fetch() will set the legacy NID if available */ 943e1051a39Sopenharmony_ci if ((md = evp_md_new()) == NULL) { 944e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 945e1051a39Sopenharmony_ci return NULL; 946e1051a39Sopenharmony_ci } 947e1051a39Sopenharmony_ci 948e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 949e1051a39Sopenharmony_ci md->type = NID_undef; 950e1051a39Sopenharmony_ci if (!evp_names_do_all(prov, name_id, set_legacy_nid, &md->type) 951e1051a39Sopenharmony_ci || md->type == -1) { 952e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); 953e1051a39Sopenharmony_ci EVP_MD_free(md); 954e1051a39Sopenharmony_ci return NULL; 955e1051a39Sopenharmony_ci } 956e1051a39Sopenharmony_ci#endif 957e1051a39Sopenharmony_ci 958e1051a39Sopenharmony_ci md->name_id = name_id; 959e1051a39Sopenharmony_ci if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { 960e1051a39Sopenharmony_ci EVP_MD_free(md); 961e1051a39Sopenharmony_ci return NULL; 962e1051a39Sopenharmony_ci } 963e1051a39Sopenharmony_ci md->description = algodef->algorithm_description; 964e1051a39Sopenharmony_ci 965e1051a39Sopenharmony_ci for (; fns->function_id != 0; fns++) { 966e1051a39Sopenharmony_ci switch (fns->function_id) { 967e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_NEWCTX: 968e1051a39Sopenharmony_ci if (md->newctx == NULL) { 969e1051a39Sopenharmony_ci md->newctx = OSSL_FUNC_digest_newctx(fns); 970e1051a39Sopenharmony_ci fncnt++; 971e1051a39Sopenharmony_ci } 972e1051a39Sopenharmony_ci break; 973e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_INIT: 974e1051a39Sopenharmony_ci if (md->dinit == NULL) { 975e1051a39Sopenharmony_ci md->dinit = OSSL_FUNC_digest_init(fns); 976e1051a39Sopenharmony_ci fncnt++; 977e1051a39Sopenharmony_ci } 978e1051a39Sopenharmony_ci break; 979e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_UPDATE: 980e1051a39Sopenharmony_ci if (md->dupdate == NULL) { 981e1051a39Sopenharmony_ci md->dupdate = OSSL_FUNC_digest_update(fns); 982e1051a39Sopenharmony_ci fncnt++; 983e1051a39Sopenharmony_ci } 984e1051a39Sopenharmony_ci break; 985e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_FINAL: 986e1051a39Sopenharmony_ci if (md->dfinal == NULL) { 987e1051a39Sopenharmony_ci md->dfinal = OSSL_FUNC_digest_final(fns); 988e1051a39Sopenharmony_ci fncnt++; 989e1051a39Sopenharmony_ci } 990e1051a39Sopenharmony_ci break; 991e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_DIGEST: 992e1051a39Sopenharmony_ci if (md->digest == NULL) 993e1051a39Sopenharmony_ci md->digest = OSSL_FUNC_digest_digest(fns); 994e1051a39Sopenharmony_ci /* We don't increment fnct for this as it is stand alone */ 995e1051a39Sopenharmony_ci break; 996e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_FREECTX: 997e1051a39Sopenharmony_ci if (md->freectx == NULL) { 998e1051a39Sopenharmony_ci md->freectx = OSSL_FUNC_digest_freectx(fns); 999e1051a39Sopenharmony_ci fncnt++; 1000e1051a39Sopenharmony_ci } 1001e1051a39Sopenharmony_ci break; 1002e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_DUPCTX: 1003e1051a39Sopenharmony_ci if (md->dupctx == NULL) 1004e1051a39Sopenharmony_ci md->dupctx = OSSL_FUNC_digest_dupctx(fns); 1005e1051a39Sopenharmony_ci break; 1006e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_GET_PARAMS: 1007e1051a39Sopenharmony_ci if (md->get_params == NULL) 1008e1051a39Sopenharmony_ci md->get_params = OSSL_FUNC_digest_get_params(fns); 1009e1051a39Sopenharmony_ci break; 1010e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_SET_CTX_PARAMS: 1011e1051a39Sopenharmony_ci if (md->set_ctx_params == NULL) 1012e1051a39Sopenharmony_ci md->set_ctx_params = OSSL_FUNC_digest_set_ctx_params(fns); 1013e1051a39Sopenharmony_ci break; 1014e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_GET_CTX_PARAMS: 1015e1051a39Sopenharmony_ci if (md->get_ctx_params == NULL) 1016e1051a39Sopenharmony_ci md->get_ctx_params = OSSL_FUNC_digest_get_ctx_params(fns); 1017e1051a39Sopenharmony_ci break; 1018e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_GETTABLE_PARAMS: 1019e1051a39Sopenharmony_ci if (md->gettable_params == NULL) 1020e1051a39Sopenharmony_ci md->gettable_params = OSSL_FUNC_digest_gettable_params(fns); 1021e1051a39Sopenharmony_ci break; 1022e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS: 1023e1051a39Sopenharmony_ci if (md->settable_ctx_params == NULL) 1024e1051a39Sopenharmony_ci md->settable_ctx_params = 1025e1051a39Sopenharmony_ci OSSL_FUNC_digest_settable_ctx_params(fns); 1026e1051a39Sopenharmony_ci break; 1027e1051a39Sopenharmony_ci case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS: 1028e1051a39Sopenharmony_ci if (md->gettable_ctx_params == NULL) 1029e1051a39Sopenharmony_ci md->gettable_ctx_params = 1030e1051a39Sopenharmony_ci OSSL_FUNC_digest_gettable_ctx_params(fns); 1031e1051a39Sopenharmony_ci break; 1032e1051a39Sopenharmony_ci } 1033e1051a39Sopenharmony_ci } 1034e1051a39Sopenharmony_ci if ((fncnt != 0 && fncnt != 5) 1035e1051a39Sopenharmony_ci || (fncnt == 0 && md->digest == NULL)) { 1036e1051a39Sopenharmony_ci /* 1037e1051a39Sopenharmony_ci * In order to be a consistent set of functions we either need the 1038e1051a39Sopenharmony_ci * whole set of init/update/final etc functions or none of them. 1039e1051a39Sopenharmony_ci * The "digest" function can standalone. We at least need one way to 1040e1051a39Sopenharmony_ci * generate digests. 1041e1051a39Sopenharmony_ci */ 1042e1051a39Sopenharmony_ci EVP_MD_free(md); 1043e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); 1044e1051a39Sopenharmony_ci return NULL; 1045e1051a39Sopenharmony_ci } 1046e1051a39Sopenharmony_ci md->prov = prov; 1047e1051a39Sopenharmony_ci if (prov != NULL) 1048e1051a39Sopenharmony_ci ossl_provider_up_ref(prov); 1049e1051a39Sopenharmony_ci 1050e1051a39Sopenharmony_ci if (!evp_md_cache_constants(md)) { 1051e1051a39Sopenharmony_ci EVP_MD_free(md); 1052e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED); 1053e1051a39Sopenharmony_ci md = NULL; 1054e1051a39Sopenharmony_ci } 1055e1051a39Sopenharmony_ci 1056e1051a39Sopenharmony_ci return md; 1057e1051a39Sopenharmony_ci} 1058e1051a39Sopenharmony_ci 1059e1051a39Sopenharmony_cistatic int evp_md_up_ref(void *md) 1060e1051a39Sopenharmony_ci{ 1061e1051a39Sopenharmony_ci return EVP_MD_up_ref(md); 1062e1051a39Sopenharmony_ci} 1063e1051a39Sopenharmony_ci 1064e1051a39Sopenharmony_cistatic void evp_md_free(void *md) 1065e1051a39Sopenharmony_ci{ 1066e1051a39Sopenharmony_ci EVP_MD_free(md); 1067e1051a39Sopenharmony_ci} 1068e1051a39Sopenharmony_ci 1069e1051a39Sopenharmony_ciEVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, 1070e1051a39Sopenharmony_ci const char *properties) 1071e1051a39Sopenharmony_ci{ 1072e1051a39Sopenharmony_ci EVP_MD *md = 1073e1051a39Sopenharmony_ci evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties, 1074e1051a39Sopenharmony_ci evp_md_from_algorithm, evp_md_up_ref, evp_md_free); 1075e1051a39Sopenharmony_ci 1076e1051a39Sopenharmony_ci return md; 1077e1051a39Sopenharmony_ci} 1078e1051a39Sopenharmony_ci 1079e1051a39Sopenharmony_ciint EVP_MD_up_ref(EVP_MD *md) 1080e1051a39Sopenharmony_ci{ 1081e1051a39Sopenharmony_ci int ref = 0; 1082e1051a39Sopenharmony_ci 1083e1051a39Sopenharmony_ci if (md->origin == EVP_ORIG_DYNAMIC) 1084e1051a39Sopenharmony_ci CRYPTO_UP_REF(&md->refcnt, &ref, md->lock); 1085e1051a39Sopenharmony_ci return 1; 1086e1051a39Sopenharmony_ci} 1087e1051a39Sopenharmony_ci 1088e1051a39Sopenharmony_civoid EVP_MD_free(EVP_MD *md) 1089e1051a39Sopenharmony_ci{ 1090e1051a39Sopenharmony_ci int i; 1091e1051a39Sopenharmony_ci 1092e1051a39Sopenharmony_ci if (md == NULL || md->origin != EVP_ORIG_DYNAMIC) 1093e1051a39Sopenharmony_ci return; 1094e1051a39Sopenharmony_ci 1095e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock); 1096e1051a39Sopenharmony_ci if (i > 0) 1097e1051a39Sopenharmony_ci return; 1098e1051a39Sopenharmony_ci evp_md_free_int(md); 1099e1051a39Sopenharmony_ci} 1100e1051a39Sopenharmony_ci 1101e1051a39Sopenharmony_civoid EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, 1102e1051a39Sopenharmony_ci void (*fn)(EVP_MD *mac, void *arg), 1103e1051a39Sopenharmony_ci void *arg) 1104e1051a39Sopenharmony_ci{ 1105e1051a39Sopenharmony_ci evp_generic_do_all(libctx, OSSL_OP_DIGEST, 1106e1051a39Sopenharmony_ci (void (*)(void *, void *))fn, arg, 1107e1051a39Sopenharmony_ci evp_md_from_algorithm, evp_md_up_ref, evp_md_free); 1108e1051a39Sopenharmony_ci} 1109