xref: /aosp_15_r20/external/tink/cc/aead/aead_config_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2017 Google Inc.
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_config.h"
18 
19 #include <list>
20 #include <memory>
21 #include <string>
22 #include <utility>
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_key_templates.h"
30 #include "tink/aead/aes_gcm_key.h"
31 #include "tink/aead/aes_gcm_key_manager.h"
32 #include "tink/aead/aes_gcm_parameters.h"
33 #include "tink/config/tink_fips.h"
34 #include "tink/insecure_secret_key_access.h"
35 #include "tink/internal/fips_utils.h"
36 #include "tink/internal/mutable_serialization_registry.h"
37 #include "tink/internal/proto_key_serialization.h"
38 #include "tink/internal/proto_parameters_serialization.h"
39 #include "tink/keyset_handle.h"
40 #include "tink/partial_key_access.h"
41 #include "tink/primitive_set.h"
42 #include "tink/registry.h"
43 #include "tink/util/status.h"
44 #include "tink/util/statusor.h"
45 #include "tink/util/test_matchers.h"
46 #include "proto/tink.pb.h"
47 
48 namespace crypto {
49 namespace tink {
50 namespace {
51 
52 using ::crypto::tink::test::IsOk;
53 using ::crypto::tink::test::StatusIs;
54 using ::crypto::tink::util::StatusOr;
55 using ::google::crypto::tink::KeyData;
56 using ::google::crypto::tink::KeyTemplate;
57 using ::google::crypto::tink::OutputPrefixType;
58 using ::testing::IsNull;
59 using ::testing::Not;
60 using ::testing::Test;
61 
62 class AeadConfigTest : public Test {
63  protected:
SetUp()64   void SetUp() override {
65     Registry::Reset();
66     internal::MutableSerializationRegistry::GlobalInstance().Reset();
67   }
68 };
69 
TEST_F(AeadConfigTest,RegisterWorks)70 TEST_F(AeadConfigTest, RegisterWorks) {
71   if (IsFipsModeEnabled()) {
72     GTEST_SKIP() << "Not supported in FIPS-only mode";
73   }
74   EXPECT_THAT(Registry::get_key_manager<Aead>(AesGcmKeyManager().get_key_type())
75                   .status(),
76               StatusIs(absl::StatusCode::kNotFound));
77   EXPECT_THAT(AeadConfig::Register(), IsOk());
78   EXPECT_THAT(Registry::get_key_manager<Aead>(AesGcmKeyManager().get_key_type())
79                   .status(),
80               IsOk());
81 }
82 
83 // Tests that the AeadWrapper has been properly registered and we can wrap
84 // primitives.
TEST_F(AeadConfigTest,WrappersRegistered)85 TEST_F(AeadConfigTest, WrappersRegistered) {
86   if (IsFipsModeEnabled()) {
87     GTEST_SKIP() << "Not supported in FIPS-only mode";
88   }
89 
90   ASSERT_THAT(AeadConfig::Register(), IsOk());
91 
92   StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
93       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm());
94   ASSERT_THAT(keyset_handle.status(), IsOk());
95   StatusOr<std::unique_ptr<Aead>> aead = (*keyset_handle)->GetPrimitive<Aead>();
96   ASSERT_THAT(aead.status(), IsOk());
97   ASSERT_THAT(*aead, Not(IsNull()));
98 }
99 
100 // FIPS-only mode tests
TEST_F(AeadConfigTest,RegisterNonFipsTemplates)101 TEST_F(AeadConfigTest, RegisterNonFipsTemplates) {
102   if (!IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
103     GTEST_SKIP() << "Only supported in FIPS-only mode with BoringCrypto.";
104   }
105 
106   ASSERT_THAT(AeadConfig::Register(), IsOk());
107 
108   std::list<KeyTemplate> non_fips_key_templates = {
109       AeadKeyTemplates::Aes128Eax(),         AeadKeyTemplates::Aes256Eax(),
110       AeadKeyTemplates::Aes128GcmSiv(),      AeadKeyTemplates::Aes256GcmSiv(),
111       AeadKeyTemplates::XChaCha20Poly1305(),
112   };
113 
114   for (auto key_template : non_fips_key_templates) {
115     auto new_keyset_handle_result = KeysetHandle::GenerateNew(key_template);
116     EXPECT_THAT(new_keyset_handle_result.status(),
117                 StatusIs(absl::StatusCode::kNotFound));
118   }
119 }
120 
TEST_F(AeadConfigTest,RegisterFipsValidTemplates)121 TEST_F(AeadConfigTest, RegisterFipsValidTemplates) {
122   if (!IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
123     GTEST_SKIP() << "Only supported in FIPS-only mode with BoringCrypto.";
124   }
125 
126   EXPECT_THAT(AeadConfig::Register(), IsOk());
127 
128   std::list<KeyTemplate> fips_key_templates = {
129       AeadKeyTemplates::Aes128Gcm(),
130       AeadKeyTemplates::Aes256Gcm(),
131       AeadKeyTemplates::Aes128CtrHmacSha256(),
132       AeadKeyTemplates::Aes256CtrHmacSha256(),
133   };
134 
135   for (auto key_template : fips_key_templates) {
136     auto new_keyset_handle_result = KeysetHandle::GenerateNew(key_template);
137     EXPECT_THAT(new_keyset_handle_result, IsOk());
138   }
139 }
140 
TEST_F(AeadConfigTest,RegisterFailsIfBoringCryptoNotAvailable)141 TEST_F(AeadConfigTest, RegisterFailsIfBoringCryptoNotAvailable) {
142   if (!IsFipsModeEnabled() || internal::IsFipsEnabledInSsl()) {
143     GTEST_SKIP()
144         << "Only supported in FIPS-only mode with BoringCrypto not available.";
145   }
146 
147   EXPECT_THAT(Registry::get_key_manager<Aead>(AesGcmKeyManager().get_key_type())
148                   .status(),
149               StatusIs(absl::StatusCode::kNotFound));
150   EXPECT_THAT(AeadConfig::Register(), StatusIs(absl::StatusCode::kInternal));
151 }
152 
TEST_F(AeadConfigTest,AesGcmProtoParamsSerializationRegistered)153 TEST_F(AeadConfigTest, AesGcmProtoParamsSerializationRegistered) {
154   if (IsFipsModeEnabled()) {
155     GTEST_SKIP() << "Not supported in FIPS-only mode";
156   }
157 
158   util::StatusOr<internal::ProtoParametersSerialization>
159       proto_params_serialization =
160           internal::ProtoParametersSerialization::Create(
161               AeadKeyTemplates::Aes256Gcm());
162   ASSERT_THAT(proto_params_serialization, IsOk());
163 
164   util::StatusOr<std::unique_ptr<Parameters>> parsed_params =
165       internal::MutableSerializationRegistry::GlobalInstance().ParseParameters(
166           *proto_params_serialization);
167   ASSERT_THAT(parsed_params.status(), StatusIs(absl::StatusCode::kNotFound));
168 
169   util::StatusOr<AesGcmParameters> params =
170       AesGcmParameters::Builder()
171           .SetVariant(AesGcmParameters::Variant::kTink)
172           .SetKeySizeInBytes(32)
173           .SetIvSizeInBytes(12)
174           .SetTagSizeInBytes(16)
175           .Build();
176   ASSERT_THAT(params, IsOk());
177 
178   util::StatusOr<std::unique_ptr<Serialization>> serialized_params =
179       internal::MutableSerializationRegistry::GlobalInstance()
180           .SerializeParameters<internal::ProtoParametersSerialization>(*params);
181   ASSERT_THAT(serialized_params.status(),
182               StatusIs(absl::StatusCode::kNotFound));
183 
184   ASSERT_THAT(AeadConfig::Register(), IsOk());
185 
186   util::StatusOr<std::unique_ptr<Parameters>> parsed_params2 =
187       internal::MutableSerializationRegistry::GlobalInstance().ParseParameters(
188           *proto_params_serialization);
189   ASSERT_THAT(parsed_params2, IsOk());
190 
191   util::StatusOr<std::unique_ptr<Serialization>> serialized_params2 =
192       internal::MutableSerializationRegistry::GlobalInstance()
193           .SerializeParameters<internal::ProtoParametersSerialization>(*params);
194   ASSERT_THAT(serialized_params2, IsOk());
195 }
196 
TEST_F(AeadConfigTest,AesGcmProtoKeySerializationRegistered)197 TEST_F(AeadConfigTest, AesGcmProtoKeySerializationRegistered) {
198   if (IsFipsModeEnabled()) {
199     GTEST_SKIP() << "Not supported in FIPS-only mode";
200   }
201 
202   google::crypto::tink::AesGcmKey key_proto;
203   key_proto.set_version(0);
204   key_proto.set_key_value(subtle::Random::GetRandomBytes(32));
205 
206   util::StatusOr<internal::ProtoKeySerialization> proto_key_serialization =
207       internal::ProtoKeySerialization::Create(
208           "type.googleapis.com/google.crypto.tink.AesGcmKey",
209           RestrictedData(key_proto.SerializeAsString(),
210                          InsecureSecretKeyAccess::Get()),
211           KeyData::SYMMETRIC, OutputPrefixType::TINK, /*id_requirement=*/123);
212   ASSERT_THAT(proto_key_serialization, IsOk());
213 
214   util::StatusOr<std::unique_ptr<Key>> parsed_key =
215       internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
216           *proto_key_serialization, InsecureSecretKeyAccess::Get());
217   ASSERT_THAT(parsed_key.status(), StatusIs(absl::StatusCode::kNotFound));
218 
219   util::StatusOr<AesGcmParameters> params =
220       AesGcmParameters::Builder()
221           .SetVariant(AesGcmParameters::Variant::kTink)
222           .SetKeySizeInBytes(32)
223           .SetIvSizeInBytes(12)
224           .SetTagSizeInBytes(16)
225           .Build();
226   ASSERT_THAT(params, IsOk());
227 
228   util::StatusOr<AesGcmKey> key =
229       AesGcmKey::Create(*params,
230                         RestrictedData(subtle::Random::GetRandomBytes(32),
231                                        InsecureSecretKeyAccess::Get()),
232                         /*id_requirement=*/123, GetPartialKeyAccess());
233   ASSERT_THAT(key, IsOk());
234 
235   util::StatusOr<std::unique_ptr<Serialization>> serialized_key =
236       internal::MutableSerializationRegistry::GlobalInstance()
237           .SerializeKey<internal::ProtoKeySerialization>(
238               *key, InsecureSecretKeyAccess::Get());
239   ASSERT_THAT(serialized_key.status(), StatusIs(absl::StatusCode::kNotFound));
240 
241   ASSERT_THAT(AeadConfig::Register(), IsOk());
242 
243   util::StatusOr<std::unique_ptr<Key>> parsed_key2 =
244       internal::MutableSerializationRegistry::GlobalInstance().ParseKey(
245           *proto_key_serialization, InsecureSecretKeyAccess::Get());
246   ASSERT_THAT(parsed_key2, IsOk());
247 
248   util::StatusOr<std::unique_ptr<Serialization>> serialized_key2 =
249       internal::MutableSerializationRegistry::GlobalInstance()
250           .SerializeKey<internal::ProtoKeySerialization>(
251               *key, InsecureSecretKeyAccess::Get());
252   ASSERT_THAT(serialized_key2, IsOk());
253 }
254 
255 }  // namespace
256 }  // namespace tink
257 }  // namespace crypto
258