diff options
author | Utkarsh Sanghi <usanghi@google.com> | 2015-10-01 10:42:10 -0700 |
---|---|---|
committer | Utkarsh Sanghi <usanghi@google.com> | 2015-10-05 13:38:45 -0700 |
commit | 37fb0f8c79ba0780b9a9b68082fd67dcc3ccb55d (patch) | |
tree | 34dbf99a9f62f1628131d70af41f13b93f2b93a0 | |
parent | c8cf2c675145a50025e714b1d4d96492216715d4 (diff) | |
download | tpm_manager-37fb0f8c79ba0780b9a9b68082fd67dcc3ccb55d.tar.gz |
tpm_manager: Define the NVRAM API surface
This CL adds the NVRAM API to the TpmManager DBus interface.
This CL also implements the TpmManagerService to perform these
operations.
Bug: 24059570
TEST=FEATURES=test emerge-link tpm_manager
Change-Id: Ia9f26fde4c6acbd7bc568ddd5ac644b680c580b2
-rw-r--r-- | common/dbus_interface.h | 7 | ||||
-rw-r--r-- | common/dbus_interface.proto | 76 | ||||
-rw-r--r-- | common/mock_tpm_manager_interface.h | 21 | ||||
-rw-r--r-- | common/print_dbus_interface_proto.cc | 314 | ||||
-rw-r--r-- | common/print_dbus_interface_proto.h | 42 | ||||
-rw-r--r-- | common/tpm_manager_interface.h | 36 | ||||
-rw-r--r-- | server/main.cc | 4 | ||||
-rw-r--r-- | server/mock_tpm_nvram.cc | 30 | ||||
-rw-r--r-- | server/mock_tpm_nvram.h | 12 | ||||
-rw-r--r-- | server/tpm_manager_service.cc | 184 | ||||
-rw-r--r-- | server/tpm_manager_service.h | 79 | ||||
-rw-r--r-- | server/tpm_manager_service_test.cc | 234 | ||||
-rw-r--r-- | server/tpm_nvram.h | 17 |
13 files changed, 991 insertions, 65 deletions
diff --git a/common/dbus_interface.h b/common/dbus_interface.h index 8acdb36..d8ebc24 100644 --- a/common/dbus_interface.h +++ b/common/dbus_interface.h @@ -26,6 +26,13 @@ constexpr char kTpmManagerServiceName[] = "org.chromium.TpmManager"; // Methods exported by tpm_manager. constexpr char kGetTpmStatus[] = "GetTpmStatus"; constexpr char kTakeOwnership[] = "TakeOwnership"; +constexpr char kDefineNvram[] = "DefineNvram"; +constexpr char kDestroyNvram[] = "DestroyNvram"; +constexpr char kWriteNvram[] = "WriteNvram"; +constexpr char kReadNvram[] = "ReadNvram"; +constexpr char kIsNvramDefined[] = "IsNvramDefined"; +constexpr char kIsNvramLocked[] = "IsNvramLocked"; +constexpr char kGetNvramSize[] = "GetNvramSize"; } // namespace tpm_manager diff --git a/common/dbus_interface.proto b/common/dbus_interface.proto index 216bda5..a875565 100644 --- a/common/dbus_interface.proto +++ b/common/dbus_interface.proto @@ -42,3 +42,79 @@ message TakeOwnershipRequest { message TakeOwnershipReply { optional TpmManagerStatus status = 1; } + +// Input for the DefineNvram method. +message DefineNvramRequest { + optional int32 index = 1; + optional int32 length = 2; +} + +// Output for the DefineNvram method. +message DefineNvramReply { + optional TpmManagerStatus status = 1; +} + +// Input for the DestroyNvram method. +message DestroyNvramRequest { + optional int32 index = 1; +} + +// Output for the DestroyNvram method. +message DestroyNvramReply { + optional TpmManagerStatus status = 1; +} + +// Input for the WriteNvram method. +message WriteNvramRequest { + optional int32 index = 1; + optional bytes data = 2; +} + +// Output for the WriteNvram method. +message WriteNvramReply { + optional TpmManagerStatus status = 1; +} + +// Input for the ReadNvram method. +message ReadNvramRequest { + optional int32 index = 1; +} + +// Output for the ReadNvram method. +message ReadNvramReply { + optional TpmManagerStatus status = 1; + optional bytes data = 2; +} + +// Input for the IsNvramDefined method. +message IsNvramDefinedRequest { + optional int32 index = 1; +} + +// Output for the IsNvramDefined method. +message IsNvramDefinedReply { + optional TpmManagerStatus status = 1; + optional bool is_defined = 2; +} + +// Input for the IsNvramLocked method. +message IsNvramLockedRequest { + optional int32 index = 1; +} + +// Output for the IsNvramLocked method. +message IsNvramLockedReply { + optional TpmManagerStatus status = 1; + optional bool is_locked = 2; +} + +// Input for the GetNvramSize method. +message GetNvramSizeRequest { + optional int32 index = 1; +} + +// Output for the GetNvramSize method. +message GetNvramSizeReply { + optional TpmManagerStatus status = 1; + optional int32 size = 2; +} diff --git a/common/mock_tpm_manager_interface.h b/common/mock_tpm_manager_interface.h index 1e1102b..8246754 100644 --- a/common/mock_tpm_manager_interface.h +++ b/common/mock_tpm_manager_interface.h @@ -35,6 +35,27 @@ class MockTpmManagerInterface : public TpmManagerInterface { MOCK_METHOD2(TakeOwnership, void(const TakeOwnershipRequest& request, const TakeOwnershipCallback& callback)); + MOCK_METHOD2(DefineNvram, + void(const DefineNvramRequest& request, + const DefineNvramCallback& callback)); + MOCK_METHOD2(DestroyNvram, + void(const DestroyNvramRequest& request, + const DestroyNvramCallback& callback)); + MOCK_METHOD2(WriteNvram, + void(const WriteNvramRequest& request, + const WriteNvramCallback& callback)); + MOCK_METHOD2(ReadNvram, + void(const ReadNvramRequest& request, + const ReadNvramCallback& callback)); + MOCK_METHOD2(IsNvramDefined, + void(const IsNvramDefinedRequest& request, + const IsNvramDefinedCallback& callback)); + MOCK_METHOD2(IsNvramLocked, + void(const IsNvramLockedRequest& request, + const IsNvramLockedCallback& callback)); + MOCK_METHOD2(GetNvramSize, + void(const GetNvramSizeRequest& request, + const GetNvramSizeCallback& callback)); }; } // namespace tpm_manager diff --git a/common/print_dbus_interface_proto.cc b/common/print_dbus_interface_proto.cc index 03d8638..3138b7a 100644 --- a/common/print_dbus_interface_proto.cc +++ b/common/print_dbus_interface_proto.cc @@ -155,4 +155,318 @@ std::string GetProtoDebugStringWithIndent(const TakeOwnershipReply& value, return output; } +std::string GetProtoDebugString(const DefineNvramRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const DefineNvramRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + if (value.has_length()) { + output += indent + " length: "; + base::StringAppendF(&output, "%d", value.length()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const DefineNvramReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const DefineNvramReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const DestroyNvramRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const DestroyNvramRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const DestroyNvramReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const DestroyNvramReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const WriteNvramRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const WriteNvramRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + if (value.has_data()) { + output += indent + " data: "; + base::StringAppendF( + &output, "%s", + base::HexEncode(value.data().data(), value.data().size()).c_str()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const WriteNvramReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const WriteNvramReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const ReadNvramRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const ReadNvramRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const ReadNvramReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const ReadNvramReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + if (value.has_data()) { + output += indent + " data: "; + base::StringAppendF( + &output, "%s", + base::HexEncode(value.data().data(), value.data().size()).c_str()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const IsNvramDefinedRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const IsNvramDefinedRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const IsNvramDefinedReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const IsNvramDefinedReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + if (value.has_is_defined()) { + output += indent + " is_defined: "; + base::StringAppendF(&output, "%s", value.is_defined() ? "true" : "false"); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const IsNvramLockedRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const IsNvramLockedRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const IsNvramLockedReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const IsNvramLockedReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + if (value.has_is_locked()) { + output += indent + " is_locked: "; + base::StringAppendF(&output, "%s", value.is_locked() ? "true" : "false"); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const GetNvramSizeRequest& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const GetNvramSizeRequest& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_index()) { + output += indent + " index: "; + base::StringAppendF(&output, "%d", value.index()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + +std::string GetProtoDebugString(const GetNvramSizeReply& value) { + return GetProtoDebugStringWithIndent(value, 0); +} + +std::string GetProtoDebugStringWithIndent(const GetNvramSizeReply& value, + int indent_size) { + std::string indent(indent_size, ' '); + std::string output = + base::StringPrintf("[%s] {\n", value.GetTypeName().c_str()); + + if (value.has_status()) { + output += indent + " status: "; + base::StringAppendF( + &output, "%s", + GetProtoDebugStringWithIndent(value.status(), indent_size + 2).c_str()); + output += "\n"; + } + if (value.has_size()) { + output += indent + " size: "; + base::StringAppendF(&output, "%d", value.size()); + output += "\n"; + } + output += indent + "}\n"; + return output; +} + } // namespace tpm_manager diff --git a/common/print_dbus_interface_proto.h b/common/print_dbus_interface_proto.h index d57f335..f5a394a 100644 --- a/common/print_dbus_interface_proto.h +++ b/common/print_dbus_interface_proto.h @@ -40,6 +40,48 @@ std::string GetProtoDebugString(const TakeOwnershipRequest& value); std::string GetProtoDebugStringWithIndent(const TakeOwnershipReply& value, int indent_size); std::string GetProtoDebugString(const TakeOwnershipReply& value); +std::string GetProtoDebugStringWithIndent(const DefineNvramRequest& value, + int indent_size); +std::string GetProtoDebugString(const DefineNvramRequest& value); +std::string GetProtoDebugStringWithIndent(const DefineNvramReply& value, + int indent_size); +std::string GetProtoDebugString(const DefineNvramReply& value); +std::string GetProtoDebugStringWithIndent(const DestroyNvramRequest& value, + int indent_size); +std::string GetProtoDebugString(const DestroyNvramRequest& value); +std::string GetProtoDebugStringWithIndent(const DestroyNvramReply& value, + int indent_size); +std::string GetProtoDebugString(const DestroyNvramReply& value); +std::string GetProtoDebugStringWithIndent(const WriteNvramRequest& value, + int indent_size); +std::string GetProtoDebugString(const WriteNvramRequest& value); +std::string GetProtoDebugStringWithIndent(const WriteNvramReply& value, + int indent_size); +std::string GetProtoDebugString(const WriteNvramReply& value); +std::string GetProtoDebugStringWithIndent(const ReadNvramRequest& value, + int indent_size); +std::string GetProtoDebugString(const ReadNvramRequest& value); +std::string GetProtoDebugStringWithIndent(const ReadNvramReply& value, + int indent_size); +std::string GetProtoDebugString(const ReadNvramReply& value); +std::string GetProtoDebugStringWithIndent(const IsNvramDefinedRequest& value, + int indent_size); +std::string GetProtoDebugString(const IsNvramDefinedRequest& value); +std::string GetProtoDebugStringWithIndent(const IsNvramDefinedReply& value, + int indent_size); +std::string GetProtoDebugString(const IsNvramDefinedReply& value); +std::string GetProtoDebugStringWithIndent(const IsNvramLockedRequest& value, + int indent_size); +std::string GetProtoDebugString(const IsNvramLockedRequest& value); +std::string GetProtoDebugStringWithIndent(const IsNvramLockedReply& value, + int indent_size); +std::string GetProtoDebugString(const IsNvramLockedReply& value); +std::string GetProtoDebugStringWithIndent(const GetNvramSizeRequest& value, + int indent_size); +std::string GetProtoDebugString(const GetNvramSizeRequest& value); +std::string GetProtoDebugStringWithIndent(const GetNvramSizeReply& value, + int indent_size); +std::string GetProtoDebugString(const GetNvramSizeReply& value); } // namespace tpm_manager diff --git a/common/tpm_manager_interface.h b/common/tpm_manager_interface.h index 341a200..967f2a2 100644 --- a/common/tpm_manager_interface.h +++ b/common/tpm_manager_interface.h @@ -43,6 +43,42 @@ class TPM_MANAGER_EXPORT TpmManagerInterface { using TakeOwnershipCallback = base::Callback<void(const TakeOwnershipReply&)>; virtual void TakeOwnership(const TakeOwnershipRequest& request, const TakeOwnershipCallback& callback) = 0; + + // Processes a DefineNvramRequest and responds with a DefineNvramReply. + using DefineNvramCallback = base::Callback<void(const DefineNvramReply&)>; + virtual void DefineNvram(const DefineNvramRequest& request, + const DefineNvramCallback& callback) = 0; + + // Processes a DestroyNvramRequest and responds with a DestroyNvramReply. + using DestroyNvramCallback = base::Callback<void(const DestroyNvramReply&)>; + virtual void DestroyNvram(const DestroyNvramRequest& request, + const DestroyNvramCallback& callback) = 0; + + // Processes a WriteNvramRequest and responds with a WriteNvramReply. + using WriteNvramCallback = base::Callback<void(const WriteNvramReply&)>; + virtual void WriteNvram(const WriteNvramRequest& request, + const WriteNvramCallback& callback) = 0; + + // Processes a ReadNvramRequest and responds with a ReadNvramReply. + using ReadNvramCallback = base::Callback<void(const ReadNvramReply&)>; + virtual void ReadNvram(const ReadNvramRequest& request, + const ReadNvramCallback& callback) = 0; + + // Processes a IsNvramDefinedRequest and responds with a IsNvramDefinedReply. + using IsNvramDefinedCallback = + base::Callback<void(const IsNvramDefinedReply&)>; + virtual void IsNvramDefined(const IsNvramDefinedRequest& request, + const IsNvramDefinedCallback& callback) = 0; + + // Processes a IsNvramLockedRequest and responds with a IsNvramLockedReply. + using IsNvramLockedCallback = base::Callback<void(const IsNvramLockedReply&)>; + virtual void IsNvramLocked(const IsNvramLockedRequest& request, + const IsNvramLockedCallback& callback) = 0; + + // Processes a GetNvramSizeRequest and responds with a GetNvramSizeReply. + using GetNvramSizeCallback = base::Callback<void(const GetNvramSizeReply&)>; + virtual void GetNvramSize(const GetNvramSizeRequest& request, + const GetNvramSizeCallback& callback) = 0; }; } // namespace tpm_manager diff --git a/server/main.cc b/server/main.cc index e9726d5..ce87bc0 100644 --- a/server/main.cc +++ b/server/main.cc @@ -64,7 +64,8 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon { command_line->HasSwitch(kWaitForOwnershipTriggerSwitch), local_data_store_.get(), tpm_status_.get(), - tpm_initializer_.get())); + tpm_initializer_.get(), + tpm_nvram_.get())); } protected: @@ -88,6 +89,7 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon { std::unique_ptr<tpm_manager::LocalDataStore> local_data_store_; std::unique_ptr<tpm_manager::TpmStatus> tpm_status_; std::unique_ptr<tpm_manager::TpmInitializer> tpm_initializer_; + std::unique_ptr<tpm_manager::TpmNvram> tpm_nvram_; std::unique_ptr<tpm_manager::TpmManagerInterface> tpm_manager_service_; std::unique_ptr<tpm_manager::DBusService> dbus_service_; diff --git a/server/mock_tpm_nvram.cc b/server/mock_tpm_nvram.cc index c7b6743..1cc6a77 100644 --- a/server/mock_tpm_nvram.cc +++ b/server/mock_tpm_nvram.cc @@ -31,11 +31,11 @@ MockTpmNvram::MockTpmNvram() { .WillByDefault(Invoke(this, &MockTpmNvram::FakeWriteNvram)); ON_CALL(*this, ReadNvram(_, _)) .WillByDefault(Invoke(this, &MockTpmNvram::FakeReadNvram)); - ON_CALL(*this, IsNvramDefined(_)) + ON_CALL(*this, IsNvramDefined(_, _)) .WillByDefault(Invoke(this, &MockTpmNvram::FakeIsNvramDefined)); - ON_CALL(*this, IsNvramLocked(_)) + ON_CALL(*this, IsNvramLocked(_, _)) .WillByDefault(Invoke(this, &MockTpmNvram::FakeIsNvramLocked)); - ON_CALL(*this, GetNvramSize(_)) + ON_CALL(*this, GetNvramSize(_, _)) .WillByDefault(Invoke(this, &MockTpmNvram::FakeGetNvramSize)); } @@ -88,19 +88,27 @@ bool MockTpmNvram::FakeReadNvram(uint32_t index, std::string* data) { return true; } -bool MockTpmNvram::FakeIsNvramDefined(uint32_t index) { - return (nvram_map_.find(index) != nvram_map_.end()); +bool MockTpmNvram::FakeIsNvramDefined(uint32_t index, bool* defined) { + *defined = (nvram_map_.find(index) != nvram_map_.end()); + return true; } -bool MockTpmNvram::FakeIsNvramLocked(uint32_t index) { - return IsNvramDefined(index) && nvram_map_[index].written; +bool MockTpmNvram::FakeIsNvramLocked(uint32_t index, bool* locked) { + bool defined; + if (!IsNvramDefined(index, &defined) || !defined) { + return false; + } + *locked = nvram_map_[index].written; + return true; } -size_t MockTpmNvram::FakeGetNvramSize(uint32_t index) { - if (!IsNvramDefined(index)) { - return 0; +bool MockTpmNvram::FakeGetNvramSize(uint32_t index, size_t* size) { + bool defined; + if (!IsNvramDefined(index, &defined) || !defined) { + return false; } - return nvram_map_[index].data.size(); + *size = nvram_map_[index].data.size(); + return true; } } // namespace tpm_manager diff --git a/server/mock_tpm_nvram.h b/server/mock_tpm_nvram.h index 57b06e7..eafe413 100644 --- a/server/mock_tpm_nvram.h +++ b/server/mock_tpm_nvram.h @@ -40,18 +40,18 @@ class MockTpmNvram : public TpmNvram { MOCK_METHOD1(DestroyNvram, bool(uint32_t)); MOCK_METHOD2(WriteNvram, bool(uint32_t, const std::string&)); MOCK_METHOD2(ReadNvram, bool(uint32_t, std::string*)); - MOCK_METHOD1(IsNvramDefined, bool(uint32_t)); - MOCK_METHOD1(IsNvramLocked, bool(uint32_t)); - MOCK_METHOD1(GetNvramSize, size_t(uint32_t)); + MOCK_METHOD2(IsNvramDefined, bool(uint32_t, bool*)); + MOCK_METHOD2(IsNvramLocked, bool(uint32_t, bool*)); + MOCK_METHOD2(GetNvramSize, bool(uint32_t, size_t*)); private: bool FakeDefineNvram(uint32_t index, size_t length); bool FakeDestroyNvram(uint32_t index); bool FakeWriteNvram(uint32_t index, const std::string& data); bool FakeReadNvram(uint32_t index, std::string* data); - bool FakeIsNvramDefined(uint32_t index); - bool FakeIsNvramLocked(uint32_t index); - size_t FakeGetNvramSize(uint32_t index); + bool FakeIsNvramDefined(uint32_t index, bool* defined); + bool FakeIsNvramLocked(uint32_t index, bool* locked); + bool FakeGetNvramSize(uint32_t index, size_t* size); std::map<uint32_t, NvSpace> nvram_map_; }; diff --git a/server/tpm_manager_service.cc b/server/tpm_manager_service.cc index 272fff1..ca0107a 100644 --- a/server/tpm_manager_service.cc +++ b/server/tpm_manager_service.cc @@ -25,13 +25,14 @@ namespace tpm_manager { TpmManagerService::TpmManagerService(bool wait_for_ownership, LocalDataStore* local_data_store, TpmStatus* tpm_status, - TpmInitializer* tpm_initializer) + TpmInitializer* tpm_initializer, + TpmNvram* tpm_nvram) : local_data_store_(local_data_store), tpm_status_(tpm_status), tpm_initializer_(tpm_initializer), + tpm_nvram_(tpm_nvram), wait_for_ownership_(wait_for_ownership), - weak_factory_(this) { -} + weak_factory_(this) {} bool TpmManagerService::Initialize() { LOG(INFO) << "TpmManager service started."; @@ -60,15 +61,8 @@ void TpmManagerService::InitializeTask() { void TpmManagerService::GetTpmStatus(const GetTpmStatusRequest& request, const GetTpmStatusCallback& callback) { - auto result = std::make_shared<GetTpmStatusReply>(); - base::Closure task = base::Bind(&TpmManagerService::GetTpmStatusTask, - base::Unretained(this), request, result); - base::Closure reply = base::Bind( - &TpmManagerService::TaskRelayCallback<GetTpmStatusReply>, - weak_factory_.GetWeakPtr(), - callback, - result); - worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); + PostTaskToWorkerThread<GetTpmStatusReply>( + request, callback, &TpmManagerService::GetTpmStatusTask); } void TpmManagerService::GetTpmStatusTask( @@ -93,19 +87,13 @@ void TpmManagerService::GetTpmStatusTask( result->set_dictionary_attack_lockout_seconds_remaining( lockout_time_remaining); } + result->set_status(STATUS_SUCCESS); } void TpmManagerService::TakeOwnership(const TakeOwnershipRequest& request, const TakeOwnershipCallback& callback) { - auto result = std::make_shared<TakeOwnershipReply>(); - base::Closure task = base::Bind(&TpmManagerService::TakeOwnershipTask, - base::Unretained(this), request, result); - base::Closure reply = base::Bind( - &TpmManagerService::TaskRelayCallback<TakeOwnershipReply>, - weak_factory_.GetWeakPtr(), - callback, - result); - worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, task, reply); + PostTaskToWorkerThread<TakeOwnershipReply>( + request, callback, &TpmManagerService::TakeOwnershipTask); } void TpmManagerService::TakeOwnershipTask( @@ -123,4 +111,158 @@ void TpmManagerService::TakeOwnershipTask( result->set_status(STATUS_SUCCESS); } +void TpmManagerService::DefineNvram(const DefineNvramRequest& request, + const DefineNvramCallback& callback) { + PostTaskToWorkerThread<DefineNvramReply>( + request, callback, &TpmManagerService::DefineNvramTask); +} + +void TpmManagerService::DefineNvramTask( + const DefineNvramRequest& request, + const std::shared_ptr<DefineNvramReply>& result) { + VLOG(1) << __func__; + if (!tpm_nvram_->DefineNvram(request.index(), request.length())) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::DestroyNvram(const DestroyNvramRequest& request, + const DestroyNvramCallback& callback) { + PostTaskToWorkerThread<DestroyNvramReply>( + request, callback, &TpmManagerService::DestroyNvramTask); +} + +void TpmManagerService::DestroyNvramTask( + const DestroyNvramRequest& request, + const std::shared_ptr<DestroyNvramReply>& result) { + VLOG(1) << __func__; + if (!tpm_nvram_->DestroyNvram(request.index())) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::WriteNvram(const WriteNvramRequest& request, + const WriteNvramCallback& callback) { + PostTaskToWorkerThread<WriteNvramReply>( + request, callback, &TpmManagerService::WriteNvramTask); +} + +void TpmManagerService::WriteNvramTask( + const WriteNvramRequest& request, + const std::shared_ptr<WriteNvramReply>& result) { + VLOG(1) << __func__; + if (!tpm_nvram_->WriteNvram(request.index(), request.data())) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::ReadNvram(const ReadNvramRequest& request, + const ReadNvramCallback& callback) { + PostTaskToWorkerThread<ReadNvramReply>( + request, callback, &TpmManagerService::ReadNvramTask); +} + +void TpmManagerService::ReadNvramTask( + const ReadNvramRequest& request, + const std::shared_ptr<ReadNvramReply>& result) { + VLOG(1) << __func__; + if (!tpm_nvram_->ReadNvram(request.index(), result->mutable_data())) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::IsNvramDefined(const IsNvramDefinedRequest& request, + const IsNvramDefinedCallback& callback) { + PostTaskToWorkerThread<IsNvramDefinedReply>( + request, callback, &TpmManagerService::IsNvramDefinedTask); +} + +void TpmManagerService::IsNvramDefinedTask( + const IsNvramDefinedRequest& request, + const std::shared_ptr<IsNvramDefinedReply>& result) { + VLOG(1) << __func__; + bool defined; + if (!tpm_nvram_->IsNvramDefined(request.index(), &defined)) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_is_defined(defined); + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::IsNvramLocked(const IsNvramLockedRequest& request, + const IsNvramLockedCallback& callback) { + PostTaskToWorkerThread<IsNvramLockedReply>( + request, callback, &TpmManagerService::IsNvramLockedTask); +} + +void TpmManagerService::IsNvramLockedTask( + const IsNvramLockedRequest& request, + const std::shared_ptr<IsNvramLockedReply>& result) { + VLOG(1) << __func__; + bool locked; + if (!tpm_nvram_->IsNvramLocked(request.index(), &locked)) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_is_locked(locked); + result->set_status(STATUS_SUCCESS); +} + +void TpmManagerService::GetNvramSize(const GetNvramSizeRequest& request, + const GetNvramSizeCallback& callback) { + PostTaskToWorkerThread<GetNvramSizeReply>( + request, callback, &TpmManagerService::GetNvramSizeTask); +} + +void TpmManagerService::GetNvramSizeTask( + const GetNvramSizeRequest& request, + const std::shared_ptr<GetNvramSizeReply>& result) { + VLOG(1) << __func__; + size_t size; + if (!tpm_nvram_->GetNvramSize(request.index(), &size)) { + result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR); + return; + } + result->set_size(size); + result->set_status(STATUS_SUCCESS); +} + +template<typename ReplyProtobufType> +void TpmManagerService::TaskRelayCallback( + const base::Callback<void(const ReplyProtobufType&)> callback, + const std::shared_ptr<ReplyProtobufType>& reply) { + callback.Run(*reply); +} + +template<typename ReplyProtobufType, + typename RequestProtobufType, + typename ReplyCallbackType, + typename TaskType> +void TpmManagerService::PostTaskToWorkerThread(RequestProtobufType& request, + ReplyCallbackType& callback, + TaskType task) { + auto result = std::make_shared<ReplyProtobufType>(); + base::Closure background_task = base::Bind(task, + base::Unretained(this), + request, + result); + base::Closure reply = base::Bind( + &TpmManagerService::TaskRelayCallback<ReplyProtobufType>, + weak_factory_.GetWeakPtr(), + callback, + result); + worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, + background_task, + reply); +} + } // namespace tpm_manager diff --git a/server/tpm_manager_service.h b/server/tpm_manager_service.h index bf98048..6871436 100644 --- a/server/tpm_manager_service.h +++ b/server/tpm_manager_service.h @@ -29,6 +29,7 @@ #include "tpm_manager/server/local_data_store.h" #include "tpm_manager/server/tpm_initializer.h" +#include "tpm_manager/server/tpm_nvram.h" #include "tpm_manager/server/tpm_status.h" namespace tpm_manager { @@ -59,7 +60,8 @@ class TpmManagerService : public TpmManagerInterface { explicit TpmManagerService(bool wait_for_ownership, LocalDataStore* local_data_store, TpmStatus* tpm_status, - TpmInitializer* tpm_initializer); + TpmInitializer* tpm_initializer, + TpmNvram* tpm_nvram); ~TpmManagerService() override = default; // TpmManagerInterface methods. @@ -68,6 +70,20 @@ class TpmManagerService : public TpmManagerInterface { const GetTpmStatusCallback& callback) override; void TakeOwnership(const TakeOwnershipRequest& request, const TakeOwnershipCallback& callback) override; + void DefineNvram(const DefineNvramRequest& request, + const DefineNvramCallback& callback) override; + void DestroyNvram(const DestroyNvramRequest& request, + const DestroyNvramCallback& callback) override; + void WriteNvram(const WriteNvramRequest& request, + const WriteNvramCallback& callback) override; + void ReadNvram(const ReadNvramRequest& request, + const ReadNvramCallback& callback) override; + void IsNvramDefined(const IsNvramDefinedRequest& request, + const IsNvramDefinedCallback& callback) override; + void IsNvramLocked(const IsNvramLockedRequest& request, + const IsNvramLockedCallback& callback) override; + void GetNvramSize(const GetNvramSizeRequest& request, + const GetNvramSizeCallback& callback) override; private: // A relay callback which allows the use of weak pointer semantics for a reply @@ -75,9 +91,24 @@ class TpmManagerService : public TpmManagerInterface { template<typename ReplyProtobufType> void TaskRelayCallback( const base::Callback<void(const ReplyProtobufType&)> callback, - const std::shared_ptr<ReplyProtobufType>& reply) { - callback.Run(*reply); - } + const std::shared_ptr<ReplyProtobufType>& reply); + + // This templated method posts the provided |TaskType| to the background + // thread with the provided |RequestProtobufType|. When |TaskType| finishes + // executing, the |ReplyCallbackType| is called with the |ReplyProtobufType|. + template<typename ReplyProtobufType, + typename RequestProtobufType, + typename ReplyCallbackType, + typename TaskType> + void PostTaskToWorkerThread(RequestProtobufType& request, + ReplyCallbackType& callback, + TaskType task); + + // Synchronously initializes the TPM according to the current configuration. + // If an initialization process was interrupted it will be continued. If the + // TPM is already initialized or cannot yet be initialized, this method has no + // effect. + void InitializeTask(); // Blocking implementation of GetTpmStatus that can be executed on the // background worker thread. @@ -89,15 +120,45 @@ class TpmManagerService : public TpmManagerInterface { void TakeOwnershipTask(const TakeOwnershipRequest& request, const std::shared_ptr<TakeOwnershipReply>& result); - // Synchronously initializes the TPM according to the current configuration. - // If an initialization process was interrupted it will be continued. If the - // TPM is already initialized or cannot yet be initialized, this method has no - // effect. - void InitializeTask(); + // Blocking implementation of DefineNvram that can be executed on the + // background worker thread. + void DefineNvramTask(const DefineNvramRequest& request, + const std::shared_ptr<DefineNvramReply>& result); + + // Blocking implementation of DestroyNvram that can be executed on the + // background worker thread. + void DestroyNvramTask(const DestroyNvramRequest& request, + const std::shared_ptr<DestroyNvramReply>& result); + + // Blocking implementation of WriteNvram that can be executed on the + // background worker thread. + void WriteNvramTask(const WriteNvramRequest& request, + const std::shared_ptr<WriteNvramReply>& result); + + // Blocking implementation of ReadNvram that can be executed on the + // background worker thread. + void ReadNvramTask(const ReadNvramRequest& request, + const std::shared_ptr<ReadNvramReply>& result); + + // Blocking implementation of IsNvramDefined that can be executed on the + // background worker thread. + void IsNvramDefinedTask(const IsNvramDefinedRequest& request, + const std::shared_ptr<IsNvramDefinedReply>& result); + + // Blocking implementation of IsNvramLocked that can be executed on the + // background worker thread. + void IsNvramLockedTask(const IsNvramLockedRequest& request, + const std::shared_ptr<IsNvramLockedReply>& result); + + // Blocking implementation of GetNvramSize that can be executed on the + // background worker thread. + void GetNvramSizeTask(const GetNvramSizeRequest& request, + const std::shared_ptr<GetNvramSizeReply>& result); LocalDataStore* local_data_store_; TpmStatus* tpm_status_; TpmInitializer* tpm_initializer_; + TpmNvram* tpm_nvram_; // Whether to wait for an explicit call to 'TakeOwnership' before initializing // the TPM. Normally tracks the --wait_for_ownership command line option. bool wait_for_ownership_; diff --git a/server/tpm_manager_service_test.cc b/server/tpm_manager_service_test.cc index 85a5c62..0ef9887 100644 --- a/server/tpm_manager_service_test.cc +++ b/server/tpm_manager_service_test.cc @@ -20,6 +20,7 @@ #include "tpm_manager/server/mock_local_data_store.h" #include "tpm_manager/server/mock_tpm_initializer.h" +#include "tpm_manager/server/mock_tpm_nvram.h" #include "tpm_manager/server/mock_tpm_status.h" #include "tpm_manager/server/tpm_manager_service.h" @@ -41,7 +42,8 @@ class TpmManagerServiceTest : public testing::Test { service_.reset(new TpmManagerService(true /*wait_for_ownership*/, &mock_local_data_store_, &mock_tpm_status_, - &mock_tpm_initializer_)); + &mock_tpm_initializer_, + &mock_tpm_nvram_)); SetupService(); } @@ -71,6 +73,7 @@ class TpmManagerServiceTest : public testing::Test { NiceMock<MockLocalDataStore> mock_local_data_store_; NiceMock<MockTpmInitializer> mock_tpm_initializer_; + NiceMock<MockTpmNvram> mock_tpm_nvram_; NiceMock<MockTpmStatus> mock_tpm_status_; std::unique_ptr<TpmManagerService> service_; @@ -87,7 +90,8 @@ class TpmManagerServiceTest_NoWaitForOwnership : public TpmManagerServiceTest { service_.reset(new TpmManagerService(false /*wait_for_ownership*/, &mock_local_data_store_, &mock_tpm_status_, - &mock_tpm_initializer_)); + &mock_tpm_initializer_, + &mock_tpm_nvram_)); } }; @@ -112,6 +116,19 @@ TEST_F(TpmManagerServiceTest_NoWaitForOwnership, AutoInitializeFailure) { RunServiceWorkerAndQuit(); } +TEST_F(TpmManagerServiceTest_NoWaitForOwnership, + TakeOwnershipAfterAutoInitialize) { + EXPECT_CALL(mock_tpm_initializer_, InitializeTpm()).Times(AtLeast(2)); + SetupService(); + auto callback = [this](const TakeOwnershipReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + Quit(); + }; + TakeOwnershipRequest request; + service_->TakeOwnership(request, base::Bind(callback)); + Run(); +} + TEST_F(TpmManagerServiceTest, NoAutoInitialize) { EXPECT_CALL(mock_tpm_initializer_, InitializeTpm()).Times(0); RunServiceWorkerAndQuit(); @@ -222,17 +239,216 @@ TEST_F(TpmManagerServiceTest, TakeOwnershipNoTpm) { Run(); } -TEST_F(TpmManagerServiceTest_NoWaitForOwnership, - TakeOwnershipAfterAutoInitialize) { - EXPECT_CALL(mock_tpm_initializer_, InitializeTpm()).Times(AtLeast(2)); - SetupService(); - auto callback = [this](const TakeOwnershipReply& reply) { +TEST_F(TpmManagerServiceTest, DefineNvramFailure) { + uint32_t nvram_index = 5; + size_t nvram_length = 32; + EXPECT_CALL(mock_tpm_nvram_, DefineNvram(nvram_index, nvram_length)) + .WillRepeatedly(Return(false)); + auto callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + Quit(); + }; + DefineNvramRequest request; + request.set_index(nvram_index); + request.set_length(nvram_length); + service_->DefineNvram(request, base::Bind(callback)); + Run(); +} + +TEST_F(TpmManagerServiceTest, DefineNvramSuccess) { + uint32_t nvram_index = 5; + uint32_t nvram_length = 32; + auto define_callback = [this](const DefineNvramReply& reply) { EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto is_defined_callback = [this](const IsNvramDefinedReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + EXPECT_EQ(true, reply.is_defined()); + }; + auto size_callback = [this, nvram_length](const GetNvramSizeReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + EXPECT_EQ(nvram_length, reply.size()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_length); + service_->DefineNvram(define_request, base::Bind(define_callback)); + IsNvramDefinedRequest is_defined_request; + is_defined_request.set_index(nvram_index); + service_->IsNvramDefined(is_defined_request, base::Bind(is_defined_callback)); + GetNvramSizeRequest size_request; + size_request.set_index(nvram_index); + service_->GetNvramSize(size_request, base::Bind(size_callback)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, DestroyUnitializedNvram) { + auto callback = [this](const DestroyNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); Quit(); }; - TakeOwnershipRequest request; - service_->TakeOwnership(request, base::Bind(callback)); + DestroyNvramRequest request; + service_->DestroyNvram(request, base::Bind(callback)); + Run(); +} + +TEST_F(TpmManagerServiceTest, DestroyNvramSuccess) { + uint32_t nvram_index = 5; + uint32_t nvram_length = 32; + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto destroy_callback = [this](const DestroyNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_length); + service_->DefineNvram(define_request, base::Bind(define_callback)); + DestroyNvramRequest destroy_request; + destroy_request.set_index(nvram_index); + service_->DestroyNvram(destroy_request, base::Bind(destroy_callback)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, DoubleDestroyNvram) { + uint32_t nvram_index = 5; + uint32_t nvram_length = 32; + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto destroy_callback_success = [this](const DestroyNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto destroy_callback_failure = [this](const DestroyNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_length); + service_->DefineNvram(define_request, base::Bind(define_callback)); + DestroyNvramRequest destroy_request; + destroy_request.set_index(nvram_index); + service_->DestroyNvram(destroy_request, base::Bind(destroy_callback_success)); + service_->DestroyNvram(destroy_request, base::Bind(destroy_callback_failure)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, WriteUninitializedNvram) { + auto callback = [this](const WriteNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + Quit(); + }; + WriteNvramRequest request; + service_->WriteNvram(request, base::Bind(callback)); Run(); } +TEST_F(TpmManagerServiceTest, WriteNvramIncorrectSize) { + uint32_t nvram_index = 5; + std::string nvram_data("nvram_data"); + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto write_callback = [this](const WriteNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_data.size() - 1); + service_->DefineNvram(define_request, base::Bind(define_callback)); + WriteNvramRequest write_request; + write_request.set_index(nvram_index); + write_request.set_data(nvram_data); + service_->WriteNvram(write_request, base::Bind(write_callback)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, DoubleWrite) { + uint32_t nvram_index = 5; + std::string nvram_data("nvram_data"); + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto write_callback_success = [this](const WriteNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto write_callback_failure = [this](const WriteNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_data.size()); + service_->DefineNvram(define_request, base::Bind(define_callback)); + WriteNvramRequest write_request; + write_request.set_index(nvram_index); + write_request.set_data(nvram_data); + service_->WriteNvram(write_request, base::Bind(write_callback_success)); + service_->WriteNvram(write_request, base::Bind(write_callback_failure)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, ReadUninitializedNvram) { + auto callback = [this](const ReadNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + Quit(); + }; + ReadNvramRequest request; + service_->ReadNvram(request, base::Bind(callback)); + Run(); +} + +TEST_F(TpmManagerServiceTest, ReadUnwrittenNvram) { + uint32_t nvram_index = 5; + uint32_t nvram_length = 32; + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto read_callback = [this](const ReadNvramReply& reply) { + EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_length); + service_->DefineNvram(define_request, base::Bind(define_callback)); + ReadNvramRequest read_request; + read_request.set_index(nvram_index); + service_->ReadNvram(read_request, base::Bind(read_callback)); + RunServiceWorkerAndQuit(); +} + +TEST_F(TpmManagerServiceTest, ReadWriteNvramSuccess) { + uint32_t nvram_index = 5; + std::string nvram_data("nvram_data"); + auto define_callback = [this](const DefineNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto write_callback = [this](const WriteNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + }; + auto read_callback = [this, nvram_data](const ReadNvramReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + EXPECT_EQ(nvram_data, reply.data()); + }; + auto locked_callback = [this](const IsNvramLockedReply& reply) { + EXPECT_EQ(STATUS_SUCCESS, reply.status()); + EXPECT_EQ(true, reply.is_locked()); + }; + DefineNvramRequest define_request; + define_request.set_index(nvram_index); + define_request.set_length(nvram_data.size()); + service_->DefineNvram(define_request, base::Bind(define_callback)); + WriteNvramRequest write_request; + write_request.set_index(nvram_index); + write_request.set_data(nvram_data); + service_->WriteNvram(write_request, base::Bind(write_callback)); + ReadNvramRequest read_request; + read_request.set_index(nvram_index); + service_->ReadNvram(read_request, base::Bind(read_callback)); + IsNvramLockedRequest locked_request; + locked_request.set_index(nvram_index); + service_->IsNvramLocked(locked_request, base::Bind(locked_callback)); + RunServiceWorkerAndQuit(); +} + } // namespace tpm_manager diff --git a/server/tpm_nvram.h b/server/tpm_nvram.h index 4de8ce0..750d778 100644 --- a/server/tpm_nvram.h +++ b/server/tpm_nvram.h @@ -45,16 +45,17 @@ class TpmNvram { // it into |data|. Returns true on success. virtual bool ReadNvram(uint32_t index, std::string* data) = 0; - // This method returns true iff |index| refers to a defined NVRAM space. - virtual bool IsNvramDefined(uint32_t index) = 0; + // This method sets the out argument |defined| to true iff the NVRAM space + // referred to by |index| is defined. Returns true on success. + virtual bool IsNvramDefined(uint32_t index, bool* defined) = 0; - // This method returns true iff |index| refers to an NVRAM space that has - // been locked for writing. - virtual bool IsNvramLocked(uint32_t index) = 0; + // This method sets the out argument |locked| to true iff the NVRAM space + // referred to by |index| is locked. Returns true on success. + virtual bool IsNvramLocked(uint32_t index, bool* locked) = 0; - // This method returns the size of the NVRAM space at |index|. Returns zero - // if the space is not defined. - virtual size_t GetNvramSize(uint32_t index) = 0; + // This method sets the out argument |size| to the size of the NVRAM space + // referred to by |index|. Returns true on success. + virtual bool GetNvramSize(uint32_t index, size_t* size) = 0; }; } // namespace tpm_manager |