diff options
author | kste <kste@google.com> | 2020-07-03 04:15:02 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2020-07-03 04:15:38 -0700 |
commit | 7913c4d162c60d243d30949026cb6b2bf7858915 (patch) | |
tree | aa11e5ae93a228d84777622c55e30f4ba6cf9899 /cc/config | |
parent | b828d2a9d4ff82386a6489d05a7f231bf8a5e2ee (diff) | |
download | tink-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.bazel | 22 | ||||
-rw-r--r-- | cc/config/CMakeLists.txt | 11 | ||||
-rw-r--r-- | cc/config/tink_fips.cc | 50 | ||||
-rw-r--r-- | cc/config/tink_fips.h | 55 | ||||
-rw-r--r-- | cc/config/tink_fips_disabled_test.cc | 48 | ||||
-rw-r--r-- | cc/config/tink_fips_enabled_test.cc | 60 |
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 |