1 // Copyright 2018 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/aead_key_templates.h"
18
19 #include <memory>
20 #include <string>
21 #include <utility>
22
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/status/status.h"
26 #include "absl/status/statusor.h"
27 #include "tink/aead.h"
28 #include "tink/aead/aead_config.h"
29 #include "tink/aead/aes_ctr_hmac_aead_key_manager.h"
30 #include "tink/aead/aes_eax_key_manager.h"
31 #include "tink/aead/aes_gcm_key_manager.h"
32 #include "tink/aead/aes_gcm_siv_key_manager.h"
33 #include "tink/aead/kms_envelope_aead_key_manager.h"
34 #include "tink/aead/xchacha20_poly1305_key_manager.h"
35 #include "tink/core/key_manager_impl.h"
36 #include "tink/key_manager.h"
37 #include "tink/keyset_handle.h"
38 #include "tink/subtle/aead_test_util.h"
39 #include "tink/util/fake_kms_client.h"
40 #include "tink/util/status.h"
41 #include "tink/util/test_matchers.h"
42 #include "proto/aes_ctr.pb.h"
43 #include "proto/aes_ctr_hmac_aead.pb.h"
44 #include "proto/aes_eax.pb.h"
45 #include "proto/aes_gcm.pb.h"
46 #include "proto/aes_gcm_siv.pb.h"
47 #include "proto/common.pb.h"
48 #include "proto/hmac.pb.h"
49 #include "proto/kms_envelope.pb.h"
50 #include "proto/tink.pb.h"
51 #include "proto/xchacha20_poly1305.pb.h"
52
53 using google::crypto::tink::AesCtrHmacAeadKeyFormat;
54 using google::crypto::tink::AesEaxKeyFormat;
55 using google::crypto::tink::AesGcmKeyFormat;
56 using google::crypto::tink::AesGcmSivKeyFormat;
57 using google::crypto::tink::HashType;
58 using google::crypto::tink::KeyTemplate;
59 using google::crypto::tink::KmsEnvelopeAeadKeyFormat;
60 using google::crypto::tink::OutputPrefixType;
61
62 namespace crypto {
63 namespace tink {
64 namespace {
65
66 using ::crypto::tink::test::IsOk;
67 using ::testing::Eq;
68 using ::testing::Ref;
69
TEST(AeadKeyTemplatesTest,testAesEaxKeyTemplates)70 TEST(AeadKeyTemplatesTest, testAesEaxKeyTemplates) {
71 std::string type_url = "type.googleapis.com/google.crypto.tink.AesEaxKey";
72
73 { // Test Aes128Eax().
74 // Check that returned template is correct.
75 const KeyTemplate& key_template = AeadKeyTemplates::Aes128Eax();
76 EXPECT_EQ(type_url, key_template.type_url());
77 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
78 AesEaxKeyFormat key_format;
79 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
80 EXPECT_EQ(16, key_format.key_size());
81 EXPECT_EQ(16, key_format.params().iv_size());
82
83 // Check that reference to the same object is returned.
84 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes128Eax();
85 EXPECT_EQ(&key_template, &key_template_2);
86
87 // Check that the template works with the key manager.
88 AesEaxKeyManager key_type_manager;
89 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
90 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
91 auto new_key_result =
92 key_manager->get_key_factory().NewKey(key_template.value());
93 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
94 }
95
96 { // Test Aes256Eax().
97 // Check that returned template is correct.
98 const KeyTemplate& key_template = AeadKeyTemplates::Aes256Eax();
99 EXPECT_EQ(type_url, key_template.type_url());
100 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
101 AesEaxKeyFormat key_format;
102 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
103 EXPECT_EQ(32, key_format.key_size());
104 EXPECT_EQ(16, key_format.params().iv_size());
105
106 // Check that reference to the same object is returned.
107 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes256Eax();
108 EXPECT_EQ(&key_template, &key_template_2);
109
110 // Check that the template works with the key manager.
111 AesEaxKeyManager key_type_manager;
112 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
113 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
114 auto new_key_result =
115 key_manager->get_key_factory().NewKey(key_template.value());
116 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
117 }
118 }
119
TEST(Aes128GcmNoPrefix,Basics)120 TEST(Aes128GcmNoPrefix, Basics) {
121 EXPECT_THAT(AeadKeyTemplates::Aes128GcmNoPrefix().type_url(),
122 Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
123 EXPECT_THAT(AeadKeyTemplates::Aes128GcmNoPrefix().type_url(),
124 Eq(AesGcmKeyManager().get_key_type()));
125 }
126
TEST(Aes128GcmNoPrefix,OutputPrefixType)127 TEST(Aes128GcmNoPrefix, OutputPrefixType) {
128 EXPECT_THAT(AeadKeyTemplates::Aes128GcmNoPrefix().output_prefix_type(),
129 Eq(OutputPrefixType::RAW));
130 }
131
TEST(Aes128GcmNoPrefix,MultipleCallsSameReference)132 TEST(Aes128GcmNoPrefix, MultipleCallsSameReference) {
133 EXPECT_THAT(AeadKeyTemplates::Aes128GcmNoPrefix(),
134 Ref(AeadKeyTemplates::Aes128GcmNoPrefix()));
135 }
136
TEST(Aes128GcmNoPrefix,WorksWithKeyTypeManager)137 TEST(Aes128GcmNoPrefix, WorksWithKeyTypeManager) {
138 const KeyTemplate& key_template = AeadKeyTemplates::Aes128GcmNoPrefix();
139 AesGcmKeyFormat key_format;
140 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
141 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(key_format), IsOk());
142 }
143
TEST(Aes128GcmNoPrefix,CheckValues)144 TEST(Aes128GcmNoPrefix, CheckValues) {
145 const KeyTemplate& key_template = AeadKeyTemplates::Aes128GcmNoPrefix();
146 AesGcmKeyFormat key_format;
147 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
148 EXPECT_THAT(key_format.key_size(), Eq(16));
149 }
150
TEST(Aes256GcmNoPrefix,Basics)151 TEST(Aes256GcmNoPrefix, Basics) {
152 EXPECT_THAT(AeadKeyTemplates::Aes256GcmNoPrefix().type_url(),
153 Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
154 EXPECT_THAT(AeadKeyTemplates::Aes256GcmNoPrefix().type_url(),
155 Eq(AesGcmKeyManager().get_key_type()));
156 }
157
TEST(Aes256GcmNoPrefix,OutputPrefixType)158 TEST(Aes256GcmNoPrefix, OutputPrefixType) {
159 EXPECT_THAT(AeadKeyTemplates::Aes256GcmNoPrefix().output_prefix_type(),
160 Eq(OutputPrefixType::RAW));
161 }
162
TEST(Aes256GcmNoPrefix,MultipleCallsSameReference)163 TEST(Aes256GcmNoPrefix, MultipleCallsSameReference) {
164 EXPECT_THAT(AeadKeyTemplates::Aes256GcmNoPrefix(),
165 Ref(AeadKeyTemplates::Aes256GcmNoPrefix()));
166 }
167
TEST(Aes256GcmNoPrefix,WorksWithKeyTypeManager)168 TEST(Aes256GcmNoPrefix, WorksWithKeyTypeManager) {
169 const KeyTemplate& key_template = AeadKeyTemplates::Aes256GcmNoPrefix();
170 AesGcmKeyFormat key_format;
171 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
172 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(key_format), IsOk());
173 }
174
TEST(Aes256GcmNoPrefix,CheckValues)175 TEST(Aes256GcmNoPrefix, CheckValues) {
176 const KeyTemplate& key_template = AeadKeyTemplates::Aes256GcmNoPrefix();
177 AesGcmKeyFormat key_format;
178 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
179 EXPECT_THAT(key_format.key_size(), Eq(32));
180 }
181
TEST(Aes256Gcm,Basics)182 TEST(Aes256Gcm, Basics) {
183 EXPECT_THAT(AeadKeyTemplates::Aes256Gcm().type_url(),
184 Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
185 EXPECT_THAT(AeadKeyTemplates::Aes256Gcm().type_url(),
186 Eq(AesGcmKeyManager().get_key_type()));
187 }
188
TEST(Aes256Gcm,OutputPrefixType)189 TEST(Aes256Gcm, OutputPrefixType) {
190 EXPECT_THAT(AeadKeyTemplates::Aes256Gcm().output_prefix_type(),
191 Eq(OutputPrefixType::TINK));
192 }
193
TEST(Aes256Gcm,MultipleCallsSameReference)194 TEST(Aes256Gcm, MultipleCallsSameReference) {
195 EXPECT_THAT(AeadKeyTemplates::Aes256Gcm(),
196 Ref(AeadKeyTemplates::Aes256Gcm()));
197 }
198
TEST(Aes256Gcm,WorksWithKeyTypeManager)199 TEST(Aes256Gcm, WorksWithKeyTypeManager) {
200 const KeyTemplate& key_template = AeadKeyTemplates::Aes256Gcm();
201 AesGcmKeyFormat key_format;
202 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
203 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(key_format), IsOk());
204 }
205
TEST(Aes256Gcm,CheckValues)206 TEST(Aes256Gcm, CheckValues) {
207 const KeyTemplate& key_template = AeadKeyTemplates::Aes256Gcm();
208 AesGcmKeyFormat key_format;
209 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
210 EXPECT_THAT(key_format.key_size(), Eq(32));
211 }
212
TEST(Aes128Gcm,Basics)213 TEST(Aes128Gcm, Basics) {
214 EXPECT_THAT(AeadKeyTemplates::Aes128Gcm().type_url(),
215 Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
216 EXPECT_THAT(AeadKeyTemplates::Aes128Gcm().type_url(),
217 Eq(AesGcmKeyManager().get_key_type()));
218 }
219
TEST(Aes128Gcm,OutputPrefixType)220 TEST(Aes128Gcm, OutputPrefixType) {
221 EXPECT_THAT(AeadKeyTemplates::Aes128Gcm().output_prefix_type(),
222 Eq(OutputPrefixType::TINK));
223 }
224
TEST(Aes128Gcm,MultipleCallsSameReference)225 TEST(Aes128Gcm, MultipleCallsSameReference) {
226 EXPECT_THAT(AeadKeyTemplates::Aes128Gcm(),
227 Ref(AeadKeyTemplates::Aes128Gcm()));
228 }
229
TEST(Aes128Gcm,WorksWithKeyTypeManager)230 TEST(Aes128Gcm, WorksWithKeyTypeManager) {
231 const KeyTemplate& key_template = AeadKeyTemplates::Aes128Gcm();
232 AesGcmKeyFormat key_format;
233 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
234 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(key_format), IsOk());
235 }
236
TEST(Aes128Gcm,CheckValues)237 TEST(Aes128Gcm, CheckValues) {
238 const KeyTemplate& key_template = AeadKeyTemplates::Aes128Gcm();
239 AesGcmKeyFormat key_format;
240 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
241 EXPECT_THAT(key_format.key_size(), Eq(16));
242 }
243
TEST(AeadKeyTemplatesTest,testAesGcmSivKeyTemplates)244 TEST(AeadKeyTemplatesTest, testAesGcmSivKeyTemplates) {
245 std::string type_url = "type.googleapis.com/google.crypto.tink.AesGcmSivKey";
246
247 { // Test Aes128GcmSiv().
248 // Check that returned template is correct.
249 const KeyTemplate& key_template = AeadKeyTemplates::Aes128GcmSiv();
250 EXPECT_EQ(type_url, key_template.type_url());
251 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
252 AesGcmSivKeyFormat key_format;
253 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
254 EXPECT_EQ(16, key_format.key_size());
255
256 // Check that reference to the same object is returned.
257 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes128GcmSiv();
258 EXPECT_EQ(&key_template, &key_template_2);
259
260 // Check that the template works with the key manager.
261 AesGcmSivKeyManager key_type_manager;
262 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
263 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
264 auto new_key_result =
265 key_manager->get_key_factory().NewKey(key_template.value());
266 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
267 }
268
269 { // Test Aes256GcmSiv().
270 // Check that returned template is correct.
271 const KeyTemplate& key_template = AeadKeyTemplates::Aes256GcmSiv();
272 EXPECT_EQ(type_url, key_template.type_url());
273 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
274 AesGcmSivKeyFormat key_format;
275 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
276 EXPECT_EQ(32, key_format.key_size());
277
278 // Check that reference to the same object is returned.
279 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes256GcmSiv();
280 EXPECT_EQ(&key_template, &key_template_2);
281
282 // Check that the template works with the key manager.
283 AesGcmSivKeyManager key_type_manager;
284 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
285 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
286 auto new_key_result =
287 key_manager->get_key_factory().NewKey(key_template.value());
288 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
289 }
290 }
291
TEST(AeadKeyTemplatesTest,testAesCtrHmacAeadKeyTemplates)292 TEST(AeadKeyTemplatesTest, testAesCtrHmacAeadKeyTemplates) {
293 std::string type_url =
294 "type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey";
295
296 { // Test Aes128CtrHmacSha256().
297 // Check that returned template is correct.
298 const KeyTemplate& key_template = AeadKeyTemplates::Aes128CtrHmacSha256();
299 EXPECT_EQ(type_url, key_template.type_url());
300 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
301 AesCtrHmacAeadKeyFormat key_format;
302 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
303 EXPECT_EQ(16, key_format.aes_ctr_key_format().key_size());
304 EXPECT_EQ(16, key_format.aes_ctr_key_format().params().iv_size());
305 EXPECT_EQ(32, key_format.hmac_key_format().key_size());
306 EXPECT_EQ(16, key_format.hmac_key_format().params().tag_size());
307 EXPECT_EQ(HashType::SHA256, key_format.hmac_key_format().params().hash());
308
309 // Check that reference to the same object is returned.
310 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes128CtrHmacSha256();
311 EXPECT_EQ(&key_template, &key_template_2);
312
313 // Check that the template works with the key manager.
314 AesCtrHmacAeadKeyManager key_type_manager;
315 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
316 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
317 auto new_key_result =
318 key_manager->get_key_factory().NewKey(key_template.value());
319 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
320 }
321
322 { // Test Aes256CtrHmacSha256().
323 // Check that returned template is correct.
324 const KeyTemplate& key_template = AeadKeyTemplates::Aes256CtrHmacSha256();
325 EXPECT_EQ(type_url, key_template.type_url());
326 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
327 AesCtrHmacAeadKeyFormat key_format;
328 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
329 EXPECT_EQ(32, key_format.aes_ctr_key_format().key_size());
330 EXPECT_EQ(16, key_format.aes_ctr_key_format().params().iv_size());
331 EXPECT_EQ(32, key_format.hmac_key_format().key_size());
332 EXPECT_EQ(32, key_format.hmac_key_format().params().tag_size());
333 EXPECT_EQ(HashType::SHA256, key_format.hmac_key_format().params().hash());
334
335 // Check that reference to the same object is returned.
336 const KeyTemplate& key_template_2 = AeadKeyTemplates::Aes256CtrHmacSha256();
337 EXPECT_EQ(&key_template, &key_template_2);
338
339 // Check that the template works with the key manager.
340 AesCtrHmacAeadKeyManager key_type_manager;
341 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
342 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
343 auto new_key_result =
344 key_manager->get_key_factory().NewKey(key_template.value());
345 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
346 }
347 }
348
TEST(AeadKeyTemplatesTest,testXChaCha20Poly1305KeyTemplates)349 TEST(AeadKeyTemplatesTest, testXChaCha20Poly1305KeyTemplates) {
350 std::string type_url =
351 "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key";
352
353 // Check that returned template is correct.
354 const KeyTemplate& key_template = AeadKeyTemplates::XChaCha20Poly1305();
355 EXPECT_EQ(type_url, key_template.type_url());
356 EXPECT_EQ(OutputPrefixType::TINK, key_template.output_prefix_type());
357
358 // Check that reference to the same object is returned.
359 const KeyTemplate& key_template_2 = AeadKeyTemplates::XChaCha20Poly1305();
360 EXPECT_EQ(&key_template, &key_template_2);
361
362 // Check that the template works with the key manager.
363 XChaCha20Poly1305KeyManager key_type_manager;
364 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
365 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
366 auto new_key_result =
367 key_manager->get_key_factory().NewKey(key_template.value());
368 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
369 }
370
TEST(AeadKeyTemplatesTest,testKmsEnvelopeAead)371 TEST(AeadKeyTemplatesTest, testKmsEnvelopeAead) {
372 std::string type_url =
373 "type.googleapis.com/google.crypto.tink.KmsEnvelopeAeadKey";
374 std::string kek_uri = "foo/bar";
375 const KeyTemplate& dek_template = AeadKeyTemplates::Aes128Gcm();
376
377 // Check that returned template is correct.
378 const KeyTemplate& key_template =
379 AeadKeyTemplates::KmsEnvelopeAead(kek_uri, dek_template);
380 EXPECT_EQ(type_url, key_template.type_url());
381 EXPECT_EQ(OutputPrefixType::RAW, key_template.output_prefix_type());
382
383 KmsEnvelopeAeadKeyFormat key_format;
384 EXPECT_TRUE(key_format.ParseFromString(key_template.value()));
385 EXPECT_EQ(kek_uri, key_format.kek_uri());
386 EXPECT_EQ(dek_template.type_url(), key_format.dek_template().type_url());
387 EXPECT_EQ(dek_template.value(), key_format.dek_template().value());
388
389 // Check that the template works with the key manager.
390 KmsEnvelopeAeadKeyManager key_type_manager;
391 auto key_manager = internal::MakeKeyManager<Aead>(&key_type_manager);
392 EXPECT_EQ(key_manager->get_key_type(), key_template.type_url());
393 auto new_key_result =
394 key_manager->get_key_factory().NewKey(key_template.value());
395 EXPECT_TRUE(new_key_result.ok()) << new_key_result.status();
396 }
397
TEST(AeadKeyTemplatesTest,testKmsEnvelopeAeadMultipleKeysSameKek)398 TEST(AeadKeyTemplatesTest, testKmsEnvelopeAeadMultipleKeysSameKek) {
399 // Initialize the registry.
400 ASSERT_TRUE(AeadConfig::Register().ok());
401
402 auto kek_uri_result = test::FakeKmsClient::CreateFakeKeyUri();
403 EXPECT_TRUE(kek_uri_result.ok()) << kek_uri_result.status();
404 std::string kek_uri = kek_uri_result.value();
405 auto register_fake_kms_client_status = test::FakeKmsClient::RegisterNewClient(
406 kek_uri, /* credentials_path= */ "");
407
408 std::string type_url =
409 "type.googleapis.com/google.crypto.tink.KmsEnvelopeAeadKey";
410 const KeyTemplate& dek_template = AeadKeyTemplates::Aes128Gcm();
411
412 const KeyTemplate& key_template1 =
413 AeadKeyTemplates::KmsEnvelopeAead(kek_uri, dek_template);
414 auto handle_result1 = KeysetHandle::GenerateNew(key_template1);
415 EXPECT_TRUE(handle_result1.ok());
416 auto handle1 = std::move(handle_result1.value());
417 auto aead_result1 = handle1->GetPrimitive<Aead>();
418 EXPECT_TRUE(aead_result1.ok());
419 auto aead1 = std::move(aead_result1.value());
420
421 const KeyTemplate& key_template2 =
422 AeadKeyTemplates::KmsEnvelopeAead(kek_uri, dek_template);
423 auto handle_result2 = KeysetHandle::GenerateNew(key_template2);
424 EXPECT_TRUE(handle_result2.ok());
425 auto handle2 = std::move(handle_result2.value());
426 auto aead_result2 = handle2->GetPrimitive<Aead>();
427 EXPECT_TRUE(aead_result2.ok());
428 auto aead2 = std::move(aead_result2.value());
429
430 EXPECT_THAT(EncryptThenDecrypt(*aead1, *aead2, "message", "aad"), IsOk());
431 }
432
433 } // namespace
434 } // namespace tink
435 } // namespace crypto
436