xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "absl/base/macros.h"
11 #include "absl/strings/escaping.h"
12 #include "absl/strings/string_view.h"
13 #include "quiche/quic/core/quic_utils.h"
14 #include "quiche/quic/platform/api/quic_test.h"
15 #include "quiche/quic/test_tools/quic_test_utils.h"
16 #include "quiche/common/test_tools/quiche_test_utils.h"
17 
18 namespace {
19 
20 // The AES GCM test vectors come from the file gcmEncryptExtIV256.rsp
21 // downloaded from
22 // https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
23 // on 2017-09-27. The test vectors in that file look like this:
24 //
25 // [Keylen = 256]
26 // [IVlen = 96]
27 // [PTlen = 0]
28 // [AADlen = 0]
29 // [Taglen = 128]
30 //
31 // Count = 0
32 // Key = b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4
33 // IV = 516c33929df5a3284ff463d7
34 // PT =
35 // AAD =
36 // CT =
37 // Tag = bdc1ac884d332457a1d2664f168c76f0
38 //
39 // Count = 1
40 // Key = 5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f
41 // IV = 770ac1a5a3d476d5d96944a1
42 // PT =
43 // AAD =
44 // CT =
45 // Tag = 196d691e1047093ca4b3d2ef4baba216
46 //
47 // ...
48 //
49 // The gcmEncryptExtIV256.rsp file is huge (3.2 MB), so a few test vectors were
50 // selected for this unit test.
51 
52 // Describes a group of test vectors that all have a given key length, IV
53 // length, plaintext length, AAD length, and tag length.
54 struct TestGroupInfo {
55   size_t key_len;
56   size_t iv_len;
57   size_t pt_len;
58   size_t aad_len;
59   size_t tag_len;
60 };
61 
62 // Each test vector consists of six strings of lowercase hexadecimal digits.
63 // The strings may be empty (zero length). A test vector with a nullptr |key|
64 // marks the end of an array of test vectors.
65 struct TestVector {
66   const char* key;
67   const char* iv;
68   const char* pt;
69   const char* aad;
70   const char* ct;
71   const char* tag;
72 };
73 
74 const TestGroupInfo test_group_info[] = {
75     {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
76     {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
77 };
78 
79 const TestVector test_group_0[] = {
80     {"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4",
81      "516c33929df5a3284ff463d7", "", "", "",
82      "bdc1ac884d332457a1d2664f168c76f0"},
83     {"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f",
84      "770ac1a5a3d476d5d96944a1", "", "", "",
85      "196d691e1047093ca4b3d2ef4baba216"},
86     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
87 
88 const TestVector test_group_1[] = {
89     {"78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223",
90      "d79cf22d504cc793c3fb6c8a", "", "b96baa8c1c75a671bfb2d08d06be5f36", "",
91      "3e5d486aa2e30b22e040b85723a06e76"},
92     {"4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88",
93      "699d1f29d7b8c55300bb1fd2", "", "6749daeea367d0e9809e2dc2f309e6e3", "",
94      "d60c74d2517fde4a74e0cd4709ed43a9"},
95     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
96 
97 const TestVector test_group_2[] = {
98     {"31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22",
99      "0d18e06c7c725ac9e362e1ce", "2db5168e932556f8089a0622981d017d", "",
100      "fa4362189661d163fcd6a56d8bf0405a", "d636ac1bbedd5cc3ee727dc2ab4a9489"},
101     {"460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99",
102      "8a4a16b9e210eb68bcb6f58d", "99e4e926ffe927f691893fb79a96b067", "",
103      "133fc15751621b5f325c7ff71ce08324", "ec4e87e0cf74a13618d0b68636ba9fa7"},
104     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
105 
106 const TestVector test_group_3[] = {
107     {"24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f",
108      "9ff18563b978ec281b3f2794",
109      "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb15"
110      "8bd9abb3868fdc0d0b074b5f01b2c",
111      "adb5ec720ccf9898500028bf34afccbcaca126ef",
112      "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057"
113      "ad55994cf59ad7f67c0fa5e85fab8",
114      "bc95c532fecc594c36d1550286a7a3f0"},
115     {"fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235",
116      "9fbb5f8252db0bca21f1c230",
117      "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f507"
118      "22e2e4f81115cfcf53f842e2a6c08",
119      "98f8ae1735c39f732e2cbee1156dabeb854ec7a2",
120      "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186"
121      "b7489db4fa060c1fd4159692612c8",
122      "07b48e4a32fac47e115d7ac7445d8330"},
123     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
124 
125 const TestVector test_group_4[] = {
126     {"148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691",
127      "b08a5ea1927499c6ecbfd4e0",
128      "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c2"
129      "75a7cd7b39d638fb81ca52b49dc41",
130      "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca57"
131      "2347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3"
132      "200162a6480a57dad408a0dfeb492e2c5d",
133      "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82"
134      "ee663919c64002a5c198d7878fd3f",
135      "adbecdb0d5c2224d804d2886ff9a5760"},
136     {"e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788",
137      "e7f37d79a6a487a5a703edbb",
138      "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804"
139      "ffdd7991da7a5b6dcf48d4bcd2cbc",
140      "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb17"
141      "8ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad8"
142      "2d5ea428778ca47ee1398792762413cff4",
143      "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae9"
144      "0d8bb3807b471677614f4198af909",
145      "3e403d035c71d88f1be1a256c89ba6ad"},
146     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
147 
148 const TestVector test_group_5[] = {
149     {"82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a",
150      "7b40b20f5f397177990ef2d1", "982a296ee1cd7086afad976945", "",
151      "ec8e05a0471d6b43a59ca5335f", "113ddeafc62373cac2f5951bb9165249"},
152     {"db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240",
153      "40e438357dd80a85cac3349e", "8ddb3397bd42853193cb0f80c9", "",
154      "b694118c85c41abf69e229cb0f", "c07f1b8aafbd152f697eb67f2a85fe45"},
155     {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
156 
157 const TestVector* const test_group_array[] = {
158     test_group_0, test_group_1, test_group_2,
159     test_group_3, test_group_4, test_group_5,
160 };
161 
162 }  // namespace
163 
164 namespace quic {
165 namespace test {
166 
167 // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
168 // in an nonce and also to allocate the buffer needed for the ciphertext.
EncryptWithNonce(Aes256GcmEncrypter * encrypter,absl::string_view nonce,absl::string_view associated_data,absl::string_view plaintext)169 QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
170                            absl::string_view nonce,
171                            absl::string_view associated_data,
172                            absl::string_view plaintext) {
173   size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
174   std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
175 
176   if (!encrypter->Encrypt(nonce, associated_data, plaintext,
177                           reinterpret_cast<unsigned char*>(ciphertext.get()))) {
178     return nullptr;
179   }
180 
181   return new QuicData(ciphertext.release(), ciphertext_size, true);
182 }
183 
184 class Aes256GcmEncrypterTest : public QuicTest {};
185 
TEST_F(Aes256GcmEncrypterTest,Encrypt)186 TEST_F(Aes256GcmEncrypterTest, Encrypt) {
187   for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
188     SCOPED_TRACE(i);
189     const TestVector* test_vectors = test_group_array[i];
190     const TestGroupInfo& test_info = test_group_info[i];
191     for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
192       // Decode the test vector.
193       std::string key;
194       std::string iv;
195       std::string pt;
196       std::string aad;
197       std::string ct;
198       std::string tag;
199       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].key, &key));
200       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].iv, &iv));
201       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].pt, &pt));
202       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].aad, &aad));
203       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].ct, &ct));
204       ASSERT_TRUE(absl::HexStringToBytes(test_vectors[j].tag, &tag));
205 
206       // The test vector's lengths should look sane. Note that the lengths
207       // in |test_info| are in bits.
208       EXPECT_EQ(test_info.key_len, key.length() * 8);
209       EXPECT_EQ(test_info.iv_len, iv.length() * 8);
210       EXPECT_EQ(test_info.pt_len, pt.length() * 8);
211       EXPECT_EQ(test_info.aad_len, aad.length() * 8);
212       EXPECT_EQ(test_info.pt_len, ct.length() * 8);
213       EXPECT_EQ(test_info.tag_len, tag.length() * 8);
214 
215       Aes256GcmEncrypter encrypter;
216       ASSERT_TRUE(encrypter.SetKey(key));
217       std::unique_ptr<QuicData> encrypted(
218           EncryptWithNonce(&encrypter, iv,
219                            // This deliberately tests that the encrypter can
220                            // handle an AAD that is set to nullptr, as opposed
221                            // to a zero-length, non-nullptr pointer.
222                            aad.length() ? aad : absl::string_view(), pt));
223       ASSERT_TRUE(encrypted.get());
224 
225       ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
226       quiche::test::CompareCharArraysWithHexError(
227           "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
228       quiche::test::CompareCharArraysWithHexError(
229           "authentication tag", encrypted->data() + ct.length(), tag.length(),
230           tag.data(), tag.length());
231     }
232   }
233 }
234 
TEST_F(Aes256GcmEncrypterTest,GetMaxPlaintextSize)235 TEST_F(Aes256GcmEncrypterTest, GetMaxPlaintextSize) {
236   Aes256GcmEncrypter encrypter;
237   EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
238   EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
239   EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
240 }
241 
TEST_F(Aes256GcmEncrypterTest,GetCiphertextSize)242 TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) {
243   Aes256GcmEncrypter encrypter;
244   EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
245   EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
246   EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
247 }
248 
TEST_F(Aes256GcmEncrypterTest,GenerateHeaderProtectionMask)249 TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
250   Aes256GcmEncrypter encrypter;
251   std::string key;
252   std::string sample;
253   std::string expected_mask;
254   ASSERT_TRUE(absl::HexStringToBytes(
255       "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788",
256       &key));
257   ASSERT_TRUE(
258       absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810", &sample));
259   ASSERT_TRUE(absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e",
260                                      &expected_mask));
261   ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
262   std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
263   quiche::test::CompareCharArraysWithHexError(
264       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
265       expected_mask.size());
266 }
267 
268 }  // namespace test
269 }  // namespace quic
270