aboutsummaryrefslogtreecommitdiff
path: root/crypto/rsa/rsa_pmeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rsa/rsa_pmeth.c')
-rw-r--r--crypto/rsa/rsa_pmeth.c159
1 files changed, 139 insertions, 20 deletions
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 6a7c67cdb86c..203635595f4c 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -64,6 +64,7 @@
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
+#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_CMS
# include <openssl/cms.h>
#endif
@@ -87,10 +88,13 @@ typedef struct {
const EVP_MD *md;
/* message digest for MGF1 */
const EVP_MD *mgf1md;
- /* PSS/OAEP salt length */
+ /* PSS salt length */
int saltlen;
/* Temp buffer */
unsigned char *tbuf;
+ /* OAEP label */
+ unsigned char *oaep_label;
+ size_t oaep_labellen;
} RSA_PKEY_CTX;
static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
@@ -108,6 +112,9 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->saltlen = -2;
+ rctx->oaep_label = NULL;
+ rctx->oaep_labellen = 0;
+
ctx->data = rctx;
ctx->keygen_info = rctx->gentmp;
ctx->keygen_info_count = 2;
@@ -130,6 +137,15 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
}
dctx->pad_mode = sctx->pad_mode;
dctx->md = sctx->md;
+ dctx->mgf1md = sctx->mgf1md;
+ if (sctx->oaep_label) {
+ if (dctx->oaep_label)
+ OPENSSL_free(dctx->oaep_label);
+ dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
+ if (!dctx->oaep_label)
+ return 0;
+ dctx->oaep_labellen = sctx->oaep_labellen;
+ }
return 1;
}
@@ -151,6 +167,8 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
BN_free(rctx->pub_exp);
if (rctx->tbuf)
OPENSSL_free(rctx->tbuf);
+ if (rctx->oaep_label)
+ OPENSSL_free(rctx->oaep_label);
OPENSSL_free(rctx);
}
}
@@ -173,10 +191,18 @@ static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx)
rv = 0;
if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv)
return -1;
- if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS))
- return rv;
- if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS))
- return rv;
+ if (rctx->md) {
+ const EVP_MD *fmd;
+ fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md));
+ if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ }
+ if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) {
+ const EVP_MD *fmd;
+ fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md));
+ if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS))
+ return rv;
+ }
return 1;
}
#endif
@@ -388,8 +414,21 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
- rctx->pad_mode);
+ if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int klen = RSA_size(ctx->pkey->pkey.rsa);
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
+ in, inlen,
+ rctx->oaep_label,
+ rctx->oaep_labellen,
+ rctx->md, rctx->mgf1md))
+ return -1;
+ ret = RSA_public_encrypt(klen, rctx->tbuf, out,
+ ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+ } else
+ ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
if (ret < 0)
return ret;
*outlen = ret;
@@ -402,8 +441,26 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
- rctx->pad_mode);
+ if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int i;
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
+ ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+ if (ret <= 0)
+ return ret;
+ for (i = 0; i < ret; i++) {
+ if (rctx->tbuf[i])
+ break;
+ }
+ ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
+ ret - i, ret,
+ rctx->oaep_label,
+ rctx->oaep_labellen,
+ rctx->md, rctx->mgf1md);
+ } else
+ ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
if (ret < 0)
return ret;
*outlen = ret;
@@ -490,18 +547,36 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
if (!p2)
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;
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) {
+ 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;
}
@@ -514,6 +589,30 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
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;
+ }
+ if (rctx->oaep_label)
+ 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_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
@@ -521,16 +620,6 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return 1;
#ifndef OPENSSL_NO_CMS
case EVP_PKEY_CTRL_CMS_DECRYPT:
- {
- X509_ALGOR *alg = NULL;
- ASN1_OBJECT *encalg = NULL;
- if (p2)
- CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg);
- if (alg)
- X509_ALGOR_get0(&encalg, NULL, NULL, alg);
- if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep)
- rctx->pad_mode = RSA_PKCS1_OAEP_PADDING;
- }
case EVP_PKEY_CTRL_CMS_ENCRYPT:
case EVP_PKEY_CTRL_CMS_SIGN:
return 1;
@@ -599,6 +688,36 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
return ret;
}
+ if (!strcmp(type, "rsa_mgf1_md")) {
+ const EVP_MD *md;
+ if (!(md = EVP_get_digestbyname(value))) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md);
+ }
+
+ if (!strcmp(type, "rsa_oaep_md")) {
+ const EVP_MD *md;
+ if (!(md = EVP_get_digestbyname(value))) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md);
+ }
+ if (!strcmp(type, "rsa_oaep_label")) {
+ unsigned char *lab;
+ long lablen;
+ int ret;
+ lab = string_to_hex(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;
}