external/boringssl: Sync to 9bbdf5832de8a2d395303c669b594fc61c791f4d.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/c642aca28feb7e18f244658559f4042286aed0c8..9bbdf5832de8a2d395303c669b594fc61c791f4d

Test: BoringSSL CTS Presubmits.
Change-Id: Ieb6fcfee99c4cc496b2f6e1d3e6597784bd80189
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index f0a67d8..dd2e418 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -389,6 +389,15 @@
 OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
                                        const uint8_t **out_iv, size_t *out_len);
 
+/* EVP_AEAD_CTX_tag_len computes the exact byte length of the tag written by
+ * |EVP_AEAD_CTX_seal_scatter| and writes it to |*out_tag_len|. It returns one
+ * on success or zero on error. |in_len| and |extra_in_len| must equal the
+ * arguments of the same names passed to |EVP_AEAD_CTX_seal_scatter|. */
+OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx,
+                                        size_t *out_tag_len,
+                                        const size_t in_len,
+                                        const size_t extra_in_len);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 64d7989..45d4848 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -876,8 +876,6 @@
 
 namespace bssl {
 
-BORINGSSL_MAKE_STACK_DELETER(ASN1_OBJECT, ASN1_OBJECT_free)
-
 BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free)
 BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free)
 BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free)
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 42ead4d..6b43c76 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -107,6 +107,10 @@
 #elif defined(__myriad2__)
 #define OPENSSL_32_BIT
 #else
+/* Note BoringSSL only supports standard 32-bit and 64-bit two's-complement,
+ * little-endian architectures. Functions will not produce the correct answer
+ * on other systems. Run the crypto_test binary, notably
+ * crypto/compiler_test.cc, before adding a new architecture. */
 #error "Unknown target CPU"
 #endif
 
@@ -367,7 +371,6 @@
 #if defined(BORINGSSL_NO_CXX)
 
 #define BORINGSSL_MAKE_DELETER(type, deleter)
-#define BORINGSSL_MAKE_STACK_DELETER(type, deleter)
 
 #else
 
@@ -410,6 +413,9 @@
   T *get() { return &ctx_; }
   const T *get() const { return &ctx_; }
 
+  T *operator->() { return &ctx_; }
+  const T *operator->() const { return &ctx_; }
+
   void Reset() {
     cleanup(&ctx_);
     init(&ctx_);
@@ -429,18 +435,6 @@
   };                                              \
   }
 
-// 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) \
-  namespace internal {                              \
-  template <>                                       \
-  struct DeleterImpl<STACK_OF(type)> {              \
-    static void Free(STACK_OF(type) *ptr) {         \
-      sk_##type##_pop_free(ptr, deleter);           \
-    }                                               \
-  };                                                \
-  }
-
 // Holds ownership of heap-allocated BoringSSL structures. Sample usage:
 //   bssl::UniquePtr<RSA> rsa(RSA_new());
 //   bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 2d0d959..9a80cd5 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -79,9 +79,9 @@
 
 DEFINE_STACK_OF(BIO)
 
-/* BIO_new creates a new BIO with the given type and a reference count of one.
+/* BIO_new creates a new BIO with the given method and a reference count of one.
  * It returns the fresh |BIO|, or NULL on error. */
-OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *type);
+OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *method);
 
 /* BIO_free decrements the reference count of |bio|. If the reference count
  * drops to zero, it (optionally) calls the BIO's callback with |BIO_CB_FREE|,
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 30f3af7..013c546 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -91,7 +91,7 @@
 
 /* BUF_MEM_grow_clean acts the same as |BUF_MEM_grow|, but clears the previous
  * contents of memory if reallocing. */
-OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len);
 
 /* BUF_strdup returns an allocated, duplicate of |str|. */
 OPENSSL_EXPORT char *BUF_strdup(const char *str);
@@ -112,7 +112,7 @@
 OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size);
 
 /* BUF_strlcat acts like strlcat(3). */
-OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t size);
+OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t dst_size);
 
 
 #if defined(__cplusplus)
diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h
index 97be067..11fc25e 100644
--- a/src/include/openssl/curve25519.h
+++ b/src/include/openssl/curve25519.h
@@ -50,7 +50,7 @@
  * public values as inputs. */
 OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32],
                           const uint8_t private_key[32],
-                          const uint8_t peers_public_value[32]);
+                          const uint8_t peer_public_value[32]);
 
 /* X25519_public_from_private calculates a Diffie-Hellman public value from the
  * given private key and writes it to |out_public_value|. */
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index afe0291..f992b91 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -298,8 +298,8 @@
                                         CRYPTO_EX_unused *unused,
                                         CRYPTO_EX_dup *dup_unused,
                                         CRYPTO_EX_free *free_func);
-OPENSSL_EXPORT int DSA_set_ex_data(DSA *d, int idx, void *arg);
-OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *d, int idx);
+OPENSSL_EXPORT int DSA_set_ex_data(DSA *dsa, int idx, void *arg);
+OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *dsa, int idx);
 
 
 /* Deprecated functions. */
diff --git a/src/include/openssl/mem.h b/src/include/openssl/mem.h
index 5d96a2d..c43a16a 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -104,10 +104,13 @@
 /* OPENSSL_strnlen has the same behaviour as strnlen(3). */
 OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len);
 
-/* OPENSSL_strcasecmp has the same behaviour as strcasecmp(3). */
+/* OPENSSL_tolower is a locale-independent version of tolower(3). */
+OPENSSL_EXPORT int OPENSSL_tolower(int c);
+
+/* OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). */
 OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b);
 
-/* OPENSSL_strncasecmp has the same behaviour as strncasecmp(3). */
+/* OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). */
 OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n);
 
 /* DECIMAL_SIZE returns an upper bound for the length of the decimal
diff --git a/src/include/openssl/pool.h b/src/include/openssl/pool.h
index 4972b93..8a07af5 100644
--- a/src/include/openssl/pool.h
+++ b/src/include/openssl/pool.h
@@ -82,8 +82,6 @@
 BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER_POOL, CRYPTO_BUFFER_POOL_free)
 BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free)
 
-BORINGSSL_MAKE_STACK_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free)
-
 }  // namespace bssl
 
 }  /* extern C++ */
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 0e9a8cd..a535fbd 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -111,6 +111,9 @@
 /* RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. */
 OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void);
 
+/* RAND_get_rand_method returns |RAND_SSLeay()|. */
+OPENSSL_EXPORT const RAND_METHOD *RAND_get_rand_method(void);
+
 /* RAND_set_rand_method does nothing. */
 OPENSSL_EXPORT void RAND_set_rand_method(const RAND_METHOD *);
 
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index a580f97..ed2c0be 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -456,8 +456,8 @@
                                         CRYPTO_EX_unused *unused,
                                         CRYPTO_EX_dup *dup_unused,
                                         CRYPTO_EX_free *free_func);
-OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg);
-OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
+OPENSSL_EXPORT int RSA_set_ex_data(RSA *rsa, int idx, void *arg);
+OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx);
 
 
 /* Flags. */
diff --git a/src/include/openssl/span.h b/src/include/openssl/span.h
new file mode 100644
index 0000000..4c09159
--- /dev/null
+++ b/src/include/openssl/span.h
@@ -0,0 +1,163 @@
+/* Copyright (c) 2017, 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_SPAN_H
+#define OPENSSL_HEADER_SSL_SPAN_H
+
+#include <openssl/base.h>
+
+#if !defined(BORINGSSL_NO_CXX)
+
+extern "C++" {
+
+#include <algorithm>
+#include <type_traits>
+
+namespace bssl {
+
+template <typename T>
+class Span;
+
+namespace internal {
+template <typename T>
+class SpanBase {
+  /* Put comparison operator implementations into a base class with const T, so
+   * they can be used with any type that implicitly converts into a Span. */
+  static_assert(std::is_const<T>::value,
+                "Span<T> must be derived from SpanBase<const T>");
+
+  friend bool operator==(Span<T> lhs, Span<T> rhs) {
+    /* MSVC issues warning C4996 because std::equal is unsafe. The pragma to
+     * suppress the warning mysteriously has no effect, hence this
+     * implementation. See
+     * https://msdn.microsoft.com/en-us/library/aa985974.aspx. */
+    if (lhs.size() != rhs.size()) {
+      return false;
+    }
+    for (T *l = lhs.begin(), *r = rhs.begin(); l != lhs.end() && r != rhs.end();
+         ++l, ++r) {
+      if (*l != *r) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  friend bool operator!=(Span<T> lhs, Span<T> rhs) { return !(lhs == rhs); }
+};
+}  // namespace internal
+
+/* A Span<T> is a non-owning reference to a contiguous array of objects of type
+ * |T|. Conceptually, a Span is a simple a pointer to |T| and a count of
+ * elements accessible via that pointer. The elements referenced by the Span can
+ * be mutated if |T| is mutable.
+ *
+ * A Span can be constructed from container types implementing |data()| and
+ * |size()| methods. If |T| is constant, construction from a container type is
+ * implicit. This allows writing methods that accept data from some unspecified
+ * container type:
+ *
+ * // Foo views data referenced by v.
+ * void Foo(bssl::Span<const uint8_t> v) { ... }
+ *
+ * std::vector<uint8_t> vec;
+ * Foo(vec);
+ *
+ * For mutable Spans, conversion is explicit:
+ *
+ * // FooMutate mutates data referenced by v.
+ * void FooMutate(bssl::Span<uint8_t> v) { ... }
+ *
+ * FooMutate(bssl::Span<uint8_t>(vec));
+ *
+ * You can also use the |MakeSpan| and |MakeConstSpan| factory methods to
+ * construct Spans in order to deduce the type of the Span automatically.
+ *
+ * FooMutate(bssl::MakeSpan(vec));
+ *
+ * Note that Spans have value type sematics. They are cheap to construct and
+ * copy, and should be passed by value whenever a method would otherwise accept
+ * a reference or pointer to a container or array. */
+template <typename T>
+class Span : private internal::SpanBase<const T> {
+ private:
+  template <bool B, class V = void>
+  using enable_if_t = typename std::enable_if<B, V>::type;
+
+  // Heuristically test whether C is a container type that can be converted into
+  // a Span by checking for data() and size() member functions.
+  template <typename C>
+  using EnableIfContainer = enable_if_t<
+      std::is_convertible<decltype(std::declval<C>().data()), T *>::value &&
+      std::is_integral<decltype(std::declval<C>().size())>::value>;
+
+ public:
+  constexpr Span() : Span(nullptr, 0) {}
+  constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
+
+  template <size_t N>
+  constexpr Span(T (&array)[N]) : Span(array, N) {}
+
+  template <typename C, typename = EnableIfContainer<C>,
+            typename = enable_if_t<std::is_const<T>::value, C>>
+  Span(const C &container) : data_(container.data()), size_(container.size()) {}
+
+  template <typename C, typename = EnableIfContainer<C>,
+            typename = enable_if_t<!std::is_const<T>::value, C>>
+  explicit Span(C &container)
+      : data_(container.data()), size_(container.size()) {}
+
+  T *data() const { return data_; }
+  size_t size() const { return size_; }
+
+  T *begin() const { return data_; }
+  const T *cbegin() const { return data_; }
+  T *end() const { return data_ + size_; };
+  const T *cend() const { return end(); };
+
+  T &operator[](size_t i) const { return data_[i]; }
+  T &at(size_t i) const { return data_[i]; }
+
+ private:
+  T *data_;
+  size_t size_;
+};
+
+template <typename T>
+Span<T> MakeSpan(T *ptr, size_t size) {
+  return Span<T>(ptr, size);
+}
+
+template <typename C>
+auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) {
+  return MakeSpan(c.data(), c.size());
+}
+
+template <typename T>
+Span<const T> MakeConstSpan(T *ptr, size_t size) {
+  return Span<const T>(ptr, size);
+}
+
+template <typename C>
+auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) {
+  return MakeConstSpan(c.data(), c.size());
+}
+
+}  // namespace bssl
+
+}  // extern C++
+
+#endif  // !defined(BORINGSSL_NO_CXX)
+
+#endif /* OPENSSL_HEADER_SSL_SPAN_H */
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 04ec4b8..a5ac325 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -149,6 +149,7 @@
 #include <openssl/hmac.h>
 #include <openssl/lhash.h>
 #include <openssl/pem.h>
+#include <openssl/span.h>
 #include <openssl/ssl3.h>
 #include <openssl/thread.h>
 #include <openssl/tls1.h>
@@ -1349,8 +1350,9 @@
  *   be used.
  *
  * Unknown rules are silently ignored by legacy APIs, and rejected by APIs with
- * "strict" in the name, which should be preferred. Cipher lists can be long and
- * it's easy to commit typos.
+ * "strict" in the name, which should be preferred. Cipher lists can be long
+ * and it's easy to commit typos. Strict functions will also reject the use of
+ * spaces, semi-colons and commas as alternative separators.
  *
  * The special |@STRENGTH| directive will sort all enabled ciphers by strength.
  *
@@ -1368,7 +1370,7 @@
  *   [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]
  *
  * Once an equal-preference group is used, future directives must be
- * opcode-less.
+ * opcode-less. Inside an equal-preference group, spaces are not allowed.
  *
  * TLS 1.3 ciphers do not participate in this mechanism and instead have a
  * built-in preference order. Functions to set cipher lists do not affect TLS
@@ -2517,7 +2519,8 @@
 
 /* SSL_get_servername, for a server, returns the hostname supplied by the
  * client or NULL if there was none. The |type| argument must be
- * |TLSEXT_NAMETYPE_host_name|. */
+ * |TLSEXT_NAMETYPE_host_name|. Note that the returned pointer points inside
+ * |ssl| and is only valid until the next operation on |ssl|. */
 OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type);
 
 /* SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name|
@@ -2816,20 +2819,17 @@
  * The callback returns the length of the PSK or 0 if no suitable identity was
  * found. */
 OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(
-    SSL_CTX *ctx,
-    unsigned (*psk_client_callback)(
-        SSL *ssl, const char *hint, char *identity,
-        unsigned max_identity_len, uint8_t *psk, unsigned max_psk_len));
+    SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+                                 unsigned max_identity_len, uint8_t *psk,
+                                 unsigned max_psk_len));
 
 /* SSL_set_psk_client_callback sets the callback to be called when PSK is
  * negotiated on the client. This callback must be set to enable PSK cipher
  * suites on the client. See also |SSL_CTX_set_psk_client_callback|. */
 OPENSSL_EXPORT void SSL_set_psk_client_callback(
-    SSL *ssl, unsigned (*psk_client_callback)(SSL *ssl, const char *hint,
-                                              char *identity,
-                                              unsigned max_identity_len,
-                                              uint8_t *psk,
-                                              unsigned max_psk_len));
+    SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+                             unsigned max_identity_len, uint8_t *psk,
+                             unsigned max_psk_len));
 
 /* SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is
  * negotiated on the server. This callback must be set to enable PSK cipher
@@ -2839,19 +2839,15 @@
  * length at most |max_psk_len| to |psk| and return the number of bytes written
  * or zero if the PSK identity is unknown. */
 OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(
-    SSL_CTX *ctx,
-    unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
-                                    uint8_t *psk,
-                                    unsigned max_psk_len));
+    SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
+                                 unsigned max_psk_len));
 
 /* SSL_set_psk_server_callback sets the callback to be called when PSK is
  * negotiated on the server. This callback must be set to enable PSK cipher
  * suites on the server. See also |SSL_CTX_set_psk_server_callback|. */
 OPENSSL_EXPORT void SSL_set_psk_server_callback(
-    SSL *ssl,
-    unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
-                                    uint8_t *psk,
-                                    unsigned max_psk_len));
+    SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
+                             unsigned max_psk_len));
 
 /* SSL_CTX_use_psk_identity_hint configures server connections to advertise an
  * identity hint of |identity_hint|. It returns one on success and zero on
@@ -2898,14 +2894,14 @@
  *
  * Early data as a client is more complex. If the offered session (see
  * |SSL_set_session|) is 0-RTT-capable, the handshake will return after sending
- * the ClientHello. The predicted peer certificate and ALPN protocol will be
+ * the ClientHello. The predicted peer certificates and ALPN protocol will be
  * available via the usual APIs. |SSL_write| will write early data, up to the
  * session's limit. Writes past this limit and |SSL_read| will complete the
  * handshake before continuing. Callers may also call |SSL_do_handshake| again
  * to complete the handshake sooner.
  *
  * If the server accepts early data, the handshake will succeed. |SSL_read| and
- * |SSL_write| will then act as in a 1-RTT handshake. The peer certificate and
+ * |SSL_write| will then act as in a 1-RTT handshake. The peer certificates and
  * ALPN protocol will be as predicted and need not be re-queried.
  *
  * If the server rejects early data, |SSL_do_handshake| (and thus |SSL_read| and
@@ -2915,10 +2911,12 @@
  * have processed the early data due to attacker replays.
  *
  * To then continue the handshake on the original connection, use
- * |SSL_reset_early_data_reject|. This allows a faster retry than making a fresh
- * connection. |SSL_do_handshake| will the complete the full handshake as in a
- * fresh connection. Once reset, the peer certificate, ALPN protocol, and other
- * properties may change so the caller must query them again.
+ * |SSL_reset_early_data_reject|. The connection will then behave as one which
+ * had not yet completed the handshake. This allows a faster retry than making a
+ * fresh connection. |SSL_do_handshake| will complete the full handshake,
+ * possibly resulting in different peer certificates, ALPN protocol, and other
+ * properties. The caller must disregard any values from before the reset and
+ * query again.
  *
  * Finally, to implement the fallback described in draft-ietf-tls-tls13-18
  * appendix C.3, retry on a fresh connection without 0-RTT if the handshake
@@ -3569,7 +3567,7 @@
 OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx);
 
 /* SSL_cutthrough_complete calls |SSL_in_false_start|. */
-OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *s);
+OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl);
 
 /* SSL_num_renegotiations calls |SSL_total_renegotiations|. */
 OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl);
@@ -3593,10 +3591,10 @@
 OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
 
 /* SSL_get_read_ahead returns zero. */
-OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
+OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl);
 
 /* SSL_set_read_ahead does nothing. */
-OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
+OPENSSL_EXPORT void SSL_set_read_ahead(SSL *ssl, int yes);
 
 /* SSL_renegotiate put an error on the error queue and returns zero. */
 OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
@@ -3661,10 +3659,10 @@
 OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles);
 
 /* SSL_get_current_compression returns NULL. */
-OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *s);
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl);
 
 /* SSL_get_current_expansion returns NULL. */
-OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl);
 
 /* SSL_get_server_tmp_key returns zero. */
 OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
@@ -3677,11 +3675,11 @@
 
 /* SSL_CTX_set_tmp_dh_callback does nothing. */
 OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
-    SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
+    SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength));
 
 /* SSL_set_tmp_dh_callback does nothing. */
 OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
-                                            DH *(*dh)(SSL *ssl, int is_export,
+                                            DH *(*cb)(SSL *ssl, int is_export,
                                                       int keylength));
 
 
@@ -3781,8 +3779,7 @@
  * this function is confusing. This callback may not be registered concurrently
  * with |SSL_CTX_set_cert_cb| or |SSL_set_cert_cb|. */
 OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
-    SSL_CTX *ctx,
-    int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey));
+    SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey));
 
 #define SSL_NOTHING 1
 #define SSL_WRITING 2
@@ -4365,7 +4362,7 @@
    *   in: points to the client's list of supported protocols in
    *       wire-format.
    *   inlen: the length of |in|. */
-  int (*alpn_select_cb)(SSL *s, const uint8_t **out, uint8_t *out_len,
+  int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
                         const uint8_t *in, unsigned in_len, void *arg);
   void *alpn_select_cb_arg;
 
@@ -4580,6 +4577,8 @@
 #if defined(__cplusplus)
 } /* extern C */
 
+#if !defined(BORINGSSL_NO_CXX)
+
 extern "C++" {
 
 namespace bssl {
@@ -4588,10 +4587,70 @@
 BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
 BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
 
+enum class OpenRecordResult {
+  kOK,
+  kDiscard,
+  kIncompleteRecord,
+  kAlertCloseNotify,
+  kAlertFatal,
+  kError,
+};
+
+/*  *** EXPERIMENTAL -- DO NOT USE ***
+ *
+ * OpenRecord decrypts the first complete SSL record from |in| in-place, sets
+ * |out| to the decrypted application data, and |out_record_len| to the length
+ * of the encrypted record. Returns:
+ * - kOK if an application-data record was successfully decrypted and verified.
+ * - kDiscard if a record was sucessfully processed, but should be discarded.
+ * - kIncompleteRecord if |in| did not contain a complete record.
+ * - kAlertCloseNotify if a record was successfully processed but is a
+ *   close_notify alert.
+ * - kAlertFatal if a record was successfully processed but is a fatal alert.
+ * - kError if an error occurred or the record is invalid. |*out_alert| will be
+ *   set to an alert to emit. */
+OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span<uint8_t> *out,
+                                           size_t *out_record_len,
+                                           uint8_t *out_alert,
+                                           Span<uint8_t> in);
+
+OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len);
+
+/* SealRecordSuffixLen returns the length of the suffix written by |SealRecord|.
+ *
+ * |plaintext_len| must be equal to the size of the plaintext passed to
+ * |SealRecord|.
+ *
+ * |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned
+ * suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. */
+OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len);
+
+/*  *** EXPERIMENTAL -- DO NOT USE ***
+ *
+ * SealRecord encrypts the cleartext of |in| and scatters the resulting TLS
+ * application data record between |out_prefix|, |out|, and |out_suffix|. It
+ * returns true on success or false if an error occurred.
+ *
+ * The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of
+ * |out| must equal the length of |in|, which must not exceed
+ * |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal
+ * |SealRecordSuffixLen|.
+ *
+ * If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting.
+ * |SealRecordPrefixLen| accounts for the required overhead if that is the case.
+ *
+ * |out| may equal |in| to encrypt in-place but may not otherwise alias.
+ * |out_prefix| and |out_suffix| may not alias anything. */
+OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span<uint8_t> out_prefix,
+                               Span<uint8_t> out, Span<uint8_t> out_suffix,
+                               Span<const uint8_t> in);
+
 }  // namespace bssl
 
 }  /* extern C++ */
 
+#endif  // !defined(BORINGSSL_NO_CXX)
+
 #endif
 
 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h
index 5c4b506..3626fb0 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -212,11 +212,39 @@
  * This set of macros is used to emit the typed functions that act on a
  * |STACK_OF(T)|. */
 
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+namespace bssl {
+namespace internal {
+template <typename T>
+struct StackTraits {};
+}
+}
+}
+
+#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \
+  extern "C++" {                                            \
+  namespace bssl {                                          \
+  namespace internal {                                      \
+  template <>                                               \
+  struct StackTraits<STACK_OF(name)> {                      \
+    static constexpr bool kIsStack = true;                  \
+    using Type = type;                                      \
+    static constexpr bool kIsConst = is_const;              \
+  };                                                        \
+  }                                                         \
+  }                                                         \
+  }
+
+#else
+#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const)
+#endif
+
 /* Stack functions must be tagged unused to support file-local stack types.
  * Clang's -Wunused-function only allows unused static inline functions if they
  * are defined in a header. */
 
-#define DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype)                      \
+#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype)            \
   DECLARE_STACK_OF(name);                                                      \
                                                                                \
   typedef int (*stack_##name##_cmp_func)(constptrtype *a, constptrtype *b);    \
@@ -323,19 +351,22 @@
 
 /* DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are
  * |type| *. */
-#define DEFINE_STACK_OF(type) DEFINE_STACK_OF_IMPL(type, type *, const type *)
+#define DEFINE_STACK_OF(type)                                \
+  BORINGSSL_DEFINE_STACK_OF_IMPL(type, type *, const type *) \
+  BORINGSSL_DEFINE_STACK_TRAITS(type, type, false)
 
 /* DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements
  * are const |type| *. */
-#define DEFINE_CONST_STACK_OF(type) \
-  DEFINE_STACK_OF_IMPL(type, const type *, const type *)
+#define DEFINE_CONST_STACK_OF(type)                                \
+  BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \
+  BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true)
 
 /* DEFINE_SPECIAL_STACK_OF defines |STACK_OF(type)| to be a stack whose elements
  * are |type|, where |type| must be a typedef for a pointer. */
 #define DEFINE_SPECIAL_STACK_OF(type)                          \
   OPENSSL_COMPILE_ASSERT(sizeof(type) == sizeof(void *),       \
                          special_stack_of_non_pointer_##type); \
-  DEFINE_STACK_OF_IMPL(type, type, const type)
+  BORINGSSL_DEFINE_STACK_OF_IMPL(type, type, const type)
 
 
 typedef char *OPENSSL_STRING;
@@ -348,4 +379,107 @@
 }  /* extern C */
 #endif
 
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+#include <type_traits>
+
+namespace bssl {
+
+namespace internal {
+
+// Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|.
+template <typename Stack>
+struct DeleterImpl<
+    Stack, typename std::enable_if<StackTraits<Stack>::kIsConst>::type> {
+  static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); }
+};
+
+// Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the
+// corresponding type's deleter.
+template <typename Stack>
+struct DeleterImpl<
+    Stack, typename std::enable_if<!StackTraits<Stack>::kIsConst>::type> {
+  static void Free(Stack *sk) {
+    sk_pop_free(
+        reinterpret_cast<_STACK *>(sk),
+        reinterpret_cast<void (*)(void *)>(
+            DeleterImpl<typename StackTraits<Stack>::Type>::Free));
+  }
+};
+
+template <typename Stack>
+class StackIteratorImpl {
+ public:
+  using Type = typename StackTraits<Stack>::Type;
+  // Iterators must be default-constructable.
+  StackIteratorImpl() : sk_(nullptr), idx_(0) {}
+  StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {}
+
+  bool operator==(StackIteratorImpl other) const {
+    return sk_ == other.sk_ && idx_ == other.idx_;
+  }
+  bool operator!=(StackIteratorImpl other) const {
+    return !(*this == other);
+  }
+
+  Type *operator*() const {
+    return reinterpret_cast<Type *>(
+        sk_value(reinterpret_cast<const _STACK *>(sk_), idx_));
+  }
+
+  StackIteratorImpl &operator++(/* prefix */) {
+    idx_++;
+    return *this;
+  }
+
+  StackIteratorImpl operator++(int /* postfix */) {
+    StackIteratorImpl copy(*this);
+    ++(*this);
+    return copy;
+  }
+
+ private:
+  const Stack *sk_;
+  size_t idx_;
+};
+
+template <typename Stack>
+using StackIterator = typename std::enable_if<StackTraits<Stack>::kIsStack,
+                                              StackIteratorImpl<Stack>>::type;
+
+}  // namespace internal
+
+// PushToStack pushes |elem| to |sk|. It returns true on success and false on
+// allocation failure.
+template <typename Stack>
+static inline
+    typename std::enable_if<!internal::StackTraits<Stack>::kIsConst, bool>::type
+    PushToStack(Stack *sk,
+                UniquePtr<typename internal::StackTraits<Stack>::Type> elem) {
+  if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) {
+    return false;
+  }
+  // sk_push takes ownership on success.
+  elem.release();
+  return true;
+}
+
+}  // namespace bssl
+
+// Define begin() and end() for stack types so C++ range for loops work.
+template <typename Stack>
+static inline bssl::internal::StackIterator<Stack> begin(const Stack *sk) {
+  return bssl::internal::StackIterator<Stack>(sk, 0);
+}
+
+template <typename Stack>
+static inline bssl::internal::StackIterator<Stack> end(const Stack *sk) {
+  return bssl::internal::StackIterator<Stack>(
+      sk, sk_num(reinterpret_cast<const _STACK *>(sk)));
+}
+
+}  // extern C++
+#endif
+
 #endif  /* OPENSSL_HEADER_STACK_H */
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index efd8c78..138c060 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -1094,16 +1094,13 @@
 
 #ifdef  __cplusplus
 }
+#endif
 
+#if !defined(BORINGSSL_NO_CXX)
 extern "C++" {
 
 namespace bssl {
 
-BORINGSSL_MAKE_STACK_DELETER(X509, X509_free)
-BORINGSSL_MAKE_STACK_DELETER(X509_CRL, X509_CRL_free)
-BORINGSSL_MAKE_STACK_DELETER(X509_EXTENSION, X509_EXTENSION_free)
-BORINGSSL_MAKE_STACK_DELETER(X509_NAME, X509_NAME_free)
-
 BORINGSSL_MAKE_DELETER(NETSCAPE_SPKI, NETSCAPE_SPKI_free)
 BORINGSSL_MAKE_DELETER(X509, X509_free)
 BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free)
@@ -1123,11 +1120,14 @@
 BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free)
 BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
 
+using ScopedX509_STORE_CTX =
+    internal::StackAllocated<X509_STORE_CTX, void, X509_STORE_CTX_zero,
+                             X509_STORE_CTX_cleanup>;
+
 }  // namespace bssl
 
 }  /* extern C++ */
-
-#endif
+#endif  /* !BORINGSSL_NO_CXX */
 
 #define X509_R_AKID_MISMATCH 100
 #define X509_R_BAD_PKCS7_VERSION 101
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index ac739ea..4abd9cd 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -449,6 +449,7 @@
 
 OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
 
+OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx);
 OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
 OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
 			 X509 *x509, STACK_OF(X509) *chain);
diff --git a/src/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index 7375d23..dd56bbc 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -747,15 +747,11 @@
 
 namespace bssl {
 
-BORINGSSL_MAKE_STACK_DELETER(DIST_POINT, DIST_POINT_free)
-BORINGSSL_MAKE_STACK_DELETER(GENERAL_NAME, GENERAL_NAME_free)
-// A STACK_OF(POLICYINFO) is also known as a CERTIFICATEPOLICIES.
-BORINGSSL_MAKE_STACK_DELETER(POLICYINFO, POLICYINFO_free)
-
 BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free)
 BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free)
 BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free)
 BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free)
+BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free)
 
 }  // namespace bssl