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.