Replace Scoped* heap types with bssl::UniquePtr.

Unlike the Scoped* types, bssl::UniquePtr is available to C++ users, and
offered for a large variety of types.  The 'extern "C++"' trick is used
to make the C++ bits digestible to C callers that wrap header files in
'extern "C"'.

Change-Id: Ifbca4c2997d6628e33028c7d7620c72aff0f862e
Reviewed-on: https://boringssl-review.googlesource.com/10521
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/API-CONVENTIONS.md b/API-CONVENTIONS.md
index 1129600..6ede00d 100644
--- a/API-CONVENTIONS.md
+++ b/API-CONVENTIONS.md
@@ -85,8 +85,8 @@
 compatibility, these functions return `int`, but callers may assume they always
 successfully return one because reference counts use saturating arithmetic.
 
-C++ consumers are recommended to use `std:unique_ptr` with a custom deallocator
-to manage heap-allocated objects.
+C++ consumers are recommended to use `bssl::UniquePtr` to manage heap-allocated
+objects.
 
 
 ### Stack-allocated types
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc
index 8b02442..77a1ee0 100644
--- a/crypto/asn1/asn1_test.cc
+++ b/crypto/asn1/asn1_test.cc
@@ -18,8 +18,6 @@
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 
-#include "../test/scoped_types.h"
-
 
 // kTag128 is an ASN.1 structure with a universal tag with number 128.
 static const uint8_t kTag128[] = {
@@ -42,7 +40,7 @@
 
 static bool TestLargeTags() {
   const uint8_t *p = kTag258;
-  ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
+  bssl::UniquePtr<ASN1_TYPE> obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
   if (obj) {
     fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
     return false;
diff --git a/crypto/bio/bio_test.cc b/crypto/bio/bio_test.cc
index d7be884..cbc4fde 100644
--- a/crypto/bio/bio_test.cc
+++ b/crypto/bio/bio_test.cc
@@ -41,7 +41,6 @@
 #include <algorithm>
 
 #include "../internal.h"
-#include "../test/scoped_types.h"
 
 
 #if !defined(OPENSSL_WINDOWS)
@@ -104,7 +103,7 @@
   char hostname[80];
   BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
                ntohs(sin.sin_port));
-  ScopedBIO bio(BIO_new_connect(hostname));
+  bssl::UniquePtr<BIO> bio(BIO_new_connect(hostname));
   if (!bio) {
     fprintf(stderr, "BIO_new_connect failed.\n");
     return false;
@@ -216,8 +215,8 @@
       if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
         return false;
       }
-      ScopedBIO bio1_scoper(bio1);
-      ScopedBIO bio2_scoper(bio2);
+      bssl::UniquePtr<BIO> bio1_scoper(bio1);
+      bssl::UniquePtr<BIO> bio2_scoper(bio2);
 
       total_write += BioWriteZeroCopyWrapper(
           bio1, bio1_application_send_buffer, kLengths[i]);
@@ -287,7 +286,7 @@
   // 256 (the size of the buffer) to ensure edge cases are correct.
   static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };
 
-  ScopedBIO bio(BIO_new(BIO_s_mem()));
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
   if (!bio) {
     fprintf(stderr, "BIO_new failed\n");
     return false;
@@ -331,7 +330,7 @@
 
 static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
                      size_t expected_len, size_t max_len) {
-  ScopedBIO bio(BIO_new_mem_buf(data, data_len));
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data, data_len));
 
   uint8_t *out;
   size_t out_len;
@@ -339,7 +338,7 @@
   if (!ok) {
     out = nullptr;
   }
-  ScopedOpenSSLBytes out_storage(out);
+  bssl::UniquePtr<uint8_t> out_storage(out);
 
   if (should_succeed != (ok == 1)) {
     return false;
@@ -369,7 +368,7 @@
   static const size_t kLargePayloadLen = 8000;
   static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
                                          kLargePayloadLen & 0xff};
-  ScopedOpenSSLBytes large(reinterpret_cast<uint8_t *>(
+  bssl::UniquePtr<uint8_t> large(reinterpret_cast<uint8_t *>(
       OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
   if (!large) {
     return false;
diff --git a/crypto/bn/bn_test.cc b/crypto/bn/bn_test.cc
index bb83a40..0867dec 100644
--- a/crypto/bn/bn_test.cc
+++ b/crypto/bn/bn_test.cc
@@ -81,30 +81,30 @@
 #include <utility>
 
 #include <openssl/bn.h>
+#include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
 #include "../internal.h"
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 #include "../test/test_util.h"
 
 
-static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
+static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
   BIGNUM *raw = NULL;
   int ret = BN_hex2bn(&raw, in);
   out->reset(raw);
   return ret;
 }
 
-static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *attribute) {
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
   std::string hex;
   if (!t->GetAttribute(&hex, attribute)) {
     return nullptr;
   }
 
-  ScopedBIGNUM ret;
+  bssl::UniquePtr<BIGNUM> ret;
   if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
     t->PrintLine("Could not decode '%s'.", hex.c_str());
     return nullptr;
@@ -113,7 +113,7 @@
 }
 
 static bool GetInt(FileTest *t, int *out, const char *attribute) {
-  ScopedBIGNUM ret = GetBIGNUM(t, attribute);
+  bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
   if (!ret) {
     return false;
   }
@@ -133,8 +133,8 @@
     return true;
   }
 
-  ScopedOpenSSLString expected_str(BN_bn2hex(expected));
-  ScopedOpenSSLString actual_str(BN_bn2hex(actual));
+  bssl::UniquePtr<char> expected_str(BN_bn2hex(expected));
+  bssl::UniquePtr<char> actual_str(BN_bn2hex(actual));
   if (!expected_str || !actual_str) {
     return false;
   }
@@ -147,14 +147,14 @@
 }
 
 static bool TestSum(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM b = GetBIGNUM(t, "B");
-  ScopedBIGNUM sum = GetBIGNUM(t, "Sum");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+  bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
   if (!a || !b || !sum) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_add(ret.get(), a.get(), b.get()) ||
       !ExpectBIGNUMsEqual(t, "A + B", sum.get(), ret.get()) ||
@@ -246,16 +246,16 @@
 }
 
 static bool TestLShift1(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM lshift1 = GetBIGNUM(t, "LShift1");
-  ScopedBIGNUM zero(BN_new());
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
+  bssl::UniquePtr<BIGNUM> zero(BN_new());
   if (!a || !lshift1 || !zero) {
     return false;
   }
 
   BN_zero(zero.get());
 
-  ScopedBIGNUM ret(BN_new()), two(BN_new()), remainder(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new()), two(BN_new()), remainder(BN_new());
   if (!ret || !two || !remainder ||
       !BN_set_word(two.get(), 2) ||
       !BN_add(ret.get(), a.get(), a.get()) ||
@@ -287,14 +287,14 @@
 }
 
 static bool TestLShift(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM lshift = GetBIGNUM(t, "LShift");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
   int n = 0;
   if (!a || !lshift || !GetInt(t, &n, "N")) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_lshift(ret.get(), a.get(), n) ||
       !ExpectBIGNUMsEqual(t, "A << N", lshift.get(), ret.get()) ||
@@ -307,14 +307,14 @@
 }
 
 static bool TestRShift(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM rshift = GetBIGNUM(t, "RShift");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
   int n = 0;
   if (!a || !rshift || !GetInt(t, &n, "N")) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_rshift(ret.get(), a.get(), n) ||
       !ExpectBIGNUMsEqual(t, "A >> N", rshift.get(), ret.get())) {
@@ -325,16 +325,16 @@
 }
 
 static bool TestSquare(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM square = GetBIGNUM(t, "Square");
-  ScopedBIGNUM zero(BN_new());
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
+  bssl::UniquePtr<BIGNUM> zero(BN_new());
   if (!a || !square || !zero) {
     return false;
   }
 
   BN_zero(zero.get());
 
-  ScopedBIGNUM ret(BN_new()), remainder(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
   if (!ret ||
       !BN_sqr(ret.get(), a.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A^2", square.get(), ret.get()) ||
@@ -354,7 +354,7 @@
 
   // BN_sqrt should fail on non-squares and negative numbers.
   if (!BN_is_zero(square.get())) {
-    ScopedBIGNUM tmp(BN_new());
+    bssl::UniquePtr<BIGNUM> tmp(BN_new());
     if (!tmp || !BN_copy(tmp.get(), square.get())) {
       return false;
     }
@@ -381,17 +381,17 @@
 }
 
 static bool TestProduct(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM b = GetBIGNUM(t, "B");
-  ScopedBIGNUM product = GetBIGNUM(t, "Product");
-  ScopedBIGNUM zero(BN_new());
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+  bssl::UniquePtr<BIGNUM> product = GetBIGNUM(t, "Product");
+  bssl::UniquePtr<BIGNUM> zero(BN_new());
   if (!a || !b || !product || !zero) {
     return false;
   }
 
   BN_zero(zero.get());
 
-  ScopedBIGNUM ret(BN_new()), remainder(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
   if (!ret || !remainder ||
       !BN_mul(ret.get(), a.get(), b.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A * B", product.get(), ret.get()) ||
@@ -408,15 +408,15 @@
 }
 
 static bool TestQuotient(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM b = GetBIGNUM(t, "B");
-  ScopedBIGNUM quotient = GetBIGNUM(t, "Quotient");
-  ScopedBIGNUM remainder = GetBIGNUM(t, "Remainder");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+  bssl::UniquePtr<BIGNUM> quotient = GetBIGNUM(t, "Quotient");
+  bssl::UniquePtr<BIGNUM> remainder = GetBIGNUM(t, "Remainder");
   if (!a || !b || !quotient || !remainder) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new()), ret2(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new()), ret2(BN_new());
   if (!ret || !ret2 ||
       !BN_div(ret.get(), ret2.get(), a.get(), b.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A / B", quotient.get(), ret.get()) ||
@@ -457,7 +457,7 @@
 
   // Test BN_nnmod.
   if (!BN_is_negative(b.get())) {
-    ScopedBIGNUM nnmod(BN_new());
+    bssl::UniquePtr<BIGNUM> nnmod(BN_new());
     if (!nnmod ||
         !BN_copy(nnmod.get(), remainder.get()) ||
         (BN_is_negative(nnmod.get()) &&
@@ -473,15 +473,15 @@
 }
 
 static bool TestModMul(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM b = GetBIGNUM(t, "B");
-  ScopedBIGNUM m = GetBIGNUM(t, "M");
-  ScopedBIGNUM mod_mul = GetBIGNUM(t, "ModMul");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+  bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+  bssl::UniquePtr<BIGNUM> mod_mul = GetBIGNUM(t, "ModMul");
   if (!a || !b || !m || !mod_mul) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_mod_mul(ret.get(), a.get(), b.get(), m.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A * B (mod M)", mod_mul.get(), ret.get())) {
@@ -490,8 +490,8 @@
 
   if (BN_is_odd(m.get())) {
     // Reduce |a| and |b| and test the Montgomery version.
-    ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
-    ScopedBIGNUM a_tmp(BN_new()), b_tmp(BN_new());
+    bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
+    bssl::UniquePtr<BIGNUM> a_tmp(BN_new()), b_tmp(BN_new());
     if (!mont || !a_tmp || !b_tmp ||
         !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
         !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
@@ -511,15 +511,15 @@
 }
 
 static bool TestModExp(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM e = GetBIGNUM(t, "E");
-  ScopedBIGNUM m = GetBIGNUM(t, "M");
-  ScopedBIGNUM mod_exp = GetBIGNUM(t, "ModExp");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
+  bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+  bssl::UniquePtr<BIGNUM> mod_exp = GetBIGNUM(t, "ModExp");
   if (!a || !e || !m || !mod_exp) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_mod_exp(ret.get(), a.get(), e.get(), m.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A ^ E (mod M)", mod_exp.get(), ret.get())) {
@@ -542,14 +542,14 @@
 }
 
 static bool TestExp(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM e = GetBIGNUM(t, "E");
-  ScopedBIGNUM exp = GetBIGNUM(t, "Exp");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
+  bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
   if (!a || !e || !exp) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_exp(ret.get(), a.get(), e.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "A ^ E", exp.get(), ret.get())) {
@@ -560,15 +560,15 @@
 }
 
 static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM p = GetBIGNUM(t, "P");
-  ScopedBIGNUM mod_sqrt = GetBIGNUM(t, "ModSqrt");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
+  bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
   if (!a || !p || !mod_sqrt) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
-  ScopedBIGNUM ret2(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret2(BN_new());
   if (!ret ||
       !ret2 ||
       !BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx) ||
@@ -586,14 +586,14 @@
 }
 
 static bool TestModInv(FileTest *t, BN_CTX *ctx) {
-  ScopedBIGNUM a = GetBIGNUM(t, "A");
-  ScopedBIGNUM m = GetBIGNUM(t, "M");
-  ScopedBIGNUM mod_inv = GetBIGNUM(t, "ModInv");
+  bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+  bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+  bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
   if (!a || !m || !mod_inv) {
     return false;
   }
 
-  ScopedBIGNUM ret(BN_new());
+  bssl::UniquePtr<BIGNUM> ret(BN_new());
   if (!ret ||
       !BN_mod_inverse(ret.get(), a.get(), m.get(), ctx) ||
       !ExpectBIGNUMsEqual(t, "inv(A) (mod M)", mod_inv.get(), ret.get())) {
@@ -650,7 +650,7 @@
   memset(zeros, 0, sizeof(zeros));
 
   // Test edge case at 0.
-  ScopedBIGNUM n(BN_new());
+  bssl::UniquePtr<BIGNUM> n(BN_new());
   if (!n || !BN_bn2bin_padded(NULL, 0, n.get())) {
     fprintf(stderr,
             "BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
@@ -713,7 +713,7 @@
   return true;
 }
 
-static int DecimalToBIGNUM(ScopedBIGNUM *out, const char *in) {
+static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
   BIGNUM *raw = NULL;
   int ret = BN_dec2bn(&raw, in);
   out->reset(raw);
@@ -721,7 +721,7 @@
 }
 
 static bool TestDec2BN(BN_CTX *ctx) {
-  ScopedBIGNUM bn;
+  bssl::UniquePtr<BIGNUM> bn;
   int ret = DecimalToBIGNUM(&bn, "0");
   if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
     fprintf(stderr, "BN_dec2bn gave a bad result.\n");
@@ -756,7 +756,7 @@
 }
 
 static bool TestHex2BN(BN_CTX *ctx) {
-  ScopedBIGNUM bn;
+  bssl::UniquePtr<BIGNUM> bn;
   int ret = HexToBIGNUM(&bn, "0");
   if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
     fprintf(stderr, "BN_hex2bn gave a bad result.\n");
@@ -790,16 +790,16 @@
   return true;
 }
 
-static ScopedBIGNUM ASCIIToBIGNUM(const char *in) {
+static bssl::UniquePtr<BIGNUM> ASCIIToBIGNUM(const char *in) {
   BIGNUM *raw = NULL;
   if (!BN_asc2bn(&raw, in)) {
     return nullptr;
   }
-  return ScopedBIGNUM(raw);
+  return bssl::UniquePtr<BIGNUM>(raw);
 }
 
 static bool TestASC2BN(BN_CTX *ctx) {
-  ScopedBIGNUM bn = ASCIIToBIGNUM("0");
+  bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("0");
   if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
     fprintf(stderr, "BN_asc2bn gave a bad result.\n");
     return false;
@@ -870,7 +870,7 @@
 
   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
     const MPITest &test = kMPITests[i];
-    ScopedBIGNUM bn(ASCIIToBIGNUM(test.base10));
+    bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
     const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
     if (mpi_len > sizeof(scratch)) {
       fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
@@ -892,7 +892,7 @@
       return false;
     }
 
-    ScopedBIGNUM bn2(BN_mpi2bn(scratch, mpi_len, NULL));
+    bssl::UniquePtr<BIGNUM> bn2(BN_mpi2bn(scratch, mpi_len, NULL));
     if (bn2.get() == nullptr) {
       fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
       return false;
@@ -908,7 +908,7 @@
 }
 
 static bool TestRand() {
-  ScopedBIGNUM bn(BN_new());
+  bssl::UniquePtr<BIGNUM> bn(BN_new());
   if (!bn) {
     return false;
   }
@@ -993,13 +993,13 @@
 
 static bool TestASN1() {
   for (const ASN1Test &test : kASN1Tests) {
-    ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
+    bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM(test.value_ascii);
     if (!bn) {
       return false;
     }
 
     // Test that the input is correctly parsed.
-    ScopedBIGNUM bn2(BN_new());
+    bssl::UniquePtr<BIGNUM> bn2(BN_new());
     if (!bn2) {
       return false;
     }
@@ -1025,7 +1025,7 @@
       CBB_cleanup(&cbb);
       return false;
     }
-    ScopedOpenSSLBytes delete_der(der);
+    bssl::UniquePtr<uint8_t> delete_der(der);
     if (der_len != test.der_len ||
         memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
       fprintf(stderr, "Bad serialization.\n");
@@ -1045,7 +1045,7 @@
   }
 
   for (const ASN1InvalidTest &test : kASN1InvalidTests) {
-    ScopedBIGNUM bn(BN_new());
+    bssl::UniquePtr<BIGNUM> bn(BN_new());
     if (!bn) {
       return false;
     }
@@ -1069,7 +1069,7 @@
 
   for (const ASN1Test &test : kASN1BuggyTests) {
     // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
-    ScopedBIGNUM bn(BN_new());
+    bssl::UniquePtr<BIGNUM> bn(BN_new());
     if (!bn) {
       return false;
     }
@@ -1083,7 +1083,7 @@
     ERR_clear_error();
 
     // However |BN_parse_asn1_unsigned_buggy| accepts them.
-    ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
+    bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
     if (!bn2) {
       return false;
     }
@@ -1101,7 +1101,7 @@
   }
 
   // Serializing negative numbers is not supported.
-  ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
+  bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("-1");
   if (!bn) {
     return false;
   }
@@ -1120,9 +1120,9 @@
 }
 
 static bool TestNegativeZero(BN_CTX *ctx) {
-  ScopedBIGNUM a(BN_new());
-  ScopedBIGNUM b(BN_new());
-  ScopedBIGNUM c(BN_new());
+  bssl::UniquePtr<BIGNUM> a(BN_new());
+  bssl::UniquePtr<BIGNUM> b(BN_new());
+  bssl::UniquePtr<BIGNUM> c(BN_new());
   if (!a || !b || !c) {
     return false;
   }
@@ -1142,7 +1142,7 @@
   }
 
   for (int consttime = 0; consttime < 2; consttime++) {
-    ScopedBIGNUM numerator(BN_new()), denominator(BN_new());
+    bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
     if (!numerator || !denominator) {
       return false;
     }
@@ -1190,8 +1190,8 @@
   // Test that forcibly creating a negative zero does not break |BN_bn2hex| or
   // |BN_bn2dec|.
   a->neg = 1;
-  ScopedOpenSSLString dec(BN_bn2dec(a.get()));
-  ScopedOpenSSLString hex(BN_bn2hex(a.get()));
+  bssl::UniquePtr<char> dec(BN_bn2dec(a.get()));
+  bssl::UniquePtr<char> hex(BN_bn2hex(a.get()));
   if (!dec || !hex ||
       strcmp(dec.get(), "-0") != 0 ||
       strcmp(hex.get(), "-0") != 0) {
@@ -1203,10 +1203,10 @@
 }
 
 static bool TestBadModulus(BN_CTX *ctx) {
-  ScopedBIGNUM a(BN_new());
-  ScopedBIGNUM b(BN_new());
-  ScopedBIGNUM zero(BN_new());
-  ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
+  bssl::UniquePtr<BIGNUM> a(BN_new());
+  bssl::UniquePtr<BIGNUM> b(BN_new());
+  bssl::UniquePtr<BIGNUM> zero(BN_new());
+  bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
   if (!a || !b || !zero || !mont) {
     return false;
   }
@@ -1290,7 +1290,7 @@
 
 // TestExpModZero tests that 1**0 mod 1 == 0.
 static bool TestExpModZero() {
-  ScopedBIGNUM zero(BN_new()), a(BN_new()), r(BN_new());
+  bssl::UniquePtr<BIGNUM> zero(BN_new()), a(BN_new()), r(BN_new());
   if (!zero || !a || !r ||
       !BN_rand(a.get(), 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
     return false;
@@ -1317,7 +1317,7 @@
 static bool TestSmallPrime(BN_CTX *ctx) {
   static const unsigned kBits = 10;
 
-  ScopedBIGNUM r(BN_new());
+  bssl::UniquePtr<BIGNUM> r(BN_new());
   if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
                                   NULL, NULL)) {
     return false;
@@ -1334,7 +1334,7 @@
 static bool TestCmpWord() {
   static const BN_ULONG kMaxWord = (BN_ULONG)-1;
 
-  ScopedBIGNUM r(BN_new());
+  bssl::UniquePtr<BIGNUM> r(BN_new());
   if (!r ||
       !BN_set_word(r.get(), 0)) {
     return false;
@@ -1416,13 +1416,13 @@
   };
 
   for (const char *test : kBN2DecTests) {
-    ScopedBIGNUM bn;
+    bssl::UniquePtr<BIGNUM> bn;
     int ret = DecimalToBIGNUM(&bn, test);
     if (ret == 0) {
       return false;
     }
 
-    ScopedOpenSSLString dec(BN_bn2dec(bn.get()));
+    bssl::UniquePtr<char> dec(BN_bn2dec(bn.get()));
     if (!dec) {
       fprintf(stderr, "BN_bn2dec failed on %s.\n", test);
       return false;
@@ -1445,7 +1445,7 @@
     return 1;
   }
 
-  ScopedBN_CTX ctx(BN_CTX_new());
+  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
   if (!ctx) {
     return 1;
   }
diff --git a/crypto/bytestring/bytestring_test.cc b/crypto/bytestring/bytestring_test.cc
index f567fd0..45a2335 100644
--- a/crypto/bytestring/bytestring_test.cc
+++ b/crypto/bytestring/bytestring_test.cc
@@ -27,7 +27,6 @@
 
 #include "internal.h"
 #include "../internal.h"
-#include "../test/scoped_types.h"
 
 namespace bssl {
 
@@ -294,7 +293,7 @@
     return false;
   }
 
-  ScopedOpenSSLBytes scoper(buf);
+  bssl::UniquePtr<uint8_t> scoper(buf);
   return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
 }
 
@@ -345,7 +344,7 @@
     CBB_cleanup(&cbb);
     return false;
   }
-  ScopedOpenSSLBytes scoper(out_buf);
+  bssl::UniquePtr<uint8_t> scoper(out_buf);
   return out_size == 1 && out_buf[0] == 0;
 }
 
@@ -378,7 +377,7 @@
     return false;
   }
 
-  ScopedOpenSSLBytes scoper(buf);
+  bssl::UniquePtr<uint8_t> scoper(buf);
   return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
 }
 
@@ -418,7 +417,7 @@
   if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
     return false;
   }
-  ScopedOpenSSLBytes scoper(buf);
+  bssl::UniquePtr<uint8_t> scoper(buf);
 
   static const uint8_t kExpected[] = {
         0xaa,
@@ -464,7 +463,7 @@
     CBB_cleanup(&cbb);
     return false;
   }
-  ScopedOpenSSLBytes scoper(buf);
+  bssl::UniquePtr<uint8_t> scoper(buf);
 
   if (buf_len != 3 ||
       memcmp(buf, "\x01\x01\x02", 3) != 0) {
@@ -488,7 +487,7 @@
     CBB_cleanup(&cbb);
     return false;
   }
-  ScopedOpenSSLBytes scoper(buf);
+  bssl::UniquePtr<uint8_t> scoper(buf);
 
   if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
     return false;
@@ -563,7 +562,7 @@
     fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
     return false;
   }
-  ScopedOpenSSLBytes scoper(out);
+  bssl::UniquePtr<uint8_t> scoper(out);
 
   if (out == NULL) {
     if (ber_len != der_len ||
@@ -676,7 +675,7 @@
     int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
                                           CBS_ASN1_CONTEXT_SPECIFIC | 0,
                                           CBS_ASN1_OCTETSTRING);
-    ScopedOpenSSLBytes scoper(storage);
+    bssl::UniquePtr<uint8_t> scoper(storage);
 
     if (static_cast<bool>(ok) != test.ok) {
       fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
@@ -754,7 +753,7 @@
       CBB_cleanup(&cbb);
       return false;
     }
-    ScopedOpenSSLBytes scoper(out);
+    bssl::UniquePtr<uint8_t> scoper(out);
     if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) {
       return false;
     }
diff --git a/crypto/cmac/cmac_test.cc b/crypto/cmac/cmac_test.cc
index 2496f2a..7cb1df5 100644
--- a/crypto/cmac/cmac_test.cc
+++ b/crypto/cmac/cmac_test.cc
@@ -16,9 +16,10 @@
 
 #include <algorithm>
 
+#include <openssl/cipher.h>
 #include <openssl/cmac.h>
+#include <openssl/mem.h>
 
-#include "../test/scoped_types.h"
 #include "../test/test_util.h"
 
 
@@ -43,7 +44,7 @@
     return 0;
   }
 
-  ScopedCMAC_CTX ctx(CMAC_CTX_new());
+  bssl::UniquePtr<CMAC_CTX> ctx(CMAC_CTX_new());
   if (!ctx || !CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
     fprintf(stderr, "%s: CMAC_Init failed.\n", name);
     return 0;
diff --git a/crypto/curve25519/spake25519_test.cc b/crypto/curve25519/spake25519_test.cc
index d97a860..363b60c 100644
--- a/crypto/curve25519/spake25519_test.cc
+++ b/crypto/curve25519/spake25519_test.cc
@@ -19,18 +19,17 @@
 #include <string.h>
 
 #include <openssl/curve25519.h>
-#include "../test/scoped_types.h"
 
 
 struct SPAKE2Run {
   bool Run() {
-    ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(
+    bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(
         spake2_role_alice,
         reinterpret_cast<const uint8_t *>(alice_names.first.data()),
         alice_names.first.size(),
         reinterpret_cast<const uint8_t *>(alice_names.second.data()),
         alice_names.second.size()));
-    ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(
+    bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(
         spake2_role_bob,
         reinterpret_cast<const uint8_t *>(bob_names.first.data()),
         bob_names.first.size(),
diff --git a/crypto/dh/dh_test.cc b/crypto/dh/dh_test.cc
index b8bfe46..12984e6 100644
--- a/crypto/dh/dh_test.cc
+++ b/crypto/dh/dh_test.cc
@@ -64,11 +64,10 @@
 #include <openssl/bn.h>
 #include <openssl/c++/bytestring.h>
 #include <openssl/crypto.h>
+#include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
-#include "../test/scoped_types.h"
-
 namespace bssl {
 
 static bool RunBasicTests();
@@ -115,7 +114,7 @@
 static bool RunBasicTests() {
   BN_GENCB cb;
   BN_GENCB_set(&cb, &GenerateCallback, stdout);
-  ScopedDH a(DH_new());
+  bssl::UniquePtr<DH> a(DH_new());
   if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) {
     return false;
   }
@@ -143,7 +142,7 @@
   BN_print_fp(stdout, a->g);
   printf("\n");
 
-  ScopedDH b(DH_new());
+  bssl::UniquePtr<DH> b(DH_new());
   if (!b) {
     return false;
   }
@@ -437,8 +436,8 @@
   for (unsigned i = 0; i < sizeof(kRFCTestData) / sizeof(RFC5114TestData); i++) {
     const RFC5114TestData *td = kRFCTestData + i;
     /* Set up DH structures setting key components */
-    ScopedDH dhA(td->get_param(nullptr));
-    ScopedDH dhB(td->get_param(nullptr));
+    bssl::UniquePtr<DH> dhA(td->get_param(nullptr));
+    bssl::UniquePtr<DH> dhB(td->get_param(nullptr));
     if (!dhA || !dhB) {
       fprintf(stderr, "Initialisation error RFC5114 set %u\n", i + 1);
       return false;
@@ -513,8 +512,8 @@
 };
 
 static bool TestBadY() {
-  ScopedDH dh(DH_get_2048_224(nullptr));
-  ScopedBIGNUM pub_key(
+  bssl::UniquePtr<DH> dh(DH_get_2048_224(nullptr));
+  bssl::UniquePtr<BIGNUM> pub_key(
       BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
   if (!dh || !pub_key || !DH_generate_key(dh.get())) {
     return false;
@@ -544,7 +543,7 @@
   if (!BN_hex2bn(&hex_bn, hex)) {
     return false;
   }
-  ScopedBIGNUM free_hex_bn(hex_bn);
+  bssl::UniquePtr<BIGNUM> free_hex_bn(hex_bn);
   return BN_cmp(bn, hex_bn) == 0;
 }
 
@@ -560,7 +559,7 @@
 
   CBS cbs;
   CBS_init(&cbs, kParams, sizeof(kParams));
-  ScopedDH dh(DH_parse_parameters(&cbs));
+  bssl::UniquePtr<DH> dh(DH_parse_parameters(&cbs));
   if (!dh || CBS_len(&cbs) != 0 ||
       !BIGNUMEqualsHex(
           dh->p,
@@ -577,7 +576,7 @@
       !CBB_finish(cbb.get(), &der, &der_len)) {
     return false;
   }
-  ScopedOpenSSLBytes free_der(der);
+  bssl::UniquePtr<uint8_t> free_der(der);
   if (der_len != sizeof(kParams) || memcmp(der, kParams, der_len) != 0) {
     return false;
   }
@@ -619,7 +618,7 @@
       !CBB_finish(cbb.get(), &der, &der_len)) {
     return false;
   }
-  ScopedOpenSSLBytes free_der2(der);
+  bssl::UniquePtr<uint8_t> free_der2(der);
   if (der_len != sizeof(kParamsDSA) || memcmp(der, kParamsDSA, der_len) != 0) {
     return false;
   }
@@ -628,7 +627,7 @@
 }
 
 static bool TestRFC3526() {
-  ScopedBIGNUM bn(BN_get_rfc3526_prime_1536(nullptr));
+  bssl::UniquePtr<BIGNUM> bn(BN_get_rfc3526_prime_1536(nullptr));
   if (!bn) {
     return false;
   }
diff --git a/crypto/ec/ec_test.cc b/crypto/ec/ec_test.cc
index ca0e140..9648d57 100644
--- a/crypto/ec/ec_test.cc
+++ b/crypto/ec/ec_test.cc
@@ -18,12 +18,13 @@
 #include <vector>
 
 #include <openssl/c++/bytestring.h>
+#include <openssl/bn.h>
 #include <openssl/crypto.h>
 #include <openssl/ec_key.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
+#include <openssl/nid.h>
 
-#include "../test/scoped_types.h"
 
 namespace bssl {
 
@@ -97,10 +98,11 @@
 
 // DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
 // result or nullptr on error.
-static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
+static bssl::UniquePtr<EC_KEY> DecodeECPrivateKey(const uint8_t *in,
+                                                  size_t in_len) {
   CBS cbs;
   CBS_init(&cbs, in, in_len);
-  ScopedEC_KEY ret(EC_KEY_parse_private_key(&cbs, NULL));
+  bssl::UniquePtr<EC_KEY> ret(EC_KEY_parse_private_key(&cbs, NULL));
   if (!ret || CBS_len(&cbs) != 0) {
     return nullptr;
   }
@@ -124,7 +126,7 @@
 }
 
 static bool Testd2i_ECPrivateKey() {
-  ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithoutPublic,
+  bssl::UniquePtr<EC_KEY> key = DecodeECPrivateKey(kECKeyWithoutPublic,
                                         sizeof(kECKeyWithoutPublic));
   if (!key) {
     fprintf(stderr, "Failed to parse private key.\n");
@@ -152,8 +154,8 @@
     return false;
   }
 
-  ScopedBIGNUM x(BN_new());
-  ScopedBIGNUM y(BN_new());
+  bssl::UniquePtr<BIGNUM> x(BN_new());
+  bssl::UniquePtr<BIGNUM> y(BN_new());
   if (!x || !y) {
     return false;
   }
@@ -162,8 +164,8 @@
     fprintf(stderr, "Failed to get public key in affine coordinates.\n");
     return false;
   }
-  ScopedOpenSSLString x_hex(BN_bn2hex(x.get()));
-  ScopedOpenSSLString y_hex(BN_bn2hex(y.get()));
+  bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get()));
+  bssl::UniquePtr<char> y_hex(BN_bn2hex(y.get()));
   if (!x_hex || !y_hex) {
     return false;
   }
@@ -182,7 +184,7 @@
 
 static bool TestZeroPadding() {
   // Check that the correct encoding round-trips.
-  ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithZeros,
+  bssl::UniquePtr<EC_KEY> key = DecodeECPrivateKey(kECKeyWithZeros,
                                         sizeof(kECKeyWithZeros));
   std::vector<uint8_t> out;
   if (!key || !EncodeECPrivateKey(&out, key.get())) {
@@ -214,7 +216,7 @@
 
 static bool TestSpecifiedCurve() {
   // Test keys with specified curves may be decoded.
-  ScopedEC_KEY key =
+  bssl::UniquePtr<EC_KEY> key =
       DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
   if (!key) {
     ERR_print_errors_fp(stderr);
@@ -245,7 +247,7 @@
 }
 
 static bool TestSetAffine(const int nid) {
-  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
   if (!key) {
     return false;
   }
@@ -265,8 +267,8 @@
     return false;
   }
 
-  ScopedBIGNUM x(BN_new());
-  ScopedBIGNUM y(BN_new());
+  bssl::UniquePtr<BIGNUM> x(BN_new());
+  bssl::UniquePtr<BIGNUM> y(BN_new());
   if (!EC_POINT_get_affine_coordinates_GFp(group,
                                            EC_KEY_get0_public_key(key.get()),
                                            x.get(), y.get(), nullptr)) {
@@ -276,7 +278,7 @@
     return false;
   }
 
-  ScopedEC_POINT point(EC_POINT_new(group));
+  auto point = bssl::UniquePtr<EC_POINT>(EC_POINT_new(group));
   if (!point) {
     return false;
   }
@@ -294,7 +296,7 @@
     return false;
   }
 
-  ScopedEC_POINT invalid_point(EC_POINT_new(group));
+  bssl::UniquePtr<EC_POINT> invalid_point(EC_POINT_new(group));
   if (!invalid_point) {
     return false;
   }
@@ -314,7 +316,7 @@
 
 static bool TestArbitraryCurve() {
   // Make a P-256 key and extract the affine coordinates.
-  ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
   if (!key || !EC_KEY_generate_key(key.get())) {
     return false;
   }
@@ -350,25 +352,25 @@
       0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
       0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
   };
-  ScopedBN_CTX ctx(BN_CTX_new());
-  ScopedBIGNUM p(BN_bin2bn(kP, sizeof(kP), nullptr));
-  ScopedBIGNUM a(BN_bin2bn(kA, sizeof(kA), nullptr));
-  ScopedBIGNUM b(BN_bin2bn(kB, sizeof(kB), nullptr));
-  ScopedBIGNUM gx(BN_bin2bn(kX, sizeof(kX), nullptr));
-  ScopedBIGNUM gy(BN_bin2bn(kY, sizeof(kY), nullptr));
-  ScopedBIGNUM order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
-  ScopedBIGNUM cofactor(BN_new());
+  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+  bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
+  bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
+  bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
+  bssl::UniquePtr<BIGNUM> gx(BN_bin2bn(kX, sizeof(kX), nullptr));
+  bssl::UniquePtr<BIGNUM> gy(BN_bin2bn(kY, sizeof(kY), nullptr));
+  bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+  bssl::UniquePtr<BIGNUM> cofactor(BN_new());
   if (!ctx || !p || !a || !b || !gx || !gy || !order || !cofactor ||
       !BN_set_word(cofactor.get(), 1)) {
     return false;
   }
 
-  ScopedEC_GROUP group(
+  bssl::UniquePtr<EC_GROUP> group(
       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
   if (!group) {
     return false;
   }
-  ScopedEC_POINT generator(EC_POINT_new(group.get()));
+  bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
   if (!generator ||
       !EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
                                            gx.get(), gy.get(), ctx.get()) ||
@@ -383,9 +385,9 @@
   }
 
   // Copy |key| to |key2| using |group|.
-  ScopedEC_KEY key2(EC_KEY_new());
-  ScopedEC_POINT point(EC_POINT_new(group.get()));
-  ScopedBIGNUM x(BN_new()), y(BN_new());
+  bssl::UniquePtr<EC_KEY> key2(EC_KEY_new());
+  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group.get()));
+  bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
   if (!key2 || !point || !x || !y ||
       !EC_KEY_set_group(key2.get(), group.get()) ||
       !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
@@ -409,7 +411,7 @@
 }
 
 static bool TestAddingEqualPoints(int nid) {
-  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
   if (!key) {
     return false;
   }
@@ -422,10 +424,10 @@
     return false;
   }
 
-  ScopedEC_POINT p1(EC_POINT_new(group));
-  ScopedEC_POINT p2(EC_POINT_new(group));
-  ScopedEC_POINT double_p1(EC_POINT_new(group));
-  ScopedEC_POINT p1_plus_p2(EC_POINT_new(group));
+  bssl::UniquePtr<EC_POINT> p1(EC_POINT_new(group));
+  bssl::UniquePtr<EC_POINT> p2(EC_POINT_new(group));
+  bssl::UniquePtr<EC_POINT> double_p1(EC_POINT_new(group));
+  bssl::UniquePtr<EC_POINT> p1_plus_p2(EC_POINT_new(group));
   if (!p1 || !p2 || !double_p1 || !p1_plus_p2) {
     return false;
   }
@@ -437,7 +439,7 @@
     return false;
   }
 
-  ScopedBN_CTX ctx(BN_CTX_new());
+  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
   if (!ctx) {
     return false;
   }
diff --git a/crypto/ecdh/ecdh_test.cc b/crypto/ecdh/ecdh_test.cc
index 95f1402..a02fd22 100644
--- a/crypto/ecdh/ecdh_test.cc
+++ b/crypto/ecdh/ecdh_test.cc
@@ -21,59 +21,60 @@
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
 #include <openssl/ecdh.h>
+#include <openssl/nid.h>
 
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 
 
-static ScopedEC_GROUP GetCurve(FileTest *t, const char *key) {
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
   std::string curve_name;
   if (!t->GetAttribute(&curve_name, key)) {
     return nullptr;
   }
 
   if (curve_name == "P-224") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp224r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
   }
   if (curve_name == "P-256") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(
+        NID_X9_62_prime256v1));
   }
   if (curve_name == "P-384") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp384r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
   }
   if (curve_name == "P-521") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp521r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
   }
 
   t->PrintLine("Unknown curve '%s'", curve_name.c_str());
   return nullptr;
 }
 
-static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *key) {
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
   std::vector<uint8_t> bytes;
   if (!t->GetBytes(&bytes, key)) {
     return nullptr;
   }
 
-  return ScopedBIGNUM(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+  return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
 }
 
 static bool TestECDH(FileTest *t, void *arg) {
-  ScopedEC_GROUP group = GetCurve(t, "Curve");
-  ScopedBIGNUM priv_key = GetBIGNUM(t, "Private");
-  ScopedBIGNUM x = GetBIGNUM(t, "X");
-  ScopedBIGNUM y = GetBIGNUM(t, "Y");
-  ScopedBIGNUM peer_x = GetBIGNUM(t, "PeerX");
-  ScopedBIGNUM peer_y = GetBIGNUM(t, "PeerY");
+  bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+  bssl::UniquePtr<BIGNUM> priv_key = GetBIGNUM(t, "Private");
+  bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+  bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+  bssl::UniquePtr<BIGNUM> peer_x = GetBIGNUM(t, "PeerX");
+  bssl::UniquePtr<BIGNUM> peer_y = GetBIGNUM(t, "PeerY");
   std::vector<uint8_t> z;
   if (!group || !priv_key || !x || !y || !peer_x || !peer_y ||
       !t->GetBytes(&z, "Z")) {
     return false;
   }
 
-  ScopedEC_KEY key(EC_KEY_new());
-  ScopedEC_POINT pub_key(EC_POINT_new(group.get()));
-  ScopedEC_POINT peer_pub_key(EC_POINT_new(group.get()));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+  bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
+  bssl::UniquePtr<EC_POINT> peer_pub_key(EC_POINT_new(group.get()));
   if (!key || !pub_key || !peer_pub_key ||
       !EC_KEY_set_group(key.get(), group.get()) ||
       !EC_KEY_set_private_key(key.get(), priv_key.get()) ||
diff --git a/crypto/ecdsa/ecdsa_sign_test.cc b/crypto/ecdsa/ecdsa_sign_test.cc
index 683f0f0..ee95773 100644
--- a/crypto/ecdsa/ecdsa_sign_test.cc
+++ b/crypto/ecdsa/ecdsa_sign_test.cc
@@ -21,59 +21,60 @@
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
 #include <openssl/ecdsa.h>
+#include <openssl/nid.h>
 
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 
 
-static ScopedEC_GROUP GetCurve(FileTest *t, const char *key) {
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
   std::string curve_name;
   if (!t->GetAttribute(&curve_name, key)) {
     return nullptr;
   }
 
   if (curve_name == "P-224") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp224r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
   }
   if (curve_name == "P-256") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    return bssl::UniquePtr<EC_GROUP>(
+        EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
   }
   if (curve_name == "P-384") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp384r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
   }
   if (curve_name == "P-521") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp521r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
   }
 
   t->PrintLine("Unknown curve '%s'", curve_name.c_str());
   return nullptr;
 }
 
-static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *key) {
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
   std::vector<uint8_t> bytes;
   if (!t->GetBytes(&bytes, key)) {
     return nullptr;
   }
 
-  return ScopedBIGNUM(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+  return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
 }
 
 static bool TestECDSASign(FileTest *t, void *arg) {
-  ScopedEC_GROUP group = GetCurve(t, "Curve");
-  ScopedBIGNUM priv_key = GetBIGNUM(t, "Private");
-  ScopedBIGNUM x = GetBIGNUM(t, "X");
-  ScopedBIGNUM y = GetBIGNUM(t, "Y");
-  ScopedBIGNUM k = GetBIGNUM(t, "K");
-  ScopedBIGNUM r = GetBIGNUM(t, "R");
-  ScopedBIGNUM s = GetBIGNUM(t, "S");
+  bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+  bssl::UniquePtr<BIGNUM> priv_key = GetBIGNUM(t, "Private");
+  bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+  bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+  bssl::UniquePtr<BIGNUM> k = GetBIGNUM(t, "K");
+  bssl::UniquePtr<BIGNUM> r = GetBIGNUM(t, "R");
+  bssl::UniquePtr<BIGNUM> s = GetBIGNUM(t, "S");
   std::vector<uint8_t> digest;
   if (!group || !priv_key || !x || !y || !k || !r || !s ||
       !t->GetBytes(&digest, "Digest")) {
     return false;
   }
 
-  ScopedEC_KEY key(EC_KEY_new());
-  ScopedEC_POINT pub_key(EC_POINT_new(group.get()));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+  bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
   if (!key || !pub_key ||
       !EC_KEY_set_group(key.get(), group.get()) ||
       !EC_KEY_set_private_key(key.get(), priv_key.get()) ||
@@ -85,15 +86,15 @@
   }
 
   // |ECDSA_do_sign_ex| expects |k| to already be inverted.
-  ScopedBN_CTX ctx(BN_CTX_new());
+  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
   if (!ctx ||
       !BN_mod_inverse(k.get(), k.get(), EC_GROUP_get0_order(group.get()),
                       ctx.get())) {
     return false;
   }
 
-  ScopedECDSA_SIG sig(ECDSA_do_sign_ex(digest.data(), digest.size(), k.get(),
-                                       r.get(), key.get()));
+  bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign_ex(digest.data(), digest.size(), k.get(),
+                                 r.get(), key.get()));
   if (!sig) {
     return false;
   }
diff --git a/crypto/ecdsa/ecdsa_test.cc b/crypto/ecdsa/ecdsa_test.cc
index 8d7827d..7c68de4 100644
--- a/crypto/ecdsa/ecdsa_test.cc
+++ b/crypto/ecdsa/ecdsa_test.cc
@@ -62,8 +62,6 @@
 #include <openssl/nid.h>
 #include <openssl/rand.h>
 
-#include "../test/scoped_types.h"
-
 enum Api {
   kEncodedApi,
   kRawApi,
@@ -82,7 +80,7 @@
       if (!ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig)) {
         return false;
       }
-      ScopedOpenSSLBytes delete_der(der);
+      bssl::UniquePtr<uint8_t> delete_der(der);
       actual_result = ECDSA_verify(0, digest, digest_len, der, der_len, eckey);
       break;
     }
@@ -171,7 +169,7 @@
     fprintf(out, "%s: ", kCurves[n].name);
 
     int nid = kCurves[n].nid;
-    ScopedEC_GROUP group(EC_GROUP_new_by_curve_name(nid));
+    bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid));
     if (!group) {
       fprintf(out, " failed\n");
       return false;
@@ -184,14 +182,14 @@
     }
 
     // Create a new ECDSA key.
-    ScopedEC_KEY eckey(EC_KEY_new());
+    bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
     if (!eckey || !EC_KEY_set_group(eckey.get(), group.get()) ||
         !EC_KEY_generate_key(eckey.get())) {
       fprintf(out, " failed\n");
       return false;
     }
     // Create a second key.
-    ScopedEC_KEY wrong_eckey(EC_KEY_new());
+    bssl::UniquePtr<EC_KEY> wrong_eckey(EC_KEY_new());
     if (!wrong_eckey || !EC_KEY_set_group(wrong_eckey.get(), group.get()) ||
         !EC_KEY_generate_key(wrong_eckey.get())) {
       fprintf(out, " failed\n");
@@ -253,7 +251,7 @@
     fprintf(out, ".");
     fflush(out);
     // Verify a tampered signature.
-    ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes(
+    bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(ECDSA_SIG_from_bytes(
         signature.data(), signature.size()));
     if (!ecdsa_sig ||
         !TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
@@ -313,7 +311,7 @@
 
 static bool TestECDSA_SIG_max_len(size_t order_len) {
   /* Create the largest possible |ECDSA_SIG| of the given constraints. */
-  ScopedECDSA_SIG sig(ECDSA_SIG_new());
+  bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
   if (!sig) {
     return false;
   }
@@ -328,7 +326,7 @@
   if (!ECDSA_SIG_to_bytes(&der, &der_len, sig.get())) {
     return false;
   }
-  ScopedOpenSSLBytes delete_der(der);
+  bssl::UniquePtr<uint8_t> delete_der(der);
 
   size_t max_len = ECDSA_SIG_max_len(order_len);
   if (max_len != der_len) {
diff --git a/crypto/ecdsa/ecdsa_verify_test.cc b/crypto/ecdsa/ecdsa_verify_test.cc
index 7ef2d29..18340e2 100644
--- a/crypto/ecdsa/ecdsa_verify_test.cc
+++ b/crypto/ecdsa/ecdsa_verify_test.cc
@@ -21,58 +21,59 @@
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
 #include <openssl/ecdsa.h>
+#include <openssl/nid.h>
 
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 
 
-static ScopedEC_GROUP GetCurve(FileTest *t, const char *key) {
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
   std::string curve_name;
   if (!t->GetAttribute(&curve_name, key)) {
     return nullptr;
   }
 
   if (curve_name == "P-224") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp224r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
   }
   if (curve_name == "P-256") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    return bssl::UniquePtr<EC_GROUP>(
+        EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
   }
   if (curve_name == "P-384") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp384r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
   }
   if (curve_name == "P-521") {
-    return ScopedEC_GROUP(EC_GROUP_new_by_curve_name(NID_secp521r1));
+    return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
   }
 
   t->PrintLine("Unknown curve '%s'", curve_name.c_str());
   return nullptr;
 }
 
-static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *key) {
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
   std::vector<uint8_t> bytes;
   if (!t->GetBytes(&bytes, key)) {
     return nullptr;
   }
 
-  return ScopedBIGNUM(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+  return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
 }
 
 static bool TestECDSASign(FileTest *t, void *arg) {
-  ScopedEC_GROUP group = GetCurve(t, "Curve");
-  ScopedBIGNUM x = GetBIGNUM(t, "X");
-  ScopedBIGNUM y = GetBIGNUM(t, "Y");
-  ScopedBIGNUM r = GetBIGNUM(t, "R");
-  ScopedBIGNUM s = GetBIGNUM(t, "S");
+  bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+  bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+  bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+  bssl::UniquePtr<BIGNUM> r = GetBIGNUM(t, "R");
+  bssl::UniquePtr<BIGNUM> s = GetBIGNUM(t, "S");
   std::vector<uint8_t> digest;
   if (!group || !x || !y || !r || !s ||
       !t->GetBytes(&digest, "Digest")) {
     return false;
   }
 
-  ScopedEC_KEY key(EC_KEY_new());
-  ScopedEC_POINT pub_key(EC_POINT_new(group.get()));
-  ScopedECDSA_SIG sig(ECDSA_SIG_new());
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+  bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
+  bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
   if (!key || !pub_key || !sig ||
       !EC_KEY_set_group(key.get(), group.get()) ||
       !EC_POINT_set_affine_coordinates_GFp(group.get(), pub_key.get(), x.get(),
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index b2c519e..125dc03 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -24,10 +24,9 @@
 #include <openssl/c++/digest.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
+#include <openssl/pkcs8.h>
 #include <openssl/rsa.h>
 
-#include "../test/scoped_types.h"
-
 namespace bssl {
 
 // kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
@@ -357,13 +356,13 @@
     0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
 };
 
-static ScopedEVP_PKEY LoadExampleRSAKey() {
-  ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
+static bssl::UniquePtr<EVP_PKEY> LoadExampleRSAKey() {
+  bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
                                            sizeof(kExampleRSAKeyDER)));
   if (!rsa) {
     return nullptr;
   }
-  ScopedEVP_PKEY pkey(EVP_PKEY_new());
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
   if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) {
     return nullptr;
   }
@@ -371,7 +370,7 @@
 }
 
 static bool TestEVP_DigestSignInit(void) {
-  ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+  bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
   ScopedEVP_MD_CTX md_ctx;
   if (!pkey ||
       !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
@@ -409,7 +408,7 @@
 }
 
 static bool TestEVP_DigestVerifyInit(void) {
-  ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+  bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
   ScopedEVP_MD_CTX md_ctx;
   if (!pkey ||
       !EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL,
@@ -422,12 +421,12 @@
 }
 
 static bool TestVerifyRecover() {
-  ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+  bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
   if (!pkey) {
     return false;
   }
 
-  ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
+  bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(pkey.get()));
   if (!rsa) {
     return false;
   }
@@ -444,7 +443,7 @@
   }
 
   size_t out_len;
-  ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
+  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
   if (!EVP_PKEY_verify_recover_init(ctx.get()) ||
       !EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) ||
       !EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) ||
@@ -502,7 +501,7 @@
 static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
                                 int expected_id) {
   const uint8_t *p = input;
-  ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
+  bssl::UniquePtr<EVP_PKEY> pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
   if (!pkey || p != input + input_len) {
     fprintf(stderr, "d2i_AutoPrivateKey failed\n");
     return false;
@@ -556,7 +555,7 @@
   }
 
   const uint8_t *p = kInvalidPrivateKey;
-  ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
+  bssl::UniquePtr<EVP_PKEY> pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
   if (pkey) {
     fprintf(stderr, "Parsed invalid private key\n");
     return false;
@@ -569,14 +568,14 @@
 // TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
 static bool TestEVP_PKCS82PKEY(void) {
   const uint8_t *derp = kExampleBadECKeyDER;
-  ScopedPKCS8_PRIV_KEY_INFO p8inf(
+  bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> p8inf(
       d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)));
   if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
     fprintf(stderr, "Failed to parse key\n");
     return false;
   }
 
-  ScopedEVP_PKEY pkey(EVP_PKCS82PKEY(p8inf.get()));
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKCS82PKEY(p8inf.get()));
   if (pkey) {
     fprintf(stderr, "Imported invalid EC key\n");
     return false;
@@ -588,7 +587,7 @@
 
 // TestEVPMarshalEmptyPublicKey tests |EVP_marshal_public_key| on an empty key.
 static bool TestEVPMarshalEmptyPublicKey(void) {
-  ScopedEVP_PKEY empty(EVP_PKEY_new());
+  bssl::UniquePtr<EVP_PKEY> empty(EVP_PKEY_new());
   if (!empty) {
     return false;
   }
@@ -608,7 +607,7 @@
 // Testd2i_PrivateKey tests |d2i_PrivateKey|.
 static bool Testd2i_PrivateKey(void) {
   const uint8_t *derp = kExampleRSAKeyDER;
-  ScopedEVP_PKEY pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+  bssl::UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
                                      sizeof(kExampleRSAKeyDER)));
   if (!pkey || derp != kExampleRSAKeyDER + sizeof(kExampleRSAKeyDER)) {
     fprintf(stderr, "Failed to import raw RSA key.\n");
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc
index 9c8735b..58d3ebd 100644
--- a/crypto/evp/evp_test.cc
+++ b/crypto/evp/evp_test.cc
@@ -74,7 +74,6 @@
 #include <openssl/err.h>
 
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 
 namespace bssl {
 
@@ -115,7 +114,7 @@
   return EVP_PKEY_NONE;
 }
 
-using KeyMap = std::map<std::string, ScopedEVP_PKEY>;
+using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;
 
 static bool ImportKey(FileTest *t, KeyMap *key_map,
                       EVP_PKEY *(*parse_func)(CBS *cbs),
@@ -127,7 +126,7 @@
 
   CBS cbs;
   CBS_init(&cbs, input.data(), input.size());
-  ScopedEVP_PKEY pkey(parse_func(&cbs));
+  bssl::UniquePtr<EVP_PKEY> pkey(parse_func(&cbs));
   if (!pkey) {
     return false;
   }
@@ -150,7 +149,7 @@
       !CBB_finish(cbb.get(), &der, &der_len)) {
     return false;
   }
-  ScopedOpenSSLBytes free_der(der);
+  bssl::UniquePtr<uint8_t> free_der(der);
 
   std::vector<uint8_t> output = input;
   if (t->HasAttribute("Output") &&
@@ -215,7 +214,7 @@
   }
 
   // Set up the EVP_PKEY_CTX.
-  ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(key, nullptr));
+  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
   if (!ctx || !key_op_init(ctx.get())) {
     return false;
   }
diff --git a/crypto/newhope/newhope_statistical_test.cc b/crypto/newhope/newhope_statistical_test.cc
index 44fac48..3ca6d78 100644
--- a/crypto/newhope/newhope_statistical_test.cc
+++ b/crypto/newhope/newhope_statistical_test.cc
@@ -19,9 +19,9 @@
 #include <string.h>
 
 #include <openssl/crypto.h>
+#include <openssl/newhope.h>
 #include <openssl/rand.h>
 
-#include "../test/scoped_types.h"
 #include "internal.h"
 
 
@@ -108,7 +108,7 @@
   uint8_t key[NEWHOPE_KEY_LENGTH];
   uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH];
 
-  ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new()), pk(NEWHOPE_POLY_new()),
+  bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new()), pk(NEWHOPE_POLY_new()),
       sp(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()), epp(NEWHOPE_POLY_new()),
       a(NEWHOPE_POLY_new()), bp(NEWHOPE_POLY_new()), rec(NEWHOPE_POLY_new());
 
diff --git a/crypto/newhope/newhope_test.cc b/crypto/newhope/newhope_test.cc
index 6637393..a590721 100644
--- a/crypto/newhope/newhope_test.cc
+++ b/crypto/newhope/newhope_test.cc
@@ -19,7 +19,6 @@
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
 
-#include "../test/scoped_types.h"
 #include "internal.h"
 
 
@@ -28,7 +27,7 @@
 
 static bool TestKeys(void) {
   // Alice generates a public key.
-  ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
   uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
   NEWHOPE_offer(offer_msg, sk.get());
 
@@ -58,7 +57,7 @@
 static bool TestInvalidSK(void) {
   // Alice generates a public key.
   uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
-  ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
   NEWHOPE_offer(offer_msg, sk.get());
 
   // Bob derives a secret key and creates a response.
@@ -93,7 +92,7 @@
 
 static bool TestInvalidAcceptMsg(void) {
   // Alice generates a public key.
-  ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
   uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
   NEWHOPE_offer(offer_msg, sk.get());
 
diff --git a/crypto/newhope/newhope_vectors_test.cc b/crypto/newhope/newhope_vectors_test.cc
index fe84cd4..64aa0bb 100644
--- a/crypto/newhope/newhope_vectors_test.cc
+++ b/crypto/newhope/newhope_vectors_test.cc
@@ -20,17 +20,16 @@
 #include <openssl/rand.h>
 
 #include "../test/file_test.h"
-#include "../test/scoped_types.h"
 #include "internal.h"
 
 
 static bool TestNewhope(FileTest *t, void *arg) {
-  ScopedNEWHOPE_POLY a(NEWHOPE_POLY_new());
-  ScopedNEWHOPE_POLY s(NEWHOPE_POLY_new()), sp(NEWHOPE_POLY_new());
-  ScopedNEWHOPE_POLY e(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()),
+  bssl::UniquePtr<NEWHOPE_POLY> a(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> s(NEWHOPE_POLY_new()), sp(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> e(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()),
       epp(NEWHOPE_POLY_new());
-  ScopedNEWHOPE_POLY in_pk(NEWHOPE_POLY_new());
-  ScopedNEWHOPE_POLY in_rec(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> in_pk(NEWHOPE_POLY_new());
+  bssl::UniquePtr<NEWHOPE_POLY> in_rec(NEWHOPE_POLY_new());
 
   if (t->GetType() == "InRandA") {
     std::vector<uint8_t> a_bytes, s_bytes, e_bytes, expected_pk;
diff --git a/crypto/pkcs8/pkcs12_test.cc b/crypto/pkcs8/pkcs12_test.cc
index 17bcd27..5c1a1b4 100644
--- a/crypto/pkcs8/pkcs12_test.cc
+++ b/crypto/pkcs8/pkcs12_test.cc
@@ -23,8 +23,6 @@
 #include <openssl/stack.h>
 #include <openssl/x509.h>
 
-#include "../test/scoped_types.h"
-
 
 /* kPKCS12DER contains sample PKCS#12 data generated by OpenSSL with:
  * openssl pkcs12 -export -inkey key.pem -in cacert.pem */
@@ -684,7 +682,7 @@
 static const char kPassword[] = "foo";
 
 static bool Test(const char *name, const uint8_t *der, size_t der_len) {
-  ScopedX509Stack certs(sk_X509_new_null());
+  bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
   if (!certs) {
     return false;
   }
@@ -697,7 +695,7 @@
     ERR_print_errors_fp(stderr);
     return false;
   }
-  ScopedEVP_PKEY delete_key(key);
+  bssl::UniquePtr<EVP_PKEY> delete_key(key);
 
   if (sk_X509_num(certs.get()) != 1 || key == nullptr) {
     fprintf(stderr, "Bad result from %s data.\n", name);
@@ -708,12 +706,12 @@
 }
 
 static bool TestCompat(const uint8_t *der, size_t der_len) {
-  ScopedBIO bio(BIO_new_mem_buf(der, der_len));
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der, der_len));
   if (!bio) {
     return false;
   }
 
-  ScopedPKCS12 p12(d2i_PKCS12_bio(bio.get(), nullptr));
+  bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
   if (!p12) {
     fprintf(stderr, "PKCS12_parse failed.\n");
     ERR_print_errors_fp(stderr);
@@ -738,9 +736,9 @@
     ERR_print_errors_fp(stderr);
     return false;
   }
-  ScopedEVP_PKEY delete_key(key);
-  ScopedX509 delete_cert(cert);
-  ScopedX509Stack delete_ca_certs(ca_certs);
+  bssl::UniquePtr<EVP_PKEY> delete_key(key);
+  bssl::UniquePtr<X509> delete_cert(cert);
+  bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
 
   if (key == nullptr || cert == nullptr) {
     fprintf(stderr, "Bad result from PKCS12_parse.\n");
diff --git a/crypto/pkcs8/pkcs8_test.cc b/crypto/pkcs8/pkcs8_test.cc
index 7a88ddf..cbb2043 100644
--- a/crypto/pkcs8/pkcs8_test.cc
+++ b/crypto/pkcs8/pkcs8_test.cc
@@ -21,8 +21,6 @@
 #include <openssl/pkcs8.h>
 #include <openssl/x509.h>
 
-#include "../test/scoped_types.h"
-
 
 /* kDER is a PKCS#8 encrypted private key. It was generated with:
  *
@@ -64,14 +62,14 @@
 
 static bool test(const uint8_t *der, size_t der_len) {
   const uint8_t *data = der;
-  ScopedX509_SIG sig(d2i_X509_SIG(NULL, &data, der_len));
+  bssl::UniquePtr<X509_SIG> sig(d2i_X509_SIG(NULL, &data, der_len));
   if (sig.get() == NULL || data != der + der_len) {
     fprintf(stderr, "d2i_X509_SIG failed or did not consume all bytes.\n");
     return false;
   }
 
   static const char kPassword[] = "testing";
-  ScopedPKCS8_PRIV_KEY_INFO keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
+  bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
   if (!keypair) {
     fprintf(stderr, "PKCS8_decrypt failed.\n");
     ERR_print_errors_fp(stderr);
diff --git a/crypto/rsa/rsa_test.cc b/crypto/rsa/rsa_test.cc
index 62177a4..8c4a787 100644
--- a/crypto/rsa/rsa_test.cc
+++ b/crypto/rsa/rsa_test.cc
@@ -65,8 +65,6 @@
 #include <openssl/err.h>
 #include <openssl/nid.h>
 
-#include "../test/scoped_types.h"
-
 
 // kPlaintext is a sample plaintext.
 static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
@@ -526,7 +524,7 @@
 static bool TestRSA(const uint8_t *der, size_t der_len,
                     const uint8_t *oaep_ciphertext,
                     size_t oaep_ciphertext_len) {
-  ScopedRSA key(RSA_private_key_from_bytes(der, der_len));
+  bssl::UniquePtr<RSA> key(RSA_private_key_from_bytes(der, der_len));
   if (!key) {
     return false;
   }
@@ -612,7 +610,7 @@
 
 static bool TestMultiPrimeKey(int nprimes, const uint8_t *der, size_t der_size,
                               const uint8_t *enc, size_t enc_size) {
-  ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
+  bssl::UniquePtr<RSA> rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
   if (!rsa) {
     fprintf(stderr, "%d-prime key failed to parse.\n", nprimes);
     ERR_print_errors_fp(stderr);
@@ -645,8 +643,8 @@
   uint8_t encrypted[kBits / 8], decrypted[kBits / 8];
   size_t encrypted_len, decrypted_len;
 
-  ScopedRSA rsa(RSA_new());
-  ScopedBIGNUM e(BN_new());
+  bssl::UniquePtr<RSA> rsa(RSA_new());
+  bssl::UniquePtr<BIGNUM> e(BN_new());
   if (!rsa || !e ||
       !BN_set_word(e.get(), RSA_F4) ||
       !RSA_generate_multi_prime_key(rsa.get(), kBits, 3, e.get(), nullptr) ||
@@ -666,8 +664,8 @@
 }
 
 static bool TestBadKey() {
-  ScopedRSA key(RSA_new());
-  ScopedBIGNUM e(BN_new());
+  bssl::UniquePtr<RSA> key(RSA_new());
+  bssl::UniquePtr<BIGNUM> e(BN_new());
 
   if (!key || !e || !BN_set_word(e.get(), RSA_F4)) {
     return false;
@@ -705,7 +703,7 @@
 
   uint8_t buf[64];
   unsigned buf_len = sizeof(buf);
-  ScopedRSA key(RSA_new());
+  bssl::UniquePtr<RSA> key(RSA_new());
   if (!key ||
       !BN_hex2bn(&key->n, kN) ||
       !BN_hex2bn(&key->e, kE) ||
@@ -739,7 +737,7 @@
   // Keys without the public exponent must continue to work when blinding is
   // disabled to support Java's RSAPrivateKeySpec API. See
   // https://bugs.chromium.org/p/boringssl/issues/detail?id=12.
-  ScopedRSA key2(RSA_new());
+  bssl::UniquePtr<RSA> key2(RSA_new());
   if (!key2 ||
       !BN_hex2bn(&key2->n, kN) ||
       !BN_hex2bn(&key2->d, kD)) {
@@ -772,7 +770,7 @@
 }
 
 static bool TestRecoverCRTParams() {
-  ScopedBIGNUM e(BN_new());
+  bssl::UniquePtr<BIGNUM> e(BN_new());
   if (!e || !BN_set_word(e.get(), RSA_F4)) {
     return false;
   }
@@ -780,7 +778,7 @@
   ERR_clear_error();
 
   for (unsigned i = 0; i < 1; i++) {
-    ScopedRSA key1(RSA_new());
+    bssl::UniquePtr<RSA> key1(RSA_new());
     if (!key1 ||
         !RSA_generate_key_ex(key1.get(), 512, e.get(), nullptr)) {
       fprintf(stderr, "RSA_generate_key_ex failed.\n");
@@ -794,7 +792,7 @@
       return false;
     }
 
-    ScopedRSA key2(RSA_new());
+    bssl::UniquePtr<RSA> key2(RSA_new());
     if (!key2) {
       return false;
     }
@@ -844,7 +842,7 @@
 
 static bool TestASN1() {
   // Test that private keys may be decoded.
-  ScopedRSA rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
+  bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
   if (!rsa) {
     return false;
   }
@@ -855,7 +853,7 @@
   if (!RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
     return false;
   }
-  ScopedOpenSSLBytes delete_der(der);
+  bssl::UniquePtr<uint8_t> delete_der(der);
   if (der_len != sizeof(kKey1) - 1 || memcmp(der, kKey1, der_len) != 0) {
     return false;
   }
@@ -878,7 +876,7 @@
   if (!RSA_public_key_to_bytes(&der2, &der2_len, rsa.get())) {
     return false;
   }
-  ScopedOpenSSLBytes delete_der2(der2);
+  bssl::UniquePtr<uint8_t> delete_der2(der2);
   if (der_len != der2_len || memcmp(der, der2, der_len) != 0) {
     return false;
   }
@@ -910,7 +908,7 @@
 }
 
 static bool TestBadExponent() {
-  ScopedRSA rsa(RSA_public_key_from_bytes(kExponent1RSAKey,
+  bssl::UniquePtr<RSA> rsa(RSA_public_key_from_bytes(kExponent1RSAKey,
                                           sizeof(kExponent1RSAKey)));
 
   if (rsa) {
diff --git a/crypto/test/scoped_types.h b/crypto/test/scoped_types.h
deleted file mode 100644
index c124235..0000000
--- a/crypto/test/scoped_types.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#ifndef OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
-#define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include <memory>
-
-#include <openssl/aead.h>
-#include <openssl/asn1.h>
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/bytestring.h>
-#include <openssl/cmac.h>
-#include <openssl/curve25519.h>
-#include <openssl/dh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/mem.h>
-#include <openssl/newhope.h>
-#include <openssl/pkcs8.h>
-#include <openssl/rsa.h>
-#include <openssl/stack.h>
-#include <openssl/x509.h>
-
-
-template<typename T, void (*func)(T*)>
-struct OpenSSLDeleter {
-  void operator()(T *obj) {
-    func(obj);
-  }
-};
-
-template<typename StackType, typename T, void (*func)(T*)>
-struct OpenSSLStackDeleter {
-  void operator()(StackType *obj) {
-    sk_pop_free(reinterpret_cast<_STACK*>(obj),
-                reinterpret_cast<void (*)(void *)>(func));
-  }
-};
-
-template<typename T>
-struct OpenSSLFree {
-  void operator()(T *buf) {
-    OPENSSL_free(buf);
-  }
-};
-
-struct FileCloser {
-  void operator()(FILE *file) {
-    fclose(file);
-  }
-};
-
-template<typename T, void (*func)(T*)>
-using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
-
-template<typename StackType, typename T, void (*func)(T*)>
-using ScopedOpenSSLStack =
-    std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
-
-template<typename T, typename CleanupRet, void (*init_func)(T*),
-         CleanupRet (*cleanup_func)(T*)>
-class ScopedOpenSSLContext {
- public:
-  ScopedOpenSSLContext() {
-    init_func(&ctx_);
-  }
-  ~ScopedOpenSSLContext() {
-    cleanup_func(&ctx_);
-  }
-
-  T *get() { return &ctx_; }
-  const T *get() const { return &ctx_; }
-
-  void Reset() {
-    cleanup_func(&ctx_);
-    init_func(&ctx_);
-  }
-
- private:
-  T ctx_;
-};
-
-using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
-using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
-using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
-using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
-using ScopedBN_MONT_CTX = ScopedOpenSSLType<BN_MONT_CTX, BN_MONT_CTX_free>;
-using ScopedCMAC_CTX = ScopedOpenSSLType<CMAC_CTX, CMAC_CTX_free>;
-using ScopedDH = ScopedOpenSSLType<DH, DH_free>;
-using ScopedECDSA_SIG = ScopedOpenSSLType<ECDSA_SIG, ECDSA_SIG_free>;
-using ScopedEC_GROUP = ScopedOpenSSLType<EC_GROUP, EC_GROUP_free>;
-using ScopedEC_KEY = ScopedOpenSSLType<EC_KEY, EC_KEY_free>;
-using ScopedEC_POINT = ScopedOpenSSLType<EC_POINT, EC_POINT_free>;
-using ScopedEVP_PKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>;
-using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
-using ScopedNEWHOPE_POLY = ScopedOpenSSLType<NEWHOPE_POLY, NEWHOPE_POLY_free>;
-using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
-                                                    PKCS8_PRIV_KEY_INFO_free>;
-using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
-using ScopedSPAKE2_CTX = ScopedOpenSSLType<SPAKE2_CTX, SPAKE2_CTX_free>;
-using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
-using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
-using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
-using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
-using ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
-
-using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
-
-using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
-using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
-
-using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
-
-#endif  // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index d1eed2a..3c7cc63 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -23,8 +23,6 @@
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 
-#include "../test/scoped_types.h"
-
 namespace bssl {
 
 static const char kCrossSigningRootPEM[] =
@@ -226,23 +224,25 @@
 
 // CertFromPEM parses the given, NUL-terminated pem block and returns an
 // |X509*|.
-static ScopedX509 CertFromPEM(const char *pem) {
-  ScopedBIO bio(BIO_new_mem_buf(pem, strlen(pem)));
-  return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
+  return bssl::UniquePtr<X509>(
+      PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
 }
 
 // PrivateKeyFromPEM parses the given, NUL-terminated pem block and returns an
 // |EVP_PKEY*|.
-static ScopedEVP_PKEY PrivateKeyFromPEM(const char *pem) {
-  ScopedBIO bio(BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
-  return ScopedEVP_PKEY(
+static bssl::UniquePtr<EVP_PKEY> PrivateKeyFromPEM(const char *pem) {
+  bssl::UniquePtr<BIO> bio(
+      BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
+  return bssl::UniquePtr<EVP_PKEY>(
       PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
 }
 
 // CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509*),
 // bumping the reference counts for each certificate in question.
 static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
-  ScopedX509Stack stack(sk_X509_new_null());
+  bssl::UniquePtr<STACK_OF(X509)> stack(sk_X509_new_null());
   if (!stack) {
     return nullptr;
   }
@@ -259,14 +259,16 @@
 static bool Verify(X509 *leaf, const std::vector<X509 *> &roots,
                    const std::vector<X509 *> &intermediates,
                    unsigned long flags = 0) {
-  ScopedX509Stack roots_stack(CertsToStack(roots));
-  ScopedX509Stack intermediates_stack(CertsToStack(intermediates));
+  bssl::UniquePtr<STACK_OF(X509)> roots_stack(CertsToStack(roots));
+  bssl::UniquePtr<STACK_OF(X509)> intermediates_stack(
+      CertsToStack(intermediates));
+
   if (!roots_stack ||
       !intermediates_stack) {
     return false;
   }
 
-  ScopedX509_STORE_CTX ctx(X509_STORE_CTX_new());
+  bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
   if (!ctx) {
     return false;
   }
@@ -293,14 +295,15 @@
 }
 
 static bool TestVerify() {
-  ScopedX509 cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
-  ScopedX509 root(CertFromPEM(kRootCAPEM));
-  ScopedX509 root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
-  ScopedX509 intermediate(CertFromPEM(kIntermediatePEM));
-  ScopedX509 intermediate_self_signed(CertFromPEM(kIntermediateSelfSignedPEM));
-  ScopedX509 leaf(CertFromPEM(kLeafPEM));
-  ScopedX509 leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
-  ScopedX509 forgery(CertFromPEM(kForgeryPEM));
+  bssl::UniquePtr<X509> cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
+  bssl::UniquePtr<X509> root(CertFromPEM(kRootCAPEM));
+  bssl::UniquePtr<X509> root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
+  bssl::UniquePtr<X509> intermediate(CertFromPEM(kIntermediatePEM));
+  bssl::UniquePtr<X509> intermediate_self_signed(
+      CertFromPEM(kIntermediateSelfSignedPEM));
+  bssl::UniquePtr<X509> leaf(CertFromPEM(kLeafPEM));
+  bssl::UniquePtr<X509> leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
+  bssl::UniquePtr<X509> forgery(CertFromPEM(kForgeryPEM));
 
   if (!cross_signing_root ||
       !root ||
@@ -380,12 +383,12 @@
 }
 
 static bool TestPSS() {
-  ScopedX509 cert(CertFromPEM(kExamplePSSCert));
+  bssl::UniquePtr<X509> cert(CertFromPEM(kExamplePSSCert));
   if (!cert) {
     return false;
   }
 
-  ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+  bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
   if (!pkey) {
     return false;
   }
@@ -398,12 +401,12 @@
 }
 
 static bool TestBadPSSParameters() {
-  ScopedX509 cert(CertFromPEM(kBadPSSCertPEM));
+  bssl::UniquePtr<X509> cert(CertFromPEM(kBadPSSCertPEM));
   if (!cert) {
     return false;
   }
 
-  ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+  bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
   if (!pkey) {
     return false;
   }
@@ -418,7 +421,7 @@
 
 static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
   // Make a certificate like signed with |md_ctx|'s settings.'
-  ScopedX509 cert(CertFromPEM(kLeafPEM));
+  bssl::UniquePtr<X509> cert(CertFromPEM(kLeafPEM));
   if (!cert || !X509_sign_ctx(cert.get(), md_ctx)) {
     return false;
   }
@@ -429,7 +432,7 @@
 }
 
 static bool TestSignCtx() {
-  ScopedEVP_PKEY pkey(PrivateKeyFromPEM(kRSAKey));
+  bssl::UniquePtr<EVP_PKEY> pkey(PrivateKeyFromPEM(kRSAKey));
   if (!pkey) {
     return false;
   }
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index e0bfc8b..e99099e 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -475,7 +475,7 @@
 
 DECLARE_ASN1_SET_OF(ASN1_INTEGER)
 
-typedef struct asn1_type_st
+struct asn1_type_st
 	{
 	int type;
 	union	{
@@ -503,7 +503,7 @@
 		ASN1_STRING *		sequence;
 		ASN1_VALUE *		asn1_value;
 		} value;
-	} ASN1_TYPE;
+    };
 
 DECLARE_ASN1_SET_OF(ASN1_TYPE)
 
@@ -923,6 +923,23 @@
 
 #ifdef  __cplusplus
 }
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free)
+BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free)
+BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define ASN1_R_ASN1_LENGTH_MISMATCH 100
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 441aa29..8347c61 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -195,6 +195,7 @@
 typedef struct asn1_string_st ASN1_UTCTIME;
 typedef struct asn1_string_st ASN1_UTF8STRING;
 typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_type_st ASN1_TYPE;
 
 typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
 typedef struct BASIC_CONSTRAINTS_st BASIC_CONSTRAINTS;
@@ -286,6 +287,7 @@
 typedef struct x509_cert_pair_st X509_CERT_PAIR;
 typedef struct x509_cinf_st X509_CINF;
 typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_lookup_st X509_LOOKUP;
 typedef struct x509_revoked_st X509_REVOKED;
 typedef struct x509_st X509;
 typedef struct x509_store_ctx_st X509_STORE_CTX;
@@ -297,6 +299,55 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+// MSVC doesn't set __cplusplus to 201103 to indicate C++11 support (see
+// https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l)
+// so MSVC is just assumed to support C++11.
+#if defined(BORINGSSL_NO_CXX) || (__cplusplus < 201103L && !defined(_MSC_VER))
+
+#define BORINGSSL_MAKE_DELETER(type, deleter)
+#define BORINGSSL_MAKE_STACK_DELETER(type, deleter)
+
+#else
+
+#include <memory>
+
+namespace bssl {
+
+namespace internal {
+
+template <class T> struct Deleter {};
+
+#define BORINGSSL_MAKE_DELETER(type, deleter)       \
+    template <> struct Deleter<type> {              \
+      void operator()(type* ptr) { deleter(ptr); }  \
+    };
+
+// This makes a unique_ptr to STACK_OF(type) that owns all elements on the
+// stack, i.e. it uses sk_pop_free() to clean up.
+#define BORINGSSL_MAKE_STACK_DELETER(type, deleter)  \
+    template <> struct Deleter<STACK_OF(type)> {     \
+      void operator()(STACK_OF(type)* ptr) {         \
+        sk_##type##_pop_free(ptr, deleter);          \
+      }                                              \
+    };
+
+}  // namespace internal
+
+// Holds ownership of heap-allocated BoringSSL structures. Sample usage:
+//   bssl::UniquePtr<BIO> rsa(RSA_new());
+//   bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
+template <typename T>
+using UniquePtr = std::unique_ptr<T, internal::Deleter<T>>;
+
+}  // namespace bssl
+
+#endif  // C++ allowed?
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_BASE_H */
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index 9622f96..4aa9070 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -895,6 +895,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(BIO, BIO_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define BIO_R_BAD_FOPEN_MODE 100
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index 67a3455..c1b9e39 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -913,6 +913,23 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(BIGNUM, BN_free)
+BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free)
+BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define BN_R_ARG2_LT_ARG3 100
diff --git a/include/openssl/buf.h b/include/openssl/buf.h
index 8ae856b..7e39864 100644
--- a/include/openssl/buf.h
+++ b/include/openssl/buf.h
@@ -117,6 +117,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(BUF_MEM, BUF_MEM_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_BUFFER_H */
diff --git a/include/openssl/cmac.h b/include/openssl/cmac.h
index 0bb44b9..fb0b9f2 100644
--- a/include/openssl/cmac.h
+++ b/include/openssl/cmac.h
@@ -71,6 +71,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_CMAC_H */
diff --git a/include/openssl/conf.h b/include/openssl/conf.h
index 2aa3b79..8acb084 100644
--- a/include/openssl/conf.h
+++ b/include/openssl/conf.h
@@ -158,6 +158,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(CONF, NCONF_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define CONF_R_LIST_CANNOT_BE_NULL 100
diff --git a/include/openssl/curve25519.h b/include/openssl/curve25519.h
index a9441cd..70eff7a 100644
--- a/include/openssl/curve25519.h
+++ b/include/openssl/curve25519.h
@@ -167,6 +167,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_CURVE25519_H */
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index 4025656..a3f34d9 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -274,6 +274,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(DH, DH_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define DH_R_BAD_GENERATOR 100
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 1e1ff65..07f1495 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -411,6 +411,22 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(DSA, DSA_free)
+BORINGSSL_MAKE_DELETER(DSA_SIG, DSA_SIG_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define DSA_R_BAD_Q_VALUE 100
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 71c59d1..2349403 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -356,6 +356,22 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(EC_POINT, EC_POINT_free)
+BORINGSSL_MAKE_DELETER(EC_GROUP, EC_GROUP_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define EC_R_BUFFER_TOO_SMALL 100
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h
index 0658deb..a7c8bf8 100644
--- a/include/openssl/ec_key.h
+++ b/include/openssl/ec_key.h
@@ -321,6 +321,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(EC_KEY, EC_KEY_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_EC_KEY_H */
diff --git a/include/openssl/ecdsa.h b/include/openssl/ecdsa.h
index a060eab..5f07a9c 100644
--- a/include/openssl/ecdsa.h
+++ b/include/openssl/ecdsa.h
@@ -194,6 +194,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(ECDSA_SIG, ECDSA_SIG_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define ECDSA_R_BAD_SIGNATURE 100
diff --git a/include/openssl/engine.h b/include/openssl/engine.h
index 128a2ae..9cbdf39 100644
--- a/include/openssl/engine.h
+++ b/include/openssl/engine.h
@@ -91,6 +91,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(ENGINE, ENGINE_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define ENGINE_R_OPERATION_NOT_SUPPORTED 100
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index d5d528e..41e9e14 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -750,6 +750,22 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
+BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free)
+BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define EVP_R_BUFFER_TOO_SMALL 100
diff --git a/include/openssl/mem.h b/include/openssl/mem.h
index 31756f0..98ee077 100644
--- a/include/openssl/mem.h
+++ b/include/openssl/mem.h
@@ -133,6 +133,22 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(char, OPENSSL_free)
+BORINGSSL_MAKE_DELETER(uint8_t, OPENSSL_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif  /* OPENSSL_HEADER_MEM_H */
diff --git a/include/openssl/newhope.h b/include/openssl/newhope.h
index 487e03f..67728ea 100644
--- a/include/openssl/newhope.h
+++ b/include/openssl/newhope.h
@@ -142,6 +142,21 @@
 
 #if defined(__cplusplus)
 } /* extern "C" */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(NEWHOPE_POLY, NEWHOPE_POLY_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #endif /* OPENSSL_HEADER_NEWHOPE_H */
diff --git a/include/openssl/pkcs8.h b/include/openssl/pkcs8.h
index 28cf6ac..0939d8c 100644
--- a/include/openssl/pkcs8.h
+++ b/include/openssl/pkcs8.h
@@ -187,6 +187,22 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(PKCS12, PKCS12_free)
+BORINGSSL_MAKE_DELETER(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define PKCS8_R_BAD_PKCS12_DATA 100
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index b4c7653..f761dc6 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -636,6 +636,21 @@
 
 #if defined(__cplusplus)
 }  /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(RSA, RSA_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define RSA_R_BAD_ENCODING 100
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 9787bcb..3d705ee 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -4646,6 +4646,23 @@
 
 #if defined(__cplusplus)
 } /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_DELETER(SSL, SSL_free)
+BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
+BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 5bbf651..c32a6e7 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -1224,6 +1224,38 @@
 
 #ifdef  __cplusplus
 }
+
+extern "C++" {
+
+namespace bssl {
+
+namespace internal {
+
+BORINGSSL_MAKE_STACK_DELETER(X509, X509_free)
+BORINGSSL_MAKE_DELETER(X509, X509_free)
+BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free)
+BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free)
+BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free)
+BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free)
+BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free)
+BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free)
+BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free)
+BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free)
+BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free)
+BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free)
+BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free)
+BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free)
+BORINGSSL_MAKE_DELETER(X509_SIG, X509_SIG_free)
+BORINGSSL_MAKE_DELETER(X509_STORE, X509_STORE_free)
+BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free)
+BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
+
+}  // namespace internal
+
+}  // namespace bssl
+
+}  /* extern C++ */
+
 #endif
 
 #define X509_R_AKID_MISMATCH 100
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 50ded0d..0a45aad 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -129,8 +129,6 @@
 		} data;
 	} X509_OBJECT;
 
-typedef struct x509_lookup_st X509_LOOKUP;
-
 DECLARE_STACK_OF(X509_LOOKUP)
 DECLARE_STACK_OF(X509_OBJECT)
 
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 1bf0b24..78900e9 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -31,7 +31,6 @@
 #include <openssl/x509.h>
 
 #include "internal.h"
-#include "test/scoped_types.h"
 #include "../crypto/internal.h"
 #include "../crypto/test/test_util.h"
 
@@ -320,7 +319,7 @@
 }
 
 static bool TestCipherRule(const CipherTest &t) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
@@ -352,7 +351,7 @@
 }
 
 static bool TestRuleDoesNotIncludeNull(const char *rule) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
   if (!ctx) {
     return false;
   }
@@ -370,7 +369,7 @@
 }
 
 static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
@@ -395,7 +394,7 @@
   }
 
   for (const char *rule : kBadRules) {
-    ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
     if (!ctx) {
       return false;
     }
@@ -631,7 +630,7 @@
   }
 
   // Verify the SSL_SESSION decodes.
-  ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
+  bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
   if (!session) {
     fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
     return false;
@@ -639,7 +638,7 @@
 
   // Verify the SSL_SESSION encoding round-trips.
   size_t encoded_len;
-  ScopedOpenSSLBytes encoded;
+  bssl::UniquePtr<uint8_t> encoded;
   uint8_t *encoded_raw;
   if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
     fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
@@ -700,7 +699,7 @@
   }
 
   // Verify that the SSL_SESSION fails to decode.
-  ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
+  bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
   if (session) {
     fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
     return false;
@@ -711,7 +710,7 @@
 
 static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
                                const SSL_METHOD *(*method)(void)) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
   if (!ctx) {
     return false;
   }
@@ -728,7 +727,7 @@
   if (cipher == NULL) {
     return false;
   }
-  ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
+  bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
   if (!rfc_name) {
     return false;
   }
@@ -794,12 +793,12 @@
 
 // CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
 // replaced for one of length |ticket_len| or nullptr on failure.
-static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
+static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
   std::vector<uint8_t> der;
   if (!DecodeBase64(&der, kOpenSSLSession)) {
     return nullptr;
   }
-  ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
+  bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
   if (!session) {
     return nullptr;
   }
@@ -819,7 +818,7 @@
 }
 
 static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
-  ScopedBIO bio(BIO_new(BIO_s_mem()));
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
   if (!bio) {
     return false;
   }
@@ -846,12 +845,12 @@
 // |ticket_len| and records the ClientHello. It returns the length of the
 // ClientHello, not including the record header, on success and zero on error.
 static size_t GetClientHelloLen(size_t ticket_len) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
-  ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
   if (!ctx || !session) {
     return 0;
   }
-  ScopedSSL ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
   if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
     return 0;
   }
@@ -916,11 +915,11 @@
 // Test that |SSL_get_client_CA_list| echoes back the configured parameter even
 // before configuring as a server.
 static bool TestClientCAList() {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
-  ScopedSSL ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
   if (!ssl) {
     return false;
   }
@@ -974,8 +973,8 @@
   return actual == expected_copy;
 }
 
-static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
-  ScopedSSL_SESSION ret(SSL_SESSION_new());
+static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
+  bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
   if (!ret) {
     return nullptr;
   }
@@ -988,15 +987,15 @@
 
 // Test that the internal session cache behaves as expected.
 static bool TestInternalSessionCache() {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
 
   // Prepare 10 test sessions.
-  std::vector<ScopedSSL_SESSION> sessions;
+  std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
   for (int i = 0; i < 10; i++) {
-    ScopedSSL_SESSION session = CreateTestSession(i);
+    bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
     if (!session) {
       return false;
     }
@@ -1032,7 +1031,7 @@
 
   // Although collisions should be impossible (256-bit session IDs), the cache
   // must handle them gracefully.
-  ScopedSSL_SESSION collision(CreateTestSession(7));
+  bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
   if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
     return false;
   }
@@ -1075,7 +1074,7 @@
   return static_cast<uint16_t>(seq >> 48);
 }
 
-static ScopedX509 GetTestCertificate() {
+static bssl::UniquePtr<X509> GetTestCertificate() {
   static const char kCertPEM[] =
       "-----BEGIN CERTIFICATE-----\n"
       "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
@@ -1092,11 +1091,11 @@
       "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
       "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
       "-----END CERTIFICATE-----\n";
-  ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
-  return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+  return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
 }
 
-static ScopedEVP_PKEY GetTestKey() {
+static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
   static const char kKeyPEM[] =
       "-----BEGIN RSA PRIVATE KEY-----\n"
       "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
@@ -1113,12 +1112,12 @@
       "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
       "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
       "-----END RSA PRIVATE KEY-----\n";
-  ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
-  return ScopedEVP_PKEY(
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+  return bssl::UniquePtr<EVP_PKEY>(
       PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
 }
 
-static ScopedX509 GetECDSATestCertificate() {
+static bssl::UniquePtr<X509> GetECDSATestCertificate() {
   static const char kCertPEM[] =
       "-----BEGIN CERTIFICATE-----\n"
       "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
@@ -1132,26 +1131,26 @@
       "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
       "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
       "-----END CERTIFICATE-----\n";
-  ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
-  return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+  return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
 }
 
-static ScopedEVP_PKEY GetECDSATestKey() {
+static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
   static const char kKeyPEM[] =
       "-----BEGIN PRIVATE KEY-----\n"
       "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
       "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
       "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
       "-----END PRIVATE KEY-----\n";
-  ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
-  return ScopedEVP_PKEY(
+  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+  return bssl::UniquePtr<EVP_PKEY>(
       PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
 }
 
-static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
+static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
                                    SSL_CTX *client_ctx, SSL_CTX *server_ctx,
                                    SSL_SESSION *session) {
-  ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
+  bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
   if (!client || !server) {
     return false;
   }
@@ -1199,21 +1198,21 @@
 }
 
 static bool TestSequenceNumber(bool dtls) {
-  ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
-  ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+  bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+  bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
   if (!client_ctx || !server_ctx) {
     return false;
   }
 
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key ||
       !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
       !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
     return false;
   }
 
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
                               server_ctx.get(), nullptr /* no session */)) {
     return false;
@@ -1268,21 +1267,21 @@
 }
 
 static bool TestOneSidedShutdown() {
-  ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
-  ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
   if (!client_ctx || !server_ctx) {
     return false;
   }
 
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key ||
       !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
       !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
     return false;
   }
 
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
                               server_ctx.get(), nullptr /* no session */)) {
     return false;
@@ -1323,28 +1322,28 @@
   return true;
 }
 static bool TestSessionDuplication() {
-  ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
-  ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
   if (!client_ctx || !server_ctx) {
     return false;
   }
 
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key ||
       !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
       !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
     return false;
   }
 
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
                               server_ctx.get(), nullptr /* no session */)) {
     return false;
   }
 
   SSL_SESSION *session0 = SSL_get_session(client.get());
-  ScopedSSL_SESSION session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
+  bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
   if (!session1) {
     return false;
   }
@@ -1355,12 +1354,12 @@
   if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
     return false;
   }
-  ScopedOpenSSLBytes free_s0(s0_bytes);
+  bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
 
   if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
     return false;
   }
-  ScopedOpenSSLBytes free_s1(s1_bytes);
+  bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
 
   return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
 }
@@ -1383,13 +1382,13 @@
 }
 
 static bool TestSetFD() {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
 
   // Test setting different read and write FDs.
-  ScopedSSL ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
   if (!ssl ||
       !SSL_set_rfd(ssl.get(), 1) ||
       !SSL_set_wfd(ssl.get(), 2) ||
@@ -1466,13 +1465,13 @@
 }
 
 static bool TestSetBIO() {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
 
-  ScopedSSL ssl(SSL_new(ctx.get()));
-  ScopedBIO bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
       bio3(BIO_new(BIO_s_mem()));
   if (!ssl || !bio1 || !bio2 || !bio3) {
     return false;
@@ -1529,15 +1528,15 @@
 static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
 
 static bool TestGetPeerCertificate() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key) {
     return false;
   }
 
   for (uint16_t version : kVersions) {
     // Configure both client and server to accept any certificate.
-    ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
     if (!ctx ||
         !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
         !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
@@ -1549,14 +1548,14 @@
         ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
     SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
 
-    ScopedSSL client, server;
+    bssl::UniquePtr<SSL> client, server;
     if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
                                 nullptr /* no session */)) {
       return false;
     }
 
     // Client and server should both see the leaf certificate.
-    ScopedX509 peer(SSL_get_peer_certificate(server.get()));
+    bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
     if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
       fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
       return false;
@@ -1585,8 +1584,8 @@
 }
 
 static bool TestRetainOnlySHA256OfCerts() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key) {
     return false;
   }
@@ -1596,7 +1595,7 @@
   if (cert_der_len < 0) {
     return false;
   }
-  ScopedOpenSSLBytes free_cert_der(cert_der);
+  bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
 
   uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
   SHA256(cert_der, cert_der_len, cert_sha256);
@@ -1604,7 +1603,7 @@
   for (uint16_t version : kVersions) {
     // Configure both client and server to accept any certificate, but the
     // server must retain only the SHA-256 of the peer.
-    ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
     if (!ctx ||
         !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
         !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
@@ -1617,14 +1616,14 @@
     SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
     SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
 
-    ScopedSSL client, server;
+    bssl::UniquePtr<SSL> client, server;
     if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
                                 nullptr /* no session */)) {
       return false;
     }
 
     // The peer certificate has been dropped.
-    ScopedX509 peer(SSL_get_peer_certificate(server.get()));
+    bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
     if (peer) {
       fprintf(stderr, "%x: Peer certificate was retained.\n", version);
       return false;
@@ -1647,7 +1646,7 @@
 
 static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
                                size_t expected_len) {
-  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   if (!ctx) {
     return false;
   }
@@ -1657,7 +1656,7 @@
   if (!SSL_CTX_set_cipher_list(ctx.get(), "!RC4:CHACHA20:ALL")) {
     return false;
   }
-  ScopedSSL ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
   if (!ssl) {
     return false;
   }
@@ -1814,7 +1813,7 @@
   return true;
 }
 
-static ScopedSSL_SESSION g_last_session;
+static bssl::UniquePtr<SSL_SESSION> g_last_session;
 
 static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
   // Save the most recent session.
@@ -1822,13 +1821,13 @@
   return 1;
 }
 
-static ScopedSSL_SESSION CreateClientSession(SSL_CTX *client_ctx,
+static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
                                              SSL_CTX *server_ctx) {
   g_last_session = nullptr;
   SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
 
   // Connect client and server to get a session.
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
                               nullptr /* no session */)) {
     fprintf(stderr, "Failed to connect client and server.\n");
@@ -1850,7 +1849,7 @@
 static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
                                 SSL_SESSION *session,
                                 bool reused) {
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx,
                               server_ctx, session)) {
     fprintf(stderr, "Failed to connect client and server.\n");
@@ -1873,8 +1872,8 @@
 }
 
 static bool TestSessionIDContext() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key) {
     return false;
   }
@@ -1883,8 +1882,8 @@
   static const uint8_t kContext2[] = {2};
 
   for (uint16_t version : kVersions) {
-    ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
-    ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
     if (!server_ctx || !client_ctx ||
         !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
         !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
@@ -1901,7 +1900,7 @@
     SSL_CTX_set_max_version(server_ctx.get(), version);
     SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
 
-    ScopedSSL_SESSION session =
+    bssl::UniquePtr<SSL_SESSION> session =
         CreateClientSession(client_ctx.get(), server_ctx.get());
     if (!session) {
       fprintf(stderr, "Error getting session (version = %04x).\n", version);
@@ -1939,15 +1938,15 @@
 }
 
 static bool TestSessionTimeout() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
   if (!cert || !key) {
     return false;
   }
 
   for (uint16_t version : kVersions) {
-    ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
-    ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
     if (!server_ctx || !client_ctx ||
         !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
         !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
@@ -1963,7 +1962,7 @@
     SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
     SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
 
-    ScopedSSL_SESSION session =
+    bssl::UniquePtr<SSL_SESSION> session =
         CreateClientSession(client_ctx.get(), server_ctx.get());
     if (!session) {
       fprintf(stderr, "Error getting session (version = %04x).\n", version);
@@ -1999,10 +1998,10 @@
 }
 
 static bool TestSNICallback() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
-  ScopedX509 cert2 = GetECDSATestCertificate();
-  ScopedEVP_PKEY key2 = GetECDSATestKey();
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
+  bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
   if (!cert || !key || !cert2 || !key2) {
     return false;
   }
@@ -2016,9 +2015,9 @@
 
     static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
 
-    ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
-    ScopedSSL_CTX server_ctx2(SSL_CTX_new(TLS_method()));
-    ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
+    bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
     if (!server_ctx || !server_ctx2 || !client_ctx ||
         !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
         !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
@@ -2043,7 +2042,7 @@
     SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
     SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
 
-    ScopedSSL client, server;
+    bssl::UniquePtr<SSL> client, server;
     if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
                                 server_ctx.get(), nullptr)) {
       fprintf(stderr, "Handshake failed at version %04x.\n", version);
@@ -2051,7 +2050,7 @@
     }
 
     // The client should have received |cert2|.
-    ScopedX509 peer(SSL_get_peer_certificate(client.get()));
+    bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
     if (!peer ||
         X509_cmp(peer.get(), cert2.get()) != 0) {
       fprintf(stderr, "Incorrect certificate received at version %04x.\n",
@@ -2071,10 +2070,10 @@
 // TestEarlyCallbackVersionSwitch tests that the early callback can swap the
 // maximum version.
 static bool TestEarlyCallbackVersionSwitch() {
-  ScopedX509 cert = GetTestCertificate();
-  ScopedEVP_PKEY key = GetTestKey();
-  ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
-  ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<X509> cert = GetTestCertificate();
+  bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
+  bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+  bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
   if (!cert || !key || !server_ctx || !client_ctx ||
       !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
       !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
@@ -2086,7 +2085,7 @@
 
   SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
 
-  ScopedSSL client, server;
+  bssl::UniquePtr<SSL> client, server;
   if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
                               server_ctx.get(), nullptr)) {
     return false;
diff --git a/ssl/test/async_bio.cc b/ssl/test/async_bio.cc
index 7a5737b..605b33a 100644
--- a/ssl/test/async_bio.cc
+++ b/ssl/test/async_bio.cc
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <string.h>
 
+#include <openssl/bio.h>
 #include <openssl/mem.h>
 
 
@@ -150,12 +151,12 @@
 
 }  // namespace
 
-ScopedBIO AsyncBioCreate() {
-  return ScopedBIO(BIO_new(&g_async_bio_method));
+bssl::UniquePtr<BIO> AsyncBioCreate() {
+  return bssl::UniquePtr<BIO>(BIO_new(&g_async_bio_method));
 }
 
-ScopedBIO AsyncBioCreateDatagram() {
-  ScopedBIO ret(BIO_new(&g_async_bio_method));
+bssl::UniquePtr<BIO> AsyncBioCreateDatagram() {
+  bssl::UniquePtr<BIO> ret(BIO_new(&g_async_bio_method));
   if (!ret) {
     return nullptr;
   }
diff --git a/ssl/test/async_bio.h b/ssl/test/async_bio.h
index fbc4016..9974139 100644
--- a/ssl/test/async_bio.h
+++ b/ssl/test/async_bio.h
@@ -17,20 +17,18 @@
 
 #include <openssl/bio.h>
 
-#include "../../crypto/test/scoped_types.h"
-
 
 // AsyncBioCreate creates a filter BIO for testing asynchronous state
 // machines which consume a stream socket. Reads and writes will fail
 // and return EAGAIN unless explicitly allowed. Each async BIO has a
 // read quota and a write quota. Initially both are zero. As each is
 // incremented, bytes are allowed to flow through the BIO.
-ScopedBIO AsyncBioCreate();
+bssl::UniquePtr<BIO> AsyncBioCreate();
 
 // AsyncBioCreateDatagram creates a filter BIO for testing for
 // asynchronous state machines which consume datagram sockets. The read
 // and write quota count in packets rather than bytes.
-ScopedBIO AsyncBioCreateDatagram();
+bssl::UniquePtr<BIO> AsyncBioCreateDatagram();
 
 // AsyncBioAllowRead increments |bio|'s read quota by |count|.
 void AsyncBioAllowRead(BIO *bio, size_t count);
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index f9ab913..ff77b63 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -46,21 +46,22 @@
 #include <openssl/c++/digest.h>
 #include <openssl/cipher.h>
 #include <openssl/crypto.h>
+#include <openssl/dh.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/nid.h>
 #include <openssl/rand.h>
 #include <openssl/ssl.h>
+#include <openssl/x509.h>
 
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "../../crypto/internal.h"
-#include "../../crypto/test/scoped_types.h"
 #include "async_bio.h"
 #include "packeted_bio.h"
-#include "scoped_types.h"
 #include "test_config.h"
 
 namespace bssl {
@@ -89,20 +90,20 @@
   BIO *async_bio = nullptr;
   // packeted_bio is the packeted BIO which simulates read timeouts.
   BIO *packeted_bio = nullptr;
-  ScopedEVP_PKEY channel_id;
+  bssl::UniquePtr<EVP_PKEY> channel_id;
   bool cert_ready = false;
-  ScopedSSL_SESSION session;
-  ScopedSSL_SESSION pending_session;
+  bssl::UniquePtr<SSL_SESSION> session;
+  bssl::UniquePtr<SSL_SESSION> pending_session;
   bool early_callback_called = false;
   bool handshake_done = false;
   // private_key is the underlying private key used when testing custom keys.
-  ScopedEVP_PKEY private_key;
+  bssl::UniquePtr<EVP_PKEY> private_key;
   std::vector<uint8_t> private_key_result;
   // private_key_retries is the number of times an asynchronous private key
   // operation has been retried.
   unsigned private_key_retries = 0;
   bool got_new_session = false;
-  ScopedSSL_SESSION new_session;
+  bssl::UniquePtr<SSL_SESSION> new_session;
   bool ticket_decrypt_done = false;
   bool alpn_select_done = false;
 };
@@ -136,20 +137,21 @@
   return (TestState *)SSL_get_ex_data(ssl, g_state_index);
 }
 
-static ScopedX509 LoadCertificate(const std::string &file) {
-  ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<X509> LoadCertificate(const std::string &file) {
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
   if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
     return nullptr;
   }
-  return ScopedX509(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
+  return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
 }
 
-static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
-  ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
   if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
     return nullptr;
   }
-  return ScopedEVP_PKEY(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
+  return bssl::UniquePtr<EVP_PKEY>(
+      PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
 }
 
 static int AsyncPrivateKeyType(SSL *ssl) {
@@ -317,8 +319,8 @@
   }
 };
 
-static bool GetCertificate(SSL *ssl, ScopedX509 *out_x509,
-                           ScopedEVP_PKEY *out_pkey) {
+static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
+                           bssl::UniquePtr<EVP_PKEY> *out_pkey) {
   const TestConfig *config = GetTestConfig(ssl);
 
   if (!config->digest_prefs.empty()) {
@@ -372,8 +374,8 @@
 }
 
 static bool InstallCertificate(SSL *ssl) {
-  ScopedX509 x509;
-  ScopedEVP_PKEY pkey;
+  bssl::UniquePtr<X509> x509;
+  bssl::UniquePtr<EVP_PKEY> pkey;
   if (!GetCertificate(ssl, &x509, &pkey)) {
     return false;
   }
@@ -453,8 +455,8 @@
     return -1;
   }
 
-  ScopedX509 x509;
-  ScopedEVP_PKEY pkey;
+  bssl::UniquePtr<X509> x509;
+  bssl::UniquePtr<EVP_PKEY> pkey;
   if (!GetCertificate(ssl, &x509, &pkey)) {
     return -1;
   }
@@ -799,8 +801,8 @@
   const int sock_;
 };
 
-static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
-  ScopedSSL_CTX ssl_ctx(SSL_CTX_new(
+static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(
       config->is_dtls ? DTLS_method() : TLS_method()));
   if (!ssl_ctx) {
     return nullptr;
@@ -831,7 +833,7 @@
     return nullptr;
   }
 
-  ScopedDH dh(DH_get_2048_256(NULL));
+  bssl::UniquePtr<DH> dh(DH_get_2048_256(NULL));
   if (!dh) {
     return nullptr;
   }
@@ -973,7 +975,8 @@
       AsyncBioAllowWrite(test_state->async_bio, 1);
       return true;
     case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP: {
-      ScopedEVP_PKEY pkey = LoadPrivateKey(GetTestConfig(ssl)->send_channel_id);
+      bssl::UniquePtr<EVP_PKEY> pkey =
+          LoadPrivateKey(GetTestConfig(ssl)->send_channel_id);
       if (!pkey) {
         return false;
       }
@@ -1256,10 +1259,10 @@
 // true and sets |*out_session| to the negotiated SSL session. If the test is a
 // resumption attempt, |is_resume| is true and |session| is the session from the
 // previous exchange.
-static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
-                       const TestConfig *config, bool is_resume,
-                       SSL_SESSION *session) {
-  ScopedSSL ssl(SSL_new(ssl_ctx));
+static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
+                       SSL_CTX *ssl_ctx, const TestConfig *config,
+                       bool is_resume, SSL_SESSION *session) {
+  bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
   if (!ssl) {
     return false;
   }
@@ -1319,7 +1322,7 @@
     SSL_enable_tls_channel_id(ssl.get());
     if (!config->async) {
       // The async case will be supplied by |ChannelIdCallback|.
-      ScopedEVP_PKEY pkey = LoadPrivateKey(config->send_channel_id);
+      bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(config->send_channel_id);
       if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
         return false;
       }
@@ -1412,12 +1415,12 @@
   }
   SocketCloser closer(sock);
 
-  ScopedBIO bio(BIO_new_socket(sock, BIO_NOCLOSE));
+  bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_NOCLOSE));
   if (!bio) {
     return false;
   }
   if (config->is_dtls) {
-    ScopedBIO packeted = PacketedBioCreate(!config->async);
+    bssl::UniquePtr<BIO> packeted = PacketedBioCreate(!config->async);
     if (!packeted) {
       return false;
     }
@@ -1426,7 +1429,7 @@
     bio = std::move(packeted);
   }
   if (config->async) {
-    ScopedBIO async_scoped =
+    bssl::UniquePtr<BIO> async_scoped =
         config->is_dtls ? AsyncBioCreateDatagram() : AsyncBioCreate();
     if (!async_scoped) {
       return false;
@@ -1692,13 +1695,13 @@
     return Usage(argv[0]);
   }
 
-  ScopedSSL_CTX ssl_ctx = SetupCtx(&config);
+  bssl::UniquePtr<SSL_CTX> ssl_ctx = SetupCtx(&config);
   if (!ssl_ctx) {
     ERR_print_errors_fp(stderr);
     return 1;
   }
 
-  ScopedSSL_SESSION session;
+  bssl::UniquePtr<SSL_SESSION> session;
   for (int i = 0; i < config.resume_count + 1; i++) {
     bool is_resume = i > 0;
     if (is_resume && !config.is_server && !session) {
@@ -1706,7 +1709,7 @@
       return 1;
     }
 
-    ScopedSSL_SESSION offer_session = std::move(session);
+    bssl::UniquePtr<SSL_SESSION> offer_session = std::move(session);
     if (!DoExchange(&session, ssl_ctx.get(), &config, is_resume,
                     offer_session.get())) {
       fprintf(stderr, "Connection %d failed.\n", i + 1);
diff --git a/ssl/test/packeted_bio.cc b/ssl/test/packeted_bio.cc
index b0982b0..f7267fc 100644
--- a/ssl/test/packeted_bio.cc
+++ b/ssl/test/packeted_bio.cc
@@ -272,8 +272,8 @@
 
 }  // namespace
 
-ScopedBIO PacketedBioCreate(bool advance_clock) {
-  ScopedBIO bio(BIO_new(&g_packeted_bio_method));
+bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock) {
+  bssl::UniquePtr<BIO> bio(BIO_new(&g_packeted_bio_method));
   if (!bio) {
     return nullptr;
   }
diff --git a/ssl/test/packeted_bio.h b/ssl/test/packeted_bio.h
index 9bab635..07930d4 100644
--- a/ssl/test/packeted_bio.h
+++ b/ssl/test/packeted_bio.h
@@ -18,8 +18,6 @@
 #include <openssl/base.h>
 #include <openssl/bio.h>
 
-#include "../../crypto/test/scoped_types.h"
-
 #if defined(OPENSSL_WINDOWS)
 OPENSSL_MSVC_PRAGMA(warning(push, 3))
 #include <winsock2.h>
@@ -38,7 +36,7 @@
 // continues reading, subject to the read deadline. Otherwise, it fails
 // immediately. The caller must then call |PacketedBioAdvanceClock| before
 // retrying |BIO_read|.
-ScopedBIO PacketedBioCreate(bool advance_clock);
+bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock);
 
 // PacketedBioGetClock returns the current time for |bio|.
 timeval PacketedBioGetClock(const BIO *bio);
diff --git a/ssl/test/scoped_types.h b/ssl/test/scoped_types.h
deleted file mode 100644
index 7e92cee..0000000
--- a/ssl/test/scoped_types.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#ifndef OPENSSL_HEADER_SSL_TEST_SCOPED_TYPES_H
-#define OPENSSL_HEADER_SSL_TEST_SCOPED_TYPES_H
-
-#include <openssl/ssl.h>
-
-#include "../../crypto/test/scoped_types.h"
-
-
-using ScopedSSL = ScopedOpenSSLType<SSL, SSL_free>;
-using ScopedSSL_CTX = ScopedOpenSSLType<SSL_CTX, SSL_CTX_free>;
-using ScopedSSL_SESSION = ScopedOpenSSLType<SSL_SESSION, SSL_SESSION_free>;
-
-
-#endif  // OPENSSL_HEADER_SSL_TEST_SCOPED_TYPES_H
diff --git a/tool/ciphers.cc b/tool/ciphers.cc
index d7cc36b..f52527b 100644
--- a/tool/ciphers.cc
+++ b/tool/ciphers.cc
@@ -20,8 +20,6 @@
 
 #include <openssl/ssl.h>
 
-#include "../crypto/test/scoped_types.h"
-#include "../ssl/test/scoped_types.h"
 #include "internal.h"
 
 
@@ -33,7 +31,7 @@
 
   const std::string &ciphers_string = args.back();
 
-  ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_client_method()));
   if (!SSL_CTX_set_cipher_list(ctx.get(), ciphers_string.c_str())) {
     fprintf(stderr, "Failed to parse cipher suite config.\n");
     ERR_print_errors_fp(stderr);
diff --git a/tool/client.cc b/tool/client.cc
index 9d662d7..9893cd4 100644
--- a/tool/client.cc
+++ b/tool/client.cc
@@ -20,8 +20,6 @@
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
 
-#include "../crypto/test/scoped_types.h"
-#include "../ssl/test/scoped_types.h"
 #include "internal.h"
 #include "transport_common.h"
 
@@ -95,13 +93,13 @@
     },
 };
 
-static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
-  ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
   if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
     return nullptr;
   }
-  ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr,
-                                              nullptr));
+  bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr,
+                                 nullptr, nullptr));
   return pkey;
 }
 
@@ -119,7 +117,7 @@
   fflush(g_keylog_file);
 }
 
-static ScopedBIO session_out;
+static bssl::UniquePtr<BIO> session_out;
 
 static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
   if (session_out) {
@@ -146,7 +144,7 @@
     return false;
   }
 
-  ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
+  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_client_method()));
 
   const char *keylog_file = getenv("SSLKEYLOGFILE");
   if (keylog_file) {
@@ -232,7 +230,8 @@
   }
 
   if (args_map.count("-channel-id-key") != 0) {
-    ScopedEVP_PKEY pkey = LoadPrivateKey(args_map["-channel-id-key"]);
+    bssl::UniquePtr<EVP_PKEY> pkey =
+        LoadPrivateKey(args_map["-channel-id-key"]);
     if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
       return false;
     }
@@ -281,22 +280,23 @@
     }
   }
 
-  ScopedBIO bio(BIO_new_socket(sock, BIO_CLOSE));
-  ScopedSSL ssl(SSL_new(ctx.get()));
+  bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_CLOSE));
+  bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
 
   if (args_map.count("-server-name") != 0) {
     SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
   }
 
   if (args_map.count("-session-in") != 0) {
-    ScopedBIO in(BIO_new_file(args_map["-session-in"].c_str(), "rb"));
+    bssl::UniquePtr<BIO> in(BIO_new_file(args_map["-session-in"].c_str(),
+                                         "rb"));
     if (!in) {
       fprintf(stderr, "Error reading session\n");
       ERR_print_errors_cb(PrintErrorCallback, stderr);
       return false;
     }
-    ScopedSSL_SESSION session(PEM_read_bio_SSL_SESSION(in.get(), nullptr,
-                                                       nullptr, nullptr));
+    bssl::UniquePtr<SSL_SESSION> session(PEM_read_bio_SSL_SESSION(in.get(),
+                                         nullptr, nullptr, nullptr));
     if (!session) {
       fprintf(stderr, "Error reading session\n");
       ERR_print_errors_cb(PrintErrorCallback, stderr);
diff --git a/tool/generate_ed25519.cc b/tool/generate_ed25519.cc
index 15d3692..35b57b9 100644
--- a/tool/generate_ed25519.cc
+++ b/tool/generate_ed25519.cc
@@ -18,10 +18,17 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "../crypto/test/scoped_types.h"
 #include "internal.h"
 
 
+struct FileCloser {
+  void operator()(FILE *file) {
+    fclose(file);
+  }
+};
+
+using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
+
 static const struct argument kArguments[] = {
     {
         "-out-public", kRequiredArgument, "The file to write the public key to",
diff --git a/tool/genrsa.cc b/tool/genrsa.cc
index 4b39401..b49ebbc 100644
--- a/tool/genrsa.cc
+++ b/tool/genrsa.cc
@@ -18,7 +18,6 @@
 #include <openssl/pem.h>
 #include <openssl/rsa.h>
 
-#include "../crypto/test/scoped_types.h"
 #include "internal.h"
 
 
@@ -51,9 +50,9 @@
     return false;
   }
 
-  ScopedRSA rsa(RSA_new());
-  ScopedBIGNUM e(BN_new());
-  ScopedBIO bio(BIO_new_fp(stdout, BIO_NOCLOSE));
+  bssl::UniquePtr<RSA> rsa(RSA_new());
+  bssl::UniquePtr<BIGNUM> e(BN_new());
+  bssl::UniquePtr<BIO> bio(BIO_new_fp(stdout, BIO_NOCLOSE));
 
   if (!BN_set_word(e.get(), RSA_F4) ||
       !RSA_generate_multi_prime_key(rsa.get(), bits, nprimes, e.get(), NULL) ||
diff --git a/tool/speed.cc b/tool/speed.cc
index 780a7ea..f089498 100644
--- a/tool/speed.cc
+++ b/tool/speed.cc
@@ -22,9 +22,13 @@
 #include <string.h>
 
 #include <openssl/aead.h>
+#include <openssl/bn.h>
 #include <openssl/curve25519.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/ec_key.h>
 #include <openssl/newhope.h>
 #include <openssl/nid.h>
 #include <openssl/rand.h>
@@ -38,7 +42,6 @@
 #include <sys/time.h>
 #endif
 
-#include "../crypto/test/scoped_types.h"
 #include "internal.h"
 
 
@@ -166,7 +169,7 @@
          * RSA key, with a new |BN_MONT_CTX| for the public modulus. If we were
          * to use |key| directly instead, then these costs wouldn't be
          * accounted for. */
-        ScopedRSA verify_key(RSA_new());
+        bssl::UniquePtr<RSA> verify_key(RSA_new());
         if (!verify_key) {
           return false;
         }
@@ -334,17 +337,17 @@
 
   TimeResults results;
   if (!TimeFunction(&results, [nid]() -> bool {
-        ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+        bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
         if (!key ||
             !EC_KEY_generate_key(key.get())) {
           return false;
         }
         const EC_GROUP *const group = EC_KEY_get0_group(key.get());
-        ScopedEC_POINT point(EC_POINT_new(group));
-        ScopedBN_CTX ctx(BN_CTX_new());
+        bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group));
+        bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
 
-        ScopedBIGNUM x(BN_new());
-        ScopedBIGNUM y(BN_new());
+        bssl::UniquePtr<BIGNUM> x(BN_new());
+        bssl::UniquePtr<BIGNUM> y(BN_new());
 
         if (!point || !ctx || !x || !y ||
             !EC_POINT_mul(group, point.get(), NULL,
@@ -370,7 +373,7 @@
     return true;
   }
 
-  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
   if (!key ||
       !EC_KEY_generate_key(key.get())) {
     return false;
@@ -499,9 +502,9 @@
   static const uint8_t kAliceName[] = {'A'};
   static const uint8_t kBobName[] = {'B'};
   static const uint8_t kPassword[] = "password";
-  ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(spake2_role_alice, kAliceName,
-                                        sizeof(kAliceName), kBobName,
-                                        sizeof(kBobName)));
+  bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(spake2_role_alice,
+                                    kAliceName, sizeof(kAliceName), kBobName,
+                                    sizeof(kBobName)));
   uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
   size_t alice_msg_len;
 
@@ -513,9 +516,9 @@
   }
 
   if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
-        ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(spake2_role_bob, kBobName,
-                                            sizeof(kBobName), kAliceName,
-                                            sizeof(kAliceName)));
+        bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(spake2_role_bob,
+                                        kBobName, sizeof(kBobName), kAliceName,
+                                        sizeof(kAliceName)));
         uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
         size_t bob_msg_len, bob_key_len;
         if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
diff --git a/util/BUILD.toplevel b/util/BUILD.toplevel
index 51e95b1..6b645e6 100644
--- a/util/BUILD.toplevel
+++ b/util/BUILD.toplevel
@@ -113,10 +113,7 @@
 
 cc_binary(
     name = "bssl",
-    srcs = tool_sources + tool_headers + [
-        "src/crypto/test/scoped_types.h",
-        "src/ssl/test/scoped_types.h",
-    ],
+    srcs = tool_sources + tool_headers,
     copts = boringssl_copts_cxx,
     visibility = ["//visibility:public"],
     deps = [":ssl"],