Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a33f46bc authored by David Drysdale's avatar David Drysdale Committed by Gerrit Code Review
Browse files

Merge "Fix flaky corrupted padding tests"

parents 4b0c7f0e 4c1f6ac4
Loading
Loading
Loading
Loading
+58 −18
Original line number Diff line number Diff line
@@ -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) {
@@ -2849,11 +2855,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) {
@@ -3876,17 +3893,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 {
@@ -4187,18 +4217,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.";
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -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;