Steve, all,

just some quick status update.

Thus wrote Dr. Stephen Henson (st...@openssl.org):

> EVP_PKEY_CTX was introduced (by me!) to contain parameters relating to
> a specific cryptographic operation. Fixed parameters should go in
> EVP_PKEY. PSS can have both so we'd need a new EVP_PKEY type and/or
> expand the RSA structure too.

In the pss certificates I've seen so far, the rsa public key is not
different from certificates with pkcs1.5 signature. All pss parameters
are encoded in the signature itself. Therefore, I don't think I can
distinguish pss and pkcs1.5 before entering ASN1_item_verify.

One approach I could get to work is as follows:

sha1_md is hard-wired to pkcs1.5 signature. I created a new sha1Pss_md
that can be used for pss. It has an md_ctrl function that reads the pss
parameters from the certificate and stores them in the evp_pkey_ctx
that's used for the signature verification.

An entry in obj_xref.txt links pss to an rsa key and the sha1Pss.

This works ok without hard-coding any NIDs. The only drawback is that
pss supports only sha1 in this approach. (Sha1 is the default anyway.
Other hashes could be used with pss but I've never seen this).

> Use of the ctrl mechanism will require some changes to ASN1_item_sign
> and ASN1_item_verify. The current code uses EVP_Sign*() and
> EVP_Verify*() which isn't flexible enough the new EVP_Digest*() API
> will need to be used instead.

Ok, I use EVP_DigestVerify.. now.

I've attached another preliminary patch that shows this idea. Please
let me know if that approach makes sense to you.

Best regards,

   Martin
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index cecdb13..085a746 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -129,14 +129,15 @@ err:
 int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature,
 	     void *asn, EVP_PKEY *pkey)
 	{
-	EVP_MD_CTX ctx;
-	const EVP_MD *type = NULL;
+	EVP_MD_CTX mctx;
+	const EVP_MD *md = NULL;
 	unsigned char *buf_in=NULL;
 	int ret= -1,inl;
+   EVP_PKEY_CTX *pctx;
 
 	int mdnid, pknid;
 
-	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_init(&mctx);
 
 	/* Convert signature OID into digest and public key OIDs */
 	if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
@@ -144,8 +145,8 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
 		goto err;
 		}
-	type=EVP_get_digestbynid(mdnid);
-	if (type == NULL)
+	md=EVP_get_digestbynid(mdnid);
+	if (md == NULL)
 		{
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
 		goto err;
@@ -158,13 +159,18 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
 		goto err;
 		}
 
-	if (!EVP_VerifyInit_ex(&ctx,type, NULL))
+	if (!EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, pkey))
 		{
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
 		ret=0;
 		goto err;
 		}
 
+   if (md && md->md_ctrl)
+      {
+      md->md_ctrl(&mctx, EVP_MD_CTRL_SET_PCTX_PARAMS, 0, (void *)a->parameter);
+      }
+
 	inl = ASN1_item_i2d(asn, &buf_in, it);
 	
 	if (buf_in == NULL)
@@ -173,24 +179,24 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
 		goto err;
 		}
 
-	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
+	EVP_DigestVerifyUpdate(&mctx,(unsigned char *)buf_in,inl);
 
 	OPENSSL_cleanse(buf_in,(unsigned int)inl);
 	OPENSSL_free(buf_in);
 
-	if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
-			(unsigned int)signature->length,pkey) <= 0)
+	if (EVP_DigestVerifyFinal(&mctx,(unsigned char *)signature->data,
+			(unsigned int)signature->length) <= 0)
 		{
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
 		ret=0;
 		goto err;
 		}
-	/* we don't need to zero the 'ctx' because we just checked
+	/* we don't need to zero the 'mctx' because we just checked
 	 * public information */
-	/* memset(&ctx,0,sizeof(ctx)); */
+	/* memset(&mctx,0,sizeof(mctx)); */
 	ret=1;
 err:
-	EVP_MD_CTX_cleanup(&ctx);
+	EVP_MD_CTX_cleanup(&mctx);
 	return(ret);
 	}
 
diff --git a/crypto/evp/c_alld.c b/crypto/evp/c_alld.c
index 5032e7c..cee322d 100644
--- a/crypto/evp/c_alld.c
+++ b/crypto/evp/c_alld.c
@@ -85,6 +85,7 @@ void OpenSSL_add_all_digests(void)
 	EVP_add_digest(EVP_sha1());
 	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
 	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
+	EVP_add_digest(EVP_sha1Pss());
 #ifndef OPENSSL_NO_DSA
 	EVP_add_digest(EVP_dss1());
 	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index 4eecdbe..7260301 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -224,6 +224,7 @@ typedef int evp_verify_method(int type,const unsigned char *m,
 /* Minimum Algorithm specific ctrl value */
 
 #define	EVP_MD_CTRL_ALG_CTRL			0x1000
+#define	EVP_MD_CTRL_SET_PCTX_PARAMS  (EVP_MD_CTRL_ALG_CTRL + 0x10)
 
 #define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
 
diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c
index 9a2790f..aa11456 100644
--- a/crypto/evp/m_sha1.c
+++ b/crypto/evp/m_sha1.c
@@ -97,6 +97,51 @@ const EVP_MD *EVP_sha1(void)
 	{
 	return(&sha1_md);
 	}
+
+
+int sha1Pss_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
+   {
+   ASN1_TYPE *at;
+
+   printf("sha1Pss_ctrl()\n");
+
+   if (cmd == EVP_MD_CTRL_SET_PCTX_PARAMS)
+      {
+      if (!ctx->pctx)
+         return -1;
+
+      printf("set PSS padding\n");
+      EVP_PKEY_CTX_set_rsa_padding(ctx->pctx, RSA_PKCS1_PSS_PADDING);
+
+      if (p2)
+         at = (ASN1_TYPE *)p2;
+      } 
+
+  /* TODO: what should this function return in case of ok, error? */
+   return 0;
+   }
+
+static const EVP_MD sha1Pss_md=
+	{
+	NID_sha1Pss,
+	NID_rsaSsaPss,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_DIGEST,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+   sha1Pss_ctrl
+	};
+
+const EVP_MD *EVP_sha1Pss(void)
+	{
+	return(&sha1Pss_md);
+	}
 #endif
 
 #ifndef OPENSSL_NO_SHA256
diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt
index e45b3d3..0117cfa 100644
--- a/crypto/objects/obj_xref.txt
+++ b/crypto/objects/obj_xref.txt
@@ -6,6 +6,7 @@ md2WithRSAEncryption	md2	rsaEncryption
 md5WithRSAEncryption	md5	rsaEncryption
 shaWithRSAEncryption	sha	rsaEncryption
 sha1WithRSAEncryption	sha1	rsaEncryption
+rsaSsaPss      sha1Pss    rsaEncryption
 md4WithRSAEncryption	md4	rsaEncryption
 sha256WithRSAEncryption sha256	rsaEncryption
 sha384WithRSAEncryption	sha384	rsaEncryption
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index 52ac0a6..45ddb59 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -166,6 +166,8 @@ pkcs1 3			: RSA-MD4		: md4WithRSAEncryption
 pkcs1 4			: RSA-MD5		: md5WithRSAEncryption
 pkcs1 5			: RSA-SHA1		: sha1WithRSAEncryption
 # According to PKCS #1 version 2.1
+pkcs1 8		: MGF1				: mgf1
+pkcs1 10		: RSASSA-PSS		: rsaSsaPss
 pkcs1 11		: RSA-SHA256		: sha256WithRSAEncryption
 pkcs1 12		: RSA-SHA384		: sha384WithRSAEncryption
 pkcs1 13		: RSA-SHA512		: sha512WithRSAEncryption
@@ -645,6 +647,7 @@ algorithm 17		: DES-EDE		: des-ede
 			: DESX-CBC		: desx-cbc
 algorithm 18		: SHA			: sha
 algorithm 26		: SHA1			: sha1
+						: SHA1PSS		: sha1Pss
 !Cname dsaWithSHA1-2
 algorithm 27		: DSA-SHA1-old		: dsaWithSHA1-old
 algorithm 29		: RSA-SHA1-2		: sha1WithRSA

Reply via email to