external/boringssl: Sync to 689019fe40d5ad94df46ffeebcd794ff359a7074.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/67e64342c1aa0b31b0b5c11e5ee21c481ce530e8..689019fe40d5ad94df46ffeebcd794ff359a7074

Test: BoringSSL CTS Presubmits
Change-Id: Ib675c5478b0e45270e31248d1dadc5f4841da990
diff --git a/src/crypto/cpu-arm-linux.c b/src/crypto/cpu-arm-linux.c
index 839b632..91078bd 100644
--- a/src/crypto/cpu-arm-linux.c
+++ b/src/crypto/cpu-arm-linux.c
@@ -14,33 +14,171 @@
 
 #include <openssl/cpu.h>
 
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP)
+#include "cpu-arm-linux.h"
+#include "internal.h"
 
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP)
 #include <errno.h>
 #include <fcntl.h>
-#include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <openssl/arm_arch.h>
 #include <openssl/buf.h>
 #include <openssl/mem.h>
+#endif
 
-#include "internal.h"
 
+// The following functions are only used in ARM, but they are defined on all
+// platforms for testing and fuzzing purposes.
+
+static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) {
+  size_t b_len = strlen(b);
+  return a->len == b_len && OPENSSL_memcmp(a->data, b, b_len) == 0;
+}
+
+// STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found,
+// sets |*out_left| and |*out_right| to |in| split before and after it. It
+// returns one if |sep| was found and zero otherwise.
+static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right,
+                              const STRING_PIECE *in, char sep) {
+  const char *p = OPENSSL_memchr(in->data, sep, in->len);
+  if (p == NULL) {
+    return 0;
+  }
+  // |out_left| or |out_right| may alias |in|, so make a copy.
+  STRING_PIECE in_copy = *in;
+  out_left->data = in_copy.data;
+  out_left->len = p - in_copy.data;
+  out_right->data = in_copy.data + out_left->len + 1;
+  out_right->len = in_copy.len - out_left->len - 1;
+  return 1;
+}
+
+// STRING_PIECE_get_delimited reads a |sep|-delimited entry from |s|, writing it
+// to |out| and updating |s| to point beyond it. It returns one on success and
+// zero if |s| is empty. If |s| is has no copies of |sep| and is non-empty, it
+// reads the entire string to |out|.
+static int STRING_PIECE_get_delimited(STRING_PIECE *s, STRING_PIECE *out, char sep) {
+  if (s->len == 0) {
+    return 0;
+  }
+  if (!STRING_PIECE_split(out, s, s, sep)) {
+    // |s| had no instances of |sep|. Return the entire string.
+    *out = *s;
+    s->data += s->len;
+    s->len = 0;
+  }
+  return 1;
+}
+
+// STRING_PIECE_trim removes leading and trailing whitespace from |s|.
+static void STRING_PIECE_trim(STRING_PIECE *s) {
+  while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) {
+    s->data++;
+    s->len--;
+  }
+  while (s->len != 0 &&
+         (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) {
+    s->len--;
+  }
+}
+
+// extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from
+// |in|. If found, it sets |*out| to the value and returns one. Otherwise, it
+// returns zero.
+static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in,
+                                 const char *field) {
+  // Process |in| one line at a time.
+  STRING_PIECE remaining = *in, line;
+  while (STRING_PIECE_get_delimited(&remaining, &line, '\n')) {
+    STRING_PIECE key, value;
+    if (!STRING_PIECE_split(&key, &value, &line, ':')) {
+      continue;
+    }
+    STRING_PIECE_trim(&key);
+    if (STRING_PIECE_equals(&key, field)) {
+      STRING_PIECE_trim(&value);
+      *out = value;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field,
+                                const char *value) {
+  STRING_PIECE extracted;
+  return extract_cpuinfo_field(&extracted, cpuinfo, field) &&
+         STRING_PIECE_equals(&extracted, value);
+}
+
+// has_list_item treats |list| as a space-separated list of items and returns
+// one if |item| is contained in |list| and zero otherwise.
+static int has_list_item(const STRING_PIECE *list, const char *item) {
+  STRING_PIECE remaining = *list, feature;
+  while (STRING_PIECE_get_delimited(&remaining, &feature, ' ')) {
+    if (STRING_PIECE_equals(&feature, item)) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+unsigned long crypto_get_arm_hwcap_from_cpuinfo(const STRING_PIECE *cpuinfo) {
+  if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) {
+    // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always
+    // available on ARMv8. Linux omits required features, so reading the
+    // "Features" line does not work. (For simplicity, use strict equality. We
+    // assume everything running on future ARM architectures will have a
+    // working |getauxval|.)
+    return HWCAP_NEON;
+  }
+
+  STRING_PIECE features;
+  if (extract_cpuinfo_field(&features, cpuinfo, "Features") &&
+      has_list_item(&features, "neon")) {
+    return HWCAP_NEON;
+  }
+  return 0;
+}
+
+unsigned long crypto_get_arm_hwcap2_from_cpuinfo(const STRING_PIECE *cpuinfo) {
+  STRING_PIECE features;
+  if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) {
+    return 0;
+  }
+
+  unsigned long ret = 0;
+  if (has_list_item(&features, "aes")) {
+    ret |= HWCAP2_AES;
+  }
+  if (has_list_item(&features, "pmull")) {
+    ret |= HWCAP2_PMULL;
+  }
+  if (has_list_item(&features, "sha1")) {
+    ret |= HWCAP2_SHA1;
+  }
+  if (has_list_item(&features, "sha2")) {
+    ret |= HWCAP2_SHA2;
+  }
+  return ret;
+}
+
+int crypto_cpuinfo_has_broken_neon(const STRING_PIECE *cpuinfo) {
+  return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") &&
+         cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") &&
+         cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") &&
+         cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") &&
+         cpuinfo_field_equals(cpuinfo, "CPU revision", "0");
+}
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP)
 
 #define AT_HWCAP 16
 #define AT_HWCAP2 26
 
-#define HWCAP_NEON (1 << 12)
-
-// See /usr/include/asm/hwcap.h on an ARM installation for the source of
-// these values.
-#define HWCAP2_AES (1 << 0)
-#define HWCAP2_PMULL (1 << 1)
-#define HWCAP2_SHA1 (1 << 2)
-#define HWCAP2_SHA2 (1 << 3)
-
 // |getauxval| is not available on Android until API level 20. Link it as a weak
 // symbol and use other methods as fallback.
 unsigned long getauxval(unsigned long type) __attribute__((weak));
@@ -154,138 +292,6 @@
   return 0;
 }
 
-typedef struct {
-  const char *data;
-  size_t len;
-} STRING_PIECE;
-
-static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) {
-  size_t b_len = strlen(b);
-  return a->len == b_len && OPENSSL_memcmp(a->data, b, b_len) == 0;
-}
-
-// STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found,
-// sets |*out_left| and |*out_right| to |in| split before and after it. It
-// returns one if |sep| was found and zero otherwise.
-static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right,
-                              const STRING_PIECE *in, char sep) {
-  const char *p = OPENSSL_memchr(in->data, sep, in->len);
-  if (p == NULL) {
-    return 0;
-  }
-  // |out_left| or |out_right| may alias |in|, so make a copy.
-  STRING_PIECE in_copy = *in;
-  out_left->data = in_copy.data;
-  out_left->len = p - in_copy.data;
-  out_right->data = in_copy.data + out_left->len + 1;
-  out_right->len = in_copy.len - out_left->len - 1;
-  return 1;
-}
-
-// STRING_PIECE_trim removes leading and trailing whitespace from |s|.
-static void STRING_PIECE_trim(STRING_PIECE *s) {
-  while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) {
-    s->data++;
-    s->len--;
-  }
-  while (s->len != 0 &&
-         (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) {
-    s->len--;
-  }
-}
-
-// extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from
-// |in|.  If found, it sets |*out| to the value and returns one. Otherwise, it
-// returns zero.
-static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in,
-                                 const char *field) {
-  // Process |in| one line at a time.
-  STRING_PIECE remaining = *in, line;
-  while (STRING_PIECE_split(&line, &remaining, &remaining, '\n')) {
-    STRING_PIECE key, value;
-    if (!STRING_PIECE_split(&key, &value, &line, ':')) {
-      continue;
-    }
-    STRING_PIECE_trim(&key);
-    if (STRING_PIECE_equals(&key, field)) {
-      STRING_PIECE_trim(&value);
-      *out = value;
-      return 1;
-    }
-  }
-
-  return 0;
-}
-
-static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field,
-                                const char *value) {
-  STRING_PIECE extracted;
-  return extract_cpuinfo_field(&extracted, cpuinfo, field) &&
-         STRING_PIECE_equals(&extracted, value);
-}
-
-// has_list_item treats |list| as a space-separated list of items and returns
-// one if |item| is contained in |list| and zero otherwise.
-static int has_list_item(const STRING_PIECE *list, const char *item) {
-  STRING_PIECE remaining = *list, feature;
-  while (STRING_PIECE_split(&feature, &remaining, &remaining, ' ')) {
-    if (STRING_PIECE_equals(&feature, item)) {
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) {
-  if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) {
-    // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always
-    // available on ARMv8. Linux omits required features, so reading the
-    // "Features" line does not work. (For simplicity, use strict equality. We
-    // assume everything running on future ARM architectures will have a
-    // working |getauxval|.)
-    return HWCAP_NEON;
-  }
-
-  STRING_PIECE features;
-  if (extract_cpuinfo_field(&features, cpuinfo, "Features") &&
-      has_list_item(&features, "neon")) {
-    return HWCAP_NEON;
-  }
-  return 0;
-}
-
-static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) {
-  STRING_PIECE features;
-  if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) {
-    return 0;
-  }
-
-  unsigned long ret = 0;
-  if (has_list_item(&features, "aes")) {
-    ret |= HWCAP2_AES;
-  }
-  if (has_list_item(&features, "pmull")) {
-    ret |= HWCAP2_PMULL;
-  }
-  if (has_list_item(&features, "sha1")) {
-    ret |= HWCAP2_SHA1;
-  }
-  if (has_list_item(&features, "sha2")) {
-    ret |= HWCAP2_SHA2;
-  }
-  return ret;
-}
-
-// has_broken_neon returns one if |in| matches a CPU known to have a broken
-// NEON unit. See https://crbug.com/341598.
-static int has_broken_neon(const STRING_PIECE *cpuinfo) {
-  return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") &&
-         cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") &&
-         cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") &&
-         cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") &&
-         cpuinfo_field_equals(cpuinfo, "CPU revision", "0");
-}
-
 extern uint32_t OPENSSL_armcap_P;
 
 static int g_has_broken_neon, g_needs_hwcap2_workaround;
@@ -315,11 +321,11 @@
     hwcap = getauxval_proc(AT_HWCAP);
   }
   if (hwcap == 0) {
-    hwcap = get_hwcap_cpuinfo(&cpuinfo);
+    hwcap = crypto_get_arm_hwcap_from_cpuinfo(&cpuinfo);
   }
 
   // Clear NEON support if known broken.
-  g_has_broken_neon = has_broken_neon(&cpuinfo);
+  g_has_broken_neon = crypto_cpuinfo_has_broken_neon(&cpuinfo);
   if (g_has_broken_neon) {
     hwcap &= ~HWCAP_NEON;
   }
@@ -335,7 +341,7 @@
       hwcap2 = getauxval(AT_HWCAP2);
     }
     if (hwcap2 == 0) {
-      hwcap2 = get_hwcap2_cpuinfo(&cpuinfo);
+      hwcap2 = crypto_get_arm_hwcap2_from_cpuinfo(&cpuinfo);
       g_needs_hwcap2_workaround = hwcap2 != 0;
     }