From: Richard Levitte Date: Tue, 1 Dec 2015 00:38:35 +0000 (+0100) Subject: Remove EVP_MD_CTX_cleanup and put its functionality into EVP_MD_CTX_init X-Git-Tag: OpenSSL_1_1_0-pre1~109 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=74cabf3fef77ab73c45e27cf6ed90f6db020e7c7;ds=sidebyside Remove EVP_MD_CTX_cleanup and put its functionality into EVP_MD_CTX_init The idea is that with EVP_MD_CTX_create() and EVP_MD_CTX_destroy(), EVP_MD_CTX_cleanup and EVP_MD_CTX_init is not used the same as before. Instead, we need a single function that can be used to reinitialise an existing EVP_MD_CTX that's been created with EVP_MD_CTX_create() previously. Combining EVP_MD_CTX_cleanup and EVP_MD_CTX_init into that one function is the answer. Reviewed-by: Rich Salz --- diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 47e987385a..ec05930f86 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -119,19 +119,46 @@ #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_init(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 *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_destroy(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_init(ctx); + OPENSSL_free(ctx); } int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) @@ -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_init(ctx); return ret; } @@ -282,7 +309,7 @@ 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_init(out); memcpy(out, in, sizeof(*out)); if (in->md_data && out->digest->ctx_size) { @@ -303,7 +330,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_init(out); return 0; } } @@ -318,55 +345,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_create(); 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_destroy(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) { diff --git a/include/openssl/evp.h b/include/openssl/evp.h index b198c0c059..ecf951f115 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -571,8 +571,7 @@ void BIO_set_md(BIO *, const EVP_MD *md); # define EVP_delete_digest_alias(alias) \ OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +int EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); EVP_MD_CTX *EVP_MD_CTX_create(void); void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);