xref: /aosp_15_r20/external/tink/cc/aead/cord_aead_wrapper_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2020 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/cord_aead_wrapper.h"
18 
19 #include <stdint.h>
20 
21 #include <memory>
22 #include <string>
23 #include <utility>
24 
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "absl/memory/memory.h"
28 #include "absl/status/status.h"
29 #include "absl/strings/cord.h"
30 #include "absl/strings/cord_test_helpers.h"
31 #include "absl/strings/str_split.h"
32 #include "absl/strings/string_view.h"
33 #include "tink/aead/cord_aead.h"
34 #include "tink/primitive_set.h"
35 #include "tink/util/status.h"
36 #include "tink/util/test_matchers.h"
37 #include "tink/util/test_util.h"
38 #include "proto/tink.pb.h"
39 
40 using ::crypto::tink::test::DummyCordAead;
41 using ::crypto::tink::test::IsOk;
42 using ::crypto::tink::test::StatusIs;
43 using ::google::crypto::tink::KeysetInfo;
44 using ::google::crypto::tink::KeyStatusType;
45 using ::google::crypto::tink::OutputPrefixType;
46 
47 namespace crypto {
48 namespace tink {
49 namespace {
50 
TEST(AeadSetWrapperTest,WrapNullptr)51 TEST(AeadSetWrapperTest, WrapNullptr) {
52   CordAeadWrapper wrapper;
53   auto aead_result = wrapper.Wrap(nullptr);
54   EXPECT_FALSE(aead_result.ok());
55   EXPECT_EQ(absl::StatusCode::kInternal, aead_result.status().code());
56   EXPECT_PRED_FORMAT2(testing::IsSubstring, "non-NULL",
57                       std::string(aead_result.status().message()));
58 }
59 
TEST(AeadSetWrapperTest,WrapEmpty)60 TEST(AeadSetWrapperTest, WrapEmpty) {
61   CordAeadWrapper wrapper;
62   auto aead_result = wrapper.Wrap(absl::make_unique<PrimitiveSet<CordAead>>());
63   EXPECT_FALSE(aead_result.ok());
64   EXPECT_EQ(absl::StatusCode::kInvalidArgument, aead_result.status().code());
65   EXPECT_PRED_FORMAT2(testing::IsSubstring, "no primary",
66                       std::string(aead_result.status().message()));
67 }
68 
setup_keyset()69 std::unique_ptr<PrimitiveSet<CordAead>> setup_keyset() {
70   KeysetInfo::KeyInfo* key_info;
71   KeysetInfo keyset_info;
72 
73   uint32_t key_id_0 = 1234543;
74   key_info = keyset_info.add_key_info();
75   key_info->set_output_prefix_type(OutputPrefixType::TINK);
76   key_info->set_key_id(key_id_0);
77   key_info->set_status(KeyStatusType::ENABLED);
78   std::string aead_name_0 = "aead0";
79   std::unique_ptr<PrimitiveSet<CordAead>> aead_set(
80       new PrimitiveSet<CordAead>());
81   std::unique_ptr<CordAead> aead =
82       absl::make_unique<DummyCordAead>(aead_name_0);
83   auto entry_result =
84       aead_set->AddPrimitive(std::move(aead), keyset_info.key_info(0));
85   auto aead_set_result = aead_set->set_primary(entry_result.value());
86   return aead_set;
87 }
88 
TEST(AeadSetWrapperTest,WrapperEncryptDecrypt)89 TEST(AeadSetWrapperTest, WrapperEncryptDecrypt) {
90   // Wrap aead_set and test the resulting Aead.
91   auto aead_set = setup_keyset();
92   CordAeadWrapper wrapper;
93   auto aead_result = wrapper.Wrap(std::move(aead_set));
94   ASSERT_THAT(aead_result, IsOk());
95   auto aead = std::move(aead_result.value());
96   absl::Cord plaintext;
97   plaintext.Append("some_plaintext");
98   absl::Cord aad;
99   aad.Append("some_aad");
100 
101   auto encrypt_result = aead->Encrypt(plaintext, aad);
102   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
103   absl::Cord ciphertext = encrypt_result.value();
104 
105   auto decrypt_result = aead->Decrypt(ciphertext, aad);
106   EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
107   EXPECT_EQ(plaintext, decrypt_result.value());
108 }
109 
TEST(AeadSetWrapperTest,WrapperEncryptDecryptMultipleKeys)110 TEST(AeadSetWrapperTest, WrapperEncryptDecryptMultipleKeys) {
111   // Wrap aead_set and test the resulting Aead.
112   auto aead_set = setup_keyset();
113 
114   // Encrypt with the primary key
115   absl::Cord plaintext;
116   plaintext.Append("some_plaintext");
117   absl::Cord aad;
118   aad.Append("some_aad");
119   auto encrypt_result =
120       aead_set->get_primary()->get_primitive().Encrypt(plaintext, aad);
121   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
122   absl::Cord ciphertext;
123   ciphertext.Append(aead_set->get_primary()->get_identifier());
124   ciphertext.Append(encrypt_result.value());
125 
126   // Add a second key
127   KeysetInfo::KeyInfo* key_info;
128   KeysetInfo keyset_info;
129   uint32_t key_id = 42;
130   key_info = keyset_info.add_key_info();
131   key_info->set_output_prefix_type(OutputPrefixType::TINK);
132   key_info->set_key_id(key_id);
133   key_info->set_status(KeyStatusType::ENABLED);
134   std::string aead_name = "aead1";
135   std::unique_ptr<CordAead> aead = absl::make_unique<DummyCordAead>(aead_name);
136   auto entry_result =
137       aead_set->AddPrimitive(std::move(aead), keyset_info.key_info(0));
138   EXPECT_TRUE(entry_result.ok()) << entry_result.status();
139 
140   // Wrap the primitive set
141   CordAeadWrapper wrapper;
142   auto aead_result = wrapper.Wrap(std::move(aead_set));
143   ASSERT_THAT(aead_result, IsOk());
144   aead = std::move(aead_result.value());
145 
146   // Encrypt with the wrapped AEAD and check if result was equal to the
147   // encryption with the primary key.
148   auto encrypt_wrap_result = aead->Encrypt(plaintext, aad);
149   EXPECT_TRUE(encrypt_wrap_result.ok()) << encrypt_wrap_result.status();
150   EXPECT_EQ(ciphertext, encrypt_wrap_result.value());
151 }
152 
TEST(AeadSetWrapperTest,WrapperEncryptDecryptManyChunks)153 TEST(AeadSetWrapperTest, WrapperEncryptDecryptManyChunks) {
154   // Wrap aead_set and test the resulting Aead.
155   auto aead_set = setup_keyset();
156   CordAeadWrapper wrapper;
157   auto aead_result = wrapper.Wrap(std::move(aead_set));
158   ASSERT_THAT(aead_result, IsOk());
159   auto aead = std::move(aead_result.value());
160 
161   std::string plaintext = "";
162   for (int i = 0; i < 1000; i++) {
163     plaintext += "chunk" + std::to_string(i);
164   }
165   absl::Cord plaintext_cord =
166       absl::MakeFragmentedCord(absl::StrSplit(plaintext, absl::ByLength(5)));
167   absl::Cord aad;
168   aad.Append("some_aad");
169 
170   auto encrypt_result = aead->Encrypt(plaintext_cord, aad);
171   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
172   absl::Cord ciphertext = encrypt_result.value();
173 
174   auto decrypt_result = aead->Decrypt(ciphertext, aad);
175   EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
176   EXPECT_EQ(plaintext, decrypt_result.value());
177 }
178 
TEST(AeadSetWrapperTest,WrapperEncryptBadDecrypt)179 TEST(AeadSetWrapperTest, WrapperEncryptBadDecrypt) {
180   // Wrap aead_set and test the resulting Aead.
181   auto aead_set = setup_keyset();
182   CordAeadWrapper wrapper;
183   auto aead_result = wrapper.Wrap(std::move(aead_set));
184   ASSERT_THAT(aead_result, IsOk());
185   auto aead = std::move(aead_result.value());
186   absl::Cord plaintext;
187   plaintext.Append("some_plaintext");
188   absl::Cord aad;
189   aad.Append("some_aad");
190 
191   absl::Cord bad_ciphertext;
192   bad_ciphertext.Append("some bad ciphertext");
193   auto decrypt_result = aead->Decrypt(bad_ciphertext, aad);
194   EXPECT_FALSE(decrypt_result.ok());
195   EXPECT_EQ(absl::StatusCode::kInvalidArgument, decrypt_result.status().code());
196   EXPECT_THAT(decrypt_result.status(),
197               StatusIs(absl::StatusCode::kInvalidArgument,
198                        testing::HasSubstr("decryption failed")));
199 }
200 
201 }  // namespace
202 }  // namespace tink
203 }  // namespace crypto
204