{
return EVP_DigestInit_ex(ctx, type, NULL);
}
+
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
{
+ EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
/* 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
ret=ctx->digest->final(ctx,md);
if (size != NULL)
*size=ctx->digest->md_size;
- /* FIXME: add a cleanup function to the ctx? */
+ if (ctx->digest->cleanup)
+ {
+ ctx->digest->cleanup(ctx);
+ EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+ }
memset(ctx->md_data,0,ctx->digest->ctx_size);
return ret;
}
/* 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)
+ 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)
{
#define EVP_MD_CTX_FLAG_ONESHOT 0x0001 /* digest update will be called
* once only */
+#define EVP_MD_CTX_FLAG_CLEANED 0x0002 /* context has already been
+ * cleaned */
struct evp_cipher_st
{
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
int EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);
#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+#define EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
+#define EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
int EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,