xref: /openbsd-src/lib/libcrypto/rsa/rsa_pmeth.c (revision f1535dc82c407426dcbc37ddee0ceff3f0c94865)
1*f1535dc8Sdjm /* crypto/rsa/rsa_pmeth.c */
2*f1535dc8Sdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3*f1535dc8Sdjm  * project 2006.
4*f1535dc8Sdjm  */
5*f1535dc8Sdjm /* ====================================================================
6*f1535dc8Sdjm  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7*f1535dc8Sdjm  *
8*f1535dc8Sdjm  * Redistribution and use in source and binary forms, with or without
9*f1535dc8Sdjm  * modification, are permitted provided that the following conditions
10*f1535dc8Sdjm  * are met:
11*f1535dc8Sdjm  *
12*f1535dc8Sdjm  * 1. Redistributions of source code must retain the above copyright
13*f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer.
14*f1535dc8Sdjm  *
15*f1535dc8Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
16*f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer in
17*f1535dc8Sdjm  *    the documentation and/or other materials provided with the
18*f1535dc8Sdjm  *    distribution.
19*f1535dc8Sdjm  *
20*f1535dc8Sdjm  * 3. All advertising materials mentioning features or use of this
21*f1535dc8Sdjm  *    software must display the following acknowledgment:
22*f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
23*f1535dc8Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24*f1535dc8Sdjm  *
25*f1535dc8Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26*f1535dc8Sdjm  *    endorse or promote products derived from this software without
27*f1535dc8Sdjm  *    prior written permission. For written permission, please contact
28*f1535dc8Sdjm  *    licensing@OpenSSL.org.
29*f1535dc8Sdjm  *
30*f1535dc8Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
31*f1535dc8Sdjm  *    nor may "OpenSSL" appear in their names without prior written
32*f1535dc8Sdjm  *    permission of the OpenSSL Project.
33*f1535dc8Sdjm  *
34*f1535dc8Sdjm  * 6. Redistributions of any form whatsoever must retain the following
35*f1535dc8Sdjm  *    acknowledgment:
36*f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
37*f1535dc8Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38*f1535dc8Sdjm  *
39*f1535dc8Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40*f1535dc8Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41*f1535dc8Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42*f1535dc8Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43*f1535dc8Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44*f1535dc8Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45*f1535dc8Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46*f1535dc8Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*f1535dc8Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48*f1535dc8Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49*f1535dc8Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50*f1535dc8Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
51*f1535dc8Sdjm  * ====================================================================
52*f1535dc8Sdjm  *
53*f1535dc8Sdjm  * This product includes cryptographic software written by Eric Young
54*f1535dc8Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
55*f1535dc8Sdjm  * Hudson (tjh@cryptsoft.com).
56*f1535dc8Sdjm  *
57*f1535dc8Sdjm  */
58*f1535dc8Sdjm 
59*f1535dc8Sdjm #include <stdio.h>
60*f1535dc8Sdjm #include "cryptlib.h"
61*f1535dc8Sdjm #include <openssl/asn1t.h>
62*f1535dc8Sdjm #include <openssl/x509.h>
63*f1535dc8Sdjm #include <openssl/rsa.h>
64*f1535dc8Sdjm #include <openssl/bn.h>
65*f1535dc8Sdjm #include <openssl/evp.h>
66*f1535dc8Sdjm #include "evp_locl.h"
67*f1535dc8Sdjm #include "rsa_locl.h"
68*f1535dc8Sdjm 
69*f1535dc8Sdjm /* RSA pkey context structure */
70*f1535dc8Sdjm 
71*f1535dc8Sdjm typedef struct
72*f1535dc8Sdjm 	{
73*f1535dc8Sdjm 	/* Key gen parameters */
74*f1535dc8Sdjm 	int nbits;
75*f1535dc8Sdjm 	BIGNUM *pub_exp;
76*f1535dc8Sdjm 	/* Keygen callback info */
77*f1535dc8Sdjm 	int gentmp[2];
78*f1535dc8Sdjm 	/* RSA padding mode */
79*f1535dc8Sdjm 	int pad_mode;
80*f1535dc8Sdjm 	/* message digest */
81*f1535dc8Sdjm 	const EVP_MD *md;
82*f1535dc8Sdjm 	/* PSS/OAEP salt length */
83*f1535dc8Sdjm 	int saltlen;
84*f1535dc8Sdjm 	/* Temp buffer */
85*f1535dc8Sdjm 	unsigned char *tbuf;
86*f1535dc8Sdjm 	} RSA_PKEY_CTX;
87*f1535dc8Sdjm 
88*f1535dc8Sdjm static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
89*f1535dc8Sdjm 	{
90*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx;
91*f1535dc8Sdjm 	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
92*f1535dc8Sdjm 	if (!rctx)
93*f1535dc8Sdjm 		return 0;
94*f1535dc8Sdjm 	rctx->nbits = 1024;
95*f1535dc8Sdjm 	rctx->pub_exp = NULL;
96*f1535dc8Sdjm 	rctx->pad_mode = RSA_PKCS1_PADDING;
97*f1535dc8Sdjm 	rctx->md = NULL;
98*f1535dc8Sdjm 	rctx->tbuf = NULL;
99*f1535dc8Sdjm 
100*f1535dc8Sdjm 	rctx->saltlen = -2;
101*f1535dc8Sdjm 
102*f1535dc8Sdjm 	ctx->data = rctx;
103*f1535dc8Sdjm 	ctx->keygen_info = rctx->gentmp;
104*f1535dc8Sdjm 	ctx->keygen_info_count = 2;
105*f1535dc8Sdjm 
106*f1535dc8Sdjm 	return 1;
107*f1535dc8Sdjm 	}
108*f1535dc8Sdjm 
109*f1535dc8Sdjm static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
110*f1535dc8Sdjm 	{
111*f1535dc8Sdjm 	RSA_PKEY_CTX *dctx, *sctx;
112*f1535dc8Sdjm 	if (!pkey_rsa_init(dst))
113*f1535dc8Sdjm 		return 0;
114*f1535dc8Sdjm        	sctx = src->data;
115*f1535dc8Sdjm 	dctx = dst->data;
116*f1535dc8Sdjm 	dctx->nbits = sctx->nbits;
117*f1535dc8Sdjm 	if (sctx->pub_exp)
118*f1535dc8Sdjm 		{
119*f1535dc8Sdjm 		dctx->pub_exp = BN_dup(sctx->pub_exp);
120*f1535dc8Sdjm 		if (!dctx->pub_exp)
121*f1535dc8Sdjm 			return 0;
122*f1535dc8Sdjm 		}
123*f1535dc8Sdjm 	dctx->pad_mode = sctx->pad_mode;
124*f1535dc8Sdjm 	dctx->md = sctx->md;
125*f1535dc8Sdjm 	return 1;
126*f1535dc8Sdjm 	}
127*f1535dc8Sdjm 
128*f1535dc8Sdjm static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
129*f1535dc8Sdjm 	{
130*f1535dc8Sdjm 	if (ctx->tbuf)
131*f1535dc8Sdjm 		return 1;
132*f1535dc8Sdjm 	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
133*f1535dc8Sdjm 	if (!ctx->tbuf)
134*f1535dc8Sdjm 		return 0;
135*f1535dc8Sdjm 	return 1;
136*f1535dc8Sdjm 	}
137*f1535dc8Sdjm 
138*f1535dc8Sdjm static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
139*f1535dc8Sdjm 	{
140*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
141*f1535dc8Sdjm 	if (rctx)
142*f1535dc8Sdjm 		{
143*f1535dc8Sdjm 		if (rctx->pub_exp)
144*f1535dc8Sdjm 			BN_free(rctx->pub_exp);
145*f1535dc8Sdjm 		if (rctx->tbuf)
146*f1535dc8Sdjm 			OPENSSL_free(rctx->tbuf);
147*f1535dc8Sdjm 		OPENSSL_free(rctx);
148*f1535dc8Sdjm 		}
149*f1535dc8Sdjm 	}
150*f1535dc8Sdjm 
151*f1535dc8Sdjm static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
152*f1535dc8Sdjm 					const unsigned char *tbs, size_t tbslen)
153*f1535dc8Sdjm 	{
154*f1535dc8Sdjm 	int ret;
155*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
156*f1535dc8Sdjm 	RSA *rsa = ctx->pkey->pkey.rsa;
157*f1535dc8Sdjm 
158*f1535dc8Sdjm 	if (rctx->md)
159*f1535dc8Sdjm 		{
160*f1535dc8Sdjm 		if (tbslen != (size_t)EVP_MD_size(rctx->md))
161*f1535dc8Sdjm 			{
162*f1535dc8Sdjm 			RSAerr(RSA_F_PKEY_RSA_SIGN,
163*f1535dc8Sdjm 					RSA_R_INVALID_DIGEST_LENGTH);
164*f1535dc8Sdjm 			return -1;
165*f1535dc8Sdjm 			}
166*f1535dc8Sdjm 		if (rctx->pad_mode == RSA_X931_PADDING)
167*f1535dc8Sdjm 			{
168*f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
169*f1535dc8Sdjm 				return -1;
170*f1535dc8Sdjm 			memcpy(rctx->tbuf, tbs, tbslen);
171*f1535dc8Sdjm 			rctx->tbuf[tbslen] =
172*f1535dc8Sdjm 				RSA_X931_hash_id(EVP_MD_type(rctx->md));
173*f1535dc8Sdjm 			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
174*f1535dc8Sdjm 						sig, rsa, RSA_X931_PADDING);
175*f1535dc8Sdjm 			}
176*f1535dc8Sdjm 		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
177*f1535dc8Sdjm 			{
178*f1535dc8Sdjm 			unsigned int sltmp;
179*f1535dc8Sdjm 			ret = RSA_sign(EVP_MD_type(rctx->md),
180*f1535dc8Sdjm 						tbs, tbslen, sig, &sltmp, rsa);
181*f1535dc8Sdjm 			if (ret <= 0)
182*f1535dc8Sdjm 				return ret;
183*f1535dc8Sdjm 			ret = sltmp;
184*f1535dc8Sdjm 			}
185*f1535dc8Sdjm 		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
186*f1535dc8Sdjm 			{
187*f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
188*f1535dc8Sdjm 				return -1;
189*f1535dc8Sdjm 			if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
190*f1535dc8Sdjm 						rctx->md, rctx->saltlen))
191*f1535dc8Sdjm 				return -1;
192*f1535dc8Sdjm 			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
193*f1535dc8Sdjm 						sig, rsa, RSA_NO_PADDING);
194*f1535dc8Sdjm 			}
195*f1535dc8Sdjm 		else
196*f1535dc8Sdjm 			return -1;
197*f1535dc8Sdjm 		}
198*f1535dc8Sdjm 	else
199*f1535dc8Sdjm 		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
200*f1535dc8Sdjm 							rctx->pad_mode);
201*f1535dc8Sdjm 	if (ret < 0)
202*f1535dc8Sdjm 		return ret;
203*f1535dc8Sdjm 	*siglen = ret;
204*f1535dc8Sdjm 	return 1;
205*f1535dc8Sdjm 	}
206*f1535dc8Sdjm 
207*f1535dc8Sdjm 
208*f1535dc8Sdjm static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
209*f1535dc8Sdjm 					unsigned char *rout, size_t *routlen,
210*f1535dc8Sdjm 					const unsigned char *sig, size_t siglen)
211*f1535dc8Sdjm 	{
212*f1535dc8Sdjm 	int ret;
213*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
214*f1535dc8Sdjm 
215*f1535dc8Sdjm 	if (rctx->md)
216*f1535dc8Sdjm 		{
217*f1535dc8Sdjm 		if (rctx->pad_mode == RSA_X931_PADDING)
218*f1535dc8Sdjm 			{
219*f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
220*f1535dc8Sdjm 				return -1;
221*f1535dc8Sdjm 			ret = RSA_public_decrypt(siglen, sig,
222*f1535dc8Sdjm 						rctx->tbuf, ctx->pkey->pkey.rsa,
223*f1535dc8Sdjm 						RSA_X931_PADDING);
224*f1535dc8Sdjm 			if (ret < 1)
225*f1535dc8Sdjm 				return 0;
226*f1535dc8Sdjm 			ret--;
227*f1535dc8Sdjm 			if (rctx->tbuf[ret] !=
228*f1535dc8Sdjm 				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
229*f1535dc8Sdjm 				{
230*f1535dc8Sdjm 				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
231*f1535dc8Sdjm 						RSA_R_ALGORITHM_MISMATCH);
232*f1535dc8Sdjm 				return 0;
233*f1535dc8Sdjm 				}
234*f1535dc8Sdjm 			if (ret != EVP_MD_size(rctx->md))
235*f1535dc8Sdjm 				{
236*f1535dc8Sdjm 				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
237*f1535dc8Sdjm 					RSA_R_INVALID_DIGEST_LENGTH);
238*f1535dc8Sdjm 				return 0;
239*f1535dc8Sdjm 				}
240*f1535dc8Sdjm 			if (rout)
241*f1535dc8Sdjm 				memcpy(rout, rctx->tbuf, ret);
242*f1535dc8Sdjm 			}
243*f1535dc8Sdjm 		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
244*f1535dc8Sdjm 			{
245*f1535dc8Sdjm 			size_t sltmp;
246*f1535dc8Sdjm 			ret = int_rsa_verify(EVP_MD_type(rctx->md),
247*f1535dc8Sdjm 						NULL, 0, rout, &sltmp,
248*f1535dc8Sdjm 					sig, siglen, ctx->pkey->pkey.rsa);
249*f1535dc8Sdjm 			if (ret <= 0)
250*f1535dc8Sdjm 				return 0;
251*f1535dc8Sdjm 			ret = sltmp;
252*f1535dc8Sdjm 			}
253*f1535dc8Sdjm 		else
254*f1535dc8Sdjm 			return -1;
255*f1535dc8Sdjm 		}
256*f1535dc8Sdjm 	else
257*f1535dc8Sdjm 		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
258*f1535dc8Sdjm 							rctx->pad_mode);
259*f1535dc8Sdjm 	if (ret < 0)
260*f1535dc8Sdjm 		return ret;
261*f1535dc8Sdjm 	*routlen = ret;
262*f1535dc8Sdjm 	return 1;
263*f1535dc8Sdjm 	}
264*f1535dc8Sdjm 
265*f1535dc8Sdjm static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
266*f1535dc8Sdjm 					const unsigned char *sig, size_t siglen,
267*f1535dc8Sdjm 					const unsigned char *tbs, size_t tbslen)
268*f1535dc8Sdjm 	{
269*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
270*f1535dc8Sdjm 	RSA *rsa = ctx->pkey->pkey.rsa;
271*f1535dc8Sdjm 	size_t rslen;
272*f1535dc8Sdjm 	if (rctx->md)
273*f1535dc8Sdjm 		{
274*f1535dc8Sdjm 		if (rctx->pad_mode == RSA_PKCS1_PADDING)
275*f1535dc8Sdjm 			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
276*f1535dc8Sdjm 					sig, siglen, rsa);
277*f1535dc8Sdjm 		if (rctx->pad_mode == RSA_X931_PADDING)
278*f1535dc8Sdjm 			{
279*f1535dc8Sdjm 			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
280*f1535dc8Sdjm 					sig, siglen) <= 0)
281*f1535dc8Sdjm 				return 0;
282*f1535dc8Sdjm 			}
283*f1535dc8Sdjm 		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
284*f1535dc8Sdjm 			{
285*f1535dc8Sdjm 			int ret;
286*f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
287*f1535dc8Sdjm 				return -1;
288*f1535dc8Sdjm 			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
289*f1535dc8Sdjm 							rsa, RSA_NO_PADDING);
290*f1535dc8Sdjm 			if (ret <= 0)
291*f1535dc8Sdjm 				return 0;
292*f1535dc8Sdjm 			ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
293*f1535dc8Sdjm 						rctx->tbuf, rctx->saltlen);
294*f1535dc8Sdjm 			if (ret <= 0)
295*f1535dc8Sdjm 				return 0;
296*f1535dc8Sdjm 			return 1;
297*f1535dc8Sdjm 			}
298*f1535dc8Sdjm 		else
299*f1535dc8Sdjm 			return -1;
300*f1535dc8Sdjm 		}
301*f1535dc8Sdjm 	else
302*f1535dc8Sdjm 		{
303*f1535dc8Sdjm 		if (!setup_tbuf(rctx, ctx))
304*f1535dc8Sdjm 			return -1;
305*f1535dc8Sdjm 		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
306*f1535dc8Sdjm 						rsa, rctx->pad_mode);
307*f1535dc8Sdjm 		if (rslen == 0)
308*f1535dc8Sdjm 			return 0;
309*f1535dc8Sdjm 		}
310*f1535dc8Sdjm 
311*f1535dc8Sdjm 	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
312*f1535dc8Sdjm 		return 0;
313*f1535dc8Sdjm 
314*f1535dc8Sdjm 	return 1;
315*f1535dc8Sdjm 
316*f1535dc8Sdjm 	}
317*f1535dc8Sdjm 
318*f1535dc8Sdjm 
319*f1535dc8Sdjm static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
320*f1535dc8Sdjm 					unsigned char *out, size_t *outlen,
321*f1535dc8Sdjm 					const unsigned char *in, size_t inlen)
322*f1535dc8Sdjm 	{
323*f1535dc8Sdjm 	int ret;
324*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
325*f1535dc8Sdjm 	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
326*f1535dc8Sdjm 							rctx->pad_mode);
327*f1535dc8Sdjm 	if (ret < 0)
328*f1535dc8Sdjm 		return ret;
329*f1535dc8Sdjm 	*outlen = ret;
330*f1535dc8Sdjm 	return 1;
331*f1535dc8Sdjm 	}
332*f1535dc8Sdjm 
333*f1535dc8Sdjm static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
334*f1535dc8Sdjm 					unsigned char *out, size_t *outlen,
335*f1535dc8Sdjm 					const unsigned char *in, size_t inlen)
336*f1535dc8Sdjm 	{
337*f1535dc8Sdjm 	int ret;
338*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
339*f1535dc8Sdjm 	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
340*f1535dc8Sdjm 							rctx->pad_mode);
341*f1535dc8Sdjm 	if (ret < 0)
342*f1535dc8Sdjm 		return ret;
343*f1535dc8Sdjm 	*outlen = ret;
344*f1535dc8Sdjm 	return 1;
345*f1535dc8Sdjm 	}
346*f1535dc8Sdjm 
347*f1535dc8Sdjm static int check_padding_md(const EVP_MD *md, int padding)
348*f1535dc8Sdjm 	{
349*f1535dc8Sdjm 	if (!md)
350*f1535dc8Sdjm 		return 1;
351*f1535dc8Sdjm 
352*f1535dc8Sdjm 	if (padding == RSA_NO_PADDING)
353*f1535dc8Sdjm 		{
354*f1535dc8Sdjm 		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
355*f1535dc8Sdjm 		return 0;
356*f1535dc8Sdjm 		}
357*f1535dc8Sdjm 
358*f1535dc8Sdjm 	if (padding == RSA_X931_PADDING)
359*f1535dc8Sdjm 		{
360*f1535dc8Sdjm 		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
361*f1535dc8Sdjm 			{
362*f1535dc8Sdjm 			RSAerr(RSA_F_CHECK_PADDING_MD,
363*f1535dc8Sdjm 						RSA_R_INVALID_X931_DIGEST);
364*f1535dc8Sdjm 			return 0;
365*f1535dc8Sdjm 			}
366*f1535dc8Sdjm 		return 1;
367*f1535dc8Sdjm 		}
368*f1535dc8Sdjm 
369*f1535dc8Sdjm 	return 1;
370*f1535dc8Sdjm 	}
371*f1535dc8Sdjm 
372*f1535dc8Sdjm 
373*f1535dc8Sdjm static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
374*f1535dc8Sdjm 	{
375*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
376*f1535dc8Sdjm 	switch (type)
377*f1535dc8Sdjm 		{
378*f1535dc8Sdjm 		case EVP_PKEY_CTRL_RSA_PADDING:
379*f1535dc8Sdjm 		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
380*f1535dc8Sdjm 			{
381*f1535dc8Sdjm 			if (!check_padding_md(rctx->md, p1))
382*f1535dc8Sdjm 				return 0;
383*f1535dc8Sdjm 			if (p1 == RSA_PKCS1_PSS_PADDING)
384*f1535dc8Sdjm 				{
385*f1535dc8Sdjm 				if (!(ctx->operation &
386*f1535dc8Sdjm 				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
387*f1535dc8Sdjm 					goto bad_pad;
388*f1535dc8Sdjm 				if (!rctx->md)
389*f1535dc8Sdjm 					rctx->md = EVP_sha1();
390*f1535dc8Sdjm 				}
391*f1535dc8Sdjm 			if (p1 == RSA_PKCS1_OAEP_PADDING)
392*f1535dc8Sdjm 				{
393*f1535dc8Sdjm 				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
394*f1535dc8Sdjm 					goto bad_pad;
395*f1535dc8Sdjm 				if (!rctx->md)
396*f1535dc8Sdjm 					rctx->md = EVP_sha1();
397*f1535dc8Sdjm 				}
398*f1535dc8Sdjm 			rctx->pad_mode = p1;
399*f1535dc8Sdjm 			return 1;
400*f1535dc8Sdjm 			}
401*f1535dc8Sdjm 		bad_pad:
402*f1535dc8Sdjm 		RSAerr(RSA_F_PKEY_RSA_CTRL,
403*f1535dc8Sdjm 				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
404*f1535dc8Sdjm 		return -2;
405*f1535dc8Sdjm 
406*f1535dc8Sdjm 		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
407*f1535dc8Sdjm 		if (p1 < -2)
408*f1535dc8Sdjm 			return -2;
409*f1535dc8Sdjm 		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
410*f1535dc8Sdjm 			{
411*f1535dc8Sdjm 			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
412*f1535dc8Sdjm 			return -2;
413*f1535dc8Sdjm 			}
414*f1535dc8Sdjm 		rctx->saltlen = p1;
415*f1535dc8Sdjm 		return 1;
416*f1535dc8Sdjm 
417*f1535dc8Sdjm 		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
418*f1535dc8Sdjm 		if (p1 < 256)
419*f1535dc8Sdjm 			{
420*f1535dc8Sdjm 			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
421*f1535dc8Sdjm 			return -2;
422*f1535dc8Sdjm 			}
423*f1535dc8Sdjm 		rctx->nbits = p1;
424*f1535dc8Sdjm 		return 1;
425*f1535dc8Sdjm 
426*f1535dc8Sdjm 		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
427*f1535dc8Sdjm 		if (!p2)
428*f1535dc8Sdjm 			return -2;
429*f1535dc8Sdjm 		rctx->pub_exp = p2;
430*f1535dc8Sdjm 		return 1;
431*f1535dc8Sdjm 
432*f1535dc8Sdjm 		case EVP_PKEY_CTRL_MD:
433*f1535dc8Sdjm 		if (!check_padding_md(p2, rctx->pad_mode))
434*f1535dc8Sdjm 			return 0;
435*f1535dc8Sdjm 		rctx->md = p2;
436*f1535dc8Sdjm 		return 1;
437*f1535dc8Sdjm 
438*f1535dc8Sdjm 		case EVP_PKEY_CTRL_DIGESTINIT:
439*f1535dc8Sdjm 		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
440*f1535dc8Sdjm 		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
441*f1535dc8Sdjm 		case EVP_PKEY_CTRL_PKCS7_SIGN:
442*f1535dc8Sdjm #ifndef OPENSSL_NO_CMS
443*f1535dc8Sdjm 		case EVP_PKEY_CTRL_CMS_ENCRYPT:
444*f1535dc8Sdjm 		case EVP_PKEY_CTRL_CMS_DECRYPT:
445*f1535dc8Sdjm 		case EVP_PKEY_CTRL_CMS_SIGN:
446*f1535dc8Sdjm #endif
447*f1535dc8Sdjm 		return 1;
448*f1535dc8Sdjm 		case EVP_PKEY_CTRL_PEER_KEY:
449*f1535dc8Sdjm 			RSAerr(RSA_F_PKEY_RSA_CTRL,
450*f1535dc8Sdjm 			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
451*f1535dc8Sdjm 			return -2;
452*f1535dc8Sdjm 
453*f1535dc8Sdjm 		default:
454*f1535dc8Sdjm 		return -2;
455*f1535dc8Sdjm 
456*f1535dc8Sdjm 		}
457*f1535dc8Sdjm 	}
458*f1535dc8Sdjm 
459*f1535dc8Sdjm static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
460*f1535dc8Sdjm 			const char *type, const char *value)
461*f1535dc8Sdjm 	{
462*f1535dc8Sdjm 	if (!value)
463*f1535dc8Sdjm 		{
464*f1535dc8Sdjm 		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
465*f1535dc8Sdjm 		return 0;
466*f1535dc8Sdjm 		}
467*f1535dc8Sdjm 	if (!strcmp(type, "rsa_padding_mode"))
468*f1535dc8Sdjm 		{
469*f1535dc8Sdjm 		int pm;
470*f1535dc8Sdjm 		if (!strcmp(value, "pkcs1"))
471*f1535dc8Sdjm 			pm = RSA_PKCS1_PADDING;
472*f1535dc8Sdjm 		else if (!strcmp(value, "sslv23"))
473*f1535dc8Sdjm 			pm = RSA_SSLV23_PADDING;
474*f1535dc8Sdjm 		else if (!strcmp(value, "none"))
475*f1535dc8Sdjm 			pm = RSA_NO_PADDING;
476*f1535dc8Sdjm 		else if (!strcmp(value, "oeap"))
477*f1535dc8Sdjm 			pm = RSA_PKCS1_OAEP_PADDING;
478*f1535dc8Sdjm 		else if (!strcmp(value, "x931"))
479*f1535dc8Sdjm 			pm = RSA_X931_PADDING;
480*f1535dc8Sdjm 		else if (!strcmp(value, "pss"))
481*f1535dc8Sdjm 			pm = RSA_PKCS1_PSS_PADDING;
482*f1535dc8Sdjm 		else
483*f1535dc8Sdjm 			{
484*f1535dc8Sdjm 			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
485*f1535dc8Sdjm 						RSA_R_UNKNOWN_PADDING_TYPE);
486*f1535dc8Sdjm 			return -2;
487*f1535dc8Sdjm 			}
488*f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
489*f1535dc8Sdjm 		}
490*f1535dc8Sdjm 
491*f1535dc8Sdjm 	if (!strcmp(type, "rsa_pss_saltlen"))
492*f1535dc8Sdjm 		{
493*f1535dc8Sdjm 		int saltlen;
494*f1535dc8Sdjm 		saltlen = atoi(value);
495*f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
496*f1535dc8Sdjm 		}
497*f1535dc8Sdjm 
498*f1535dc8Sdjm 	if (!strcmp(type, "rsa_keygen_bits"))
499*f1535dc8Sdjm 		{
500*f1535dc8Sdjm 		int nbits;
501*f1535dc8Sdjm 		nbits = atoi(value);
502*f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
503*f1535dc8Sdjm 		}
504*f1535dc8Sdjm 
505*f1535dc8Sdjm 	if (!strcmp(type, "rsa_keygen_pubexp"))
506*f1535dc8Sdjm 		{
507*f1535dc8Sdjm 		int ret;
508*f1535dc8Sdjm 		BIGNUM *pubexp = NULL;
509*f1535dc8Sdjm 		if (!BN_asc2bn(&pubexp, value))
510*f1535dc8Sdjm 			return 0;
511*f1535dc8Sdjm 		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
512*f1535dc8Sdjm 		if (ret <= 0)
513*f1535dc8Sdjm 			BN_free(pubexp);
514*f1535dc8Sdjm 		return ret;
515*f1535dc8Sdjm 		}
516*f1535dc8Sdjm 
517*f1535dc8Sdjm 	return -2;
518*f1535dc8Sdjm 	}
519*f1535dc8Sdjm 
520*f1535dc8Sdjm static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
521*f1535dc8Sdjm 	{
522*f1535dc8Sdjm 	RSA *rsa = NULL;
523*f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
524*f1535dc8Sdjm 	BN_GENCB *pcb, cb;
525*f1535dc8Sdjm 	int ret;
526*f1535dc8Sdjm 	if (!rctx->pub_exp)
527*f1535dc8Sdjm 		{
528*f1535dc8Sdjm 		rctx->pub_exp = BN_new();
529*f1535dc8Sdjm 		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
530*f1535dc8Sdjm 			return 0;
531*f1535dc8Sdjm 		}
532*f1535dc8Sdjm 	rsa = RSA_new();
533*f1535dc8Sdjm 	if (!rsa)
534*f1535dc8Sdjm 		return 0;
535*f1535dc8Sdjm 	if (ctx->pkey_gencb)
536*f1535dc8Sdjm 		{
537*f1535dc8Sdjm 		pcb = &cb;
538*f1535dc8Sdjm 		evp_pkey_set_cb_translate(pcb, ctx);
539*f1535dc8Sdjm 		}
540*f1535dc8Sdjm 	else
541*f1535dc8Sdjm 		pcb = NULL;
542*f1535dc8Sdjm 	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
543*f1535dc8Sdjm 	if (ret > 0)
544*f1535dc8Sdjm 		EVP_PKEY_assign_RSA(pkey, rsa);
545*f1535dc8Sdjm 	else
546*f1535dc8Sdjm 		RSA_free(rsa);
547*f1535dc8Sdjm 	return ret;
548*f1535dc8Sdjm 	}
549*f1535dc8Sdjm 
550*f1535dc8Sdjm const EVP_PKEY_METHOD rsa_pkey_meth =
551*f1535dc8Sdjm 	{
552*f1535dc8Sdjm 	EVP_PKEY_RSA,
553*f1535dc8Sdjm 	EVP_PKEY_FLAG_AUTOARGLEN,
554*f1535dc8Sdjm 	pkey_rsa_init,
555*f1535dc8Sdjm 	pkey_rsa_copy,
556*f1535dc8Sdjm 	pkey_rsa_cleanup,
557*f1535dc8Sdjm 
558*f1535dc8Sdjm 	0,0,
559*f1535dc8Sdjm 
560*f1535dc8Sdjm 	0,
561*f1535dc8Sdjm 	pkey_rsa_keygen,
562*f1535dc8Sdjm 
563*f1535dc8Sdjm 	0,
564*f1535dc8Sdjm 	pkey_rsa_sign,
565*f1535dc8Sdjm 
566*f1535dc8Sdjm 	0,
567*f1535dc8Sdjm 	pkey_rsa_verify,
568*f1535dc8Sdjm 
569*f1535dc8Sdjm 	0,
570*f1535dc8Sdjm 	pkey_rsa_verifyrecover,
571*f1535dc8Sdjm 
572*f1535dc8Sdjm 
573*f1535dc8Sdjm 	0,0,0,0,
574*f1535dc8Sdjm 
575*f1535dc8Sdjm 	0,
576*f1535dc8Sdjm 	pkey_rsa_encrypt,
577*f1535dc8Sdjm 
578*f1535dc8Sdjm 	0,
579*f1535dc8Sdjm 	pkey_rsa_decrypt,
580*f1535dc8Sdjm 
581*f1535dc8Sdjm 	0,0,
582*f1535dc8Sdjm 
583*f1535dc8Sdjm 	pkey_rsa_ctrl,
584*f1535dc8Sdjm 	pkey_rsa_ctrl_str
585*f1535dc8Sdjm 
586*f1535dc8Sdjm 
587*f1535dc8Sdjm 	};
588