aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/evp/digest.c
diff options
context:
space:
mode:
authorGeoff Thorpe <geoff@openssl.org>2001-09-25 21:37:02 +0000
committerGeoff Thorpe <geoff@openssl.org>2001-09-25 21:37:02 +0000
commit11a57c7be519b8977cc345db1b51a3e596faaec4 (patch)
tree3d0eb9743f122e1dd061d989b911abfe1a0694ed /crypto/evp/digest.c
parentb370230b786eed9b73c9a1f5c0a5e008e8009989 (diff)
downloadopenssl-11a57c7be519b8977cc345db1b51a3e596faaec4.tar.gz
This changes EVP's cipher and digest code to hook via the ENGINE support.
See crypto/engine/README for details. - it also removes openbsd_hw.c from the build (that functionality is going to be available in the openbsd ENGINE in a upcoming commit) - evp_test has had the extra initialisation added so it will use (if possible) any ENGINEs supporting the algorithms required.
Diffstat (limited to 'crypto/evp/digest.c')
-rw-r--r--crypto/evp/digest.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 0143ab6f94..5178df6eb2 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -113,6 +113,7 @@
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
+#include <openssl/engine.h>
void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
@@ -130,6 +131,52 @@ EVP_MD_CTX *EVP_MD_CTX_create(void)
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
{
+ return EVP_DigestInit_ex(ctx, type, NULL);
+ }
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+ {
+ /* 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 EVP_MD could be used). */
+ if(ctx->engine)
+ ENGINE_finish(ctx->engine);
+ if(!impl)
+ /* Ask if an ENGINE is reserved for this job */
+ 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, type->type);
+ if(!d)
+ {
+ /* Same comment from evp_enc.c */
+ EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ /* We'll use the ENGINE's private digest definition */
+ type = d;
+ /* Store the ENGINE functional reference so we know
+ * 'type' came from an ENGINE and we need to release
+ * it when done. */
+ ctx->engine = impl;
+ }
+ else
+ ctx->engine = NULL;
+ }
+ else if(!ctx->digest)
+ {
+ EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_NO_DIGEST_SET);
+ return 0;
+ }
if (ctx->digest != type)
{
if (ctx->digest && ctx->digest->ctx_size)
@@ -138,6 +185,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
if (type->ctx_size)
ctx->md_data=OPENSSL_malloc(type->ctx_size);
}
+skip_to_init:
return type->init(ctx);
}
@@ -166,6 +214,12 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
EVPerr(EVP_F_EVP_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
return 0;
}
+ /* Make sure it's safe to copy a digest context using an ENGINE */
+ if (in->engine && !ENGINE_init(in->engine))
+ {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY,ERR_R_ENGINE_LIB);
+ return 0;
+ }
EVP_MD_CTX_cleanup(out);
memcpy(out,in,sizeof *out);
@@ -217,6 +271,10 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
memset(ctx->md_data,0,ctx->digest->ctx_size);
OPENSSL_free(ctx->md_data);
}
+ if(ctx->engine)
+ /* The EVP_MD we used belongs to an ENGINE, release the
+ * functional reference we held for this reason. */
+ ENGINE_finish(ctx->engine);
memset(ctx,'\0',sizeof *ctx);
return 1;