X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fdigest.c;h=33688f99e432c383286d4f10e0a350247818b328;hp=47e987385a2f1e9deadcfe563bb524f13822b2fe;hb=6aa0ba4bb2833b1e0d6ae98c54c79bfed8257c3a;hpb=ab0a14bbc7bc7cdda4cfb2b2a730804b3437429f diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 47e987385a..33688f99e4 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -119,24 +119,51 @@ #include "internal/evp_int.h" #include "evp_locl.h" -void EVP_MD_CTX_init(EVP_MD_CTX *ctx) +/* This call frees resources associated with the context */ +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { + if (ctx == NULL) + return 1; + + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because + * sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); + } + EVP_PKEY_CTX_free(ctx->pctx); +#ifndef OPENSSL_NO_ENGINE + if (ctx->engine) + /* + * The EVP_MD we used belongs to an ENGINE, release the functional + * reference we held for this reason. + */ + ENGINE_finish(ctx->engine); +#endif memset(ctx, 0, sizeof(*ctx)); + + return 1; } -EVP_MD_CTX *EVP_MD_CTX_create(void) +EVP_MD_CTX *EVP_MD_CTX_new(void) { - EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); - - if (ctx != NULL) - EVP_MD_CTX_init(ctx); + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} - return ctx; +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_reset(ctx); + OPENSSL_free(ctx); } int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) { - EVP_MD_CTX_init(ctx); + EVP_MD_CTX_reset(ctx); return EVP_DigestInit_ex(ctx, type, NULL); } @@ -235,7 +262,7 @@ 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_cleanup(ctx); + EVP_MD_CTX_reset(ctx); return ret; } @@ -258,7 +285,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) { - EVP_MD_CTX_init(out); + EVP_MD_CTX_reset(out); return EVP_MD_CTX_copy_ex(out, in); } @@ -282,9 +309,16 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); } else tmp_buf = NULL; - EVP_MD_CTX_cleanup(out); + EVP_MD_CTX_reset(out); memcpy(out, in, sizeof(*out)); + /* 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; @@ -303,7 +337,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) if (in->pctx) { out->pctx = EVP_PKEY_CTX_dup(in->pctx); if (!out->pctx) { - EVP_MD_CTX_cleanup(out); + EVP_MD_CTX_reset(out); return 0; } } @@ -318,55 +352,20 @@ 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 *ctx = EVP_MD_CTX_new(); int ret; - EVP_MD_CTX_init(&ctx); - 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_cleanup(&ctx); + 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; } -void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) -{ - if (ctx) { - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(ctx); - } -} - -/* This call frees resources associated with the context */ -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) -{ - /* - * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because - * sometimes only copies of the context are ever finalised. - */ - if (ctx->digest && ctx->digest->cleanup - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) - ctx->digest->cleanup(ctx); - if (ctx->digest && ctx->digest->ctx_size && ctx->md_data - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { - OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); - } - EVP_PKEY_CTX_free(ctx->pctx); -#ifndef OPENSSL_NO_ENGINE - if (ctx->engine) - /* - * The EVP_MD we used belongs to an ENGINE, release the functional - * reference we held for this reason. - */ - ENGINE_finish(ctx->engine); -#endif - memset(ctx, 0, sizeof(*ctx)); - - return 1; -} - int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) { if (ctx->digest && ctx->digest->md_ctrl) {