X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frsa%2Frsa_pmeth.c;h=989a7d794db4c637deeb989764a361780d5c0450;hp=a0db5ee2fa6f5bf0c129a8b9704e6e09b76794de;hb=29db322e8f2b0568322b80e3be28446463d74010;hpb=a58a6368383d55ab35ad4f4cdcb0f54310e7fd32 diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index a0db5ee2fa..989a7d794d 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -77,8 +77,10 @@ typedef struct 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; @@ -92,9 +94,11 @@ static int pkey_rsa_init(EVP_PKEY_CTX *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; @@ -129,15 +133,21 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen, 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); @@ -145,8 +155,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen, 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; @@ -162,50 +176,98 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen, static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, - unsigned char *sig, int *siglen, - const 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_public_decrypt(tbslen, tbs, + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, ctx->pkey->pkey.rsa, RSA_X931_PADDING); if (ret < 1) return 0; ret--; - if (rctx->tbuf[ret] != RSA_X931_hash_id(rctx->md_nid)) + 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; } - 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, const unsigned char *in, int inlen) { @@ -232,9 +294,9 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen, 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) { @@ -244,7 +306,7 @@ static int check_padding_nid(int nid, int 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); @@ -263,22 +325,27 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 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: @@ -305,6 +372,8 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, 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); @@ -326,7 +395,8 @@ const EVP_PKEY_METHOD rsa_pkey_meth = 0, pkey_rsa_sign, - 0,0, + 0, + pkey_rsa_verify, 0, pkey_rsa_verifyrecover,