xref: /openbsd-src/lib/libcrypto/rsa/rsa_ameth.c (revision 603e484152292f737f00c3af0a3004d6ee24ef5a)
1*603e4841Stb /* $OpenBSD: rsa_ameth.c,v 1.62 2024/11/02 07:11:14 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 
59b8a66e7eStb #include <stdint.h>
60*603e4841Stb #include <stdio.h>
61b8a66e7eStb #include <stdlib.h>
628cf4d6a6Sjsing 
638cf4d6a6Sjsing #include <openssl/opensslconf.h>
648cf4d6a6Sjsing 
65b8a66e7eStb #include <openssl/asn1.h>
66b8a66e7eStb #include <openssl/bio.h>
67f1535dc8Sdjm #include <openssl/bn.h>
68c4380ae9Sjsing #include <openssl/cms.h>
69b6ab114eSjsing #include <openssl/err.h>
70b8a66e7eStb #include <openssl/evp.h>
71b8a66e7eStb #include <openssl/objects.h>
72b8a66e7eStb #include <openssl/pkcs7.h>
737758229eStb #include <openssl/rsa.h>
74b8a66e7eStb #include <openssl/sha.h>
75b6ab114eSjsing #include <openssl/x509.h>
76b6ab114eSjsing 
77c9675a23Stb #include "asn1_local.h"
78549c133bStb #include "bn_local.h"
79c9675a23Stb #include "evp_local.h"
80c9675a23Stb #include "rsa_local.h"
8182b80301Stb #include "x509_local.h"
82e119b44aSjsing 
83c4380ae9Sjsing #ifndef OPENSSL_NO_CMS
84c4380ae9Sjsing static int rsa_cms_sign(CMS_SignerInfo *si);
85c4380ae9Sjsing static int rsa_cms_verify(CMS_SignerInfo *si);
86c4380ae9Sjsing static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
87c4380ae9Sjsing static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
88c4380ae9Sjsing #endif
89c4380ae9Sjsing 
90e119b44aSjsing static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg);
91e119b44aSjsing 
92ffbbbf5cStb static int rsa_alg_set_pkcs1_padding(X509_ALGOR *alg);
93ffbbbf5cStb 
94e119b44aSjsing /* Set any parameters associated with pkey */
95e119b44aSjsing static int
96e119b44aSjsing rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype)
97e119b44aSjsing {
98e119b44aSjsing 	const RSA *rsa = pkey->pkey.rsa;
99e119b44aSjsing 
100e119b44aSjsing 	*pstr = NULL;
101e119b44aSjsing 
102e119b44aSjsing 	/* If RSA it's just NULL type */
103e119b44aSjsing 	if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) {
104e119b44aSjsing 		*pstrtype = V_ASN1_NULL;
105e119b44aSjsing 		return 1;
106e119b44aSjsing 	}
107e119b44aSjsing 
108e119b44aSjsing 	/* If no PSS parameters we omit parameters entirely */
109e119b44aSjsing 	if (rsa->pss == NULL) {
110e119b44aSjsing 		*pstrtype = V_ASN1_UNDEF;
111e119b44aSjsing 		return 1;
112e119b44aSjsing 	}
113e119b44aSjsing 
114e119b44aSjsing 	/* Encode PSS parameters */
115e119b44aSjsing 	if (ASN1_item_pack(rsa->pss, &RSA_PSS_PARAMS_it, pstr) == NULL)
116e119b44aSjsing 		return 0;
117e119b44aSjsing 
118e119b44aSjsing 	*pstrtype = V_ASN1_SEQUENCE;
119e119b44aSjsing 	return 1;
120e119b44aSjsing }
121e119b44aSjsing 
122e119b44aSjsing /* Decode any parameters and set them in RSA structure */
123e119b44aSjsing static int
124e119b44aSjsing rsa_param_decode(RSA *rsa, const X509_ALGOR *alg)
125e119b44aSjsing {
126e119b44aSjsing 	const ASN1_OBJECT *algoid;
127e119b44aSjsing 	const void *algp;
128e119b44aSjsing 	int algptype;
129e119b44aSjsing 
130e119b44aSjsing 	X509_ALGOR_get0(&algoid, &algptype, &algp, alg);
131e119b44aSjsing 	if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS)
132e119b44aSjsing 		return 1;
133e119b44aSjsing 	if (algptype == V_ASN1_UNDEF)
134e119b44aSjsing 		return 1;
135e119b44aSjsing 	if (algptype != V_ASN1_SEQUENCE) {
136e119b44aSjsing 		RSAerror(RSA_R_INVALID_PSS_PARAMETERS);
137e119b44aSjsing 		return 0;
138e119b44aSjsing 	}
139e119b44aSjsing 	rsa->pss = rsa_pss_decode(alg);
140e119b44aSjsing 	if (rsa->pss == NULL)
141e119b44aSjsing 		return 0;
142e119b44aSjsing 	return 1;
143e119b44aSjsing }
144f1535dc8Sdjm 
14587203b09Smiod static int
14687203b09Smiod rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
147f1535dc8Sdjm {
148a8b3ece1Stb 	ASN1_STRING *str = NULL;
149e119b44aSjsing 	int strtype;
150a8b3ece1Stb 	unsigned char *penc = NULL;
151a8b3ece1Stb 	int penclen = 0;
152a8b3ece1Stb 	ASN1_OBJECT *aobj;
15387203b09Smiod 
154e119b44aSjsing 	if (!rsa_param_encode(pkey, &str, &strtype))
155a8b3ece1Stb 		goto err;
156a8b3ece1Stb 	if ((penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc)) <= 0) {
157a8b3ece1Stb 		penclen = 0;
158a8b3ece1Stb 		goto err;
159a8b3ece1Stb 	}
160a8b3ece1Stb 	if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL)
161a8b3ece1Stb 		goto err;
162a8b3ece1Stb 	if (!X509_PUBKEY_set0_param(pk, aobj, strtype, str, penc, penclen))
163a8b3ece1Stb 		goto err;
164a8b3ece1Stb 
165f1535dc8Sdjm 	return 1;
166f1535dc8Sdjm 
167a8b3ece1Stb  err:
168a8b3ece1Stb 	ASN1_STRING_free(str);
169a8b3ece1Stb 	freezero(penc, penclen);
170e119b44aSjsing 
171f1535dc8Sdjm 	return 0;
172f1535dc8Sdjm }
173f1535dc8Sdjm 
17487203b09Smiod static int
17587203b09Smiod rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
176f1535dc8Sdjm {
177f1535dc8Sdjm 	const unsigned char *p;
178f1535dc8Sdjm 	int pklen;
179e119b44aSjsing 	X509_ALGOR *alg;
180f1535dc8Sdjm 	RSA *rsa = NULL;
18187203b09Smiod 
182e119b44aSjsing 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey))
183f1535dc8Sdjm 		return 0;
184e119b44aSjsing 	if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) {
1855067ae9fSbeck 		RSAerror(ERR_R_RSA_LIB);
186f1535dc8Sdjm 		return 0;
187f1535dc8Sdjm 	}
188e119b44aSjsing 	if (!rsa_param_decode(rsa, alg)) {
189e119b44aSjsing 		RSA_free(rsa);
190e119b44aSjsing 		return 0;
191e119b44aSjsing 	}
192e119b44aSjsing 	if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) {
193e119b44aSjsing 		RSA_free(rsa);
194e119b44aSjsing 		return 0;
195e119b44aSjsing 	}
196f1535dc8Sdjm 	return 1;
197f1535dc8Sdjm }
198f1535dc8Sdjm 
19987203b09Smiod static int
20087203b09Smiod rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
201f1535dc8Sdjm {
20287203b09Smiod 	if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 ||
20387203b09Smiod 	    BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0)
204f1535dc8Sdjm 		return 0;
205e119b44aSjsing 
206f1535dc8Sdjm 	return 1;
207f1535dc8Sdjm }
208f1535dc8Sdjm 
20987203b09Smiod static int
21087203b09Smiod old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
211f1535dc8Sdjm {
212f1535dc8Sdjm 	RSA *rsa;
213dc613282Stb 	int ret = 0;
21487203b09Smiod 
215e119b44aSjsing 	if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) {
2165067ae9fSbeck 		RSAerror(ERR_R_RSA_LIB);
217dc613282Stb 		goto err;
218f1535dc8Sdjm 	}
219dc613282Stb 	if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa))
220dc613282Stb 		goto err;
221dc613282Stb 	rsa = NULL;
222dc613282Stb 
223dc613282Stb 	ret = 1;
224dc613282Stb 
225dc613282Stb  err:
226dc613282Stb 	RSA_free(rsa);
227dc613282Stb 
228dc613282Stb 	return ret;
229f1535dc8Sdjm }
230f1535dc8Sdjm 
23187203b09Smiod static int
23287203b09Smiod old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
233f1535dc8Sdjm {
234f1535dc8Sdjm 	return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
235f1535dc8Sdjm }
236f1535dc8Sdjm 
23787203b09Smiod static int
23887203b09Smiod rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
239f1535dc8Sdjm {
240e4c1e59cStb 	ASN1_STRING *str = NULL;
241e4c1e59cStb 	ASN1_OBJECT *aobj;
242e119b44aSjsing 	int strtype;
243e4c1e59cStb 	unsigned char *rk = NULL;
244e4c1e59cStb 	int rklen = 0;
245e119b44aSjsing 
246e119b44aSjsing 	if (!rsa_param_encode(pkey, &str, &strtype))
247e4c1e59cStb 		goto err;
248e4c1e59cStb 	if ((rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk)) <= 0) {
2495067ae9fSbeck 		RSAerror(ERR_R_MALLOC_FAILURE);
250e4c1e59cStb 		rklen = 0;
251e4c1e59cStb 		goto err;
252f1535dc8Sdjm 	}
253e4c1e59cStb 	if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL)
254e4c1e59cStb 		goto err;
255e4c1e59cStb 	if (!PKCS8_pkey_set0(p8, aobj, 0, strtype, str, rk, rklen)) {
2565067ae9fSbeck 		RSAerror(ERR_R_MALLOC_FAILURE);
257e4c1e59cStb 		goto err;
258f1535dc8Sdjm 	}
259f1535dc8Sdjm 
260f1535dc8Sdjm 	return 1;
261e4c1e59cStb 
262e4c1e59cStb  err:
263e4c1e59cStb 	ASN1_STRING_free(str);
264e4c1e59cStb 	freezero(rk, rklen);
265e4c1e59cStb 
266e4c1e59cStb 	return 0;
267f1535dc8Sdjm }
268f1535dc8Sdjm 
26987203b09Smiod static int
2708d6bc8b3Stb rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
271f1535dc8Sdjm {
272f1535dc8Sdjm 	const unsigned char *p;
273c27d5f27Stb 	RSA *rsa = NULL;
274f1535dc8Sdjm 	int pklen;
275e119b44aSjsing 	const X509_ALGOR *alg;
276c27d5f27Stb 	int ret = 0;
27787203b09Smiod 
278e119b44aSjsing 	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8))
279c27d5f27Stb 		goto err;
280c27d5f27Stb 	if ((rsa = d2i_RSAPrivateKey(NULL, &p, pklen)) == NULL)
281c27d5f27Stb 		goto err;
282c27d5f27Stb 	if (!rsa_param_decode(rsa, alg))
283c27d5f27Stb 		goto err;
284c27d5f27Stb 	if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa))
285c27d5f27Stb 		goto err;
286c27d5f27Stb 	rsa = NULL;
287e119b44aSjsing 
288c27d5f27Stb 	ret = 1;
289c27d5f27Stb 
290c27d5f27Stb  err:
291c27d5f27Stb 	RSA_free(rsa);
292c27d5f27Stb 
293c27d5f27Stb 	return ret;
294f1535dc8Sdjm }
295f1535dc8Sdjm 
29687203b09Smiod static int
297c5ca9a16Stb rsa_size(const EVP_PKEY *pkey)
298f1535dc8Sdjm {
299f1535dc8Sdjm 	return RSA_size(pkey->pkey.rsa);
300f1535dc8Sdjm }
301f1535dc8Sdjm 
30287203b09Smiod static int
30387203b09Smiod rsa_bits(const EVP_PKEY *pkey)
304f1535dc8Sdjm {
305f1535dc8Sdjm 	return BN_num_bits(pkey->pkey.rsa->n);
306f1535dc8Sdjm }
307f1535dc8Sdjm 
3085cdf0398Stb static int
3095cdf0398Stb rsa_security_bits(const EVP_PKEY *pkey)
3105cdf0398Stb {
3115cdf0398Stb 	return RSA_security_bits(pkey->pkey.rsa);
3125cdf0398Stb }
3135cdf0398Stb 
31487203b09Smiod static void
315c5ca9a16Stb rsa_free(EVP_PKEY *pkey)
316f1535dc8Sdjm {
317f1535dc8Sdjm 	RSA_free(pkey->pkey.rsa);
318f1535dc8Sdjm }
319f1535dc8Sdjm 
320e119b44aSjsing static X509_ALGOR *
321e119b44aSjsing rsa_mgf1_decode(X509_ALGOR *alg)
322f1535dc8Sdjm {
323e119b44aSjsing 	if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
324e119b44aSjsing 		return NULL;
32587203b09Smiod 
326e119b44aSjsing 	return ASN1_TYPE_unpack_sequence(&X509_ALGOR_it, alg->parameter);
327f1535dc8Sdjm }
328f1535dc8Sdjm 
32987203b09Smiod static RSA_PSS_PARAMS *
330e119b44aSjsing rsa_pss_decode(const X509_ALGOR *alg)
331ec07fdf1Sdjm {
332ec07fdf1Sdjm 	RSA_PSS_PARAMS *pss;
333ec07fdf1Sdjm 
334e119b44aSjsing 	pss = ASN1_TYPE_unpack_sequence(&RSA_PSS_PARAMS_it, alg->parameter);
335e119b44aSjsing 	if (pss == NULL)
336ec07fdf1Sdjm 		return NULL;
33714a995a9Sjsing 
338e119b44aSjsing 	if (pss->maskGenAlgorithm != NULL) {
339e119b44aSjsing 		pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
340e119b44aSjsing 		if (pss->maskHash == NULL) {
341e119b44aSjsing 			RSA_PSS_PARAMS_free(pss);
342ec07fdf1Sdjm 			return NULL;
343ec07fdf1Sdjm 		}
344ec07fdf1Sdjm 	}
345ec07fdf1Sdjm 
346ec07fdf1Sdjm 	return pss;
347ec07fdf1Sdjm }
348ec07fdf1Sdjm 
34987203b09Smiod static int
350e119b44aSjsing rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, int indent)
351ec07fdf1Sdjm {
352ec07fdf1Sdjm 	int rv = 0;
353e119b44aSjsing 	X509_ALGOR *maskHash = NULL;
35487203b09Smiod 
355e119b44aSjsing 	if (!BIO_indent(bp, indent, 128))
356e119b44aSjsing 		goto err;
357e119b44aSjsing 	if (pss_key) {
358e119b44aSjsing 		if (pss == NULL) {
359e119b44aSjsing 			if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0)
360e119b44aSjsing 				return 0;
361e119b44aSjsing 			return 1;
362e119b44aSjsing 		} else {
363e119b44aSjsing 			if (BIO_puts(bp, "PSS parameter restrictions:") <= 0)
364e119b44aSjsing 				return 0;
365e119b44aSjsing 		}
366e119b44aSjsing 	} else if (pss == NULL) {
367ec07fdf1Sdjm 		if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0)
368ec07fdf1Sdjm 			return 0;
369ec07fdf1Sdjm 		return 1;
370ec07fdf1Sdjm 	}
371ec07fdf1Sdjm 	if (BIO_puts(bp, "\n") <= 0)
372ec07fdf1Sdjm 		goto err;
373e119b44aSjsing 	if (pss_key)
374e119b44aSjsing 		indent += 2;
375ec07fdf1Sdjm 	if (!BIO_indent(bp, indent, 128))
376ec07fdf1Sdjm 		goto err;
377ec07fdf1Sdjm 	if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
378ec07fdf1Sdjm 		goto err;
379ec07fdf1Sdjm 
38087203b09Smiod 	if (pss->hashAlgorithm) {
381ec07fdf1Sdjm 		if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
382ec07fdf1Sdjm 			goto err;
383e119b44aSjsing 	} else if (BIO_puts(bp, "sha1 (default)") <= 0) {
384ec07fdf1Sdjm 		goto err;
385e119b44aSjsing 	}
386ec07fdf1Sdjm 
387ec07fdf1Sdjm 	if (BIO_puts(bp, "\n") <= 0)
388ec07fdf1Sdjm 		goto err;
389ec07fdf1Sdjm 
390ec07fdf1Sdjm 	if (!BIO_indent(bp, indent, 128))
391ec07fdf1Sdjm 		goto err;
392ec07fdf1Sdjm 
393ec07fdf1Sdjm 	if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
394ec07fdf1Sdjm 		goto err;
39587203b09Smiod 	if (pss->maskGenAlgorithm) {
396ec07fdf1Sdjm 		if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
397ec07fdf1Sdjm 			goto err;
398ec07fdf1Sdjm 		if (BIO_puts(bp, " with ") <= 0)
399ec07fdf1Sdjm 			goto err;
400e119b44aSjsing 		maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
401e119b44aSjsing 		if (maskHash != NULL) {
402ec07fdf1Sdjm 			if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
403ec07fdf1Sdjm 				goto err;
404e119b44aSjsing 		} else if (BIO_puts(bp, "INVALID") <= 0) {
405ec07fdf1Sdjm 			goto err;
406e119b44aSjsing 		}
407e119b44aSjsing 	} else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
408ec07fdf1Sdjm 		goto err;
409e119b44aSjsing 	}
410ec07fdf1Sdjm 	BIO_puts(bp, "\n");
411ec07fdf1Sdjm 
412ec07fdf1Sdjm 	if (!BIO_indent(bp, indent, 128))
413ec07fdf1Sdjm 		goto err;
414e119b44aSjsing 	if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0)
415ec07fdf1Sdjm 		goto err;
41687203b09Smiod 	if (pss->saltLength) {
417ec07fdf1Sdjm 		if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
418ec07fdf1Sdjm 			goto err;
419e119b44aSjsing 	} else if (BIO_puts(bp, "14 (default)") <= 0) {
420ec07fdf1Sdjm 		goto err;
421e119b44aSjsing 	}
422ec07fdf1Sdjm 	BIO_puts(bp, "\n");
423ec07fdf1Sdjm 
424ec07fdf1Sdjm 	if (!BIO_indent(bp, indent, 128))
425ec07fdf1Sdjm 		goto err;
4269eac5592Smiod 	if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
427ec07fdf1Sdjm 		goto err;
42887203b09Smiod 	if (pss->trailerField) {
429ec07fdf1Sdjm 		if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
430ec07fdf1Sdjm 			goto err;
431e119b44aSjsing 	} else if (BIO_puts(bp, "BC (default)") <= 0) {
432ec07fdf1Sdjm 		goto err;
433e119b44aSjsing 	}
434ec07fdf1Sdjm 	BIO_puts(bp, "\n");
435ec07fdf1Sdjm 
436ec07fdf1Sdjm 	rv = 1;
437ec07fdf1Sdjm 
438ec07fdf1Sdjm  err:
439e119b44aSjsing 	X509_ALGOR_free(maskHash);
440ec07fdf1Sdjm 	return rv;
441e119b44aSjsing 
442e119b44aSjsing }
443e119b44aSjsing 
444e119b44aSjsing static int
445e119b44aSjsing pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv)
446e119b44aSjsing {
447e119b44aSjsing 	const RSA *x = pkey->pkey.rsa;
448e119b44aSjsing 	char *str;
449e119b44aSjsing 	const char *s;
450e119b44aSjsing 	int ret = 0, mod_len = 0;
451e119b44aSjsing 
452e119b44aSjsing 	if (x->n != NULL)
453e119b44aSjsing 		mod_len = BN_num_bits(x->n);
454e119b44aSjsing 
455e119b44aSjsing 	if (!BIO_indent(bp, off, 128))
456e119b44aSjsing 		goto err;
457e119b44aSjsing 
45868f05024Stb 	if (BIO_printf(bp, "%s ",
45968f05024Stb 	    pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS ? "RSA-PSS" : "RSA") <= 0)
460e119b44aSjsing 		goto err;
461e119b44aSjsing 
4620cee8b35Sinoguchi 	if (priv && x->d != NULL) {
4630cee8b35Sinoguchi 		if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0)
4640cee8b35Sinoguchi 			goto err;
4650cee8b35Sinoguchi 		str = "modulus:";
4660cee8b35Sinoguchi 		s = "publicExponent:";
4670cee8b35Sinoguchi 	} else {
468e119b44aSjsing 		if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
469e119b44aSjsing 			goto err;
470e119b44aSjsing 		str = "Modulus:";
471e119b44aSjsing 		s = "Exponent:";
4720cee8b35Sinoguchi 	}
473549c133bStb 	if (!bn_printf(bp, x->n, off, "%s", str))
474e119b44aSjsing 		goto err;
475549c133bStb 	if (!bn_printf(bp, x->e, off, "%s", s))
476e119b44aSjsing 		goto err;
477e119b44aSjsing 	if (priv) {
478549c133bStb 		if (!bn_printf(bp, x->d, off, "privateExponent:"))
479e119b44aSjsing 			goto err;
480549c133bStb 		if (!bn_printf(bp, x->p, off, "prime1:"))
481e119b44aSjsing 			goto err;
482549c133bStb 		if (!bn_printf(bp, x->q, off, "prime2:"))
483e119b44aSjsing 			goto err;
484549c133bStb 		if (!bn_printf(bp, x->dmp1, off, "exponent1:"))
485e119b44aSjsing 			goto err;
486549c133bStb 		if (!bn_printf(bp, x->dmq1, off, "exponent2:"))
487e119b44aSjsing 			goto err;
488549c133bStb 		if (!bn_printf(bp, x->iqmp, off, "coefficient:"))
489e119b44aSjsing 			goto err;
490e119b44aSjsing 	}
49168f05024Stb 	if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS &&
49268f05024Stb 	    !rsa_pss_param_print(bp, 1, x->pss, off))
493e119b44aSjsing 		goto err;
494e119b44aSjsing 	ret = 1;
495e119b44aSjsing  err:
496e119b44aSjsing 	return ret;
497e119b44aSjsing }
498e119b44aSjsing 
499e119b44aSjsing static int
500e119b44aSjsing rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
501e119b44aSjsing {
502e119b44aSjsing 	return pkey_rsa_print(bp, pkey, indent, 0);
503e119b44aSjsing }
504e119b44aSjsing 
505e119b44aSjsing static int
506e119b44aSjsing rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
507e119b44aSjsing {
508e119b44aSjsing 	return pkey_rsa_print(bp, pkey, indent, 1);
509ec07fdf1Sdjm }
510ec07fdf1Sdjm 
51187203b09Smiod static int
51287203b09Smiod rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
513ec07fdf1Sdjm     int indent, ASN1_PCTX *pctx)
514ec07fdf1Sdjm {
515e119b44aSjsing 	if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) {
516ec07fdf1Sdjm 		int rv;
517e119b44aSjsing 		RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg);
518e119b44aSjsing 
519e119b44aSjsing 		rv = rsa_pss_param_print(bp, 0, pss, indent);
520ec07fdf1Sdjm 		RSA_PSS_PARAMS_free(pss);
521ec07fdf1Sdjm 		if (!rv)
522ec07fdf1Sdjm 			return 0;
523e119b44aSjsing 	} else if (!sig && BIO_puts(bp, "\n") <= 0) {
524ec07fdf1Sdjm 		return 0;
525e119b44aSjsing 	}
526ec07fdf1Sdjm 	if (sig)
527ec07fdf1Sdjm 		return X509_signature_dump(bp, sig, indent);
528ec07fdf1Sdjm 	return 1;
529ec07fdf1Sdjm }
530f1535dc8Sdjm 
53187203b09Smiod static int
53287203b09Smiod rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
533f1535dc8Sdjm {
534f1535dc8Sdjm 	X509_ALGOR *alg = NULL;
535e119b44aSjsing 	const EVP_MD *md;
536e119b44aSjsing 	const EVP_MD *mgf1md;
537e119b44aSjsing 	int min_saltlen;
53814a995a9Sjsing 
53987203b09Smiod 	switch (op) {
540f1535dc8Sdjm 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
541f1535dc8Sdjm 		if (arg1 == 0)
542f1535dc8Sdjm 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
543f1535dc8Sdjm 		break;
544f1535dc8Sdjm 
545f1535dc8Sdjm 	case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
54668f05024Stb 		if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS)
547e119b44aSjsing 			return -2;
548f1535dc8Sdjm 		if (arg1 == 0)
549f1535dc8Sdjm 			PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
550f1535dc8Sdjm 		break;
551c4380ae9Sjsing #ifndef OPENSSL_NO_CMS
552c4380ae9Sjsing 	case ASN1_PKEY_CTRL_CMS_SIGN:
553c4380ae9Sjsing 		if (arg1 == 0)
554c4380ae9Sjsing 			return rsa_cms_sign(arg2);
555c4380ae9Sjsing 		else if (arg1 == 1)
556c4380ae9Sjsing 			return rsa_cms_verify(arg2);
557c4380ae9Sjsing 		break;
558c4380ae9Sjsing 
559c4380ae9Sjsing 	case ASN1_PKEY_CTRL_CMS_ENVELOPE:
56068f05024Stb 		if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS)
561c4380ae9Sjsing 			return -2;
562c4380ae9Sjsing 		if (arg1 == 0)
563c4380ae9Sjsing 			return rsa_cms_encrypt(arg2);
564c4380ae9Sjsing 		else if (arg1 == 1)
565c4380ae9Sjsing 			return rsa_cms_decrypt(arg2);
566c4380ae9Sjsing 		break;
567c4380ae9Sjsing 
568c4380ae9Sjsing 	case ASN1_PKEY_CTRL_CMS_RI_TYPE:
56968f05024Stb 		if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS)
570c4380ae9Sjsing 			return -2;
571c4380ae9Sjsing 		*(int *)arg2 = CMS_RECIPINFO_TRANS;
572c4380ae9Sjsing 		return 1;
573c4380ae9Sjsing #endif
574f1535dc8Sdjm 
575f1535dc8Sdjm 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
576e119b44aSjsing 		if (pkey->pkey.rsa->pss != NULL) {
577e119b44aSjsing 			if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md,
578e119b44aSjsing 			    &min_saltlen)) {
579e119b44aSjsing 				RSAerror(ERR_R_INTERNAL_ERROR);
580e119b44aSjsing 				return 0;
581e119b44aSjsing 			}
582e119b44aSjsing 			*(int *)arg2 = EVP_MD_type(md);
583e119b44aSjsing 			/* Return of 2 indicates this MD is mandatory */
584e119b44aSjsing 			return 2;
585e119b44aSjsing 		}
586e119b44aSjsing 		*(int *)arg2 = NID_sha256;
587f1535dc8Sdjm 		return 1;
588f1535dc8Sdjm 
589f1535dc8Sdjm 	default:
590f1535dc8Sdjm 		return -2;
591f1535dc8Sdjm 	}
592f1535dc8Sdjm 
593ffbbbf5cStb 	if (alg != NULL)
594ffbbbf5cStb 		return rsa_alg_set_pkcs1_padding(alg);
595f1535dc8Sdjm 
596f1535dc8Sdjm 	return 1;
597f1535dc8Sdjm }
598f1535dc8Sdjm 
599ba05ae2dSjsing static int
60082b80301Stb rsa_md_to_algor(const EVP_MD *md, X509_ALGOR **out_alg)
601ba05ae2dSjsing {
60282b80301Stb 	X509_ALGOR *alg = NULL;
60382b80301Stb 	int ret = 0;
60482b80301Stb 
60582b80301Stb 	X509_ALGOR_free(*out_alg);
60682b80301Stb 	*out_alg = NULL;
60782b80301Stb 
60882b80301Stb 	/* RFC 8017 - default hash is SHA-1 and hence omitted. */
609ba05ae2dSjsing 	if (md == NULL || EVP_MD_type(md) == NID_sha1)
61082b80301Stb 		goto done;
61182b80301Stb 
61282b80301Stb 	if ((alg = X509_ALGOR_new()) == NULL)
61382b80301Stb 		goto err;
6141eb3d403Stb 	/*
6151eb3d403Stb 	 * XXX - This omits the parameters, whereas RFC 4055, section 2.1
6161eb3d403Stb 	 * explicitly states that an explicit ASN.1 NULL is required.
6171eb3d403Stb 	 */
61882b80301Stb 	if (!X509_ALGOR_set_evp_md(alg, md))
61982b80301Stb 		goto err;
62082b80301Stb 
62182b80301Stb  done:
62282b80301Stb 	*out_alg = alg;
62382b80301Stb 	alg = NULL;
62482b80301Stb 
62582b80301Stb 	ret = 1;
62682b80301Stb 
62782b80301Stb  err:
62882b80301Stb 	X509_ALGOR_free(alg);
62982b80301Stb 
63082b80301Stb 	return ret;
631ba05ae2dSjsing }
632ba05ae2dSjsing 
63382b80301Stb /*
63482b80301Stb  * RFC 8017, A.2.1 and A.2.3 - encode maskGenAlgorithm for RSAES-OAEP
63582b80301Stb  * and RSASSA-PSS. The default is mgfSHA1 and hence omitted.
63682b80301Stb  */
637ba05ae2dSjsing static int
63882b80301Stb rsa_mgf1md_to_maskGenAlgorithm(const EVP_MD *mgf1md, X509_ALGOR **out_alg)
639ba05ae2dSjsing {
64082b80301Stb 	X509_ALGOR *alg = NULL;
64182b80301Stb 	X509_ALGOR *inner_alg = NULL;
64282b80301Stb 	ASN1_STRING *astr = NULL;
64382b80301Stb 	int ret = 0;
644ba05ae2dSjsing 
64582b80301Stb 	X509_ALGOR_free(*out_alg);
64682b80301Stb 	*out_alg = NULL;
64782b80301Stb 
648ba05ae2dSjsing 	if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1)
64982b80301Stb 		goto done;
65082b80301Stb 
65182b80301Stb 	if ((inner_alg = X509_ALGOR_new()) == NULL)
652ba05ae2dSjsing 		goto err;
6531eb3d403Stb 	/*
6541eb3d403Stb 	 * XXX - This omits the parameters, whereas RFC 4055, section 2.1
6551eb3d403Stb 	 * explicitly states that an explicit ASN.1 NULL is required.
6561eb3d403Stb 	 */
65782b80301Stb 	if (!X509_ALGOR_set_evp_md(inner_alg, mgf1md))
658ba05ae2dSjsing 		goto err;
65982b80301Stb 	if ((astr = ASN1_item_pack(inner_alg, &X509_ALGOR_it, NULL)) == NULL)
660ba05ae2dSjsing 		goto err;
66182b80301Stb 
66282b80301Stb 	if ((alg = X509_ALGOR_new()) == NULL)
66382b80301Stb 		goto err;
6646b23e18aStb 	if (!X509_ALGOR_set0_by_nid(alg, NID_mgf1, V_ASN1_SEQUENCE, astr))
66582b80301Stb 		goto err;
66682b80301Stb 	astr = NULL;
66782b80301Stb 
66882b80301Stb  done:
66982b80301Stb 	*out_alg = alg;
67082b80301Stb 	alg = NULL;
67182b80301Stb 
67282b80301Stb 	ret = 1;
67382b80301Stb 
674ba05ae2dSjsing  err:
67582b80301Stb 	X509_ALGOR_free(alg);
67682b80301Stb 	X509_ALGOR_free(inner_alg);
67782b80301Stb 	ASN1_STRING_free(astr);
67882b80301Stb 
67982b80301Stb 	return ret;
680ba05ae2dSjsing }
681ba05ae2dSjsing 
682ba05ae2dSjsing /* Convert algorithm ID to EVP_MD, defaults to SHA1. */
683ba05ae2dSjsing static const EVP_MD *
684ba05ae2dSjsing rsa_algor_to_md(X509_ALGOR *alg)
685ba05ae2dSjsing {
686ba05ae2dSjsing 	const EVP_MD *md;
687ba05ae2dSjsing 
688ba05ae2dSjsing 	if (!alg)
689ba05ae2dSjsing 		return EVP_sha1();
690ba05ae2dSjsing 	md = EVP_get_digestbyobj(alg->algorithm);
691ba05ae2dSjsing 	if (md == NULL)
692ba05ae2dSjsing 		RSAerror(RSA_R_UNKNOWN_DIGEST);
693ba05ae2dSjsing 	return md;
694ba05ae2dSjsing }
695ba05ae2dSjsing 
696e119b44aSjsing /*
697e119b44aSjsing  * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter,
698e119b44aSjsing  * suitable for setting an AlgorithmIdentifier.
699e119b44aSjsing  */
700e119b44aSjsing static RSA_PSS_PARAMS *
70118d2dab4Stb rsa_ctx_to_pss(EVP_PKEY_CTX *pkey_ctx)
702e119b44aSjsing {
703e119b44aSjsing 	const EVP_MD *sigmd, *mgf1md;
70418d2dab4Stb 	EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkey_ctx);
705e119b44aSjsing 	int saltlen;
706e119b44aSjsing 
70718d2dab4Stb 	if (EVP_PKEY_CTX_get_signature_md(pkey_ctx, &sigmd) <= 0)
708e119b44aSjsing 		return NULL;
70918d2dab4Stb 	if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkey_ctx, &mgf1md) <= 0)
710e119b44aSjsing 		return NULL;
71118d2dab4Stb 	if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkey_ctx, &saltlen))
712e119b44aSjsing 		return NULL;
713e119b44aSjsing 	if (saltlen == -1) {
714e119b44aSjsing 		saltlen = EVP_MD_size(sigmd);
715e119b44aSjsing 	} else if (saltlen == -2 || saltlen == -3) {
716e119b44aSjsing 		saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
717e119b44aSjsing 		if ((EVP_PKEY_bits(pk) & 0x7) == 1)
718e119b44aSjsing 			saltlen--;
719e119b44aSjsing 		if (saltlen < 0)
720e119b44aSjsing 			return NULL;
721e119b44aSjsing 	}
722e119b44aSjsing 
723e119b44aSjsing 	return rsa_pss_params_create(sigmd, mgf1md, saltlen);
724e119b44aSjsing }
725e119b44aSjsing 
726ba05ae2dSjsing RSA_PSS_PARAMS *
727ba05ae2dSjsing rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, int saltlen)
728ba05ae2dSjsing {
72982b80301Stb 	RSA_PSS_PARAMS *pss = NULL;
730ba05ae2dSjsing 
73182b80301Stb 	if (mgf1md == NULL)
73282b80301Stb 		mgf1md = sigmd;
73382b80301Stb 
73482b80301Stb 	if ((pss = RSA_PSS_PARAMS_new()) == NULL)
735ba05ae2dSjsing 		goto err;
73682b80301Stb 
73782b80301Stb 	if (!rsa_md_to_algor(sigmd, &pss->hashAlgorithm))
73882b80301Stb 		goto err;
73982b80301Stb 	if (!rsa_mgf1md_to_maskGenAlgorithm(mgf1md, &pss->maskGenAlgorithm))
74082b80301Stb 		goto err;
74182b80301Stb 
74282b80301Stb 	/* Translate mgf1md to X509_ALGOR in decoded form for internal use. */
74382b80301Stb 	if (!rsa_md_to_algor(mgf1md, &pss->maskHash))
74482b80301Stb 		goto err;
74582b80301Stb 
74682b80301Stb 	/* RFC 8017, A.2.3 - default saltLength is SHA_DIGEST_LENGTH. */
74782b80301Stb 	if (saltlen != SHA_DIGEST_LENGTH) {
74882b80301Stb 		if ((pss->saltLength = ASN1_INTEGER_new()) == NULL)
749ba05ae2dSjsing 			goto err;
750ba05ae2dSjsing 		if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
751ba05ae2dSjsing 			goto err;
752ba05ae2dSjsing 	}
75382b80301Stb 
754ba05ae2dSjsing 	return pss;
75582b80301Stb 
756ba05ae2dSjsing  err:
757ba05ae2dSjsing 	RSA_PSS_PARAMS_free(pss);
75882b80301Stb 
759ba05ae2dSjsing 	return NULL;
760ba05ae2dSjsing }
761ba05ae2dSjsing 
762e119b44aSjsing /*
763e119b44aSjsing  * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL
764e119b44aSjsing  * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are
76518d2dab4Stb  * passed to pkey_ctx instead.
766e119b44aSjsing  */
767e119b44aSjsing 
768e119b44aSjsing static int
76918d2dab4Stb rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkey_ctx,
770e119b44aSjsing     X509_ALGOR *sigalg, EVP_PKEY *pkey)
771e119b44aSjsing {
772e119b44aSjsing 	int rv = -1;
773e119b44aSjsing 	int saltlen;
774e119b44aSjsing 	const EVP_MD *mgf1md = NULL, *md = NULL;
775e119b44aSjsing 	RSA_PSS_PARAMS *pss;
776e119b44aSjsing 
777e119b44aSjsing 	/* Sanity check: make sure it is PSS */
778e119b44aSjsing 	if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) {
779e119b44aSjsing 		RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
780e119b44aSjsing 		return -1;
781e119b44aSjsing 	}
782e119b44aSjsing 	/* Decode PSS parameters */
783e119b44aSjsing 	pss = rsa_pss_decode(sigalg);
784e119b44aSjsing 
785e119b44aSjsing 	if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) {
786e119b44aSjsing 		RSAerror(RSA_R_INVALID_PSS_PARAMETERS);
787e119b44aSjsing 		goto err;
788e119b44aSjsing 	}
789e119b44aSjsing 
790e119b44aSjsing 	/* We have all parameters now set up context */
791e119b44aSjsing 	if (pkey) {
79218d2dab4Stb 		if (!EVP_DigestVerifyInit(ctx, &pkey_ctx, md, NULL, pkey))
793e119b44aSjsing 			goto err;
794e119b44aSjsing 	} else {
795e119b44aSjsing 		const EVP_MD *checkmd;
79618d2dab4Stb 		if (EVP_PKEY_CTX_get_signature_md(pkey_ctx, &checkmd) <= 0)
797e119b44aSjsing 			goto err;
798e119b44aSjsing 		if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
799e119b44aSjsing 			RSAerror(RSA_R_DIGEST_DOES_NOT_MATCH);
800e119b44aSjsing 			goto err;
801e119b44aSjsing 		}
802e119b44aSjsing 	}
803e119b44aSjsing 
80418d2dab4Stb 	if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0)
805e119b44aSjsing 		goto err;
806e119b44aSjsing 
80718d2dab4Stb 	if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, saltlen) <= 0)
808e119b44aSjsing 		goto err;
809e119b44aSjsing 
81018d2dab4Stb 	if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) <= 0)
811e119b44aSjsing 		goto err;
812e119b44aSjsing 	/* Carry on */
813e119b44aSjsing 	rv = 1;
814e119b44aSjsing 
815e119b44aSjsing  err:
816e119b44aSjsing 	RSA_PSS_PARAMS_free(pss);
817e119b44aSjsing 	return rv;
818e119b44aSjsing }
819e119b44aSjsing 
820ba05ae2dSjsing int
821ba05ae2dSjsing rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd,
822ba05ae2dSjsing     const EVP_MD **pmgf1md, int *psaltlen)
823ba05ae2dSjsing {
824ba05ae2dSjsing 	if (pss == NULL)
825ba05ae2dSjsing 		return 0;
826ba05ae2dSjsing 	*pmd = rsa_algor_to_md(pss->hashAlgorithm);
827ba05ae2dSjsing 	if (*pmd == NULL)
828ba05ae2dSjsing 		return 0;
829ba05ae2dSjsing 	*pmgf1md = rsa_algor_to_md(pss->maskHash);
830ba05ae2dSjsing 	if (*pmgf1md == NULL)
831ba05ae2dSjsing 		return 0;
832ba05ae2dSjsing 	if (pss->saltLength) {
833ba05ae2dSjsing 		*psaltlen = ASN1_INTEGER_get(pss->saltLength);
834ba05ae2dSjsing 		if (*psaltlen < 0) {
835ba05ae2dSjsing 			RSAerror(RSA_R_INVALID_SALT_LENGTH);
836ba05ae2dSjsing 			return 0;
837ba05ae2dSjsing 		}
838ba05ae2dSjsing 	} else {
839ba05ae2dSjsing 		*psaltlen = 20;
840ba05ae2dSjsing 	}
841ba05ae2dSjsing 
842ba05ae2dSjsing 	/*
843ba05ae2dSjsing 	 * low-level routines support only trailer field 0xbc (value 1) and
844ba05ae2dSjsing 	 * PKCS#1 says we should reject any other value anyway.
845ba05ae2dSjsing 	 */
846ba05ae2dSjsing 	if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
847ba05ae2dSjsing 		RSAerror(RSA_R_INVALID_TRAILER);
848ba05ae2dSjsing 		return 0;
849ba05ae2dSjsing 	}
850ba05ae2dSjsing 
851ba05ae2dSjsing 	return 1;
852ba05ae2dSjsing }
853ba05ae2dSjsing 
854c5d7bed5Stb static int
855c5d7bed5Stb rsa_pss_signature_info(const X509_ALGOR *alg, int *out_md_nid,
856c5d7bed5Stb     int *out_pkey_nid, int *out_security_bits, uint32_t *out_flags)
857c5d7bed5Stb {
858c5d7bed5Stb 	RSA_PSS_PARAMS *pss = NULL;
859c5d7bed5Stb 	const ASN1_OBJECT *aobj;
860c5d7bed5Stb 	const EVP_MD *md, *mgf1md;
861c5d7bed5Stb 	int md_len, salt_len;
862c5d7bed5Stb 	int md_nid = NID_undef, pkey_nid = NID_undef;
863c5d7bed5Stb 	int security_bits = -1;
864c5d7bed5Stb 	uint32_t flags = 0;
865c5d7bed5Stb 
866c5d7bed5Stb 	X509_ALGOR_get0(&aobj, NULL, NULL, alg);
867c5d7bed5Stb 	if (OBJ_obj2nid(aobj) != EVP_PKEY_RSA_PSS)
868c5d7bed5Stb 		goto err;
869c5d7bed5Stb 
870c5d7bed5Stb 	if ((pss = rsa_pss_decode(alg)) == NULL)
871c5d7bed5Stb 		goto err;
872c5d7bed5Stb 	if (!rsa_pss_get_param(pss, &md, &mgf1md, &salt_len))
873c5d7bed5Stb 		goto err;
874c5d7bed5Stb 
875c5d7bed5Stb 	if ((md_nid = EVP_MD_type(md)) == NID_undef)
876c5d7bed5Stb 		goto err;
877c5d7bed5Stb 	if ((md_len = EVP_MD_size(md)) <= 0)
878c5d7bed5Stb 		goto err;
879c5d7bed5Stb 
880c5d7bed5Stb 	/*
881c5d7bed5Stb 	 * RFC 8446, section 4.2.3 - restricts the digest algorithm:
882c5d7bed5Stb 	 * - it must be one of SHA256, SHA384, and SHA512;
883c5d7bed5Stb 	 * - the same digest must be used in the mask generation function;
884c5d7bed5Stb 	 * - the salt length must match the output length of the digest.
885c5d7bed5Stb 	 * XXX - consider separate flags for these checks.
886c5d7bed5Stb 	 */
887c5d7bed5Stb 	if (md_nid == NID_sha256 || md_nid == NID_sha384 || md_nid == NID_sha512) {
888c5d7bed5Stb 		if (md_nid == EVP_MD_type(mgf1md) && salt_len == md_len)
889c5d7bed5Stb 			flags |= X509_SIG_INFO_TLS;
890c5d7bed5Stb 	}
891c5d7bed5Stb 
892c5d7bed5Stb 	security_bits = md_len * 4;
893c5d7bed5Stb 	flags |= X509_SIG_INFO_VALID;
894c5d7bed5Stb 
895c5d7bed5Stb 	*out_md_nid = md_nid;
896c5d7bed5Stb 	*out_pkey_nid = pkey_nid;
897c5d7bed5Stb 	*out_security_bits = security_bits;
898c5d7bed5Stb 	*out_flags = flags;
899c5d7bed5Stb 
900c5d7bed5Stb  err:
901c5d7bed5Stb 	RSA_PSS_PARAMS_free(pss);
902c5d7bed5Stb 
903c5d7bed5Stb 	return (flags & X509_SIG_INFO_VALID) != 0;
904c5d7bed5Stb }
905c5d7bed5Stb 
906c4380ae9Sjsing #ifndef OPENSSL_NO_CMS
907c4380ae9Sjsing static int
908c4380ae9Sjsing rsa_cms_verify(CMS_SignerInfo *si)
909c4380ae9Sjsing {
910c4380ae9Sjsing 	int nid, nid2;
911c4380ae9Sjsing 	X509_ALGOR *alg;
91218d2dab4Stb 	EVP_PKEY_CTX *pkey_ctx = CMS_SignerInfo_get0_pkey_ctx(si);
913c4380ae9Sjsing 
914c4380ae9Sjsing 	CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
915c4380ae9Sjsing 	nid = OBJ_obj2nid(alg->algorithm);
916c4380ae9Sjsing 	if (nid == EVP_PKEY_RSA_PSS)
91718d2dab4Stb 		return rsa_pss_to_ctx(NULL, pkey_ctx, alg, NULL);
918c4380ae9Sjsing 	/* Only PSS allowed for PSS keys */
91968f05024Stb 	if (pkey_ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) {
920c4380ae9Sjsing 		RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
921c4380ae9Sjsing 		return 0;
922c4380ae9Sjsing 	}
923c4380ae9Sjsing 	if (nid == NID_rsaEncryption)
924c4380ae9Sjsing 		return 1;
925c4380ae9Sjsing 	/* Workaround for some implementation that use a signature OID */
926c4380ae9Sjsing 	if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
927c4380ae9Sjsing 		if (nid2 == NID_rsaEncryption)
928c4380ae9Sjsing 			return 1;
929c4380ae9Sjsing 	}
930c4380ae9Sjsing 	return 0;
931c4380ae9Sjsing }
932c4380ae9Sjsing #endif
933c4380ae9Sjsing 
934e119b44aSjsing /*
935e119b44aSjsing  * Customised RSA item verification routine. This is called when a signature
936e119b44aSjsing  * is encountered requiring special handling. We currently only handle PSS.
937ec07fdf1Sdjm  */
93887203b09Smiod static int
93987203b09Smiod rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
94087203b09Smiod     X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey)
941ec07fdf1Sdjm {
942ec07fdf1Sdjm 	/* Sanity check: make sure it is PSS */
943e119b44aSjsing 	if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) {
9445067ae9fSbeck 		RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
945ec07fdf1Sdjm 		return -1;
946ec07fdf1Sdjm 	}
947e119b44aSjsing 	if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
948ec07fdf1Sdjm 		/* Carry on */
949e119b44aSjsing 		return 2;
950e119b44aSjsing 	}
951e119b44aSjsing 	return -1;
952ec07fdf1Sdjm }
953ec07fdf1Sdjm 
954ffbbbf5cStb static int
955ffbbbf5cStb rsa_alg_set_pkcs1_padding(X509_ALGOR *alg)
956ffbbbf5cStb {
957ffbbbf5cStb 	return X509_ALGOR_set0_by_nid(alg, NID_rsaEncryption, V_ASN1_NULL, NULL);
958ffbbbf5cStb }
959ffbbbf5cStb 
9608d53fb6cStb static int
9618d53fb6cStb rsa_alg_set_pss_padding(X509_ALGOR *alg, EVP_PKEY_CTX *pkey_ctx)
9628d53fb6cStb {
9638c8a22a1Stb 	RSA_PSS_PARAMS *pss = NULL;
9648d53fb6cStb 	ASN1_STRING *astr = NULL;
9658d53fb6cStb 	int ret = 0;
9668d53fb6cStb 
9678d53fb6cStb 	if (pkey_ctx == NULL)
9688d53fb6cStb 		goto err;
9698d53fb6cStb 
9708c8a22a1Stb 	if ((pss = rsa_ctx_to_pss(pkey_ctx)) == NULL)
9718c8a22a1Stb 		goto err;
9728c8a22a1Stb 	if ((astr = ASN1_item_pack(pss, &RSA_PSS_PARAMS_it, NULL)) == NULL)
9738d53fb6cStb 		goto err;
9748d53fb6cStb 	if (!X509_ALGOR_set0_by_nid(alg, EVP_PKEY_RSA_PSS, V_ASN1_SEQUENCE, astr))
9758d53fb6cStb 		goto err;
9768d53fb6cStb 	astr = NULL;
9778d53fb6cStb 
9788d53fb6cStb 	ret = 1;
9798d53fb6cStb 
9808d53fb6cStb  err:
9818d53fb6cStb 	ASN1_STRING_free(astr);
9828c8a22a1Stb 	RSA_PSS_PARAMS_free(pss);
9838d53fb6cStb 
9848d53fb6cStb 	return ret;
9858d53fb6cStb }
9868d53fb6cStb 
987c4380ae9Sjsing #ifndef OPENSSL_NO_CMS
988c4380ae9Sjsing static int
989478a1d06Stb rsa_alg_set_oaep_padding(X509_ALGOR *alg, EVP_PKEY_CTX *pkey_ctx)
990b7ca3793Stb {
991b7ca3793Stb 	const EVP_MD *md, *mgf1md;
992b7ca3793Stb 	RSA_OAEP_PARAMS *oaep = NULL;
993ff99fddfStb 	ASN1_STRING *astr = NULL;
9944a452264Stb 	ASN1_OCTET_STRING *ostr = NULL;
995b7ca3793Stb 	unsigned char *label;
99689be7242Stb 	int labellen;
99789be7242Stb 	int ret = 0;
998b7ca3793Stb 
999478a1d06Stb 	if (EVP_PKEY_CTX_get_rsa_oaep_md(pkey_ctx, &md) <= 0)
1000b7ca3793Stb 		goto err;
1001478a1d06Stb 	if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkey_ctx, &mgf1md) <= 0)
1002b7ca3793Stb 		goto err;
1003478a1d06Stb 	labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkey_ctx, &label);
1004b7ca3793Stb 	if (labellen < 0)
1005b7ca3793Stb 		goto err;
1006b7ca3793Stb 
1007b7ca3793Stb 	if ((oaep = RSA_OAEP_PARAMS_new()) == NULL)
1008b7ca3793Stb 		goto err;
1009b7ca3793Stb 
1010b7ca3793Stb 	if (!rsa_md_to_algor(md, &oaep->hashFunc))
1011b7ca3793Stb 		goto err;
1012b7ca3793Stb 	if (!rsa_mgf1md_to_maskGenAlgorithm(mgf1md, &oaep->maskGenFunc))
1013b7ca3793Stb 		goto err;
1014b7ca3793Stb 
1015b7ca3793Stb 	/* XXX - why do we not set oaep->maskHash here? */
1016b7ca3793Stb 
1017b7ca3793Stb 	if (labellen > 0) {
1018807ef32cStb 		if ((oaep->pSourceFunc = X509_ALGOR_new()) == NULL)
1019b7ca3793Stb 			goto err;
10204a452264Stb 		if ((ostr = ASN1_OCTET_STRING_new()) == NULL)
1021b7ca3793Stb 			goto err;
10224a452264Stb 		if (!ASN1_OCTET_STRING_set(ostr, label, labellen))
1023b7ca3793Stb 			goto err;
1024adf90ca0Stb 		if (!X509_ALGOR_set0_by_nid(oaep->pSourceFunc, NID_pSpecified,
1025adf90ca0Stb 		    V_ASN1_OCTET_STRING, ostr))
1026adf90ca0Stb 			goto err;
10274a452264Stb 		ostr = NULL;
1028b7ca3793Stb 	}
1029807ef32cStb 
1030ff99fddfStb 	if ((astr = ASN1_item_pack(oaep, &RSA_OAEP_PARAMS_it, NULL)) == NULL)
1031b7ca3793Stb 		goto err;
1032adf90ca0Stb 	if (!X509_ALGOR_set0_by_nid(alg, NID_rsaesOaep, V_ASN1_SEQUENCE, astr))
1033adf90ca0Stb 		goto err;
1034ff99fddfStb 	astr = NULL;
103589be7242Stb 
103689be7242Stb 	ret = 1;
103789be7242Stb 
1038b7ca3793Stb  err:
1039b7ca3793Stb 	RSA_OAEP_PARAMS_free(oaep);
1040ff99fddfStb 	ASN1_STRING_free(astr);
10414a452264Stb 	ASN1_OCTET_STRING_free(ostr);
104289be7242Stb 
104389be7242Stb 	return ret;
1044b7ca3793Stb }
1045b7ca3793Stb 
1046b7ca3793Stb static int
1047c4380ae9Sjsing rsa_cms_sign(CMS_SignerInfo *si)
1048c4380ae9Sjsing {
104918d2dab4Stb 	EVP_PKEY_CTX *pkey_ctx;
1050c4380ae9Sjsing 	X509_ALGOR *alg;
105117d3caffStb 	int pad_mode = RSA_PKCS1_PADDING;
1052c4380ae9Sjsing 
105318d2dab4Stb 	if ((pkey_ctx = CMS_SignerInfo_get0_pkey_ctx(si)) != NULL) {
105418d2dab4Stb 		if (EVP_PKEY_CTX_get_rsa_padding(pkey_ctx, &pad_mode) <= 0)
1055c4380ae9Sjsing 			return 0;
1056c4380ae9Sjsing 	}
10578d53fb6cStb 
105817d3caffStb 	CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
1059ffbbbf5cStb 	if (pad_mode == RSA_PKCS1_PADDING)
1060ffbbbf5cStb 		return rsa_alg_set_pkcs1_padding(alg);
10618d53fb6cStb 	if (pad_mode == RSA_PKCS1_PSS_PADDING)
106218d2dab4Stb 		return rsa_alg_set_pss_padding(alg, pkey_ctx);
10638d53fb6cStb 
1064c4380ae9Sjsing 	return 0;
1065c4380ae9Sjsing }
1066c4380ae9Sjsing #endif
1067c4380ae9Sjsing 
106887203b09Smiod static int
106987203b09Smiod rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
107087203b09Smiod     X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig)
1071ec07fdf1Sdjm {
107218d2dab4Stb 	EVP_PKEY_CTX *pkey_ctx = ctx->pctx;
1073e119b44aSjsing 	int pad_mode;
107487203b09Smiod 
107518d2dab4Stb 	if (EVP_PKEY_CTX_get_rsa_padding(pkey_ctx, &pad_mode) <= 0)
1076ec07fdf1Sdjm 		return 0;
1077ec07fdf1Sdjm 	if (pad_mode == RSA_PKCS1_PADDING)
1078ec07fdf1Sdjm 		return 2;
107987203b09Smiod 	if (pad_mode == RSA_PKCS1_PSS_PADDING) {
108018d2dab4Stb 		if (!rsa_alg_set_pss_padding(alg1, pkey_ctx))
1081e119b44aSjsing 			return 0;
1082c5211295Stb 		if (alg2 != NULL) {
108318d2dab4Stb 			if (!rsa_alg_set_pss_padding(alg2, pkey_ctx))
1084e119b44aSjsing 				return 0;
1085e119b44aSjsing 		}
1086e119b44aSjsing 		return 3;
1087ec07fdf1Sdjm 	}
1088ec07fdf1Sdjm 	return 2;
1089ec07fdf1Sdjm }
1090f1535dc8Sdjm 
1091c4380ae9Sjsing #ifndef OPENSSL_NO_CMS
1092c4380ae9Sjsing static RSA_OAEP_PARAMS *
1093c4380ae9Sjsing rsa_oaep_decode(const X509_ALGOR *alg)
1094c4380ae9Sjsing {
1095c4380ae9Sjsing 	RSA_OAEP_PARAMS *oaep;
1096c4380ae9Sjsing 
1097c4380ae9Sjsing 	oaep = ASN1_TYPE_unpack_sequence(&RSA_OAEP_PARAMS_it, alg->parameter);
1098c4380ae9Sjsing 	if (oaep == NULL)
1099c4380ae9Sjsing 		return NULL;
1100c4380ae9Sjsing 
1101c4380ae9Sjsing 	if (oaep->maskGenFunc != NULL) {
1102c4380ae9Sjsing 		oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc);
1103c4380ae9Sjsing 		if (oaep->maskHash == NULL) {
1104c4380ae9Sjsing 			RSA_OAEP_PARAMS_free(oaep);
1105c4380ae9Sjsing 			return NULL;
1106c4380ae9Sjsing 		}
1107c4380ae9Sjsing 	}
1108c4380ae9Sjsing 	return oaep;
1109c4380ae9Sjsing }
1110c4380ae9Sjsing 
1111c4380ae9Sjsing static int
1112c4380ae9Sjsing rsa_cms_decrypt(CMS_RecipientInfo *ri)
1113c4380ae9Sjsing {
1114c4380ae9Sjsing 	EVP_PKEY_CTX *pkctx;
1115c4380ae9Sjsing 	X509_ALGOR *cmsalg;
1116c4380ae9Sjsing 	int nid;
1117c4380ae9Sjsing 	int rv = -1;
1118c4380ae9Sjsing 	unsigned char *label = NULL;
1119c4380ae9Sjsing 	int labellen = 0;
1120c4380ae9Sjsing 	const EVP_MD *mgf1md = NULL, *md = NULL;
1121c4380ae9Sjsing 	RSA_OAEP_PARAMS *oaep;
1122c4380ae9Sjsing 
1123c4380ae9Sjsing 	pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
1124c4380ae9Sjsing 	if (pkctx == NULL)
1125c4380ae9Sjsing 		return 0;
1126c4380ae9Sjsing 	if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
1127c4380ae9Sjsing 		return -1;
1128c4380ae9Sjsing 	nid = OBJ_obj2nid(cmsalg->algorithm);
1129c4380ae9Sjsing 	if (nid == NID_rsaEncryption)
1130c4380ae9Sjsing 		return 1;
1131c4380ae9Sjsing 	if (nid != NID_rsaesOaep) {
1132c4380ae9Sjsing 		RSAerror(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE);
1133c4380ae9Sjsing 		return -1;
1134c4380ae9Sjsing 	}
1135c4380ae9Sjsing 	/* Decode OAEP parameters */
1136c4380ae9Sjsing 	oaep = rsa_oaep_decode(cmsalg);
1137c4380ae9Sjsing 
1138c4380ae9Sjsing 	if (oaep == NULL) {
1139c4380ae9Sjsing 		RSAerror(RSA_R_INVALID_OAEP_PARAMETERS);
1140c4380ae9Sjsing 		goto err;
1141c4380ae9Sjsing 	}
1142c4380ae9Sjsing 
1143c4380ae9Sjsing 	mgf1md = rsa_algor_to_md(oaep->maskHash);
1144c4380ae9Sjsing 	if (mgf1md == NULL)
1145c4380ae9Sjsing 		goto err;
1146c4380ae9Sjsing 	md = rsa_algor_to_md(oaep->hashFunc);
1147c4380ae9Sjsing 	if (md == NULL)
1148c4380ae9Sjsing 		goto err;
1149c4380ae9Sjsing 
1150c4380ae9Sjsing 	if (oaep->pSourceFunc != NULL) {
1151c4380ae9Sjsing 		X509_ALGOR *plab = oaep->pSourceFunc;
1152c4380ae9Sjsing 
1153c4380ae9Sjsing 		if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
1154c4380ae9Sjsing 			RSAerror(RSA_R_UNSUPPORTED_LABEL_SOURCE);
1155c4380ae9Sjsing 			goto err;
1156c4380ae9Sjsing 		}
1157c4380ae9Sjsing 		if (plab->parameter->type != V_ASN1_OCTET_STRING) {
1158c4380ae9Sjsing 			RSAerror(RSA_R_INVALID_LABEL);
1159c4380ae9Sjsing 			goto err;
1160c4380ae9Sjsing 		}
1161c4380ae9Sjsing 
1162c4380ae9Sjsing 		label = plab->parameter->value.octet_string->data;
1163c4380ae9Sjsing 
1164c4380ae9Sjsing 		/* Stop label being freed when OAEP parameters are freed */
1165c4380ae9Sjsing 		/* XXX - this leaks label on error... */
1166c4380ae9Sjsing 		plab->parameter->value.octet_string->data = NULL;
1167c4380ae9Sjsing 		labellen = plab->parameter->value.octet_string->length;
1168c4380ae9Sjsing 	}
1169c4380ae9Sjsing 
1170c4380ae9Sjsing 	if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
1171c4380ae9Sjsing 		goto err;
1172c4380ae9Sjsing 	if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
1173c4380ae9Sjsing 		goto err;
1174c4380ae9Sjsing 	if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
1175c4380ae9Sjsing 		goto err;
1176c4380ae9Sjsing 	if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
1177c4380ae9Sjsing 		goto err;
1178c4380ae9Sjsing 
1179c4380ae9Sjsing 	rv = 1;
1180c4380ae9Sjsing 
1181c4380ae9Sjsing  err:
1182c4380ae9Sjsing 	RSA_OAEP_PARAMS_free(oaep);
1183c4380ae9Sjsing 	return rv;
1184c4380ae9Sjsing }
1185c4380ae9Sjsing 
1186c4380ae9Sjsing static int
1187c4380ae9Sjsing rsa_cms_encrypt(CMS_RecipientInfo *ri)
1188c4380ae9Sjsing {
1189c4380ae9Sjsing 	X509_ALGOR *alg;
1190478a1d06Stb 	EVP_PKEY_CTX *pkey_ctx;
1191b7ca3793Stb 	int pad_mode = RSA_PKCS1_PADDING;
1192c4380ae9Sjsing 
1193478a1d06Stb 	if ((pkey_ctx = CMS_RecipientInfo_get0_pkey_ctx(ri)) != NULL) {
1194478a1d06Stb 		if (EVP_PKEY_CTX_get_rsa_padding(pkey_ctx, &pad_mode) <= 0)
1195c4380ae9Sjsing 			return 0;
1196c4380ae9Sjsing 	}
11976b9d0bbcStb 
11986b9d0bbcStb 	if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg))
11996b9d0bbcStb 		return 0;
1200ffbbbf5cStb 	if (pad_mode == RSA_PKCS1_PADDING)
1201ffbbbf5cStb 		return rsa_alg_set_pkcs1_padding(alg);
1202b7ca3793Stb 	if (pad_mode == RSA_PKCS1_OAEP_PADDING)
1203478a1d06Stb 		return rsa_alg_set_oaep_padding(alg, pkey_ctx);
12046b9d0bbcStb 
1205c4380ae9Sjsing 	return 0;
1206c4380ae9Sjsing }
1207c4380ae9Sjsing #endif
1208c4380ae9Sjsing 
1209fa20815cStb const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
12109ed721ecStb 	.base_method = &rsa_asn1_meth,
1211e402ce74Smiod 	.pkey_id = EVP_PKEY_RSA,
1212e402ce74Smiod 	.pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
1213f1535dc8Sdjm 
1214e402ce74Smiod 	.pem_str = "RSA",
1215e402ce74Smiod 	.info = "OpenSSL RSA method",
1216f1535dc8Sdjm 
1217e402ce74Smiod 	.pub_decode = rsa_pub_decode,
1218e402ce74Smiod 	.pub_encode = rsa_pub_encode,
1219e402ce74Smiod 	.pub_cmp = rsa_pub_cmp,
1220e402ce74Smiod 	.pub_print = rsa_pub_print,
1221f1535dc8Sdjm 
1222e402ce74Smiod 	.priv_decode = rsa_priv_decode,
1223e402ce74Smiod 	.priv_encode = rsa_priv_encode,
1224e402ce74Smiod 	.priv_print = rsa_priv_print,
1225f1535dc8Sdjm 
1226c5ca9a16Stb 	.pkey_size = rsa_size,
1227e402ce74Smiod 	.pkey_bits = rsa_bits,
12285cdf0398Stb 	.pkey_security_bits = rsa_security_bits,
1229f1535dc8Sdjm 
1230e402ce74Smiod 	.sig_print = rsa_sig_print,
1231f1535dc8Sdjm 
1232c5ca9a16Stb 	.pkey_free = rsa_free,
1233e402ce74Smiod 	.pkey_ctrl = rsa_pkey_ctrl,
1234e402ce74Smiod 	.old_priv_decode = old_rsa_priv_decode,
1235e402ce74Smiod 	.old_priv_encode = old_rsa_priv_encode,
1236e402ce74Smiod 	.item_verify = rsa_item_verify,
1237c0f4ec48Stb 	.item_sign = rsa_item_sign,
1238fa20815cStb };
1239f1535dc8Sdjm 
1240fa20815cStb const EVP_PKEY_ASN1_METHOD rsa2_asn1_meth = {
12419ed721ecStb 	.base_method = &rsa_asn1_meth,
1242e402ce74Smiod 	.pkey_id = EVP_PKEY_RSA2,
1243c0f4ec48Stb 	.pkey_flags = ASN1_PKEY_ALIAS,
1244f1535dc8Sdjm };
1245e119b44aSjsing 
1246e119b44aSjsing const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = {
12479ed721ecStb 	.base_method = &rsa_pss_asn1_meth,
1248e119b44aSjsing 	.pkey_id = EVP_PKEY_RSA_PSS,
1249e119b44aSjsing 	.pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
1250e119b44aSjsing 
1251e119b44aSjsing 	.pem_str = "RSA-PSS",
1252e119b44aSjsing 	.info = "OpenSSL RSA-PSS method",
1253e119b44aSjsing 
1254e119b44aSjsing 	.pub_decode = rsa_pub_decode,
1255e119b44aSjsing 	.pub_encode = rsa_pub_encode,
1256e119b44aSjsing 	.pub_cmp = rsa_pub_cmp,
1257e119b44aSjsing 	.pub_print = rsa_pub_print,
1258e119b44aSjsing 
1259e119b44aSjsing 	.priv_decode = rsa_priv_decode,
1260e119b44aSjsing 	.priv_encode = rsa_priv_encode,
1261e119b44aSjsing 	.priv_print = rsa_priv_print,
1262e119b44aSjsing 
1263c5ca9a16Stb 	.pkey_size = rsa_size,
1264e119b44aSjsing 	.pkey_bits = rsa_bits,
1265d99e169eStb 	.pkey_security_bits = rsa_security_bits,
1266e119b44aSjsing 
1267c5d7bed5Stb 	.signature_info = rsa_pss_signature_info,
1268c5d7bed5Stb 
1269e119b44aSjsing 	.sig_print = rsa_sig_print,
1270e119b44aSjsing 
1271c5ca9a16Stb 	.pkey_free = rsa_free,
1272e119b44aSjsing 	.pkey_ctrl = rsa_pkey_ctrl,
1273e119b44aSjsing 	.item_verify = rsa_item_verify,
1274e119b44aSjsing 	.item_sign = rsa_item_sign
1275e119b44aSjsing };
1276