Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

654 linhas
26 KiB

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