Merge "Fix flaky corrupted padding tests" am: a33f46bc2a am: 61cf943208 am: 02951d1167

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1903312

Change-Id: Ie50a00970832fc03691a66907534ccc0fc71208f
This commit is contained in:
David Drysdale 2021-11-30 07:28:03 +00:00 committed by Automerger Merge Worker
commit d1c5ed5bec
2 changed files with 59 additions and 19 deletions

View file

@ -81,6 +81,12 @@ bool operator==(const KeyCharacteristics& a, const KeyCharacteristics& b) {
namespace test {
namespace {
// The maximum number of times we'll attempt to verify that corruption
// of an encrypted blob results in an error. Retries are necessary as there
// is a small (roughly 1/256) chance that corrupting ciphertext still results
// in valid PKCS7 padding.
constexpr size_t kMaxPaddingCorruptionRetries = 8;
template <TagType tag_type, Tag tag, typename ValueT>
bool contains(hidl_vec<KeyParameter>& set, TypedTag<tag_type, tag> ttag, ValueT expected_value) {
size_t count = std::count_if(set.begin(), set.end(), [&](const KeyParameter& param) {
@ -2853,11 +2859,22 @@ TEST_P(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
string ciphertext = EncryptMessage(message, params);
EXPECT_EQ(16U, ciphertext.size());
EXPECT_NE(ciphertext, message);
for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
++ciphertext[ciphertext.size() / 2];
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
string plaintext;
EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &plaintext));
ErrorCode error = Finish(message, &plaintext);
if (error == ErrorCode::INVALID_INPUT_LENGTH) {
// This is the expected error, we can exit the test now.
return;
} else {
// Very small chance we got valid decryption, so try again.
ASSERT_EQ(error, ErrorCode::OK);
}
}
FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
HidlBuf CopyIv(const AuthorizationSet& set) {
@ -3880,17 +3897,30 @@ TEST_P(EncryptionOperationsTest, TripleDesEcbPkcs7PaddingCorrupted) {
string ciphertext = EncryptMessage(message, BlockMode::ECB, PaddingMode::PKCS7);
EXPECT_EQ(8U, ciphertext.size());
EXPECT_NE(ciphertext, message);
++ciphertext[ciphertext.size() / 2];
AuthorizationSetBuilder begin_params;
begin_params.push_back(TAG_BLOCK_MODE, BlockMode::ECB);
begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
++ciphertext[ciphertext.size() / 2];
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
size_t input_consumed;
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
ErrorCode error = Finish(&plaintext);
if (error == ErrorCode::INVALID_ARGUMENT) {
// This is the expected error, we can exit the test now.
return;
} else {
// Very small chance we got valid decryption, so try again.
ASSERT_EQ(error, ErrorCode::OK);
}
}
FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
struct TripleDesTestVector {
@ -4191,18 +4221,28 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) {
string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv);
EXPECT_EQ(8U, ciphertext.size());
EXPECT_NE(ciphertext, message);
++ciphertext[ciphertext.size() / 2];
auto begin_params = AuthorizationSetBuilder()
.BlockMode(BlockMode::CBC)
.Padding(PaddingMode::PKCS7)
.Authorization(TAG_NONCE, iv);
for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
++ciphertext[ciphertext.size() / 2];
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
size_t input_consumed;
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
ErrorCode error = Finish(&plaintext);
if (error == ErrorCode::INVALID_ARGUMENT) {
// This is the expected error, we can exit the test now.
return;
} else {
// Very small chance we got valid decryption, so try again.
ASSERT_EQ(error, ErrorCode::OK);
}
}
FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
/*

View file

@ -70,7 +70,7 @@ namespace aidl::android::hardware::security::keymint::test {
namespace {
// The maximum number of times we'll attempt to verify that corruption
// of an ecrypted blob results in an error. Retries are necessary as there
// of an encrypted blob results in an error. Retries are necessary as there
// is a small (roughly 1/256) chance that corrupting ciphertext still results
// in valid PKCS7 padding.
constexpr size_t kMaxPaddingCorruptionRetries = 8;