diff options
author | Rob Barnes <robbarnes@google.com> | 2019-09-13 18:00:44 -0600 |
---|---|---|
committer | Rob Barnes <robbarnes@google.com> | 2019-09-19 10:03:35 -0600 |
commit | 8ddc1c700d63d03336d168703664ecf28ce12c15 (patch) | |
tree | 9097bf34f88a0e2eecc0bb000026b943c75b346a /keymaster | |
parent | 71cb010ba3e44189e5a5a887e1b756df5bdc1df0 (diff) | |
download | platform_hardware_interfaces-8ddc1c700d63d03336d168703664ecf28ce12c15.tar.gz platform_hardware_interfaces-8ddc1c700d63d03336d168703664ecf28ce12c15.tar.bz2 platform_hardware_interfaces-8ddc1c700d63d03336d168703664ecf28ce12c15.zip |
Add Keymaster VTS tests for some AES cases:
1. AES operation attempted with unauthorized purpose.
2. AES-GCM encryption performed with different nonces, should
generate different ciphertexts.
3. AES-GCM encryption decryption round trip with delays between
begin and update and finish.
Bug: 133258003
Test: VtsHalKeymasterV4_0TargetTest
Change-Id: Ia8b4b4b317ecff51b18e64dfa3b84bf77475812d
Diffstat (limited to 'keymaster')
-rw-r--r-- | keymaster/4.0/vts/functional/KeymasterHidlTest.cpp | 14 | ||||
-rw-r--r-- | keymaster/4.0/vts/functional/KeymasterHidlTest.h | 2 | ||||
-rw-r--r-- | keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp | 120 |
3 files changed, 136 insertions, 0 deletions
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp index 3af1df32d3..15d5fd8e69 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp @@ -611,6 +611,20 @@ string KeymasterHidlTest::EncryptMessage(const string& message, BlockMode block_ return ciphertext; } +string KeymasterHidlTest::EncryptMessage(const string& message, BlockMode block_mode, + PaddingMode padding, uint8_t mac_length_bits, + const HidlBuf& iv_in) { + SCOPED_TRACE("EncryptMessage"); + auto params = AuthorizationSetBuilder() + .BlockMode(block_mode) + .Padding(padding) + .Authorization(TAG_MAC_LENGTH, mac_length_bits) + .Authorization(TAG_NONCE, iv_in); + AuthorizationSet out_params; + string ciphertext = EncryptMessage(message, params, &out_params); + return ciphertext; +} + string KeymasterHidlTest::DecryptMessage(const HidlBuf& key_blob, const string& ciphertext, const AuthorizationSet& params) { SCOPED_TRACE("DecryptMessage"); diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h index 015fc43752..8fe223fcf0 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h @@ -201,6 +201,8 @@ class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase { HidlBuf* iv_out); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, const HidlBuf& iv_in); + string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, + uint8_t mac_length_bits, const HidlBuf& iv_in); string DecryptMessage(const HidlBuf& key_blob, const string& ciphertext, const AuthorizationSet& params); 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 9e6cce7e97..dc1dfdcc7e 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -2706,6 +2706,40 @@ TEST_F(EncryptionOperationsTest, AesWrongMode) { } /* + * EncryptionOperationsTest.AesWrongPurpose + * + * Verifies that AES encryption fails in the correct way when an unauthorized purpose is specified. + */ +TEST_F(EncryptionOperationsTest, AesWrongPurpose) { + auto err = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesKey(128) + .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT) + .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) + .Authorization(TAG_MIN_MAC_LENGTH, 128) + .Padding(PaddingMode::NONE)); + ASSERT_EQ(ErrorCode::OK, err) << "Got " << err; + + err = Begin(KeyPurpose::DECRYPT, + AuthorizationSetBuilder().BlockMode(BlockMode::GCM).Padding(PaddingMode::NONE)); + EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, err) << "Got " << err; + + CheckedDeleteKey(); + + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesKey(128) + .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT) + .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) + .Authorization(TAG_MIN_MAC_LENGTH, 128) + .Padding(PaddingMode::NONE))); + + err = Begin(KeyPurpose::ENCRYPT, + AuthorizationSetBuilder().BlockMode(BlockMode::GCM).Padding(PaddingMode::NONE)); + EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, err) << "Got " << err; +} + +/* * EncryptionOperationsTest.AesEcbNoPaddingWrongInputSize * * Verifies that AES encryption fails in the correct way when provided an input that is not a @@ -3225,6 +3259,92 @@ TEST_F(EncryptionOperationsTest, AesGcmRoundTripSuccess) { } /* + * EncryptionOperationsTest.AesGcmRoundTripWithDelaySuccess + * + * Verifies that AES GCM mode works, even when there's a long delay + * between operations. + */ +TEST_F(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesEncryptionKey(128) + .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) + .Padding(PaddingMode::NONE) + .Authorization(TAG_MIN_MAC_LENGTH, 128))); + + string aad = "foobar"; + string message = "123456789012345678901234567890123456"; + + auto begin_params = AuthorizationSetBuilder() + .BlockMode(BlockMode::GCM) + .Padding(PaddingMode::NONE) + .Authorization(TAG_MAC_LENGTH, 128); + + auto update_params = + AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size()); + + // Encrypt + AuthorizationSet begin_out_params; + ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)) + << "Begin encrypt"; + string ciphertext; + AuthorizationSet update_out_params; + sleep(5); + ASSERT_EQ(ErrorCode::OK, + Finish(op_handle_, update_params, message, "", &update_out_params, &ciphertext)); + + ASSERT_EQ(ciphertext.length(), message.length() + 16); + + // Grab nonce + begin_params.push_back(begin_out_params); + + // Decrypt. + ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt"; + string plaintext; + size_t input_consumed; + sleep(5); + ASSERT_EQ(ErrorCode::OK, Update(op_handle_, update_params, ciphertext, &update_out_params, + &plaintext, &input_consumed)); + EXPECT_EQ(ciphertext.size(), input_consumed); + sleep(5); + EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext)); + EXPECT_EQ(message.length(), plaintext.length()); + EXPECT_EQ(message, plaintext); +} + +/* + * EncryptionOperationsTest.AesGcmDifferentNonces + * + * Verifies that encrypting the same data with different nonces produces different outputs. + */ +TEST_F(EncryptionOperationsTest, AesGcmDifferentNonces) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesEncryptionKey(128) + .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) + .Padding(PaddingMode::NONE) + .Authorization(TAG_MIN_MAC_LENGTH, 128) + .Authorization(TAG_CALLER_NONCE))); + + string aad = "foobar"; + string message = "123456789012345678901234567890123456"; + string nonce1 = "000000000000"; + string nonce2 = "111111111111"; + string nonce3 = "222222222222"; + + string ciphertext1 = + EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce1)); + string ciphertext2 = + EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce2)); + string ciphertext3 = + EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce3)); + + ASSERT_NE(ciphertext1, ciphertext2); + ASSERT_NE(ciphertext1, ciphertext3); + ASSERT_NE(ciphertext2, ciphertext3); +} + +/* * EncryptionOperationsTest.AesGcmTooShortTag * * Verifies that AES GCM mode fails correctly when a too-short tag length is specified. |