1 // Copyright 2023 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/aead/aes_gcm_parameters.h"
18
19 #include <tuple>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "tink/util/statusor.h"
24 #include "tink/util/test_matchers.h"
25
26 namespace crypto {
27 namespace tink {
28 namespace {
29
30 using ::crypto::tink::test::IsOk;
31 using ::crypto::tink::test::StatusIs;
32 using ::testing::Combine;
33 using ::testing::Eq;
34 using ::testing::IsTrue;
35 using ::testing::Range;
36 using ::testing::TestWithParam;
37 using ::testing::Values;
38
39 struct BuildTestCase {
40 AesGcmParameters::Variant variant;
41 int key_size;
42 int iv_size;
43 int tag_size;
44 bool has_id_requirement;
45 };
46
47 using AesGcmParametersBuildTest = TestWithParam<BuildTestCase>;
48
49 INSTANTIATE_TEST_SUITE_P(
50 AesGcmParametersBuildTestSuite, AesGcmParametersBuildTest,
51 Values(BuildTestCase{AesGcmParameters::Variant::kTink, /*key_size=*/16,
52 /*iv_size=*/12, /*tag_size=*/12,
53 /*has_id_requirement=*/true},
54 BuildTestCase{AesGcmParameters::Variant::kCrunchy, /*key_size=*/24,
55 /*iv_size=*/14, /*tag_size=*/14,
56 /*has_id_requirement=*/true},
57 BuildTestCase{AesGcmParameters::Variant::kNoPrefix,
58 /*key_size=*/32, /*iv_size=*/16, /*tag_size=*/16,
59 /*has_id_requirement=*/false}));
60
TEST_P(AesGcmParametersBuildTest,Build)61 TEST_P(AesGcmParametersBuildTest, Build) {
62 BuildTestCase test_case = GetParam();
63
64 util::StatusOr<AesGcmParameters> parameters =
65 AesGcmParameters::Builder()
66 .SetKeySizeInBytes(test_case.key_size)
67 .SetIvSizeInBytes(test_case.iv_size)
68 .SetTagSizeInBytes(test_case.tag_size)
69 .SetVariant(test_case.variant)
70 .Build();
71 ASSERT_THAT(parameters, IsOk());
72
73 EXPECT_THAT(parameters->KeySizeInBytes(), Eq(test_case.key_size));
74 EXPECT_THAT(parameters->IvSizeInBytes(), Eq(test_case.iv_size));
75 EXPECT_THAT(parameters->TagSizeInBytes(), Eq(test_case.tag_size));
76 EXPECT_THAT(parameters->GetVariant(), Eq(test_case.variant));
77 EXPECT_THAT(parameters->HasIdRequirement(), Eq(test_case.has_id_requirement));
78 }
79
TEST(AesGcmParametersTest,BuildWithoutSettingVariantFails)80 TEST(AesGcmParametersTest, BuildWithoutSettingVariantFails) {
81 EXPECT_THAT(AesGcmParameters::Builder()
82 .SetKeySizeInBytes(16)
83 .SetIvSizeInBytes(16)
84 .SetTagSizeInBytes(16)
85 .Build()
86 .status(),
87 StatusIs(absl::StatusCode::kInvalidArgument));
88 }
89
TEST(AesGcmParametersTest,BuildWithInvalidVariantFails)90 TEST(AesGcmParametersTest, BuildWithInvalidVariantFails) {
91 EXPECT_THAT(
92 AesGcmParameters::Builder()
93 .SetKeySizeInBytes(32)
94 .SetIvSizeInBytes(16)
95 .SetTagSizeInBytes(16)
96 .SetVariant(AesGcmParameters::Variant::
97 kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements)
98 .Build()
99 .status(),
100 StatusIs(absl::StatusCode::kInvalidArgument));
101 }
102
TEST(AesGcmParametersTest,BuildWithoutSettingKeySizeFails)103 TEST(AesGcmParametersTest, BuildWithoutSettingKeySizeFails) {
104 EXPECT_THAT(AesGcmParameters::Builder()
105 .SetIvSizeInBytes(16)
106 .SetTagSizeInBytes(16)
107 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
108 .Build()
109 .status(),
110 StatusIs(absl::StatusCode::kInvalidArgument));
111 }
112
TEST(AesGcmParametersTest,BuildWithInvalidKeySizeFails)113 TEST(AesGcmParametersTest, BuildWithInvalidKeySizeFails) {
114 EXPECT_THAT(AesGcmParameters::Builder()
115 .SetKeySizeInBytes(15)
116 .SetIvSizeInBytes(16)
117 .SetTagSizeInBytes(16)
118 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
119 .Build()
120 .status(),
121 StatusIs(absl::StatusCode::kInvalidArgument));
122 EXPECT_THAT(AesGcmParameters::Builder()
123 .SetKeySizeInBytes(17)
124 .SetIvSizeInBytes(16)
125 .SetTagSizeInBytes(16)
126 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
127 .Build()
128 .status(),
129 StatusIs(absl::StatusCode::kInvalidArgument));
130 EXPECT_THAT(AesGcmParameters::Builder()
131 .SetKeySizeInBytes(23)
132 .SetIvSizeInBytes(16)
133 .SetTagSizeInBytes(16)
134 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
135 .Build()
136 .status(),
137 StatusIs(absl::StatusCode::kInvalidArgument));
138 EXPECT_THAT(AesGcmParameters::Builder()
139 .SetKeySizeInBytes(25)
140 .SetIvSizeInBytes(16)
141 .SetTagSizeInBytes(16)
142 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
143 .Build()
144 .status(),
145 StatusIs(absl::StatusCode::kInvalidArgument));
146 EXPECT_THAT(AesGcmParameters::Builder()
147 .SetKeySizeInBytes(31)
148 .SetIvSizeInBytes(16)
149 .SetTagSizeInBytes(16)
150 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
151 .Build()
152 .status(),
153 StatusIs(absl::StatusCode::kInvalidArgument));
154 EXPECT_THAT(AesGcmParameters::Builder()
155 .SetKeySizeInBytes(33)
156 .SetIvSizeInBytes(16)
157 .SetTagSizeInBytes(16)
158 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
159 .Build()
160 .status(),
161 StatusIs(absl::StatusCode::kInvalidArgument));
162 }
163
TEST(AesGcmParametersTest,BuildWithoutSettingIvSizeFails)164 TEST(AesGcmParametersTest, BuildWithoutSettingIvSizeFails) {
165 EXPECT_THAT(AesGcmParameters::Builder()
166 .SetKeySizeInBytes(16)
167 .SetTagSizeInBytes(16)
168 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
169 .Build()
170 .status(),
171 StatusIs(absl::StatusCode::kInvalidArgument));
172 }
173
TEST(AesGcmParametersTest,BuildWithInvalidIvSizeFails)174 TEST(AesGcmParametersTest, BuildWithInvalidIvSizeFails) {
175 EXPECT_THAT(AesGcmParameters::Builder()
176 .SetKeySizeInBytes(16)
177 .SetIvSizeInBytes(0)
178 .SetTagSizeInBytes(16)
179 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
180 .Build()
181 .status(),
182 StatusIs(absl::StatusCode::kInvalidArgument));
183 }
184
TEST(AesGcmParametersTest,BuildWithoutSettingTagSizeFails)185 TEST(AesGcmParametersTest, BuildWithoutSettingTagSizeFails) {
186 EXPECT_THAT(AesGcmParameters::Builder()
187 .SetKeySizeInBytes(16)
188 .SetIvSizeInBytes(16)
189 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
190 .Build()
191 .status(),
192 StatusIs(absl::StatusCode::kInvalidArgument));
193 }
194
TEST(AesGcmParametersTest,BuildWithInvalidTagSizeFails)195 TEST(AesGcmParametersTest, BuildWithInvalidTagSizeFails) {
196 // Too small.
197 EXPECT_THAT(AesGcmParameters::Builder()
198 .SetKeySizeInBytes(16)
199 .SetIvSizeInBytes(16)
200 .SetTagSizeInBytes(11)
201 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
202 .Build()
203 .status(),
204 StatusIs(absl::StatusCode::kInvalidArgument));
205 // Too big.
206 EXPECT_THAT(AesGcmParameters::Builder()
207 .SetKeySizeInBytes(16)
208 .SetIvSizeInBytes(16)
209 .SetTagSizeInBytes(17)
210 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
211 .Build()
212 .status(),
213 StatusIs(absl::StatusCode::kInvalidArgument));
214 }
215
TEST(AesGcmParametersTest,CopyConstructor)216 TEST(AesGcmParametersTest, CopyConstructor) {
217 util::StatusOr<AesGcmParameters> parameters =
218 AesGcmParameters::Builder()
219 .SetKeySizeInBytes(16)
220 .SetIvSizeInBytes(16)
221 .SetTagSizeInBytes(16)
222 .SetVariant(AesGcmParameters::Variant::kTink)
223 .Build();
224 ASSERT_THAT(parameters, IsOk());
225
226 AesGcmParameters copy(*parameters);
227 EXPECT_THAT(copy.KeySizeInBytes(), Eq(16));
228 EXPECT_THAT(copy.IvSizeInBytes(), Eq(16));
229 EXPECT_THAT(copy.TagSizeInBytes(), Eq(16));
230 EXPECT_THAT(copy.GetVariant(), Eq(AesGcmParameters::Variant::kTink));
231 EXPECT_THAT(copy.HasIdRequirement(), IsTrue());
232 }
233
TEST(AesGcmParametersTest,CopyAssignment)234 TEST(AesGcmParametersTest, CopyAssignment) {
235 util::StatusOr<AesGcmParameters> parameters =
236 AesGcmParameters::Builder()
237 .SetKeySizeInBytes(16)
238 .SetIvSizeInBytes(16)
239 .SetTagSizeInBytes(16)
240 .SetVariant(AesGcmParameters::Variant::kTink)
241 .Build();
242 ASSERT_THAT(parameters, IsOk());
243
244 AesGcmParameters copy = *parameters;
245 EXPECT_THAT(copy.KeySizeInBytes(), Eq(16));
246 EXPECT_THAT(copy.IvSizeInBytes(), Eq(16));
247 EXPECT_THAT(copy.TagSizeInBytes(), Eq(16));
248 EXPECT_THAT(copy.GetVariant(), Eq(AesGcmParameters::Variant::kTink));
249 EXPECT_THAT(copy.HasIdRequirement(), IsTrue());
250 }
251
252 using AesGcmParametersVariantTest =
253 TestWithParam<std::tuple<int, int, AesGcmParameters::Variant>>;
254
255 INSTANTIATE_TEST_SUITE_P(AesGcmParametersVariantTestSuite,
256 AesGcmParametersVariantTest,
257 Combine(Values(16, 24, 32), Range(12, 16),
258 Values(AesGcmParameters::Variant::kTink,
259 AesGcmParameters::Variant::kCrunchy,
260 AesGcmParameters::Variant::kNoPrefix)));
261
TEST_P(AesGcmParametersVariantTest,ParametersEquals)262 TEST_P(AesGcmParametersVariantTest, ParametersEquals) {
263 int key_size;
264 int iv_and_tag_size;
265 AesGcmParameters::Variant variant;
266 std::tie(key_size, iv_and_tag_size, variant) = GetParam();
267
268 util::StatusOr<AesGcmParameters> parameters =
269 AesGcmParameters::Builder()
270 .SetKeySizeInBytes(key_size)
271 .SetIvSizeInBytes(iv_and_tag_size)
272 .SetTagSizeInBytes(iv_and_tag_size)
273 .SetVariant(variant)
274 .Build();
275 ASSERT_THAT(parameters, IsOk());
276
277 util::StatusOr<AesGcmParameters> other_parameters =
278 AesGcmParameters::Builder()
279 .SetKeySizeInBytes(key_size)
280 .SetIvSizeInBytes(iv_and_tag_size)
281 .SetTagSizeInBytes(iv_and_tag_size)
282 .SetVariant(variant)
283 .Build();
284 ASSERT_THAT(other_parameters, IsOk());
285
286 EXPECT_TRUE(*parameters == *other_parameters);
287 EXPECT_TRUE(*other_parameters == *parameters);
288 EXPECT_FALSE(*parameters != *other_parameters);
289 EXPECT_FALSE(*other_parameters != *parameters);
290 }
291
TEST(AesGcmParametersTest,KeySizeNotEqual)292 TEST(AesGcmParametersTest, KeySizeNotEqual) {
293 util::StatusOr<AesGcmParameters> parameters =
294 AesGcmParameters::Builder()
295 .SetKeySizeInBytes(32)
296 .SetIvSizeInBytes(16)
297 .SetTagSizeInBytes(16)
298 .SetVariant(AesGcmParameters::Variant::kTink)
299 .Build();
300 ASSERT_THAT(parameters, IsOk());
301
302 util::StatusOr<AesGcmParameters> other_parameters =
303 AesGcmParameters::Builder()
304 .SetKeySizeInBytes(24)
305 .SetIvSizeInBytes(16)
306 .SetTagSizeInBytes(16)
307 .SetVariant(AesGcmParameters::Variant::kTink)
308 .Build();
309 ASSERT_THAT(other_parameters, IsOk());
310
311 EXPECT_TRUE(*parameters != *other_parameters);
312 EXPECT_FALSE(*parameters == *other_parameters);
313 }
314
TEST(AesGcmParametersTest,IvSizeNotEqual)315 TEST(AesGcmParametersTest, IvSizeNotEqual) {
316 util::StatusOr<AesGcmParameters> parameters =
317 AesGcmParameters::Builder()
318 .SetKeySizeInBytes(32)
319 .SetIvSizeInBytes(16)
320 .SetTagSizeInBytes(16)
321 .SetVariant(AesGcmParameters::Variant::kTink)
322 .Build();
323 ASSERT_THAT(parameters, IsOk());
324
325 util::StatusOr<AesGcmParameters> other_parameters =
326 AesGcmParameters::Builder()
327 .SetKeySizeInBytes(32)
328 .SetIvSizeInBytes(12)
329 .SetTagSizeInBytes(16)
330 .SetVariant(AesGcmParameters::Variant::kTink)
331 .Build();
332 ASSERT_THAT(other_parameters, IsOk());
333
334 EXPECT_TRUE(*parameters != *other_parameters);
335 EXPECT_FALSE(*parameters == *other_parameters);
336 }
337
TEST(AesGcmParametersTest,TagSizeNotEqual)338 TEST(AesGcmParametersTest, TagSizeNotEqual) {
339 util::StatusOr<AesGcmParameters> parameters =
340 AesGcmParameters::Builder()
341 .SetKeySizeInBytes(32)
342 .SetIvSizeInBytes(16)
343 .SetTagSizeInBytes(16)
344 .SetVariant(AesGcmParameters::Variant::kTink)
345 .Build();
346 ASSERT_THAT(parameters, IsOk());
347
348 util::StatusOr<AesGcmParameters> other_parameters =
349 AesGcmParameters::Builder()
350 .SetKeySizeInBytes(32)
351 .SetIvSizeInBytes(16)
352 .SetTagSizeInBytes(14)
353 .SetVariant(AesGcmParameters::Variant::kTink)
354 .Build();
355 ASSERT_THAT(other_parameters, IsOk());
356
357 EXPECT_TRUE(*parameters != *other_parameters);
358 EXPECT_FALSE(*parameters == *other_parameters);
359 }
360
TEST(AesGcmParametersTest,VariantNotEqual)361 TEST(AesGcmParametersTest, VariantNotEqual) {
362 util::StatusOr<AesGcmParameters> parameters =
363 AesGcmParameters::Builder()
364 .SetKeySizeInBytes(32)
365 .SetIvSizeInBytes(16)
366 .SetTagSizeInBytes(16)
367 .SetVariant(AesGcmParameters::Variant::kTink)
368 .Build();
369 ASSERT_THAT(parameters, IsOk());
370
371 util::StatusOr<AesGcmParameters> other_parameters =
372 AesGcmParameters::Builder()
373 .SetKeySizeInBytes(32)
374 .SetIvSizeInBytes(16)
375 .SetTagSizeInBytes(16)
376 .SetVariant(AesGcmParameters::Variant::kNoPrefix)
377 .Build();
378 ASSERT_THAT(other_parameters, IsOk());
379
380 EXPECT_TRUE(*parameters != *other_parameters);
381 EXPECT_FALSE(*parameters == *other_parameters);
382 }
383
384 } // namespace
385 } // namespace tink
386 } // namespace crypto
387