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/crypto/asn1/asn1_locl.h b/src/crypto/asn1/asn1_locl.h
index ce8146b..fef00ac 100644
--- a/src/crypto/asn1/asn1_locl.h
+++ b/src/crypto/asn1/asn1_locl.h
@@ -72,7 +72,7 @@
 /* Wrapper functions for time functions. */
 
 /* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */
-struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result);
 
 /* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec|
  * seconds. */
diff --git a/src/crypto/asn1/time_support.c b/src/crypto/asn1/time_support.c
index 194dc3a..3efd43e 100644
--- a/src/crypto/asn1/time_support.c
+++ b/src/crypto/asn1/time_support.c
@@ -171,7 +171,7 @@
   return 1;
 }
 
-int OPENSSL_gmtime_diff(int *pday, int *psec, const struct tm *from,
+int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
                         const struct tm *to) {
   int from_sec, to_sec, diff_sec;
   long from_jd, to_jd, diff_day;
@@ -195,11 +195,11 @@
     diff_sec -= SECS_PER_DAY;
   }
 
-  if (pday) {
-    *pday = (int)diff_day;
+  if (out_days) {
+    *out_days = (int)diff_day;
   }
-  if (psec) {
-    *psec = diff_sec;
+  if (out_secs) {
+    *out_secs = diff_sec;
   }
 
   return 1;
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index ca1d70b..f1fcae6 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -153,12 +153,12 @@
   return buf_mem_grow(buf, len, 1 /* clear old buffer contents. */);
 }
 
-char *BUF_strdup(const char *buf) {
-  if (buf == NULL) {
+char *BUF_strdup(const char *str) {
+  if (str == NULL) {
     return NULL;
   }
 
-  return BUF_strndup(buf, strlen(buf));
+  return BUF_strndup(str, strlen(str));
 }
 
 size_t BUF_strnlen(const char *str, size_t max_len) {
@@ -173,15 +173,15 @@
   return i;
 }
 
-char *BUF_strndup(const char *buf, size_t size) {
+char *BUF_strndup(const char *str, size_t size) {
   char *ret;
   size_t alloc_size;
 
-  if (buf == NULL) {
+  if (str == NULL) {
     return NULL;
   }
 
-  size = BUF_strnlen(buf, size);
+  size = BUF_strnlen(str, size);
 
   alloc_size = size + 1;
   if (alloc_size < size) {
@@ -195,7 +195,7 @@
     return NULL;
   }
 
-  OPENSSL_memcpy(ret, buf, size);
+  OPENSSL_memcpy(ret, str, size);
   ret[size] = '\0';
   return ret;
 }
@@ -223,19 +223,17 @@
   return l + BUF_strlcpy(dst, src, dst_size);
 }
 
-void *BUF_memdup(const void *data, size_t dst_size) {
-  void *ret;
-
-  if (dst_size == 0) {
+void *BUF_memdup(const void *data, size_t size) {
+  if (size == 0) {
     return NULL;
   }
 
-  ret = OPENSSL_malloc(dst_size);
+  void *ret = OPENSSL_malloc(size);
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
-  OPENSSL_memcpy(ret, data, dst_size);
+  OPENSSL_memcpy(ret, data, size);
   return ret;
 }
diff --git a/src/crypto/chacha/asm/chacha-x86_64.pl b/src/crypto/chacha/asm/chacha-x86_64.pl
index 5ab6f87..6b2065e 100755
--- a/src/crypto/chacha/asm/chacha-x86_64.pl
+++ b/src/crypto/chacha/asm/chacha-x86_64.pl
@@ -24,7 +24,7 @@
 #
 # Performance in cycles per byte out of large buffer.
 #
-#		IALU/gcc 4.8(i)	1xSSSE3/SSE2	4xSSSE3	    8xAVX2
+#		IALU/gcc 4.8(i)	1xSSSE3/SSE2	4xSSSE3	    NxAVX(v)
 #
 # P4		9.48/+99%	-/22.7(ii)	-
 # Core2		7.83/+55%	7.90/8.08	4.35
@@ -32,11 +32,13 @@
 # Sandy Bridge	8.31/+42%	5.45/6.76	2.72
 # Ivy Bridge	6.71/+46%	5.40/6.49	2.41
 # Haswell	5.92/+43%	5.20/6.45	2.42	    1.23
-# Skylake	5.87/+39%	4.70/-		2.31	    1.19
+# Skylake[-X]	5.87/+39%	4.70/-		2.31	    1.19[0.57]
 # Silvermont	12.0/+33%	7.75/7.40	7.03(iii)
+# Knights L	11.7/-		-		9.60(iii)   0.80
 # Goldmont	10.6/+17%	5.10/-		3.28
 # Sledgehammer	7.28/+52%	-/14.2(ii)	-
 # Bulldozer	9.66/+28%	9.85/11.1	3.06(iv)
+# Ryzen		5.96/+50%	5.19/-		2.40        2.09
 # VIA Nano	10.5/+46%	6.72/8.60	6.05
 #
 # (i)	compared to older gcc 3.x one can observe >2x improvement on
diff --git a/src/crypto/cipher_extra/e_aesctrhmac.c b/src/crypto/cipher_extra/e_aesctrhmac.c
index 2982d0d..3034b8f 100644
--- a/src/crypto/cipher_extra/e_aesctrhmac.c
+++ b/src/crypto/cipher_extra/e_aesctrhmac.c
@@ -254,6 +254,7 @@
     aead_aes_ctr_hmac_sha256_seal_scatter,
     aead_aes_ctr_hmac_sha256_open_gather,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
@@ -270,6 +271,7 @@
     aead_aes_ctr_hmac_sha256_seal_scatter,
     aead_aes_ctr_hmac_sha256_open_gather,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
diff --git a/src/crypto/cipher_extra/e_aesgcmsiv.c b/src/crypto/cipher_extra/e_aesgcmsiv.c
index 2dd1267..6adcf17 100644
--- a/src/crypto/cipher_extra/e_aesgcmsiv.c
+++ b/src/crypto/cipher_extra/e_aesgcmsiv.c
@@ -520,6 +520,7 @@
     aead_aes_gcm_siv_asm_seal_scatter,
     NULL /* open_gather */,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 static const EVP_AEAD aead_aes_256_gcm_siv_asm = {
@@ -536,6 +537,7 @@
     aead_aes_gcm_siv_asm_seal_scatter,
     NULL /* open_gather */,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 #endif  /* X86_64 && !NO_ASM */
@@ -804,6 +806,7 @@
     aead_aes_gcm_siv_seal_scatter,
     aead_aes_gcm_siv_open_gather,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 static const EVP_AEAD aead_aes_256_gcm_siv = {
@@ -820,6 +823,7 @@
     aead_aes_gcm_siv_seal_scatter,
     aead_aes_gcm_siv_open_gather,
     NULL /* get_iv */,
+    NULL /* tag_len */,
 };
 
 #if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
diff --git a/src/crypto/cipher_extra/e_chacha20poly1305.c b/src/crypto/cipher_extra/e_chacha20poly1305.c
index 515b60f..8946f1f 100644
--- a/src/crypto/cipher_extra/e_chacha20poly1305.c
+++ b/src/crypto/cipher_extra/e_chacha20poly1305.c
@@ -22,6 +22,7 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 #include <openssl/poly1305.h>
+#include <openssl/type_check.h>
 
 #include "../fipsmodule/cipher/internal.h"
 #include "../internal.h"
@@ -30,7 +31,34 @@
 #define POLY1305_TAG_LEN 16
 
 struct aead_chacha20_poly1305_ctx {
-  unsigned char key[32];
+  uint8_t key[32];
+};
+
+// For convenience (the x86_64 calling convention allows only six parameters in
+// registers), the final parameter for the assembly functions is both an input
+// and output parameter.
+union open_data {
+  struct {
+    alignas(16) uint8_t key[32];
+    uint32_t counter;
+    uint8_t nonce[12];
+  } in;
+  struct {
+    uint8_t tag[POLY1305_TAG_LEN];
+  } out;
+};
+
+union seal_data {
+  struct {
+    alignas(16) uint8_t key[32];
+    uint32_t counter;
+    uint8_t nonce[12];
+    const uint8_t *extra_ciphertext;
+    size_t extra_ciphertext_len;
+  } in;
+  struct {
+    uint8_t tag[POLY1305_TAG_LEN];
+  } out;
 };
 
 #if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
@@ -40,42 +68,42 @@
   return sse41_capable;
 }
 
-// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
-// decrypts |plaintext_len| bytes from |ciphertext| and writes them to
-// |out_plaintext|. On entry, |aead_data| must contain the final 48 bytes of
-// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
-// by the nonce. On exit, it will contain the calculated tag value, which the
-// caller must check.
+OPENSSL_COMPILE_ASSERT(sizeof(union open_data) == 48, wrong_open_data_size);
+OPENSSL_COMPILE_ASSERT(sizeof(union seal_data) == 48 + 8 + 8,
+                       wrong_seal_data_size);
+
+// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It decrypts
+// |plaintext_len| bytes from |ciphertext| and writes them to |out_plaintext|.
+// Additional input parameters are passed in |aead_data->in|. On exit, it will
+// write calculated tag value to |aead_data->out.tag|, which the caller must
+// check.
 extern void chacha20_poly1305_open(uint8_t *out_plaintext,
                                    const uint8_t *ciphertext,
                                    size_t plaintext_len, const uint8_t *ad,
-                                   size_t ad_len, uint8_t *aead_data);
+                                   size_t ad_len, union open_data *aead_data);
 
-// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
-// encrypts |plaintext_len| bytes from |plaintext| and writes them to
-// |out_ciphertext|. On entry, |aead_data| must contain the final 48 bytes of
-// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
-// by the nonce. On exit, it will contain the calculated tag value, which the
-// caller must append to the ciphertext.
+// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It encrypts
+// |plaintext_len| bytes from |plaintext| and writes them to |out_ciphertext|.
+// Additional input parameters are passed in |aead_data->in|. The calculated tag
+// value is over the computed ciphertext concatenated with |extra_ciphertext|
+// and written to |aead_data->out.tag|.
 extern void chacha20_poly1305_seal(uint8_t *out_ciphertext,
                                    const uint8_t *plaintext,
                                    size_t plaintext_len, const uint8_t *ad,
-                                   size_t ad_len, uint8_t *aead_data);
+                                   size_t ad_len, union seal_data *aead_data);
 #else
-static int asm_capable(void) {
-  return 0;
-}
+static int asm_capable(void) { return 0; }
 
 
 static void chacha20_poly1305_open(uint8_t *out_plaintext,
                                    const uint8_t *ciphertext,
                                    size_t plaintext_len, const uint8_t *ad,
-                                   size_t ad_len, uint8_t *aead_data) {}
+                                   size_t ad_len, union open_data *aead_data) {}
 
 static void chacha20_poly1305_seal(uint8_t *out_ciphertext,
                                    const uint8_t *plaintext,
                                    size_t plaintext_len, const uint8_t *ad,
-                                   size_t ad_len, uint8_t *aead_data) {}
+                                   size_t ad_len, union seal_data *aead_data) {}
 #endif
 
 static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
@@ -212,22 +240,21 @@
     }
   }
 
-  alignas(16) uint8_t tag[48 + 8 + 8];
-
+  union seal_data data;
   if (asm_capable()) {
-    OPENSSL_memcpy(tag, c20_ctx->key, 32);
-    OPENSSL_memset(tag + 32, 0, 4);
-    OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
-    OPENSSL_memcpy(tag + 48, &out_tag, sizeof(out_tag));
-    OPENSSL_memcpy(tag + 56, &extra_in_len, sizeof(extra_in_len));
-    chacha20_poly1305_seal(out, in, in_len, ad, ad_len, tag);
+    OPENSSL_memcpy(data.in.key, c20_ctx->key, 32);
+    data.in.counter = 0;
+    OPENSSL_memcpy(data.in.nonce, nonce, 12);
+    data.in.extra_ciphertext = out_tag;
+    data.in.extra_ciphertext_len = extra_in_len;
+    chacha20_poly1305_seal(out, in, in_len, ad, ad_len, &data);
   } else {
     CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
-    calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len,
-             out_tag, extra_in_len);
+    calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, out, in_len, out_tag,
+             extra_in_len);
   }
 
-  OPENSSL_memcpy(out_tag + extra_in_len, tag, ctx->tag_len);
+  OPENSSL_memcpy(out_tag + extra_in_len, data.out.tag, ctx->tag_len);
   *out_tag_len = extra_in_len + ctx->tag_len;
   return 1;
 }
@@ -260,19 +287,18 @@
     return 0;
   }
 
-  alignas(16) uint8_t tag[48];
-
+  union open_data data;
   if (asm_capable()) {
-    OPENSSL_memcpy(tag, c20_ctx->key, 32);
-    OPENSSL_memset(tag + 32, 0, 4);
-    OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
-    chacha20_poly1305_open(out, in, in_len, ad, ad_len, tag);
+    OPENSSL_memcpy(data.in.key, c20_ctx->key, 32);
+    data.in.counter = 0;
+    OPENSSL_memcpy(data.in.nonce, nonce, 12);
+    chacha20_poly1305_open(out, in, in_len, ad, ad_len, &data);
   } else {
-    calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0);
+    calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0);
     CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
   }
 
-  if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) {
+  if (CRYPTO_memcmp(data.out.tag, in_tag, ctx->tag_len) != 0) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
     return 0;
   }
@@ -294,6 +320,7 @@
     aead_chacha20_poly1305_seal_scatter,
     aead_chacha20_poly1305_open_gather,
     NULL, /* get_iv */
+    NULL, /* tag_len */
 };
 
 const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
diff --git a/src/crypto/cipher_extra/e_ssl3.c b/src/crypto/cipher_extra/e_ssl3.c
index f2eb357..dc43713 100644
--- a/src/crypto/cipher_extra/e_ssl3.c
+++ b/src/crypto/cipher_extra/e_ssl3.c
@@ -123,13 +123,33 @@
   return 1;
 }
 
+static size_t aead_ssl3_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len,
+                                const size_t extra_in_len) {
+  assert(extra_in_len == 0);
+  const AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX*)ctx->aead_state;
+
+  const size_t digest_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
+  if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) {
+    // The NULL cipher.
+    return digest_len;
+  }
+
+  const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx);
+  /* An overflow of |in_len + digest_len| doesn't affect the result mod
+   * |block_size|, provided that |block_size| is a smaller power of two. */
+  assert(block_size != 0 && (block_size & (block_size - 1)) == 0);
+  const size_t pad_len = block_size - ((in_len + digest_len) % block_size);
+  return digest_len + pad_len;
+}
+
 static int aead_ssl3_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
                                   uint8_t *out_tag, size_t *out_tag_len,
-                                  size_t max_out_tag_len, const uint8_t *nonce,
-                                  size_t nonce_len, const uint8_t *in,
-                                  size_t in_len, const uint8_t *extra_in,
-                                  size_t extra_in_len, const uint8_t *ad,
-                                  size_t ad_len) {
+                                  const size_t max_out_tag_len,
+                                  const uint8_t *nonce, const size_t nonce_len,
+                                  const uint8_t *in, const size_t in_len,
+                                  const uint8_t *extra_in,
+                                  const size_t extra_in_len, const uint8_t *ad,
+                                  const size_t ad_len) {
   AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
 
   if (!ssl3_ctx->cipher_ctx.encrypt) {
@@ -144,8 +164,7 @@
     return 0;
   }
 
-  const size_t max_overhead = EVP_AEAD_max_overhead(ctx->aead);
-  if (max_out_tag_len < max_overhead) {
+  if (max_out_tag_len < aead_ssl3_tag_len(ctx, in_len, extra_in_len)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
@@ -222,7 +241,7 @@
     return 0;
   }
   tag_len += len;
-  assert(tag_len <= max_overhead);
+  assert(tag_len == aead_ssl3_tag_len(ctx, in_len, extra_in_len));
 
   *out_tag_len = tag_len;
   return 1;
@@ -372,6 +391,7 @@
     aead_ssl3_seal_scatter,
     NULL, /* open_gather */
     aead_ssl3_get_iv,
+    aead_ssl3_tag_len,
 };
 
 static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
@@ -388,6 +408,7 @@
     aead_ssl3_seal_scatter,
     NULL, /* open_gather */
     aead_ssl3_get_iv,
+    aead_ssl3_tag_len,
 };
 
 static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
@@ -404,6 +425,7 @@
     aead_ssl3_seal_scatter,
     NULL, /* open_gather */
     aead_ssl3_get_iv,
+    aead_ssl3_tag_len,
 };
 
 static const EVP_AEAD aead_null_sha1_ssl3 = {
@@ -420,6 +442,7 @@
     aead_ssl3_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_ssl3_tag_len,
 };
 
 const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void) {
diff --git a/src/crypto/cipher_extra/e_tls.c b/src/crypto/cipher_extra/e_tls.c
index 14d5377..ca206ab 100644
--- a/src/crypto/cipher_extra/e_tls.c
+++ b/src/crypto/cipher_extra/e_tls.c
@@ -99,13 +99,33 @@
   return 1;
 }
 
+static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len,
+                               const size_t extra_in_len) {
+  assert(extra_in_len == 0);
+  AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
+
+  const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx);
+  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) {
+    // The NULL cipher.
+    return hmac_len;
+  }
+
+  const size_t block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
+  /* An overflow of |in_len + hmac_len| doesn't affect the result mod
+   * |block_size|, provided that |block_size| is a smaller power of two. */
+  assert(block_size != 0 && (block_size & (block_size - 1)) == 0);
+  const size_t pad_len = block_size - (in_len + hmac_len) % block_size;
+  return hmac_len + pad_len;
+}
+
 static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
                                  uint8_t *out_tag, size_t *out_tag_len,
-                                 size_t max_out_tag_len, const uint8_t *nonce,
-                                 size_t nonce_len, const uint8_t *in,
-                                 size_t in_len, const uint8_t *extra_in,
-                                 size_t extra_in_len, const uint8_t *ad,
-                                 size_t ad_len) {
+                                 const size_t max_out_tag_len,
+                                 const uint8_t *nonce, const size_t nonce_len,
+                                 const uint8_t *in, const size_t in_len,
+                                 const uint8_t *extra_in,
+                                 const size_t extra_in_len, const uint8_t *ad,
+                                 const size_t ad_len) {
   AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
 
   if (!tls_ctx->cipher_ctx.encrypt) {
@@ -120,8 +140,7 @@
     return 0;
   }
 
-  const size_t max_overhead = EVP_AEAD_max_overhead(ctx->aead);
-  if (max_out_tag_len < max_overhead) {
+  if (max_out_tag_len < aead_tls_tag_len(ctx, in_len, extra_in_len)) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
@@ -173,7 +192,8 @@
    * block from encrypting the input and split the result between |out| and
    * |out_tag|. Then feed the rest. */
 
-  size_t early_mac_len = (block_size - (in_len % block_size)) % block_size;
+  const size_t early_mac_len =
+      (block_size - (in_len % block_size) % block_size);
   if (early_mac_len != 0) {
     assert(len + block_size - early_mac_len == in_len);
     uint8_t buf[EVP_MAX_BLOCK_LENGTH];
@@ -212,8 +232,8 @@
   if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len)) {
     return 0;
   }
-  tag_len += len;
-  assert(tag_len <= max_overhead);
+  assert(len == 0); /* Padding is explicit. */
+  assert(tag_len == aead_tls_tag_len(ctx, in_len, extra_in_len));
 
   *out_tag_len = tag_len;
   return 1;
@@ -467,6 +487,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
@@ -483,6 +504,7 @@
     aead_tls_seal_scatter,
     NULL,            /* open_gather */
     aead_tls_get_iv, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
@@ -499,6 +521,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
@@ -515,6 +538,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
@@ -531,6 +555,7 @@
     aead_tls_seal_scatter,
     NULL,            /* open_gather */
     aead_tls_get_iv, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
@@ -547,6 +572,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
@@ -563,6 +589,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
@@ -579,6 +606,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
@@ -595,6 +623,7 @@
     aead_tls_seal_scatter,
     NULL,            /* open_gather */
     aead_tls_get_iv, /* get_iv */
+    aead_tls_tag_len,
 };
 
 static const EVP_AEAD aead_null_sha1_tls = {
@@ -611,6 +640,7 @@
     aead_tls_seal_scatter,
     NULL, /* open_gather */
     NULL, /* get_iv */
+    aead_tls_tag_len,
 };
 
 const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
diff --git a/src/crypto/compiler_test.cc b/src/crypto/compiler_test.cc
index 2836276..29375a5 100644
--- a/src/crypto/compiler_test.cc
+++ b/src/crypto/compiler_test.cc
@@ -149,11 +149,11 @@
   CheckRepresentation(static_cast<uint64_t>(0));
 }
 
-// Converting pointers to integers and doing arithmetic on those values are both
-// defined. Converting those values back into pointers is undefined, but, for
-// aliasing checks, we require that the implementation-defined result of that
-// computation commutes with pointer arithmetic.
 TEST(CompilerTest, PointerRepresentation) {
+  // Converting pointers to integers and doing arithmetic on those values are
+  // both defined. Converting those values back into pointers is undefined,
+  // but, for aliasing checks, we require that the implementation-defined
+  // result of that computation commutes with pointer arithmetic.
   char chars[256];
   for (size_t i = 0; i < sizeof(chars); i++) {
     EXPECT_EQ(reinterpret_cast<uintptr_t>(chars) + i,
@@ -165,4 +165,11 @@
     EXPECT_EQ(reinterpret_cast<uintptr_t>(ints) + i * sizeof(int),
               reinterpret_cast<uintptr_t>(ints + i));
   }
+
+  // nullptr must be represented by all zeros in memory. This is necessary so
+  // structs may be initialized by memset(0).
+  int *null = nullptr;
+  uint8_t bytes[sizeof(null)] = {0};
+  EXPECT_EQ(Bytes(bytes),
+            Bytes(reinterpret_cast<uint8_t *>(&null), sizeof(null)));
 }
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index f2e0c4c..ef327df 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -207,6 +207,14 @@
   /* Reserved bit #30 is repurposed to signal an Intel CPU. */
   if (is_intel) {
     edx |= (1 << 30);
+
+    /* Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables
+     * some Silvermont-specific codepaths which perform better. See OpenSSL
+     * commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. */
+    if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ ||
+        (eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) {
+      ecx &= ~(1 << 26);
+    }
   } else {
     edx &= ~(1 << 30);
   }
@@ -223,13 +231,30 @@
     /* XCR0 may only be queried if the OSXSAVE bit is set. */
     xcr0 = OPENSSL_xgetbv(0);
   }
-  /* See Intel manual, section 14.3. */
+  /* See Intel manual, volume 1, section 14.3. */
   if ((xcr0 & 6) != 6) {
     /* YMM registers cannot be used. */
     ecx &= ~(1 << 28); /* AVX */
     ecx &= ~(1 << 12); /* FMA */
     ecx &= ~(1 << 11); /* AMD XOP */
-    extended_features &= ~(1 << 5); /* AVX2 */
+    /* Clear AVX2 and AVX512* bits.
+     *
+     * TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream
+     * doesn't clear those. */
+    extended_features &=
+        ~((1 << 5) | (1 << 16) | (1 << 21) | (1 << 30) | (1 << 31));
+  }
+  /* See Intel manual, volume 1, section 15.2. */
+  if ((xcr0 & 0xe6) != 0xe6) {
+    /* Clear AVX512F. Note we don't touch other AVX512 extensions because they
+     * can be used with YMM. */
+    extended_features &= ~(1 << 16);
+  }
+
+  /* Disable ADX instructions on Knights Landing. See OpenSSL commit
+   * 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. */
+  if ((ecx & (1 << 26)) == 0) {
+    extended_features &= ~(1 << 19);
   }
 
   OPENSSL_ia32cap_P[0] = edx;
diff --git a/src/crypto/dh/check.c b/src/crypto/dh/check.c
index e3c111b..55fc1c3 100644
--- a/src/crypto/dh/check.c
+++ b/src/crypto/dh/check.c
@@ -59,8 +59,8 @@
 #include <openssl/bn.h>
 
 
-int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
-  *ret = 0;
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) {
+  *out_flags = 0;
 
   BN_CTX *ctx = BN_CTX_new();
   if (ctx == NULL) {
@@ -77,7 +77,7 @@
     goto err;
   }
   if (BN_cmp(pub_key, tmp) <= 0) {
-    *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+    *out_flags |= DH_CHECK_PUBKEY_TOO_SMALL;
   }
 
   /* Check |pub_key| is less than |dh->p| - 1. */
@@ -86,7 +86,7 @@
     goto err;
   }
   if (BN_cmp(pub_key, tmp) >= 0) {
-    *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+    *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE;
   }
 
   if (dh->q != NULL) {
@@ -97,7 +97,7 @@
       goto err;
     }
     if (!BN_is_one(tmp)) {
-      *ret |= DH_CHECK_PUBKEY_INVALID;
+      *out_flags |= DH_CHECK_PUBKEY_INVALID;
     }
   }
 
@@ -110,7 +110,7 @@
 }
 
 
-int DH_check(const DH *dh, int *ret) {
+int DH_check(const DH *dh, int *out_flags) {
   /* Check that p is a safe prime and if g is 2, 3 or 5, check that it is a
    * suitable generator where:
    *   for 2, p mod 24 == 11
@@ -123,7 +123,7 @@
   BN_ULONG l;
   BIGNUM *t1 = NULL, *t2 = NULL;
 
-  *ret = 0;
+  *out_flags = 0;
   ctx = BN_CTX_new();
   if (ctx == NULL) {
     goto err;
@@ -140,16 +140,16 @@
 
   if (dh->q) {
     if (BN_cmp(dh->g, BN_value_one()) <= 0) {
-      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+      *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     } else if (BN_cmp(dh->g, dh->p) >= 0) {
-      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+      *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     } else {
       /* Check g^q == 1 mod p */
       if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) {
         goto err;
       }
       if (!BN_is_one(t1)) {
-        *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+        *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
       }
     }
     r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
@@ -157,17 +157,17 @@
       goto err;
     }
     if (!r) {
-      *ret |= DH_CHECK_Q_NOT_PRIME;
+      *out_flags |= DH_CHECK_Q_NOT_PRIME;
     }
     /* Check p == 1 mod q  i.e. q divides p - 1 */
     if (!BN_div(t1, t2, dh->p, dh->q, ctx)) {
       goto err;
     }
     if (!BN_is_one(t2)) {
-      *ret |= DH_CHECK_INVALID_Q_VALUE;
+      *out_flags |= DH_CHECK_INVALID_Q_VALUE;
     }
     if (dh->j && BN_cmp(dh->j, t1)) {
-      *ret |= DH_CHECK_INVALID_J_VALUE;
+      *out_flags |= DH_CHECK_INVALID_J_VALUE;
     }
   } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
     l = BN_mod_word(dh->p, 24);
@@ -175,7 +175,7 @@
       goto err;
     }
     if (l != 11) {
-      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+      *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     }
   } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
     l = BN_mod_word(dh->p, 10);
@@ -183,10 +183,10 @@
       goto err;
     }
     if (l != 3 && l != 7) {
-      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+      *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     }
   } else {
-    *ret |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
+    *out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
   }
 
   r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
@@ -194,7 +194,7 @@
     goto err;
   }
   if (!r) {
-    *ret |= DH_CHECK_P_NOT_PRIME;
+    *out_flags |= DH_CHECK_P_NOT_PRIME;
   } else if (!dh->q) {
     if (!BN_rshift1(t1, dh->p)) {
       goto err;
@@ -204,7 +204,7 @@
       goto err;
     }
     if (!r) {
-      *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+      *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME;
     }
   }
   ok = 1;
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index 58126c3..d445f14 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -917,35 +917,35 @@
   return index;
 }
 
-int DSA_set_ex_data(DSA *d, int idx, void *arg) {
-  return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+int DSA_set_ex_data(DSA *dsa, int idx, void *arg) {
+  return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg);
 }
 
-void *DSA_get_ex_data(const DSA *d, int idx) {
-  return CRYPTO_get_ex_data(&d->ex_data, idx);
+void *DSA_get_ex_data(const DSA *dsa, int idx) {
+  return CRYPTO_get_ex_data(&dsa->ex_data, idx);
 }
 
-DH *DSA_dup_DH(const DSA *r) {
-  DH *ret = NULL;
-
-  if (r == NULL) {
-    goto err;
+DH *DSA_dup_DH(const DSA *dsa) {
+  if (dsa == NULL) {
+    return NULL;
   }
-  ret = DH_new();
+
+  DH *ret = DH_new();
   if (ret == NULL) {
     goto err;
   }
-  if (r->q != NULL) {
-    ret->priv_length = BN_num_bits(r->q);
-    if ((ret->q = BN_dup(r->q)) == NULL) {
+  if (dsa->q != NULL) {
+    ret->priv_length = BN_num_bits(dsa->q);
+    if ((ret->q = BN_dup(dsa->q)) == NULL) {
       goto err;
     }
   }
-  if ((r->p != NULL && (ret->p = BN_dup(r->p)) == NULL) ||
-      (r->g != NULL && (ret->g = BN_dup(r->g)) == NULL) ||
-      (r->pub_key != NULL && (ret->pub_key = BN_dup(r->pub_key)) == NULL) ||
-      (r->priv_key != NULL && (ret->priv_key = BN_dup(r->priv_key)) == NULL)) {
-      goto err;
+  if ((dsa->p != NULL && (ret->p = BN_dup(dsa->p)) == NULL) ||
+      (dsa->g != NULL && (ret->g = BN_dup(dsa->g)) == NULL) ||
+      (dsa->pub_key != NULL && (ret->pub_key = BN_dup(dsa->pub_key)) == NULL) ||
+      (dsa->priv_key != NULL &&
+       (ret->priv_key = BN_dup(dsa->priv_key)) == NULL)) {
+    goto err;
   }
 
   return ret;
diff --git a/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl b/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl
index 4ad0fb1..a9b3151 100644
--- a/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl
+++ b/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl
@@ -179,8 +179,10 @@
 # Haswell	4.44/0.63	0.63	0.73	0.63	0.70
 # Skylake	2.62/0.63	0.63	0.63	0.63
 # Silvermont	5.75/3.54	3.56	4.12	3.87(*)	4.11
+# Knights L	2.54/0.77	0.78	0.85	-	1.50
 # Goldmont	3.82/1.26	1.26	1.29	1.29	1.50
 # Bulldozer	5.77/0.70	0.72	0.90	0.70	0.95
+# Ryzen		2.71/0.35	0.35	0.44	0.38	0.49
 #
 # (*)	Atom Silvermont ECB result is suboptimal because of penalties
 #	incurred by operations on %xmm8-15. As ECB is not considered
diff --git a/src/crypto/fipsmodule/cipher/aead.c b/src/crypto/fipsmodule/cipher/aead.c
index 79139e6..ed30209 100644
--- a/src/crypto/fipsmodule/cipher/aead.c
+++ b/src/crypto/fipsmodule/cipher/aead.c
@@ -264,3 +264,21 @@
 
   return ctx->aead->get_iv(ctx, out_iv, out_len);
 }
+
+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) {
+  assert(ctx->aead->seal_scatter_supports_extra_in || !extra_in_len);
+
+  if (ctx->aead->tag_len) {
+    *out_tag_len = ctx->aead->tag_len(ctx, in_len, extra_in_len);
+    return 1;
+  }
+
+  if (extra_in_len + ctx->tag_len < extra_in_len) {
+    OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW);
+    *out_tag_len = 0;
+    return 0;
+  }
+  *out_tag_len = extra_in_len + ctx->tag_len;
+  return 1;
+}
diff --git a/src/crypto/fipsmodule/cipher/e_aes.c b/src/crypto/fipsmodule/cipher/e_aes.c
index 7c7521b..2c6fc41 100644
--- a/src/crypto/fipsmodule/cipher/e_aes.c
+++ b/src/crypto/fipsmodule/cipher/e_aes.c
@@ -1217,7 +1217,7 @@
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
     return 0;
   }
-  if (max_out_tag_len < ctx->tag_len + extra_in_len) {
+  if (max_out_tag_len < extra_in_len + ctx->tag_len) {
     OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
     return 0;
   }
@@ -1226,11 +1226,6 @@
     return 0;
   }
 
-  if (max_out_tag_len < ctx->tag_len) {
-    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
-    return 0;
-  }
-
   const AES_KEY *key = &gcm_ctx->ks.ks;
 
   OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
diff --git a/src/crypto/fipsmodule/cipher/internal.h b/src/crypto/fipsmodule/cipher/internal.h
index ea59723..02335e0 100644
--- a/src/crypto/fipsmodule/cipher/internal.h
+++ b/src/crypto/fipsmodule/cipher/internal.h
@@ -107,6 +107,9 @@
 
   int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
                 size_t *out_len);
+
+  size_t (*tag_len)(const EVP_AEAD_CTX *ctx, size_t in_Len,
+                    size_t extra_in_len);
 };
 
 /* aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|,
diff --git a/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
index 57a6a8d..dd6657b 100644
--- a/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -28,6 +35,8 @@
 # Applications using the EVP interface will observe a few percent
 # worse performance.]
 #
+# Knights Landing processes 1 byte in 1.25 cycles (measured with EVP).
+#
 # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest
 # [2] http://www.intel.com/content/dam/www/public/us/en/documents/software-support/enabling-high-performance-gcm.pdf
 
diff --git a/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl b/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl
index 1778ac0..e6dd041 100644
--- a/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -67,6 +74,7 @@
 # Skylake	0.44(+110%)(if system doesn't support AVX)
 # Bulldozer	1.49(+27%)
 # Silvermont	2.88(+13%)
+# Knights L	2.12(-)    (if system doesn't support AVX)
 # Goldmont	1.08(+24%)
 
 # March 2013
@@ -79,6 +87,8 @@
 # it performs in 0.41 cycles per byte on Haswell processor, in
 # 0.29 on Broadwell, and in 0.36 on Skylake.
 #
+# Knights Landing achieves 1.09 cpb.
+#
 # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest
 
 $flavour = shift;
diff --git a/src/crypto/fipsmodule/rand/ctrdrbg_test.cc b/src/crypto/fipsmodule/rand/ctrdrbg_test.cc
index bd84782..0cc48b1 100644
--- a/src/crypto/fipsmodule/rand/ctrdrbg_test.cc
+++ b/src/crypto/fipsmodule/rand/ctrdrbg_test.cc
@@ -100,19 +100,19 @@
 
     CTR_DRBG_STATE drbg;
     CTR_DRBG_init(&drbg, seed.data(),
-                  personalisation.size() > 0 ? personalisation.data() : nullptr,
+                  personalisation.empty() ? nullptr : personalisation.data(),
                   personalisation.size());
     CTR_DRBG_reseed(&drbg, reseed.data(),
-                    ai_reseed.size() > 0 ? ai_reseed.data() : nullptr,
+                    ai_reseed.empty() ? nullptr : ai_reseed.data(),
                     ai_reseed.size());
 
     std::vector<uint8_t> out;
     out.resize(expected.size());
 
     CTR_DRBG_generate(&drbg, out.data(), out.size(),
-                      ai1.size() > 0 ? ai1.data() : nullptr, ai1.size());
+                      ai1.empty() ? nullptr : ai1.data(), ai1.size());
     CTR_DRBG_generate(&drbg, out.data(), out.size(),
-                      ai2.size() > 0 ? ai2.data() : nullptr, ai2.size());
+                      ai2.empty() ? nullptr : ai2.data(), ai2.size());
 
     EXPECT_EQ(Bytes(expected), Bytes(out));
   });
diff --git a/src/crypto/fipsmodule/rand/rand.c b/src/crypto/fipsmodule/rand/rand.c
index eb99f72..9480ddb 100644
--- a/src/crypto/fipsmodule/rand/rand.c
+++ b/src/crypto/fipsmodule/rand/rand.c
@@ -345,8 +345,6 @@
 #if defined(BORINGSSL_FIPS)
   CRYPTO_STATIC_MUTEX_unlock_read(thread_states_list_lock_bss_get());
 #endif
-
-  return;
 }
 
 int RAND_bytes(uint8_t *out, size_t out_len) {
diff --git a/src/crypto/fipsmodule/rsa/rsa.c b/src/crypto/fipsmodule/rsa/rsa.c
index 21dcacd..a434cb1 100644
--- a/src/crypto/fipsmodule/rsa/rsa.c
+++ b/src/crypto/fipsmodule/rsa/rsa.c
@@ -293,12 +293,12 @@
   return index;
 }
 
-int RSA_set_ex_data(RSA *d, int idx, void *arg) {
-  return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+int RSA_set_ex_data(RSA *rsa, int idx, void *arg) {
+  return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg);
 }
 
-void *RSA_get_ex_data(const RSA *d, int idx) {
-  return CRYPTO_get_ex_data(&d->ex_data, idx);
+void *RSA_get_ex_data(const RSA *rsa, int idx) {
+  return CRYPTO_get_ex_data(&rsa->ex_data, idx);
 }
 
 /* SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
diff --git a/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl b/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl
index b269e84..f5bc2e6 100755
--- a/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl
+++ b/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -75,9 +82,11 @@
 # Haswell	5.45		4.15/+31%	3.57/+53%
 # Skylake	5.18		4.06/+28%	3.54/+46%
 # Bulldozer	9.11		5.95/+53%
+# Ryzen		4.75		3.80/+24%	1.93/+150%(**)
 # VIA Nano	9.32		7.15/+30%
 # Atom		10.3		9.17/+12%
 # Silvermont	13.1(*)		9.37/+40%
+# Knights L	13.2(*)		9.68/+36%	8.30/+59%
 # Goldmont	8.13		6.42/+27%	1.70/+380%(**)
 #
 # (*)	obviously suboptimal result, nothing was done about it,
@@ -537,7 +546,7 @@
     $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
 }
 
-sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
+sub Xupdate_ssse3_16_31()		# recall that $Xi starts with 4
 { use integer;
   my $body = shift;
   my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
@@ -1458,7 +1467,7 @@
 	)
 }
 
-sub Xupdate_avx2_16_31()		# recall that $Xi starts wtih 4
+sub Xupdate_avx2_16_31()		# recall that $Xi starts with 4
 { use integer;
   my $body = shift;
   my @insns = (&$body,&$body,&$body,&$body,&$body);	# 35 instructions
diff --git a/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl b/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl
index 7ad7491..e62ad75 100755
--- a/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl
+++ b/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -88,9 +95,11 @@
 # Haswell	12.2	9.28(+31%)  7.80(+56%)	    7.66    5.40(+42%)
 # Skylake	11.4	9.03(+26%)  7.70(+48%)      7.25    5.20(+40%)
 # Bulldozer	21.1	13.6(+54%)  13.6(+54%(***)) 13.5    8.58(+57%)
+# Ryzen		11.0	9.02(+22%)  2.05(+440%)     7.05    5.67(+20%)
 # VIA Nano	23.0	16.5(+39%)  -		    14.7    -
 # Atom		23.0	18.9(+22%)  -		    14.7    -
 # Silvermont	27.4	20.6(+33%)  -               17.5    -
+# Knights L	27.4	21.0(+30%)  19.6(+40%)	    17.5    12.8(+37%)
 # Goldmont	18.9	14.3(+32%)  4.16(+350%)     12.0    -
 #
 # (*)	whichever best applicable, including SHAEXT;
@@ -311,7 +320,6 @@
 	mov	$SZ*5($ctx),$F
 	mov	$SZ*6($ctx),$G
 	mov	$SZ*7($ctx),$H
-
 	jmp	.Lloop
 
 .align	16
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index 390ca2e..f451a12 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -159,27 +159,50 @@
 
 char *OPENSSL_strdup(const char *s) { return _strdup(s); }
 
-int OPENSSL_strcasecmp(const char *a, const char *b) {
-  return _stricmp(a, b);
-}
-
-int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
-  return _strnicmp(a, b, n);
-}
-
 #else
 
 char *OPENSSL_strdup(const char *s) { return strdup(s); }
 
+#endif
+
+int OPENSSL_tolower(int c) {
+  if (c >= 'A' && c <= 'Z') {
+    return c + ('a' - 'A');
+  }
+  return c;
+}
+
 int OPENSSL_strcasecmp(const char *a, const char *b) {
-  return strcasecmp(a, b);
+  for (size_t i = 0;; i++) {
+    const int aa = OPENSSL_tolower(a[i]);
+    const int bb = OPENSSL_tolower(b[i]);
+
+    if (aa < bb) {
+      return -1;
+    } else if (aa > bb) {
+      return 1;
+    } else if (aa == 0) {
+      return 0;
+    }
+  }
 }
 
 int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
-  return strncasecmp(a, b, n);
-}
+  for (size_t i = 0; i < n; i++) {
+    const int aa = OPENSSL_tolower(a[i]);
+    const int bb = OPENSSL_tolower(b[i]);
 
-#endif
+    if (aa < bb) {
+      return -1;
+    } else if (aa > bb) {
+      return 1;
+    } else if (aa == 0) {
+      return 0;
+    }
+  }
+
+  return 0;
+}
 
 int BIO_snprintf(char *buf, size_t n, const char *format, ...) {
   va_list args;
diff --git a/src/crypto/rand_extra/rand_extra.c b/src/crypto/rand_extra/rand_extra.c
index 8fce3c8..3b37e29 100644
--- a/src/crypto/rand_extra/rand_extra.c
+++ b/src/crypto/rand_extra/rand_extra.c
@@ -63,6 +63,8 @@
   return (RAND_METHOD*) &kSSLeayMethod;
 }
 
+const RAND_METHOD *RAND_get_rand_method(void) { return RAND_SSLeay(); }
+
 void RAND_set_rand_method(const RAND_METHOD *method) {}
 
 void RAND_cleanup(void) {}
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index c85fac6..ea1fc3c 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -32,7 +32,8 @@
 
 FileTest::FileTest(std::unique_ptr<FileTest::LineReader> reader,
                    std::function<void(const std::string &)> comment_callback)
-    : reader_(std::move(reader)), comment_callback_(comment_callback) {}
+    : reader_(std::move(reader)),
+      comment_callback_(std::move(comment_callback)) {}
 
 FileTest::~FileTest() {}
 
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 2413a1c..b427df6 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -2254,10 +2254,15 @@
         OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
-    OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+    X509_STORE_CTX_zero(ctx);
     return ctx;
 }
 
+void X509_STORE_CTX_zero(X509_STORE_CTX *ctx)
+{
+    OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+}
+
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
 {
     if (ctx == NULL) {
@@ -2272,7 +2277,7 @@
 {
     int ret = 1;
 
-    OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+    X509_STORE_CTX_zero(ctx);
     ctx->ctx = store;
     ctx->cert = x509;
     ctx->untrusted = chain;
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index e6eeb95..5fa9077 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -492,7 +492,7 @@
             }
             while (!(*from & 0x80) && isspace(*from));
         } else {
-            *to++ = tolower(*from);
+            *to++ = OPENSSL_tolower(*from);
             from++;
             i++;
         }
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index fe7787b..feb3dc6 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -454,15 +454,13 @@
             OPENSSL_free(hexbuf);
             return NULL;
         }
-        if (isupper(ch))
-            ch = tolower(ch);
-        if (isupper(cl))
-            cl = tolower(cl);
 
         if ((ch >= '0') && (ch <= '9'))
             ch -= '0';
         else if ((ch >= 'a') && (ch <= 'f'))
             ch -= 'a' - 10;
+        else if ((ch >= 'A') && (ch <= 'F'))
+            ch -= 'A' - 10;
         else
             goto badhex;
 
@@ -470,6 +468,8 @@
             cl -= '0';
         else if ((cl >= 'a') && (cl <= 'f'))
             cl -= 'a' - 10;
+        else if ((cl >= 'A') && (cl <= 'F'))
+            cl -= 'A' - 10;
         else
             goto badhex;