diff options
author | Geoff Thorpe <geoff@openssl.org> | 2001-09-25 21:37:02 +0000 |
---|---|---|
committer | Geoff Thorpe <geoff@openssl.org> | 2001-09-25 21:37:02 +0000 |
commit | 11a57c7be519b8977cc345db1b51a3e596faaec4 (patch) | |
tree | 3d0eb9743f122e1dd061d989b911abfe1a0694ed /crypto/evp/digest.c | |
parent | b370230b786eed9b73c9a1f5c0a5e008e8009989 (diff) | |
download | openssl-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.c | 58 |
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; |