1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * RSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <string.h> 17e1051a39Sopenharmony_ci#include <openssl/core_names.h> 18e1051a39Sopenharmony_ci#include <openssl/params.h> 19e1051a39Sopenharmony_ci#include <openssl/err.h> 20e1051a39Sopenharmony_ci#include <openssl/evp.h> 21e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 22e1051a39Sopenharmony_ci# include <openssl/x509.h> 23e1051a39Sopenharmony_ci# include "crypto/asn1.h" 24e1051a39Sopenharmony_ci#endif 25e1051a39Sopenharmony_ci#include "internal/sizes.h" 26e1051a39Sopenharmony_ci#include "internal/param_build_set.h" 27e1051a39Sopenharmony_ci#include "crypto/rsa.h" 28e1051a39Sopenharmony_ci#include "rsa_local.h" 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci/* 31e1051a39Sopenharmony_ci * The intention with the "backend" source file is to offer backend support 32e1051a39Sopenharmony_ci * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider 33e1051a39Sopenharmony_ci * implementations alike. 34e1051a39Sopenharmony_ci */ 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ciDEFINE_STACK_OF(BIGNUM) 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_cistatic int collect_numbers(STACK_OF(BIGNUM) *numbers, 39e1051a39Sopenharmony_ci const OSSL_PARAM params[], const char *names[]) 40e1051a39Sopenharmony_ci{ 41e1051a39Sopenharmony_ci const OSSL_PARAM *p = NULL; 42e1051a39Sopenharmony_ci int i; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci if (numbers == NULL) 45e1051a39Sopenharmony_ci return 0; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci for (i = 0; names[i] != NULL; i++){ 48e1051a39Sopenharmony_ci p = OSSL_PARAM_locate_const(params, names[i]); 49e1051a39Sopenharmony_ci if (p != NULL) { 50e1051a39Sopenharmony_ci BIGNUM *tmp = NULL; 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_BN(p, &tmp)) 53e1051a39Sopenharmony_ci return 0; 54e1051a39Sopenharmony_ci if (sk_BIGNUM_push(numbers, tmp) == 0) { 55e1051a39Sopenharmony_ci BN_clear_free(tmp); 56e1051a39Sopenharmony_ci return 0; 57e1051a39Sopenharmony_ci } 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci } 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ci return 1; 62e1051a39Sopenharmony_ci} 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ciint ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci const OSSL_PARAM *param_n, *param_e, *param_d = NULL; 67e1051a39Sopenharmony_ci BIGNUM *n = NULL, *e = NULL, *d = NULL; 68e1051a39Sopenharmony_ci STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL; 69e1051a39Sopenharmony_ci int is_private = 0; 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_ci if (rsa == NULL) 72e1051a39Sopenharmony_ci return 0; 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N); 75e1051a39Sopenharmony_ci param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E); 76e1051a39Sopenharmony_ci if (include_private) 77e1051a39Sopenharmony_ci param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D); 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci if ((param_n != NULL && !OSSL_PARAM_get_BN(param_n, &n)) 80e1051a39Sopenharmony_ci || (param_e != NULL && !OSSL_PARAM_get_BN(param_e, &e)) 81e1051a39Sopenharmony_ci || (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d))) 82e1051a39Sopenharmony_ci goto err; 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ci is_private = (d != NULL); 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci if (!RSA_set0_key(rsa, n, e, d)) 87e1051a39Sopenharmony_ci goto err; 88e1051a39Sopenharmony_ci n = e = d = NULL; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci if (is_private) { 91e1051a39Sopenharmony_ci if (!collect_numbers(factors = sk_BIGNUM_new_null(), params, 92e1051a39Sopenharmony_ci ossl_rsa_mp_factor_names) 93e1051a39Sopenharmony_ci || !collect_numbers(exps = sk_BIGNUM_new_null(), params, 94e1051a39Sopenharmony_ci ossl_rsa_mp_exp_names) 95e1051a39Sopenharmony_ci || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params, 96e1051a39Sopenharmony_ci ossl_rsa_mp_coeff_names)) 97e1051a39Sopenharmony_ci goto err; 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci /* It's ok if this private key just has n, e and d */ 100e1051a39Sopenharmony_ci if (sk_BIGNUM_num(factors) != 0 101e1051a39Sopenharmony_ci && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs)) 102e1051a39Sopenharmony_ci goto err; 103e1051a39Sopenharmony_ci } 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci sk_BIGNUM_free(factors); 107e1051a39Sopenharmony_ci sk_BIGNUM_free(exps); 108e1051a39Sopenharmony_ci sk_BIGNUM_free(coeffs); 109e1051a39Sopenharmony_ci return 1; 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci err: 112e1051a39Sopenharmony_ci BN_free(n); 113e1051a39Sopenharmony_ci BN_free(e); 114e1051a39Sopenharmony_ci BN_free(d); 115e1051a39Sopenharmony_ci sk_BIGNUM_pop_free(factors, BN_free); 116e1051a39Sopenharmony_ci sk_BIGNUM_pop_free(exps, BN_free); 117e1051a39Sopenharmony_ci sk_BIGNUM_pop_free(coeffs, BN_free); 118e1051a39Sopenharmony_ci return 0; 119e1051a39Sopenharmony_ci} 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ciDEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ciint ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], 124e1051a39Sopenharmony_ci int include_private) 125e1051a39Sopenharmony_ci{ 126e1051a39Sopenharmony_ci int ret = 0; 127e1051a39Sopenharmony_ci const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; 128e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null(); 129e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null(); 130e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null(); 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ci if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL) 133e1051a39Sopenharmony_ci goto err; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); 136e1051a39Sopenharmony_ci ossl_rsa_get0_all_params(rsa, factors, exps, coeffs); 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n) 139e1051a39Sopenharmony_ci || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)) 140e1051a39Sopenharmony_ci goto err; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci /* Check private key data integrity */ 143e1051a39Sopenharmony_ci if (include_private && rsa_d != NULL) { 144e1051a39Sopenharmony_ci int numprimes = sk_BIGNUM_const_num(factors); 145e1051a39Sopenharmony_ci int numexps = sk_BIGNUM_const_num(exps); 146e1051a39Sopenharmony_ci int numcoeffs = sk_BIGNUM_const_num(coeffs); 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci /* 149e1051a39Sopenharmony_ci * It's permissible to have zero primes, i.e. no CRT params. 150e1051a39Sopenharmony_ci * Otherwise, there must be at least two, as many exponents, 151e1051a39Sopenharmony_ci * and one coefficient less. 152e1051a39Sopenharmony_ci */ 153e1051a39Sopenharmony_ci if (numprimes != 0 154e1051a39Sopenharmony_ci && (numprimes < 2 || numexps < 2 || numcoeffs < 1)) 155e1051a39Sopenharmony_ci goto err; 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, 158e1051a39Sopenharmony_ci rsa_d) 159e1051a39Sopenharmony_ci || !ossl_param_build_set_multi_key_bn(bld, params, 160e1051a39Sopenharmony_ci ossl_rsa_mp_factor_names, 161e1051a39Sopenharmony_ci factors) 162e1051a39Sopenharmony_ci || !ossl_param_build_set_multi_key_bn(bld, params, 163e1051a39Sopenharmony_ci ossl_rsa_mp_exp_names, exps) 164e1051a39Sopenharmony_ci || !ossl_param_build_set_multi_key_bn(bld, params, 165e1051a39Sopenharmony_ci ossl_rsa_mp_coeff_names, 166e1051a39Sopenharmony_ci coeffs)) 167e1051a39Sopenharmony_ci goto err; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) 171e1051a39Sopenharmony_ci /* The acvp test results are not meant for export so check for bld == NULL */ 172e1051a39Sopenharmony_ci if (bld == NULL) 173e1051a39Sopenharmony_ci ossl_rsa_acvp_test_get_params(rsa, params); 174e1051a39Sopenharmony_ci#endif 175e1051a39Sopenharmony_ci ret = 1; 176e1051a39Sopenharmony_ci err: 177e1051a39Sopenharmony_ci sk_BIGNUM_const_free(factors); 178e1051a39Sopenharmony_ci sk_BIGNUM_const_free(exps); 179e1051a39Sopenharmony_ci sk_BIGNUM_const_free(coeffs); 180e1051a39Sopenharmony_ci return ret; 181e1051a39Sopenharmony_ci} 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ciint ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, 184e1051a39Sopenharmony_ci OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) 185e1051a39Sopenharmony_ci{ 186e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { 187e1051a39Sopenharmony_ci int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); 188e1051a39Sopenharmony_ci int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss); 189e1051a39Sopenharmony_ci int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); 190e1051a39Sopenharmony_ci int saltlen = ossl_rsa_pss_params_30_saltlen(pss); 191e1051a39Sopenharmony_ci int default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL); 192e1051a39Sopenharmony_ci int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); 193e1051a39Sopenharmony_ci int default_maskgenhashalg_nid = 194e1051a39Sopenharmony_ci ossl_rsa_pss_params_30_maskgenhashalg(NULL); 195e1051a39Sopenharmony_ci const char *mdname = 196e1051a39Sopenharmony_ci (hashalg_nid == default_hashalg_nid 197e1051a39Sopenharmony_ci ? NULL : ossl_rsa_oaeppss_nid2name(hashalg_nid)); 198e1051a39Sopenharmony_ci const char *mgfname = 199e1051a39Sopenharmony_ci (maskgenalg_nid == default_maskgenalg_nid 200e1051a39Sopenharmony_ci ? NULL : ossl_rsa_oaeppss_nid2name(maskgenalg_nid)); 201e1051a39Sopenharmony_ci const char *mgf1mdname = 202e1051a39Sopenharmony_ci (maskgenhashalg_nid == default_maskgenhashalg_nid 203e1051a39Sopenharmony_ci ? NULL : ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid)); 204e1051a39Sopenharmony_ci const char *key_md = OSSL_PKEY_PARAM_RSA_DIGEST; 205e1051a39Sopenharmony_ci const char *key_mgf = OSSL_PKEY_PARAM_RSA_MASKGENFUNC; 206e1051a39Sopenharmony_ci const char *key_mgf1_md = OSSL_PKEY_PARAM_RSA_MGF1_DIGEST; 207e1051a39Sopenharmony_ci const char *key_saltlen = OSSL_PKEY_PARAM_RSA_PSS_SALTLEN; 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci /* 210e1051a39Sopenharmony_ci * To ensure that the key isn't seen as unrestricted by the recipient, 211e1051a39Sopenharmony_ci * we make sure that at least one PSS-related parameter is passed, even 212e1051a39Sopenharmony_ci * if it has a default value; saltlen. 213e1051a39Sopenharmony_ci */ 214e1051a39Sopenharmony_ci if ((mdname != NULL 215e1051a39Sopenharmony_ci && !ossl_param_build_set_utf8_string(bld, params, key_md, mdname)) 216e1051a39Sopenharmony_ci || (mgfname != NULL 217e1051a39Sopenharmony_ci && !ossl_param_build_set_utf8_string(bld, params, 218e1051a39Sopenharmony_ci key_mgf, mgfname)) 219e1051a39Sopenharmony_ci || (mgf1mdname != NULL 220e1051a39Sopenharmony_ci && !ossl_param_build_set_utf8_string(bld, params, 221e1051a39Sopenharmony_ci key_mgf1_md, mgf1mdname)) 222e1051a39Sopenharmony_ci || (!ossl_param_build_set_int(bld, params, key_saltlen, saltlen))) 223e1051a39Sopenharmony_ci return 0; 224e1051a39Sopenharmony_ci } 225e1051a39Sopenharmony_ci return 1; 226e1051a39Sopenharmony_ci} 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_ciint ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, 229e1051a39Sopenharmony_ci int *defaults_set, 230e1051a39Sopenharmony_ci const OSSL_PARAM params[], 231e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx) 232e1051a39Sopenharmony_ci{ 233e1051a39Sopenharmony_ci const OSSL_PARAM *param_md, *param_mgf, *param_mgf1md, *param_saltlen; 234e1051a39Sopenharmony_ci const OSSL_PARAM *param_propq; 235e1051a39Sopenharmony_ci const char *propq = NULL; 236e1051a39Sopenharmony_ci EVP_MD *md = NULL, *mgf1md = NULL; 237e1051a39Sopenharmony_ci int saltlen; 238e1051a39Sopenharmony_ci int ret = 0; 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci if (pss_params == NULL) 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci param_propq = 243e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS); 244e1051a39Sopenharmony_ci param_md = 245e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST); 246e1051a39Sopenharmony_ci param_mgf = 247e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MASKGENFUNC); 248e1051a39Sopenharmony_ci param_mgf1md = 249e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST); 250e1051a39Sopenharmony_ci param_saltlen = 251e1051a39Sopenharmony_ci OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN); 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci if (param_propq != NULL) { 254e1051a39Sopenharmony_ci if (param_propq->data_type == OSSL_PARAM_UTF8_STRING) 255e1051a39Sopenharmony_ci propq = param_propq->data; 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci /* 258e1051a39Sopenharmony_ci * If we get any of the parameters, we know we have at least some 259e1051a39Sopenharmony_ci * restrictions, so we start by setting default values, and let each 260e1051a39Sopenharmony_ci * parameter override their specific restriction data. 261e1051a39Sopenharmony_ci */ 262e1051a39Sopenharmony_ci if (!*defaults_set 263e1051a39Sopenharmony_ci && (param_md != NULL || param_mgf != NULL || param_mgf1md != NULL 264e1051a39Sopenharmony_ci || param_saltlen != NULL)) { 265e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_set_defaults(pss_params)) 266e1051a39Sopenharmony_ci return 0; 267e1051a39Sopenharmony_ci *defaults_set = 1; 268e1051a39Sopenharmony_ci } 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ci if (param_mgf != NULL) { 271e1051a39Sopenharmony_ci int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); 272e1051a39Sopenharmony_ci const char *mgfname = NULL; 273e1051a39Sopenharmony_ci 274e1051a39Sopenharmony_ci if (param_mgf->data_type == OSSL_PARAM_UTF8_STRING) 275e1051a39Sopenharmony_ci mgfname = param_mgf->data; 276e1051a39Sopenharmony_ci else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgfname)) 277e1051a39Sopenharmony_ci return 0; 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci if (OPENSSL_strcasecmp(param_mgf->data, 280e1051a39Sopenharmony_ci ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) != 0) 281e1051a39Sopenharmony_ci return 0; 282e1051a39Sopenharmony_ci } 283e1051a39Sopenharmony_ci 284e1051a39Sopenharmony_ci /* 285e1051a39Sopenharmony_ci * We're only interested in the NIDs that correspond to the MDs, so the 286e1051a39Sopenharmony_ci * exact propquery is unimportant in the EVP_MD_fetch() calls below. 287e1051a39Sopenharmony_ci */ 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci if (param_md != NULL) { 290e1051a39Sopenharmony_ci const char *mdname = NULL; 291e1051a39Sopenharmony_ci 292e1051a39Sopenharmony_ci if (param_md->data_type == OSSL_PARAM_UTF8_STRING) 293e1051a39Sopenharmony_ci mdname = param_md->data; 294e1051a39Sopenharmony_ci else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mdname)) 295e1051a39Sopenharmony_ci goto err; 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ci if ((md = EVP_MD_fetch(libctx, mdname, propq)) == NULL 298e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_hashalg(pss_params, 299e1051a39Sopenharmony_ci ossl_rsa_oaeppss_md2nid(md))) 300e1051a39Sopenharmony_ci goto err; 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_ci if (param_mgf1md != NULL) { 304e1051a39Sopenharmony_ci const char *mgf1mdname = NULL; 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci if (param_mgf1md->data_type == OSSL_PARAM_UTF8_STRING) 307e1051a39Sopenharmony_ci mgf1mdname = param_mgf1md->data; 308e1051a39Sopenharmony_ci else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgf1mdname)) 309e1051a39Sopenharmony_ci goto err; 310e1051a39Sopenharmony_ci 311e1051a39Sopenharmony_ci if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, propq)) == NULL 312e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_maskgenhashalg( 313e1051a39Sopenharmony_ci pss_params, ossl_rsa_oaeppss_md2nid(mgf1md))) 314e1051a39Sopenharmony_ci goto err; 315e1051a39Sopenharmony_ci } 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ci if (param_saltlen != NULL) { 318e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_int(param_saltlen, &saltlen) 319e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_saltlen(pss_params, saltlen)) 320e1051a39Sopenharmony_ci goto err; 321e1051a39Sopenharmony_ci } 322e1051a39Sopenharmony_ci 323e1051a39Sopenharmony_ci ret = 1; 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci err: 326e1051a39Sopenharmony_ci EVP_MD_free(md); 327e1051a39Sopenharmony_ci EVP_MD_free(mgf1md); 328e1051a39Sopenharmony_ci return ret; 329e1051a39Sopenharmony_ci} 330e1051a39Sopenharmony_ci 331e1051a39Sopenharmony_ciint ossl_rsa_is_foreign(const RSA *rsa) 332e1051a39Sopenharmony_ci{ 333e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 334e1051a39Sopenharmony_ci if (rsa->engine != NULL || RSA_get_method(rsa) != RSA_PKCS1_OpenSSL()) 335e1051a39Sopenharmony_ci return 1; 336e1051a39Sopenharmony_ci#endif 337e1051a39Sopenharmony_ci return 0; 338e1051a39Sopenharmony_ci} 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_cistatic ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) 341e1051a39Sopenharmony_ci{ 342e1051a39Sopenharmony_ci if (f != NULL && (*out = BN_dup(f)) == NULL) 343e1051a39Sopenharmony_ci return 0; 344e1051a39Sopenharmony_ci return 1; 345e1051a39Sopenharmony_ci} 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ciRSA *ossl_rsa_dup(const RSA *rsa, int selection) 348e1051a39Sopenharmony_ci{ 349e1051a39Sopenharmony_ci RSA *dupkey = NULL; 350e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 351e1051a39Sopenharmony_ci int pnum, i; 352e1051a39Sopenharmony_ci#endif 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci /* Do not try to duplicate foreign RSA keys */ 355e1051a39Sopenharmony_ci if (ossl_rsa_is_foreign(rsa)) 356e1051a39Sopenharmony_ci return NULL; 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL) 359e1051a39Sopenharmony_ci return NULL; 360e1051a39Sopenharmony_ci 361e1051a39Sopenharmony_ci /* public key */ 362e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 363e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->n, rsa->n)) 364e1051a39Sopenharmony_ci goto err; 365e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->e, rsa->e)) 366e1051a39Sopenharmony_ci goto err; 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 370e1051a39Sopenharmony_ci 371e1051a39Sopenharmony_ci /* private key */ 372e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->d, rsa->d)) 373e1051a39Sopenharmony_ci goto err; 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ci /* factors and crt params */ 376e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->p, rsa->p)) 377e1051a39Sopenharmony_ci goto err; 378e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->q, rsa->q)) 379e1051a39Sopenharmony_ci goto err; 380e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1)) 381e1051a39Sopenharmony_ci goto err; 382e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1)) 383e1051a39Sopenharmony_ci goto err; 384e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp)) 385e1051a39Sopenharmony_ci goto err; 386e1051a39Sopenharmony_ci } 387e1051a39Sopenharmony_ci 388e1051a39Sopenharmony_ci dupkey->version = rsa->version; 389e1051a39Sopenharmony_ci dupkey->flags = rsa->flags; 390e1051a39Sopenharmony_ci /* we always copy the PSS parameters regardless of selection */ 391e1051a39Sopenharmony_ci dupkey->pss_params = rsa->pss_params; 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 394e1051a39Sopenharmony_ci /* multiprime */ 395e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 396e1051a39Sopenharmony_ci && (pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) > 0) { 397e1051a39Sopenharmony_ci dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); 398e1051a39Sopenharmony_ci if (dupkey->prime_infos == NULL) 399e1051a39Sopenharmony_ci goto err; 400e1051a39Sopenharmony_ci for (i = 0; i < pnum; i++) { 401e1051a39Sopenharmony_ci const RSA_PRIME_INFO *pinfo = NULL; 402e1051a39Sopenharmony_ci RSA_PRIME_INFO *duppinfo = NULL; 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) { 405e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 406e1051a39Sopenharmony_ci goto err; 407e1051a39Sopenharmony_ci } 408e1051a39Sopenharmony_ci /* push first so cleanup in error case works */ 409e1051a39Sopenharmony_ci (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo); 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); 412e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r)) 413e1051a39Sopenharmony_ci goto err; 414e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d)) 415e1051a39Sopenharmony_ci goto err; 416e1051a39Sopenharmony_ci if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t)) 417e1051a39Sopenharmony_ci goto err; 418e1051a39Sopenharmony_ci } 419e1051a39Sopenharmony_ci if (!ossl_rsa_multip_calc_product(dupkey)) 420e1051a39Sopenharmony_ci goto err; 421e1051a39Sopenharmony_ci } 422e1051a39Sopenharmony_ci 423e1051a39Sopenharmony_ci if (rsa->pss != NULL) { 424e1051a39Sopenharmony_ci dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss); 425e1051a39Sopenharmony_ci if (rsa->pss->maskGenAlgorithm != NULL 426e1051a39Sopenharmony_ci && dupkey->pss->maskGenAlgorithm == NULL) { 427e1051a39Sopenharmony_ci dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm); 428e1051a39Sopenharmony_ci if (dupkey->pss->maskHash == NULL) 429e1051a39Sopenharmony_ci goto err; 430e1051a39Sopenharmony_ci } 431e1051a39Sopenharmony_ci } 432e1051a39Sopenharmony_ci if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA, 433e1051a39Sopenharmony_ci &dupkey->ex_data, &rsa->ex_data)) 434e1051a39Sopenharmony_ci goto err; 435e1051a39Sopenharmony_ci#endif 436e1051a39Sopenharmony_ci 437e1051a39Sopenharmony_ci return dupkey; 438e1051a39Sopenharmony_ci 439e1051a39Sopenharmony_ci err: 440e1051a39Sopenharmony_ci RSA_free(dupkey); 441e1051a39Sopenharmony_ci return NULL; 442e1051a39Sopenharmony_ci} 443e1051a39Sopenharmony_ci 444e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 445e1051a39Sopenharmony_ciRSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg) 446e1051a39Sopenharmony_ci{ 447e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss; 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ci pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), 450e1051a39Sopenharmony_ci alg->parameter); 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ci if (pss == NULL) 453e1051a39Sopenharmony_ci return NULL; 454e1051a39Sopenharmony_ci 455e1051a39Sopenharmony_ci if (pss->maskGenAlgorithm != NULL) { 456e1051a39Sopenharmony_ci pss->maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); 457e1051a39Sopenharmony_ci if (pss->maskHash == NULL) { 458e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 459e1051a39Sopenharmony_ci return NULL; 460e1051a39Sopenharmony_ci } 461e1051a39Sopenharmony_ci } 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci return pss; 464e1051a39Sopenharmony_ci} 465e1051a39Sopenharmony_ci 466e1051a39Sopenharmony_cistatic int ossl_rsa_sync_to_pss_params_30(RSA *rsa) 467e1051a39Sopenharmony_ci{ 468e1051a39Sopenharmony_ci const RSA_PSS_PARAMS *legacy_pss = NULL; 469e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 *pss = NULL; 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci if (rsa != NULL 472e1051a39Sopenharmony_ci && (legacy_pss = RSA_get0_pss_params(rsa)) != NULL 473e1051a39Sopenharmony_ci && (pss = ossl_rsa_get0_pss_params_30(rsa)) != NULL) { 474e1051a39Sopenharmony_ci const EVP_MD *md = NULL, *mgf1md = NULL; 475e1051a39Sopenharmony_ci int md_nid, mgf1md_nid, saltlen, trailerField; 476e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 pss_params; 477e1051a39Sopenharmony_ci 478e1051a39Sopenharmony_ci /* 479e1051a39Sopenharmony_ci * We don't care about the validity of the fields here, we just 480e1051a39Sopenharmony_ci * want to synchronise values. Verifying here makes it impossible 481e1051a39Sopenharmony_ci * to even read a key with invalid values, making it hard to test 482e1051a39Sopenharmony_ci * a bad situation. 483e1051a39Sopenharmony_ci * 484e1051a39Sopenharmony_ci * Other routines use ossl_rsa_pss_get_param(), so the values will 485e1051a39Sopenharmony_ci * be checked, eventually. 486e1051a39Sopenharmony_ci */ 487e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param_unverified(legacy_pss, &md, &mgf1md, 488e1051a39Sopenharmony_ci &saltlen, &trailerField)) 489e1051a39Sopenharmony_ci return 0; 490e1051a39Sopenharmony_ci md_nid = EVP_MD_get_type(md); 491e1051a39Sopenharmony_ci mgf1md_nid = EVP_MD_get_type(mgf1md); 492e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) 493e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) 494e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, 495e1051a39Sopenharmony_ci mgf1md_nid) 496e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) 497e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params, 498e1051a39Sopenharmony_ci trailerField)) 499e1051a39Sopenharmony_ci return 0; 500e1051a39Sopenharmony_ci *pss = pss_params; 501e1051a39Sopenharmony_ci } 502e1051a39Sopenharmony_ci return 1; 503e1051a39Sopenharmony_ci} 504e1051a39Sopenharmony_ci 505e1051a39Sopenharmony_ciint ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, 506e1051a39Sopenharmony_ci const EVP_MD **pmd, const EVP_MD **pmgf1md, 507e1051a39Sopenharmony_ci int *psaltlen, int *ptrailerField) 508e1051a39Sopenharmony_ci{ 509e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 pss_params; 510e1051a39Sopenharmony_ci 511e1051a39Sopenharmony_ci /* Get the defaults from the ONE place */ 512e1051a39Sopenharmony_ci (void)ossl_rsa_pss_params_30_set_defaults(&pss_params); 513e1051a39Sopenharmony_ci 514e1051a39Sopenharmony_ci if (pss == NULL) 515e1051a39Sopenharmony_ci return 0; 516e1051a39Sopenharmony_ci *pmd = ossl_x509_algor_get_md(pss->hashAlgorithm); 517e1051a39Sopenharmony_ci if (*pmd == NULL) 518e1051a39Sopenharmony_ci return 0; 519e1051a39Sopenharmony_ci *pmgf1md = ossl_x509_algor_get_md(pss->maskHash); 520e1051a39Sopenharmony_ci if (*pmgf1md == NULL) 521e1051a39Sopenharmony_ci return 0; 522e1051a39Sopenharmony_ci if (pss->saltLength) 523e1051a39Sopenharmony_ci *psaltlen = ASN1_INTEGER_get(pss->saltLength); 524e1051a39Sopenharmony_ci else 525e1051a39Sopenharmony_ci *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params); 526e1051a39Sopenharmony_ci if (pss->trailerField) 527e1051a39Sopenharmony_ci *ptrailerField = ASN1_INTEGER_get(pss->trailerField); 528e1051a39Sopenharmony_ci else 529e1051a39Sopenharmony_ci *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; 530e1051a39Sopenharmony_ci 531e1051a39Sopenharmony_ci return 1; 532e1051a39Sopenharmony_ci} 533e1051a39Sopenharmony_ci 534e1051a39Sopenharmony_ciint ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) 535e1051a39Sopenharmony_ci{ 536e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss; 537e1051a39Sopenharmony_ci const ASN1_OBJECT *algoid; 538e1051a39Sopenharmony_ci const void *algp; 539e1051a39Sopenharmony_ci int algptype; 540e1051a39Sopenharmony_ci 541e1051a39Sopenharmony_ci X509_ALGOR_get0(&algoid, &algptype, &algp, alg); 542e1051a39Sopenharmony_ci if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) 543e1051a39Sopenharmony_ci return 1; 544e1051a39Sopenharmony_ci if (algptype == V_ASN1_UNDEF) 545e1051a39Sopenharmony_ci return 1; 546e1051a39Sopenharmony_ci if (algptype != V_ASN1_SEQUENCE) { 547e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); 548e1051a39Sopenharmony_ci return 0; 549e1051a39Sopenharmony_ci } 550e1051a39Sopenharmony_ci if ((pss = ossl_rsa_pss_decode(alg)) == NULL 551e1051a39Sopenharmony_ci || !ossl_rsa_set0_pss_params(rsa, pss)) { 552e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 553e1051a39Sopenharmony_ci return 0; 554e1051a39Sopenharmony_ci } 555e1051a39Sopenharmony_ci if (!ossl_rsa_sync_to_pss_params_30(rsa)) 556e1051a39Sopenharmony_ci return 0; 557e1051a39Sopenharmony_ci return 1; 558e1051a39Sopenharmony_ci} 559e1051a39Sopenharmony_ci 560e1051a39Sopenharmony_ciRSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, 561e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 562e1051a39Sopenharmony_ci{ 563e1051a39Sopenharmony_ci const unsigned char *p; 564e1051a39Sopenharmony_ci RSA *rsa; 565e1051a39Sopenharmony_ci int pklen; 566e1051a39Sopenharmony_ci const X509_ALGOR *alg; 567e1051a39Sopenharmony_ci 568e1051a39Sopenharmony_ci if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8inf)) 569e1051a39Sopenharmony_ci return 0; 570e1051a39Sopenharmony_ci rsa = d2i_RSAPrivateKey(NULL, &p, pklen); 571e1051a39Sopenharmony_ci if (rsa == NULL) { 572e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB); 573e1051a39Sopenharmony_ci return NULL; 574e1051a39Sopenharmony_ci } 575e1051a39Sopenharmony_ci if (!ossl_rsa_param_decode(rsa, alg)) { 576e1051a39Sopenharmony_ci RSA_free(rsa); 577e1051a39Sopenharmony_ci return NULL; 578e1051a39Sopenharmony_ci } 579e1051a39Sopenharmony_ci 580e1051a39Sopenharmony_ci RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); 581e1051a39Sopenharmony_ci switch (OBJ_obj2nid(alg->algorithm)) { 582e1051a39Sopenharmony_ci case EVP_PKEY_RSA: 583e1051a39Sopenharmony_ci RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); 584e1051a39Sopenharmony_ci break; 585e1051a39Sopenharmony_ci case EVP_PKEY_RSA_PSS: 586e1051a39Sopenharmony_ci RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); 587e1051a39Sopenharmony_ci break; 588e1051a39Sopenharmony_ci default: 589e1051a39Sopenharmony_ci /* Leave the type bits zero */ 590e1051a39Sopenharmony_ci break; 591e1051a39Sopenharmony_ci } 592e1051a39Sopenharmony_ci 593e1051a39Sopenharmony_ci return rsa; 594e1051a39Sopenharmony_ci} 595e1051a39Sopenharmony_ci#endif 596