summaryrefslogtreecommitdiffstats
path: root/crypto/evp/m_sigver.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2013-11-13 14:33:57 +0000
committerDr. Stephen Henson <steve@openssl.org>2013-11-13 23:48:35 +0000
commitafa23c46d966fc3862804612be999d403a755cd7 (patch)
tree020e0687b6acef46dba7bb02f2616eeb7cf066cc /crypto/evp/m_sigver.c
parent629b640bbc5391c6ac727aaa8465c5c5f99a5708 (diff)
Flag to disable automatic copying of contexts.
Some functions such as EVP_VerifyFinal only finalise a copy of the passed context in case an application wants to digest more data. Doing this when it is not needed is inefficient and many applications don't require it. For compatibility the default is to still finalise a copy unless the flag EVP_MD_CTX_FLAG_FINALISE is set in which case the passed context is finalised an *no* further data can be digested after finalisation.
Diffstat (limited to 'crypto/evp/m_sigver.c')
-rw-r--r--crypto/evp/m_sigver.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 664ed0c212..9f83d3e25f 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -140,14 +140,18 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
EVP_PKEY_CTX *pctx = ctx->pctx;
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
{
- EVP_PKEY_CTX *dctx;
if (!sigret)
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
- dctx = EVP_PKEY_CTX_dup(ctx->pctx);
- if (!dctx)
- return 0;
- r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
- EVP_PKEY_CTX_free(dctx);
+ if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
+ r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+ else
+ {
+ EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
+ if (!dctx)
+ return 0;
+ r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+ EVP_PKEY_CTX_free(dctx);
+ }
return r;
}
if (pctx->pmeth->signctx)
@@ -156,18 +160,29 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
sctx = 0;
if (sigret)
{
- EVP_MD_CTX tmp_ctx;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
- EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
- return 0;
- if (sctx)
- r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
- sigret, siglen, &tmp_ctx);
+ if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
+ {
+ if (sctx)
+ r = ctx->pctx->pmeth->signctx(ctx->pctx,
+ sigret, siglen, ctx);
+ else
+ r = EVP_DigestFinal_ex(ctx, md, &mdlen);
+ }
else
- r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
- EVP_MD_CTX_cleanup(&tmp_ctx);
+ {
+ EVP_MD_CTX tmp_ctx;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ return 0;
+ if (sctx)
+ r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
+ sigret, siglen, &tmp_ctx);
+ else
+ r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+ }
if (sctx || !r)
return r;
if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
@@ -192,7 +207,6 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
{
- EVP_MD_CTX tmp_ctx;
unsigned char md[EVP_MAX_MD_SIZE];
int r;
unsigned int mdlen;
@@ -202,17 +216,31 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
vctx = 1;
else
vctx = 0;
- EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
- return -1;
- if (vctx)
+ if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
{
- r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
- sig, siglen, &tmp_ctx);
+ if (vctx)
+ {
+ r = ctx->pctx->pmeth->verifyctx(ctx->pctx,
+ sig, siglen, ctx);
+ }
+ else
+ r = EVP_DigestFinal_ex(ctx, md, &mdlen);
}
else
- r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
- EVP_MD_CTX_cleanup(&tmp_ctx);
+ {
+ EVP_MD_CTX tmp_ctx;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ return -1;
+ if (vctx)
+ {
+ r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
+ sig, siglen, &tmp_ctx);
+ }
+ else
+ r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+ }
if (vctx || !r)
return r;
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);