1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-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 <openssl/crypto.h> 17e1051a39Sopenharmony_ci#include <openssl/core_names.h> 18e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 19e1051a39Sopenharmony_ci# include <openssl/engine.h> 20e1051a39Sopenharmony_ci#endif 21e1051a39Sopenharmony_ci#include <openssl/evp.h> 22e1051a39Sopenharmony_ci#include <openssl/param_build.h> 23e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 24e1051a39Sopenharmony_ci#include "internal/refcount.h" 25e1051a39Sopenharmony_ci#include "crypto/bn.h" 26e1051a39Sopenharmony_ci#include "crypto/evp.h" 27e1051a39Sopenharmony_ci#include "crypto/rsa.h" 28e1051a39Sopenharmony_ci#include "crypto/security_bits.h" 29e1051a39Sopenharmony_ci#include "rsa_local.h" 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_cistatic RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 34e1051a39Sopenharmony_ciRSA *RSA_new(void) 35e1051a39Sopenharmony_ci{ 36e1051a39Sopenharmony_ci return rsa_new_intern(NULL, NULL); 37e1051a39Sopenharmony_ci} 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ciconst RSA_METHOD *RSA_get_method(const RSA *rsa) 40e1051a39Sopenharmony_ci{ 41e1051a39Sopenharmony_ci return rsa->meth; 42e1051a39Sopenharmony_ci} 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ciint RSA_set_method(RSA *rsa, const RSA_METHOD *meth) 45e1051a39Sopenharmony_ci{ 46e1051a39Sopenharmony_ci /* 47e1051a39Sopenharmony_ci * NB: The caller is specifically setting a method, so it's not up to us 48e1051a39Sopenharmony_ci * to deal with which ENGINE it comes from. 49e1051a39Sopenharmony_ci */ 50e1051a39Sopenharmony_ci const RSA_METHOD *mtmp; 51e1051a39Sopenharmony_ci mtmp = rsa->meth; 52e1051a39Sopenharmony_ci if (mtmp->finish) 53e1051a39Sopenharmony_ci mtmp->finish(rsa); 54e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 55e1051a39Sopenharmony_ci ENGINE_finish(rsa->engine); 56e1051a39Sopenharmony_ci rsa->engine = NULL; 57e1051a39Sopenharmony_ci#endif 58e1051a39Sopenharmony_ci rsa->meth = meth; 59e1051a39Sopenharmony_ci if (meth->init) 60e1051a39Sopenharmony_ci meth->init(rsa); 61e1051a39Sopenharmony_ci return 1; 62e1051a39Sopenharmony_ci} 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ciRSA *RSA_new_method(ENGINE *engine) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci return rsa_new_intern(engine, NULL); 67e1051a39Sopenharmony_ci} 68e1051a39Sopenharmony_ci#endif 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ciRSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx) 71e1051a39Sopenharmony_ci{ 72e1051a39Sopenharmony_ci return rsa_new_intern(NULL, libctx); 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_cistatic RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci RSA *ret = OPENSSL_zalloc(sizeof(*ret)); 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci if (ret == NULL) { 80e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 81e1051a39Sopenharmony_ci return NULL; 82e1051a39Sopenharmony_ci } 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ci ret->references = 1; 85e1051a39Sopenharmony_ci ret->lock = CRYPTO_THREAD_lock_new(); 86e1051a39Sopenharmony_ci if (ret->lock == NULL) { 87e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 88e1051a39Sopenharmony_ci OPENSSL_free(ret); 89e1051a39Sopenharmony_ci return NULL; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci ret->libctx = libctx; 93e1051a39Sopenharmony_ci ret->meth = RSA_get_default_method(); 94e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 95e1051a39Sopenharmony_ci ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; 96e1051a39Sopenharmony_ci if (engine) { 97e1051a39Sopenharmony_ci if (!ENGINE_init(engine)) { 98e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_ENGINE_LIB); 99e1051a39Sopenharmony_ci goto err; 100e1051a39Sopenharmony_ci } 101e1051a39Sopenharmony_ci ret->engine = engine; 102e1051a39Sopenharmony_ci } else { 103e1051a39Sopenharmony_ci ret->engine = ENGINE_get_default_RSA(); 104e1051a39Sopenharmony_ci } 105e1051a39Sopenharmony_ci if (ret->engine) { 106e1051a39Sopenharmony_ci ret->meth = ENGINE_get_RSA(ret->engine); 107e1051a39Sopenharmony_ci if (ret->meth == NULL) { 108e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_ENGINE_LIB); 109e1051a39Sopenharmony_ci goto err; 110e1051a39Sopenharmony_ci } 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci#endif 113e1051a39Sopenharmony_ci 114e1051a39Sopenharmony_ci ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; 115e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 116e1051a39Sopenharmony_ci if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { 117e1051a39Sopenharmony_ci goto err; 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci#endif 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 122e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_INIT_FAIL); 123e1051a39Sopenharmony_ci goto err; 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci return ret; 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ci err: 129e1051a39Sopenharmony_ci RSA_free(ret); 130e1051a39Sopenharmony_ci return NULL; 131e1051a39Sopenharmony_ci} 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_civoid RSA_free(RSA *r) 134e1051a39Sopenharmony_ci{ 135e1051a39Sopenharmony_ci int i; 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_ci if (r == NULL) 138e1051a39Sopenharmony_ci return; 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&r->references, &i, r->lock); 141e1051a39Sopenharmony_ci REF_PRINT_COUNT("RSA", r); 142e1051a39Sopenharmony_ci if (i > 0) 143e1051a39Sopenharmony_ci return; 144e1051a39Sopenharmony_ci REF_ASSERT_ISNT(i < 0); 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci if (r->meth != NULL && r->meth->finish != NULL) 147e1051a39Sopenharmony_ci r->meth->finish(r); 148e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 149e1051a39Sopenharmony_ci ENGINE_finish(r->engine); 150e1051a39Sopenharmony_ci#endif 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 153e1051a39Sopenharmony_ci CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); 154e1051a39Sopenharmony_ci#endif 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(r->lock); 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci BN_free(r->n); 159e1051a39Sopenharmony_ci BN_free(r->e); 160e1051a39Sopenharmony_ci BN_clear_free(r->d); 161e1051a39Sopenharmony_ci BN_clear_free(r->p); 162e1051a39Sopenharmony_ci BN_clear_free(r->q); 163e1051a39Sopenharmony_ci BN_clear_free(r->dmp1); 164e1051a39Sopenharmony_ci BN_clear_free(r->dmq1); 165e1051a39Sopenharmony_ci BN_clear_free(r->iqmp); 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) 168e1051a39Sopenharmony_ci ossl_rsa_acvp_test_free(r->acvp_test); 169e1051a39Sopenharmony_ci#endif 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 172e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(r->pss); 173e1051a39Sopenharmony_ci sk_RSA_PRIME_INFO_pop_free(r->prime_infos, ossl_rsa_multip_info_free); 174e1051a39Sopenharmony_ci#endif 175e1051a39Sopenharmony_ci BN_BLINDING_free(r->blinding); 176e1051a39Sopenharmony_ci BN_BLINDING_free(r->mt_blinding); 177e1051a39Sopenharmony_ci OPENSSL_free(r); 178e1051a39Sopenharmony_ci} 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ciint RSA_up_ref(RSA *r) 181e1051a39Sopenharmony_ci{ 182e1051a39Sopenharmony_ci int i; 183e1051a39Sopenharmony_ci 184e1051a39Sopenharmony_ci if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) 185e1051a39Sopenharmony_ci return 0; 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_ci REF_PRINT_COUNT("RSA", r); 188e1051a39Sopenharmony_ci REF_ASSERT_ISNT(i < 2); 189e1051a39Sopenharmony_ci return i > 1 ? 1 : 0; 190e1051a39Sopenharmony_ci} 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ciOSSL_LIB_CTX *ossl_rsa_get0_libctx(RSA *r) 193e1051a39Sopenharmony_ci{ 194e1051a39Sopenharmony_ci return r->libctx; 195e1051a39Sopenharmony_ci} 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_civoid ossl_rsa_set0_libctx(RSA *r, OSSL_LIB_CTX *libctx) 198e1051a39Sopenharmony_ci{ 199e1051a39Sopenharmony_ci r->libctx = libctx; 200e1051a39Sopenharmony_ci} 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 203e1051a39Sopenharmony_ciint RSA_set_ex_data(RSA *r, int idx, void *arg) 204e1051a39Sopenharmony_ci{ 205e1051a39Sopenharmony_ci return CRYPTO_set_ex_data(&r->ex_data, idx, arg); 206e1051a39Sopenharmony_ci} 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_civoid *RSA_get_ex_data(const RSA *r, int idx) 209e1051a39Sopenharmony_ci{ 210e1051a39Sopenharmony_ci return CRYPTO_get_ex_data(&r->ex_data, idx); 211e1051a39Sopenharmony_ci} 212e1051a39Sopenharmony_ci#endif 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci/* 215e1051a39Sopenharmony_ci * Define a scaling constant for our fixed point arithmetic. 216e1051a39Sopenharmony_ci * This value must be a power of two because the base two logarithm code 217e1051a39Sopenharmony_ci * makes this assumption. The exponent must also be a multiple of three so 218e1051a39Sopenharmony_ci * that the scale factor has an exact cube root. Finally, the scale factor 219e1051a39Sopenharmony_ci * should not be so large that a multiplication of two scaled numbers 220e1051a39Sopenharmony_ci * overflows a 64 bit unsigned integer. 221e1051a39Sopenharmony_ci */ 222e1051a39Sopenharmony_cistatic const unsigned int scale = 1 << 18; 223e1051a39Sopenharmony_cistatic const unsigned int cbrt_scale = 1 << (2 * 18 / 3); 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci/* Define some constants, none exceed 32 bits */ 226e1051a39Sopenharmony_cistatic const unsigned int log_2 = 0x02c5c8; /* scale * log(2) */ 227e1051a39Sopenharmony_cistatic const unsigned int log_e = 0x05c551; /* scale * log2(M_E) */ 228e1051a39Sopenharmony_cistatic const unsigned int c1_923 = 0x07b126; /* scale * 1.923 */ 229e1051a39Sopenharmony_cistatic const unsigned int c4_690 = 0x12c28f; /* scale * 4.690 */ 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci/* 232e1051a39Sopenharmony_ci * Multiply two scaled integers together and rescale the result. 233e1051a39Sopenharmony_ci */ 234e1051a39Sopenharmony_cistatic ossl_inline uint64_t mul2(uint64_t a, uint64_t b) 235e1051a39Sopenharmony_ci{ 236e1051a39Sopenharmony_ci return a * b / scale; 237e1051a39Sopenharmony_ci} 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ci/* 240e1051a39Sopenharmony_ci * Calculate the cube root of a 64 bit scaled integer. 241e1051a39Sopenharmony_ci * Although the cube root of a 64 bit number does fit into a 32 bit unsigned 242e1051a39Sopenharmony_ci * integer, this is not guaranteed after scaling, so this function has a 243e1051a39Sopenharmony_ci * 64 bit return. This uses the shifting nth root algorithm with some 244e1051a39Sopenharmony_ci * algebraic simplifications. 245e1051a39Sopenharmony_ci */ 246e1051a39Sopenharmony_cistatic uint64_t icbrt64(uint64_t x) 247e1051a39Sopenharmony_ci{ 248e1051a39Sopenharmony_ci uint64_t r = 0; 249e1051a39Sopenharmony_ci uint64_t b; 250e1051a39Sopenharmony_ci int s; 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_ci for (s = 63; s >= 0; s -= 3) { 253e1051a39Sopenharmony_ci r <<= 1; 254e1051a39Sopenharmony_ci b = 3 * r * (r + 1) + 1; 255e1051a39Sopenharmony_ci if ((x >> s) >= b) { 256e1051a39Sopenharmony_ci x -= b << s; 257e1051a39Sopenharmony_ci r++; 258e1051a39Sopenharmony_ci } 259e1051a39Sopenharmony_ci } 260e1051a39Sopenharmony_ci return r * cbrt_scale; 261e1051a39Sopenharmony_ci} 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci/* 264e1051a39Sopenharmony_ci * Calculate the natural logarithm of a 64 bit scaled integer. 265e1051a39Sopenharmony_ci * This is done by calculating a base two logarithm and scaling. 266e1051a39Sopenharmony_ci * The maximum logarithm (base 2) is 64 and this reduces base e, so 267e1051a39Sopenharmony_ci * a 32 bit result should not overflow. The argument passed must be 268e1051a39Sopenharmony_ci * greater than unity so we don't need to handle negative results. 269e1051a39Sopenharmony_ci */ 270e1051a39Sopenharmony_cistatic uint32_t ilog_e(uint64_t v) 271e1051a39Sopenharmony_ci{ 272e1051a39Sopenharmony_ci uint32_t i, r = 0; 273e1051a39Sopenharmony_ci 274e1051a39Sopenharmony_ci /* 275e1051a39Sopenharmony_ci * Scale down the value into the range 1 .. 2. 276e1051a39Sopenharmony_ci * 277e1051a39Sopenharmony_ci * If fractional numbers need to be processed, another loop needs 278e1051a39Sopenharmony_ci * to go here that checks v < scale and if so multiplies it by 2 and 279e1051a39Sopenharmony_ci * reduces r by scale. This also means making r signed. 280e1051a39Sopenharmony_ci */ 281e1051a39Sopenharmony_ci while (v >= 2 * scale) { 282e1051a39Sopenharmony_ci v >>= 1; 283e1051a39Sopenharmony_ci r += scale; 284e1051a39Sopenharmony_ci } 285e1051a39Sopenharmony_ci for (i = scale / 2; i != 0; i /= 2) { 286e1051a39Sopenharmony_ci v = mul2(v, v); 287e1051a39Sopenharmony_ci if (v >= 2 * scale) { 288e1051a39Sopenharmony_ci v >>= 1; 289e1051a39Sopenharmony_ci r += i; 290e1051a39Sopenharmony_ci } 291e1051a39Sopenharmony_ci } 292e1051a39Sopenharmony_ci r = (r * (uint64_t)scale) / log_e; 293e1051a39Sopenharmony_ci return r; 294e1051a39Sopenharmony_ci} 295e1051a39Sopenharmony_ci 296e1051a39Sopenharmony_ci/* 297e1051a39Sopenharmony_ci * NIST SP 800-56B rev 2 Appendix D: Maximum Security Strength Estimates for IFC 298e1051a39Sopenharmony_ci * Modulus Lengths. 299e1051a39Sopenharmony_ci * 300e1051a39Sopenharmony_ci * Note that this formula is also referred to in SP800-56A rev3 Appendix D: 301e1051a39Sopenharmony_ci * for FFC safe prime groups for modp and ffdhe. 302e1051a39Sopenharmony_ci * After Table 25 and Table 26 it refers to 303e1051a39Sopenharmony_ci * "The maximum security strength estimates were calculated using the formula in 304e1051a39Sopenharmony_ci * Section 7.5 of the FIPS 140 IG and rounded to the nearest multiple of eight 305e1051a39Sopenharmony_ci * bits". 306e1051a39Sopenharmony_ci * 307e1051a39Sopenharmony_ci * The formula is: 308e1051a39Sopenharmony_ci * 309e1051a39Sopenharmony_ci * E = \frac{1.923 \sqrt[3]{nBits \cdot log_e(2)} 310e1051a39Sopenharmony_ci * \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)} 311e1051a39Sopenharmony_ci * The two cube roots are merged together here. 312e1051a39Sopenharmony_ci */ 313e1051a39Sopenharmony_ciuint16_t ossl_ifc_ffc_compute_security_bits(int n) 314e1051a39Sopenharmony_ci{ 315e1051a39Sopenharmony_ci uint64_t x; 316e1051a39Sopenharmony_ci uint32_t lx; 317e1051a39Sopenharmony_ci uint16_t y, cap; 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci /* 320e1051a39Sopenharmony_ci * Look for common values as listed in standards. 321e1051a39Sopenharmony_ci * These values are not exactly equal to the results from the formulae in 322e1051a39Sopenharmony_ci * the standards but are defined to be canonical. 323e1051a39Sopenharmony_ci */ 324e1051a39Sopenharmony_ci switch (n) { 325e1051a39Sopenharmony_ci case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ 326e1051a39Sopenharmony_ci return 112; 327e1051a39Sopenharmony_ci case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ 328e1051a39Sopenharmony_ci return 128; 329e1051a39Sopenharmony_ci case 4096: /* SP 800-56B rev 2 Appendix D */ 330e1051a39Sopenharmony_ci return 152; 331e1051a39Sopenharmony_ci case 6144: /* SP 800-56B rev 2 Appendix D */ 332e1051a39Sopenharmony_ci return 176; 333e1051a39Sopenharmony_ci case 7680: /* FIPS 140-2 IG 7.5 */ 334e1051a39Sopenharmony_ci return 192; 335e1051a39Sopenharmony_ci case 8192: /* SP 800-56B rev 2 Appendix D */ 336e1051a39Sopenharmony_ci return 200; 337e1051a39Sopenharmony_ci case 15360: /* FIPS 140-2 IG 7.5 */ 338e1051a39Sopenharmony_ci return 256; 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci /* 342e1051a39Sopenharmony_ci * The first incorrect result (i.e. not accurate or off by one low) occurs 343e1051a39Sopenharmony_ci * for n = 699668. The true value here is 1200. Instead of using this n 344e1051a39Sopenharmony_ci * as the check threshold, the smallest n such that the correct result is 345e1051a39Sopenharmony_ci * 1200 is used instead. 346e1051a39Sopenharmony_ci */ 347e1051a39Sopenharmony_ci if (n >= 687737) 348e1051a39Sopenharmony_ci return 1200; 349e1051a39Sopenharmony_ci if (n < 8) 350e1051a39Sopenharmony_ci return 0; 351e1051a39Sopenharmony_ci 352e1051a39Sopenharmony_ci /* 353e1051a39Sopenharmony_ci * To ensure that the output is non-decreasing with respect to n, 354e1051a39Sopenharmony_ci * a cap needs to be applied to the two values where the function over 355e1051a39Sopenharmony_ci * estimates the strength (according to the above fast path). 356e1051a39Sopenharmony_ci */ 357e1051a39Sopenharmony_ci if (n <= 7680) 358e1051a39Sopenharmony_ci cap = 192; 359e1051a39Sopenharmony_ci else if (n <= 15360) 360e1051a39Sopenharmony_ci cap = 256; 361e1051a39Sopenharmony_ci else 362e1051a39Sopenharmony_ci cap = 1200; 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci x = n * (uint64_t)log_2; 365e1051a39Sopenharmony_ci lx = ilog_e(x); 366e1051a39Sopenharmony_ci y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690) 367e1051a39Sopenharmony_ci / log_2); 368e1051a39Sopenharmony_ci y = (y + 4) & ~7; 369e1051a39Sopenharmony_ci if (y > cap) 370e1051a39Sopenharmony_ci y = cap; 371e1051a39Sopenharmony_ci return y; 372e1051a39Sopenharmony_ci} 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ci 376e1051a39Sopenharmony_ciint RSA_security_bits(const RSA *rsa) 377e1051a39Sopenharmony_ci{ 378e1051a39Sopenharmony_ci int bits = BN_num_bits(rsa->n); 379e1051a39Sopenharmony_ci 380e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 381e1051a39Sopenharmony_ci if (rsa->version == RSA_ASN1_VERSION_MULTI) { 382e1051a39Sopenharmony_ci /* This ought to mean that we have private key at hand. */ 383e1051a39Sopenharmony_ci int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos); 384e1051a39Sopenharmony_ci 385e1051a39Sopenharmony_ci if (ex_primes <= 0 || (ex_primes + 2) > ossl_rsa_multip_cap(bits)) 386e1051a39Sopenharmony_ci return 0; 387e1051a39Sopenharmony_ci } 388e1051a39Sopenharmony_ci#endif 389e1051a39Sopenharmony_ci return ossl_ifc_ffc_compute_security_bits(bits); 390e1051a39Sopenharmony_ci} 391e1051a39Sopenharmony_ci 392e1051a39Sopenharmony_ciint RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) 393e1051a39Sopenharmony_ci{ 394e1051a39Sopenharmony_ci /* If the fields n and e in r are NULL, the corresponding input 395e1051a39Sopenharmony_ci * parameters MUST be non-NULL for n and e. d may be 396e1051a39Sopenharmony_ci * left NULL (in case only the public key is used). 397e1051a39Sopenharmony_ci */ 398e1051a39Sopenharmony_ci if ((r->n == NULL && n == NULL) 399e1051a39Sopenharmony_ci || (r->e == NULL && e == NULL)) 400e1051a39Sopenharmony_ci return 0; 401e1051a39Sopenharmony_ci 402e1051a39Sopenharmony_ci if (n != NULL) { 403e1051a39Sopenharmony_ci BN_free(r->n); 404e1051a39Sopenharmony_ci r->n = n; 405e1051a39Sopenharmony_ci } 406e1051a39Sopenharmony_ci if (e != NULL) { 407e1051a39Sopenharmony_ci BN_free(r->e); 408e1051a39Sopenharmony_ci r->e = e; 409e1051a39Sopenharmony_ci } 410e1051a39Sopenharmony_ci if (d != NULL) { 411e1051a39Sopenharmony_ci BN_clear_free(r->d); 412e1051a39Sopenharmony_ci r->d = d; 413e1051a39Sopenharmony_ci BN_set_flags(r->d, BN_FLG_CONSTTIME); 414e1051a39Sopenharmony_ci } 415e1051a39Sopenharmony_ci r->dirty_cnt++; 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci return 1; 418e1051a39Sopenharmony_ci} 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ciint RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) 421e1051a39Sopenharmony_ci{ 422e1051a39Sopenharmony_ci /* If the fields p and q in r are NULL, the corresponding input 423e1051a39Sopenharmony_ci * parameters MUST be non-NULL. 424e1051a39Sopenharmony_ci */ 425e1051a39Sopenharmony_ci if ((r->p == NULL && p == NULL) 426e1051a39Sopenharmony_ci || (r->q == NULL && q == NULL)) 427e1051a39Sopenharmony_ci return 0; 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_ci if (p != NULL) { 430e1051a39Sopenharmony_ci BN_clear_free(r->p); 431e1051a39Sopenharmony_ci r->p = p; 432e1051a39Sopenharmony_ci BN_set_flags(r->p, BN_FLG_CONSTTIME); 433e1051a39Sopenharmony_ci } 434e1051a39Sopenharmony_ci if (q != NULL) { 435e1051a39Sopenharmony_ci BN_clear_free(r->q); 436e1051a39Sopenharmony_ci r->q = q; 437e1051a39Sopenharmony_ci BN_set_flags(r->q, BN_FLG_CONSTTIME); 438e1051a39Sopenharmony_ci } 439e1051a39Sopenharmony_ci r->dirty_cnt++; 440e1051a39Sopenharmony_ci 441e1051a39Sopenharmony_ci return 1; 442e1051a39Sopenharmony_ci} 443e1051a39Sopenharmony_ci 444e1051a39Sopenharmony_ciint RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) 445e1051a39Sopenharmony_ci{ 446e1051a39Sopenharmony_ci /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input 447e1051a39Sopenharmony_ci * parameters MUST be non-NULL. 448e1051a39Sopenharmony_ci */ 449e1051a39Sopenharmony_ci if ((r->dmp1 == NULL && dmp1 == NULL) 450e1051a39Sopenharmony_ci || (r->dmq1 == NULL && dmq1 == NULL) 451e1051a39Sopenharmony_ci || (r->iqmp == NULL && iqmp == NULL)) 452e1051a39Sopenharmony_ci return 0; 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci if (dmp1 != NULL) { 455e1051a39Sopenharmony_ci BN_clear_free(r->dmp1); 456e1051a39Sopenharmony_ci r->dmp1 = dmp1; 457e1051a39Sopenharmony_ci BN_set_flags(r->dmp1, BN_FLG_CONSTTIME); 458e1051a39Sopenharmony_ci } 459e1051a39Sopenharmony_ci if (dmq1 != NULL) { 460e1051a39Sopenharmony_ci BN_clear_free(r->dmq1); 461e1051a39Sopenharmony_ci r->dmq1 = dmq1; 462e1051a39Sopenharmony_ci BN_set_flags(r->dmq1, BN_FLG_CONSTTIME); 463e1051a39Sopenharmony_ci } 464e1051a39Sopenharmony_ci if (iqmp != NULL) { 465e1051a39Sopenharmony_ci BN_clear_free(r->iqmp); 466e1051a39Sopenharmony_ci r->iqmp = iqmp; 467e1051a39Sopenharmony_ci BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); 468e1051a39Sopenharmony_ci } 469e1051a39Sopenharmony_ci r->dirty_cnt++; 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci return 1; 472e1051a39Sopenharmony_ci} 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 475e1051a39Sopenharmony_ci/* 476e1051a39Sopenharmony_ci * Is it better to export RSA_PRIME_INFO structure 477e1051a39Sopenharmony_ci * and related functions to let user pass a triplet? 478e1051a39Sopenharmony_ci */ 479e1051a39Sopenharmony_ciint RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], 480e1051a39Sopenharmony_ci BIGNUM *coeffs[], int pnum) 481e1051a39Sopenharmony_ci{ 482e1051a39Sopenharmony_ci STACK_OF(RSA_PRIME_INFO) *prime_infos, *old = NULL; 483e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo; 484e1051a39Sopenharmony_ci int i; 485e1051a39Sopenharmony_ci 486e1051a39Sopenharmony_ci if (primes == NULL || exps == NULL || coeffs == NULL || pnum == 0) 487e1051a39Sopenharmony_ci return 0; 488e1051a39Sopenharmony_ci 489e1051a39Sopenharmony_ci prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); 490e1051a39Sopenharmony_ci if (prime_infos == NULL) 491e1051a39Sopenharmony_ci return 0; 492e1051a39Sopenharmony_ci 493e1051a39Sopenharmony_ci if (r->prime_infos != NULL) 494e1051a39Sopenharmony_ci old = r->prime_infos; 495e1051a39Sopenharmony_ci 496e1051a39Sopenharmony_ci for (i = 0; i < pnum; i++) { 497e1051a39Sopenharmony_ci pinfo = ossl_rsa_multip_info_new(); 498e1051a39Sopenharmony_ci if (pinfo == NULL) 499e1051a39Sopenharmony_ci goto err; 500e1051a39Sopenharmony_ci if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) { 501e1051a39Sopenharmony_ci BN_clear_free(pinfo->r); 502e1051a39Sopenharmony_ci BN_clear_free(pinfo->d); 503e1051a39Sopenharmony_ci BN_clear_free(pinfo->t); 504e1051a39Sopenharmony_ci pinfo->r = primes[i]; 505e1051a39Sopenharmony_ci pinfo->d = exps[i]; 506e1051a39Sopenharmony_ci pinfo->t = coeffs[i]; 507e1051a39Sopenharmony_ci BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); 508e1051a39Sopenharmony_ci BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); 509e1051a39Sopenharmony_ci BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); 510e1051a39Sopenharmony_ci } else { 511e1051a39Sopenharmony_ci ossl_rsa_multip_info_free(pinfo); 512e1051a39Sopenharmony_ci goto err; 513e1051a39Sopenharmony_ci } 514e1051a39Sopenharmony_ci (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); 515e1051a39Sopenharmony_ci } 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_ci r->prime_infos = prime_infos; 518e1051a39Sopenharmony_ci 519e1051a39Sopenharmony_ci if (!ossl_rsa_multip_calc_product(r)) { 520e1051a39Sopenharmony_ci r->prime_infos = old; 521e1051a39Sopenharmony_ci goto err; 522e1051a39Sopenharmony_ci } 523e1051a39Sopenharmony_ci 524e1051a39Sopenharmony_ci if (old != NULL) { 525e1051a39Sopenharmony_ci /* 526e1051a39Sopenharmony_ci * This is hard to deal with, since the old infos could 527e1051a39Sopenharmony_ci * also be set by this function and r, d, t should not 528e1051a39Sopenharmony_ci * be freed in that case. So currently, stay consistent 529e1051a39Sopenharmony_ci * with other *set0* functions: just free it... 530e1051a39Sopenharmony_ci */ 531e1051a39Sopenharmony_ci sk_RSA_PRIME_INFO_pop_free(old, ossl_rsa_multip_info_free); 532e1051a39Sopenharmony_ci } 533e1051a39Sopenharmony_ci 534e1051a39Sopenharmony_ci r->version = RSA_ASN1_VERSION_MULTI; 535e1051a39Sopenharmony_ci r->dirty_cnt++; 536e1051a39Sopenharmony_ci 537e1051a39Sopenharmony_ci return 1; 538e1051a39Sopenharmony_ci err: 539e1051a39Sopenharmony_ci /* r, d, t should not be freed */ 540e1051a39Sopenharmony_ci sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex); 541e1051a39Sopenharmony_ci return 0; 542e1051a39Sopenharmony_ci} 543e1051a39Sopenharmony_ci#endif 544e1051a39Sopenharmony_ci 545e1051a39Sopenharmony_civoid RSA_get0_key(const RSA *r, 546e1051a39Sopenharmony_ci const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) 547e1051a39Sopenharmony_ci{ 548e1051a39Sopenharmony_ci if (n != NULL) 549e1051a39Sopenharmony_ci *n = r->n; 550e1051a39Sopenharmony_ci if (e != NULL) 551e1051a39Sopenharmony_ci *e = r->e; 552e1051a39Sopenharmony_ci if (d != NULL) 553e1051a39Sopenharmony_ci *d = r->d; 554e1051a39Sopenharmony_ci} 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_civoid RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) 557e1051a39Sopenharmony_ci{ 558e1051a39Sopenharmony_ci if (p != NULL) 559e1051a39Sopenharmony_ci *p = r->p; 560e1051a39Sopenharmony_ci if (q != NULL) 561e1051a39Sopenharmony_ci *q = r->q; 562e1051a39Sopenharmony_ci} 563e1051a39Sopenharmony_ci 564e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 565e1051a39Sopenharmony_ciint RSA_get_multi_prime_extra_count(const RSA *r) 566e1051a39Sopenharmony_ci{ 567e1051a39Sopenharmony_ci int pnum; 568e1051a39Sopenharmony_ci 569e1051a39Sopenharmony_ci pnum = sk_RSA_PRIME_INFO_num(r->prime_infos); 570e1051a39Sopenharmony_ci if (pnum <= 0) 571e1051a39Sopenharmony_ci pnum = 0; 572e1051a39Sopenharmony_ci return pnum; 573e1051a39Sopenharmony_ci} 574e1051a39Sopenharmony_ci 575e1051a39Sopenharmony_ciint RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]) 576e1051a39Sopenharmony_ci{ 577e1051a39Sopenharmony_ci int pnum, i; 578e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo; 579e1051a39Sopenharmony_ci 580e1051a39Sopenharmony_ci if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) 581e1051a39Sopenharmony_ci return 0; 582e1051a39Sopenharmony_ci 583e1051a39Sopenharmony_ci /* 584e1051a39Sopenharmony_ci * return other primes 585e1051a39Sopenharmony_ci * it's caller's responsibility to allocate oth_primes[pnum] 586e1051a39Sopenharmony_ci */ 587e1051a39Sopenharmony_ci for (i = 0; i < pnum; i++) { 588e1051a39Sopenharmony_ci pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); 589e1051a39Sopenharmony_ci primes[i] = pinfo->r; 590e1051a39Sopenharmony_ci } 591e1051a39Sopenharmony_ci 592e1051a39Sopenharmony_ci return 1; 593e1051a39Sopenharmony_ci} 594e1051a39Sopenharmony_ci#endif 595e1051a39Sopenharmony_ci 596e1051a39Sopenharmony_civoid RSA_get0_crt_params(const RSA *r, 597e1051a39Sopenharmony_ci const BIGNUM **dmp1, const BIGNUM **dmq1, 598e1051a39Sopenharmony_ci const BIGNUM **iqmp) 599e1051a39Sopenharmony_ci{ 600e1051a39Sopenharmony_ci if (dmp1 != NULL) 601e1051a39Sopenharmony_ci *dmp1 = r->dmp1; 602e1051a39Sopenharmony_ci if (dmq1 != NULL) 603e1051a39Sopenharmony_ci *dmq1 = r->dmq1; 604e1051a39Sopenharmony_ci if (iqmp != NULL) 605e1051a39Sopenharmony_ci *iqmp = r->iqmp; 606e1051a39Sopenharmony_ci} 607e1051a39Sopenharmony_ci 608e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 609e1051a39Sopenharmony_ciint RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], 610e1051a39Sopenharmony_ci const BIGNUM *coeffs[]) 611e1051a39Sopenharmony_ci{ 612e1051a39Sopenharmony_ci int pnum; 613e1051a39Sopenharmony_ci 614e1051a39Sopenharmony_ci if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) 615e1051a39Sopenharmony_ci return 0; 616e1051a39Sopenharmony_ci 617e1051a39Sopenharmony_ci /* return other primes */ 618e1051a39Sopenharmony_ci if (exps != NULL || coeffs != NULL) { 619e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo; 620e1051a39Sopenharmony_ci int i; 621e1051a39Sopenharmony_ci 622e1051a39Sopenharmony_ci /* it's the user's job to guarantee the buffer length */ 623e1051a39Sopenharmony_ci for (i = 0; i < pnum; i++) { 624e1051a39Sopenharmony_ci pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); 625e1051a39Sopenharmony_ci if (exps != NULL) 626e1051a39Sopenharmony_ci exps[i] = pinfo->d; 627e1051a39Sopenharmony_ci if (coeffs != NULL) 628e1051a39Sopenharmony_ci coeffs[i] = pinfo->t; 629e1051a39Sopenharmony_ci } 630e1051a39Sopenharmony_ci } 631e1051a39Sopenharmony_ci 632e1051a39Sopenharmony_ci return 1; 633e1051a39Sopenharmony_ci} 634e1051a39Sopenharmony_ci#endif 635e1051a39Sopenharmony_ci 636e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_n(const RSA *r) 637e1051a39Sopenharmony_ci{ 638e1051a39Sopenharmony_ci return r->n; 639e1051a39Sopenharmony_ci} 640e1051a39Sopenharmony_ci 641e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_e(const RSA *r) 642e1051a39Sopenharmony_ci{ 643e1051a39Sopenharmony_ci return r->e; 644e1051a39Sopenharmony_ci} 645e1051a39Sopenharmony_ci 646e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_d(const RSA *r) 647e1051a39Sopenharmony_ci{ 648e1051a39Sopenharmony_ci return r->d; 649e1051a39Sopenharmony_ci} 650e1051a39Sopenharmony_ci 651e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_p(const RSA *r) 652e1051a39Sopenharmony_ci{ 653e1051a39Sopenharmony_ci return r->p; 654e1051a39Sopenharmony_ci} 655e1051a39Sopenharmony_ci 656e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_q(const RSA *r) 657e1051a39Sopenharmony_ci{ 658e1051a39Sopenharmony_ci return r->q; 659e1051a39Sopenharmony_ci} 660e1051a39Sopenharmony_ci 661e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_dmp1(const RSA *r) 662e1051a39Sopenharmony_ci{ 663e1051a39Sopenharmony_ci return r->dmp1; 664e1051a39Sopenharmony_ci} 665e1051a39Sopenharmony_ci 666e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_dmq1(const RSA *r) 667e1051a39Sopenharmony_ci{ 668e1051a39Sopenharmony_ci return r->dmq1; 669e1051a39Sopenharmony_ci} 670e1051a39Sopenharmony_ci 671e1051a39Sopenharmony_ciconst BIGNUM *RSA_get0_iqmp(const RSA *r) 672e1051a39Sopenharmony_ci{ 673e1051a39Sopenharmony_ci return r->iqmp; 674e1051a39Sopenharmony_ci} 675e1051a39Sopenharmony_ci 676e1051a39Sopenharmony_ciconst RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) 677e1051a39Sopenharmony_ci{ 678e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 679e1051a39Sopenharmony_ci return NULL; 680e1051a39Sopenharmony_ci#else 681e1051a39Sopenharmony_ci return r->pss; 682e1051a39Sopenharmony_ci#endif 683e1051a39Sopenharmony_ci} 684e1051a39Sopenharmony_ci 685e1051a39Sopenharmony_ci/* Internal */ 686e1051a39Sopenharmony_ciint ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss) 687e1051a39Sopenharmony_ci{ 688e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 689e1051a39Sopenharmony_ci return 0; 690e1051a39Sopenharmony_ci#else 691e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(r->pss); 692e1051a39Sopenharmony_ci r->pss = pss; 693e1051a39Sopenharmony_ci return 1; 694e1051a39Sopenharmony_ci#endif 695e1051a39Sopenharmony_ci} 696e1051a39Sopenharmony_ci 697e1051a39Sopenharmony_ci/* Internal */ 698e1051a39Sopenharmony_ciRSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r) 699e1051a39Sopenharmony_ci{ 700e1051a39Sopenharmony_ci return &r->pss_params; 701e1051a39Sopenharmony_ci} 702e1051a39Sopenharmony_ci 703e1051a39Sopenharmony_civoid RSA_clear_flags(RSA *r, int flags) 704e1051a39Sopenharmony_ci{ 705e1051a39Sopenharmony_ci r->flags &= ~flags; 706e1051a39Sopenharmony_ci} 707e1051a39Sopenharmony_ci 708e1051a39Sopenharmony_ciint RSA_test_flags(const RSA *r, int flags) 709e1051a39Sopenharmony_ci{ 710e1051a39Sopenharmony_ci return r->flags & flags; 711e1051a39Sopenharmony_ci} 712e1051a39Sopenharmony_ci 713e1051a39Sopenharmony_civoid RSA_set_flags(RSA *r, int flags) 714e1051a39Sopenharmony_ci{ 715e1051a39Sopenharmony_ci r->flags |= flags; 716e1051a39Sopenharmony_ci} 717e1051a39Sopenharmony_ci 718e1051a39Sopenharmony_ciint RSA_get_version(RSA *r) 719e1051a39Sopenharmony_ci{ 720e1051a39Sopenharmony_ci /* { two-prime(0), multi(1) } */ 721e1051a39Sopenharmony_ci return r->version; 722e1051a39Sopenharmony_ci} 723e1051a39Sopenharmony_ci 724e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 725e1051a39Sopenharmony_ciENGINE *RSA_get0_engine(const RSA *r) 726e1051a39Sopenharmony_ci{ 727e1051a39Sopenharmony_ci return r->engine; 728e1051a39Sopenharmony_ci} 729e1051a39Sopenharmony_ci 730e1051a39Sopenharmony_ciint RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) 731e1051a39Sopenharmony_ci{ 732e1051a39Sopenharmony_ci /* If key type not RSA or RSA-PSS return error */ 733e1051a39Sopenharmony_ci if (ctx != NULL && ctx->pmeth != NULL 734e1051a39Sopenharmony_ci && ctx->pmeth->pkey_id != EVP_PKEY_RSA 735e1051a39Sopenharmony_ci && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) 736e1051a39Sopenharmony_ci return -1; 737e1051a39Sopenharmony_ci return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); 738e1051a39Sopenharmony_ci} 739e1051a39Sopenharmony_ci#endif 740e1051a39Sopenharmony_ci 741e1051a39Sopenharmony_ciDEFINE_STACK_OF(BIGNUM) 742e1051a39Sopenharmony_ci 743e1051a39Sopenharmony_ciint ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, 744e1051a39Sopenharmony_ci const STACK_OF(BIGNUM) *exps, 745e1051a39Sopenharmony_ci const STACK_OF(BIGNUM) *coeffs) 746e1051a39Sopenharmony_ci{ 747e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 748e1051a39Sopenharmony_ci STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL; 749e1051a39Sopenharmony_ci#endif 750e1051a39Sopenharmony_ci int pnum; 751e1051a39Sopenharmony_ci 752e1051a39Sopenharmony_ci if (primes == NULL || exps == NULL || coeffs == NULL) 753e1051a39Sopenharmony_ci return 0; 754e1051a39Sopenharmony_ci 755e1051a39Sopenharmony_ci pnum = sk_BIGNUM_num(primes); 756e1051a39Sopenharmony_ci if (pnum < 2 757e1051a39Sopenharmony_ci || pnum != sk_BIGNUM_num(exps) 758e1051a39Sopenharmony_ci || pnum != sk_BIGNUM_num(coeffs) + 1) 759e1051a39Sopenharmony_ci return 0; 760e1051a39Sopenharmony_ci 761e1051a39Sopenharmony_ci if (!RSA_set0_factors(r, sk_BIGNUM_value(primes, 0), 762e1051a39Sopenharmony_ci sk_BIGNUM_value(primes, 1)) 763e1051a39Sopenharmony_ci || !RSA_set0_crt_params(r, sk_BIGNUM_value(exps, 0), 764e1051a39Sopenharmony_ci sk_BIGNUM_value(exps, 1), 765e1051a39Sopenharmony_ci sk_BIGNUM_value(coeffs, 0))) 766e1051a39Sopenharmony_ci return 0; 767e1051a39Sopenharmony_ci 768e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 769e1051a39Sopenharmony_ci old_infos = r->prime_infos; 770e1051a39Sopenharmony_ci#endif 771e1051a39Sopenharmony_ci 772e1051a39Sopenharmony_ci if (pnum > 2) { 773e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 774e1051a39Sopenharmony_ci int i; 775e1051a39Sopenharmony_ci 776e1051a39Sopenharmony_ci prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); 777e1051a39Sopenharmony_ci if (prime_infos == NULL) 778e1051a39Sopenharmony_ci return 0; 779e1051a39Sopenharmony_ci 780e1051a39Sopenharmony_ci for (i = 2; i < pnum; i++) { 781e1051a39Sopenharmony_ci BIGNUM *prime = sk_BIGNUM_value(primes, i); 782e1051a39Sopenharmony_ci BIGNUM *exp = sk_BIGNUM_value(exps, i); 783e1051a39Sopenharmony_ci BIGNUM *coeff = sk_BIGNUM_value(coeffs, i - 1); 784e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo = NULL; 785e1051a39Sopenharmony_ci 786e1051a39Sopenharmony_ci if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL)) 787e1051a39Sopenharmony_ci goto err; 788e1051a39Sopenharmony_ci 789e1051a39Sopenharmony_ci /* Using ossl_rsa_multip_info_new() is wasteful, so allocate directly */ 790e1051a39Sopenharmony_ci if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) { 791e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 792e1051a39Sopenharmony_ci goto err; 793e1051a39Sopenharmony_ci } 794e1051a39Sopenharmony_ci 795e1051a39Sopenharmony_ci pinfo->r = prime; 796e1051a39Sopenharmony_ci pinfo->d = exp; 797e1051a39Sopenharmony_ci pinfo->t = coeff; 798e1051a39Sopenharmony_ci BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); 799e1051a39Sopenharmony_ci BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); 800e1051a39Sopenharmony_ci BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); 801e1051a39Sopenharmony_ci (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); 802e1051a39Sopenharmony_ci } 803e1051a39Sopenharmony_ci 804e1051a39Sopenharmony_ci r->prime_infos = prime_infos; 805e1051a39Sopenharmony_ci 806e1051a39Sopenharmony_ci if (!ossl_rsa_multip_calc_product(r)) { 807e1051a39Sopenharmony_ci r->prime_infos = old_infos; 808e1051a39Sopenharmony_ci goto err; 809e1051a39Sopenharmony_ci } 810e1051a39Sopenharmony_ci#else 811e1051a39Sopenharmony_ci return 0; 812e1051a39Sopenharmony_ci#endif 813e1051a39Sopenharmony_ci } 814e1051a39Sopenharmony_ci 815e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 816e1051a39Sopenharmony_ci if (old_infos != NULL) { 817e1051a39Sopenharmony_ci /* 818e1051a39Sopenharmony_ci * This is hard to deal with, since the old infos could 819e1051a39Sopenharmony_ci * also be set by this function and r, d, t should not 820e1051a39Sopenharmony_ci * be freed in that case. So currently, stay consistent 821e1051a39Sopenharmony_ci * with other *set0* functions: just free it... 822e1051a39Sopenharmony_ci */ 823e1051a39Sopenharmony_ci sk_RSA_PRIME_INFO_pop_free(old_infos, ossl_rsa_multip_info_free); 824e1051a39Sopenharmony_ci } 825e1051a39Sopenharmony_ci#endif 826e1051a39Sopenharmony_ci 827e1051a39Sopenharmony_ci r->version = pnum > 2 ? RSA_ASN1_VERSION_MULTI : RSA_ASN1_VERSION_DEFAULT; 828e1051a39Sopenharmony_ci r->dirty_cnt++; 829e1051a39Sopenharmony_ci 830e1051a39Sopenharmony_ci return 1; 831e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 832e1051a39Sopenharmony_ci err: 833e1051a39Sopenharmony_ci /* r, d, t should not be freed */ 834e1051a39Sopenharmony_ci sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex); 835e1051a39Sopenharmony_ci return 0; 836e1051a39Sopenharmony_ci#endif 837e1051a39Sopenharmony_ci} 838e1051a39Sopenharmony_ci 839e1051a39Sopenharmony_ciDEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) 840e1051a39Sopenharmony_ci 841e1051a39Sopenharmony_ciint ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, 842e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *exps, 843e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *coeffs) 844e1051a39Sopenharmony_ci{ 845e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 846e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo; 847e1051a39Sopenharmony_ci int i, pnum; 848e1051a39Sopenharmony_ci#endif 849e1051a39Sopenharmony_ci 850e1051a39Sopenharmony_ci if (r == NULL) 851e1051a39Sopenharmony_ci return 0; 852e1051a39Sopenharmony_ci 853e1051a39Sopenharmony_ci /* If |p| is NULL, there are no CRT parameters */ 854e1051a39Sopenharmony_ci if (RSA_get0_p(r) == NULL) 855e1051a39Sopenharmony_ci return 1; 856e1051a39Sopenharmony_ci 857e1051a39Sopenharmony_ci sk_BIGNUM_const_push(primes, RSA_get0_p(r)); 858e1051a39Sopenharmony_ci sk_BIGNUM_const_push(primes, RSA_get0_q(r)); 859e1051a39Sopenharmony_ci sk_BIGNUM_const_push(exps, RSA_get0_dmp1(r)); 860e1051a39Sopenharmony_ci sk_BIGNUM_const_push(exps, RSA_get0_dmq1(r)); 861e1051a39Sopenharmony_ci sk_BIGNUM_const_push(coeffs, RSA_get0_iqmp(r)); 862e1051a39Sopenharmony_ci 863e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 864e1051a39Sopenharmony_ci pnum = RSA_get_multi_prime_extra_count(r); 865e1051a39Sopenharmony_ci for (i = 0; i < pnum; i++) { 866e1051a39Sopenharmony_ci pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); 867e1051a39Sopenharmony_ci sk_BIGNUM_const_push(primes, pinfo->r); 868e1051a39Sopenharmony_ci sk_BIGNUM_const_push(exps, pinfo->d); 869e1051a39Sopenharmony_ci sk_BIGNUM_const_push(coeffs, pinfo->t); 870e1051a39Sopenharmony_ci } 871e1051a39Sopenharmony_ci#endif 872e1051a39Sopenharmony_ci 873e1051a39Sopenharmony_ci return 1; 874e1051a39Sopenharmony_ci} 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 877e1051a39Sopenharmony_ci/* Helpers to set or get diverse hash algorithm names */ 878e1051a39Sopenharmony_cistatic int int_set_rsa_md_name(EVP_PKEY_CTX *ctx, 879e1051a39Sopenharmony_ci /* For checks */ 880e1051a39Sopenharmony_ci int keytype, int optype, 881e1051a39Sopenharmony_ci /* For EVP_PKEY_CTX_set_params() */ 882e1051a39Sopenharmony_ci const char *mdkey, const char *mdname, 883e1051a39Sopenharmony_ci const char *propkey, const char *mdprops) 884e1051a39Sopenharmony_ci{ 885e1051a39Sopenharmony_ci OSSL_PARAM params[3], *p = params; 886e1051a39Sopenharmony_ci 887e1051a39Sopenharmony_ci if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) { 888e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 889e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 890e1051a39Sopenharmony_ci return -2; 891e1051a39Sopenharmony_ci } 892e1051a39Sopenharmony_ci 893e1051a39Sopenharmony_ci /* If key type not RSA return error */ 894e1051a39Sopenharmony_ci switch (keytype) { 895e1051a39Sopenharmony_ci case -1: 896e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA") 897e1051a39Sopenharmony_ci && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) 898e1051a39Sopenharmony_ci return -1; 899e1051a39Sopenharmony_ci break; 900e1051a39Sopenharmony_ci default: 901e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype))) 902e1051a39Sopenharmony_ci return -1; 903e1051a39Sopenharmony_ci break; 904e1051a39Sopenharmony_ci } 905e1051a39Sopenharmony_ci 906e1051a39Sopenharmony_ci /* Cast away the const. This is read only so should be safe */ 907e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, 0); 908e1051a39Sopenharmony_ci if (evp_pkey_ctx_is_provided(ctx) && mdprops != NULL) { 909e1051a39Sopenharmony_ci /* Cast away the const. This is read only so should be safe */ 910e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_utf8_string(propkey, (char *)mdprops, 0); 911e1051a39Sopenharmony_ci } 912e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 913e1051a39Sopenharmony_ci 914e1051a39Sopenharmony_ci return evp_pkey_ctx_set_params_strict(ctx, params); 915e1051a39Sopenharmony_ci} 916e1051a39Sopenharmony_ci 917e1051a39Sopenharmony_ci/* Helpers to set or get diverse hash algorithm names */ 918e1051a39Sopenharmony_cistatic int int_get_rsa_md_name(EVP_PKEY_CTX *ctx, 919e1051a39Sopenharmony_ci /* For checks */ 920e1051a39Sopenharmony_ci int keytype, int optype, 921e1051a39Sopenharmony_ci /* For EVP_PKEY_CTX_get_params() */ 922e1051a39Sopenharmony_ci const char *mdkey, 923e1051a39Sopenharmony_ci char *mdname, size_t mdnamesize) 924e1051a39Sopenharmony_ci{ 925e1051a39Sopenharmony_ci OSSL_PARAM params[2], *p = params; 926e1051a39Sopenharmony_ci 927e1051a39Sopenharmony_ci if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) { 928e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 929e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 930e1051a39Sopenharmony_ci return -2; 931e1051a39Sopenharmony_ci } 932e1051a39Sopenharmony_ci 933e1051a39Sopenharmony_ci /* If key type not RSA return error */ 934e1051a39Sopenharmony_ci switch (keytype) { 935e1051a39Sopenharmony_ci case -1: 936e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA") 937e1051a39Sopenharmony_ci && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) 938e1051a39Sopenharmony_ci return -1; 939e1051a39Sopenharmony_ci break; 940e1051a39Sopenharmony_ci default: 941e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype))) 942e1051a39Sopenharmony_ci return -1; 943e1051a39Sopenharmony_ci break; 944e1051a39Sopenharmony_ci } 945e1051a39Sopenharmony_ci 946e1051a39Sopenharmony_ci /* Cast away the const. This is read only so should be safe */ 947e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, mdnamesize); 948e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 949e1051a39Sopenharmony_ci 950e1051a39Sopenharmony_ci return evp_pkey_ctx_get_params_strict(ctx, params); 951e1051a39Sopenharmony_ci} 952e1051a39Sopenharmony_ci 953e1051a39Sopenharmony_ci/* 954e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 955e1051a39Sopenharmony_ci * simply because that's easier. 956e1051a39Sopenharmony_ci */ 957e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) 958e1051a39Sopenharmony_ci{ 959e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, 960e1051a39Sopenharmony_ci pad_mode, NULL); 961e1051a39Sopenharmony_ci} 962e1051a39Sopenharmony_ci 963e1051a39Sopenharmony_ci/* 964e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 965e1051a39Sopenharmony_ci * simply because that's easier. 966e1051a39Sopenharmony_ci */ 967e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode) 968e1051a39Sopenharmony_ci{ 969e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 970e1051a39Sopenharmony_ci 0, pad_mode); 971e1051a39Sopenharmony_ci} 972e1051a39Sopenharmony_ci 973e1051a39Sopenharmony_ci/* 974e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 975e1051a39Sopenharmony_ci * simply because that's easier. 976e1051a39Sopenharmony_ci */ 977e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) 978e1051a39Sopenharmony_ci{ 979e1051a39Sopenharmony_ci return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, 980e1051a39Sopenharmony_ci EVP_PKEY_CTRL_MD, 0, (void *)(md)); 981e1051a39Sopenharmony_ci} 982e1051a39Sopenharmony_ci 983e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx, 984e1051a39Sopenharmony_ci const char *mdname, 985e1051a39Sopenharmony_ci const char *mdprops) 986e1051a39Sopenharmony_ci{ 987e1051a39Sopenharmony_ci return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, 988e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_RSA_DIGEST, mdname, 989e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, mdprops); 990e1051a39Sopenharmony_ci} 991e1051a39Sopenharmony_ci 992e1051a39Sopenharmony_ci/* 993e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 994e1051a39Sopenharmony_ci * simply because that's easier. 995e1051a39Sopenharmony_ci */ 996e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) 997e1051a39Sopenharmony_ci{ 998e1051a39Sopenharmony_ci return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 999e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)); 1000e1051a39Sopenharmony_ci} 1001e1051a39Sopenharmony_ci 1002e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname, 1003e1051a39Sopenharmony_ci const char *mdprops) 1004e1051a39Sopenharmony_ci{ 1005e1051a39Sopenharmony_ci return 1006e1051a39Sopenharmony_ci int_set_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 1007e1051a39Sopenharmony_ci OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, mdname, 1008e1051a39Sopenharmony_ci OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, mdprops); 1009e1051a39Sopenharmony_ci} 1010e1051a39Sopenharmony_ci 1011e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name, 1012e1051a39Sopenharmony_ci size_t namesize) 1013e1051a39Sopenharmony_ci{ 1014e1051a39Sopenharmony_ci return int_get_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 1015e1051a39Sopenharmony_ci OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, 1016e1051a39Sopenharmony_ci name, namesize); 1017e1051a39Sopenharmony_ci} 1018e1051a39Sopenharmony_ci 1019e1051a39Sopenharmony_ci/* 1020e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1021e1051a39Sopenharmony_ci * simply because that's easier. 1022e1051a39Sopenharmony_ci */ 1023e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) 1024e1051a39Sopenharmony_ci{ 1025e1051a39Sopenharmony_ci return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, 1026e1051a39Sopenharmony_ci EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md); 1027e1051a39Sopenharmony_ci} 1028e1051a39Sopenharmony_ci 1029e1051a39Sopenharmony_ci/* 1030e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1031e1051a39Sopenharmony_ci * simply because that's easier. 1032e1051a39Sopenharmony_ci */ 1033e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) 1034e1051a39Sopenharmony_ci{ 1035e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 1036e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)); 1037e1051a39Sopenharmony_ci} 1038e1051a39Sopenharmony_ci 1039e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, 1040e1051a39Sopenharmony_ci const char *mdprops) 1041e1051a39Sopenharmony_ci{ 1042e1051a39Sopenharmony_ci return int_set_rsa_md_name(ctx, -1, 1043e1051a39Sopenharmony_ci EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, 1044e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_MGF1_DIGEST, mdname, 1045e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_MGF1_PROPERTIES, mdprops); 1046e1051a39Sopenharmony_ci} 1047e1051a39Sopenharmony_ci 1048e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name, 1049e1051a39Sopenharmony_ci size_t namesize) 1050e1051a39Sopenharmony_ci{ 1051e1051a39Sopenharmony_ci return int_get_rsa_md_name(ctx, -1, 1052e1051a39Sopenharmony_ci EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, 1053e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_MGF1_DIGEST, name, namesize); 1054e1051a39Sopenharmony_ci} 1055e1051a39Sopenharmony_ci 1056e1051a39Sopenharmony_ci/* 1057e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1058e1051a39Sopenharmony_ci * simply because that's easier. 1059e1051a39Sopenharmony_ci */ 1060e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) 1061e1051a39Sopenharmony_ci{ 1062e1051a39Sopenharmony_ci return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, 1063e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)); 1064e1051a39Sopenharmony_ci} 1065e1051a39Sopenharmony_ci 1066e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name(EVP_PKEY_CTX *ctx, 1067e1051a39Sopenharmony_ci const char *mdname) 1068e1051a39Sopenharmony_ci{ 1069e1051a39Sopenharmony_ci return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, 1070e1051a39Sopenharmony_ci OSSL_PKEY_PARAM_MGF1_DIGEST, mdname, 1071e1051a39Sopenharmony_ci NULL, NULL); 1072e1051a39Sopenharmony_ci} 1073e1051a39Sopenharmony_ci 1074e1051a39Sopenharmony_ci/* 1075e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1076e1051a39Sopenharmony_ci * simply because that's easier. 1077e1051a39Sopenharmony_ci */ 1078e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) 1079e1051a39Sopenharmony_ci{ 1080e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, 1081e1051a39Sopenharmony_ci EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(md)); 1082e1051a39Sopenharmony_ci} 1083e1051a39Sopenharmony_ci 1084e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen) 1085e1051a39Sopenharmony_ci{ 1086e1051a39Sopenharmony_ci OSSL_PARAM rsa_params[2], *p = rsa_params; 1087e1051a39Sopenharmony_ci int ret; 1088e1051a39Sopenharmony_ci 1089e1051a39Sopenharmony_ci if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { 1090e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 1091e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 1092e1051a39Sopenharmony_ci return -2; 1093e1051a39Sopenharmony_ci } 1094e1051a39Sopenharmony_ci 1095e1051a39Sopenharmony_ci /* If key type not RSA return error */ 1096e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA")) 1097e1051a39Sopenharmony_ci return -1; 1098e1051a39Sopenharmony_ci 1099e1051a39Sopenharmony_ci /* Cast away the const. This is read only so should be safe */ 1100e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, 1101e1051a39Sopenharmony_ci (void *)label, (size_t)llen); 1102e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 1103e1051a39Sopenharmony_ci 1104e1051a39Sopenharmony_ci ret = evp_pkey_ctx_set_params_strict(ctx, rsa_params); 1105e1051a39Sopenharmony_ci if (ret <= 0) 1106e1051a39Sopenharmony_ci return ret; 1107e1051a39Sopenharmony_ci 1108e1051a39Sopenharmony_ci /* Ownership is supposed to be transfered to the callee. */ 1109e1051a39Sopenharmony_ci OPENSSL_free(label); 1110e1051a39Sopenharmony_ci return 1; 1111e1051a39Sopenharmony_ci} 1112e1051a39Sopenharmony_ci 1113e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) 1114e1051a39Sopenharmony_ci{ 1115e1051a39Sopenharmony_ci OSSL_PARAM rsa_params[2], *p = rsa_params; 1116e1051a39Sopenharmony_ci size_t labellen; 1117e1051a39Sopenharmony_ci 1118e1051a39Sopenharmony_ci if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { 1119e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 1120e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 1121e1051a39Sopenharmony_ci return -2; 1122e1051a39Sopenharmony_ci } 1123e1051a39Sopenharmony_ci 1124e1051a39Sopenharmony_ci /* If key type not RSA return error */ 1125e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA")) 1126e1051a39Sopenharmony_ci return -1; 1127e1051a39Sopenharmony_ci 1128e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, 1129e1051a39Sopenharmony_ci (void **)label, 0); 1130e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 1131e1051a39Sopenharmony_ci 1132e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_get_params(ctx, rsa_params)) 1133e1051a39Sopenharmony_ci return -1; 1134e1051a39Sopenharmony_ci 1135e1051a39Sopenharmony_ci labellen = rsa_params[0].return_size; 1136e1051a39Sopenharmony_ci if (labellen > INT_MAX) 1137e1051a39Sopenharmony_ci return -1; 1138e1051a39Sopenharmony_ci 1139e1051a39Sopenharmony_ci return (int)labellen; 1140e1051a39Sopenharmony_ci} 1141e1051a39Sopenharmony_ci 1142e1051a39Sopenharmony_ci/* 1143e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1144e1051a39Sopenharmony_ci * simply because that's easier. 1145e1051a39Sopenharmony_ci */ 1146e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen) 1147e1051a39Sopenharmony_ci{ 1148e1051a39Sopenharmony_ci /* 1149e1051a39Sopenharmony_ci * For some reason, the optype was set to this: 1150e1051a39Sopenharmony_ci * 1151e1051a39Sopenharmony_ci * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY 1152e1051a39Sopenharmony_ci * 1153e1051a39Sopenharmony_ci * However, we do use RSA-PSS with the whole gamut of diverse signature 1154e1051a39Sopenharmony_ci * and verification operations, so the optype gets upgraded to this: 1155e1051a39Sopenharmony_ci * 1156e1051a39Sopenharmony_ci * EVP_PKEY_OP_TYPE_SIG 1157e1051a39Sopenharmony_ci */ 1158e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG, 1159e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltlen, NULL); 1160e1051a39Sopenharmony_ci} 1161e1051a39Sopenharmony_ci 1162e1051a39Sopenharmony_ci/* 1163e1051a39Sopenharmony_ci * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, 1164e1051a39Sopenharmony_ci * simply because that's easier. 1165e1051a39Sopenharmony_ci */ 1166e1051a39Sopenharmony_ciint EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen) 1167e1051a39Sopenharmony_ci{ 1168e1051a39Sopenharmony_ci /* 1169e1051a39Sopenharmony_ci * Because of circumstances, the optype is updated from: 1170e1051a39Sopenharmony_ci * 1171e1051a39Sopenharmony_ci * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY 1172e1051a39Sopenharmony_ci * 1173e1051a39Sopenharmony_ci * to: 1174e1051a39Sopenharmony_ci * 1175e1051a39Sopenharmony_ci * EVP_PKEY_OP_TYPE_SIG 1176e1051a39Sopenharmony_ci */ 1177e1051a39Sopenharmony_ci return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG, 1178e1051a39Sopenharmony_ci EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, saltlen); 1179e1051a39Sopenharmony_ci} 1180e1051a39Sopenharmony_ci 1181e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen) 1182e1051a39Sopenharmony_ci{ 1183e1051a39Sopenharmony_ci OSSL_PARAM pad_params[2], *p = pad_params; 1184e1051a39Sopenharmony_ci 1185e1051a39Sopenharmony_ci if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { 1186e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 1187e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 1188e1051a39Sopenharmony_ci return -2; 1189e1051a39Sopenharmony_ci } 1190e1051a39Sopenharmony_ci 1191e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) 1192e1051a39Sopenharmony_ci return -1; 1193e1051a39Sopenharmony_ci 1194e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, 1195e1051a39Sopenharmony_ci &saltlen); 1196e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 1197e1051a39Sopenharmony_ci 1198e1051a39Sopenharmony_ci return evp_pkey_ctx_set_params_strict(ctx, pad_params); 1199e1051a39Sopenharmony_ci} 1200e1051a39Sopenharmony_ci 1201e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) 1202e1051a39Sopenharmony_ci{ 1203e1051a39Sopenharmony_ci OSSL_PARAM params[2], *p = params; 1204e1051a39Sopenharmony_ci size_t bits2 = bits; 1205e1051a39Sopenharmony_ci 1206e1051a39Sopenharmony_ci if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { 1207e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 1208e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 1209e1051a39Sopenharmony_ci return -2; 1210e1051a39Sopenharmony_ci } 1211e1051a39Sopenharmony_ci 1212e1051a39Sopenharmony_ci /* If key type not RSA return error */ 1213e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA") 1214e1051a39Sopenharmony_ci && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) 1215e1051a39Sopenharmony_ci return -1; 1216e1051a39Sopenharmony_ci 1217e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits2); 1218e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 1219e1051a39Sopenharmony_ci 1220e1051a39Sopenharmony_ci return evp_pkey_ctx_set_params_strict(ctx, params); 1221e1051a39Sopenharmony_ci} 1222e1051a39Sopenharmony_ci 1223e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) 1224e1051a39Sopenharmony_ci{ 1225e1051a39Sopenharmony_ci int ret = RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, 1226e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); 1227e1051a39Sopenharmony_ci 1228e1051a39Sopenharmony_ci /* 1229e1051a39Sopenharmony_ci * Satisfy memory semantics for pre-3.0 callers of 1230e1051a39Sopenharmony_ci * EVP_PKEY_CTX_set_rsa_keygen_pubexp(): their expectation is that input 1231e1051a39Sopenharmony_ci * pubexp BIGNUM becomes managed by the EVP_PKEY_CTX on success. 1232e1051a39Sopenharmony_ci */ 1233e1051a39Sopenharmony_ci if (ret > 0 && evp_pkey_ctx_is_provided(ctx)) { 1234e1051a39Sopenharmony_ci BN_free(ctx->rsa_pubexp); 1235e1051a39Sopenharmony_ci ctx->rsa_pubexp = pubexp; 1236e1051a39Sopenharmony_ci } 1237e1051a39Sopenharmony_ci 1238e1051a39Sopenharmony_ci return ret; 1239e1051a39Sopenharmony_ci} 1240e1051a39Sopenharmony_ci 1241e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) 1242e1051a39Sopenharmony_ci{ 1243e1051a39Sopenharmony_ci int ret = 0; 1244e1051a39Sopenharmony_ci 1245e1051a39Sopenharmony_ci /* 1246e1051a39Sopenharmony_ci * When we're dealing with a provider, there's no need to duplicate 1247e1051a39Sopenharmony_ci * pubexp, as it gets copied when transforming to an OSSL_PARAM anyway. 1248e1051a39Sopenharmony_ci */ 1249e1051a39Sopenharmony_ci if (evp_pkey_ctx_is_legacy(ctx)) { 1250e1051a39Sopenharmony_ci pubexp = BN_dup(pubexp); 1251e1051a39Sopenharmony_ci if (pubexp == NULL) 1252e1051a39Sopenharmony_ci return 0; 1253e1051a39Sopenharmony_ci } 1254e1051a39Sopenharmony_ci ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, 1255e1051a39Sopenharmony_ci EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); 1256e1051a39Sopenharmony_ci if (evp_pkey_ctx_is_legacy(ctx) && ret <= 0) 1257e1051a39Sopenharmony_ci BN_free(pubexp); 1258e1051a39Sopenharmony_ci return ret; 1259e1051a39Sopenharmony_ci} 1260e1051a39Sopenharmony_ci 1261e1051a39Sopenharmony_ciint EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes) 1262e1051a39Sopenharmony_ci{ 1263e1051a39Sopenharmony_ci OSSL_PARAM params[2], *p = params; 1264e1051a39Sopenharmony_ci size_t primes2 = primes; 1265e1051a39Sopenharmony_ci 1266e1051a39Sopenharmony_ci if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { 1267e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); 1268e1051a39Sopenharmony_ci /* Uses the same return values as EVP_PKEY_CTX_ctrl */ 1269e1051a39Sopenharmony_ci return -2; 1270e1051a39Sopenharmony_ci } 1271e1051a39Sopenharmony_ci 1272e1051a39Sopenharmony_ci /* If key type not RSA return error */ 1273e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_is_a(ctx, "RSA") 1274e1051a39Sopenharmony_ci && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) 1275e1051a39Sopenharmony_ci return -1; 1276e1051a39Sopenharmony_ci 1277e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, &primes2); 1278e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_end(); 1279e1051a39Sopenharmony_ci 1280e1051a39Sopenharmony_ci return evp_pkey_ctx_set_params_strict(ctx, params); 1281e1051a39Sopenharmony_ci} 1282e1051a39Sopenharmony_ci#endif 1283