// // 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 <gmock/gmock.h> #include <gtest/gtest.h> #include "trunks/mock_tpm.h" #include "trunks/tpm_generated.h" #include "trunks/tpm_state_impl.h" #include "trunks/trunks_factory_for_test.h" using testing::_; using testing::DoAll; using testing::Invoke; using testing::NiceMock; using testing::Return; using testing::SetArgPointee; using testing::WithArgs; namespace trunks { // From definition of TPMA_STARTUP_CLEAR. const trunks::TPMA_STARTUP_CLEAR kPlatformHierarchyMask = 1U; // A test fixture for TpmState tests. class TpmStateTest : public testing::Test { public: TpmStateTest() {} ~TpmStateTest() override {} void SetUp() override { factory_.set_tpm(&mock_tpm_); permanent_data_ = GetValidCapabilityData(TPM_PT_PERMANENT, 0); startup_clear_data_ = GetValidCapabilityData(TPM_PT_STARTUP_CLEAR, 0); rsa_data_ = GetValidAlgorithmData(TPM_ALG_RSA, 0); ecc_data_ = GetValidAlgorithmData(TPM_ALG_ECC, 0); lockout_counter_ = GetValidCapabilityData(TPM_PT_LOCKOUT_COUNTER, 0); lockout_threshold_ = GetValidCapabilityData(TPM_PT_MAX_AUTH_FAIL, 0); lockout_interval_ = GetValidCapabilityData(TPM_PT_LOCKOUT_INTERVAL, 0); lockout_recovery_ = GetValidCapabilityData(TPM_PT_LOCKOUT_RECOVERY, 0); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_PERMANENT, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLivePermanent))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_STARTUP_CLEAR, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveStartupClear))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_ALGS, TPM_ALG_RSA, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveRSA))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_ALGS, TPM_ALG_ECC, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveECC))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_LOCKOUT_COUNTER, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveLockoutCounter))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_MAX_AUTH_FAIL, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveLockoutThreshold))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_LOCKOUT_INTERVAL, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveLockoutInterval))); EXPECT_CALL(mock_tpm_, GetCapabilitySync(TPM_CAP_TPM_PROPERTIES, TPM_PT_LOCKOUT_RECOVERY, 1, _, _, _)) .WillRepeatedly(WithArgs<4>( Invoke(this, &TpmStateTest::GetLiveLockoutRecovery))); } TPM_RC GetLivePermanent(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = permanent_data_; return TPM_RC_SUCCESS; } TPM_RC GetLiveStartupClear(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = startup_clear_data_; return TPM_RC_SUCCESS; } TPM_RC GetLiveRSA(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = rsa_data_; return TPM_RC_SUCCESS; } TPM_RC GetLiveECC(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = ecc_data_; return TPM_RC_SUCCESS; } TPM_RC GetLiveLockoutCounter(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = lockout_counter_; return TPM_RC_SUCCESS; } TPM_RC GetLiveLockoutThreshold(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = lockout_threshold_; return TPM_RC_SUCCESS; } TPM_RC GetLiveLockoutInterval(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = lockout_interval_; return TPM_RC_SUCCESS; } TPM_RC GetLiveLockoutRecovery(TPMS_CAPABILITY_DATA* capability_data) { *capability_data = lockout_recovery_; return TPM_RC_SUCCESS; } protected: TPMS_CAPABILITY_DATA GetValidCapabilityData(TPM_PT property, UINT32 value) { TPMS_CAPABILITY_DATA data; memset(&data, 0, sizeof(TPMS_CAPABILITY_DATA)); data.capability = TPM_CAP_TPM_PROPERTIES; data.data.tpm_properties.count = 1; data.data.tpm_properties.tpm_property[0].property = property; data.data.tpm_properties.tpm_property[0].value = value; return data; } TPMS_CAPABILITY_DATA GetValidAlgorithmData(TPM_ALG_ID alg_id, UINT32 value) { TPMS_CAPABILITY_DATA data; memset(&data, 0, sizeof(TPMS_CAPABILITY_DATA)); data.capability = TPM_CAP_ALGS; data.data.tpm_properties.count = 1; data.data.algorithms.alg_properties[0].alg = alg_id; data.data.algorithms.alg_properties[0].alg_properties = value; return data; } TrunksFactoryForTest factory_; NiceMock<MockTpm> mock_tpm_; TPMS_CAPABILITY_DATA permanent_data_; TPMS_CAPABILITY_DATA startup_clear_data_; TPMS_CAPABILITY_DATA rsa_data_; TPMS_CAPABILITY_DATA ecc_data_; TPMS_CAPABILITY_DATA lockout_counter_; TPMS_CAPABILITY_DATA lockout_threshold_; TPMS_CAPABILITY_DATA lockout_interval_; TPMS_CAPABILITY_DATA lockout_recovery_; }; TEST(TpmState_DeathTest, NotInitialized) { TrunksFactoryForTest factory; TpmStateImpl tpm_state(factory); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsOwnerPasswordSet(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsEndorsementPasswordSet(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsLockoutPasswordSet(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsOwned(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsInLockout(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsPlatformHierarchyEnabled(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsStorageHierarchyEnabled(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsEndorsementHierarchyEnabled(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsEnabled(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.WasShutdownOrderly(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsRSASupported(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.IsECCSupported(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetLockoutCounter(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetLockoutThreshold(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetLockoutInterval(), "Check failed"); EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetLockoutRecovery(), "Check failed"); } TEST_F(TpmStateTest, FlagsClear) { TpmStateImpl tpm_state(factory_); EXPECT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); EXPECT_FALSE(tpm_state.IsOwnerPasswordSet()); EXPECT_FALSE(tpm_state.IsEndorsementPasswordSet()); EXPECT_FALSE(tpm_state.IsLockoutPasswordSet()); EXPECT_FALSE(tpm_state.IsInLockout()); EXPECT_FALSE(tpm_state.IsOwned()); EXPECT_FALSE(tpm_state.IsPlatformHierarchyEnabled()); EXPECT_FALSE(tpm_state.IsStorageHierarchyEnabled()); EXPECT_FALSE(tpm_state.IsEndorsementHierarchyEnabled()); EXPECT_FALSE(tpm_state.IsEnabled()); EXPECT_FALSE(tpm_state.WasShutdownOrderly()); EXPECT_FALSE(tpm_state.IsRSASupported()); EXPECT_FALSE(tpm_state.IsECCSupported()); EXPECT_EQ(0u, tpm_state.GetLockoutCounter()); EXPECT_EQ(0u, tpm_state.GetLockoutThreshold()); EXPECT_EQ(0u, tpm_state.GetLockoutInterval()); EXPECT_EQ(0u, tpm_state.GetLockoutRecovery()); } TEST_F(TpmStateTest, FlagsSet) { uint32_t lockout_counter = 5; uint32_t lockout_threshold = 8; uint32_t lockout_interval = 1200; uint32_t lockout_recovery = 84600; permanent_data_.data.tpm_properties.tpm_property[0].value = ~0U; startup_clear_data_.data.tpm_properties.tpm_property[0].value = ~0U; lockout_counter_.data.tpm_properties.tpm_property[0].value = lockout_counter; lockout_threshold_.data.tpm_properties.tpm_property[0].value = lockout_threshold; lockout_interval_.data.tpm_properties.tpm_property[0].value = lockout_interval; lockout_recovery_.data.tpm_properties.tpm_property[0].value = lockout_recovery; rsa_data_.data.algorithms.alg_properties[0].alg_properties = ~0U; ecc_data_.data.algorithms.alg_properties[0].alg_properties = ~0U; TpmStateImpl tpm_state(factory_); EXPECT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); EXPECT_TRUE(tpm_state.IsOwnerPasswordSet()); EXPECT_TRUE(tpm_state.IsEndorsementPasswordSet()); EXPECT_TRUE(tpm_state.IsLockoutPasswordSet()); EXPECT_TRUE(tpm_state.IsOwned()); EXPECT_TRUE(tpm_state.IsInLockout()); EXPECT_TRUE(tpm_state.IsPlatformHierarchyEnabled()); EXPECT_TRUE(tpm_state.IsStorageHierarchyEnabled()); EXPECT_TRUE(tpm_state.IsEndorsementHierarchyEnabled()); EXPECT_FALSE(tpm_state.IsEnabled()); EXPECT_TRUE(tpm_state.WasShutdownOrderly()); EXPECT_TRUE(tpm_state.IsRSASupported()); EXPECT_TRUE(tpm_state.IsECCSupported()); EXPECT_EQ(lockout_counter, tpm_state.GetLockoutCounter()); EXPECT_EQ(lockout_threshold, tpm_state.GetLockoutThreshold()); EXPECT_EQ(lockout_interval, tpm_state.GetLockoutInterval()); EXPECT_EQ(lockout_recovery, tpm_state.GetLockoutRecovery()); } TEST_F(TpmStateTest, EnabledTpm) { startup_clear_data_.data.tpm_properties.tpm_property[0].value = ~kPlatformHierarchyMask; TpmStateImpl tpm_state(factory_); EXPECT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); EXPECT_FALSE(tpm_state.IsPlatformHierarchyEnabled()); EXPECT_TRUE(tpm_state.IsStorageHierarchyEnabled()); EXPECT_TRUE(tpm_state.IsEndorsementHierarchyEnabled()); EXPECT_TRUE(tpm_state.IsEnabled()); EXPECT_TRUE(tpm_state.WasShutdownOrderly()); } TEST_F(TpmStateTest, BadResponsePermanentCapabilityType) { permanent_data_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseStartupClearCapabilityType) { startup_clear_data_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutCounterCapabilityType) { lockout_counter_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutThresholdCapabilityType) { lockout_threshold_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutIntervalCapabilityType) { lockout_interval_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutRecoveryCapabilityType) { lockout_recovery_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseRSAAlgCapabilityType) { rsa_data_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseECCAlgCapabilityType) { ecc_data_.capability = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponsePermanentPropertyCount) { permanent_data_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseStartupClearPropertyCount) { startup_clear_data_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutCounterPropertyCount) { lockout_counter_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutThresholdPropertyCount) { lockout_threshold_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutIntervalPropertyCount) { lockout_interval_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutRecoveryPropertyCount) { lockout_recovery_.data.tpm_properties.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseRSAAlgPropertyCount) { rsa_data_.data.algorithms.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseECCAlgPropertyCount) { ecc_data_.data.algorithms.count = 0; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponsePermanentPropertyType) { permanent_data_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseStartupClearPropertyType) { startup_clear_data_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutCounterPropertyType) { lockout_counter_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutThresholdPropertyType) { lockout_threshold_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutIntervalPropertyType) { lockout_interval_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } TEST_F(TpmStateTest, BadResponseLockoutRecoveryPropertyType) { lockout_recovery_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; TpmStateImpl tpm_state(factory_); EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); } } // namespace trunks