Remove non-namespaced symbols for ctor/dtor of RSA. Bug: 42220000 Change-Id: I70504fa1747fc8de2196b9d013eca7de6a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88568 Reviewed-by: Xiangfei Ding <xfding@google.com> Commit-Queue: Xiangfei Ding <xfding@google.com>
diff --git a/crypto/evp/p_rsa.cc b/crypto/evp/p_rsa.cc index b156a90..1855cd7 100644 --- a/crypto/evp/p_rsa.cc +++ b/crypto/evp/p_rsa.cc
@@ -167,7 +167,7 @@ } static int rsa_pub_encode_pss(CBB *out, const EVP_PKEY *key) { - const RSA *rsa = reinterpret_cast<const RSA *>(key->pkey); + const RSAImpl *rsa = reinterpret_cast<const RSAImpl *>(key->pkey); CBB spki, algorithm, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || @@ -194,7 +194,8 @@ return ret; } - UniquePtr<RSA> rsa(RSA_public_key_from_bytes(CBS_data(key), CBS_len(key))); + UniquePtr<RSAImpl> rsa( + FromOpaque(RSA_public_key_from_bytes(CBS_data(key), CBS_len(key)))); if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return evp_decode_error; @@ -206,7 +207,7 @@ } static int rsa_priv_encode_pss(CBB *out, const EVP_PKEY *key) { - const RSA *rsa = reinterpret_cast<const RSA *>(key->pkey); + const RSAImpl *rsa = reinterpret_cast<const RSAImpl *>(key->pkey); CBB pkcs8, algorithm, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || @@ -233,7 +234,8 @@ return ret; } - UniquePtr<RSA> rsa(RSA_private_key_from_bytes(CBS_data(key), CBS_len(key))); + UniquePtr<RSAImpl> rsa( + FromOpaque(RSA_private_key_from_bytes(CBS_data(key), CBS_len(key)))); if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return evp_decode_error; @@ -374,7 +376,7 @@ rctx->pad_mode = RSA_PKCS1_PSS_PADDING; // Pick up PSS parameters from the key. if (ctx->pkey != nullptr && ctx->pkey->pkey != nullptr) { - RSA *rsa = static_cast<RSA *>(ctx->pkey->pkey); + RSAImpl *rsa = static_cast<RSAImpl *>(ctx->pkey->pkey); const EVP_MD *md = rsa_pss_params_get_md(rsa->pss_params); if (md != nullptr) { rctx->md = rctx->mgf1md = md;
diff --git a/crypto/evp/print.cc b/crypto/evp/print.cc index 50d158d..4582fe9 100644 --- a/crypto/evp/print.cc +++ b/crypto/evp/print.cc
@@ -26,6 +26,8 @@ #include "../internal.h" +using namespace bssl; + static int print_hex(BIO *bp, const uint8_t *data, size_t len, int off) { for (size_t i = 0; i < len; i++) { if ((i % 15) == 0) { @@ -98,7 +100,7 @@ // RSA keys. -static int do_rsa_print(BIO *out, const RSA *rsa, int off, +static int do_rsa_print(BIO *out, const RSAImpl *rsa, int off, int include_private) { int mod_len = 0; if (rsa->n != nullptr) { @@ -142,11 +144,11 @@ } static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 0); + return do_rsa_print(bp, FromOpaque(EVP_PKEY_get0_RSA(pkey)), indent, 0); } static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 1); + return do_rsa_print(bp, FromOpaque(EVP_PKEY_get0_RSA(pkey)), indent, 1); }
diff --git a/crypto/fipsmodule/rsa/internal.h b/crypto/fipsmodule/rsa/internal.h index 11e6099..602573b 100644 --- a/crypto/fipsmodule/rsa/internal.h +++ b/crypto/fipsmodule/rsa/internal.h
@@ -23,6 +23,8 @@ #include "../../internal.h" +DECLARE_OPAQUE_STRUCT(rsa_st, RSAImpl) + BSSL_NAMESPACE_BEGIN // TODO(crbug.com/42290480): Raise this limit. 512-bit RSA was factored in 1999. @@ -42,9 +44,13 @@ rsa_pss_sha512, }; -BSSL_NAMESPACE_END +// Exported because rsa_test.cc uses this class and links to the .so. +class OPENSSL_EXPORT RSAImpl : public rsa_st { + public: + static constexpr bool kAllowUniquePtr = true; -struct rsa_st { + ~RSAImpl(); + RSA_METHOD *meth; BIGNUM *n; @@ -85,12 +91,9 @@ // private_key_frozen is one if the key has been used for a private key // operation and may no longer be mutated. - unsigned private_key_frozen:1; + unsigned private_key_frozen : 1; }; - -BSSL_NAMESPACE_BEGIN - #define RSA_PKCS1_PADDING_SIZE 11 // Default implementations of RSA operations.
diff --git a/crypto/fipsmodule/rsa/padding.cc.inc b/crypto/fipsmodule/rsa/padding.cc.inc index 5f0e41f..a68f14d 100644 --- a/crypto/fipsmodule/rsa/padding.cc.inc +++ b/crypto/fipsmodule/rsa/padding.cc.inc
@@ -192,7 +192,7 @@ goto err; } - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + MSBits = (BN_num_bits(FromOpaque(rsa)->n) - 1) & 0x7; emLen = RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID); @@ -281,12 +281,12 @@ FIPS_service_indicator_lock_state(); hLen = EVP_MD_size(Hash); - if (BN_is_zero(rsa->n)) { + if (BN_is_zero(FromOpaque(rsa)->n)) { OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); goto err; } - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + MSBits = (BN_num_bits(FromOpaque(rsa)->n) - 1) & 0x7; emLen = RSA_size(rsa); if (MSBits == 0) { assert(emLen >= 1);
diff --git a/crypto/fipsmodule/rsa/rsa.cc.inc b/crypto/fipsmodule/rsa/rsa.cc.inc index 94d5ddb..a3e8fe0 100644 --- a/crypto/fipsmodule/rsa/rsa.cc.inc +++ b/crypto/fipsmodule/rsa/rsa.cc.inc
@@ -57,7 +57,7 @@ } RSA *RSA_new_public_key(const BIGNUM *n, const BIGNUM *e) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr || // !bn_dup_into(&rsa->n, n) || // !bn_dup_into(&rsa->e, e) || // @@ -72,7 +72,7 @@ RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, const BIGNUM *iqmp) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr || // !bn_dup_into(&rsa->n, n) || // !bn_dup_into(&rsa->e, e) || // @@ -92,7 +92,7 @@ RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr || // !bn_dup_into(&rsa->n, n) || // !bn_dup_into(&rsa->e, e) || // @@ -106,7 +106,7 @@ } RSA *RSA_new_private_key_no_e(const BIGNUM *n, const BIGNUM *d) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr) { return nullptr; } @@ -123,7 +123,7 @@ } RSA *RSA_new_public_key_large_e(const BIGNUM *n, const BIGNUM *e) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr) { return nullptr; } @@ -143,7 +143,7 @@ const BIGNUM *d, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, const BIGNUM *iqmp) { - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr) { return nullptr; } @@ -168,7 +168,7 @@ RSA *RSA_new() { return RSA_new_method(nullptr); } RSA *RSA_new_method(const ENGINE *engine) { - RSA *rsa = NewZeroed<RSA>(); + RSAImpl *rsa = NewZeroed<RSAImpl>(); if (rsa == nullptr) { return nullptr; } @@ -197,7 +197,7 @@ } RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n) { - RSA *rsa = RSA_new_method(engine); + RSAImpl *rsa = FromOpaque(RSA_new_method(engine)); if (rsa == nullptr || !bn_dup_into(&rsa->n, n)) { RSA_free(rsa); return nullptr; @@ -206,111 +206,150 @@ return rsa; } +RSAImpl::~RSAImpl() { + // Refcount can be 1 if called by UniquePtr, and 0 if called by RSA_free. + BSSL_CHECK(references.load() <= 1); + + if (meth != nullptr && meth->finish != nullptr) { + meth->finish(this); + } + METHOD_unref(meth); + + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), &ex_data); + + BN_free(n); + BN_free(e); + BN_free(d); + BN_free(p); + BN_free(q); + BN_free(dmp1); + BN_free(dmq1); + BN_free(iqmp); + rsa_invalidate_key(this); + CRYPTO_MUTEX_cleanup(&lock); +} + void RSA_free(RSA *rsa) { if (rsa == nullptr) { return; } - if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) { + auto *impl = FromOpaque(rsa); + if (!CRYPTO_refcount_dec_and_test_zero(&impl->references)) { return; } - - if (rsa->meth != nullptr && rsa->meth->finish != nullptr) { - rsa->meth->finish(rsa); - } - METHOD_unref(rsa->meth); - - CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), &rsa->ex_data); - - BN_free(rsa->n); - BN_free(rsa->e); - BN_free(rsa->d); - BN_free(rsa->p); - BN_free(rsa->q); - BN_free(rsa->dmp1); - BN_free(rsa->dmq1); - BN_free(rsa->iqmp); - rsa_invalidate_key(rsa); - CRYPTO_MUTEX_cleanup(&rsa->lock); - Delete(rsa); + Delete(impl); } int RSA_up_ref(RSA *rsa) { - CRYPTO_refcount_inc(&rsa->references); + auto *impl = FromOpaque(rsa); + CRYPTO_refcount_inc(&impl->references); return 1; } -unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); } +unsigned RSA_bits(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return BN_num_bits(impl->n); +} -const BIGNUM *RSA_get0_n(const RSA *rsa) { return rsa->n; } +const BIGNUM *RSA_get0_n(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->n; +} -const BIGNUM *RSA_get0_e(const RSA *rsa) { return rsa->e; } +const BIGNUM *RSA_get0_e(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->e; +} -const BIGNUM *RSA_get0_d(const RSA *rsa) { return rsa->d; } +const BIGNUM *RSA_get0_d(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->d; +} -const BIGNUM *RSA_get0_p(const RSA *rsa) { return rsa->p; } +const BIGNUM *RSA_get0_p(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->p; +} -const BIGNUM *RSA_get0_q(const RSA *rsa) { return rsa->q; } +const BIGNUM *RSA_get0_q(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->q; +} -const BIGNUM *RSA_get0_dmp1(const RSA *rsa) { return rsa->dmp1; } +const BIGNUM *RSA_get0_dmp1(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->dmp1; +} -const BIGNUM *RSA_get0_dmq1(const RSA *rsa) { return rsa->dmq1; } +const BIGNUM *RSA_get0_dmq1(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->dmq1; +} -const BIGNUM *RSA_get0_iqmp(const RSA *rsa) { return rsa->iqmp; } +const BIGNUM *RSA_get0_iqmp(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->iqmp; +} void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, const BIGNUM **out_d) { + auto *impl = FromOpaque(rsa); if (out_n != nullptr) { - *out_n = rsa->n; + *out_n = impl->n; } if (out_e != nullptr) { - *out_e = rsa->e; + *out_e = impl->e; } if (out_d != nullptr) { - *out_d = rsa->d; + *out_d = impl->d; } } void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, const BIGNUM **out_q) { + auto *impl = FromOpaque(rsa); if (out_p != nullptr) { - *out_p = rsa->p; + *out_p = impl->p; } if (out_q != nullptr) { - *out_q = rsa->q; + *out_q = impl->q; } } void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { + auto *impl = FromOpaque(rsa); if (out_dmp1 != nullptr) { - *out_dmp1 = rsa->dmp1; + *out_dmp1 = impl->dmp1; } if (out_dmq1 != nullptr) { - *out_dmq1 = rsa->dmq1; + *out_dmq1 = impl->dmq1; } if (out_iqmp != nullptr) { - *out_iqmp = rsa->iqmp; + *out_iqmp = impl->iqmp; } } int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - if ((rsa->n == nullptr && n == nullptr) || - (rsa->e == nullptr && e == nullptr)) { + auto *impl = FromOpaque(rsa); + + if ((impl->n == nullptr && n == nullptr) || + (impl->e == nullptr && e == nullptr)) { return 0; } if (n != nullptr) { - BN_free(rsa->n); - rsa->n = n; + BN_free(impl->n); + impl->n = n; } if (e != nullptr) { - BN_free(rsa->e); - rsa->e = e; + BN_free(impl->e); + impl->e = e; } if (d != nullptr) { - BN_free(rsa->d); - rsa->d = d; + BN_free(impl->d); + impl->d = d; } rsa_invalidate_key(rsa); @@ -318,18 +357,20 @@ } int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { - if ((rsa->p == nullptr && p == nullptr) || - (rsa->q == nullptr && q == nullptr)) { + auto *impl = FromOpaque(rsa); + + if ((impl->p == nullptr && p == nullptr) || + (impl->q == nullptr && q == nullptr)) { return 0; } if (p != nullptr) { - BN_free(rsa->p); - rsa->p = p; + BN_free(impl->p); + impl->p = p; } if (q != nullptr) { - BN_free(rsa->q); - rsa->q = q; + BN_free(impl->q); + impl->q = q; } rsa_invalidate_key(rsa); @@ -337,23 +378,25 @@ } int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { - if ((rsa->dmp1 == nullptr && dmp1 == nullptr) || - (rsa->dmq1 == nullptr && dmq1 == nullptr) || - (rsa->iqmp == nullptr && iqmp == nullptr)) { + auto *impl = FromOpaque(rsa); + + if ((impl->dmp1 == nullptr && dmp1 == nullptr) || + (impl->dmq1 == nullptr && dmq1 == nullptr) || + (impl->iqmp == nullptr && iqmp == nullptr)) { return 0; } if (dmp1 != nullptr) { - BN_free(rsa->dmp1); - rsa->dmp1 = dmp1; + BN_free(impl->dmp1); + impl->dmp1 = dmp1; } if (dmq1 != nullptr) { - BN_free(rsa->dmq1); - rsa->dmq1 = dmq1; + BN_free(impl->dmq1); + impl->dmq1 = dmq1; } if (iqmp != nullptr) { - BN_free(rsa->iqmp); - rsa->iqmp = iqmp; + BN_free(impl->iqmp); + impl->iqmp = iqmp; } rsa_invalidate_key(rsa); @@ -363,8 +406,11 @@ static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { - if (rsa->meth->sign_raw) { - return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); + auto *impl = FromOpaque(rsa); + + if (impl->meth->sign_raw) { + return impl->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, + padding); } return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding); @@ -377,10 +423,14 @@ padding); } -unsigned RSA_size(const RSA *rsa) { return BN_num_bytes(rsa->n); } +unsigned RSA_size(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return BN_num_bytes(impl->n); +} int RSA_is_opaque(const RSA *rsa) { - return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); + auto *impl = FromOpaque(rsa); + return impl->meth && (impl->meth->flags & RSA_FLAG_OPAQUE); } int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, @@ -390,11 +440,13 @@ } int RSA_set_ex_data(RSA *rsa, int idx, void *arg) { - return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg); + auto *impl = FromOpaque(rsa); + return CRYPTO_set_ex_data(&impl->ex_data, idx, arg); } void *RSA_get_ex_data(const RSA *rsa, int idx) { - return CRYPTO_get_ex_data(&rsa->ex_data, idx); + auto *impl = FromOpaque(rsa); + return CRYPTO_get_ex_data(&impl->ex_data, idx); } // SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's @@ -546,15 +598,17 @@ int bssl::rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa) { - if (rsa->meth->sign) { + auto *impl = FromOpaque(rsa); + + if (impl->meth->sign) { if (!rsa_check_digest_size(hash_nid, digest_len)) { return 0; } // All supported digest lengths fit in |unsigned|. assert(digest_len <= EVP_MAX_MD_SIZE); static_assert(EVP_MAX_MD_SIZE <= UINT_MAX, "digest too long"); - return rsa->meth->sign(hash_nid, digest, (unsigned)digest_len, out, out_len, - rsa); + return impl->meth->sign(hash_nid, digest, (unsigned)digest_len, out, + out_len, rsa); } const unsigned rsa_size = RSA_size(rsa); @@ -619,7 +673,8 @@ int bssl::rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, size_t digest_len, const uint8_t *sig, size_t sig_len, RSA *rsa) { - if (rsa->n == nullptr || rsa->e == nullptr) { + auto *impl = FromOpaque(rsa); + if (impl->n == nullptr || impl->e == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -738,20 +793,21 @@ return 0; } - if ((key->p != nullptr) != (key->q != nullptr)) { + auto *impl = FromOpaque(key); + if ((impl->p != nullptr) != (impl->q != nullptr)) { OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); return 0; } - // |key->d| must be bounded by |key->n|. This ensures bounds on |RSA_bits| + // |impl->d| must be bounded by |impl->n|. This ensures bounds on |RSA_bits| // translate to bounds on the running time of private key operations. - if (key->d != nullptr && - (BN_is_negative(key->d) || BN_cmp(key->d, key->n) >= 0)) { + if (impl->d != nullptr && + (BN_is_negative(impl->d) || BN_cmp(impl->d, impl->n) >= 0)) { OPENSSL_PUT_ERROR(RSA, RSA_R_D_OUT_OF_RANGE); return 0; } - if (key->d == nullptr || key->p == nullptr) { + if (impl->d == nullptr || impl->p == nullptr) { // For a public key, or without p and q, there's nothing that can be // checked. return 1; @@ -776,18 +832,18 @@ // bounds, to avoid a DoS vector in |bn_mul_consttime| below. Note that // n was bound by |rsa_check_public_key|. This also implicitly checks p and q // are odd, which is a necessary condition for Montgomery reduction. - if (BN_is_negative(key->p) || - constant_time_declassify_int(BN_cmp(key->p, key->n) >= 0) || - BN_is_negative(key->q) || - constant_time_declassify_int(BN_cmp(key->q, key->n) >= 0)) { + if (BN_is_negative(impl->p) || + constant_time_declassify_int(BN_cmp(impl->p, impl->n) >= 0) || + BN_is_negative(impl->q) || + constant_time_declassify_int(BN_cmp(impl->q, impl->n) >= 0)) { OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); goto out; } - if (!bn_mul_consttime(&tmp, key->p, key->q, ctx)) { + if (!bn_mul_consttime(&tmp, impl->p, impl->q, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } - if (BN_cmp(&tmp, key->n) != 0) { + if (BN_cmp(&tmp, impl->n) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); goto out; } @@ -796,14 +852,14 @@ // may be unreduced because other implementations use the Euler totient. We // simply check that d * e is one mod p-1 and mod q-1. Note d and e were bound // by earlier checks in this function. - if (!bn_usub_consttime(&pm1, key->p, BN_value_one()) || - !bn_usub_consttime(&qm1, key->q, BN_value_one())) { + if (!bn_usub_consttime(&pm1, impl->p, BN_value_one()) || + !bn_usub_consttime(&qm1, impl->q, BN_value_one())) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } pm1_bits = BN_num_bits(&pm1); qm1_bits = BN_num_bits(&qm1); - if (!bn_mul_consttime(&de, key->d, key->e, ctx) || + if (!bn_mul_consttime(&de, impl->d, impl->e, ctx) || !bn_div_consttime(nullptr, &tmp, &de, &pm1, pm1_bits, ctx) || !bn_div_consttime(nullptr, &de, &de, &qm1, qm1_bits, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); @@ -816,20 +872,22 @@ goto out; } - has_crt_values = key->dmp1 != nullptr; - if (has_crt_values != (key->dmq1 != nullptr) || - has_crt_values != (key->iqmp != nullptr)) { + has_crt_values = impl->dmp1 != nullptr; + if (has_crt_values != (impl->dmq1 != nullptr) || + has_crt_values != (impl->iqmp != nullptr)) { OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); goto out; } if (has_crt_values) { int dmp1_ok, dmq1_ok, iqmp_ok; - if (!check_mod_inverse(&dmp1_ok, key->e, key->dmp1, &pm1, pm1_bits, ctx) || - !check_mod_inverse(&dmq1_ok, key->e, key->dmq1, &qm1, qm1_bits, ctx) || + if (!check_mod_inverse(&dmp1_ok, impl->e, impl->dmp1, &pm1, pm1_bits, + ctx) || + !check_mod_inverse(&dmq1_ok, impl->e, impl->dmq1, &qm1, qm1_bits, + ctx) || // |p| is odd, so |pm1| and |p| have the same bit width. If they didn't, // we only need a lower bound anyway. - !check_mod_inverse(&iqmp_ok, key->q, key->iqmp, key->p, pm1_bits, + !check_mod_inverse(&iqmp_ok, impl->q, impl->iqmp, impl->p, pm1_bits, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; @@ -907,14 +965,15 @@ // // |key->e| may be nullptr if created with |RSA_new_private_key_no_e|. enum bn_primality_result_t primality_result; - if (key->e == nullptr || // - BN_num_bits(key->e) <= 16 || // - BN_num_bits(key->e) > 256 || // - !BN_is_odd(key->n) || // - !BN_is_odd(key->e) || - !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) || + auto *impl = FromOpaque(key); + if (impl->e == nullptr || // + BN_num_bits(impl->e) <= 16 || // + BN_num_bits(impl->e) > 256 || // + !BN_is_odd(impl->n) || // + !BN_is_odd(impl->e) || + !BN_gcd(&small_gcd, impl->n, g_small_factors(), ctx) || !BN_is_one(&small_gcd) || - !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n, + !BN_enhanced_miller_rabin_primality_test(&primality_result, impl->n, BN_prime_checks_for_generation, ctx, nullptr) || primality_result != bn_non_prime_power_composite) { @@ -925,7 +984,7 @@ BN_free(&small_gcd); BN_CTX_free(ctx); - if (!ret || key->d == nullptr || key->p == nullptr) { + if (!ret || impl->d == nullptr || impl->p == nullptr) { // On a failure or on only a public key, there's nothing else can be // checked. return ret; @@ -963,8 +1022,10 @@ int bssl::rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { - if (rsa->meth->private_transform) { - return rsa->meth->private_transform(rsa, out, in, len); + auto *impl = FromOpaque(rsa); + + if (impl->meth->private_transform) { + return impl->meth->private_transform(rsa, out, in, len); } return rsa_default_private_transform(rsa, out, in, len); @@ -976,6 +1037,12 @@ return rsa_private_transform_no_self_test(rsa, out, in, len); } -int RSA_flags(const RSA *rsa) { return rsa->flags; } +int RSA_flags(const RSA *rsa) { + auto *impl = FromOpaque(rsa); + return impl->flags; +} -int RSA_test_flags(const RSA *rsa, int flags) { return rsa->flags & flags; } +int RSA_test_flags(const RSA *rsa, int flags) { + auto *impl = FromOpaque(rsa); + return impl->flags & flags; +}
diff --git a/crypto/fipsmodule/rsa/rsa_impl.cc.inc b/crypto/fipsmodule/rsa/rsa_impl.cc.inc index 77cbca9..150d17a 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.cc.inc +++ b/crypto/fipsmodule/rsa/rsa_impl.cc.inc
@@ -26,6 +26,7 @@ #include "../../bcm_support.h" #include "../../internal.h" +#include "../../mem_internal.h" #include "../bn/internal.h" #include "../delocate.h" #include "../service_indicator/internal.h" @@ -39,12 +40,14 @@ "Max RSA size too big for Montgomery arithmetic"); int bssl::rsa_check_public_key(const RSA *rsa) { - if (rsa->n == nullptr) { + auto *impl = FromOpaque(rsa); + + if (impl->n == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } - unsigned n_bits = BN_num_bits(rsa->n); + unsigned n_bits = BN_num_bits(impl->n); if (n_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); return 0; @@ -57,24 +60,24 @@ // RSA moduli must be positive and odd. In addition to being necessary for RSA // in general, we cannot setup Montgomery reduction with even moduli. - if (!BN_is_odd(rsa->n) || BN_is_negative(rsa->n)) { + if (!BN_is_odd(impl->n) || BN_is_negative(impl->n)) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); return 0; } static const unsigned kMaxExponentBits = 33; - if (rsa->e != nullptr) { + if (impl->e != nullptr) { // Reject e = 1, negative e, and even e. e must be odd to be relatively // prime with phi(n). - unsigned e_bits = BN_num_bits(rsa->e); - if (e_bits < 2 || BN_is_negative(rsa->e) || !BN_is_odd(rsa->e)) { + unsigned e_bits = BN_num_bits(impl->e); + if (e_bits < 2 || BN_is_negative(impl->e) || !BN_is_odd(impl->e)) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } - if (rsa->flags & RSA_FLAG_LARGE_PUBLIC_EXPONENT) { + if (impl->flags & RSA_FLAG_LARGE_PUBLIC_EXPONENT) { // The caller has requested disabling DoS protections. Still, e must be // less than n. - if (BN_ucmp(rsa->n, rsa->e) <= 0) { + if (BN_ucmp(impl->n, impl->e) <= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } @@ -95,9 +98,9 @@ // The upper bound on |e_bits| and lower bound on |n_bits| imply e is // bounded by n. - assert(BN_ucmp(rsa->n, rsa->e) > 0); + assert(BN_ucmp(impl->n, impl->e) > 0); } - } else if (!(rsa->flags & RSA_FLAG_NO_PUBLIC_EXPONENT)) { + } else if (!(impl->flags & RSA_FLAG_NO_PUBLIC_EXPONENT)) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -124,7 +127,7 @@ // After this function has returned, |rsa| may not be changed. This is needed // because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified // it wrong (see https://github.com/openssl/openssl/issues/5158). -static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { +static int freeze_private_key(RSAImpl *rsa, BN_CTX *ctx) { CRYPTO_MUTEX_lock_read(&rsa->lock); int frozen = rsa->private_key_frozen; CRYPTO_MUTEX_unlock_read(&rsa->lock); @@ -222,23 +225,25 @@ } void bssl::rsa_invalidate_key(RSA *rsa) { - rsa->private_key_frozen = 0; + auto *impl = FromOpaque(rsa); - BN_MONT_CTX_free(rsa->mont_n); - rsa->mont_n = nullptr; - BN_MONT_CTX_free(rsa->mont_p); - rsa->mont_p = nullptr; - BN_MONT_CTX_free(rsa->mont_q); - rsa->mont_q = nullptr; + impl->private_key_frozen = 0; - BN_free(rsa->d_fixed); - rsa->d_fixed = nullptr; - BN_free(rsa->dmp1_fixed); - rsa->dmp1_fixed = nullptr; - BN_free(rsa->dmq1_fixed); - rsa->dmq1_fixed = nullptr; - BN_free(rsa->iqmp_mont); - rsa->iqmp_mont = nullptr; + BN_MONT_CTX_free(impl->mont_n); + impl->mont_n = nullptr; + BN_MONT_CTX_free(impl->mont_p); + impl->mont_p = nullptr; + BN_MONT_CTX_free(impl->mont_q); + impl->mont_q = nullptr; + + BN_free(impl->d_fixed); + impl->d_fixed = nullptr; + BN_free(impl->dmp1_fixed); + impl->dmp1_fixed = nullptr; + BN_free(impl->dmq1_fixed); + impl->dmq1_fixed = nullptr; + BN_free(impl->iqmp_mont); + impl->iqmp_mont = nullptr; } int bssl::rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, @@ -289,12 +294,15 @@ } -static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); +static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSAImpl *rsa, + BN_CTX *ctx); int bssl::rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { - if (rsa->n == nullptr || rsa->e == nullptr) { + auto *impl = FromOpaque(rsa); + + if (impl->n == nullptr || impl->e == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -342,14 +350,14 @@ goto err; } - if (BN_ucmp(f, rsa->n) >= 0) { + if (BN_ucmp(f, impl->n) >= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(), - rsa->mont_n)) { + if (!BN_MONT_CTX_set_locked(&impl->mont_n, &impl->lock, impl->n, ctx.get()) || + !BN_mod_exp_mont(result, f, impl->e, &impl->mont_n->N, ctx.get(), + impl->mont_n)) { goto err; } @@ -393,7 +401,9 @@ int bssl::rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { - if (rsa->n == nullptr || rsa->d == nullptr) { + auto *impl = FromOpaque(rsa); + + if (impl->n == nullptr || impl->d == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -410,25 +420,25 @@ } // The caller should have ensured this. - assert(len == BN_num_bytes(rsa->n)); + assert(len == BN_num_bytes(impl->n)); if (BN_bin2bn(in, len, f) == nullptr) { return 0; } // The input to the RSA private transform may be secret, but padding is // expected to construct a value within range, so we can leak this comparison. - if (constant_time_declassify_int(BN_ucmp(f, rsa->n) >= 0)) { + if (constant_time_declassify_int(BN_ucmp(f, impl->n) >= 0)) { // Usually the padding functions would catch this. OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); return 0; } - if (!freeze_private_key(rsa, ctx.get())) { + if (!freeze_private_key(impl, ctx.get())) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; } - if (rsa->e == nullptr && (rsa->flags & RSA_FLAG_NO_PUBLIC_EXPONENT) == 0) { + if (impl->e == nullptr && (impl->flags & RSA_FLAG_NO_PUBLIC_EXPONENT) == 0) { // Unless the private key was specifically created with an API like // |RSA_new_private_key_no_e|, don't allow RSA keys to be missing the public // exponent, which disables some fault attack mitigations. (It should not be @@ -437,19 +447,19 @@ return 0; } - if (rsa->p != nullptr && rsa->q != nullptr && rsa->e != nullptr && - rsa->dmp1 != nullptr && rsa->dmq1 != nullptr && rsa->iqmp != nullptr && - // Require that we can reduce |f| by |rsa->p| and |rsa->q| in constant + if (impl->p != nullptr && impl->q != nullptr && impl->e != nullptr && + impl->dmp1 != nullptr && impl->dmq1 != nullptr && impl->iqmp != nullptr && + // Require that we can reduce |f| by |impl->p| and |impl->q| in constant // time, which requires primes be the same size, rounded to the Montgomery // coefficient. (See |mod_montgomery|.) This is not required by RFC 8017, // but it is true for keys generated by us and all common implementations. - bn_less_than_montgomery_R(rsa->q, rsa->mont_p) && - bn_less_than_montgomery_R(rsa->p, rsa->mont_q)) { - if (!rsa_mod_exp_crt(result, f, rsa, ctx.get())) { + bn_less_than_montgomery_R(impl->q, impl->mont_p) && + bn_less_than_montgomery_R(impl->p, impl->mont_q)) { + if (!rsa_mod_exp_crt(result, f, impl, ctx.get())) { return 0; } - } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, - ctx.get(), rsa->mont_n)) { + } else if (!BN_mod_exp_mont_consttime(result, f, impl->d_fixed, impl->n, + ctx.get(), impl->mont_n)) { return 0; } @@ -463,11 +473,11 @@ // // This check is cheap assuming |e| is small, which we require in // |rsa_check_public_key|. - if (rsa->e != nullptr) { + if (impl->e != nullptr) { BIGNUM *vrfy = BN_CTX_get(ctx.get()); if (vrfy == nullptr || - !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx.get(), - rsa->mont_n) || + !BN_mod_exp_mont(vrfy, result, impl->e, impl->n, ctx.get(), + impl->mont_n) || !constant_time_declassify_int(BN_equal_consttime(vrfy, f))) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; @@ -479,7 +489,7 @@ // the result. // // See Falko Strenzke, "Manger's Attack revisited", ICICS 2010. - assert(result->width == rsa->mont_n->N.width); + assert(result->width == impl->mont_n->N.width); bn_assert_fits_in_bytes(result, len); if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); @@ -520,7 +530,8 @@ return 1; } -static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { +static int rsa_mod_exp_crt(BIGNUM *r0, const BIGNUM *I, RSAImpl *rsa, + BN_CTX *ctx) { assert(ctx != nullptr); assert(rsa->n != nullptr); @@ -559,7 +570,7 @@ !BN_mod_exp_mont_consttime(r0, r1, rsa->dmp1_fixed, p, ctx, rsa->mont_p) || // Compute r0 = r0 - m1 mod p. |m1| is reduced mod |q|, not |p|, so we - // just run |mod_montgomery| again for simplicity. This could be more + // just run |mod_montgomery| again for srsaicity. This could be more // efficient with more cases: if |p > q|, |m1| is already reduced. If // |p < q| but they have the same bit width, |bn_reduce_once| suffices. // However, compared to over 2048 Montgomery multiplications above, this @@ -724,7 +735,7 @@ // // This function returns one on success and zero on failure. It has a failure // probability of about 2^-20. -static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value, +static int rsa_generate_key_impl(RSAImpl *rsa, int bits, const BIGNUM *e_value, BN_GENCB *cb) { if (bits > OPENSSL_RSA_MAX_MODULUS_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); @@ -814,7 +825,7 @@ } // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-5. This differs - // from typical RSA implementations which use (p-1)*(q-1). + // from typical RSA rsaementations which use (p-1)*(q-1). // // Note this means the size of d might reveal information about p-1 and // q-1. However, we do operations with Chinese Remainder Theorem, so we only @@ -862,7 +873,7 @@ return 0; } - // Sanity-check that |rsa->n| has the specified size. This is implied by + // Sanity-check that |rsa->n| has the specified size. This is rsaied by // |generate_prime|'s bounds. if (BN_num_bits(rsa->n) != (unsigned)bits) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); @@ -892,7 +903,7 @@ *in = nullptr; } -static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, +static int RSA_generate_key_ex_maybe_fips(RSAImpl *rsa, int bits, const BIGNUM *e_value, BN_GENCB *cb, int check_fips) { boringssl_ensure_rsa_self_test(); @@ -902,7 +913,7 @@ return 0; } - UniquePtr<RSA> tmp; + UniquePtr<RSAImpl> tmp; // |rsa_generate_key_impl|'s 2^-20 failure probability is too high at scale, // so we run the FIPS algorithm four times, bringing it down to 2^-80. We @@ -912,7 +923,7 @@ do { ERR_clear_error(); // Generate into scratch space, to avoid leaving partial work on failure. - tmp.reset(RSA_new()); + tmp.reset(FromOpaque(RSA_new())); if (tmp == nullptr) { return 0; } @@ -955,7 +966,7 @@ int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e_value, BN_GENCB *cb) { - return RSA_generate_key_ex_maybe_fips(rsa, bits, e_value, cb, + return RSA_generate_key_ex_maybe_fips(FromOpaque(rsa), bits, e_value, cb, /*check_fips=*/0); } @@ -972,7 +983,8 @@ BIGNUM *e = BN_new(); int ret = e != nullptr && BN_set_word(e, RSA_F4) && - RSA_generate_key_ex_maybe_fips(rsa, bits, e, cb, /*check_fips=*/1); + RSA_generate_key_ex_maybe_fips(FromOpaque(rsa), bits, e, cb, + /*check_fips=*/1); BN_free(e); if (ret) {
diff --git a/crypto/fipsmodule/self_check/self_check.cc.inc b/crypto/fipsmodule/self_check/self_check.cc.inc index 2477f36..37da586 100644 --- a/crypto/fipsmodule/self_check/self_check.cc.inc +++ b/crypto/fipsmodule/self_check/self_check.cc.inc
@@ -192,7 +192,7 @@ 0x89, 0x29, 0xc7, 0x05, 0x27, 0x68, 0x90, 0x15, }; - RSA *rsa = RSA_new(); + RSAImpl *rsa = FromOpaque(RSA_new()); if (rsa == nullptr || // !set_bignum(&rsa->n, kN, sizeof(kN)) || !set_bignum(&rsa->e, kE, sizeof(kE)) ||
diff --git a/crypto/rsa/rsa_asn1.cc b/crypto/rsa/rsa_asn1.cc index 4b99643..93818b5 100644 --- a/crypto/rsa/rsa_asn1.cc +++ b/crypto/rsa/rsa_asn1.cc
@@ -54,7 +54,7 @@ } RSA *RSA_parse_public_key(CBS *cbs) { - RSA *ret = RSA_new(); + RSAImpl *ret = FromOpaque(RSA_new()); if (ret == nullptr) { return nullptr; } @@ -91,9 +91,9 @@ int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) { CBB child; + const RSAImpl *impl = FromOpaque(rsa); if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || - !marshal_integer(&child, rsa->n) || - !marshal_integer(&child, rsa->e) || + !marshal_integer(&child, impl->n) || !marshal_integer(&child, impl->e) || !CBB_flush(cbb)) { OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); return 0; @@ -120,7 +120,7 @@ static const uint64_t kVersionTwoPrime = 0; RSA *RSA_parse_private_key(CBS *cbs) { - RSA *ret = RSA_new(); + RSAImpl *ret = FromOpaque(RSA_new()); if (ret == nullptr) { return nullptr; } @@ -179,18 +179,16 @@ } int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) { + const RSAImpl *impl = FromOpaque(rsa); CBB child; if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&child, kVersionTwoPrime) || - !marshal_integer(&child, rsa->n) || - !marshal_integer(&child, rsa->e) || - !marshal_integer(&child, rsa->d) || - !marshal_integer(&child, rsa->p) || - !marshal_integer(&child, rsa->q) || - !marshal_integer(&child, rsa->dmp1) || - !marshal_integer(&child, rsa->dmq1) || - !marshal_integer(&child, rsa->iqmp) || - !CBB_flush(cbb)) { + !marshal_integer(&child, impl->n) || !marshal_integer(&child, impl->e) || + !marshal_integer(&child, impl->d) || !marshal_integer(&child, impl->p) || + !marshal_integer(&child, impl->q) || + !marshal_integer(&child, impl->dmp1) || + !marshal_integer(&child, impl->dmq1) || + !marshal_integer(&child, impl->iqmp) || !CBB_flush(cbb)) { OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); return 0; }
diff --git a/crypto/rsa/rsa_crypt.cc b/crypto/rsa/rsa_crypt.cc index aa1004d..68fb133 100644 --- a/crypto/rsa/rsa_crypt.cc +++ b/crypto/rsa/rsa_crypt.cc
@@ -342,7 +342,9 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { - if (rsa->n == nullptr || rsa->e == nullptr) { + auto *impl = FromOpaque(rsa); + + if (impl->n == nullptr || impl->e == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -396,15 +398,15 @@ goto err; } - if (BN_ucmp(f, rsa->n) >= 0) { + if (BN_ucmp(f, impl->n) >= 0) { // usually the padding functions would catch this OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(), - rsa->mont_n)) { + if (!BN_MONT_CTX_set_locked(&impl->mont_n, &impl->lock, impl->n, ctx.get()) || + !BN_mod_exp_mont(result, f, impl->e, &impl->mont_n->N, ctx.get(), + impl->mont_n)) { goto err; } @@ -490,8 +492,9 @@ int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { - if (rsa->meth->decrypt) { - return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + auto *impl = FromOpaque(rsa); + if (impl->meth->decrypt) { + return impl->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); } return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
diff --git a/crypto/rsa/rsa_test.cc b/crypto/rsa/rsa_test.cc index a0ded6f..bdee9a2 100644 --- a/crypto/rsa/rsa_test.cc +++ b/crypto/rsa/rsa_test.cc
@@ -34,6 +34,7 @@ #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/rsa/internal.h" #include "../internal.h" +#include "../mem_internal.h" #include "../test/test_data.h" #include "../test/test_util.h" @@ -576,7 +577,7 @@ } TEST(RSATest, GenerateFIPS) { - UniquePtr<RSA> rsa(RSA_new()); + UniquePtr<RSAImpl> rsa(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); // RSA_generate_key_fips may only be used for 2048-, 3072-, and 4096-bit @@ -595,7 +596,7 @@ for (const size_t bits : {2048, 3072, 4096}) { SCOPED_TRACE(bits); - rsa.reset(RSA_new()); + rsa.reset(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), bits, nullptr)); EXPECT_EQ(bits, BN_num_bits(rsa->n)); @@ -603,7 +604,7 @@ } TEST(RSATest, BadKey) { - UniquePtr<RSA> key(RSA_new()); + UniquePtr<RSAImpl> key(FromOpaque(RSA_new())); UniquePtr<BIGNUM> e(BN_new()); ASSERT_TRUE(key); ASSERT_TRUE(e); @@ -622,13 +623,14 @@ size_t der_len; ASSERT_TRUE(RSA_private_key_to_bytes(&der, &der_len, key.get())); UniquePtr<uint8_t> delete_der(der); - key.reset(RSA_private_key_from_bytes(der, der_len)); + key.reset(FromOpaque(RSA_private_key_from_bytes(der, der_len))); EXPECT_FALSE(key); } TEST(RSATest, ASN1) { // Test that private keys may be decoded. - UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + UniquePtr<RSAImpl> rsa( + FromOpaque(RSA_private_key_from_bytes(kKey1, sizeof(kKey1)))); ASSERT_TRUE(rsa); // Test that the serialization round-trips. @@ -643,7 +645,7 @@ delete_der.reset(der); // Public keys may be parsed back out. - rsa.reset(RSA_public_key_from_bytes(der, der_len)); + rsa.reset(FromOpaque(RSA_public_key_from_bytes(der, der_len))); ASSERT_TRUE(rsa); EXPECT_FALSE(rsa->p); EXPECT_FALSE(rsa->q); @@ -664,8 +666,8 @@ ERR_clear_error(); // Public keys with negative moduli are invalid. - rsa.reset( - RSA_public_key_from_bytes(kEstonianRSAKey, sizeof(kEstonianRSAKey))); + rsa.reset(FromOpaque( + RSA_public_key_from_bytes(kEstonianRSAKey, sizeof(kEstonianRSAKey)))); EXPECT_FALSE(rsa); ERR_clear_error(); } @@ -683,22 +685,22 @@ ASSERT_TRUE(e); ASSERT_TRUE(BN_set_word(e.get(), RSA_F4)); - UniquePtr<RSA> rsa(RSA_new()); + UniquePtr<RSAImpl> rsa(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_ex(rsa.get(), 1025, e.get(), nullptr)); EXPECT_EQ(1024u, BN_num_bits(rsa->n)); - rsa.reset(RSA_new()); + rsa.reset(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_ex(rsa.get(), 1027, e.get(), nullptr)); EXPECT_EQ(1024u, BN_num_bits(rsa->n)); - rsa.reset(RSA_new()); + rsa.reset(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_ex(rsa.get(), 1151, e.get(), nullptr)); EXPECT_EQ(1024u, BN_num_bits(rsa->n)); - rsa.reset(RSA_new()); + rsa.reset(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_ex(rsa.get(), 1152, e.get(), nullptr)); EXPECT_EQ(1152u, BN_num_bits(rsa->n)); @@ -750,7 +752,7 @@ "a54bb61ea5e64b9423102933ea100c12dad809fbf9589515e9d28e867f6b95c2d307f792" "cac28c6d7d23f441cb5b62798233db29b5cc0348"; - UniquePtr<RSA> rsa(RSA_new()); + UniquePtr<RSAImpl> rsa(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); // Missing n or e does not pass. @@ -895,7 +897,7 @@ } TEST(RSATest, KeygenFail) { - UniquePtr<RSA> rsa(RSA_new()); + UniquePtr<RSAImpl> rsa(FromOpaque(RSA_new())); ASSERT_TRUE(rsa); // Cause RSA key generation after a prime has been generated, to test that @@ -1195,7 +1197,8 @@ TEST(RSATest, LargeE) { // Test an RSA key with large e by swapping d and e in kKey1. // Since e is small, e mod (p-1) and e mod (q-1) will simply be e. - UniquePtr<RSA> key(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + UniquePtr<RSAImpl> key( + FromOpaque(RSA_private_key_from_bytes(kKey1, sizeof(kKey1)))); ASSERT_TRUE(key); const BIGNUM *n = RSA_get0_n(key.get()); const BIGNUM *e = RSA_get0_e(key.get()); @@ -1207,14 +1210,15 @@ // By default, the large exponent is not allowed as e. UniquePtr<RSA> pub(RSA_new_public_key(n, /*e=*/d)); EXPECT_FALSE(pub); - UniquePtr<RSA> priv(RSA_new_private_key(n, /*e=*/d, /*d=*/e, p, q, - /*dmp1=*/e, /*dmq1=*/e, iqmp)); + UniquePtr<RSAImpl> priv( + FromOpaque(RSA_new_private_key(n, /*e=*/d, /*d=*/e, p, q, + /*dmp1=*/e, /*dmq1=*/e, iqmp))); EXPECT_FALSE(priv); // Constructing such a key piecemeal also would not work. This was only // possible with private APIs, so when |RSA| is opaque, this case will be // impossible. - priv.reset(RSA_new()); + priv.reset(FromOpaque(RSA_new())); ASSERT_TRUE(priv); priv->n = BN_dup(n); ASSERT_TRUE(priv->n); @@ -1233,8 +1237,9 @@ // But the "large e" APIs tolerate it. pub.reset(RSA_new_public_key_large_e(n, /*e=*/d)); ASSERT_TRUE(pub); - priv.reset(RSA_new_private_key_large_e(n, /*e=*/d, /*d=*/e, p, q, /*dmp1=*/e, - /*dmq1=*/e, iqmp)); + priv.reset(FromOpaque(RSA_new_private_key_large_e(n, /*e=*/d, /*d=*/e, p, q, + /*dmp1=*/e, + /*dmq1=*/e, iqmp))); ASSERT_TRUE(priv); // Test that operations work correctly. @@ -1342,7 +1347,8 @@ #if defined(OPENSSL_THREADS) TEST(RSATest, Threads) { - UniquePtr<RSA> rsa_template(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + UniquePtr<RSAImpl> rsa_template( + FromOpaque(RSA_private_key_from_bytes(kKey1, sizeof(kKey1)))); ASSERT_TRUE(rsa_template); const uint8_t kDummyHash[32] = {0}; @@ -1354,7 +1360,7 @@ // RSA keys may be assembled piece-meal and then used in parallel between // threads, which requires internal locking to create some derived properties. - UniquePtr<RSA> rsa(RSA_new()); + UniquePtr<RSAImpl> rsa(FromOpaque(RSA_new())); rsa->n = BN_dup(rsa_template->n); ASSERT_TRUE(rsa->n); rsa->e = BN_dup(rsa_template->e);
diff --git a/util/audit_symbols.go b/util/audit_symbols.go index 586ed8f..9a9c9a9 100644 --- a/util/audit_symbols.go +++ b/util/audit_symbols.go
@@ -89,7 +89,6 @@ // TODO(crbug.com/42220000): Temporary symbols, to be eliminated. regexp.MustCompile(`.*ec_group_st.*`), regexp.MustCompile(`.*evp_pkey_st.*`), - regexp.MustCompile(`.*rsa_st.*`), } const (