xref: /aosp_15_r20/external/tink/cc/aead/internal/ssl_aead_large_inputs_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2021 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 #include <algorithm>
17 #include <cstdint>
18 #include <iterator>
19 #include <limits>
20 #include <memory>
21 #include <string>
22 #include <unordered_set>
23 #include <vector>
24 
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "absl/container/flat_hash_set.h"
28 #include "absl/memory/memory.h"
29 #include "absl/status/status.h"
30 #include "absl/strings/escaping.h"
31 #include "absl/strings/string_view.h"
32 #include "absl/types/span.h"
33 #include "tink/aead/internal/ssl_aead.h"
34 #include "tink/config/tink_fips.h"
35 #include "tink/internal/ssl_util.h"
36 #include "tink/internal/util.h"
37 #include "tink/subtle/subtle_util.h"
38 #include "tink/util/secret_data.h"
39 #include "tink/util/statusor.h"
40 #include "tink/util/test_matchers.h"
41 
42 // We test SslOneShotAead implementations against a very large input.
43 namespace crypto {
44 namespace tink {
45 namespace internal {
46 namespace {
47 
48 using ::crypto::tink::test::IsOk;
49 using ::testing::TestWithParam;
50 
51 constexpr absl::string_view kAad = "Some data to authenticate.";
52 // 128 bits key.
53 constexpr absl::string_view k128Key = "000102030405060708090a0b0c0d0e0f";
54 // 256 bits key.
55 constexpr absl::string_view k256Key =
56     "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f";
57 // 12 bytes IV.
58 constexpr absl::string_view kAesGcmIvHex = "0123456789012345678901234";
59 // 24 bytes IV.
60 constexpr absl::string_view kXchacha20Poly1305IvHex =
61     "012345678901234567890123456789012345678901234567";
62 
63 struct TestParams {
64   std::string test_name;
65   std::string cipher;
66   int tag_size;
67   absl::string_view iv_hex;
68   absl::string_view key_hex;
69 };
70 
71 // Returns a SslOneShotAead from `cipher_name` and `key`.
CipherFromName(absl::string_view cipher,const util::SecretData & key)72 util::StatusOr<std::unique_ptr<SslOneShotAead>> CipherFromName(
73     absl::string_view cipher, const util::SecretData& key) {
74   if (cipher == "aes_gcm") {
75     return CreateAesGcmOneShotCrypter(key);
76   }
77   if (cipher == "aes_gcm_siv") {
78     return CreateAesGcmSivOneShotCrypter(key);
79   }
80   if (cipher == "xchacha20_poly1305") {
81     return CreateXchacha20Poly1305OneShotCrypter(key);
82   }
83   return util::Status(absl::StatusCode::kInvalidArgument,
84                       absl::StrCat("Invalid cipher ", cipher));
85 }
86 
87 using SslOneShotAeadLargeInputsTest = TestWithParam<TestParams>;
88 
89 // Encrypt/decrypt with an input larger than a MAX int.
TEST_P(SslOneShotAeadLargeInputsTest,EncryptDecryptLargeInput)90 TEST_P(SslOneShotAeadLargeInputsTest, EncryptDecryptLargeInput) {
91   if (IsWindows()) {
92     GTEST_SKIP() << "Skipping on Windows: this currently times out";
93   }
94   const int64_t buff_size =
95       static_cast<int64_t>(std::numeric_limits<int>::max()) + 1024;
96   std::string large_input(buff_size, '0');
97 
98   TestParams test_param = GetParam();
99   util::StatusOr<std::unique_ptr<SslOneShotAead>> aead = CipherFromName(
100       test_param.cipher, util::SecretDataFromStringView(
101                              absl::HexStringToBytes(test_param.key_hex)));
102   ASSERT_THAT(aead, IsOk());
103 
104   std::string iv = absl::HexStringToBytes(test_param.iv_hex);
105   std::string ciphertext_buffer;
106   // Length of the message + tag.
107   subtle::ResizeStringUninitialized(
108       &ciphertext_buffer, (*aead)->CiphertextSize(large_input.size()));
109 
110   // Encrypt.
111   ASSERT_GE(ciphertext_buffer.size(), large_input.size() + test_param.tag_size);
112   util::StatusOr<int64_t> res = (*aead)->Encrypt(
113       large_input, kAad, iv, absl::MakeSpan(ciphertext_buffer));
114   ASSERT_THAT(res, IsOk());
115   EXPECT_EQ(*res, large_input.size() + test_param.tag_size);
116 
117   // Decrypt.
118   std::string plaintext_buff;
119   subtle::ResizeStringUninitialized(&plaintext_buff, large_input.size());
120   util::StatusOr<int64_t> written_bytes = (*aead)->Decrypt(
121       ciphertext_buffer, kAad, iv, absl::MakeSpan(plaintext_buff));
122   ASSERT_THAT(written_bytes, IsOk());
123   EXPECT_EQ(*written_bytes, large_input.size());
124   EXPECT_EQ(plaintext_buff, large_input);
125 }
126 
GetTestParams()127 std::vector<TestParams> GetTestParams() {
128   std::vector<TestParams> params = {
129       {/*test_name=*/"AesGcm256", /*cipher=*/"aes_gcm",
130        /*tag_size=*/kAesGcmTagSizeInBytes,
131        /*iv_hex=*/kAesGcmIvHex,
132        /*key_hex=*/k256Key},
133       {/*test_name=*/"AesGcm128", /*cipher=*/"aes_gcm",
134        /*tag_size=*/kAesGcmTagSizeInBytes,
135        /*iv_hex=*/kAesGcmIvHex,
136        /*key_hex=*/k128Key}};
137   if (IsBoringSsl()) {
138     params.push_back({/*test_name=*/"AesGcmSiv256", /*cipher=*/"aes_gcm_siv",
139                       /*tag_size=*/kAesGcmTagSizeInBytes,
140                       /*iv_hex=*/kAesGcmIvHex,
141                       /*key_hex=*/k256Key});
142     params.push_back({/*test_name=*/"AesGcmSiv128", /*cipher=*/"aes_gcm_siv",
143                       /*tag_size=*/kAesGcmTagSizeInBytes,
144                       /*iv_hex=*/kAesGcmIvHex,
145                       /*key_hex=*/k128Key});
146     params.push_back({/*test_name=*/"Xchacha20Poly1305",
147                       /*cipher=*/"xchacha20_poly1305",
148                       /*tag_size=*/kXchacha20Poly1305TagSizeInBytes,
149                       /*iv_hex=*/kXchacha20Poly1305IvHex,
150                       /*key_hex=*/k256Key});
151   }
152   return params;
153 }
154 
155 INSTANTIATE_TEST_SUITE_P(
156     SslOneShotAeadLargeInputsTests, SslOneShotAeadLargeInputsTest,
157     testing::ValuesIn(GetTestParams()),
158     [](const testing::TestParamInfo<SslOneShotAeadLargeInputsTest::ParamType>&
__anoncc17e4820202(const testing::TestParamInfo<SslOneShotAeadLargeInputsTest::ParamType>& info) 159            info) { return info.param.test_name; });
160 
161 }  // namespace
162 }  // namespace internal
163 }  // namespace tink
164 }  // namespace crypto
165