Commit 97191932 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

New EVP sign and verify functionality.

parent e6fa7c12
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -4,6 +4,14 @@

 Changes between 0.9.8e and 0.9.8f-fips  [xx XXX xxxx]

  *) New flag EVP_MD_FLAG_SVCTX which passes EVP_MD_CTX and key to underlying
     sign/verify method. This permits the method to perform finalization
     and signing itself and have access to the EVP_MD_CTX structure in case
     additional parameters are needed. Modify fips_{dsa,rsa}_{sign,verify}
     to use EVP_MD_FLAG_SVCTX and support PSS and X9.31 RSA modes.
     Modify RSA algorithm test programs to use new parameters.
     [Steve Henson]

  *) Add small standalone ASN1 encoder/decoder to handle DSA signature format.
     Modify test, algorithm test and selftest routines to use EVP for DSA.
     Move FIPS implementation of EVP_sha*() and EVP_dss1() under fips-1.0.
+19 −0
Original line number Diff line number Diff line
@@ -254,11 +254,19 @@ typedef int evp_verify_method(int type,const unsigned char *m,
			    unsigned int m_length,const unsigned char *sigbuf,
			    unsigned int siglen, void *key);

typedef struct
	{
	EVP_MD_CTX *mctx;
	void *key;
	} EVP_MD_SVCTX;

#define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
					* block */

#define EVP_MD_FLAG_FIPS	0x0400 /* Note if suitable for use in FIPS mode */

#define EVP_MD_FLAG_SVCTX	0x0800 /* pass EVP_MD_SVCTX to sign/verify */

#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}

#ifndef OPENSSL_NO_DSA
@@ -312,6 +320,15 @@ struct env_md_ctx_st
#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
						 * in FIPS mode */

#define EVP_MD_CTX_FLAG_PAD_MASK	0xF0	/* RSA mode to use */
#define EVP_MD_CTX_FLAG_PAD_PKCS1	0x00	/* PKCS#1 v1.5 mode */
#define EVP_MD_CTX_FLAG_PAD_X931	0x10	/* X9.31 mode */
#define EVP_MD_CTX_FLAG_PAD_PSS		0x20	/* PSS mode */
#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
		((ctx->flags>>16) &0xFFFF) /* seed length */
#define EVP_MD_CTX_FLAG_PSS_MDLEN	0xFFFF	/* salt len same as digest */
#define EVP_MD_CTX_FLAG_PSS_MREC	0xFFFE	/* salt max or auto recovered */

struct evp_cipher_st
	{
	int nid;
@@ -448,6 +465,8 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
#define M_EVP_MD_type(e)			((e)->type)
#define M_EVP_MD_CTX_type(e)		M_EVP_MD_type(M_EVP_MD_CTX_md(e))
#define M_EVP_MD_CTX_md(e)			((e)->digest)


int EVP_MD_type(const EVP_MD *md);
+18 −6
Original line number Diff line number Diff line
@@ -84,10 +84,6 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
	MS_STATIC EVP_MD_CTX tmp_ctx;

	*siglen=0;
	EVP_MD_CTX_init(&tmp_ctx);
	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);   
	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
	EVP_MD_CTX_cleanup(&tmp_ctx);
	for (i=0; i<4; i++)
		{
		v=ctx->digest->required_pkey_type[i];
@@ -108,7 +104,23 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
		return(0);
		}
	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
		pkey->pkey.ptr));
	EVP_MD_CTX_init(&tmp_ctx);
	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
	if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
		{
		EVP_MD_SVCTX sctmp;
		sctmp.mctx = &tmp_ctx;
		sctmp.key = pkey->pkey.ptr;
		i = ctx->digest->sign(ctx->digest->type,
			NULL, -1, sigret, siglen, &sctmp);
		}
	else
		{
		EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
		i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
					pkey->pkey.ptr);
		}
	EVP_MD_CTX_cleanup(&tmp_ctx);
	return i;
	}
+19 −7
Original line number Diff line number Diff line
@@ -85,17 +85,29 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
		return(-1);
		}
	EVP_MD_CTX_init(&tmp_ctx);
	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
	EVP_MD_CTX_cleanup(&tmp_ctx);
	if (ctx->digest->verify == NULL)
                {
		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
		return(0);
		}

	return(ctx->digest->verify(ctx->digest->type,m,m_len,
		sigbuf,siglen,pkey->pkey.ptr));
	EVP_MD_CTX_init(&tmp_ctx);
	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
	if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
		{
		EVP_MD_SVCTX sctmp;
		sctmp.mctx = &tmp_ctx;
		sctmp.key = pkey->pkey.ptr;
		i = ctx->digest->verify(ctx->digest->type,
			NULL, -1, sigbuf, siglen, &sctmp);
		}
	else
		{
		EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
		i = ctx->digest->verify(ctx->digest->type,m,m_len,
					sigbuf,siglen,pkey->pkey.ptr);
		}
	EVP_MD_CTX_cleanup(&tmp_ctx);
	return i;
	}
+17 −7
Original line number Diff line number Diff line
@@ -177,11 +177,16 @@ int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen)
	return 1;
	}

static int fips_dsa_sign(int type, const unsigned char *dgst, int dlen,
		unsigned char *sig, unsigned int *siglen, DSA *dsa)
static int fips_dsa_sign(int type, const unsigned char *x, int y,
	     unsigned char *sig, unsigned int *siglen, EVP_MD_SVCTX *sv)
	{
	DSA *dsa = sv->key;
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int dlen;
	DSA_SIG *s;
	s=dsa->meth->dsa_do_sign(dgst,dlen,dsa);
        EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
	s=dsa->meth->dsa_do_sign(dig,dlen,dsa);
	OPENSSL_cleanse(dig, dlen);
	if (s == NULL)
		{
		*siglen=0;
@@ -194,18 +199,23 @@ static int fips_dsa_sign(int type, const unsigned char *dgst, int dlen,
	return 1;
	}

static int fips_dsa_verify(int type, const unsigned char *dgst, int dgst_len,
	     const unsigned char *sigbuf, int siglen, DSA *dsa)
static int fips_dsa_verify(int type, const unsigned char *x, int y,
	     const unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
	{
	DSA *dsa = sv->key;
	DSA_SIG *s;
	int ret=-1;
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int dlen;

	s = DSA_SIG_new();
	if (s == NULL)
		return ret;
	if (!FIPS_dsa_sig_decode(s,sigbuf,siglen))
		goto err;
	ret=dsa->meth->dsa_do_verify(dgst,dgst_len,s,dsa);
        EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
	ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
	OPENSSL_cleanse(dig, dlen);
err:
	DSA_SIG_free(s);
	return ret;
@@ -225,7 +235,7 @@ static const EVP_MD dss1_md=
	NID_dsa,
	NID_dsaWithSHA1,
	SHA_DIGEST_LENGTH,
	EVP_MD_FLAG_FIPS,
	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
	init,
	update,
	final,
Loading