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); |