2 * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * RSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
17 #include <openssl/core_names.h>
18 #include <openssl/params.h>
19 #include <openssl/evp.h>
20 #include "internal/sizes.h"
21 #include "internal/param_build_set.h"
22 #include "crypto/rsa.h"
24 #include "e_os.h" /* strcasecmp for Windows() */
27 * The intention with the "backend" source file is to offer backend support
28 * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
29 * implementations alike.
32 DEFINE_STACK_OF(BIGNUM
)
34 static int collect_numbers(STACK_OF(BIGNUM
) *numbers
,
35 const OSSL_PARAM params
[], const char *names
[])
37 const OSSL_PARAM
*p
= NULL
;
43 for (i
= 0; names
[i
] != NULL
; i
++){
44 p
= OSSL_PARAM_locate_const(params
, names
[i
]);
48 if (!OSSL_PARAM_get_BN(p
, &tmp
)
49 || sk_BIGNUM_push(numbers
, tmp
) == 0)
57 int ossl_rsa_fromdata(RSA
*rsa
, const OSSL_PARAM params
[])
59 const OSSL_PARAM
*param_n
, *param_e
, *param_d
;
60 BIGNUM
*n
= NULL
, *e
= NULL
, *d
= NULL
;
61 STACK_OF(BIGNUM
) *factors
= NULL
, *exps
= NULL
, *coeffs
= NULL
;
67 param_n
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_N
);
68 param_e
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_E
);
69 param_d
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_D
);
71 if ((param_n
!= NULL
&& !OSSL_PARAM_get_BN(param_n
, &n
))
72 || (param_e
!= NULL
&& !OSSL_PARAM_get_BN(param_e
, &e
))
73 || (param_d
!= NULL
&& !OSSL_PARAM_get_BN(param_d
, &d
)))
76 is_private
= (d
!= NULL
);
78 if (!RSA_set0_key(rsa
, n
, e
, d
))
83 if (!collect_numbers(factors
= sk_BIGNUM_new_null(), params
,
84 ossl_rsa_mp_factor_names
)
85 || !collect_numbers(exps
= sk_BIGNUM_new_null(), params
,
86 ossl_rsa_mp_exp_names
)
87 || !collect_numbers(coeffs
= sk_BIGNUM_new_null(), params
,
88 ossl_rsa_mp_coeff_names
))
91 /* It's ok if this private key just has n, e and d */
92 if (sk_BIGNUM_num(factors
) != 0
93 && !ossl_rsa_set0_all_params(rsa
, factors
, exps
, coeffs
))
98 sk_BIGNUM_free(factors
);
100 sk_BIGNUM_free(coeffs
);
107 sk_BIGNUM_pop_free(factors
, BN_free
);
108 sk_BIGNUM_pop_free(exps
, BN_free
);
109 sk_BIGNUM_pop_free(coeffs
, BN_free
);
113 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const
, BIGNUM
)
115 int ossl_rsa_todata(RSA
*rsa
, OSSL_PARAM_BLD
*bld
, OSSL_PARAM params
[])
118 const BIGNUM
*rsa_d
= NULL
, *rsa_n
= NULL
, *rsa_e
= NULL
;
119 STACK_OF(BIGNUM_const
) *factors
= sk_BIGNUM_const_new_null();
120 STACK_OF(BIGNUM_const
) *exps
= sk_BIGNUM_const_new_null();
121 STACK_OF(BIGNUM_const
) *coeffs
= sk_BIGNUM_const_new_null();
123 if (rsa
== NULL
|| factors
== NULL
|| exps
== NULL
|| coeffs
== NULL
)
126 RSA_get0_key(rsa
, &rsa_n
, &rsa_e
, &rsa_d
);
127 ossl_rsa_get0_all_params(rsa
, factors
, exps
, coeffs
);
129 if (!ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_N
, rsa_n
)
130 || !ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_E
, rsa_e
))
133 /* Check private key data integrity */
135 int numprimes
= sk_BIGNUM_const_num(factors
);
136 int numexps
= sk_BIGNUM_const_num(exps
);
137 int numcoeffs
= sk_BIGNUM_const_num(coeffs
);
140 * It's permissible to have zero primes, i.e. no CRT params.
141 * Otherwise, there must be at least two, as many exponents,
142 * and one coefficient less.
145 && (numprimes
< 2 || numexps
< 2 || numcoeffs
< 1))
148 if (!ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_D
,
150 || !ossl_param_build_set_multi_key_bn(bld
, params
,
151 ossl_rsa_mp_factor_names
,
153 || !ossl_param_build_set_multi_key_bn(bld
, params
,
154 ossl_rsa_mp_exp_names
, exps
)
155 || !ossl_param_build_set_multi_key_bn(bld
, params
,
156 ossl_rsa_mp_coeff_names
,
161 #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
162 /* The acvp test results are not meant for export so check for bld == NULL */
164 rsa_acvp_test_get_params(rsa
, params
);
168 sk_BIGNUM_const_free(factors
);
169 sk_BIGNUM_const_free(exps
);
170 sk_BIGNUM_const_free(coeffs
);
174 int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30
*pss
,
175 OSSL_PARAM_BLD
*bld
, OSSL_PARAM params
[])
177 if (!ossl_rsa_pss_params_30_is_unrestricted(pss
)) {
178 int hashalg_nid
= ossl_rsa_pss_params_30_hashalg(pss
);
179 int maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(pss
);
180 int maskgenhashalg_nid
= ossl_rsa_pss_params_30_maskgenhashalg(pss
);
181 int saltlen
= ossl_rsa_pss_params_30_saltlen(pss
);
182 int default_hashalg_nid
= ossl_rsa_pss_params_30_hashalg(NULL
);
183 int default_maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(NULL
);
184 int default_maskgenhashalg_nid
=
185 ossl_rsa_pss_params_30_maskgenhashalg(NULL
);
187 (hashalg_nid
== default_hashalg_nid
188 ? NULL
: ossl_rsa_oaeppss_nid2name(hashalg_nid
));
189 const char *mgfname
=
190 (maskgenalg_nid
== default_maskgenalg_nid
191 ? NULL
: ossl_rsa_oaeppss_nid2name(maskgenalg_nid
));
192 const char *mgf1mdname
=
193 (maskgenhashalg_nid
== default_maskgenhashalg_nid
194 ? NULL
: ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid
));
195 const char *key_md
= OSSL_PKEY_PARAM_RSA_DIGEST
;
196 const char *key_mgf
= OSSL_PKEY_PARAM_RSA_MASKGENFUNC
;
197 const char *key_mgf1_md
= OSSL_PKEY_PARAM_RSA_MGF1_DIGEST
;
198 const char *key_saltlen
= OSSL_PKEY_PARAM_RSA_PSS_SALTLEN
;
201 * To ensure that the key isn't seen as unrestricted by the recipient,
202 * we make sure that at least one PSS-related parameter is passed, even
203 * if it has a default value; saltlen.
206 && !ossl_param_build_set_utf8_string(bld
, params
, key_md
, mdname
))
208 && !ossl_param_build_set_utf8_string(bld
, params
,
210 || (mgf1mdname
!= NULL
211 && !ossl_param_build_set_utf8_string(bld
, params
,
212 key_mgf1_md
, mgf1mdname
))
213 || (!ossl_param_build_set_int(bld
, params
, key_saltlen
, saltlen
)))
219 int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30
*pss_params
,
220 const OSSL_PARAM params
[],
221 OSSL_LIB_CTX
*libctx
)
223 const OSSL_PARAM
*param_md
, *param_mgf
, *param_mgf1md
, *param_saltlen
;
224 const OSSL_PARAM
*param_propq
;
225 const char *propq
= NULL
;
226 EVP_MD
*md
= NULL
, *mgf1md
= NULL
;
230 if (pss_params
== NULL
)
233 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS
);
235 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_DIGEST
);
237 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_MASKGENFUNC
);
239 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST
);
241 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN
);
243 if (param_propq
!= NULL
) {
244 if (param_propq
->data_type
== OSSL_PARAM_UTF8_STRING
)
245 propq
= param_propq
->data
;
248 * If we get any of the parameters, we know we have at least some
249 * restrictions, so we start by setting default values, and let each
250 * parameter override their specific restriction data.
252 if (param_md
!= NULL
|| param_mgf
!= NULL
|| param_mgf1md
!= NULL
253 || param_saltlen
!= NULL
)
254 if (!ossl_rsa_pss_params_30_set_defaults(pss_params
))
257 if (param_mgf
!= NULL
) {
258 int default_maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(NULL
);
259 const char *mgfname
= NULL
;
261 if (param_mgf
->data_type
== OSSL_PARAM_UTF8_STRING
)
262 mgfname
= param_mgf
->data
;
263 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mgfname
))
266 /* TODO Revisit this if / when a new MGF algorithm appears */
267 if (strcasecmp(param_mgf
->data
,
268 ossl_rsa_mgf_nid2name(default_maskgenalg_nid
)) != 0)
273 * We're only interested in the NIDs that correspond to the MDs, so the
274 * exact propquery is unimportant in the EVP_MD_fetch() calls below.
277 if (param_md
!= NULL
) {
278 const char *mdname
= NULL
;
280 if (param_md
->data_type
== OSSL_PARAM_UTF8_STRING
)
281 mdname
= param_md
->data
;
282 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mdname
))
285 if ((md
= EVP_MD_fetch(libctx
, mdname
, propq
)) == NULL
286 || !ossl_rsa_pss_params_30_set_hashalg(pss_params
,
287 ossl_rsa_oaeppss_md2nid(md
)))
291 if (param_mgf1md
!= NULL
) {
292 const char *mgf1mdname
= NULL
;
294 if (param_mgf1md
->data_type
== OSSL_PARAM_UTF8_STRING
)
295 mgf1mdname
= param_mgf1md
->data
;
296 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mgf1mdname
))
299 if ((mgf1md
= EVP_MD_fetch(libctx
, mgf1mdname
, propq
)) == NULL
300 || !ossl_rsa_pss_params_30_set_maskgenhashalg(
301 pss_params
, ossl_rsa_oaeppss_md2nid(mgf1md
)))
305 if (param_saltlen
!= NULL
) {
306 if (!OSSL_PARAM_get_int(param_saltlen
, &saltlen
)
307 || !ossl_rsa_pss_params_30_set_saltlen(pss_params
, saltlen
))