xref: /aosp_15_r20/external/tink/cc/mac/hmac_key_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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_key.h"
18*e7b1675dSTing-Kang Chang 
19*e7b1675dSTing-Kang Chang #include <memory>
20*e7b1675dSTing-Kang Chang #include <string>
21*e7b1675dSTing-Kang Chang #include <tuple>
22*e7b1675dSTing-Kang Chang #include <utility>
23*e7b1675dSTing-Kang Chang 
24*e7b1675dSTing-Kang Chang #include "gmock/gmock.h"
25*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
26*e7b1675dSTing-Kang Chang #include "absl/types/optional.h"
27*e7b1675dSTing-Kang Chang #include "tink/mac/hmac_parameters.h"
28*e7b1675dSTing-Kang Chang #include "tink/partial_key_access.h"
29*e7b1675dSTing-Kang Chang #include "tink/restricted_data.h"
30*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
31*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
32*e7b1675dSTing-Kang Chang 
33*e7b1675dSTing-Kang Chang namespace crypto {
34*e7b1675dSTing-Kang Chang namespace tink {
35*e7b1675dSTing-Kang Chang namespace {
36*e7b1675dSTing-Kang Chang 
37*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
38*e7b1675dSTing-Kang Chang using ::crypto::tink::test::StatusIs;
39*e7b1675dSTing-Kang Chang using ::testing::Combine;
40*e7b1675dSTing-Kang Chang using ::testing::Eq;
41*e7b1675dSTing-Kang Chang using ::testing::Range;
42*e7b1675dSTing-Kang Chang using ::testing::TestWithParam;
43*e7b1675dSTing-Kang Chang using ::testing::Values;
44*e7b1675dSTing-Kang Chang 
45*e7b1675dSTing-Kang Chang struct TestCase {
46*e7b1675dSTing-Kang Chang   HmacParameters::Variant variant;
47*e7b1675dSTing-Kang Chang   absl::optional<int> id_requirement;
48*e7b1675dSTing-Kang Chang   std::string output_prefix;
49*e7b1675dSTing-Kang Chang };
50*e7b1675dSTing-Kang Chang 
51*e7b1675dSTing-Kang Chang using HmacKeyTest =
52*e7b1675dSTing-Kang Chang     TestWithParam<std::tuple<int, int, HmacParameters::HashType, TestCase>>;
53*e7b1675dSTing-Kang Chang 
54*e7b1675dSTing-Kang Chang INSTANTIATE_TEST_SUITE_P(
55*e7b1675dSTing-Kang Chang     HmacKeyTestSuite, HmacKeyTest,
56*e7b1675dSTing-Kang Chang     Combine(Values(16, 32), Range(10, 20),
57*e7b1675dSTing-Kang Chang             Values(HmacParameters::HashType::kSha1,
58*e7b1675dSTing-Kang Chang                    HmacParameters::HashType::kSha224,
59*e7b1675dSTing-Kang Chang                    HmacParameters::HashType::kSha256,
60*e7b1675dSTing-Kang Chang                    HmacParameters::HashType::kSha384,
61*e7b1675dSTing-Kang Chang                    HmacParameters::HashType::kSha512),
62*e7b1675dSTing-Kang Chang             Values(TestCase{HmacParameters::Variant::kTink, 0x02030400,
63*e7b1675dSTing-Kang Chang                             std::string("\x01\x02\x03\x04\x00", 5)},
64*e7b1675dSTing-Kang Chang                    TestCase{HmacParameters::Variant::kCrunchy, 0x01030005,
65*e7b1675dSTing-Kang Chang                             std::string("\x00\x01\x03\x00\x05", 5)},
66*e7b1675dSTing-Kang Chang                    TestCase{HmacParameters::Variant::kLegacy, 0x01020304,
67*e7b1675dSTing-Kang Chang                             std::string("\x00\x01\x02\x03\x04", 5)},
68*e7b1675dSTing-Kang Chang                    TestCase{HmacParameters::Variant::kNoPrefix, absl::nullopt,
69*e7b1675dSTing-Kang Chang                             ""})));
70*e7b1675dSTing-Kang Chang 
TEST_P(HmacKeyTest,CreateSucceeds)71*e7b1675dSTing-Kang Chang TEST_P(HmacKeyTest, CreateSucceeds) {
72*e7b1675dSTing-Kang Chang   int key_size;
73*e7b1675dSTing-Kang Chang   int cryptographic_tag_size;
74*e7b1675dSTing-Kang Chang   HmacParameters::HashType hash_type;
75*e7b1675dSTing-Kang Chang   TestCase test_case;
76*e7b1675dSTing-Kang Chang   std::tie(key_size, cryptographic_tag_size, hash_type, test_case) = GetParam();
77*e7b1675dSTing-Kang Chang 
78*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
79*e7b1675dSTing-Kang Chang       key_size, cryptographic_tag_size, hash_type, test_case.variant);
80*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
81*e7b1675dSTing-Kang Chang 
82*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(key_size);
83*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key = HmacKey::Create(
84*e7b1675dSTing-Kang Chang       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
85*e7b1675dSTing-Kang Chang   ASSERT_THAT(key.status(), IsOk());
86*e7b1675dSTing-Kang Chang 
87*e7b1675dSTing-Kang Chang   EXPECT_THAT(key->GetParameters(), Eq(*params));
88*e7b1675dSTing-Kang Chang   EXPECT_THAT(key->GetIdRequirement(), Eq(test_case.id_requirement));
89*e7b1675dSTing-Kang Chang   EXPECT_THAT(key->GetOutputPrefix(), Eq(test_case.output_prefix));
90*e7b1675dSTing-Kang Chang }
91*e7b1675dSTing-Kang Chang 
TEST(HmacKeyTest,CreateKeyWithMismatchedKeySizeFails)92*e7b1675dSTing-Kang Chang TEST(HmacKeyTest, CreateKeyWithMismatchedKeySizeFails) {
93*e7b1675dSTing-Kang Chang   // Key size parameter is 32 bytes.
94*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
95*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
96*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha256, HmacParameters::Variant::kTink);
97*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
98*e7b1675dSTing-Kang Chang 
99*e7b1675dSTing-Kang Chang   // Key material is 16 bytes (another valid key length).
100*e7b1675dSTing-Kang Chang   RestrictedData mismatched_secret = RestrictedData(/*num_random_bytes=*/16);
101*e7b1675dSTing-Kang Chang 
102*e7b1675dSTing-Kang Chang   EXPECT_THAT(HmacKey::Create(*params, mismatched_secret,
103*e7b1675dSTing-Kang Chang                               /*id_requirement=*/123, GetPartialKeyAccess())
104*e7b1675dSTing-Kang Chang                   .status(),
105*e7b1675dSTing-Kang Chang               StatusIs(absl::StatusCode::kInvalidArgument));
106*e7b1675dSTing-Kang Chang }
107*e7b1675dSTing-Kang Chang 
TEST(HmacKeyTest,CreateKeyWithWrongIdRequirementFails)108*e7b1675dSTing-Kang Chang TEST(HmacKeyTest, CreateKeyWithWrongIdRequirementFails) {
109*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> no_prefix_params = HmacParameters::Create(
110*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
111*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha512, HmacParameters::Variant::kNoPrefix);
112*e7b1675dSTing-Kang Chang   ASSERT_THAT(no_prefix_params, IsOk());
113*e7b1675dSTing-Kang Chang 
114*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> tink_params = HmacParameters::Create(
115*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
116*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha512, HmacParameters::Variant::kTink);
117*e7b1675dSTing-Kang Chang   ASSERT_THAT(tink_params, IsOk());
118*e7b1675dSTing-Kang Chang 
119*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
120*e7b1675dSTing-Kang Chang 
121*e7b1675dSTing-Kang Chang   EXPECT_THAT(HmacKey::Create(*no_prefix_params, secret,
122*e7b1675dSTing-Kang Chang                               /*id_requirement=*/123, GetPartialKeyAccess())
123*e7b1675dSTing-Kang Chang                   .status(),
124*e7b1675dSTing-Kang Chang               StatusIs(absl::StatusCode::kInvalidArgument));
125*e7b1675dSTing-Kang Chang   EXPECT_THAT(
126*e7b1675dSTing-Kang Chang       HmacKey::Create(*tink_params, secret,
127*e7b1675dSTing-Kang Chang                       /*id_requirement=*/absl::nullopt, GetPartialKeyAccess())
128*e7b1675dSTing-Kang Chang           .status(),
129*e7b1675dSTing-Kang Chang       StatusIs(absl::StatusCode::kInvalidArgument));
130*e7b1675dSTing-Kang Chang }
131*e7b1675dSTing-Kang Chang 
TEST_P(HmacKeyTest,GetKeyBytes)132*e7b1675dSTing-Kang Chang TEST_P(HmacKeyTest, GetKeyBytes) {
133*e7b1675dSTing-Kang Chang   int key_size;
134*e7b1675dSTing-Kang Chang   int cryptographic_tag_size;
135*e7b1675dSTing-Kang Chang   HmacParameters::HashType hash_type;
136*e7b1675dSTing-Kang Chang   TestCase test_case;
137*e7b1675dSTing-Kang Chang   std::tie(key_size, cryptographic_tag_size, hash_type, test_case) = GetParam();
138*e7b1675dSTing-Kang Chang 
139*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
140*e7b1675dSTing-Kang Chang       key_size, cryptographic_tag_size, hash_type, test_case.variant);
141*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
142*e7b1675dSTing-Kang Chang 
143*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(key_size);
144*e7b1675dSTing-Kang Chang 
145*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key = HmacKey::Create(
146*e7b1675dSTing-Kang Chang       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
147*e7b1675dSTing-Kang Chang   ASSERT_THAT(key.status(), IsOk());
148*e7b1675dSTing-Kang Chang 
149*e7b1675dSTing-Kang Chang   EXPECT_THAT(key->GetKeyBytes(GetPartialKeyAccess()), Eq(secret));
150*e7b1675dSTing-Kang Chang }
151*e7b1675dSTing-Kang Chang 
TEST_P(HmacKeyTest,KeyEquals)152*e7b1675dSTing-Kang Chang TEST_P(HmacKeyTest, KeyEquals) {
153*e7b1675dSTing-Kang Chang   int key_size;
154*e7b1675dSTing-Kang Chang   int cryptographic_tag_size;
155*e7b1675dSTing-Kang Chang   HmacParameters::HashType hash_type;
156*e7b1675dSTing-Kang Chang   TestCase test_case;
157*e7b1675dSTing-Kang Chang   std::tie(key_size, cryptographic_tag_size, hash_type, test_case) = GetParam();
158*e7b1675dSTing-Kang Chang 
159*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
160*e7b1675dSTing-Kang Chang       key_size, cryptographic_tag_size, hash_type, test_case.variant);
161*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
162*e7b1675dSTing-Kang Chang 
163*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(key_size);
164*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key = HmacKey::Create(
165*e7b1675dSTing-Kang Chang       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
166*e7b1675dSTing-Kang Chang   ASSERT_THAT(key, IsOk());
167*e7b1675dSTing-Kang Chang 
168*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> other_key = HmacKey::Create(
169*e7b1675dSTing-Kang Chang       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
170*e7b1675dSTing-Kang Chang   ASSERT_THAT(other_key, IsOk());
171*e7b1675dSTing-Kang Chang 
172*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*key == *other_key);
173*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*other_key == *key);
174*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*key != *other_key);
175*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*other_key != *key);
176*e7b1675dSTing-Kang Chang }
177*e7b1675dSTing-Kang Chang 
TEST(HmacKeyTest,DifferentFormatNotEqual)178*e7b1675dSTing-Kang Chang TEST(HmacKeyTest, DifferentFormatNotEqual) {
179*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> legacy_params = HmacParameters::Create(
180*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
181*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha256, HmacParameters::Variant::kLegacy);
182*e7b1675dSTing-Kang Chang   ASSERT_THAT(legacy_params, IsOk());
183*e7b1675dSTing-Kang Chang 
184*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> tink_params = HmacParameters::Create(
185*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
186*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha256, HmacParameters::Variant::kTink);
187*e7b1675dSTing-Kang Chang   ASSERT_THAT(tink_params, IsOk());
188*e7b1675dSTing-Kang Chang 
189*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
190*e7b1675dSTing-Kang Chang 
191*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key =
192*e7b1675dSTing-Kang Chang       HmacKey::Create(*legacy_params, secret, /*id_requirement=*/0x01020304,
193*e7b1675dSTing-Kang Chang                       GetPartialKeyAccess());
194*e7b1675dSTing-Kang Chang   ASSERT_THAT(key.status(), IsOk());
195*e7b1675dSTing-Kang Chang 
196*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> other_key =
197*e7b1675dSTing-Kang Chang       HmacKey::Create(*tink_params, secret, /*id_requirement=*/0x01020304,
198*e7b1675dSTing-Kang Chang                       GetPartialKeyAccess());
199*e7b1675dSTing-Kang Chang   ASSERT_THAT(other_key.status(), IsOk());
200*e7b1675dSTing-Kang Chang 
201*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*key != *other_key);
202*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*other_key != *key);
203*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*key == *other_key);
204*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*other_key == *key);
205*e7b1675dSTing-Kang Chang }
206*e7b1675dSTing-Kang Chang 
TEST(HmacKeyTest,DifferentSecretDataNotEqual)207*e7b1675dSTing-Kang Chang TEST(HmacKeyTest, DifferentSecretDataNotEqual) {
208*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
209*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
210*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha384, HmacParameters::Variant::kTink);
211*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
212*e7b1675dSTing-Kang Chang 
213*e7b1675dSTing-Kang Chang   RestrictedData secret1 = RestrictedData(/*num_random_bytes=*/32);
214*e7b1675dSTing-Kang Chang   RestrictedData secret2 = RestrictedData(/*num_random_bytes=*/32);
215*e7b1675dSTing-Kang Chang 
216*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key = HmacKey::Create(
217*e7b1675dSTing-Kang Chang       *params, secret1, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
218*e7b1675dSTing-Kang Chang   ASSERT_THAT(key.status(), IsOk());
219*e7b1675dSTing-Kang Chang 
220*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> other_key = HmacKey::Create(
221*e7b1675dSTing-Kang Chang       *params, secret2, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
222*e7b1675dSTing-Kang Chang   ASSERT_THAT(other_key.status(), IsOk());
223*e7b1675dSTing-Kang Chang 
224*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*key != *other_key);
225*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*other_key != *key);
226*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*key == *other_key);
227*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*other_key == *key);
228*e7b1675dSTing-Kang Chang }
229*e7b1675dSTing-Kang Chang 
TEST(HmacKeyTest,DifferentIdRequirementNotEqual)230*e7b1675dSTing-Kang Chang TEST(HmacKeyTest, DifferentIdRequirementNotEqual) {
231*e7b1675dSTing-Kang Chang   util::StatusOr<HmacParameters> params = HmacParameters::Create(
232*e7b1675dSTing-Kang Chang       /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
233*e7b1675dSTing-Kang Chang       HmacParameters::HashType::kSha224, HmacParameters::Variant::kTink);
234*e7b1675dSTing-Kang Chang   ASSERT_THAT(params, IsOk());
235*e7b1675dSTing-Kang Chang 
236*e7b1675dSTing-Kang Chang   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
237*e7b1675dSTing-Kang Chang 
238*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> key = HmacKey::Create(
239*e7b1675dSTing-Kang Chang       *params, secret, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
240*e7b1675dSTing-Kang Chang   ASSERT_THAT(key.status(), IsOk());
241*e7b1675dSTing-Kang Chang 
242*e7b1675dSTing-Kang Chang   util::StatusOr<HmacKey> other_key = HmacKey::Create(
243*e7b1675dSTing-Kang Chang       *params, secret, /*id_requirement=*/0x02030405, GetPartialKeyAccess());
244*e7b1675dSTing-Kang Chang   ASSERT_THAT(other_key.status(), IsOk());
245*e7b1675dSTing-Kang Chang 
246*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*key != *other_key);
247*e7b1675dSTing-Kang Chang   EXPECT_TRUE(*other_key != *key);
248*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*key == *other_key);
249*e7b1675dSTing-Kang Chang   EXPECT_FALSE(*other_key == *key);
250*e7b1675dSTing-Kang Chang }
251*e7b1675dSTing-Kang Chang 
252*e7b1675dSTing-Kang Chang }  // namespace
253*e7b1675dSTing-Kang Chang }  // namespace tink
254*e7b1675dSTing-Kang Chang }  // namespace crypto
255