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