Migrate RSAImpl to RefCounted. Bug: 42290295 Change-Id: Iea6a067c6e473ac0944aabc2f286e40b6a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/89169 Reviewed-by: Xiangfei Ding <xfding@google.com> Commit-Queue: Xiangfei Ding <xfding@google.com>
diff --git a/crypto/fipsmodule/rsa/internal.h b/crypto/fipsmodule/rsa/internal.h index 46f3d1a..d8b4f1d 100644 --- a/crypto/fipsmodule/rsa/internal.h +++ b/crypto/fipsmodule/rsa/internal.h
@@ -21,6 +21,7 @@ #include <openssl/rsa.h> #include "../../internal.h" +#include "../../mem_internal.h" DECLARE_OPAQUE_STRUCT(rsa_st, RSAImpl) @@ -44,53 +45,54 @@ rsa_pss_sha512, }; -class RSAImpl : public rsa_st { +class RSAImpl : public rsa_st, public RefCounted<RSAImpl> { public: - static constexpr bool kAllowUniquePtr = true; - - ~RSAImpl(); + explicit RSAImpl(const ENGINE *engine); RSA_METHOD *meth; - BIGNUM *n; - BIGNUM *e; - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *dmp1; - BIGNUM *dmq1; - BIGNUM *iqmp; + BIGNUM *n = nullptr; + BIGNUM *e = nullptr; + BIGNUM *d = nullptr; + BIGNUM *p = nullptr; + BIGNUM *q = nullptr; + BIGNUM *dmp1 = nullptr; + BIGNUM *dmq1 = nullptr; + BIGNUM *iqmp = nullptr; // be careful using this if the RSA structure is shared - CRYPTO_EX_DATA ex_data; - bssl::CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data = {}; int flags; bssl::CRYPTO_MUTEX lock; // Used to cache montgomery values. The creation of these values is protected // by |lock|. - BN_MONT_CTX *mont_n; - BN_MONT_CTX *mont_p; - BN_MONT_CTX *mont_q; + BN_MONT_CTX *mont_n = nullptr; + BN_MONT_CTX *mont_p = nullptr; + BN_MONT_CTX *mont_q = nullptr; // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, // but with the correct widths to prevent side channels. These must use // separate copies due to threading concerns caused by OpenSSL's API // mistakes. See https://github.com/openssl/openssl/issues/5158 and // the |freeze_private_key| implementation. - BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; + BIGNUM *d_fixed = nullptr, *dmp1_fixed = nullptr, *dmq1_fixed = nullptr; // iqmp_mont is q^-1 mod p in Montgomery form, using |mont_p|. - BIGNUM *iqmp_mont; + BIGNUM *iqmp_mont = nullptr; // pss_params is the RSA-PSS parameters associated with the key. This is not // used by the low-level RSA implementation, just the EVP layer. - bssl::rsa_pss_params_t pss_params; + bssl::rsa_pss_params_t pss_params = {}; // 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 = 0; + + private: + friend RefCounted; + ~RSAImpl(); }; #define RSA_PKCS1_PADDING_SIZE 11
diff --git a/crypto/fipsmodule/rsa/rsa.cc.inc b/crypto/fipsmodule/rsa/rsa.cc.inc index a3e8fe0..b7b0857 100644 --- a/crypto/fipsmodule/rsa/rsa.cc.inc +++ b/crypto/fipsmodule/rsa/rsa.cc.inc
@@ -165,35 +165,33 @@ return rsa; } +RSAImpl::RSAImpl(const ENGINE *engine) + : RefCounted(CheckSubClass()), + meth(engine ? ENGINE_get_RSA_method(engine) : nullptr) { + if (meth == nullptr) { + meth = (RSA_METHOD *)RSA_default_method(); + } + METHOD_ref(meth); + flags = meth->flags; + CRYPTO_MUTEX_init(&lock); + CRYPTO_new_ex_data(&ex_data); +} + RSA *RSA_new() { return RSA_new_method(nullptr); } RSA *RSA_new_method(const ENGINE *engine) { - RSAImpl *rsa = NewZeroed<RSAImpl>(); + UniquePtr<RSAImpl> rsa(New<RSAImpl>(engine)); if (rsa == nullptr) { return nullptr; } - if (engine) { - rsa->meth = ENGINE_get_RSA_method(engine); - } - - if (rsa->meth == nullptr) { - rsa->meth = (RSA_METHOD *)RSA_default_method(); - } - METHOD_ref(rsa->meth); - - rsa->references = 1; - rsa->flags = rsa->meth->flags; - CRYPTO_MUTEX_init(&rsa->lock); - CRYPTO_new_ex_data(&rsa->ex_data); - - if (rsa->meth->init && !rsa->meth->init(rsa)) { + if (rsa->meth->init && !rsa->meth->init(rsa.get())) { + METHOD_unref(rsa->meth); rsa->meth = nullptr; - RSA_free(rsa); return nullptr; } - return rsa; + return rsa.release(); } RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n) { @@ -207,9 +205,6 @@ } 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); } @@ -235,15 +230,12 @@ } auto *impl = FromOpaque(rsa); - if (!CRYPTO_refcount_dec_and_test_zero(&impl->references)) { - return; - } - Delete(impl); + impl->DecRefInternal(); } int RSA_up_ref(RSA *rsa) { auto *impl = FromOpaque(rsa); - CRYPTO_refcount_inc(&impl->references); + impl->UpRefInternal(); return 1; }