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>
This commit is contained in:
Adam Langley 2019-10-01 10:01:25 -07:00 committed by CQ bot account: commit-bot@chromium.org
parent 1458b49a9e
commit 9638f8fba9
5 changed files with 54 additions and 29 deletions

View File

@ -136,8 +136,6 @@ static void BORINGSSL_maybe_set_module_text_permissions(int permission) {
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 @@ BORINGSSL_bcm_power_on_self_test(void) {
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;

View File

@ -243,27 +243,39 @@ static EC_KEY *self_test_ecdsa_key(void) {
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 @@ int BORINGSSL_self_test(
#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 @@ err:
return ret;
}
int BORINGSSL_self_test(void) {
return boringssl_fips_self_test(NULL, 0);
}
#endif // !_MSC_VER

View File

@ -798,6 +798,15 @@ static inline void *OPENSSL_memset(void *dst, int c, size_t n) {
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

View File

@ -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
}

View File

@ -64,8 +64,7 @@ OPENSSL_EXPORT int FIPS_mode(void);
// 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.