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