20 #include <gtest/gtest.h>
26 #include "../fipsmodule/cipher/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"
57 return (
length & 0xf) << 3;
63 return (
flags >> 3) & 0xf;
69 return (
length & 0xf) << 8;
73 return ((
flags >> 8) & 0xf) == 0 ? 1 : ((
flags >> 8) & 0xf);
106 "aes_128_gcm_randnonce_tests.txt",
110 "aes_256_gcm_randnonce_tests.txt",
120 "aes_128_cbc_sha1_tls_tests.txt",
123 {
"AES_128_CBC_SHA1_TLSImplicitIV",
125 "aes_128_cbc_sha1_tls_implicit_iv_tests.txt",
129 "aes_256_cbc_sha1_tls_tests.txt",
132 {
"AES_256_CBC_SHA1_TLSImplicitIV",
134 "aes_256_cbc_sha1_tls_implicit_iv_tests.txt",
138 "des_ede3_cbc_sha1_tls_tests.txt",
141 {
"DES_EDE3_CBC_SHA1_TLSImplicitIV",
143 "des_ede3_cbc_sha1_tls_implicit_iv_tests.txt",
153 "aes_128_ccm_bluetooth_tests.txt", 0},
156 "aes_128_ccm_bluetooth_8_tests.txt", 0},
178 std::string test_vectors =
"crypto/cipher_extra/test/";
179 test_vectors += GetParam().test_vectors;
181 std::vector<uint8_t> key, nonce, in, ad, ct, tag;
182 ASSERT_TRUE(t->GetBytes(&key,
"KEY"));
183 ASSERT_TRUE(t->GetBytes(&nonce,
"NONCE"));
184 ASSERT_TRUE(t->GetBytes(&in,
"IN"));
185 ASSERT_TRUE(t->GetBytes(&ad,
"AD"));
186 ASSERT_TRUE(t->GetBytes(&ct,
"CT"));
187 ASSERT_TRUE(t->GetBytes(&tag,
"TAG"));
188 size_t tag_len = tag.size();
189 if (t->HasAttribute(
"TAG_LEN")) {
192 std::string tag_len_str;
193 ASSERT_TRUE(t->GetAttribute(&tag_len_str,
"TAG_LEN"));
194 tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
195 ASSERT_TRUE(tag_len);
198 bssl::ScopedEVP_AEAD_CTX
ctx;
203 if (!t->HasAttribute(
"NO_SEAL") &&
207 nonce.data(), nonce.size(),
in.data(),
208 in.size(), ad.data(), ad.size()));
215 out.resize(ct.size() +
tag.size());
226 std::vector<uint8_t> out2(
out.size());
229 nonce.data(), nonce.size(),
out.data(),
230 out.size(), ad.data(), ad.size());
231 if (t->HasAttribute(
"FAILS")) {
238 out2.resize(out2_len);
249 out2.resize(
out.size());
251 ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
252 nonce.size(),
out.data(),
out.size(), ad.data(), ad.size()))
253 <<
"Decrypted bad data with trailing garbage.";
264 out.resize(
out.size() - 1);
265 out2.resize(
out.size());
267 ctx.get(), out2.data(), &out2_len, out2.size(), nonce.data(),
268 nonce.size(),
out.data(),
out.size(), ad.data(), ad.size()))
269 <<
"Decrypted bad data with corrupted byte.";
275 const KnownAEAD &aead_config = GetParam();
276 if (!aead()->seal_scatter_supports_extra_in) {
283 if (t->HasAttribute(
"NO_SEAL") ||
284 t->HasAttribute(
"FAILS") ||
285 (aead_config.flags & kNondeterministic)) {
290 std::vector<uint8_t>
key, nonce,
in, ad, ct,
tag;
298 bssl::ScopedEVP_AEAD_CTX
ctx;
300 tag.size(),
nullptr));
302 std::vector<uint8_t>
out(
in.size());
304 for (
size_t extra_in_size = 0; extra_in_size <
in.size(); extra_in_size++) {
305 size_t tag_bytes_written;
308 ctx.get(),
out.data(), out_tag.data(), &tag_bytes_written,
309 out_tag.size(), nonce.data(), nonce.size(),
in.data(),
310 in.size() - extra_in_size,
in.data() +
in.size() - extra_in_size,
311 extra_in_size, ad.data(), ad.size()));
313 ASSERT_EQ(tag_bytes_written, extra_in_size +
tag.size());
315 memcpy(
out.data() +
in.size() - extra_in_size, out_tag.data(),
320 tag_bytes_written - extra_in_size));
326 std::string test_vectors =
"crypto/cipher_extra/test/";
327 const KnownAEAD &aead_config = GetParam();
330 std::vector<uint8_t> key, nonce, in, ad, ct, tag;
331 ASSERT_TRUE(t->GetBytes(&key,
"KEY"));
332 ASSERT_TRUE(t->GetBytes(&nonce,
"NONCE"));
333 ASSERT_TRUE(t->GetBytes(&in,
"IN"));
334 ASSERT_TRUE(t->GetBytes(&ad,
"AD"));
335 ASSERT_TRUE(t->GetBytes(&ct,
"CT"));
336 ASSERT_TRUE(t->GetBytes(&tag,
"TAG"));
337 size_t tag_len = tag.size();
338 if (t->HasAttribute(
"TAG_LEN")) {
341 std::string tag_len_str;
342 ASSERT_TRUE(t->GetAttribute(&tag_len_str,
"TAG_LEN"));
343 tag_len = strtoul(tag_len_str.c_str(), nullptr, 10);
344 ASSERT_TRUE(tag_len);
347 bssl::ScopedEVP_AEAD_CTX
ctx;
351 std::vector<uint8_t>
out(
in.size());
353 if (!t->HasAttribute(
"NO_SEAL") &&
356 ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
357 ctx.get(), out.data(), out_tag.data(), &out_tag_len, out_tag.size(),
358 nonce.data(), nonce.size(), in.data(), in.size(), nullptr, 0,
359 ad.data(), ad.size()));
360 out_tag.resize(out_tag_len);
362 ASSERT_EQ(out.size(), ct.size());
363 ASSERT_EQ(out_tag.size(), tag.size());
364 EXPECT_EQ(Bytes(ct), Bytes(out.data(), ct.size()));
365 EXPECT_EQ(Bytes(tag), Bytes(out_tag.data(), tag.size()));
367 out.resize(ct.size());
368 out_tag.resize(tag.size());
369 OPENSSL_memcpy(out.data(), ct.data(), ct.size());
370 OPENSSL_memcpy(out_tag.data(), tag.data(), tag.size());
379 std::vector<uint8_t> out2(
out.size());
381 ctx.get(), out2.data(), nonce.data(), nonce.size(),
out.data(),
382 out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size());
394 if (t->HasAttribute(
"FAILS")) {
411 out_tag.push_back(0);
412 out2.resize(
out.size());
414 ctx.get(), out2.data(), nonce.data(), nonce.size(),
out.data(),
415 out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
416 <<
"Decrypted bad data with trailing garbage.";
427 out_tag.resize(out_tag.size() - 1);
428 out2.resize(
out.size());
430 ctx.get(), out2.data(), nonce.data(), nonce.size(),
out.data(),
431 out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
432 <<
"Decrypted bad data with corrupted byte.";
441 ctx.get(), out2.data(), nonce.data(), nonce.size(),
out.data(),
442 out.size(), out_tag.data(), 0, ad.data(), ad.size()))
443 <<
"Decrypted bad data with corrupted byte.";
456 &
ctx, aead(),
key, key_len,
462 &
ctx, aead(),
key, key_len,
487 bssl::ScopedEVP_AEAD_CTX
ctx;
494 size_t ciphertext_len;
502 for (
size_t i = ciphertext_len;
i <
sizeof(
ciphertext);
i++) {
505 <<
"Sealing wrote off the end of the buffer.";
508 const size_t overhead_used = ciphertext_len -
sizeof(
plaintext);
509 const size_t expected_overhead =
511 EXPECT_EQ(overhead_used, expected_overhead)
512 <<
"AEAD is probably ignoring request to truncate tags.";
517 size_t plaintext2_len;
519 ctx.get(), plaintext2, &plaintext2_len,
sizeof(plaintext2), nonce,
520 nonce_len,
ciphertext, ciphertext_len,
nullptr , 0))
521 <<
"Opening with truncated tag didn't work.";
523 for (
size_t i = plaintext2_len;
i <
sizeof(plaintext2);
i++) {
526 <<
"Opening wrote off the end of the buffer.";
541 std::vector<uint8_t>
key(key_len,
'a');
542 bssl::ScopedEVP_AEAD_CTX
ctx;
547 "testing123456testing123456testing123456testing123456testing123456testing"
548 "123456testing123456testing123456testing123456testing123456testing123456t"
549 "esting123456testing123456testing123456testing123456testing123456testing1"
550 "23456testing123456testing123456testing12345";
551 const std::vector<size_t> offsets = {
552 0, 1, 2, 8, 15, 16, 17, 31, 32, 33, 63,
553 64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
556 std::vector<uint8_t> nonce(nonce_len,
'b');
557 std::vector<uint8_t> valid_encryption(
sizeof(
kPlaintext) + max_overhead);
558 size_t valid_encryption_len;
560 ctx.get(), valid_encryption.data(), &valid_encryption_len,
563 <<
"EVP_AEAD_CTX_seal failed with disjoint buffers.";
566 std::vector<uint8_t>
buffer(2 + valid_encryption_len);
574 ctx.get(), out1 , &out_len,
sizeof(
kPlaintext) + max_overhead,
575 nonce.data(), nonce_len,
in,
sizeof(
kPlaintext),
nullptr, 0));
577 ctx.get(), out2 , &out_len,
sizeof(
kPlaintext) + max_overhead,
578 nonce.data(), nonce_len,
in,
sizeof(
kPlaintext),
nullptr, 0));
583 valid_encryption_len, nonce.data(), nonce_len,
584 in, valid_encryption_len,
nullptr, 0));
586 valid_encryption_len, nonce.data(), nonce_len,
587 in, valid_encryption_len,
nullptr, 0));
594 sizeof(
kPlaintext) + max_overhead, nonce.data(),
604 nonce.data(), nonce_len,
in,
605 valid_encryption_len,
nullptr, 0));
613 alignas(16)
uint8_t ad[32 + 1];
628 bssl::ScopedEVP_AEAD_CTX
ctx;
633 size_t ciphertext_len;
648 ciphertext_len, ad + 1, ad_len));
657 bssl::ScopedEVP_AEAD_CTX
ctx;
665 size_t ciphertext_len;
680 std::vector<size_t> nonce_lens;
681 if (valid_nonce_len != 0) {
685 nonce_lens.push_back(0);
688 nonce_lens.push_back(valid_nonce_len + 1);
689 if (valid_nonce_len != 0) {
690 nonce_lens.push_back(valid_nonce_len - 1);
700 for (
size_t nonce_len : nonce_lens) {
704 std::vector<uint8_t> nonce(nonce_len);
705 bssl::ScopedEVP_AEAD_CTX
ctx;
711 nonce.data(), nonce.size(),
nullptr ,
712 0, kZeros , ad_len));
725 nonce.data(), nonce.size(), kZeros ,
726 sizeof(kZeros), kZeros , ad_len));
735 #if defined(SUPPORTS_ABI_TEST)
754 size_t *out_ciphertext_len,
const uint8_t *nonce,
756 const uint8_t *ad,
size_t ad_len) {
760 nonce_len,
plaintext, plaintext_len, ad, ad_len);
764 size_t *out_plaintext_len,
const uint8_t *nonce,
766 const uint8_t *ad,
size_t ad_len) {
770 ciphertext_len, ad, ad_len);
779 bssl::ScopedEVP_AEAD_CTX ctx_seal;
781 CHECK_ABI(aead_ctx_init_for_seal, ctx_seal.get(), aead(),
key, key_len));
783 bssl::ScopedEVP_AEAD_CTX ctx_open;
785 CHECK_ABI(aead_ctx_init_for_open, ctx_open.get(), aead(),
key, key_len));
790 alignas(2)
uint8_t ad_buf[512];
792 const uint8_t *
const ad = ad_buf + 1;
796 : sizeof(ad_buf) - 1;
804 size_t ciphertext_len;
812 size_t plaintext2_len;
814 &plaintext2_len, nonce,
ciphertext + 1, ciphertext_len,
818 Bytes(plaintext2 + 1, plaintext2_len));
821 TEST(ChaChaPoly1305Test, ABI) {
826 std::unique_ptr<uint8_t[]>
buf(
new uint8_t[1024]);
827 for (
size_t len = 0;
len <= 1024;
len += 5) {
831 len % 128, &open_ctx);
834 for (
size_t len = 0;
len <= 1024;
len += 5) {
838 len % 128, &seal_ctx);
841 #endif // SUPPORTS_ABI_TEST
843 TEST(AEADTest, AESCCMLargeAD) {
844 static const std::vector<uint8_t>
kKey(16,
'A');
845 static const std::vector<uint8_t>
kNonce(13,
'N');
846 static const std::vector<uint8_t> kAD(65536,
'D');
847 static const std::vector<uint8_t>
kPlaintext = {
848 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
849 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
850 static const std::vector<uint8_t> kCiphertext = {
851 0xa2, 0x12, 0x3f, 0x0b, 0x07, 0xd5, 0x02, 0xff,
852 0xa9, 0xcd, 0xa0, 0xf3, 0x69, 0x1c, 0x49, 0x0c};
853 static const std::vector<uint8_t> kTag = {0x4a, 0x31, 0x82, 0x96};
856 bssl::ScopedEVP_AEAD_CTX
ctx;
861 std::vector<uint8_t>
out(kCiphertext.size() + kTag.size());
867 ASSERT_EQ(out_len, kCiphertext.size() + kTag.size());
873 out.size(), kAD.data(), kAD.size()));
880 t->IgnoreInstruction(
"ivSize");
882 std::vector<uint8_t> aad, ct, iv,
key,
msg,
tag;
890 ASSERT_TRUE(t->GetInstruction(&tag_size_str,
"tagSize"));
891 size_t tag_size =
static_cast<size_t>(atoi(tag_size_str.c_str()));
897 std::vector<uint8_t> ct_and_tag = ct;
898 ct_and_tag.insert(ct_and_tag.end(),
tag.begin(),
tag.end());
900 bssl::ScopedEVP_AEAD_CTX
ctx;
903 std::vector<uint8_t>
out(
msg.size());
908 if (
result.IsValid({
"SmallIv"})) {
911 iv.data(), iv.size(), ct_and_tag.data(),
912 ct_and_tag.size(), aad.data(), aad.size()));
918 iv.data(), iv.size(),
out.data(),
out.size(),
919 aad.data(), aad.size()));
923 out.resize(ct_and_tag.size());
925 iv.data(), iv.size(),
msg.data(),
msg.size(),
926 aad.data(), aad.size()));
931 out.resize(ct_and_tag.size());
933 iv.data(), iv.size(),
out.data(),
msg.size(),
934 aad.data(), aad.size()));
939 iv.data(), iv.size(), ct_and_tag.data(),
940 ct_and_tag.size(), aad.data(), aad.size()));
945 iv.data(), iv.size(),
out.data(),
out.size(),
946 aad.data(), aad.size()));
950 TEST(AEADTest, WycheproofAESGCMSIV) {
951 FileTestGTest(
"third_party/wycheproof_testvectors/aes_gcm_siv_test.txt",
954 ASSERT_TRUE(t->GetInstruction(&key_size_str,
"keySize"));
956 switch (atoi(key_size_str.c_str())) {
964 FAIL() <<
"Unknown key size: " << key_size_str;
971 TEST(AEADTest, WycheproofAESGCM) {
972 FileTestGTest(
"third_party/wycheproof_testvectors/aes_gcm_test.txt",
975 ASSERT_TRUE(t->GetInstruction(&key_size_str,
"keySize"));
977 switch (atoi(key_size_str.c_str())) {
988 FAIL() <<
"Unknown key size: " << key_size_str;
995 TEST(AEADTest, WycheproofChaCha20Poly1305) {
996 FileTestGTest(
"third_party/wycheproof_testvectors/chacha20_poly1305_test.txt",
998 t->IgnoreInstruction(
"keySize");
1003 TEST(AEADTest, WycheproofXChaCha20Poly1305) {
1005 "third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt",
1007 t->IgnoreInstruction(
"keySize");