Preliminary PSS support.

This commit is contained in:
Dr. Stephen Henson 2006-04-10 12:41:21 +00:00
parent 29db322e8f
commit a7ffd9d19c

View File

@ -79,8 +79,8 @@ typedef struct
int pad_mode; int pad_mode;
/* message digest */ /* message digest */
const EVP_MD *md; const EVP_MD *md;
/* PSS seedlength */ /* PSS/OAEP salt length */
int pss_seedlen; int saltlen;
/* Temp buffer */ /* Temp buffer */
unsigned char *tbuf; unsigned char *tbuf;
} RSA_PKEY_CTX; } RSA_PKEY_CTX;
@ -97,7 +97,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->md = NULL; rctx->md = NULL;
rctx->tbuf = NULL; rctx->tbuf = NULL;
rctx->pss_seedlen = 0; rctx->saltlen = -2;
ctx->data = rctx; ctx->data = rctx;
@ -132,6 +132,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
{ {
int ret; int ret;
RSA_PKEY_CTX *rctx = ctx->data; RSA_PKEY_CTX *rctx = ctx->data;
RSA *rsa = ctx->pkey->pkey.rsa;
if (rctx->md) if (rctx->md)
{ {
@ -149,19 +150,27 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
rctx->tbuf[tbslen] = rctx->tbuf[tbslen] =
RSA_X931_hash_id(EVP_MD_type(rctx->md)); RSA_X931_hash_id(EVP_MD_type(rctx->md));
ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
sig, ctx->pkey->pkey.rsa, sig, rsa, RSA_X931_PADDING);
RSA_X931_PADDING);
} }
else if (rctx->pad_mode == RSA_PKCS1_PADDING) else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{ {
unsigned int sltmp; unsigned int sltmp;
ret = RSA_sign(EVP_MD_type(rctx->md), ret = RSA_sign(EVP_MD_type(rctx->md),
tbs, tbslen, sig, &sltmp, tbs, tbslen, sig, &sltmp, rsa);
ctx->pkey->pkey.rsa);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
ret = sltmp; 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 else
return -1; return -1;
} }
@ -235,18 +244,34 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
const unsigned char *tbs, int tbslen) const unsigned char *tbs, int tbslen)
{ {
RSA_PKEY_CTX *rctx = ctx->data; RSA_PKEY_CTX *rctx = ctx->data;
RSA *rsa = ctx->pkey->pkey.rsa;
int rslen; int rslen;
if (rctx->md) if (rctx->md)
{ {
if (rctx->pad_mode == RSA_PKCS1_PADDING) if (rctx->pad_mode == RSA_PKCS1_PADDING)
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, 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 (rctx->pad_mode == RSA_X931_PADDING)
{ {
if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
sig, siglen) <= 0) sig, siglen) <= 0)
return 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 else
return -1; return -1;
} }
@ -255,7 +280,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
if (!setup_tbuf(rctx, ctx)) if (!setup_tbuf(rctx, ctx))
return -1; return -1;
rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
ctx->pkey->pkey.rsa, rctx->pad_mode); rsa, rctx->pad_mode);
if (rslen <= 0) if (rslen <= 0)
return 0; return 0;
} }
@ -298,6 +323,7 @@ static int check_padding_md(const EVP_MD *md, int padding)
{ {
if (!md) if (!md)
return 1; return 1;
if (padding == RSA_NO_PADDING) if (padding == RSA_NO_PADDING)
{ {
RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE); 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; return -2;
if (!check_padding_md(rctx->md, p1)) if (!check_padding_md(rctx->md, p1))
return 0; return 0;
if ((p1 == RSA_PKCS1_PSS_PADDING) if (p1 == RSA_PKCS1_PSS_PADDING)
&& !(ctx->operation & EVP_PKEY_OP_TYPE_SIG)) {
return -2; if (!(ctx->operation & EVP_PKEY_OP_TYPE_SIG))
if ((p1 == RSA_PKCS1_OAEP_PADDING) return -2;
&& !(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) if (!rctx->md)
return -2; 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; rctx->pad_mode = p1;
return 1; return 1;
} }