From: Dr. Stephen Henson Date: Tue, 3 Apr 2007 21:01:29 +0000 (+0000) Subject: New EVP sign and verify functionality. X-Git-Tag: FIPS_098_TEST_1~35 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=971919322282f081fb8403e273aa15a72f162d92;p=oweals%2Fopenssl.git New EVP sign and verify functionality. --- diff --git a/CHANGES b/CHANGES index cbeaf193dc..221ce1efd8 100644 --- a/CHANGES +++ b/CHANGES @@ -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. diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 1ac619c087..a0b4636b47 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -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); diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index e4ae5906f5..bf41a0db68 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -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; } diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index 21a40a375e..2d46dffe7e 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -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) + 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; } diff --git a/fips-1.0/dsa/fips_dsa_sign.c b/fips-1.0/dsa/fips_dsa_sign.c index 5bedc66bda..1707ff39b2 100644 --- a/fips-1.0/dsa/fips_dsa_sign.c +++ b/fips-1.0/dsa/fips_dsa_sign.c @@ -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, diff --git a/fips-1.0/rsa/fips_rsa_sign.c b/fips-1.0/rsa/fips_rsa_sign.c index b9880741a5..797c3c08c4 100644 --- a/fips-1.0/rsa/fips_rsa_sign.c +++ b/fips-1.0/rsa/fips_rsa_sign.c @@ -126,107 +126,207 @@ static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len) } } -static int fips_rsa_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, RSA *rsa) +static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y, + unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv) { - int i,j,ret=1; + int i,j,ret=0; unsigned int dlen; const unsigned char *der; + unsigned int m_len; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode; + RSA *rsa = sv->key; /* Largest DigestInfo: 19 (max encoding) + max MD */ unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE + 1]; + + EVP_DigestFinal_ex(sv->mctx, md, &m_len); + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { - return rsa->meth->rsa_sign(type, m, m_len, + ret = rsa->meth->rsa_sign(type, md, m_len, sigret, siglen, rsa); + goto done; } - if(m_len > EVP_MAX_MD_SIZE) + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) { - RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH); - return 0; + memcpy(tmpdinfo, md, m_len); + tmpdinfo[m_len] = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)); + i = m_len + 1; + rsa_pad_mode = RSA_X931_PADDING; } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { - der = fips_digestinfo_encoding(type, &dlen); - - if (!der) + der = fips_digestinfo_encoding(type, &dlen); + + if (!der) + { + RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return(0); + } + memcpy(tmpdinfo, der, dlen); + memcpy(tmpdinfo + dlen, md, m_len); + + i = dlen + m_len; + rsa_pad_mode = RSA_PKCS1_PADDING; + + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) { - RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); - return(0); + unsigned char *sbuf; + int saltlen; + i = RSA_size(rsa); + sbuf = OPENSSL_malloc(RSA_size(rsa)); + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (!sbuf) + { + RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE); + goto psserr; + } + if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md, + M_EVP_MD_CTX_md(sv->mctx), saltlen)) + goto psserr; + j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING); + if (j > 0) + { + ret=1; + *siglen=j; + } + psserr: + OPENSSL_cleanse(md,m_len); + OPENSSL_cleanse(sbuf, i); + OPENSSL_free(sbuf); + return ret; } - memcpy(tmpdinfo, der, dlen); - memcpy(tmpdinfo + dlen, m, m_len); - - i = dlen + m_len; j=RSA_size(rsa); if (i > (j-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); - return(0); + goto done; } /* NB: call underlying method directly to avoid FIPS blocking */ - j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,RSA_PKCS1_PADDING); - if (j <= 0) - ret=0; - else + j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode); + if (j > 0) + { + ret=1; *siglen=j; + } + done: OPENSSL_cleanse(tmpdinfo,i); - return(ret); + OPENSSL_cleanse(md,m_len); + return ret; } static int fips_rsa_verify(int dtype, - const unsigned char *m, unsigned int m_len, - unsigned char *sigbuf, unsigned int siglen, RSA *rsa) + const unsigned char *x, unsigned int y, + unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv) { int i,ret=0; - unsigned int dlen; + unsigned int dlen, diglen; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode; unsigned char *s; const unsigned char *der; + unsigned char dig[EVP_MAX_MD_SIZE]; + RSA *rsa = sv->key; - if (siglen != (unsigned int)RSA_size(rsa)) + if (siglen != (unsigned int)RSA_size(sv->key)) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } + EVP_DigestFinal_ex(sv->mctx, dig, &diglen); + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { - return rsa->meth->rsa_verify(dtype, m, m_len, + return rsa->meth->rsa_verify(dtype, dig, diglen, sigbuf, siglen, rsa); } + s= OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + rsa_pad_mode = RSA_X931_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + rsa_pad_mode = RSA_PKCS1_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + rsa_pad_mode = RSA_NO_PADDING; /* NB: call underlying method directly to avoid FIPS blocking */ - i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); + i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode); if (i <= 0) goto err; - der = fips_digestinfo_encoding(dtype, &dlen); - - if (!der) + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) { - RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); - return(0); + if (i != diglen + 1) + { + RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + if (s[diglen] != RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx))) + { + RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + if (memcmp(s, dig, diglen)) + { + RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { + + der = fips_digestinfo_encoding(dtype, &dlen); + + if (!der) + { + RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return(0); + } + + /* Compare, DigestInfo length, DigestInfo header and finally + * digest value itself + */ + if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen) + || memcmp(s + dlen, dig, diglen)) + { + RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + else + ret = 1; - /* Compare, DigestInfo length, DigestInfo header and finally - * digest value itself - */ - if ((i != (int)(dlen + m_len)) || memcmp(der, s, dlen) - || memcmp(s + dlen, m, m_len)) + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); - goto err; + int saltlen; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx), + s, saltlen); + if (ret < 0) + ret = 0; } - else - ret = 1; err: if (s != NULL) { @@ -255,7 +355,7 @@ static const EVP_MD sha1_md= NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, init, update, final, @@ -290,7 +390,7 @@ static const EVP_MD sha224_md= NID_sha224, NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, init224, update256, final256, @@ -309,7 +409,7 @@ static const EVP_MD sha256_md= NID_sha256, NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, init256, update256, final256, @@ -338,7 +438,7 @@ static const EVP_MD sha384_md= NID_sha384, NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, init384, update512, final512, @@ -357,7 +457,7 @@ static const EVP_MD sha512_md= NID_sha512, NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_FIPS, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, init512, update512, final512, diff --git a/fips-1.0/rsa/fips_rsastest.c b/fips-1.0/rsa/fips_rsastest.c index a73c9a1d65..da78f20671 100644 --- a/fips-1.0/rsa/fips_rsastest.c +++ b/fips-1.0/rsa/fips_rsastest.c @@ -336,46 +336,19 @@ static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, EVP_MD_CTX_init(&ctx); - if (Saltlen != -1) + if (Saltlen >= 0) { - unsigned int mdlen; - unsigned char mdtmp[EVP_MAX_MD_SIZE + 1]; - - if (!EVP_DigestInit_ex(&ctx, dgst, NULL)) - goto error; - if (!EVP_DigestUpdate(&ctx, Msg, Msglen)) - goto error; - if (!EVP_DigestFinal(&ctx, mdtmp, &mdlen)) - goto error; - - if (Saltlen == -2) - { - mdtmp[mdlen] = RSA_X931_hash_id(M_EVP_MD_type(dgst)); - siglen = RSA_private_encrypt(mdlen + 1, mdtmp, - sigbuf, rsa, RSA_X931_PADDING); - if (siglen <= 0) - goto error; - } - else - { - if (!RSA_padding_add_PKCS1_PSS(rsa, sigbuf, mdtmp, - dgst, Saltlen)) - goto error; - siglen = RSA_private_encrypt(siglen, sigbuf, sigbuf, - rsa, RSA_NO_PADDING); - if (siglen <= 0) - goto error; - } - } - else - { - if (!EVP_SignInit_ex(&ctx, dgst, NULL)) - goto error; - if (!EVP_SignUpdate(&ctx, Msg, Msglen)) - goto error; - if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) - goto error; + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_SignInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_SignUpdate(&ctx, Msg, Msglen)) + goto error; + if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) + goto error; EVP_MD_CTX_cleanup(&ctx); diff --git a/fips-1.0/rsa/fips_rsavtest.c b/fips-1.0/rsa/fips_rsavtest.c index 028d79f72f..edfa0cfbbf 100644 --- a/fips-1.0/rsa/fips_rsavtest.c +++ b/fips-1.0/rsa/fips_rsavtest.c @@ -336,58 +336,20 @@ static int rsa_printver(FILE *out, EVP_MD_CTX_init(&ctx); - if (Saltlen != -1) + if (Saltlen >= 0) { - int pad; - unsigned char mdtmp[EVP_MAX_MD_SIZE]; - buf = OPENSSL_malloc(RSA_size(rsa_pubkey)); - if (Saltlen == -2) - pad = RSA_X931_PADDING; - else - pad = RSA_NO_PADDING; - if (!buf) - goto error; - r = RSA_public_decrypt(Slen, S, buf, rsa_pubkey, pad); - - if (r > 0) - { - EVP_DigestInit_ex(&ctx, dgst, NULL); - if (!EVP_DigestUpdate(&ctx, Msg, Msglen)) - goto error; - if (!EVP_DigestFinal_ex(&ctx, mdtmp, NULL)) - goto error; - if (pad == RSA_X931_PADDING) - { - int mdlen = M_EVP_MD_size(dgst); - if (r != mdlen + 1) - r = 0; - else if (buf[mdlen] != - RSA_X931_hash_id(M_EVP_MD_type(dgst))) - r = 0; - else if (memcmp(buf, mdtmp, mdlen)) - r = 0; - else - r = 1; - } - else - r = RSA_verify_PKCS1_PSS(rsa_pubkey, - mdtmp, dgst, - buf, Saltlen); - } - if (r < 0) - r = 0; + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); } - else - { - - if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) - goto error; - if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) - goto error; + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) + goto error; - r = EVP_VerifyFinal(&ctx, S, Slen, &pk); + r = EVP_VerifyFinal(&ctx, S, Slen, &pk); - } EVP_MD_CTX_cleanup(&ctx);