1*e7b1675dSTing-Kang Chang // Copyright 2023 Google LLC
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang #include "tink/mac/hmac_proto_serialization.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <string>
20*e7b1675dSTing-Kang Chang
21*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
22*e7b1675dSTing-Kang Chang #include "absl/types/optional.h"
23*e7b1675dSTing-Kang Chang #include "tink/internal/key_parser.h"
24*e7b1675dSTing-Kang Chang #include "tink/internal/key_serializer.h"
25*e7b1675dSTing-Kang Chang #include "tink/internal/mutable_serialization_registry.h"
26*e7b1675dSTing-Kang Chang #include "tink/internal/parameters_parser.h"
27*e7b1675dSTing-Kang Chang #include "tink/internal/parameters_serializer.h"
28*e7b1675dSTing-Kang Chang #include "tink/internal/proto_key_serialization.h"
29*e7b1675dSTing-Kang Chang #include "tink/internal/proto_parameters_serialization.h"
30*e7b1675dSTing-Kang Chang #include "tink/mac/hmac_key.h"
31*e7b1675dSTing-Kang Chang #include "tink/mac/hmac_parameters.h"
32*e7b1675dSTing-Kang Chang #include "tink/partial_key_access.h"
33*e7b1675dSTing-Kang Chang #include "tink/restricted_data.h"
34*e7b1675dSTing-Kang Chang #include "tink/secret_key_access_token.h"
35*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
36*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
37*e7b1675dSTing-Kang Chang #include "proto/common.pb.h"
38*e7b1675dSTing-Kang Chang #include "proto/hmac.pb.h"
39*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
40*e7b1675dSTing-Kang Chang
41*e7b1675dSTing-Kang Chang namespace crypto {
42*e7b1675dSTing-Kang Chang namespace tink {
43*e7b1675dSTing-Kang Chang namespace {
44*e7b1675dSTing-Kang Chang
45*e7b1675dSTing-Kang Chang using ::google::crypto::tink::HashType;
46*e7b1675dSTing-Kang Chang using ::google::crypto::tink::HmacKeyFormat;
47*e7b1675dSTing-Kang Chang using ::google::crypto::tink::HmacParams;
48*e7b1675dSTing-Kang Chang using ::google::crypto::tink::OutputPrefixType;
49*e7b1675dSTing-Kang Chang
50*e7b1675dSTing-Kang Chang using HmacProtoParametersParserImpl =
51*e7b1675dSTing-Kang Chang internal::ParametersParserImpl<internal::ProtoParametersSerialization,
52*e7b1675dSTing-Kang Chang HmacParameters>;
53*e7b1675dSTing-Kang Chang using HmacProtoParametersSerializerImpl =
54*e7b1675dSTing-Kang Chang internal::ParametersSerializerImpl<HmacParameters,
55*e7b1675dSTing-Kang Chang internal::ProtoParametersSerialization>;
56*e7b1675dSTing-Kang Chang using HmacProtoKeyParserImpl =
57*e7b1675dSTing-Kang Chang internal::KeyParserImpl<internal::ProtoKeySerialization, HmacKey>;
58*e7b1675dSTing-Kang Chang using HmacProtoKeySerializerImpl =
59*e7b1675dSTing-Kang Chang internal::KeySerializerImpl<HmacKey, internal::ProtoKeySerialization>;
60*e7b1675dSTing-Kang Chang
61*e7b1675dSTing-Kang Chang const absl::string_view kTypeUrl =
62*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.HmacKey";
63*e7b1675dSTing-Kang Chang
ToVariant(OutputPrefixType output_prefix_type)64*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::Variant> ToVariant(
65*e7b1675dSTing-Kang Chang OutputPrefixType output_prefix_type) {
66*e7b1675dSTing-Kang Chang switch (output_prefix_type) {
67*e7b1675dSTing-Kang Chang case OutputPrefixType::CRUNCHY:
68*e7b1675dSTing-Kang Chang return HmacParameters::Variant::kCrunchy;
69*e7b1675dSTing-Kang Chang case OutputPrefixType::LEGACY:
70*e7b1675dSTing-Kang Chang return HmacParameters::Variant::kLegacy;
71*e7b1675dSTing-Kang Chang case OutputPrefixType::RAW:
72*e7b1675dSTing-Kang Chang return HmacParameters::Variant::kNoPrefix;
73*e7b1675dSTing-Kang Chang case OutputPrefixType::TINK:
74*e7b1675dSTing-Kang Chang return HmacParameters::Variant::kTink;
75*e7b1675dSTing-Kang Chang default:
76*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
77*e7b1675dSTing-Kang Chang "Could not determine HmacParameters::Variant");
78*e7b1675dSTing-Kang Chang }
79*e7b1675dSTing-Kang Chang }
80*e7b1675dSTing-Kang Chang
ToOutputPrefixType(HmacParameters::Variant variant)81*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> ToOutputPrefixType(
82*e7b1675dSTing-Kang Chang HmacParameters::Variant variant) {
83*e7b1675dSTing-Kang Chang switch (variant) {
84*e7b1675dSTing-Kang Chang case HmacParameters::Variant::kCrunchy:
85*e7b1675dSTing-Kang Chang return OutputPrefixType::CRUNCHY;
86*e7b1675dSTing-Kang Chang case HmacParameters::Variant::kLegacy:
87*e7b1675dSTing-Kang Chang return OutputPrefixType::LEGACY;
88*e7b1675dSTing-Kang Chang case HmacParameters::Variant::kNoPrefix:
89*e7b1675dSTing-Kang Chang return OutputPrefixType::RAW;
90*e7b1675dSTing-Kang Chang case HmacParameters::Variant::kTink:
91*e7b1675dSTing-Kang Chang return OutputPrefixType::TINK;
92*e7b1675dSTing-Kang Chang default:
93*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
94*e7b1675dSTing-Kang Chang "Could not determine output prefix type");
95*e7b1675dSTing-Kang Chang }
96*e7b1675dSTing-Kang Chang }
97*e7b1675dSTing-Kang Chang
ToHashType(HashType hash_type)98*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::HashType> ToHashType(HashType hash_type) {
99*e7b1675dSTing-Kang Chang switch (hash_type) {
100*e7b1675dSTing-Kang Chang case HashType::SHA1:
101*e7b1675dSTing-Kang Chang return HmacParameters::HashType::kSha1;
102*e7b1675dSTing-Kang Chang case HashType::SHA224:
103*e7b1675dSTing-Kang Chang return HmacParameters::HashType::kSha224;
104*e7b1675dSTing-Kang Chang case HashType::SHA256:
105*e7b1675dSTing-Kang Chang return HmacParameters::HashType::kSha256;
106*e7b1675dSTing-Kang Chang case HashType::SHA384:
107*e7b1675dSTing-Kang Chang return HmacParameters::HashType::kSha384;
108*e7b1675dSTing-Kang Chang case HashType::SHA512:
109*e7b1675dSTing-Kang Chang return HmacParameters::HashType::kSha512;
110*e7b1675dSTing-Kang Chang default:
111*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
112*e7b1675dSTing-Kang Chang "Could not determine HashType");
113*e7b1675dSTing-Kang Chang }
114*e7b1675dSTing-Kang Chang }
115*e7b1675dSTing-Kang Chang
ToProtoHashType(HmacParameters::HashType hash_type)116*e7b1675dSTing-Kang Chang util::StatusOr<HashType> ToProtoHashType(HmacParameters::HashType hash_type) {
117*e7b1675dSTing-Kang Chang switch (hash_type) {
118*e7b1675dSTing-Kang Chang case HmacParameters::HashType::kSha1:
119*e7b1675dSTing-Kang Chang return HashType::SHA1;
120*e7b1675dSTing-Kang Chang case HmacParameters::HashType::kSha224:
121*e7b1675dSTing-Kang Chang return HashType::SHA224;
122*e7b1675dSTing-Kang Chang case HmacParameters::HashType::kSha256:
123*e7b1675dSTing-Kang Chang return HashType::SHA256;
124*e7b1675dSTing-Kang Chang case HmacParameters::HashType::kSha384:
125*e7b1675dSTing-Kang Chang return HashType::SHA384;
126*e7b1675dSTing-Kang Chang case HmacParameters::HashType::kSha512:
127*e7b1675dSTing-Kang Chang return HashType::SHA512;
128*e7b1675dSTing-Kang Chang default:
129*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
130*e7b1675dSTing-Kang Chang "Could not determine HmacParameters::HashType");
131*e7b1675dSTing-Kang Chang }
132*e7b1675dSTing-Kang Chang }
133*e7b1675dSTing-Kang Chang
ParseParameters(const internal::ProtoParametersSerialization & serialization)134*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters> ParseParameters(
135*e7b1675dSTing-Kang Chang const internal::ProtoParametersSerialization& serialization) {
136*e7b1675dSTing-Kang Chang if (serialization.GetKeyTemplate().type_url() != kTypeUrl) {
137*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
138*e7b1675dSTing-Kang Chang "Wrong type URL when parsing HmacParameters.");
139*e7b1675dSTing-Kang Chang }
140*e7b1675dSTing-Kang Chang
141*e7b1675dSTing-Kang Chang HmacKeyFormat proto_key_format;
142*e7b1675dSTing-Kang Chang if (!proto_key_format.ParseFromString(
143*e7b1675dSTing-Kang Chang serialization.GetKeyTemplate().value())) {
144*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
145*e7b1675dSTing-Kang Chang "Failed to parse HmacKeyFormat proto");
146*e7b1675dSTing-Kang Chang }
147*e7b1675dSTing-Kang Chang if (proto_key_format.version() != 0) {
148*e7b1675dSTing-Kang Chang return util::Status(
149*e7b1675dSTing-Kang Chang absl::StatusCode::kInvalidArgument,
150*e7b1675dSTing-Kang Chang "Parsing HmacParameters failed: only version 0 is accepted");
151*e7b1675dSTing-Kang Chang }
152*e7b1675dSTing-Kang Chang
153*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::Variant> variant =
154*e7b1675dSTing-Kang Chang ToVariant(serialization.GetKeyTemplate().output_prefix_type());
155*e7b1675dSTing-Kang Chang if (!variant.ok()) return variant.status();
156*e7b1675dSTing-Kang Chang
157*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::HashType> hash_type =
158*e7b1675dSTing-Kang Chang ToHashType(proto_key_format.params().hash());
159*e7b1675dSTing-Kang Chang if (!hash_type.ok()) return variant.status();
160*e7b1675dSTing-Kang Chang
161*e7b1675dSTing-Kang Chang return HmacParameters::Create(proto_key_format.key_size(),
162*e7b1675dSTing-Kang Chang proto_key_format.params().tag_size(),
163*e7b1675dSTing-Kang Chang *hash_type, *variant);
164*e7b1675dSTing-Kang Chang }
165*e7b1675dSTing-Kang Chang
SerializeParameters(const HmacParameters & parameters)166*e7b1675dSTing-Kang Chang util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters(
167*e7b1675dSTing-Kang Chang const HmacParameters& parameters) {
168*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> output_prefix_type =
169*e7b1675dSTing-Kang Chang ToOutputPrefixType(parameters.GetVariant());
170*e7b1675dSTing-Kang Chang if (!output_prefix_type.ok()) return output_prefix_type.status();
171*e7b1675dSTing-Kang Chang util::StatusOr<HashType> proto_hash_type =
172*e7b1675dSTing-Kang Chang ToProtoHashType(parameters.GetHashType());
173*e7b1675dSTing-Kang Chang if (!proto_hash_type.ok()) return proto_hash_type.status();
174*e7b1675dSTing-Kang Chang
175*e7b1675dSTing-Kang Chang HmacParams proto_params;
176*e7b1675dSTing-Kang Chang proto_params.set_tag_size(parameters.CryptographicTagSizeInBytes());
177*e7b1675dSTing-Kang Chang proto_params.set_hash(*proto_hash_type);
178*e7b1675dSTing-Kang Chang HmacKeyFormat proto_key_format;
179*e7b1675dSTing-Kang Chang proto_key_format.set_key_size(parameters.KeySizeInBytes());
180*e7b1675dSTing-Kang Chang proto_key_format.set_version(0);
181*e7b1675dSTing-Kang Chang *proto_key_format.mutable_params() = proto_params;
182*e7b1675dSTing-Kang Chang
183*e7b1675dSTing-Kang Chang return internal::ProtoParametersSerialization::Create(
184*e7b1675dSTing-Kang Chang kTypeUrl, *output_prefix_type, proto_key_format.SerializeAsString());
185*e7b1675dSTing-Kang Chang }
186*e7b1675dSTing-Kang Chang
ParseKey(const internal::ProtoKeySerialization & serialization,absl::optional<SecretKeyAccessToken> token)187*e7b1675dSTing-Kang Chang util::StatusOr<HmacKey> ParseKey(
188*e7b1675dSTing-Kang Chang const internal::ProtoKeySerialization& serialization,
189*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken> token) {
190*e7b1675dSTing-Kang Chang if (serialization.TypeUrl() != kTypeUrl) {
191*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
192*e7b1675dSTing-Kang Chang "Wrong type URL when parsing HmacKey.");
193*e7b1675dSTing-Kang Chang }
194*e7b1675dSTing-Kang Chang if (!token.has_value()) {
195*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
196*e7b1675dSTing-Kang Chang "SecretKeyAccess is required");
197*e7b1675dSTing-Kang Chang }
198*e7b1675dSTing-Kang Chang
199*e7b1675dSTing-Kang Chang google::crypto::tink::HmacKey proto_key;
200*e7b1675dSTing-Kang Chang RestrictedData restricted_data = serialization.SerializedKeyProto();
201*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
202*e7b1675dSTing-Kang Chang if (!proto_key.ParseFromString(
203*e7b1675dSTing-Kang Chang std::string(restricted_data.GetSecret(*token)))) {
204*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
205*e7b1675dSTing-Kang Chang "Failed to parse HmacKey proto");
206*e7b1675dSTing-Kang Chang }
207*e7b1675dSTing-Kang Chang if (proto_key.version() != 0) {
208*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
209*e7b1675dSTing-Kang Chang "Only version 0 keys are accepted.");
210*e7b1675dSTing-Kang Chang }
211*e7b1675dSTing-Kang Chang
212*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::Variant> variant =
213*e7b1675dSTing-Kang Chang ToVariant(serialization.GetOutputPrefixType());
214*e7b1675dSTing-Kang Chang if (!variant.ok()) return variant.status();
215*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters::HashType> hash_type =
216*e7b1675dSTing-Kang Chang ToHashType(proto_key.params().hash());
217*e7b1675dSTing-Kang Chang if (!hash_type.ok()) return variant.status();
218*e7b1675dSTing-Kang Chang
219*e7b1675dSTing-Kang Chang util::StatusOr<HmacParameters> parameters = HmacParameters::Create(
220*e7b1675dSTing-Kang Chang proto_key.key_value().length(), proto_key.params().tag_size(), *hash_type,
221*e7b1675dSTing-Kang Chang *variant);
222*e7b1675dSTing-Kang Chang if (!parameters.ok()) return parameters.status();
223*e7b1675dSTing-Kang Chang
224*e7b1675dSTing-Kang Chang return HmacKey::Create(*parameters,
225*e7b1675dSTing-Kang Chang RestrictedData(proto_key.key_value(), *token),
226*e7b1675dSTing-Kang Chang serialization.IdRequirement(), GetPartialKeyAccess());
227*e7b1675dSTing-Kang Chang }
228*e7b1675dSTing-Kang Chang
SerializeKey(const HmacKey & key,absl::optional<SecretKeyAccessToken> token)229*e7b1675dSTing-Kang Chang util::StatusOr<internal::ProtoKeySerialization> SerializeKey(
230*e7b1675dSTing-Kang Chang const HmacKey& key, absl::optional<SecretKeyAccessToken> token) {
231*e7b1675dSTing-Kang Chang util::StatusOr<RestrictedData> restricted_input =
232*e7b1675dSTing-Kang Chang key.GetKeyBytes(GetPartialKeyAccess());
233*e7b1675dSTing-Kang Chang if (!token.has_value()) {
234*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
235*e7b1675dSTing-Kang Chang "SecretKeyAccess is required");
236*e7b1675dSTing-Kang Chang }
237*e7b1675dSTing-Kang Chang if (!restricted_input.ok()) return restricted_input.status();
238*e7b1675dSTing-Kang Chang util::StatusOr<HashType> proto_hash_type =
239*e7b1675dSTing-Kang Chang ToProtoHashType(key.GetParameters().GetHashType());
240*e7b1675dSTing-Kang Chang if (!proto_hash_type.ok()) return proto_hash_type.status();
241*e7b1675dSTing-Kang Chang
242*e7b1675dSTing-Kang Chang HmacParams proto_params;
243*e7b1675dSTing-Kang Chang proto_params.set_tag_size(key.GetParameters().CryptographicTagSizeInBytes());
244*e7b1675dSTing-Kang Chang proto_params.set_hash(*proto_hash_type);
245*e7b1675dSTing-Kang Chang google::crypto::tink::HmacKey proto_key;
246*e7b1675dSTing-Kang Chang *proto_key.mutable_params() = proto_params;
247*e7b1675dSTing-Kang Chang proto_key.set_version(0);
248*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
249*e7b1675dSTing-Kang Chang proto_key.set_key_value(std::string(restricted_input->GetSecret(*token)));
250*e7b1675dSTing-Kang Chang
251*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> output_prefix_type =
252*e7b1675dSTing-Kang Chang ToOutputPrefixType(key.GetParameters().GetVariant());
253*e7b1675dSTing-Kang Chang if (!output_prefix_type.ok()) return output_prefix_type.status();
254*e7b1675dSTing-Kang Chang
255*e7b1675dSTing-Kang Chang RestrictedData restricted_output =
256*e7b1675dSTing-Kang Chang RestrictedData(proto_key.SerializeAsString(), *token);
257*e7b1675dSTing-Kang Chang return internal::ProtoKeySerialization::Create(
258*e7b1675dSTing-Kang Chang kTypeUrl, restricted_output, google::crypto::tink::KeyData::SYMMETRIC,
259*e7b1675dSTing-Kang Chang *output_prefix_type, key.GetIdRequirement());
260*e7b1675dSTing-Kang Chang }
261*e7b1675dSTing-Kang Chang
HmacProtoParametersParser()262*e7b1675dSTing-Kang Chang HmacProtoParametersParserImpl* HmacProtoParametersParser() {
263*e7b1675dSTing-Kang Chang static auto* parser =
264*e7b1675dSTing-Kang Chang new HmacProtoParametersParserImpl(kTypeUrl, ParseParameters);
265*e7b1675dSTing-Kang Chang return parser;
266*e7b1675dSTing-Kang Chang }
267*e7b1675dSTing-Kang Chang
HmacProtoParametersSerializer()268*e7b1675dSTing-Kang Chang HmacProtoParametersSerializerImpl* HmacProtoParametersSerializer() {
269*e7b1675dSTing-Kang Chang static auto* serializer =
270*e7b1675dSTing-Kang Chang new HmacProtoParametersSerializerImpl(kTypeUrl, SerializeParameters);
271*e7b1675dSTing-Kang Chang return serializer;
272*e7b1675dSTing-Kang Chang }
273*e7b1675dSTing-Kang Chang
HmacProtoKeyParser()274*e7b1675dSTing-Kang Chang HmacProtoKeyParserImpl* HmacProtoKeyParser() {
275*e7b1675dSTing-Kang Chang static auto* parser = new HmacProtoKeyParserImpl(kTypeUrl, ParseKey);
276*e7b1675dSTing-Kang Chang return parser;
277*e7b1675dSTing-Kang Chang }
278*e7b1675dSTing-Kang Chang
HmacProtoKeySerializer()279*e7b1675dSTing-Kang Chang HmacProtoKeySerializerImpl* HmacProtoKeySerializer() {
280*e7b1675dSTing-Kang Chang static auto* serializer = new HmacProtoKeySerializerImpl(SerializeKey);
281*e7b1675dSTing-Kang Chang return serializer;
282*e7b1675dSTing-Kang Chang }
283*e7b1675dSTing-Kang Chang
284*e7b1675dSTing-Kang Chang } // namespace
285*e7b1675dSTing-Kang Chang
RegisterHmacProtoSerialization()286*e7b1675dSTing-Kang Chang util::Status RegisterHmacProtoSerialization() {
287*e7b1675dSTing-Kang Chang util::Status status =
288*e7b1675dSTing-Kang Chang internal::MutableSerializationRegistry::GlobalInstance()
289*e7b1675dSTing-Kang Chang .RegisterParametersParser(HmacProtoParametersParser());
290*e7b1675dSTing-Kang Chang if (!status.ok()) return status;
291*e7b1675dSTing-Kang Chang
292*e7b1675dSTing-Kang Chang status = internal::MutableSerializationRegistry::GlobalInstance()
293*e7b1675dSTing-Kang Chang .RegisterParametersSerializer(HmacProtoParametersSerializer());
294*e7b1675dSTing-Kang Chang if (!status.ok()) return status;
295*e7b1675dSTing-Kang Chang
296*e7b1675dSTing-Kang Chang status = internal::MutableSerializationRegistry::GlobalInstance()
297*e7b1675dSTing-Kang Chang .RegisterKeyParser(HmacProtoKeyParser());
298*e7b1675dSTing-Kang Chang if (!status.ok()) return status;
299*e7b1675dSTing-Kang Chang
300*e7b1675dSTing-Kang Chang return internal::MutableSerializationRegistry::GlobalInstance()
301*e7b1675dSTing-Kang Chang .RegisterKeySerializer(HmacProtoKeySerializer());
302*e7b1675dSTing-Kang Chang }
303*e7b1675dSTing-Kang Chang
304*e7b1675dSTing-Kang Chang } // namespace tink
305*e7b1675dSTing-Kang Chang } // namespace crypto
306