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