Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / boringssl / crypto / cipher_extra / aead_test.cc
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 "../test/file_test.h"
29 #include "../test/test_util.h"
30
31
32 struct KnownAEAD {
33   const char name[40];
34   const EVP_AEAD *(*func)(void);
35   const char *test_vectors;
36   // limited_implementation indicates that tests that assume a generic AEAD
37   // interface should not be performed. For example, the key-wrap AEADs only
38   // handle inputs that are a multiple of eight bytes in length and the
39   // SSLv3/TLS AEADs have the concept of “direction”.
40   bool limited_implementation;
41   // truncated_tags is true if the AEAD supports truncating tags to arbitrary
42   // lengths.
43   bool truncated_tags;
44   // ad_len, if non-zero, is the required length of the AD.
45   size_t ad_len;
46 };
47
48 static const struct KnownAEAD kAEADs[] = {
49     {"AES_128_GCM", EVP_aead_aes_128_gcm, "aes_128_gcm_tests.txt", false, true,
50      0},
51     {"AES_128_GCM_NIST", EVP_aead_aes_128_gcm, "nist_cavp/aes_128_gcm.txt",
52      false, true, 0},
53     {"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt", false, true,
54      0},
55     {"AES_256_GCM_NIST", EVP_aead_aes_256_gcm, "nist_cavp/aes_256_gcm.txt",
56      false, true, 0},
57 #if !defined(OPENSSL_SMALL)
58     {"AES_128_GCM_SIV", EVP_aead_aes_128_gcm_siv, "aes_128_gcm_siv_tests.txt",
59      false, false, 0},
60     {"AES_256_GCM_SIV", EVP_aead_aes_256_gcm_siv, "aes_256_gcm_siv_tests.txt",
61      false, false, 0},
62 #endif
63     {"ChaCha20Poly1305", EVP_aead_chacha20_poly1305,
64      "chacha20_poly1305_tests.txt", false, true, 0},
65     {"AES_128_CBC_SHA1_TLS", EVP_aead_aes_128_cbc_sha1_tls,
66      "aes_128_cbc_sha1_tls_tests.txt", true, false, 11},
67     {"AES_128_CBC_SHA1_TLSImplicitIV",
68      EVP_aead_aes_128_cbc_sha1_tls_implicit_iv,
69      "aes_128_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
70     {"AES_128_CBC_SHA256_TLS", EVP_aead_aes_128_cbc_sha256_tls,
71      "aes_128_cbc_sha256_tls_tests.txt", true, false, 11},
72     {"AES_256_CBC_SHA1_TLS", EVP_aead_aes_256_cbc_sha1_tls,
73      "aes_256_cbc_sha1_tls_tests.txt", true, false, 11},
74     {"AES_256_CBC_SHA1_TLSImplicitIV",
75      EVP_aead_aes_256_cbc_sha1_tls_implicit_iv,
76      "aes_256_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
77     {"AES_256_CBC_SHA256_TLS", EVP_aead_aes_256_cbc_sha256_tls,
78      "aes_256_cbc_sha256_tls_tests.txt", true, false, 11},
79     {"AES_256_CBC_SHA384_TLS", EVP_aead_aes_256_cbc_sha384_tls,
80      "aes_256_cbc_sha384_tls_tests.txt", true, false, 11},
81     {"DES_EDE3_CBC_SHA1_TLS", EVP_aead_des_ede3_cbc_sha1_tls,
82      "des_ede3_cbc_sha1_tls_tests.txt", true, false, 11},
83     {"DES_EDE3_CBC_SHA1_TLSImplicitIV",
84      EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv,
85      "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt", true, false, 11},
86     {"AES_128_CBC_SHA1_SSL3", EVP_aead_aes_128_cbc_sha1_ssl3,
87      "aes_128_cbc_sha1_ssl3_tests.txt", true, false, 9},
88     {"AES_256_CBC_SHA1_SSL3", EVP_aead_aes_256_cbc_sha1_ssl3,
89      "aes_256_cbc_sha1_ssl3_tests.txt", true, false, 9},
90     {"DES_EDE3_CBC_SHA1_SSL3", EVP_aead_des_ede3_cbc_sha1_ssl3,
91      "des_ede3_cbc_sha1_ssl3_tests.txt", true, false, 9},
92     {"AES_128_CTR_HMAC_SHA256", EVP_aead_aes_128_ctr_hmac_sha256,
93      "aes_128_ctr_hmac_sha256.txt", false, true, 0},
94     {"AES_256_CTR_HMAC_SHA256", EVP_aead_aes_256_ctr_hmac_sha256,
95      "aes_256_ctr_hmac_sha256.txt", false, true, 0},
96     {"AES_128_CCM_BLUETOOTH", EVP_aead_aes_128_ccm_bluetooth,
97      "aes_128_ccm_bluetooth_tests.txt", false, false, 0},
98     {"AES_128_CCM_BLUETOOTH_8", EVP_aead_aes_128_ccm_bluetooth_8,
99      "aes_128_ccm_bluetooth_8_tests.txt", false, false, 0},
100 };
101
102 class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
103  public:
104   const EVP_AEAD *aead() { return GetParam().func(); }
105 };
106
107 INSTANTIATE_TEST_CASE_P(, PerAEADTest, testing::ValuesIn(kAEADs),
108                         [](const testing::TestParamInfo<KnownAEAD> &params)
109                             -> std::string { return params.param.name; });
110
111 // Tests an AEAD against a series of test vectors from a file, using the
112 // FileTest format. As an example, here's a valid test case:
113 //
114 //   KEY: 5a19f3173586b4c42f8412f4d5a786531b3231753e9e00998aec12fda8df10e4
115 //   NONCE: 978105dfce667bf4
116 //   IN: 6a4583908d
117 //   AD: b654574932
118 //   CT: 5294265a60
119 //   TAG: 1d45758621762e061368e68868e2f929
120 TEST_P(PerAEADTest, TestVector) {
121   std::string test_vectors = "crypto/cipher_extra/test/";
122   test_vectors += GetParam().test_vectors;
123   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
124     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
125     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
126     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
127     ASSERT_TRUE(t->GetBytes(&in, "IN"));
128     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
129     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
130     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
131     size_t tag_len = tag.size();
132     if (t->HasAttribute("TAG_LEN")) {
133       // Legacy AEADs are MAC-then-encrypt and may include padding in the TAG
134       // field. TAG_LEN contains the actual size of the digest in that case.
135       std::string tag_len_str;
136       ASSERT_TRUE(t->GetAttribute(&tag_len_str, "TAG_LEN"));
137       tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
138       ASSERT_TRUE(tag_len);
139     }
140
141     bssl::ScopedEVP_AEAD_CTX ctx;
142     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
143         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_seal));
144
145     std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead()));
146     if (!t->HasAttribute("NO_SEAL")) {
147       size_t out_len;
148       ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
149                                     nonce.data(), nonce.size(), in.data(),
150                                     in.size(), ad.data(), ad.size()));
151       out.resize(out_len);
152
153       ASSERT_EQ(out.size(), ct.size() + tag.size());
154       EXPECT_EQ(Bytes(ct), Bytes(out.data(), ct.size()));
155       EXPECT_EQ(Bytes(tag), Bytes(out.data() + ct.size(), tag.size()));
156     } else {
157       out.resize(ct.size() + tag.size());
158       OPENSSL_memcpy(out.data(), ct.data(), ct.size());
159       OPENSSL_memcpy(out.data() + ct.size(), tag.data(), tag.size());
160     }
161
162     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
163     // reset after each operation.
164     ctx.Reset();
165     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
166         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
167
168     std::vector<uint8_t> out2(out.size());
169     size_t out2_len;
170     int ret = EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
171                                 nonce.data(), nonce.size(), out.data(),
172                                 out.size(), ad.data(), ad.size());
173     if (t->HasAttribute("FAILS")) {
174       ASSERT_FALSE(ret) << "Decrypted bad data.";
175       ERR_clear_error();
176       return;
177     }
178
179     ASSERT_TRUE(ret) << "Failed to decrypt.";
180     out2.resize(out2_len);
181     EXPECT_EQ(Bytes(in), Bytes(out2));
182
183     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
184     // reset after each operation.
185     ctx.Reset();
186     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
187         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
188
189     // Garbage at the end isn't ignored.
190     out.push_back(0);
191     out2.resize(out.size());
192     EXPECT_FALSE(EVP_AEAD_CTX_open(
193         ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
194         nonce.size(), out.data(), out.size(), ad.data(), ad.size()))
195         << "Decrypted bad data with trailing garbage.";
196     ERR_clear_error();
197
198     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
199     // reset after each operation.
200     ctx.Reset();
201     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
202         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
203
204     // Verify integrity is checked.
205     out[0] ^= 0x80;
206     out.resize(out.size() - 1);
207     out2.resize(out.size());
208     EXPECT_FALSE(EVP_AEAD_CTX_open(
209         ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
210         nonce.size(), out.data(), out.size(), ad.data(), ad.size()))
211         << "Decrypted bad data with corrupted byte.";
212     ERR_clear_error();
213   });
214 }
215
216 TEST_P(PerAEADTest, TestExtraInput) {
217   const KnownAEAD &aead_config = GetParam();
218   if (!aead()->seal_scatter_supports_extra_in) {
219     return;
220   }
221
222   const std::string test_vectors =
223       "crypto/cipher_extra/test/" + std::string(aead_config.test_vectors);
224   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
225     if (t->HasAttribute("NO_SEAL") ||
226         t->HasAttribute("FAILS")) {
227       t->SkipCurrent();
228       return;
229     }
230
231     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
232     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
233     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
234     ASSERT_TRUE(t->GetBytes(&in, "IN"));
235     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
236     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
237     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
238
239     bssl::ScopedEVP_AEAD_CTX ctx;
240     ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key.data(), key.size(),
241                                   tag.size(), nullptr));
242     std::vector<uint8_t> out_tag(EVP_AEAD_max_overhead(aead()) + in.size());
243     std::vector<uint8_t> out(in.size());
244
245     for (size_t extra_in_size = 0; extra_in_size < in.size(); extra_in_size++) {
246       size_t tag_bytes_written;
247       SCOPED_TRACE(extra_in_size);
248       ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
249           ctx.get(), out.data(), out_tag.data(), &tag_bytes_written,
250           out_tag.size(), nonce.data(), nonce.size(), in.data(),
251           in.size() - extra_in_size, in.data() + in.size() - extra_in_size,
252           extra_in_size, ad.data(), ad.size()));
253
254       ASSERT_EQ(tag_bytes_written, extra_in_size + tag.size());
255
256       memcpy(out.data() + in.size() - extra_in_size, out_tag.data(),
257              extra_in_size);
258
259       EXPECT_EQ(Bytes(ct), Bytes(out.data(), in.size()));
260       EXPECT_EQ(Bytes(tag), Bytes(out_tag.data() + extra_in_size,
261                                   tag_bytes_written - extra_in_size));
262     }
263   });
264 }
265
266 TEST_P(PerAEADTest, TestVectorScatterGather) {
267   std::string test_vectors = "crypto/cipher_extra/test/";
268   const KnownAEAD &aead_config = GetParam();
269   test_vectors += aead_config.test_vectors;
270   FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
271     std::vector<uint8_t> key, nonce, in, ad, ct, tag;
272     ASSERT_TRUE(t->GetBytes(&key, "KEY"));
273     ASSERT_TRUE(t->GetBytes(&nonce, "NONCE"));
274     ASSERT_TRUE(t->GetBytes(&in, "IN"));
275     ASSERT_TRUE(t->GetBytes(&ad, "AD"));
276     ASSERT_TRUE(t->GetBytes(&ct, "CT"));
277     ASSERT_TRUE(t->GetBytes(&tag, "TAG"));
278     size_t tag_len = tag.size();
279     if (t->HasAttribute("TAG_LEN")) {
280       // Legacy AEADs are MAC-then-encrypt and may include padding in the TAG
281       // field. TAG_LEN contains the actual size of the digest in that case.
282       std::string tag_len_str;
283       ASSERT_TRUE(t->GetAttribute(&tag_len_str, "TAG_LEN"));
284       tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
285       ASSERT_TRUE(tag_len);
286     }
287
288     bssl::ScopedEVP_AEAD_CTX ctx;
289     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
290         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_seal));
291
292     std::vector<uint8_t> out(in.size());
293     std::vector<uint8_t> out_tag(EVP_AEAD_max_overhead(aead()));
294     if (!t->HasAttribute("NO_SEAL")) {
295       size_t out_tag_len;
296       ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
297           ctx.get(), out.data(), out_tag.data(), &out_tag_len, out_tag.size(),
298           nonce.data(), nonce.size(), in.data(), in.size(), nullptr, 0,
299           ad.data(), ad.size()));
300       out_tag.resize(out_tag_len);
301
302       ASSERT_EQ(out.size(), ct.size());
303       ASSERT_EQ(out_tag.size(), tag.size());
304       EXPECT_EQ(Bytes(ct), Bytes(out.data(), ct.size()));
305       EXPECT_EQ(Bytes(tag), Bytes(out_tag.data(), tag.size()));
306     } else {
307       out.resize(ct.size());
308       out_tag.resize(tag.size());
309       OPENSSL_memcpy(out.data(), ct.data(), ct.size());
310       OPENSSL_memcpy(out_tag.data(), tag.data(), tag.size());
311     }
312
313     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
314     // reset after each operation.
315     ctx.Reset();
316     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
317         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
318
319     std::vector<uint8_t> out2(out.size());
320     int ret = EVP_AEAD_CTX_open_gather(
321         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
322         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size());
323
324     // Skip decryption for AEADs that don't implement open_gather().
325     if (!ret) {
326       int err = ERR_peek_error();
327       if (ERR_GET_LIB(err) == ERR_LIB_CIPHER &&
328           ERR_GET_REASON(err) == CIPHER_R_CTRL_NOT_IMPLEMENTED) {
329           t->SkipCurrent();
330           return;
331         }
332     }
333
334     if (t->HasAttribute("FAILS")) {
335       ASSERT_FALSE(ret) << "Decrypted bad data";
336       ERR_clear_error();
337       return;
338     }
339
340     ASSERT_TRUE(ret) << "Failed to decrypt: "
341                      << ERR_reason_error_string(ERR_get_error());
342     EXPECT_EQ(Bytes(in), Bytes(out2));
343
344     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
345     // reset after each operation.
346     ctx.Reset();
347     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
348         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
349
350     // Garbage at the end isn't ignored.
351     out_tag.push_back(0);
352     out2.resize(out.size());
353     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
354         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
355         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
356         << "Decrypted bad data with trailing garbage.";
357     ERR_clear_error();
358
359     // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
360     // reset after each operation.
361     ctx.Reset();
362     ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
363         ctx.get(), aead(), key.data(), key.size(), tag_len, evp_aead_open));
364
365     // Verify integrity is checked.
366     out_tag[0] ^= 0x80;
367     out_tag.resize(out_tag.size() - 1);
368     out2.resize(out.size());
369     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
370         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
371         out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
372         << "Decrypted bad data with corrupted byte.";
373     ERR_clear_error();
374
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     // Check edge case for tag length.
380     EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
381         ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
382         out.size(), out_tag.data(), 0, ad.data(), ad.size()))
383         << "Decrypted bad data with corrupted byte.";
384     ERR_clear_error();
385   });
386 }
387
388 TEST_P(PerAEADTest, CleanupAfterInitFailure) {
389   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
390   OPENSSL_memset(key, 0, sizeof(key));
391   const size_t key_len = EVP_AEAD_key_length(aead());
392   ASSERT_GE(sizeof(key), key_len);
393
394   EVP_AEAD_CTX ctx;
395   ASSERT_FALSE(EVP_AEAD_CTX_init(
396       &ctx, aead(), key, key_len,
397       9999 /* a silly tag length to trigger an error */, NULL /* ENGINE */));
398   ERR_clear_error();
399
400   // Running a second, failed _init should not cause a memory leak.
401   ASSERT_FALSE(EVP_AEAD_CTX_init(
402       &ctx, aead(), key, key_len,
403       9999 /* a silly tag length to trigger an error */, NULL /* ENGINE */));
404   ERR_clear_error();
405
406   // Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
407   // no-op.
408   EVP_AEAD_CTX_cleanup(&ctx);
409 }
410
411 TEST_P(PerAEADTest, TruncatedTags) {
412   if (!GetParam().truncated_tags) {
413     return;
414   }
415
416   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
417   OPENSSL_memset(key, 0, sizeof(key));
418   const size_t key_len = EVP_AEAD_key_length(aead());
419   ASSERT_GE(sizeof(key), key_len);
420
421   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
422   OPENSSL_memset(nonce, 0, sizeof(nonce));
423   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
424   ASSERT_GE(sizeof(nonce), nonce_len);
425
426   bssl::ScopedEVP_AEAD_CTX ctx;
427   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key, key_len,
428                                 1 /* one byte tag */, NULL /* ENGINE */));
429
430   const uint8_t plaintext[1] = {'A'};
431
432   uint8_t ciphertext[128];
433   size_t ciphertext_len;
434   constexpr uint8_t kSentinel = 42;
435   OPENSSL_memset(ciphertext, kSentinel, sizeof(ciphertext));
436
437   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), ciphertext, &ciphertext_len,
438                                 sizeof(ciphertext), nonce, nonce_len, plaintext,
439                                 sizeof(plaintext), nullptr /* ad */, 0));
440
441   for (size_t i = ciphertext_len; i < sizeof(ciphertext); i++) {
442     // Sealing must not write past where it said it did.
443     EXPECT_EQ(kSentinel, ciphertext[i])
444         << "Sealing wrote off the end of the buffer.";
445   }
446
447   const size_t overhead_used = ciphertext_len - sizeof(plaintext);
448   const size_t expected_overhead =
449       1 + EVP_AEAD_max_overhead(aead()) - EVP_AEAD_max_tag_len(aead());
450   EXPECT_EQ(overhead_used, expected_overhead)
451       << "AEAD is probably ignoring request to truncate tags.";
452
453   uint8_t plaintext2[sizeof(plaintext) + 16];
454   OPENSSL_memset(plaintext2, kSentinel, sizeof(plaintext2));
455
456   size_t plaintext2_len;
457   ASSERT_TRUE(EVP_AEAD_CTX_open(
458       ctx.get(), plaintext2, &plaintext2_len, sizeof(plaintext2), nonce,
459       nonce_len, ciphertext, ciphertext_len, nullptr /* ad */, 0))
460       << "Opening with truncated tag didn't work.";
461
462   for (size_t i = plaintext2_len; i < sizeof(plaintext2); i++) {
463     // Likewise, opening should also stay within bounds.
464     EXPECT_EQ(kSentinel, plaintext2[i])
465         << "Opening wrote off the end of the buffer.";
466   }
467
468   EXPECT_EQ(Bytes(plaintext), Bytes(plaintext2, plaintext2_len));
469 }
470
471 TEST_P(PerAEADTest, AliasedBuffers) {
472   if (GetParam().limited_implementation) {
473     return;
474   }
475
476   const size_t key_len = EVP_AEAD_key_length(aead());
477   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
478   const size_t max_overhead = EVP_AEAD_max_overhead(aead());
479
480   std::vector<uint8_t> key(key_len, 'a');
481   bssl::ScopedEVP_AEAD_CTX ctx;
482   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key.data(), key_len,
483                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
484
485   static const uint8_t kPlaintext[260] =
486       "testing123456testing123456testing123456testing123456testing123456testing"
487       "123456testing123456testing123456testing123456testing123456testing123456t"
488       "esting123456testing123456testing123456testing123456testing123456testing1"
489       "23456testing123456testing123456testing12345";
490   const std::vector<size_t> offsets = {
491       0,  1,  2,  8,  15, 16,  17,  31,  32,  33,  63,
492       64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
493   };
494
495   std::vector<uint8_t> nonce(nonce_len, 'b');
496   std::vector<uint8_t> valid_encryption(sizeof(kPlaintext) + max_overhead);
497   size_t valid_encryption_len;
498   ASSERT_TRUE(EVP_AEAD_CTX_seal(
499       ctx.get(), valid_encryption.data(), &valid_encryption_len,
500       sizeof(kPlaintext) + max_overhead, nonce.data(), nonce_len, kPlaintext,
501       sizeof(kPlaintext), nullptr, 0))
502       << "EVP_AEAD_CTX_seal failed with disjoint buffers.";
503
504   // Test with out != in which we expect to fail.
505   std::vector<uint8_t> buffer(2 + valid_encryption_len);
506   uint8_t *in = buffer.data() + 1;
507   uint8_t *out1 = buffer.data();
508   uint8_t *out2 = buffer.data() + 2;
509
510   OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
511   size_t out_len;
512   EXPECT_FALSE(EVP_AEAD_CTX_seal(
513       ctx.get(), out1 /* in - 1 */, &out_len, sizeof(kPlaintext) + max_overhead,
514       nonce.data(), nonce_len, in, sizeof(kPlaintext), nullptr, 0));
515   EXPECT_FALSE(EVP_AEAD_CTX_seal(
516       ctx.get(), out2 /* in + 1 */, &out_len, sizeof(kPlaintext) + max_overhead,
517       nonce.data(), nonce_len, in, sizeof(kPlaintext), nullptr, 0));
518   ERR_clear_error();
519
520   OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
521   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out1 /* in - 1 */, &out_len,
522                                  valid_encryption_len, nonce.data(), nonce_len,
523                                  in, valid_encryption_len, nullptr, 0));
524   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), out2 /* in + 1 */, &out_len,
525                                  valid_encryption_len, nonce.data(), nonce_len,
526                                  in, valid_encryption_len, nullptr, 0));
527   ERR_clear_error();
528
529   // Test with out == in, which we expect to work.
530   OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
531
532   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), in, &out_len,
533                                 sizeof(kPlaintext) + max_overhead, nonce.data(),
534                                 nonce_len, in, sizeof(kPlaintext), nullptr, 0));
535   EXPECT_EQ(Bytes(valid_encryption.data(), valid_encryption_len),
536             Bytes(in, out_len));
537
538   OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
539   ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), in, &out_len, valid_encryption_len,
540                                 nonce.data(), nonce_len, in,
541                                 valid_encryption_len, nullptr, 0));
542   EXPECT_EQ(Bytes(kPlaintext), Bytes(in, out_len));
543 }
544
545 TEST_P(PerAEADTest, UnalignedInput) {
546   alignas(64) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH + 1];
547   alignas(64) uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH + 1];
548   alignas(64) uint8_t plaintext[32 + 1];
549   alignas(64) uint8_t ad[32 + 1];
550   OPENSSL_memset(key, 'K', sizeof(key));
551   OPENSSL_memset(nonce, 'N', sizeof(nonce));
552   OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
553   OPENSSL_memset(ad, 'A', sizeof(ad));
554   const size_t key_len = EVP_AEAD_key_length(aead());
555   ASSERT_GE(sizeof(key) - 1, key_len);
556   const size_t nonce_len = EVP_AEAD_nonce_length(aead());
557   ASSERT_GE(sizeof(nonce) - 1, nonce_len);
558   const size_t ad_len =
559       GetParam().ad_len != 0 ? GetParam().ad_len : sizeof(ad) - 1;
560   ASSERT_GE(sizeof(ad) - 1, ad_len);
561
562   // Encrypt some input.
563   bssl::ScopedEVP_AEAD_CTX ctx;
564   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
565       ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
566       evp_aead_seal));
567   alignas(64) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD];
568   size_t ciphertext_len;
569   ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), ciphertext + 1, &ciphertext_len,
570                                 sizeof(ciphertext) - 1, nonce + 1, nonce_len,
571                                 plaintext + 1, sizeof(plaintext) - 1, ad + 1,
572                                 ad_len));
573
574   // It must successfully decrypt.
575   alignas(64) uint8_t out[sizeof(ciphertext)];
576   ctx.Reset();
577   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
578       ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
579       evp_aead_open));
580   size_t out_len;
581   ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out + 1, &out_len, sizeof(out) - 1,
582                                 nonce + 1, nonce_len, ciphertext + 1,
583                                 ciphertext_len, ad + 1, ad_len));
584   EXPECT_EQ(Bytes(plaintext + 1, sizeof(plaintext) - 1),
585             Bytes(out + 1, out_len));
586 }
587
588 TEST_P(PerAEADTest, Overflow) {
589   alignas(64) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
590   OPENSSL_memset(key, 'K', sizeof(key));
591
592   bssl::ScopedEVP_AEAD_CTX ctx;
593   const size_t max_tag_len = EVP_AEAD_max_tag_len(aead());
594   ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(ctx.get(), aead(), key,
595                                                EVP_AEAD_key_length(aead()),
596                                                max_tag_len, evp_aead_seal));
597
598   uint8_t plaintext[1] = {0};
599   uint8_t ciphertext[1024] = {0};
600   size_t ciphertext_len;
601   // The AEAD must not overflow when calculating the ciphertext length.
602   ASSERT_FALSE(EVP_AEAD_CTX_seal(
603       ctx.get(), ciphertext, &ciphertext_len, sizeof(ciphertext), nullptr, 0,
604       plaintext, std::numeric_limits<size_t>::max() - max_tag_len + 1, nullptr,
605       0));
606   ERR_clear_error();
607
608   // (Can't test the scatter interface because it'll attempt to zero the output
609   // buffer on error and the primary output buffer is implicitly the same size
610   // as the input.)
611 }
612
613 // Test that EVP_aead_aes_128_gcm and EVP_aead_aes_256_gcm reject empty nonces.
614 // AES-GCM is not defined for those.
615 TEST(AEADTest, AESGCMEmptyNonce) {
616   static const uint8_t kZeros[32] = {0};
617
618   // Test AES-128-GCM.
619   uint8_t buf[16];
620   size_t len;
621   bssl::ScopedEVP_AEAD_CTX ctx;
622   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_gcm(), kZeros, 16,
623                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
624
625   EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
626                                  nullptr /* nonce */, 0, nullptr /* in */, 0,
627                                  nullptr /* ad */, 0));
628   uint32_t err = ERR_get_error();
629   EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
630   EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
631
632   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
633                                  nullptr /* nonce */, 0, kZeros /* in */,
634                                  sizeof(kZeros), nullptr /* ad */, 0));
635   err = ERR_get_error();
636   EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
637   EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
638
639   // Test AES-256-GCM.
640   ctx.Reset();
641   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_256_gcm(), kZeros, 32,
642                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
643
644   EXPECT_FALSE(EVP_AEAD_CTX_seal(ctx.get(), buf, &len, sizeof(buf),
645                                  nullptr /* nonce */, 0, nullptr /* in */, 0,
646                                  nullptr /* ad */, 0));
647   err = ERR_get_error();
648   EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
649   EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
650
651   EXPECT_FALSE(EVP_AEAD_CTX_open(ctx.get(), buf, &len, sizeof(buf),
652                                  nullptr /* nonce */, 0, kZeros /* in */,
653                                  sizeof(kZeros), nullptr /* ad */, 0));
654   err = ERR_get_error();
655   EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
656   EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
657 }
658
659 TEST(AEADTest, AESCCMLargeAD) {
660   static const std::vector<uint8_t> kKey(16, 'A');
661   static const std::vector<uint8_t> kNonce(13, 'N');
662   static const std::vector<uint8_t> kAD(65536, 'D');
663   static const std::vector<uint8_t> kPlaintext = {
664       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
665       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
666   static const std::vector<uint8_t> kCiphertext = {
667       0xa2, 0x12, 0x3f, 0x0b, 0x07, 0xd5, 0x02, 0xff,
668       0xa9, 0xcd, 0xa0, 0xf3, 0x69, 0x1c, 0x49, 0x0c};
669   static const std::vector<uint8_t> kTag = {0x4a, 0x31, 0x82, 0x96};
670
671   // Test AES-128-CCM-Bluetooth.
672   bssl::ScopedEVP_AEAD_CTX ctx;
673   ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_ccm_bluetooth(),
674                                 kKey.data(), kKey.size(),
675                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
676
677   std::vector<uint8_t> out(kCiphertext.size() + kTag.size());
678   size_t out_len;
679   EXPECT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
680                                 kNonce.data(), kNonce.size(), kPlaintext.data(),
681                                 kPlaintext.size(), kAD.data(), kAD.size()));
682
683   ASSERT_EQ(out_len, kCiphertext.size() + kTag.size());
684   EXPECT_EQ(Bytes(kCiphertext), Bytes(out.data(), kCiphertext.size()));
685   EXPECT_EQ(Bytes(kTag), Bytes(out.data() + kCiphertext.size(), kTag.size()));
686
687   EXPECT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
688                                 kNonce.data(), kNonce.size(), out.data(),
689                                 out.size(), kAD.data(), kAD.size()));
690
691   ASSERT_EQ(out_len, kPlaintext.size());
692   EXPECT_EQ(Bytes(kPlaintext), Bytes(out.data(), kPlaintext.size()));
693 }