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)
{
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
- 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;
- }
-
if (type != NULL) {
ctx->reqdigest = type;
} else {
#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);
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
#endif
}
- if (ctx->algctx != NULL && ctx->digest != NULL && ctx->digest != type) {
- if (ctx->digest->freectx != NULL)
- ctx->digest->freectx(ctx->algctx);
- ctx->algctx = NULL;
- }
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);
void *provkey = NULL;
int ret, iter, reinit = 1;
- 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;
- }
+ if (!evp_md_ctx_free_algctx(ctx))
+ return 0;
if (ctx->pctx == NULL) {
reinit = 0;
char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig);
void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force, int keep_digest);
+/* just free the algctx if set, returns 0 on inconsistent state of ctx */
+int evp_md_ctx_free_algctx(EVP_MD_CTX *ctx);
/* Three possible states: */
# define EVP_PKEY_STATE_UNKNOWN 0