// // Copyright (C) 2014 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include <base/stl_util.h> #include <crypto/sha2.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <openssl/aes.h> #include "trunks/error_codes.h" #include "trunks/hmac_authorization_delegate.h" #include "trunks/mock_authorization_delegate.h" #include "trunks/mock_blob_parser.h" #include "trunks/mock_hmac_session.h" #include "trunks/mock_policy_session.h" #include "trunks/mock_tpm.h" #include "trunks/mock_tpm_state.h" #include "trunks/tpm_constants.h" #include "trunks/tpm_utility_impl.h" #include "trunks/trunks_factory_for_test.h" using testing::_; using testing::DoAll; using testing::NiceMock; using testing::Return; using testing::SaveArg; using testing::SetArgPointee; namespace trunks { // A test fixture for TpmUtility tests. class TpmUtilityTest : public testing::Test { public: TpmUtilityTest() : utility_(factory_) {} ~TpmUtilityTest() override {} void SetUp() override { factory_.set_blob_parser(&mock_blob_parser_); factory_.set_tpm_state(&mock_tpm_state_); factory_.set_tpm(&mock_tpm_); factory_.set_hmac_session(&mock_hmac_session_); factory_.set_policy_session(&mock_policy_session_); } TPM_RC ComputeKeyName(const TPMT_PUBLIC& public_area, std::string* object_name) { return utility_.ComputeKeyName(public_area, object_name); } void SetNVRAMMap(uint32_t index, const TPMS_NV_PUBLIC& public_area) { utility_.nvram_public_area_map_[index] = public_area; } TPM_RC GetNVRAMMap(uint32_t index, TPMS_NV_PUBLIC* public_area) { auto it = utility_.nvram_public_area_map_.find(index); if (it == utility_.nvram_public_area_map_.end()) { return TPM_RC_FAILURE; } *public_area = it->second; return TPM_RC_SUCCESS; } TPM_RC SetKnownOwnerPassword(const std::string& owner_password) { return utility_.SetKnownOwnerPassword(owner_password); } TPM_RC CreateStorageRootKeys(const std::string& owner_password) { return utility_.CreateStorageRootKeys(owner_password); } TPM_RC CreateSaltingKey(const std::string& owner_password) { return utility_.CreateSaltingKey(owner_password); } void SetExistingKeyHandleExpectation(TPM_HANDLE handle) { TPMS_CAPABILITY_DATA capability_data = {}; TPML_HANDLE& handles = capability_data.data.handles; handles.count = 1; handles.handle[0] = handle; EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_HANDLES, handle, _, _, _, _)) .WillRepeatedly( DoAll(SetArgPointee<4>(capability_data), Return(TPM_RC_SUCCESS))); } void PopulatePCRSelection(bool has_sha1_pcrs, bool make_sha1_bank_empty, bool has_sha256_pcrs, TPML_PCR_SELECTION* pcrs) { memset(pcrs, 0, sizeof(TPML_PCR_SELECTION)); // By convention fill SHA-256 first. This is a bit brittle because order is // not important but it simplifies comparison to memcmp. if (has_sha256_pcrs) { pcrs->pcr_selections[pcrs->count].hash = TPM_ALG_SHA256; pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MIN; for (int i = 0; i < PCR_SELECT_MIN; ++i) { pcrs->pcr_selections[pcrs->count].pcr_select[i] = 0xff; } ++pcrs->count; } if (has_sha1_pcrs) { pcrs->pcr_selections[pcrs->count].hash = TPM_ALG_SHA1; if (make_sha1_bank_empty) { pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MAX; } else { pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MIN; for (int i = 0; i < PCR_SELECT_MIN; ++i) { pcrs->pcr_selections[pcrs->count].pcr_select[i] = 0xff; } } ++pcrs->count; } } void SetExistingPCRSExpectation(bool has_sha1_pcrs, bool has_sha256_pcrs) { TPMS_CAPABILITY_DATA capability_data = {}; TPML_PCR_SELECTION& pcrs = capability_data.data.assigned_pcr; PopulatePCRSelection(has_sha1_pcrs, false, has_sha256_pcrs, &pcrs); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_PCRS, _, _, _, _, _)) .WillRepeatedly( DoAll(SetArgPointee<4>(capability_data), Return(TPM_RC_SUCCESS))); } protected: TrunksFactoryForTest factory_; NiceMock<MockBlobParser> mock_blob_parser_; NiceMock<MockTpmState> mock_tpm_state_; NiceMock<MockTpm> mock_tpm_; NiceMock<MockAuthorizationDelegate> mock_authorization_delegate_; NiceMock<MockHmacSession> mock_hmac_session_; NiceMock<MockPolicySession> mock_policy_session_; TpmUtilityImpl utility_; }; TEST_F(TpmUtilityTest, StartupSuccess) { EXPECT_EQ(TPM_RC_SUCCESS, utility_.Startup()); } TEST_F(TpmUtilityTest, StartupAlreadyStarted) { EXPECT_CALL(mock_tpm_, StartupSync(_, _)) .WillRepeatedly(Return(TPM_RC_INITIALIZE)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Startup()); } TEST_F(TpmUtilityTest, StartupFailure) { EXPECT_CALL(mock_tpm_, StartupSync(_, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.Startup()); } TEST_F(TpmUtilityTest, StartupSelfTestFailure) { EXPECT_CALL(mock_tpm_, SelfTestSync(_, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.Startup()); } TEST_F(TpmUtilityTest, ClearSuccess) { EXPECT_EQ(TPM_RC_SUCCESS, utility_.Clear()); } TEST_F(TpmUtilityTest, ClearAfterBadInit) { EXPECT_CALL(mock_tpm_, ClearSync(_, _, _)) .WillOnce(Return(TPM_RC_AUTH_MISSING)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Clear()); } TEST_F(TpmUtilityTest, ClearFail) { EXPECT_CALL(mock_tpm_, ClearSync(_, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.Clear()); } TEST_F(TpmUtilityTest, ShutdownTest) { EXPECT_CALL(mock_tpm_, ShutdownSync(TPM_SU_CLEAR, _)); utility_.Shutdown(); } TEST_F(TpmUtilityTest, InitializeTpmAlreadyInit) { SetExistingPCRSExpectation(false, true); EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm()); EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm()); } TEST_F(TpmUtilityTest, InitializeTpmSuccess) { SetExistingPCRSExpectation(false, true); EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm()); } TEST_F(TpmUtilityTest, InitializeTpmBadAuth) { SetExistingPCRSExpectation(false, true); // Reject attempts to set platform auth. EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_PLATFORM, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.InitializeTpm()); } TEST_F(TpmUtilityTest, InitializeTpmDisablePHFails) { SetExistingPCRSExpectation(false, true); // Reject attempts to disable the platform hierarchy. EXPECT_CALL(mock_tpm_, HierarchyControlSync(_, _, TPM_RH_PLATFORM, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.InitializeTpm()); } TEST_F(TpmUtilityTest, AllocatePCRFromNone) { SetExistingPCRSExpectation(false, false); TPML_PCR_SELECTION new_pcr_allocation; EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation), SetArgPointee<3>(YES), Return(TPM_RC_SUCCESS))); ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR("")); ASSERT_EQ(1u, new_pcr_allocation.count); TPML_PCR_SELECTION expected_pcr_allocation; PopulatePCRSelection(false, false, true, &expected_pcr_allocation); ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation, sizeof(TPML_PCR_SELECTION))); } TEST_F(TpmUtilityTest, AllocatePCRFromSHA1Only) { SetExistingPCRSExpectation(true, false); TPML_PCR_SELECTION new_pcr_allocation; EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation), SetArgPointee<3>(YES), Return(TPM_RC_SUCCESS))); ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR("")); ASSERT_EQ(2u, new_pcr_allocation.count); TPML_PCR_SELECTION expected_pcr_allocation; PopulatePCRSelection(true, true, true, &expected_pcr_allocation); ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation, sizeof(TPML_PCR_SELECTION))); } TEST_F(TpmUtilityTest, AllocatePCRFromSHA1AndSHA256) { SetExistingPCRSExpectation(true, true); TPML_PCR_SELECTION new_pcr_allocation; EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation), SetArgPointee<3>(YES), Return(TPM_RC_SUCCESS))); ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR("")); ASSERT_EQ(1u, new_pcr_allocation.count); TPML_PCR_SELECTION expected_pcr_allocation; PopulatePCRSelection(true, true, false, &expected_pcr_allocation); ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation, sizeof(TPML_PCR_SELECTION))); } TEST_F(TpmUtilityTest, AllocatePCRFromSHA256Only) { SetExistingPCRSExpectation(false, true); EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _)) .Times(0); ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR("")); } TEST_F(TpmUtilityTest, AllocatePCRCommandFailure) { SetExistingPCRSExpectation(false, false); EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.AllocatePCR("")); } TEST_F(TpmUtilityTest, AllocatePCRTpmFailure) { SetExistingPCRSExpectation(false, false); EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<3>(NO), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_FAILURE, utility_.AllocatePCR("")); } TEST_F(TpmUtilityTest, TakeOwnershipSuccess) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, TakeOwnershipOwnershipDone) { EXPECT_EQ(TPM_RC_SUCCESS, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, TakeOwnershipBadSession) { EXPECT_CALL(mock_hmac_session_, StartUnboundSession(true)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, TakeOwnershipFailure) { EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, ChangeOwnerPasswordEndorsementDone) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, ChangeOwnerPasswordLockoutDone) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, ChangeOwnerPasswordEndorsementLockoutDone) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, ChangeOwnerPasswordEndorsementFail) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(_, _, _, _)) .WillRepeatedly(Return(TPM_RC_SUCCESS)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, ChangeOwnerPasswordLockoutFailure) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet()) .WillRepeatedly(Return(false)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(_, _, _, _)) .WillRepeatedly(Return(TPM_RC_SUCCESS)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.TakeOwnership("owner", "endorsement", "lockout")); } TEST_F(TpmUtilityTest, StirRandomSuccess) { std::string entropy_data("large test data", 100); EXPECT_EQ(TPM_RC_SUCCESS, utility_.StirRandom(entropy_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, StirRandomFails) { std::string entropy_data("test data"); EXPECT_CALL(mock_tpm_, StirRandomSync(_, nullptr)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.StirRandom(entropy_data, nullptr)); } TEST_F(TpmUtilityTest, GenerateRandomSuccess) { // This number is larger than the max bytes the GetRandom call can return. // Therefore we expect software to make multiple calls to fill this many // bytes. size_t num_bytes = 72; std::string random_data; TPM2B_DIGEST large_random; large_random.size = 32; TPM2B_DIGEST small_random; small_random.size = 8; EXPECT_CALL(mock_tpm_, GetRandomSync(_, _, &mock_authorization_delegate_)) .Times(2) .WillRepeatedly(DoAll(SetArgPointee<1>(large_random), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, GetRandomSync(8, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SetArgPointee<1>(small_random), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GenerateRandom( num_bytes, &mock_authorization_delegate_, &random_data)); EXPECT_EQ(num_bytes, random_data.size()); } TEST_F(TpmUtilityTest, GenerateRandomFails) { size_t num_bytes = 5; std::string random_data; EXPECT_CALL(mock_tpm_, GetRandomSync(_, _, nullptr)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GenerateRandom(num_bytes, nullptr, &random_data)); } TEST_F(TpmUtilityTest, ExtendPCRSuccess) { TPM_HANDLE pcr_handle = HR_PCR + 1; TPML_DIGEST_VALUES digests; EXPECT_CALL(mock_tpm_, PCR_ExtendSync(pcr_handle, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SaveArg<2>(&digests), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.ExtendPCR(1, "test digest", &mock_authorization_delegate_)); EXPECT_EQ(1u, digests.count); EXPECT_EQ(TPM_ALG_SHA256, digests.digests[0].hash_alg); std::string hash_string = crypto::SHA256HashString("test digest"); EXPECT_EQ(0, memcmp(hash_string.data(), digests.digests[0].digest.sha256, crypto::kSHA256Length)); } TEST_F(TpmUtilityTest, ExtendPCRFail) { int pcr_index = 0; TPM_HANDLE pcr_handle = HR_PCR + pcr_index; EXPECT_CALL(mock_tpm_, PCR_ExtendSync(pcr_handle, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ExtendPCR(pcr_index, "test digest", nullptr)); } TEST_F(TpmUtilityTest, ExtendPCRBadParam) { EXPECT_EQ(TPM_RC_FAILURE, utility_.ExtendPCR(-1, "test digest", nullptr)); } TEST_F(TpmUtilityTest, ReadPCRSuccess) { // The |pcr_index| is chosen to match the structure for |pcr_select|. // If you change |pcr_index|, remember to change |pcr_select|. int pcr_index = 1; std::string pcr_value; TPML_PCR_SELECTION pcr_select; pcr_select.count = 1; pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256; pcr_select.pcr_selections[0].sizeof_select = 1; pcr_select.pcr_selections[0].pcr_select[0] = 2; TPML_DIGEST pcr_values; pcr_values.count = 1; pcr_values.digests[0].size = 5; EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<2>(pcr_select), SetArgPointee<3>(pcr_values), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.ReadPCR(pcr_index, &pcr_value)); } TEST_F(TpmUtilityTest, ReadPCRFail) { std::string pcr_value; EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ReadPCR(1, &pcr_value)); } TEST_F(TpmUtilityTest, ReadPCRBadReturn) { std::string pcr_value; EXPECT_EQ(TPM_RC_FAILURE, utility_.ReadPCR(1, &pcr_value)); } TEST_F(TpmUtilityTest, AsymmetricEncryptSuccess) { TPM_HANDLE key_handle; std::string plaintext; std::string output_ciphertext("ciphertext"); std::string ciphertext; TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_ciphertext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_EncryptSync(key_handle, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SetArgPointee<5>(out_message), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricEncrypt( key_handle, TPM_ALG_NULL, TPM_ALG_NULL, plaintext, &mock_authorization_delegate_, &ciphertext)); EXPECT_EQ(0, ciphertext.compare(output_ciphertext)); } TEST_F(TpmUtilityTest, AsymmetricEncryptFail) { TPM_HANDLE key_handle; std::string plaintext; std::string ciphertext; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_EncryptSync(key_handle, _, _, _, _, _, nullptr)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, plaintext, nullptr, &ciphertext)); } TEST_F(TpmUtilityTest, AsymmetricEncryptBadParams) { TPM_HANDLE key_handle = TPM_RH_FIRST; std::string plaintext; std::string ciphertext; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt | kRestricted; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, nullptr)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.AsymmetricEncrypt(key_handle, TPM_ALG_RSAES, TPM_ALG_NULL, plaintext, nullptr, &ciphertext)); } TEST_F(TpmUtilityTest, AsymmetricEncryptNullSchemeForward) { TPM_HANDLE key_handle; std::string plaintext; std::string output_ciphertext("ciphertext"); std::string ciphertext; TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_ciphertext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; TPMT_RSA_DECRYPT scheme; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_EncryptSync(key_handle, _, _, _, _, _, nullptr)) .WillOnce(DoAll(SetArgPointee<5>(out_message), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, plaintext, nullptr, &ciphertext)); EXPECT_EQ(scheme.scheme, TPM_ALG_OAEP); EXPECT_EQ(scheme.details.oaep.hash_alg, TPM_ALG_SHA256); } TEST_F(TpmUtilityTest, AsymmetricEncryptSchemeForward) { TPM_HANDLE key_handle; std::string plaintext; std::string output_ciphertext("ciphertext"); std::string ciphertext; TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_ciphertext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; TPMT_RSA_DECRYPT scheme; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_EncryptSync(key_handle, _, _, _, _, _, nullptr)) .WillOnce(DoAll(SetArgPointee<5>(out_message), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricEncrypt(key_handle, TPM_ALG_RSAES, TPM_ALG_NULL, plaintext, nullptr, &ciphertext)); EXPECT_EQ(scheme.scheme, TPM_ALG_RSAES); } TEST_F(TpmUtilityTest, AsymmetricDecryptSuccess) { TPM_HANDLE key_handle; std::string plaintext; std::string output_plaintext("plaintext"); std::string ciphertext; std::string password("password"); TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_plaintext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_DecryptSync(key_handle, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SetArgPointee<5>(out_message), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_NULL, TPM_ALG_NULL, ciphertext, &mock_authorization_delegate_, &plaintext)); EXPECT_EQ(0, plaintext.compare(output_plaintext)); } TEST_F(TpmUtilityTest, AsymmetricDecryptFail) { TPM_HANDLE key_handle; std::string key_name; std::string plaintext; std::string ciphertext; std::string password; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_DecryptSync(key_handle, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_NULL, TPM_ALG_NULL, ciphertext, &mock_authorization_delegate_, &plaintext)); } TEST_F(TpmUtilityTest, AsymmetricDecryptBadParams) { TPM_HANDLE key_handle = TPM_RH_FIRST; std::string plaintext; std::string ciphertext; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt | kRestricted; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_RSAES, TPM_ALG_NULL, ciphertext, &mock_authorization_delegate_, &plaintext)); } TEST_F(TpmUtilityTest, AsymmetricDecryptBadSession) { TPM_HANDLE key_handle = TPM_RH_FIRST; std::string key_name; std::string plaintext; std::string ciphertext; std::string password; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_RSAES, TPM_ALG_NULL, ciphertext, nullptr, &plaintext)); } TEST_F(TpmUtilityTest, AsymmetricDecryptNullSchemeForward) { TPM_HANDLE key_handle; std::string plaintext; std::string output_plaintext("plaintext"); std::string ciphertext; std::string password; TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_plaintext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; TPMT_RSA_DECRYPT scheme; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_DecryptSync(key_handle, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<5>(out_message), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_NULL, TPM_ALG_NULL, ciphertext, &mock_authorization_delegate_, &plaintext)); EXPECT_EQ(scheme.scheme, TPM_ALG_OAEP); EXPECT_EQ(scheme.details.oaep.hash_alg, TPM_ALG_SHA256); } TEST_F(TpmUtilityTest, AsymmetricDecryptSchemeForward) { TPM_HANDLE key_handle; std::string plaintext; std::string output_plaintext("plaintext"); std::string ciphertext; std::string password; TPM2B_PUBLIC_KEY_RSA out_message = Make_TPM2B_PUBLIC_KEY_RSA( output_plaintext); TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; TPMT_RSA_DECRYPT scheme; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, RSA_DecryptSync(key_handle, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<5>(out_message), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.AsymmetricDecrypt( key_handle, TPM_ALG_RSAES, TPM_ALG_NULL, ciphertext, &mock_authorization_delegate_, &plaintext)); EXPECT_EQ(scheme.scheme, TPM_ALG_RSAES); } TEST_F(TpmUtilityTest, SignSuccess) { TPM_HANDLE key_handle; std::string password("password"); std::string digest(32, 'a'); TPMT_SIGNATURE signature_out; signature_out.signature.rsassa.sig.size = 2; signature_out.signature.rsassa.sig.buffer[0] = 'h'; signature_out.signature.rsassa.sig.buffer[1] = 'i'; std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, SignSync(key_handle, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SetArgPointee<5>(signature_out), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Sign(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); EXPECT_EQ(0, signature.compare("hi")); } TEST_F(TpmUtilityTest, SignFail) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, SignSync(key_handle, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.Sign(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignBadParams1) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign | kRestricted; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignBadAuthorizationSession) { TPM_HANDLE key_handle = TPM_RH_FIRST; std::string password; std::string digest(32, 'a'); std::string signature; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_NULL, digest, nullptr, &signature)); } TEST_F(TpmUtilityTest, SignBadParams2) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignBadParams3) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_ECC; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignBadParams4) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_FAILURE))); EXPECT_EQ(TPM_RC_FAILURE, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignBadParams5) { TPM_HANDLE key_handle = 0; std::string password; std::string digest(32, 'a'); std::string signature; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Sign(key_handle, TPM_ALG_AES, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); } TEST_F(TpmUtilityTest, SignNullSchemeForward) { TPM_HANDLE key_handle; std::string password; std::string digest(32, 'a'); TPMT_SIGNATURE signature_out; signature_out.signature.rsassa.sig.size = 0; std::string signature; TPM2B_PUBLIC public_area; TPMT_SIG_SCHEME scheme; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, SignSync(key_handle, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<5>(signature_out), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Sign(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, &mock_authorization_delegate_, &signature)); EXPECT_EQ(scheme.scheme, TPM_ALG_RSASSA); EXPECT_EQ(scheme.details.rsassa.hash_alg, TPM_ALG_SHA256); } TEST_F(TpmUtilityTest, SignSchemeForward) { TPM_HANDLE key_handle; std::string password; std::string digest(64, 'a'); TPMT_SIGNATURE signature_out; signature_out.signature.rsassa.sig.size = 0; std::string signature; TPM2B_PUBLIC public_area; TPMT_SIG_SCHEME scheme; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, SignSync(key_handle, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<5>(signature_out), SaveArg<3>(&scheme), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Sign(key_handle, TPM_ALG_RSAPSS, TPM_ALG_SHA1, digest, &mock_authorization_delegate_, &signature)); EXPECT_EQ(scheme.scheme, TPM_ALG_RSAPSS); EXPECT_EQ(scheme.details.rsapss.hash_alg, TPM_ALG_SHA1); } TEST_F(TpmUtilityTest, VerifySuccess) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, VerifySignatureSync(key_handle, _, _, _, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyFail) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, VerifySignatureSync(key_handle, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyBadParams1) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign | kRestricted; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyBadParams2) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kDecrypt; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyBadParams3) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_ECC; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyBadParams4) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_FAILURE))); EXPECT_EQ(TPM_RC_FAILURE, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyBadParams5) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.Verify(key_handle, TPM_ALG_AES, TPM_ALG_NULL, digest, signature, nullptr)); } TEST_F(TpmUtilityTest, VerifyNullSchemeForward) { TPM_HANDLE key_handle; std::string digest(32, 'a'); std::string signature; TPM2B_PUBLIC public_area; TPMT_SIGNATURE signature_in; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, VerifySignatureSync(key_handle, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&signature_in), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Verify(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, digest, signature, nullptr)); EXPECT_EQ(signature_in.sig_alg, TPM_ALG_RSASSA); EXPECT_EQ(signature_in.signature.rsassa.hash, TPM_ALG_SHA256); } TEST_F(TpmUtilityTest, VerifySchemeForward) { TPM_HANDLE key_handle; std::string digest(64, 'a'); std::string signature; TPM2B_PUBLIC public_area; TPMT_SIGNATURE signature_in; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.object_attributes = kSign; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, VerifySignatureSync(key_handle, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&signature_in), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.Verify(key_handle, TPM_ALG_RSAPSS, TPM_ALG_SHA1, digest, signature, nullptr)); EXPECT_EQ(signature_in.sig_alg, TPM_ALG_RSAPSS); EXPECT_EQ(signature_in.signature.rsassa.hash, TPM_ALG_SHA1); } TEST_F(TpmUtilityTest, CertifyCreationSuccess) { TPM_HANDLE key_handle = 42; std::string creation_blob; EXPECT_CALL(mock_tpm_, CertifyCreationSyncShort(TPM_RH_NULL, key_handle, _, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.CertifyCreation(key_handle, creation_blob)); } TEST_F(TpmUtilityTest, CertifyCreationParserError) { TPM_HANDLE key_handle = 42; std::string creation_blob; EXPECT_CALL(mock_blob_parser_, ParseCreationBlob(creation_blob, _, _, _)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.CertifyCreation(key_handle, creation_blob)); } TEST_F(TpmUtilityTest, CertifyCreationFailure) { TPM_HANDLE key_handle = 42; std::string creation_blob; EXPECT_CALL(mock_tpm_, CertifyCreationSyncShort(TPM_RH_NULL, key_handle, _, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.CertifyCreation(key_handle, creation_blob)); } TEST_F(TpmUtilityTest, ChangeAuthDataSuccess) { TPM_HANDLE key_handle = 1; std::string new_password; std::string key_blob; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.ChangeKeyAuthorizationData( key_handle, new_password, &mock_authorization_delegate_, &key_blob)); } TEST_F(TpmUtilityTest, ChangeAuthDataKeyNameFail) { TPM_HANDLE key_handle = 1; std::string old_password; std::string new_password; EXPECT_CALL(mock_tpm_, ReadPublicSync(key_handle, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ChangeKeyAuthorizationData( key_handle, new_password, &mock_authorization_delegate_, nullptr)); } TEST_F(TpmUtilityTest, ChangeAuthDataFailure) { TPM_HANDLE key_handle = 1; std::string new_password; EXPECT_CALL(mock_tpm_, ObjectChangeAuthSync(key_handle, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ChangeKeyAuthorizationData( key_handle, new_password, &mock_authorization_delegate_, nullptr)); } TEST_F(TpmUtilityTest, ChangeAuthDataParserFail) { TPM_HANDLE key_handle = 1; std::string new_password; std::string key_blob; TPM2B_PUBLIC public_area; public_area.public_area.type = TPM_ALG_RSA; public_area.public_area.auth_policy.size = 0; public_area.public_area.unique.rsa.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_area), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_blob_parser_, SerializeKeyBlob(_, _, &key_blob)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.ChangeKeyAuthorizationData( key_handle, new_password, &mock_authorization_delegate_, &key_blob)); } TEST_F(TpmUtilityTest, ImportRSAKeySuccess) { uint32_t public_exponent = 0x10001; std::string modulus(256, 'a'); std::string prime_factor(128, 'b'); std::string password("password"); std::string key_blob; TPM2B_DATA encryption_key; TPM2B_PUBLIC public_data; TPM2B_PRIVATE private_data; EXPECT_CALL(mock_tpm_, ImportSync(_, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<2>(&encryption_key), SaveArg<3>(&public_data), SaveArg<4>(&private_data), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.ImportRSAKey( TpmUtility::AsymmetricKeyUsage::kDecryptKey, modulus, public_exponent, prime_factor, password, &mock_authorization_delegate_, &key_blob)); // Validate that the public area was properly constructed. EXPECT_EQ(public_data.public_area.parameters.rsa_detail.key_bits, modulus.size() * 8); EXPECT_EQ(public_data.public_area.parameters.rsa_detail.exponent, public_exponent); EXPECT_EQ(public_data.public_area.unique.rsa.size, modulus.size()); EXPECT_EQ(0, memcmp(public_data.public_area.unique.rsa.buffer, modulus.data(), modulus.size())); // Validate the private struct construction. EXPECT_EQ(kAesKeySize, encryption_key.size); AES_KEY key; AES_set_encrypt_key(encryption_key.buffer, kAesKeySize * 8, &key); unsigned char iv[MAX_AES_BLOCK_SIZE_BYTES] = {0}; int iv_in = 0; std::string unencrypted_private(private_data.size, 0); AES_cfb128_encrypt( reinterpret_cast<const unsigned char*>(private_data.buffer), reinterpret_cast<unsigned char*>(string_as_array(&unencrypted_private)), private_data.size, &key, iv, &iv_in, AES_DECRYPT); TPM2B_DIGEST inner_integrity; EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPM2B_DIGEST(&unencrypted_private, &inner_integrity, nullptr)); std::string object_name; EXPECT_EQ(TPM_RC_SUCCESS, ComputeKeyName(public_data.public_area, &object_name)); std::string integrity_value = crypto::SHA256HashString(unencrypted_private + object_name); EXPECT_EQ(integrity_value.size(), inner_integrity.size); EXPECT_EQ(0, memcmp(inner_integrity.buffer, integrity_value.data(), inner_integrity.size)); TPM2B_SENSITIVE sensitive_data; EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPM2B_SENSITIVE(&unencrypted_private, &sensitive_data, nullptr)); EXPECT_EQ(sensitive_data.sensitive_area.auth_value.size, password.size()); EXPECT_EQ(0, memcmp(sensitive_data.sensitive_area.auth_value.buffer, password.data(), password.size())); EXPECT_EQ(sensitive_data.sensitive_area.sensitive.rsa.size, prime_factor.size()); EXPECT_EQ(0, memcmp(sensitive_data.sensitive_area.sensitive.rsa.buffer, prime_factor.data(), prime_factor.size())); } TEST_F(TpmUtilityTest, ImportRSAKeySuccessWithNoBlob) { uint32_t public_exponent = 0x10001; std::string modulus(256, 'a'); std::string prime_factor(128, 'b'); std::string password; EXPECT_EQ(TPM_RC_SUCCESS, utility_.ImportRSAKey( TpmUtility::AsymmetricKeyUsage::kDecryptKey, modulus, public_exponent, prime_factor, password, &mock_authorization_delegate_, nullptr)); } TEST_F(TpmUtilityTest, ImportRSAKeyParentNameFail) { uint32_t public_exponent = 0x10001; std::string modulus(256, 'a'); std::string prime_factor(128, 'b'); std::string password; EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ImportRSAKey( TpmUtility::AsymmetricKeyUsage::kDecryptKey, modulus, public_exponent, prime_factor, password, &mock_authorization_delegate_, nullptr)); } TEST_F(TpmUtilityTest, ImportRSAKeyFail) { std::string modulus; std::string prime_factor; std::string password; EXPECT_CALL(mock_tpm_, ImportSync(_, _, _, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ImportRSAKey( TpmUtility::AsymmetricKeyUsage::kDecryptKey, modulus, 0x10001, prime_factor, password, &mock_authorization_delegate_, nullptr)); } TEST_F(TpmUtilityTest, ImportRSAKeyParserFail) { std::string modulus; std::string prime_factor; std::string password; std::string key_blob; EXPECT_CALL(mock_blob_parser_, SerializeKeyBlob(_, _, &key_blob)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.ImportRSAKey( TpmUtility::AsymmetricKeyUsage::kDecryptKey, modulus, 0x10001, prime_factor, password, &mock_authorization_delegate_, &key_blob)); } TEST_F(TpmUtilityTest, CreateRSAKeyPairSuccess) { TPM2B_PUBLIC public_area; TPML_PCR_SELECTION creation_pcrs; EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SaveArg<2>(&public_area), SaveArg<3>(&creation_pcrs), Return(TPM_RC_SUCCESS))); std::string key_blob; std::string creation_blob; int creation_pcr = 12; EXPECT_EQ(TPM_RC_SUCCESS, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, "password", "", false, creation_pcr, &mock_authorization_delegate_, &key_blob, &creation_blob)); EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, kDecrypt); EXPECT_EQ(public_area.public_area.object_attributes & kSign, kSign); EXPECT_EQ(public_area.public_area.object_attributes & kUserWithAuth, kUserWithAuth); EXPECT_EQ(public_area.public_area.object_attributes & kAdminWithPolicy, 0u); EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme, TPM_ALG_NULL); EXPECT_EQ(1u, creation_pcrs.count); EXPECT_EQ(TPM_ALG_SHA256, creation_pcrs.pcr_selections[0].hash); EXPECT_EQ(PCR_SELECT_MIN, creation_pcrs.pcr_selections[0].sizeof_select); EXPECT_EQ(1u << (creation_pcr % 8), creation_pcrs.pcr_selections[0].pcr_select[creation_pcr / 8]); } TEST_F(TpmUtilityTest, CreateRSAKeyPairDecryptKeySuccess) { TPM2B_PUBLIC public_area; EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SaveArg<2>(&public_area), Return(TPM_RC_SUCCESS))); std::string key_blob; EXPECT_EQ(TPM_RC_SUCCESS, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "password", "", false, kNoCreationPCR, &mock_authorization_delegate_, &key_blob, nullptr)); EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, kDecrypt); EXPECT_EQ(public_area.public_area.object_attributes & kSign, 0u); EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme, TPM_ALG_NULL); } TEST_F(TpmUtilityTest, CreateRSAKeyPairSignKeySuccess) { TPM2B_PUBLIC public_area; TPM2B_SENSITIVE_CREATE sensitive_create; EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SaveArg<1>(&sensitive_create), SaveArg<2>(&public_area), Return(TPM_RC_SUCCESS))); std::string key_blob; std::string policy_digest(32, 'a'); std::string key_auth("password"); EXPECT_EQ(TPM_RC_SUCCESS, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, key_auth, policy_digest, true /* use_only_policy_authorization */, kNoCreationPCR, &mock_authorization_delegate_, &key_blob, nullptr)); EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, 0u); EXPECT_EQ(public_area.public_area.object_attributes & kSign, kSign); EXPECT_EQ(public_area.public_area.object_attributes & kUserWithAuth, 0u); EXPECT_EQ(public_area.public_area.object_attributes & kAdminWithPolicy, kAdminWithPolicy); EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme, TPM_ALG_NULL); EXPECT_EQ(public_area.public_area.parameters.rsa_detail.key_bits, 2048); EXPECT_EQ(public_area.public_area.parameters.rsa_detail.exponent, 0x10001u); EXPECT_EQ(public_area.public_area.auth_policy.size, policy_digest.size()); EXPECT_EQ(0, memcmp(public_area.public_area.auth_policy.buffer, policy_digest.data(), policy_digest.size())); EXPECT_EQ(sensitive_create.sensitive.user_auth.size, key_auth.size()); EXPECT_EQ(0, memcmp(sensitive_create.sensitive.user_auth.buffer, key_auth.data(), key_auth.size())); } TEST_F(TpmUtilityTest, CreateRSAKeyPairBadDelegate) { std::string key_blob; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "password", "", false, kNoCreationPCR, nullptr, &key_blob, nullptr)); } TEST_F(TpmUtilityTest, CreateRSAKeyPairFailure) { EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(Return(TPM_RC_FAILURE)); std::string key_blob; EXPECT_EQ(TPM_RC_FAILURE, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, "password", "", false, kNoCreationPCR, &mock_authorization_delegate_, &key_blob, nullptr)); } TEST_F(TpmUtilityTest, CreateRSAKeyPairKeyParserFail) { std::string key_blob; EXPECT_CALL(mock_blob_parser_, SerializeKeyBlob(_, _, &key_blob)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, "password", "", false, kNoCreationPCR, &mock_authorization_delegate_, &key_blob, nullptr)); } TEST_F(TpmUtilityTest, CreateRSAKeyPairCreationParserFail) { std::string creation_blob; std::string key_blob; EXPECT_CALL(mock_blob_parser_, SerializeCreationBlob(_, _, _, &creation_blob)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.CreateRSAKeyPair( TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, "password", "", false, kNoCreationPCR, &mock_authorization_delegate_, &key_blob, &creation_blob)); } TEST_F(TpmUtilityTest, LoadKeySuccess) { TPM_HANDLE key_handle = TPM_RH_FIRST; TPM_HANDLE loaded_handle; EXPECT_CALL(mock_tpm_, LoadSync(kRSAStorageRootKey, _, _, _, _, _, &mock_authorization_delegate_)) .WillOnce(DoAll(SetArgPointee<4>(key_handle), Return(TPM_RC_SUCCESS))); std::string key_blob; EXPECT_EQ(TPM_RC_SUCCESS, utility_.LoadKey( key_blob, &mock_authorization_delegate_, &loaded_handle)); EXPECT_EQ(loaded_handle, key_handle); } TEST_F(TpmUtilityTest, LoadKeyFailure) { TPM_HANDLE key_handle; EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); std::string key_blob; EXPECT_EQ(TPM_RC_FAILURE, utility_.LoadKey( key_blob, &mock_authorization_delegate_, &key_handle)); } TEST_F(TpmUtilityTest, LoadKeyBadDelegate) { TPM_HANDLE key_handle; std::string key_blob; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.LoadKey( key_blob, nullptr, &key_handle)); } TEST_F(TpmUtilityTest, LoadKeyParserFail) { TPM_HANDLE key_handle; std::string key_blob; EXPECT_CALL(mock_blob_parser_, ParseKeyBlob(key_blob, _, _)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.LoadKey( key_blob, &mock_authorization_delegate_, &key_handle)); } TEST_F(TpmUtilityTest, SealedDataSuccess) { std::string data_to_seal("seal_data"); std::string sealed_data; TPM2B_SENSITIVE_CREATE sensitive_create; TPM2B_PUBLIC in_public; EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<1>(&sensitive_create), SaveArg<2>(&in_public), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.SealData( data_to_seal, "", &mock_authorization_delegate_, &sealed_data)); EXPECT_EQ(sensitive_create.sensitive.data.size, data_to_seal.size()); EXPECT_EQ(0, memcmp(sensitive_create.sensitive.data.buffer, data_to_seal.data(), data_to_seal.size())); EXPECT_EQ(in_public.public_area.type, TPM_ALG_KEYEDHASH); EXPECT_EQ(in_public.public_area.name_alg, TPM_ALG_SHA256); } TEST_F(TpmUtilityTest, SealDataBadDelegate) { std::string data_to_seal("seal_data"); std::string sealed_data; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.SealData( data_to_seal, "", nullptr, &sealed_data)); } TEST_F(TpmUtilityTest, SealDataFailure) { std::string data_to_seal("seal_data"); std::string sealed_data; EXPECT_CALL(mock_tpm_, CreateSyncShort(kRSAStorageRootKey, _, _, _, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.SealData( data_to_seal, "", &mock_authorization_delegate_, &sealed_data)); } TEST_F(TpmUtilityTest, SealDataParserFail) { std::string data_to_seal("seal_data"); std::string sealed_data; EXPECT_CALL(mock_blob_parser_, SerializeKeyBlob(_, _, &sealed_data)) .WillOnce(Return(false)); EXPECT_EQ(SAPI_RC_BAD_TCTI_STRUCTURE, utility_.SealData( data_to_seal, "", &mock_authorization_delegate_, &sealed_data)); } TEST_F(TpmUtilityTest, UnsealDataSuccess) { std::string sealed_data; std::string tpm_unsealed_data("password"); std::string unsealed_data; TPM_HANDLE object_handle = 42; TPM2B_PUBLIC public_data; public_data.public_area.auth_policy.size = 0; EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_data), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, ReadPublicSync(object_handle, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(public_data), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<4>(object_handle), Return(TPM_RC_SUCCESS))); TPM2B_SENSITIVE_DATA out_data = Make_TPM2B_SENSITIVE_DATA(tpm_unsealed_data); EXPECT_CALL(mock_tpm_, UnsealSync(object_handle, _, _, _)) .WillOnce(DoAll(SetArgPointee<2>(out_data), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.UnsealData( sealed_data, &mock_authorization_delegate_, &unsealed_data)); EXPECT_EQ(unsealed_data, tpm_unsealed_data); } TEST_F(TpmUtilityTest, UnsealDataBadDelegate) { std::string sealed_data; std::string unsealed_data; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.UnsealData( sealed_data, nullptr, &unsealed_data)); } TEST_F(TpmUtilityTest, UnsealDataLoadFail) { std::string sealed_data; std::string unsealed_data; EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.UnsealData( sealed_data, &mock_authorization_delegate_, &unsealed_data)); } TEST_F(TpmUtilityTest, UnsealDataBadKeyName) { std::string sealed_data; std::string unsealed_data; EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.UnsealData( sealed_data, &mock_authorization_delegate_, &unsealed_data)); } TEST_F(TpmUtilityTest, UnsealObjectFailure) { std::string sealed_data; std::string unsealed_data; EXPECT_CALL(mock_tpm_, UnsealSync(_, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.UnsealData( sealed_data, &mock_authorization_delegate_, &unsealed_data)); } TEST_F(TpmUtilityTest, StartSessionSuccess) { EXPECT_CALL(mock_hmac_session_, StartUnboundSession(true)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.StartSession(&mock_hmac_session_)); } TEST_F(TpmUtilityTest, StartSessionFailure) { EXPECT_CALL(mock_hmac_session_, StartUnboundSession(true)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.StartSession(&mock_hmac_session_)); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValueSuccess) { int index = 5; std::string pcr_value("pcr_value"); std::string policy_digest; TPML_PCR_SELECTION pcr_select; pcr_select.count = 1; pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256; pcr_select.pcr_selections[0].sizeof_select = 1; pcr_select.pcr_selections[0].pcr_select[index / 8] = 1 << (index % 8); TPML_DIGEST pcr_values; pcr_values.count = 1; pcr_values.digests[0] = Make_TPM2B_DIGEST(pcr_value); EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _)) .WillOnce(DoAll(SetArgPointee<2>(pcr_select), SetArgPointee<3>(pcr_values), Return(TPM_RC_SUCCESS))); std::string tpm_pcr_value; EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _)) .WillOnce(DoAll(SaveArg<1>(&tpm_pcr_value), Return(TPM_RC_SUCCESS))); std::string tpm_policy_digest("digest"); EXPECT_CALL(mock_policy_session_, GetDigest(_)) .WillOnce(DoAll(SetArgPointee<0>(tpm_policy_digest), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetPolicyDigestForPcrValue(index, "", &policy_digest)); EXPECT_EQ(policy_digest, tpm_policy_digest); EXPECT_EQ(pcr_value, tpm_pcr_value); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValueSuccessWithPcrValue) { int index = 5; std::string pcr_value("pcr_value"); std::string policy_digest; std::string tpm_pcr_value; EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _)) .WillOnce(DoAll(SaveArg<1>(&tpm_pcr_value), Return(TPM_RC_SUCCESS))); std::string tpm_policy_digest("digest"); EXPECT_CALL(mock_policy_session_, GetDigest(_)) .WillOnce(DoAll(SetArgPointee<0>(tpm_policy_digest), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetPolicyDigestForPcrValue(index, pcr_value, &policy_digest)); EXPECT_EQ(policy_digest, tpm_policy_digest); EXPECT_EQ(pcr_value, tpm_pcr_value); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValueBadSession) { int index = 5; std::string pcr_value("value"); std::string policy_digest; EXPECT_CALL(mock_policy_session_, StartUnboundSession(false)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(index, pcr_value, &policy_digest)); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValuePcrReadFail) { int index = 5; std::string policy_digest; EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(index, "", &policy_digest)); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValueBadPcr) { int index = 5; std::string pcr_value("value"); std::string policy_digest; EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(index, pcr_value, &policy_digest)); } TEST_F(TpmUtilityTest, GetPolicyDigestForPcrValueBadDigest) { int index = 5; std::string pcr_value("value"); std::string policy_digest; EXPECT_CALL(mock_policy_session_, GetDigest(&policy_digest)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(index, pcr_value, &policy_digest)); } TEST_F(TpmUtilityTest, DefineNVSpaceSuccess) { uint32_t index = 59; uint32_t nvram_index = NV_INDEX_FIRST + index; size_t length = 256; TPM2B_NV_PUBLIC public_data; EXPECT_CALL(mock_tpm_, NV_DefineSpaceSync(TPM_RH_OWNER, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&public_data), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, utility_.DefineNVSpace( index, length, &mock_authorization_delegate_)); EXPECT_EQ(public_data.nv_public.nv_index, nvram_index); EXPECT_EQ(public_data.nv_public.name_alg, TPM_ALG_SHA256); EXPECT_EQ(public_data.nv_public.attributes, TPMA_NV_NO_DA | TPMA_NV_OWNERWRITE | TPMA_NV_WRITEDEFINE | TPMA_NV_AUTHREAD); EXPECT_EQ(public_data.nv_public.data_size, length); } TEST_F(TpmUtilityTest, DefineNVSpaceBadLength) { size_t bad_length = 3000; EXPECT_EQ(SAPI_RC_BAD_SIZE, utility_.DefineNVSpace(0, bad_length, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, DefineNVSpaceBadIndex) { uint32_t bad_index = 1<<29; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.DefineNVSpace(bad_index, 2, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, DefineNVSpaceBadSession) { EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.DefineNVSpace(0, 2, nullptr)); } TEST_F(TpmUtilityTest, DefineNVSpaceFail) { uint32_t index = 59; size_t length = 256; EXPECT_CALL(mock_tpm_, NV_DefineSpaceSync(TPM_RH_OWNER, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.DefineNVSpace(index, length, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, DestroyNVSpaceSuccess) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_UndefineSpaceSync(TPM_RH_OWNER, _, nvram_index, _, _)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.DestroyNVSpace(index, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, DestroyNVSpaceBadIndex) { uint32_t bad_index = 1<<29; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.DestroyNVSpace(bad_index, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, DestroyNVSpaceBadSession) { EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.DestroyNVSpace(3, nullptr)); } TEST_F(TpmUtilityTest, DestroyNVSpaceFailure) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_UndefineSpaceSync(TPM_RH_OWNER, _, nvram_index, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.DestroyNVSpace(index, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, LockNVSpaceSuccess) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.LockNVSpace(index, &mock_authorization_delegate_)); TPMS_NV_PUBLIC public_area; EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area)); EXPECT_EQ(public_area.attributes & TPMA_NV_WRITELOCKED, TPMA_NV_WRITELOCKED); } TEST_F(TpmUtilityTest, LockNVSpaceBadIndex) { uint32_t bad_index = 1<<24; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.LockNVSpace(bad_index, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, LockNVSpaceBadSession) { EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.LockNVSpace(52, nullptr)); } TEST_F(TpmUtilityTest, LockNVSpaceFailure) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.LockNVSpace(index, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, WriteNVSpaceSuccess) { uint32_t index = 53; uint32_t offset = 5; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_WriteSync(TPM_RH_OWNER, _, nvram_index, _, _, offset, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.WriteNVSpace( index, offset, "", &mock_authorization_delegate_)); TPMS_NV_PUBLIC public_area; EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area)); EXPECT_EQ(public_area.attributes & TPMA_NV_WRITTEN, TPMA_NV_WRITTEN); } TEST_F(TpmUtilityTest, WriteNVSpaceBadSize) { uint32_t index = 53; std::string nvram_data(1025, 0); EXPECT_EQ(SAPI_RC_BAD_SIZE, utility_.WriteNVSpace( index, 0, nvram_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, WriteNVSpaceBadIndex) { uint32_t bad_index = 1<<24; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.WriteNVSpace( bad_index, 0, "", &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, WriteNVSpaceBadSessions) { EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.WriteNVSpace(53, 0, "", nullptr)); } TEST_F(TpmUtilityTest, WriteNVSpaceFailure) { uint32_t index = 53; uint32_t offset = 5; uint32_t nvram_index = NV_INDEX_FIRST + index; EXPECT_CALL(mock_tpm_, NV_WriteSync(TPM_RH_OWNER, _, nvram_index, _, _, offset, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.WriteNVSpace( index, offset, "", &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, ReadNVSpaceSuccess) { uint32_t index = 53; uint32_t offset = 5; uint32_t nv_index = NV_INDEX_FIRST + index; size_t length = 24; std::string nvram_data; EXPECT_CALL(mock_tpm_, NV_ReadSync(nv_index, _, nv_index, _, length, offset, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.ReadNVSpace( index, offset, length, &nvram_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, ReadNVSpaceBadReadLength) { size_t length = 1025; std::string nvram_data; EXPECT_EQ(SAPI_RC_BAD_SIZE, utility_.ReadNVSpace( 52, 0, length, &nvram_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, ReadNVSpaceBadIndex) { uint32_t bad_index = 1<<24; std::string nvram_data; EXPECT_EQ(SAPI_RC_BAD_PARAMETER, utility_.ReadNVSpace( bad_index, 0, 5, &nvram_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, ReadNVSpaceBadSession) { std::string nvram_data; EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.ReadNVSpace(53, 0, 5, &nvram_data, nullptr)); } TEST_F(TpmUtilityTest, ReadNVSpaceFailure) { uint32_t index = 53; uint32_t offset = 5; uint32_t nv_index = NV_INDEX_FIRST + index; size_t length = 24; std::string nvram_data; EXPECT_CALL(mock_tpm_, NV_ReadSync(nv_index, _, nv_index, _, length, offset, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.ReadNVSpace( index, offset, length, &nvram_data, &mock_authorization_delegate_)); } TEST_F(TpmUtilityTest, GetNVSpaceNameSuccess) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; std::string name; EXPECT_CALL(mock_tpm_, NV_ReadPublicSync(nvram_index, _, _, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetNVSpaceName(index, &name)); } TEST_F(TpmUtilityTest, GetNVSpaceNameFailure) { uint32_t index = 53; std::string name; EXPECT_CALL(mock_tpm_, NV_ReadPublicSync(_, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetNVSpaceName(index, &name)); } TEST_F(TpmUtilityTest, GetNVSpacePublicAreaCachedSuccess) { uint32_t index = 53; TPMS_NV_PUBLIC public_area; SetNVRAMMap(index, public_area); EXPECT_CALL(mock_tpm_, NV_ReadPublicSync(_, _, _, _, _)) .Times(0); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetNVSpacePublicArea(index, &public_area)); } TEST_F(TpmUtilityTest, GetNVSpacePublicAreaSuccess) { uint32_t index = 53; uint32_t nvram_index = NV_INDEX_FIRST + index; TPMS_NV_PUBLIC public_area; EXPECT_CALL(mock_tpm_, NV_ReadPublicSync(nvram_index, _, _, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetNVSpacePublicArea(index, &public_area)); } TEST_F(TpmUtilityTest, GetNVSpacePublicAreaFailure) { uint32_t index = 53; TPMS_NV_PUBLIC public_area; EXPECT_CALL(mock_tpm_, NV_ReadPublicSync(_, _, _, _, _)) .WillOnce(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, utility_.GetNVSpacePublicArea(index, &public_area)); } TEST_F(TpmUtilityTest, SetKnownPasswordSuccess) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillOnce(Return(false)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _)) .WillOnce(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, SetKnownOwnerPassword("password")); } TEST_F(TpmUtilityTest, SetKnownPasswordOwnershipDone) { EXPECT_EQ(TPM_RC_SUCCESS, SetKnownOwnerPassword("password")); } TEST_F(TpmUtilityTest, SetKnownPasswordFailure) { EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet()) .WillOnce(Return(false)); EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, SetKnownOwnerPassword("password")); } TEST_F(TpmUtilityTest, RootKeysSuccess) { EXPECT_EQ(TPM_RC_SUCCESS, CreateStorageRootKeys("password")); } TEST_F(TpmUtilityTest, RootKeysHandleConsistency) { TPM_HANDLE test_handle = 42; EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<3>(test_handle), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, test_handle, _, _, _)) .WillRepeatedly(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, CreateStorageRootKeys("password")); } TEST_F(TpmUtilityTest, RootKeysCreateFailure) { EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, CreateStorageRootKeys("password")); } TEST_F(TpmUtilityTest, RootKeysPersistFailure) { EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, _, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, CreateStorageRootKeys("password")); } TEST_F(TpmUtilityTest, RootKeysAlreadyExist) { SetExistingKeyHandleExpectation(kRSAStorageRootKey); SetExistingKeyHandleExpectation(kECCStorageRootKey); EXPECT_EQ(TPM_RC_SUCCESS, CreateStorageRootKeys("password")); } TEST_F(TpmUtilityTest, SaltingKeySuccess) { TPM2B_PUBLIC public_area; EXPECT_CALL(mock_tpm_, CreateSyncShort(_, _, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<2>(&public_area), Return(TPM_RC_SUCCESS))); EXPECT_EQ(TPM_RC_SUCCESS, CreateSaltingKey("password")); EXPECT_EQ(TPM_ALG_SHA256, public_area.public_area.name_alg); } TEST_F(TpmUtilityTest, SaltingKeyConsistency) { TPM_HANDLE test_handle = 42; EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<4>(test_handle), Return(TPM_RC_SUCCESS))); EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, test_handle, _, _, _)) .WillRepeatedly(Return(TPM_RC_SUCCESS)); EXPECT_EQ(TPM_RC_SUCCESS, CreateSaltingKey("password")); } TEST_F(TpmUtilityTest, SaltingKeyCreateFailure) { EXPECT_CALL(mock_tpm_, CreateSyncShort(_, _, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password")); } TEST_F(TpmUtilityTest, SaltingKeyLoadFailure) { EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password")); } TEST_F(TpmUtilityTest, SaltingKeyPersistFailure) { EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, _, _, _, _)) .WillRepeatedly(Return(TPM_RC_FAILURE)); EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password")); } TEST_F(TpmUtilityTest, SaltingKeyAlreadyExists) { SetExistingKeyHandleExpectation(kSaltingKey); EXPECT_EQ(TPM_RC_SUCCESS, CreateSaltingKey("password")); } } // namespace trunks