extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *rm, unsigned int *prm_len,
- unsigned char *sigbuf, unsigned int siglen,
+ const unsigned char *sigbuf, unsigned int siglen,
RSA *rsa);
/* RSA pkey context structure */
BIGNUM *pub_exp;
/* RSA padding mode */
int pad_mode;
- /* nid for message digest */
- int md_nid;
+ /* message digest */
+ const EVP_MD *md;
+ /* PSS seedlength */
+ int pss_seedlen;
/* Temp buffer */
unsigned char *tbuf;
} RSA_PKEY_CTX;
rctx->nbits = 1024;
rctx->pub_exp = NULL;
rctx->pad_mode = RSA_PKCS1_PADDING;
- rctx->md_nid = NID_undef;
+ rctx->md = NULL;
rctx->tbuf = NULL;
+ rctx->pss_seedlen = 0;
+
ctx->data = rctx;
return 1;
{
if (rctx->pub_exp)
BN_free(rctx->pub_exp);
+ if (rctx->tbuf)
+ OPENSSL_free(rctx->tbuf);
}
OPENSSL_free(rctx);
}
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
- unsigned char *tbs, int tbslen)
+ const unsigned char *tbs, int tbslen)
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- if (rctx->md_nid != NID_undef)
+ if (rctx->md)
{
-
+ if (tbslen != EVP_MD_size(rctx->md))
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN,
+ RSA_R_INVALID_DIGEST_LENGTH);
+ return -1;
+ }
if (rctx->pad_mode == RSA_X931_PADDING)
{
if (!setup_tbuf(rctx, ctx))
return -1;
memcpy(rctx->tbuf, tbs, tbslen);
- rctx->tbuf[tbslen] = RSA_X931_hash_id(rctx->md_nid);
+ 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);
else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{
unsigned int sltmp;
- ret = RSA_sign(rctx->md_nid, tbs, tbslen, sig, &sltmp,
+ ret = RSA_sign(EVP_MD_type(rctx->md),
+ tbs, tbslen, sig, &sltmp,
ctx->pkey->pkey.rsa);
+ if (ret <= 0)
+ return ret;
+ ret = sltmp;
}
else
return -1;
static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
- unsigned char *sig, int *siglen,
- unsigned char *tbs, int tbslen)
+ unsigned char *rout, int *routlen,
+ const unsigned char *sig, int siglen)
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- if (rctx->md_nid != NID_undef)
+ if (rctx->md)
{
if (rctx->pad_mode == RSA_X931_PADDING)
{
if (!setup_tbuf(rctx, ctx))
return -1;
- ret = RSA_private_encrypt(tbslen, tbs,
+ ret = RSA_public_decrypt(siglen, sig,
rctx->tbuf, ctx->pkey->pkey.rsa,
RSA_X931_PADDING);
if (ret < 1)
return 0;
- if (rctx->tbuf[ret] != RSA_X931_hash_id(rctx->md_nid))
+ ret--;
+ if (rctx->tbuf[ret] !=
+ RSA_X931_hash_id(EVP_MD_type(rctx->md)))
{
RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
RSA_R_ALGORITHM_MISMATCH);
return 0;
}
- ret--;
- memcpy(sig, rctx->tbuf, ret);
+ if (ret != EVP_MD_size(rctx->md))
+ {
+ RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+ RSA_R_INVALID_DIGEST_LENGTH);
+ return 0;
+ }
+ if (rout)
+ memcpy(rout, rctx->tbuf, ret);
}
else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{
unsigned int sltmp;
- ret = int_rsa_verify(rctx->md_nid, NULL, 0, sig, &sltmp,
- tbs, tbslen, ctx->pkey->pkey.rsa);
+ ret = int_rsa_verify(EVP_MD_type(rctx->md),
+ NULL, 0, rout, &sltmp,
+ sig, siglen, ctx->pkey->pkey.rsa);
+ ret = sltmp;
}
else
return -1;
}
else
- ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+ ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
rctx->pad_mode);
if (ret < 0)
return ret;
- *siglen = ret;
+ *routlen = ret;
return 1;
}
+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, int siglen,
+ const unsigned char *tbs, int tbslen)
+ {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ 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);
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
+ sig, siglen) <= 0)
+ return 0;
+ }
+ else
+ return -1;
+ }
+ else
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+ ctx->pkey->pkey.rsa, rctx->pad_mode);
+ if (rslen <= 0)
+ return 0;
+ }
+
+ if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
+ return 0;
+
+ return 1;
+
+ }
+
+
static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
- unsigned char *in, int inlen)
+ const unsigned char *in, int inlen)
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
}
static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
- unsigned char *in, int inlen)
+ const unsigned char *in, int inlen)
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
return 1;
}
-static int check_padding_nid(int nid, int padding)
+static int check_padding_md(const EVP_MD *md, int padding)
{
- if (nid == NID_undef)
+ if (!md)
return 1;
if (padding == RSA_NO_PADDING)
{
if (padding == RSA_X931_PADDING)
{
- if (RSA_X931_hash_id(nid) == -1)
+ if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
{
RSAerr(RSA_F_CHECK_PADDING_NID,
RSA_R_INVALID_X931_DIGEST);
switch (type)
{
case EVP_PKEY_CTRL_RSA_PADDING:
- /* TODO: add PSS support */
- if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_X931_PADDING))
+ if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
{
- if (ctx->operation == EVP_PKEY_OP_KEYGEN)
+ if (ctx->operation & EVP_PKEY_OP_TYPE_GEN)
return -2;
- if (!check_padding_nid(rctx->md_nid, p1))
+ 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;
rctx->pad_mode = p1;
return 1;
}
return -2;
- case EVP_PKEY_CTRL_MD_NID:
- if (!check_padding_nid(p1, rctx->pad_mode))
+ case EVP_PKEY_CTRL_MD:
+ if (!check_padding_md(p2, rctx->pad_mode))
return 0;
- rctx->md_nid = p1;
+ rctx->md = p2;
return 1;
default:
pm = RSA_PKCS1_OAEP_PADDING;
else if (!strcmp(value, "x931"))
pm = RSA_X931_PADDING;
+ else if (!strcmp(value, "pss"))
+ pm = RSA_PKCS1_PSS_PADDING;
else
return -2;
return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
0,
pkey_rsa_sign,
- 0,0,
+ 0,
+ pkey_rsa_verify,
0,
pkey_rsa_verifyrecover,