1 // Copyright 2014 The BoringSSL Authors
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 //     https://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 #include <assert.h>
16 #include <stdint.h>
17 #include <string.h>
18 
19 #include <vector>
20 
21 #include <gtest/gtest.h>
22 
23 #include <openssl/aead.h>
24 #include <openssl/cipher.h>
25 #include <openssl/err.h>
26 
27 #include "../fipsmodule/cipher/internal.h"
28 #include "../internal.h"
29 #include "../test/abi_test.h"
30 #include "../test/file_test.h"
31 #include "../test/test_util.h"
32 #include "../test/wycheproof_util.h"
33 #include "internal.h"
34 
35 namespace {
36 
37 // kLimitedImplementation indicates that tests that assume a generic AEAD
38 // interface should not be performed. For example, the key-wrap AEADs only
39 // handle inputs that are a multiple of eight bytes in length and the TLS CBC
40 // AEADs have the concept of “direction”.
41 constexpr uint32_t kLimitedImplementation = 1 << 0;
42 // kCanTruncateTags indicates that the AEAD supports truncatating tags to
43 // arbitrary lengths.
44 constexpr uint32_t kCanTruncateTags = 1 << 1;
45 // kVariableNonce indicates that the AEAD supports a variable-length nonce.
46 constexpr uint32_t kVariableNonce = 1 << 2;
47 // kNondeterministic indicates that the AEAD performs randomised encryption thus
48 // one cannot assume that encrypting the same data will result in the same
49 // ciphertext.
50 constexpr uint32_t kNondeterministic = 1 << 7;
51 
52 // RequiresADLength encodes an AD length requirement into flags.
RequiresADLength(size_t length)53 constexpr uint32_t RequiresADLength(size_t length) {
54   assert(length < 16);
55   return static_cast<uint32_t>((length & 0xf) << 3);
56 }
57 
58 // RequiredADLength returns the AD length requirement encoded in |flags|, or
59 // zero if there isn't one.
RequiredADLength(uint32_t flags)60 constexpr size_t RequiredADLength(uint32_t flags) { return (flags >> 3) & 0xf; }
61 
RequiresMinimumTagLength(size_t length)62 constexpr uint32_t RequiresMinimumTagLength(size_t length) {
63   assert(length < 16);
64   return static_cast<uint32_t>((length & 0xf) << 8);
65 }
66 
MinimumTagLength(uint32_t flags)67 constexpr size_t MinimumTagLength(uint32_t flags) {
68   return ((flags >> 8) & 0xf) == 0 ? 1 : ((flags >> 8) & 0xf);
69 }
70 
71 struct KnownAEAD {
72   const char name[40];
73   const EVP_AEAD *(*func)(void);
74   const char *test_vectors;
75   uint32_t flags;
76 };
77 
78 static const struct KnownAEAD kAEADs[] = {
79     {"AES_128_GCM", EVP_aead_aes_128_gcm, "aes_128_gcm_tests.txt",
80      kCanTruncateTags | kVariableNonce},
81 
82     {"AES_128_GCM_NIST", EVP_aead_aes_128_gcm, "nist_cavp/aes_128_gcm.txt",
83      kCanTruncateTags | kVariableNonce},
84 
85     {"AES_192_GCM", EVP_aead_aes_192_gcm, "aes_192_gcm_tests.txt",
86      kCanTruncateTags | kVariableNonce},
87 
88     {"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt",
89      kCanTruncateTags | kVariableNonce},
90 
91     {"AES_256_GCM_NIST", EVP_aead_aes_256_gcm, "nist_cavp/aes_256_gcm.txt",
92      kCanTruncateTags | kVariableNonce},
93 
94     {"AES_128_GCM_SIV", EVP_aead_aes_128_gcm_siv, "aes_128_gcm_siv_tests.txt",
95      0},
96 
97     {"AES_256_GCM_SIV", EVP_aead_aes_256_gcm_siv, "aes_256_gcm_siv_tests.txt",
98      0},
99 
100     {"AES_128_GCM_RandomNonce", EVP_aead_aes_128_gcm_randnonce,
101      "aes_128_gcm_randnonce_tests.txt",
102      kNondeterministic | kCanTruncateTags | RequiresMinimumTagLength(13)},
103 
104     {"AES_256_GCM_RandomNonce", EVP_aead_aes_256_gcm_randnonce,
105      "aes_256_gcm_randnonce_tests.txt",
106      kNondeterministic | kCanTruncateTags | RequiresMinimumTagLength(13)},
107 
108     {"ChaCha20Poly1305", EVP_aead_chacha20_poly1305,
109      "chacha20_poly1305_tests.txt", kCanTruncateTags},
110 
111     {"XChaCha20Poly1305", EVP_aead_xchacha20_poly1305,
112      "xchacha20_poly1305_tests.txt", kCanTruncateTags},
113 
114     {"AES_128_CBC_SHA1_TLS", EVP_aead_aes_128_cbc_sha1_tls,
115      "aes_128_cbc_sha1_tls_tests.txt",
116      kLimitedImplementation | RequiresADLength(11)},
117 
118     {"AES_128_CBC_SHA1_TLSImplicitIV",
119      EVP_aead_aes_128_cbc_sha1_tls_implicit_iv,
120      "aes_128_cbc_sha1_tls_implicit_iv_tests.txt",
121      kLimitedImplementation | RequiresADLength(11)},
122 
123     {"AES_256_CBC_SHA1_TLS", EVP_aead_aes_256_cbc_sha1_tls,
124      "aes_256_cbc_sha1_tls_tests.txt",
125      kLimitedImplementation | RequiresADLength(11)},
126 
127     {"AES_256_CBC_SHA1_TLSImplicitIV",
128      EVP_aead_aes_256_cbc_sha1_tls_implicit_iv,
129      "aes_256_cbc_sha1_tls_implicit_iv_tests.txt",
130      kLimitedImplementation | RequiresADLength(11)},
131 
132     {"DES_EDE3_CBC_SHA1_TLS", EVP_aead_des_ede3_cbc_sha1_tls,
133      "des_ede3_cbc_sha1_tls_tests.txt",
134      kLimitedImplementation | RequiresADLength(11)},
135 
136     {"DES_EDE3_CBC_SHA1_TLSImplicitIV",
137      EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv,
138      "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt",
139      kLimitedImplementation | RequiresADLength(11)},
140 
141     {"AES_128_CTR_HMAC_SHA256", EVP_aead_aes_128_ctr_hmac_sha256,
142      "aes_128_ctr_hmac_sha256.txt", kCanTruncateTags},
143 
144     {"AES_256_CTR_HMAC_SHA256", EVP_aead_aes_256_ctr_hmac_sha256,
145      "aes_256_ctr_hmac_sha256.txt", kCanTruncateTags},
146 
147     {"AES_128_CCM_BLUETOOTH", EVP_aead_aes_128_ccm_bluetooth,
148      "aes_128_ccm_bluetooth_tests.txt", 0},
149 
150     {"AES_128_CCM_BLUETOOTH_8", EVP_aead_aes_128_ccm_bluetooth_8,
151      "aes_128_ccm_bluetooth_8_tests.txt", 0},
152 
153     {"AES_128_CCM_Matter", EVP_aead_aes_128_ccm_matter,
154      "aes_128_ccm_matter_tests.txt", 0},
155 
156     {"AES_128_EAX", EVP_aead_aes_128_eax, "aes_128_eax_test.txt",
157      kVariableNonce},
158 
159     {"AES_256_EAX", EVP_aead_aes_256_eax, "aes_256_eax_test.txt",
160      kVariableNonce},
161 };
162 
163 class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
164  public:
aead()165   const EVP_AEAD *aead() { return GetParam().func(); }
166 };
167 
168 INSTANTIATE_TEST_SUITE_P(All, PerAEADTest, testing::ValuesIn(kAEADs),
169                          [](const testing::TestParamInfo<KnownAEAD> &params)
__anonfbd1ca810202(const testing::TestParamInfo<KnownAEAD> &params) 170                              -> std::string { return params.param.name; });
171 
172 // Tests an AEAD against a series of test vectors from a file, using the
173 // FileTest format. As an example, here's a valid test case:
174 //
175 //   KEY: 5a19f3173586b4c42f8412f4d5a786531b3231753e9e00998aec12fda8df10e4
176 //   NONCE: 978105dfce667bf4
177 //   IN: 6a4583908d
178 //   AD: b654574932
179 //   CT: 5294265a60
180 //   TAG: 1d45758621762e061368e68868e2f929
TEST_P(PerAEADTest,TestVector)181 TEST_P(PerAEADTest, TestVector) {
182   std::string test_vectors = "crypto/cipher/test/";
183   test_vectors += GetParam().test_vectors;
184   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
185     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
186     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
187     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
188     ASSERT_TRUE(t->GetBytes(&in, "IN"));
189     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
190     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
191     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
192     size_t tag_len = tag.size();
193     if (t->HasAttribute("TAG_LEN")) {
194       // Legacy AEADs are MAC-then-encrypt and may include padding in the TAG
195       // field. TAG_LEN contains the actual size of the digest in that case.
196       std::string tag_len_str;
197       ASSERT_TRUE(t->GetAttribute(&tag_len_str, "TAG_LEN"));
198       tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
199       ASSERT_TRUE(tag_len);
200     }
201 
202     bssl::ScopedEVP_AEAD_CTX ctx;
203     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
204         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_seal));
205 
206     std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead()));
207     if (!t->HasAttribute("NO_SEAL") &&
208         !(GetParam().flags & kNondeterministic)) {
209       size_t out_len;
210       ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
211                                     nonce.data(), nonce.size(), in.data(),
212                                     in.size(), ad.data(), ad.size()));
213       out.resize(out_len);
214 
215       ASSERT_EQ(out.size(), ct.size() + tag.size());
216       EXPECT_EQ(Bytes(ct), Bytes(out.data(), ct.size()));
217       EXPECT_EQ(Bytes(tag), Bytes(out.data() + ct.size(), tag.size()));
218     } else {
219       out.resize(ct.size() + tag.size());
220       OPENSSL_memcpy(out.data(), ct.data(), ct.size());
221       OPENSSL_memcpy(out.data() + ct.size(), tag.data(), tag.size());
222     }
223 
224     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
225     // reset after each operation.
226     ctx.Reset();
227     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
228         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
229 
230     std::vector<uint8_t> out2(out.size());
231     size_t out2_len;
232     int ret = EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
233                                 nonce.data(), nonce.size(), out.data(),
234                                 out.size(), ad.data(), ad.size());
235     if (t->HasAttribute("FAILS")) {
236       ASSERT_FALSE(ret) << "Decrypted bad data.";
237       ERR_clear_error();
238       return;
239     }
240 
241     ASSERT_TRUE(ret) << "Failed to decrypt.";
242     out2.resize(out2_len);
243     EXPECT_EQ(Bytes(in), Bytes(out2));
244 
245     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
246     // reset after each operation.
247     ctx.Reset();
248     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
249         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
250 
251     // Garbage at the end isn't ignored.
252     out.push_back(0);
253     out2.resize(out.size());
254     EXPECT_FALSE(EVP_AEAD_CTX_open(
255         ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
256         nonce.size(), out.data(), out.size(), ad.data(), ad.size()))
257         << "Decrypted bad data with trailing garbage.";
258     ERR_clear_error();
259 
260     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
261     // reset after each operation.
262     ctx.Reset();
263     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
264         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
265 
266     // Verify integrity is checked.
267     out[0] ^= 0x80;
268     out.resize(out.size() - 1);
269     out2.resize(out.size());
270     EXPECT_FALSE(EVP_AEAD_CTX_open(
271         ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
272         nonce.size(), out.data(), out.size(), ad.data(), ad.size()))
273         << "Decrypted bad data with corrupted byte.";
274     ERR_clear_error();
275   });
276 }
277 
TEST_P(PerAEADTest,TestExtraInput)278 TEST_P(PerAEADTest, TestExtraInput) {
279   const KnownAEAD &aead_config = GetParam();
280   if (!aead()->seal_scatter_supports_extra_in) {
281     return;
282   }
283 
284   const std::string test_vectors =
285       "crypto/cipher/test/" + std::string(aead_config.test_vectors);
286   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
287     if (t->HasAttribute("NO_SEAL") ||  //
288         t->HasAttribute("FAILS") ||    //
289         (aead_config.flags & kNondeterministic)) {
290       t->SkipCurrent();
291       return;
292     }
293 
294     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
295     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
296     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
297     ASSERT_TRUE(t->GetBytes(&in, "IN"));
298     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
299     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
300     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
301 
302     bssl::ScopedEVP_AEAD_CTX ctx;
303     ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key.data(), key.size(),
304                                   tag.size(), nullptr));
305     std::vector<uint8_t> out_tag(EVP_AEAD_max_overhead(aead()) + in.size());
306     std::vector<uint8_t> out(in.size());
307 
308     for (size_t extra_in_size = 0; extra_in_size < in.size(); extra_in_size++) {
309       size_t tag_bytes_written;
310       SCOPED_TRACE(extra_in_size);
311       ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
312           ctx.get(), out.data(), out_tag.data(), &tag_bytes_written,
313           out_tag.size(), nonce.data(), nonce.size(), in.data(),
314           in.size() - extra_in_size, in.data() + in.size() - extra_in_size,
315           extra_in_size, ad.data(), ad.size()));
316 
317       ASSERT_EQ(tag_bytes_written, extra_in_size + tag.size());
318 
319       memcpy(out.data() + in.size() - extra_in_size, out_tag.data(),
320              extra_in_size);
321 
322       EXPECT_EQ(Bytes(ct), Bytes(out.data(), in.size()));
323       EXPECT_EQ(Bytes(tag), Bytes(out_tag.data() + extra_in_size,
324                                   tag_bytes_written - extra_in_size));
325     }
326   });
327 }
328 
TEST_P(PerAEADTest,TestVectorScatterGather)329 TEST_P(PerAEADTest, TestVectorScatterGather) {
330   std::string test_vectors = "crypto/cipher/test/";
331   const KnownAEAD &aead_config = GetParam();
332   test_vectors += aead_config.test_vectors;
333   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
334     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
335     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
336     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
337     ASSERT_TRUE(t->GetBytes(&in, "IN"));
338     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
339     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
340     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
341     size_t tag_len = tag.size();
342     if (t->HasAttribute("TAG_LEN")) {
343       // Legacy AEADs are MAC-then-encrypt and may include padding in the TAG
344       // field. TAG_LEN contains the actual size of the digest in that case.
345       std::string tag_len_str;
346       ASSERT_TRUE(t->GetAttribute(&tag_len_str, "TAG_LEN"));
347       tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
348       ASSERT_TRUE(tag_len);
349     }
350 
351     bssl::ScopedEVP_AEAD_CTX ctx;
352     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
353         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_seal));
354 
355     std::vector<uint8_t> out(in.size());
356     std::vector<uint8_t> out_tag(EVP_AEAD_max_overhead(aead()));
357     if (!t->HasAttribute("NO_SEAL") &&
358         !(aead_config.flags & kNondeterministic)) {
359       size_t out_tag_len;
360       ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
361           ctx.get(), out.data(), out_tag.data(), &out_tag_len, out_tag.size(),
362           nonce.data(), nonce.size(), in.data(), in.size(), nullptr, 0,
363           ad.data(), ad.size()));
364       out_tag.resize(out_tag_len);
365 
366       ASSERT_EQ(out.size(), ct.size());
367       ASSERT_EQ(out_tag.size(), tag.size());
368       EXPECT_EQ(Bytes(ct), Bytes(out.data(), ct.size()));
369       EXPECT_EQ(Bytes(tag), Bytes(out_tag.data(), tag.size()));
370     } else {
371       out.resize(ct.size());
372       out_tag.resize(tag.size());
373       OPENSSL_memcpy(out.data(), ct.data(), ct.size());
374       OPENSSL_memcpy(out_tag.data(), tag.data(), tag.size());
375     }
376 
377     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
378     // reset after each operation.
379     ctx.Reset();
380     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
381         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
382 
383     std::vector<uint8_t> out2(out.size());
384     int ret = EVP_AEAD_CTX_open_gather(
385         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
386         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size());
387 
388     // Skip decryption for AEADs that don't implement open_gather().
389     if (!ret) {
390       uint32_t err = ERR_peek_error();
391       if (ERR_GET_LIB(err) == ERR_LIB_CIPHER &&
392           ERR_GET_REASON(err) == CIPHER_R_CTRL_NOT_IMPLEMENTED) {
393         t->SkipCurrent();
394         return;
395       }
396     }
397 
398     if (t->HasAttribute("FAILS")) {
399       ASSERT_FALSE(ret) << "Decrypted bad data";
400       ERR_clear_error();
401       return;
402     }
403 
404     ASSERT_TRUE(ret) << "Failed to decrypt: "
405                      << ERR_reason_error_string(ERR_get_error());
406     EXPECT_EQ(Bytes(in), Bytes(out2));
407 
408     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
409     // reset after each operation.
410     ctx.Reset();
411     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
412         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
413 
414     // Garbage at the end isn't ignored.
415     out_tag.push_back(0);
416     ASSERT_EQ(out2.size(), out.size());
417     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
418         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
419         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
420         << "Decrypted bad data with trailing garbage.";
421     ERR_clear_error();
422 
423     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
424     // reset after each operation.
425     ctx.Reset();
426     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
427         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
428 
429     // Verify integrity is checked.
430     out_tag[0] ^= 0x80;
431     out_tag.resize(out_tag.size() - 1);
432     ASSERT_EQ(out2.size(), out.size());
433     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
434         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
435         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
436         << "Decrypted bad data with corrupted byte.";
437     ERR_clear_error();
438 
439     ctx.Reset();
440     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
441         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
442 
443     // Check edge case for tag length.
444     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
445         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
446         out.size(), out_tag.data(), 0, ad.data(), ad.size()))
447         << "Decrypted bad data with corrupted byte.";
448     ERR_clear_error();
449   });
450 }
451 
TEST_P(PerAEADTest,CleanupAfterInitFailure)452 TEST_P(PerAEADTest, CleanupAfterInitFailure) {
453   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
454   OPENSSL_memset(key, 0, sizeof(key));
455   const size_t key_len = EVP_AEAD_key_length(aead());
456   ASSERT_GE(sizeof(key), key_len);
457 
458   EVP_AEAD_CTX ctx;
459   ASSERT_FALSE(EVP_AEAD_CTX_init(
460       &ctx, aead(), key, key_len,
461       9999 /* a silly tag length to trigger an error */, NULL /* ENGINE */));
462   ERR_clear_error();
463 
464   // Running a second, failed _init should not cause a memory leak.
465   ASSERT_FALSE(EVP_AEAD_CTX_init(
466       &ctx, aead(), key, key_len,
467       9999 /* a silly tag length to trigger an error */, NULL /* ENGINE */));
468   ERR_clear_error();
469 
470   // Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
471   // no-op.
472   EVP_AEAD_CTX_cleanup(&ctx);
473 }
474 
TEST_P(PerAEADTest,TruncatedTags)475 TEST_P(PerAEADTest, TruncatedTags) {
476   if (!(GetParam().flags & kCanTruncateTags)) {
477     return;
478   }
479 
480   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
481   OPENSSL_memset(key, 0, sizeof(key));
482   const size_t key_len = EVP_AEAD_key_length(aead());
483   ASSERT_GE(sizeof(key), key_len);
484 
485   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
486   OPENSSL_memset(nonce, 0, sizeof(nonce));
487   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
488   ASSERT_GE(sizeof(nonce), nonce_len);
489 
490   const size_t tag_len = MinimumTagLength(GetParam().flags);
491   bssl::ScopedEVP_AEAD_CTX ctx;
492   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key, key_len, tag_len,
493                                 NULL /* ENGINE */));
494 
495   const uint8_t plaintext[1] = {'A'};
496 
497   uint8_t ciphertext[128];
498   size_t ciphertext_len;
499   constexpr uint8_t kSentinel = 42;
500   OPENSSL_memset(ciphertext, kSentinel, sizeof(ciphertext));
501 
502   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), ciphertext, &ciphertext_len,
503                                 sizeof(ciphertext), nonce, nonce_len, plaintext,
504                                 sizeof(plaintext), nullptr /* ad */, 0));
505 
506   for (size_t i = ciphertext_len; i < sizeof(ciphertext); i++) {
507     // Sealing must not write past where it said it did.
508     EXPECT_EQ(kSentinel, ciphertext[i])
509         << "Sealing wrote off the end of the buffer.";
510   }
511 
512   const size_t overhead_used = ciphertext_len - sizeof(plaintext);
513   const size_t expected_overhead =
514       tag_len + EVP_AEAD_max_overhead(aead()) - EVP_AEAD_max_tag_len(aead());
515   EXPECT_EQ(overhead_used, expected_overhead)
516       << "AEAD is probably ignoring request to truncate tags.";
517 
518   uint8_t plaintext2[sizeof(plaintext) + 16];
519   OPENSSL_memset(plaintext2, kSentinel, sizeof(plaintext2));
520 
521   size_t plaintext2_len;
522   ASSERT_TRUE(EVP_AEAD_CTX_open(
523       ctx.get(), plaintext2, &plaintext2_len, sizeof(plaintext2), nonce,
524       nonce_len, ciphertext, ciphertext_len, nullptr /* ad */, 0))
525       << "Opening with truncated tag didn't work.";
526 
527   for (size_t i = plaintext2_len; i < sizeof(plaintext2); i++) {
528     // Likewise, opening should also stay within bounds.
529     EXPECT_EQ(kSentinel, plaintext2[i])
530         << "Opening wrote off the end of the buffer.";
531   }
532 
533   EXPECT_EQ(Bytes(plaintext), Bytes(plaintext2, plaintext2_len));
534 }
535 
TEST_P(PerAEADTest,AliasedBuffers)536 TEST_P(PerAEADTest, AliasedBuffers) {
537   if (GetParam().flags & kLimitedImplementation) {
538     return;
539   }
540 
541   const size_t key_len = EVP_AEAD_key_length(aead());
542   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
543   const size_t max_overhead = EVP_AEAD_max_overhead(aead());
544 
545   std::vector<uint8_t> key(key_len, 'a');
546   bssl::ScopedEVP_AEAD_CTX ctx;
547   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key.data(), key_len,
548                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
549 
550   static const uint8_t kPlaintext[260] =
551       "testing123456testing123456testing123456testing123456testing123456testing"
552       "123456testing123456testing123456testing123456testing123456testing123456t"
553       "esting123456testing123456testing123456testing123456testing123456testing1"
554       "23456testing123456testing123456testing12345";
555   const std::vector<size_t> offsets = {
556       0,  1,  2,  8,  15, 16,  17,  31,  32,  33,  63,
557       64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
558   };
559 
560   std::vector<uint8_t> nonce(nonce_len, 'b');
561   std::vector<uint8_t> valid_encryption(sizeof(kPlaintext) + max_overhead);
562   size_t valid_encryption_len;
563   ASSERT_TRUE(EVP_AEAD_CTX_seal(
564       ctx.get(), valid_encryption.data(), &valid_encryption_len,
565       sizeof(kPlaintext) + max_overhead, nonce.data(), nonce_len, kPlaintext,
566       sizeof(kPlaintext), nullptr, 0))
567       << "EVP_AEAD_CTX_seal failed with disjoint buffers.";
568 
569   // Test with out != in which we expect to fail.
570   std::vector<uint8_t> buffer(2 + valid_encryption_len);
571   uint8_t *in = buffer.data() + 1;
572   uint8_t *out1 = buffer.data();
573   uint8_t *out2 = buffer.data() + 2;
574 
575   OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
576   size_t out_len;
577   EXPECT_FALSE(EVP_AEAD_CTX_seal(
578       ctx.get(), out1 /* in - 1 */, &out_len, sizeof(kPlaintext) + max_overhead,
579       nonce.data(), nonce_len, in, sizeof(kPlaintext), nullptr, 0));
580   EXPECT_FALSE(EVP_AEAD_CTX_seal(
581       ctx.get(), out2 /* in + 1 */, &out_len, sizeof(kPlaintext) + max_overhead,
582       nonce.data(), nonce_len, in, sizeof(kPlaintext), nullptr, 0));
583   ERR_clear_error();
584 
585   OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
586   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out1 /* in - 1 */, &out_len,
587                                  valid_encryption_len, nonce.data(), nonce_len,
588                                  in, valid_encryption_len, nullptr, 0));
589   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out2 /* in + 1 */, &out_len,
590                                  valid_encryption_len, nonce.data(), nonce_len,
591                                  in, valid_encryption_len, nullptr, 0));
592   ERR_clear_error();
593 
594   // Test with out == in, which we expect to work.
595   OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
596 
597   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), in, &out_len,
598                                 sizeof(kPlaintext) + max_overhead, nonce.data(),
599                                 nonce_len, in, sizeof(kPlaintext), nullptr, 0));
600 
601   if (!(GetParam().flags & kNondeterministic)) {
602     EXPECT_EQ(Bytes(valid_encryption.data(), valid_encryption_len),
603               Bytes(in, out_len));
604   }
605 
606   OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
607   ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), in, &out_len, valid_encryption_len,
608                                 nonce.data(), nonce_len, in,
609                                 valid_encryption_len, nullptr, 0));
610   EXPECT_EQ(Bytes(kPlaintext), Bytes(in, out_len));
611 }
612 
TEST_P(PerAEADTest,UnalignedInput)613 TEST_P(PerAEADTest, UnalignedInput) {
614   alignas(16) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH + 1];
615   alignas(16) uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH + 1];
616   alignas(16) uint8_t plaintext[32 + 1];
617   alignas(16) uint8_t ad[32 + 1];
618   OPENSSL_memset(key, 'K', sizeof(key));
619   OPENSSL_memset(nonce, 'N', sizeof(nonce));
620   OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
621   OPENSSL_memset(ad, 'A', sizeof(ad));
622   const size_t key_len = EVP_AEAD_key_length(aead());
623   ASSERT_GE(sizeof(key) - 1, key_len);
624   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
625   ASSERT_GE(sizeof(nonce) - 1, nonce_len);
626   const size_t ad_len = RequiredADLength(GetParam().flags) != 0
627                             ? RequiredADLength(GetParam().flags)
628                             : sizeof(ad) - 1;
629   ASSERT_GE(sizeof(ad) - 1, ad_len);
630 
631   // Encrypt some input.
632   bssl::ScopedEVP_AEAD_CTX ctx;
633   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
634       ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
635       evp_aead_seal));
636   alignas(16) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD];
637   size_t ciphertext_len;
638   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), ciphertext + 1, &ciphertext_len,
639                                 sizeof(ciphertext) - 1, nonce + 1, nonce_len,
640                                 plaintext + 1, sizeof(plaintext) - 1, ad + 1,
641                                 ad_len));
642 
643   // It must successfully decrypt.
644   alignas(16) uint8_t out[sizeof(ciphertext)];
645   ctx.Reset();
646   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
647       ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
648       evp_aead_open));
649   size_t out_len;
650   ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out + 1, &out_len, sizeof(out) - 1,
651                                 nonce + 1, nonce_len, ciphertext + 1,
652                                 ciphertext_len, ad + 1, ad_len));
653   EXPECT_EQ(Bytes(plaintext + 1, sizeof(plaintext) - 1),
654             Bytes(out + 1, out_len));
655 }
656 
TEST_P(PerAEADTest,Overflow)657 TEST_P(PerAEADTest, Overflow) {
658   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
659   OPENSSL_memset(key, 'K', sizeof(key));
660 
661   bssl::ScopedEVP_AEAD_CTX ctx;
662   const size_t max_tag_len = EVP_AEAD_max_tag_len(aead());
663   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(ctx.get(), aead(), key,
664                                                EVP_AEAD_key_length(aead()),
665                                                max_tag_len, evp_aead_seal));
666 
667   uint8_t plaintext[1] = {0};
668   uint8_t ciphertext[1024] = {0};
669   size_t ciphertext_len;
670   // The AEAD must not overflow when calculating the ciphertext length.
671   ASSERT_FALSE(EVP_AEAD_CTX_seal(
672       ctx.get(), ciphertext, &ciphertext_len, sizeof(ciphertext), nullptr, 0,
673       plaintext, std::numeric_limits<size_t>::max() - max_tag_len + 1, nullptr,
674       0));
675   ERR_clear_error();
676 
677   // (Can't test the scatter interface because it'll attempt to zero the output
678   // buffer on error and the primary output buffer is implicitly the same size
679   // as the input.)
680 }
681 
TEST_P(PerAEADTest,InvalidNonceLength)682 TEST_P(PerAEADTest, InvalidNonceLength) {
683   size_t valid_nonce_len = EVP_AEAD_nonce_length(aead());
684   std::vector<size_t> nonce_lens;
685   if (valid_nonce_len != 0) {
686     // Other than the implicit IV TLS "AEAD"s, none of our AEADs allow empty
687     // nonces. In particular, although AES-GCM was incorrectly specified with
688     // variable-length nonces, it does not allow the empty nonce.
689     nonce_lens.push_back(0);
690   }
691   if (!(GetParam().flags & kVariableNonce)) {
692     nonce_lens.push_back(valid_nonce_len + 1);
693     if (valid_nonce_len != 0) {
694       nonce_lens.push_back(valid_nonce_len - 1);
695     }
696   }
697 
698   static const uint8_t kZeros[EVP_AEAD_MAX_KEY_LENGTH] = {0};
699   const size_t ad_len = RequiredADLength(GetParam().flags) != 0
700                             ? RequiredADLength(GetParam().flags)
701                             : 16;
702   ASSERT_LE(ad_len, sizeof(kZeros));
703 
704   for (size_t nonce_len : nonce_lens) {
705     SCOPED_TRACE(nonce_len);
706     uint8_t buf[256];
707     size_t len;
708     std::vector<uint8_t> nonce(nonce_len);
709     bssl::ScopedEVP_AEAD_CTX ctx;
710     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
711         ctx.get(), aead(), kZeros, EVP_AEAD_key_length(aead()),
712         EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_seal));
713 
714     EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
715                                    nonce.data(), nonce.size(), nullptr /* in */,
716                                    0, kZeros /* ad */, ad_len));
717     uint32_t err = ERR_get_error();
718     // TODO(davidben): Merge these errors. https://crbug.com/boringssl/129.
719     if (!ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE)) {
720       EXPECT_TRUE(
721           ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_INVALID_NONCE_SIZE));
722     }
723 
724     ctx.Reset();
725     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
726         ctx.get(), aead(), kZeros, EVP_AEAD_key_length(aead()),
727         EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_open));
728     EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
729                                    nonce.data(), nonce.size(), kZeros /* in */,
730                                    sizeof(kZeros), kZeros /* ad */, ad_len));
731     err = ERR_get_error();
732     if (!ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE)) {
733       EXPECT_TRUE(
734           ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_INVALID_NONCE_SIZE));
735     }
736   }
737 }
738 
739 #if defined(SUPPORTS_ABI_TEST)
740 // CHECK_ABI can't pass enums, i.e. |evp_aead_seal| and |evp_aead_open|. Thus
741 // these two wrappers.
aead_ctx_init_for_seal(EVP_AEAD_CTX * ctx,const EVP_AEAD * aead,const uint8_t * key,size_t key_len)742 static int aead_ctx_init_for_seal(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
743                                   const uint8_t *key, size_t key_len) {
744   return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, 0,
745                                           evp_aead_seal);
746 }
747 
aead_ctx_init_for_open(EVP_AEAD_CTX * ctx,const EVP_AEAD * aead,const uint8_t * key,size_t key_len)748 static int aead_ctx_init_for_open(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
749                                   const uint8_t *key, size_t key_len) {
750   return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, 0,
751                                           evp_aead_open);
752 }
753 
754 // CHECK_ABI can pass, at most, eight arguments. Thus these wrappers that
755 // figure out the output length from the input length, and take the nonce length
756 // from the configuration of the AEAD.
aead_ctx_seal(EVP_AEAD_CTX * ctx,uint8_t * out_ciphertext,size_t * out_ciphertext_len,const uint8_t * nonce,const uint8_t * plaintext,size_t plaintext_len,const uint8_t * ad,size_t ad_len)757 static int aead_ctx_seal(EVP_AEAD_CTX *ctx, uint8_t *out_ciphertext,
758                          size_t *out_ciphertext_len, const uint8_t *nonce,
759                          const uint8_t *plaintext, size_t plaintext_len,
760                          const uint8_t *ad, size_t ad_len) {
761   const size_t nonce_len = EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(ctx));
762   return EVP_AEAD_CTX_seal(ctx, out_ciphertext, out_ciphertext_len,
763                            plaintext_len + EVP_AEAD_MAX_OVERHEAD, nonce,
764                            nonce_len, plaintext, plaintext_len, ad, ad_len);
765 }
766 
aead_ctx_open(EVP_AEAD_CTX * ctx,uint8_t * out_plaintext,size_t * out_plaintext_len,const uint8_t * nonce,const uint8_t * ciphertext,size_t ciphertext_len,const uint8_t * ad,size_t ad_len)767 static int aead_ctx_open(EVP_AEAD_CTX *ctx, uint8_t *out_plaintext,
768                          size_t *out_plaintext_len, const uint8_t *nonce,
769                          const uint8_t *ciphertext, size_t ciphertext_len,
770                          const uint8_t *ad, size_t ad_len) {
771   const size_t nonce_len = EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(ctx));
772   return EVP_AEAD_CTX_open(ctx, out_plaintext, out_plaintext_len,
773                            ciphertext_len, nonce, nonce_len, ciphertext,
774                            ciphertext_len, ad, ad_len);
775 }
776 
TEST_P(PerAEADTest,ABI)777 TEST_P(PerAEADTest, ABI) {
778   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
779   OPENSSL_memset(key, 'K', sizeof(key));
780   const size_t key_len = EVP_AEAD_key_length(aead());
781   ASSERT_LE(key_len, sizeof(key));
782 
783   bssl::ScopedEVP_AEAD_CTX ctx_seal;
784   ASSERT_TRUE(
785       CHECK_ABI(aead_ctx_init_for_seal, ctx_seal.get(), aead(), key, key_len));
786 
787   bssl::ScopedEVP_AEAD_CTX ctx_open;
788   ASSERT_TRUE(
789       CHECK_ABI(aead_ctx_init_for_open, ctx_open.get(), aead(), key, key_len));
790 
791   alignas(2) uint8_t plaintext[512];
792   OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
793 
794   alignas(2) uint8_t ad_buf[512];
795   OPENSSL_memset(ad_buf, 'A', sizeof(ad_buf));
796   const uint8_t *const ad = ad_buf + 1;
797   ASSERT_LE(RequiredADLength(GetParam().flags), sizeof(ad_buf) - 1);
798   const size_t ad_len = RequiredADLength(GetParam().flags) != 0
799                             ? RequiredADLength(GetParam().flags)
800                             : sizeof(ad_buf) - 1;
801 
802   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
803   OPENSSL_memset(nonce, 'N', sizeof(nonce));
804   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
805   ASSERT_LE(nonce_len, sizeof(nonce));
806 
807   alignas(2) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD + 1];
808   size_t ciphertext_len;
809   // Knock plaintext, ciphertext, and AD off alignment and give odd lengths for
810   // plaintext and AD. This hopefully triggers any edge-cases in the assembly.
811   ASSERT_TRUE(CHECK_ABI(aead_ctx_seal, ctx_seal.get(), ciphertext + 1,
812                         &ciphertext_len, nonce, plaintext + 1,
813                         sizeof(plaintext) - 1, ad, ad_len));
814 
815   alignas(2) uint8_t plaintext2[sizeof(ciphertext) + 1];
816   size_t plaintext2_len;
817   ASSERT_TRUE(CHECK_ABI(aead_ctx_open, ctx_open.get(), plaintext2 + 1,
818                         &plaintext2_len, nonce, ciphertext + 1, ciphertext_len,
819                         ad, ad_len));
820 
821   EXPECT_EQ(Bytes(plaintext + 1, sizeof(plaintext) - 1),
822             Bytes(plaintext2 + 1, plaintext2_len));
823 }
824 
TEST(ChaChaPoly1305Test,ABI)825 TEST(ChaChaPoly1305Test, ABI) {
826   if (!chacha20_poly1305_asm_capable()) {
827     return;
828   }
829 
830   auto buf = std::make_unique<uint8_t[]>(1024);
831   for (size_t len = 0; len <= 1024; len += 5) {
832     SCOPED_TRACE(len);
833     union chacha20_poly1305_open_data open_ctx = {};
834 #if defined(OPENSSL_X86_64)
835     CHECK_ABI(chacha20_poly1305_open_sse41, buf.get(), buf.get(), len,
836               buf.get(), len % 128, &open_ctx);
837     if (CRYPTO_is_AVX2_capable() && CRYPTO_is_BMI2_capable()) {
838       CHECK_ABI(chacha20_poly1305_open_avx2, buf.get(), buf.get(), len,
839                 buf.get(), len % 128, &open_ctx);
840     }
841 #else
842     CHECK_ABI(chacha20_poly1305_open, buf.get(), buf.get(), len, buf.get(),
843               len % 128, &open_ctx);
844 #endif
845   }
846 
847   for (size_t len = 0; len <= 1024; len += 5) {
848     SCOPED_TRACE(len);
849     union chacha20_poly1305_seal_data seal_ctx = {};
850 #if defined(OPENSSL_X86_64)
851     CHECK_ABI(chacha20_poly1305_seal_sse41, buf.get(), buf.get(), len,
852               buf.get(), len % 128, &seal_ctx);
853     if (CRYPTO_is_AVX2_capable() && CRYPTO_is_BMI2_capable()) {
854       CHECK_ABI(chacha20_poly1305_seal_avx2, buf.get(), buf.get(), len,
855                 buf.get(), len % 128, &seal_ctx);
856     }
857 #else
858     CHECK_ABI(chacha20_poly1305_seal, buf.get(), buf.get(), len, buf.get(),
859               len % 128, &seal_ctx);
860 #endif
861   }
862 }
863 #endif  // SUPPORTS_ABI_TEST
864 
TEST(AEADTest,AESCCMLargeAD)865 TEST(AEADTest, AESCCMLargeAD) {
866   static const std::vector<uint8_t> kKey(16, 'A');
867   static const std::vector<uint8_t> kNonce(13, 'N');
868   static const std::vector<uint8_t> kAD(65536, 'D');
869   static const std::vector<uint8_t> kPlaintext = {
870       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
871       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
872   static const std::vector<uint8_t> kCiphertext = {
873       0xa2, 0x12, 0x3f, 0x0b, 0x07, 0xd5, 0x02, 0xff,
874       0xa9, 0xcd, 0xa0, 0xf3, 0x69, 0x1c, 0x49, 0x0c};
875   static const std::vector<uint8_t> kTag = {0x4a, 0x31, 0x82, 0x96};
876 
877   // Test AES-128-CCM-Bluetooth.
878   bssl::ScopedEVP_AEAD_CTX ctx;
879   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_ccm_bluetooth(),
880                                 kKey.data(), kKey.size(),
881                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
882 
883   std::vector<uint8_t> out(kCiphertext.size() + kTag.size());
884   size_t out_len;
885   EXPECT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
886                                 kNonce.data(), kNonce.size(), kPlaintext.data(),
887                                 kPlaintext.size(), kAD.data(), kAD.size()));
888 
889   ASSERT_EQ(out_len, kCiphertext.size() + kTag.size());
890   EXPECT_EQ(Bytes(kCiphertext), Bytes(out.data(), kCiphertext.size()));
891   EXPECT_EQ(Bytes(kTag), Bytes(out.data() + kCiphertext.size(), kTag.size()));
892 
893   EXPECT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
894                                 kNonce.data(), kNonce.size(), out.data(),
895                                 out.size(), kAD.data(), kAD.size()));
896 
897   ASSERT_EQ(out_len, kPlaintext.size());
898   EXPECT_EQ(Bytes(kPlaintext), Bytes(out.data(), kPlaintext.size()));
899 }
900 
RunWycheproofTestCase(FileTest * t,const EVP_AEAD * aead)901 static void RunWycheproofTestCase(FileTest *t, const EVP_AEAD *aead) {
902   t->IgnoreInstruction("ivSize");
903 
904   std::vector<uint8_t> aad, ct, iv, key, msg, tag;
905   ASSERT_TRUE(t->GetBytes(&aad, "aad"));
906   ASSERT_TRUE(t->GetBytes(&ct, "ct"));
907   ASSERT_TRUE(t->GetBytes(&iv, "iv"));
908   ASSERT_TRUE(t->GetBytes(&key, "key"));
909   ASSERT_TRUE(t->GetBytes(&msg, "msg"));
910   ASSERT_TRUE(t->GetBytes(&tag, "tag"));
911   std::string tag_size_str;
912   ASSERT_TRUE(t->GetInstruction(&tag_size_str, "tagSize"));
913   size_t tag_size = static_cast<size_t>(atoi(tag_size_str.c_str()));
914   ASSERT_EQ(0u, tag_size % 8);
915   tag_size /= 8;
916   WycheproofResult result;
917   ASSERT_TRUE(GetWycheproofResult(t, &result));
918 
919   std::vector<uint8_t> ct_and_tag = ct;
920   ct_and_tag.insert(ct_and_tag.end(), tag.begin(), tag.end());
921 
922   bssl::ScopedEVP_AEAD_CTX ctx;
923   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key.size(),
924                                 tag_size, nullptr));
925   std::vector<uint8_t> out(msg.size());
926   size_t out_len;
927   // Wycheproof tags small AES-GCM IVs as "acceptable" and otherwise does not
928   // use it in AEADs. Any AES-GCM IV that isn't 96 bits is absurd, but our API
929   // supports those, so we treat SmallIv tests as valid.
930   if (result.IsValid({"SmallIv"})) {
931     // Decryption should succeed.
932     ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
933                                   iv.data(), iv.size(), ct_and_tag.data(),
934                                   ct_and_tag.size(), aad.data(), aad.size()));
935     EXPECT_EQ(Bytes(msg), Bytes(out.data(), out_len));
936 
937     // Decryption in-place should succeed.
938     out = ct_and_tag;
939     ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
940                                   iv.data(), iv.size(), out.data(), out.size(),
941                                   aad.data(), aad.size()));
942     EXPECT_EQ(Bytes(msg), Bytes(out.data(), out_len));
943 
944     // AEADs are deterministic, so encryption should produce the same result.
945     out.resize(ct_and_tag.size());
946     ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
947                                   iv.data(), iv.size(), msg.data(), msg.size(),
948                                   aad.data(), aad.size()));
949     EXPECT_EQ(Bytes(ct_and_tag), Bytes(out.data(), out_len));
950 
951     // Encrypt in-place.
952     out = msg;
953     out.resize(ct_and_tag.size());
954     ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
955                                   iv.data(), iv.size(), out.data(), msg.size(),
956                                   aad.data(), aad.size()));
957     EXPECT_EQ(Bytes(ct_and_tag), Bytes(out.data(), out_len));
958   } else {
959     // Decryption should fail.
960     EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
961                                    iv.data(), iv.size(), ct_and_tag.data(),
962                                    ct_and_tag.size(), aad.data(), aad.size()));
963 
964     // Decryption in-place should also fail.
965     out = ct_and_tag;
966     EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
967                                    iv.data(), iv.size(), out.data(), out.size(),
968                                    aad.data(), aad.size()));
969   }
970 }
971 
TEST(AEADTest,WycheproofAESGCMSIV)972 TEST(AEADTest, WycheproofAESGCMSIV) {
973   FileTestGTest("third_party/wycheproof_testvectors/aes_gcm_siv_test.txt",
974                 [](FileTest *t) {
975                   std::string key_size_str;
976                   ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
977                   const EVP_AEAD *aead;
978                   switch (atoi(key_size_str.c_str())) {
979                     case 128:
980                       aead = EVP_aead_aes_128_gcm_siv();
981                       break;
982                     case 256:
983                       aead = EVP_aead_aes_256_gcm_siv();
984                       break;
985                     default:
986                       FAIL() << "Unknown key size: " << key_size_str;
987                   }
988 
989                   RunWycheproofTestCase(t, aead);
990                 });
991 }
992 
TEST(AEADTest,WycheproofAESGCM)993 TEST(AEADTest, WycheproofAESGCM) {
994   FileTestGTest("third_party/wycheproof_testvectors/aes_gcm_test.txt",
995                 [](FileTest *t) {
996                   std::string key_size_str;
997                   ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
998                   const EVP_AEAD *aead;
999                   switch (atoi(key_size_str.c_str())) {
1000                     case 128:
1001                       aead = EVP_aead_aes_128_gcm();
1002                       break;
1003                     case 192:
1004                       aead = EVP_aead_aes_192_gcm();
1005                       break;
1006                     case 256:
1007                       aead = EVP_aead_aes_256_gcm();
1008                       break;
1009                     default:
1010                       FAIL() << "Unknown key size: " << key_size_str;
1011                   }
1012 
1013                   RunWycheproofTestCase(t, aead);
1014                 });
1015 }
1016 
TEST(AEADTest,WycheproofChaCha20Poly1305)1017 TEST(AEADTest, WycheproofChaCha20Poly1305) {
1018   FileTestGTest("third_party/wycheproof_testvectors/chacha20_poly1305_test.txt",
1019                 [](FileTest *t) {
1020                   t->IgnoreInstruction("keySize");
1021                   RunWycheproofTestCase(t, EVP_aead_chacha20_poly1305());
1022                 });
1023 }
1024 
TEST(AEADTest,WycheproofXChaCha20Poly1305)1025 TEST(AEADTest, WycheproofXChaCha20Poly1305) {
1026   FileTestGTest(
1027       "third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt",
1028       [](FileTest *t) {
1029         t->IgnoreInstruction("keySize");
1030         RunWycheproofTestCase(t, EVP_aead_xchacha20_poly1305());
1031       });
1032 }
1033 
TEST(AEADTest,WycheproofAESEAX)1034 TEST(AEADTest, WycheproofAESEAX) {
1035   FileTestGTest(
1036       "third_party/wycheproof_testvectors/aes_eax_test.txt", [](FileTest *t) {
1037         std::string key_size_str;
1038         ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
1039         const EVP_AEAD *aead;
1040         switch (atoi(key_size_str.c_str())) {
1041           case 128:
1042             aead = EVP_aead_aes_128_eax();
1043             break;
1044           case 256:
1045             aead = EVP_aead_aes_256_eax();
1046             break;
1047           default:
1048             t->SkipCurrent();
1049             GTEST_SKIP() << "Unsupported key size: " << key_size_str;
1050         }
1051 
1052         std::string nonce_size_str;
1053         ASSERT_TRUE(t->GetInstruction(&nonce_size_str, "ivSize"));
1054         // Skip tests with invalid nonce size.
1055         if (nonce_size_str != "96" && nonce_size_str != "128") {
1056           t->SkipCurrent();
1057           GTEST_SKIP() << "Unsupported nonce size: " << nonce_size_str;
1058         }
1059 
1060         RunWycheproofTestCase(t, aead);
1061       });
1062 }
1063 
TEST(AEADTest,FreeNull)1064 TEST(AEADTest, FreeNull) { EVP_AEAD_CTX_free(nullptr); }
1065 
1066 }  // namespace
1067