/* Set PSS parameters when generating a key, if necessary */ 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 */ if (rctx->md == NULL && rctx->mgf1md == NULL && rctx->saltlen == -2) return 1; rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, rctx->saltlen == -2 ? 0 : rctx->saltlen); if (rsa->pss == NULL) return 0; return 1; }
static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); if (rctx == NULL) return 0; rctx->nbits = 1024; if (pkey_ctx_is_pss(ctx)) rctx->pad_mode = RSA_PKCS1_PSS_PADDING; else rctx->pad_mode = RSA_PKCS1_PADDING; /* Maximum for sign, auto for verify */ rctx->saltlen = RSA_PSS_SALTLEN_AUTO; rctx->min_saltlen = -1; ctx->data = rctx; ctx->keygen_info = rctx->gentmp; ctx->keygen_info_count = 2; return 1; }
static int pkey_pss_init(EVP_PKEY_CTX *ctx) { RSA *rsa; RSA_PKEY_CTX *rctx = ctx->data; const EVP_MD *md; const EVP_MD *mgf1md; int min_saltlen, max_saltlen; /* Should never happen */ if (!pkey_ctx_is_pss(ctx)) return 0; rsa = ctx->pkey->pkey.rsa; /* If no restrictions just return */ if (rsa->pss == NULL) return 1; /* Get and check parameters */ 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; /* * Set PSS restrictions as defaults: we can then block any attempt to * use invalid values in pkey_rsa_ctrl */ rctx->md = md; rctx->mgf1md = mgf1md; rctx->saltlen = min_saltlen; return 1; }
static int rsa_cms_verify(CMS_SignerInfo *si) { int nid, nid2; X509_ALGOR *alg; EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); nid = OBJ_obj2nid(alg->algorithm); if (nid == EVP_PKEY_RSA_PSS) return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); /* Only PSS allowed for PSS keys */ if (pkey_ctx_is_pss(pkctx)) { RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } if (nid == NID_rsaEncryption) return 1; /* Workaround for some implementation that use a signature OID */ if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { if (nid2 == NID_rsaEncryption) return 1; } return 0; }
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { if (value == NULL) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); return 0; } if (strcmp(type, "rsa_padding_mode") == 0) { int pm; if (strcmp(value, "pkcs1") == 0) { pm = RSA_PKCS1_PADDING; } else if (strcmp(value, "sslv23") == 0) { pm = RSA_SSLV23_PADDING; } else if (strcmp(value, "none") == 0) { pm = RSA_NO_PADDING; } else if (strcmp(value, "oeap") == 0) { pm = RSA_PKCS1_OAEP_PADDING; } else if (strcmp(value, "oaep") == 0) { pm = RSA_PKCS1_OAEP_PADDING; } else if (strcmp(value, "x931") == 0) { pm = RSA_X931_PADDING; } else if (strcmp(value, "pss") == 0) { pm = RSA_PKCS1_PSS_PADDING; } else { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); return -2; } return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); } if (strcmp(type, "rsa_pss_saltlen") == 0) { int saltlen; 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); } if (strcmp(type, "rsa_keygen_bits") == 0) { int nbits; nbits = atoi(value); return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); } if (strcmp(type, "rsa_keygen_pubexp") == 0) { int ret; BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) return 0; ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); if (ret <= 0) BN_free(pubexp); return ret; } if (strcmp(type, "rsa_mgf1_md") == 0) return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_MGF1_MD, value); if (pkey_ctx_is_pss(ctx)) { if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_MGF1_MD, value); if (strcmp(type, "rsa_pss_keygen_md") == 0) return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, value); if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { int saltlen = atoi(value); return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); } } if (strcmp(type, "rsa_oaep_md") == 0) return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, value); if (strcmp(type, "rsa_oaep_label") == 0) { unsigned char *lab; long lablen; int ret; lab = OPENSSL_hexstr2buf(value, &lablen); if (!lab) return 0; ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); if (ret <= 0) OPENSSL_free(lab); return ret; } return -2; }
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 (!check_padding_md(rctx->md, p1)) return 0; if (p1 == RSA_PKCS1_PSS_PADDING) { if (!(ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } else if (pkey_ctx_is_pss(ctx)) { goto bad_pad; } if (p1 == RSA_PKCS1_OAEP_PADDING) { if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; } bad_pad: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_GET_RSA_PADDING: *(int *)p2 = rctx->pad_mode; return 1; case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { *(int *)p2 = rctx->saltlen; } else { if (p1 < RSA_PSS_SALTLEN_MAX) return -2; 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; } return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 512) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); return -2; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); return -2; } BN_free(rctx->pub_exp); rctx->pub_exp = p2; return 1; case EVP_PKEY_CTRL_RSA_OAEP_MD: case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) *(const EVP_MD **)p2 = rctx->md; else rctx->md = p2; return 1; case EVP_PKEY_CTRL_MD: if (!check_padding_md(p2, rctx->pad_mode)) return 0; 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); return 0; } rctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = rctx->md; return 1; case EVP_PKEY_CTRL_RSA_MGF1_MD: case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { if (rctx->mgf1md) *(const EVP_MD **)p2 = rctx->mgf1md; else *(const EVP_MD **)p2 = rctx->md; } else { if (rsa_pss_restricted(rctx)) { if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) return 1; RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_MGF1_DIGEST_NOT_ALLOWED); return 0; } rctx->mgf1md = p2; } return 1; case EVP_PKEY_CTRL_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } OPENSSL_free(rctx->oaep_label); if (p2 && p1 > 0) { rctx->oaep_label = p2; rctx->oaep_labellen = p1; } else { rctx->oaep_label = NULL; rctx->oaep_labellen = 0; } return 1; case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } *(unsigned char **)p2 = rctx->oaep_label; 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: #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_DECRYPT: case EVP_PKEY_CTRL_CMS_ENCRYPT: #endif if (!pkey_ctx_is_pss(ctx)) return 1; /* fall through */ case EVP_PKEY_CTRL_PEER_KEY: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; } }