diff options
author | Darren Krahn <dkrahn@google.com> | 2016-06-14 20:36:18 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-06-14 20:36:18 +0000 |
commit | df3a5b9734d1f5bbdf4366ced7adfeaec59abd6f (patch) | |
tree | 74c707f5ed29a7e4c85c80b0268db3af80ba1416 | |
parent | aae3aebe3a349783f322a5eed21e841b38dc2abe (diff) | |
parent | ce32afbb304bbca521ec0333b41c82d736295ec7 (diff) | |
download | tpm-df3a5b9734d1f5bbdf4366ced7adfeaec59abd6f.tar.gz |
trunks: Refactored TpmState.
am: ce32afbb30
Change-Id: Iaef61ac5d08d6245e241af87d66591efe164c278
-rw-r--r-- | trunks/Android.mk | 46 | ||||
-rw-r--r-- | trunks/error_codes.h | 1 | ||||
-rw-r--r-- | trunks/mock_tpm_state.cc | 1 | ||||
-rw-r--r-- | trunks/mock_tpm_state.h | 3 | ||||
-rw-r--r-- | trunks/tpm_state.h | 12 | ||||
-rw-r--r-- | trunks/tpm_state_impl.cc | 246 | ||||
-rw-r--r-- | trunks/tpm_state_impl.h | 38 | ||||
-rw-r--r-- | trunks/tpm_state_test.cc | 476 | ||||
-rw-r--r-- | trunks/trunks_factory_for_test.cc | 13 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-amd64.policy | 1 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-arm.policy | 1 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-arm64.policy | 1 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-mips.policy | 1 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-x86.policy | 1 | ||||
-rw-r--r-- | trunks/trunksd-seccomp-x86_64.policy | 1 |
15 files changed, 446 insertions, 396 deletions
diff --git a/trunks/Android.mk b/trunks/Android.mk index 28d71ec..c801699 100644 --- a/trunks/Android.mk +++ b/trunks/Android.mk @@ -21,8 +21,7 @@ trunksCFlags := \ -Wall -Werror \ -Wno-unused-parameter \ -DUSE_BINDER_IPC \ - -fvisibility=hidden \ - + -fvisibility=hidden trunksIncludes := $(LOCAL_PATH)/.. trunksSharedLibraries := \ libbinder \ @@ -33,7 +32,7 @@ trunksSharedLibraries := \ libchrome-crypto \ libcrypto \ libprotobuf-cpp-lite \ - libutils \ + libutils # libtrunks_generated # ======================================================== @@ -51,8 +50,7 @@ LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries) LOCAL_SRC_FILES := \ interface.proto \ aidl/android/trunks/ITrunks.aidl \ - aidl/android/trunks/ITrunksClient.aidl \ - + aidl/android/trunks/ITrunksClient.aidl LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl include $(BUILD_STATIC_LIBRARY) @@ -79,8 +77,7 @@ LOCAL_SRC_FILES := \ tpm_generated.cc \ tpm_state_impl.cc \ tpm_utility_impl.cc \ - trunks_factory_impl.cc \ - + trunks_factory_impl.cc include $(BUILD_STATIC_LIBRARY) # trunksd @@ -102,25 +99,21 @@ LOCAL_C_INCLUDES := $(trunksIncludes) LOCAL_SHARED_LIBRARIES := \ $(trunksSharedLibraries) \ libbrillo-minijail \ - libminijail \ - + libminijail ifeq ($(BRILLOEMULATOR),true) LOCAL_SHARED_LIBRARIES += libtpm2 endif LOCAL_STATIC_LIBRARIES := \ libtrunks_generated \ - libtrunks_common \ - + libtrunks_common LOCAL_REQUIRED_MODULES := \ - trunksd-seccomp.policy \ - + trunksd-seccomp.policy LOCAL_SRC_FILES := \ resource_manager.cc \ tpm_handle.cc \ tpm_simulator_handle.cc \ trunks_binder_service.cc \ - trunksd.cc \ - + trunksd.cc include $(BUILD_EXECUTABLE) # trunksd-seccomp.policy @@ -141,14 +134,12 @@ LOCAL_CFLAGS := $(trunksCFlags) LOCAL_CLANG := true LOCAL_C_INCLUDES := $(trunksIncludes) LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries) - LOCAL_WHOLE_STATIC_LIBRARIES := \ libtrunks_common \ - libtrunks_generated \ - + libtrunks_generated LOCAL_SRC_FILES := \ - trunks_binder_proxy.cc \ - + trunks_binder_proxy.cc +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/.. include $(BUILD_SHARED_LIBRARY) # trunks_client @@ -162,8 +153,7 @@ LOCAL_C_INCLUDES := $(trunksIncludes) LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries) libtrunks LOCAL_SRC_FILES := \ trunks_client.cc \ - trunks_client_test.cc \ - + trunks_client_test.cc include $(BUILD_EXECUTABLE) # libtrunks_test @@ -186,11 +176,9 @@ LOCAL_SRC_FILES := \ mock_tpm.cc \ mock_tpm_state.cc \ mock_tpm_utility.cc \ - trunks_factory_for_test.cc \ - + trunks_factory_for_test.cc LOCAL_STATIC_LIBRARIES := \ - libgmock \ - + libgmock include $(BUILD_STATIC_LIBRARY) # Target unit tests @@ -215,13 +203,11 @@ LOCAL_SRC_FILES := \ session_manager_test.cc \ tpm_generated_test.cc \ tpm_state_test.cc \ - tpm_utility_test.cc \ - + tpm_utility_test.cc LOCAL_STATIC_LIBRARIES := \ libBionicGtestMain \ libgmock \ libtrunks_common \ libtrunks_generated \ - libtrunks_test \ - + libtrunks_test include $(BUILD_NATIVE_TEST) diff --git a/trunks/error_codes.h b/trunks/error_codes.h index 4b8d61a..eac57e9 100644 --- a/trunks/error_codes.h +++ b/trunks/error_codes.h @@ -41,6 +41,7 @@ const TPM_RC TRUNKS_RC_READ_ERROR = kTrunksErrorBase + 3; const TPM_RC TRUNKS_RC_WRITE_ERROR = kTrunksErrorBase + 4; const TPM_RC TRUNKS_RC_IPC_ERROR = kTrunksErrorBase + 5; const TPM_RC TRUNKS_RC_SESSION_SETUP_ERROR = kTrunksErrorBase + 6; +const TPM_RC TRUNKS_RC_INVALID_TPM_CONFIGURATION = kTrunksErrorBase + 7; const TPM_RC TCTI_RC_TRY_AGAIN = kTctiErrorBase + 1; const TPM_RC TCTI_RC_GENERAL_FAILURE = kTctiErrorBase + 2; diff --git a/trunks/mock_tpm_state.cc b/trunks/mock_tpm_state.cc index ee52e3b..fad7a75 100644 --- a/trunks/mock_tpm_state.cc +++ b/trunks/mock_tpm_state.cc @@ -38,6 +38,7 @@ MockTpmState::MockTpmState() { ON_CALL(*this, GetLockoutThreshold()).WillByDefault(Return(0)); ON_CALL(*this, GetLockoutInterval()).WillByDefault(Return(0)); ON_CALL(*this, GetLockoutRecovery()).WillByDefault(Return(0)); + ON_CALL(*this, GetMaxNVSize()).WillByDefault(Return(2048)); } MockTpmState::~MockTpmState() {} diff --git a/trunks/mock_tpm_state.h b/trunks/mock_tpm_state.h index 9c3073a..20dd338 100644 --- a/trunks/mock_tpm_state.h +++ b/trunks/mock_tpm_state.h @@ -45,6 +45,9 @@ class MockTpmState : public TpmState { MOCK_METHOD0(GetLockoutThreshold, uint32_t()); MOCK_METHOD0(GetLockoutInterval, uint32_t()); MOCK_METHOD0(GetLockoutRecovery, uint32_t()); + MOCK_METHOD0(GetMaxNVSize, uint32_t()); + MOCK_METHOD2(GetTpmProperty, bool(TPM_PT, uint32_t*)); + MOCK_METHOD2(GetAlgorithmProperties, bool(TPM_ALG_ID, TPMA_ALGORITHM*)); }; } // namespace trunks diff --git a/trunks/tpm_state.h b/trunks/tpm_state.h index 21443de..7367022 100644 --- a/trunks/tpm_state.h +++ b/trunks/tpm_state.h @@ -85,6 +85,18 @@ class TRUNKS_EXPORT TpmState { // LockoutAuth can be used again. virtual uint32_t GetLockoutRecovery() = 0; + // Returns the maximum size, in bytes, of an NV index data area. + virtual uint32_t GetMaxNVSize() = 0; + + // Gets the |value| of any |property|. |value| may be NULL. Returns false if + // a value is not available for the property. + virtual bool GetTpmProperty(TPM_PT property, uint32_t* value) = 0; + + // Gets |algorithm| |properties|. |properties| may be NULL. Returns false if + // properties are not available for the algorithm. + virtual bool GetAlgorithmProperties(TPM_ALG_ID algorithm, + TPMA_ALGORITHM* properties) = 0; + private: DISALLOW_COPY_AND_ASSIGN(TpmState); }; diff --git a/trunks/tpm_state_impl.cc b/trunks/tpm_state_impl.cc index 93874c4..e453cae 100644 --- a/trunks/tpm_state_impl.cc +++ b/trunks/tpm_state_impl.cc @@ -17,6 +17,7 @@ #include "trunks/tpm_state_impl.h" #include <base/logging.h> +#include <brillo/bind_lambda.h> #include "trunks/error_codes.h" #include "trunks/tpm_generated.h" @@ -36,109 +37,49 @@ const trunks::TPMA_STARTUP_CLEAR kStorageHierarchyMask = 1U << 1; const trunks::TPMA_STARTUP_CLEAR kEndorsementHierarchyMask = 1U << 2; const trunks::TPMA_STARTUP_CLEAR kOrderlyShutdownMask = 1U << 31; -// From definition of TPMA_ALGORITHM -const trunks::TPMA_ALGORITHM kAsymmetricAlgMask = 1U; - } // namespace namespace trunks { -TpmStateImpl::TpmStateImpl(const TrunksFactory& factory) - : factory_(factory), - initialized_(false), - permanent_flags_(0), - startup_clear_flags_(0), - rsa_flags_(0), - ecc_flags_(0) {} - -TpmStateImpl::~TpmStateImpl() {} +TpmStateImpl::TpmStateImpl(const TrunksFactory& factory) : factory_(factory) {} TPM_RC TpmStateImpl::Initialize() { - TPM_RC result = GetTpmProperty(TPM_PT_PERMANENT, &permanent_flags_); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting permanent flags: " << GetErrorString(result); - return result; - } - result = GetTpmProperty(TPM_PT_STARTUP_CLEAR, &startup_clear_flags_); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting startup flags: " << GetErrorString(result); - return result; - } - result = GetTpmProperty(TPM_PT_LOCKOUT_COUNTER, &lockout_counter_); + TPM_RC result = CacheTpmProperties(); if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting lockout counter: " << GetErrorString(result); + LOG(ERROR) << "Failed to query TPM properties: " << GetErrorString(result); return result; } - result = GetTpmProperty(TPM_PT_MAX_AUTH_FAIL, &lockout_threshold_); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting lockout threshold: " << GetErrorString(result); - return result; - } - result = GetTpmProperty(TPM_PT_LOCKOUT_INTERVAL, &lockout_interval_); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting lockout interval: " << GetErrorString(result); - return result; - } - result = GetTpmProperty(TPM_PT_LOCKOUT_RECOVERY, &lockout_recovery_); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << "Error getting lockout recovery: " << GetErrorString(result); - return result; + if (tpm_properties_.count(TPM_PT_PERMANENT) == 0 || + tpm_properties_.count(TPM_PT_STARTUP_CLEAR) == 0) { + LOG(ERROR) << "Required properties missing!"; + return TRUNKS_RC_INVALID_TPM_CONFIGURATION; } - TPMI_YES_NO more_data; - TPMS_CAPABILITY_DATA capability_data; - result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_ALGS, TPM_ALG_RSA, - 1, // There is only one value. - &more_data, &capability_data, - nullptr); - if (result) { - LOG(ERROR) << __func__ << ": " << GetErrorString(result); - return result; - } - if (capability_data.capability != TPM_CAP_ALGS || - capability_data.data.algorithms.count != 1) { - LOG(ERROR) << __func__ << ": Unexpected capability data."; - return SAPI_RC_MALFORMED_RESPONSE; - } - if (capability_data.data.algorithms.alg_properties[0].alg == TPM_ALG_RSA) { - rsa_flags_ = - capability_data.data.algorithms.alg_properties[0].alg_properties; - } - result = factory_.GetTpm()->GetCapabilitySync(TPM_CAP_ALGS, TPM_ALG_ECC, - 1, // There is only one value. - &more_data, &capability_data, - nullptr); - if (result) { - LOG(ERROR) << __func__ << ": " << GetErrorString(result); + result = CacheAlgorithmProperties(); + if (result != TPM_RC_SUCCESS) { + LOG(ERROR) << "Failed to query TPM algorithms: " << GetErrorString(result); return result; } - if (capability_data.capability != TPM_CAP_ALGS || - capability_data.data.algorithms.count != 1) { - LOG(ERROR) << __func__ << ": Unexpected capability data."; - return SAPI_RC_MALFORMED_RESPONSE; - } - if (capability_data.data.algorithms.alg_properties[0].alg == TPM_ALG_ECC) { - ecc_flags_ = - capability_data.data.algorithms.alg_properties[0].alg_properties; - } initialized_ = true; return TPM_RC_SUCCESS; } bool TpmStateImpl::IsOwnerPasswordSet() { CHECK(initialized_); - return ((permanent_flags_ & kOwnerAuthSetMask) == kOwnerAuthSetMask); + return ((tpm_properties_[TPM_PT_PERMANENT] & kOwnerAuthSetMask) == + kOwnerAuthSetMask); } bool TpmStateImpl::IsEndorsementPasswordSet() { CHECK(initialized_); - return ((permanent_flags_ & kEndorsementAuthSetMask) == + return ((tpm_properties_[TPM_PT_PERMANENT] & kEndorsementAuthSetMask) == kEndorsementAuthSetMask); } bool TpmStateImpl::IsLockoutPasswordSet() { CHECK(initialized_); - return ((permanent_flags_ & kLockoutAuthSetMask) == kLockoutAuthSetMask); + return ((tpm_properties_[TPM_PT_PERMANENT] & kLockoutAuthSetMask) == + kLockoutAuthSetMask); } bool TpmStateImpl::IsOwned() { @@ -148,24 +89,25 @@ bool TpmStateImpl::IsOwned() { bool TpmStateImpl::IsInLockout() { CHECK(initialized_); - return ((permanent_flags_ & kInLockoutMask) == kInLockoutMask); + return ((tpm_properties_[TPM_PT_PERMANENT] & kInLockoutMask) == + kInLockoutMask); } bool TpmStateImpl::IsPlatformHierarchyEnabled() { CHECK(initialized_); - return ((startup_clear_flags_ & kPlatformHierarchyMask) == + return ((tpm_properties_[TPM_PT_STARTUP_CLEAR] & kPlatformHierarchyMask) == kPlatformHierarchyMask); } bool TpmStateImpl::IsStorageHierarchyEnabled() { CHECK(initialized_); - return ((startup_clear_flags_ & kStorageHierarchyMask) == + return ((tpm_properties_[TPM_PT_STARTUP_CLEAR] & kStorageHierarchyMask) == kStorageHierarchyMask); } bool TpmStateImpl::IsEndorsementHierarchyEnabled() { CHECK(initialized_); - return ((startup_clear_flags_ & kEndorsementHierarchyMask) == + return ((tpm_properties_[TPM_PT_STARTUP_CLEAR] & kEndorsementHierarchyMask) == kEndorsementHierarchyMask); } @@ -176,60 +118,156 @@ bool TpmStateImpl::IsEnabled() { bool TpmStateImpl::WasShutdownOrderly() { CHECK(initialized_); - return ((startup_clear_flags_ & kOrderlyShutdownMask) == + return ((tpm_properties_[TPM_PT_STARTUP_CLEAR] & kOrderlyShutdownMask) == kOrderlyShutdownMask); } bool TpmStateImpl::IsRSASupported() { CHECK(initialized_); - return ((rsa_flags_ & kAsymmetricAlgMask) == kAsymmetricAlgMask); + return (algorithm_properties_.count(TPM_ALG_RSA) > 0); } bool TpmStateImpl::IsECCSupported() { CHECK(initialized_); - return ((ecc_flags_ & kAsymmetricAlgMask) == kAsymmetricAlgMask); + return (algorithm_properties_.count(TPM_ALG_ECC) > 0); } uint32_t TpmStateImpl::GetLockoutCounter() { CHECK(initialized_); - return lockout_counter_; + return tpm_properties_[TPM_PT_LOCKOUT_COUNTER]; } uint32_t TpmStateImpl::GetLockoutThreshold() { CHECK(initialized_); - return lockout_threshold_; + return tpm_properties_[TPM_PT_MAX_AUTH_FAIL]; } uint32_t TpmStateImpl::GetLockoutInterval() { CHECK(initialized_); - return lockout_interval_; + return tpm_properties_[TPM_PT_LOCKOUT_INTERVAL]; } uint32_t TpmStateImpl::GetLockoutRecovery() { CHECK(initialized_); - return lockout_recovery_; + return tpm_properties_[TPM_PT_LOCKOUT_RECOVERY]; } -TPM_RC TpmStateImpl::GetTpmProperty(uint32_t property, uint32_t* value) { - CHECK(value); - TPMI_YES_NO more_data; - TPMS_CAPABILITY_DATA capability_data; - TPM_RC result = factory_.GetTpm()->GetCapabilitySync( - TPM_CAP_TPM_PROPERTIES, property, - 1, // Only one property. - &more_data, &capability_data, nullptr); - if (result != TPM_RC_SUCCESS) { - LOG(ERROR) << __func__ << ": " << GetErrorString(result); - return result; +uint32_t TpmStateImpl::GetMaxNVSize() { + CHECK(initialized_); + uint32_t max_nv_size; + if (!GetTpmProperty(TPM_PT_NV_INDEX_MAX, &max_nv_size)) { + max_nv_size = 2048; + } + uint32_t max_nv_buffer; + if (GetTpmProperty(TPM_PT_NV_BUFFER_MAX, &max_nv_buffer) && + max_nv_buffer < max_nv_size) { + max_nv_size = max_nv_buffer; + } + return max_nv_size; +} + +bool TpmStateImpl::GetTpmProperty(TPM_PT property, uint32_t* value) { + CHECK(initialized_); + if (tpm_properties_.count(property) == 0) { + return false; + } + if (value) { + *value = tpm_properties_[property]; } - if (capability_data.capability != TPM_CAP_TPM_PROPERTIES || - capability_data.data.tpm_properties.count != 1 || - capability_data.data.tpm_properties.tpm_property[0].property != - property) { - LOG(ERROR) << __func__ << ": Unexpected capability data."; - return SAPI_RC_MALFORMED_RESPONSE; + return true; +} + +bool TpmStateImpl::GetAlgorithmProperties(TPM_ALG_ID algorithm, + TPMA_ALGORITHM* properties) { + CHECK(initialized_); + if (algorithm_properties_.count(algorithm) == 0) { + return false; + } + if (properties) { + *properties = algorithm_properties_[algorithm]; + } + return true; +} + +TPM_RC TpmStateImpl::GetCapability(const CapabilityCallback& callback, + TPM_CAP capability, + uint32_t property, + uint32_t max_properties_per_call) { + TPMI_YES_NO more_data = YES; + while (more_data) { + TPMS_CAPABILITY_DATA capability_data; + TPM_RC result = factory_.GetTpm()->GetCapabilitySync( + capability, property, max_properties_per_call, &more_data, + &capability_data, nullptr); + if (result != TPM_RC_SUCCESS) { + LOG(ERROR) << __func__ << ": " << GetErrorString(result); + return result; + } + if (capability_data.capability != capability) { + LOG(ERROR) << __func__ << ": Unexpected capability data."; + return SAPI_RC_MALFORMED_RESPONSE; + } + uint32_t next_property = callback.Run(capability_data.data); + if (more_data) { + if (next_property == 0) { + LOG(ERROR) << __func__ << ": No properties in response."; + return SAPI_RC_MALFORMED_RESPONSE; + } + if (next_property <= property) { + LOG(ERROR) << __func__ << ": Lower properties in response."; + return SAPI_RC_MALFORMED_RESPONSE; + } + property = next_property; + } + } + return TPM_RC_SUCCESS; +} + +TPM_RC TpmStateImpl::CacheTpmProperties() { + CapabilityCallback callback = + base::Bind([this](const TPMU_CAPABILITIES& capability_data) { + uint32_t next_property = 0; + for (uint32_t i = 0; + i < capability_data.tpm_properties.count && i < MAX_TPM_PROPERTIES; + ++i) { + const TPMS_TAGGED_PROPERTY& property = + capability_data.tpm_properties.tpm_property[i]; + VLOG(1) << "TPM Property 0x" << std::hex << property.property + << " = 0x" << property.value; + tpm_properties_[property.property] = property.value; + next_property = property.property + 1; + } + return next_property; + }); + if (tpm_properties_.empty()) { + TPM_RC result = GetCapability(callback, TPM_CAP_TPM_PROPERTIES, PT_FIXED, + MAX_TPM_PROPERTIES); + if (result != TPM_RC_SUCCESS) { + return result; + } + } + return GetCapability(callback, TPM_CAP_TPM_PROPERTIES, PT_VAR, + MAX_TPM_PROPERTIES); +} + +TPM_RC TpmStateImpl::CacheAlgorithmProperties() { + CapabilityCallback callback = + base::Bind([this](const TPMU_CAPABILITIES& capability_data) { + uint32_t next_property = 0; + for (uint32_t i = 0; + i < capability_data.algorithms.count && i < MAX_CAP_ALGS; ++i) { + const TPMS_ALG_PROPERTY& property = + capability_data.algorithms.alg_properties[i]; + VLOG(1) << "Algorithm Properties 0x" << std::hex << property.alg + << " = 0x" << property.alg_properties; + algorithm_properties_[property.alg] = property.alg_properties; + next_property = property.alg + 1; + } + return next_property; + }); + if (algorithm_properties_.empty()) { + return GetCapability(callback, TPM_CAP_ALGS, TPM_ALG_FIRST, MAX_CAP_ALGS); } - *value = capability_data.data.tpm_properties.tpm_property[0].value; return TPM_RC_SUCCESS; } diff --git a/trunks/tpm_state_impl.h b/trunks/tpm_state_impl.h index 14247ff..4a26f73 100644 --- a/trunks/tpm_state_impl.h +++ b/trunks/tpm_state_impl.h @@ -19,6 +19,9 @@ #include "trunks/tpm_state.h" +#include <map> + +#include <base/callback.h> #include <base/macros.h> #include "trunks/tpm_generated.h" @@ -32,7 +35,7 @@ class TrunksFactory; class TRUNKS_EXPORT TpmStateImpl : public TpmState { public: explicit TpmStateImpl(const TrunksFactory& factory); - ~TpmStateImpl() override; + ~TpmStateImpl() override = default; // TpmState methods. TPM_RC Initialize() override; @@ -52,23 +55,30 @@ class TRUNKS_EXPORT TpmStateImpl : public TpmState { uint32_t GetLockoutThreshold() override; uint32_t GetLockoutInterval() override; uint32_t GetLockoutRecovery() override; + uint32_t GetMaxNVSize() override; + bool GetTpmProperty(TPM_PT property, uint32_t* value) override; + bool GetAlgorithmProperties(TPM_ALG_ID algorithm, + TPMA_ALGORITHM* properties) override; private: - // This helped method calls Tpm2_GetCapability with TPM_CAP_TPM_PROPERTIES - // and |property|. The returned structure is validated, and the value returned - // is stored in the out argument |value|. Returns TPM_RC_SUCCESS on success. - TPM_RC GetTpmProperty(uint32_t property, uint32_t* value); + // This helper method calls TPM2_GetCapability in a loop until all available + // capabilities of the given type are sent to the |callback|. The callback + // returns the next property value to query if there is more data available or + // 0 if the capability data was empty. + using CapabilityCallback = base::Callback<uint32_t(const TPMU_CAPABILITIES&)>; + TPM_RC GetCapability(const CapabilityCallback& callback, + TPM_CAP capability, + uint32_t property, + uint32_t max_properties_per_call); + // Queries TPM properties and populates tpm_properties_. + TPM_RC CacheTpmProperties(); + // Queries algorithm properties and populates algorithm_properties_. + TPM_RC CacheAlgorithmProperties(); const TrunksFactory& factory_; - bool initialized_; - TPMA_PERMANENT permanent_flags_; - TPMA_STARTUP_CLEAR startup_clear_flags_; - uint32_t lockout_counter_; - uint32_t lockout_threshold_; - uint32_t lockout_interval_; - uint32_t lockout_recovery_; - TPMA_ALGORITHM rsa_flags_; - TPMA_ALGORITHM ecc_flags_; + bool initialized_{false}; + std::map<TPM_PT, uint32_t> tpm_properties_; + std::map<TPM_ALG_ID, TPMA_ALGORITHM> algorithm_properties_; DISALLOW_COPY_AND_ASSIGN(TpmStateImpl); }; diff --git a/trunks/tpm_state_test.cc b/trunks/tpm_state_test.cc index 7356d8e..24d17ca 100644 --- a/trunks/tpm_state_test.cc +++ b/trunks/tpm_state_test.cc @@ -32,124 +32,89 @@ 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 {} + TpmStateTest() = default; + ~TpmStateTest() override = default; 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; + // All auth set (i.e. IsOwned() -> true) and in lockout. + fake_tpm_properties_[TPM_PT_PERMANENT] = 0x207; + // Orderly shutdown, storage and endorsement enabled, platform disabled + // (i.e. IsEnabled() -> true). + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0x80000006; + fake_tpm_properties_[TPM_PT_LOCKOUT_COUNTER] = 2; + fake_tpm_properties_[TPM_PT_MAX_AUTH_FAIL] = 5; + fake_tpm_properties_[TPM_PT_LOCKOUT_INTERVAL] = 100; + fake_tpm_properties_[TPM_PT_LOCKOUT_RECOVERY] = 200; + fake_tpm_properties_[TPM_PT_NV_INDEX_MAX] = 2048; + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX] = 2048; + fake_algorithm_properties_[TPM_ALG_RSA] = 0x9; + fake_algorithm_properties_[TPM_ALG_ECC] = 0x9; + EXPECT_CALL(mock_tpm_, GetCapabilitySync(_, _, _, _, _, _)) + .WillRepeatedly(Invoke(this, &TpmStateTest::FakeGetCapability)); } 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; + TPM_RC FakeGetCapability(const TPM_CAP& capability, + const UINT32& property, + const UINT32& property_count, + TPMI_YES_NO* more_data, + TPMS_CAPABILITY_DATA* capability_data, + AuthorizationDelegate* /* not_used */) { + // Return only two properties at a time, this will exercise the more_data + // logic. + constexpr uint32_t kMaxProperties = 2; + *more_data = NO; + memset(capability_data, 0, sizeof(TPMS_CAPABILITY_DATA)); + capability_data->capability = capability; + TPMU_CAPABILITIES& data = capability_data->data; + if (capability == TPM_CAP_TPM_PROPERTIES) { + // TPM properties get returned one group at a time, mimic this. + uint32_t group = (property >> 8); + uint32_t stop = PT_GROUP * (group + 1); + for (uint32_t i = property; i < stop; ++i) { + if (fake_tpm_properties_.count(i) > 0) { + if (data.tpm_properties.count == kMaxProperties || + data.tpm_properties.count == property_count) { + // There are more properties than we can fit. + *more_data = YES; + break; + } + data.tpm_properties.tpm_property[data.tpm_properties.count].property = + i; + data.tpm_properties.tpm_property[data.tpm_properties.count].value = + fake_tpm_properties_[i]; + data.tpm_properties.count++; + } + } + } else if (capability == TPM_CAP_ALGS) { + // Algorithm properties. + uint32_t stop = TPM_ALG_LAST + 1; + for (uint32_t i = property; i < stop; ++i) { + if (fake_algorithm_properties_.count(i) > 0) { + if (data.algorithms.count == kMaxProperties || + data.algorithms.count == property_count) { + // There are more properties than we can fit. + *more_data = YES; + break; + } + data.algorithms.alg_properties[data.algorithms.count].alg = i; + data.algorithms.alg_properties[data.algorithms.count].alg_properties = + fake_algorithm_properties_[i]; + data.algorithms.count++; + } + } + } + return TPM_RC_SUCCESS; } 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_; + std::map<TPM_PT, uint32_t> fake_tpm_properties_; + std::map<TPM_ALG_ID, TPMA_ALGORITHM> fake_algorithm_properties_; }; TEST(TpmState_DeathTest, NotInitialized) { @@ -175,11 +140,18 @@ TEST(TpmState_DeathTest, NotInitialized) { 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"); + EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetMaxNVSize(), "Check failed"); + EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetTpmProperty(0, nullptr), + "Check failed"); + EXPECT_DEATH_IF_SUPPORTED(tpm_state.GetAlgorithmProperties(0, nullptr), + "Check failed"); } TEST_F(TpmStateTest, FlagsClear) { + fake_tpm_properties_[TPM_PT_PERMANENT] = 0; + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0; TpmStateImpl tpm_state(factory_); - EXPECT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); EXPECT_FALSE(tpm_state.IsOwnerPasswordSet()); EXPECT_FALSE(tpm_state.IsEndorsementPasswordSet()); EXPECT_FALSE(tpm_state.IsLockoutPasswordSet()); @@ -188,34 +160,15 @@ TEST_F(TpmStateTest, FlagsClear) { 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; + fake_tpm_properties_[TPM_PT_PERMANENT] = ~0; + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = ~0; + TpmStateImpl tpm_state(factory_); - EXPECT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); EXPECT_TRUE(tpm_state.IsOwnerPasswordSet()); EXPECT_TRUE(tpm_state.IsEndorsementPasswordSet()); EXPECT_TRUE(tpm_state.IsLockoutPasswordSet()); @@ -224,158 +177,189 @@ TEST_F(TpmStateTest, FlagsSet) { 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()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); 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()); + // All hierarchies enabled. + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0x7; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsEnabled()); + // All hierarchies disabled. + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0x0; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsEnabled()); + // Storage disabled. + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0x5; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsEnabled()); + // Endorsement disabled. + fake_tpm_properties_[TPM_PT_STARTUP_CLEAR] = 0x3; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsEnabled()); } -TEST_F(TpmStateTest, BadResponseLockoutIntervalPropertyCount) { - lockout_interval_.data.tpm_properties.count = 0; +TEST_F(TpmStateTest, OwnedTpm) { TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_TRUE(tpm_state.IsOwned()); + // All auth missing. + fake_tpm_properties_[TPM_PT_PERMANENT] = 0x0; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsOwned()); + // Owner auth missing. + fake_tpm_properties_[TPM_PT_PERMANENT] = 0x6; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsOwned()); + // Endorsement auth missing. + fake_tpm_properties_[TPM_PT_PERMANENT] = 0x5; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsOwned()); + // Lockout auth missing. + fake_tpm_properties_[TPM_PT_PERMANENT] = 0x3; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.IsOwned()); } -TEST_F(TpmStateTest, BadResponseLockoutRecoveryPropertyCount) { - lockout_recovery_.data.tpm_properties.count = 0; +TEST_F(TpmStateTest, AlgorithmSupport) { TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); -} + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_TRUE(tpm_state.IsRSASupported()); + EXPECT_TRUE(tpm_state.IsECCSupported()); -TEST_F(TpmStateTest, BadResponseRSAAlgPropertyCount) { - rsa_data_.data.algorithms.count = 0; - TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + fake_algorithm_properties_.clear(); + // Use a new instance because algorithm properties will not be queried again. + TpmStateImpl tpm_state2(factory_); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state2.Initialize()); + EXPECT_FALSE(tpm_state2.IsRSASupported()); + EXPECT_FALSE(tpm_state2.IsECCSupported()); } -TEST_F(TpmStateTest, BadResponseECCAlgPropertyCount) { - ecc_data_.data.algorithms.count = 0; +TEST_F(TpmStateTest, LockoutValuePassthrough) { TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_EQ(tpm_state.GetLockoutCounter(), + fake_tpm_properties_[TPM_PT_LOCKOUT_COUNTER]); + EXPECT_EQ(tpm_state.GetLockoutThreshold(), + fake_tpm_properties_[TPM_PT_MAX_AUTH_FAIL]); + EXPECT_EQ(tpm_state.GetLockoutInterval(), + fake_tpm_properties_[TPM_PT_LOCKOUT_INTERVAL]); + EXPECT_EQ(tpm_state.GetLockoutRecovery(), + fake_tpm_properties_[TPM_PT_LOCKOUT_RECOVERY]); + + fake_tpm_properties_[TPM_PT_LOCKOUT_COUNTER]++; + fake_tpm_properties_[TPM_PT_MAX_AUTH_FAIL]++; + fake_tpm_properties_[TPM_PT_LOCKOUT_INTERVAL]++; + fake_tpm_properties_[TPM_PT_LOCKOUT_RECOVERY]++; + // Refresh and check for the new values. + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_EQ(tpm_state.GetLockoutCounter(), + fake_tpm_properties_[TPM_PT_LOCKOUT_COUNTER]); + EXPECT_EQ(tpm_state.GetLockoutThreshold(), + fake_tpm_properties_[TPM_PT_MAX_AUTH_FAIL]); + EXPECT_EQ(tpm_state.GetLockoutInterval(), + fake_tpm_properties_[TPM_PT_LOCKOUT_INTERVAL]); + EXPECT_EQ(tpm_state.GetLockoutRecovery(), + fake_tpm_properties_[TPM_PT_LOCKOUT_RECOVERY]); } -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, MaxNVSize) { + auto CheckMaxNVSize = [this]() { + TpmStateImpl tpm_state(factory_); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + bool has_index = fake_tpm_properties_.count(TPM_PT_NV_INDEX_MAX) > 0; + bool has_buffer = fake_tpm_properties_.count(TPM_PT_NV_BUFFER_MAX) > 0; + if (has_index && has_buffer) { + EXPECT_EQ(tpm_state.GetMaxNVSize(), + std::min(fake_tpm_properties_[TPM_PT_NV_INDEX_MAX], + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX])); + } else if (has_index) { + EXPECT_EQ(tpm_state.GetMaxNVSize(), + fake_tpm_properties_[TPM_PT_NV_INDEX_MAX]); + } else if (has_buffer) { + EXPECT_EQ(tpm_state.GetMaxNVSize(), + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX]); + } else { + // Check for a reasonable default value. Brillo specs a minimum of 2048 so + // it shouldn't be less than that. + EXPECT_GE(tpm_state.GetMaxNVSize(), 2048u); + } + }; + // Check with the defaults (same index and buffer max). + CheckMaxNVSize(); + // Check with lower buffer max. + fake_tpm_properties_[TPM_PT_NV_INDEX_MAX] = 20; + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX] = 10; + CheckMaxNVSize(); + // Check with lower index max. + fake_tpm_properties_[TPM_PT_NV_INDEX_MAX] = 10; + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX] = 20; + CheckMaxNVSize(); + // Check without index property. + fake_tpm_properties_.erase(TPM_PT_NV_INDEX_MAX); + fake_tpm_properties_[TPM_PT_NV_BUFFER_MAX] = 5; + CheckMaxNVSize(); + // Check without buffer property. + fake_tpm_properties_[TPM_PT_NV_INDEX_MAX] = 5; + fake_tpm_properties_.erase(TPM_PT_NV_BUFFER_MAX); + CheckMaxNVSize(); + // Check without any properties. + fake_tpm_properties_.erase(TPM_PT_NV_INDEX_MAX); + fake_tpm_properties_.erase(TPM_PT_NV_BUFFER_MAX); + CheckMaxNVSize(); } -TEST_F(TpmStateTest, BadResponseStartupClearPropertyType) { - startup_clear_data_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; +TEST_F(TpmStateTest, RawTpmProperty) { + constexpr TPM_PT kProperty = 0x2FF; TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.GetTpmProperty(kProperty, nullptr)); + uint32_t value; + EXPECT_FALSE(tpm_state.GetTpmProperty(kProperty, &value)); + + fake_tpm_properties_[kProperty] = 1234; + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_TRUE(tpm_state.GetTpmProperty(kProperty, nullptr)); + EXPECT_TRUE(tpm_state.GetTpmProperty(kProperty, &value)); + EXPECT_EQ(value, fake_tpm_properties_[kProperty]); } -TEST_F(TpmStateTest, BadResponseLockoutCounterPropertyType) { - lockout_counter_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; +TEST_F(TpmStateTest, RawAlgorithmProperties) { + constexpr TPM_ALG_ID kAlgorithm = 0x39; TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_FALSE(tpm_state.GetAlgorithmProperties(kAlgorithm, nullptr)); + uint32_t value; + EXPECT_FALSE(tpm_state.GetAlgorithmProperties(kAlgorithm, &value)); + + fake_algorithm_properties_[kAlgorithm] = 1234; + TpmStateImpl tpm_state2(factory_); + ASSERT_EQ(TPM_RC_SUCCESS, tpm_state2.Initialize()); + EXPECT_TRUE(tpm_state2.GetAlgorithmProperties(kAlgorithm, nullptr)); + EXPECT_TRUE(tpm_state2.GetAlgorithmProperties(kAlgorithm, &value)); + EXPECT_EQ(value, fake_algorithm_properties_[kAlgorithm]); } -TEST_F(TpmStateTest, BadResponseLockoutThresholdPropertyType) { - lockout_threshold_.data.tpm_properties.tpm_property[0].property = 0xFFFFF; +TEST_F(TpmStateTest, InitFailOnMissingPermanentFlags) { + fake_tpm_properties_.erase(TPM_PT_PERMANENT); 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; +TEST_F(TpmStateTest, InitFailOnMissingStartupClearFlags) { + fake_tpm_properties_.erase(TPM_PT_STARTUP_CLEAR); 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; +TEST_F(TpmStateTest, InitFailOnFailedTPMCommand) { + EXPECT_CALL(mock_tpm_, GetCapabilitySync(_, _, _, _, _, _)) + .WillRepeatedly(Return(TPM_RC_FAILURE)); TpmStateImpl tpm_state(factory_); - EXPECT_NE(TPM_RC_SUCCESS, tpm_state.Initialize()); + EXPECT_EQ(TPM_RC_FAILURE, tpm_state.Initialize()); } } // namespace trunks diff --git a/trunks/trunks_factory_for_test.cc b/trunks/trunks_factory_for_test.cc index f18bb0d..792adf9 100644 --- a/trunks/trunks_factory_for_test.cc +++ b/trunks/trunks_factory_for_test.cc @@ -97,6 +97,17 @@ class TpmStateForwarder : public TpmState { return target_->GetLockoutRecovery(); } + uint32_t GetMaxNVSize() override { return target_->GetMaxNVSize(); } + + bool GetTpmProperty(TPM_PT property, uint32_t* value) override { + return target_->GetTpmProperty(property, value); + } + + bool GetAlgorithmProperties(TPM_ALG_ID algorithm, + TPMA_ALGORITHM* properties) override { + return target_->GetAlgorithmProperties(algorithm, properties); + } + private: TpmState* target_; }; @@ -576,7 +587,7 @@ std::unique_ptr<PolicySession> TrunksFactoryForTest::GetPolicySession() const { } std::unique_ptr<PolicySession> TrunksFactoryForTest::GetTrialSession() const { - return base::MakeUnique<PolicySessionForwarder>(policy_session_); + return base::MakeUnique<PolicySessionForwarder>(trial_session_); } std::unique_ptr<BlobParser> TrunksFactoryForTest::GetBlobParser() const { diff --git a/trunks/trunksd-seccomp-amd64.policy b/trunks/trunksd-seccomp-amd64.policy index aa8650b..fa8db09 100644 --- a/trunks/trunksd-seccomp-amd64.policy +++ b/trunks/trunksd-seccomp-amd64.policy @@ -78,6 +78,7 @@ rt_sigprocmask: 1 signalfd4: 1 ioctl: 1 getpriority: 1 +setpriority: 1 exit: 1 exit_group: 1 chdir: 1 diff --git a/trunks/trunksd-seccomp-arm.policy b/trunks/trunksd-seccomp-arm.policy index 40b0c1a..cc9e2b7 100644 --- a/trunks/trunksd-seccomp-arm.policy +++ b/trunks/trunksd-seccomp-arm.policy @@ -72,6 +72,7 @@ rt_sigprocmask: 1 signalfd4: 1 ioctl: 1 getpriority: 1 +setpriority: 1 exit: 1 exit_group: 1 chdir: 1 diff --git a/trunks/trunksd-seccomp-arm64.policy b/trunks/trunksd-seccomp-arm64.policy index 7581d3c..12d4a31 100644 --- a/trunks/trunksd-seccomp-arm64.policy +++ b/trunks/trunksd-seccomp-arm64.policy @@ -72,6 +72,7 @@ rt_sigprocmask: 1 signalfd4: 1 ioctl: 1 getpriority: 1 +setpriority: 1 exit: 1 exit_group: 1 chdir: 1 diff --git a/trunks/trunksd-seccomp-mips.policy b/trunks/trunksd-seccomp-mips.policy index f6ca4da..24b78b5 100644 --- a/trunks/trunksd-seccomp-mips.policy +++ b/trunks/trunksd-seccomp-mips.policy @@ -76,4 +76,3 @@ setpriority: 1 exit: 1 exit_group: 1 chdir: 1 - diff --git a/trunks/trunksd-seccomp-x86.policy b/trunks/trunksd-seccomp-x86.policy index 575ccb8..b525b5f 100644 --- a/trunks/trunksd-seccomp-x86.policy +++ b/trunks/trunksd-seccomp-x86.policy @@ -79,6 +79,7 @@ rt_sigprocmask: 1 signalfd4: 1 ioctl: 1 getpriority: 1 +setpriority: 1 exit: 1 exit_group: 1 chdir: 1 diff --git a/trunks/trunksd-seccomp-x86_64.policy b/trunks/trunksd-seccomp-x86_64.policy index aa8650b..fa8db09 100644 --- a/trunks/trunksd-seccomp-x86_64.policy +++ b/trunks/trunksd-seccomp-x86_64.policy @@ -78,6 +78,7 @@ rt_sigprocmask: 1 signalfd4: 1 ioctl: 1 getpriority: 1 +setpriority: 1 exit: 1 exit_group: 1 chdir: 1 |