diff options
author | kste <kste@google.com> | 2021-04-16 08:25:15 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-04-16 08:25:45 -0700 |
commit | d0795b2b41a78eaa90a3243d55382625cd8c282d (patch) | |
tree | 55d790f1d08db7fb2a850924cf683637bed6a0b9 /cc/config | |
parent | 47b6e1783c8dc1eaed150632efd2ceb50f3f867c (diff) | |
download | tink-d0795b2b41a78eaa90a3243d55382625cd8c282d.tar.gz |
Add a function to enable FIPS restrictions at runtime in C++.
PiperOrigin-RevId: 368850964
Diffstat (limited to 'cc/config')
-rw-r--r-- | cc/config/BUILD.bazel | 5 | ||||
-rw-r--r-- | cc/config/tink_fips.cc | 4 | ||||
-rw-r--r-- | cc/config/tink_fips.h | 5 | ||||
-rw-r--r-- | cc/config/tink_fips_test.cc | 73 |
4 files changed, 85 insertions, 2 deletions
diff --git a/cc/config/BUILD.bazel b/cc/config/BUILD.bazel index 89f5445d9..a9dbd1435 100644 --- a/cc/config/BUILD.bazel +++ b/cc/config/BUILD.bazel @@ -107,7 +107,12 @@ cc_test( deps = [ ":tink_config", ":tink_fips", + "//:registry", + "//aead:aead_config", "//internal:fips_utils", + "//util:status", + "//util:test_matchers", + "@boringssl//:crypto", "@com_google_googletest//:gtest_main", ], ) diff --git a/cc/config/tink_fips.cc b/cc/config/tink_fips.cc index 61875c971..ecefa821a 100644 --- a/cc/config/tink_fips.cc +++ b/cc/config/tink_fips.cc @@ -27,5 +27,9 @@ bool IsFipsModeEnabled() { return internal::IsFipsModeEnabled(); } +crypto::tink::util::Status RestrictToFips() { + return internal::RegistryImpl::GlobalInstance().RestrictToFipsIfEmpty(); +} + } // namespace tink } // namespace crypto diff --git a/cc/config/tink_fips.h b/cc/config/tink_fips.h index 2cfef9c23..4c02b35c1 100644 --- a/cc/config/tink_fips.h +++ b/cc/config/tink_fips.h @@ -28,6 +28,11 @@ namespace tink { // the FIPS restrictions have been enabled at runtime. bool IsFipsModeEnabled(); +// Enables the FIPS restrictions for the registry and subtle primitives. If Tink +// has been built in FIPS this is redundant. This method must be called before +// handling any key material or calling any of the functions in subtle. +crypto::tink::util::Status RestrictToFips(); + } // namespace tink } // namespace crypto diff --git a/cc/config/tink_fips_test.cc b/cc/config/tink_fips_test.cc index 23d317e71..b611cb818 100644 --- a/cc/config/tink_fips_test.cc +++ b/cc/config/tink_fips_test.cc @@ -15,9 +15,14 @@ /////////////////////////////////////////////////////////////////////////////// #include "tink/config/tink_fips.h" -#include "tink/internal/fips_utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "openssl/crypto.h" +#include "tink/aead/aead_config.h" +#include "tink/internal/fips_utils.h" +#include "tink/registry.h" +#include "tink/util/status.h" +#include "tink/util/test_matchers.h" namespace crypto { namespace tink { @@ -25,8 +30,21 @@ namespace tink { namespace { using testing::Eq; +using ::crypto::tink::test::IsOk; +using ::crypto::tink::test::StatusIs; + +class FipsIncompatible { + public: + static constexpr crypto::tink::internal::FipsCompatibility kFipsStatus = + crypto::tink::internal::FipsCompatibility::kNotFips; +}; + +class FipsCompatibleWithBoringCrypto { + public: + static constexpr crypto::tink::internal::FipsCompatibility kFipsStatus = + crypto::tink::internal::FipsCompatibility::kRequiresBoringCrypto; +}; -// All tests in this file assume that Tink is not build in FIPS mode. TEST(TinkFipsTest, FipsEnabledWhenBuiltInFipsMode) { // Check if the built flag is set. if (!internal::kUseOnlyFips) { @@ -45,6 +63,57 @@ TEST(TinkFipsTest, FipsDisabledWhenNotBuildInFipsMode) { EXPECT_THAT(IsFipsModeEnabled(), Eq(false)); } +TEST(TinkFipsTest, CompatibilityChecksWithBoringCrypto) { + if (!FIPS_mode()) { + GTEST_SKIP() << "Test only run if BoringCrypto module is available."; + } + + // Tink is not build in FIPS mode, but the FIPS mode is enabled at runtime. + EXPECT_THAT(crypto::tink::RestrictToFips(), IsOk()); + + // In FIPS only mode compatibility checks should disallow algorithms + // with the FipsCompatibility::kNone flag. + EXPECT_THAT(internal::CheckFipsCompatibility<FipsIncompatible>(), + StatusIs(util::error::INTERNAL)); + + // FIPS validated implementations should still be allowed. + EXPECT_THAT( + internal::CheckFipsCompatibility<FipsCompatibleWithBoringCrypto>(), + IsOk()); +} + +TEST(TinkFipsTest, CompatibilityChecksWithoutBoringCrypto) { + if (FIPS_mode()) { + GTEST_SKIP() << "Test only run if BoringCrypto module is not available."; + } + + // Tink is not build in FIPS mode, but the FIPS mode is enabled at runtime. + EXPECT_THAT(crypto::tink::RestrictToFips(), IsOk()); + + // In FIPS only mode compatibility checks should disallow algorithms + // with the FipsCompatibility::kNone flag. + EXPECT_THAT(internal::CheckFipsCompatibility<FipsIncompatible>(), + StatusIs(util::error::INTERNAL)); + + // FIPS validated implementations are not allowed if BoringCrypto is not + // available. + EXPECT_THAT( + internal::CheckFipsCompatibility<FipsCompatibleWithBoringCrypto>(), + StatusIs(util::error::INTERNAL)); +} + +TEST(TinkFipsTest, FailIfRegistryNotEmpty) { + if (internal::kUseOnlyFips) { + GTEST_SKIP() << "Not supported in FIPS-only mode"; + } + + Registry::Reset(); + internal::UnSetFipsRestricted(); + + EXPECT_THAT(AeadConfig::Register(), IsOk()); + EXPECT_THAT(crypto::tink::RestrictToFips(), StatusIs(util::error::INTERNAL)); +} + } // namespace } // namespace tink |