xref: /openbsd-src/lib/libcrypto/rsa/rsa_pmeth.c (revision 457dff4263e6ab7af4b3e754543aca09367910ba)
1*457dff42Stb /* $OpenBSD: rsa_pmeth.c,v 1.43 2025/01/17 15:39:19 tb Exp $ */
2f1535dc8Sdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3f1535dc8Sdjm  * project 2006.
4f1535dc8Sdjm  */
5f1535dc8Sdjm /* ====================================================================
6f1535dc8Sdjm  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7f1535dc8Sdjm  *
8f1535dc8Sdjm  * Redistribution and use in source and binary forms, with or without
9f1535dc8Sdjm  * modification, are permitted provided that the following conditions
10f1535dc8Sdjm  * are met:
11f1535dc8Sdjm  *
12f1535dc8Sdjm  * 1. Redistributions of source code must retain the above copyright
13f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer.
14f1535dc8Sdjm  *
15f1535dc8Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
16f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer in
17f1535dc8Sdjm  *    the documentation and/or other materials provided with the
18f1535dc8Sdjm  *    distribution.
19f1535dc8Sdjm  *
20f1535dc8Sdjm  * 3. All advertising materials mentioning features or use of this
21f1535dc8Sdjm  *    software must display the following acknowledgment:
22f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
23f1535dc8Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24f1535dc8Sdjm  *
25f1535dc8Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f1535dc8Sdjm  *    endorse or promote products derived from this software without
27f1535dc8Sdjm  *    prior written permission. For written permission, please contact
28f1535dc8Sdjm  *    licensing@OpenSSL.org.
29f1535dc8Sdjm  *
30f1535dc8Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
31f1535dc8Sdjm  *    nor may "OpenSSL" appear in their names without prior written
32f1535dc8Sdjm  *    permission of the OpenSSL Project.
33f1535dc8Sdjm  *
34f1535dc8Sdjm  * 6. Redistributions of any form whatsoever must retain the following
35f1535dc8Sdjm  *    acknowledgment:
36f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
37f1535dc8Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38f1535dc8Sdjm  *
39f1535dc8Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f1535dc8Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f1535dc8Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f1535dc8Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f1535dc8Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f1535dc8Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f1535dc8Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f1535dc8Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f1535dc8Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f1535dc8Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f1535dc8Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f1535dc8Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
51f1535dc8Sdjm  * ====================================================================
52f1535dc8Sdjm  *
53f1535dc8Sdjm  * This product includes cryptographic software written by Eric Young
54f1535dc8Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
55f1535dc8Sdjm  * Hudson (tjh@cryptsoft.com).
56f1535dc8Sdjm  *
57f1535dc8Sdjm  */
58f1535dc8Sdjm 
59b1d57841Sderaadt #include <limits.h>
60a8913c44Sjsing #include <stdio.h>
6140e63673Sop #include <stdlib.h>
62a8913c44Sjsing #include <string.h>
63a8913c44Sjsing 
648cf4d6a6Sjsing #include <openssl/opensslconf.h>
658cf4d6a6Sjsing 
66f1535dc8Sdjm #include <openssl/asn1t.h>
67f1535dc8Sdjm #include <openssl/bn.h>
68b6ab114eSjsing #include <openssl/err.h>
69f1535dc8Sdjm #include <openssl/evp.h>
70b6ab114eSjsing #include <openssl/rsa.h>
71b6ab114eSjsing #include <openssl/x509.h>
7295285806Sjsing #include <openssl/x509v3.h>
73b6ab114eSjsing 
74c9675a23Stb #include "bn_local.h"
75c9675a23Stb #include "evp_local.h"
76c9675a23Stb #include "rsa_local.h"
77f1535dc8Sdjm 
78f1535dc8Sdjm /* RSA pkey context structure */
79f1535dc8Sdjm 
8087203b09Smiod typedef struct {
81f1535dc8Sdjm 	/* Key gen parameters */
82f1535dc8Sdjm 	int nbits;
83f1535dc8Sdjm 	BIGNUM *pub_exp;
84f1535dc8Sdjm 	/* Keygen callback info */
85f1535dc8Sdjm 	int gentmp[2];
86f1535dc8Sdjm 	/* RSA padding mode */
87f1535dc8Sdjm 	int pad_mode;
88f1535dc8Sdjm 	/* message digest */
89f1535dc8Sdjm 	const EVP_MD *md;
90ec07fdf1Sdjm 	/* message digest for MGF1 */
91ec07fdf1Sdjm 	const EVP_MD *mgf1md;
9295285806Sjsing 	/* PSS salt length */
93f1535dc8Sdjm 	int saltlen;
94ba05ae2dSjsing 	/* Minimum salt length or -1 if no PSS parameter restriction */
95ba05ae2dSjsing 	int min_saltlen;
96f1535dc8Sdjm 	/* Temp buffer */
97f1535dc8Sdjm 	unsigned char *tbuf;
9895285806Sjsing 	/* OAEP label */
9995285806Sjsing 	unsigned char *oaep_label;
10095285806Sjsing 	size_t oaep_labellen;
101f1535dc8Sdjm } RSA_PKEY_CTX;
102f1535dc8Sdjm 
103ba05ae2dSjsing /* True if PSS parameters are restricted */
104ba05ae2dSjsing #define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1)
105ba05ae2dSjsing 
10687203b09Smiod static int
10787203b09Smiod pkey_rsa_init(EVP_PKEY_CTX *ctx)
108f1535dc8Sdjm {
109f1535dc8Sdjm 	RSA_PKEY_CTX *rctx;
11087203b09Smiod 
11195285806Sjsing 	if ((rctx = calloc(1, sizeof(RSA_PKEY_CTX))) == NULL)
112f1535dc8Sdjm 		return 0;
11395285806Sjsing 
1144794023eSsthen 	rctx->nbits = 2048;
115ba05ae2dSjsing 
116ba05ae2dSjsing 	if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS)
117ba05ae2dSjsing 		rctx->pad_mode = RSA_PKCS1_PSS_PADDING;
118ba05ae2dSjsing 	else
119f1535dc8Sdjm 		rctx->pad_mode = RSA_PKCS1_PADDING;
120f1535dc8Sdjm 
121ba05ae2dSjsing 	/* Maximum for sign, auto for verify */
122ba05ae2dSjsing 	rctx->saltlen = RSA_PSS_SALTLEN_AUTO;
123ba05ae2dSjsing 	rctx->min_saltlen = -1;
124f1535dc8Sdjm 
125f1535dc8Sdjm 	ctx->data = rctx;
126f1535dc8Sdjm 	ctx->keygen_info = rctx->gentmp;
127f1535dc8Sdjm 	ctx->keygen_info_count = 2;
128f1535dc8Sdjm 
129f1535dc8Sdjm 	return 1;
130f1535dc8Sdjm }
131f1535dc8Sdjm 
13287203b09Smiod static int
13387203b09Smiod pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
134f1535dc8Sdjm {
135f1535dc8Sdjm 	RSA_PKEY_CTX *dctx, *sctx;
13687203b09Smiod 
137f1535dc8Sdjm 	if (!pkey_rsa_init(dst))
138f1535dc8Sdjm 		return 0;
13995285806Sjsing 
140f1535dc8Sdjm 	sctx = src->data;
141f1535dc8Sdjm 	dctx = dst->data;
142f1535dc8Sdjm 	dctx->nbits = sctx->nbits;
143b8d43259Sjsing 	if (sctx->pub_exp != NULL) {
144b8d43259Sjsing 		BN_free(dctx->pub_exp);
145b8d43259Sjsing 		if ((dctx->pub_exp = BN_dup(sctx->pub_exp)) == NULL)
146f1535dc8Sdjm 			return 0;
147f1535dc8Sdjm 	}
148f1535dc8Sdjm 	dctx->pad_mode = sctx->pad_mode;
149f1535dc8Sdjm 	dctx->md = sctx->md;
15095285806Sjsing 	dctx->mgf1md = sctx->mgf1md;
15195285806Sjsing 	if (sctx->oaep_label != NULL) {
15295285806Sjsing 		free(dctx->oaep_label);
15395285806Sjsing 		if ((dctx->oaep_label = calloc(1, sctx->oaep_labellen)) == NULL)
15495285806Sjsing 			return 0;
15595285806Sjsing 		memcpy(dctx->oaep_label, sctx->oaep_label, sctx->oaep_labellen);
15695285806Sjsing 		dctx->oaep_labellen = sctx->oaep_labellen;
15795285806Sjsing 	}
15895285806Sjsing 
159f1535dc8Sdjm 	return 1;
160f1535dc8Sdjm }
161f1535dc8Sdjm 
16287203b09Smiod static int
16387203b09Smiod setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
164f1535dc8Sdjm {
1655bc73cc3Sjsing 	if (ctx->tbuf != NULL)
166f1535dc8Sdjm 		return 1;
1675bc73cc3Sjsing 	if ((ctx->tbuf = calloc(1, EVP_PKEY_size(pk->pkey))) == NULL) {
1685bc73cc3Sjsing 		RSAerror(ERR_R_MALLOC_FAILURE);
169f1535dc8Sdjm 		return 0;
1705bc73cc3Sjsing 	}
171f1535dc8Sdjm 	return 1;
172f1535dc8Sdjm }
173f1535dc8Sdjm 
17487203b09Smiod static void
17587203b09Smiod pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
176f1535dc8Sdjm {
177f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
17887203b09Smiod 
17987203b09Smiod 	if (rctx) {
180f1535dc8Sdjm 		BN_free(rctx->pub_exp);
1816f3a6cb1Sbeck 		free(rctx->tbuf);
18295285806Sjsing 		free(rctx->oaep_label);
1836f3a6cb1Sbeck 		free(rctx);
184f1535dc8Sdjm 	}
185f1535dc8Sdjm }
18687203b09Smiod 
18787203b09Smiod static int
18887203b09Smiod pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
189f1535dc8Sdjm     const unsigned char *tbs, size_t tbslen)
190f1535dc8Sdjm {
1914349b8b3Stb 	int ret;
192f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
193f1535dc8Sdjm 	RSA *rsa = ctx->pkey->pkey.rsa;
194f1535dc8Sdjm 
19587203b09Smiod 	if (rctx->md) {
19687203b09Smiod 		if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
1975067ae9fSbeck 			RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
198f1535dc8Sdjm 			return -1;
199f1535dc8Sdjm 		}
200ec07fdf1Sdjm 
2014349b8b3Stb 		if (rctx->pad_mode == RSA_X931_PADDING) {
2024349b8b3Stb 			if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
2034349b8b3Stb 				RSAerror(RSA_R_KEY_SIZE_TOO_SMALL);
204f1535dc8Sdjm 				return -1;
2054349b8b3Stb 			}
2064349b8b3Stb 			if (!setup_tbuf(rctx, ctx)) {
2074349b8b3Stb 				RSAerror(ERR_R_MALLOC_FAILURE);
2084349b8b3Stb 				return -1;
2094349b8b3Stb 			}
2104349b8b3Stb 			memcpy(rctx->tbuf, tbs, tbslen);
2114349b8b3Stb 			rctx->tbuf[tbslen] =
2124349b8b3Stb 			    RSA_X931_hash_id(EVP_MD_type(rctx->md));
2134349b8b3Stb 			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig,
2144349b8b3Stb 			    rsa, RSA_X931_PADDING);
2154349b8b3Stb 		} else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
216f1535dc8Sdjm 			unsigned int sltmp;
21787203b09Smiod 
21887203b09Smiod 			ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig,
21987203b09Smiod 			    &sltmp, rsa);
220f1535dc8Sdjm 			if (ret <= 0)
221f1535dc8Sdjm 				return ret;
222f1535dc8Sdjm 			ret = sltmp;
22387203b09Smiod 		} else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
224f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
225f1535dc8Sdjm 				return -1;
22687203b09Smiod 			if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf,
22787203b09Smiod 			    tbs, rctx->md, rctx->mgf1md, rctx->saltlen))
228f1535dc8Sdjm 				return -1;
229f1535dc8Sdjm 			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
230f1535dc8Sdjm 			    sig, rsa, RSA_NO_PADDING);
2314349b8b3Stb 		} else {
2324349b8b3Stb 			return -1;
2330a0c1944Sjsing 		}
2340a0c1944Sjsing 	} else {
235f1535dc8Sdjm 		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
236f1535dc8Sdjm 		    rctx->pad_mode);
2370a0c1944Sjsing 	}
238f1535dc8Sdjm 	if (ret < 0)
239f1535dc8Sdjm 		return ret;
240f1535dc8Sdjm 	*siglen = ret;
241f1535dc8Sdjm 	return 1;
242f1535dc8Sdjm }
243f1535dc8Sdjm 
24487203b09Smiod static int
24587203b09Smiod pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
246f1535dc8Sdjm     const unsigned char *sig, size_t siglen)
247f1535dc8Sdjm {
248f1535dc8Sdjm 	int ret;
249f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
250f1535dc8Sdjm 
25187203b09Smiod 	if (rctx->md) {
2524349b8b3Stb 		if (rctx->pad_mode == RSA_X931_PADDING) {
2534349b8b3Stb 			if (!setup_tbuf(rctx, ctx))
254e0681702Stb 				return -1;
2554349b8b3Stb 			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
2564349b8b3Stb 			    ctx->pkey->pkey.rsa, RSA_X931_PADDING);
2574349b8b3Stb 			if (ret < 1)
2584349b8b3Stb 				return 0;
2594349b8b3Stb 			ret--;
2604349b8b3Stb 			if (rctx->tbuf[ret] !=
2614349b8b3Stb 			    RSA_X931_hash_id(EVP_MD_type(rctx->md))) {
2624349b8b3Stb 				RSAerror(RSA_R_ALGORITHM_MISMATCH);
2634349b8b3Stb 				return 0;
2644349b8b3Stb 			}
2654349b8b3Stb 			if (ret != EVP_MD_size(rctx->md)) {
2664349b8b3Stb 				RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
2674349b8b3Stb 				return 0;
2684349b8b3Stb 			}
2694349b8b3Stb 			if (rout)
2704349b8b3Stb 				memcpy(rout, rctx->tbuf, ret);
2714349b8b3Stb 		} else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
2724349b8b3Stb 			size_t sltmp;
273e0681702Stb 
27487203b09Smiod 			ret = int_rsa_verify(EVP_MD_type(rctx->md), NULL, 0,
27587203b09Smiod 			    rout, &sltmp, sig, siglen, ctx->pkey->pkey.rsa);
276f1535dc8Sdjm 			if (ret <= 0)
277f1535dc8Sdjm 				return 0;
278f1535dc8Sdjm 			ret = sltmp;
2790a0c1944Sjsing 		} else {
2804349b8b3Stb 			return -1;
2814349b8b3Stb 		}
2824349b8b3Stb 	} else {
283f1535dc8Sdjm 		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
284f1535dc8Sdjm 		    rctx->pad_mode);
2850a0c1944Sjsing 	}
286f1535dc8Sdjm 	if (ret < 0)
287f1535dc8Sdjm 		return ret;
288f1535dc8Sdjm 	*routlen = ret;
289f1535dc8Sdjm 	return 1;
290f1535dc8Sdjm }
291f1535dc8Sdjm 
29287203b09Smiod static int
29387203b09Smiod pkey_rsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
294f1535dc8Sdjm     const unsigned char *tbs, size_t tbslen)
295f1535dc8Sdjm {
296f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
297f1535dc8Sdjm 	RSA *rsa = ctx->pkey->pkey.rsa;
298f1535dc8Sdjm 	size_t rslen;
29987203b09Smiod 
30087203b09Smiod 	if (rctx->md) {
301f1535dc8Sdjm 		if (rctx->pad_mode == RSA_PKCS1_PADDING)
302f1535dc8Sdjm 			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
303f1535dc8Sdjm 			    sig, siglen, rsa);
3046fbfd349Sjsing 		if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
3056fbfd349Sjsing 			RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
3066fbfd349Sjsing 			return -1;
3076fbfd349Sjsing 		}
3084349b8b3Stb 		if (rctx->pad_mode == RSA_X931_PADDING) {
3094349b8b3Stb 			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig,
3104349b8b3Stb 			    siglen) <= 0)
3114349b8b3Stb 				return 0;
3124349b8b3Stb 		} else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
3134349b8b3Stb 			int ret;
31487203b09Smiod 
315f1535dc8Sdjm 			if (!setup_tbuf(rctx, ctx))
316f1535dc8Sdjm 				return -1;
317f1535dc8Sdjm 			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
318f1535dc8Sdjm 			    rsa, RSA_NO_PADDING);
319f1535dc8Sdjm 			if (ret <= 0)
320f1535dc8Sdjm 				return 0;
32187203b09Smiod 			ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md,
32287203b09Smiod 			    rctx->mgf1md, rctx->tbuf, rctx->saltlen);
323f1535dc8Sdjm 			if (ret <= 0)
324f1535dc8Sdjm 				return 0;
325f1535dc8Sdjm 			return 1;
3260a0c1944Sjsing 		} else {
3274349b8b3Stb 			return -1;
3284349b8b3Stb 		}
3294349b8b3Stb 	} else {
3304349b8b3Stb 		int ret;
3314349b8b3Stb 
332f1535dc8Sdjm 		if (!setup_tbuf(rctx, ctx))
333f1535dc8Sdjm 			return -1;
334e8c28445Stb 
335e8c28445Stb 		if ((ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa,
336e8c28445Stb 		    rctx->pad_mode)) <= 0)
337f1535dc8Sdjm 			return 0;
338e8c28445Stb 
339e8c28445Stb 		rslen = ret;
340f1535dc8Sdjm 	}
341f1535dc8Sdjm 
3422f115aa8Sdjm 	if (rslen != tbslen || timingsafe_bcmp(tbs, rctx->tbuf, rslen))
343f1535dc8Sdjm 		return 0;
344f1535dc8Sdjm 
345f1535dc8Sdjm 	return 1;
346f1535dc8Sdjm }
347f1535dc8Sdjm 
34887203b09Smiod static int
34987203b09Smiod pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
350f1535dc8Sdjm     const unsigned char *in, size_t inlen)
351f1535dc8Sdjm {
352f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
35395285806Sjsing 	int ret;
35487203b09Smiod 
35595285806Sjsing 	if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
35695285806Sjsing 		int klen = RSA_size(ctx->pkey->pkey.rsa);
35795285806Sjsing 		if (!setup_tbuf(rctx, ctx))
35895285806Sjsing 			return -1;
35995285806Sjsing 		if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
36095285806Sjsing 		    in, inlen, rctx->oaep_label, rctx->oaep_labellen,
36195285806Sjsing 		    rctx->md, rctx->mgf1md))
36295285806Sjsing 			return -1;
36395285806Sjsing 		ret = RSA_public_encrypt(klen, rctx->tbuf, out,
36495285806Sjsing 		    ctx->pkey->pkey.rsa, RSA_NO_PADDING);
36595285806Sjsing 	} else {
366f1535dc8Sdjm 		ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
367f1535dc8Sdjm 		    rctx->pad_mode);
36895285806Sjsing 	}
369f1535dc8Sdjm 	if (ret < 0)
370f1535dc8Sdjm 		return ret;
371f1535dc8Sdjm 	*outlen = ret;
372f1535dc8Sdjm 	return 1;
373f1535dc8Sdjm }
374f1535dc8Sdjm 
37587203b09Smiod static int
37687203b09Smiod pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
377f1535dc8Sdjm     const unsigned char *in, size_t inlen)
378f1535dc8Sdjm {
379f1535dc8Sdjm 	int ret;
380f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
38187203b09Smiod 
38295285806Sjsing 	if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
38395285806Sjsing 		if (!setup_tbuf(rctx, ctx))
38495285806Sjsing 			return -1;
38595285806Sjsing 		ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
38695285806Sjsing 		    ctx->pkey->pkey.rsa, RSA_NO_PADDING);
38795285806Sjsing 		if (ret <= 0)
38895285806Sjsing 			return ret;
38995285806Sjsing 		ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf,
39095285806Sjsing 		    ret, ret, rctx->oaep_label, rctx->oaep_labellen, rctx->md,
39195285806Sjsing 		    rctx->mgf1md);
39295285806Sjsing 	} else {
393f1535dc8Sdjm 		ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
394f1535dc8Sdjm 		    rctx->pad_mode);
39595285806Sjsing 	}
396f1535dc8Sdjm 	if (ret < 0)
397f1535dc8Sdjm 		return ret;
398f1535dc8Sdjm 	*outlen = ret;
399f1535dc8Sdjm 	return 1;
400f1535dc8Sdjm }
401f1535dc8Sdjm 
40287203b09Smiod static int
40387203b09Smiod check_padding_md(const EVP_MD *md, int padding)
404f1535dc8Sdjm {
405ba05ae2dSjsing 	if (md == NULL)
406f1535dc8Sdjm 		return 1;
407f1535dc8Sdjm 
4084349b8b3Stb 	if (padding == RSA_NO_PADDING) {
4094349b8b3Stb 		RSAerror(RSA_R_INVALID_PADDING_MODE);
410f1535dc8Sdjm 		return 0;
411f1535dc8Sdjm 	}
412f1535dc8Sdjm 
4134349b8b3Stb 	if (padding == RSA_X931_PADDING) {
4144349b8b3Stb 		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) {
4154349b8b3Stb 			RSAerror(RSA_R_INVALID_X931_DIGEST);
4164349b8b3Stb 			return 0;
4174349b8b3Stb 		}
4184349b8b3Stb 	} else {
419ba05ae2dSjsing 		/* List of all supported RSA digests. */
4209a5a6ad9Stb 		/* RFC 8017 and NIST CSOR. */
421ba05ae2dSjsing 		switch(EVP_MD_type(md)) {
422ba05ae2dSjsing 		case NID_sha1:
423ba05ae2dSjsing 		case NID_sha224:
424ba05ae2dSjsing 		case NID_sha256:
425ba05ae2dSjsing 		case NID_sha384:
426ba05ae2dSjsing 		case NID_sha512:
4279a5a6ad9Stb 		case NID_sha512_224:
4289a5a6ad9Stb 		case NID_sha512_256:
4299a5a6ad9Stb 		case NID_sha3_224:
4309a5a6ad9Stb 		case NID_sha3_256:
4319a5a6ad9Stb 		case NID_sha3_384:
4329a5a6ad9Stb 		case NID_sha3_512:
433ba05ae2dSjsing 		case NID_md5:
434ba05ae2dSjsing 		case NID_md5_sha1:
435ba05ae2dSjsing 		case NID_md4:
436ba05ae2dSjsing 		case NID_ripemd160:
437f1535dc8Sdjm 			return 1;
438ba05ae2dSjsing 
439ba05ae2dSjsing 		default:
440ba05ae2dSjsing 			RSAerror(RSA_R_INVALID_DIGEST);
441ba05ae2dSjsing 			return 0;
442ba05ae2dSjsing 		}
4434349b8b3Stb 	}
444f1535dc8Sdjm 
445f1535dc8Sdjm 	return 1;
446f1535dc8Sdjm }
447f1535dc8Sdjm 
44887203b09Smiod static int
44987203b09Smiod pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
450f1535dc8Sdjm {
451f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
45214a995a9Sjsing 
45387203b09Smiod 	switch (type) {
454f1535dc8Sdjm 	case EVP_PKEY_CTRL_RSA_PADDING:
45587203b09Smiod 		if (p1 >= RSA_PKCS1_PADDING && p1 <= RSA_PKCS1_PSS_PADDING) {
456f1535dc8Sdjm 			if (!check_padding_md(rctx->md, p1))
457f1535dc8Sdjm 				return 0;
45887203b09Smiod 			if (p1 == RSA_PKCS1_PSS_PADDING) {
459f1535dc8Sdjm 				if (!(ctx->operation &
460f1535dc8Sdjm 				    (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
461f1535dc8Sdjm 					goto bad_pad;
462f1535dc8Sdjm 				if (!rctx->md)
463f1535dc8Sdjm 					rctx->md = EVP_sha1();
464ba05ae2dSjsing 			} else if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) {
465ba05ae2dSjsing 				goto bad_pad;
466f1535dc8Sdjm 			}
46787203b09Smiod 			if (p1 == RSA_PKCS1_OAEP_PADDING) {
468f1535dc8Sdjm 				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
469f1535dc8Sdjm 					goto bad_pad;
470f1535dc8Sdjm 				if (!rctx->md)
471f1535dc8Sdjm 					rctx->md = EVP_sha1();
472f1535dc8Sdjm 			}
473f1535dc8Sdjm 			rctx->pad_mode = p1;
474f1535dc8Sdjm 			return 1;
475f1535dc8Sdjm 		}
476f1535dc8Sdjm  bad_pad:
4775067ae9fSbeck 		RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
478f1535dc8Sdjm 		return -2;
479f1535dc8Sdjm 
480ec07fdf1Sdjm 	case EVP_PKEY_CTRL_GET_RSA_PADDING:
481ec07fdf1Sdjm 		*(int *)p2 = rctx->pad_mode;
482ec07fdf1Sdjm 		return 1;
483ec07fdf1Sdjm 
484f1535dc8Sdjm 	case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
485ec07fdf1Sdjm 	case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
48687203b09Smiod 		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
4875067ae9fSbeck 			RSAerror(RSA_R_INVALID_PSS_SALTLEN);
488f1535dc8Sdjm 			return -2;
489f1535dc8Sdjm 		}
4900a0c1944Sjsing 		if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
491ec07fdf1Sdjm 			*(int *)p2 = rctx->saltlen;
4920a0c1944Sjsing 		} else {
493ba05ae2dSjsing 			if (p1 < RSA_PSS_SALTLEN_MAX)
494ec07fdf1Sdjm 				return -2;
495ba05ae2dSjsing 			if (rsa_pss_restricted(rctx)) {
496ba05ae2dSjsing 				if (p1 == RSA_PSS_SALTLEN_AUTO &&
497ba05ae2dSjsing 				    ctx->operation == EVP_PKEY_OP_VERIFY) {
498ba05ae2dSjsing 					RSAerror(RSA_R_INVALID_PSS_SALTLEN);
499ba05ae2dSjsing 					return -2;
500ba05ae2dSjsing 				}
501ba05ae2dSjsing 				if ((p1 == RSA_PSS_SALTLEN_DIGEST &&
502ba05ae2dSjsing 				    rctx->min_saltlen > EVP_MD_size(rctx->md)) ||
503ba05ae2dSjsing 				    (p1 >= 0 && p1 < rctx->min_saltlen)) {
504ba05ae2dSjsing 					RSAerror(RSA_R_PSS_SALTLEN_TOO_SMALL);
505ba05ae2dSjsing 					return 0;
506ba05ae2dSjsing 				}
507ba05ae2dSjsing 			}
508f1535dc8Sdjm 			rctx->saltlen = p1;
509ec07fdf1Sdjm 		}
510f1535dc8Sdjm 		return 1;
511f1535dc8Sdjm 
512f1535dc8Sdjm 	case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
513a307e4caSjsing 		if (p1 < RSA_MIN_MODULUS_BITS) {
514a307e4caSjsing 			RSAerror(RSA_R_KEY_SIZE_TOO_SMALL);
515f1535dc8Sdjm 			return -2;
516f1535dc8Sdjm 		}
517f1535dc8Sdjm 		rctx->nbits = p1;
518f1535dc8Sdjm 		return 1;
519f1535dc8Sdjm 
520f1535dc8Sdjm 	case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
5216fbfd349Sjsing 		if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) ||
5226fbfd349Sjsing 		    BN_is_one((BIGNUM *)p2)) {
5236fbfd349Sjsing 			RSAerror(RSA_R_BAD_E_VALUE);
524f1535dc8Sdjm 			return -2;
5256fbfd349Sjsing 		}
5266fbfd349Sjsing 		BN_free(rctx->pub_exp);
527f1535dc8Sdjm 		rctx->pub_exp = p2;
528f1535dc8Sdjm 		return 1;
529f1535dc8Sdjm 
53085ca4670Sjsing 	case EVP_PKEY_CTRL_RSA_OAEP_MD:
53185ca4670Sjsing 	case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
53285ca4670Sjsing 		if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
53385ca4670Sjsing 			RSAerror(RSA_R_INVALID_PADDING_MODE);
53485ca4670Sjsing 			return -2;
53585ca4670Sjsing 		}
53685ca4670Sjsing 		if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD)
53785ca4670Sjsing 			*(const EVP_MD **)p2 = rctx->md;
53885ca4670Sjsing 		else
53985ca4670Sjsing 			rctx->md = p2;
54085ca4670Sjsing 		return 1;
54185ca4670Sjsing 
542f1535dc8Sdjm 	case EVP_PKEY_CTRL_MD:
543f1535dc8Sdjm 		if (!check_padding_md(p2, rctx->pad_mode))
544f1535dc8Sdjm 			return 0;
545ba05ae2dSjsing 		if (rsa_pss_restricted(rctx)) {
546ba05ae2dSjsing 			if (EVP_MD_type(rctx->md) == EVP_MD_type(p2))
547ba05ae2dSjsing 				return 1;
548ba05ae2dSjsing 			RSAerror(RSA_R_DIGEST_NOT_ALLOWED);
549ba05ae2dSjsing 			return 0;
550ba05ae2dSjsing 		}
551f1535dc8Sdjm 		rctx->md = p2;
552f1535dc8Sdjm 		return 1;
553f1535dc8Sdjm 
5546627381bSjsing 	case EVP_PKEY_CTRL_GET_MD:
5556627381bSjsing 		*(const EVP_MD **)p2 = rctx->md;
5566627381bSjsing 		return 1;
5576627381bSjsing 
558ec07fdf1Sdjm 	case EVP_PKEY_CTRL_RSA_MGF1_MD:
559ec07fdf1Sdjm 	case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
56095285806Sjsing 		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
56195285806Sjsing 		    rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
5625067ae9fSbeck 			RSAerror(RSA_R_INVALID_MGF1_MD);
563ec07fdf1Sdjm 			return -2;
564ec07fdf1Sdjm 		}
56587203b09Smiod 		if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
566ec07fdf1Sdjm 			if (rctx->mgf1md)
567ec07fdf1Sdjm 				*(const EVP_MD **)p2 = rctx->mgf1md;
568ec07fdf1Sdjm 			else
569ec07fdf1Sdjm 				*(const EVP_MD **)p2 = rctx->md;
570ba05ae2dSjsing 		} else {
571ba05ae2dSjsing 			if (rsa_pss_restricted(rctx)) {
572ba05ae2dSjsing 				if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2))
573ba05ae2dSjsing 					return 1;
574ba05ae2dSjsing 				RSAerror(RSA_R_MGF1_DIGEST_NOT_ALLOWED);
575ba05ae2dSjsing 				return 0;
576ba05ae2dSjsing 			}
577ec07fdf1Sdjm 			rctx->mgf1md = p2;
578ba05ae2dSjsing 		}
579ec07fdf1Sdjm 		return 1;
580ec07fdf1Sdjm 
58195285806Sjsing 	case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
58295285806Sjsing 		if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
58395285806Sjsing 			RSAerror(RSA_R_INVALID_PADDING_MODE);
58495285806Sjsing 			return -2;
58595285806Sjsing 		}
58695285806Sjsing 		free(rctx->oaep_label);
58795285806Sjsing 		if (p2 != NULL && p1 > 0) {
58895285806Sjsing 			rctx->oaep_label = p2;
58995285806Sjsing 			rctx->oaep_labellen = p1;
59095285806Sjsing 		} else {
59195285806Sjsing 			rctx->oaep_label = NULL;
59295285806Sjsing 			rctx->oaep_labellen = 0;
59395285806Sjsing 		}
59495285806Sjsing 		return 1;
59595285806Sjsing 
59695285806Sjsing 	case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
59795285806Sjsing 		if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
59895285806Sjsing 			RSAerror(RSA_R_INVALID_PADDING_MODE);
59995285806Sjsing 			return -2;
60095285806Sjsing 		}
60195285806Sjsing 		*(unsigned char **)p2 = rctx->oaep_label;
60295285806Sjsing 		return rctx->oaep_labellen;
60395285806Sjsing 
604f1535dc8Sdjm 	case EVP_PKEY_CTRL_DIGESTINIT:
605f1535dc8Sdjm 	case EVP_PKEY_CTRL_PKCS7_SIGN:
606a48d29b1Sjsing #ifndef OPENSSL_NO_CMS
607a48d29b1Sjsing 	case EVP_PKEY_CTRL_CMS_SIGN:
608a48d29b1Sjsing #endif
609f1535dc8Sdjm 		return 1;
610ba05ae2dSjsing 
611ba05ae2dSjsing 	case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
612ba05ae2dSjsing 	case EVP_PKEY_CTRL_PKCS7_DECRYPT:
613a48d29b1Sjsing #ifndef OPENSSL_NO_CMS
614a48d29b1Sjsing 	case EVP_PKEY_CTRL_CMS_DECRYPT:
615a48d29b1Sjsing 	case EVP_PKEY_CTRL_CMS_ENCRYPT:
616a48d29b1Sjsing #endif
617ba05ae2dSjsing 		if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
618ba05ae2dSjsing 			return 1;
619ba05ae2dSjsing 
620ba05ae2dSjsing 	/* fall through */
621f1535dc8Sdjm 	case EVP_PKEY_CTRL_PEER_KEY:
6225067ae9fSbeck 		RSAerror(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
623f1535dc8Sdjm 		return -2;
624f1535dc8Sdjm 
625f1535dc8Sdjm 	default:
626f1535dc8Sdjm 		return -2;
627ba05ae2dSjsing 
628f1535dc8Sdjm 	}
629f1535dc8Sdjm }
630f1535dc8Sdjm 
63187203b09Smiod static int
63287203b09Smiod pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
633f1535dc8Sdjm {
63440e63673Sop 	const char *errstr;
63540e63673Sop 
63687203b09Smiod 	if (!value) {
6375067ae9fSbeck 		RSAerror(RSA_R_VALUE_MISSING);
638f1535dc8Sdjm 		return 0;
639f1535dc8Sdjm 	}
640*457dff42Stb 	if (strcmp(type, "rsa_padding_mode") == 0) {
641f1535dc8Sdjm 		int pm;
642*457dff42Stb 		if (strcmp(value, "pkcs1") == 0)
643f1535dc8Sdjm 			pm = RSA_PKCS1_PADDING;
644*457dff42Stb 		else if (strcmp(value, "none") == 0)
645f1535dc8Sdjm 			pm = RSA_NO_PADDING;
646*457dff42Stb 		else if (strcmp(value, "oaep") == 0 || strcmp(value, "oeap") == 0)
647f1535dc8Sdjm 			pm = RSA_PKCS1_OAEP_PADDING;
648*457dff42Stb 		else if (strcmp(value, "x931") == 0)
6494349b8b3Stb 			pm = RSA_X931_PADDING;
650*457dff42Stb 		else if (strcmp(value, "pss") == 0)
651f1535dc8Sdjm 			pm = RSA_PKCS1_PSS_PADDING;
65287203b09Smiod 		else {
6535067ae9fSbeck 			RSAerror(RSA_R_UNKNOWN_PADDING_TYPE);
654f1535dc8Sdjm 			return -2;
655f1535dc8Sdjm 		}
656f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
657f1535dc8Sdjm 	}
658f1535dc8Sdjm 
659ba05ae2dSjsing 	if (strcmp(type, "rsa_pss_saltlen") == 0) {
660f1535dc8Sdjm 		int saltlen;
661b1d57841Sderaadt 
662*457dff42Stb 		if (strcmp(value, "digest") == 0)
663ba05ae2dSjsing 			saltlen = RSA_PSS_SALTLEN_DIGEST;
664*457dff42Stb 		else if (strcmp(value, "max") == 0)
665ba05ae2dSjsing 			saltlen = RSA_PSS_SALTLEN_MAX;
666*457dff42Stb 		else if (strcmp(value, "auto") == 0)
667ba05ae2dSjsing 			saltlen = RSA_PSS_SALTLEN_AUTO;
66840e63673Sop 		else {
669ac07061aStb 			/*
670ac07061aStb 			 * Accept the special values -1, -2, -3 since that's
671ac07061aStb 			 * what atoi() historically did. Lower values are later
672ac07061aStb 			 * rejected in EVP_PKEY_CTRL_RSA_PSS_SALTLEN anyway.
673ac07061aStb 			 */
674ac07061aStb 			saltlen = strtonum(value, -3, INT_MAX, &errstr);
67540e63673Sop 			if (errstr != NULL) {
67640e63673Sop 				RSAerror(RSA_R_INVALID_PSS_SALTLEN);
67740e63673Sop 				return -2;
67840e63673Sop 			}
67940e63673Sop 		}
680f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
681f1535dc8Sdjm 	}
682f1535dc8Sdjm 
683ba05ae2dSjsing 	if (strcmp(type, "rsa_keygen_bits") == 0) {
68440e63673Sop 		int nbits;
68540e63673Sop 
68640e63673Sop 		nbits = strtonum(value, 0, INT_MAX, &errstr);
68740e63673Sop 		if (errstr != NULL) {
68840e63673Sop 			RSAerror(RSA_R_INVALID_KEYBITS);
68940e63673Sop 			return -2;
69040e63673Sop 		}
691b1d57841Sderaadt 
692f1535dc8Sdjm 		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
693f1535dc8Sdjm 	}
694f1535dc8Sdjm 
695ba05ae2dSjsing 	if (strcmp(type, "rsa_keygen_pubexp") == 0) {
696f1535dc8Sdjm 		BIGNUM *pubexp = NULL;
697ba05ae2dSjsing 		int ret;
69887203b09Smiod 
699f1535dc8Sdjm 		if (!BN_asc2bn(&pubexp, value))
700f1535dc8Sdjm 			return 0;
701f1535dc8Sdjm 		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
702f1535dc8Sdjm 		if (ret <= 0)
703f1535dc8Sdjm 			BN_free(pubexp);
704f1535dc8Sdjm 		return ret;
705f1535dc8Sdjm 	}
706f1535dc8Sdjm 
70795285806Sjsing 	if (strcmp(type, "rsa_mgf1_md") == 0)
70895285806Sjsing 		return EVP_PKEY_CTX_md(ctx,
70995285806Sjsing 		    EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
71095285806Sjsing 		    EVP_PKEY_CTRL_RSA_MGF1_MD, value);
71195285806Sjsing 
712ba05ae2dSjsing 	if (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) {
713ba05ae2dSjsing 		if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0)
714ba05ae2dSjsing 			return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN,
715ba05ae2dSjsing 			    EVP_PKEY_CTRL_RSA_MGF1_MD, value);
716ba05ae2dSjsing 
717ba05ae2dSjsing 		if (strcmp(type, "rsa_pss_keygen_md") == 0)
718ba05ae2dSjsing 			return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN,
719ba05ae2dSjsing 			    EVP_PKEY_CTRL_MD, value);
720ba05ae2dSjsing 
721ba05ae2dSjsing 		if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) {
72240e63673Sop 			int saltlen;
72340e63673Sop 
724ac07061aStb 			/*
725ac07061aStb 			 * Accept the special values -1, -2, -3 since that's
726ac07061aStb 			 * what atoi() historically did. Lower values are later
727ac07061aStb 			 * rejected in EVP_PKEY_CTRL_RSA_PSS_SALTLEN anyway.
728ac07061aStb 			 */
729ac07061aStb 			saltlen = strtonum(value, -3, INT_MAX, &errstr);
73040e63673Sop 			if (errstr != NULL) {
73140e63673Sop 				RSAerror(RSA_R_INVALID_PSS_SALTLEN);
73240e63673Sop 				return -2;
73340e63673Sop 			}
734ba05ae2dSjsing 
735ba05ae2dSjsing 			return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen);
736ba05ae2dSjsing 		}
737ba05ae2dSjsing 	}
738ba05ae2dSjsing 
73995285806Sjsing 	if (strcmp(type, "rsa_oaep_md") == 0)
74095285806Sjsing 		return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT,
74195285806Sjsing 		    EVP_PKEY_CTRL_RSA_OAEP_MD, value);
74295285806Sjsing 
74395285806Sjsing 	if (strcmp(type, "rsa_oaep_label") == 0) {
74495285806Sjsing 		unsigned char *lab;
74595285806Sjsing 		long lablen;
74695285806Sjsing 		int ret;
74795285806Sjsing 
74895285806Sjsing 		if ((lab = string_to_hex(value, &lablen)) == NULL)
74995285806Sjsing 			return 0;
75095285806Sjsing 		ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
75195285806Sjsing 		if (ret <= 0)
75295285806Sjsing 			free(lab);
75395285806Sjsing 
75495285806Sjsing 		return ret;
75595285806Sjsing 	}
75695285806Sjsing 
757f1535dc8Sdjm 	return -2;
758f1535dc8Sdjm }
759f1535dc8Sdjm 
760ba05ae2dSjsing /* Set PSS parameters when generating a key, if necessary. */
761ba05ae2dSjsing static int
762ba05ae2dSjsing rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx)
763ba05ae2dSjsing {
764ba05ae2dSjsing 	RSA_PKEY_CTX *rctx = ctx->data;
765ba05ae2dSjsing 
766ba05ae2dSjsing 	if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
767ba05ae2dSjsing 		return 1;
768ba05ae2dSjsing 
769ba05ae2dSjsing 	/* If all parameters are default values then do not set PSS. */
770ba05ae2dSjsing 	if (rctx->md == NULL && rctx->mgf1md == NULL &&
771ba05ae2dSjsing 	    rctx->saltlen == RSA_PSS_SALTLEN_AUTO)
772ba05ae2dSjsing 		return 1;
773ba05ae2dSjsing 
774ba05ae2dSjsing 	rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md,
775ba05ae2dSjsing 	    rctx->saltlen == RSA_PSS_SALTLEN_AUTO ? 0 : rctx->saltlen);
776ba05ae2dSjsing 	if (rsa->pss == NULL)
777ba05ae2dSjsing 		return 0;
778ba05ae2dSjsing 
779ba05ae2dSjsing 	return 1;
780ba05ae2dSjsing }
781ba05ae2dSjsing 
78287203b09Smiod static int
78387203b09Smiod pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
784f1535dc8Sdjm {
785f1535dc8Sdjm 	RSA *rsa = NULL;
786f1535dc8Sdjm 	RSA_PKEY_CTX *rctx = ctx->data;
7870f0ee19aStb 	BN_GENCB *pcb = NULL;
7880f0ee19aStb 	BN_GENCB cb = {0};
7890f0ee19aStb 	int ret = 0;
79087203b09Smiod 
7915bc73cc3Sjsing 	if (rctx->pub_exp == NULL) {
7925bc73cc3Sjsing 		if ((rctx->pub_exp = BN_new()) == NULL)
7930f0ee19aStb 			goto err;
7945bc73cc3Sjsing 		if (!BN_set_word(rctx->pub_exp, RSA_F4))
7950f0ee19aStb 			goto err;
796f1535dc8Sdjm 	}
7970f0ee19aStb 
7985bc73cc3Sjsing 	if ((rsa = RSA_new()) == NULL)
7990f0ee19aStb 		goto err;
8005bc73cc3Sjsing 	if (ctx->pkey_gencb != NULL) {
801f1535dc8Sdjm 		pcb = &cb;
802f1535dc8Sdjm 		evp_pkey_set_cb_translate(pcb, ctx);
8035bc73cc3Sjsing 	}
8040f0ee19aStb 	if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb))
8050f0ee19aStb 		goto err;
8060f0ee19aStb 	if (!rsa_set_pss_param(rsa, ctx))
8070f0ee19aStb 		goto err;
8080f0ee19aStb 	if (!EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa))
8090f0ee19aStb 		goto err;
8100f0ee19aStb 	rsa = NULL;
8110f0ee19aStb 
8120f0ee19aStb 	ret = 1;
8130f0ee19aStb 
8140f0ee19aStb  err:
815ba05ae2dSjsing 	RSA_free(rsa);
8160f0ee19aStb 
817f1535dc8Sdjm 	return ret;
818f1535dc8Sdjm }
819f1535dc8Sdjm 
820e402ce74Smiod const EVP_PKEY_METHOD rsa_pkey_meth = {
821e402ce74Smiod 	.pkey_id = EVP_PKEY_RSA,
822e402ce74Smiod 	.flags = EVP_PKEY_FLAG_AUTOARGLEN,
823f1535dc8Sdjm 
824e402ce74Smiod 	.init = pkey_rsa_init,
825e402ce74Smiod 	.copy = pkey_rsa_copy,
826e402ce74Smiod 	.cleanup = pkey_rsa_cleanup,
827f1535dc8Sdjm 
828e402ce74Smiod 	.keygen = pkey_rsa_keygen,
829f1535dc8Sdjm 
830e402ce74Smiod 	.sign = pkey_rsa_sign,
831f1535dc8Sdjm 
832e402ce74Smiod 	.verify = pkey_rsa_verify,
833f1535dc8Sdjm 
834e402ce74Smiod 	.verify_recover = pkey_rsa_verifyrecover,
835f1535dc8Sdjm 
836e402ce74Smiod 	.encrypt = pkey_rsa_encrypt,
837f1535dc8Sdjm 
838e402ce74Smiod 	.decrypt = pkey_rsa_decrypt,
839f1535dc8Sdjm 
840e402ce74Smiod 	.ctrl = pkey_rsa_ctrl,
841e402ce74Smiod 	.ctrl_str = pkey_rsa_ctrl_str
842f1535dc8Sdjm };
843ba05ae2dSjsing 
844ba05ae2dSjsing /*
845ba05ae2dSjsing  * Called for PSS sign or verify initialisation: checks PSS parameter
846ba05ae2dSjsing  * sanity and sets any restrictions on key usage.
847ba05ae2dSjsing  */
848ba05ae2dSjsing 
849ba05ae2dSjsing static int
850ba05ae2dSjsing pkey_pss_init(EVP_PKEY_CTX *ctx)
851ba05ae2dSjsing {
852ba05ae2dSjsing 	RSA *rsa;
853ba05ae2dSjsing 	RSA_PKEY_CTX *rctx = ctx->data;
854ba05ae2dSjsing 	const EVP_MD *md;
855ba05ae2dSjsing 	const EVP_MD *mgf1md;
856ba05ae2dSjsing 	int min_saltlen, max_saltlen;
857ba05ae2dSjsing 
858ba05ae2dSjsing 	/* Should never happen */
859ba05ae2dSjsing 	if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
860ba05ae2dSjsing 		return 0;
861ba05ae2dSjsing 	rsa = ctx->pkey->pkey.rsa;
862ba05ae2dSjsing 
863ba05ae2dSjsing 	/* If no restrictions just return */
864ba05ae2dSjsing 	if (rsa->pss == NULL)
865ba05ae2dSjsing 		return 1;
866ba05ae2dSjsing 
867ba05ae2dSjsing 	/* Get and check parameters */
868ba05ae2dSjsing 	if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen))
869ba05ae2dSjsing 		return 0;
870ba05ae2dSjsing 
871ba05ae2dSjsing 	/* See if minimum salt length exceeds maximum possible */
872ba05ae2dSjsing 	max_saltlen = RSA_size(rsa) - EVP_MD_size(md);
873ba05ae2dSjsing 	if ((RSA_bits(rsa) & 0x7) == 1)
874ba05ae2dSjsing 		max_saltlen--;
875ba05ae2dSjsing 	if (min_saltlen > max_saltlen) {
876ba05ae2dSjsing 		RSAerror(RSA_R_INVALID_SALT_LENGTH);
877ba05ae2dSjsing 		return 0;
878ba05ae2dSjsing 	}
879ba05ae2dSjsing 	rctx->min_saltlen = min_saltlen;
880ba05ae2dSjsing 
881ba05ae2dSjsing 	/*
882ba05ae2dSjsing 	 * Set PSS restrictions as defaults: we can then block any attempt to
883ba05ae2dSjsing 	 * use invalid values in pkey_rsa_ctrl
884ba05ae2dSjsing 	 */
885ba05ae2dSjsing 
886ba05ae2dSjsing 	rctx->md = md;
887ba05ae2dSjsing 	rctx->mgf1md = mgf1md;
888ba05ae2dSjsing 	rctx->saltlen = min_saltlen;
889ba05ae2dSjsing 
890ba05ae2dSjsing 	return 1;
891ba05ae2dSjsing }
892ba05ae2dSjsing 
893ba05ae2dSjsing const EVP_PKEY_METHOD rsa_pss_pkey_meth = {
894ba05ae2dSjsing 	.pkey_id = EVP_PKEY_RSA_PSS,
895ba05ae2dSjsing 	.flags = EVP_PKEY_FLAG_AUTOARGLEN,
896ba05ae2dSjsing 
897ba05ae2dSjsing 	.init = pkey_rsa_init,
898ba05ae2dSjsing 	.copy = pkey_rsa_copy,
899ba05ae2dSjsing 	.cleanup = pkey_rsa_cleanup,
900ba05ae2dSjsing 
901ba05ae2dSjsing 	.keygen = pkey_rsa_keygen,
902ba05ae2dSjsing 
903ba05ae2dSjsing 	.sign_init = pkey_pss_init,
904ba05ae2dSjsing 	.sign = pkey_rsa_sign,
905ba05ae2dSjsing 
906ba05ae2dSjsing 	.verify_init = pkey_pss_init,
907ba05ae2dSjsing 	.verify = pkey_rsa_verify,
908ba05ae2dSjsing 
909ba05ae2dSjsing 	.ctrl = pkey_rsa_ctrl,
910ba05ae2dSjsing 	.ctrl_str = pkey_rsa_ctrl_str
911ba05ae2dSjsing };
912