Replace malloc/sizeof pattern by New.

This ensures no objects can be placed in a struct without having a
public constructor.

Bug: 477574200
Change-Id: I6d7e74008f3eaab473193d8d8fea9ad46a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/87567
Reviewed-by: Xiangfei Ding <xfding@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/STYLE.md b/STYLE.md
index e5efe0b..e0c9fda 100644
--- a/STYLE.md
+++ b/STYLE.md
@@ -45,7 +45,8 @@
     const auto& blah;
 
 Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
-and `OPENSSL_free()`. Use the standard C `assert()` function freely.
+and `OPENSSL_free()`. Similarly, rather than `new` and `delete`, use the
+wrappers `New` and `Delete`. Use the standard C `assert()` function freely.
 
 Use the following wrappers, found in `crypto/internal.h` instead of the
 corresponding C standard library functions. They behave the same but avoid
diff --git a/crypto/asn1/a_object.cc b/crypto/asn1/a_object.cc
index a3143b7..e9312b2 100644
--- a/crypto/asn1/a_object.cc
+++ b/crypto/asn1/a_object.cc
@@ -24,6 +24,7 @@
 
 #include "../bytestring/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -139,9 +140,7 @@
 }
 
 ASN1_OBJECT *bssl::ASN1_OBJECT_new() {
-  ASN1_OBJECT *ret;
-
-  ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
+  ASN1_OBJECT *ret = New<ASN1_OBJECT>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/asn1/a_strnid.cc b/crypto/asn1/a_strnid.cc
index 6aff48d..821cb3b 100644
--- a/crypto/asn1/a_strnid.cc
+++ b/crypto/asn1/a_strnid.cc
@@ -26,6 +26,7 @@
 
 #include "../internal.h"
 #include "../lhash/internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -182,8 +183,7 @@
     }
   }
 
-  tbl = reinterpret_cast<ASN1_STRING_TABLE *>(
-      OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)));
+  tbl = New<ASN1_STRING_TABLE>();
   if (tbl == nullptr) {
     goto err;
   }
diff --git a/crypto/asn1/asn1_lib.cc b/crypto/asn1/asn1_lib.cc
index 225361d..44b6585 100644
--- a/crypto/asn1/asn1_lib.cc
+++ b/crypto/asn1/asn1_lib.cc
@@ -22,6 +22,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -287,9 +288,7 @@
 }
 
 ASN1_STRING *ASN1_STRING_type_new(int type) {
-  ASN1_STRING *ret;
-
-  ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
+  ASN1_STRING *ret = New<ASN1_STRING>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/asn1/tasn_new.cc b/crypto/asn1/tasn_new.cc
index 8278c87..f73484b 100644
--- a/crypto/asn1/tasn_new.cc
+++ b/crypto/asn1/tasn_new.cc
@@ -22,6 +22,7 @@
 #include <openssl/obj.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -239,8 +240,7 @@
       return 1;
 
     case V_ASN1_ANY: {
-      ASN1_TYPE *typ =
-          reinterpret_cast<ASN1_TYPE *>(OPENSSL_malloc(sizeof(ASN1_TYPE)));
+      ASN1_TYPE *typ = New<ASN1_TYPE>();
       if (!typ) {
         return 0;
       }
diff --git a/crypto/base64/base64.cc b/crypto/base64/base64.cc
index 4e35690..91a44df 100644
--- a/crypto/base64/base64.cc
+++ b/crypto/base64/base64.cc
@@ -19,6 +19,7 @@
 #include <string.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
 using namespace bssl;
@@ -80,10 +81,7 @@
   return 1;
 }
 
-EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() {
-  return reinterpret_cast<EVP_ENCODE_CTX *>(
-      OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX)));
-}
+EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() { return NewZeroed<EVP_ENCODE_CTX>(); }
 
 void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) { OPENSSL_free(ctx); }
 
diff --git a/crypto/bio/bio.cc b/crypto/bio/bio.cc
index 5031f3c..9e89e9e 100644
--- a/crypto/bio/bio.cc
+++ b/crypto/bio/bio.cc
@@ -24,6 +24,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -33,7 +34,7 @@
     CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
 
 BIO *BIO_new(const BIO_METHOD *method) {
-  BIO *ret = reinterpret_cast<BIO *>(OPENSSL_zalloc(sizeof(BIO)));
+  BIO *ret = NewZeroed<BIO>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -588,8 +589,7 @@
 }
 
 BIO_METHOD *BIO_meth_new(int type, const char *name) {
-  BIO_METHOD *method =
-      reinterpret_cast<BIO_METHOD *>(OPENSSL_zalloc(sizeof(BIO_METHOD)));
+  BIO_METHOD *method = NewZeroed<BIO_METHOD>();
   if (method == nullptr) {
     return nullptr;
   }
diff --git a/crypto/bio/connect.cc b/crypto/bio/connect.cc
index b1466e4..7b6ab9e 100644
--- a/crypto/bio/connect.cc
+++ b/crypto/bio/connect.cc
@@ -34,6 +34,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -256,8 +257,7 @@
 }
 
 static BIO_CONNECT *BIO_CONNECT_new() {
-  BIO_CONNECT *ret =
-      reinterpret_cast<BIO_CONNECT *>(OPENSSL_zalloc(sizeof(BIO_CONNECT)));
+  BIO_CONNECT *ret = NewZeroed<BIO_CONNECT>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/bio/pair.cc b/crypto/bio/pair.cc
index 5a74201..a1d15a7 100644
--- a/crypto/bio/pair.cc
+++ b/crypto/bio/pair.cc
@@ -21,6 +21,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -48,8 +49,7 @@
 }  // namespace
 
 static int bio_new(BIO *bio) {
-  struct bio_bio_st *b =
-      reinterpret_cast<bio_bio_st *>(OPENSSL_zalloc(sizeof *b));
+  struct bio_bio_st *b = NewZeroed<struct bio_bio_st>();
   if (b == nullptr) {
     return 0;
   }
diff --git a/crypto/buf/buf.cc b/crypto/buf/buf.cc
index 773e8a7..a7c43aa 100644
--- a/crypto/buf/buf.cc
+++ b/crypto/buf/buf.cc
@@ -20,13 +20,12 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
 using namespace bssl;
 
-BUF_MEM *BUF_MEM_new() {
-  return reinterpret_cast<BUF_MEM *>(OPENSSL_zalloc(sizeof(BUF_MEM)));
-}
+BUF_MEM *BUF_MEM_new() { return NewZeroed<BUF_MEM>(); }
 
 void BUF_MEM_free(BUF_MEM *buf) {
   if (buf == nullptr) {
diff --git a/crypto/cms/cms.cc b/crypto/cms/cms.cc
index 82d2176..bee0d09 100644
--- a/crypto/cms/cms.cc
+++ b/crypto/cms/cms.cc
@@ -20,6 +20,7 @@
 #include <openssl/mem.h>
 #include <openssl/x509.h>
 
+#include "../mem_internal.h"
 #include "../pkcs7/internal.h"
 
 
@@ -53,8 +54,7 @@
     return nullptr;
   }
 
-  UniquePtr<CMS_ContentInfo> cms(
-      static_cast<CMS_ContentInfo *>(OPENSSL_zalloc(sizeof(CMS_ContentInfo))));
+  UniquePtr<CMS_ContentInfo> cms(NewZeroed<CMS_ContentInfo>());
   if (cms == nullptr) {
     return nullptr;
   }
diff --git a/crypto/conf/conf.cc b/crypto/conf/conf.cc
index 7ae71af..04b1eda 100644
--- a/crypto/conf/conf.cc
+++ b/crypto/conf/conf.cc
@@ -24,6 +24,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -69,7 +70,7 @@
     return nullptr;
   }
 
-  CONF *conf = reinterpret_cast<CONF *>(OPENSSL_malloc(sizeof(CONF)));
+  CONF *conf = New<CONF>();
   if (conf == nullptr) {
     return nullptr;
   }
@@ -84,9 +85,7 @@
   return conf;
 }
 
-CONF_VALUE *bssl::CONF_VALUE_new() {
-  return reinterpret_cast<CONF_VALUE *>(OPENSSL_zalloc(sizeof(CONF_VALUE)));
-}
+CONF_VALUE *bssl::CONF_VALUE_new() { return NewZeroed<CONF_VALUE>(); }
 
 static void value_free(CONF_VALUE *value) {
   if (value == nullptr) {
@@ -126,8 +125,7 @@
 }
 
 static CONF_SECTION *NCONF_new_section(const CONF *conf, const char *section) {
-  CONF_SECTION *s =
-      reinterpret_cast<CONF_SECTION *>(OPENSSL_malloc(sizeof(CONF_SECTION)));
+  CONF_SECTION *s = New<CONF_SECTION>();
   if (!s) {
     return nullptr;
   }
diff --git a/crypto/curve25519/spake25519.cc b/crypto/curve25519/spake25519.cc
index 32defdc..085e2e0 100644
--- a/crypto/curve25519/spake25519.cc
+++ b/crypto/curve25519/spake25519.cc
@@ -26,6 +26,7 @@
 
 #include "../fipsmodule/bn/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "./internal.h"
 
 
@@ -280,8 +281,7 @@
 SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role, const uint8_t *my_name,
                            size_t my_name_len, const uint8_t *their_name,
                            size_t their_name_len) {
-  SPAKE2_CTX *ctx =
-      reinterpret_cast<SPAKE2_CTX *>(OPENSSL_zalloc(sizeof(SPAKE2_CTX)));
+  SPAKE2_CTX *ctx = NewZeroed<SPAKE2_CTX>();
   if (ctx == nullptr) {
     return nullptr;
   }
diff --git a/crypto/dsa/dsa.cc b/crypto/dsa/dsa.cc
index 6d9c1fd..566cf15 100644
--- a/crypto/dsa/dsa.cc
+++ b/crypto/dsa/dsa.cc
@@ -29,6 +29,7 @@
 #include "../fipsmodule/bn/internal.h"
 #include "../fipsmodule/dh/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -48,7 +49,7 @@
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 DSA *DSA_new() {
-  DSA *dsa = reinterpret_cast<DSA *>(OPENSSL_zalloc(sizeof(DSA)));
+  DSA *dsa = NewZeroed<DSA>();
   if (dsa == nullptr) {
     return nullptr;
   }
@@ -479,9 +480,7 @@
   return ok;
 }
 
-DSA_SIG *DSA_SIG_new() {
-  return reinterpret_cast<DSA_SIG *>(OPENSSL_zalloc(sizeof(DSA_SIG)));
-}
+DSA_SIG *DSA_SIG_new() { return NewZeroed<DSA_SIG>(); }
 
 void DSA_SIG_free(DSA_SIG *sig) {
   if (!sig) {
diff --git a/crypto/ecdsa/ecdsa_asn1.cc b/crypto/ecdsa/ecdsa_asn1.cc
index 0270b26..6c3daa7 100644
--- a/crypto/ecdsa/ecdsa_asn1.cc
+++ b/crypto/ecdsa/ecdsa_asn1.cc
@@ -26,6 +26,7 @@
 #include "../bytestring/internal.h"
 #include "../fipsmodule/ecdsa/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
 using namespace bssl;
@@ -154,8 +155,7 @@
 }
 
 ECDSA_SIG *ECDSA_SIG_new() {
-  ECDSA_SIG *sig =
-      reinterpret_cast<ECDSA_SIG *>(OPENSSL_malloc(sizeof(ECDSA_SIG)));
+  ECDSA_SIG *sig = New<ECDSA_SIG>();
   if (sig == nullptr) {
     return nullptr;
   }
diff --git a/crypto/engine/engine.cc b/crypto/engine/engine.cc
index 1143465..90a71b3 100644
--- a/crypto/engine/engine.cc
+++ b/crypto/engine/engine.cc
@@ -23,16 +23,17 @@
 #include <openssl/rsa.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
+using namespace bssl;
+
 struct engine_st {
   RSA_METHOD *rsa_method;
   ECDSA_METHOD *ecdsa_method;
 };
 
-ENGINE *ENGINE_new() {
-  return reinterpret_cast<ENGINE *>(OPENSSL_zalloc(sizeof(ENGINE)));
-}
+ENGINE *ENGINE_new() { return NewZeroed<ENGINE>(); }
 
 int ENGINE_free(ENGINE *engine) {
   // Methods are currently required to be static so are not unref'ed.
diff --git a/crypto/evp/evp.cc b/crypto/evp/evp.cc
index c6845af..94f607f 100644
--- a/crypto/evp/evp.cc
+++ b/crypto/evp/evp.cc
@@ -22,6 +22,7 @@
 #include <openssl/nid.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -37,8 +38,7 @@
 OPENSSL_DECLARE_ERROR_REASON(EVP, EMPTY_PSK)
 
 EVP_PKEY *EVP_PKEY_new() {
-  EVP_PKEY *ret =
-      reinterpret_cast<EVP_PKEY *>(OPENSSL_zalloc(sizeof(EVP_PKEY)));
+  EVP_PKEY *ret = NewZeroed<EVP_PKEY>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/evp/p_dh.cc b/crypto/evp/p_dh.cc
index 178b6c8..1e09900 100644
--- a/crypto/evp/p_dh.cc
+++ b/crypto/evp/p_dh.cc
@@ -22,6 +22,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -169,8 +170,7 @@
 }  // namespace
 
 static int pkey_dh_init(EvpPkeyCtx *ctx) {
-  DH_PKEY_CTX *dctx =
-      reinterpret_cast<DH_PKEY_CTX *>(OPENSSL_zalloc(sizeof(DH_PKEY_CTX)));
+  DH_PKEY_CTX *dctx = NewZeroed<DH_PKEY_CTX>();
   if (dctx == nullptr) {
     return 0;
   }
diff --git a/crypto/evp/p_ec.cc b/crypto/evp/p_ec.cc
index 8ebeaaf..1a21d10 100644
--- a/crypto/evp/p_ec.cc
+++ b/crypto/evp/p_ec.cc
@@ -31,6 +31,7 @@
 #include "../ec/internal.h"
 #include "../fipsmodule/ec/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -381,8 +382,7 @@
 } EC_PKEY_CTX;
 
 static int pkey_ec_init(EvpPkeyCtx *ctx) {
-  EC_PKEY_CTX *dctx =
-      reinterpret_cast<EC_PKEY_CTX *>(OPENSSL_zalloc(sizeof(EC_PKEY_CTX)));
+  EC_PKEY_CTX *dctx = NewZeroed<EC_PKEY_CTX>();
   if (!dctx) {
     return 0;
   }
diff --git a/crypto/evp/p_ed25519.cc b/crypto/evp/p_ed25519.cc
index e01985c..110e66f 100644
--- a/crypto/evp/p_ed25519.cc
+++ b/crypto/evp/p_ed25519.cc
@@ -20,6 +20,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 using namespace bssl;
@@ -50,8 +51,7 @@
     return 0;
   }
 
-  ED25519_KEY *key =
-      reinterpret_cast<ED25519_KEY *>(OPENSSL_malloc(sizeof(ED25519_KEY)));
+  ED25519_KEY *key = New<ED25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
@@ -71,8 +71,7 @@
     return 0;
   }
 
-  ED25519_KEY *key =
-      reinterpret_cast<ED25519_KEY *>(OPENSSL_malloc(sizeof(ED25519_KEY)));
+  ED25519_KEY *key = New<ED25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
@@ -259,8 +258,7 @@
 static int pkey_ed25519_copy(EvpPkeyCtx *dst, EvpPkeyCtx *src) { return 1; }
 
 static int pkey_ed25519_keygen(EvpPkeyCtx *ctx, EVP_PKEY *pkey) {
-  ED25519_KEY *key =
-      reinterpret_cast<ED25519_KEY *>(OPENSSL_malloc(sizeof(ED25519_KEY)));
+  ED25519_KEY *key = New<ED25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
diff --git a/crypto/evp/p_hkdf.cc b/crypto/evp/p_hkdf.cc
index 613cefc..e40275b 100644
--- a/crypto/evp/p_hkdf.cc
+++ b/crypto/evp/p_hkdf.cc
@@ -21,6 +21,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -37,8 +38,7 @@
 } HKDF_PKEY_CTX;
 
 static int pkey_hkdf_init(EvpPkeyCtx *ctx) {
-  HKDF_PKEY_CTX *hctx =
-      reinterpret_cast<HKDF_PKEY_CTX *>(OPENSSL_zalloc(sizeof(HKDF_PKEY_CTX)));
+  HKDF_PKEY_CTX *hctx = NewZeroed<HKDF_PKEY_CTX>();
   if (hctx == nullptr) {
     return 0;
   }
diff --git a/crypto/evp/p_x25519.cc b/crypto/evp/p_x25519.cc
index 6259008..07eabaa 100644
--- a/crypto/evp/p_x25519.cc
+++ b/crypto/evp/p_x25519.cc
@@ -20,6 +20,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -46,8 +47,7 @@
     return 0;
   }
 
-  X25519_KEY *key =
-      reinterpret_cast<X25519_KEY *>(OPENSSL_malloc(sizeof(X25519_KEY)));
+  X25519_KEY *key = New<X25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
@@ -66,8 +66,7 @@
     return 0;
   }
 
-  X25519_KEY *key =
-      reinterpret_cast<X25519_KEY *>(OPENSSL_malloc(sizeof(X25519_KEY)));
+  X25519_KEY *key = New<X25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
@@ -276,8 +275,7 @@
 static int pkey_x25519_copy(EvpPkeyCtx *dst, EvpPkeyCtx *src) { return 1; }
 
 static int pkey_x25519_keygen(EvpPkeyCtx *ctx, EVP_PKEY *pkey) {
-  X25519_KEY *key =
-      reinterpret_cast<X25519_KEY *>(OPENSSL_malloc(sizeof(X25519_KEY)));
+  X25519_KEY *key = New<X25519_KEY>();
   if (key == nullptr) {
     return 0;
   }
diff --git a/crypto/ex_data.cc b/crypto/ex_data.cc
index d9495c6..fc6a102 100644
--- a/crypto/ex_data.cc
+++ b/crypto/ex_data.cc
@@ -24,6 +24,7 @@
 #include <openssl/mem.h>
 
 #include "internal.h"
+#include "mem_internal.h"
 
 
 BSSL_NAMESPACE_BEGIN
@@ -39,8 +40,7 @@
 
 int CRYPTO_get_ex_new_index_ex(CRYPTO_EX_DATA_CLASS *ex_data_class, long argl,
                                void *argp, CRYPTO_EX_free *free_func) {
-  CRYPTO_EX_DATA_FUNCS *funcs = reinterpret_cast<CRYPTO_EX_DATA_FUNCS *>(
-      OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)));
+  CRYPTO_EX_DATA_FUNCS *funcs = New<CRYPTO_EX_DATA_FUNCS>();
   if (funcs == nullptr) {
     return -1;
   }
diff --git a/crypto/fipsmodule/bn/bn.cc.inc b/crypto/fipsmodule/bn/bn.cc.inc
index f97bb63..670761d 100644
--- a/crypto/fipsmodule/bn/bn.cc.inc
+++ b/crypto/fipsmodule/bn/bn.cc.inc
@@ -21,6 +21,7 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../../mem_internal.h"
 #include "../delocate.h"
 #include "internal.h"
 
@@ -33,7 +34,7 @@
 #define BN_MAX_WORDS (INT_MAX / (4 * BN_BITS2))
 
 BIGNUM *BN_new() {
-  BIGNUM *bn = reinterpret_cast<BIGNUM *>(OPENSSL_malloc(sizeof(BIGNUM)));
+  BIGNUM *bn = New<BIGNUM>();
 
   if (bn == nullptr) {
     return nullptr;
diff --git a/crypto/fipsmodule/bn/montgomery.cc.inc b/crypto/fipsmodule/bn/montgomery.cc.inc
index cb253d8..18c1a30 100644
--- a/crypto/fipsmodule/bn/montgomery.cc.inc
+++ b/crypto/fipsmodule/bn/montgomery.cc.inc
@@ -23,6 +23,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "internal.h"
 
 
@@ -40,8 +41,7 @@
 }
 
 BN_MONT_CTX *BN_MONT_CTX_new() {
-  BN_MONT_CTX *ret =
-      reinterpret_cast<BN_MONT_CTX *>(OPENSSL_malloc(sizeof(BN_MONT_CTX)));
+  BN_MONT_CTX *ret = New<BN_MONT_CTX>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/bn/prime.cc.inc b/crypto/fipsmodule/bn/prime.cc.inc
index 5f00d65..aab1501 100644
--- a/crypto/fipsmodule/bn/prime.cc.inc
+++ b/crypto/fipsmodule/bn/prime.cc.inc
@@ -20,6 +20,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "internal.h"
 
 
@@ -269,9 +270,7 @@
 static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
                                   const BIGNUM *rem, BN_CTX *ctx);
 
-BN_GENCB *BN_GENCB_new() {
-  return reinterpret_cast<BN_GENCB *>(OPENSSL_zalloc(sizeof(BN_GENCB)));
-}
+BN_GENCB *BN_GENCB_new() { return NewZeroed<BN_GENCB>(); }
 
 void BN_GENCB_free(BN_GENCB *callback) { OPENSSL_free(callback); }
 
diff --git a/crypto/fipsmodule/cipher/aead.cc.inc b/crypto/fipsmodule/cipher/aead.cc.inc
index 123857d..ee0dabf 100644
--- a/crypto/fipsmodule/cipher/aead.cc.inc
+++ b/crypto/fipsmodule/cipher/aead.cc.inc
@@ -45,8 +45,7 @@
 
 EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key,
                                size_t key_len, size_t tag_len) {
-  EVP_AEAD_CTX *ctx =
-      reinterpret_cast<EVP_AEAD_CTX *>(OPENSSL_malloc(sizeof(EVP_AEAD_CTX)));
+  EVP_AEAD_CTX *ctx = New<EVP_AEAD_CTX>();
   if (!ctx) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/cipher/cipher.cc.inc b/crypto/fipsmodule/cipher/cipher.cc.inc
index 8ac9766..ab96513 100644
--- a/crypto/fipsmodule/cipher/cipher.cc.inc
+++ b/crypto/fipsmodule/cipher/cipher.cc.inc
@@ -24,6 +24,7 @@
 #include <openssl/span.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../service_indicator/internal.h"
 #include "internal.h"
 
@@ -35,8 +36,7 @@
 }
 
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new() {
-  EVP_CIPHER_CTX *ctx = reinterpret_cast<EVP_CIPHER_CTX *>(
-      OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)));
+  EVP_CIPHER_CTX *ctx = New<EVP_CIPHER_CTX>();
   if (ctx) {
     EVP_CIPHER_CTX_init(ctx);
   }
diff --git a/crypto/fipsmodule/cmac/cmac.cc.inc b/crypto/fipsmodule/cmac/cmac.cc.inc
index 038e629..b306696 100644
--- a/crypto/fipsmodule/cmac/cmac.cc.inc
+++ b/crypto/fipsmodule/cmac/cmac.cc.inc
@@ -23,6 +23,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../service_indicator/internal.h"
 
 
@@ -87,7 +88,7 @@
 }
 
 CMAC_CTX *CMAC_CTX_new() {
-  CMAC_CTX *ctx = reinterpret_cast<CMAC_CTX *>(OPENSSL_malloc(sizeof(*ctx)));
+  CMAC_CTX *ctx = New<CMAC_CTX>();
   if (ctx != nullptr) {
     CMAC_CTX_init(ctx);
   }
diff --git a/crypto/fipsmodule/dh/dh.cc.inc b/crypto/fipsmodule/dh/dh.cc.inc
index b3bd164..ac4c464 100644
--- a/crypto/fipsmodule/dh/dh.cc.inc
+++ b/crypto/fipsmodule/dh/dh.cc.inc
@@ -24,6 +24,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../bn/internal.h"
 #include "../service_indicator/internal.h"
 #include "internal.h"
@@ -32,7 +33,7 @@
 using namespace bssl;
 
 DH *DH_new() {
-  DH *dh = reinterpret_cast<DH *>(OPENSSL_zalloc(sizeof(DH)));
+  DH *dh = NewZeroed<DH>();
   if (dh == nullptr) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/digest/digest.cc.inc b/crypto/fipsmodule/digest/digest.cc.inc
index 95cad20..a70a6c4 100644
--- a/crypto/fipsmodule/digest/digest.cc.inc
+++ b/crypto/fipsmodule/digest/digest.cc.inc
@@ -21,6 +21,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "internal.h"
 
 
@@ -44,8 +45,7 @@
 }
 
 EVP_MD_CTX *EVP_MD_CTX_new() {
-  EVP_MD_CTX *ctx =
-      reinterpret_cast<EVP_MD_CTX *>(OPENSSL_malloc(sizeof(EVP_MD_CTX)));
+  EVP_MD_CTX *ctx = New<EVP_MD_CTX>();
 
   if (ctx) {
     EVP_MD_CTX_init(ctx);
diff --git a/crypto/fipsmodule/ec/ec.cc.inc b/crypto/fipsmodule/ec/ec.cc.inc
index 37ec575..16cd80e 100644
--- a/crypto/fipsmodule/ec/ec.cc.inc
+++ b/crypto/fipsmodule/ec/ec.cc.inc
@@ -26,6 +26,7 @@
 #include <openssl/nid.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../bn/internal.h"
 #include "../delocate.h"
 #include "internal.h"
@@ -201,8 +202,7 @@
     return nullptr;
   }
 
-  UniquePtr<EC_GROUP> ret(
-      reinterpret_cast<EC_GROUP *>(OPENSSL_zalloc(sizeof(EC_GROUP))));
+  UniquePtr<EC_GROUP> ret(NewZeroed<EC_GROUP>());
   if (ret == nullptr) {
     return nullptr;
   }
@@ -411,7 +411,7 @@
     return nullptr;
   }
 
-  EC_POINT *ret = reinterpret_cast<EC_POINT *>(OPENSSL_malloc(sizeof *ret));
+  EC_POINT *ret = New<EC_POINT>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/ec/ec_key.cc.inc b/crypto/fipsmodule/ec/ec_key.cc.inc
index d5133a7..c8d0acc 100644
--- a/crypto/fipsmodule/ec/ec_key.cc.inc
+++ b/crypto/fipsmodule/ec/ec_key.cc.inc
@@ -25,6 +25,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../bcm_interface.h"
 #include "../delocate.h"
 #include "../ecdsa/internal.h"
@@ -37,8 +38,7 @@
 DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class)
 
 static bssl::EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) {
-  EC_WRAPPED_SCALAR *wrapped = reinterpret_cast<EC_WRAPPED_SCALAR *>(
-      OPENSSL_zalloc(sizeof(EC_WRAPPED_SCALAR)));
+  EC_WRAPPED_SCALAR *wrapped = NewZeroed<EC_WRAPPED_SCALAR>();
   if (wrapped == nullptr) {
     return nullptr;
   }
@@ -57,7 +57,7 @@
 EC_KEY *EC_KEY_new() { return EC_KEY_new_method(nullptr); }
 
 EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
-  EC_KEY *ret = reinterpret_cast<EC_KEY *>(OPENSSL_zalloc(sizeof(EC_KEY)));
+  EC_KEY *ret = NewZeroed<EC_KEY>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/hmac/hmac.cc.inc b/crypto/fipsmodule/hmac/hmac.cc.inc
index 5a628db..b72997b 100644
--- a/crypto/fipsmodule/hmac/hmac.cc.inc
+++ b/crypto/fipsmodule/hmac/hmac.cc.inc
@@ -21,6 +21,7 @@
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../service_indicator/internal.h"
 
 
@@ -58,8 +59,7 @@
 }
 
 HMAC_CTX *HMAC_CTX_new() {
-  HMAC_CTX *ctx =
-      reinterpret_cast<HMAC_CTX *>(OPENSSL_malloc(sizeof(HMAC_CTX)));
+  HMAC_CTX *ctx = New<HMAC_CTX>();
   if (ctx != nullptr) {
     HMAC_CTX_init(ctx);
   }
diff --git a/crypto/fipsmodule/rand/ctrdrbg.cc.inc b/crypto/fipsmodule/rand/ctrdrbg.cc.inc
index 171754b..50b4a8d 100644
--- a/crypto/fipsmodule/rand/ctrdrbg.cc.inc
+++ b/crypto/fipsmodule/rand/ctrdrbg.cc.inc
@@ -19,6 +19,7 @@
 #include <openssl/mem.h>
 #include <algorithm>
 
+#include "../../mem_internal.h"
 #include "../aes/internal.h"
 #include "../service_indicator/internal.h"
 #include "internal.h"
@@ -149,8 +150,7 @@
 CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN],
                              const uint8_t *personalization,
                              size_t personalization_len) {
-  CTR_DRBG_STATE *drbg = reinterpret_cast<CTR_DRBG_STATE *>(
-      OPENSSL_malloc(sizeof(CTR_DRBG_STATE)));
+  CTR_DRBG_STATE *drbg = New<CTR_DRBG_STATE>();
   if (drbg == nullptr ||
       !CTR_DRBG_init(drbg, /*df=*/false, entropy, CTR_DRBG_ENTROPY_LEN,
                      /*nonce=*/nullptr, personalization, personalization_len)) {
@@ -165,8 +165,7 @@
                                 const uint8_t nonce[CTR_DRBG_NONCE_LEN],
                                 const uint8_t *personalization,
                                 size_t personalization_len) {
-  CTR_DRBG_STATE *drbg = reinterpret_cast<CTR_DRBG_STATE *>(
-      OPENSSL_malloc(sizeof(CTR_DRBG_STATE)));
+  CTR_DRBG_STATE *drbg = New<CTR_DRBG_STATE>();
   if (drbg == nullptr ||
       !CTR_DRBG_init(drbg, /*df=*/true, entropy, entropy_len, nonce,
                      personalization, personalization_len)) {
diff --git a/crypto/fipsmodule/rand/rand.cc.inc b/crypto/fipsmodule/rand/rand.cc.inc
index da47583..8375072 100644
--- a/crypto/fipsmodule/rand/rand.cc.inc
+++ b/crypto/fipsmodule/rand/rand.cc.inc
@@ -26,6 +26,7 @@
 #include <openssl/rand.h>
 
 #include "../../bcm_support.h"
+#include "../../mem_internal.h"
 #include "../bcm_interface.h"
 #include "../delocate.h"
 #include "internal.h"
@@ -371,8 +372,7 @@
       CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND));
 
   if (state == nullptr) {
-    state = reinterpret_cast<rand_thread_state *>(
-        OPENSSL_zalloc(sizeof(struct rand_thread_state)));
+    state = NewZeroed<rand_thread_state>();
     if (state == nullptr ||
         !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state,
                                  rand_thread_state_free)) {
diff --git a/crypto/fipsmodule/rsa/rsa.cc.inc b/crypto/fipsmodule/rsa/rsa.cc.inc
index 08b7ae8..81ae9f6 100644
--- a/crypto/fipsmodule/rsa/rsa.cc.inc
+++ b/crypto/fipsmodule/rsa/rsa.cc.inc
@@ -30,6 +30,7 @@
 #include <openssl/nid.h>
 
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "../bcm_interface.h"
 #include "../bn/internal.h"
 #include "../delocate.h"
@@ -167,7 +168,7 @@
 RSA *RSA_new() { return RSA_new_method(nullptr); }
 
 RSA *RSA_new_method(const ENGINE *engine) {
-  RSA *rsa = reinterpret_cast<RSA *>(OPENSSL_zalloc(sizeof(RSA)));
+  RSA *rsa = NewZeroed<RSA>();
   if (rsa == nullptr) {
     return nullptr;
   }
diff --git a/crypto/fipsmodule/service_indicator/service_indicator.cc.inc b/crypto/fipsmodule/service_indicator/service_indicator.cc.inc
index fd34802..ef8fb35 100644
--- a/crypto/fipsmodule/service_indicator/service_indicator.cc.inc
+++ b/crypto/fipsmodule/service_indicator/service_indicator.cc.inc
@@ -20,6 +20,7 @@
 
 #include "../../evp/internal.h"
 #include "../../internal.h"
+#include "../../mem_internal.h"
 #include "internal.h"
 
 
@@ -52,8 +53,7 @@
           OPENSSL_THREAD_LOCAL_FIPS_SERVICE_INDICATOR_STATE));
 
   if (indicator == nullptr) {
-    indicator = reinterpret_cast<fips_service_indicator_state *>(
-        OPENSSL_malloc(sizeof(struct fips_service_indicator_state)));
+    indicator = New<struct fips_service_indicator_state>();
     if (indicator == nullptr) {
       return nullptr;
     }
diff --git a/crypto/hpke/hpke.cc b/crypto/hpke/hpke.cc
index a8f9b94..752ea13 100644
--- a/crypto/hpke/hpke.cc
+++ b/crypto/hpke/hpke.cc
@@ -34,6 +34,7 @@
 #include "../fipsmodule/bcm_interface.h"
 #include "../fipsmodule/ec/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
 using namespace bssl;
@@ -898,8 +899,7 @@
 }
 
 EVP_HPKE_KEY *EVP_HPKE_KEY_new() {
-  EVP_HPKE_KEY *key =
-      reinterpret_cast<EVP_HPKE_KEY *>(OPENSSL_malloc(sizeof(EVP_HPKE_KEY)));
+  EVP_HPKE_KEY *key = New<EVP_HPKE_KEY>();
   if (key == nullptr) {
     return nullptr;
   }
@@ -1124,8 +1124,7 @@
 }
 
 EVP_HPKE_CTX *EVP_HPKE_CTX_new() {
-  EVP_HPKE_CTX *ctx =
-      reinterpret_cast<EVP_HPKE_CTX *>(OPENSSL_malloc(sizeof(EVP_HPKE_CTX)));
+  EVP_HPKE_CTX *ctx = New<EVP_HPKE_CTX>();
   if (ctx == nullptr) {
     return nullptr;
   }
diff --git a/crypto/lhash/lhash.cc b/crypto/lhash/lhash.cc
index a2cfc0c..eb2df04 100644
--- a/crypto/lhash/lhash.cc
+++ b/crypto/lhash/lhash.cc
@@ -19,6 +19,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -62,7 +63,7 @@
 };
 
 _LHASH *OPENSSL_lh_new(lhash_hash_func hash, lhash_cmp_func comp) {
-  _LHASH *ret = reinterpret_cast<_LHASH *>(OPENSSL_zalloc(sizeof(_LHASH)));
+  _LHASH *ret = NewZeroed<_LHASH>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -241,7 +242,7 @@
   }
 
   // An element equal to |data| doesn't exist in the hash table yet.
-  item = reinterpret_cast<LHASH_ITEM *>(OPENSSL_malloc(sizeof(LHASH_ITEM)));
+  item = New<LHASH_ITEM>();
   if (item == nullptr) {
     return 0;
   }
diff --git a/crypto/mem_internal.h b/crypto/mem_internal.h
index 3c6b347..4087cdc 100644
--- a/crypto/mem_internal.h
+++ b/crypto/mem_internal.h
@@ -52,6 +52,25 @@
   return new (t) T(std::forward<Args>(args)...);
 }
 
+// NewZeroed behaves like |new| but uses |OPENSSL_zalloc| for memory
+// allocation, thereby zeroing the memory prior to calling constructors. It
+// returns nullptr on allocation error. It only implements single-object
+// allocation and not new T[n].
+//
+// Note: unlike |new|, this does not support non-public constructors.
+//
+// TODO(crbug.com/42220000): Actually replace calls to this by explicitly
+// setting default values in the structs, or - when it can be shown this is not
+// necessary - simply by |New|.
+template <typename T, typename... Args>
+T *NewZeroed(Args &&...args) {
+  void *t = OPENSSL_zalloc(sizeof(T));
+  if (t == nullptr) {
+    return nullptr;
+  }
+  return new (t) T(std::forward<Args>(args)...);
+}
+
 // Delete behaves like |delete| but uses |OPENSSL_free| to release memory.
 //
 // Note: unlike |delete| this does not support non-public destructors.
diff --git a/crypto/pem/pem_info.cc b/crypto/pem/pem_info.cc
index 0a647fc..138ca81 100644
--- a/crypto/pem/pem_info.cc
+++ b/crypto/pem/pem_info.cc
@@ -27,14 +27,13 @@
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
 
+#include "../mem_internal.h"
 #include "internal.h"
 
 
 using namespace bssl;
 
-static X509_PKEY *X509_PKEY_new() {
-  return reinterpret_cast<X509_PKEY *>(OPENSSL_zalloc(sizeof(X509_PKEY)));
-}
+static X509_PKEY *X509_PKEY_new() { return NewZeroed<X509_PKEY>(); }
 
 static void X509_PKEY_free(X509_PKEY *x) {
   if (x == nullptr) {
@@ -45,9 +44,7 @@
   OPENSSL_free(x);
 }
 
-static X509_INFO *X509_INFO_new() {
-  return reinterpret_cast<X509_INFO *>(OPENSSL_zalloc(sizeof(X509_INFO)));
-}
+static X509_INFO *X509_INFO_new() { return NewZeroed<X509_INFO>(); }
 
 void X509_INFO_free(X509_INFO *x) {
   if (x == nullptr) {
diff --git a/crypto/pkcs7/pkcs7_x509.cc b/crypto/pkcs7/pkcs7_x509.cc
index 4207f2d..9af644c 100644
--- a/crypto/pkcs7/pkcs7_x509.cc
+++ b/crypto/pkcs7/pkcs7_x509.cc
@@ -32,6 +32,7 @@
 
 #include "../asn1/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "../x509/internal.h"
 #include "internal.h"
 
@@ -244,13 +245,12 @@
 
 static PKCS7 *pkcs7_new(CBS *cbs) {
   CBS copy = *cbs, copy2 = *cbs;
-  PKCS7 *ret = reinterpret_cast<PKCS7 *>(OPENSSL_zalloc(sizeof(PKCS7)));
+  PKCS7 *ret = NewZeroed<PKCS7>();
   if (ret == nullptr) {
     return nullptr;
   }
   ret->type = OBJ_nid2obj(NID_pkcs7_signed);
-  ret->d.sign =
-      reinterpret_cast<PKCS7_SIGNED *>(OPENSSL_malloc(sizeof(PKCS7_SIGNED)));
+  ret->d.sign = New<PKCS7_SIGNED>();
   if (ret->d.sign == nullptr) {
     goto err;
   }
diff --git a/crypto/pkcs8/pkcs8_x509.cc b/crypto/pkcs8/pkcs8_x509.cc
index c6cf3fb..9686485 100644
--- a/crypto/pkcs8/pkcs8_x509.cc
+++ b/crypto/pkcs8/pkcs8_x509.cc
@@ -33,6 +33,7 @@
 
 #include "../bytestring/internal.h"
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "../x509/internal.h"
 #include "internal.h"
 
@@ -700,7 +701,7 @@
 
 PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes,
                    size_t ber_len) {
-  PKCS12 *p12 = reinterpret_cast<PKCS12 *>(OPENSSL_malloc(sizeof(PKCS12)));
+  PKCS12 *p12 = New<PKCS12>();
   if (!p12) {
     return nullptr;
   }
@@ -1304,7 +1305,7 @@
       goto err;
     }
 
-    ret = reinterpret_cast<PKCS12 *>(OPENSSL_malloc(sizeof(PKCS12)));
+    ret = New<PKCS12>();
     if (ret == nullptr || !CBB_finish(&cbb, &ret->ber_bytes, &ret->ber_len)) {
       OPENSSL_free(ret);
       ret = nullptr;
diff --git a/crypto/pool/internal.h b/crypto/pool/internal.h
index 400eaae..a931638 100644
--- a/crypto/pool/internal.h
+++ b/crypto/pool/internal.h
@@ -39,7 +39,7 @@
 struct crypto_buffer_pool_st {
   LHASH_OF(CRYPTO_BUFFER) *bufs;
   bssl::CRYPTO_MUTEX lock;
-  const uint64_t hash_key[2];
+  uint64_t hash_key[2];
 };
 
 #endif  // OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H
diff --git a/crypto/pool/pool.cc b/crypto/pool/pool.cc
index e275274..cf71fd1 100644
--- a/crypto/pool/pool.cc
+++ b/crypto/pool/pool.cc
@@ -23,6 +23,7 @@
 #include <openssl/siphash.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -46,8 +47,7 @@
 }
 
 CRYPTO_BUFFER_POOL *CRYPTO_BUFFER_POOL_new() {
-  CRYPTO_BUFFER_POOL *pool = reinterpret_cast<CRYPTO_BUFFER_POOL *>(
-      OPENSSL_zalloc(sizeof(CRYPTO_BUFFER_POOL)));
+  CRYPTO_BUFFER_POOL *pool = NewZeroed<CRYPTO_BUFFER_POOL>();
   if (pool == nullptr) {
     return nullptr;
   }
@@ -114,8 +114,7 @@
     }
   }
 
-  CryptoBuffer *const buf =
-      reinterpret_cast<CryptoBuffer *>(OPENSSL_zalloc(sizeof(CryptoBuffer)));
+  CryptoBuffer *const buf = NewZeroed<CryptoBuffer>();
   if (buf == nullptr) {
     return nullptr;
   }
@@ -176,8 +175,7 @@
 }
 
 CRYPTO_BUFFER *CRYPTO_BUFFER_alloc(uint8_t **out_data, size_t len) {
-  CryptoBuffer *const buf =
-      reinterpret_cast<CryptoBuffer *>(OPENSSL_zalloc(sizeof(CryptoBuffer)));
+  CryptoBuffer *const buf = NewZeroed<CryptoBuffer>();
   if (buf == nullptr) {
     return nullptr;
   }
diff --git a/crypto/stack/stack.cc b/crypto/stack/stack.cc
index e46dfeb..1a217b1 100644
--- a/crypto/stack/stack.cc
+++ b/crypto/stack/stack.cc
@@ -21,6 +21,7 @@
 #include <openssl/mem.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 
 
 using namespace bssl;
@@ -44,8 +45,7 @@
 static const size_t kMinSize = 4;
 
 OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) {
-  OPENSSL_STACK *ret =
-      reinterpret_cast<OPENSSL_STACK *>(OPENSSL_zalloc(sizeof(OPENSSL_STACK)));
+  OPENSSL_STACK *ret = NewZeroed<OPENSSL_STACK>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -329,8 +329,7 @@
     return nullptr;
   }
 
-  OPENSSL_STACK *ret =
-      reinterpret_cast<OPENSSL_STACK *>(OPENSSL_zalloc(sizeof(OPENSSL_STACK)));
+  OPENSSL_STACK *ret = NewZeroed<OPENSSL_STACK>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/stack/stack_test.cc b/crypto/stack/stack_test.cc
index 6f1c359..4af1cc9 100644
--- a/crypto/stack/stack_test.cc
+++ b/crypto/stack/stack_test.cc
@@ -27,19 +27,20 @@
 #include <openssl/mem.h>
 #include <openssl/rand.h>
 
+#include "../mem_internal.h"
+
+
+BSSL_NAMESPACE_BEGIN
 
 // Define a custom stack type for testing.
 using TEST_INT = int;
 
 static void TEST_INT_free(TEST_INT *x) { OPENSSL_free(x); }
 
-BSSL_NAMESPACE_BEGIN
 BORINGSSL_MAKE_DELETER(TEST_INT, TEST_INT_free)
-BSSL_NAMESPACE_END
 
-static bssl::UniquePtr<TEST_INT> TEST_INT_new(int x) {
-  bssl::UniquePtr<TEST_INT> ret(
-      static_cast<TEST_INT *>(OPENSSL_malloc(sizeof(TEST_INT))));
+static UniquePtr<TEST_INT> TEST_INT_new(int x) {
+  UniquePtr<TEST_INT> ret(New<TEST_INT>());
   if (!ret) {
     return nullptr;
   }
@@ -47,7 +48,7 @@
   return ret;
 }
 
-DEFINE_STACK_OF(TEST_INT)
+DEFINE_NAMESPACED_STACK_OF(TEST_INT)
 
 namespace {
 
@@ -83,7 +84,7 @@
 }
 
 TEST(StackTest, Basic) {
-  bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
+  UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
   ASSERT_TRUE(sk);
 
   // The stack starts out empty.
@@ -98,7 +99,7 @@
   for (int i = 0; i < 6; i++) {
     auto value = TEST_INT_new(i);
     ASSERT_TRUE(value);
-    ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+    ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
   }
 
   ExpectStackEquals(sk.get(), {0, 1, 2, 3, 4, 5});
@@ -138,7 +139,7 @@
   ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7, 8});
 
   // Test removing elements from various places.
-  bssl::UniquePtr<TEST_INT> removed(sk_TEST_INT_pop(sk.get()));
+  UniquePtr<TEST_INT> removed(sk_TEST_INT_pop(sk.get()));
   EXPECT_EQ(8, *removed);
   ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7});
 
@@ -165,7 +166,7 @@
   ExpectStackEquals(sk.get(), {kNull, 1, 2, 4, 5, 7});
 
   // Test both deep and shallow copies.
-  bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
+  UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
       sk.get(),
       [](const TEST_INT *x) -> TEST_INT * {
         return x == nullptr ? nullptr : TEST_INT_new(*x).release();
@@ -198,7 +199,7 @@
 }
 
 TEST(StackTest, BigStack) {
-  bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
+  UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
   ASSERT_TRUE(sk);
 
   std::vector<int> expected;
@@ -206,7 +207,7 @@
   for (int i = 0; i < kCount; i++) {
     auto value = TEST_INT_new(i);
     ASSERT_TRUE(value);
-    ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+    ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
     expected.push_back(i);
   }
   ExpectStackEquals(sk.get(), expected);
@@ -233,12 +234,12 @@
   std::vector<int> vec_sorted = {0, 1, 2, 3, 4, 5, 6};
   std::vector<int> vec = vec_sorted;
   do {
-    bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+    UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
     ASSERT_TRUE(sk);
     for (int v : vec) {
       auto value = TEST_INT_new(v);
       ASSERT_TRUE(value);
-      ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+      ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
     }
 
     // The stack is not (known to be) sorted.
@@ -275,7 +276,7 @@
     EXPECT_EQ(3u, index);
 
     // Copies preserve comparison and sorted information.
-    bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
+    UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
         sk.get(),
         [](const TEST_INT *x) -> TEST_INT * {
           return TEST_INT_new(*x).release();
@@ -311,7 +312,7 @@
     // Inserting a new element invalidates sortedness.
     auto tmp = TEST_INT_new(10);
     ASSERT_TRUE(tmp);
-    ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(tmp)));
+    ASSERT_TRUE(PushToStack(sk.get(), std::move(tmp)));
     EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
     ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
     EXPECT_EQ(6u, index);
@@ -320,15 +321,15 @@
 
 // sk_*_find should return the first matching element in all cases.
 TEST(StackTest, FindFirst) {
-  bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+  UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
   ASSERT_TRUE(sk);
   auto value = TEST_INT_new(1);
   ASSERT_TRUE(value);
-  ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+  ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
   for (int i = 0; i < 10; i++) {
     value = TEST_INT_new(2);
     ASSERT_TRUE(value);
-    ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+    ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
   }
 
   const TEST_INT *two = sk_TEST_INT_value(sk.get(), 1);
@@ -366,22 +367,22 @@
       SCOPED_TRACE(j);
       // Make a stack where [0, i) are below, [i, j) match, and [j, kCount) are
       // above.
-      bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+      UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
       ASSERT_TRUE(sk);
       for (size_t k = 0; k < i; k++) {
         auto value = TEST_INT_new(-1);
         ASSERT_TRUE(value);
-        ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+        ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
       }
       for (size_t k = i; k < j; k++) {
         auto value = TEST_INT_new(0);
         ASSERT_TRUE(value);
-        ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+        ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
       }
       for (size_t k = j; k < kCount; k++) {
         auto value = TEST_INT_new(1);
         ASSERT_TRUE(value);
-        ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+        ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
       }
       sk_TEST_INT_sort(sk.get());
 
@@ -401,12 +402,12 @@
 }
 
 TEST(StackTest, DeleteIf) {
-  bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+  UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
   ASSERT_TRUE(sk);
   for (int v : {1, 9, 2, 8, 3, 7, 4, 6, 5}) {
     auto obj = TEST_INT_new(v);
     ASSERT_TRUE(obj);
-    ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(obj)));
+    ASSERT_TRUE(PushToStack(sk.get(), std::move(obj)));
   }
 
   auto keep_only_multiples = [](TEST_INT *x, void *data) {
@@ -443,7 +444,7 @@
 }
 
 TEST(StackTest, IsSorted) {
-  bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
+  UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
   ASSERT_TRUE(sk);
   EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
 
@@ -454,13 +455,13 @@
   // As are one-element lists.
   auto value = TEST_INT_new(2);
   ASSERT_TRUE(value);
-  ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+  ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
   EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
 
   // Two-element lists require an explicit sort.
   value = TEST_INT_new(1);
   ASSERT_TRUE(value);
-  ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+  ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
   EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
 
   // The list is now sorted.
@@ -499,12 +500,12 @@
       SCOPED_TRACE(testing::PrintToString(vec));
 
       // Convert it to a |STACK_OF(TEST_INT)|.
-      bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+      UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
       ASSERT_TRUE(sk);
       for (int v : vec) {
         auto value = TEST_INT_new(v);
         ASSERT_TRUE(value);
-        ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
+        ASSERT_TRUE(PushToStack(sk.get(), std::move(value)));
       }
 
       // Sort it with our sort implementation.
@@ -531,7 +532,7 @@
   EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 0));
   EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 1));
 
-  bssl::UniquePtr<TEST_INT> value = TEST_INT_new(6);
+  UniquePtr<TEST_INT> value = TEST_INT_new(6);
   ASSERT_TRUE(value);
   size_t index;
   EXPECT_FALSE(sk_TEST_INT_find(nullptr, &index, value.get()));
@@ -572,3 +573,4 @@
 }
 
 }  // namespace
+BSSL_NAMESPACE_END
diff --git a/crypto/trust_token/pmbtoken.cc b/crypto/trust_token/pmbtoken.cc
index 5fed2b4..5daa147 100644
--- a/crypto/trust_token/pmbtoken.cc
+++ b/crypto/trust_token/pmbtoken.cc
@@ -26,6 +26,7 @@
 #include "../ec/internal.h"
 #include "../fipsmodule/bn/internal.h"
 #include "../fipsmodule/ec/internal.h"
+#include "../mem_internal.h"
 
 #include "internal.h"
 
@@ -337,8 +338,7 @@
 
   for (size_t i = 0; i < count; i++) {
     // Insert |pretoken| into |pretokens| early to simplify error-handling.
-    TRUST_TOKEN_PRETOKEN *pretoken = reinterpret_cast<TRUST_TOKEN_PRETOKEN *>(
-        OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)));
+    TRUST_TOKEN_PRETOKEN *pretoken = New<TRUST_TOKEN_PRETOKEN>();
     if (pretoken == nullptr ||
         !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) {
       TRUST_TOKEN_PRETOKEN_free(pretoken);
diff --git a/crypto/trust_token/trust_token.cc b/crypto/trust_token/trust_token.cc
index d356b50..6f72785 100644
--- a/crypto/trust_token/trust_token.cc
+++ b/crypto/trust_token/trust_token.cc
@@ -22,6 +22,7 @@
 #include <openssl/mem.h>
 #include <openssl/sha2.h>
 
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -123,8 +124,7 @@
 }
 
 TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
-  TRUST_TOKEN *ret =
-      reinterpret_cast<TRUST_TOKEN *>(OPENSSL_zalloc(sizeof(TRUST_TOKEN)));
+  TRUST_TOKEN *ret = NewZeroed<TRUST_TOKEN>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -210,8 +210,7 @@
     return nullptr;
   }
 
-  TRUST_TOKEN_CLIENT *ret = reinterpret_cast<TRUST_TOKEN_CLIENT *>(
-      OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT)));
+  TRUST_TOKEN_CLIENT *ret = NewZeroed<TRUST_TOKEN_CLIENT>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -475,8 +474,7 @@
     return nullptr;
   }
 
-  TRUST_TOKEN_ISSUER *ret = reinterpret_cast<TRUST_TOKEN_ISSUER *>(
-      OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER)));
+  TRUST_TOKEN_ISSUER *ret = NewZeroed<TRUST_TOKEN_ISSUER>();
   if (ret == nullptr) {
     return nullptr;
   }
diff --git a/crypto/trust_token/voprf.cc b/crypto/trust_token/voprf.cc
index 16101e2..5c44c6c 100644
--- a/crypto/trust_token/voprf.cc
+++ b/crypto/trust_token/voprf.cc
@@ -25,6 +25,7 @@
 
 #include "../ec/internal.h"
 #include "../fipsmodule/ec/internal.h"
+#include "../mem_internal.h"
 
 #include "internal.h"
 
@@ -211,8 +212,7 @@
 
   for (size_t i = 0; i < count; i++) {
     // Insert |pretoken| into |pretokens| early to simplify error-handling.
-    TRUST_TOKEN_PRETOKEN *pretoken = reinterpret_cast<TRUST_TOKEN_PRETOKEN *>(
-        OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)));
+    TRUST_TOKEN_PRETOKEN *pretoken = New<TRUST_TOKEN_PRETOKEN>();
     if (pretoken == nullptr ||
         !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) {
       TRUST_TOKEN_PRETOKEN_free(pretoken);
diff --git a/crypto/x509/by_dir.cc b/crypto/x509/by_dir.cc
index 9f625b2..bc96828 100644
--- a/crypto/x509/by_dir.cc
+++ b/crypto/x509/by_dir.cc
@@ -21,6 +21,7 @@
 #include <openssl/x509.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -96,7 +97,7 @@
 static int new_dir(X509_LOOKUP *lu) {
   BY_DIR *a;
 
-  if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == nullptr) {
+  if ((a = New<BY_DIR>()) == nullptr) {
     return 0;
   }
   a->dirs = nullptr;
@@ -175,8 +176,7 @@
           return 0;
         }
       }
-      ent = reinterpret_cast<BY_DIR_ENTRY *>(
-          OPENSSL_malloc(sizeof(BY_DIR_ENTRY)));
+      ent = New<BY_DIR_ENTRY>();
       if (!ent) {
         return 0;
       }
@@ -309,8 +309,7 @@
           }
         }
         if (!hent) {
-          hent = reinterpret_cast<BY_DIR_HASH *>(
-              OPENSSL_malloc(sizeof(BY_DIR_HASH)));
+          hent = New<BY_DIR_HASH>();
           if (hent == nullptr) {
             CRYPTO_MUTEX_unlock_write(&ent->lock);
             ok = 0;
diff --git a/crypto/x509/policy.cc b/crypto/x509/policy.cc
index c35641e..a507914 100644
--- a/crypto/x509/policy.cc
+++ b/crypto/x509/policy.cc
@@ -21,6 +21,7 @@
 #include <openssl/stack.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -105,8 +106,7 @@
 
 static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) {
   assert(!is_any_policy(policy));
-  X509_POLICY_NODE *node = reinterpret_cast<X509_POLICY_NODE *>(
-      OPENSSL_zalloc(sizeof(X509_POLICY_NODE)));
+  X509_POLICY_NODE *node = NewZeroed<X509_POLICY_NODE>();
   if (node == nullptr) {
     return nullptr;
   }
@@ -132,8 +132,7 @@
 }
 
 static X509_POLICY_LEVEL *x509_policy_level_new() {
-  X509_POLICY_LEVEL *level = reinterpret_cast<X509_POLICY_LEVEL *>(
-      OPENSSL_zalloc(sizeof(X509_POLICY_LEVEL)));
+  X509_POLICY_LEVEL *level = NewZeroed<X509_POLICY_LEVEL>();
   if (level == nullptr) {
     return nullptr;
   }
diff --git a/crypto/x509/v3_lib.cc b/crypto/x509/v3_lib.cc
index b972d17..4a80b5d 100644
--- a/crypto/x509/v3_lib.cc
+++ b/crypto/x509/v3_lib.cc
@@ -159,8 +159,7 @@
     OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
     return 0;
   }
-  if (!(tmpext =
-            (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
+  if (!(tmpext = New<X509V3_EXT_METHOD>())) {
     return 0;
   }
   *tmpext = *ext;
diff --git a/crypto/x509/x509_lu.cc b/crypto/x509/x509_lu.cc
index a7380b5..ae2b93c 100644
--- a/crypto/x509/x509_lu.cc
+++ b/crypto/x509/x509_lu.cc
@@ -21,6 +21,7 @@
 #include <openssl/x509.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -42,8 +43,7 @@
 
 static X509_LOOKUP *X509_LOOKUP_new(const X509_LOOKUP_METHOD *method,
                                     X509_STORE *store) {
-  X509_LOOKUP *ret =
-      reinterpret_cast<X509_LOOKUP *>(OPENSSL_zalloc(sizeof(X509_LOOKUP)));
+  X509_LOOKUP *ret = NewZeroed<X509_LOOKUP>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -129,8 +129,7 @@
 }
 
 X509_STORE *X509_STORE_new() {
-  X509_STORE *ret =
-      reinterpret_cast<X509_STORE *>(OPENSSL_zalloc(sizeof(X509_STORE)));
+  X509_STORE *ret = NewZeroed<X509_STORE>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -258,9 +257,7 @@
   return x509_store_add(ctx, x, /*is_crl=*/1);
 }
 
-X509_OBJECT *X509_OBJECT_new() {
-  return reinterpret_cast<X509_OBJECT *>(OPENSSL_zalloc(sizeof(X509_OBJECT)));
-}
+X509_OBJECT *X509_OBJECT_new() { return NewZeroed<X509_OBJECT>(); }
 
 void X509_OBJECT_free(X509_OBJECT *obj) {
   if (obj == nullptr) {
diff --git a/crypto/x509/x509_vfy.cc b/crypto/x509/x509_vfy.cc
index 4cd301e..efe5527 100644
--- a/crypto/x509/x509_vfy.cc
+++ b/crypto/x509/x509_vfy.cc
@@ -25,6 +25,7 @@
 #include <openssl/x509.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -1486,10 +1487,7 @@
   return 1;
 }
 
-X509_STORE_CTX *X509_STORE_CTX_new() {
-  return reinterpret_cast<X509_STORE_CTX *>(
-      OPENSSL_zalloc(sizeof(X509_STORE_CTX)));
-}
+X509_STORE_CTX *X509_STORE_CTX_new() { return NewZeroed<X509_STORE_CTX>(); }
 
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx) {
   if (ctx == nullptr) {
diff --git a/crypto/x509/x509_vpm.cc b/crypto/x509/x509_vpm.cc
index 4ab6a6b..b06f32b 100644
--- a/crypto/x509/x509_vpm.cc
+++ b/crypto/x509/x509_vpm.cc
@@ -20,6 +20,7 @@
 #include <openssl/x509.h>
 
 #include "../internal.h"
+#include "../mem_internal.h"
 #include "internal.h"
 
 
@@ -76,8 +77,7 @@
 }
 
 X509_VERIFY_PARAM *X509_VERIFY_PARAM_new() {
-  X509_VERIFY_PARAM *param = reinterpret_cast<X509_VERIFY_PARAM *>(
-      OPENSSL_zalloc(sizeof(X509_VERIFY_PARAM)));
+  X509_VERIFY_PARAM *param = NewZeroed<X509_VERIFY_PARAM>();
   if (!param) {
     return nullptr;
   }
diff --git a/crypto/x509/x_name.cc b/crypto/x509/x_name.cc
index b92eb6c..3715e04 100644
--- a/crypto/x509/x_name.cc
+++ b/crypto/x509/x_name.cc
@@ -141,9 +141,7 @@
   x509_name_cache_free(impl->cache.exchange(nullptr));
 }
 
-X509_NAME *X509_NAME_new() {
-  return static_cast<X509Name *>(OPENSSL_zalloc(sizeof(X509Name)));
-}
+X509_NAME *X509_NAME_new() { return NewZeroed<X509Name>(); }
 
 void X509_NAME_free(X509_NAME *name) {
   if (name != nullptr) {
@@ -230,8 +228,7 @@
     return cache;
   }
 
-  X509_NAME_CACHE *new_cache =
-      static_cast<X509_NAME_CACHE *>(OPENSSL_zalloc(sizeof(X509_NAME_CACHE)));
+  X509_NAME_CACHE *new_cache = NewZeroed<X509_NAME_CACHE>();
   // Cache the DER encoding, including the outer TLV.
   ScopedCBB cbb;
   CBB seq;
diff --git a/crypto/x509/x_x509.cc b/crypto/x509/x_x509.cc
index ca33526..dced8fd 100644
--- a/crypto/x509/x_x509.cc
+++ b/crypto/x509/x_x509.cc
@@ -45,11 +45,10 @@
     CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
 
 X509 *X509_new() {
-  UniquePtr<X509Impl> ret(New<X509Impl>());
+  UniquePtr<X509Impl> ret(NewZeroed<X509Impl>());
   if (ret == nullptr) {
     return nullptr;
   }
-  OPENSSL_memset(ret.get(), 0, sizeof(*ret));
 
   ret->references = 1;
   ret->ex_pathlen = -1;
diff --git a/decrepit/bio/base64_bio.cc b/decrepit/bio/base64_bio.cc
index f5fa50d..056cf3c 100644
--- a/decrepit/bio/base64_bio.cc
+++ b/decrepit/bio/base64_bio.cc
@@ -23,8 +23,9 @@
 #include <openssl/evp.h>
 #include <openssl/mem.h>
 
-#include "../../crypto/internal.h"
 #include "../../crypto/bio/internal.h"
+#include "../../crypto/internal.h"
+#include "../../crypto/mem_internal.h"
 
 
 #define B64_BLOCK_SIZE 1024
@@ -50,8 +51,7 @@
 } BIO_B64_CTX;
 
 static int b64_new(BIO *bio) {
-  BIO_B64_CTX *ctx =
-      reinterpret_cast<BIO_B64_CTX *>(OPENSSL_zalloc(sizeof(*ctx)));
+  BIO_B64_CTX *ctx = NewZeroed<BIO_B64_CTX>();
   if (ctx == nullptr) {
     return 0;
   }
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index fec191e..7e9805f 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -629,6 +629,20 @@
   return true;
 }
 
+// Define begin() and end() for stack types so C++ range for loops work.
+// This pair of functions is for DEFINE_NAMESPACED_STACK_OF stacks, unlike
+// the other pair, which is for DEFINE_STACK_OF ones.
+template <typename Stack>
+inline bssl::internal::StackIterator<Stack> begin(const Stack *sk) {
+  return bssl::internal::StackIterator<Stack>(sk, 0);
+}
+
+template <typename Stack>
+inline bssl::internal::StackIterator<Stack> end(const Stack *sk) {
+  return bssl::internal::StackIterator<Stack>(
+      sk, OPENSSL_sk_num(reinterpret_cast<const OPENSSL_STACK *>(sk)));
+}
+
 BSSL_NAMESPACE_END
 
 // Define begin() and end() for stack types so C++ range for loops work.
diff --git a/util/audit_symbols.go b/util/audit_symbols.go
index 1f8a48f..6aef183 100644
--- a/util/audit_symbols.go
+++ b/util/audit_symbols.go
@@ -89,6 +89,14 @@
 	// TODO(crbug.com/42220000): Temporary symbols, to be eliminated.
 	regexp.MustCompile(`.*CMS_ContentInfo_st.*`),
 	regexp.MustCompile(`.*CMS_SignerInfo_st.*`),
+	regexp.MustCompile(`.*bio_st.*`),
+	regexp.MustCompile(`.*dh_st.*`),
+	regexp.MustCompile(`.*dsa_st.*`),
+	regexp.MustCompile(`.*ec_group_st.*`),
+	regexp.MustCompile(`.*ec_key_st.*`),
+	regexp.MustCompile(`.*evp_pkey_st.*`),
+	regexp.MustCompile(`.*rsa_st.*`),
+	regexp.MustCompile(`.*x509_store_st.*`),
 }
 
 const (