1221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* crypto/rsa/rsa_pmeth.c */
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * project 2006.
4221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* ====================================================================
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
8221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Redistribution and use in source and binary forms, with or without
9221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * modification, are permitted provided that the following conditions
10221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * are met:
11221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
12221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 1. Redistributions of source code must retain the above copyright
13221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer.
14221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
15221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright
16221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer in
17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    the documentation and/or other materials provided with the
18221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    distribution.
19221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
20221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 3. All advertising materials mentioning features or use of this
21221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    software must display the following acknowledgment:
22221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
23221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
25221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    endorse or promote products derived from this software without
27221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    prior written permission. For written permission, please contact
28221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    licensing@OpenSSL.org.
29221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
30221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL"
31221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    nor may "OpenSSL" appear in their names without prior written
32221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    permission of the OpenSSL Project.
33221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
34221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following
35221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    acknowledgment:
36221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
37221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
39221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE.
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ====================================================================
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * This product includes cryptographic software written by Eric Young
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * (eay@cryptsoft.com).  This product includes software written by Tim
55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Hudson (tjh@cryptsoft.com).
56221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
57221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <stdio.h>
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "cryptlib.h"
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/asn1t.h>
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/x509.h>
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/rsa.h>
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/bn.h>
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/evp.h>
66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_CMS
67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/cms.h>
68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips.h>
71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "evp_locl.h"
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "rsa_locl.h"
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* RSA pkey context structure */
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Key gen parameters */
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int nbits;
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIGNUM *pub_exp;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Keygen callback info */
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int gentmp[2];
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* RSA padding mode */
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int pad_mode;
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* message digest */
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_MD *md;
88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* message digest for MGF1 */
89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const EVP_MD *mgf1md;
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* PSS/OAEP salt length */
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int saltlen;
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Temp buffer */
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *tbuf;
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} RSA_PKEY_CTX;
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_init(EVP_PKEY_CTX *ctx)
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx;
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!rctx)
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->nbits = 1024;
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->pub_exp = NULL;
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->pad_mode = RSA_PKCS1_PADDING;
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->md = NULL;
106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	rctx->mgf1md = NULL;
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->tbuf = NULL;
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rctx->saltlen = -2;
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->data = rctx;
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->keygen_info = rctx->gentmp;
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->keygen_info_count = 2;
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *dctx, *sctx;
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!pkey_rsa_init(dst))
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom       	sctx = src->data;
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dctx = dst->data;
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dctx->nbits = sctx->nbits;
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (sctx->pub_exp)
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		dctx->pub_exp = BN_dup(sctx->pub_exp);
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!dctx->pub_exp)
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dctx->pad_mode = sctx->pad_mode;
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dctx->md = sctx->md;
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->tbuf)
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->tbuf)
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (rctx)
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->pub_exp)
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BN_free(rctx->pub_exp);
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->tbuf)
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			OPENSSL_free(rctx->tbuf);
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		OPENSSL_free(rctx);
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* FIP checker. Return value indicates status of context parameters:
161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 1  : redirect to FIPS.
162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 0  : don't redirect to FIPS.
163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * -1 : illegal operation in FIPS mode.
164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx)
167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	RSA *rsa = ctx->pkey->pkey.rsa;
170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int rv = -1;
171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!FIPS_mode())
172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		rv = 0;
175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv)
176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS))
178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return rv;
179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS))
180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return rv;
181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *tbs, size_t tbslen)
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA *rsa = ctx->pkey->pkey.rsa;
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ret = pkey_fips_check_ctx(ctx);
194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ret < 0)
195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (rctx->md)
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (tbslen != (size_t)EVP_MD_size(rctx->md))
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_SIGN,
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					RSA_R_INVALID_DIGEST_LENGTH);
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -1;
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (ret > 0)
211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned int slen;
213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->pad_mode,
215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->saltlen,
216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->mgf1md,
217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							sig, &slen);
218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (ret > 0)
219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				*siglen = slen;
220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				*siglen = 0;
222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return ret;
223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (EVP_MD_type(rctx->md) == NID_mdc2)
227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned int sltmp;
229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (rctx->pad_mode != RSA_PKCS1_PADDING)
230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2,
232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						tbs, tbslen, sig, &sltmp, rsa);
233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (ret <= 0)
235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return ret;
236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ret = sltmp;
237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else if (rctx->pad_mode == RSA_X931_PADDING)
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!setup_tbuf(rctx, ctx))
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return -1;
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memcpy(rctx->tbuf, tbs, tbslen);
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			rctx->tbuf[tbslen] =
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				RSA_X931_hash_id(EVP_MD_type(rctx->md));
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						sig, rsa, RSA_X931_PADDING);
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned int sltmp;
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = RSA_sign(EVP_MD_type(rctx->md),
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						tbs, tbslen, sig, &sltmp, rsa);
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ret <= 0)
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return ret;
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = sltmp;
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!setup_tbuf(rctx, ctx))
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return -1;
261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						rctx->tbuf, tbs,
263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						rctx->md, rctx->mgf1md,
264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						rctx->saltlen))
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return -1;
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						sig, rsa, RSA_NO_PADDING);
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -1;
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							rctx->pad_mode);
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret < 0)
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*siglen = ret;
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					unsigned char *rout, size_t *routlen,
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *sig, size_t siglen)
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (rctx->md)
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->pad_mode == RSA_X931_PADDING)
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!setup_tbuf(rctx, ctx))
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return -1;
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = RSA_public_decrypt(siglen, sig,
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						rctx->tbuf, ctx->pkey->pkey.rsa,
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						RSA_X931_PADDING);
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ret < 1)
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret--;
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (rctx->tbuf[ret] !=
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						RSA_R_ALGORITHM_MISMATCH);
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ret != EVP_MD_size(rctx->md))
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					RSA_R_INVALID_DIGEST_LENGTH);
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (rout)
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				memcpy(rout, rctx->tbuf, ret);
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			size_t sltmp;
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = int_rsa_verify(EVP_MD_type(rctx->md),
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						NULL, 0, rout, &sltmp,
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					sig, siglen, ctx->pkey->pkey.rsa);
3233d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			if (ret <= 0)
3243d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				return 0;
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = sltmp;
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -1;
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							rctx->pad_mode);
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret < 0)
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*routlen = ret;
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *sig, size_t siglen,
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *tbs, size_t tbslen)
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA *rsa = ctx->pkey->pkey.rsa;
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	size_t rslen;
346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int rv;
348392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	rv = pkey_fips_check_ctx(ctx);
349392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (rv < 0)
350392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
351392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
352392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
353392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
354392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (rctx->md)
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
357392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
358392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (rv > 0)
359392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
360392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return FIPS_rsa_verify_digest(rsa,
361392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							tbs, tbslen,
362392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->md,
363392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->pad_mode,
364392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->saltlen,
365392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							rctx->mgf1md,
366392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							sig, siglen);
367392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
368392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
369392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->pad_mode == RSA_PKCS1_PADDING)
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					sig, siglen, rsa);
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->pad_mode == RSA_X931_PADDING)
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					sig, siglen) <= 0)
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int ret;
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!setup_tbuf(rctx, ctx))
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return -1;
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							rsa, RSA_NO_PADDING);
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ret <= 0)
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
388392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
389392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						rctx->md, rctx->mgf1md,
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						rctx->tbuf, rctx->saltlen);
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ret <= 0)
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 1;
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -1;
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!setup_tbuf(rctx, ctx))
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -1;
402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						rsa, rctx->pad_mode);
404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rslen == 0)
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					unsigned char *out, size_t *outlen,
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *in, size_t inlen)
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							rctx->pad_mode);
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret < 0)
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*outlen = ret;
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					unsigned char *out, size_t *outlen,
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char *in, size_t inlen)
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							rctx->pad_mode);
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret < 0)
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*outlen = ret;
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int check_padding_md(const EVP_MD *md, int padding)
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!md)
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (padding == RSA_NO_PADDING)
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (padding == RSA_X931_PADDING)
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_CHECK_PADDING_MD,
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						RSA_R_INVALID_X931_DIGEST);
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	switch (type)
474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_RSA_PADDING:
476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!check_padding_md(rctx->md, p1))
479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				return 0;
480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (p1 == RSA_PKCS1_PSS_PADDING)
481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!(ctx->operation &
483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto bad_pad;
485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!rctx->md)
486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					rctx->md = EVP_sha1();
487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (p1 == RSA_PKCS1_OAEP_PADDING)
489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto bad_pad;
492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!rctx->md)
493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					rctx->md = EVP_sha1();
494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			rctx->pad_mode = p1;
496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 1;
497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		bad_pad:
499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		RSAerr(RSA_F_PKEY_RSA_CTRL,
500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
503392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case EVP_PKEY_CTRL_GET_RSA_PADDING:
504392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		*(int *)p2 = rctx->pad_mode;
505392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
506392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
508392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
511221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -2;
513221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
514392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
515392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			*(int *)p2 = rctx->saltlen;
516392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
517392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
518392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (p1 < -2)
519392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -2;
520392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rctx->saltlen = p1;
521392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
522221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
524221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
525221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (p1 < 256)
526221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
527221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
528221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -2;
529221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		rctx->nbits = p1;
531221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
532221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
533221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
534221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!p2)
535221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -2;
536221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		rctx->pub_exp = p2;
537221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
538221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
539221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_MD:
540221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!check_padding_md(p2, rctx->pad_mode))
541221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
542221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		rctx->md = p2;
543221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
544221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
545392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case EVP_PKEY_CTRL_RSA_MGF1_MD:
546392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
547392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
548392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
549392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
550392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -2;
551392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
552392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD)
553392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
554392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (rctx->mgf1md)
555392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				*(const EVP_MD **)p2 = rctx->mgf1md;
556392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
557392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				*(const EVP_MD **)p2 = rctx->md;
558392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
559392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
560392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rctx->mgf1md = p2;
561392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
562392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
563221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_DIGESTINIT:
564221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
565221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
566221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_PKCS7_SIGN:
567392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
568221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_CMS
569221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_CMS_DECRYPT:
570392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
571392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		X509_ALGOR *alg = NULL;
572392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ASN1_OBJECT *encalg = NULL;
573392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (p2)
574392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg);
575392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (alg)
576392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			X509_ALGOR_get0(&encalg, NULL, NULL, alg);
577392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep)
578392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rctx->pad_mode = RSA_PKCS1_OAEP_PADDING;
579392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
580392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case EVP_PKEY_CTRL_CMS_ENCRYPT:
581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_CMS_SIGN:
582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
583392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
584221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		case EVP_PKEY_CTRL_PEER_KEY:
585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_CTRL,
586221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
587221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -2;
588221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		default:
590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
591221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const char *type, const char *value)
597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!value)
599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
602221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!strcmp(type, "rsa_padding_mode"))
604221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
605221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int pm;
606221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!strcmp(value, "pkcs1"))
607221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_PKCS1_PADDING;
608221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp(value, "sslv23"))
609221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_SSLV23_PADDING;
610221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp(value, "none"))
611221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_NO_PADDING;
612221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp(value, "oeap"))
613221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_PKCS1_OAEP_PADDING;
614ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		else if (!strcmp(value, "oaep"))
615ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root			pm = RSA_PKCS1_OAEP_PADDING;
616221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp(value, "x931"))
617221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_X931_PADDING;
618221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp(value, "pss"))
619221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pm = RSA_PKCS1_PSS_PADDING;
620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
621221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
622221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
623221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						RSA_R_UNKNOWN_PADDING_TYPE);
624221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return -2;
625221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
626221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
627221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
628221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
629221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!strcmp(type, "rsa_pss_saltlen"))
630221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
631221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int saltlen;
632221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		saltlen = atoi(value);
633221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
634221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
635221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
636221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!strcmp(type, "rsa_keygen_bits"))
637221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
638221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int nbits;
639221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		nbits = atoi(value);
640221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
641221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
642221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
643221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!strcmp(type, "rsa_keygen_pubexp"))
644221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
645221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int ret;
646221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIGNUM *pubexp = NULL;
647221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!BN_asc2bn(&pubexp, value))
648221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
649221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ret <= 0)
651221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BN_free(pubexp);
652221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
653221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
655221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return -2;
656221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
657221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
658221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
659221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
660221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA *rsa = NULL;
661221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	RSA_PKEY_CTX *rctx = ctx->data;
662221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BN_GENCB *pcb, cb;
663221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
664221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!rctx->pub_exp)
665221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
666221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		rctx->pub_exp = BN_new();
667221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
668221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
669221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
670221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rsa = RSA_new();
671221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!rsa)
672221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
673221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->pkey_gencb)
674221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
675221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pcb = &cb;
676221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		evp_pkey_set_cb_translate(pcb, ctx);
677221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
678221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
679221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pcb = NULL;
680221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
681221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret > 0)
682221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVP_PKEY_assign_RSA(pkey, rsa);
683221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
684221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		RSA_free(rsa);
685221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
686221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
687221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
688221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_PKEY_METHOD rsa_pkey_meth =
689221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
690221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_RSA,
691221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_FLAG_AUTOARGLEN,
692221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_init,
693221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_copy,
694221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_cleanup,
695221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
696221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,0,
697221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
698221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
699221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_keygen,
700221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
701221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
702221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_sign,
703221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
704221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
705221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_verify,
706221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
707221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
708221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_verifyrecover,
709221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
710221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
711221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,0,0,0,
712221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
713221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
714221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_encrypt,
715221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
716221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
717221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_decrypt,
718221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
719221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,0,
720221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
721221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_ctrl,
722221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pkey_rsa_ctrl_str
723221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
724221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
725221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
726