xref: /aosp_15_r20/external/tink/cc/aead/kms_envelope_aead_key_manager_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2019 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/kms_envelope_aead_key_manager.h"
18 
19 #include <stdlib.h>
20 
21 #include <memory>
22 #include <string>
23 
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/memory/memory.h"
27 #include "absl/status/status.h"
28 #include "tink/aead.h"
29 #include "tink/aead/aead_config.h"
30 #include "tink/aead/aead_key_templates.h"
31 #include "tink/aead/aes_eax_key_manager.h"
32 #include "tink/aead/kms_envelope_aead.h"
33 #include "tink/kms_client.h"
34 #include "tink/kms_clients.h"
35 #include "tink/mac/mac_key_templates.h"
36 #include "tink/registry.h"
37 #include "tink/subtle/aead_test_util.h"
38 #include "tink/util/fake_kms_client.h"
39 #include "tink/util/status.h"
40 #include "tink/util/statusor.h"
41 #include "tink/util/test_matchers.h"
42 #include "tink/util/test_util.h"
43 #include "proto/kms_envelope.pb.h"
44 #include "proto/tink.pb.h"
45 
46 namespace crypto {
47 namespace tink {
48 
49 using ::crypto::tink::test::DummyAead;
50 using ::crypto::tink::test::DummyKmsClient;
51 using ::crypto::tink::test::IsOk;
52 using ::crypto::tink::test::IsOkAndHolds;
53 using ::crypto::tink::test::StatusIs;
54 using ::google::crypto::tink::KeyTemplate;
55 using ::google::crypto::tink::KmsEnvelopeAeadKey;
56 using ::google::crypto::tink::KmsEnvelopeAeadKeyFormat;
57 using ::testing::Eq;
58 using ::testing::Not;
59 
60 namespace {
61 
TEST(KmsEnvelopeAeadKeyManagerTest,Basics)62 TEST(KmsEnvelopeAeadKeyManagerTest, Basics) {
63   EXPECT_THAT(KmsEnvelopeAeadKeyManager().get_version(), Eq(0));
64   EXPECT_THAT(KmsEnvelopeAeadKeyManager().get_key_type(),
65               Eq("type.googleapis.com/google.crypto.tink.KmsEnvelopeAeadKey"));
66   EXPECT_THAT(KmsEnvelopeAeadKeyManager().key_material_type(),
67               Eq(google::crypto::tink::KeyData::REMOTE));
68 }
69 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateEmptyKey)70 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateEmptyKey) {
71   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKey(KmsEnvelopeAeadKey()),
72               StatusIs(absl::StatusCode::kInvalidArgument));
73 }
74 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateValidKey)75 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateValidKey) {
76   KmsEnvelopeAeadKey key;
77   key.set_version(0);
78   key.mutable_params()->set_kek_uri("Some uri");
79   *(key.mutable_params()->mutable_dek_template()) =
80       AeadKeyTemplates::Aes128Eax();
81 
82   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKey(key), IsOk());
83 }
84 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateWrongVersion)85 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateWrongVersion) {
86   KmsEnvelopeAeadKey key;
87   key.set_version(1);
88   key.mutable_params()->set_kek_uri("Some uri");
89   *(key.mutable_params()->mutable_dek_template()) =
90       AeadKeyTemplates::Aes128Eax();
91   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKey(key), Not(IsOk()));
92 }
93 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateNoUri)94 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateNoUri) {
95   KmsEnvelopeAeadKey key;
96   key.set_version(1);
97   *(key.mutable_params()->mutable_dek_template()) =
98       AeadKeyTemplates::Aes128Eax();
99   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKey(key), Not(IsOk()));
100 }
101 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateKeyFormatEmptyKey)102 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateKeyFormatEmptyKey) {
103   EXPECT_THAT(
104       KmsEnvelopeAeadKeyManager().ValidateKeyFormat(KmsEnvelopeAeadKeyFormat()),
105       StatusIs(absl::StatusCode::kInvalidArgument));
106 }
107 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateKeyFormatValidKey)108 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateKeyFormatValidKey) {
109   KmsEnvelopeAeadKeyFormat key_format;
110   key_format.set_kek_uri("Some uri");
111   *key_format.mutable_dek_template() = AeadKeyTemplates::Aes128Eax();
112   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKeyFormat(key_format),
113               IsOk());
114 }
115 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateKeyFormatNoUri)116 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateKeyFormatNoUri) {
117   KmsEnvelopeAeadKeyFormat key_format;
118   *key_format.mutable_dek_template() = AeadKeyTemplates::Aes128Eax();
119   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKeyFormat(key_format),
120               Not(IsOk()));
121 }
122 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateKeyFormatNoTemplate)123 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateKeyFormatNoTemplate) {
124   KmsEnvelopeAeadKeyFormat key_format;
125   key_format.set_kek_uri("Some uri");
126   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKeyFormat(key_format),
127               Not(IsOk()));
128 }
129 
TEST(KmsEnvelopeAeadKeyManagerTest,ValidateKeyFormatInvalidDekTemplate)130 TEST(KmsEnvelopeAeadKeyManagerTest, ValidateKeyFormatInvalidDekTemplate) {
131   KmsEnvelopeAeadKeyFormat key_format;
132   key_format.set_kek_uri("Some uri");
133   *key_format.mutable_dek_template() = MacKeyTemplates::HmacSha256();
134   EXPECT_THAT(KmsEnvelopeAeadKeyManager().ValidateKeyFormat(key_format),
135               Not(IsOk()));
136 }
137 
TEST(KmsEnvelopeAeadKeyManagerTest,CreateKey)138 TEST(KmsEnvelopeAeadKeyManagerTest, CreateKey) {
139   KmsEnvelopeAeadKeyFormat key_format;
140   key_format.set_kek_uri("Some uri");
141   *key_format.mutable_dek_template() = AeadKeyTemplates::Aes128Eax();
142   auto key_or = KmsEnvelopeAeadKeyManager().CreateKey(key_format);
143   ASSERT_THAT(key_or, IsOk());
144   EXPECT_THAT(key_or.value().params().kek_uri(), Eq(key_format.kek_uri()));
145   EXPECT_THAT(key_or.value().params().dek_template().value(),
146               Eq(key_format.dek_template().value()));
147 }
148 
149 class KmsEnvelopeAeadKeyManagerCreateTest : public ::testing::Test {
150  public:
151   // The KmsClients class has a global variable which keeps the registered
152   // clients. To reflect that in the test, we set them up in the SetUpTestSuite
153   // function.
SetUpTestSuite()154   static void SetUpTestSuite() {
155     if (!KmsClients::Add(
156              absl::make_unique<DummyKmsClient>("prefix1", "prefix1:some_key1"))
157              .ok())
158       abort();
159     if (!KmsClients::Add(absl::make_unique<DummyKmsClient>("prefix2", "")).ok())
160       abort();
161 
162     if (!Registry::RegisterKeyTypeManager(absl::make_unique<AesEaxKeyManager>(),
163                                           true)
164              .ok())
165       abort();
166   }
167 };
168 
TEST_F(KmsEnvelopeAeadKeyManagerCreateTest,CreateAead)169 TEST_F(KmsEnvelopeAeadKeyManagerCreateTest, CreateAead) {
170   KmsEnvelopeAeadKey key;
171   key.set_version(0);
172   key.mutable_params()->set_kek_uri("prefix1:some_key1");
173   *(key.mutable_params()->mutable_dek_template()) =
174       AeadKeyTemplates::Aes128Eax();
175 
176   auto kms_aead = KmsEnvelopeAeadKeyManager().GetPrimitive<Aead>(key);
177   ASSERT_THAT(kms_aead, IsOk());
178 
179   auto direct_aead =
180       KmsEnvelopeAead::New(key.params().dek_template(),
181                            absl::make_unique<DummyAead>("prefix1:some_key1"));
182   ASSERT_THAT(direct_aead, IsOk());
183 
184   EXPECT_THAT(EncryptThenDecrypt(*kms_aead.value(), *direct_aead.value(),
185                                  "plaintext", "aad"),
186               IsOk());
187 }
188 
TEST_F(KmsEnvelopeAeadKeyManagerCreateTest,CreateAeadWrongKeyName)189 TEST_F(KmsEnvelopeAeadKeyManagerCreateTest, CreateAeadWrongKeyName) {
190   KmsEnvelopeAeadKey key;
191   key.set_version(0);
192   key.mutable_params()->set_kek_uri("prefix1:some_other_key");
193   *(key.mutable_params()->mutable_dek_template()) =
194       AeadKeyTemplates::Aes128Eax();
195 
196   auto kms_aead = KmsEnvelopeAeadKeyManager().GetPrimitive<Aead>(key);
197   ASSERT_THAT(kms_aead, Not(IsOk()));
198 }
199 
TEST_F(KmsEnvelopeAeadKeyManagerCreateTest,CreateAeadWrongTypeUrl)200 TEST_F(KmsEnvelopeAeadKeyManagerCreateTest, CreateAeadWrongTypeUrl) {
201   KmsEnvelopeAeadKey key;
202   key.set_version(0);
203   key.mutable_params()->set_kek_uri("prefix1:some_other_key");
204   *(key.mutable_params()->mutable_dek_template()) =
205       AeadKeyTemplates::Aes128Eax();
206   key.mutable_params()->mutable_dek_template()->set_type_url(
207       "Some unkonwn type url");
208 
209   auto kms_aead = KmsEnvelopeAeadKeyManager().GetPrimitive<Aead>(key);
210   ASSERT_THAT(kms_aead, Not(IsOk()));
211 }
212 
TEST_F(KmsEnvelopeAeadKeyManagerCreateTest,CreateAeadWrongPrefix)213 TEST_F(KmsEnvelopeAeadKeyManagerCreateTest, CreateAeadWrongPrefix) {
214   KmsEnvelopeAeadKey key;
215   key.set_version(0);
216   key.mutable_params()->set_kek_uri("non-existing-prefix:some_key1");
217   *(key.mutable_params()->mutable_dek_template()) =
218       AeadKeyTemplates::Aes128Eax();
219 
220   auto kms_aead = KmsEnvelopeAeadKeyManager().GetPrimitive<Aead>(key);
221   ASSERT_THAT(kms_aead, Not(IsOk()));
222 }
223 
TEST_F(KmsEnvelopeAeadKeyManagerCreateTest,CreateAeadUnboundKey)224 TEST_F(KmsEnvelopeAeadKeyManagerCreateTest, CreateAeadUnboundKey) {
225   KmsEnvelopeAeadKey key;
226   key.set_version(0);
227   key.mutable_params()->set_kek_uri("prefix2:some_key2");
228   *(key.mutable_params()->mutable_dek_template()) =
229       AeadKeyTemplates::Aes128Eax();
230 
231   auto kms_aead = KmsEnvelopeAeadKeyManager().GetPrimitive<Aead>(key);
232   ASSERT_THAT(kms_aead, IsOk());
233 
234   auto direct_aead =
235       KmsEnvelopeAead::New(key.params().dek_template(),
236                            absl::make_unique<DummyAead>("prefix2:some_key2"));
237   ASSERT_THAT(direct_aead, IsOk());
238 
239   EXPECT_THAT(EncryptThenDecrypt(*kms_aead.value(), *direct_aead.value(),
240                                  "plaintext", "aad"),
241               IsOk());
242 }
243 
244 class KmsEnvelopeAeadKeyManagerDekTemplatesTest
245     : public testing::TestWithParam<KeyTemplate> {
SetUp()246   void SetUp() override { ASSERT_THAT(AeadConfig::Register(), IsOk()); }
247 };
248 
TEST_P(KmsEnvelopeAeadKeyManagerDekTemplatesTest,EncryptDecryp)249 TEST_P(KmsEnvelopeAeadKeyManagerDekTemplatesTest, EncryptDecryp) {
250   util::StatusOr<std::string> kek_uri_result =
251       test::FakeKmsClient::CreateFakeKeyUri();
252   ASSERT_THAT(kek_uri_result, IsOk());
253   std::string kek_uri = kek_uri_result.value();
254   util::Status register_fake_kms_client_status =
255       test::FakeKmsClient::RegisterNewClient(kek_uri, /*credentials_path=*/"");
256   ASSERT_THAT(register_fake_kms_client_status, IsOk());
257 
258   KeyTemplate dek_template = GetParam();
259   KeyTemplate env_template =
260       AeadKeyTemplates::KmsEnvelopeAead(kek_uri, dek_template);
261   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
262       KeysetHandle::GenerateNew(env_template);
263   ASSERT_THAT(handle, IsOk());
264   util::StatusOr<std::unique_ptr<Aead>> envelope_aead =
265       (*handle)->GetPrimitive<Aead>();
266   ASSERT_THAT(envelope_aead, IsOk());
267 
268   std::string plaintext = "plaintext";
269   std::string associated_data = "associated_data";
270   util::StatusOr<std::string> ciphertext =
271       (*envelope_aead)->Encrypt(plaintext, associated_data);
272   ASSERT_THAT(ciphertext, IsOk());
273   util::StatusOr<std::string> decrypted =
274       (*envelope_aead)->Decrypt(ciphertext.value(), associated_data);
275   EXPECT_THAT(decrypted, IsOkAndHolds(plaintext));
276 
277   std::string invalid_associated_data = "invalid_associated_data";
278   util::StatusOr<std::string> decrypted_with_invalid_associated_data =
279       (*envelope_aead)->Decrypt(ciphertext.value(), invalid_associated_data);
280   EXPECT_THAT(decrypted_with_invalid_associated_data.status(), Not(IsOk()));
281 }
282 
283 INSTANTIATE_TEST_SUITE_P(
284     KmsEnvelopeAeadKeyManagerDekTemplatesTest,
285     KmsEnvelopeAeadKeyManagerDekTemplatesTest,
286     testing::Values(AeadKeyTemplates::Aes128Gcm(),
287                     AeadKeyTemplates::Aes256Gcm(),
288                     AeadKeyTemplates::Aes128CtrHmacSha256(),
289                     AeadKeyTemplates::Aes128Eax(),
290                     AeadKeyTemplates::Aes128GcmNoPrefix()));
291 
292 }  // namespace
293 }  // namespace tink
294 }  // namespace crypto
295