diff options
author | cinlin <cinlin@google.com> | 2023-03-14 19:57:58 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-03-14 19:59:07 -0700 |
commit | e3f5a133dd1e794c71bbf6c4cd269260ace58d10 (patch) | |
tree | f61d554dcdb89a62a1cd25115d9634307f5b8fbd /cc/config | |
parent | cec227e3a284606a95692cf3a9da188d09548727 (diff) | |
download | tink-e3f5a133dd1e794c71bbf6c4cd269260ace58d10.tar.gz |
Define crypto::tink::ConfigFips140_2(). #tinkApiChange
PiperOrigin-RevId: 516701128
Diffstat (limited to 'cc/config')
-rw-r--r-- | cc/config/BUILD.bazel | 52 | ||||
-rw-r--r-- | cc/config/CMakeLists.txt | 51 | ||||
-rw-r--r-- | cc/config/fips_140_2.cc | 134 | ||||
-rw-r--r-- | cc/config/fips_140_2.h | 33 | ||||
-rw-r--r-- | cc/config/fips_140_2_test.cc | 138 |
5 files changed, 408 insertions, 0 deletions
diff --git a/cc/config/BUILD.bazel b/cc/config/BUILD.bazel index e377fd61f..7ecb7b8e4 100644 --- a/cc/config/BUILD.bazel +++ b/cc/config/BUILD.bazel @@ -103,3 +103,55 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "fips_140_2", + srcs = ["fips_140_2.cc"], + hdrs = ["fips_140_2.h"], + include_prefix = "tink/config", + deps = [ + "//:configuration", + "//aead:aead_wrapper", + "//aead:aes_ctr_hmac_aead_key_manager", + "//aead:aes_gcm_key_manager", + "//internal:configuration_impl", + "//mac:hmac_key_manager", + "//mac:mac_wrapper", + "//mac/internal:chunked_mac_wrapper", + "//prf:hmac_prf_key_manager", + "//prf:prf_set_wrapper", + "//signature:ecdsa_sign_key_manager", + "//signature:ecdsa_verify_key_manager", + "//signature:public_key_sign_wrapper", + "//signature:public_key_verify_wrapper", + "//signature:rsa_ssa_pkcs1_sign_key_manager", + "//signature:rsa_ssa_pkcs1_verify_key_manager", + "//signature:rsa_ssa_pss_sign_key_manager", + "//signature:rsa_ssa_pss_verify_key_manager", + "@com_google_absl//absl/log:check", + ], +) + +cc_test( + name = "fips_140_2_test", + srcs = ["fips_140_2_test.cc"], + deps = [ + ":fips_140_2", + "//aead:aead_key_templates", + "//aead:aes_ctr_hmac_aead_key_manager", + "//aead:aes_gcm_key_manager", + "//internal:configuration_impl", + "//internal:fips_utils", + "//internal:registry_impl", + "//mac:aes_cmac_key_manager", + "//mac:hmac_key_manager", + "//prf:hmac_prf_key_manager", + "//proto:tink_cc_proto", + "//signature:ecdsa_verify_key_manager", + "//signature:rsa_ssa_pkcs1_verify_key_manager", + "//signature:rsa_ssa_pss_verify_key_manager", + "//util:test_matchers", + "//util:test_util", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/cc/config/CMakeLists.txt b/cc/config/CMakeLists.txt index 7fb341bdc..38a51df5f 100644 --- a/cc/config/CMakeLists.txt +++ b/cc/config/CMakeLists.txt @@ -87,3 +87,54 @@ tink_cc_test( tink::util::status tink::util::test_matchers ) + +tink_cc_library( + NAME fips_140_2 + SRCS + fips_140_2.cc + fips_140_2.h + DEPS + absl::check + tink::core::configuration + tink::aead::aead_wrapper + tink::aead::aes_ctr_hmac_aead_key_manager + tink::aead::aes_gcm_key_manager + tink::internal::configuration_impl + tink::mac::hmac_key_manager + tink::mac::mac_wrapper + tink::mac::internal::chunked_mac_wrapper + tink::prf::hmac_prf_key_manager + tink::prf::prf_set_wrapper + tink::signature::ecdsa_sign_key_manager + tink::signature::ecdsa_verify_key_manager + tink::signature::public_key_sign_wrapper + tink::signature::public_key_verify_wrapper + tink::signature::rsa_ssa_pkcs1_sign_key_manager + tink::signature::rsa_ssa_pkcs1_verify_key_manager + tink::signature::rsa_ssa_pss_sign_key_manager + tink::signature::rsa_ssa_pss_verify_key_manager +) + +tink_cc_test( + NAME fips_140_2_test + SRCS + fips_140_2_test.cc + DEPS + tink::config::fips_140_2 + gmock + tink::aead::aead_key_templates + tink::aead::aes_ctr_hmac_aead_key_manager + tink::aead::aes_gcm_key_manager + tink::internal::configuration_impl + tink::internal::fips_utils + tink::internal::registry_impl + tink::mac::aes_cmac_key_manager + tink::mac::hmac_key_manager + tink::prf::hmac_prf_key_manager + tink::signature::ecdsa_verify_key_manager + tink::signature::rsa_ssa_pkcs1_verify_key_manager + tink::signature::rsa_ssa_pss_verify_key_manager + tink::util::test_matchers + tink::util::test_util + tink::proto::tink_cc_proto +) diff --git a/cc/config/fips_140_2.cc b/cc/config/fips_140_2.cc new file mode 100644 index 000000000..792b6803a --- /dev/null +++ b/cc/config/fips_140_2.cc @@ -0,0 +1,134 @@ +// Copyright 2023 Google LLC +// +// 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/fips_140_2.h" + +#include "absl/log/check.h" +#include "tink/aead/aead_wrapper.h" +#include "tink/aead/aes_ctr_hmac_aead_key_manager.h" +#include "tink/aead/aes_gcm_key_manager.h" +#include "tink/configuration.h" +#include "tink/internal/configuration_impl.h" +#include "tink/internal/fips_utils.h" +#include "tink/mac/hmac_key_manager.h" +#include "tink/mac/internal/chunked_mac_wrapper.h" +#include "tink/mac/mac_wrapper.h" +#include "tink/prf/hmac_prf_key_manager.h" +#include "tink/prf/prf_set_wrapper.h" +#include "tink/signature/ecdsa_verify_key_manager.h" +#include "tink/signature/public_key_sign_wrapper.h" +#include "tink/signature/public_key_verify_wrapper.h" +#include "tink/signature/rsa_ssa_pkcs1_sign_key_manager.h" +#include "tink/signature/rsa_ssa_pkcs1_verify_key_manager.h" +#include "tink/signature/rsa_ssa_pss_sign_key_manager.h" +#include "tink/signature/rsa_ssa_pss_verify_key_manager.h" +#include "tink/signature/ecdsa_sign_key_manager.h" + +namespace crypto { +namespace tink { +namespace { + +util::Status RegisterMac(Configuration& config) { + util::Status status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<MacWrapper>(), config); + if (!status.ok()) { + return status; + } + status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<internal::ChunkedMacWrapper>(), config); + if (!status.ok()) { + return status; + } + + return internal::ConfigurationImpl::RegisterKeyTypeManager( + absl::make_unique<HmacKeyManager>(), config); +} + +util::Status RegisterAead(Configuration& config) { + util::Status status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<AeadWrapper>(), config); + if (!status.ok()) { + return status; + } + + status = internal::ConfigurationImpl::RegisterKeyTypeManager( + absl::make_unique<AesCtrHmacAeadKeyManager>(), config); + if (!status.ok()) { + return status; + } + return internal::ConfigurationImpl::RegisterKeyTypeManager( + absl::make_unique<AesGcmKeyManager>(), config); +} + +util::Status RegisterPrf(Configuration& config) { + util::Status status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<PrfSetWrapper>(), config); + if (!status.ok()) { + return status; + } + + return internal::ConfigurationImpl::RegisterKeyTypeManager( + absl::make_unique<HmacPrfKeyManager>(), config); +} + +util::Status RegisterSignature(Configuration& config) { + util::Status status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<PublicKeySignWrapper>(), config); + if (!status.ok()) { + return status; + } + status = internal::ConfigurationImpl::RegisterPrimitiveWrapper( + absl::make_unique<PublicKeyVerifyWrapper>(), config); + if (!status.ok()) { + return status; + } + + status = internal::ConfigurationImpl::RegisterAsymmetricKeyManagers( + absl::make_unique<EcdsaSignKeyManager>(), + absl::make_unique<EcdsaVerifyKeyManager>(), config); + if (!status.ok()) { + return status; + } + status = internal::ConfigurationImpl::RegisterAsymmetricKeyManagers( + absl::make_unique<RsaSsaPssSignKeyManager>(), + absl::make_unique<RsaSsaPssVerifyKeyManager>(), config); + if (!status.ok()) { + return status; + } + return internal::ConfigurationImpl::RegisterAsymmetricKeyManagers( + absl::make_unique<RsaSsaPkcs1SignKeyManager>(), + absl::make_unique<RsaSsaPkcs1VerifyKeyManager>(), config); +} + +} // namespace + +const Configuration& ConfigFips140_2() { + static const Configuration* instance = [] { + internal::SetFipsRestricted(); + + static Configuration* config = new Configuration(); + CHECK_OK(RegisterMac(*config)); + CHECK_OK(RegisterAead(*config)); + CHECK_OK(RegisterPrf(*config)); + CHECK_OK(RegisterSignature(*config)); + + return config; + }(); + return *instance; +} + +} // namespace tink +} // namespace crypto diff --git a/cc/config/fips_140_2.h b/cc/config/fips_140_2.h new file mode 100644 index 000000000..ae4b93d48 --- /dev/null +++ b/cc/config/fips_140_2.h @@ -0,0 +1,33 @@ +// Copyright 2023 Google LLC +// +// 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_FIPS_140_2_H_ +#define TINK_CONFIG_FIPS_140_2_H_ + +#include "tink/configuration.h" + +namespace crypto { +namespace tink { + +// Allows primitive generation using FIPS 140-2-compliant key types. Importing +// this Configuration restricts Tink to FIPS globally and requires BoringSSL to +// be built with the BoringCrypto module. +const Configuration& ConfigFips140_2(); + +} // namespace tink +} // namespace crypto + +#endif // TINK_CONFIG_FIPS_140_2_H_ diff --git a/cc/config/fips_140_2_test.cc b/cc/config/fips_140_2_test.cc new file mode 100644 index 000000000..d4c79282a --- /dev/null +++ b/cc/config/fips_140_2_test.cc @@ -0,0 +1,138 @@ +// Copyright 2023 Google LLC +// +// 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/fips_140_2.h" + +#include <memory> +#include <string> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "tink/aead/aead_key_templates.h" +#include "tink/aead/aes_ctr_hmac_aead_key_manager.h" +#include "tink/aead/aes_gcm_key_manager.h" +#include "tink/internal/configuration_impl.h" +#include "tink/internal/fips_utils.h" +#include "tink/internal/registry_impl.h" +#include "tink/mac/aes_cmac_key_manager.h" +#include "tink/mac/hmac_key_manager.h" +#include "tink/prf/hmac_prf_key_manager.h" +#include "tink/signature/ecdsa_verify_key_manager.h" +#include "tink/signature/rsa_ssa_pkcs1_verify_key_manager.h" +#include "tink/signature/rsa_ssa_pss_verify_key_manager.h" +#include "tink/util/test_matchers.h" +#include "tink/util/test_util.h" +#include "proto/tink.pb.h" + +namespace crypto { +namespace tink { +namespace { + +using ::crypto::tink::test::IsOk; +using ::crypto::tink::test::IsOkAndHolds; +using ::google::crypto::tink::KeyData; +using ::google::crypto::tink::Keyset; +using ::google::crypto::tink::KeyStatusType; +using ::google::crypto::tink::OutputPrefixType; +using ::testing::Not; + +class Fips1402Test : public ::testing::Test { + protected: + void TearDown() override { internal::UnSetFipsRestricted(); } +}; + +TEST_F(Fips1402Test, ConfigFips1402) { + if (!FIPS_mode()) { + GTEST_SKIP() << "Only test in FIPS mode"; + } + + const internal::RegistryImpl& registry = + internal::ConfigurationImpl::get_registry(ConfigFips140_2()); + EXPECT_THAT(registry.get_key_manager<Mac>(HmacKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT( + registry.get_key_manager<Aead>(AesCtrHmacAeadKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT(registry.get_key_manager<Aead>(AesGcmKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT(registry.get_key_manager<Prf>(HmacPrfKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT(registry.get_key_manager<PublicKeyVerify>( + EcdsaVerifyKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT(registry.get_key_manager<PublicKeyVerify>( + RsaSsaPssVerifyKeyManager().get_key_type()), + IsOk()); + EXPECT_THAT(registry.get_key_manager<PublicKeyVerify>( + RsaSsaPkcs1VerifyKeyManager().get_key_type()), + IsOk()); +} + +TEST_F(Fips1402Test, NonFipsKeyManagerIsNotPresent) { + if (!FIPS_mode()) { + GTEST_SKIP() << "Only test in FIPS mode"; + } + + const internal::RegistryImpl& registry = + internal::ConfigurationImpl::get_registry(ConfigFips140_2()); + EXPECT_THAT(registry.get_key_manager<Mac>(AesCmacKeyManager().get_key_type()), + Not(IsOk())); +} + +TEST_F(Fips1402Test, ConfigFips1402FailsInNonFipsMode) { + if (FIPS_mode()) { + GTEST_SKIP() << "Only test in non-FIPS mode"; + } + + EXPECT_DEATH_IF_SUPPORTED( + ConfigFips140_2(), "BoringSSL not built with the BoringCrypto module."); +} + +TEST_F(Fips1402Test, NewKeyDataAndWrapKeysetSucceeds) { + if (!FIPS_mode()) { + GTEST_SKIP() << "Only test in FIPS mode"; + } + + const internal::RegistryImpl& registry = + internal::ConfigurationImpl::get_registry(ConfigFips140_2()); + + util::StatusOr<std::unique_ptr<KeyData>> key_data = + registry.NewKeyData(AeadKeyTemplates::Aes128Gcm()); + ASSERT_THAT(key_data, IsOk()); + + Keyset keyset; + uint32_t key_id = 0; + test::AddKeyData(**key_data, key_id, OutputPrefixType::TINK, + KeyStatusType::ENABLED, &keyset); + keyset.set_primary_key_id(key_id); + + absl::flat_hash_map<std::string, std::string> annotations; + util::StatusOr<std::unique_ptr<Aead>> aead = + registry.WrapKeyset<Aead>(keyset, annotations); + ASSERT_THAT(aead, IsOk()); + + std::string plaintext = "plaintext"; + std::string ad = "ad"; + util::StatusOr<std::string> ciphertext = (*aead)->Encrypt(plaintext, ad); + ASSERT_THAT(ciphertext, IsOk()); + + util::StatusOr<std::string> decrypted = (*aead)->Decrypt(*ciphertext, ad); + EXPECT_THAT(decrypted, IsOkAndHolds(plaintext)); +} + +} // namespace +} // namespace tink +} // namespace crypto |