xref: /aosp_15_r20/external/tink/cc/keyderivation/internal/prf_based_deriver_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/keyderivation/internal/prf_based_deriver_key_manager.h"
18 
19 #include <memory>
20 #include <string>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/aead/aead_key_templates.h"
26 #include "tink/aead/aes_gcm_key_manager.h"
27 #include "tink/cleartext_keyset_handle.h"
28 #include "tink/keyderivation/keyset_deriver.h"
29 #include "tink/prf/hkdf_prf_key_manager.h"
30 #include "tink/subtle/random.h"
31 #include "tink/util/statusor.h"
32 #include "tink/util/test_matchers.h"
33 #include "tink/util/test_util.h"
34 #include "proto/aes_gcm.pb.h"
35 #include "proto/hkdf_prf.pb.h"
36 #include "proto/prf_based_deriver.pb.h"
37 #include "proto/tink.pb.h"
38 
39 namespace crypto {
40 namespace tink {
41 namespace internal {
42 namespace {
43 
44 using ::crypto::tink::test::IsOk;
45 using ::crypto::tink::test::StatusIs;
46 using ::crypto::tink::util::StatusOr;
47 using ::google::crypto::tink::AesGcmKey;
48 using ::google::crypto::tink::HashType;
49 using ::google::crypto::tink::HkdfPrfKey;
50 using ::google::crypto::tink::HkdfPrfKeyFormat;
51 using ::google::crypto::tink::KeyData;
52 using ::google::crypto::tink::Keyset;
53 using ::google::crypto::tink::KeyTemplate;
54 using ::google::crypto::tink::PrfBasedDeriverKey;
55 using ::google::crypto::tink::PrfBasedDeriverKeyFormat;
56 using ::testing::Eq;
57 using ::testing::SizeIs;
58 
TEST(PrfBasedDeriverKeyManagerTest,Basics)59 TEST(PrfBasedDeriverKeyManagerTest, Basics) {
60   EXPECT_THAT(PrfBasedDeriverKeyManager().get_version(), Eq(0));
61   EXPECT_THAT(PrfBasedDeriverKeyManager().get_key_type(),
62               Eq("type.googleapis.com/google.crypto.tink.PrfBasedDeriverKey"));
63   EXPECT_THAT(PrfBasedDeriverKeyManager().key_material_type(),
64               Eq(KeyData::SYMMETRIC));
65 }
66 
TEST(PrfBasedDeriverKeyManagerTest,ValidateKeyEmpty)67 TEST(PrfBasedDeriverKeyManagerTest, ValidateKeyEmpty) {
68   EXPECT_THAT(PrfBasedDeriverKeyManager().ValidateKey(PrfBasedDeriverKey()),
69               StatusIs(absl::StatusCode::kInvalidArgument));
70 }
71 
TEST(PrfBasedDeriverKeyManagerTest,ValidateKey)72 TEST(PrfBasedDeriverKeyManagerTest, ValidateKey) {
73   HkdfPrfKey prf_key;
74   prf_key.set_version(0);
75   prf_key.set_key_value("0123456789abcdef");
76   prf_key.mutable_params()->set_hash(HashType::SHA256);
77 
78   PrfBasedDeriverKey key;
79   key.set_version(0);
80   *key.mutable_prf_key() = test::AsKeyData(prf_key, KeyData::SYMMETRIC);
81   *key.mutable_params()->mutable_derived_key_template() =
82       AeadKeyTemplates::Aes256Gcm();
83 
84   EXPECT_THAT(PrfBasedDeriverKeyManager().ValidateKey(key), IsOk());
85 }
86 
TEST(PrfBasedDeriverKeyManagerTest,ValidateKeyWithWrongVersion)87 TEST(PrfBasedDeriverKeyManagerTest, ValidateKeyWithWrongVersion) {
88   HkdfPrfKey prf_key;
89   prf_key.set_version(0);
90   prf_key.set_key_value("0123456789abcdef");
91   prf_key.mutable_params()->set_hash(HashType::SHA256);
92 
93   PrfBasedDeriverKey key;
94   key.set_version(1);
95   *key.mutable_prf_key() = test::AsKeyData(prf_key, KeyData::SYMMETRIC);
96   *key.mutable_params()->mutable_derived_key_template() =
97       AeadKeyTemplates::Aes256Gcm();
98 
99   EXPECT_THAT(PrfBasedDeriverKeyManager().ValidateKey(key),
100               StatusIs(absl::StatusCode::kInvalidArgument));
101 }
102 
TEST(PrfBasedDeriverKeyManagerTest,ValidateKeyFormat)103 TEST(PrfBasedDeriverKeyManagerTest, ValidateKeyFormat) {
104   HkdfPrfKeyFormat prf_key_format;
105   prf_key_format.set_key_size(16);
106   prf_key_format.mutable_params()->set_hash(HashType::SHA256);
107 
108   PrfBasedDeriverKeyFormat key_format;
109   key_format.mutable_prf_key_template()->set_type_url(
110       HkdfPrfKeyManager().get_key_type());
111   key_format.mutable_prf_key_template()->set_value(
112       prf_key_format.SerializeAsString());
113   *key_format.mutable_params()->mutable_derived_key_template() =
114       AeadKeyTemplates::Aes256Gcm();
115 
116   EXPECT_THAT(PrfBasedDeriverKeyManager().ValidateKeyFormat(key_format),
117               IsOk());
118 }
119 
TEST(PrfBasedDeriverKeyManagerTest,ValidateKeyFormatEmpty)120 TEST(PrfBasedDeriverKeyManagerTest, ValidateKeyFormatEmpty) {
121   EXPECT_THAT(
122       PrfBasedDeriverKeyManager().ValidateKeyFormat(PrfBasedDeriverKeyFormat()),
123       StatusIs(absl::StatusCode::kInvalidArgument));
124 }
125 
TEST(PrfBasedDeriverKeyManagerTest,CreateKey)126 TEST(PrfBasedDeriverKeyManagerTest, CreateKey) {
127   Registry::Reset();
128   ASSERT_THAT(Registry::RegisterKeyTypeManager(
129                   absl::make_unique<HkdfPrfKeyManager>(), true),
130               IsOk());
131   ASSERT_THAT(Registry::RegisterKeyTypeManager(
132                   absl::make_unique<HkdfPrfKeyManager>(), true),
133               IsOk());
134   ASSERT_THAT(Registry::RegisterKeyTypeManager(
135                   absl::make_unique<AesGcmKeyManager>(), true),
136               IsOk());
137 
138   HkdfPrfKeyFormat prf_key_format;
139   prf_key_format.set_key_size(32);
140   prf_key_format.mutable_params()->set_hash(HashType::SHA256);
141 
142   PrfBasedDeriverKeyFormat key_format;
143   key_format.mutable_prf_key_template()->set_type_url(
144       HkdfPrfKeyManager().get_key_type());
145   key_format.mutable_prf_key_template()->set_value(
146       prf_key_format.SerializeAsString());
147   *key_format.mutable_params()->mutable_derived_key_template() =
148       AeadKeyTemplates::Aes256Gcm();
149 
150   util::StatusOr<PrfBasedDeriverKey> key =
151       PrfBasedDeriverKeyManager().CreateKey(key_format);
152   ASSERT_THAT(key, IsOk());
153   EXPECT_THAT((*key).version(), Eq(0));
154   EXPECT_THAT((*key).prf_key().type_url(),
155               Eq(HkdfPrfKeyManager().get_key_type()));
156   EXPECT_THAT((*key).prf_key().key_material_type(), Eq(KeyData::SYMMETRIC));
157 
158   HkdfPrfKey prf_key;
159   ASSERT_TRUE(prf_key.ParseFromString((*key).prf_key().value()));
160   EXPECT_THAT(prf_key.key_value().size(), Eq(32));
161 
162   EXPECT_THAT((*key).params().derived_key_template().type_url(),
163               Eq(key_format.params().derived_key_template().type_url()));
164   EXPECT_THAT((*key).params().derived_key_template().value(),
165               Eq(key_format.params().derived_key_template().value()));
166 }
167 
TEST(PrfBasedDeriverKeyManagerTest,CreateKeyWithInvalidPrfKey)168 TEST(PrfBasedDeriverKeyManagerTest, CreateKeyWithInvalidPrfKey) {
169   Registry::Reset();
170   ASSERT_THAT(Registry::RegisterKeyTypeManager(
171                   absl::make_unique<HkdfPrfKeyManager>(), true),
172               IsOk());
173   ASSERT_THAT(Registry::RegisterKeyTypeManager(
174                   absl::make_unique<HkdfPrfKeyManager>(), true),
175               IsOk());
176   ASSERT_THAT(Registry::RegisterKeyTypeManager(
177                   absl::make_unique<AesGcmKeyManager>(), true),
178               IsOk());
179 
180   HkdfPrfKeyFormat prf_key_format;
181   prf_key_format.set_key_size(32);
182   prf_key_format.mutable_params()->set_hash(HashType::UNKNOWN_HASH);
183 
184   PrfBasedDeriverKeyFormat key_format;
185   key_format.mutable_prf_key_template()->set_type_url(
186       HkdfPrfKeyManager().get_key_type());
187   key_format.mutable_prf_key_template()->set_value(
188       prf_key_format.SerializeAsString());
189   *key_format.mutable_params()->mutable_derived_key_template() =
190       AeadKeyTemplates::Aes256Gcm();
191 
192   EXPECT_THAT(PrfBasedDeriverKeyManager().CreateKey(key_format).status(),
193               StatusIs(absl::StatusCode::kInvalidArgument));
194 }
195 
TEST(PrfBasedDeriverKeyManagerTest,CreateKeyWithInvalidDerivedKeyTemplate)196 TEST(PrfBasedDeriverKeyManagerTest, CreateKeyWithInvalidDerivedKeyTemplate) {
197   Registry::Reset();
198   ASSERT_THAT(Registry::RegisterKeyTypeManager(
199                   absl::make_unique<HkdfPrfKeyManager>(), true),
200               IsOk());
201   ASSERT_THAT(Registry::RegisterKeyTypeManager(
202                   absl::make_unique<HkdfPrfKeyManager>(), true),
203               IsOk());
204   ASSERT_THAT(Registry::RegisterKeyTypeManager(
205                   absl::make_unique<AesGcmKeyManager>(), true),
206               IsOk());
207 
208   HkdfPrfKeyFormat prf_key_format;
209   prf_key_format.set_key_size(32);
210   prf_key_format.mutable_params()->set_hash(HashType::SHA256);
211   KeyTemplate derived_template;
212   derived_template.set_type_url("nonexistent.type.url");
213 
214   PrfBasedDeriverKeyFormat key_format;
215   key_format.mutable_prf_key_template()->set_type_url(
216       HkdfPrfKeyManager().get_key_type());
217   key_format.mutable_prf_key_template()->set_value(
218       prf_key_format.SerializeAsString());
219   *key_format.mutable_params()->mutable_derived_key_template() =
220       derived_template;
221 
222   // See comment in PrfBasedDeriverKeyManager::CreateKey().
223   EXPECT_THAT(PrfBasedDeriverKeyManager().CreateKey(key_format).status(),
224               IsOk());
225 }
226 
TEST(PrfBasedDeriverKeyManagerTest,GetPrimitive)227 TEST(PrfBasedDeriverKeyManagerTest, GetPrimitive) {
228   Registry::Reset();
229   ASSERT_THAT(Registry::RegisterKeyTypeManager(
230                   absl::make_unique<PrfBasedDeriverKeyManager>(), true),
231               IsOk());
232   ASSERT_THAT(Registry::RegisterKeyTypeManager(
233                   absl::make_unique<HkdfPrfKeyManager>(), true),
234               IsOk());
235   ASSERT_THAT(Registry::RegisterKeyTypeManager(
236                   absl::make_unique<AesGcmKeyManager>(), true),
237               IsOk());
238 
239   HkdfPrfKey prf_key;
240   prf_key.set_version(0);
241   prf_key.mutable_params()->set_hash(HashType::SHA256);
242   prf_key.mutable_params()->set_salt(subtle::Random::GetRandomBytes(15));
243   prf_key.set_key_value(subtle::Random::GetRandomBytes(33));
244   prf_key.mutable_params()->set_hash(HashType::SHA256);
245   PrfBasedDeriverKey key;
246   key.set_version(0);
247   *key.mutable_prf_key() = test::AsKeyData(prf_key, KeyData::SYMMETRIC);
248   *key.mutable_params()->mutable_derived_key_template() =
249       AeadKeyTemplates::Aes256Gcm();
250 
251   StatusOr<std::unique_ptr<KeysetDeriver>> deriver =
252       PrfBasedDeriverKeyManager().GetPrimitive<KeysetDeriver>(key);
253   ASSERT_THAT(deriver, IsOk());
254 
255   std::string salt = subtle::Random::GetRandomBytes(23);
256   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
257       (*deriver)->DeriveKeyset(salt);
258   ASSERT_THAT(handle, IsOk());
259   Keyset keyset = CleartextKeysetHandle::GetKeyset(**handle);
260 
261   StatusOr<std::unique_ptr<KeysetDeriver>> direct_deriver =
262       internal::PrfBasedDeriver::New(key.prf_key(),
263                                      key.params().derived_key_template());
264   ASSERT_THAT(direct_deriver, IsOk());
265   util::StatusOr<std::unique_ptr<KeysetHandle>> direct_handle =
266       (*direct_deriver)->DeriveKeyset(salt);
267   ASSERT_THAT(direct_handle, IsOk());
268   Keyset direct_keyset = CleartextKeysetHandle::GetKeyset(**direct_handle);
269 
270   ASSERT_THAT(keyset.key(), SizeIs(1));
271   ASSERT_THAT(direct_keyset.key(), SizeIs(1));
272 
273   ASSERT_THAT(keyset.key(0).key_data().type_url(),
274               Eq(keyset.key(0).key_data().type_url()));
275 
276   AesGcmKey derived_key;
277   ASSERT_TRUE(derived_key.ParseFromString(keyset.key(0).key_data().value()));
278   AesGcmKey direct_derived_key;
279   ASSERT_TRUE(direct_derived_key.ParseFromString(
280       direct_keyset.key(0).key_data().value()));
281   EXPECT_THAT(derived_key.key_value(), Eq(direct_derived_key.key_value()));
282 }
283 
284 }  // namespace
285 }  // namespace internal
286 }  // namespace tink
287 }  // namespace crypto
288