aboutsummaryrefslogtreecommitdiff
path: root/cc/config
diff options
context:
space:
mode:
authorkste <kste@google.com>2021-04-16 08:25:15 -0700
committerCopybara-Service <copybara-worker@google.com>2021-04-16 08:25:45 -0700
commitd0795b2b41a78eaa90a3243d55382625cd8c282d (patch)
tree55d790f1d08db7fb2a850924cf683637bed6a0b9 /cc/config
parent47b6e1783c8dc1eaed150632efd2ceb50f3f867c (diff)
downloadtink-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.bazel5
-rw-r--r--cc/config/tink_fips.cc4
-rw-r--r--cc/config/tink_fips.h5
-rw-r--r--cc/config/tink_fips_test.cc73
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