From 19a4ca17eab8a914436d23b4ca9e968765259def Mon Sep 17 00:00:00 2001 From: "anil.hiranniah" Date: Thu, 3 Mar 2022 17:39:30 +0530 Subject: [PATCH] Split AESincremental VTS test into 4 Tests(For blockmodes-ECB,CBC,GCM,CTR) Change mentioned above is done in VTS for Keymaster4.0 and Keymint Test: VTS tests with tradefed Change-Id: Id62fdce65131ee00c88e5849955a937f1c171748 --- .../4.0/vts/functional/KeymasterHidlTest.cpp | 92 +++++++++++++ .../4.0/vts/functional/KeymasterHidlTest.h | 2 + .../functional/keymaster_hidl_hal_test.cpp | 122 ++++-------------- .../vts/functional/KeyMintAidlTestBase.cpp | 72 +++++++++++ .../aidl/vts/functional/KeyMintAidlTestBase.h | 2 + .../aidl/vts/functional/KeyMintTest.cpp | 106 ++++----------- 6 files changed, 224 insertions(+), 172 deletions(-) diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp index d0ad433464..5c3576e225 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp @@ -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"); diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h index 2ca7ea7a71..ad30aa7792 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h @@ -166,6 +166,8 @@ class KeymasterHidlTest : public ::testing::TestWithParam { 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); diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 2ff33b0940..14c756db7b 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -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, - }; +TEST_P(EncryptionOperationsTest, AesEcbIncremental) { + CheckAesIncrementalEncryptOperation(BlockMode::ECB, 240); +} - 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))); +/* + * 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); +} - 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 */; +/* + * 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); +} - 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; - } - } - } +/* + * 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 { diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index ff4036c1a8..c17a0b8f83 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -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"); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 6fb5bf5bdd..e59443c44e 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -169,6 +169,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { 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); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 767de2bdee..c734c373a7 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -5441,89 +5441,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, - }; +TEST_P(EncryptionOperationsTest, AesEcbIncremental) { + CheckAesIncrementalEncryptOperation(BlockMode::ECB, 240); +} - 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))); +/* + * 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); +} - 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); - if (block_mode == BlockMode::GCM) { - params.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */; - } +/* + * 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); +} - 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; - } - } - } +/* + * 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 {