aboutsummaryrefslogtreecommitdiff
path: root/cc/prf
diff options
context:
space:
mode:
authorsschmieg <sschmieg@google.com>2020-04-01 14:54:03 -0700
committerCopybara-Service <copybara-worker@google.com>2020-04-01 14:54:44 -0700
commit8785fbc794e8b75370cdeb0f31af3c9756daae47 (patch)
tree3bd1996cdce164e29654a883b705e5adc2ac863d /cc/prf
parent24fb495a44e8517141806ac744158fd919704993 (diff)
downloadtink-8785fbc794e8b75370cdeb0f31af3c9756daae47.tar.gz
Adding KeyTypeManager for HMAC as PRF, for PrfSet.
PiperOrigin-RevId: 304268055
Diffstat (limited to 'cc/prf')
-rw-r--r--cc/prf/BUILD.bazel49
-rw-r--r--cc/prf/CMakeLists.txt47
-rw-r--r--cc/prf/hmac_prf_key_manager.cc102
-rw-r--r--cc/prf/hmac_prf_key_manager.h110
-rw-r--r--cc/prf/hmac_prf_key_manager_test.cc185
-rw-r--r--cc/prf/prf_key_templates.cc6
-rw-r--r--cc/prf/prf_key_templates_test.cc11
7 files changed, 507 insertions, 3 deletions
diff --git a/cc/prf/BUILD.bazel b/cc/prf/BUILD.bazel
index f70f060aa..47e931153 100644
--- a/cc/prf/BUILD.bazel
+++ b/cc/prf/BUILD.bazel
@@ -49,6 +49,7 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":aes_cmac_prf_key_manager",
+ ":hmac_prf_key_manager",
"//proto:aes_cmac_prf_cc_proto",
"//proto:hkdf_prf_cc_proto",
"//proto:hmac_prf_cc_proto",
@@ -95,6 +96,34 @@ cc_library(
],
)
+cc_library(
+ name = "hmac_prf_key_manager",
+ srcs = ["hmac_prf_key_manager.cc"],
+ hdrs = ["hmac_prf_key_manager.h"],
+ include_prefix = "tink/prf",
+ deps = [
+ "//:core/key_type_manager",
+ "//:key_manager",
+ "//proto:hmac_prf_cc_proto",
+ "//proto:tink_cc_proto",
+ "//subtle:common_enums",
+ "//subtle:random",
+ "//subtle:stateful_hmac_boringssl",
+ "//subtle/prf:prf_set_util",
+ "//util:constants",
+ "//util:enums",
+ "//util:errors",
+ "//util:input_stream_util",
+ "//util:protobuf_helper",
+ "//util:secret_data",
+ "//util:status",
+ "//util:statusor",
+ "//util:validation",
+ "@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
+ ],
+)
+
cc_test(
name = "hkdf_prf_key_manager_test",
srcs = ["hkdf_prf_key_manager_test.cc"],
@@ -116,8 +145,10 @@ cc_test(
deps = [
":aes_cmac_prf_key_manager",
":hkdf_prf_key_manager",
+ ":hmac_prf_key_manager",
":prf_key_templates",
"//proto:aes_cmac_prf_cc_proto",
+ "//proto:hmac_prf_cc_proto",
"//util:test_matchers",
"@com_google_absl//absl/memory",
"@com_google_googletest//:gtest_main",
@@ -150,3 +181,21 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
+
+cc_test(
+ name = "hmac_prf_key_manager_test",
+ srcs = ["hmac_prf_key_manager_test.cc"],
+ deps = [
+ ":hmac_prf_key_manager",
+ ":prf_set",
+ "//:core/key_manager_impl",
+ "//proto:hmac_prf_cc_proto",
+ "//subtle:hmac_boringssl",
+ "//util:istream_input_stream",
+ "//util:secret_data",
+ "//util:status",
+ "//util:statusor",
+ "//util:test_matchers",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
diff --git a/cc/prf/CMakeLists.txt b/cc/prf/CMakeLists.txt
index 1ece39131..1c186a9ca 100644
--- a/cc/prf/CMakeLists.txt
+++ b/cc/prf/CMakeLists.txt
@@ -42,6 +42,7 @@ tink_cc_library(
prf_key_templates.cc
DEPS
tink::prf::aes_cmac_prf_key_manager
+ tink::prf::hmac_prf_key_manager
tink::proto::aes_cmac_prf_cc_proto
tink::proto::hkdf_prf_cc_proto
tink::proto::hmac_prf_cc_proto
@@ -83,6 +84,33 @@ tink_cc_library(
absl::strings
)
+tink_cc_library(
+ NAME hmac_prf_key_manager
+ SRCS
+ hmac_prf_key_manager.cc
+ hmac_prf_key_manager.h
+ DEPS
+ tink::core::key_type_manager
+ tink::core::key_manager
+ tink::proto::hmac_prf_cc_proto
+ tink::proto::tink_cc_proto
+ tink::subtle::common_enums
+ tink::subtle::random
+ tink::subtle::stateful_hmac_boringssl
+ tink::subtle::prf::prf_set_util
+ tink::util::constants
+ tink::util::errors
+ tink::util::enums
+ tink::util::input_stream_util
+ tink::util::protobuf_helper
+ tink::util::secret_data
+ tink::util::status
+ tink::util::statusor
+ tink::util::validation
+ absl::memory
+ absl::strings
+)
+
tink_cc_test(
NAME hkdf_prf_key_manager_test
SRCS hkdf_prf_key_manager_test.cc
@@ -104,9 +132,11 @@ tink_cc_test(
SRCS prf_key_templates_test.cc
DEPS
tink::prf::aes_cmac_prf_key_manager
+ tink::prf::hmac_prf_key_manager
tink::prf::hkdf_prf_key_manager
tink::prf::prf_key_templates
tink::proto::aes_cmac_prf_cc_proto
+ tink::proto::hmac_prf_cc_proto
tink::util::test_matchers
absl::memory
gmock
@@ -136,3 +166,20 @@ tink_cc_test(
tink::util::test_matchers
gmock
)
+
+tink_cc_test(
+ NAME hmac_prf_key_manager_test
+ SRCS hmac_prf_key_manager_test.cc
+ DEPS
+ tink::prf::hmac_prf_key_manager
+ tink::prf::prf_set
+ tink::core::key_manager_impl
+ tink::proto::hmac_prf_cc_proto
+ tink::subtle::hmac_boringssl
+ tink::util::istream_input_stream
+ tink::util::secret_data
+ tink::util::status
+ tink::util::statusor
+ tink::util::test_matchers
+ gmock
+)
diff --git a/cc/prf/hmac_prf_key_manager.cc b/cc/prf/hmac_prf_key_manager.cc
new file mode 100644
index 000000000..f3620bcf2
--- /dev/null
+++ b/cc/prf/hmac_prf_key_manager.cc
@@ -0,0 +1,102 @@
+// 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/prf/hmac_prf_key_manager.h"
+
+#include <set>
+
+#include "tink/subtle/common_enums.h"
+#include "tink/util/enums.h"
+#include "tink/util/input_stream_util.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "proto/hmac_prf.pb.h"
+
+namespace crypto {
+namespace tink {
+namespace {
+constexpr int kMinKeySizeInBytes = 16;
+}
+
+using google::crypto::tink::HmacPrfKey;
+using google::crypto::tink::HmacPrfKeyFormat;
+using google::crypto::tink::HmacPrfParams;
+using subtle::HashType;
+using util::Enums;
+using util::Status;
+using util::StatusOr;
+
+util::Status HmacPrfKeyManager::ValidateKey(const HmacPrfKey& key) const {
+ util::Status status = ValidateVersion(key.version(), get_version());
+ if (!status.ok()) return status;
+ if (key.key_value().size() < kMinKeySizeInBytes) {
+ return util::Status(util::error::INVALID_ARGUMENT,
+ "Invalid HmacPrfKey: key_value wrong length.");
+ }
+ return ValidateParams(key.params());
+}
+
+util::Status HmacPrfKeyManager::ValidateKeyFormat(
+ const HmacPrfKeyFormat& key_format) const {
+ util::Status status = ValidateVersion(key_format.version(), get_version());
+ if (!status.ok()) return status;
+ if (key_format.key_size() < kMinKeySizeInBytes) {
+ return util::Status(util::error::INVALID_ARGUMENT,
+ "Invalid HmacPrfKeyFormat: invalid key_size.");
+ }
+ return ValidateParams(key_format.params());
+}
+
+crypto::tink::util::StatusOr<HmacPrfKey> HmacPrfKeyManager::CreateKey(
+ const HmacPrfKeyFormat& key_format) const {
+ HmacPrfKey key;
+ key.set_version(get_version());
+ key.set_key_value(subtle::Random::GetRandomBytes(key_format.key_size()));
+ *(key.mutable_params()) = key_format.params();
+ return key;
+}
+
+StatusOr<HmacPrfKey> HmacPrfKeyManager::DeriveKey(
+ const HmacPrfKeyFormat& hmac_prf_key_format,
+ InputStream* input_stream) const {
+ crypto::tink::util::Status status = ValidateKeyFormat(hmac_prf_key_format);
+ if (!status.ok()) return status;
+
+ crypto::tink::util::StatusOr<std::string> randomness =
+ ReadBytesFromStream(hmac_prf_key_format.key_size(), input_stream);
+ if (!randomness.status().ok()) {
+ return randomness.status();
+ }
+
+ HmacPrfKey key;
+ key.set_version(get_version());
+ *(key.mutable_params()) = hmac_prf_key_format.params();
+ key.set_key_value(randomness.ValueOrDie());
+ return key;
+}
+
+Status HmacPrfKeyManager::ValidateParams(const HmacPrfParams& params) const {
+ static const std::set<HashType>* supported_hash_types =
+ new std::set<HashType>(
+ {HashType::SHA1, HashType::SHA256, HashType::SHA512});
+ if (supported_hash_types->find(Enums::ProtoToSubtle(params.hash())) ==
+ supported_hash_types->end()) {
+ return ToStatusF(util::error::INVALID_ARGUMENT,
+ "Invalid HmacParams: HashType '%s' not supported.",
+ Enums::HashName(params.hash()));
+ }
+ return Status::OK;
+}
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/prf/hmac_prf_key_manager.h b/cc/prf/hmac_prf_key_manager.h
new file mode 100644
index 000000000..3c640bc47
--- /dev/null
+++ b/cc/prf/hmac_prf_key_manager.h
@@ -0,0 +1,110 @@
+// 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_PRF_HMAC_PRF_KEY_MANAGER_H_
+#define TINK_PRF_HMAC_PRF_KEY_MANAGER_H_
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "tink/core/key_type_manager.h"
+#include "tink/key_manager.h"
+#include "tink/subtle/common_enums.h"
+#include "tink/subtle/prf/prf_set_util.h"
+#include "tink/subtle/random.h"
+#include "tink/subtle/stateful_hmac_boringssl.h"
+#include "tink/util/constants.h"
+#include "tink/util/enums.h"
+#include "tink/util/errors.h"
+#include "tink/util/protobuf_helper.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/validation.h"
+#include "proto/hmac_prf.pb.h"
+#include "proto/tink.pb.h"
+
+namespace crypto {
+namespace tink {
+
+class HmacPrfKeyManager
+ : public KeyTypeManager<google::crypto::tink::HmacPrfKey,
+ google::crypto::tink::HmacPrfKeyFormat,
+ List<PrfSet>> {
+ public:
+ class PrfSetFactory : public PrimitiveFactory<PrfSet> {
+ crypto::tink::util::StatusOr<std::unique_ptr<PrfSet>> Create(
+ const google::crypto::tink::HmacPrfKey& key) const override {
+ return subtle::CreatePrfSetFromPrf(
+ subtle::CreatePrfFromStatefulMacFactory(
+ absl::make_unique<subtle::StatefulHmacBoringSslFactory>(
+ util::Enums::ProtoToSubtle(key.params().hash()),
+ MaxOutputLength(
+ util::Enums::ProtoToSubtle(key.params().hash())),
+ util::SecretDataFromStringView(key.key_value()))));
+ }
+ };
+
+ HmacPrfKeyManager()
+ : KeyTypeManager(absl::make_unique<HmacPrfKeyManager::PrfSetFactory>()) {}
+
+ uint32_t get_version() const override { return 0; }
+
+ google::crypto::tink::KeyData::KeyMaterialType key_material_type()
+ const override {
+ return google::crypto::tink::KeyData::SYMMETRIC;
+ }
+
+ static uint64_t MaxOutputLength(subtle::HashType hash_type) {
+ static std::map<subtle::HashType, uint64_t>* max_output_length =
+ new std::map<subtle::HashType, uint64_t>(
+ {{subtle::HashType::SHA1, 20},
+ {subtle::HashType::SHA256, 32},
+ {subtle::HashType::SHA512, 64}});
+ auto length_it = max_output_length->find(hash_type);
+ if (length_it == max_output_length->end()) {
+ return 0;
+ }
+ return length_it->second;
+ }
+
+ const std::string& get_key_type() const override { return key_type_; }
+
+ crypto::tink::util::Status ValidateKey(
+ const google::crypto::tink::HmacPrfKey& key) const override;
+
+ crypto::tink::util::Status ValidateKeyFormat(
+ const google::crypto::tink::HmacPrfKeyFormat& key_format) const override;
+
+ crypto::tink::util::StatusOr<google::crypto::tink::HmacPrfKey> CreateKey(
+ const google::crypto::tink::HmacPrfKeyFormat& key_format) const override;
+
+ util::StatusOr<google::crypto::tink::HmacPrfKey> DeriveKey(
+ const google::crypto::tink::HmacPrfKeyFormat& hmac_prf_key_format,
+ InputStream* input_stream) const override;
+
+ private:
+ util::Status ValidateParams(
+ const google::crypto::tink::HmacPrfParams& params) const;
+
+ const std::string key_type_ = absl::StrCat(
+ kTypeGoogleapisCom, google::crypto::tink::HmacPrfKey().GetTypeName());
+};
+
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_PRF_HMAC_PRF_KEY_MANAGER_H_
diff --git a/cc/prf/hmac_prf_key_manager_test.cc b/cc/prf/hmac_prf_key_manager_test.cc
new file mode 100644
index 000000000..e1ed0079e
--- /dev/null
+++ b/cc/prf/hmac_prf_key_manager_test.cc
@@ -0,0 +1,185 @@
+// 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/prf/hmac_prf_key_manager.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "tink/core/key_manager_impl.h"
+#include "tink/prf/prf_set.h"
+#include "tink/subtle/hmac_boringssl.h"
+#include "tink/util/istream_input_stream.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/test_matchers.h"
+#include "proto/hmac_prf.pb.h"
+
+namespace crypto {
+namespace tink {
+
+using ::crypto::tink::test::IsOk;
+using ::crypto::tink::test::StatusIs;
+using ::crypto::tink::util::IstreamInputStream;
+using ::crypto::tink::util::StatusOr;
+using ::google::crypto::tink::HashType;
+using ::google::crypto::tink::HmacPrfKey;
+using ::google::crypto::tink::HmacPrfKeyFormat;
+using ::google::crypto::tink::KeyData;
+using ::testing::Eq;
+using ::testing::HasSubstr;
+using ::testing::Not;
+using ::testing::SizeIs;
+using ::testing::StartsWith;
+
+namespace {
+
+TEST(HmacPrfKeyManagerTest, Basics) {
+ EXPECT_THAT(HmacPrfKeyManager().get_version(), Eq(0));
+ EXPECT_THAT(HmacPrfKeyManager().get_key_type(),
+ Eq("type.googleapis.com/google.crypto.tink.HmacPrfKey"));
+ EXPECT_THAT(HmacPrfKeyManager().key_material_type(),
+ Eq(google::crypto::tink::KeyData::SYMMETRIC));
+}
+
+TEST(HmacPrfKeyManagerTest, ValidateEmptyKey) {
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKey(HmacPrfKey()), Not(IsOk()));
+}
+
+TEST(HmacPrfKeyManagerTest, ValidateEmptyKeyFormat) {
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKeyFormat(HmacPrfKeyFormat()),
+ Not(IsOk()));
+}
+
+TEST(HmacPrfKeyManagerTest, ValidKeyFormat) {
+ HmacPrfKeyFormat key_format;
+ key_format.mutable_params()->set_hash(HashType::SHA256);
+ key_format.set_key_size(16);
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
+}
+
+TEST(HmacPrfKeyManagerTest, ValidateKeyFormatKeySizes) {
+ HmacPrfKeyFormat key_format;
+ key_format.mutable_params()->set_hash(HashType::SHA512);
+
+ key_format.set_key_size(15);
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
+
+ key_format.set_key_size(16);
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
+}
+
+TEST(HmacPrfKeyManagerTest, CreateKey) {
+ HmacPrfKeyFormat key_format;
+ key_format.set_key_size(16);
+ key_format.mutable_params()->set_hash(HashType::SHA512);
+ auto hmac_key_or = HmacPrfKeyManager().CreateKey(key_format);
+ ASSERT_THAT(hmac_key_or.status(), IsOk());
+ EXPECT_THAT(hmac_key_or.ValueOrDie().version(), Eq(0));
+ EXPECT_THAT(hmac_key_or.ValueOrDie().params().hash(),
+ Eq(key_format.params().hash()));
+ EXPECT_THAT(hmac_key_or.ValueOrDie().key_value(),
+ SizeIs(key_format.key_size()));
+
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKey(hmac_key_or.ValueOrDie()),
+ IsOk());
+}
+
+TEST(HmacPrfKeyManagerTest, ValidKey) {
+ HmacPrfKey key;
+ key.set_version(0);
+
+ key.mutable_params()->set_hash(HashType::SHA256);
+ key.set_key_value("0123456789abcdef");
+
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKey(key), IsOk());
+}
+
+TEST(HmacPrfKeyManagerTest, ValidateKeyShortKey) {
+ HmacPrfKey key;
+ key.set_version(0);
+
+ key.mutable_params()->set_hash(HashType::SHA256);
+ key.set_key_value("0123456789abcde");
+
+ EXPECT_THAT(HmacPrfKeyManager().ValidateKey(key), Not(IsOk()));
+}
+
+TEST(HmacPrfKeyManagerTest, DeriveKey) {
+ HmacPrfKeyFormat format;
+ format.set_key_size(23);
+ format.set_version(0);
+ format.mutable_params()->set_hash(HashType::SHA256);
+
+ IstreamInputStream input_stream{
+ absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
+
+ StatusOr<HmacPrfKey> key_or =
+ HmacPrfKeyManager().DeriveKey(format, &input_stream);
+ ASSERT_THAT(key_or.status(), IsOk());
+ EXPECT_THAT(key_or.ValueOrDie().key_value(), Eq("0123456789abcdefghijklm"));
+ EXPECT_THAT(key_or.ValueOrDie().params().hash(), Eq(format.params().hash()));
+}
+
+TEST(HmacPrfKeyManagerTest, DeriveKeyNotEnoughRandomness) {
+ HmacPrfKeyFormat format;
+ format.set_key_size(17);
+ format.set_version(0);
+ format.mutable_params()->set_hash(HashType::SHA256);
+
+ IstreamInputStream input_stream{
+ absl::make_unique<std::stringstream>("0123456789abcdef")};
+
+ ASSERT_THAT(HmacPrfKeyManager().DeriveKey(format, &input_stream).status(),
+ Not(IsOk()));
+}
+
+TEST(HmacPrfKeyManagerTest, DeriveKeyWrongVersion) {
+ HmacPrfKeyFormat format;
+ format.set_key_size(16);
+ format.set_version(1);
+ format.mutable_params()->set_hash(HashType::SHA256);
+
+ IstreamInputStream input_stream{
+ absl::make_unique<std::stringstream>("0123456789abcdef")};
+
+ ASSERT_THAT(HmacPrfKeyManager().DeriveKey(format, &input_stream).status(),
+ StatusIs(util::error::INVALID_ARGUMENT, HasSubstr("version")));
+}
+
+TEST(HmacPrfKeyManagerTest, GetPrimitive) {
+ HmacPrfKeyFormat key_format;
+ key_format.mutable_params()->set_hash(HashType::SHA256);
+ key_format.set_key_size(16);
+ HmacPrfKey key = HmacPrfKeyManager().CreateKey(key_format).ValueOrDie();
+ auto manager_mac_or = HmacPrfKeyManager().GetPrimitive<PrfSet>(key);
+ ASSERT_THAT(manager_mac_or.status(), IsOk());
+ auto prf_value_or =
+ manager_mac_or.ValueOrDie()->ComputePrimary("some plaintext", 16);
+ ASSERT_THAT(prf_value_or.status(), IsOk());
+
+ auto direct_prf_or = subtle::HmacBoringSsl::New(
+ util::Enums::ProtoToSubtle(key.params().hash()), 16,
+ util::SecretDataFromStringView(key.key_value()));
+ ASSERT_THAT(direct_prf_or.status(), IsOk());
+ auto direct_prf_value_or =
+ direct_prf_or.ValueOrDie()->ComputeMac("some plaintext");
+ ASSERT_THAT(direct_prf_value_or.status(), IsOk());
+ EXPECT_THAT(direct_prf_value_or.ValueOrDie(),
+ StartsWith(prf_value_or.ValueOrDie()));
+}
+
+} // namespace
+} // namespace tink
+} // namespace crypto
diff --git a/cc/prf/prf_key_templates.cc b/cc/prf/prf_key_templates.cc
index 7cba04f91..38e094695 100644
--- a/cc/prf/prf_key_templates.cc
+++ b/cc/prf/prf_key_templates.cc
@@ -15,6 +15,7 @@
#include "absl/memory/memory.h"
#include "tink/prf/aes_cmac_prf_key_manager.h"
+#include "tink/prf/hmac_prf_key_manager.h"
#include "proto/aes_cmac_prf.pb.h"
#include "proto/hkdf_prf.pb.h"
#include "proto/hmac_prf.pb.h"
@@ -44,12 +45,13 @@ std::unique_ptr<google::crypto::tink::KeyTemplate> NewHkdfSha256Template() {
std::unique_ptr<google::crypto::tink::KeyTemplate> NewHmacTemplate(
google::crypto::tink::HashType hash_type, uint32_t key_size) {
auto key_template = absl::make_unique<google::crypto::tink::KeyTemplate>();
- key_template->set_type_url(
- "type.googleapis.com/google.crypto.tink.HmacPrfKey");
+ auto hmac_prf_key_manager = absl::make_unique<HmacPrfKeyManager>();
+ key_template->set_type_url(hmac_prf_key_manager->get_key_type());
key_template->set_output_prefix_type(
google::crypto::tink::OutputPrefixType::RAW);
HmacPrfKeyFormat key_format;
key_format.set_key_size(key_size);
+ key_format.set_version(hmac_prf_key_manager->get_version());
key_format.mutable_params()->set_hash(hash_type);
key_format.SerializeToString(key_template->mutable_value());
return key_template;
diff --git a/cc/prf/prf_key_templates_test.cc b/cc/prf/prf_key_templates_test.cc
index 7795b06bb..10955ab79 100644
--- a/cc/prf/prf_key_templates_test.cc
+++ b/cc/prf/prf_key_templates_test.cc
@@ -19,8 +19,10 @@
#include "absl/memory/memory.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/util/test_matchers.h"
#include "proto/aes_cmac_prf.pb.h"
+#include "proto/hmac_prf.pb.h"
namespace crypto {
namespace tink {
@@ -62,7 +64,14 @@ TEST(HmacPrfTest, Basics) {
Eq("type.googleapis.com/google.crypto.tink.HmacPrfKey"));
EXPECT_THAT(PrfKeyTemplates::HmacSha512().type_url(),
Eq("type.googleapis.com/google.crypto.tink.HmacPrfKey"));
- // TODO(sschmieg): Add key type manager test
+ auto manager = absl::make_unique<HmacPrfKeyManager>();
+ EXPECT_THAT(PrfKeyTemplates::HmacSha256().type_url(),
+ Eq(manager->get_key_type()));
+ google::crypto::tink::HmacPrfKeyFormat format;
+ ASSERT_TRUE(format.ParseFromString(PrfKeyTemplates::HmacSha256().value()));
+ EXPECT_THAT(manager->ValidateKeyFormat(format), IsOk());
+ ASSERT_TRUE(format.ParseFromString(PrfKeyTemplates::HmacSha512().value()));
+ EXPECT_THAT(manager->ValidateKeyFormat(format), IsOk());
}
TEST(HmacPrfTest, OutputPrefixType) {