From a3f59428f050ba749163712459d0a6043034a48d Mon Sep 17 00:00:00 2001 From: WillChilds-Klein Date: Sat, 7 Sep 2024 01:13:40 +0000 Subject: [PATCH] Add round-trip for BIO_write --- crypto/pkcs7/pkcs7_internal_bio_test.cc | 40 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/crypto/pkcs7/pkcs7_internal_bio_test.cc b/crypto/pkcs7/pkcs7_internal_bio_test.cc index 954f3749b62..d10a3217ec7 100644 --- a/crypto/pkcs7/pkcs7_internal_bio_test.cc +++ b/crypto/pkcs7/pkcs7_internal_bio_test.cc @@ -14,6 +14,12 @@ #include "../test/test_util.h" #include "./internal.h" +// TODO [childw] +// 1. parameterize over a meaningful set of ciphers +// 2. deduplicate round-trip code to the extent possible +// 3. seed RNG with fixed (random? need to print stdout?) value +// 4. clang-format all the things +// 5. parameterize over plaintext sizes that break cipher block size boundaries TEST(PKCS7Test, CipherBIO) { uint8_t key[EVP_MAX_KEY_LENGTH]; @@ -29,6 +35,7 @@ TEST(PKCS7Test, CipherBIO) { ASSERT_TRUE(RAND_bytes(key, sizeof(key))); ASSERT_TRUE(RAND_bytes(iv, sizeof(iv))); + // Round-trip using the |BIO_read| bio_cipher.reset(BIO_new(BIO_f_cipher())); ASSERT_TRUE(bio_cipher); EXPECT_TRUE(BIO_get_cipher_ctx(bio_cipher.get(), &ctx)); @@ -37,14 +44,12 @@ TEST(PKCS7Test, CipherBIO) { bio_mem.reset(BIO_new_mem_buf(pt, sizeof(pt))); ASSERT_TRUE(bio_mem); ASSERT_TRUE(BIO_up_ref(bio_mem.get())); // |bio_cipher| will take ownership - ASSERT_TRUE(BIO_set_mem_eof_return(bio_mem.get(), 0)); ASSERT_TRUE(BIO_push(bio_cipher.get(), bio_mem.get())); EXPECT_TRUE(BIO_read(bio_cipher.get(), ct, sizeof(ct))); - EXPECT_TRUE(BIO_flush(bio_cipher.get())); EXPECT_TRUE(BIO_get_cipher_status(bio_cipher.get())); // only consider first |sizeof(pt)| bytes of |ct|, exclude tag EXPECT_NE(Bytes(pt, sizeof(pt)), Bytes(ct, sizeof(pt))); - + // Reset both BIOs and decrypt bio_cipher.reset(BIO_new(BIO_f_cipher())); ASSERT_TRUE(bio_cipher); EXPECT_TRUE(BIO_get_cipher_ctx(bio_cipher.get(), &ctx)); @@ -57,4 +62,33 @@ TEST(PKCS7Test, CipherBIO) { EXPECT_TRUE(BIO_read(bio_cipher.get(), pt_decrypted, sizeof(pt_decrypted))); EXPECT_TRUE(BIO_get_cipher_status(bio_cipher.get())); EXPECT_EQ(Bytes(pt, sizeof(pt)), Bytes(pt_decrypted, sizeof(pt_decrypted))); + + // Round-trip using |BIO_write| for pt/ct instead of |BIO_new_mem_buf| + bio_cipher.reset(BIO_new(BIO_f_cipher())); + ASSERT_TRUE(bio_cipher); + EXPECT_TRUE(BIO_get_cipher_ctx(bio_cipher.get(), &ctx)); + ASSERT_TRUE( + EVP_CipherInit_ex(ctx, EVP_aes_128_gcm(), NULL, key, iv, /*enc*/ 1)); + bio_mem.reset(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio_mem); + ASSERT_TRUE(BIO_up_ref(bio_mem.get())); // |bio_cipher| will take ownership + ASSERT_TRUE(BIO_push(bio_cipher.get(), bio_mem.get())); + EXPECT_TRUE(BIO_write(bio_cipher.get(), pt, sizeof(pt))); + EXPECT_TRUE(BIO_get_cipher_status(bio_cipher.get())); + // Only consider first |sizeof(pt)| bytes of |ct|, exclude tag + EXPECT_NE(Bytes(pt, sizeof(pt)), Bytes(ct, sizeof(pt))); + // Reset both BIOs and decrypt + bio_cipher.reset(BIO_new(BIO_f_cipher())); + ASSERT_TRUE(bio_cipher); + EXPECT_TRUE(BIO_get_cipher_ctx(bio_cipher.get(), &ctx)); + ASSERT_TRUE( + EVP_CipherInit_ex(ctx, EVP_aes_128_gcm(), NULL, key, iv, /*enc*/ 0)); + bio_mem.reset(BIO_new(BIO_s_mem())); + EXPECT_TRUE(BIO_write(bio_mem.get(), ct, sizeof(ct))); + ASSERT_TRUE(bio_mem); + ASSERT_TRUE(BIO_up_ref(bio_mem.get())); // |bio_cipher| will take ownership + ASSERT_TRUE(BIO_push(bio_cipher.get(), bio_mem.get())); + EXPECT_TRUE(BIO_read(bio_cipher.get(), pt_decrypted, sizeof(pt_decrypted))); + EXPECT_TRUE(BIO_get_cipher_status(bio_cipher.get())); + EXPECT_EQ(Bytes(pt, sizeof(pt)), Bytes(pt_decrypted, sizeof(pt_decrypted))); }