} RSA_PKEY_CTX;
/* True if PSS parameters are restricted */
-#define rsa_pss_param(rctx) (rctx->min_saltlen != -1)
+#define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1)
static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
{
- RSA_PKEY_CTX *rctx;
- rctx = OPENSSL_zalloc(sizeof(*rctx));
+ RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx));
+
if (rctx == NULL)
return 0;
rctx->nbits = 1024;
rctx->pad_mode = RSA_PKCS1_PSS_PADDING;
else
rctx->pad_mode = RSA_PKCS1_PADDING;
- rctx->saltlen = -2;
+ /* Maximum for sign, auto for verify */
+ rctx->saltlen = RSA_PSS_SALTLEN_AUTO;
rctx->min_saltlen = -1;
ctx->data = rctx;
ctx->keygen_info = rctx->gentmp;
static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
RSA_PKEY_CTX *dctx, *sctx;
+
if (!pkey_rsa_init(dst))
return 0;
sctx = src->data;
static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
{
- if (ctx->tbuf)
+ if (ctx->tbuf != NULL)
return 1;
ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
if (ctx->tbuf == NULL)
RSA_PKEY_CTX *rctx = ctx->data;
RSA *rsa = ctx->pkey->pkey.rsa;
size_t rslen;
+
if (rctx->md) {
if (rctx->pad_mode == RSA_PKCS1_PADDING)
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
+
if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
int klen = RSA_size(ctx->pkey->pkey.rsa);
if (!setup_tbuf(rctx, ctx))
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
+
if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
int i;
if (!setup_tbuf(rctx, ctx))
static int check_padding_md(const EVP_MD *md, int padding)
{
int mdnid;
+
if (!md)
return 1;
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
RSA_PKEY_CTX *rctx = ctx->data;
+
switch (type) {
case EVP_PKEY_CTRL_RSA_PADDING:
if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) {
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
*(int *)p2 = rctx->saltlen;
} else {
- if (p1 < -2)
+ if (p1 < RSA_PSS_SALTLEN_MAX)
return -2;
- if (rsa_pss_param(rctx) && p1 < rctx->min_saltlen) {
- RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_PSS_SALTLEN_TOO_SMALL);
- return 0;
+ if (rsa_pss_restricted(rctx)) {
+ if (p1 == RSA_PSS_SALTLEN_AUTO
+ && ctx->operation == EVP_PKEY_OP_VERIFY) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+ return -2;
+ }
+ if ((p1 == RSA_PSS_SALTLEN_DIGEST
+ && rctx->min_saltlen > EVP_MD_size(rctx->md))
+ || (p1 >= 0 && p1 < rctx->min_saltlen)) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_PSS_SALTLEN_TOO_SMALL);
+ return 0;
+ }
}
rctx->saltlen = p1;
}
case EVP_PKEY_CTRL_MD:
if (!check_padding_md(p2, rctx->pad_mode))
return 0;
- if (rsa_pss_param(rctx)) {
+ if (rsa_pss_restricted(rctx)) {
if (EVP_MD_type(rctx->md) == EVP_MD_type(p2))
return 1;
RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_DIGEST_NOT_ALLOWED);
else
*(const EVP_MD **)p2 = rctx->md;
} else {
- if (rsa_pss_param(rctx)) {
+ if (rsa_pss_restricted(rctx)) {
if (EVP_MD_type(rctx->md) == EVP_MD_type(p2))
return 1;
RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_MGF1_DIGEST_NOT_ALLOWED);
return rctx->oaep_labellen;
case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+ return 1;
+
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
- case EVP_PKEY_CTRL_PKCS7_SIGN:
- return 1;
#ifndef OPENSSL_NO_CMS
case EVP_PKEY_CTRL_CMS_DECRYPT:
case EVP_PKEY_CTRL_CMS_ENCRYPT:
- case EVP_PKEY_CTRL_CMS_SIGN:
+ if (!pkey_ctx_is_pss(ctx))
return 1;
#endif
case EVP_PKEY_CTRL_PEER_KEY:
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
- if (!value) {
+ if (value == NULL) {
RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
return 0;
}
if (strcmp(type, "rsa_pss_saltlen") == 0) {
int saltlen;
- saltlen = atoi(value);
+ if (!strcmp(value, "digest"))
+ saltlen = RSA_PSS_SALTLEN_DIGEST;
+ else if (!strcmp(value, "max"))
+ saltlen = RSA_PSS_SALTLEN_MAX;
+ else if (!strcmp(value, "auto"))
+ saltlen = RSA_PSS_SALTLEN_AUTO;
+ else
+ saltlen = atoi(value);
return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
}
EVP_PKEY_CTRL_MD, value);
if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) {
- int saltlen;
- saltlen = atoi(value);
+ int saltlen = atoi(value);
+
return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen);
}
}
static int rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx)
{
RSA_PKEY_CTX *rctx = ctx->data;
+
if (!pkey_ctx_is_pss(ctx))
return 1;
/* If all parameters are default values don't set pss */
RSA_PKEY_CTX *rctx = ctx->data;
BN_GENCB *pcb;
int ret;
+
if (rctx->pub_exp == NULL) {
rctx->pub_exp = BN_new();
if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4))
RSA_PKEY_CTX *rctx = ctx->data;
const EVP_MD *md;
const EVP_MD *mgf1md;
- int min_saltlen;
+ int min_saltlen, max_saltlen;
+
/* Should never happen */
if (!pkey_ctx_is_pss(ctx))
return 0;
if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen))
return 0;
+ /* See if minumum salt length exceeds maximum possible */
+ max_saltlen = RSA_size(rsa) - EVP_MD_size(md);
+ if ((RSA_bits(rsa) & 0x7) == 1)
+ max_saltlen--;
+ if (min_saltlen > max_saltlen) {
+ RSAerr(RSA_F_PKEY_PSS_INIT, RSA_R_INVALID_SALT_LENGTH);
+ return 0;
+ }
+
rctx->min_saltlen = min_saltlen;
/*