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 #include <openssl/core_names.h>
12 #include <openssl/params.h>
13 #include <openssl/evp.h>
14 #include "internal/sizes.h"
15 #include "internal/param_build_set.h"
16 #include "crypto/rsa.h"
18 #include "e_os.h" /* strcasecmp for Windows() */
21 * The intention with the "backend" source file is to offer backend support
22 * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
23 * implementations alike.
26 DEFINE_STACK_OF(BIGNUM
)
28 static int collect_numbers(STACK_OF(BIGNUM
) *numbers
,
29 const OSSL_PARAM params
[], const char *names
[])
31 const OSSL_PARAM
*p
= NULL
;
37 for (i
= 0; names
[i
] != NULL
; i
++){
38 p
= OSSL_PARAM_locate_const(params
, names
[i
]);
42 if (!OSSL_PARAM_get_BN(p
, &tmp
)
43 || sk_BIGNUM_push(numbers
, tmp
) == 0)
51 int ossl_rsa_fromdata(RSA
*rsa
, const OSSL_PARAM params
[])
53 const OSSL_PARAM
*param_n
, *param_e
, *param_d
;
54 BIGNUM
*n
= NULL
, *e
= NULL
, *d
= NULL
;
55 STACK_OF(BIGNUM
) *factors
= NULL
, *exps
= NULL
, *coeffs
= NULL
;
61 param_n
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_N
);
62 param_e
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_E
);
63 param_d
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_D
);
65 if ((param_n
!= NULL
&& !OSSL_PARAM_get_BN(param_n
, &n
))
66 || (param_e
!= NULL
&& !OSSL_PARAM_get_BN(param_e
, &e
))
67 || (param_d
!= NULL
&& !OSSL_PARAM_get_BN(param_d
, &d
)))
70 is_private
= (d
!= NULL
);
72 if (!RSA_set0_key(rsa
, n
, e
, d
))
77 if (!collect_numbers(factors
= sk_BIGNUM_new_null(), params
,
78 ossl_rsa_mp_factor_names
)
79 || !collect_numbers(exps
= sk_BIGNUM_new_null(), params
,
80 ossl_rsa_mp_exp_names
)
81 || !collect_numbers(coeffs
= sk_BIGNUM_new_null(), params
,
82 ossl_rsa_mp_coeff_names
))
85 /* It's ok if this private key just has n, e and d */
86 if (sk_BIGNUM_num(factors
) != 0
87 && !ossl_rsa_set0_all_params(rsa
, factors
, exps
, coeffs
))
92 sk_BIGNUM_free(factors
);
94 sk_BIGNUM_free(coeffs
);
101 sk_BIGNUM_pop_free(factors
, BN_free
);
102 sk_BIGNUM_pop_free(exps
, BN_free
);
103 sk_BIGNUM_pop_free(coeffs
, BN_free
);
107 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const
, BIGNUM
)
109 int ossl_rsa_todata(RSA
*rsa
, OSSL_PARAM_BLD
*bld
, OSSL_PARAM params
[])
112 const BIGNUM
*rsa_d
= NULL
, *rsa_n
= NULL
, *rsa_e
= NULL
;
113 STACK_OF(BIGNUM_const
) *factors
= sk_BIGNUM_const_new_null();
114 STACK_OF(BIGNUM_const
) *exps
= sk_BIGNUM_const_new_null();
115 STACK_OF(BIGNUM_const
) *coeffs
= sk_BIGNUM_const_new_null();
117 if (rsa
== NULL
|| factors
== NULL
|| exps
== NULL
|| coeffs
== NULL
)
120 RSA_get0_key(rsa
, &rsa_n
, &rsa_e
, &rsa_d
);
121 ossl_rsa_get0_all_params(rsa
, factors
, exps
, coeffs
);
123 if (!ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_N
, rsa_n
)
124 || !ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_E
, rsa_e
))
127 /* Check private key data integrity */
129 int numprimes
= sk_BIGNUM_const_num(factors
);
130 int numexps
= sk_BIGNUM_const_num(exps
);
131 int numcoeffs
= sk_BIGNUM_const_num(coeffs
);
134 * It's permissible to have zero primes, i.e. no CRT params.
135 * Otherwise, there must be at least two, as many exponents,
136 * and one coefficient less.
139 && (numprimes
< 2 || numexps
< 2 || numcoeffs
< 1))
142 if (!ossl_param_build_set_bn(bld
, params
, OSSL_PKEY_PARAM_RSA_D
,
144 || !ossl_param_build_set_multi_key_bn(bld
, params
,
145 ossl_rsa_mp_factor_names
,
147 || !ossl_param_build_set_multi_key_bn(bld
, params
,
148 ossl_rsa_mp_exp_names
, exps
)
149 || !ossl_param_build_set_multi_key_bn(bld
, params
,
150 ossl_rsa_mp_coeff_names
,
155 #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
156 /* The acvp test results are not meant for export so check for bld == NULL */
158 rsa_acvp_test_get_params(rsa
, params
);
162 sk_BIGNUM_const_free(factors
);
163 sk_BIGNUM_const_free(exps
);
164 sk_BIGNUM_const_free(coeffs
);
168 int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30
*pss
,
169 OSSL_PARAM_BLD
*bld
, OSSL_PARAM params
[])
171 if (!ossl_rsa_pss_params_30_is_unrestricted(pss
)) {
172 int hashalg_nid
= ossl_rsa_pss_params_30_hashalg(pss
);
173 int maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(pss
);
174 int maskgenhashalg_nid
= ossl_rsa_pss_params_30_maskgenhashalg(pss
);
175 int saltlen
= ossl_rsa_pss_params_30_saltlen(pss
);
176 int default_hashalg_nid
= ossl_rsa_pss_params_30_hashalg(NULL
);
177 int default_maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(NULL
);
178 int default_maskgenhashalg_nid
=
179 ossl_rsa_pss_params_30_maskgenhashalg(NULL
);
181 (hashalg_nid
== default_hashalg_nid
182 ? NULL
: ossl_rsa_oaeppss_nid2name(hashalg_nid
));
183 const char *mgfname
=
184 (maskgenalg_nid
== default_maskgenalg_nid
185 ? NULL
: ossl_rsa_oaeppss_nid2name(maskgenalg_nid
));
186 const char *mgf1mdname
=
187 (maskgenhashalg_nid
== default_maskgenhashalg_nid
188 ? NULL
: ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid
));
189 const char *key_md
= OSSL_PKEY_PARAM_RSA_DIGEST
;
190 const char *key_mgf
= OSSL_PKEY_PARAM_RSA_MASKGENFUNC
;
191 const char *key_mgf1_md
= OSSL_PKEY_PARAM_RSA_MGF1_DIGEST
;
192 const char *key_saltlen
= OSSL_PKEY_PARAM_RSA_PSS_SALTLEN
;
195 * To ensure that the key isn't seen as unrestricted by the recipient,
196 * we make sure that at least one PSS-related parameter is passed, even
197 * if it has a default value; saltlen.
200 && !ossl_param_build_set_utf8_string(bld
, params
, key_md
, mdname
))
202 && !ossl_param_build_set_utf8_string(bld
, params
,
204 || (mgf1mdname
!= NULL
205 && !ossl_param_build_set_utf8_string(bld
, params
,
206 key_mgf1_md
, mgf1mdname
))
207 || (!ossl_param_build_set_int(bld
, params
, key_saltlen
, saltlen
)))
213 int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30
*pss_params
,
214 const OSSL_PARAM params
[],
217 const OSSL_PARAM
*param_md
, *param_mgf
, *param_mgf1md
, *param_saltlen
;
218 const OSSL_PARAM
*param_propq
;
219 const char *propq
= NULL
;
220 EVP_MD
*md
= NULL
, *mgf1md
= NULL
;
224 if (pss_params
== NULL
)
227 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS
);
229 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_DIGEST
);
231 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_MASKGENFUNC
);
233 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST
);
235 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN
);
237 if (param_propq
!= NULL
) {
238 if (param_propq
->data_type
== OSSL_PARAM_UTF8_STRING
)
239 propq
= param_propq
->data
;
242 * If we get any of the parameters, we know we have at least some
243 * restrictions, so we start by setting default values, and let each
244 * parameter override their specific restriction data.
246 if (param_md
!= NULL
|| param_mgf
!= NULL
|| param_mgf1md
!= NULL
247 || param_saltlen
!= NULL
)
248 if (!ossl_rsa_pss_params_30_set_defaults(pss_params
))
251 if (param_mgf
!= NULL
) {
252 int default_maskgenalg_nid
= ossl_rsa_pss_params_30_maskgenalg(NULL
);
253 const char *mgfname
= NULL
;
255 if (param_mgf
->data_type
== OSSL_PARAM_UTF8_STRING
)
256 mgfname
= param_mgf
->data
;
257 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mgfname
))
260 /* TODO Revisit this if / when a new MGF algorithm appears */
261 if (strcasecmp(param_mgf
->data
,
262 ossl_rsa_mgf_nid2name(default_maskgenalg_nid
)) != 0)
267 * We're only interested in the NIDs that correspond to the MDs, so the
268 * exact propquery is unimportant in the EVP_MD_fetch() calls below.
271 if (param_md
!= NULL
) {
272 const char *mdname
= NULL
;
274 if (param_md
->data_type
== OSSL_PARAM_UTF8_STRING
)
275 mdname
= param_md
->data
;
276 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mdname
))
279 if ((md
= EVP_MD_fetch(libctx
, mdname
, propq
)) == NULL
280 || !ossl_rsa_pss_params_30_set_hashalg(pss_params
,
281 ossl_rsa_oaeppss_md2nid(md
)))
285 if (param_mgf1md
!= NULL
) {
286 const char *mgf1mdname
= NULL
;
288 if (param_mgf1md
->data_type
== OSSL_PARAM_UTF8_STRING
)
289 mgf1mdname
= param_mgf1md
->data
;
290 else if (!OSSL_PARAM_get_utf8_ptr(param_mgf
, &mgf1mdname
))
293 if ((mgf1md
= EVP_MD_fetch(libctx
, mgf1mdname
, propq
)) == NULL
294 || !ossl_rsa_pss_params_30_set_maskgenhashalg(
295 pss_params
, ossl_rsa_oaeppss_md2nid(mgf1md
)))
299 if (param_saltlen
!= NULL
) {
300 if (!OSSL_PARAM_get_int(param_saltlen
, &saltlen
)
301 || !ossl_rsa_pss_params_30_set_saltlen(pss_params
, saltlen
))