| Index: openssl/crypto/evp/digest.c
|
| ===================================================================
|
| --- openssl/crypto/evp/digest.c (revision 105093)
|
| +++ openssl/crypto/evp/digest.c (working copy)
|
| @@ -116,7 +116,6 @@
|
| #ifndef OPENSSL_NO_ENGINE
|
| #include <openssl/engine.h>
|
| #endif
|
| -#include "evp_locl.h"
|
|
|
| void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
|
| {
|
| @@ -139,77 +138,18 @@
|
| return EVP_DigestInit_ex(ctx, type, NULL);
|
| }
|
|
|
| -#ifdef OPENSSL_FIPS
|
| -
|
| -/* The purpose of these is to trap programs that attempt to use non FIPS
|
| - * algorithms in FIPS mode and ignore the errors.
|
| - */
|
| -
|
| -static int bad_init(EVP_MD_CTX *ctx)
|
| - { FIPS_ERROR_IGNORED("Digest init"); return 0;}
|
| -
|
| -static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count)
|
| - { FIPS_ERROR_IGNORED("Digest update"); return 0;}
|
| -
|
| -static int bad_final(EVP_MD_CTX *ctx,unsigned char *md)
|
| - { FIPS_ERROR_IGNORED("Digest Final"); return 0;}
|
| -
|
| -static const EVP_MD bad_md =
|
| +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
| {
|
| - 0,
|
| - 0,
|
| - 0,
|
| - 0,
|
| - bad_init,
|
| - bad_update,
|
| - bad_final,
|
| - NULL,
|
| - NULL,
|
| - NULL,
|
| - 0,
|
| - {0,0,0,0},
|
| - };
|
| -
|
| -#endif
|
| -
|
| + EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
| #ifndef OPENSSL_NO_ENGINE
|
| -
|
| -#ifdef OPENSSL_FIPS
|
| -
|
| -static int do_engine_null(ENGINE *impl) { return 0;}
|
| -static int do_evp_md_engine_null(EVP_MD_CTX *ctx,
|
| - const EVP_MD **ptype, ENGINE *impl)
|
| - { return 1; }
|
| -
|
| -static int (*do_engine_init)(ENGINE *impl)
|
| - = do_engine_null;
|
| -
|
| -static int (*do_engine_finish)(ENGINE *impl)
|
| - = do_engine_null;
|
| -
|
| -static int (*do_evp_md_engine)
|
| - (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
|
| - = do_evp_md_engine_null;
|
| -
|
| -void int_EVP_MD_set_engine_callbacks(
|
| - int (*eng_md_init)(ENGINE *impl),
|
| - int (*eng_md_fin)(ENGINE *impl),
|
| - int (*eng_md_evp)
|
| - (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl))
|
| - {
|
| - do_engine_init = eng_md_init;
|
| - do_engine_finish = eng_md_fin;
|
| - do_evp_md_engine = eng_md_evp;
|
| - }
|
| -
|
| -#else
|
| -
|
| -#define do_engine_init ENGINE_init
|
| -#define do_engine_finish ENGINE_finish
|
| -
|
| -static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
|
| - {
|
| - if (*ptype)
|
| + /* 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
|
| + * reinitialisation, when it may all be unecessary. */
|
| + if (ctx->engine && ctx->digest && (!type ||
|
| + (type && (type->type == ctx->digest->type))))
|
| + goto skip_to_init;
|
| + if (type)
|
| {
|
| /* Ensure an ENGINE left lying around from last time is cleared
|
| * (the previous check attempted to avoid this if the same
|
| @@ -220,26 +160,26 @@
|
| {
|
| if (!ENGINE_init(impl))
|
| {
|
| - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
|
| + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
|
| return 0;
|
| }
|
| }
|
| else
|
| /* Ask if an ENGINE is reserved for this job */
|
| - impl = ENGINE_get_digest_engine((*ptype)->type);
|
| + impl = ENGINE_get_digest_engine(type->type);
|
| if(impl)
|
| {
|
| /* There's an ENGINE for this job ... (apparently) */
|
| - const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
|
| + const EVP_MD *d = ENGINE_get_digest(impl, type->type);
|
| if(!d)
|
| {
|
| /* Same comment from evp_enc.c */
|
| - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
|
| + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
|
| ENGINE_finish(impl);
|
| return 0;
|
| }
|
| /* We'll use the ENGINE's private digest definition */
|
| - *ptype = d;
|
| + type = d;
|
| /* Store the ENGINE functional reference so we know
|
| * 'type' came from an ENGINE and we need to release
|
| * it when done. */
|
| @@ -251,78 +191,46 @@
|
| else
|
| if(!ctx->digest)
|
| {
|
| - EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET);
|
| + EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
|
| return 0;
|
| }
|
| - return 1;
|
| - }
|
| -
|
| #endif
|
| -
|
| -#endif
|
| -
|
| -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
| - {
|
| - M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
| -#ifdef OPENSSL_FIPS
|
| - if(FIPS_selftest_failed())
|
| - {
|
| - FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
|
| - ctx->digest = &bad_md;
|
| - return 0;
|
| - }
|
| -#endif
|
| -#ifndef OPENSSL_NO_ENGINE
|
| - /* 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
|
| - * reinitialisation, when it may all be unecessary. */
|
| - if (ctx->engine && ctx->digest && (!type ||
|
| - (type && (type->type == ctx->digest->type))))
|
| - goto skip_to_init;
|
| - if (!do_evp_md_engine(ctx, &type, impl))
|
| - return 0;
|
| -#endif
|
| if (ctx->digest != type)
|
| {
|
| -#ifdef OPENSSL_FIPS
|
| - if (FIPS_mode())
|
| - {
|
| - if (!(type->flags & EVP_MD_FLAG_FIPS)
|
| - && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))
|
| - {
|
| - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS);
|
| - ctx->digest = &bad_md;
|
| - return 0;
|
| - }
|
| - }
|
| -#endif
|
| if (ctx->digest && ctx->digest->ctx_size)
|
| OPENSSL_free(ctx->md_data);
|
| ctx->digest=type;
|
| - if (type->ctx_size)
|
| + if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
|
| {
|
| + ctx->update = type->update;
|
| ctx->md_data=OPENSSL_malloc(type->ctx_size);
|
| - if (!ctx->md_data)
|
| + if (ctx->md_data == NULL)
|
| {
|
| - EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
|
| + EVPerr(EVP_F_EVP_DIGESTINIT_EX,
|
| + ERR_R_MALLOC_FAILURE);
|
| return 0;
|
| }
|
| }
|
| }
|
| #ifndef OPENSSL_NO_ENGINE
|
| - skip_to_init:
|
| +skip_to_init:
|
| #endif
|
| + if (ctx->pctx)
|
| + {
|
| + int r;
|
| + r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
| + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
|
| + if (r <= 0 && (r != -2))
|
| + return 0;
|
| + }
|
| + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
|
| + return 1;
|
| return ctx->digest->init(ctx);
|
| }
|
|
|
| -int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
|
| - size_t count)
|
| +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
|
| {
|
| -#ifdef OPENSSL_FIPS
|
| - FIPS_selftest_check();
|
| -#endif
|
| - return ctx->digest->update(ctx,data,count);
|
| + return ctx->update(ctx,data,count);
|
| }
|
|
|
| /* The caller can assume that this removes any secret data from the context */
|
| @@ -338,9 +246,6 @@
|
| int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
|
| {
|
| int ret;
|
| -#ifdef OPENSSL_FIPS
|
| - FIPS_selftest_check();
|
| -#endif
|
|
|
| OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
|
| ret=ctx->digest->final(ctx,md);
|
| @@ -349,7 +254,7 @@
|
| if (ctx->digest->cleanup)
|
| {
|
| ctx->digest->cleanup(ctx);
|
| - M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
| + EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
| }
|
| memset(ctx->md_data,0,ctx->digest->ctx_size);
|
| return ret;
|
| @@ -371,7 +276,7 @@
|
| }
|
| #ifndef OPENSSL_NO_ENGINE
|
| /* Make sure it's safe to copy a digest context using an ENGINE */
|
| - if (in->engine && !do_engine_init(in->engine))
|
| + if (in->engine && !ENGINE_init(in->engine))
|
| {
|
| EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
|
| return 0;
|
| @@ -381,13 +286,13 @@
|
| if (out->digest == in->digest)
|
| {
|
| tmp_buf = out->md_data;
|
| - M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
|
| + EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
|
| }
|
| else tmp_buf = NULL;
|
| EVP_MD_CTX_cleanup(out);
|
| memcpy(out,in,sizeof *out);
|
|
|
| - if (out->digest->ctx_size)
|
| + if (in->md_data && out->digest->ctx_size)
|
| {
|
| if (tmp_buf)
|
| out->md_data = tmp_buf;
|
| @@ -403,6 +308,18 @@
|
| memcpy(out->md_data,in->md_data,out->digest->ctx_size);
|
| }
|
|
|
| + out->update = in->update;
|
| +
|
| + if (in->pctx)
|
| + {
|
| + out->pctx = EVP_PKEY_CTX_dup(in->pctx);
|
| + if (!out->pctx)
|
| + {
|
| + EVP_MD_CTX_cleanup(out);
|
| + return 0;
|
| + }
|
| + }
|
| +
|
| if (out->digest->copy)
|
| return out->digest->copy(out,in);
|
|
|
| @@ -416,7 +333,7 @@
|
| int ret;
|
|
|
| EVP_MD_CTX_init(&ctx);
|
| - M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
|
| + 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);
|
| @@ -438,19 +355,21 @@
|
| * because sometimes only copies of the context are ever finalised.
|
| */
|
| if (ctx->digest && ctx->digest->cleanup
|
| - && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
|
| + && !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
|
| - && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
|
| + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
|
| {
|
| OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
|
| OPENSSL_free(ctx->md_data);
|
| }
|
| + if (ctx->pctx)
|
| + 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. */
|
| - do_engine_finish(ctx->engine);
|
| + ENGINE_finish(ctx->engine);
|
| #endif
|
| memset(ctx,'\0',sizeof *ctx);
|
|
|
|
|