Use a smaller hex digest in FIPS flag files when SHA-256 used.

1458b49a9e5 switched to using HMAC-SHA256 for FIPS integrity checks on
Android. However, the flag file was named after a full 64-byte hex
digest. The additional 32 bytes weren't uninitialised, but are still
superfluous. This change gets rid of them.

Change-Id: I192af9eb2b94833cdea3620a153d4fd05c7265b9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/37864
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index c9e4ef3..f3f66f4 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -136,8 +136,6 @@
 static void BORINGSSL_maybe_set_module_text_permissions(int permission) {}
 #endif  // !ANDROID
 
-#else
-static const uint8_t BORINGSSL_bcm_text_hash[SHA512_DIGEST_LENGTH] = {0};
 #endif  // !ASAN
 
 static void __attribute__((constructor))
@@ -198,11 +196,15 @@
   if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) {
     goto err;
   }
-#endif
 
-  if (!BORINGSSL_self_test(BORINGSSL_bcm_text_hash)) {
+  if (!boringssl_fips_self_test(BORINGSSL_bcm_text_hash, sizeof(result))) {
     goto err;
   }
+#else
+  if (!BORINGSSL_self_test()) {
+    goto err;
+  }
+#endif  // OPENSSL_ASAN
 
   return;
 
diff --git a/crypto/fipsmodule/self_check/self_check.c b/crypto/fipsmodule/self_check/self_check.c
index 71d1c18..8a9e16b 100644
--- a/crypto/fipsmodule/self_check/self_check.c
+++ b/crypto/fipsmodule/self_check/self_check.c
@@ -243,27 +243,39 @@
   return ec_key;
 }
 
-int BORINGSSL_self_test(
-    const uint8_t module_sha512_hash[SHA512_DIGEST_LENGTH]) {
-#if defined(BORINGSSL_FIPS_SELF_TEST_FLAG_FILE)
-  // Test whether the flag file exists.
-  char flag_path[sizeof(kFlagPrefix) + 2*SHA512_DIGEST_LENGTH];
-  memcpy(flag_path, kFlagPrefix, sizeof(kFlagPrefix) - 1);
-  static const char kHexTable[17] = "0123456789abcdef";
-  uint8_t module_hash_sum = 0;
-  for (size_t i = 0; i < SHA512_DIGEST_LENGTH; i++) {
-    module_hash_sum |= module_sha512_hash[i];
-    flag_path[sizeof(kFlagPrefix) - 1 + 2 * i] =
-        kHexTable[module_sha512_hash[i] >> 4];
-    flag_path[sizeof(kFlagPrefix) - 1 + 2 * i + 1] =
-        kHexTable[module_sha512_hash[i] & 15];
-  }
-  flag_path[sizeof(flag_path) - 1] = 0;
+#if defined(OPENSSL_ANDROID)
+static const size_t kModuleDigestSize = SHA256_DIGEST_LENGTH;
+#else
+static const size_t kModuleDigestSize = SHA512_DIGEST_LENGTH;
+#endif
 
-  const int flag_path_valid = (module_hash_sum != 0);
-  if (flag_path_valid && access(flag_path, F_OK) == 0) {
-    // Flag file found. Skip self-tests.
-    return 1;
+int boringssl_fips_self_test(
+    const uint8_t module_hash[kModuleDigestSize], size_t module_hash_len) {
+#if defined(BORINGSSL_FIPS_SELF_TEST_FLAG_FILE)
+  char flag_path[sizeof(kFlagPrefix) + 2*kModuleDigestSize];
+  if (module_hash_len != 0) {
+    if (module_hash_len != kModuleDigestSize) {
+      fprintf(stderr,
+              "module hash of length %zu does not match expected length %zu\n",
+              module_hash_len, kModuleDigestSize);
+      BORINGSSL_FIPS_abort();
+    }
+
+    // Test whether the flag file exists.
+    memcpy(flag_path, kFlagPrefix, sizeof(kFlagPrefix) - 1);
+    static const char kHexTable[17] = "0123456789abcdef";
+    for (size_t i = 0; i < kModuleDigestSize; i++) {
+      flag_path[sizeof(kFlagPrefix) - 1 + 2 * i] =
+          kHexTable[module_hash[i] >> 4];
+      flag_path[sizeof(kFlagPrefix) - 1 + 2 * i + 1] =
+          kHexTable[module_hash[i] & 15];
+    }
+    flag_path[sizeof(flag_path) - 1] = 0;
+
+    if (access(flag_path, F_OK) == 0) {
+      // Flag file found. Skip self-tests.
+      return 1;
+    }
   }
 #endif // BORINGSSL_FIPS_SELF_TEST_FLAG_FILE
 
@@ -618,7 +630,7 @@
 
 #if defined(BORINGSSL_FIPS_SELF_TEST_FLAG_FILE)
   // Tests were successful. Write flag file if requested.
-  if (flag_path_valid && getenv(kFlagWriteEnableEnvVar) != NULL) {
+  if (module_hash_len != 0 && getenv(kFlagWriteEnableEnvVar) != NULL) {
     const int fd = open(flag_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
     if (fd >= 0) {
       close(fd);
@@ -635,4 +647,8 @@
   return ret;
 }
 
+int BORINGSSL_self_test(void) {
+  return boringssl_fips_self_test(NULL, 0);
+}
+
 #endif  // !_MSC_VER
diff --git a/crypto/internal.h b/crypto/internal.h
index 4772ebe..1fba5b6 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -798,6 +798,15 @@
 void BORINGSSL_FIPS_abort(void) __attribute__((noreturn));
 #endif
 
+// boringssl_fips_self_test runs the FIPS KAT-based self tests. It returns one
+// on success and zero on error. The argument is the integrity hash of the FIPS
+// module and may be used to check and write flag files to suppress duplicate
+// self-tests. If |module_hash_len| is zero then no flag file will be checked
+// nor written and tests will always be run.
+int boringssl_fips_self_test(const uint8_t *module_hash,
+                             size_t module_hash_len);
+
+
 #if defined(__cplusplus)
 }  // extern C
 #endif
diff --git a/crypto/self_test.cc b/crypto/self_test.cc
index b0c769d..c20b5de 100644
--- a/crypto/self_test.cc
+++ b/crypto/self_test.cc
@@ -19,7 +19,6 @@
 
 TEST(SelfTests, KAT) {
 #if !defined(_MSC_VER)
-  const uint8_t zero_hash[SHA512_DIGEST_LENGTH] = {0};
-  EXPECT_TRUE(BORINGSSL_self_test(zero_hash));
+  EXPECT_TRUE(BORINGSSL_self_test());
 #endif
 }
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index b9d8449..6aa661a 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -64,8 +64,7 @@
 // module and may be used to check and write flag files to suppress duplicate
 // self-tests. If it is all zeros, no flag file will be checked nor written and
 // tests will always be run.
-OPENSSL_EXPORT int BORINGSSL_self_test(
-    const uint8_t module_sha512_hash[SHA512_DIGEST_LENGTH]);
+OPENSSL_EXPORT int BORINGSSL_self_test(void);
 
 
 // Deprecated functions.