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

Commit 04fc0c4f authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Split AESincremental VTS test into 4 Tests(For...

Merge "Split AESincremental VTS test into 4 Tests(For blockmodes-ECB,CBC,GCM,CTR)" am: 90019d46 am: bfdd991c am: 8be10ddc

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

Change-Id: Iffe169fcff0a11478672bf8f5895a93fcdcc9003
parents 3059790c 8be10ddc
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -443,6 +443,98 @@ string KeymasterHidlTest::MacMessage(const string& message, Digest digest, size_
        AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length));
}

void KeymasterHidlTest::CheckAesIncrementalEncryptOperation(BlockMode block_mode,
                                                            int message_size) {
    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
                                                 .AesEncryptionKey(128)
                                                 .BlockMode(block_mode)
                                                 .Padding(PaddingMode::NONE)
                                                 .Authorization(TAG_MIN_MAC_LENGTH, 128)));

    for (int increment = 1; increment <= message_size; ++increment) {
        string message(message_size, 'a');
        auto params = AuthorizationSetBuilder()
                              .BlockMode(block_mode)
                              .Padding(PaddingMode::NONE)
                              .Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;

        AuthorizationSet output_params;
        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));

        string ciphertext;
        size_t input_consumed;
        string to_send;
        for (size_t i = 0; i < message.size(); i += increment) {
            to_send.append(message.substr(i, increment));
            EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed));
            EXPECT_EQ(to_send.length(), input_consumed);
            to_send = to_send.substr(input_consumed);
            EXPECT_EQ(0U, to_send.length());

            switch (block_mode) {
                case BlockMode::ECB:
                case BlockMode::CBC:
                    // Implementations must take as many blocks as possible, leaving less than
                    // a block.
                    EXPECT_LE(to_send.length(), 16U);
                    break;
                case BlockMode::GCM:
                case BlockMode::CTR:
                    // Implementations must always take all the data.
                    EXPECT_EQ(0U, to_send.length());
                    break;
            }
        }
        EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send;

        switch (block_mode) {
            case BlockMode::GCM:
                EXPECT_EQ(message.size() + 16, ciphertext.size());
                break;
            case BlockMode::CTR:
                EXPECT_EQ(message.size(), ciphertext.size());
                break;
            case BlockMode::CBC:
            case BlockMode::ECB:
                EXPECT_EQ(message.size() + message.size() % 16, ciphertext.size());
                break;
        }

        auto iv = output_params.GetTagValue(TAG_NONCE);
        switch (block_mode) {
            case BlockMode::CBC:
            case BlockMode::GCM:
            case BlockMode::CTR:
                ASSERT_TRUE(iv.isOk()) << "No IV for block mode " << block_mode;
                EXPECT_EQ(block_mode == BlockMode::GCM ? 12U : 16U, iv.value().size());
                params.push_back(TAG_NONCE, iv.value());
                break;

            case BlockMode::ECB:
                EXPECT_FALSE(iv.isOk()) << "ECB mode should not generate IV";
                break;
        }

        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params))
                << "Decrypt begin() failed for block mode " << block_mode;

        string plaintext;
        for (size_t i = 0; i < ciphertext.size(); i += increment) {
            to_send.append(ciphertext.substr(i, increment));
            EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed));
            to_send = to_send.substr(input_consumed);
        }
        ErrorCode error = Finish(to_send, &plaintext);
        ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
                                        << " and increment " << increment;
        if (error == ErrorCode::OK) {
            ASSERT_EQ(message, plaintext) << "Decryption didn't match for block mode " << block_mode
                                          << " and increment " << increment;
        }
    }
}

void KeymasterHidlTest::CheckHmacTestVector(const string& key, const string& message, Digest digest,
                                            const string& expected_mac) {
    SCOPED_TRACE("CheckHmacTestVector");
+2 −0
Original line number Diff line number Diff line
@@ -166,6 +166,8 @@ class KeymasterHidlTest : public ::testing::TestWithParam<std::string> {

    string MacMessage(const string& message, Digest digest, size_t mac_length);

    void CheckAesIncrementalEncryptOperation(BlockMode block_mode, int message_size);

    void CheckHmacTestVector(const string& key, const string& message, Digest digest,
                             const string& expected_mac);

+28 −94
Original line number Diff line number Diff line
@@ -2932,105 +2932,39 @@ TEST_P(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
}

/*
 * EncryptionOperationsTest.AesIncremental
 * EncryptionOperationsTest.AesEcbIncremental
 *
 * Verifies that AES works, all modes, when provided data in various size increments.
 * Verifies that AES works for ECB block mode, when provided data in various size increments.
 */
TEST_P(EncryptionOperationsTest, AesIncremental) {
    auto block_modes = {
        BlockMode::ECB, BlockMode::CBC, BlockMode::CTR, BlockMode::GCM,
    };

    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                             .Authorization(TAG_NO_AUTH_REQUIRED)
                                             .AesEncryptionKey(128)
                                             .BlockMode(block_modes)
                                             .Padding(PaddingMode::NONE)
                                             .Authorization(TAG_MIN_MAC_LENGTH, 128)));

    for (int increment = 1; increment <= 240; ++increment) {
        for (auto block_mode : block_modes) {
            string message(240, 'a');
            auto params = AuthorizationSetBuilder()
                              .BlockMode(block_mode)
                              .Padding(PaddingMode::NONE)
                              .Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;

            AuthorizationSet output_params;
            EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));

            string ciphertext;
            size_t input_consumed;
            string to_send;
            for (size_t i = 0; i < message.size(); i += increment) {
                to_send.append(message.substr(i, increment));
                EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed));
                EXPECT_EQ(to_send.length(), input_consumed);
                to_send = to_send.substr(input_consumed);
                EXPECT_EQ(0U, to_send.length());

                switch (block_mode) {
                    case BlockMode::ECB:
                    case BlockMode::CBC:
                        // Implementations must take as many blocks as possible, leaving less than
                        // a block.
                        EXPECT_LE(to_send.length(), 16U);
                        break;
                    case BlockMode::GCM:
                    case BlockMode::CTR:
                        // Implementations must always take all the data.
                        EXPECT_EQ(0U, to_send.length());
                        break;
                }
TEST_P(EncryptionOperationsTest, AesEcbIncremental) {
    CheckAesIncrementalEncryptOperation(BlockMode::ECB, 240);
}
            EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send;

            switch (block_mode) {
                case BlockMode::GCM:
                    EXPECT_EQ(message.size() + 16, ciphertext.size());
                    break;
                case BlockMode::CTR:
                    EXPECT_EQ(message.size(), ciphertext.size());
                    break;
                case BlockMode::CBC:
                case BlockMode::ECB:
                    EXPECT_EQ(message.size() + message.size() % 16, ciphertext.size());
                    break;
/*
 * EncryptionOperationsTest.AesCbcIncremental
 *
 * Verifies that AES works for CBC block mode, when provided data in various size increments.
 */
TEST_P(EncryptionOperationsTest, AesCbcIncremental) {
    CheckAesIncrementalEncryptOperation(BlockMode::CBC, 240);
}

            auto iv = output_params.GetTagValue(TAG_NONCE);
            switch (block_mode) {
                case BlockMode::CBC:
                case BlockMode::GCM:
                case BlockMode::CTR:
                    ASSERT_TRUE(iv.isOk()) << "No IV for block mode " << block_mode;
                    EXPECT_EQ(block_mode == BlockMode::GCM ? 12U : 16U, iv.value().size());
                    params.push_back(TAG_NONCE, iv.value());
                    break;

                case BlockMode::ECB:
                    EXPECT_FALSE(iv.isOk()) << "ECB mode should not generate IV";
                    break;
/*
 * EncryptionOperationsTest.AesCtrIncremental
 *
 * Verifies that AES works for CTR block mode, when provided data in various size increments.
 */
TEST_P(EncryptionOperationsTest, AesCtrIncremental) {
    CheckAesIncrementalEncryptOperation(BlockMode::CTR, 240);
}

            EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params))
                << "Decrypt begin() failed for block mode " << block_mode;

            string plaintext;
            for (size_t i = 0; i < ciphertext.size(); i += increment) {
                to_send.append(ciphertext.substr(i, increment));
                EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed));
                to_send = to_send.substr(input_consumed);
            }
            ErrorCode error = Finish(to_send, &plaintext);
            ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
                                            << " and increment " << increment;
            if (error == ErrorCode::OK) {
                ASSERT_EQ(message, plaintext) << "Decryption didn't match for block mode "
                                              << block_mode << " and increment " << increment;
            }
        }
    }
/*
 * EncryptionOperationsTest.AesGcmIncremental
 *
 * Verifies that AES works for GCM block mode, when provided data in various size increments.
 */
TEST_P(EncryptionOperationsTest, AesGcmIncremental) {
    CheckAesIncrementalEncryptOperation(BlockMode::GCM, 240);
}

struct AesCtrSp80038aTestVector {
+72 −0
Original line number Diff line number Diff line
@@ -665,6 +665,78 @@ string KeyMintAidlTestBase::MacMessage(const string& message, Digest digest, siz
            AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length));
}

void KeyMintAidlTestBase::CheckAesIncrementalEncryptOperation(BlockMode block_mode,
                                                              int message_size) {
    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
                                                 .AesEncryptionKey(128)
                                                 .BlockMode(block_mode)
                                                 .Padding(PaddingMode::NONE)
                                                 .Authorization(TAG_MIN_MAC_LENGTH, 128)));

    for (int increment = 1; increment <= message_size; ++increment) {
        string message(message_size, 'a');
        auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(PaddingMode::NONE);
        if (block_mode == BlockMode::GCM) {
            params.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
        }

        AuthorizationSet output_params;
        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));

        string ciphertext;
        string to_send;
        for (size_t i = 0; i < message.size(); i += increment) {
            EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
        }
        EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext))
                << "Error sending " << to_send << " with block mode " << block_mode;

        switch (block_mode) {
            case BlockMode::GCM:
                EXPECT_EQ(message.size() + 16, ciphertext.size());
                break;
            case BlockMode::CTR:
                EXPECT_EQ(message.size(), ciphertext.size());
                break;
            case BlockMode::CBC:
            case BlockMode::ECB:
                EXPECT_EQ(message.size() + message.size() % 16, ciphertext.size());
                break;
        }

        auto iv = output_params.GetTagValue(TAG_NONCE);
        switch (block_mode) {
            case BlockMode::CBC:
            case BlockMode::GCM:
            case BlockMode::CTR:
                ASSERT_TRUE(iv) << "No IV for block mode " << block_mode;
                EXPECT_EQ(block_mode == BlockMode::GCM ? 12U : 16U, iv->get().size());
                params.push_back(TAG_NONCE, iv->get());
                break;

            case BlockMode::ECB:
                EXPECT_FALSE(iv) << "ECB mode should not generate IV";
                break;
        }

        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params))
                << "Decrypt begin() failed for block mode " << block_mode;

        string plaintext;
        for (size_t i = 0; i < ciphertext.size(); i += increment) {
            EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
        }
        ErrorCode error = Finish(to_send, &plaintext);
        ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
                                        << " and increment " << increment;
        if (error == ErrorCode::OK) {
            ASSERT_EQ(message, plaintext) << "Decryption didn't match for block mode " << block_mode
                                          << " and increment " << increment;
        }
    }
}

void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message,
                                              Digest digest, const string& expected_mac) {
    SCOPED_TRACE("CheckHmacTestVector");
+2 −0
Original line number Diff line number Diff line
@@ -169,6 +169,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {

    string MacMessage(const string& message, Digest digest, size_t mac_length);

    void CheckAesIncrementalEncryptOperation(BlockMode block_mode, int message_size);

    void CheckHmacTestVector(const string& key, const string& message, Digest digest,
                             const string& expected_mac);

Loading