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