Migrate DHImpl to RefCounted.

Bug: 42290295
Change-Id: I4c860b497070734b57521641a0bc06646a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/89190
Commit-Queue: Xiangfei Ding <xfding@google.com>
Reviewed-by: Xiangfei Ding <xfding@google.com>
diff --git a/crypto/fipsmodule/dh/dh.cc.inc b/crypto/fipsmodule/dh/dh.cc.inc
index f1370fd..2e4f75f 100644
--- a/crypto/fipsmodule/dh/dh.cc.inc
+++ b/crypto/fipsmodule/dh/dh.cc.inc
@@ -32,36 +32,28 @@
 
 using namespace bssl;
 
-DH *DH_new() {
-  DHImpl *dh = NewZeroed<DHImpl>();
-  if (dh == nullptr) {
-    return nullptr;
-  }
+DHImpl::DHImpl() : RefCounted(CheckSubClass()) {
+  CRYPTO_MUTEX_init(&method_mont_p_lock);
+}
 
-  CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
-  dh->references = 1;
-  return dh;
+DH *DH_new() { return New<DHImpl>(); }
+
+DHImpl::~DHImpl() {
+  BN_MONT_CTX_free(method_mont_p);
+  BN_clear_free(p);
+  BN_clear_free(g);
+  BN_clear_free(q);
+  BN_clear_free(pub_key);
+  BN_clear_free(priv_key);
+  CRYPTO_MUTEX_cleanup(&method_mont_p_lock);
 }
 
 void DH_free(DH *dh) {
   if (dh == nullptr) {
     return;
   }
-
   auto *impl = FromOpaque(dh);
-  if (!CRYPTO_refcount_dec_and_test_zero(&impl->references)) {
-    return;
-  }
-
-  BN_MONT_CTX_free(impl->method_mont_p);
-  BN_clear_free(impl->p);
-  BN_clear_free(impl->g);
-  BN_clear_free(impl->q);
-  BN_clear_free(impl->pub_key);
-  BN_clear_free(impl->priv_key);
-  CRYPTO_MUTEX_cleanup(&impl->method_mont_p_lock);
-
-  Delete(impl);
+  impl->DecRefInternal();
 }
 
 unsigned DH_bits(const DH *dh) {
@@ -413,7 +405,7 @@
 
 int DH_up_ref(DH *dh) {
   auto *impl = FromOpaque(dh);
-  CRYPTO_refcount_inc(&impl->references);
+  impl->UpRefInternal();
   return 1;
 }
 
diff --git a/crypto/fipsmodule/dh/internal.h b/crypto/fipsmodule/dh/internal.h
index 3ce9d13..fd5eed0 100644
--- a/crypto/fipsmodule/dh/internal.h
+++ b/crypto/fipsmodule/dh/internal.h
@@ -18,28 +18,33 @@
 #include <openssl/base.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 
 
 DECLARE_OPAQUE_STRUCT(dh_st, DHImpl)
 
 BSSL_NAMESPACE_BEGIN
 
-class DHImpl : public dh_st {
+class DHImpl : public dh_st, public RefCounted<DHImpl> {
  public:
-  BIGNUM *p;
-  BIGNUM *g;
-  BIGNUM *q;
-  BIGNUM *pub_key;   // g^x mod p
-  BIGNUM *priv_key;  // x
+  DHImpl();
+
+  BIGNUM *p = nullptr;
+  BIGNUM *g = nullptr;
+  BIGNUM *q = nullptr;
+  BIGNUM *pub_key = nullptr;   // g^x mod p
+  BIGNUM *priv_key = nullptr;  // x
 
   // priv_length contains the length, in bits, of the private value. If zero,
   // the private value will be the same length as |p|.
-  unsigned priv_length;
+  unsigned priv_length = 0;
 
   bssl::CRYPTO_MUTEX method_mont_p_lock;
-  BN_MONT_CTX *method_mont_p;
+  BN_MONT_CTX *method_mont_p = nullptr;
 
-  bssl::CRYPTO_refcount_t references;
+ private:
+  friend RefCounted;
+  ~DHImpl();
 };
 
 // dh_check_params_fast checks basic invariants on |dh|'s domain parameters. It