summaryrefslogtreecommitdiffstats
path: root/crypto/rsa/rsa_pmeth.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-04-10 12:41:21 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-04-10 12:41:21 +0000
commita7ffd9d19cd9bf2bf576e6eafa3c21ee7bd4bede (patch)
tree46f66f61782ac587755ada5e282de768e67a08fa /crypto/rsa/rsa_pmeth.c
parent29db322e8f2b0568322b80e3be28446463d74010 (diff)
Preliminary PSS support.
Diffstat (limited to 'crypto/rsa/rsa_pmeth.c')
-rw-r--r--crypto/rsa/rsa_pmeth.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 989a7d794d..f8ce45ca2e 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -79,8 +79,8 @@ typedef struct
int pad_mode;
/* message digest */
const EVP_MD *md;
- /* PSS seedlength */
- int pss_seedlen;
+ /* PSS/OAEP salt length */
+ int saltlen;
/* Temp buffer */
unsigned char *tbuf;
} RSA_PKEY_CTX;
@@ -97,7 +97,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->md = NULL;
rctx->tbuf = NULL;
- rctx->pss_seedlen = 0;
+ rctx->saltlen = -2;
ctx->data = rctx;
@@ -132,6 +132,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
if (rctx->md)
{
@@ -149,19 +150,27 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
rctx->tbuf[tbslen] =
RSA_X931_hash_id(EVP_MD_type(rctx->md));
ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
- sig, ctx->pkey->pkey.rsa,
- RSA_X931_PADDING);
+ sig, rsa, RSA_X931_PADDING);
}
else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{
unsigned int sltmp;
ret = RSA_sign(EVP_MD_type(rctx->md),
- tbs, tbslen, sig, &sltmp,
- ctx->pkey->pkey.rsa);
+ tbs, tbslen, sig, &sltmp, rsa);
if (ret <= 0)
return ret;
ret = sltmp;
}
+ else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
+ rctx->md, rctx->saltlen))
+ return -1;
+ ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+ sig, rsa, RSA_NO_PADDING);
+ }
else
return -1;
}
@@ -235,18 +244,34 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
const unsigned char *tbs, int tbslen)
{
RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
int rslen;
if (rctx->md)
{
if (rctx->pad_mode == RSA_PKCS1_PADDING)
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
- sig, siglen, ctx->pkey->pkey.rsa);
+ sig, siglen, rsa);
if (rctx->pad_mode == RSA_X931_PADDING)
{
if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
sig, siglen) <= 0)
return 0;
}
+ else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+ {
+ int ret;
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+ rsa, RSA_NO_PADDING);
+ if (ret <= 0)
+ return 0;
+ ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
+ rctx->tbuf, rctx->saltlen);
+ if (ret <= 0)
+ return 0;
+ return 1;
+ }
else
return -1;
}
@@ -255,7 +280,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
if (!setup_tbuf(rctx, ctx))
return -1;
rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
- ctx->pkey->pkey.rsa, rctx->pad_mode);
+ rsa, rctx->pad_mode);
if (rslen <= 0)
return 0;
}
@@ -298,6 +323,7 @@ static int check_padding_md(const EVP_MD *md, int padding)
{
if (!md)
return 1;
+
if (padding == RSA_NO_PADDING)
{
RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE);
@@ -331,12 +357,20 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return -2;
if (!check_padding_md(rctx->md, p1))
return 0;
- if ((p1 == RSA_PKCS1_PSS_PADDING)
- && !(ctx->operation & EVP_PKEY_OP_TYPE_SIG))
- return -2;
- if ((p1 == RSA_PKCS1_OAEP_PADDING)
- && !(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
- return -2;
+ if (p1 == RSA_PKCS1_PSS_PADDING)
+ {
+ if (!(ctx->operation & EVP_PKEY_OP_TYPE_SIG))
+ return -2;
+ if (!rctx->md)
+ rctx->md = EVP_sha1();
+ }
+ if (p1 == RSA_PKCS1_OAEP_PADDING)
+ {
+ if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+ return -2;
+ if (!rctx->md)
+ rctx->md = EVP_sha1();
+ }
rctx->pad_mode = p1;
return 1;
}