in Sources/CCryptoBoringSSL/crypto/evp/p_rsa.c [396:517]
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 (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) ||
(p1 == RSA_PKCS1_PSS_PADDING &&
0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) ||
(p1 == RSA_PKCS1_OAEP_PADDING &&
0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
return 0;
}
if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
rctx->md == NULL) {
rctx->md = EVP_sha1();
}
rctx->pad_mode = p1;
return 1;
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) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
*(int *)p2 = rctx->saltlen;
} else {
if (p1 < -2) {
return 0;
}
rctx->saltlen = p1;
}
return 1;
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
if (p1 < 256) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS);
return 0;
}
rctx->nbits = p1;
return 1;
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
if (!p2) {
return 0;
}
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) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
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;
}
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) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD);
return 0;
}
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 {
rctx->mgf1md = p2;
}
return 1;
case EVP_PKEY_CTRL_RSA_OAEP_LABEL: {
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
OPENSSL_free(rctx->oaep_label);
RSA_OAEP_LABEL_PARAMS *params = p2;
rctx->oaep_label = params->data;
rctx->oaep_labellen = params->len;
return 1;
}
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
return 1;
default:
OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}