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.