diff options
author | sschmieg <sschmieg@google.com> | 2020-04-01 16:33:28 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2020-04-01 16:34:02 -0700 |
commit | a389e601043a61d129264a66d0487c04d84a207a (patch) | |
tree | 85ea7b63c452d06be5aaa6e9ce9746c5fd1f6799 /cc/prf | |
parent | 61442e6cb557c2adfee4e1ea33500c73bccda8c2 (diff) | |
download | tink-a389e601043a61d129264a66d0487c04d84a207a.tar.gz |
PrfSet implementation last CL: Registering the key managers and wrappers in the config and adding an end to end test.
Also adds a statistical test to find obvious non randomness.
PiperOrigin-RevId: 304286550
Diffstat (limited to 'cc/prf')
-rw-r--r-- | cc/prf/BUILD.bazel | 9 | ||||
-rw-r--r-- | cc/prf/CMakeLists.txt | 9 | ||||
-rw-r--r-- | cc/prf/prf_config.cc | 19 | ||||
-rw-r--r-- | cc/prf/prf_set_test.cc | 93 |
4 files changed, 129 insertions, 1 deletions
diff --git a/cc/prf/BUILD.bazel b/cc/prf/BUILD.bazel index b110db907..b0bc6abcc 100644 --- a/cc/prf/BUILD.bazel +++ b/cc/prf/BUILD.bazel @@ -38,7 +38,10 @@ cc_library( include_prefix = "tink/prf", visibility = ["//visibility:public"], deps = [ + ":aes_cmac_prf_key_manager", ":hkdf_prf_key_manager", + ":hmac_prf_key_manager", + ":prf_set_wrapper", "//:registry", "//proto:tink_cc_proto", "//util:status", @@ -195,8 +198,14 @@ cc_test( name = "prf_set_test", srcs = ["prf_set_test.cc"], deps = [ + ":prf_config", + ":prf_key_templates", ":prf_set", + "//:keyset_handle", + "//:keyset_manager", "//util:statusor", + "//util:test_matchers", + "//util:test_util", "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/cc/prf/CMakeLists.txt b/cc/prf/CMakeLists.txt index f3114300b..4c61a97ba 100644 --- a/cc/prf/CMakeLists.txt +++ b/cc/prf/CMakeLists.txt @@ -32,7 +32,10 @@ tink_cc_library( prf_config.cc prf_config.h DEPS + tink::prf::aes_cmac_prf_key_manager tink::prf::hkdf_prf_key_manager + tink::prf::hmac_prf_key_manager + tink::prf::prf_set_wrapper tink::core::registry tink::util::status tink::proto::tink_cc_proto @@ -180,7 +183,13 @@ tink_cc_test( SRCS prf_set_test.cc DEPS tink::prf::prf_set + tink::prf::prf_config + tink::prf::prf_key_templates + tink::core::keyset_handle + tink::core::keyset_manager tink::util::statusor + tink::util::test_matchers + tink::util::test_util absl::memory absl::strings gmock diff --git a/cc/prf/prf_config.cc b/cc/prf/prf_config.cc index 17498513d..1a3861407 100644 --- a/cc/prf/prf_config.cc +++ b/cc/prf/prf_config.cc @@ -13,15 +13,32 @@ //////////////////////////////////////////////////////////////////////////////// #include "tink/prf/prf_config.h" +#include "tink/prf/aes_cmac_prf_key_manager.h" #include "tink/prf/hkdf_prf_key_manager.h" +#include "tink/prf/hmac_prf_key_manager.h" +#include "tink/prf/prf_set_wrapper.h" #include "tink/registry.h" namespace crypto { namespace tink { crypto::tink::util::Status PrfConfig::Register() { - return Registry::RegisterKeyTypeManager( + auto status = Registry::RegisterKeyTypeManager( absl::make_unique<HkdfPrfKeyManager>(), true); + if (!status.ok()) { + return status; + } + status = Registry::RegisterKeyTypeManager( + absl::make_unique<HmacPrfKeyManager>(), true); + if (!status.ok()) { + return status; + } + status = Registry::RegisterKeyTypeManager( + absl::make_unique<AesCmacPrfKeyManager>(), true); + if (!status.ok()) { + return status; + } + return Registry::RegisterPrimitiveWrapper(absl::make_unique<PrfSetWrapper>()); } } // namespace tink diff --git a/cc/prf/prf_set_test.cc b/cc/prf/prf_set_test.cc index e7ee43981..20c592673 100644 --- a/cc/prf/prf_set_test.cc +++ b/cc/prf/prf_set_test.cc @@ -19,13 +19,28 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "tink/keyset_handle.h" +#include "tink/keyset_manager.h" +#include "tink/prf/prf_config.h" +#include "tink/prf/prf_key_templates.h" #include "tink/util/statusor.h" +#include "tink/util/test_matchers.h" +#include "tink/util/test_util.h" namespace crypto { namespace tink { namespace { +using ::crypto::tink::test::IsOk; +using ::testing::_; +using ::testing::Eq; +using ::testing::Pair; +using ::testing::SizeIs; +using ::testing::StrEq; +using ::testing::UnorderedElementsAre; + class DummyPrf : public Prf { util::StatusOr<std::string> Compute(absl::string_view input, size_t output_length) const override { @@ -66,6 +81,84 @@ TEST(PrfSetTest, ComputePrimary) { << "Expected broken PrfSet to not be able to compute the primary PRF"; } +TEST(PrfSetWrapperTest, TestPrimitivesEndToEnd) { + auto status = PrfConfig::Register(); + ASSERT_TRUE(status.ok()) << status; + auto keyset_manager_result = + KeysetManager::New(PrfKeyTemplates::HkdfSha256()); + ASSERT_TRUE(keyset_manager_result.ok()) << keyset_manager_result.status(); + auto keyset_manager = std::move(keyset_manager_result.ValueOrDie()); + auto id_result = keyset_manager->Add(PrfKeyTemplates::HmacSha256()); + ASSERT_TRUE(id_result.ok()) << id_result.status(); + uint32_t hmac_sha256_id = id_result.ValueOrDie(); + id_result = keyset_manager->Add(PrfKeyTemplates::HmacSha512()); + ASSERT_TRUE(id_result.ok()) << id_result.status(); + uint32_t hmac_sha512_id = id_result.ValueOrDie(); + id_result = keyset_manager->Add(PrfKeyTemplates::AesCmac()); + ASSERT_TRUE(id_result.ok()) << id_result.status(); + uint32_t aes_cmac_id = id_result.ValueOrDie(); + auto keyset_handle = keyset_manager->GetKeysetHandle(); + uint32_t hkdf_id = keyset_handle->GetKeysetInfo().primary_key_id(); + auto prf_set_result = keyset_handle->GetPrimitive<PrfSet>(); + ASSERT_TRUE(prf_set_result.ok()) << prf_set_result.status(); + auto prf_set = std::move(prf_set_result.ValueOrDie()); + EXPECT_THAT(prf_set->GetPrimaryId(), Eq(hkdf_id)); + auto prf_map = prf_set->GetPrfs(); + EXPECT_THAT(prf_map, UnorderedElementsAre(Pair(Eq(hkdf_id), _), + Pair(Eq(hmac_sha256_id), _), + Pair(Eq(hmac_sha512_id), _), + Pair(Eq(aes_cmac_id), _))); + std::string input = "This is an input string"; + std::string input2 = "This is a second input string"; + std::vector<size_t> output_lengths = {15, 16, 17, 31, 32, + 33, 63, 64, 65, 100}; + for (size_t output_length : output_lengths) { + bool aes_cmac_ok = output_length <= 16; + bool hmac_sha256_ok = output_length <= 32; + bool hmac_sha512_ok = output_length <= 64; + bool hkdf_sha256_ok = output_length <= 8192; + std::vector<std::string> results; + for (auto prf : prf_map) { + SCOPED_TRACE(absl::StrCat("Computing prf ", prf.first, + " with output_length ", output_length)); + bool ok = (prf.first == aes_cmac_id && aes_cmac_ok) || + (prf.first == hmac_sha256_id && hmac_sha256_ok) || + (prf.first == hmac_sha512_id && hmac_sha512_ok) || + (prf.first == hkdf_id && hkdf_sha256_ok); + auto output_result = prf.second->Compute(input, output_length); + EXPECT_THAT(output_result.ok(), Eq(ok)) << output_result.status(); + if (!ok) { + continue; + } + std::string output; + if (output_result.ok()) { + output = output_result.ValueOrDie(); + results.push_back(output); + } + output_result = prf.second->Compute(input2, output_length); + EXPECT_TRUE(output_result.ok()) << output_result.status(); + if (output_result.ok()) { + results.push_back(output_result.ValueOrDie()); + } + output_result = prf.second->Compute(input, output_length); + EXPECT_TRUE(output_result.ok()) << output_result.status(); + if (output_result.ok()) { + EXPECT_THAT(output_result.ValueOrDie(), StrEq(output)); + } + } + for (int i = 0; i < results.size(); i++) { + EXPECT_THAT(results[i], SizeIs(output_length)); + EXPECT_THAT(test::ZTestUniformString(results[i]), IsOk()); + EXPECT_THAT(test::ZTestAutocorrelationUniformString(results[i]), IsOk()); + for (int j = i + 1; j < results.size(); j++) { + EXPECT_THAT( + test::ZTestCrosscorrelationUniformStrings(results[i], results[j]), + IsOk()); + } + } + } +} + } // namespace } // namespace tink } // namespace crypto |