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