summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/evp/digest.c
diff options
context:
space:
mode:
authorGary Ching-Pang Lin <glin@suse.com>2015-07-28 11:46:38 -0400
committerPeter Jones <pjones@redhat.com>2015-07-28 11:46:38 -0400
commit5ce38c90cf43ee79cd999716ea83a5a44eeb819e (patch)
tree2fb3d9dd667c772fae5f87fa61e1501cf12da0ce /Cryptlib/OpenSSL/crypto/evp/digest.c
parent69ba24ff72921ecabbb47178de40dc5a79350040 (diff)
downloadefi-boot-shim-5ce38c90cf43ee79cd999716ea83a5a44eeb819e.tar.gz
efi-boot-shim-5ce38c90cf43ee79cd999716ea83a5a44eeb819e.zip
Update openssl to 1.0.2d
Also update Cryptlib to edk2 r17731 Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/evp/digest.c')
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/digest.c248
1 files changed, 97 insertions, 151 deletions
diff --git a/Cryptlib/OpenSSL/crypto/evp/digest.c b/Cryptlib/OpenSSL/crypto/evp/digest.c
index 9f5ee7b9..f2643f32 100644
--- a/Cryptlib/OpenSSL/crypto/evp/digest.c
+++ b/Cryptlib/OpenSSL/crypto/evp/digest.c
@@ -116,7 +116,11 @@
#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif
-#include "evp_locl.h"
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include "evp_locl.h"
+#endif
void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
@@ -139,93 +143,33 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
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)
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
{
- FIPS_ERROR_IGNORED("Digest Final");
- return 0;
-}
-
-static const EVP_MD bad_md = {
- 0,
- 0,
- 0,
- 0,
- bad_init,
- bad_update,
- bad_final,
- NULL,
- NULL,
- NULL,
- 0,
- {0, 0, 0, 0},
-};
-
+ EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+#ifdef OPENSSL_FIPS
+ /* If FIPS mode switch to approved implementation if possible */
+ if (FIPS_mode()) {
+ const EVP_MD *fipsmd;
+ if (type) {
+ fipsmd = evp_get_fips_md(type);
+ if (fipsmd)
+ type = fipsmd;
+ }
+ }
#endif
-
#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 ENGINE and
@@ -235,23 +179,23 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype,
ENGINE_finish(ctx->engine);
if (impl) {
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.
@@ -259,59 +203,22 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype,
ctx->engine = impl;
} else
ctx->engine = NULL;
- } else if (!ctx->digest) {
- EVPerr(EVP_F_DO_EVP_MD_ENGINE, 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;
+ } else {
+ if (!ctx->digest) {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
+ return 0;
+ }
+ type = ctx->digest;
}
#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);
return 0;
}
@@ -320,15 +227,34 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
#ifndef OPENSSL_NO_ENGINE
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;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ if (FIPS_digestinit(ctx, type))
+ return 1;
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ return 0;
+ }
+#endif
return ctx->digest->init(ctx);
}
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
#ifdef OPENSSL_FIPS
- FIPS_selftest_check();
+ return FIPS_digestupdate(ctx, data, count);
+#else
+ return ctx->update(ctx, data, count);
#endif
- return ctx->digest->update(ctx, data, count);
}
/* The caller can assume that this removes any secret data from the context */
@@ -343,10 +269,10 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
- int ret;
#ifdef OPENSSL_FIPS
- FIPS_selftest_check();
-#endif
+ return FIPS_digestfinal(ctx, md, size);
+#else
+ int ret;
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
ret = ctx->digest->final(ctx, md);
@@ -354,10 +280,11 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
*size = ctx->digest->md_size;
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;
+#endif
}
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
@@ -375,7 +302,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
}
#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;
}
@@ -383,13 +310,13 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
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;
else {
@@ -402,6 +329,16 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
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 +353,7 @@ int EVP_Digest(const void *data, size_t count,
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);
@@ -427,32 +364,41 @@ int EVP_Digest(const void *data, size_t count,
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
{
- EVP_MD_CTX_cleanup(ctx);
- OPENSSL_free(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)
{
+#ifndef OPENSSL_FIPS
/*
* 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
- && !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);
}
+#endif
+ 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
+#ifdef OPENSSL_FIPS
+ FIPS_md_ctx_cleanup(ctx);
#endif
memset(ctx, '\0', sizeof *ctx);