diff --git a/CMakeLists.txt b/CMakeLists.txt
index 378b36e..f0ea702 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -116,104 +116,27 @@
 set(CMAKE_C_STANDARD 11)
 set(CMAKE_C_STANDARD_REQUIRED ON)
 
+# Set some project-wide compiler flags.
 if(CMAKE_COMPILER_IS_GNUCXX OR CLANG)
-  # Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration
-  # primarily on our normal Clang one.
-  set(C_CXX_FLAGS "-Werror -Wformat=2 -Wmissing-field-initializers -Wshadow -Wsign-compare -Wtype-limits -Wvla -Wwrite-strings -fno-strict-aliasing")
-  if(MSVC)
-    # clang-cl sets different default warnings than clang. It also treats -Wall
-    # as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall.
-    # See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -W3 -Wno-unused-parameter -fmsc-version=1900")
-  else()
+  set(C_CXX_FLAGS "-fno-strict-aliasing")
+  if(NOT MSVC)
     if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
       # emscripten's emcc/clang does not accept the "-ggdb" flag.
       set(C_CXX_FLAGS "${C_CXX_FLAGS} -g")
     else()
       set(C_CXX_FLAGS "${C_CXX_FLAGS} -ggdb")
     endif()
-
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -fno-common -fvisibility=hidden")
+    set(C_CXX_FLAGS "${C_CXX_FLAGS} -fno-common -fvisibility=hidden")
   endif()
-
-  if(CLANG)
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wnewline-eof -Wextra-semi -fcolor-diagnostics")
-  else()
-    # GCC (at least 4.8.4) has a bug where it'll find unreachable free() calls
-    # and declare that the code is trying to free a stack pointer.
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-free-nonheap-object")
-  endif()
-
-  # -Wstring-concatenation was added in Clang 12.0.0, which corresponds to
-  # AppleClang 13.0.0 per the table in
-  # https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
-  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0") OR
-     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0"))
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wstring-concatenation")
-  endif()
-
-  # Clang 12's -Wframe-larger-than reportedly does not work in clang-cl. See
-  # https://crbug.com/boringssl/709. Clang 13 includes the following fix, which
-  # may be related. Speculatively gate on Clang 13. That corresponds to
-  # AppleClang 13.1.6.
-  # https://github.com/llvm/llvm-project/commit/6aaf4fa2885600b0e31042071ad06f78218ab0f2
-  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0") OR
-     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.1.6"))
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wframe-larger-than=25344")
-  endif()
-
-  # -Wctad-maybe-unsupported was added in Clang 10, which is AppleClang 12.0.0.
-  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0") OR
-     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
-      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0"))
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wctad-maybe-unsupported")
-  endif()
-
-  if(CLANG OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0")
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wimplicit-fallthrough")
-  endif()
-
-  if(CMAKE_COMPILER_IS_GNUCXX)
-    set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wformat-signedness")
-  endif()
-
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} -Wmissing-declarations -Wnon-virtual-dtor")
-
-  # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes
-  # and using the wrong one is an error. In Clang, -Wmissing-prototypes is the
-  # spelling for both and -Wmissing-declarations is some other warning.
-  #
-  # https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Warning-Options.html#Warning-Options
-  # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-prototypes
-  # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-declarations
-  if(CLANG)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-prototypes")
-  endif()
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS}")
+  set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS}")
 elseif(MSVC)
-  set(MSVC_DISABLED_WARNINGS_LIST
-      "C4100" # 'exarg' : unreferenced formal parameter
-      "C4127" # conditional expression is constant
-      "C4244" # 'function' : conversion from 'int' to 'uint8_t',
-              # possible loss of data
-      "C4267" # conversion from 'size_t' to 'int', possible loss of data
-      "C4702" # unreachable code; MSVC's warning is too aggressive. See
-              # https://crbug.com/385161043
-      "C4706" # assignment within conditional expression
-      )
-  string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
-                            ${MSVC_DISABLED_WARNINGS_LIST})
-  set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -utf-8")
   # Without /Zc:__cplusplus, MSVC does not define the right value for
   # __cplusplus. See https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
   # If this becomes too problematic for downstream code, we can look at
   # _MSVC_LANG.
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR} -Zc:__cplusplus")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -utf-8 -Zc:__cplusplus")
 endif()
 
 if(WIN32)
@@ -393,6 +316,8 @@
   add_definitions(-DOPENSSL_NO_SSE2_FOR_TESTING)
 endif()
 
+# Build a custom libc++. This must be the first target, so that it is linked to
+# every subsequent target.
 if(USE_CUSTOM_LIBCXX)
   if(NOT CLANG)
     message(FATAL_ERROR "USE_CUSTOM_LIBCXX only supported with Clang")
@@ -456,7 +381,6 @@
   target_include_directories(libcxx PRIVATE util/bot/llvm-libc)
   set_target_properties(
     libcxx libcxxabi PROPERTIES
-    COMPILE_FLAGS "-Wno-missing-prototypes -Wno-implicit-fallthrough"
     # libc++ and libc++abi must be built in C++23 mode.
     CXX_STANDARD 23
     CXX_STANDARD_REQUIRED TRUE
@@ -464,6 +388,15 @@
   # libc++abi depends on libc++ internal headers.
   set_property(TARGET libcxx libcxxabi APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/util/bot/libcxx/src")
   target_link_libraries(libcxx libcxxabi)
+
+  # Link all subsequent libraries to the custom libc++.
+  link_libraries(libcxx)
+
+  # Third-party CMake files that export targets will this target itself be
+  # exported. This is not meant to be imported, as USE_CUSTOM_LIBCXX is a
+  # test-only configuration.
+  export(TARGETS libcxx libcxxabi NAMESPACE bssl_test_only
+         FILE ${PROJECT_BINARY_DIR}/bssl_test_only.cmake)
 endif()
 
 if(BUILD_TESTING)
@@ -474,9 +407,6 @@
     third_party/googletest/googlemock/src/gmock-all.cc
     third_party/googletest/googletest/src/gtest-all.cc
   )
-  if(USE_CUSTOM_LIBCXX)
-    target_link_libraries(boringssl_gtest libcxx)
-  endif()
   target_include_directories(
       boringssl_gtest
       PUBLIC
@@ -486,12 +416,113 @@
       third_party/googletest/googlemock
       third_party/googletest/googletest
   )
+endif()
 
-  # Declare a dummy target to build all unit tests. Test targets should inject
-  # themselves as dependencies next to the target definition.
-  add_custom_target(boringssl_all_tests)
+if(FUZZ AND LIBFUZZER_FROM_DEPS)
+  file(GLOB LIBFUZZER_SOURCES "util/bot/libFuzzer/*.cpp")
+  add_library(Fuzzer STATIC ${LIBFUZZER_SOURCES})
+  # libFuzzer must be built without -fsanitize-coverage options or clang
+  # crashes.
+  set_target_properties(
+    Fuzzer PROPERTIES
+    COMPILE_FLAGS "-fsanitize-coverage=0"
+  )
+endif()
 
-  add_subdirectory(ssl/test)
+# Enable a suite of warnings. We do this here to avoid applying to external
+# dependencies, built above. Note this uses the list-based add_compile_options,
+# instead of CMAKE_*_FLAGS (string-based). Changes to CMAKE_*_FLAGS still apply
+# to earlier-defined targets.
+#
+# TODO(crbug.com/389897612): Should these be set on a per-target basis?
+if(CMAKE_COMPILER_IS_GNUCXX OR CLANG)
+  set(C_CXX_WARNINGS -Werror -Wformat=2 -Wmissing-field-initializers -Wshadow
+      -Wsign-compare -Wtype-limits -Wvla -Wwrite-strings -Wimplicit-fallthrough)
+  set(C_WARNINGS -Wold-style-definition -Wstrict-prototypes)
+  set(CXX_WARNING -Wnon-virtual-dtor)
+
+  # clang-cl sets both CLANG and MSVC. It implements clang's diagnostics, but
+  # some options behave as in MSVC.
+  if(MSVC)
+    # clang-cl sets different default warnings than clang. It also treats -Wall
+    # as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall.
+    # See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116
+    list(APPEND C_CXX_WARNINGS -W3 -Wno-unused-parameter)
+  else()
+    list(APPEND C_CXX_WARNINGS -Wall)
+  endif()
+
+  if(CLANG)
+    list(APPEND C_CXX_WARNINGS -Wnewline-eof -Wextra-semi -fcolor-diagnostics)
+  else()
+    list(APPEND C_CXX_WARNINGS -Wformat-signedness)
+    # GCC (at least 4.8.4) has a bug where it'll find unreachable free() calls
+    # and declare that the code is trying to free a stack pointer.
+    list(APPEND C_CXX_WARNINGS -Wno-free-nonheap-object)
+  endif()
+
+  # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes
+  # and using the wrong one is an error. In Clang, -Wmissing-prototypes is the
+  # spelling for both and -Wmissing-declarations is some other warning.
+  #
+  # https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Warning-Options.html#Warning-Options
+  # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-prototypes
+  # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-declarations
+  if(CLANG)
+    list(APPEND C_CXX_WARNINGS -Wmissing-prototypes)
+  else()
+    list(APPEND C_WARNINGS -Wmissing-prototypes)
+    list(APPEND CXX_WARNINGS -Wmissing-declarations)
+  endif()
+
+  # -Wstring-concatenation was added in Clang 12.0.0, which corresponds to
+  # AppleClang 13.0.0 per the table in
+  # https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
+  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0") OR
+     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0"))
+    list(APPEND C_CXX_WARNINGS -Wstring-concatenation)
+  endif()
+
+  # Clang 12's -Wframe-larger-than reportedly does not work in clang-cl. See
+  # https://crbug.com/boringssl/709. Clang 13 includes the following fix, which
+  # may be related. Speculatively gate on Clang 13. That corresponds to
+  # AppleClang 13.1.6.
+  # https://github.com/llvm/llvm-project/commit/6aaf4fa2885600b0e31042071ad06f78218ab0f2
+  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0") OR
+     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.1.6"))
+    list(APPEND C_CXX_WARNINGS -Wframe-larger-than=25344)
+  endif()
+
+  # -Wctad-maybe-unsupported was added in Clang 10, which is AppleClang 12.0.0.
+  if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0") OR
+     (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND
+      CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0"))
+    list(APPEND C_CXX_WARNINGS -Wctad-maybe-unsupported)
+  endif()
+
+  add_compile_options(
+    "$<$<COMPILE_LANGUAGE:C,CXX>:${C_CXX_WARNINGS}>"
+    "$<$<COMPILE_LANGUAGE:C>:${C_WARNINGS}>"
+    "$<$<COMPILE_LANGUAGE:CXX>:${CXX_WARNINGS}>"
+  )
+elseif(MSVC)
+  set(MSVC_DISABLED_WARNINGS_LIST
+      "-wd4100" # 'exarg' : unreferenced formal parameter
+      "-wd4127" # conditional expression is constant
+      "-wd4244" # 'function' : conversion from 'int' to 'uint8_t',
+                # possible loss of data
+      "-wd4267" # conversion from 'size_t' to 'int', possible loss of data
+      "-wd4702" # unreachable code; MSVC's warning is too aggressive. See
+                # https://crbug.com/385161043
+      "-wd4706" # assignment within conditional expression
+      )
+  add_compile_options(
+    "$<$<COMPILE_LANGUAGE:C,CXX>:-W4;-WX;${MSVC_DISABLED_WARNINGS_LIST}>")
 endif()
 
 if(OPENSSL_ASM)
@@ -636,12 +667,6 @@
   target_link_libraries(crypto Threads::Threads)
 endif()
 
-# Every target depends on crypto, so we add libcxx as a dependency here to
-# simplify injecting it everywhere.
-if(USE_CUSTOM_LIBCXX)
-  target_link_libraries(crypto libcxx)
-endif()
-
 add_library(ssl ${SSL_SOURCES})
 # Although libssl also provides headers that require an include directory, the
 # flag is already specified by libcrypto, so we omit target_include_directories
@@ -672,6 +697,13 @@
   endif()
   target_link_libraries(test_support_lib boringssl_gtest crypto)
 
+  # Declare a dummy target to build all unit tests. Test targets should inject
+  # themselves as dependencies next to the target definition.
+  add_custom_target(boringssl_all_tests)
+
+  # TODO(crbug.com/42290412): Drive this build with build.json and flatten.
+  add_subdirectory(ssl/test)
+
   # urandom_test is a separate binary because it needs to be able to observe the
   # PRNG initialisation, which means that it can't have other tests running before
   # it does.
@@ -714,17 +746,7 @@
 target_link_libraries(bssl ssl crypto)
 
 if(FUZZ)
-  if(LIBFUZZER_FROM_DEPS)
-    file(GLOB LIBFUZZER_SOURCES "util/bot/libFuzzer/*.cpp")
-    add_library(Fuzzer STATIC ${LIBFUZZER_SOURCES})
-    # libFuzzer does not pass our aggressive warnings. It also must be built
-    # without -fsanitize-coverage options or clang crashes.
-    set_target_properties(
-      Fuzzer PROPERTIES
-      COMPILE_FLAGS "-Wno-shadow -Wno-format-nonliteral -Wno-missing-prototypes -fsanitize-coverage=0"
-    )
-  endif()
-
+  # TODO(crbug.com/42290412): Drive this build with build.json and flatten.
   add_subdirectory(fuzz)
 endif()
 
diff --git a/crypto/cipher/e_tls.cc b/crypto/cipher/e_tls.cc
index f6c8241..b0f3ab3 100644
--- a/crypto/cipher/e_tls.cc
+++ b/crypto/cipher/e_tls.cc
@@ -102,18 +102,14 @@
                                const size_t extra_in_len) {
   assert(extra_in_len == 0);
   const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
 
   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;
+  assert(block_size == 8 /*3DES*/ || block_size == 16 /*AES*/);
+  const size_t pad_len = block_size - ((in_len + hmac_len) & (block_size - 1));
   return hmac_len + pad_len;
 }
 
@@ -167,8 +163,8 @@
   }
 
   // Configure the explicit IV.
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      !tls_ctx->implicit_iv &&
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
+  if (!tls_ctx->implicit_iv &&
       !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
                           nonce)) {
     return 0;
@@ -182,13 +178,13 @@
   }
 
   unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
+  assert(block_size == 8 /*3DES*/ || block_size == 16 /*AES*/);
 
   // Feed the MAC into the cipher in two steps. First complete the final partial
   // block from encrypting the input and split the result between |out| and
   // |out_tag|. Then feed the rest.
 
-  const 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 - 1);
   if (early_mac_len != 0) {
     assert(len + block_size - early_mac_len == in_len);
     uint8_t buf[EVP_MAX_BLOCK_LENGTH];
@@ -210,21 +206,15 @@
   }
   tag_len += len;
 
-  if (block_size > 1) {
-    assert(block_size <= 256);
-    assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
-
-    // Compute padding and feed that into the cipher.
-    uint8_t padding[256];
-    unsigned padding_len = block_size - ((in_len + mac_len) % block_size);
-    OPENSSL_memset(padding, padding_len - 1, padding_len);
-    if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
-                              max_out_tag_len - tag_len, padding,
-                              padding_len)) {
-      return 0;
-    }
-    tag_len += len;
+  // Compute padding and feed that into the cipher.
+  uint8_t padding[256];
+  unsigned padding_len = block_size - ((in_len + mac_len) & (block_size - 1));
+  OPENSSL_memset(padding, padding_len - 1, padding_len);
+  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
+                            max_out_tag_len - tag_len, padding, padding_len)) {
+    return 0;
   }
+  tag_len += len;
 
   if (!EVP_EncryptFinal_ex2(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
                             max_out_tag_len - tag_len)) {
@@ -272,8 +262,8 @@
   }
 
   // Configure the explicit IV.
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      !tls_ctx->implicit_iv &&
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
+  if (!tls_ctx->implicit_iv &&
       !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
                           nonce)) {
     return 0;
@@ -300,21 +290,13 @@
   // |padding_ok| and |data_plus_mac_len| for CBC ciphers.
   size_t data_plus_mac_len;
   crypto_word_t padding_ok;
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
-    if (!EVP_tls_cbc_remove_padding(
-            &padding_ok, &data_plus_mac_len, out, total,
-            EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
-            HMAC_size(tls_ctx->hmac_ctx))) {
-      // Publicly invalid. This can be rejected in non-constant time.
-      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
-      return 0;
-    }
-  } else {
-    padding_ok = CONSTTIME_TRUE_W;
-    data_plus_mac_len = total;
-    // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has
-    // already been checked against the MAC size at the top of the function.
-    assert(data_plus_mac_len >= HMAC_size(tls_ctx->hmac_ctx));
+  if (!EVP_tls_cbc_remove_padding(
+          &padding_ok, &data_plus_mac_len, out, total,
+          EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
+          HMAC_size(tls_ctx->hmac_ctx))) {
+    // Publicly invalid. This can be rejected in non-constant time.
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
+    return 0;
   }
   size_t data_len = data_plus_mac_len - HMAC_size(tls_ctx->hmac_ctx);
 
@@ -333,37 +315,17 @@
   // Compute the MAC and extract the one in the record.
   uint8_t mac[EVP_MAX_MD_SIZE];
   size_t mac_len;
-  uint8_t record_mac_tmp[EVP_MAX_MD_SIZE];
-  uint8_t *record_mac;
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md)) {
-    if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len,
-                                   ad_fixed, out, data_len, total,
-                                   tls_ctx->mac_key, tls_ctx->mac_key_len)) {
-      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
-      return 0;
-    }
-    assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
-
-    record_mac = record_mac_tmp;
-    EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
-  } else {
-    // We should support the constant-time path for all CBC-mode ciphers
-    // implemented.
-    assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
-
-    unsigned mac_len_u;
-    if (!HMAC_Init_ex(tls_ctx->hmac_ctx, nullptr, 0, nullptr, nullptr) ||
-        !HMAC_Update(tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
-        !HMAC_Update(tls_ctx->hmac_ctx, out, data_len) ||
-        !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len_u)) {
-      return 0;
-    }
-    mac_len = mac_len_u;
-
-    assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
-    record_mac = &out[data_len];
+  assert(EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md));
+  if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len, ad_fixed,
+                                 out, data_len, total, tls_ctx->mac_key,
+                                 tls_ctx->mac_key_len)) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
+    return 0;
   }
+  assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
+
+  uint8_t record_mac[EVP_MAX_MD_SIZE];
+  EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
 
   // Perform the MAC check and the padding check in constant-time. It should be
   // safe to simply perform the padding check first, but it would not be under a
diff --git a/crypto/fipsmodule/self_check/self_check.cc.inc b/crypto/fipsmodule/self_check/self_check.cc.inc
index 13b4e13..300c892 100644
--- a/crypto/fipsmodule/self_check/self_check.cc.inc
+++ b/crypto/fipsmodule/self_check/self_check.cc.inc
@@ -68,14 +68,6 @@
   return 1;
 }
 
-// MSVC wants to put a NUL byte at the end of non-char arrays and so cannot
-// compile the real logic.
-#if defined(_MSC_VER)
-
-int BORINGSSL_self_test(void) { return 0; }
-
-#else
-
 static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) {
   *out = BN_bin2bn(in, len, nullptr);
   return *out != nullptr;
@@ -1060,5 +1052,3 @@
 #if defined(BORINGSSL_FIPS)
 int boringssl_self_test_startup(void) { return boringssl_self_test_fast(); }
 #endif
-
-#endif  // !_MSC_VER
diff --git a/crypto/self_test.cc b/crypto/self_test.cc
index 231fd62..f985fa6 100644
--- a/crypto/self_test.cc
+++ b/crypto/self_test.cc
@@ -18,7 +18,5 @@
 
 
 TEST(SelfTests, KAT) {
-#if !defined(_MSC_VER)
   EXPECT_TRUE(BORINGSSL_self_test());
-#endif
 }
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg
index 1fc09f6..c8b8361 100644
--- a/infra/config/generated/commit-queue.cfg
+++ b/infra/config/generated/commit-queue.cfg
@@ -185,6 +185,7 @@
       }
       builders {
         name: "boringssl/try/mac_arm64_bazel"
+        includable_only: true
       }
       builders {
         name: "boringssl/try/mac_rel"
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index c1554c8..39e2875 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -21,7 +21,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -45,7 +45,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -69,7 +69,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -93,7 +93,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -117,7 +117,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -141,7 +141,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -165,7 +165,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -189,7 +189,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -213,7 +213,7 @@
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
       }
       execution_timeout_secs: 3600
       caches {
@@ -1173,7 +1173,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
-        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_SMALL=1\"}"
+        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1\"}"
         properties_j: "msvc_target:\"x86\""
       }
       execution_timeout_secs: 1800
@@ -1320,7 +1320,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "$gatekeeper:{\"group\":\"client.boringssl\"}"
-        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_SMALL=1\"}"
+        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1\"}"
         properties_j: "msvc_target:\"x64\""
       }
       execution_timeout_secs: 1800
@@ -1429,7 +1429,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1445,7 +1445,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1462,7 +1462,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1478,7 +1478,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1495,7 +1495,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1511,7 +1511,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\",\"OPENSSL_NO_ASM\":\"1\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1528,7 +1528,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1544,7 +1544,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"FIPS\":\"1\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1561,7 +1561,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1577,7 +1577,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"arm64-v8a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1594,7 +1594,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1609,7 +1609,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1625,7 +1625,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_ARM_MODE\":\"arm\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1643,7 +1643,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1660,7 +1660,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1676,7 +1676,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"BUILD_SHARED_LIBS\":\"1\",\"FIPS\":\"1\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -1693,7 +1693,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
       }
       execution_timeout_secs: 3600
       service_account: "boringssl-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -1709,7 +1709,7 @@
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
         properties_j: "android:true"
-        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-21\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
+        properties_j: "cmake_args:{\"ANDROID_ABI\":\"armeabi-v7a\",\"ANDROID_PLATFORM\":\"android-24\",\"CMAKE_BUILD_TYPE\":\"Release\",\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_NO_STATIC_NEON_FOR_TESTING=1\"}"
         properties_j: "run_ssl_tests:false"
         properties_j: "run_unit_tests:false"
       }
@@ -2382,7 +2382,7 @@
         name: "boringssl"
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
-        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_SMALL=1\"}"
+        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1\"}"
         properties_j: "msvc_target:\"x86\""
       }
       execution_timeout_secs: 1800
@@ -2527,7 +2527,7 @@
         name: "boringssl"
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
-        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"-DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"-DOPENSSL_SMALL=1\"}"
+        properties_j: "cmake_args:{\"CMAKE_CXX_FLAGS\":\"/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1\",\"CMAKE_C_FLAGS\":\"/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1\"}"
         properties_j: "msvc_target:\"x64\""
       }
       execution_timeout_secs: 1800
diff --git a/infra/config/generated/project.cfg b/infra/config/generated/project.cfg
index be39cc9..3b1ab2e 100644
--- a/infra/config/generated/project.cfg
+++ b/infra/config/generated/project.cfg
@@ -7,7 +7,7 @@
 name: "boringssl"
 access: "group:all"
 lucicfg {
-  version: "1.46.0"
+  version: "1.46.1"
   package_dir: ".."
   config_dir: "generated"
   entry_point: "main.star"
diff --git a/infra/config/main.star b/infra/config/main.star
index baebc91..dccedd4 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -356,7 +356,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "arm64-v8a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
         },
     },
 )
@@ -371,7 +371,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "arm64-v8a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             "CMAKE_BUILD_TYPE": "Release",
         },
     },
@@ -387,7 +387,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "arm64-v8a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             # FIPS mode on Android uses shared libraries.
             "BUILD_SHARED_LIBS": "1",
             "FIPS": "1",
@@ -407,7 +407,7 @@
         "cmake_args": {
             "OPENSSL_NO_ASM": "1",
             "ANDROID_ABI": "arm64-v8a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             # FIPS mode on Android uses shared libraries.
             "BUILD_SHARED_LIBS": "1",
             "FIPS": "1",
@@ -429,7 +429,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "arm64-v8a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             "FIPS": "1",
         },
     },
@@ -445,7 +445,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "armeabi-v7a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
         },
     },
 )
@@ -460,7 +460,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "armeabi-v7a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             "CMAKE_BUILD_TYPE": "Release",
             # Although Android now requires NEON support, on one builder, we
             # ignore the |__ARM_NEON| preprocessor option, to keep testing
@@ -482,7 +482,7 @@
         "android": True,
         "cmake_args": {
             "ANDROID_ABI": "armeabi-v7a",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             # FIPS mode on Android uses shared libraries.
             "BUILD_SHARED_LIBS": "1",
             "FIPS": "1",
@@ -500,7 +500,7 @@
         "cmake_args": {
             "ANDROID_ABI": "armeabi-v7a",
             "ANDROID_ARM_MODE": "arm",
-            "ANDROID_PLATFORM": "android-21",
+            "ANDROID_PLATFORM": "android-24",
             "CMAKE_BUILD_TYPE": "Release",
         },
     },
@@ -940,6 +940,8 @@
     category = "mac",
     short_name = "bzl",
     recipe = "boringssl_bazel",
+    # TODO(crbug.com/463446310): Re-enable once the builder is fixed.
+    cq_enabled = False,
 )
 both_builders(
     "win32",
@@ -986,8 +988,12 @@
     short_name = "sm",
     properties = {
         "cmake_args": {
-            "CMAKE_C_FLAGS": "-DOPENSSL_SMALL=1",
-            "CMAKE_CXX_FLAGS": "-DOPENSSL_SMALL=1",
+            # Setting CMAKE_${LANG}_FLAGS this way overrides CMake's default
+            # toolchain-level flags, so we must respecify them.
+            # TODO(davidben): Should we be specify flags differently? C(XX)FLAGS
+            # environment variable or a CMake-level OPENSSL_SMALL toggle?
+            "CMAKE_C_FLAGS": "/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1",
+            "CMAKE_CXX_FLAGS": "/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1",
         },
         "msvc_target": "x86",
     },
@@ -1063,8 +1069,12 @@
     short_name = "sm",
     properties = {
         "cmake_args": {
-            "CMAKE_C_FLAGS": "-DOPENSSL_SMALL=1",
-            "CMAKE_CXX_FLAGS": "-DOPENSSL_SMALL=1",
+            # Setting CMAKE_${LANG}_FLAGS this way overrides CMake's default
+            # toolchain-level flags, so we must respecify them.
+            # TODO(davidben): Should we be specify flags differently? C(XX)FLAGS
+            # environment variable or a CMake-level OPENSSL_SMALL toggle?
+            "CMAKE_C_FLAGS": "/DWIN32 /D_WINDOWS /DOPENSSL_SMALL=1",
+            "CMAKE_CXX_FLAGS": "/DWIN32 /D_WINDOWS /EHsc /DOPENSSL_SMALL=1",
         },
         "msvc_target": "x64",
     },