Skip to content

Commit

Permalink
Allow the FIPS integrity test to be run on demand (#489)
Browse files Browse the repository at this point in the history
Allow the FIPS integrity test to be run on demand (FIPS 140-3 requirement).
  • Loading branch information
dkostic authored May 19, 2022
1 parent 7fcfea8 commit 67a2c4a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 20 deletions.
7 changes: 7 additions & 0 deletions crypto/crypto_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,10 @@ TEST(CryptoTest, FIPSdownstreamPrecompilationFlag) {
#endif
}
#endif // defined(BORINGSSL_FIPS)

#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN)
TEST(Crypto, OnDemandIntegrityTest) {
BORINGSSL_integrity_test();
}
#endif

46 changes: 26 additions & 20 deletions crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,29 @@ BORINGSSL_bcm_power_on_self_test(void) {
goto err;
}

// Per FIPS 140-3 we have to perform the CAST of the HMAC used for integrity
// check before the integrity check itself. So we first call the self-test
// before we calculate the hash of the module.
if (!boringssl_fips_self_test()) {
goto err;
}

#if !defined(OPENSSL_ASAN)
// Integrity tests cannot run under ASAN because it involves reading the full
// .text section, which triggers the global-buffer overflow detection.
if (!BORINGSSL_integrity_test()) {
goto err;
}
#endif // OPENSSL_ASAN

return;

err:
BORINGSSL_FIPS_abort();
}

#if !defined(OPENSSL_ASAN)
int BORINGSSL_integrity_test(void) {
const uint8_t *const start = BORINGSSL_bcm_text_start;
const uint8_t *const end = BORINGSSL_bcm_text_end;

Expand All @@ -219,13 +239,6 @@ BORINGSSL_bcm_power_on_self_test(void) {
assert_within(rodata_start, kP256Params, rodata_end);
assert_within(rodata_start, kPKCS1SigPrefixes, rodata_end);

// Per FIPS 140-3 we have to perform the CAST of the HMAC used for integrity
// check before the integrity check itself. So we first call the self-test
// before we calculate the hash of the module.
if (!boringssl_fips_self_test()) {
goto err;
}

uint8_t result[SHA256_DIGEST_LENGTH];
const EVP_MD *const kHashFunction = EVP_sha256();

Expand All @@ -236,7 +249,7 @@ BORINGSSL_bcm_power_on_self_test(void) {
if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), kHashFunction,
NULL /* no ENGINE */)) {
fprintf(stderr, "HMAC_Init_ex failed.\n");
goto err;
return 0;
}

BORINGSSL_maybe_set_module_text_permissions(PROT_READ | PROT_EXEC);
Expand All @@ -256,27 +269,20 @@ BORINGSSL_bcm_power_on_self_test(void) {
if (!HMAC_Final(&hmac_ctx, result, &result_len) ||
result_len != sizeof(result)) {
fprintf(stderr, "HMAC failed.\n");
goto err;
return 0;
}
HMAC_CTX_cleanup(&hmac_ctx);

const uint8_t *expected = BORINGSSL_bcm_text_hash;

if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) {
goto err;
}

#else
if (!BORINGSSL_self_test()) {
goto err;
return 0;
}
#endif // OPENSSL_ASAN

return;

err:
BORINGSSL_FIPS_abort();
OPENSSL_cleanse(result, sizeof(result)); // FIPS 140-3, AS05.10.
return 1;
}
#endif // OPENSSL_ASAN

void BORINGSSL_FIPS_abort(void) {
for (;;) {
Expand Down
6 changes: 6 additions & 0 deletions include/openssl/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ OPENSSL_EXPORT int CRYPTO_has_asm(void);
// success and zero on error.
OPENSSL_EXPORT int BORINGSSL_self_test(void);

// BORINGSSL_integrity_test triggers the module's integrity test where the code
// and data of the module is matched against a hash injected at build time. It
// returns one on success or zero if there's a mismatch. This function only
// exists if the module was built in FIPS mode without ASAN.
OPENSSL_EXPORT int BORINGSSL_integrity_test(void);

// CRYPTO_pre_sandbox_init initializes the crypto library, pre-acquiring some
// unusual resources to aid running in sandboxed environments. It is safe to
// call this function multiple times and concurrently from multiple threads.
Expand Down

0 comments on commit 67a2c4a

Please sign in to comment.