Add OPENSSL_zalloc

OpenSSL added a similar helper function. It's very, very common for us
to malloc something an then zero it. This saves some effort. Also
replace some more malloc + memcpy pairs with memdup.

Change-Id: I1e765c8774a0d15742827c39a1f16df9748ef247
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63345
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 8a90b43..e896ead 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -127,11 +127,10 @@
           return 1;
         }
       }
-      *pval = OPENSSL_malloc(it->size);
+      *pval = OPENSSL_zalloc(it->size);
       if (!*pval) {
         goto memerr;
       }
-      OPENSSL_memset(*pval, 0, it->size);
       asn1_set_choice_selector(pval, -1, it);
       if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) {
         goto auxerr2;
@@ -151,11 +150,10 @@
           return 1;
         }
       }
-      *pval = OPENSSL_malloc(it->size);
+      *pval = OPENSSL_zalloc(it->size);
       if (!*pval) {
         goto memerr;
       }
-      OPENSSL_memset(*pval, 0, it->size);
       asn1_refcount_set_one(pval, it);
       asn1_enc_init(pval, it);
       for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
diff --git a/crypto/base64/base64.c b/crypto/base64/base64.c
index d2b1e58..666f832 100644
--- a/crypto/base64/base64.c
+++ b/crypto/base64/base64.c
@@ -121,12 +121,7 @@
 }
 
 EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void) {
-  EVP_ENCODE_CTX *ret = OPENSSL_malloc(sizeof(EVP_ENCODE_CTX));
-  if (ret == NULL) {
-    return NULL;
-  }
-  OPENSSL_memset(ret, 0, sizeof(EVP_ENCODE_CTX));
-  return ret;
+  return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
 }
 
 void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) {
diff --git a/crypto/bio/bio.c b/crypto/bio/bio.c
index b2d9563..ed24560 100644
--- a/crypto/bio/bio.c
+++ b/crypto/bio/bio.c
@@ -70,12 +70,11 @@
 
 
 BIO *BIO_new(const BIO_METHOD *method) {
-  BIO *ret = OPENSSL_malloc(sizeof(BIO));
+  BIO *ret = OPENSSL_zalloc(sizeof(BIO));
   if (ret == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(ret, 0, sizeof(BIO));
   ret->method = method;
   ret->shutdown = 1;
   ret->references = 1;
@@ -640,11 +639,10 @@
 }
 
 BIO_METHOD *BIO_meth_new(int type, const char *name) {
-  BIO_METHOD *method = OPENSSL_malloc(sizeof(BIO_METHOD));
+  BIO_METHOD *method = OPENSSL_zalloc(sizeof(BIO_METHOD));
   if (method == NULL) {
     return NULL;
   }
-  OPENSSL_memset(method, 0, sizeof(BIO_METHOD));
   method->type = type;
   method->name = name;
   return method;
diff --git a/crypto/bio/connect.c b/crypto/bio/connect.c
index d48d14e..900e659 100644
--- a/crypto/bio/connect.c
+++ b/crypto/bio/connect.c
@@ -296,13 +296,10 @@
 }
 
 static BIO_CONNECT *BIO_CONNECT_new(void) {
-  BIO_CONNECT *ret = OPENSSL_malloc(sizeof(BIO_CONNECT));
-
+  BIO_CONNECT *ret = OPENSSL_zalloc(sizeof(BIO_CONNECT));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(BIO_CONNECT));
-
   ret->state = BIO_CONN_S_BEFORE;
   return ret;
 }
diff --git a/crypto/bio/pair.c b/crypto/bio/pair.c
index 40711cd..988b4ce 100644
--- a/crypto/bio/pair.c
+++ b/crypto/bio/pair.c
@@ -81,13 +81,10 @@
 };
 
 static int bio_new(BIO *bio) {
-  struct bio_bio_st *b;
-
-  b = OPENSSL_malloc(sizeof *b);
+  struct bio_bio_st *b = OPENSSL_zalloc(sizeof *b);
   if (b == NULL) {
     return 0;
   }
-  OPENSSL_memset(b, 0, sizeof(struct bio_bio_st));
 
   b->size = 17 * 1024;  // enough for one TLS record (just a default)
   bio->ptr = b;
diff --git a/crypto/buf/buf.c b/crypto/buf/buf.c
index 57bf34d..1fe8fe6 100644
--- a/crypto/buf/buf.c
+++ b/crypto/buf/buf.c
@@ -64,17 +64,7 @@
 #include "../internal.h"
 
 
-BUF_MEM *BUF_MEM_new(void) {
-  BUF_MEM *ret;
-
-  ret = OPENSSL_malloc(sizeof(BUF_MEM));
-  if (ret == NULL) {
-    return NULL;
-  }
-
-  OPENSSL_memset(ret, 0, sizeof(BUF_MEM));
-  return ret;
-}
+BUF_MEM *BUF_MEM_new(void) { return OPENSSL_zalloc(sizeof(BUF_MEM)); }
 
 void BUF_MEM_free(BUF_MEM *buf) {
   if (buf == NULL) {
diff --git a/crypto/conf/conf.c b/crypto/conf/conf.c
index ca950d6..024fa74 100644
--- a/crypto/conf/conf.c
+++ b/crypto/conf/conf.c
@@ -118,14 +118,7 @@
   return conf;
 }
 
-CONF_VALUE *CONF_VALUE_new(void) {
-  CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE));
-  if (!v) {
-    return NULL;
-  }
-  OPENSSL_memset(v, 0, sizeof(CONF_VALUE));
-  return v;
-}
+CONF_VALUE *CONF_VALUE_new(void) { return OPENSSL_zalloc(sizeof(CONF_VALUE)); }
 
 static void value_free_contents(CONF_VALUE *value) {
   OPENSSL_free(value->section);
diff --git a/crypto/curve25519/spake25519.c b/crypto/curve25519/spake25519.c
index c45d15a..adbf60d 100644
--- a/crypto/curve25519/spake25519.c
+++ b/crypto/curve25519/spake25519.c
@@ -272,12 +272,11 @@
 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 = OPENSSL_malloc(sizeof(SPAKE2_CTX));
+  SPAKE2_CTX *ctx = OPENSSL_zalloc(sizeof(SPAKE2_CTX));
   if (ctx == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(ctx, 0, sizeof(SPAKE2_CTX));
   ctx->my_role = my_role;
 
   CBS my_name_cbs, their_name_cbs;
diff --git a/crypto/dsa/dsa.c b/crypto/dsa/dsa.c
index 5eb7894..4583dc6 100644
--- a/crypto/dsa/dsa.c
+++ b/crypto/dsa/dsa.c
@@ -88,18 +88,14 @@
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 DSA *DSA_new(void) {
-  DSA *dsa = OPENSSL_malloc(sizeof(DSA));
+  DSA *dsa = OPENSSL_zalloc(sizeof(DSA));
   if (dsa == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(dsa, 0, sizeof(DSA));
-
   dsa->references = 1;
-
   CRYPTO_MUTEX_init(&dsa->method_mont_lock);
   CRYPTO_new_ex_data(&dsa->ex_data);
-
   return dsa;
 }
 
@@ -533,16 +529,7 @@
   return ok;
 }
 
-DSA_SIG *DSA_SIG_new(void) {
-  DSA_SIG *sig;
-  sig = OPENSSL_malloc(sizeof(DSA_SIG));
-  if (!sig) {
-    return NULL;
-  }
-  sig->r = NULL;
-  sig->s = NULL;
-  return sig;
-}
+DSA_SIG *DSA_SIG_new(void) { return OPENSSL_zalloc(sizeof(DSA_SIG)); }
 
 void DSA_SIG_free(DSA_SIG *sig) {
   if (!sig) {
diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c
index 973a57c..831d468 100644
--- a/crypto/engine/engine.c
+++ b/crypto/engine/engine.c
@@ -31,15 +31,7 @@
   ECDSA_METHOD *ecdsa_method;
 };
 
-ENGINE *ENGINE_new(void) {
-  ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE));
-  if (engine == NULL) {
-    return NULL;
-  }
-
-  OPENSSL_memset(engine, 0, sizeof(ENGINE));
-  return engine;
-}
+ENGINE *ENGINE_new(void) { return OPENSSL_zalloc(sizeof(ENGINE)); }
 
 int ENGINE_free(ENGINE *engine) {
   // Methods are currently required to be static so are not unref'ed.
diff --git a/crypto/evp/evp.c b/crypto/evp/evp.c
index 37b3631..f3f3d7e 100644
--- a/crypto/evp/evp.c
+++ b/crypto/evp/evp.c
@@ -81,17 +81,13 @@
 OPENSSL_DECLARE_ERROR_REASON(EVP, EMPTY_PSK)
 
 EVP_PKEY *EVP_PKEY_new(void) {
-  EVP_PKEY *ret;
-
-  ret = OPENSSL_malloc(sizeof(EVP_PKEY));
+  EVP_PKEY *ret = OPENSSL_zalloc(sizeof(EVP_PKEY));
   if (ret == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(ret, 0, sizeof(EVP_PKEY));
   ret->type = EVP_PKEY_NONE;
   ret->references = 1;
-
   return ret;
 }
 
diff --git a/crypto/evp/evp_ctx.c b/crypto/evp/evp_ctx.c
index 771f13f..ea2781f 100644
--- a/crypto/evp/evp_ctx.c
+++ b/crypto/evp/evp_ctx.c
@@ -86,11 +86,10 @@
 
 static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e,
                                       const EVP_PKEY_METHOD *pmeth) {
-  EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+  EVP_PKEY_CTX *ret = OPENSSL_zalloc(sizeof(EVP_PKEY_CTX));
   if (!ret) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX));
 
   ret->engine = e;
   ret->pmeth = pmeth;
@@ -156,13 +155,11 @@
     return NULL;
   }
 
-  EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+  EVP_PKEY_CTX *ret = OPENSSL_zalloc(sizeof(EVP_PKEY_CTX));
   if (!ret) {
     return NULL;
   }
 
-  OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX));
-
   ret->pmeth = ctx->pmeth;
   ret->engine = ctx->engine;
   ret->operation = ctx->operation;
diff --git a/crypto/evp/p_ec.c b/crypto/evp/p_ec.c
index ed89cc3..0e4349f 100644
--- a/crypto/evp/p_ec.c
+++ b/crypto/evp/p_ec.c
@@ -80,15 +80,12 @@
 
 
 static int pkey_ec_init(EVP_PKEY_CTX *ctx) {
-  EC_PKEY_CTX *dctx;
-  dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
+  EC_PKEY_CTX *dctx = OPENSSL_zalloc(sizeof(EC_PKEY_CTX));
   if (!dctx) {
     return 0;
   }
-  OPENSSL_memset(dctx, 0, sizeof(EC_PKEY_CTX));
 
   ctx->data = dctx;
-
   return 1;
 }
 
diff --git a/crypto/evp/p_hkdf.c b/crypto/evp/p_hkdf.c
index 0d7ede8..d9cbfc7 100644
--- a/crypto/evp/p_hkdf.c
+++ b/crypto/evp/p_hkdf.c
@@ -35,12 +35,11 @@
 } HKDF_PKEY_CTX;
 
 static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) {
-  HKDF_PKEY_CTX *hctx = OPENSSL_malloc(sizeof(HKDF_PKEY_CTX));
+  HKDF_PKEY_CTX *hctx = OPENSSL_zalloc(sizeof(HKDF_PKEY_CTX));
   if (hctx == NULL) {
     return 0;
   }
 
-  OPENSSL_memset(hctx, 0, sizeof(HKDF_PKEY_CTX));
   if (!CBB_init(&hctx->info, 0)) {
     OPENSSL_free(hctx);
     return 0;
diff --git a/crypto/evp/p_rsa.c b/crypto/evp/p_rsa.c
index 15eb1ef..3bdd85d 100644
--- a/crypto/evp/p_rsa.c
+++ b/crypto/evp/p_rsa.c
@@ -97,12 +97,10 @@
 } RSA_OAEP_LABEL_PARAMS;
 
 static int pkey_rsa_init(EVP_PKEY_CTX *ctx) {
-  RSA_PKEY_CTX *rctx;
-  rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
+  RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(RSA_PKEY_CTX));
   if (!rctx) {
     return 0;
   }
-  OPENSSL_memset(rctx, 0, sizeof(RSA_PKEY_CTX));
 
   rctx->nbits = 2048;
   rctx->pad_mode = RSA_PKCS1_PADDING;
diff --git a/crypto/fipsmodule/bn/prime.c b/crypto/fipsmodule/bn/prime.c
index 2d2ab69..fb30768 100644
--- a/crypto/fipsmodule/bn/prime.c
+++ b/crypto/fipsmodule/bn/prime.c
@@ -359,14 +359,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(void) {
-  BN_GENCB *callback = OPENSSL_malloc(sizeof(BN_GENCB));
-  if (callback == NULL) {
-    return NULL;
-  }
-  OPENSSL_memset(callback, 0, sizeof(BN_GENCB));
-  return callback;
-}
+BN_GENCB *BN_GENCB_new(void) { return OPENSSL_zalloc(sizeof(BN_GENCB)); }
 
 void BN_GENCB_free(BN_GENCB *callback) { OPENSSL_free(callback); }
 
diff --git a/crypto/fipsmodule/cipher/cipher.c b/crypto/fipsmodule/cipher/cipher.c
index bff7996..7ce3c20 100644
--- a/crypto/fipsmodule/cipher/cipher.c
+++ b/crypto/fipsmodule/cipher/cipher.c
@@ -113,12 +113,11 @@
   OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX));
 
   if (in->cipher_data && in->cipher->ctx_size) {
-    out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
+    out->cipher_data = OPENSSL_memdup(in->cipher_data, in->cipher->ctx_size);
     if (!out->cipher_data) {
       out->cipher = NULL;
       return 0;
     }
-    OPENSSL_memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
   }
 
   if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) {
diff --git a/crypto/fipsmodule/dh/dh.c b/crypto/fipsmodule/dh/dh.c
index a20b6d1..d57b093 100644
--- a/crypto/fipsmodule/dh/dh.c
+++ b/crypto/fipsmodule/dh/dh.c
@@ -71,17 +71,13 @@
 
 
 DH *DH_new(void) {
-  DH *dh = OPENSSL_malloc(sizeof(DH));
+  DH *dh = OPENSSL_zalloc(sizeof(DH));
   if (dh == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(dh, 0, sizeof(DH));
-
   CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
-
   dh->references = 1;
-
   return dh;
 }
 
diff --git a/crypto/fipsmodule/ec/ec.c b/crypto/fipsmodule/ec/ec.c
index 00587a1..0ae566a 100644
--- a/crypto/fipsmodule/ec/ec.c
+++ b/crypto/fipsmodule/ec/ec.c
@@ -250,11 +250,10 @@
     goto err;
   }
 
-  ret = OPENSSL_malloc(sizeof(EC_GROUP));
+  ret = OPENSSL_zalloc(sizeof(EC_GROUP));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
   ret->references = 1;
   ret->meth = EC_GFp_mont_method();
   bn_mont_ctx_init(&ret->field);
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
index 90a4404..a48671a 100644
--- a/crypto/fipsmodule/ec/ec_key.c
+++ b/crypto/fipsmodule/ec/ec_key.c
@@ -86,12 +86,11 @@
 DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class)
 
 static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) {
-  EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR));
+  EC_WRAPPED_SCALAR *wrapped = OPENSSL_zalloc(sizeof(EC_WRAPPED_SCALAR));
   if (wrapped == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR));
   wrapped->bignum.d = wrapped->scalar.words;
   wrapped->bignum.width = group->order.N.width;
   wrapped->bignum.dmax = group->order.N.width;
@@ -106,13 +105,11 @@
 EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); }
 
 EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
-  EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY));
+  EC_KEY *ret = OPENSSL_zalloc(sizeof(EC_KEY));
   if (ret == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(ret, 0, sizeof(EC_KEY));
-
   if (engine) {
     ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine);
   }
diff --git a/crypto/fipsmodule/rsa/blinding.c b/crypto/fipsmodule/rsa/blinding.c
index c4cfcc2..8838ad8 100644
--- a/crypto/fipsmodule/rsa/blinding.c
+++ b/crypto/fipsmodule/rsa/blinding.c
@@ -130,11 +130,10 @@
                                     const BN_MONT_CTX *mont, BN_CTX *ctx);
 
 BN_BLINDING *BN_BLINDING_new(void) {
-  BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
+  BN_BLINDING *ret = OPENSSL_zalloc(sizeof(BN_BLINDING));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(BN_BLINDING));
 
   ret->A = BN_new();
   if (ret->A == NULL) {
diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c
index 77ab6c6..8babba1 100644
--- a/crypto/fipsmodule/rsa/rsa.c
+++ b/crypto/fipsmodule/rsa/rsa.c
@@ -206,13 +206,11 @@
 RSA *RSA_new(void) { return RSA_new_method(NULL); }
 
 RSA *RSA_new_method(const ENGINE *engine) {
-  RSA *rsa = OPENSSL_malloc(sizeof(RSA));
+  RSA *rsa = OPENSSL_zalloc(sizeof(RSA));
   if (rsa == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(rsa, 0, sizeof(RSA));
-
   if (engine) {
     rsa->meth = ENGINE_get_RSA_method(engine);
   }
diff --git a/crypto/fipsmodule/self_check/fips.c b/crypto/fipsmodule/self_check/fips.c
index ce03957..c3515ea 100644
--- a/crypto/fipsmodule/self_check/fips.c
+++ b/crypto/fipsmodule/self_check/fips.c
@@ -94,12 +94,11 @@
       CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS);
   if (!array) {
     const size_t num_bytes = sizeof(size_t) * (fips_counter_max + 1);
-    array = OPENSSL_malloc(num_bytes);
+    array = OPENSSL_zalloc(num_bytes);
     if (!array) {
       return;
     }
 
-    OPENSSL_memset(array, 0, num_bytes);
     if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS, array,
                                  OPENSSL_free)) {
       // |OPENSSL_free| has already been called by |CRYPTO_set_thread_local|.
diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c
index 4a95a2e..8e20c88 100644
--- a/crypto/lhash/lhash.c
+++ b/crypto/lhash/lhash.c
@@ -104,19 +104,17 @@
 };
 
 _LHASH *OPENSSL_lh_new(lhash_hash_func hash, lhash_cmp_func comp) {
-  _LHASH *ret = OPENSSL_malloc(sizeof(_LHASH));
+  _LHASH *ret = OPENSSL_zalloc(sizeof(_LHASH));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(_LHASH));
 
   ret->num_buckets = kMinNumBuckets;
-  ret->buckets = OPENSSL_malloc(sizeof(LHASH_ITEM *) * ret->num_buckets);
+  ret->buckets = OPENSSL_zalloc(sizeof(LHASH_ITEM *) * ret->num_buckets);
   if (ret->buckets == NULL) {
     OPENSSL_free(ret);
     return NULL;
   }
-  OPENSSL_memset(ret->buckets, 0, sizeof(LHASH_ITEM *) * ret->num_buckets);
 
   ret->comp = comp;
   ret->hash = hash;
@@ -214,11 +212,10 @@
     return;
   }
 
-  new_buckets = OPENSSL_malloc(alloc_size);
+  new_buckets = OPENSSL_zalloc(alloc_size);
   if (new_buckets == NULL) {
     return;
   }
-  OPENSSL_memset(new_buckets, 0, alloc_size);
 
   for (i = 0; i < lh->num_buckets; i++) {
     for (cur = lh->buckets[i]; cur != NULL; cur = next) {
diff --git a/crypto/mem.c b/crypto/mem.c
index 89832fc..b17267f 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -267,6 +267,14 @@
   return NULL;
 }
 
+void *OPENSSL_zalloc(size_t size) {
+  void *ret = OPENSSL_malloc(size);
+  if (ret != NULL) {
+    OPENSSL_memset(ret, 0, size);
+  }
+  return ret;
+}
+
 void OPENSSL_free(void *orig_ptr) {
   if (orig_ptr == NULL) {
     return;
diff --git a/crypto/obj/obj.c b/crypto/obj/obj.c
index 9be3730..6519933 100644
--- a/crypto/obj/obj.c
+++ b/crypto/obj/obj.c
@@ -115,16 +115,12 @@
   }
   r->ln = r->sn = NULL;
 
-  data = OPENSSL_malloc(o->length);
-  if (data == NULL) {
+  // once data is attached to an object, it remains const
+  r->data = OPENSSL_memdup(o->data, o->length);
+  if (o->length != 0 && r->data == NULL) {
     goto err;
   }
-  if (o->data != NULL) {
-    OPENSSL_memcpy(data, o->data, o->length);
-  }
 
-  // once data is attached to an object, it remains const
-  r->data = data;
   r->length = o->length;
   r->nid = o->nid;
 
diff --git a/crypto/pkcs7/pkcs7_x509.c b/crypto/pkcs7/pkcs7_x509.c
index fd71bd7..7b10f6f 100644
--- a/crypto/pkcs7/pkcs7_x509.c
+++ b/crypto/pkcs7/pkcs7_x509.c
@@ -237,11 +237,10 @@
 }
 
 static PKCS7 *pkcs7_new(CBS *cbs) {
-  PKCS7 *ret = OPENSSL_malloc(sizeof(PKCS7));
+  PKCS7 *ret = OPENSSL_zalloc(sizeof(PKCS7));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(PKCS7));
   ret->type = OBJ_nid2obj(NID_pkcs7_signed);
   ret->d.sign = OPENSSL_malloc(sizeof(PKCS7_SIGNED));
   if (ret->d.sign == NULL) {
@@ -326,11 +325,10 @@
   }
 
   if (*out == NULL) {
-    *out = OPENSSL_malloc(p7->ber_len);
+    *out = OPENSSL_memdup(p7->ber_bytes, p7->ber_len);
     if (*out == NULL) {
       return -1;
     }
-    OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len);
   } else {
     OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len);
     *out += p7->ber_len;
diff --git a/crypto/pkcs8/pkcs8_x509.c b/crypto/pkcs8/pkcs8_x509.c
index 92bdb9d..2d0bf08 100644
--- a/crypto/pkcs8/pkcs8_x509.c
+++ b/crypto/pkcs8/pkcs8_x509.c
@@ -741,26 +741,22 @@
 
 PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes,
                    size_t ber_len) {
-  PKCS12 *p12;
-
-  p12 = OPENSSL_malloc(sizeof(PKCS12));
+  PKCS12 *p12 = OPENSSL_malloc(sizeof(PKCS12));
   if (!p12) {
     return NULL;
   }
 
-  p12->ber_bytes = OPENSSL_malloc(ber_len);
+  p12->ber_bytes = OPENSSL_memdup(*ber_bytes, ber_len);
   if (!p12->ber_bytes) {
     OPENSSL_free(p12);
     return NULL;
   }
 
-  OPENSSL_memcpy(p12->ber_bytes, *ber_bytes, ber_len);
   p12->ber_len = ber_len;
   *ber_bytes += ber_len;
 
   if (out_p12) {
     PKCS12_free(*out_p12);
-
     *out_p12 = p12;
   }
 
@@ -843,11 +839,10 @@
   }
 
   if (*out == NULL) {
-    *out = OPENSSL_malloc(p12->ber_len);
+    *out = OPENSSL_memdup(p12->ber_bytes, p12->ber_len);
     if (*out == NULL) {
       return -1;
     }
-    OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len);
   } else {
     OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len);
     *out += p12->ber_len;
diff --git a/crypto/pool/pool.c b/crypto/pool/pool.c
index e889f52..fc04840 100644
--- a/crypto/pool/pool.c
+++ b/crypto/pool/pool.c
@@ -42,12 +42,11 @@
 }
 
 CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) {
-  CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL));
+  CRYPTO_BUFFER_POOL *pool = OPENSSL_zalloc(sizeof(CRYPTO_BUFFER_POOL));
   if (pool == NULL) {
     return NULL;
   }
 
-  OPENSSL_memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL));
   pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp);
   if (pool->bufs == NULL) {
     OPENSSL_free(pool);
@@ -109,11 +108,10 @@
     }
   }
 
-  CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER));
+  CRYPTO_BUFFER *const buf = OPENSSL_zalloc(sizeof(CRYPTO_BUFFER));
   if (buf == NULL) {
     return NULL;
   }
-  OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER));
 
   if (data_is_static) {
     buf->data = (uint8_t *)data;
@@ -170,11 +168,10 @@
 }
 
 CRYPTO_BUFFER *CRYPTO_BUFFER_alloc(uint8_t **out_data, size_t len) {
-  CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER));
+  CRYPTO_BUFFER *const buf = OPENSSL_zalloc(sizeof(CRYPTO_BUFFER));
   if (buf == NULL) {
     return NULL;
   }
-  OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER));
 
   buf->data = OPENSSL_malloc(len);
   if (len != 0 && buf->data == NULL) {
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index a326eb7..269959e 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -84,19 +84,16 @@
 static const size_t kMinSize = 4;
 
 OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) {
-  OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK));
+  OPENSSL_STACK *ret = OPENSSL_zalloc(sizeof(OPENSSL_STACK));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK));
 
-  ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize);
+  ret->data = OPENSSL_zalloc(sizeof(void *) * kMinSize);
   if (ret->data == NULL) {
     goto err;
   }
 
-  OPENSSL_memset(ret->data, 0, sizeof(void *) * kMinSize);
-
   ret->comp = comp;
   ret->num_alloc = kMinSize;
 
@@ -370,19 +367,17 @@
     return NULL;
   }
 
-  OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK));
+  OPENSSL_STACK *ret = OPENSSL_zalloc(sizeof(OPENSSL_STACK));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK));
 
-  ret->data = OPENSSL_malloc(sizeof(void *) * sk->num_alloc);
+  ret->data = OPENSSL_memdup(sk->data, sizeof(void *) * sk->num_alloc);
   if (ret->data == NULL) {
     goto err;
   }
 
   ret->num = sk->num;
-  OPENSSL_memcpy(ret->data, sk->data, sizeof(void *) * sk->num);
   ret->sorted = sk->sorted;
   ret->num_alloc = sk->num_alloc;
   ret->comp = sk->comp;
diff --git a/crypto/trust_token/trust_token.c b/crypto/trust_token/trust_token.c
index 93172c3..521e7ad 100644
--- a/crypto/trust_token/trust_token.c
+++ b/crypto/trust_token/trust_token.c
@@ -118,11 +118,10 @@
 }
 
 TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
-  TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN));
+  TRUST_TOKEN *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN));
   ret->data = OPENSSL_memdup(data, len);
   if (len != 0 && ret->data == NULL) {
     OPENSSL_free(ret);
@@ -205,11 +204,10 @@
     return NULL;
   }
 
-  TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT));
+  TRUST_TOKEN_CLIENT *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT));
   ret->method = method;
   ret->max_batchsize = (uint16_t)max_batchsize;
   return ret;
@@ -446,11 +444,10 @@
     return NULL;
   }
 
-  TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER));
+  TRUST_TOKEN_ISSUER *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER));
   ret->method = method;
   ret->max_batchsize = (uint16_t)max_batchsize;
   return ret;
diff --git a/crypto/x509/policy.c b/crypto/x509/policy.c
index b0c2712..ce99599 100644
--- a/crypto/x509/policy.c
+++ b/crypto/x509/policy.c
@@ -107,11 +107,10 @@
 
 static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) {
   assert(!is_any_policy(policy));
-  X509_POLICY_NODE *node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
+  X509_POLICY_NODE *node = OPENSSL_zalloc(sizeof(X509_POLICY_NODE));
   if (node == NULL) {
     return NULL;
   }
-  OPENSSL_memset(node, 0, sizeof(X509_POLICY_NODE));
   node->policy = OBJ_dup(policy);
   node->parent_policies = sk_ASN1_OBJECT_new_null();
   if (node->policy == NULL || node->parent_policies == NULL) {
@@ -134,11 +133,10 @@
 }
 
 static X509_POLICY_LEVEL *x509_policy_level_new(void) {
-  X509_POLICY_LEVEL *level = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL));
+  X509_POLICY_LEVEL *level = OPENSSL_zalloc(sizeof(X509_POLICY_LEVEL));
   if (level == NULL) {
     return NULL;
   }
-  OPENSSL_memset(level, 0, sizeof(X509_POLICY_LEVEL));
   level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp);
   if (level->nodes == NULL) {
     x509_policy_level_free(level);
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index c1389cc..814f0ce 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -164,10 +164,9 @@
 X509_STORE *X509_STORE_new(void) {
   X509_STORE *ret;
 
-  if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) {
+  if ((ret = (X509_STORE *)OPENSSL_zalloc(sizeof(X509_STORE))) == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(*ret));
   CRYPTO_MUTEX_init(&ret->objs_lock);
   ret->objs = sk_X509_OBJECT_new(x509_object_cmp_sk);
   if (ret->objs == NULL) {
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 583b4a0..c13437d 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -156,12 +156,10 @@
 }
 
 X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) {
-  X509_VERIFY_PARAM *param;
-  param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+  X509_VERIFY_PARAM *param = OPENSSL_zalloc(sizeof(X509_VERIFY_PARAM));
   if (!param) {
     return NULL;
   }
-  OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM));
   x509_verify_param_zero(param);
   return param;
 }
diff --git a/crypto/x509/x_pkey.c b/crypto/x509/x_pkey.c
index d48ecd1..33a9aa9 100644
--- a/crypto/x509/x_pkey.c
+++ b/crypto/x509/x_pkey.c
@@ -67,11 +67,10 @@
 
 
 X509_PKEY *X509_PKEY_new(void) {
-  X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
+  X509_PKEY *ret = OPENSSL_zalloc(sizeof(X509_PKEY));
   if (ret == NULL) {
     goto err;
   }
-  OPENSSL_memset(ret, 0, sizeof(X509_PKEY));
 
   ret->enc_algor = X509_ALGOR_new();
   if (ret->enc_algor == NULL) {
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 31dbebe..37a11c6 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -92,11 +92,10 @@
 // x509_new_null returns a new |X509| object where the |cert_info|, |sig_alg|,
 // and |signature| fields are not yet filled in.
 static X509 *x509_new_null(void) {
-  X509 *ret = OPENSSL_malloc(sizeof(X509));
+  X509 *ret = OPENSSL_zalloc(sizeof(X509));
   if (ret == NULL) {
     return NULL;
   }
-  OPENSSL_memset(ret, 0, sizeof(X509));
 
   ret->references = 1;
   ret->ex_pathlen = -1;
diff --git a/decrepit/bio/base64_bio.c b/decrepit/bio/base64_bio.c
index eb87186..3521897 100644
--- a/decrepit/bio/base64_bio.c
+++ b/decrepit/bio/base64_bio.c
@@ -89,15 +89,11 @@
 } BIO_B64_CTX;
 
 static int b64_new(BIO *bio) {
-  BIO_B64_CTX *ctx;
-
-  ctx = OPENSSL_malloc(sizeof(*ctx));
+  BIO_B64_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
   if (ctx == NULL) {
     return 0;
   }
 
-  OPENSSL_memset(ctx, 0, sizeof(*ctx));
-
   ctx->cont = 1;
   ctx->start = 1;
 
diff --git a/include/openssl/mem.h b/include/openssl/mem.h
index 8da1dd6..cbbb11f 100644
--- a/include/openssl/mem.h
+++ b/include/openssl/mem.h
@@ -81,6 +81,10 @@
 // the case of a malloc failure, prior to returning NULL |OPENSSL_malloc| will
 // push |ERR_R_MALLOC_FAILURE| onto the openssl error stack.
 OPENSSL_EXPORT void *OPENSSL_malloc(size_t size);
+
+// OPENSSL_zalloc behaves like |OPENSSL_malloc| except it also initializes the
+// resulting memory to zero.
+OPENSSL_EXPORT void *OPENSSL_zalloc(size_t size);
 #endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC
 
 // OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc
index 55c92fa..b910b96 100644
--- a/ssl/d1_both.cc
+++ b/ssl/d1_both.cc
@@ -184,11 +184,10 @@
       return nullptr;
     }
     size_t bitmask_len = (msg_hdr->msg_len + 7) / 8;
-    frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len);
+    frag->reassembly = (uint8_t *)OPENSSL_zalloc(bitmask_len);
     if (frag->reassembly == NULL) {
       return nullptr;
     }
-    OPENSSL_memset(frag->reassembly, 0, bitmask_len);
   }
 
   return frag;
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index b97680d..fc3d4c3 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -4725,8 +4725,8 @@
 };
 
 struct ssl_test_ticket_aead_state {
-  unsigned retry_count;
-  ssl_test_ticket_aead_failure_mode failure_mode;
+  unsigned retry_count = 0;
+  ssl_test_ticket_aead_failure_mode failure_mode = ssl_test_ticket_aead_ok;
 };
 
 static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
@@ -4739,12 +4739,7 @@
 static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
                                                CRYPTO_EX_DATA *ad, int index,
                                                long argl, void *argp) {
-  auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
-  if (state == nullptr) {
-    return;
-  }
-
-  OPENSSL_free(state);
+  delete reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
 }
 
 static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
@@ -4835,10 +4830,7 @@
   SSL_set_connect_state(client.get());
   SSL_set_accept_state(server.get());
 
-  auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
-      OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
-  ASSERT_TRUE(state);
-  OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
+  auto state = new ssl_test_ticket_aead_state;
   state->retry_count = retry_count;
   state->failure_mode = failure_mode;
 
diff --git a/ssl/test/async_bio.cc b/ssl/test/async_bio.cc
index 9eae290..1c9859a 100644
--- a/ssl/test/async_bio.cc
+++ b/ssl/test/async_bio.cc
@@ -108,11 +108,10 @@
 }
 
 static int AsyncNew(BIO *bio) {
-  AsyncBio *a = (AsyncBio *)OPENSSL_malloc(sizeof(*a));
+  AsyncBio *a = (AsyncBio *)OPENSSL_zalloc(sizeof(*a));
   if (a == NULL) {
     return 0;
   }
-  OPENSSL_memset(a, 0, sizeof(*a));
   a->enforce_write_quota = true;
   bio->init = 1;
   bio->ptr = (char *)a;