diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2007-04-11 14:33:06 +0200 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2007-04-11 14:33:06 +0200 |
commit | 74633553a912519a6e73a9d830132e58f420a6c9 (patch) | |
tree | ad4b498680c993039f5b6371fd53c0091c828801 /crypto/evp | |
parent | Constification. (diff) | |
download | openssl-74633553a912519a6e73a9d830132e58f420a6c9.tar.xz openssl-74633553a912519a6e73a9d830132e58f420a6c9.zip |
Experimental HMAC support via EVP_PKEY_METHOD.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/digest.c | 19 | ||||
-rw-r--r-- | crypto/evp/evp.h | 8 | ||||
-rw-r--r-- | crypto/evp/m_sigver.c | 44 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 6 |
4 files changed, 57 insertions, 20 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 256efd6e9d..095774bf62 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -198,19 +198,32 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) 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); + } } #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; return ctx->digest->init(ctx); } int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { - 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 */ @@ -272,7 +285,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) 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 out->md_data=OPENSSL_malloc(out->digest->ctx_size); diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 8a7218fa09..b2fb2a6a4b 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -115,6 +115,7 @@ #define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 #define EVP_PKEY_DH NID_dhKeyAgreement #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_HMAC NID_hmac #ifdef __cplusplus extern "C" { @@ -266,6 +267,8 @@ struct env_md_ctx_st void *md_data; /* Public key context for sign/verify */ EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count); } /* EVP_MD_CTX */; /* values for EVP_MD_CTX flags */ @@ -276,6 +279,7 @@ struct env_md_ctx_st * cleaned */ #define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ +#define EVP_MD_CTX_FLAG_NO_INIT 0x0008 /* Don't initialized md_data */ /* MD operational flags */ @@ -997,6 +1001,10 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, #define EVP_PKEY_CTRL_PKCS7_SIGN 5 +#define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +#define EVP_PKEY_CTRL_DIGESTINIT 7 + #define EVP_PKEY_ALG_CTRL 0x1000 #define EVP_PKEY_FLAG_AUTOARGLEN 2 diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 6ab71907ab..8fdfe61b3f 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -67,7 +67,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, int ver) { - int r = 0; if (ctx->pctx == NULL) ctx->pctx = EVP_PKEY_CTX_new(pkey, e); if (ctx->pctx == NULL) @@ -76,9 +75,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, { if (ctx->pctx->pmeth->verifyctx_init) { - r = ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx); - if (r <= 0) + if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0) return 0; + ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) return 0; @@ -87,18 +86,18 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, { if (ctx->pctx->pmeth->signctx_init) { - r = ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx); - if (r <= 0) + if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) return 0; + ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; } - if (EVP_PKEY_sign_init(ctx->pctx) <= 0) + else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) return 0; } if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) return 0; if (pctx) *pctx = ctx->pctx; - if ((r != 2) && !EVP_DigestInit_ex(ctx, type, e)) + if (!EVP_DigestInit_ex(ctx, type, e)) return 0; return 1; } @@ -118,7 +117,11 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { - int r; + int sctx, r = 0; + if (ctx->pctx->pmeth->signctx) + sctx = 1; + else + sctx = 0; if (sigret) { MS_STATIC EVP_MD_CTX tmp_ctx; @@ -127,20 +130,26 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) return 0; - if (tmp_ctx.pctx->pmeth->signctx) + 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 (!r) - return 0; + if (sctx || !r) + return r; if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) return 0; } else { - if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, + if (sctx) + { + if (ctx->pctx->pmeth->signctx(ctx->pctx, + sigret, siglen, ctx) <= 0) + return 0; + } + else if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, EVP_MD_size(ctx->digest)) <= 0) return 0; } @@ -153,10 +162,15 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) unsigned char md[EVP_MAX_MD_SIZE]; int r; unsigned int mdlen; + int vctx; + if (ctx->pctx->pmeth->signctx) + vctx = 1; + else + vctx = 0; EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) return -1; - if (tmp_ctx.pctx->pmeth->verifyctx) + if (vctx) { r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, siglen, &tmp_ctx); @@ -164,7 +178,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) else r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen); EVP_MD_CTX_cleanup(&tmp_ctx); - if (!r) - return -1; + if (vctx || !r) + return r; return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 500aad967b..6abb951d0c 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -70,14 +70,16 @@ typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); STACK *app_pkey_methods = NULL; -extern EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth, ec_pkey_meth; +extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth; static const EVP_PKEY_METHOD *standard_methods[] = { &rsa_pkey_meth, &dh_pkey_meth, &dsa_pkey_meth, - &ec_pkey_meth + &ec_pkey_meth, + &hmac_pkey_meth, }; static int pmeth_cmp(const EVP_PKEY_METHOD * const *a, |