xref: /aosp_15_r20/external/tink/cc/mac/aes_cmac_key_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 #include "tink/mac/aes_cmac_key.h"
18 
19 #include <memory>
20 #include <string>
21 #include <tuple>
22 #include <utility>
23 
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/types/optional.h"
27 #include "tink/mac/aes_cmac_parameters.h"
28 #include "tink/partial_key_access.h"
29 #include "tink/restricted_data.h"
30 #include "tink/util/statusor.h"
31 #include "tink/util/test_matchers.h"
32 
33 namespace crypto {
34 namespace tink {
35 namespace {
36 
37 using ::crypto::tink::test::IsOk;
38 using ::crypto::tink::test::StatusIs;
39 using ::testing::Combine;
40 using ::testing::Eq;
41 using ::testing::Range;
42 using ::testing::TestWithParam;
43 using ::testing::Values;
44 
45 struct TestCase {
46   AesCmacParameters::Variant variant;
47   absl::optional<int> id_requirement;
48   std::string output_prefix;
49 };
50 
51 using AesCmacKeyTest = TestWithParam<std::tuple<int, int, TestCase>>;
52 
53 INSTANTIATE_TEST_SUITE_P(
54     AesCmacKeyTestSuite, AesCmacKeyTest,
55     Combine(Values(16, 32), Range(10, 16),
56             Values(TestCase{AesCmacParameters::Variant::kTink, 0x02030400,
57                             std::string("\x01\x02\x03\x04\x00", 5)},
58                    TestCase{AesCmacParameters::Variant::kCrunchy, 0x01030005,
59                             std::string("\x00\x01\x03\x00\x05", 5)},
60                    TestCase{AesCmacParameters::Variant::kLegacy, 0x01020304,
61                             std::string("\x00\x01\x02\x03\x04", 5)},
62                    TestCase{AesCmacParameters::Variant::kNoPrefix,
63                             absl::nullopt, ""})));
64 
TEST_P(AesCmacKeyTest,CreateSucceeds)65 TEST_P(AesCmacKeyTest, CreateSucceeds) {
66   int key_size;
67   int cryptographic_tag_size;
68   TestCase test_case;
69   std::tie(key_size, cryptographic_tag_size, test_case) = GetParam();
70 
71   util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
72       key_size, cryptographic_tag_size, test_case.variant);
73   ASSERT_THAT(params, IsOk());
74 
75   RestrictedData secret = RestrictedData(key_size);
76   util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
77       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
78   ASSERT_THAT(key.status(), IsOk());
79 
80   EXPECT_THAT(key->GetParameters(), Eq(*params));
81   EXPECT_THAT(key->GetIdRequirement(), Eq(test_case.id_requirement));
82   EXPECT_THAT(key->GetOutputPrefix(), Eq(test_case.output_prefix));
83 }
84 
TEST(AesCmacKeyTest,CreateKeyWithMismatchedKeySizeFails)85 TEST(AesCmacKeyTest, CreateKeyWithMismatchedKeySizeFails) {
86   // Key size parameter is 32 bytes.
87   util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
88       /*key_size_in_bytes=*/32,
89       /*cryptographic_tag_size_in_bytes=*/16,
90       AesCmacParameters::Variant::kTink);
91   ASSERT_THAT(params, IsOk());
92 
93   // Key material is 16 bytes (another valid key length).
94   RestrictedData mismatched_secret = RestrictedData(/*num_random_bytes=*/16);
95 
96   EXPECT_THAT(AesCmacKey::Create(*params, mismatched_secret,
97                                  /*id_requirement=*/123, GetPartialKeyAccess())
98                   .status(),
99               StatusIs(absl::StatusCode::kInvalidArgument));
100 }
101 
TEST(AesCmacKeyTest,CreateKeyWithWrongIdRequirementFails)102 TEST(AesCmacKeyTest, CreateKeyWithWrongIdRequirementFails) {
103   util::StatusOr<AesCmacParameters> no_prefix_params =
104       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
105                                 /*cryptographic_tag_size_in_bytes=*/16,
106                                 AesCmacParameters::Variant::kNoPrefix);
107   ASSERT_THAT(no_prefix_params, IsOk());
108 
109   util::StatusOr<AesCmacParameters> tink_params =
110       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
111                                 /*cryptographic_tag_size_in_bytes=*/16,
112                                 AesCmacParameters::Variant::kTink);
113   ASSERT_THAT(tink_params, IsOk());
114 
115   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
116 
117   EXPECT_THAT(AesCmacKey::Create(*no_prefix_params, secret,
118                                  /*id_requirement=*/123, GetPartialKeyAccess())
119                   .status(),
120               StatusIs(absl::StatusCode::kInvalidArgument));
121   EXPECT_THAT(AesCmacKey::Create(*tink_params, secret,
122                                  /*id_requirement=*/absl::nullopt,
123                                  GetPartialKeyAccess())
124                   .status(),
125               StatusIs(absl::StatusCode::kInvalidArgument));
126 }
127 
TEST_P(AesCmacKeyTest,GetAesCmacKey)128 TEST_P(AesCmacKeyTest, GetAesCmacKey) {
129   int key_size;
130   int cryptographic_tag_size;
131   TestCase test_case;
132   std::tie(key_size, cryptographic_tag_size, test_case) = GetParam();
133 
134   util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
135       key_size, cryptographic_tag_size, test_case.variant);
136   ASSERT_THAT(params, IsOk());
137 
138   RestrictedData secret = RestrictedData(key_size);
139 
140   util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
141       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
142   ASSERT_THAT(key.status(), IsOk());
143 
144   EXPECT_THAT(key->GetKeyBytes(GetPartialKeyAccess()), Eq(secret));
145 }
146 
TEST_P(AesCmacKeyTest,KeyEquals)147 TEST_P(AesCmacKeyTest, KeyEquals) {
148   int key_size;
149   int cryptographic_tag_size;
150   TestCase test_case;
151   std::tie(key_size, cryptographic_tag_size, test_case) = GetParam();
152 
153   util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
154       key_size, cryptographic_tag_size, test_case.variant);
155   ASSERT_THAT(params, IsOk());
156 
157   RestrictedData secret = RestrictedData(key_size);
158   util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
159       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
160   ASSERT_THAT(key, IsOk());
161 
162   util::StatusOr<AesCmacKey> other_key = AesCmacKey::Create(
163       *params, secret, test_case.id_requirement, GetPartialKeyAccess());
164   ASSERT_THAT(other_key, IsOk());
165 
166   EXPECT_TRUE(*key == *other_key);
167   EXPECT_TRUE(*other_key == *key);
168   EXPECT_FALSE(*key != *other_key);
169   EXPECT_FALSE(*other_key != *key);
170 }
171 
TEST(AesCmacKeyTest,DifferentFormatNotEqual)172 TEST(AesCmacKeyTest, DifferentFormatNotEqual) {
173   util::StatusOr<AesCmacParameters> legacy_params =
174       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
175                                 /*cryptographic_tag_size_in_bytes=*/16,
176                                 AesCmacParameters::Variant::kLegacy);
177   ASSERT_THAT(legacy_params, IsOk());
178 
179   util::StatusOr<AesCmacParameters> tink_params =
180       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
181                                 /*cryptographic_tag_size_in_bytes=*/16,
182                                 AesCmacParameters::Variant::kTink);
183   ASSERT_THAT(tink_params, IsOk());
184 
185   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
186 
187   util::StatusOr<AesCmacKey> key =
188       AesCmacKey::Create(*legacy_params, secret, /*id_requirement=*/0x01020304,
189                          GetPartialKeyAccess());
190   ASSERT_THAT(key.status(), IsOk());
191 
192   util::StatusOr<AesCmacKey> other_key =
193       AesCmacKey::Create(*tink_params, secret, /*id_requirement=*/0x01020304,
194                          GetPartialKeyAccess());
195   ASSERT_THAT(other_key.status(), IsOk());
196 
197   EXPECT_TRUE(*key != *other_key);
198   EXPECT_TRUE(*other_key != *key);
199   EXPECT_FALSE(*key == *other_key);
200   EXPECT_FALSE(*other_key == *key);
201 }
202 
TEST(AesCmacKeyTest,DifferentSecretDataNotEqual)203 TEST(AesCmacKeyTest, DifferentSecretDataNotEqual) {
204   util::StatusOr<AesCmacParameters> params =
205       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
206                                 /*cryptographic_tag_size_in_bytes=*/16,
207                                 AesCmacParameters::Variant::kTink);
208   ASSERT_THAT(params, IsOk());
209 
210   RestrictedData secret1 = RestrictedData(/*num_random_bytes=*/32);
211   RestrictedData secret2 = RestrictedData(/*num_random_bytes=*/32);
212 
213   util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
214       *params, secret1, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
215   ASSERT_THAT(key.status(), IsOk());
216 
217   util::StatusOr<AesCmacKey> other_key = AesCmacKey::Create(
218       *params, secret2, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
219   ASSERT_THAT(other_key.status(), IsOk());
220 
221   EXPECT_TRUE(*key != *other_key);
222   EXPECT_TRUE(*other_key != *key);
223   EXPECT_FALSE(*key == *other_key);
224   EXPECT_FALSE(*other_key == *key);
225 }
226 
TEST(AesCmacKeyTest,DifferentIdRequirementNotEqual)227 TEST(AesCmacKeyTest, DifferentIdRequirementNotEqual) {
228   util::StatusOr<AesCmacParameters> params =
229       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
230                                 /*cryptographic_tag_size_in_bytes=*/16,
231                                 AesCmacParameters::Variant::kTink);
232   ASSERT_THAT(params, IsOk());
233 
234   RestrictedData secret = RestrictedData(/*num_random_bytes=*/32);
235 
236   util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
237       *params, secret, /*id_requirement=*/0x01020304, GetPartialKeyAccess());
238   ASSERT_THAT(key.status(), IsOk());
239 
240   util::StatusOr<AesCmacKey> other_key = AesCmacKey::Create(
241       *params, secret, /*id_requirement=*/0x02030405, GetPartialKeyAccess());
242   ASSERT_THAT(other_key.status(), IsOk());
243 
244   EXPECT_TRUE(*key != *other_key);
245   EXPECT_TRUE(*other_key != *key);
246   EXPECT_FALSE(*key == *other_key);
247   EXPECT_FALSE(*other_key == *key);
248 }
249 
250 }  // namespace
251 }  // namespace tink
252 }  // namespace crypto
253