aboutsummaryrefslogtreecommitdiff
path: root/cc/config
diff options
context:
space:
mode:
authorkste <kste@google.com>2020-07-03 04:15:02 -0700
committerCopybara-Service <copybara-worker@google.com>2020-07-03 04:15:38 -0700
commit7913c4d162c60d243d30949026cb6b2bf7858915 (patch)
treeaa11e5ae93a228d84777622c55e30f4ba6cf9899 /cc/config
parentb828d2a9d4ff82386a6489d05a7f231bf8a5e2ee (diff)
downloadtink-7913c4d162c60d243d30949026cb6b2bf7858915.tar.gz
Add build flag to enable FIPS only mode which restricts the usage of Tink to primitives which utilize implementations in the FIPS validated BoringCrypto module.
PiperOrigin-RevId: 319499654
Diffstat (limited to 'cc/config')
-rw-r--r--cc/config/BUILD.bazel22
-rw-r--r--cc/config/CMakeLists.txt11
-rw-r--r--cc/config/tink_fips.cc50
-rw-r--r--cc/config/tink_fips.h55
-rw-r--r--cc/config/tink_fips_disabled_test.cc48
-rw-r--r--cc/config/tink_fips_enabled_test.cc60
6 files changed, 246 insertions, 0 deletions
diff --git a/cc/config/BUILD.bazel b/cc/config/BUILD.bazel
index dde6656d5..9c0faa301 100644
--- a/cc/config/BUILD.bazel
+++ b/cc/config/BUILD.bazel
@@ -32,6 +32,28 @@ cc_library(
],
)
+config_setting(
+ name = "only_fips",
+ values = {"define": "use_only_fips=on"},
+)
+
+cc_library(
+ name = "tink_fips",
+ srcs = ["tink_fips.cc"],
+ hdrs = ["tink_fips.h"],
+ include_prefix = "tink/config",
+ defines = select({
+ "only_fips": ["TINK_USE_ONLY_FIPS"],
+ "//conditions:default": [],
+ }),
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_google_absl//absl/base:core_headers",
+ "@boringssl//:crypto",
+ "//util:status",
+ ],
+)
+
# tests
cc_test(
diff --git a/cc/config/CMakeLists.txt b/cc/config/CMakeLists.txt
index e7224dc21..f8ce26581 100644
--- a/cc/config/CMakeLists.txt
+++ b/cc/config/CMakeLists.txt
@@ -27,6 +27,17 @@ tink_cc_library(
tink::proto::config_cc_proto
)
+tink_cc_library(
+ NAME tink_fips
+ SRCS
+ tink_fips.cc
+ tink_fips.h
+ DEPS
+ absl::base
+ crypto
+ tink::util::status
+)
+
# tests
tink_cc_test(
diff --git a/cc/config/tink_fips.cc b/cc/config/tink_fips.cc
new file mode 100644
index 000000000..402f5272b
--- /dev/null
+++ b/cc/config/tink_fips.cc
@@ -0,0 +1,50 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "tink/config/tink_fips.h"
+
+namespace crypto {
+namespace tink {
+
+#ifdef TINK_USE_ONLY_FIPS
+const bool kUseOnlyFips = true;
+#else
+const bool kUseOnlyFips = false;
+#endif
+
+crypto::tink::util::Status ChecksFipsCompatibility(
+ FipsCompatibility fips_status) {
+ switch (fips_status) {
+ case FipsCompatibility::kNotFips:
+ if (kUseOnlyFips) {
+ return util::Status(util::error::INTERNAL,
+ "Primitive not available in FIPS only mode");
+ } else {
+ return util::OkStatus();
+ }
+ case FipsCompatibility::kRequiresBoringCrypto:
+ if (kUseOnlyFips && !FIPS_mode()) {
+ return util::Status(
+ util::error::INTERNAL,
+ "BoringSSL not built with the BoringCrypto module. If you want to "
+ "use "
+ "FIPS only mode you have to build BoringSSL in FIPS Mode.");
+
+ } else {
+ return util::OkStatus();
+ }
+ }
+}
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/config/tink_fips.h b/cc/config/tink_fips.h
new file mode 100644
index 000000000..8d1e8ed3a
--- /dev/null
+++ b/cc/config/tink_fips.h
@@ -0,0 +1,55 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+#ifndef TINK_CONFIG_TINK_FIPS_H_
+#define TINK_CONFIG_TINK_FIPS_H_
+
+#include "absl/base/attributes.h"
+#include "openssl/crypto.h"
+#include "tink/util/status.h"
+
+namespace crypto {
+namespace tink {
+
+// This flag indicates whether Tink was build in FIPS only mode. If the flag
+// is set, then usage of algorithms will be restricted to algorithms which
+// utilize the FIPS validated BoringCrypto module.
+ABSL_CONST_INIT extern const bool kUseOnlyFips;
+
+// Should be used to indicate whether an algorithm can be used in FIPS only
+// mode or not.
+enum class FipsCompatibility {
+ kNotFips = 0, // The algorithm can not use a FIPS validated implementation.
+ kRequiresBoringCrypto, // The algorithm requires BoringCrypto to use a FIPS
+ // validated implementation.
+};
+
+// Allows to check for a cryptographic algorithm whether it is available in
+// the FIPS only mode, based on it's FipsCompatibility flag. If FIPS only
+// mode is enabled this will return an INTERNAL error if:
+// 1) The algorithm has no FIPS support.
+// 2) The algorithm has FIPS support, but BoringSSL has not been compiled with
+// the BoringCrypto module.
+crypto::tink::util::Status ChecksFipsCompatibility(
+ FipsCompatibility fips_status);
+
+// Utility function wich calls CheckFipsCompatibility(T::kFipsStatus).
+template <class T>
+crypto::tink::util::Status CheckFipsCompatibility() {
+ return ChecksFipsCompatibility(T::kFipsStatus);
+}
+
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_CONFIG_TINK_FIPS_H_
diff --git a/cc/config/tink_fips_disabled_test.cc b/cc/config/tink_fips_disabled_test.cc
new file mode 100644
index 000000000..d9877b440
--- /dev/null
+++ b/cc/config/tink_fips_disabled_test.cc
@@ -0,0 +1,48 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "tink/config/tink_fips.h"
+#include "tink/util/test_matchers.h"
+
+namespace crypto {
+namespace tink {
+namespace {
+
+using ::crypto::tink::test::IsOk;
+using testing::Eq;
+
+TEST(TinkFipsTest, FlagCorrectlySet) { EXPECT_THAT(kUseOnlyFips, Eq(false)); }
+
+class FipsIncompatible {
+ public:
+ static constexpr crypto::tink::FipsCompatibility kFipsStatus =
+ crypto::tink::FipsCompatibility::kNotFips;
+};
+
+class FipsCompatibleWithBoringCrypto {
+ public:
+ static constexpr crypto::tink::FipsCompatibility kFipsStatus =
+ crypto::tink::FipsCompatibility::kRequiresBoringCrypto;
+};
+
+TEST(TinkFipsTest, Compatibility) {
+ // With FIPS only mode disabled no restrictions should apply.
+ EXPECT_THAT(CheckFipsCompatibility<FipsIncompatible>(), IsOk());
+ EXPECT_THAT(CheckFipsCompatibility<FipsCompatibleWithBoringCrypto>(), IsOk());
+}
+
+} // namespace
+} // namespace tink
+} // namespace crypto
diff --git a/cc/config/tink_fips_enabled_test.cc b/cc/config/tink_fips_enabled_test.cc
new file mode 100644
index 000000000..f43e5f4de
--- /dev/null
+++ b/cc/config/tink_fips_enabled_test.cc
@@ -0,0 +1,60 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "tink/aead.h"
+#include "tink/aead/aead_config.h"
+#include "tink/aead/aead_key_templates.h"
+#include "tink/config/tink_fips.h"
+#include "tink/keyset_handle.h"
+#include "tink/util/status.h"
+#include "tink/util/test_matchers.h"
+#include "tink/util/test_util.h"
+
+namespace crypto {
+namespace tink {
+namespace {
+
+using ::crypto::tink::test::IsOk;
+using ::crypto::tink::test::StatusIs;
+
+TEST(TinkFipsTest, FlagCorrectlySet) {
+ EXPECT_THAT(kUseOnlyFips, testing::Eq(true));
+}
+
+class FipsIncompatible {
+ public:
+ static constexpr crypto::tink::FipsCompatibility kFipsStatus =
+ crypto::tink::FipsCompatibility::kNotFips;
+};
+
+class FipsCompatibleWithBoringCrypto {
+ public:
+ static constexpr crypto::tink::FipsCompatibility kFipsStatus =
+ crypto::tink::FipsCompatibility::kRequiresBoringCrypto;
+};
+
+TEST(TinkFipsTest, CompatibilityChecks) {
+ // In FIPS only mode compatibility checks should disallow algorithms
+ // with the FipsCompatibility::kNone flag.
+ EXPECT_THAT(CheckFipsCompatibility<FipsIncompatible>(),
+ StatusIs(util::error::INTERNAL));
+
+ // FIPS validated implementations should still be allowed.
+ EXPECT_THAT(CheckFipsCompatibility<FipsCompatibleWithBoringCrypto>(), IsOk());
+}
+
+} // namespace
+} // namespace tink
+} // namespace crypto