Skip to content

Commit

Permalink
Account for padding-related edge case in testing
Browse files Browse the repository at this point in the history
  • Loading branch information
WillChilds-Klein committed Nov 18, 2024
1 parent b39bf41 commit 5c09e5b
Showing 1 changed file with 25 additions and 7 deletions.
32 changes: 25 additions & 7 deletions crypto/pkcs7/pkcs7_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1780,15 +1780,33 @@ TEST(PKCS7Test, TestEnveloped) {
// to the output |bio|. The cipher ends up in an unhealthy state due to bad
// padding (what should be the final pad block is now just random bytes), so
// the overall |PKCS7_decrypt| operation fails.
EXPECT_FALSE(PKCS7_decrypt(p7.get(), rsa_pkey.get(), /*certs*/ nullptr,
bio.get(),
/*flags*/ 0));
EXPECT_EQ(sizeof(decrypted), BIO_pending(bio.get()));
int decrypt_ok =
PKCS7_decrypt(p7.get(), rsa_pkey.get(), /*certs*/ nullptr, bio.get(),
/*flags*/ 0);
EXPECT_LE(sizeof(decrypted), BIO_pending(bio.get()));
OPENSSL_cleanse(decrypted, sizeof(decrypted));
ASSERT_EQ((int)sizeof(decrypted),
BIO_read(bio.get(), decrypted, sizeof(decrypted)));
// There's a fun edge case here where the MMA defence can fool the block
// cipher into thinking the garbled "plaintext" padding is valid thus it's
// successfully decrypted the content. For block ciphers using conventional
// PKCS#7 padding, where the last byte of the padded plaintext determines how
// many bytes of padding have been appended, a random MMA-defense-garbled
// plaintext with last byte of 0x01 will trick the cipher into thinking there
// is only one byte of padding to remove, leaving the other block_size-1 bytes
// in place.
int max_decrypt =
sizeof(decrypted) + EVP_CIPHER_block_size(EVP_aes_128_cbc());
int decrypted_len = BIO_read(bio.get(), decrypted, max_decrypt);
if (decrypted_len > (int)sizeof(decrypted)) {
EXPECT_EQ(max_decrypt - 1, decrypted_len);
EXPECT_TRUE(decrypt_ok);
EXPECT_FALSE(ERR_GET_REASON(ERR_peek_error()));
} else {
EXPECT_EQ((int)sizeof(decrypted), decrypted_len);
EXPECT_FALSE(decrypt_ok);
EXPECT_EQ(CIPHER_R_BAD_DECRYPT, ERR_GET_REASON(ERR_peek_error()));
}
// Of course, plaintext shouldn't equal decrypted in any case here
EXPECT_NE(Bytes(buf, sizeof(buf)), Bytes(decrypted, sizeof(decrypted)));
EXPECT_EQ(CIPHER_R_BAD_DECRYPT, ERR_GET_REASON(ERR_peek_error()));

// test "MMA" decrypt as above, but with stream cipher. stream cipher has no
// padding, so content encryption should "succeed" but return nonsense because
Expand Down

0 comments on commit 5c09e5b

Please sign in to comment.