summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2007-04-11 14:33:06 +0200
committerDr. Stephen Henson <steve@openssl.org>2007-04-11 14:33:06 +0200
commit74633553a912519a6e73a9d830132e58f420a6c9 (patch)
treead4b498680c993039f5b6371fd53c0091c828801 /crypto/evp
parentConstification. (diff)
downloadopenssl-74633553a912519a6e73a9d830132e58f420a6c9.tar.xz
openssl-74633553a912519a6e73a9d830132e58f420a6c9.zip
Experimental HMAC support via EVP_PKEY_METHOD.
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/digest.c19
-rw-r--r--crypto/evp/evp.h8
-rw-r--r--crypto/evp/m_sigver.c44
-rw-r--r--crypto/evp/pmeth_lib.c6
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,