tpm_manager: Port to brillo and enhance NVRAM interface.

This CL includes a set of changes required to run tpm_manager on Brillo.
- Android.mk
- Abstract IPC mechanism and add support for binder
- Combine protobufs into a single file
- Enhance the NVRAM interface for Brillo
- Rewrite the NVRAM implementation to be flexible enough for the new
  interface
- Enhance the tpm_manager_client for the new NVRAM interface
- Implement TPM 2.0 initialization logic that was missing
- General cleanup, including scoped_ptr -> std::unique_ptr

BUG=b:25360511
TEST=builds on Brillo and ChromiumOS, unit tests, manual tests

Change-Id: Ib9c41c75f570187d60399639bd539d6a107ef944
diff --git a/tpm_manager/Android.mk b/tpm_manager/Android.mk
new file mode 100644
index 0000000..dbcf05c
--- /dev/null
+++ b/tpm_manager/Android.mk
@@ -0,0 +1,184 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Common variables
+# ========================================================
+defaultCppExtension := .cc
+defaultCFlags := \
+  -Wall -Werror \
+  -Wno-unused-parameter \
+  -fvisibility=hidden \
+  -DUSE_TPM2 \
+  -DUSE_BINDER_IPC
+defaultIncludes := $(LOCAL_PATH)/..
+defaultSharedLibraries := \
+  libbase \
+  libbinder \
+  libbinderwrapper \
+  libbrillo \
+  libbrillo-binder \
+  libchrome \
+  libchrome-crypto \
+  libcrypto \
+  libprotobuf-cpp-lite \
+  libtrunks \
+  libutils
+
+# libtpm_manager_generated
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtpm_manager_generated
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags) -fvisibility=default
+LOCAL_CLANG := true
+proto_include := $(call local-generated-sources-dir)/proto/$(LOCAL_PATH)/..
+aidl_include := $(call local-generated-sources-dir)/aidl-generated/include
+LOCAL_C_INCLUDES := $(proto_include) $(aidl_include) $(defaultIncludes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(proto_include) $(aidl_include)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries)
+LOCAL_SRC_FILES := \
+  common/tpm_manager.proto \
+  aidl/android/tpm_manager/ITpmManagerClient.aidl \
+  aidl/android/tpm_manager/ITpmNvram.aidl \
+  aidl/android/tpm_manager/ITpmOwnership.aidl
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
+include $(BUILD_STATIC_LIBRARY)
+
+# libtpm_manager_common
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtpm_manager_common
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags) -fvisibility=default
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries)
+LOCAL_STATIC_LIBRARIES := libtpm_manager_generated
+LOCAL_SRC_FILES := \
+  common/print_tpm_manager_proto.cc
+include $(BUILD_STATIC_LIBRARY)
+
+# libtpm_manager_server
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtpm_manager_server
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries)
+LOCAL_STATIC_LIBRARIES := libtpm_manager_generated
+LOCAL_SRC_FILES := \
+  server/binder_service.cc \
+  server/local_data_store_impl.cc \
+  server/openssl_crypto_util_impl.cc \
+  server/tpm2_initializer_impl.cc \
+  server/tpm2_nvram_impl.cc \
+  server/tpm2_status_impl.cc \
+  server/tpm_manager_service.cc
+include $(BUILD_STATIC_LIBRARY)
+
+# tpm_managerd
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := tpm_managerd
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags)
+LOCAL_CLANG := true
+LOCAL_INIT_RC := server/tpm_managerd.rc
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries)
+LOCAL_STATIC_LIBRARIES := \
+  libtpm_manager_server \
+  libtpm_manager_common \
+  libtpm_manager_generated
+LOCAL_REQUIRED_MODULES := tpm_managerd-seccomp.policy
+LOCAL_SRC_FILES := \
+  server/main.cc
+
+include $(BUILD_EXECUTABLE)
+
+# tpm_managerd-seccomp.policy
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := tpm_managerd-seccomp.policy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/policy/
+LOCAL_SRC_FILES := server/tpm_managerd-seccomp-$(TARGET_ARCH).policy
+include $(BUILD_PREBUILT)
+
+# libtpm_manager
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtpm_manager
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries)
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+  libtpm_manager_common \
+  libtpm_manager_generated
+LOCAL_SRC_FILES := \
+  client/tpm_nvram_binder_proxy.cc \
+  client/tpm_ownership_binder_proxy.cc
+include $(BUILD_SHARED_LIBRARY)
+
+# tpm_manager_client
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := tpm_manager_client
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries) libtpm_manager
+LOCAL_SRC_FILES := \
+  client/main.cc
+include $(BUILD_EXECUTABLE)
+
+# Target unit tests
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := tpm_manager_test
+LOCAL_MODULE_TAGS := eng
+LOCAL_CPP_EXTENSION := $(defaultCppExtension)
+LOCAL_CFLAGS := $(defaultCFlags) -Wno-sign-compare
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(defaultIncludes)
+LOCAL_SHARED_LIBRARIES := $(defaultSharedLibraries) libtpm_manager
+LOCAL_SRC_FILES := \
+  common/mock_tpm_nvram_interface.cc \
+  common/mock_tpm_ownership_interface.cc \
+  server/binder_service_test.cc \
+  server/mock_local_data_store.cc \
+  server/mock_openssl_crypto_util.cc \
+  server/mock_tpm_initializer.cc \
+  server/mock_tpm_nvram.cc \
+  server/mock_tpm_status.cc \
+  server/tpm2_initializer_test.cc \
+  server/tpm2_nvram_test.cc \
+  server/tpm2_status_test.cc \
+  server/tpm_manager_service_test.cc
+LOCAL_STATIC_LIBRARIES := \
+  libBionicGtestMain \
+  libgmock \
+  libtpm_manager_common \
+  libtpm_manager_generated \
+  libtpm_manager_server \
+  libtrunks_test
+include $(BUILD_NATIVE_TEST)
diff --git a/tpm_manager/aidl/android/tpm_manager/ITpmManagerClient.aidl b/tpm_manager/aidl/android/tpm_manager/ITpmManagerClient.aidl
new file mode 100644
index 0000000..5e14d68
--- /dev/null
+++ b/tpm_manager/aidl/android/tpm_manager/ITpmManagerClient.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tpm_manager;
+
+interface ITpmManagerClient {
+  oneway void OnCommandResponse(in byte[] response_proto);
+}
diff --git a/tpm_manager/aidl/android/tpm_manager/ITpmNvram.aidl b/tpm_manager/aidl/android/tpm_manager/ITpmNvram.aidl
new file mode 100644
index 0000000..034508c
--- /dev/null
+++ b/tpm_manager/aidl/android/tpm_manager/ITpmNvram.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tpm_manager;
+
+import android.tpm_manager.ITpmManagerClient;
+
+// See tpm_nvram_interface.h for expected protobuf payloads.
+interface ITpmNvram {
+  oneway void DefineSpace(in byte[] command_proto, in ITpmManagerClient client);
+  oneway void DestroySpace(in byte[] command_proto,
+                           in ITpmManagerClient client);
+  oneway void WriteSpace(in byte[] command_proto, in ITpmManagerClient client);
+  oneway void ReadSpace(in byte[] command_proto, in ITpmManagerClient client);
+  oneway void LockSpace(in byte[] command_proto, in ITpmManagerClient client);
+  oneway void ListSpaces(in byte[] command_proto, in ITpmManagerClient client);
+  oneway void GetSpaceInfo(in byte[] command_proto,
+                           in ITpmManagerClient client);
+}
diff --git a/tpm_manager/aidl/android/tpm_manager/ITpmOwnership.aidl b/tpm_manager/aidl/android/tpm_manager/ITpmOwnership.aidl
new file mode 100644
index 0000000..666aede
--- /dev/null
+++ b/tpm_manager/aidl/android/tpm_manager/ITpmOwnership.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tpm_manager;
+
+import android.tpm_manager.ITpmManagerClient;
+
+// See tpm_ownership_interface.h for expected protobuf payloads.
+interface ITpmOwnership {
+  oneway void GetTpmStatus(in byte[] command_proto,
+                           in ITpmManagerClient client);
+  oneway void TakeOwnership(in byte[] command_proto,
+                            in ITpmManagerClient client);
+  oneway void RemoveOwnerDependency(in byte[] command_proto,
+                                    in ITpmManagerClient client);
+}
diff --git a/tpm_manager/client/binder_proxy_helper.h b/tpm_manager/client/binder_proxy_helper.h
new file mode 100644
index 0000000..ad4b7bc
--- /dev/null
+++ b/tpm_manager/client/binder_proxy_helper.h
@@ -0,0 +1,95 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+namespace tpm_manager {
+
+// Handles protobuf conversions for a binder proxy. Implements ITpmManagerClient
+// and acts as a response observer for async requests it sends out. The
+// |RequestProtobufType| and |ResponseProtobufType| types can be any protobufs.
+template<typename RequestProtobufType, typename ResponseProtobufType>
+class BinderProxyHelper {
+ public:
+  using CallbackType = base::Callback<void(const ResponseProtobufType&)>;
+  using GetErrorResponseCallbackType =
+      base::Callback<void(ResponseProtobufType*)>;
+  using BinderMethodType = base::Callback<android::binder::Status(
+      const std::vector<uint8_t>& command_proto,
+      const android::sp<android::tpm_manager::ITpmManagerClient>& client)>;
+
+  BinderProxyHelper(const BinderMethodType& method,
+                    const CallbackType& callback,
+                    const GetErrorResponseCallbackType& get_error_response)
+      : method_(method),
+        callback_(callback),
+        get_error_response_(get_error_response) {}
+
+  void SendErrorResponse() {
+    ResponseProtobufType response_proto;
+    get_error_response_.Run(&response_proto);
+    callback_.Run(response_proto);
+  }
+
+  void SendRequest(const RequestProtobufType& request) {
+    VLOG(2) << __func__;
+    android::sp<ResponseObserver> observer(
+        new ResponseObserver(callback_, get_error_response_));
+    std::vector<uint8_t> request_bytes;
+    request_bytes.resize(request.ByteSize());
+    if (!request.SerializeToArray(request_bytes.data(), request_bytes.size())) {
+      LOG(ERROR) << "BinderProxyHelper: Failed to serialize protobuf.";
+      SendErrorResponse();
+      return;
+    }
+    android::binder::Status status = method_.Run(request_bytes, observer);
+    if (!status.isOk()) {
+      LOG(ERROR) << "BinderProxyHelper: Binder error: " << status.toString8();
+      SendErrorResponse();
+      return;
+    }
+  }
+
+ private:
+  class ResponseObserver : public android::tpm_manager::BnTpmManagerClient {
+   public:
+    ResponseObserver(const CallbackType& callback,
+                     const GetErrorResponseCallbackType& get_error_response)
+        : callback_(callback), get_error_response_(get_error_response) {}
+
+    // ITpmManagerClient interface.
+    android::binder::Status OnCommandResponse(
+        const std::vector<uint8_t>& response_proto_data) override {
+      VLOG(2) << __func__;
+      ResponseProtobufType response_proto;
+      if (!response_proto.ParseFromArray(response_proto_data.data(),
+                                         response_proto_data.size())) {
+        LOG(ERROR) << "BinderProxyHelper: Bad response data.";
+        get_error_response_.Run(&response_proto);
+      }
+      callback_.Run(response_proto);
+      return android::binder::Status::ok();
+    }
+
+   private:
+    CallbackType callback_;
+    GetErrorResponseCallbackType get_error_response_;
+  };
+
+  BinderMethodType method_;
+  CallbackType callback_;
+  GetErrorResponseCallbackType get_error_response_;
+};
+
+}  // tpm_manager
diff --git a/tpm_manager/client/main.cc b/tpm_manager/client/main.cc
index f96d959..1d30a41 100644
--- a/tpm_manager/client/main.cc
+++ b/tpm_manager/client/main.cc
@@ -22,68 +22,137 @@
 #include <string>
 
 #include <base/command_line.h>
+#include <base/files/file_util.h>
 #include <base/logging.h>
+#include <base/memory/ptr_util.h>
 #include <base/message_loop/message_loop.h>
 #include <brillo/bind_lambda.h>
+#if defined(USE_BINDER_IPC)
+#include <brillo/binder_watcher.h>
+#endif
 #include <brillo/daemons/daemon.h>
 #include <brillo/syslog_logging.h>
+#include <crypto/sha2.h>
 
+#if defined(USE_BINDER_IPC)
+#include "tpm_manager/client/tpm_nvram_binder_proxy.h"
+#include "tpm_manager/client/tpm_ownership_binder_proxy.h"
+#else
 #include "tpm_manager/client/tpm_nvram_dbus_proxy.h"
 #include "tpm_manager/client/tpm_ownership_dbus_proxy.h"
-#include "tpm_manager/common/print_tpm_ownership_interface_proto.h"
-#include "tpm_manager/common/print_tpm_nvram_interface_proto.h"
-#include "tpm_manager/common/tpm_ownership_interface.pb.h"
-#include "tpm_manager/common/tpm_nvram_interface.pb.h"
+#endif
+#include "tpm_manager/common/print_tpm_manager_proto.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
+#include "trunks/tpm_generated.h"
 
 namespace tpm_manager {
 
-const char kGetTpmStatusCommand[] = "status";
-const char kTakeOwnershipCommand[] = "take_ownership";
-const char kRemoveOwnerDependencyCommand[] = "remove_dependency";
-const char kDefineNvramCommand[] = "define_nvram";
-const char kDestroyNvramCommand[] = "destroy_nvram";
-const char kWriteNvramCommand[] = "write_nvram";
-const char kReadNvramCommand[] = "read_nvram";
-const char kIsNvramDefinedCommand[] = "is_nvram_defined";
-const char kIsNvramLockedCommand[] = "is_nvram_locked";
-const char kGetNvramSizeCommand[] = "get_nvram_size";
+constexpr char kGetTpmStatusCommand[] = "status";
+constexpr char kTakeOwnershipCommand[] = "take_ownership";
+constexpr char kRemoveOwnerDependencyCommand[] = "remove_dependency";
+constexpr char kDefineSpaceCommand[] = "define_space";
+constexpr char kDestroySpaceCommand[] = "destroy_space";
+constexpr char kWriteSpaceCommand[] = "write_space";
+constexpr char kReadSpaceCommand[] = "read_space";
+constexpr char kLockSpaceCommand[] = "lock_space";
+constexpr char kListSpacesCommand[] = "list_spaces";
+constexpr char kGetSpaceInfoCommand[] = "get_space_info";
 
-const char kNvramIndexArg[] = "nvram_index";
-const char kNvramLengthArg[] = "nvram_length";
-const char kNvramDataArg[] = "nvram_data";
+constexpr char kDependencySwitch[] = "dependency";
+constexpr char kIndexSwitch[] = "index";
+constexpr char kSizeSwitch[] = "size";
+constexpr char kAttributesSwitch[] = "attributes";
+constexpr char kPasswordSwitch[] = "password";
+constexpr char kBindToPCR0Switch[] = "bind_to_pcr0";
+constexpr char kFileSwitch[] = "file";
+constexpr char kUseOwnerSwitch[] = "use_owner_authorization";
+constexpr char kLockRead[] = "lock_read";
+constexpr char kLockWrite[] = "lock_write";
 
-const char kUsage[] = R"(
+constexpr char kUsage[] = R"(
 Usage: tpm_manager_client <command> [<arguments>]
-Commands (used as switches):
-  --status
-      Prints the current status of the Tpm.
-  --take_ownership
+Commands:
+  status
+      Prints TPM status information.
+  take_ownership
       Takes ownership of the Tpm with a random password.
-  --remove_dependency=<owner_dependency>
-      Removes the provided Tpm owner dependency.
-  --define_nvram
-      Defines an NV space at |nvram_index| with length |nvram_length|.
-  --destroy_nvram
-      Destroys the NV space at |nvram_index|.
-  --write_nvram
-      Writes the NV space at |nvram_index| with |nvram_data|.
-  --read_nvram
-      Prints the contents of the NV space at |nvram_index|.
-  --is_nvram_defined
-      Prints whether the NV space at |nvram_index| is defined.
-  --is_nvram_locked
-      Prints whether the NV space at |nvram_index|  is locked for writing.
-  --get_nvram_size
-      Prints the size of the NV space at |nvram_index|.
-Arguments (used as switches):
-  --nvram_index=<index>
-      Index of NV space to operate on.
-  --nvram_length=<length>
-      Size in bytes of the NV space to be created.
-  --nvram_data=<data>
-      Data to write to NV space.
+  remove_dependency --dependency=<owner_dependency>
+      Removes the named Tpm owner dependency. E.g. \"Nvram\" or \"Attestation\".
+  define_space --index=<index> --size=<size> [--attributes=<attribute_list>]
+               [--password=<password>] [--bind_to_pcr0]
+      Defines an NV space. The attribute format is a '|' separated list of:
+          PERSISTENT_WRITE_LOCK: Allow write lock; stay locked until destroyed.
+          BOOT_WRITE_LOCK: Allow write lock; stay locked until next boot.
+          BOOT_READ_LOCK: Allow read lock; stay locked until next boot.
+          WRITE_AUTHORIZATION: Require authorization to write.
+          READ_AUTHORIZATION: Require authorization to read.
+          WRITE_EXTEND: Allow only extend operations, not direct writes.
+          GLOBAL_LOCK: Engage write lock when the global lock is engaged.
+          PLATFORM_WRITE: Allow write only with 'platform' authorization. This
+                          is similar to the TPM 1.2 'physical presence' notion.
+          OWNER_WRITE: Allow write only with TPM owner authorization.
+          OWNER_READ: Allow read only with TPM owner authorization.
+      This command requires that owner authorization is available. If a password
+      is given it will be required only as specified by the attributes. E.g. if
+      READ_AUTHORIZATION is not listed, then the password will not be required
+      in order to read. Similarly, if the --bind_to_pcr0 option is given, the
+      current PCR0 value will be required only as specified by the attributes.
+  destroy_space --index=<index>
+      Destroys an NV space. This command requires that owner authorization is
+      available.
+  write_space --index=<index> --file=<input_file> [--password=<password>]
+              [--use_owner_authorization]
+      Writes data from a file to an NV space. Any existing data will be
+      overwritten.
+  read_space --index=<index> --file=<output_file> [--password=<password>]
+             [--use_owner_authorization]
+      Reads the entire contents of an NV space to a file.
+  lock_space --index=<index> [--lock_read] [--lock_write]
+             [--password=<password>] [--use_owner_authorization]
+      Locks an NV space for read and / or write.
+  list_spaces
+      Prints a list of all defined index values.
+  get_space_info --index=<index>
+      Prints public information about an NV space.
 )";
 
+constexpr char kKnownNVRAMSpaces[] = R"(
+NVRAM Index Reference:
+ TPM 1.2 (32-bit values)
+  0x00001007 - Chrome OS Firmware Version Rollback Protection
+  0x00001008 - Chrome OS Kernel Version Rollback Protection
+  0x00001009 - Chrome OS Firmware Backup
+  0x0000100A - Chrome OS Firmware Management Parameters
+  0x20000004 - Chrome OS Install Attributes (aka LockBox)
+  0x10000001 - Standard TPM_NV_INDEX_DIR (Permanent)
+  0x1000F000 - Endorsement Certificate (Permanent)
+  0x30000001 - Endorsement Authority Certificate (Permanent)
+  0x0000F004 - Standard Test Index (for testing TPM_NV_DefineSpace)
+
+ TPM 2.0 (24-bit values)
+  0x400000 and following - Reserved for Firmware
+  0x800000 and following - Reserved for Software
+  0xC00000 and following - Endorsement Certificates
+)";
+
+bool ReadFileToString(const std::string& filename, std::string* data) {
+  return base::ReadFileToString(base::FilePath(filename), data);
+}
+
+bool WriteStringToFile(const std::string& data, const std::string& filename) {
+  int result =
+      base::WriteFile(base::FilePath(filename), data.data(), data.size());
+  return (result != -1 && static_cast<size_t>(result) == data.size());
+}
+
+uint32_t StringToUint32(const std::string& s) {
+  return strtoul(s.c_str(), nullptr, 0);
+}
+
+uint32_t StringToNvramIndex(const std::string& s) {
+  return trunks::HR_HANDLE_MASK & StringToUint32(s);
+}
+
 using ClientLoopBase = brillo::Daemon;
 class ClientLoop : public ClientLoopBase {
  public:
@@ -97,21 +166,34 @@
       LOG(ERROR) << "Error initializing tpm_manager_client.";
       return exit_code;
     }
-    TpmNvramDBusProxy* nvram_proxy = new TpmNvramDBusProxy();
+#if defined(USE_BINDER_IPC)
+    if (!binder_watcher_.Init()) {
+      LOG(ERROR) << "Error initializing binder watcher.";
+      return EX_UNAVAILABLE;
+    }
+    std::unique_ptr<TpmNvramBinderProxy> nvram_proxy =
+        base::MakeUnique<TpmNvramBinderProxy>();
+    std::unique_ptr<TpmOwnershipBinderProxy> ownership_proxy =
+        base::MakeUnique<TpmOwnershipBinderProxy>();
+#else
+    std::unique_ptr<TpmNvramDBusProxy> nvram_proxy =
+        base::MakeUnique<TpmNvramDBusProxy>();
+    std::unique_ptr<TpmOwnershipDBusProxy> ownership_proxy =
+        base::MakeUnique<TpmOwnershipDBusProxy>();
+#endif
     if (!nvram_proxy->Initialize()) {
-      LOG(ERROR) << "Error initializing proxy to nvram interface.";
+      LOG(ERROR) << "Error initializing nvram proxy.";
       return EX_UNAVAILABLE;
     }
-    TpmOwnershipDBusProxy* ownership_proxy = new TpmOwnershipDBusProxy();
     if (!ownership_proxy->Initialize()) {
-      LOG(ERROR) << "Error initializing proxy to ownership interface.";
+      LOG(ERROR) << "Error initializing ownership proxy.";
       return EX_UNAVAILABLE;
     }
-    tpm_nvram_.reset(nvram_proxy);
-    tpm_ownership_.reset(ownership_proxy);
+    tpm_nvram_ = std::move(nvram_proxy);
+    tpm_ownership_ = std::move(ownership_proxy);
     exit_code = ScheduleCommand();
     if (exit_code == EX_USAGE) {
-      printf("%s", kUsage);
+      printf("%s%s", kUsage, kKnownNVRAMSpaces);
     }
     return exit_code;
   }
@@ -127,81 +209,88 @@
   int ScheduleCommand() {
     base::Closure task;
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-    if (command_line->HasSwitch("help") || command_line->HasSwitch("h")) {
+    if (command_line->HasSwitch("help") || command_line->HasSwitch("h") ||
+        command_line->GetArgs().size() == 0) {
       return EX_USAGE;
-    } else if (command_line->HasSwitch(kGetTpmStatusCommand)) {
+    }
+    std::string command = command_line->GetArgs()[0];
+    if (command == kGetTpmStatusCommand) {
       task = base::Bind(&ClientLoop::HandleGetTpmStatus,
                         weak_factory_.GetWeakPtr());
-    } else if (command_line->HasSwitch(kTakeOwnershipCommand)) {
+    } else if (command == kTakeOwnershipCommand) {
       task = base::Bind(&ClientLoop::HandleTakeOwnership,
                         weak_factory_.GetWeakPtr());
-    } else if (command_line->HasSwitch(kRemoveOwnerDependencyCommand)) {
-      task = base::Bind(
-          &ClientLoop::HandleRemoveOwnerDependency, weak_factory_.GetWeakPtr(),
-          command_line->GetSwitchValueASCII(kRemoveOwnerDependencyCommand));
-    } else if (command_line->HasSwitch(kDefineNvramCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg) ||
-          !command_line->HasSwitch(kNvramLengthArg)) {
-        LOG(ERROR) << "Cannot define nvram without a valid index and length.";
+    } else if (command == kRemoveOwnerDependencyCommand) {
+      if (!command_line->HasSwitch(kDependencySwitch)) {
+        return EX_USAGE;
+      }
+      task = base::Bind(&ClientLoop::HandleRemoveOwnerDependency,
+                        weak_factory_.GetWeakPtr(),
+                        command_line->GetSwitchValueASCII(kDependencySwitch));
+    } else if (command == kDefineSpaceCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch) ||
+          !command_line->HasSwitch(kSizeSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleDefineNvram, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()),
-          atoi(command_line->GetSwitchValueASCII(kNvramLengthArg).c_str()));
-    } else if (command_line->HasSwitch(kDestroyNvramCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg)) {
-        LOG(ERROR) << "Cannot destroy nvram without a valid index.";
+          &ClientLoop::HandleDefineSpace, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
+          StringToUint32(command_line->GetSwitchValueASCII(kSizeSwitch)),
+          command_line->GetSwitchValueASCII(kAttributesSwitch),
+          command_line->GetSwitchValueASCII(kPasswordSwitch),
+          command_line->HasSwitch(kBindToPCR0Switch));
+    } else if (command == kDestroySpaceCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleDestroyNvram, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()));
-    } else if (command_line->HasSwitch(kWriteNvramCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg) ||
-          !command_line->HasSwitch(kNvramDataArg)) {
-        LOG(ERROR) << "Cannot write nvram without a valid index and data.";
+          &ClientLoop::HandleDestroySpace, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)));
+    } else if (command == kWriteSpaceCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch) ||
+          !command_line->HasSwitch(kFileSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleWriteNvram, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()),
-          command_line->GetSwitchValueASCII(kNvramDataArg));
-    } else if (command_line->HasSwitch(kReadNvramCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg)) {
-        LOG(ERROR) << "Cannot read nvram without a valid index.";
+          &ClientLoop::HandleWriteSpace, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
+          command_line->GetSwitchValueASCII(kFileSwitch),
+          command_line->GetSwitchValueASCII(kPasswordSwitch),
+          command_line->HasSwitch(kUseOwnerSwitch));
+    } else if (command == kReadSpaceCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch) ||
+          !command_line->HasSwitch(kFileSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleReadNvram, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()));
-    } else if (command_line->HasSwitch(kIsNvramDefinedCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg)) {
-        LOG(ERROR) << "Cannot query nvram without a valid index.";
+          &ClientLoop::HandleReadSpace, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
+          command_line->GetSwitchValueASCII(kFileSwitch),
+          command_line->GetSwitchValueASCII(kPasswordSwitch),
+          command_line->HasSwitch(kUseOwnerSwitch));
+    } else if (command == kLockSpaceCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleIsNvramDefined, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()));
-    } else if (command_line->HasSwitch(kIsNvramLockedCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg)) {
-        LOG(ERROR) << "Cannot query nvram without a valid index.";
+          &ClientLoop::HandleLockSpace, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
+          command_line->HasSwitch(kLockRead),
+          command_line->HasSwitch(kLockWrite),
+          command_line->GetSwitchValueASCII(kPasswordSwitch),
+          command_line->HasSwitch(kUseOwnerSwitch));
+    } else if (command == kListSpacesCommand) {
+      task =
+          base::Bind(&ClientLoop::HandleListSpaces, weak_factory_.GetWeakPtr());
+    } else if (command == kGetSpaceInfoCommand) {
+      if (!command_line->HasSwitch(kIndexSwitch)) {
         return EX_USAGE;
       }
       task = base::Bind(
-          &ClientLoop::HandleIsNvramLocked, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()));
-    } else if (command_line->HasSwitch(kGetNvramSizeCommand)) {
-      if (!command_line->HasSwitch(kNvramIndexArg)) {
-        LOG(ERROR) << "Cannot query nvram without a valid index.";
-        return EX_USAGE;
-      }
-      task = base::Bind(
-          &ClientLoop::HandleGetNvramSize, weak_factory_.GetWeakPtr(),
-          atoi(command_line->GetSwitchValueASCII(kNvramIndexArg).c_str()));
+          &ClientLoop::HandleGetSpaceInfo, weak_factory_.GetWeakPtr(),
+          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)));
     } else {
       // Command line arguments did not match any valid commands.
-      LOG(ERROR) << "No Valid Command selected.";
       return EX_USAGE;
     }
     base::MessageLoop::current()->PostTask(FROM_HERE, task);
@@ -238,68 +327,177 @@
                    weak_factory_.GetWeakPtr()));
   }
 
-  void HandleDefineNvram(uint32_t index, size_t length) {
-    DefineNvramRequest request;
+  bool DecodeAttribute(const std::string& attribute_str,
+                       NvramSpaceAttribute* attribute) {
+    if (attribute_str == "PERSISTENT_WRITE_LOCK") {
+      *attribute = NVRAM_PERSISTENT_WRITE_LOCK;
+      return true;
+    }
+    if (attribute_str == "BOOT_WRITE_LOCK") {
+      *attribute = NVRAM_BOOT_WRITE_LOCK;
+      return true;
+    }
+    if (attribute_str == "BOOT_READ_LOCK") {
+      *attribute = NVRAM_BOOT_READ_LOCK;
+      return true;
+    }
+    if (attribute_str == "WRITE_AUTHORIZATION") {
+      *attribute = NVRAM_WRITE_AUTHORIZATION;
+      return true;
+    }
+    if (attribute_str == "READ_AUTHORIZATION") {
+      *attribute = NVRAM_READ_AUTHORIZATION;
+      return true;
+    }
+    if (attribute_str == "WRITE_EXTEND") {
+      *attribute = NVRAM_WRITE_EXTEND;
+      return true;
+    }
+    if (attribute_str == "GLOBAL_LOCK") {
+      *attribute = NVRAM_GLOBAL_LOCK;
+      return true;
+    }
+    if (attribute_str == "PLATFORM_WRITE") {
+      *attribute = NVRAM_PLATFORM_WRITE;
+      return true;
+    }
+    if (attribute_str == "OWNER_WRITE") {
+      *attribute = NVRAM_OWNER_WRITE;
+      return true;
+    }
+    if (attribute_str == "OWNER_READ") {
+      *attribute = NVRAM_OWNER_READ;
+      return true;
+    }
+    LOG(ERROR) << "Unrecognized attribute: " << attribute_str;
+    return false;
+  }
+
+  void HandleDefineSpace(uint32_t index,
+                         size_t size,
+                         const std::string& attributes,
+                         const std::string& password,
+                         bool bind_to_pcr0) {
+    DefineSpaceRequest request;
     request.set_index(index);
-    request.set_length(length);
-    tpm_nvram_->DefineNvram(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DefineNvramReply>,
+    request.set_size(size);
+    std::string::size_type pos = 0;
+    std::string::size_type next_pos = 0;
+    while (next_pos != std::string::npos) {
+      next_pos = attributes.find('|', pos);
+      std::string attribute_str;
+      if (next_pos == std::string::npos) {
+        attribute_str = attributes.substr(pos);
+      } else {
+        attribute_str = attributes.substr(pos, next_pos - pos);
+      }
+      if (!attribute_str.empty()) {
+        NvramSpaceAttribute attribute;
+        if (!DecodeAttribute(attribute_str, &attribute)) {
+          Quit();
+          return;
+        }
+        request.add_attributes(attribute);
+      }
+      pos = next_pos + 1;
+    }
+    request.set_authorization_value(crypto::SHA256HashString(password));
+    request.set_policy(bind_to_pcr0 ? NVRAM_POLICY_PCR0 : NVRAM_POLICY_NONE);
+    tpm_nvram_->DefineSpace(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DefineSpaceReply>,
                             weak_factory_.GetWeakPtr()));
   }
 
-  void HandleDestroyNvram(uint32_t index) {
-    DestroyNvramRequest request;
+  void HandleDestroySpace(uint32_t index) {
+    DestroySpaceRequest request;
     request.set_index(index);
-    tpm_nvram_->DestroyNvram(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DestroyNvramReply>,
+    tpm_nvram_->DestroySpace(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DestroySpaceReply>,
                             weak_factory_.GetWeakPtr()));
   }
 
-  void HandleWriteNvram(uint32_t index, const std::string& data) {
-    WriteNvramRequest request;
+  void HandleWriteSpace(uint32_t index,
+                        const std::string& input_file,
+                        const std::string& password,
+                        bool use_owner_authorization) {
+    WriteSpaceRequest request;
     request.set_index(index);
+    std::string data;
+    if (!ReadFileToString(input_file, &data)) {
+      LOG(ERROR) << "Failed to read input file.";
+      Quit();
+      return;
+    }
     request.set_data(data);
-    tpm_nvram_->WriteNvram(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<WriteNvramReply>,
+    request.set_authorization_value(crypto::SHA256HashString(password));
+    request.set_use_owner_authorization(use_owner_authorization);
+    tpm_nvram_->WriteSpace(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<WriteSpaceReply>,
                             weak_factory_.GetWeakPtr()));
   }
 
-  void HandleReadNvram(uint32_t index) {
-    ReadNvramRequest request;
+  void HandleReadSpaceReply(const std::string& output_file,
+                            const ReadSpaceReply& reply) {
+    if (!WriteStringToFile(reply.data(), output_file)) {
+      LOG(ERROR) << "Failed to write output file.";
+    }
+    LOG(INFO) << "Message Reply: " << GetProtoDebugString(reply);
+    Quit();
+  }
+
+  void HandleReadSpace(uint32_t index,
+                       const std::string& output_file,
+                       const std::string& password,
+                       bool use_owner_authorization) {
+    ReadSpaceRequest request;
     request.set_index(index);
-    tpm_nvram_->ReadNvram(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<ReadNvramReply>,
-                            weak_factory_.GetWeakPtr()));
+    request.set_authorization_value(crypto::SHA256HashString(password));
+    request.set_use_owner_authorization(use_owner_authorization);
+    tpm_nvram_->ReadSpace(request,
+                          base::Bind(&ClientLoop::HandleReadSpaceReply,
+                                     weak_factory_.GetWeakPtr(), output_file));
   }
 
-  void HandleIsNvramDefined(uint32_t index) {
-    IsNvramDefinedRequest request;
+  void HandleLockSpace(uint32_t index,
+                       bool lock_read,
+                       bool lock_write,
+                       const std::string& password,
+                       bool use_owner_authorization) {
+    LockSpaceRequest request;
     request.set_index(index);
-    tpm_nvram_->IsNvramDefined(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<IsNvramDefinedReply>,
+    request.set_lock_read(lock_read);
+    request.set_lock_write(lock_write);
+    request.set_authorization_value(crypto::SHA256HashString(password));
+    request.set_use_owner_authorization(use_owner_authorization);
+    tpm_nvram_->LockSpace(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<LockSpaceReply>,
                             weak_factory_.GetWeakPtr()));
   }
 
-  void HandleIsNvramLocked(uint32_t index) {
-    IsNvramLockedRequest request;
+  void HandleListSpaces() {
+    printf("%s\n", kKnownNVRAMSpaces);
+    ListSpacesRequest request;
+    tpm_nvram_->ListSpaces(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<ListSpacesReply>,
+                            weak_factory_.GetWeakPtr()));
+  }
+
+  void HandleGetSpaceInfo(uint32_t index) {
+    GetSpaceInfoRequest request;
     request.set_index(index);
-    tpm_nvram_->IsNvramLocked(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<IsNvramLockedReply>,
+    tpm_nvram_->GetSpaceInfo(
+        request, base::Bind(&ClientLoop::PrintReplyAndQuit<GetSpaceInfoReply>,
                             weak_factory_.GetWeakPtr()));
   }
 
-  void HandleGetNvramSize(uint32_t index) {
-    GetNvramSizeRequest request;
-    request.set_index(index);
-    tpm_nvram_->GetNvramSize(
-        request, base::Bind(&ClientLoop::PrintReplyAndQuit<GetNvramSizeReply>,
-                            weak_factory_.GetWeakPtr()));
-  }
-
-  // Pointer to a DBus proxy to tpm_managerd.
+  // IPC proxy interfaces.
   std::unique_ptr<tpm_manager::TpmNvramInterface> tpm_nvram_;
   std::unique_ptr<tpm_manager::TpmOwnershipInterface> tpm_ownership_;
 
+#if defined(USE_BINDER_IPC)
+  brillo::BinderWatcher binder_watcher_;
+#endif
+
   // Declared last so that weak pointers will be destroyed first.
   base::WeakPtrFactory<ClientLoop> weak_factory_{this};
 
diff --git a/tpm_manager/client/tpm_nvram_binder_proxy.cc b/tpm_manager/client/tpm_nvram_binder_proxy.cc
new file mode 100644
index 0000000..1e0393f
--- /dev/null
+++ b/tpm_manager/client/tpm_nvram_binder_proxy.cc
@@ -0,0 +1,125 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "tpm_manager/client/tpm_nvram_binder_proxy.h"
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <utils/Errors.h>
+
+#include "android/tpm_manager/BnTpmManagerClient.h"
+#include "android/tpm_manager/BpTpmNvram.h"
+#include "tpm_manager/client/binder_proxy_helper.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
+#include "tpm_manager/common/tpm_manager_constants.h"
+
+namespace {
+
+template <typename ResponseProtobufType>
+void CreateErrorResponse(ResponseProtobufType* response) {
+  response->set_result(tpm_manager::NVRAM_RESULT_IPC_ERROR);
+}
+
+}  // namespace
+
+namespace tpm_manager {
+
+using android::tpm_manager::ITpmNvram;
+
+TpmNvramBinderProxy::TpmNvramBinderProxy(ITpmNvram* binder) : binder_(binder) {}
+
+bool TpmNvramBinderProxy::Initialize() {
+  if (binder_) {
+    return true;
+  }
+  android::sp<android::IBinder> service_binder =
+      android::BinderWrapper::GetOrCreateInstance()->GetService(
+          kTpmNvramBinderName);
+  if (!service_binder.get()) {
+    LOG(ERROR) << "TpmNvramBinderProxy: Service does not exist.";
+    return false;
+  }
+  default_binder_ = new android::tpm_manager::BpTpmNvram(service_binder);
+  binder_ = default_binder_.get();
+  return true;
+}
+
+void TpmNvramBinderProxy::DefineSpace(const DefineSpaceRequest& request,
+                                      const DefineSpaceCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::DefineSpace, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<DefineSpaceReply>);
+  BinderProxyHelper<DefineSpaceRequest, DefineSpaceReply> helper(
+      method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::DestroySpace(const DestroySpaceRequest& request,
+                                       const DestroySpaceCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::DestroySpace, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<DestroySpaceReply>);
+  BinderProxyHelper<DestroySpaceRequest, DestroySpaceReply> helper(
+      method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::WriteSpace(const WriteSpaceRequest& request,
+                                     const WriteSpaceCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::WriteSpace, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<WriteSpaceReply>);
+  BinderProxyHelper<WriteSpaceRequest, WriteSpaceReply> helper(method, callback,
+                                                               get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::ReadSpace(const ReadSpaceRequest& request,
+                                    const ReadSpaceCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::ReadSpace, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<ReadSpaceReply>);
+  BinderProxyHelper<ReadSpaceRequest, ReadSpaceReply> helper(method, callback,
+                                                             get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::LockSpace(const LockSpaceRequest& request,
+                                    const LockSpaceCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::LockSpace, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<LockSpaceReply>);
+  BinderProxyHelper<LockSpaceRequest, LockSpaceReply> helper(method, callback,
+                                                             get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::ListSpaces(const ListSpacesRequest& request,
+                                     const ListSpacesCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::ListSpaces, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<ListSpacesReply>);
+  BinderProxyHelper<ListSpacesRequest, ListSpacesReply> helper(method, callback,
+                                                               get_error);
+  helper.SendRequest(request);
+}
+
+void TpmNvramBinderProxy::GetSpaceInfo(const GetSpaceInfoRequest& request,
+                                       const GetSpaceInfoCallback& callback) {
+  auto method = base::Bind(&ITpmNvram::GetSpaceInfo, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<GetSpaceInfoReply>);
+  BinderProxyHelper<GetSpaceInfoRequest, GetSpaceInfoReply> helper(
+      method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+}  // namespace tpm_manager
diff --git a/tpm_manager/client/tpm_nvram_binder_proxy.h b/tpm_manager/client/tpm_nvram_binder_proxy.h
new file mode 100644
index 0000000..6b4e00c
--- /dev/null
+++ b/tpm_manager/client/tpm_nvram_binder_proxy.h
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TPM_MANAGER_CLIENT_TPM_NVRAM_BINDER_PROXY_H_
+#define TPM_MANAGER_CLIENT_TPM_NVRAM_BINDER_PROXY_H_
+
+#include <base/macros.h>
+
+#include "android/tpm_manager/ITpmNvram.h"
+#include "tpm_manager/common/export.h"
+#include "tpm_manager/common/tpm_nvram_interface.h"
+
+namespace tpm_manager {
+
+// An implementation of TpmNvramInterface that forwards requests to tpm_managerd
+// using Binder.
+class TPM_MANAGER_EXPORT TpmNvramBinderProxy : public TpmNvramInterface {
+ public:
+  TpmNvramBinderProxy() = default;
+  explicit TpmNvramBinderProxy(android::tpm_manager::ITpmNvram* binder);
+  ~TpmNvramBinderProxy() override = default;
+
+  // Initializes the client. Returns true on success.
+  bool Initialize();
+
+  // TpmNvramInterface methods. All assume a message loop and binder watcher
+  // have already been configured elsewhere.
+  void DefineSpace(const DefineSpaceRequest& request,
+                   const DefineSpaceCallback& callback) override;
+  void DestroySpace(const DestroySpaceRequest& request,
+                    const DestroySpaceCallback& callback) override;
+  void WriteSpace(const WriteSpaceRequest& request,
+                  const WriteSpaceCallback& callback) override;
+  void ReadSpace(const ReadSpaceRequest& request,
+                 const ReadSpaceCallback& callback) override;
+  void LockSpace(const LockSpaceRequest& request,
+                 const LockSpaceCallback& callback) override;
+  void ListSpaces(const ListSpacesRequest& request,
+                  const ListSpacesCallback& callback) override;
+  void GetSpaceInfo(const GetSpaceInfoRequest& request,
+                    const GetSpaceInfoCallback& callback) override;
+
+ private:
+  android::sp<android::tpm_manager::ITpmNvram> default_binder_;
+  android::tpm_manager::ITpmNvram* binder_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(TpmNvramBinderProxy);
+};
+
+}  // namespace tpm_manager
+
+#endif  // TPM_MANAGER_CLIENT_TPM_NVRAM_BINDER_PROXY_H_
diff --git a/tpm_manager/client/tpm_nvram_dbus_proxy.cc b/tpm_manager/client/tpm_nvram_dbus_proxy.cc
index aed66dc..df14037 100644
--- a/tpm_manager/client/tpm_nvram_dbus_proxy.cc
+++ b/tpm_manager/client/tpm_nvram_dbus_proxy.cc
@@ -47,41 +47,39 @@
   return (object_proxy_ != nullptr);
 }
 
-void TpmNvramDBusProxy::DefineNvram(const DefineNvramRequest& request,
-                                    const DefineNvramCallback& callback) {
-  CallMethod<DefineNvramReply>(tpm_manager::kDefineNvram, request, callback);
+void TpmNvramDBusProxy::DefineSpace(const DefineSpaceRequest& request,
+                                    const DefineSpaceCallback& callback) {
+  CallMethod<DefineSpaceReply>(tpm_manager::kDefineSpace, request, callback);
 }
 
-void TpmNvramDBusProxy::DestroyNvram(const DestroyNvramRequest& request,
-                                     const DestroyNvramCallback& callback) {
-  CallMethod<DestroyNvramReply>(tpm_manager::kDestroyNvram, request, callback);
+void TpmNvramDBusProxy::DestroySpace(const DestroySpaceRequest& request,
+                                     const DestroySpaceCallback& callback) {
+  CallMethod<DestroySpaceReply>(tpm_manager::kDestroySpace, request, callback);
 }
 
-void TpmNvramDBusProxy::WriteNvram(const WriteNvramRequest& request,
-                                   const WriteNvramCallback& callback) {
-  CallMethod<WriteNvramReply>(tpm_manager::kWriteNvram, request, callback);
+void TpmNvramDBusProxy::WriteSpace(const WriteSpaceRequest& request,
+                                   const WriteSpaceCallback& callback) {
+  CallMethod<WriteSpaceReply>(tpm_manager::kWriteSpace, request, callback);
 }
 
-void TpmNvramDBusProxy::ReadNvram(const ReadNvramRequest& request,
-                                  const ReadNvramCallback& callback) {
-  CallMethod<ReadNvramReply>(tpm_manager::kReadNvram, request, callback);
+void TpmNvramDBusProxy::ReadSpace(const ReadSpaceRequest& request,
+                                  const ReadSpaceCallback& callback) {
+  CallMethod<ReadSpaceReply>(tpm_manager::kReadSpace, request, callback);
 }
 
-void TpmNvramDBusProxy::IsNvramDefined(const IsNvramDefinedRequest& request,
-                                       const IsNvramDefinedCallback& callback) {
-  CallMethod<IsNvramDefinedReply>(tpm_manager::kIsNvramDefined, request,
-                                  callback);
+void TpmNvramDBusProxy::LockSpace(const LockSpaceRequest& request,
+                                  const LockSpaceCallback& callback) {
+  CallMethod<LockSpaceReply>(tpm_manager::kLockSpace, request, callback);
 }
 
-void TpmNvramDBusProxy::IsNvramLocked(const IsNvramLockedRequest& request,
-                                      const IsNvramLockedCallback& callback) {
-  CallMethod<IsNvramLockedReply>(tpm_manager::kIsNvramLocked, request,
-                                 callback);
+void TpmNvramDBusProxy::ListSpaces(const ListSpacesRequest& request,
+                                   const ListSpacesCallback& callback) {
+  CallMethod<ListSpacesReply>(tpm_manager::kListSpaces, request, callback);
 }
 
-void TpmNvramDBusProxy::GetNvramSize(const GetNvramSizeRequest& request,
-                                     const GetNvramSizeCallback& callback) {
-  CallMethod<GetNvramSizeReply>(tpm_manager::kGetNvramSize, request, callback);
+void TpmNvramDBusProxy::GetSpaceInfo(const GetSpaceInfoRequest& request,
+                                     const GetSpaceInfoCallback& callback) {
+  CallMethod<GetSpaceInfoReply>(tpm_manager::kGetSpaceInfo, request, callback);
 }
 
 template <typename ReplyProtobufType,
@@ -92,7 +90,7 @@
                                    const CallbackType& callback) {
   auto on_error = [callback](brillo::Error* error) {
     ReplyProtobufType reply;
-    reply.set_status(STATUS_NOT_AVAILABLE);
+    reply.set_result(NVRAM_RESULT_IPC_ERROR);
     callback.Run(reply);
   };
   brillo::dbus_utils::CallMethodWithTimeout(
diff --git a/tpm_manager/client/tpm_nvram_dbus_proxy.h b/tpm_manager/client/tpm_nvram_dbus_proxy.h
index c757f2c..a4cd4c5 100644
--- a/tpm_manager/client/tpm_nvram_dbus_proxy.h
+++ b/tpm_manager/client/tpm_nvram_dbus_proxy.h
@@ -34,7 +34,7 @@
 // tpm_managerd over D-Bus.
 // Usage:
 // std::unique_ptr<TpmNvramInterface> tpm_manager = new TpmNvramDBusProxy();
-// tpm_manager->DefineNvram(...);
+// tpm_manager->DefineSpace(...);
 class TPM_MANAGER_EXPORT TpmNvramDBusProxy : public TpmNvramInterface {
  public:
   TpmNvramDBusProxy() = default;
@@ -45,20 +45,20 @@
   bool Initialize();
 
   // TpmNvramInterface methods.
-  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;
+  void DefineSpace(const DefineSpaceRequest& request,
+                   const DefineSpaceCallback& callback) override;
+  void DestroySpace(const DestroySpaceRequest& request,
+                    const DestroySpaceCallback& callback) override;
+  void WriteSpace(const WriteSpaceRequest& request,
+                  const WriteSpaceCallback& callback) override;
+  void ReadSpace(const ReadSpaceRequest& request,
+                 const ReadSpaceCallback& callback) override;
+  void LockSpace(const LockSpaceRequest& request,
+                 const LockSpaceCallback& callback) override;
+  void ListSpaces(const ListSpacesRequest& request,
+                  const ListSpacesCallback& callback) override;
+  void GetSpaceInfo(const GetSpaceInfoRequest& request,
+                    const GetSpaceInfoCallback& callback) override;
 
   void set_object_proxy(dbus::ObjectProxy* object_proxy) {
     object_proxy_ = object_proxy;
diff --git a/tpm_manager/client/tpm_nvram_dbus_proxy_test.cc b/tpm_manager/client/tpm_nvram_dbus_proxy_test.cc
index 9f31918..9b9fdc1 100644
--- a/tpm_manager/client/tpm_nvram_dbus_proxy_test.cc
+++ b/tpm_manager/client/tpm_nvram_dbus_proxy_test.cc
@@ -44,25 +44,25 @@
   TpmNvramDBusProxy proxy_;
 };
 
-TEST_F(TpmNvramDBusProxyTest, DefineNvram) {
+TEST_F(TpmNvramDBusProxyTest, DefineSpace) {
   uint32_t nvram_index = 5;
-  size_t nvram_length = 32;
-  auto fake_dbus_call = [nvram_index, nvram_length](
+  size_t nvram_size = 32;
+  auto fake_dbus_call = [nvram_index, nvram_size](
       dbus::MethodCall* method_call,
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    DefineNvramRequest request;
+    DefineSpaceRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
-    EXPECT_TRUE(request.has_length());
-    EXPECT_EQ(nvram_length, request.length());
+    EXPECT_TRUE(request.has_size());
+    EXPECT_EQ(nvram_size, request.size());
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    DefineNvramReply reply;
-    reply.set_status(STATUS_SUCCESS);
+    DefineSpaceReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
   };
@@ -70,33 +70,33 @@
       .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
   // Set expectations on the outputs.
   int callback_count = 0;
-  auto callback = [&callback_count](const DefineNvramReply& reply) {
+  auto callback = [&callback_count](const DefineSpaceReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  DefineNvramRequest request;
+  DefineSpaceRequest request;
   request.set_index(nvram_index);
-  request.set_length(nvram_length);
-  proxy_.DefineNvram(request, base::Bind(callback));
+  request.set_size(nvram_size);
+  proxy_.DefineSpace(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
 
-TEST_F(TpmNvramDBusProxyTest, DestroyNvram) {
+TEST_F(TpmNvramDBusProxyTest, DestroySpaceRequest) {
   uint32_t nvram_index = 5;
   auto fake_dbus_call = [nvram_index](
       dbus::MethodCall* method_call,
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    DestroyNvramRequest request;
+    DestroySpaceRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    DestroyNvramReply reply;
-    reply.set_status(STATUS_SUCCESS);
+    DestroySpaceReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
   };
@@ -104,16 +104,16 @@
       .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
   // Set expectations on the outputs.
   int callback_count = 0;
-  auto callback = [&callback_count](const DestroyNvramReply& reply) {
+  auto callback = [&callback_count](const DestroySpaceReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  DestroyNvramRequest request;
+  DestroySpaceRequest request;
   request.set_index(nvram_index);
-  proxy_.DestroyNvram(request, base::Bind(callback));
+  proxy_.DestroySpace(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
-TEST_F(TpmNvramDBusProxyTest, WriteNvram) {
+TEST_F(TpmNvramDBusProxyTest, WriteSpace) {
   uint32_t nvram_index = 5;
   std::string nvram_data("nvram_data");
   auto fake_dbus_call = [nvram_index, nvram_data](
@@ -121,7 +121,7 @@
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    WriteNvramRequest request;
+    WriteSpaceRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
@@ -130,8 +130,8 @@
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    WriteNvramReply reply;
-    reply.set_status(STATUS_SUCCESS);
+    WriteSpaceReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
   };
@@ -139,18 +139,18 @@
       .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
   // Set expectations on the outputs.
   int callback_count = 0;
-  auto callback = [&callback_count](const WriteNvramReply& reply) {
+  auto callback = [&callback_count](const WriteSpaceReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  WriteNvramRequest request;
+  WriteSpaceRequest request;
   request.set_index(nvram_index);
   request.set_data(nvram_data);
-  proxy_.WriteNvram(request, base::Bind(callback));
+  proxy_.WriteSpace(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
 
-TEST_F(TpmNvramDBusProxyTest, ReadNvram) {
+TEST_F(TpmNvramDBusProxyTest, ReadSpace) {
   uint32_t nvram_index = 5;
   std::string nvram_data("nvram_data");
   auto fake_dbus_call = [nvram_index, nvram_data](
@@ -158,15 +158,15 @@
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    ReadNvramRequest request;
+    ReadSpaceRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    ReadNvramReply reply;
-    reply.set_status(STATUS_SUCCESS);
+    ReadSpaceReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
     reply.set_data(nvram_data);
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
@@ -175,36 +175,68 @@
       .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
   // Set expectations on the outputs.
   int callback_count = 0;
-  auto callback = [&callback_count, nvram_data](const ReadNvramReply& reply) {
+  auto callback = [&callback_count, nvram_data](const ReadSpaceReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
     EXPECT_TRUE(reply.has_data());
     EXPECT_EQ(nvram_data, reply.data());
   };
-  ReadNvramRequest request;
+  ReadSpaceRequest request;
   request.set_index(nvram_index);
-  proxy_.ReadNvram(request, base::Bind(callback));
+  proxy_.ReadSpace(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
 
-TEST_F(TpmNvramDBusProxyTest, IsNvramDefined) {
+TEST_F(TpmNvramDBusProxyTest, LockSpace) {
   uint32_t nvram_index = 5;
-  bool nvram_defined = true;
-  auto fake_dbus_call = [nvram_index, nvram_defined](
+  auto fake_dbus_call = [nvram_index](
       dbus::MethodCall* method_call,
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    IsNvramDefinedRequest request;
+    LockSpaceRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    IsNvramDefinedReply reply;
-    reply.set_status(STATUS_SUCCESS);
-    reply.set_is_defined(nvram_defined);
+    LockSpaceReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
+    writer.AppendProtoAsArrayOfBytes(reply);
+    response_callback.Run(response.release());
+  };
+  EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
+  // Set expectations on the outputs.
+  int callback_count = 0;
+  auto callback = [&callback_count](const LockSpaceReply& reply) {
+    callback_count++;
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+  };
+  LockSpaceRequest request;
+  request.set_index(nvram_index);
+  proxy_.LockSpace(request, base::Bind(callback));
+  EXPECT_EQ(1, callback_count);
+}
+
+TEST_F(TpmNvramDBusProxyTest, ListSpaces) {
+  constexpr uint32_t nvram_index_list[] = {3, 4, 5};
+  auto fake_dbus_call = [nvram_index_list](
+      dbus::MethodCall* method_call,
+      const dbus::MockObjectProxy::ResponseCallback& response_callback) {
+    // Verify request protobuf.
+    dbus::MessageReader reader(method_call);
+    ListSpacesRequest request;
+    EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
+    // Create reply protobuf.
+    auto response = dbus::Response::CreateEmpty();
+    dbus::MessageWriter writer(response.get());
+    ListSpacesReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
+    for (auto index : nvram_index_list) {
+      reply.add_index_list(index);
+    }
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
   };
@@ -213,57 +245,20 @@
   // Set expectations on the outputs.
   int callback_count = 0;
   auto callback = [&callback_count,
-                   nvram_defined](const IsNvramDefinedReply& reply) {
+                   nvram_index_list](const ListSpacesReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
-    EXPECT_TRUE(reply.has_is_defined());
-    EXPECT_EQ(nvram_defined, reply.is_defined());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+    EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size());
+    for (size_t i = 0; i < 3; i++) {
+      EXPECT_EQ(nvram_index_list[i], reply.index_list(i));
+    }
   };
-  IsNvramDefinedRequest request;
-  request.set_index(nvram_index);
-  proxy_.IsNvramDefined(request, base::Bind(callback));
+  ListSpacesRequest request;
+  proxy_.ListSpaces(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
 
-TEST_F(TpmNvramDBusProxyTest, IsNvramLocked) {
-  uint32_t nvram_index = 5;
-  bool nvram_locked = true;
-  auto fake_dbus_call = [nvram_index, nvram_locked](
-      dbus::MethodCall* method_call,
-      const dbus::MockObjectProxy::ResponseCallback& response_callback) {
-    // Verify request protobuf.
-    dbus::MessageReader reader(method_call);
-    IsNvramLockedRequest request;
-    EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
-    EXPECT_TRUE(request.has_index());
-    EXPECT_EQ(nvram_index, request.index());
-    // Create reply protobuf.
-    auto response = dbus::Response::CreateEmpty();
-    dbus::MessageWriter writer(response.get());
-    IsNvramLockedReply reply;
-    reply.set_status(STATUS_SUCCESS);
-    reply.set_is_locked(nvram_locked);
-    writer.AppendProtoAsArrayOfBytes(reply);
-    response_callback.Run(response.release());
-  };
-  EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
-      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
-  // Set expectations on the outputs.
-  int callback_count = 0;
-  auto callback = [&callback_count,
-                   nvram_locked](const IsNvramLockedReply& reply) {
-    callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
-    EXPECT_TRUE(reply.has_is_locked());
-    EXPECT_EQ(nvram_locked, reply.is_locked());
-  };
-  IsNvramLockedRequest request;
-  request.set_index(nvram_index);
-  proxy_.IsNvramLocked(request, base::Bind(callback));
-  EXPECT_EQ(1, callback_count);
-}
-
-TEST_F(TpmNvramDBusProxyTest, GetNvramSize) {
+TEST_F(TpmNvramDBusProxyTest, GetSpaceInfo) {
   uint32_t nvram_index = 5;
   size_t nvram_size = 32;
   auto fake_dbus_call = [nvram_index, nvram_size](
@@ -271,15 +266,15 @@
       const dbus::MockObjectProxy::ResponseCallback& response_callback) {
     // Verify request protobuf.
     dbus::MessageReader reader(method_call);
-    GetNvramSizeRequest request;
+    GetSpaceInfoRequest request;
     EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
     EXPECT_TRUE(request.has_index());
     EXPECT_EQ(nvram_index, request.index());
     // Create reply protobuf.
     auto response = dbus::Response::CreateEmpty();
     dbus::MessageWriter writer(response.get());
-    GetNvramSizeReply reply;
-    reply.set_status(STATUS_SUCCESS);
+    GetSpaceInfoReply reply;
+    reply.set_result(NVRAM_RESULT_SUCCESS);
     reply.set_size(nvram_size);
     writer.AppendProtoAsArrayOfBytes(reply);
     response_callback.Run(response.release());
@@ -289,15 +284,15 @@
   // Set expectations on the outputs.
   int callback_count = 0;
   auto callback = [&callback_count,
-                   nvram_size](const GetNvramSizeReply& reply) {
+                   nvram_size](const GetSpaceInfoReply& reply) {
     callback_count++;
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
     EXPECT_TRUE(reply.has_size());
     EXPECT_EQ(nvram_size, reply.size());
   };
-  GetNvramSizeRequest request;
+  GetSpaceInfoRequest request;
   request.set_index(nvram_index);
-  proxy_.GetNvramSize(request, base::Bind(callback));
+  proxy_.GetSpaceInfo(request, base::Bind(callback));
   EXPECT_EQ(1, callback_count);
 }
 
diff --git a/tpm_manager/client/tpm_ownership_binder_proxy.cc b/tpm_manager/client/tpm_ownership_binder_proxy.cc
new file mode 100644
index 0000000..0f0d52c
--- /dev/null
+++ b/tpm_manager/client/tpm_ownership_binder_proxy.cc
@@ -0,0 +1,96 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "tpm_manager/client/tpm_ownership_binder_proxy.h"
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <utils/Errors.h>
+
+#include "android/tpm_manager/BnTpmManagerClient.h"
+#include "android/tpm_manager/BpTpmOwnership.h"
+#include "tpm_manager/client/binder_proxy_helper.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
+#include "tpm_manager/common/tpm_manager_constants.h"
+
+namespace {
+
+template <typename ResponseProtobufType>
+void CreateErrorResponse(ResponseProtobufType* response) {
+  response->set_status(tpm_manager::STATUS_DEVICE_ERROR);
+}
+
+}  // namespace
+
+namespace tpm_manager {
+
+using android::tpm_manager::ITpmOwnership;
+
+TpmOwnershipBinderProxy::TpmOwnershipBinderProxy(ITpmOwnership* binder)
+    : binder_(binder) {}
+
+bool TpmOwnershipBinderProxy::Initialize() {
+  if (binder_) {
+    return true;
+  }
+  android::sp<android::IBinder> service_binder =
+      android::BinderWrapper::GetOrCreateInstance()->GetService(
+          kTpmOwnershipBinderName);
+  if (!service_binder.get()) {
+    LOG(ERROR) << "TpmOwnershipBinderProxy: Service does not exist.";
+    return false;
+  }
+  default_binder_ = new android::tpm_manager::BpTpmOwnership(service_binder);
+  binder_ = default_binder_.get();
+  return true;
+}
+
+void TpmOwnershipBinderProxy::GetTpmStatus(
+    const GetTpmStatusRequest& request,
+    const GetTpmStatusCallback& callback) {
+  auto method =
+      base::Bind(&ITpmOwnership::GetTpmStatus, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<GetTpmStatusReply>);
+  BinderProxyHelper<GetTpmStatusRequest, GetTpmStatusReply> helper(
+      method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+void TpmOwnershipBinderProxy::TakeOwnership(
+    const TakeOwnershipRequest& request,
+    const TakeOwnershipCallback& callback) {
+  auto method =
+      base::Bind(&ITpmOwnership::TakeOwnership, base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<TakeOwnershipReply>);
+  BinderProxyHelper<TakeOwnershipRequest, TakeOwnershipReply> helper(
+      method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+void TpmOwnershipBinderProxy::RemoveOwnerDependency(
+    const RemoveOwnerDependencyRequest& request,
+    const RemoveOwnerDependencyCallback& callback) {
+  auto method = base::Bind(&ITpmOwnership::RemoveOwnerDependency,
+                           base::Unretained(binder_));
+  auto get_error = base::Bind(&CreateErrorResponse<RemoveOwnerDependencyReply>);
+  BinderProxyHelper<RemoveOwnerDependencyRequest, RemoveOwnerDependencyReply>
+      helper(method, callback, get_error);
+  helper.SendRequest(request);
+}
+
+}  // namespace tpm_manager
diff --git a/tpm_manager/client/tpm_ownership_binder_proxy.h b/tpm_manager/client/tpm_ownership_binder_proxy.h
new file mode 100644
index 0000000..e028ad5
--- /dev/null
+++ b/tpm_manager/client/tpm_ownership_binder_proxy.h
@@ -0,0 +1,59 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TPM_MANAGER_CLIENT_TPM_OWNERSHIP_BINDER_PROXY_H_
+#define TPM_MANAGER_CLIENT_TPM_OWNERSHIP_BINDER_PROXY_H_
+
+#include <base/macros.h>
+
+#include "android/tpm_manager/ITpmOwnership.h"
+#include "tpm_manager/common/export.h"
+#include "tpm_manager/common/tpm_ownership_interface.h"
+
+namespace tpm_manager {
+
+// An implementation of TpmOwnershipInterface that forwards requests to
+// tpm_managerd using Binder.
+class TPM_MANAGER_EXPORT TpmOwnershipBinderProxy
+    : public TpmOwnershipInterface {
+ public:
+  TpmOwnershipBinderProxy() = default;
+  explicit TpmOwnershipBinderProxy(android::tpm_manager::ITpmOwnership* binder);
+  ~TpmOwnershipBinderProxy() override = default;
+
+  // Initializes the client. Returns true on success.
+  bool Initialize();
+
+  // TpmOwnershipInterface methods. All assume a message loop and binder watcher
+  // have already been configured elsewhere.
+  void GetTpmStatus(const GetTpmStatusRequest& request,
+                    const GetTpmStatusCallback& callback) override;
+  void TakeOwnership(const TakeOwnershipRequest& request,
+                     const TakeOwnershipCallback& callback) override;
+  void RemoveOwnerDependency(
+      const RemoveOwnerDependencyRequest& request,
+      const RemoveOwnerDependencyCallback& callback) override;
+
+ private:
+  android::sp<android::tpm_manager::ITpmOwnership> default_binder_;
+  android::tpm_manager::ITpmOwnership* binder_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(TpmOwnershipBinderProxy);
+};
+
+}  // namespace tpm_manager
+
+#endif  // TPM_MANAGER_CLIENT_TPM_OWNERSHIP_BINDER_PROXY_H_
diff --git a/tpm_manager/common/local_data.proto b/tpm_manager/common/local_data.proto
deleted file mode 100644
index a6ba6e1..0000000
--- a/tpm_manager/common/local_data.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-option optimize_for = LITE_RUNTIME;
-package tpm_manager;
-
-// The format of persistent local TPM management data stored on the device.
-// When Tpm ownership is taken, this protobuf is populated with the passwords
-// used to take ownership, and with a list of clients who have a dependency on
-// the owner password (like Attestation, InstallAttributes and BootLockbox).
-// when all the clients have the owner password injected, this protobuf is
-// cleared of all passwords.
-message LocalData {
-  optional bytes owner_password = 2;
-  repeated string owner_dependency = 3;
-  optional bytes endorsement_password = 4;
-  optional bytes lockout_password = 5;
-}
diff --git a/tpm_manager/common/mock_tpm_nvram_interface.h b/tpm_manager/common/mock_tpm_nvram_interface.h
index 2f8364d..bba1e6b 100644
--- a/tpm_manager/common/mock_tpm_nvram_interface.h
+++ b/tpm_manager/common/mock_tpm_nvram_interface.h
@@ -28,27 +28,27 @@
   MockTpmNvramInterface();
   ~MockTpmNvramInterface() override;
 
-  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));
+  MOCK_METHOD2(DefineSpace,
+               void(const DefineSpaceRequest& request,
+                    const DefineSpaceCallback& callback));
+  MOCK_METHOD2(DestroySpace,
+               void(const DestroySpaceRequest& request,
+                    const DestroySpaceCallback& callback));
+  MOCK_METHOD2(WriteSpace,
+               void(const WriteSpaceRequest& request,
+                    const WriteSpaceCallback& callback));
+  MOCK_METHOD2(ReadSpace,
+               void(const ReadSpaceRequest& request,
+                    const ReadSpaceCallback& callback));
+  MOCK_METHOD2(LockSpace,
+               void(const LockSpaceRequest& request,
+                    const LockSpaceCallback& callback));
+  MOCK_METHOD2(ListSpaces,
+               void(const ListSpacesRequest& request,
+                    const ListSpacesCallback& callback));
+  MOCK_METHOD2(GetSpaceInfo,
+               void(const GetSpaceInfoRequest& request,
+                    const GetSpaceInfoCallback& callback));
 };
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/common/print_local_data_proto.cc b/tpm_manager/common/print_local_data_proto.cc
deleted file mode 100644
index 76cb98e..0000000
--- a/tpm_manager/common/print_local_data_proto.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// THIS CODE IS GENERATED.
-
-#include "tpm_manager/common/print_local_data_proto.h"
-
-#include <string>
-
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/stringprintf.h>
-
-namespace tpm_manager {
-
-std::string GetProtoDebugString(const LocalData& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(const LocalData& value,
-                                          int indent_size) {
-  std::string indent(indent_size, ' ');
-  std::string output =
-      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
-
-  if (value.has_owner_password()) {
-    output += indent + "  owner_password: ";
-    base::StringAppendF(&output, "%s",
-                        base::HexEncode(value.owner_password().data(),
-                                        value.owner_password().size())
-                            .c_str());
-    output += "\n";
-  }
-  output += indent + "  owner_dependency: {";
-  for (int i = 0; i < value.owner_dependency_size(); ++i) {
-    base::StringAppendF(&output, "%s", value.owner_dependency(i).c_str());
-  }
-  output += "}\n";
-  if (value.has_endorsement_password()) {
-    output += indent + "  endorsement_password: ";
-    base::StringAppendF(&output, "%s",
-                        base::HexEncode(value.endorsement_password().data(),
-                                        value.endorsement_password().size())
-                            .c_str());
-    output += "\n";
-  }
-  if (value.has_lockout_password()) {
-    output += indent + "  lockout_password: ";
-    base::StringAppendF(&output, "%s",
-                        base::HexEncode(value.lockout_password().data(),
-                                        value.lockout_password().size())
-                            .c_str());
-    output += "\n";
-  }
-  output += indent + "}\n";
-  return output;
-}
-
-}  // namespace tpm_manager
diff --git a/tpm_manager/common/print_local_data_proto.h b/tpm_manager/common/print_local_data_proto.h
deleted file mode 100644
index fe231bb..0000000
--- a/tpm_manager/common/print_local_data_proto.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#ifndef TPM_MANAGER_COMMON_PRINT_LOCAL_DATA_PROTO_H_
-#define TPM_MANAGER_COMMON_PRINT_LOCAL_DATA_PROTO_H_
-
-#include <string>
-
-#include "tpm_manager/common/local_data.pb.h"
-
-namespace tpm_manager {
-
-std::string GetProtoDebugStringWithIndent(const LocalData& value,
-                                          int indent_size);
-std::string GetProtoDebugString(const LocalData& value);
-
-}  // namespace tpm_manager
-
-#endif  // TPM_MANAGER_COMMON_PRINT_LOCAL_DATA_PROTO_H_
diff --git a/tpm_manager/common/print_tpm_manager_proto.cc b/tpm_manager/common/print_tpm_manager_proto.cc
new file mode 100644
index 0000000..5ac301d
--- /dev/null
+++ b/tpm_manager/common/print_tpm_manager_proto.cc
@@ -0,0 +1,803 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// THIS CODE IS GENERATED.
+
+#include "tpm_manager/common/print_tpm_manager_proto.h"
+
+#include <string>
+
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
+
+namespace tpm_manager {
+
+std::string GetProtoDebugString(TpmManagerStatus value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(TpmManagerStatus value,
+                                          int indent_size) {
+  if (value == STATUS_SUCCESS) {
+    return "STATUS_SUCCESS";
+  }
+  if (value == STATUS_DEVICE_ERROR) {
+    return "STATUS_DEVICE_ERROR";
+  }
+  if (value == STATUS_NOT_AVAILABLE) {
+    return "STATUS_NOT_AVAILABLE";
+  }
+  return "<unknown>";
+}
+
+std::string GetProtoDebugString(NvramResult value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(NvramResult value, int indent_size) {
+  if (value == NVRAM_RESULT_SUCCESS) {
+    return "NVRAM_RESULT_SUCCESS";
+  }
+  if (value == NVRAM_RESULT_DEVICE_ERROR) {
+    return "NVRAM_RESULT_DEVICE_ERROR";
+  }
+  if (value == NVRAM_RESULT_ACCESS_DENIED) {
+    return "NVRAM_RESULT_ACCESS_DENIED";
+  }
+  if (value == NVRAM_RESULT_INVALID_PARAMETER) {
+    return "NVRAM_RESULT_INVALID_PARAMETER";
+  }
+  if (value == NVRAM_RESULT_SPACE_DOES_NOT_EXIST) {
+    return "NVRAM_RESULT_SPACE_DOES_NOT_EXIST";
+  }
+  if (value == NVRAM_RESULT_SPACE_ALREADY_EXISTS) {
+    return "NVRAM_RESULT_SPACE_ALREADY_EXISTS";
+  }
+  if (value == NVRAM_RESULT_OPERATION_DISABLED) {
+    return "NVRAM_RESULT_OPERATION_DISABLED";
+  }
+  if (value == NVRAM_RESULT_INSUFFICIENT_SPACE) {
+    return "NVRAM_RESULT_INSUFFICIENT_SPACE";
+  }
+  if (value == NVRAM_RESULT_IPC_ERROR) {
+    return "NVRAM_RESULT_IPC_ERROR";
+  }
+  return "<unknown>";
+}
+
+std::string GetProtoDebugString(NvramSpaceAttribute value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(NvramSpaceAttribute value,
+                                          int indent_size) {
+  if (value == NVRAM_PERSISTENT_WRITE_LOCK) {
+    return "NVRAM_PERSISTENT_WRITE_LOCK";
+  }
+  if (value == NVRAM_BOOT_WRITE_LOCK) {
+    return "NVRAM_BOOT_WRITE_LOCK";
+  }
+  if (value == NVRAM_BOOT_READ_LOCK) {
+    return "NVRAM_BOOT_READ_LOCK";
+  }
+  if (value == NVRAM_WRITE_AUTHORIZATION) {
+    return "NVRAM_WRITE_AUTHORIZATION";
+  }
+  if (value == NVRAM_READ_AUTHORIZATION) {
+    return "NVRAM_READ_AUTHORIZATION";
+  }
+  if (value == NVRAM_WRITE_EXTEND) {
+    return "NVRAM_WRITE_EXTEND";
+  }
+  if (value == NVRAM_GLOBAL_LOCK) {
+    return "NVRAM_GLOBAL_LOCK";
+  }
+  if (value == NVRAM_PLATFORM_WRITE) {
+    return "NVRAM_PLATFORM_WRITE";
+  }
+  if (value == NVRAM_OWNER_WRITE) {
+    return "NVRAM_OWNER_WRITE";
+  }
+  if (value == NVRAM_OWNER_READ) {
+    return "NVRAM_OWNER_READ";
+  }
+  return "<unknown>";
+}
+
+std::string GetProtoDebugString(NvramSpacePolicy value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(NvramSpacePolicy value,
+                                          int indent_size) {
+  if (value == NVRAM_POLICY_NONE) {
+    return "NVRAM_POLICY_NONE";
+  }
+  if (value == NVRAM_POLICY_PCR0) {
+    return "NVRAM_POLICY_PCR0";
+  }
+  return "<unknown>";
+}
+
+std::string GetProtoDebugString(const NvramPolicyRecord& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const NvramPolicyRecord& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  if (value.has_policy()) {
+    output += indent + "  policy: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.policy(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  if (value.has_world_read_allowed()) {
+    output += indent + "  world_read_allowed: ";
+    base::StringAppendF(&output, "%s",
+                        value.world_read_allowed() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_world_write_allowed()) {
+    output += indent + "  world_write_allowed: ";
+    base::StringAppendF(&output, "%s",
+                        value.world_write_allowed() ? "true" : "false");
+    output += "\n";
+  }
+  output += indent + "  policy_digests: {";
+  for (int i = 0; i < value.policy_digests_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.policy_digests(i).data(),
+                                        value.policy_digests(i).size())
+                            .c_str());
+  }
+  output += "}\n";
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const LocalData& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const LocalData& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_owner_password()) {
+    output += indent + "  owner_password: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.owner_password().data(),
+                                        value.owner_password().size())
+                            .c_str());
+    output += "\n";
+  }
+  output += indent + "  owner_dependency: {";
+  for (int i = 0; i < value.owner_dependency_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(&output, "%s", value.owner_dependency(i).c_str());
+  }
+  output += "}\n";
+  if (value.has_endorsement_password()) {
+    output += indent + "  endorsement_password: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.endorsement_password().data(),
+                                        value.endorsement_password().size())
+                            .c_str());
+    output += "\n";
+  }
+  if (value.has_lockout_password()) {
+    output += indent + "  lockout_password: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.lockout_password().data(),
+                                        value.lockout_password().size())
+                            .c_str());
+    output += "\n";
+  }
+  output += indent + "  nvram_policy: {";
+  for (int i = 0; i < value.nvram_policy_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.nvram_policy(i), indent_size + 2)
+            .c_str());
+  }
+  output += "}\n";
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const DefineSpaceRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const DefineSpaceRequest& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  if (value.has_size()) {
+    output += indent + "  size: ";
+    base::StringAppendF(&output, "%u (0x%08X)", value.size(), value.size());
+    output += "\n";
+  }
+  output += indent + "  attributes: {";
+  for (int i = 0; i < value.attributes_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(&output, "%s", GetProtoDebugStringWithIndent(
+                                           value.attributes(i), indent_size + 2)
+                                           .c_str());
+  }
+  output += "}\n";
+  if (value.has_authorization_value()) {
+    output += indent + "  authorization_value: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.authorization_value().data(),
+                                        value.authorization_value().size())
+                            .c_str());
+    output += "\n";
+  }
+  if (value.has_policy()) {
+    output += indent + "  policy: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.policy(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const DefineSpaceReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const DefineSpaceReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const DestroySpaceRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const DestroySpaceRequest& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const DestroySpaceReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const DestroySpaceReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const WriteSpaceRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const WriteSpaceRequest& 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, "%u (0x%08X)", value.index(), 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";
+  }
+  if (value.has_authorization_value()) {
+    output += indent + "  authorization_value: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.authorization_value().data(),
+                                        value.authorization_value().size())
+                            .c_str());
+    output += "\n";
+  }
+  if (value.has_use_owner_authorization()) {
+    output += indent + "  use_owner_authorization: ";
+    base::StringAppendF(&output, "%s",
+                        value.use_owner_authorization() ? "true" : "false");
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const WriteSpaceReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const WriteSpaceReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const ReadSpaceRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const ReadSpaceRequest& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  if (value.has_authorization_value()) {
+    output += indent + "  authorization_value: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.authorization_value().data(),
+                                        value.authorization_value().size())
+                            .c_str());
+    output += "\n";
+  }
+  if (value.has_use_owner_authorization()) {
+    output += indent + "  use_owner_authorization: ";
+    base::StringAppendF(&output, "%s",
+                        value.use_owner_authorization() ? "true" : "false");
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const ReadSpaceReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const ReadSpaceReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), 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 LockSpaceRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const LockSpaceRequest& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  if (value.has_lock_read()) {
+    output += indent + "  lock_read: ";
+    base::StringAppendF(&output, "%s", value.lock_read() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_lock_write()) {
+    output += indent + "  lock_write: ";
+    base::StringAppendF(&output, "%s", value.lock_write() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_authorization_value()) {
+    output += indent + "  authorization_value: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.authorization_value().data(),
+                                        value.authorization_value().size())
+                            .c_str());
+    output += "\n";
+  }
+  if (value.has_use_owner_authorization()) {
+    output += indent + "  use_owner_authorization: ";
+    base::StringAppendF(&output, "%s",
+                        value.use_owner_authorization() ? "true" : "false");
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const LockSpaceReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const LockSpaceReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const ListSpacesRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const ListSpacesRequest& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const ListSpacesReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const ListSpacesReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "  index_list: {";
+  for (int i = 0; i < value.index_list_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(&output, "%u (0x%08X)", value.index_list(i),
+                        value.index_list(i));
+  }
+  output += "}\n";
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const GetSpaceInfoRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const GetSpaceInfoRequest& 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, "%u (0x%08X)", value.index(), value.index());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const GetSpaceInfoReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const GetSpaceInfoReply& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_result()) {
+    output += indent + "  result: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.result(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  if (value.has_size()) {
+    output += indent + "  size: ";
+    base::StringAppendF(&output, "%u (0x%08X)", value.size(), value.size());
+    output += "\n";
+  }
+  if (value.has_is_read_locked()) {
+    output += indent + "  is_read_locked: ";
+    base::StringAppendF(&output, "%s",
+                        value.is_read_locked() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_is_write_locked()) {
+    output += indent + "  is_write_locked: ";
+    base::StringAppendF(&output, "%s",
+                        value.is_write_locked() ? "true" : "false");
+    output += "\n";
+  }
+  output += indent + "  attributes: {";
+  for (int i = 0; i < value.attributes_size(); ++i) {
+    if (i > 0) {
+      base::StringAppendF(&output, ", ");
+    }
+    base::StringAppendF(&output, "%s", GetProtoDebugStringWithIndent(
+                                           value.attributes(i), indent_size + 2)
+                                           .c_str());
+  }
+  output += "}\n";
+  if (value.has_policy()) {
+    output += indent + "  policy: ";
+    base::StringAppendF(
+        &output, "%s",
+        GetProtoDebugStringWithIndent(value.policy(), indent_size + 2).c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const GetTpmStatusRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const GetTpmStatusRequest& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const GetTpmStatusReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const GetTpmStatusReply& 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_enabled()) {
+    output += indent + "  enabled: ";
+    base::StringAppendF(&output, "%s", value.enabled() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_owned()) {
+    output += indent + "  owned: ";
+    base::StringAppendF(&output, "%s", value.owned() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_local_data()) {
+    output += indent + "  local_data: ";
+    base::StringAppendF(&output, "%s", GetProtoDebugStringWithIndent(
+                                           value.local_data(), indent_size + 2)
+                                           .c_str());
+    output += "\n";
+  }
+  if (value.has_dictionary_attack_counter()) {
+    output += indent + "  dictionary_attack_counter: ";
+    base::StringAppendF(&output, "%u (0x%08X)",
+                        value.dictionary_attack_counter(),
+                        value.dictionary_attack_counter());
+    output += "\n";
+  }
+  if (value.has_dictionary_attack_threshold()) {
+    output += indent + "  dictionary_attack_threshold: ";
+    base::StringAppendF(&output, "%u (0x%08X)",
+                        value.dictionary_attack_threshold(),
+                        value.dictionary_attack_threshold());
+    output += "\n";
+  }
+  if (value.has_dictionary_attack_lockout_in_effect()) {
+    output += indent + "  dictionary_attack_lockout_in_effect: ";
+    base::StringAppendF(
+        &output, "%s",
+        value.dictionary_attack_lockout_in_effect() ? "true" : "false");
+    output += "\n";
+  }
+  if (value.has_dictionary_attack_lockout_seconds_remaining()) {
+    output += indent + "  dictionary_attack_lockout_seconds_remaining: ";
+    base::StringAppendF(&output, "%u (0x%08X)",
+                        value.dictionary_attack_lockout_seconds_remaining(),
+                        value.dictionary_attack_lockout_seconds_remaining());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const TakeOwnershipRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const TakeOwnershipRequest& value,
+                                          int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const TakeOwnershipReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(const TakeOwnershipReply& 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 RemoveOwnerDependencyRequest& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(
+    const RemoveOwnerDependencyRequest& value,
+    int indent_size) {
+  std::string indent(indent_size, ' ');
+  std::string output =
+      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
+
+  if (value.has_owner_dependency()) {
+    output += indent + "  owner_dependency: ";
+    base::StringAppendF(&output, "%s",
+                        base::HexEncode(value.owner_dependency().data(),
+                                        value.owner_dependency().size())
+                            .c_str());
+    output += "\n";
+  }
+  output += indent + "}\n";
+  return output;
+}
+
+std::string GetProtoDebugString(const RemoveOwnerDependencyReply& value) {
+  return GetProtoDebugStringWithIndent(value, 0);
+}
+
+std::string GetProtoDebugStringWithIndent(
+    const RemoveOwnerDependencyReply& 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;
+}
+
+}  // namespace tpm_manager
diff --git a/tpm_manager/common/print_tpm_manager_proto.h b/tpm_manager/common/print_tpm_manager_proto.h
new file mode 100644
index 0000000..f6e3407
--- /dev/null
+++ b/tpm_manager/common/print_tpm_manager_proto.h
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// THIS CODE IS GENERATED.
+
+#ifndef TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_PROTO_H_
+#define TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_PROTO_H_
+
+#include <string>
+
+#include "tpm_manager/common/tpm_manager.pb.h"
+
+namespace tpm_manager {
+
+std::string GetProtoDebugStringWithIndent(TpmManagerStatus value,
+                                          int indent_size);
+std::string GetProtoDebugString(TpmManagerStatus value);
+std::string GetProtoDebugStringWithIndent(NvramResult value, int indent_size);
+std::string GetProtoDebugString(NvramResult value);
+std::string GetProtoDebugStringWithIndent(NvramSpaceAttribute value,
+                                          int indent_size);
+std::string GetProtoDebugString(NvramSpaceAttribute value);
+std::string GetProtoDebugStringWithIndent(NvramSpacePolicy value,
+                                          int indent_size);
+std::string GetProtoDebugString(NvramSpacePolicy value);
+std::string GetProtoDebugStringWithIndent(const NvramPolicyRecord& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const NvramPolicyRecord& value);
+std::string GetProtoDebugStringWithIndent(const LocalData& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const LocalData& value);
+std::string GetProtoDebugStringWithIndent(const DefineSpaceRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const DefineSpaceRequest& value);
+std::string GetProtoDebugStringWithIndent(const DefineSpaceReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const DefineSpaceReply& value);
+std::string GetProtoDebugStringWithIndent(const DestroySpaceRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const DestroySpaceRequest& value);
+std::string GetProtoDebugStringWithIndent(const DestroySpaceReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const DestroySpaceReply& value);
+std::string GetProtoDebugStringWithIndent(const WriteSpaceRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const WriteSpaceRequest& value);
+std::string GetProtoDebugStringWithIndent(const WriteSpaceReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const WriteSpaceReply& value);
+std::string GetProtoDebugStringWithIndent(const ReadSpaceRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const ReadSpaceRequest& value);
+std::string GetProtoDebugStringWithIndent(const ReadSpaceReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const ReadSpaceReply& value);
+std::string GetProtoDebugStringWithIndent(const LockSpaceRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const LockSpaceRequest& value);
+std::string GetProtoDebugStringWithIndent(const LockSpaceReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const LockSpaceReply& value);
+std::string GetProtoDebugStringWithIndent(const ListSpacesRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const ListSpacesRequest& value);
+std::string GetProtoDebugStringWithIndent(const ListSpacesReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const ListSpacesReply& value);
+std::string GetProtoDebugStringWithIndent(const GetSpaceInfoRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const GetSpaceInfoRequest& value);
+std::string GetProtoDebugStringWithIndent(const GetSpaceInfoReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const GetSpaceInfoReply& value);
+std::string GetProtoDebugStringWithIndent(const GetTpmStatusRequest& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const GetTpmStatusRequest& value);
+std::string GetProtoDebugStringWithIndent(const GetTpmStatusReply& value,
+                                          int indent_size);
+std::string GetProtoDebugString(const GetTpmStatusReply& value);
+std::string GetProtoDebugStringWithIndent(const TakeOwnershipRequest& value,
+                                          int indent_size);
+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 RemoveOwnerDependencyRequest& value,
+    int indent_size);
+std::string GetProtoDebugString(const RemoveOwnerDependencyRequest& value);
+std::string GetProtoDebugStringWithIndent(
+    const RemoveOwnerDependencyReply& value,
+    int indent_size);
+std::string GetProtoDebugString(const RemoveOwnerDependencyReply& value);
+
+}  // namespace tpm_manager
+
+#endif  // TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_PROTO_H_
diff --git a/tpm_manager/common/print_tpm_manager_status_proto.cc b/tpm_manager/common/print_tpm_manager_status_proto.cc
deleted file mode 100644
index e51e370..0000000
--- a/tpm_manager/common/print_tpm_manager_status_proto.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#include "tpm_manager/common/print_tpm_manager_status_proto.h"
-
-#include <string>
-
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/stringprintf.h>
-
-namespace tpm_manager {
-
-std::string GetProtoDebugString(TpmManagerStatus value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(TpmManagerStatus value,
-                                          int indent_size) {
-  if (value == STATUS_SUCCESS) {
-    return "STATUS_SUCCESS";
-  }
-  if (value == STATUS_UNEXPECTED_DEVICE_ERROR) {
-    return "STATUS_UNEXPECTED_DEVICE_ERROR";
-  }
-  if (value == STATUS_NOT_AVAILABLE) {
-    return "STATUS_NOT_AVAILABLE";
-  }
-  return "<unknown>";
-}
-
-}  // namespace tpm_manager
diff --git a/tpm_manager/common/print_tpm_manager_status_proto.h b/tpm_manager/common/print_tpm_manager_status_proto.h
deleted file mode 100644
index 3a23778..0000000
--- a/tpm_manager/common/print_tpm_manager_status_proto.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#ifndef TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_STATUS_PROTO_H_
-#define TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_STATUS_PROTO_H_
-
-#include <string>
-
-#include "tpm_manager/common/tpm_manager_status.pb.h"
-
-namespace tpm_manager {
-
-std::string GetProtoDebugStringWithIndent(TpmManagerStatus value,
-                                          int indent_size);
-std::string GetProtoDebugString(TpmManagerStatus value);
-
-}  // namespace tpm_manager
-
-#endif  // TPM_MANAGER_COMMON_PRINT_TPM_MANAGER_STATUS_PROTO_H_
diff --git a/tpm_manager/common/print_tpm_nvram_interface_proto.cc b/tpm_manager/common/print_tpm_nvram_interface_proto.cc
deleted file mode 100644
index 2e46900..0000000
--- a/tpm_manager/common/print_tpm_nvram_interface_proto.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#include "tpm_manager/common/print_tpm_nvram_interface_proto.h"
-
-#include <string>
-
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/stringprintf.h>
-
-#include "tpm_manager/common/print_tpm_manager_status_proto.h"
-
-namespace tpm_manager {
-
-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/tpm_manager/common/print_tpm_nvram_interface_proto.h b/tpm_manager/common/print_tpm_nvram_interface_proto.h
deleted file mode 100644
index 3db43f6..0000000
--- a/tpm_manager/common/print_tpm_nvram_interface_proto.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#ifndef TPM_MANAGER_COMMON_PRINT_TPM_NVRAM_INTERFACE_PROTO_H_
-#define TPM_MANAGER_COMMON_PRINT_TPM_NVRAM_INTERFACE_PROTO_H_
-
-#include <string>
-
-#include "tpm_manager/common/tpm_nvram_interface.pb.h"
-
-namespace tpm_manager {
-
-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
-
-#endif  // TPM_MANAGER_COMMON_PRINT_TPM_NVRAM_INTERFACE_PROTO_H_
diff --git a/tpm_manager/common/print_tpm_ownership_interface_proto.cc b/tpm_manager/common/print_tpm_ownership_interface_proto.cc
deleted file mode 100644
index 3d56ae1..0000000
--- a/tpm_manager/common/print_tpm_ownership_interface_proto.cc
+++ /dev/null
@@ -1,186 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#include "tpm_manager/common/print_tpm_ownership_interface_proto.h"
-
-#include <string>
-
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/stringprintf.h>
-
-#include "tpm_manager/common/print_local_data_proto.h"
-#include "tpm_manager/common/print_tpm_manager_status_proto.h"
-
-namespace tpm_manager {
-
-std::string GetProtoDebugString(const GetTpmStatusRequest& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(const GetTpmStatusRequest& value,
-                                          int indent_size) {
-  std::string indent(indent_size, ' ');
-  std::string output =
-      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
-
-  output += indent + "}\n";
-  return output;
-}
-
-std::string GetProtoDebugString(const GetTpmStatusReply& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(const GetTpmStatusReply& 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_enabled()) {
-    output += indent + "  enabled: ";
-    base::StringAppendF(&output, "%s", value.enabled() ? "true" : "false");
-    output += "\n";
-  }
-  if (value.has_owned()) {
-    output += indent + "  owned: ";
-    base::StringAppendF(&output, "%s", value.owned() ? "true" : "false");
-    output += "\n";
-  }
-  if (value.has_local_data()) {
-    output += indent + "  local_data: ";
-    base::StringAppendF(&output, "%s", GetProtoDebugStringWithIndent(
-                                           value.local_data(), indent_size + 2)
-                                           .c_str());
-    output += "\n";
-  }
-  if (value.has_dictionary_attack_counter()) {
-    output += indent + "  dictionary_attack_counter: ";
-    base::StringAppendF(&output, "%d", value.dictionary_attack_counter());
-    output += "\n";
-  }
-  if (value.has_dictionary_attack_threshold()) {
-    output += indent + "  dictionary_attack_threshold: ";
-    base::StringAppendF(&output, "%d", value.dictionary_attack_threshold());
-    output += "\n";
-  }
-  if (value.has_dictionary_attack_lockout_in_effect()) {
-    output += indent + "  dictionary_attack_lockout_in_effect: ";
-    base::StringAppendF(
-        &output, "%s",
-        value.dictionary_attack_lockout_in_effect() ? "true" : "false");
-    output += "\n";
-  }
-  if (value.has_dictionary_attack_lockout_seconds_remaining()) {
-    output += indent + "  dictionary_attack_lockout_seconds_remaining: ";
-    base::StringAppendF(&output, "%d",
-                        value.dictionary_attack_lockout_seconds_remaining());
-    output += "\n";
-  }
-  output += indent + "}\n";
-  return output;
-}
-
-std::string GetProtoDebugString(const TakeOwnershipRequest& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(const TakeOwnershipRequest& value,
-                                          int indent_size) {
-  std::string indent(indent_size, ' ');
-  std::string output =
-      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
-
-  output += indent + "}\n";
-  return output;
-}
-
-std::string GetProtoDebugString(const TakeOwnershipReply& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(const TakeOwnershipReply& 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 RemoveOwnerDependencyRequest& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(
-    const RemoveOwnerDependencyRequest& value,
-    int indent_size) {
-  std::string indent(indent_size, ' ');
-  std::string output =
-      base::StringPrintf("[%s] {\n", value.GetTypeName().c_str());
-
-  if (value.has_owner_dependency()) {
-    output += indent + "  owner_dependency: ";
-    base::StringAppendF(&output, "%s",
-                        base::HexEncode(value.owner_dependency().data(),
-                                        value.owner_dependency().size())
-                            .c_str());
-    output += "\n";
-  }
-  output += indent + "}\n";
-  return output;
-}
-
-std::string GetProtoDebugString(const RemoveOwnerDependencyReply& value) {
-  return GetProtoDebugStringWithIndent(value, 0);
-}
-
-std::string GetProtoDebugStringWithIndent(
-    const RemoveOwnerDependencyReply& 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;
-}
-
-}  // namespace tpm_manager
diff --git a/tpm_manager/common/print_tpm_ownership_interface_proto.h b/tpm_manager/common/print_tpm_ownership_interface_proto.h
deleted file mode 100644
index 8e13510..0000000
--- a/tpm_manager/common/print_tpm_ownership_interface_proto.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// THIS CODE IS GENERATED.
-
-#ifndef TPM_MANAGER_COMMON_PRINT_TPM_OWNERSHIP_INTERFACE_PROTO_H_
-#define TPM_MANAGER_COMMON_PRINT_TPM_OWNERSHIP_INTERFACE_PROTO_H_
-
-#include <string>
-
-#include "tpm_manager/common/tpm_ownership_interface.pb.h"
-
-namespace tpm_manager {
-
-std::string GetProtoDebugStringWithIndent(const GetTpmStatusRequest& value,
-                                          int indent_size);
-std::string GetProtoDebugString(const GetTpmStatusRequest& value);
-std::string GetProtoDebugStringWithIndent(const GetTpmStatusReply& value,
-                                          int indent_size);
-std::string GetProtoDebugString(const GetTpmStatusReply& value);
-std::string GetProtoDebugStringWithIndent(const TakeOwnershipRequest& value,
-                                          int indent_size);
-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 RemoveOwnerDependencyRequest& value,
-    int indent_size);
-std::string GetProtoDebugString(const RemoveOwnerDependencyRequest& value);
-std::string GetProtoDebugStringWithIndent(
-    const RemoveOwnerDependencyReply& value,
-    int indent_size);
-std::string GetProtoDebugString(const RemoveOwnerDependencyReply& value);
-
-}  // namespace tpm_manager
-
-#endif  // TPM_MANAGER_COMMON_PRINT_TPM_OWNERSHIP_INTERFACE_PROTO_H_
diff --git a/tpm_manager/common/tpm_manager.proto b/tpm_manager/common/tpm_manager.proto
new file mode 100644
index 0000000..2fa1b2e
--- /dev/null
+++ b/tpm_manager/common/tpm_manager.proto
@@ -0,0 +1,237 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// NOTE: All tpm_manager protobufs are in the same file because the Android
+// build system cannot handle import statements without using Android-specific
+// paths.
+
+option optimize_for = LITE_RUNTIME;
+package tpm_manager;
+
+enum TpmManagerStatus {
+  STATUS_SUCCESS = 0;
+  STATUS_DEVICE_ERROR = 1;
+  STATUS_NOT_AVAILABLE = 2;
+}
+
+// Result codes. For convenience, keep these in sync with Brillo NVRAM HAL
+// values defined in hardware/nvram_defs.h.
+enum NvramResult {
+  NVRAM_RESULT_SUCCESS = 0;
+  // An unexpected TPM error occurred. More information should be in logs.
+  NVRAM_RESULT_DEVICE_ERROR = 1;
+  // The caller is not authorized to perform the requested operation. This may
+  // be due to a bad authorization value or to system state.
+  NVRAM_RESULT_ACCESS_DENIED = 2;
+  NVRAM_RESULT_INVALID_PARAMETER = 3;
+  NVRAM_RESULT_SPACE_DOES_NOT_EXIST = 4;
+  NVRAM_RESULT_SPACE_ALREADY_EXISTS = 5;
+  // This may be because a space is locked or because an operation has been
+  // explicitly disabled.
+  NVRAM_RESULT_OPERATION_DISABLED = 6;
+  // Literally, the TPM is out of non-volatile storage.
+  NVRAM_RESULT_INSUFFICIENT_SPACE = 7;
+  // An error occurred sending the request to the system service.
+  NVRAM_RESULT_IPC_ERROR = 100;
+}
+
+// More background on these attributes can be found by looking up the TPMA_NV_*
+// constants in the TPM 2.0 specification or the TPM_NV_PER_* constants in the
+// TPM 1.2 specification.
+enum NvramSpaceAttribute {
+  // The space can be locked for writing until it is destroyed. Without TPM
+  // owner privilege this is always after the TPM is cleared. This typically
+  // occurs during device factory reset.
+  NVRAM_PERSISTENT_WRITE_LOCK = 0;
+  // The space can be locked for writing until the next boot.
+  NVRAM_BOOT_WRITE_LOCK = 1;
+  // The space can be locked for reading until the next boot.
+  NVRAM_BOOT_READ_LOCK = 2;
+  // The space requires an authorization value for writing.
+  NVRAM_WRITE_AUTHORIZATION = 3;
+  // The space requires an authorization value for reading.
+  NVRAM_READ_AUTHORIZATION = 4;
+  // The space can not be written directly, only extended.
+  // E.g. new_value = HASH(old_value + input)
+  NVRAM_WRITE_EXTEND = 5;
+  // The space is tied to the global lock (bGlobalLock). This global lock is
+  // typically locked early in boot. This is defined for inspecting existing
+  // spaces, this interface cannot be used to define spaces with this attribute.
+  NVRAM_GLOBAL_LOCK = 6;
+  // The space is tied to the platform rather than the TPM owner. The 'platform'
+  // is whatever executes first after boot. Typically this access is locked
+  // early in boot. This is defined for inspecting existing spaces, this
+  // interface cannot be used to define spaces with this attribute.
+  NVRAM_PLATFORM_WRITE = 7;
+  // The space can only be written by the TPM owner. For TPM 2.0 this can be
+  // used only for inspecting existing spaces, not for defining new spaces.
+  NVRAM_OWNER_WRITE = 8;
+  // The space can only be read by the TPM owner. For TPM 2.0 this can be used
+  // only for inspecting existing spaces, not for defining new spaces.
+  NVRAM_OWNER_READ = 9;
+}
+
+enum NvramSpacePolicy {
+  // No policy. Authorization values are still enforced. This is the default.
+  NVRAM_POLICY_NONE = 0;
+  // Bind both read and write access to the current PCR0 value in addition to
+  // enforcing any authorization value.
+  NVRAM_POLICY_PCR0 = 1;
+}
+
+// Tracks the expected policy for a particular NVRAM space.
+message NvramPolicyRecord {
+  optional uint32 index = 1;
+  optional NvramSpacePolicy policy = 2;
+  // This will be true if the NVRAM_READ_AUTHORIZATION attribute was not
+  // specified when the space was created.
+  optional bool world_read_allowed = 3;
+  // This will be true if the NVRAM_WRITE_AUTHORIZATION attribute was not
+  // specified when the space was created.
+  optional bool world_write_allowed = 4;
+  repeated bytes policy_digests = 5;
+}
+
+// The format of persistent local TPM management data stored on the device.
+// When TPM ownership is taken, this protobuf is populated with the passwords
+// used to take ownership, and with a list of clients who have a dependency on
+// the owner password (like Attestation, InstallAttributes and BootLockbox).
+// when all the clients have the owner password injected, this protobuf is
+// cleared of all passwords.
+message LocalData {
+  optional bytes owner_password = 2;
+  repeated string owner_dependency = 3;
+  optional bytes endorsement_password = 4;
+  optional bytes lockout_password = 5;
+  repeated NvramPolicyRecord nvram_policy = 6;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// A series of request and reply messages for the NVRAM interface methods.
+////////////////////////////////////////////////////////////////////////////////
+message DefineSpaceRequest {
+  optional uint32 index = 1;
+  optional uint32 size = 2;
+  repeated NvramSpaceAttribute attributes = 3;
+  optional bytes authorization_value = 4;
+  optional NvramSpacePolicy policy = 5;
+}
+
+message DefineSpaceReply {
+  optional NvramResult result = 1;
+}
+
+message DestroySpaceRequest {
+  optional uint32 index = 1;
+}
+
+message DestroySpaceReply {
+  optional NvramResult result = 1;
+}
+
+message WriteSpaceRequest {
+  optional uint32 index = 1;
+  optional bytes data = 2;
+  optional bytes authorization_value = 3;
+  optional bool use_owner_authorization = 4;
+}
+
+message WriteSpaceReply {
+  optional NvramResult result = 1;
+}
+
+message ReadSpaceRequest {
+  optional uint32 index = 1;
+  optional bytes authorization_value = 2;
+  optional bool use_owner_authorization = 3;
+}
+
+message ReadSpaceReply {
+  optional NvramResult result = 1;
+  optional bytes data = 2;
+}
+
+message LockSpaceRequest {
+  optional uint32 index = 1;
+  optional bool lock_read = 2;
+  optional bool lock_write = 3;
+  optional bytes authorization_value = 4;
+  optional bool use_owner_authorization = 5;
+}
+
+message LockSpaceReply {
+  optional NvramResult result = 1;
+}
+
+message ListSpacesRequest {
+}
+
+message ListSpacesReply {
+  optional NvramResult result = 1;
+  repeated uint32 index_list = 2;
+}
+
+message GetSpaceInfoRequest {
+  optional uint32 index = 1;
+}
+
+message GetSpaceInfoReply {
+  optional NvramResult result = 1;
+  optional uint32 size = 2;
+  optional bool is_read_locked = 3;
+  optional bool is_write_locked = 4;
+  repeated NvramSpaceAttribute attributes = 5;
+  optional NvramSpacePolicy policy = 6;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// A series of request and reply messages for the ownership interface methods.
+////////////////////////////////////////////////////////////////////////////////
+message GetTpmStatusRequest {
+}
+
+message GetTpmStatusReply {
+  optional TpmManagerStatus status = 1;
+  // Whether a TPM is enabled on the system.
+  optional bool enabled = 2;
+  // Whether the TPM has been owned.
+  optional bool owned = 3;
+  // Local TPM management data (including the owner password if available).
+  optional LocalData local_data = 4;
+  // The current dictionary attack counter value.
+  optional uint32 dictionary_attack_counter = 5;
+  // The current dictionary attack counter threshold.
+  optional uint32 dictionary_attack_threshold = 6;
+  // Whether the TPM is in some form of dictionary attack lockout.
+  optional bool dictionary_attack_lockout_in_effect = 7;
+  // The number of seconds remaining in the lockout.
+  optional uint32 dictionary_attack_lockout_seconds_remaining = 8;
+}
+
+message TakeOwnershipRequest {
+}
+
+message TakeOwnershipReply {
+  optional TpmManagerStatus status = 1;
+}
+
+message RemoveOwnerDependencyRequest {
+  optional bytes owner_dependency = 1;
+}
+
+message RemoveOwnerDependencyReply {
+  optional TpmManagerStatus status = 1;
+}
diff --git a/tpm_manager/common/tpm_manager_constants.h b/tpm_manager/common/tpm_manager_constants.h
index 725300e..7c925c7 100644
--- a/tpm_manager/common/tpm_manager_constants.h
+++ b/tpm_manager/common/tpm_manager_constants.h
@@ -19,22 +19,23 @@
 
 namespace tpm_manager {
 
-// These constants are used to set up and access the D-Bus interface for
-// TpmManager.
+// D-Bus service constants.
 constexpr char kTpmManagerServiceName[] = "org.chromium.TpmManager";
 constexpr char kTpmManagerServicePath[] = "/org/chromium/TpmManager";
 
-// These constants define the ownership dependencies. On a chromeos system,
-// there are dependencies on Attestation and InstallAttributes, but at the
-// moment TpmManager has no clients, so we only add a dependency on Test.
-// TODO(usanghi): Figure out a way to handle ownership dependencies
-// dynamically (b/25341605).
-constexpr const char* kTestDependency = "Test";
+// Binder service constants.
+constexpr char kTpmNvramBinderName [] = "android.tpm_manager.ITpmNvram";
+constexpr char kTpmOwnershipBinderName [] = "android.tpm_manager.ITpmOwnership";
 
-// Array to easily access the list of ownership dependencies.
-// Note: When dependencies are added/removed from the above list, they should
-// be modified here as well.
-constexpr const char* kInitialTpmOwnerDependencies[] = {kTestDependency};
+// Default dependencies on TPM owner privilege. The TPM owner password will not
+// be destroyed until all of these dependencies have been explicitly removed
+// using the RemoveOwnerDependency method.
+constexpr const char* kTpmOwnerDependency_Nvram = "TpmOwnerDependency_Nvram";
+constexpr const char* kTpmOwnerDependency_Attestation =
+    "TpmOwnerDependency_Attestation";
+
+constexpr const char* kInitialTpmOwnerDependencies[] = {
+    kTpmOwnerDependency_Nvram, kTpmOwnerDependency_Attestation};
 
 }  // namespace tpm_manager
 
diff --git a/tpm_manager/common/tpm_manager_status.proto b/tpm_manager/common/tpm_manager_status.proto
deleted file mode 100644
index 4008d38..0000000
--- a/tpm_manager/common/tpm_manager_status.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-option optimize_for = LITE_RUNTIME;
-package tpm_manager;
-
-enum TpmManagerStatus {
-  STATUS_SUCCESS = 0;
-  STATUS_UNEXPECTED_DEVICE_ERROR = 1;
-  STATUS_NOT_AVAILABLE = 2;
-}
diff --git a/tpm_manager/common/tpm_nvram_dbus_interface.h b/tpm_manager/common/tpm_nvram_dbus_interface.h
index cd70595..0692ed1 100644
--- a/tpm_manager/common/tpm_nvram_dbus_interface.h
+++ b/tpm_manager/common/tpm_nvram_dbus_interface.h
@@ -22,13 +22,13 @@
 constexpr char kTpmNvramInterface[] = "org.chromium.TpmNvram";
 
 // Methods exported by tpm_manager nvram D-Bus interface.
-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";
+constexpr char kDefineSpace[] = "DefineSpace";
+constexpr char kDestroySpace[] = "DestroySpace";
+constexpr char kWriteSpace[] = "WriteSpace";
+constexpr char kReadSpace[] = "ReadSpace";
+constexpr char kLockSpace[] = "LockSpace";
+constexpr char kListSpaces[] = "ListSpaces";
+constexpr char kGetSpaceInfo[] = "GetSpaceInfo";
 
 }  // namespace tpm_manager
 
diff --git a/tpm_manager/common/tpm_nvram_interface.h b/tpm_manager/common/tpm_nvram_interface.h
index a78ff87..ca25b9a 100644
--- a/tpm_manager/common/tpm_nvram_interface.h
+++ b/tpm_manager/common/tpm_nvram_interface.h
@@ -20,51 +20,51 @@
 #include <base/callback.h>
 
 #include "tpm_manager/common/export.h"
-#include "tpm_manager/common/tpm_nvram_interface.pb.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
 
 namespace tpm_manager {
 
-// This is the interface to access the nvram subsystem of the Tpm. It is
-// extended by TpmManagerInterface.
+// The command interface for working with TPM NVRAM. Inherited by both IPC proxy
+// and service classes. All methods are asynchronous because all TPM operations
+// may take a long time to finish.
 class TPM_MANAGER_EXPORT TpmNvramInterface {
  public:
   virtual ~TpmNvramInterface() = default;
 
-  // 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 DefineSpaceRequest and responds with a DefineSpaceReply.
+  using DefineSpaceCallback = base::Callback<void(const DefineSpaceReply&)>;
+  virtual void DefineSpace(const DefineSpaceRequest& request,
+                           const DefineSpaceCallback& 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 DestroySpaceRequest and responds with a DestroySpaceReply.
+  using DestroySpaceCallback = base::Callback<void(const DestroySpaceReply&)>;
+  virtual void DestroySpace(const DestroySpaceRequest& request,
+                            const DestroySpaceCallback& 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 WriteSpaceRequest and responds with a WriteSpaceReply.
+  using WriteSpaceCallback = base::Callback<void(const WriteSpaceReply&)>;
+  virtual void WriteSpace(const WriteSpaceRequest& request,
+                          const WriteSpaceCallback& 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 ReadSpaceRequest and responds with a ReadSpaceReply.
+  using ReadSpaceCallback = base::Callback<void(const ReadSpaceReply&)>;
+  virtual void ReadSpace(const ReadSpaceRequest& request,
+                         const ReadSpaceCallback& 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 LockSpaceRequest and responds with a LockSpaceReply.
+  using LockSpaceCallback = base::Callback<void(const LockSpaceReply&)>;
+  virtual void LockSpace(const LockSpaceRequest& request,
+                         const LockSpaceCallback& 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 ListSpacesRequest and responds with a ListSpacesReply.
+  using ListSpacesCallback = base::Callback<void(const ListSpacesReply&)>;
+  virtual void ListSpaces(const ListSpacesRequest& request,
+                          const ListSpacesCallback& 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;
+  // Processes a GetSpaceInfoRequest and responds with a GetSpaceInfoReply.
+  using GetSpaceInfoCallback = base::Callback<void(const GetSpaceInfoReply&)>;
+  virtual void GetSpaceInfo(const GetSpaceInfoRequest& request,
+                            const GetSpaceInfoCallback& callback) = 0;
 };
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/common/tpm_nvram_interface.proto b/tpm_manager/common/tpm_nvram_interface.proto
deleted file mode 100644
index cecf8dc..0000000
--- a/tpm_manager/common/tpm_nvram_interface.proto
+++ /dev/null
@@ -1,99 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-option optimize_for = LITE_RUNTIME;
-package tpm_manager;
-
-import "tpm_manager_status.proto";
-
-// The messages in this file correspond to the D-Bus interface for accessing
-// Tpm backed Nvram.
-
-// 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/tpm_manager/common/tpm_ownership_interface.h b/tpm_manager/common/tpm_ownership_interface.h
index 6219a1e..bb54c1d 100644
--- a/tpm_manager/common/tpm_ownership_interface.h
+++ b/tpm_manager/common/tpm_ownership_interface.h
@@ -20,12 +20,13 @@
 #include <base/callback.h>
 
 #include "tpm_manager/common/export.h"
-#include "tpm_manager/common/tpm_ownership_interface.pb.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
 
 namespace tpm_manager {
 
-// This is the interface to access the ownership subsystem of the Tpm. It is
-// extended by TpmManagerInterface.
+// The command interface for TPM administration. Inherited by both IPC proxy
+// and service classes. All methods are asynchronous because all TPM operations
+// may take a long time to finish.
 class TPM_MANAGER_EXPORT TpmOwnershipInterface {
  public:
   virtual ~TpmOwnershipInterface() = default;
diff --git a/tpm_manager/common/tpm_ownership_interface.proto b/tpm_manager/common/tpm_ownership_interface.proto
deleted file mode 100644
index e01a2bc..0000000
--- a/tpm_manager/common/tpm_ownership_interface.proto
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-option optimize_for = LITE_RUNTIME;
-package tpm_manager;
-
-import "local_data.proto";
-import "tpm_manager_status.proto";
-
-// The messages in this file correspond to the D-Bus interface to handle
-// ownership of the Tpm.
-
-// Input for the GetTpmStatus method.
-message GetTpmStatusRequest {
-}
-
-// Output from the GetTpmStatus method.
-message GetTpmStatusReply {
-  optional TpmManagerStatus status = 1;
-  // Whether a TPM is enabled on the system.
-  optional bool enabled = 2;
-  // Whether the TPM has been owned.
-  optional bool owned = 3;
-  // Local TPM management data (including the owner password if available).
-  optional LocalData local_data = 4;
-  // The current dictionary attack counter value.
-  optional int32 dictionary_attack_counter = 5;
-  // The current dictionary attack counter threshold.
-  optional int32 dictionary_attack_threshold = 6;
-  // Whether the TPM is in some form of dictionary attack lockout.
-  optional bool dictionary_attack_lockout_in_effect = 7;
-  // The number of seconds remaining in the lockout.
-  optional int32 dictionary_attack_lockout_seconds_remaining = 8;
-}
-
-// Input for the TakeOwnership method.
-message TakeOwnershipRequest {
-}
-
-// Output from the TakeOwnership method.
-message TakeOwnershipReply {
-  optional TpmManagerStatus status = 1;
-}
-
-// Input for the RemoveOwnerDependency method.
-message RemoveOwnerDependencyRequest {
-  optional bytes owner_dependency = 1;
-}
-
-// Output for the RemoveOwnerDependency method.
-message RemoveOwnerDependencyReply {
-  optional TpmManagerStatus status = 1;
-}
diff --git a/tpm_manager/server/binder_service.cc b/tpm_manager/server/binder_service.cc
new file mode 100644
index 0000000..38d5daf
--- /dev/null
+++ b/tpm_manager/server/binder_service.cc
@@ -0,0 +1,238 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "tpm_manager/server/binder_service.h"
+
+#include <sysexits.h>
+
+#include <base/bind.h>
+#include <binderwrapper/binder_wrapper.h>
+
+#include "tpm_manager/common/tpm_manager.pb.h"
+#include "tpm_manager/common/tpm_manager_constants.h"
+
+namespace {
+
+// Sends a |response_proto| to |client| for an arbitrary protobuf type.
+template <typename ResponseProtobufType>
+void ResponseHandler(
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client,
+    const ResponseProtobufType& response_proto) {
+  VLOG(2) << __func__;
+  std::vector<uint8_t> binder_response;
+  binder_response.resize(response_proto.ByteSize());
+  CHECK(response_proto.SerializeToArray(binder_response.data(),
+                                        binder_response.size()))
+      << "BinderService: Failed to serialize protobuf.";
+  android::binder::Status status = client->OnCommandResponse(binder_response);
+  if (!status.isOk()) {
+    LOG(ERROR) << "BinderService: Failed to send response to client: "
+               << status.toString8();
+  }
+}
+
+// Creates an error protobuf for NVRAM commands.
+template <typename ResponseProtobufType>
+void CreateNvramErrorResponse(ResponseProtobufType* proto) {
+  proto->set_result(tpm_manager::NVRAM_RESULT_IPC_ERROR);
+}
+
+// Creates an error protobuf for ownership commands.
+template <typename ResponseProtobufType>
+void CreateOwnershipErrorResponse(ResponseProtobufType* proto) {
+  proto->set_status(tpm_manager::STATUS_DEVICE_ERROR);
+}
+
+// Calls |method| with a protobuf decoded from |request| using ResponseHandler()
+// and |client| to handle the response. On error, uses |get_error_response| to
+// construct a response and sends that to |client|.
+template <typename RequestProtobufType, typename ResponseProtobufType>
+void RequestHandler(
+    const std::vector<uint8_t>& request,
+    const base::Callback<
+        void(const RequestProtobufType&,
+             const base::Callback<void(const ResponseProtobufType&)>&)>& method,
+    const base::Callback<void(ResponseProtobufType*)>& get_error_response,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  VLOG(2) << __func__;
+  base::Callback<void(const ResponseProtobufType&)> callback =
+      base::Bind(ResponseHandler<ResponseProtobufType>, client);
+  RequestProtobufType request_proto;
+  if (!request_proto.ParseFromArray(request.data(), request.size())) {
+    LOG(ERROR) << "BinderService: Bad request data.";
+    // Send an error response.
+    ResponseProtobufType response_proto;
+    get_error_response.Run(&response_proto);
+    callback.Run(response_proto);
+    return;
+  }
+  method.Run(request_proto, callback);
+}
+
+}  // namespace
+
+namespace tpm_manager {
+
+BinderService::BinderService(TpmNvramInterface* nvram_service,
+                             TpmOwnershipInterface* ownership_service)
+    : nvram_service_(nvram_service), ownership_service_(ownership_service) {}
+
+void BinderService::InitForTesting() {
+  nvram_binder_ = new NvramServiceInternal(nvram_service_);
+  ownership_binder_ = new OwnershipServiceInternal(ownership_service_);
+}
+
+int BinderService::OnInit() {
+  if (!watcher_.Init()) {
+    LOG(ERROR) << "BinderService: BinderWatcher::Init failed.";
+    return EX_UNAVAILABLE;
+  }
+  nvram_binder_ = new NvramServiceInternal(nvram_service_);
+  ownership_binder_ = new OwnershipServiceInternal(ownership_service_);
+  if (!android::BinderWrapper::GetOrCreateInstance()->RegisterService(
+          kTpmNvramBinderName, android::IInterface::asBinder(nvram_binder_))) {
+    LOG(ERROR) << "BinderService: RegisterService failed (nvram).";
+    return EX_UNAVAILABLE;
+  }
+  if (!android::BinderWrapper::GetOrCreateInstance()->RegisterService(
+          kTpmOwnershipBinderName,
+          android::IInterface::asBinder(ownership_binder_))) {
+    LOG(ERROR) << "BinderService: RegisterService failed (ownership).";
+    return EX_UNAVAILABLE;
+  }
+  LOG(INFO) << "TpmManager: Binder services registered.";
+  return brillo::Daemon::OnInit();
+}
+
+android::tpm_manager::ITpmNvram* BinderService::GetITpmNvram() {
+  return nvram_binder_.get();
+}
+
+android::tpm_manager::ITpmOwnership* BinderService::GetITpmOwnership() {
+  return ownership_binder_.get();
+}
+
+BinderService::NvramServiceInternal::NvramServiceInternal(
+    TpmNvramInterface* nvram_service)
+    : nvram_service_(nvram_service) {}
+
+android::binder::Status BinderService::NvramServiceInternal::DefineSpace(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<DefineSpaceRequest, DefineSpaceReply>(
+      command_proto, base::Bind(&TpmNvramInterface::DefineSpace,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<DefineSpaceReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::DestroySpace(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<DestroySpaceRequest, DestroySpaceReply>(
+      command_proto, base::Bind(&TpmNvramInterface::DestroySpace,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<DestroySpaceReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::WriteSpace(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<WriteSpaceRequest, WriteSpaceReply>(
+      command_proto, base::Bind(&TpmNvramInterface::WriteSpace,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<WriteSpaceReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::ReadSpace(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<ReadSpaceRequest, ReadSpaceReply>(
+      command_proto, base::Bind(&TpmNvramInterface::ReadSpace,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<ReadSpaceReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::LockSpace(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<LockSpaceRequest, LockSpaceReply>(
+      command_proto, base::Bind(&TpmNvramInterface::LockSpace,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<LockSpaceReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::ListSpaces(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<ListSpacesRequest, ListSpacesReply>(
+      command_proto, base::Bind(&TpmNvramInterface::ListSpaces,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<ListSpacesReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::NvramServiceInternal::GetSpaceInfo(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<GetSpaceInfoRequest, GetSpaceInfoReply>(
+      command_proto, base::Bind(&TpmNvramInterface::GetSpaceInfo,
+                                base::Unretained(nvram_service_)),
+      base::Bind(CreateNvramErrorResponse<GetSpaceInfoReply>), client);
+  return android::binder::Status::ok();
+}
+
+BinderService::OwnershipServiceInternal::OwnershipServiceInternal(
+    TpmOwnershipInterface* ownership_service)
+    : ownership_service_(ownership_service) {}
+
+android::binder::Status BinderService::OwnershipServiceInternal::GetTpmStatus(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<GetTpmStatusRequest, GetTpmStatusReply>(
+      command_proto, base::Bind(&TpmOwnershipInterface::GetTpmStatus,
+                                base::Unretained(ownership_service_)),
+      base::Bind(CreateOwnershipErrorResponse<GetTpmStatusReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status BinderService::OwnershipServiceInternal::TakeOwnership(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<TakeOwnershipRequest, TakeOwnershipReply>(
+      command_proto, base::Bind(&TpmOwnershipInterface::TakeOwnership,
+                                base::Unretained(ownership_service_)),
+      base::Bind(CreateOwnershipErrorResponse<TakeOwnershipReply>), client);
+  return android::binder::Status::ok();
+}
+
+android::binder::Status
+BinderService::OwnershipServiceInternal::RemoveOwnerDependency(
+    const std::vector<uint8_t>& command_proto,
+    const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
+  RequestHandler<RemoveOwnerDependencyRequest, RemoveOwnerDependencyReply>(
+      command_proto, base::Bind(&TpmOwnershipInterface::RemoveOwnerDependency,
+                                base::Unretained(ownership_service_)),
+      base::Bind(CreateOwnershipErrorResponse<RemoveOwnerDependencyReply>),
+      client);
+  return android::binder::Status::ok();
+}
+
+}  // namespace tpm_manager
diff --git a/tpm_manager/server/binder_service.h b/tpm_manager/server/binder_service.h
new file mode 100644
index 0000000..c4de0c6
--- /dev/null
+++ b/tpm_manager/server/binder_service.h
@@ -0,0 +1,130 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TPM_MANAGER_SERVER_BINDER_SERVICE_H_
+#define TPM_MANAGER_SERVER_BINDER_SERVICE_H_
+
+#include <brillo/binder_watcher.h>
+#include <brillo/daemons/daemon.h>
+
+#include "android/tpm_manager/BnTpmNvram.h"
+#include "android/tpm_manager/BnTpmOwnership.h"
+#include "tpm_manager/common/tpm_nvram_interface.h"
+#include "tpm_manager/common/tpm_ownership_interface.h"
+
+namespace tpm_manager {
+
+// BinderService registers for and handles all incoming binder calls for the
+// tpm_managerd system daemon.
+//
+// Example Usage:
+//
+// BinderService service(&nvram_service, &ownership_service);
+// service.Run();
+class BinderService : public brillo::Daemon {
+ public:
+  BinderService(TpmNvramInterface* nvram_service,
+                TpmOwnershipInterface* ownership_service);
+  ~BinderService() override = default;
+
+  // Does basic setup but does not register with the binder subsystem.
+  void InitForTesting();
+
+  // Getters for binder interfaces. Callers do not take ownership. These should
+  // only be used for testing.
+  android::tpm_manager::ITpmNvram* GetITpmNvram();
+  android::tpm_manager::ITpmOwnership* GetITpmOwnership();
+
+ protected:
+  int OnInit() override;
+
+ private:
+  friend class NvramServiceInternal;
+  class NvramServiceInternal : public android::tpm_manager::BnTpmNvram {
+   public:
+    NvramServiceInternal(TpmNvramInterface* service);
+    ~NvramServiceInternal() override = default;
+
+    // ITpmNvram interface.
+    android::binder::Status DefineSpace(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status DestroySpace(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status WriteSpace(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status ReadSpace(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status ListSpaces(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status GetSpaceInfo(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status LockSpace(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+
+   private:
+    TpmNvramInterface* nvram_service_;
+  };
+
+  friend class OwnershipServiceInternal;
+  class OwnershipServiceInternal : public android::tpm_manager::BnTpmOwnership {
+   public:
+    OwnershipServiceInternal(TpmOwnershipInterface* service);
+    ~OwnershipServiceInternal() override = default;
+
+    // ITpmOwnership interface.
+    android::binder::Status GetTpmStatus(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status TakeOwnership(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+    android::binder::Status RemoveOwnerDependency(
+        const std::vector<uint8_t>& command_proto,
+        const android::sp<android::tpm_manager::ITpmManagerClient>& client)
+        override;
+
+   private:
+    TpmOwnershipInterface* ownership_service_;
+  };
+
+  brillo::BinderWatcher watcher_;
+  android::sp<NvramServiceInternal> nvram_binder_;
+  android::sp<OwnershipServiceInternal> ownership_binder_;
+  TpmNvramInterface* nvram_service_;
+  TpmOwnershipInterface* ownership_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(BinderService);
+};
+
+}  // namespace tpm_manager
+
+#endif  // TPM_MANAGER_SERVER_BINDER_SERVICE_H_
diff --git a/tpm_manager/server/binder_service_test.cc b/tpm_manager/server/binder_service_test.cc
new file mode 100644
index 0000000..1415019
--- /dev/null
+++ b/tpm_manager/server/binder_service_test.cc
@@ -0,0 +1,310 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <string>
+
+#include <brillo/bind_lambda.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "tpm_manager/client/tpm_nvram_binder_proxy.h"
+#include "tpm_manager/client/tpm_ownership_binder_proxy.h"
+#include "tpm_manager/common/mock_tpm_nvram_interface.h"
+#include "tpm_manager/common/mock_tpm_ownership_interface.h"
+#include "tpm_manager/common/tpm_manager_constants.h"
+#include "tpm_manager/server/binder_service.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace tpm_manager {
+
+// A test fixture to exercise both proxy and service layers. Tpm*BinderProxy
+// classes get coverage here and do not need additional unit tests.
+class BinderServiceTest : public testing::Test {
+ public:
+  ~BinderServiceTest() override = default;
+  void SetUp() override {
+    binder_service_.reset(
+        new BinderService(&mock_nvram_service_, &mock_ownership_service_));
+    binder_service_->InitForTesting();
+    nvram_proxy_.reset(
+        new TpmNvramBinderProxy(binder_service_->GetITpmNvram()));
+    ownership_proxy_.reset(
+        new TpmOwnershipBinderProxy(binder_service_->GetITpmOwnership()));
+  }
+
+  template <typename ResponseProtobufType>
+  base::Callback<void(const ResponseProtobufType&)> GetCallback(
+      ResponseProtobufType* proto) {
+    return base::Bind(
+        [proto](const ResponseProtobufType& response) { *proto = response; });
+  }
+
+ protected:
+  StrictMock<MockTpmNvramInterface> mock_nvram_service_;
+  StrictMock<MockTpmOwnershipInterface> mock_ownership_service_;
+  std::unique_ptr<BinderService> binder_service_;
+  std::unique_ptr<TpmNvramBinderProxy> nvram_proxy_;
+  std::unique_ptr<TpmOwnershipBinderProxy> ownership_proxy_;
+};
+
+TEST_F(BinderServiceTest, CopyableCallback) {
+  EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
+      .WillOnce(WithArgs<1>(Invoke(
+          [](const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
+            // Copy the callback, then call the original.
+            GetTpmStatusReply reply;
+            base::Closure copy = base::Bind(callback, reply);
+            callback.Run(reply);
+          })));
+  GetTpmStatusRequest request;
+  GetTpmStatusReply reply;
+  ownership_proxy_->GetTpmStatus(request,
+                                 GetCallback<GetTpmStatusReply>(&reply));
+}
+
+TEST_F(BinderServiceTest, GetTpmStatus) {
+  GetTpmStatusRequest request;
+  EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
+      .WillOnce(Invoke(
+          [](const GetTpmStatusRequest& request,
+             const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
+            GetTpmStatusReply reply;
+            reply.set_status(STATUS_SUCCESS);
+            reply.set_enabled(true);
+            reply.set_owned(true);
+            reply.set_dictionary_attack_counter(3);
+            reply.set_dictionary_attack_threshold(4);
+            reply.set_dictionary_attack_lockout_in_effect(true);
+            reply.set_dictionary_attack_lockout_seconds_remaining(5);
+            callback.Run(reply);
+          }));
+  GetTpmStatusReply reply;
+  ownership_proxy_->GetTpmStatus(request,
+                                 GetCallback<GetTpmStatusReply>(&reply));
+  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  EXPECT_TRUE(reply.enabled());
+  EXPECT_TRUE(reply.owned());
+  EXPECT_EQ(3, reply.dictionary_attack_counter());
+  EXPECT_EQ(4, reply.dictionary_attack_threshold());
+  EXPECT_TRUE(reply.dictionary_attack_lockout_in_effect());
+  EXPECT_EQ(5, reply.dictionary_attack_lockout_seconds_remaining());
+}
+
+TEST_F(BinderServiceTest, TakeOwnership) {
+  EXPECT_CALL(mock_ownership_service_, TakeOwnership(_, _))
+      .WillOnce(Invoke(
+          [](const TakeOwnershipRequest& request,
+             const TpmOwnershipInterface::TakeOwnershipCallback& callback) {
+            TakeOwnershipReply reply;
+            reply.set_status(STATUS_SUCCESS);
+            callback.Run(reply);
+          }));
+  TakeOwnershipRequest request;
+  TakeOwnershipReply reply;
+  ownership_proxy_->TakeOwnership(request,
+                                  GetCallback<TakeOwnershipReply>(&reply));
+  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(BinderServiceTest, RemoveOwnerDependency) {
+  std::string owner_dependency("owner_dependency");
+  RemoveOwnerDependencyRequest request;
+  request.set_owner_dependency(owner_dependency);
+  EXPECT_CALL(mock_ownership_service_, RemoveOwnerDependency(_, _))
+      .WillOnce(Invoke([&owner_dependency](
+          const RemoveOwnerDependencyRequest& request,
+          const TpmOwnershipInterface::RemoveOwnerDependencyCallback&
+              callback) {
+        EXPECT_TRUE(request.has_owner_dependency());
+        EXPECT_EQ(owner_dependency, request.owner_dependency());
+        RemoveOwnerDependencyReply reply;
+        reply.set_status(STATUS_SUCCESS);
+        callback.Run(reply);
+      }));
+  RemoveOwnerDependencyReply reply;
+  ownership_proxy_->RemoveOwnerDependency(
+      request, GetCallback<RemoveOwnerDependencyReply>(&reply));
+  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(BinderServiceTest, DefineSpace) {
+  uint32_t nvram_index = 5;
+  size_t nvram_length = 32;
+  DefineSpaceRequest request;
+  request.set_index(nvram_index);
+  request.set_size(nvram_length);
+  EXPECT_CALL(mock_nvram_service_, DefineSpace(_, _))
+      .WillOnce(Invoke([nvram_index, nvram_length](
+          const DefineSpaceRequest& request,
+          const TpmNvramInterface::DefineSpaceCallback& callback) {
+        EXPECT_TRUE(request.has_index());
+        EXPECT_EQ(nvram_index, request.index());
+        EXPECT_TRUE(request.has_size());
+        EXPECT_EQ(nvram_length, request.size());
+        DefineSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        callback.Run(reply);
+      }));
+  DefineSpaceReply reply;
+  nvram_proxy_->DefineSpace(request, GetCallback<DefineSpaceReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+}
+
+TEST_F(BinderServiceTest, DestroySpace) {
+  uint32_t nvram_index = 5;
+  DestroySpaceRequest request;
+  request.set_index(nvram_index);
+  EXPECT_CALL(mock_nvram_service_, DestroySpace(_, _))
+      .WillOnce(Invoke([nvram_index](
+          const DestroySpaceRequest& request,
+          const TpmNvramInterface::DestroySpaceCallback& callback) {
+        EXPECT_TRUE(request.has_index());
+        EXPECT_EQ(nvram_index, request.index());
+        DestroySpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        callback.Run(reply);
+      }));
+  DestroySpaceReply reply;
+  nvram_proxy_->DestroySpace(request, GetCallback<DestroySpaceReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+}
+
+TEST_F(BinderServiceTest, WriteSpace) {
+  uint32_t nvram_index = 5;
+  std::string nvram_data("nvram_data");
+  WriteSpaceRequest request;
+  request.set_index(nvram_index);
+  request.set_data(nvram_data);
+  EXPECT_CALL(mock_nvram_service_, WriteSpace(_, _))
+      .WillOnce(Invoke([nvram_index, nvram_data](
+          const WriteSpaceRequest& request,
+          const TpmNvramInterface::WriteSpaceCallback& callback) {
+        EXPECT_TRUE(request.has_index());
+        EXPECT_EQ(nvram_index, request.index());
+        EXPECT_TRUE(request.has_data());
+        EXPECT_EQ(nvram_data, request.data());
+        WriteSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        callback.Run(reply);
+      }));
+  WriteSpaceReply reply;
+  nvram_proxy_->WriteSpace(request, GetCallback<WriteSpaceReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+}
+
+TEST_F(BinderServiceTest, ReadSpace) {
+  uint32_t nvram_index = 5;
+  std::string nvram_data("nvram_data");
+  ReadSpaceRequest request;
+  request.set_index(nvram_index);
+  EXPECT_CALL(mock_nvram_service_, ReadSpace(_, _))
+      .WillOnce(Invoke([nvram_index, nvram_data](
+          const ReadSpaceRequest& request,
+          const TpmNvramInterface::ReadSpaceCallback& callback) {
+        EXPECT_TRUE(request.has_index());
+        EXPECT_EQ(nvram_index, request.index());
+        ReadSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        reply.set_data(nvram_data);
+        callback.Run(reply);
+      }));
+  ReadSpaceReply reply;
+  nvram_proxy_->ReadSpace(request, GetCallback<ReadSpaceReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+  EXPECT_TRUE(reply.has_data());
+  EXPECT_EQ(nvram_data, reply.data());
+}
+
+TEST_F(BinderServiceTest, LockSpace) {
+  uint32_t nvram_index = 5;
+  LockSpaceRequest request;
+  request.set_index(nvram_index);
+  request.set_lock_read(true);
+  request.set_lock_write(true);
+  EXPECT_CALL(mock_nvram_service_, LockSpace(_, _))
+      .WillOnce(Invoke(
+          [nvram_index](const LockSpaceRequest& request,
+                        const TpmNvramInterface::LockSpaceCallback& callback) {
+            EXPECT_TRUE(request.has_index());
+            EXPECT_EQ(nvram_index, request.index());
+            EXPECT_TRUE(request.lock_read());
+            EXPECT_TRUE(request.lock_write());
+            LockSpaceReply reply;
+            reply.set_result(NVRAM_RESULT_SUCCESS);
+            callback.Run(reply);
+          }));
+  LockSpaceReply reply;
+  nvram_proxy_->LockSpace(request, GetCallback<LockSpaceReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+}
+
+TEST_F(BinderServiceTest, ListSpaces) {
+  constexpr uint32_t nvram_index_list[] = {3, 4, 5};
+  ListSpacesRequest request;
+  EXPECT_CALL(mock_nvram_service_, ListSpaces(_, _))
+      .WillOnce(Invoke([nvram_index_list](
+          const ListSpacesRequest& request,
+          const TpmNvramInterface::ListSpacesCallback& callback) {
+        ListSpacesReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        for (auto index : nvram_index_list) {
+          reply.add_index_list(index);
+        }
+        callback.Run(reply);
+      }));
+  ListSpacesReply reply;
+  nvram_proxy_->ListSpaces(request, GetCallback<ListSpacesReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+  EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size());
+  for (size_t i = 0; i < 3; i++) {
+    EXPECT_EQ(nvram_index_list[i], reply.index_list(i));
+  }
+}
+
+TEST_F(BinderServiceTest, GetSpaceInfo) {
+  uint32_t nvram_index = 5;
+  size_t nvram_size = 32;
+  GetSpaceInfoRequest request;
+  request.set_index(nvram_index);
+  EXPECT_CALL(mock_nvram_service_, GetSpaceInfo(_, _))
+      .WillOnce(Invoke([nvram_index, nvram_size](
+          const GetSpaceInfoRequest& request,
+          const TpmNvramInterface::GetSpaceInfoCallback& callback) {
+        EXPECT_TRUE(request.has_index());
+        EXPECT_EQ(nvram_index, request.index());
+        GetSpaceInfoReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        reply.set_size(nvram_size);
+        reply.set_is_read_locked(true);
+        reply.set_is_write_locked(true);
+        callback.Run(reply);
+      }));
+  GetSpaceInfoReply reply;
+  nvram_proxy_->GetSpaceInfo(request, GetCallback<GetSpaceInfoReply>(&reply));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+  EXPECT_TRUE(reply.has_size());
+  EXPECT_EQ(nvram_size, reply.size());
+  EXPECT_TRUE(reply.is_read_locked());
+  EXPECT_TRUE(reply.is_write_locked());
+}
+
+}  // namespace tpm_manager
diff --git a/tpm_manager/server/dbus_service.cc b/tpm_manager/server/dbus_service.cc
index 5c914fe..61630cb 100644
--- a/tpm_manager/server/dbus_service.cc
+++ b/tpm_manager/server/dbus_service.cc
@@ -20,6 +20,8 @@
 #include <string>
 
 #include <brillo/bind_lambda.h>
+#include <brillo/daemons/dbus_daemon.h>
+#include <brillo/dbus/async_event_sequencer.h>
 #include <dbus/bus.h>
 #include <dbus/object_path.h>
 
@@ -29,16 +31,34 @@
 
 namespace tpm_manager {
 
-DBusService::DBusService(const scoped_refptr<dbus::Bus>& bus,
-                         TpmNvramInterface* nvram_service,
+using brillo::dbus_utils::DBusObject;
+
+DBusService::DBusService(TpmNvramInterface* nvram_service,
                          TpmOwnershipInterface* ownership_service)
-    : dbus_object_(nullptr, bus, dbus::ObjectPath(kTpmManagerServicePath)),
+    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
       nvram_service_(nvram_service),
       ownership_service_(ownership_service) {}
 
-void DBusService::Register(const CompletionAction& callback) {
+DBusService::DBusService(scoped_refptr<dbus::Bus> bus,
+                         TpmNvramInterface* nvram_service,
+                         TpmOwnershipInterface* ownership_service)
+    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
+      dbus_object_(new DBusObject(nullptr,
+                                  bus,
+                                  dbus::ObjectPath(kTpmManagerServicePath))),
+      nvram_service_(nvram_service),
+      ownership_service_(ownership_service) {}
+
+void DBusService::RegisterDBusObjectsAsync(
+    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
+  if (!dbus_object_.get()) {
+    // At this point bus_ should be valid.
+    CHECK(bus_.get());
+    dbus_object_.reset(new DBusObject(
+        nullptr, bus_, dbus::ObjectPath(kTpmManagerServicePath)));
+  }
   brillo::dbus_utils::DBusInterface* ownership_dbus_interface =
-      dbus_object_.AddOrGetInterface(kTpmOwnershipInterface);
+      dbus_object_->AddOrGetInterface(kTpmOwnershipInterface);
 
   ownership_dbus_interface->AddMethodHandler(
       kGetTpmStatus, base::Unretained(this),
@@ -59,48 +79,47 @@
           &TpmOwnershipInterface::RemoveOwnerDependency>);
 
   brillo::dbus_utils::DBusInterface* nvram_dbus_interface =
-      dbus_object_.AddOrGetInterface(kTpmNvramInterface);
+      dbus_object_->AddOrGetInterface(kTpmNvramInterface);
 
   nvram_dbus_interface->AddMethodHandler(
-      kDefineNvram, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<DefineNvramRequest, DefineNvramReply,
-                                          &TpmNvramInterface::DefineNvram>);
+      kDefineSpace, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<DefineSpaceRequest, DefineSpaceReply,
+                                          &TpmNvramInterface::DefineSpace>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kDestroyNvram, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<DestroyNvramRequest,
-                                          DestroyNvramReply,
-                                          &TpmNvramInterface::DestroyNvram>);
+      kDestroySpace, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<DestroySpaceRequest,
+                                          DestroySpaceReply,
+                                          &TpmNvramInterface::DestroySpace>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kWriteNvram, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<WriteNvramRequest, WriteNvramReply,
-                                          &TpmNvramInterface::WriteNvram>);
+      kWriteSpace, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<WriteSpaceRequest, WriteSpaceReply,
+                                          &TpmNvramInterface::WriteSpace>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kReadNvram, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<ReadNvramRequest, ReadNvramReply,
-                                          &TpmNvramInterface::ReadNvram>);
+      kReadSpace, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<ReadSpaceRequest, ReadSpaceReply,
+                                          &TpmNvramInterface::ReadSpace>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kIsNvramDefined, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<IsNvramDefinedRequest,
-                                          IsNvramDefinedReply,
-                                          &TpmNvramInterface::IsNvramDefined>);
+      kLockSpace, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<LockSpaceRequest, LockSpaceReply,
+                                          &TpmNvramInterface::LockSpace>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kIsNvramLocked, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<IsNvramLockedRequest,
-                                          IsNvramLockedReply,
-                                          &TpmNvramInterface::IsNvramLocked>);
+      kListSpaces, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<ListSpacesRequest, ListSpacesReply,
+                                          &TpmNvramInterface::ListSpaces>);
 
   nvram_dbus_interface->AddMethodHandler(
-      kGetNvramSize, base::Unretained(this),
-      &DBusService::HandleNvramDBusMethod<GetNvramSizeRequest,
-                                          GetNvramSizeReply,
-                                          &TpmNvramInterface::GetNvramSize>);
+      kGetSpaceInfo, base::Unretained(this),
+      &DBusService::HandleNvramDBusMethod<GetSpaceInfoRequest,
+                                          GetSpaceInfoReply,
+                                          &TpmNvramInterface::GetSpaceInfo>);
 
-  dbus_object_.RegisterAsync(callback);
+  dbus_object_->RegisterAsync(
+      sequencer->GetHandler("Failed to register D-Bus object.", true));
 }
 
 template <typename RequestProtobufType,
diff --git a/tpm_manager/server/dbus_service.h b/tpm_manager/server/dbus_service.h
index b49cc83..fc45497 100644
--- a/tpm_manager/server/dbus_service.h
+++ b/tpm_manager/server/dbus_service.h
@@ -19,6 +19,7 @@
 
 #include <memory>
 
+#include <brillo/daemons/dbus_daemon.h>
 #include <brillo/dbus/dbus_method_response.h>
 #include <brillo/dbus/dbus_object.h>
 #include <dbus/bus.h>
@@ -29,22 +30,24 @@
 namespace tpm_manager {
 
 using brillo::dbus_utils::DBusMethodResponse;
-using CompletionAction =
-    brillo::dbus_utils::AsyncEventSequencer::CompletionAction;
 
-// Handles D-Bus communtion with the TpmManager daemon.
-class DBusService {
+// Handles D-Bus communication with the TpmManager daemon.
+class DBusService : public brillo::DBusServiceDaemon {
  public:
   // Does not take ownership of |nvram_service| or |ownership_service|. The
-  // services proviced must be initialized, and must remain valid for the
+  // services provided must be initialized, and must remain valid for the
   // lifetime of this instance.
-  DBusService(const scoped_refptr<dbus::Bus>& bus,
+  DBusService(TpmNvramInterface* nvram_service,
+              TpmOwnershipInterface* ownership_service);
+  // Used to inject a mock bus.
+  DBusService(scoped_refptr<dbus::Bus> bus,
               TpmNvramInterface* nvram_service,
               TpmOwnershipInterface* ownership_service);
   virtual ~DBusService() = default;
 
-  // Connects to D-Bus system bus and exports TpmManager methods.
-  void Register(const CompletionAction& callback);
+  // Registers objects exported by this service.
+  void RegisterDBusObjectsAsync(
+      brillo::dbus_utils::AsyncEventSequencer* sequencer) override;
 
  private:
   friend class DBusServiceTest;
@@ -75,7 +78,7 @@
       std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
       const RequestProtobufType& request);
 
-  brillo::dbus_utils::DBusObject dbus_object_;
+  std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_;
   TpmNvramInterface* nvram_service_;
   TpmOwnershipInterface* ownership_service_;
   DISALLOW_COPY_AND_ASSIGN(DBusService);
diff --git a/tpm_manager/server/dbus_service_test.cc b/tpm_manager/server/dbus_service_test.cc
index 8ba84d9..bc2ac98 100644
--- a/tpm_manager/server/dbus_service_test.cc
+++ b/tpm_manager/server/dbus_service_test.cc
@@ -52,8 +52,9 @@
         .WillByDefault(Return(mock_exported_object_.get()));
     dbus_service_.reset(new DBusService(mock_bus_, &mock_nvram_service_,
                                         &mock_ownership_service_));
-    dbus_service_->Register(
-        brillo::dbus_utils::AsyncEventSequencer::GetDefaultCompletionAction());
+    scoped_refptr<brillo::dbus_utils::AsyncEventSequencer> sequencer(
+        new brillo::dbus_utils::AsyncEventSequencer());
+    dbus_service_->RegisterDBusObjectsAsync(sequencer.get());
   }
 
   template <typename RequestProtobufType, typename ReplyProtobufType>
@@ -165,161 +166,165 @@
   EXPECT_EQ(STATUS_SUCCESS, reply.status());
 }
 
-TEST_F(DBusServiceTest, DefineNvram) {
+TEST_F(DBusServiceTest, DefineSpace) {
   uint32_t nvram_index = 5;
   size_t nvram_length = 32;
-  DefineNvramRequest request;
+  DefineSpaceRequest request;
   request.set_index(nvram_index);
-  request.set_length(nvram_length);
-  EXPECT_CALL(mock_nvram_service_, DefineNvram(_, _))
+  request.set_size(nvram_length);
+  EXPECT_CALL(mock_nvram_service_, DefineSpace(_, _))
       .WillOnce(Invoke([nvram_index, nvram_length](
-          const DefineNvramRequest& request,
-          const TpmNvramInterface::DefineNvramCallback& callback) {
+          const DefineSpaceRequest& request,
+          const TpmNvramInterface::DefineSpaceCallback& callback) {
         EXPECT_TRUE(request.has_index());
         EXPECT_EQ(nvram_index, request.index());
-        EXPECT_TRUE(request.has_length());
-        EXPECT_EQ(nvram_length, request.length());
-        DefineNvramReply reply;
-        reply.set_status(STATUS_SUCCESS);
+        EXPECT_TRUE(request.has_size());
+        EXPECT_EQ(nvram_length, request.size());
+        DefineSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
         callback.Run(reply);
       }));
-  DefineNvramReply reply;
-  ExecuteMethod(kDefineNvram, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  DefineSpaceReply reply;
+  ExecuteMethod(kDefineSpace, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
 }
 
-TEST_F(DBusServiceTest, DestroyNvram) {
+TEST_F(DBusServiceTest, DestroySpace) {
   uint32_t nvram_index = 5;
-  DestroyNvramRequest request;
+  DestroySpaceRequest request;
   request.set_index(nvram_index);
-  EXPECT_CALL(mock_nvram_service_, DestroyNvram(_, _))
+  EXPECT_CALL(mock_nvram_service_, DestroySpace(_, _))
       .WillOnce(Invoke([nvram_index](
-          const DestroyNvramRequest& request,
-          const TpmNvramInterface::DestroyNvramCallback& callback) {
+          const DestroySpaceRequest& request,
+          const TpmNvramInterface::DestroySpaceCallback& callback) {
         EXPECT_TRUE(request.has_index());
         EXPECT_EQ(nvram_index, request.index());
-        DestroyNvramReply reply;
-        reply.set_status(STATUS_SUCCESS);
+        DestroySpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
         callback.Run(reply);
       }));
-  DestroyNvramReply reply;
-  ExecuteMethod(kDestroyNvram, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  DestroySpaceReply reply;
+  ExecuteMethod(kDestroySpace, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
 }
 
-TEST_F(DBusServiceTest, WriteNvram) {
+TEST_F(DBusServiceTest, WriteSpace) {
   uint32_t nvram_index = 5;
   std::string nvram_data("nvram_data");
-  WriteNvramRequest request;
+  WriteSpaceRequest request;
   request.set_index(nvram_index);
   request.set_data(nvram_data);
-  EXPECT_CALL(mock_nvram_service_, WriteNvram(_, _))
+  EXPECT_CALL(mock_nvram_service_, WriteSpace(_, _))
       .WillOnce(Invoke([nvram_index, nvram_data](
-          const WriteNvramRequest& request,
-          const TpmNvramInterface::WriteNvramCallback& callback) {
+          const WriteSpaceRequest& request,
+          const TpmNvramInterface::WriteSpaceCallback& callback) {
         EXPECT_TRUE(request.has_index());
         EXPECT_EQ(nvram_index, request.index());
         EXPECT_TRUE(request.has_data());
         EXPECT_EQ(nvram_data, request.data());
-        WriteNvramReply reply;
-        reply.set_status(STATUS_SUCCESS);
+        WriteSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
         callback.Run(reply);
       }));
-  WriteNvramReply reply;
-  ExecuteMethod(kWriteNvram, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  WriteSpaceReply reply;
+  ExecuteMethod(kWriteSpace, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
 }
 
-TEST_F(DBusServiceTest, ReadNvram) {
+TEST_F(DBusServiceTest, ReadSpace) {
   uint32_t nvram_index = 5;
   std::string nvram_data("nvram_data");
-  ReadNvramRequest request;
+  ReadSpaceRequest request;
   request.set_index(nvram_index);
-  EXPECT_CALL(mock_nvram_service_, ReadNvram(_, _))
+  EXPECT_CALL(mock_nvram_service_, ReadSpace(_, _))
       .WillOnce(Invoke([nvram_index, nvram_data](
-          const ReadNvramRequest& request,
-          const TpmNvramInterface::ReadNvramCallback& callback) {
+          const ReadSpaceRequest& request,
+          const TpmNvramInterface::ReadSpaceCallback& callback) {
         EXPECT_TRUE(request.has_index());
         EXPECT_EQ(nvram_index, request.index());
-        ReadNvramReply reply;
-        reply.set_status(STATUS_SUCCESS);
+        ReadSpaceReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
         reply.set_data(nvram_data);
         callback.Run(reply);
       }));
-  ReadNvramReply reply;
-  ExecuteMethod(kReadNvram, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  ReadSpaceReply reply;
+  ExecuteMethod(kReadSpace, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   EXPECT_TRUE(reply.has_data());
   EXPECT_EQ(nvram_data, reply.data());
 }
 
-TEST_F(DBusServiceTest, IsNvramDefined) {
+TEST_F(DBusServiceTest, LockSpace) {
   uint32_t nvram_index = 5;
-  bool nvram_defined = true;
-  IsNvramDefinedRequest request;
+  LockSpaceRequest request;
   request.set_index(nvram_index);
-  EXPECT_CALL(mock_nvram_service_, IsNvramDefined(_, _))
-      .WillOnce(Invoke([nvram_index, nvram_defined](
-          const IsNvramDefinedRequest& request,
-          const TpmNvramInterface::IsNvramDefinedCallback& callback) {
-        EXPECT_TRUE(request.has_index());
-        EXPECT_EQ(nvram_index, request.index());
-        IsNvramDefinedReply reply;
-        reply.set_status(STATUS_SUCCESS);
-        reply.set_is_defined(nvram_defined);
-        callback.Run(reply);
-      }));
-  IsNvramDefinedReply reply;
-  ExecuteMethod(kIsNvramDefined, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
-  EXPECT_TRUE(reply.has_is_defined());
-  EXPECT_EQ(nvram_defined, reply.is_defined());
+  request.set_lock_read(true);
+  request.set_lock_write(true);
+  EXPECT_CALL(mock_nvram_service_, LockSpace(_, _))
+      .WillOnce(Invoke(
+          [nvram_index](const LockSpaceRequest& request,
+                        const TpmNvramInterface::LockSpaceCallback& callback) {
+            EXPECT_TRUE(request.has_index());
+            EXPECT_EQ(nvram_index, request.index());
+            EXPECT_TRUE(request.lock_read());
+            EXPECT_TRUE(request.lock_write());
+            LockSpaceReply reply;
+            reply.set_result(NVRAM_RESULT_SUCCESS);
+            callback.Run(reply);
+          }));
+  LockSpaceReply reply;
+  ExecuteMethod(kLockSpace, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
 }
 
-TEST_F(DBusServiceTest, IsNvramLocked) {
-  uint32_t nvram_index = 5;
-  bool nvram_locked = true;
-  IsNvramLockedRequest request;
-  request.set_index(nvram_index);
-  EXPECT_CALL(mock_nvram_service_, IsNvramLocked(_, _))
-      .WillOnce(Invoke([nvram_index, nvram_locked](
-          const IsNvramLockedRequest& request,
-          const TpmNvramInterface::IsNvramLockedCallback& callback) {
-        EXPECT_TRUE(request.has_index());
-        EXPECT_EQ(nvram_index, request.index());
-        IsNvramLockedReply reply;
-        reply.set_status(STATUS_SUCCESS);
-        reply.set_is_locked(nvram_locked);
+TEST_F(DBusServiceTest, ListSpaces) {
+  constexpr uint32_t nvram_index_list[] = {3, 4, 5};
+  ListSpacesRequest request;
+  EXPECT_CALL(mock_nvram_service_, ListSpaces(_, _))
+      .WillOnce(Invoke([nvram_index_list](
+          const ListSpacesRequest& request,
+          const TpmNvramInterface::ListSpacesCallback& callback) {
+        ListSpacesReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
+        for (auto index : nvram_index_list) {
+          reply.add_index_list(index);
+        }
         callback.Run(reply);
       }));
-  IsNvramLockedReply reply;
-  ExecuteMethod(kIsNvramLocked, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
-  EXPECT_TRUE(reply.has_is_locked());
-  EXPECT_EQ(nvram_locked, reply.is_locked());
+  ListSpacesReply reply;
+  ExecuteMethod(kListSpaces, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+  EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size());
+  for (size_t i = 0; i < 3; i++) {
+    EXPECT_EQ(nvram_index_list[i], reply.index_list(i));
+  }
 }
 
-TEST_F(DBusServiceTest, GetNvramSize) {
+TEST_F(DBusServiceTest, GetSpaceInfo) {
   uint32_t nvram_index = 5;
   size_t nvram_size = 32;
-  GetNvramSizeRequest request;
+  GetSpaceInfoRequest request;
   request.set_index(nvram_index);
-  EXPECT_CALL(mock_nvram_service_, GetNvramSize(_, _))
+  EXPECT_CALL(mock_nvram_service_, GetSpaceInfo(_, _))
       .WillOnce(Invoke([nvram_index, nvram_size](
-          const GetNvramSizeRequest& request,
-          const TpmNvramInterface::GetNvramSizeCallback& callback) {
+          const GetSpaceInfoRequest& request,
+          const TpmNvramInterface::GetSpaceInfoCallback& callback) {
         EXPECT_TRUE(request.has_index());
         EXPECT_EQ(nvram_index, request.index());
-        GetNvramSizeReply reply;
-        reply.set_status(STATUS_SUCCESS);
+        GetSpaceInfoReply reply;
+        reply.set_result(NVRAM_RESULT_SUCCESS);
         reply.set_size(nvram_size);
+        reply.set_is_read_locked(true);
+        reply.set_is_write_locked(true);
         callback.Run(reply);
       }));
-  GetNvramSizeReply reply;
-  ExecuteMethod(kGetNvramSize, request, &reply, kTpmNvramInterface);
-  EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  GetSpaceInfoReply reply;
+  ExecuteMethod(kGetSpaceInfo, request, &reply, kTpmNvramInterface);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   EXPECT_TRUE(reply.has_size());
   EXPECT_EQ(nvram_size, reply.size());
+  EXPECT_TRUE(reply.is_read_locked());
+  EXPECT_TRUE(reply.is_write_locked());
 }
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/local_data_store.h b/tpm_manager/server/local_data_store.h
index eccc3ca..1aebd1f 100644
--- a/tpm_manager/server/local_data_store.h
+++ b/tpm_manager/server/local_data_store.h
@@ -17,7 +17,7 @@
 #ifndef TPM_MANAGER_SERVER_LOCAL_DATA_STORE_H_
 #define TPM_MANAGER_SERVER_LOCAL_DATA_STORE_H_
 
-#include "tpm_manager/common/local_data.pb.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
 
 namespace tpm_manager {
 
diff --git a/tpm_manager/server/local_data_store_impl.cc b/tpm_manager/server/local_data_store_impl.cc
index 9851c08..abe7c22 100644
--- a/tpm_manager/server/local_data_store_impl.cc
+++ b/tpm_manager/server/local_data_store_impl.cc
@@ -28,7 +28,11 @@
 
 namespace tpm_manager {
 
+#if defined(__ANDROID__)
+const char kTpmLocalDataFile[] = "/data/misc/tpm_managerd/local_tpm_data";
+#else
 const char kTpmLocalDataFile[] = "/var/lib/tpm_manager/local_tpm_data";
+#endif
 const mode_t kLocalDataPermissions = 0600;
 
 bool LocalDataStoreImpl::Read(LocalData* data) {
diff --git a/tpm_manager/server/main.cc b/tpm_manager/server/main.cc
index 77632d3..d6aaa3e 100644
--- a/tpm_manager/server/main.cc
+++ b/tpm_manager/server/main.cc
@@ -14,22 +14,24 @@
 // limitations under the License.
 //
 
-#include <sysexits.h>
 #include <string>
 
 #include <base/command_line.h>
-#include <brillo/daemons/dbus_daemon.h>
-#include <brillo/dbus/async_event_sequencer.h>
-#include <brillo/minijail/minijail.h>
 #include <brillo/syslog_logging.h>
-#include <brillo/userdb_utils.h>
+#if defined(USE_TPM2)
+#include <trunks/trunks_factory_impl.h>
+#endif
 
 #include "tpm_manager/common/tpm_manager_constants.h"
+#if defined(USE_BINDER_IPC)
+#include "tpm_manager/server/binder_service.h"
+#else
 #include "tpm_manager/server/dbus_service.h"
+#endif
 #include "tpm_manager/server/local_data_store_impl.h"
 #include "tpm_manager/server/tpm_manager_service.h"
 
-#if USE_TPM2
+#if defined(USE_TPM2)
 #include "tpm_manager/server/tpm2_initializer_impl.h"
 #include "tpm_manager/server/tpm2_nvram_impl.h"
 #include "tpm_manager/server/tpm2_status_impl.h"
@@ -39,62 +41,10 @@
 #include "tpm_manager/server/tpm_status_impl.h"
 #endif
 
-using brillo::dbus_utils::AsyncEventSequencer;
-
 namespace {
 
-const char kWaitForOwnershipTriggerSwitch[] = "wait_for_ownership_trigger";
-
-class TpmManagerDaemon : public brillo::DBusServiceDaemon {
- public:
-  TpmManagerDaemon()
-      : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName) {
-    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-    local_data_store_.reset(new tpm_manager::LocalDataStoreImpl());
-#if USE_TPM2
-    tpm_status_.reset(new tpm_manager::Tpm2StatusImpl);
-    tpm_initializer_.reset(new tpm_manager::Tpm2InitializerImpl(
-        local_data_store_.get(), tpm_status_.get()));
-    tpm_nvram_.reset(new tpm_manager::Tpm2NvramImpl(local_data_store_.get()));
-#else
-    tpm_status_.reset(new tpm_manager::TpmStatusImpl);
-    tpm_initializer_.reset(new tpm_manager::TpmInitializerImpl(
-        local_data_store_.get(), tpm_status_.get()));
-    tpm_nvram_.reset(new tpm_manager::TpmNvramImpl(local_data_store_.get()));
-#endif
-    tpm_manager_service_.reset(new tpm_manager::TpmManagerService(
-        command_line->HasSwitch(kWaitForOwnershipTriggerSwitch),
-        local_data_store_.get(), tpm_status_.get(), tpm_initializer_.get(),
-        tpm_nvram_.get()));
-  }
-
- protected:
-  int OnInit() override {
-    int result = brillo::DBusServiceDaemon::OnInit();
-    if (result != EX_OK) {
-      LOG(ERROR) << "Error starting tpm_manager dbus daemon.";
-      return result;
-    }
-    CHECK(tpm_manager_service_->Initialize());
-    return EX_OK;
-  }
-
-  void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
-    dbus_service_.reset(new tpm_manager::DBusService(
-        bus_, tpm_manager_service_.get(), tpm_manager_service_.get()));
-    dbus_service_->Register(sequencer->GetHandler("Register() failed.", true));
-  }
-
- private:
-  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::TpmManagerService> tpm_manager_service_;
-  std::unique_ptr<tpm_manager::DBusService> dbus_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(TpmManagerDaemon);
-};
+constexpr char kWaitForOwnershipTriggerSwitch[] = "wait_for_ownership_trigger";
+constexpr char kLogToStderrSwitch[] = "log_to_stderr";
 
 }  // namespace
 
@@ -102,11 +52,43 @@
   base::CommandLine::Init(argc, argv);
   base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
   int flags = brillo::kLogToSyslog;
-  if (cl->HasSwitch("log_to_stderr")) {
+  if (cl->HasSwitch(kLogToStderrSwitch)) {
     flags |= brillo::kLogToStderr;
   }
   brillo::InitLog(flags);
-  TpmManagerDaemon daemon;
-  LOG(INFO) << "TpmManager Daemon Started.";
-  return daemon.Run();
+
+  tpm_manager::LocalDataStoreImpl local_data_store;
+#if defined(USE_TPM2)
+  trunks::TrunksFactoryImpl trunks_factory;
+  // Tolerate some delay in trunksd being up and ready.
+  constexpr int kTrunksDaemonTimeoutMS = 30000;  // 30 seconds
+  int ms_waited = 0;
+  while (!trunks_factory.Initialize() && ms_waited < kTrunksDaemonTimeoutMS) {
+    usleep(300000);
+    ms_waited += 300;
+  }
+  tpm_manager::Tpm2StatusImpl tpm_status(trunks_factory);
+  tpm_manager::Tpm2InitializerImpl tpm_initializer(
+      trunks_factory, &local_data_store, &tpm_status);
+  tpm_manager::Tpm2NvramImpl tpm_nvram(trunks_factory, &local_data_store);
+#else
+  tpm_manager::TpmStatusImpl tpm_status;
+  tpm_manager::TpmInitializerImpl tpm_initializer(&local_data_store,
+                                                  &tpm_status);
+  tpm_manager::TpmNvramImpl tpm_nvram(&local_data_store);
+#endif
+  tpm_manager::TpmManagerService tpm_manager_service(
+      cl->HasSwitch(kWaitForOwnershipTriggerSwitch), &local_data_store,
+      &tpm_status, &tpm_initializer, &tpm_nvram);
+
+#if defined(USE_BINDER_IPC)
+  tpm_manager::BinderService ipc_service(&tpm_manager_service,
+                                         &tpm_manager_service);
+#else
+  tpm_manager::DBusService ipc_service(&tpm_manager_service,
+                                       &tpm_manager_service);
+#endif
+  CHECK(tpm_manager_service.Initialize()) << "Failed to initialize service.";
+  LOG(INFO) << "Starting TPM Manager...";
+  return ipc_service.Run();
 }
diff --git a/tpm_manager/server/mock_local_data_store.cc b/tpm_manager/server/mock_local_data_store.cc
index 6c53947..e4139e3 100644
--- a/tpm_manager/server/mock_local_data_store.cc
+++ b/tpm_manager/server/mock_local_data_store.cc
@@ -17,6 +17,7 @@
 #include "tpm_manager/server/mock_local_data_store.h"
 
 using testing::_;
+using testing::ByRef;
 using testing::DoAll;
 using testing::Return;
 using testing::SaveArg;
@@ -26,7 +27,7 @@
 
 MockLocalDataStore::MockLocalDataStore() {
   ON_CALL(*this, Read(_))
-      .WillByDefault(DoAll(SetArgPointee<0>(fake_), Return(true)));
+      .WillByDefault(DoAll(SetArgPointee<0>(ByRef(fake_)), Return(true)));
   ON_CALL(*this, Write(_))
       .WillByDefault(DoAll(SaveArg<0>(&fake_), Return(true)));
 }
diff --git a/tpm_manager/server/mock_local_data_store.h b/tpm_manager/server/mock_local_data_store.h
index c7f849d..ca5d270 100644
--- a/tpm_manager/server/mock_local_data_store.h
+++ b/tpm_manager/server/mock_local_data_store.h
@@ -31,6 +31,9 @@
   MOCK_METHOD1(Read, bool(LocalData*));
   MOCK_METHOD1(Write, bool(const LocalData&));
 
+  const LocalData& GetFakeData() const { return fake_; }
+  LocalData& GetMutableFakeData() { return fake_; }
+
  private:
   LocalData fake_;
 };
diff --git a/tpm_manager/server/mock_tpm_initializer.cc b/tpm_manager/server/mock_tpm_initializer.cc
index 1d03c47..4f9dba6 100644
--- a/tpm_manager/server/mock_tpm_initializer.cc
+++ b/tpm_manager/server/mock_tpm_initializer.cc
@@ -22,6 +22,7 @@
 
 MockTpmInitializer::MockTpmInitializer() {
   ON_CALL(*this, InitializeTpm()).WillByDefault(Return(true));
+  ON_CALL(*this, ResetDictionaryAttackLock()).WillByDefault(Return(true));
 }
 MockTpmInitializer::~MockTpmInitializer() {}
 
diff --git a/tpm_manager/server/mock_tpm_initializer.h b/tpm_manager/server/mock_tpm_initializer.h
index 45f2fc1..2d3936f 100644
--- a/tpm_manager/server/mock_tpm_initializer.h
+++ b/tpm_manager/server/mock_tpm_initializer.h
@@ -29,6 +29,8 @@
   ~MockTpmInitializer() override;
 
   MOCK_METHOD0(InitializeTpm, bool());
+  MOCK_METHOD0(VerifiedBootHelper, void());
+  MOCK_METHOD0(ResetDictionaryAttackLock, bool());
 };
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/mock_tpm_nvram.cc b/tpm_manager/server/mock_tpm_nvram.cc
index 1cc6a77..7f3f546 100644
--- a/tpm_manager/server/mock_tpm_nvram.cc
+++ b/tpm_manager/server/mock_tpm_nvram.cc
@@ -23,92 +23,139 @@
 using testing::Return;
 
 MockTpmNvram::MockTpmNvram() {
-  ON_CALL(*this, DefineNvram(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeDefineNvram));
-  ON_CALL(*this, DestroyNvram(_))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeDestroyNvram));
-  ON_CALL(*this, WriteNvram(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeWriteNvram));
-  ON_CALL(*this, ReadNvram(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeReadNvram));
-  ON_CALL(*this, IsNvramDefined(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeIsNvramDefined));
-  ON_CALL(*this, IsNvramLocked(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeIsNvramLocked));
-  ON_CALL(*this, GetNvramSize(_, _))
-      .WillByDefault(Invoke(this, &MockTpmNvram::FakeGetNvramSize));
+  ON_CALL(*this, DefineSpace(_, _, _, _, _))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeDefineSpace));
+  ON_CALL(*this, DestroySpace(_))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeDestroySpace));
+  ON_CALL(*this, WriteSpace(_, _, _))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeWriteSpace));
+  ON_CALL(*this, ReadSpace(_, _, _))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeReadSpace));
+  ON_CALL(*this, LockSpace(_, _, _, _))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeLockSpace));
+  ON_CALL(*this, ListSpaces(_))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeListSpaces));
+  ON_CALL(*this, GetSpaceInfo(_, _, _, _, _, _))
+      .WillByDefault(Invoke(this, &MockTpmNvram::FakeGetSpaceInfo));
 }
 
 MockTpmNvram::~MockTpmNvram() {}
 
-bool MockTpmNvram::FakeDefineNvram(uint32_t index, size_t length) {
-  if (length == 0) {
-    return false;
+NvramResult MockTpmNvram::FakeDefineSpace(
+    uint32_t index,
+    size_t size,
+    const std::vector<NvramSpaceAttribute>& attributes,
+    const std::string& authorization_value,
+    NvramSpacePolicy policy) {
+  if (size == 0) {
+    return NVRAM_RESULT_INVALID_PARAMETER;
+  }
+  if (nvram_map_.count(index) != 0) {
+    return NVRAM_RESULT_SPACE_ALREADY_EXISTS;
   }
   NvSpace ns;
-  ns.data.resize(length, '\xff');
-  ns.written = false;
+  ns.data.resize(size, '\xff');
+  ns.read_locked = false;
+  ns.write_locked = false;
+  ns.attributes = attributes;
+  ns.authorization_value = authorization_value;
+  ns.policy = policy;
   nvram_map_[index] = ns;
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeDestroyNvram(uint32_t index) {
-  auto it = nvram_map_.find(index);
-  if (it == nvram_map_.end()) {
-    return false;
+NvramResult MockTpmNvram::FakeDestroySpace(uint32_t index) {
+  if (nvram_map_.count(index) == 0) {
+    return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
   }
-  nvram_map_.erase(it);
-  return true;
+  nvram_map_.erase(index);
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeWriteNvram(uint32_t index, const std::string& data) {
-  auto it = nvram_map_.find(index);
-  if (it == nvram_map_.end()) {
-    return false;
+NvramResult MockTpmNvram::FakeWriteSpace(
+    uint32_t index,
+    const std::string& data,
+    const std::string& authorization_value) {
+  if (nvram_map_.count(index) == 0) {
+    return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
   }
-  NvSpace& nv = it->second;
-  if (nv.written || nv.data.size() < data.size()) {
-    return false;
+  if (nvram_map_[index].authorization_value != authorization_value) {
+    return NVRAM_RESULT_ACCESS_DENIED;
   }
-  nv.data.replace(0, data.size(), data);
-  nv.written = true;
-  return true;
+  if (nvram_map_[index].write_locked) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  std::string& space_data = nvram_map_[index].data;
+  size_t size = space_data.size();
+  if (data.size() > size) {
+    return NVRAM_RESULT_INVALID_PARAMETER;
+  }
+  space_data = data;
+  space_data.resize(size);
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeReadNvram(uint32_t index, std::string* data) {
-  auto it = nvram_map_.find(index);
-  if (it == nvram_map_.end()) {
-    return false;
+NvramResult MockTpmNvram::FakeReadSpace(
+    uint32_t index,
+    std::string* data,
+    const std::string& authorization_value) {
+  if (nvram_map_.count(index) == 0) {
+    return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
   }
-  const NvSpace& nv = it->second;
-  if (!nv.written) {
-    return false;
+  if (nvram_map_[index].authorization_value != authorization_value) {
+    return NVRAM_RESULT_ACCESS_DENIED;
   }
-  data->assign(nv.data);
-  return true;
+  if (nvram_map_[index].read_locked) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  *data = nvram_map_[index].data;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeIsNvramDefined(uint32_t index, bool* defined) {
-  *defined = (nvram_map_.find(index) != nvram_map_.end());
-  return true;
+NvramResult MockTpmNvram::FakeLockSpace(
+    uint32_t index,
+    bool lock_read,
+    bool lock_write,
+    const std::string& authorization_value) {
+  if (nvram_map_.count(index) == 0) {
+    return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
+  }
+  if (nvram_map_[index].authorization_value != authorization_value) {
+    return NVRAM_RESULT_ACCESS_DENIED;
+  }
+  if (lock_read) {
+    nvram_map_[index].read_locked = true;
+  }
+  if (lock_write) {
+    nvram_map_[index].write_locked = true;
+  }
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeIsNvramLocked(uint32_t index, bool* locked) {
-  bool defined;
-  if (!IsNvramDefined(index, &defined) || !defined) {
-    return false;
+NvramResult MockTpmNvram::FakeListSpaces(std::vector<uint32_t>* index_list) {
+  for (auto iter : nvram_map_) {
+    index_list->push_back(iter.first);
   }
-  *locked = nvram_map_[index].written;
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool MockTpmNvram::FakeGetNvramSize(uint32_t index, size_t* size) {
-  bool defined;
-  if (!IsNvramDefined(index, &defined) || !defined) {
-    return false;
+NvramResult MockTpmNvram::FakeGetSpaceInfo(
+    uint32_t index,
+    size_t* size,
+    bool* is_read_locked,
+    bool* is_write_locked,
+    std::vector<NvramSpaceAttribute>* attributes,
+    NvramSpacePolicy* policy) {
+  if (nvram_map_.count(index) == 0) {
+    return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
   }
-  *size = nvram_map_[index].data.size();
-  return true;
+  NvSpace& space = nvram_map_[index];
+  *size = space.data.size();
+  *is_read_locked = space.read_locked;
+  *is_write_locked = space.write_locked;
+  *attributes = space.attributes;
+  *policy = space.policy;
+  return NVRAM_RESULT_SUCCESS;
 }
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/mock_tpm_nvram.h b/tpm_manager/server/mock_tpm_nvram.h
index eafe413..fe61baa 100644
--- a/tpm_manager/server/mock_tpm_nvram.h
+++ b/tpm_manager/server/mock_tpm_nvram.h
@@ -28,7 +28,11 @@
 
 struct NvSpace {
   std::string data;
-  bool written;
+  bool read_locked;
+  bool write_locked;
+  std::vector<NvramSpaceAttribute> attributes;
+  std::string authorization_value;
+  NvramSpacePolicy policy;
 };
 
 class MockTpmNvram : public TpmNvram {
@@ -36,22 +40,53 @@
   MockTpmNvram();
   ~MockTpmNvram() override;
 
-  MOCK_METHOD2(DefineNvram, bool(uint32_t, size_t));
-  MOCK_METHOD1(DestroyNvram, bool(uint32_t));
-  MOCK_METHOD2(WriteNvram, bool(uint32_t, const std::string&));
-  MOCK_METHOD2(ReadNvram, bool(uint32_t, std::string*));
-  MOCK_METHOD2(IsNvramDefined, bool(uint32_t, bool*));
-  MOCK_METHOD2(IsNvramLocked, bool(uint32_t, bool*));
-  MOCK_METHOD2(GetNvramSize, bool(uint32_t, size_t*));
+  MOCK_METHOD5(DefineSpace,
+               NvramResult(uint32_t,
+                           size_t,
+                           const std::vector<NvramSpaceAttribute>&,
+                           const std::string&,
+                           NvramSpacePolicy));
+  MOCK_METHOD1(DestroySpace, NvramResult(uint32_t));
+  MOCK_METHOD3(WriteSpace,
+               NvramResult(uint32_t, const std::string&, const std::string&));
+  MOCK_METHOD3(ReadSpace,
+               NvramResult(uint32_t, std::string*, const std::string&));
+  MOCK_METHOD4(LockSpace,
+               NvramResult(uint32_t, bool, bool, const std::string&));
+  MOCK_METHOD1(ListSpaces, NvramResult(std::vector<uint32_t>*));
+  MOCK_METHOD6(GetSpaceInfo,
+               NvramResult(uint32_t,
+                           size_t*,
+                           bool*,
+                           bool*,
+                           std::vector<NvramSpaceAttribute>*,
+                           NvramSpacePolicy*));
 
  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* defined);
-  bool FakeIsNvramLocked(uint32_t index, bool* locked);
-  bool FakeGetNvramSize(uint32_t index, size_t* size);
+  NvramResult FakeDefineSpace(
+      uint32_t index,
+      size_t size,
+      const std::vector<NvramSpaceAttribute>& attributes,
+      const std::string& authorization_value,
+      NvramSpacePolicy policy);
+  NvramResult FakeDestroySpace(uint32_t index);
+  NvramResult FakeWriteSpace(uint32_t index,
+                             const std::string& data,
+                             const std::string& authorization_value);
+  NvramResult FakeReadSpace(uint32_t index,
+                            std::string* data,
+                            const std::string& authorization_value);
+  NvramResult FakeLockSpace(uint32_t index,
+                            bool lock_read,
+                            bool lock_write,
+                            const std::string& authorization_value);
+  NvramResult FakeListSpaces(std::vector<uint32_t>* index_list);
+  NvramResult FakeGetSpaceInfo(uint32_t index,
+                               size_t* size,
+                               bool* is_read_locked,
+                               bool* is_write_locked,
+                               std::vector<NvramSpaceAttribute>* attributes,
+                               NvramSpacePolicy* policy);
 
   std::map<uint32_t, NvSpace> nvram_map_;
 };
diff --git a/tpm_manager/server/org.chromium.TpmManager.conf b/tpm_manager/server/org.chromium.TpmManager.conf
index 70eca0f..265d45b 100644
--- a/tpm_manager/server/org.chromium.TpmManager.conf
+++ b/tpm_manager/server/org.chromium.TpmManager.conf
@@ -6,6 +6,10 @@
     <allow own="org.chromium.TpmManager" />
     <allow send_destination="org.chromium.TpmManager" />
   </policy>
+  <policy user="root">
+    <allow own="org.chromium.TpmManager" />
+    <allow send_destination="org.chromium.TpmManager" />
+  </policy>
   <policy context="default">
     <allow send_destination="org.chromium.TpmManager" />
     <!-- introspection denied -->
diff --git a/tpm_manager/server/tpm2_initializer_impl.cc b/tpm_manager/server/tpm2_initializer_impl.cc
index e2e24aa..9c557a0 100644
--- a/tpm_manager/server/tpm2_initializer_impl.cc
+++ b/tpm_manager/server/tpm2_initializer_impl.cc
@@ -19,27 +19,32 @@
 #include <string>
 
 #include <base/logging.h>
+#include <trunks/error_codes.h>
 #include <trunks/tpm_utility.h>
 #include <trunks/trunks_factory_impl.h>
 
-#include "tpm_manager/common/local_data.pb.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
 #include "tpm_manager/common/tpm_manager_constants.h"
 #include "tpm_manager/server/openssl_crypto_util_impl.h"
 
+using trunks::TPM_RC;
+using trunks::TPM_RC_SUCCESS;
+
 namespace {
 const size_t kDefaultPasswordSize = 20;
 }  // namespace
 
 namespace tpm_manager {
 
-Tpm2InitializerImpl::Tpm2InitializerImpl(LocalDataStore* local_data_store,
+Tpm2InitializerImpl::Tpm2InitializerImpl(const trunks::TrunksFactory& factory,
+                                         LocalDataStore* local_data_store,
                                          TpmStatus* tpm_status)
-    : trunks_factory_(new trunks::TrunksFactoryImpl()),
+    : trunks_factory_(factory),
       openssl_util_(new OpensslCryptoUtilImpl()),
       local_data_store_(local_data_store),
       tpm_status_(tpm_status) {}
 
-Tpm2InitializerImpl::Tpm2InitializerImpl(trunks::TrunksFactory* factory,
+Tpm2InitializerImpl::Tpm2InitializerImpl(const trunks::TrunksFactory& factory,
                                          OpensslCryptoUtil* openssl_util,
                                          LocalDataStore* local_data_store,
                                          TpmStatus* tpm_status)
@@ -100,12 +105,69 @@
     LOG(ERROR) << "Error saving local data.";
     return false;
   }
-  trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->TakeOwnership(
+  TPM_RC result = trunks_factory_.GetTpmUtility()->TakeOwnership(
       owner_password, endorsement_password, lockout_password);
-  if (result != trunks::TPM_RC_SUCCESS) {
+  if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error taking ownership of TPM2.0";
     return false;
   }
+
+  return true;
+}
+
+void Tpm2InitializerImpl::VerifiedBootHelper() {
+  constexpr char kVerifiedBootLateStageTag[] = "BOOT_PCR_LATE_STAGE";
+  std::unique_ptr<trunks::TpmUtility> tpm_utility =
+      trunks_factory_.GetTpmUtility();
+  // Make sure PCRs 0-3 can't be spoofed from this point forward.
+  for (int pcr : {0, 1, 2, 3}) {
+    std::string value;
+    TPM_RC result = tpm_utility->ReadPCR(pcr, &value);
+    if (result) {
+      LOG(ERROR) << "Failed to read PCR " << pcr << ": "
+                 << trunks::GetErrorString(result);
+      continue;
+    }
+    if (value == std::string(32, 0)) {
+      LOG(WARNING) << "WARNING: Verified boot PCR " << pcr
+                   << " is not initialized.";
+      result = tpm_utility->ExtendPCR(pcr, kVerifiedBootLateStageTag, nullptr);
+      if (result) {
+        LOG(ERROR) << "Failed to extend PCR " << pcr << ": "
+                   << trunks::GetErrorString(result);
+      }
+    }
+  }
+}
+
+bool Tpm2InitializerImpl::ResetDictionaryAttackLock() {
+  LocalData local_data;
+  if (!local_data_store_->Read(&local_data)) {
+    LOG(ERROR) << __func__ << ": Error reading local data.";
+    return false;
+  }
+  if (!local_data.has_lockout_password()) {
+    LOG(ERROR) << __func__ << ": Lockout password not available.";
+    return false;
+  }
+  std::unique_ptr<trunks::HmacSession> session =
+      trunks_factory_.GetHmacSession();
+  TPM_RC result = session->StartUnboundSession(false);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << __func__ << ": Error initializing AuthorizationSession: "
+               << trunks::GetErrorString(result);
+    return false;
+  }
+  session->SetEntityAuthorizationValue(local_data.lockout_password());
+  std::unique_ptr<trunks::TpmUtility> tpm_utility =
+      trunks_factory_.GetTpmUtility();
+  result =
+      tpm_utility->ResetDictionaryAttackLock(session->GetDelegate());
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << __func__ << ": Error resetting lock: "
+               << trunks::GetErrorString(result);
+    return false;
+  }
   return true;
 }
 
@@ -114,9 +176,9 @@
   if (!openssl_util_->GetRandomBytes(kDefaultPasswordSize, &random_bytes)) {
     return false;
   }
-  trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->StirRandom(
+  TPM_RC result = trunks_factory_.GetTpmUtility()->StirRandom(
       random_bytes, nullptr /* No Authorization */);
-  if (result != trunks::TPM_RC_SUCCESS) {
+  if (result != TPM_RC_SUCCESS) {
     return false;
   }
   return true;
@@ -124,9 +186,9 @@
 
 bool Tpm2InitializerImpl::GetTpmRandomData(size_t num_bytes,
                                            std::string* random_data) {
-  trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->GenerateRandom(
+  TPM_RC result = trunks_factory_.GetTpmUtility()->GenerateRandom(
       num_bytes, nullptr /* No Authorization */, random_data);
-  if (result != trunks::TPM_RC_SUCCESS) {
+  if (result != TPM_RC_SUCCESS) {
     return false;
   }
   return true;
diff --git a/tpm_manager/server/tpm2_initializer_impl.h b/tpm_manager/server/tpm2_initializer_impl.h
index aa217c4..ca874bc 100644
--- a/tpm_manager/server/tpm2_initializer_impl.h
+++ b/tpm_manager/server/tpm2_initializer_impl.h
@@ -42,11 +42,12 @@
 // the passwords to disk until all the owner dependencies are satisfied.
 class Tpm2InitializerImpl : public TpmInitializer {
  public:
-  // Does not take ownership of |local_data_store| or |tpm_status|.
-  Tpm2InitializerImpl(LocalDataStore* local_data_store, TpmStatus* tpm_status);
-  // Does not take ownership of |openssl_util|, |local_data_store| or
-  // |tpm_status|. Takes ownership of |factory|.
-  Tpm2InitializerImpl(trunks::TrunksFactory* factory,
+  // Does not take ownership of arguments.
+  Tpm2InitializerImpl(const trunks::TrunksFactory& factory,
+                      LocalDataStore* local_data_store,
+                      TpmStatus* tpm_status);
+  // Does not take ownership of arguments.
+  Tpm2InitializerImpl(const trunks::TrunksFactory& factory,
                       OpensslCryptoUtil* openssl_util,
                       LocalDataStore* local_data_store,
                       TpmStatus* tpm_status);
@@ -54,6 +55,8 @@
 
   // TpmInitializer methods.
   bool InitializeTpm() override;
+  void VerifiedBootHelper() override;
+  bool ResetDictionaryAttackLock() override;
 
  private:
   // Seeds the onboard Tpm random number generator with random bytes from
@@ -64,7 +67,7 @@
   // |random_data|. Returns true on success.
   bool GetTpmRandomData(size_t num_bytes, std::string* random_data);
 
-  std::unique_ptr<trunks::TrunksFactory> trunks_factory_;
+  const trunks::TrunksFactory& trunks_factory_;
   OpensslCryptoUtil* openssl_util_;
   LocalDataStore* local_data_store_;
   TpmStatus* tpm_status_;
diff --git a/tpm_manager/server/tpm2_initializer_test.cc b/tpm_manager/server/tpm2_initializer_test.cc
index 536ed7a..7fc0a3d 100644
--- a/tpm_manager/server/tpm2_initializer_test.cc
+++ b/tpm_manager/server/tpm2_initializer_test.cc
@@ -29,6 +29,8 @@
 #include "tpm_manager/server/mock_tpm_status.h"
 
 using testing::_;
+using testing::AtLeast;
+using testing::Invoke;
 using testing::DoAll;
 using testing::NiceMock;
 using testing::Return;
@@ -43,17 +45,28 @@
   virtual ~Tpm2InitializerTest() = default;
 
   void SetUp() {
-    trunks::TrunksFactoryForTest* factory = new trunks::TrunksFactoryForTest();
-    factory->set_tpm_utility(&mock_tpm_utility_);
+    EXPECT_CALL(mock_data_store_, Read(_))
+        .WillRepeatedly(Invoke([this](LocalData* arg) {
+          *arg = fake_local_data_;
+          return true;
+        }));
+    EXPECT_CALL(mock_data_store_, Write(_))
+        .WillRepeatedly(Invoke([this](const LocalData& arg) {
+          fake_local_data_ = arg;
+          return true;
+        }));
+    factory_.set_tpm_utility(&mock_tpm_utility_);
     tpm_initializer_.reset(new Tpm2InitializerImpl(
-        factory, &mock_openssl_util_, &mock_data_store_, &mock_tpm_status_));
+        factory_, &mock_openssl_util_, &mock_data_store_, &mock_tpm_status_));
   }
 
  protected:
+  LocalData fake_local_data_;
   NiceMock<MockOpensslCryptoUtil> mock_openssl_util_;
   NiceMock<MockLocalDataStore> mock_data_store_;
   NiceMock<MockTpmStatus> mock_tpm_status_;
   NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
+  trunks::TrunksFactoryForTest factory_;
   std::unique_ptr<TpmInitializer> tpm_initializer_;
 };
 
@@ -92,18 +105,18 @@
 
 TEST_F(Tpm2InitializerTest, InitializeTpmSuccess) {
   EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillOnce(Return(false));
-  std::string owner_password;
-  std::string endorsement_password;
-  std::string lockout_password;
-  LocalData local_data;
-  EXPECT_CALL(mock_data_store_, Read(_))
-      .WillOnce(DoAll(SetArgPointee<0>(local_data), Return(true)));
+  std::string password = "hunter2";
   EXPECT_CALL(mock_tpm_utility_, GenerateRandom(_, _, _))
       .Times(3)  // Once for owner, endorsement and lockout passwords
-      .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
+      .WillRepeatedly(
+          DoAll(SetArgPointee<2>(password), Return(trunks::TPM_RC_SUCCESS)));
   EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
       .WillOnce(Return(trunks::TPM_RC_SUCCESS));
   EXPECT_TRUE(tpm_initializer_->InitializeTpm());
+  EXPECT_LT(0, fake_local_data_.owner_dependency_size());
+  EXPECT_EQ(password, fake_local_data_.owner_password());
+  EXPECT_EQ(password, fake_local_data_.endorsement_password());
+  EXPECT_EQ(password, fake_local_data_.lockout_password());
 }
 
 TEST_F(Tpm2InitializerTest, InitializeTpmSuccessAfterError) {
@@ -111,25 +124,66 @@
   std::string owner_password("owner");
   std::string endorsement_password("endorsement");
   std::string lockout_password("lockout");
-  LocalData local_data;
-  local_data.add_owner_dependency(kTestDependency);
-  local_data.set_owner_password(owner_password);
-  local_data.set_endorsement_password(endorsement_password);
-  local_data.set_lockout_password(lockout_password);
-  EXPECT_CALL(mock_data_store_, Read(_))
-      .WillOnce(DoAll(SetArgPointee<0>(local_data), Return(true)));
-  EXPECT_CALL(mock_data_store_, Write(_))
-      .WillOnce(DoAll(SaveArg<0>(&local_data), Return(true)));
-  EXPECT_EQ(1, local_data.owner_dependency_size());
-  EXPECT_EQ(kTestDependency, local_data.owner_dependency(0));
-  EXPECT_EQ(owner_password, local_data.owner_password());
-  EXPECT_EQ(endorsement_password, local_data.endorsement_password());
-  EXPECT_EQ(lockout_password, local_data.lockout_password());
+  fake_local_data_.add_owner_dependency("test");
+  fake_local_data_.set_owner_password(owner_password);
+  fake_local_data_.set_endorsement_password(endorsement_password);
+  fake_local_data_.set_lockout_password(lockout_password);
   EXPECT_CALL(
       mock_tpm_utility_,
       TakeOwnership(owner_password, endorsement_password, lockout_password))
       .WillOnce(Return(trunks::TPM_RC_SUCCESS));
   EXPECT_TRUE(tpm_initializer_->InitializeTpm());
+  EXPECT_LT(0, fake_local_data_.owner_dependency_size());
+  EXPECT_EQ(owner_password, fake_local_data_.owner_password());
+  EXPECT_EQ(endorsement_password, fake_local_data_.endorsement_password());
+  EXPECT_EQ(lockout_password, fake_local_data_.lockout_password());
+}
+
+TEST_F(Tpm2InitializerTest, PCRSpoofGuard) {
+  // Setup empty PCRs that need to be extended.
+  EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
+      .WillRepeatedly(DoAll(SetArgPointee<1>(std::string(32, 0)),
+                            Return(trunks::TPM_RC_SUCCESS)));
+  // Expect at least four PCRs to be extended.
+  EXPECT_CALL(mock_tpm_utility_, ExtendPCR(_, _, _))
+      .Times(AtLeast(4))
+      .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
+  tpm_initializer_->VerifiedBootHelper();
+}
+
+TEST_F(Tpm2InitializerTest, PCRSpoofGuardReadFailure) {
+  EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
+      .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
+  tpm_initializer_->VerifiedBootHelper();
+}
+
+TEST_F(Tpm2InitializerTest, PCRSpoofGuardExtendFailure) {
+  EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
+      .WillRepeatedly(DoAll(SetArgPointee<1>(std::string(32, 0)),
+                            Return(trunks::TPM_RC_SUCCESS)));
+  EXPECT_CALL(mock_tpm_utility_, ExtendPCR(_, _, _))
+      .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
+  tpm_initializer_->VerifiedBootHelper();
+}
+
+TEST_F(Tpm2InitializerTest, DAResetSuccess) {
+  fake_local_data_.set_lockout_password("lockout");
+  EXPECT_CALL(mock_tpm_utility_, ResetDictionaryAttackLock(_))
+      .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
+  EXPECT_TRUE(tpm_initializer_->ResetDictionaryAttackLock());
+}
+
+TEST_F(Tpm2InitializerTest, DAResetNoLockoutPassword) {
+  fake_local_data_.clear_lockout_password();
+  EXPECT_FALSE(tpm_initializer_->ResetDictionaryAttackLock());
+}
+
+TEST_F(Tpm2InitializerTest, DAResetFailure) {
+  fake_local_data_.set_lockout_password("lockout");
+  EXPECT_CALL(mock_tpm_utility_, ResetDictionaryAttackLock(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
+  EXPECT_FALSE(tpm_initializer_->ResetDictionaryAttackLock());
 }
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm2_nvram_impl.cc b/tpm_manager/server/tpm2_nvram_impl.cc
index bee3b54..e8951b3 100644
--- a/tpm_manager/server/tpm2_nvram_impl.cc
+++ b/tpm_manager/server/tpm2_nvram_impl.cc
@@ -21,9 +21,9 @@
 
 #include <base/logging.h>
 #include <trunks/error_codes.h>
+#include <trunks/policy_session.h>
 #include <trunks/tpm_constants.h>
 #include <trunks/tpm_utility.h>
-#include <trunks/trunks_factory_impl.h>
 
 namespace tpm_manager {
 
@@ -31,159 +31,628 @@
 using trunks::TPM_RC;
 using trunks::TPM_RC_SUCCESS;
 
-Tpm2NvramImpl::Tpm2NvramImpl(LocalDataStore* local_data_store)
-    : trunks_factory_(new trunks::TrunksFactoryImpl()),
-      local_data_store_(local_data_store),
-      initialized_(false),
-      trunks_session_(trunks_factory_->GetHmacSession()),
-      trunks_utility_(trunks_factory_->GetTpmUtility()) {}
+namespace {
 
-Tpm2NvramImpl::Tpm2NvramImpl(std::unique_ptr<trunks::TrunksFactory> factory,
+void MapAttributesFromTpm(trunks::TPMA_NV tpm_flags,
+                          std::vector<NvramSpaceAttribute>* attributes) {
+  if (tpm_flags & trunks::TPMA_NV_WRITEDEFINE)
+    attributes->push_back(NVRAM_PERSISTENT_WRITE_LOCK);
+  if (tpm_flags & trunks::TPMA_NV_WRITE_STCLEAR)
+    attributes->push_back(NVRAM_BOOT_WRITE_LOCK);
+  if (tpm_flags & trunks::TPMA_NV_READ_STCLEAR)
+    attributes->push_back(NVRAM_BOOT_READ_LOCK);
+  if (tpm_flags & (trunks::TPMA_NV_AUTHWRITE))
+    attributes->push_back(NVRAM_WRITE_AUTHORIZATION);
+  if (tpm_flags & (trunks::TPMA_NV_AUTHREAD))
+    attributes->push_back(NVRAM_READ_AUTHORIZATION);
+  if (tpm_flags & trunks::TPMA_NV_GLOBALLOCK)
+    attributes->push_back(NVRAM_GLOBAL_LOCK);
+  if (tpm_flags & trunks::TPMA_NV_PPWRITE)
+    attributes->push_back(NVRAM_PLATFORM_WRITE);
+  if (tpm_flags & trunks::TPMA_NV_OWNERWRITE)
+    attributes->push_back(NVRAM_OWNER_WRITE);
+  if (tpm_flags & trunks::TPMA_NV_OWNERREAD)
+    attributes->push_back(NVRAM_OWNER_READ);
+  if (tpm_flags & trunks::TPMA_NV_EXTEND)
+    attributes->push_back(NVRAM_WRITE_EXTEND);
+}
+
+bool MapAttributesToTpm(
+    const std::vector<NvramSpaceAttribute>& attributes,
+    trunks::TPMA_NV* tpm_flags,
+    bool* world_read_allowed,
+    bool* world_write_allowed) {
+  // Always require policy, even if it's an empty policy.
+  *tpm_flags = trunks::TPMA_NV_POLICYWRITE | trunks::TPMA_NV_POLICYREAD;
+  *world_read_allowed = true;
+  *world_write_allowed = true;
+  for (auto attribute : attributes) {
+    switch (attribute) {
+      case NVRAM_PERSISTENT_WRITE_LOCK:
+        *tpm_flags |= trunks::TPMA_NV_WRITEDEFINE;
+        break;
+      case NVRAM_BOOT_WRITE_LOCK:
+        *tpm_flags |= trunks::TPMA_NV_WRITE_STCLEAR;
+        break;
+      case NVRAM_BOOT_READ_LOCK:
+        *tpm_flags |= trunks::TPMA_NV_READ_STCLEAR;
+        break;
+      case NVRAM_WRITE_AUTHORIZATION:
+        *world_write_allowed = false;
+        break;
+      case NVRAM_READ_AUTHORIZATION:
+        *world_read_allowed = false;
+        break;
+      case NVRAM_WRITE_EXTEND:
+        *tpm_flags |= trunks::TPMA_NV_EXTEND;
+        break;
+      case NVRAM_GLOBAL_LOCK:
+      case NVRAM_PLATFORM_WRITE:
+      case NVRAM_OWNER_WRITE:
+      case NVRAM_OWNER_READ:
+        return false;
+      default:
+        break;
+    }
+  }
+  return true;
+}
+
+NvramResult MapTpmError(TPM_RC tpm_error) {
+  switch (trunks::GetFormatOneError(tpm_error)) {
+    case trunks::TPM_RC_SUCCESS:
+      return NVRAM_RESULT_SUCCESS;
+    case trunks::TPM_RC_NV_RANGE:
+    case trunks::TPM_RC_NV_SIZE:
+    case trunks::TPM_RC_ATTRIBUTES:
+      return NVRAM_RESULT_INVALID_PARAMETER;
+    case trunks::TPM_RC_NV_LOCKED:
+    case trunks::TPM_RC_NV_UNINITIALIZED:
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    case trunks::TPM_RC_NV_AUTHORIZATION:
+    case trunks::TPM_RC_BAD_AUTH:
+    case trunks::TPM_RC_AUTH_FAIL:
+    case trunks::TPM_RC_POLICY_FAIL:
+      return NVRAM_RESULT_ACCESS_DENIED;
+    case trunks::TPM_RC_NV_SPACE:
+      return NVRAM_RESULT_INSUFFICIENT_SPACE;
+    case trunks::TPM_RC_NV_DEFINED:
+      return NVRAM_RESULT_SPACE_ALREADY_EXISTS;
+    case trunks::TPM_RC_HANDLE:
+      return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
+  }
+  return NVRAM_RESULT_DEVICE_ERROR;
+}
+
+}  // namespace
+
+Tpm2NvramImpl::Tpm2NvramImpl(const trunks::TrunksFactory& factory,
                              LocalDataStore* local_data_store)
-    : trunks_factory_(std::move(factory)),
+    : trunks_factory_(factory),
       local_data_store_(local_data_store),
       initialized_(false),
-      trunks_session_(trunks_factory_->GetHmacSession()),
-      trunks_utility_(trunks_factory_->GetTpmUtility()) {}
+      trunks_session_(trunks_factory_.GetHmacSession()),
+      trunks_utility_(trunks_factory_.GetTpmUtility()) {}
 
-bool Tpm2NvramImpl::Initialize() {
-  if (initialized_) {
-    return true;
-  }
-  TPM_RC result = trunks_utility_->StartSession(trunks_session_.get());
-  if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error starting an authorization session with trunks: "
-               << GetErrorString(result);
-    return false;
-  }
-  LocalData local_data;
-  if (!local_data_store_->Read(&local_data)) {
-    LOG(ERROR) << "Error reading local tpm data.";
-    return false;
-  }
-  if (!local_data.owner_password().empty()) {
-    owner_password_.assign(local_data.owner_password());
-    initialized_ = true;
-  }
-  return true;
-}
-
-bool Tpm2NvramImpl::InitializeWithOwnerPassword() {
+NvramResult Tpm2NvramImpl::DefineSpace(
+    uint32_t index,
+    size_t size,
+    const std::vector<NvramSpaceAttribute>& attributes,
+    const std::string& authorization_value,
+    NvramSpacePolicy policy) {
   if (!Initialize()) {
-    return false;
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  if (owner_password_.empty()) {
-    LOG(ERROR) << "Error owner password not available.";
-    return false;
+  if (!SetupOwnerSession()) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
   }
-  trunks_session_->SetEntityAuthorizationValue(owner_password_);
-  return true;
-}
-
-bool Tpm2NvramImpl::DefineNvram(uint32_t index, size_t length) {
-  if (!InitializeWithOwnerPassword()) {
-    return false;
+  trunks::TPMA_NV attribute_flags = 0;
+  bool world_read_allowed = false;
+  bool world_write_allowed = false;
+  if (!MapAttributesToTpm(attributes, &attribute_flags, &world_read_allowed,
+                          &world_write_allowed)) {
+    return NVRAM_RESULT_INVALID_PARAMETER;
+  }
+  NvramPolicyRecord policy_record;
+  policy_record.set_index(index);
+  policy_record.set_policy(policy);
+  policy_record.set_world_read_allowed(world_read_allowed);
+  policy_record.set_world_write_allowed(world_write_allowed);
+  std::string policy_digest;
+  if (!ComputePolicyDigest(&policy_record, &policy_digest)) {
+    LOG(ERROR) << "Failed to compute policy digest.";
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
   TPM_RC result = trunks_utility_->DefineNVSpace(
-      index, length, trunks_session_->GetDelegate());
+      index, size, attribute_flags, authorization_value, policy_digest,
+      trunks_session_->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error defining nvram space: " << GetErrorString(result);
-    return false;
+    return MapTpmError(result);
   }
-  return true;
+  if (!SavePolicyRecord(policy_record)) {
+    trunks_utility_->DestroyNVSpace(index, trunks_session_->GetDelegate());
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool Tpm2NvramImpl::DestroyNvram(uint32_t index) {
-  if (!InitializeWithOwnerPassword()) {
-    return false;
+NvramResult Tpm2NvramImpl::DestroySpace(uint32_t index) {
+  if (!Initialize()) {
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
+  if (!SetupOwnerSession()) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
   }
   TPM_RC result =
       trunks_utility_->DestroyNVSpace(index, trunks_session_->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error destroying nvram space:" << GetErrorString(result);
-    return false;
+    return MapTpmError(result);
   }
-  return true;
+  DeletePolicyRecord(index);
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool Tpm2NvramImpl::WriteNvram(uint32_t index, const std::string& data) {
-  if (!InitializeWithOwnerPassword()) {
-    return false;
+NvramResult Tpm2NvramImpl::WriteSpace(uint32_t index,
+                                      const std::string& data,
+                                      const std::string& authorization_value) {
+  if (!Initialize()) {
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  TPM_RC result =
-      trunks_utility_->WriteNVSpace(index,
-                                    0,  // offset
-                                    data, trunks_session_->GetDelegate());
+  trunks::TPMS_NV_PUBLIC nvram_public;
+  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error reading nvram space public area: "
+               << GetErrorString(result);
+    return MapTpmError(result);
+  }
+  if (nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  trunks::AuthorizationDelegate* authorization = nullptr;
+  std::unique_ptr<trunks::PolicySession> policy_session =
+      trunks_factory_.GetPolicySession();
+  bool using_owner_authorization = false;
+  bool extend = (nvram_public.attributes & trunks::TPMA_NV_EXTEND) != 0;
+  if (nvram_public.attributes & trunks::TPMA_NV_POLICYWRITE) {
+    NvramPolicyRecord policy_record;
+    if (!GetPolicyRecord(index, &policy_record)) {
+      LOG(ERROR) << "Policy record missing.";
+      return NVRAM_RESULT_INVALID_PARAMETER;
+    }
+    if (!SetupPolicySession(
+            policy_record, authorization_value,
+            extend ? trunks::TPM_CC_NV_Extend : trunks::TPM_CC_NV_Write,
+            policy_session.get())) {
+      // This will fail if policy is not met, e.g. a PCR value is not the
+      // required value.
+      return NVRAM_RESULT_ACCESS_DENIED;
+    }
+    authorization = policy_session->GetDelegate();
+  } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHWRITE) {
+    trunks_session_->SetEntityAuthorizationValue(authorization_value);
+    authorization = trunks_session_->GetDelegate();
+  } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERWRITE) {
+    if (!SetupOwnerSession()) {
+      // The owner password has been destroyed.
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    }
+    using_owner_authorization = true;
+    authorization = trunks_session_->GetDelegate();
+  } else {
+    // TPMA_NV_PPWRITE: Platform authorization is long gone.
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  result = trunks_utility_->WriteNVSpace(index, 0 /* offset */, data,
+                                         using_owner_authorization, extend,
+                                         authorization);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error writing to nvram space: " << GetErrorString(result);
-    return false;
+    return MapTpmError(result);
   }
-  result = trunks_utility_->LockNVSpace(index, trunks_session_->GetDelegate());
-  if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
-    return false;
-  }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool Tpm2NvramImpl::ReadNvram(uint32_t index, std::string* data) {
+NvramResult Tpm2NvramImpl::ReadSpace(uint32_t index,
+                                     std::string* data,
+                                     const std::string& authorization_value) {
   if (!Initialize()) {
-    return false;
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  size_t nvram_size;
-  if (!GetNvramSize(index, &nvram_size)) {
-    LOG(ERROR) << "Error getting size of nvram space.";
-    return false;
+  trunks::TPMS_NV_PUBLIC nvram_public;
+  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error reading nvram space public area: "
+               << GetErrorString(result);
+    return MapTpmError(result);
   }
-  trunks_session_->SetEntityAuthorizationValue("");
-  TPM_RC result = trunks_utility_->ReadNVSpace(index,
-                                               0,  // offset
-                                               nvram_size, data,
-                                               trunks_session_->GetDelegate());
+  if (nvram_public.attributes & trunks::TPMA_NV_READLOCKED) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  // Handle the case when the space has never been written to.
+  if ((nvram_public.attributes & trunks::TPMA_NV_WRITTEN) == 0) {
+    *data = std::string(nvram_public.data_size, 0);
+    return NVRAM_RESULT_SUCCESS;
+  }
+  trunks::AuthorizationDelegate* authorization = nullptr;
+  std::unique_ptr<trunks::PolicySession> policy_session =
+      trunks_factory_.GetPolicySession();
+  bool using_owner_authorization = false;
+  if (nvram_public.attributes & trunks::TPMA_NV_POLICYREAD) {
+    NvramPolicyRecord policy_record;
+    if (!GetPolicyRecord(index, &policy_record)) {
+      LOG(ERROR) << "Policy record missing.";
+      return NVRAM_RESULT_INVALID_PARAMETER;
+    }
+    if (!SetupPolicySession(policy_record, authorization_value,
+                            trunks::TPM_CC_NV_Read, policy_session.get())) {
+      // This will fail if policy is not met, e.g. a PCR value is not the
+      // required value.
+      return NVRAM_RESULT_ACCESS_DENIED;
+    }
+    authorization = policy_session->GetDelegate();
+  } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHREAD) {
+    trunks_session_->SetEntityAuthorizationValue(authorization_value);
+    authorization = trunks_session_->GetDelegate();
+  } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERREAD) {
+    if (!SetupOwnerSession()) {
+      // The owner password has been destroyed.
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    }
+    using_owner_authorization = true;
+    authorization = trunks_session_->GetDelegate();
+  } else {
+    // TPMA_NV_PPREAD: Platform authorization is long gone.
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  result = trunks_utility_->ReadNVSpace(
+      index, 0 /* offset */, nvram_public.data_size, using_owner_authorization,
+      data, authorization);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error reading nvram space: " << GetErrorString(result);
-    return false;
+    return MapTpmError(result);
   }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool Tpm2NvramImpl::IsNvramDefined(uint32_t index, bool* defined) {
+NvramResult Tpm2NvramImpl::LockSpace(uint32_t index,
+                                     bool lock_read,
+                                     bool lock_write,
+                                     const std::string& authorization_value) {
+  if (!Initialize()) {
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
   trunks::TPMS_NV_PUBLIC nvram_public;
   TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
-  if (trunks::GetFormatOneError(result) == trunks::TPM_RC_HANDLE) {
-    *defined = false;
-  } else if (result == TPM_RC_SUCCESS) {
-    *defined = true;
-  } else {
-    LOG(ERROR) << "Error reading NV space for index " << index
-               << " with error: " << GetErrorString(result);
-    return false;
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error reading nvram space public area: "
+               << GetErrorString(result);
+    return MapTpmError(result);
   }
-  return true;
+  bool is_read_locked =
+      ((nvram_public.attributes & trunks::TPMA_NV_READLOCKED) != 0);
+  bool is_write_locked =
+      ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
+  if ((!lock_read || is_read_locked) && (!lock_write || is_write_locked)) {
+    // Already locked.
+    return NVRAM_RESULT_SUCCESS;
+  }
+  // Handle locking read and write separately because the authorization might be
+  // different.
+  if (lock_read && !is_read_locked) {
+    trunks::AuthorizationDelegate* authorization = nullptr;
+    std::unique_ptr<trunks::PolicySession> policy_session =
+        trunks_factory_.GetPolicySession();
+    bool using_owner_authorization = false;
+    if (nvram_public.attributes & trunks::TPMA_NV_POLICYREAD) {
+      NvramPolicyRecord policy_record;
+      if (!GetPolicyRecord(index, &policy_record)) {
+        LOG(ERROR) << "Policy record missing.";
+        return NVRAM_RESULT_INVALID_PARAMETER;
+      }
+      if (!SetupPolicySession(policy_record, authorization_value,
+                              trunks::TPM_CC_NV_ReadLock,
+                              policy_session.get())) {
+        // This will fail if policy is not met, e.g. a PCR value is not the
+        // required value.
+        return NVRAM_RESULT_ACCESS_DENIED;
+      }
+      authorization = policy_session->GetDelegate();
+    } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHREAD) {
+      trunks_session_->SetEntityAuthorizationValue(authorization_value);
+      authorization = trunks_session_->GetDelegate();
+    } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERREAD) {
+      if (!SetupOwnerSession()) {
+        // The owner password has been destroyed.
+        return NVRAM_RESULT_OPERATION_DISABLED;
+      }
+      using_owner_authorization = true;
+      authorization = trunks_session_->GetDelegate();
+    } else {
+      // TPMA_NV_PPREAD: Platform authorization is long gone.
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    }
+    result = trunks_utility_->LockNVSpace(
+        index, true /* lock_read */, false /* lock_write */,
+        using_owner_authorization, authorization);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
+      return MapTpmError(result);
+    }
+  }
+  if (lock_write && !is_write_locked) {
+    trunks::AuthorizationDelegate* authorization = nullptr;
+    std::unique_ptr<trunks::PolicySession> policy_session =
+        trunks_factory_.GetPolicySession();
+    bool using_owner_authorization = false;
+    if (nvram_public.attributes & trunks::TPMA_NV_POLICYWRITE) {
+      NvramPolicyRecord policy_record;
+      if (!GetPolicyRecord(index, &policy_record)) {
+        LOG(ERROR) << "Policy record missing.";
+        return NVRAM_RESULT_INVALID_PARAMETER;
+      }
+      if (!SetupPolicySession(policy_record, authorization_value,
+                              trunks::TPM_CC_NV_WriteLock,
+                              policy_session.get())) {
+        // This will fail if policy is not met, e.g. a PCR value is not the
+        // required value.
+        return NVRAM_RESULT_ACCESS_DENIED;
+      }
+      authorization = policy_session->GetDelegate();
+    } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHWRITE) {
+      trunks_session_->SetEntityAuthorizationValue(authorization_value);
+      authorization = trunks_session_->GetDelegate();
+    } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERWRITE) {
+      if (!SetupOwnerSession()) {
+        // The owner password has been destroyed.
+        return NVRAM_RESULT_OPERATION_DISABLED;
+      }
+      using_owner_authorization = true;
+      authorization = trunks_session_->GetDelegate();
+    } else {
+      // TPMA_NV_PPWRITE: Platform authorization is long gone.
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    }
+    result = trunks_utility_->LockNVSpace(
+        index, false /* lock_read */, true /* lock_write */,
+        using_owner_authorization, authorization);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
+      return MapTpmError(result);
+    }
+  }
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool Tpm2NvramImpl::IsNvramLocked(uint32_t index, bool* locked) {
+NvramResult Tpm2NvramImpl::ListSpaces(std::vector<uint32_t>* index_list) {
+  return MapTpmError(trunks_utility_->ListNVSpaces(index_list));
+}
+
+NvramResult Tpm2NvramImpl::GetSpaceInfo(
+    uint32_t index,
+    size_t* size,
+    bool* is_read_locked,
+    bool* is_write_locked,
+    std::vector<NvramSpaceAttribute>* attributes,
+    NvramSpacePolicy* policy) {
   trunks::TPMS_NV_PUBLIC nvram_public;
   TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error reading NV space for index " << index
                << " with error: " << GetErrorString(result);
-    return false;
-  }
-  *locked = ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
-  return true;
-}
-
-bool Tpm2NvramImpl::GetNvramSize(uint32_t index, size_t* size) {
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
-  if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error reading NV space for index " << index
-               << " with error: " << GetErrorString(result);
-    return false;
+    return MapTpmError(result);
   }
   *size = nvram_public.data_size;
+  *is_read_locked =
+      ((nvram_public.attributes & trunks::TPMA_NV_READLOCKED) != 0);
+  *is_write_locked =
+      ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
+  MapAttributesFromTpm(nvram_public.attributes, attributes);
+  *policy = NVRAM_POLICY_NONE;
+  NvramPolicyRecord policy_record;
+  if (GetPolicyRecord(index, &policy_record)) {
+    *policy = policy_record.policy();
+    if (!policy_record.world_read_allowed()) {
+      attributes->push_back(NVRAM_READ_AUTHORIZATION);
+    }
+    if (!policy_record.world_write_allowed()) {
+      attributes->push_back(NVRAM_WRITE_AUTHORIZATION);
+    }
+  }
+  return NVRAM_RESULT_SUCCESS;
+}
+
+bool Tpm2NvramImpl::Initialize() {
+  if (initialized_) {
+    return true;
+  }
+  TPM_RC result =
+      trunks_session_->StartUnboundSession(true /* enable_encryption */);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error starting a default authorization session: "
+               << GetErrorString(result);
+    return false;
+  }
+  initialized_ = true;
   return true;
 }
 
+std::string Tpm2NvramImpl::GetOwnerPassword() {
+  LocalData local_data;
+  if (local_data_store_ && local_data_store_->Read(&local_data)) {
+    return local_data.owner_password();
+  }
+  LOG(ERROR) << "TPM owner password requested but not available.";
+  return std::string();
+}
+
+bool Tpm2NvramImpl::SetupOwnerSession() {
+  std::string owner_password = GetOwnerPassword();
+  if (owner_password.empty()) {
+    LOG(ERROR) << "Owner authorization required but not available.";
+    return false;
+  }
+  trunks_session_->SetEntityAuthorizationValue(owner_password);
+  return true;
+}
+
+bool Tpm2NvramImpl::SetupPolicySession(
+    const NvramPolicyRecord& policy_record,
+    const std::string& authorization_value,
+    trunks::TPM_CC command_code,
+    trunks::PolicySession* session) {
+  TPM_RC result = session->StartUnboundSession(true /* enable_encryption */);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error starting a policy authorization session: "
+               << GetErrorString(result);
+    return false;
+  }
+  session->SetEntityAuthorizationValue(authorization_value);
+  if (!AddPoliciesForCommand(policy_record, command_code, session)) {
+    return false;
+  }
+  if (!AddPolicyOR(policy_record, session)) {
+    return false;
+  }
+  return true;
+}
+
+bool Tpm2NvramImpl::AddPoliciesForCommand(
+    const NvramPolicyRecord& policy_record,
+    trunks::TPM_CC command_code,
+    trunks::PolicySession* session) {
+  TPM_RC result = session->PolicyCommandCode(command_code);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Failed to setup command code policy.";
+    return false;
+  }
+  bool is_write_command = (command_code == trunks::TPM_CC_NV_Write ||
+                           command_code == trunks::TPM_CC_NV_WriteLock ||
+                           command_code == trunks::TPM_CC_NV_Extend);
+  bool is_read_command = !is_write_command;
+  // Check if this operation requires an authorization value.
+  if ((is_read_command && !policy_record.world_read_allowed()) ||
+      (is_write_command && !policy_record.world_write_allowed())) {
+    result = session->PolicyAuthValue();
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Failed to setup auth policy.";
+      return false;
+    }
+  }
+  if (policy_record.policy() == NVRAM_POLICY_PCR0) {
+    std::string current_pcr_value;
+    result = trunks_utility_->ReadPCR(0, &current_pcr_value);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Failed to read the current PCR value.";
+      return false;
+    }
+    result = session->PolicyPCR(0, current_pcr_value);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Failed to setup PCR policy.";
+      return false;
+    }
+  }
+  return true;
+}
+
+bool Tpm2NvramImpl::AddPolicyOR(
+    const NvramPolicyRecord& policy_record,
+    trunks::PolicySession* session) {
+  std::vector<std::string> digests;
+  for (int i = 0; i < policy_record.policy_digests_size(); ++i) {
+    digests.push_back(policy_record.policy_digests(i));
+  }
+  TPM_RC result = session->PolicyOR(digests);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Failed to setup OR policy.";
+    return false;
+  }
+  return true;
+}
+
+bool Tpm2NvramImpl::ComputePolicyDigest(NvramPolicyRecord* policy_record,
+                                        std::string* digest) {
+  // Compute a policy digest for each command then OR them all together. This
+  // approach gives flexibility to have different requirements for read and
+  // write operations, and the ability to support authorization values combined
+  // with other policies.
+  std::unique_ptr<trunks::PolicySession> trial_session;
+  for (trunks::TPM_CC command_code :
+       {trunks::TPM_CC_NV_Extend, trunks::TPM_CC_NV_Write,
+        trunks::TPM_CC_NV_WriteLock, trunks::TPM_CC_NV_Read,
+        trunks::TPM_CC_NV_ReadLock, trunks::TPM_CC_NV_Certify}) {
+    trial_session = trunks_factory_.GetTrialSession();
+    if (trial_session->StartUnboundSession(false /* enable_encryption */) !=
+        TPM_RC_SUCCESS) {
+      return false;
+    }
+    if (!AddPoliciesForCommand(*policy_record, command_code,
+                               trial_session.get())) {
+      return false;
+    }
+    if (trial_session->GetDigest(digest) != TPM_RC_SUCCESS) {
+      return false;
+    }
+    policy_record->add_policy_digests(*digest);
+  }
+  if (!AddPolicyOR(*policy_record, trial_session.get())) {
+    return false;
+  }
+  if (trial_session->GetDigest(digest) != TPM_RC_SUCCESS) {
+    return false;
+  }
+  return true;
+}
+
+bool Tpm2NvramImpl::GetPolicyRecord(uint32_t index, NvramPolicyRecord* record) {
+  LocalData local_data;
+  if (local_data_store_ && local_data_store_->Read(&local_data)) {
+    for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
+      if (local_data.nvram_policy(i).index() == index) {
+        *record = local_data.nvram_policy(i);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool Tpm2NvramImpl::SavePolicyRecord(const NvramPolicyRecord& record) {
+  LocalData local_data;
+  if (!local_data_store_ || !local_data_store_->Read(&local_data)) {
+    LOG(ERROR) << "Failed to read local data.";
+    return false;
+  }
+  LocalData new_local_data = local_data;
+  new_local_data.clear_nvram_policy();
+  for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
+    // Keep only the ones that don't match |record|.
+    if (local_data.nvram_policy(i).index() != record.index()) {
+      *new_local_data.add_nvram_policy() = local_data.nvram_policy(i);
+    }
+  }
+  *new_local_data.add_nvram_policy() = record;
+  if (!local_data_store_->Write(new_local_data)) {
+    LOG(ERROR) << "Failed to write local data.";
+    return false;
+  }
+  return true;
+}
+
+void Tpm2NvramImpl::DeletePolicyRecord(uint32_t index) {
+  LocalData local_data;
+  if (local_data_store_ && local_data_store_->Read(&local_data)) {
+    LocalData new_local_data = local_data;
+    new_local_data.clear_nvram_policy();
+    for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
+      // Keep only the ones that don't match |index|.
+      if (local_data.nvram_policy(i).index() != index) {
+        *new_local_data.add_nvram_policy() = local_data.nvram_policy(i);
+      }
+    }
+    local_data_store_->Write(new_local_data);
+  }
+}
+
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm2_nvram_impl.h b/tpm_manager/server/tpm2_nvram_impl.h
index 43b8e2b..0152539 100644
--- a/tpm_manager/server/tpm2_nvram_impl.h
+++ b/tpm_manager/server/tpm2_nvram_impl.h
@@ -23,50 +23,97 @@
 #include <string>
 
 #include <base/macros.h>
-#include <base/memory/scoped_ptr.h>
 #include <trunks/trunks_factory.h>
 
+#include "tpm_manager/common/tpm_manager.pb.h"
 #include "tpm_manager/server/local_data_store.h"
 
 namespace tpm_manager {
 
+// A TpmNvram implementation backed by a TPM 2.0 device. All index values are
+// the 'index' portion of an NV handle and must fit in 24 bits.
 class Tpm2NvramImpl : public TpmNvram {
  public:
-  // Does not take ownership of |local_data_store|.
-  explicit Tpm2NvramImpl(LocalDataStore* local_data_store);
-  // Does not take ownership of |local_data_store|, but takes ownership of
-  // |factory|.
-  Tpm2NvramImpl(std::unique_ptr<trunks::TrunksFactory> factory,
+  // Does not take ownership of arguments.
+  Tpm2NvramImpl(const trunks::TrunksFactory& factory,
                 LocalDataStore* local_data_store);
   ~Tpm2NvramImpl() override = default;
 
   // TpmNvram methods.
-  bool DefineNvram(uint32_t index, size_t length) override;
-  bool DestroyNvram(uint32_t index) override;
-  bool WriteNvram(uint32_t index, const std::string& data) override;
-  bool ReadNvram(uint32_t index, std::string* data) override;
-  bool IsNvramDefined(uint32_t index, bool* defined) override;
-  bool IsNvramLocked(uint32_t index, bool* locked) override;
-  bool GetNvramSize(uint32_t index, size_t* size) override;
+  NvramResult DefineSpace(uint32_t index,
+                          size_t size,
+                          const std::vector<NvramSpaceAttribute>& attributes,
+                          const std::string& authorization_value,
+                          NvramSpacePolicy policy) override;
+  NvramResult DestroySpace(uint32_t index) override;
+  NvramResult WriteSpace(uint32_t index,
+                         const std::string& data,
+                         const std::string& authorization_value) override;
+  NvramResult ReadSpace(uint32_t index,
+                        std::string* data,
+                        const std::string& authorization_value) override;
+  NvramResult LockSpace(uint32_t index,
+                        bool lock_read,
+                        bool lock_write,
+                        const std::string& authorization_value) override;
+  NvramResult ListSpaces(std::vector<uint32_t>* index_list) override;
+  NvramResult GetSpaceInfo(
+      uint32_t index,
+      size_t* size,
+      bool* is_read_locked,
+      bool* is_write_locked,
+      std::vector<NvramSpaceAttribute>* attributes,
+      NvramSpacePolicy* policy) override;
 
  private:
-  // Initializes the connection to the Tpm2.0 and starts an authorization
-  // session.
-  // Note: there are no guarantees about the authorization value loaded into
-  // |trunks_session_| at the end of this method.
+  // Must be called before using any data members. This may be called multiple
+  // times and will be very fast if already initialized.
   bool Initialize();
 
-  // This method initializes and ensures that a valid owner password is
-  // available. When this method returns, |owner_password_| will be loaded
-  // into |trunks_session_|.
-  bool InitializeWithOwnerPassword();
+  // Gets the TPM owner password. Returns an empty string if not available.
+  std::string GetOwnerPassword();
 
-  std::unique_ptr<trunks::TrunksFactory> trunks_factory_;
+  // Configures |trunks_session_| with owner authorization. Returns true on
+  // success.
+  bool SetupOwnerSession();
+
+  // Configures a new policy |session| for a given |policy_record|,
+  // |authorization_value|, and |command_code|. Returns true on success.
+  bool SetupPolicySession(const NvramPolicyRecord& policy_record,
+                          const std::string& authorization_value,
+                          trunks::TPM_CC command_code,
+                          trunks::PolicySession* session);
+
+  // A helper to add policies to a |session| for a particular |command_code| and
+  // |policy_record|. Returns true on success.
+  bool AddPoliciesForCommand(const NvramPolicyRecord& policy_record,
+                             trunks::TPM_CC command_code,
+                             trunks::PolicySession* session);
+
+  // A helper to add an OR policy to |session| based on |policy_record|. Returns
+  // true on success.
+  bool AddPolicyOR(const NvramPolicyRecord& policy_record,
+                   trunks::PolicySession* session);
+
+  // Computes the policy |digest| for a given |policy_record| and fills the
+  // policy_digests field in the |policy_record|.
+  bool ComputePolicyDigest(NvramPolicyRecord* policy_record,
+                           std::string* digest);
+
+  // Gets the policy |record| for the given |index|. Returns true on success.
+  bool GetPolicyRecord(uint32_t index, NvramPolicyRecord* record);
+
+  // Saves a policy |record| in the local_data_store_.
+  bool SavePolicyRecord(const NvramPolicyRecord& record);
+
+  // Best effort delete of the policy |record| for |index|.
+  void DeletePolicyRecord(uint32_t index);
+
+  const trunks::TrunksFactory& trunks_factory_;
   LocalDataStore* local_data_store_;
   bool initialized_;
-  std::string owner_password_;
-  scoped_ptr<trunks::HmacSession> trunks_session_;
-  scoped_ptr<trunks::TpmUtility> trunks_utility_;
+  std::unique_ptr<trunks::HmacSession> trunks_session_;
+  std::unique_ptr<trunks::TpmUtility> trunks_utility_;
 
   friend class Tpm2NvramTest;
   DISALLOW_COPY_AND_ASSIGN(Tpm2NvramImpl);
diff --git a/tpm_manager/server/tpm2_nvram_test.cc b/tpm_manager/server/tpm2_nvram_test.cc
index 8dc284b..b1440b3 100644
--- a/tpm_manager/server/tpm2_nvram_test.cc
+++ b/tpm_manager/server/tpm2_nvram_test.cc
@@ -19,6 +19,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <trunks/mock_hmac_session.h>
+#include <trunks/mock_policy_session.h>
 #include <trunks/mock_tpm_utility.h>
 #include <trunks/tpm_constants.h>
 #include <trunks/trunks_factory_for_test.h>
@@ -26,12 +27,24 @@
 #include "tpm_manager/server/mock_local_data_store.h"
 
 namespace {
-const char kTestOwnerPassword[] = "owner";
+
+constexpr char kTestOwnerPassword[] = "owner";
+constexpr char kFakePolicyDigest[] = "fake_policy_digest";
+constexpr char kFakePCRValue[] = "fake_pcr_value";
+constexpr char kFakeAuthorizationValue[] = "fake_authorization";
+trunks::AuthorizationDelegate* const kHMACAuth =
+    reinterpret_cast<trunks::AuthorizationDelegate*>(1ull);
+trunks::AuthorizationDelegate* const kPolicyAuth =
+    reinterpret_cast<trunks::AuthorizationDelegate*>(2ull);
+constexpr trunks::TPMA_NV kNoExtraAttributes = 0;
+
 }  // namespace
 
 namespace tpm_manager {
 
 using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
 using testing::DoAll;
 using testing::Mock;
 using testing::NiceMock;
@@ -39,6 +52,7 @@
 using testing::SetArgPointee;
 using trunks::TPM_RC_SUCCESS;
 using trunks::TPM_RC_FAILURE;
+using trunks::TPM_RC_HANDLE;
 
 class Tpm2NvramTest : public testing::Test {
  public:
@@ -46,218 +60,521 @@
   virtual ~Tpm2NvramTest() = default;
 
   void SetUp() {
-    trunks::TrunksFactoryForTest* factory = new trunks::TrunksFactoryForTest();
-    factory->set_hmac_session(&mock_hmac_session_);
-    factory->set_tpm_utility(&mock_tpm_utility_);
-    tpm_nvram_.reset(new Tpm2NvramImpl(
-        std::unique_ptr<trunks::TrunksFactory>(factory), &mock_data_store_));
+    factory_.set_hmac_session(&mock_hmac_session_);
+    factory_.set_policy_session(&mock_policy_session_);
+    factory_.set_trial_session(&mock_trial_session_);
+    factory_.set_tpm_utility(&mock_tpm_utility_);
+    tpm_nvram_.reset(new Tpm2NvramImpl(factory_, &mock_data_store_));
+    ON_CALL(mock_hmac_session_, GetDelegate()).WillByDefault(Return(kHMACAuth));
+    ON_CALL(mock_policy_session_, GetDelegate())
+        .WillByDefault(Return(kPolicyAuth));
+    ON_CALL(mock_policy_session_, GetDigest(_))
+        .WillByDefault(
+            DoAll(SetArgPointee<0>(kFakePolicyDigest), Return(TPM_RC_SUCCESS)));
+    ON_CALL(mock_trial_session_, GetDigest(_))
+        .WillByDefault(
+            DoAll(SetArgPointee<0>(kFakePolicyDigest), Return(TPM_RC_SUCCESS)));
   }
 
-  void InitializeNvram(const std::string& owner_password) {
-    LocalData local_data;
-    local_data.set_owner_password(owner_password);
-    ON_CALL(mock_data_store_, Read(_))
-        .WillByDefault(DoAll(SetArgPointee<0>(local_data), Return(true)));
-    tpm_nvram_->Initialize();
-    Mock::VerifyAndClearExpectations(&mock_data_store_);
-    Mock::VerifyAndClearExpectations(&mock_hmac_session_);
-    Mock::VerifyAndClearExpectations(&mock_tpm_utility_);
+  void SetupOwnerPassword() {
+    LocalData& local_data = mock_data_store_.GetMutableFakeData();
+    local_data.set_owner_password(kTestOwnerPassword);
+  }
+
+  enum ExpectAuth { NO_EXPECT_AUTH, EXPECT_AUTH };
+  enum AuthType { NORMAL_AUTH, POLICY_AUTH, OWNER_AUTH };
+  void SetupExistingSpace(uint32_t index,
+                          uint32_t size,
+                          trunks::TPMA_NV extra_attributes,
+                          ExpectAuth expect_auth,
+                          AuthType auth_type) {
+    trunks::TPMS_NV_PUBLIC public_data;
+    public_data.nv_index = index;
+    public_data.data_size = size;
+    public_data.attributes = trunks::TPMA_NV_READ_STCLEAR |
+                             trunks::TPMA_NV_WRITE_STCLEAR | extra_attributes;
+    switch (auth_type) {
+      case NORMAL_AUTH:
+        public_data.attributes |=
+            trunks::TPMA_NV_AUTHREAD | trunks::TPMA_NV_AUTHWRITE;
+        break;
+      case POLICY_AUTH:
+        public_data.attributes |=
+            trunks::TPMA_NV_POLICYREAD | trunks::TPMA_NV_POLICYWRITE;
+        break;
+      case OWNER_AUTH:
+        public_data.attributes |=
+            trunks::TPMA_NV_OWNERREAD | trunks::TPMA_NV_OWNERWRITE;
+        break;
+    }
+    ON_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
+        .WillByDefault(
+            DoAll(SetArgPointee<1>(public_data), Return(TPM_RC_SUCCESS)));
+    LocalData& local_data = mock_data_store_.GetMutableFakeData();
+    NvramPolicyRecord& policy_record = *local_data.add_nvram_policy();
+    policy_record.set_index(index);
+    if (auth_type == POLICY_AUTH) {
+      policy_record.set_policy(NVRAM_POLICY_PCR0);
+    }
+    if (!expect_auth) {
+      EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue(_)).Times(0);
+      EXPECT_CALL(mock_policy_session_, SetEntityAuthorizationValue(_))
+          .Times(0);
+      EXPECT_CALL(mock_policy_session_, PolicyAuthValue()).Times(0);
+    } else if (auth_type == NORMAL_AUTH) {
+      EXPECT_CALL(mock_hmac_session_,
+                  SetEntityAuthorizationValue(kFakeAuthorizationValue))
+          .Times(AtLeast(1));
+      EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue("")).Times(0);
+    } else if (auth_type == OWNER_AUTH) {
+      EXPECT_CALL(mock_hmac_session_,
+                  SetEntityAuthorizationValue(kTestOwnerPassword))
+          .Times(AtLeast(1));
+      EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue("")).Times(0);
+    } else {
+      EXPECT_CALL(mock_policy_session_,
+                  SetEntityAuthorizationValue(kFakeAuthorizationValue))
+          .Times(AtLeast(1));
+      EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue("")).Times(0);
+      EXPECT_CALL(mock_tpm_utility_, ReadPCR(0, _))
+          .Times(AtLeast(1))
+          .WillRepeatedly(
+              DoAll(SetArgPointee<1>(kFakePCRValue), Return(TPM_RC_SUCCESS)));
+      EXPECT_CALL(mock_policy_session_, PolicyAuthValue()).Times(AtLeast(1));
+      EXPECT_CALL(mock_policy_session_, PolicyPCR(0, kFakePCRValue))
+          .Times(AtLeast(1));
+    }
   }
 
  protected:
+  trunks::TrunksFactoryForTest factory_;
   NiceMock<trunks::MockHmacSession> mock_hmac_session_;
+  NiceMock<trunks::MockPolicySession> mock_policy_session_;
+  NiceMock<trunks::MockPolicySession> mock_trial_session_;
   NiceMock<MockLocalDataStore> mock_data_store_;
   NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
   std::unique_ptr<Tpm2NvramImpl> tpm_nvram_;
 };
 
-TEST_F(Tpm2NvramTest, NvramNoOwnerFailure) {
-  uint32_t index = 42;
-  EXPECT_FALSE(tpm_nvram_->DefineNvram(index, 5));
-  EXPECT_FALSE(tpm_nvram_->DestroyNvram(index));
-  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
+TEST_F(Tpm2NvramTest, NoOwnerFailure) {
+  EXPECT_EQ(NVRAM_RESULT_OPERATION_DISABLED,
+            tpm_nvram_->DefineSpace(0, 0, {}, "", NVRAM_POLICY_NONE));
+  EXPECT_EQ(NVRAM_RESULT_OPERATION_DISABLED, tpm_nvram_->DestroySpace(0));
 }
 
-TEST_F(Tpm2NvramTest, DefineNvramSuccess) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, SessionFailure) {
+  EXPECT_CALL(mock_hmac_session_, StartUnboundSession(_))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->DefineSpace(0, 0, {}, "", NVRAM_POLICY_NONE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->DestroySpace(0));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->WriteSpace(0, "", ""));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->ReadSpace(0, nullptr, ""));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->LockSpace(0, false, false, ""));
+}
+
+TEST_F(Tpm2NvramTest, DefineSpaceSuccess) {
+  SetupOwnerPassword();
   EXPECT_CALL(mock_hmac_session_,
-              SetEntityAuthorizationValue(kTestOwnerPassword));
+              SetEntityAuthorizationValue(kTestOwnerPassword))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_trial_session_, PolicyAuthValue()).Times(0);
+  EXPECT_CALL(mock_trial_session_, PolicyPCR(_, _)).Times(0);
   uint32_t index = 42;
-  size_t length = 20;
-  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(index, length, _))
+  size_t size = 20;
+  std::vector<NvramSpaceAttribute> attributes{NVRAM_PERSISTENT_WRITE_LOCK};
+  EXPECT_CALL(
+      mock_tpm_utility_,
+      DefineNVSpace(index, size,
+                    trunks::TPMA_NV_WRITEDEFINE | trunks::TPMA_NV_POLICYWRITE |
+                        trunks::TPMA_NV_POLICYREAD,
+                    kFakeAuthorizationValue, kFakePolicyDigest, kHMACAuth))
       .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_TRUE(tpm_nvram_->DefineNvram(index, length));
+  EXPECT_EQ(
+      NVRAM_RESULT_SUCCESS,
+      tpm_nvram_->DefineSpace(index, size, attributes, kFakeAuthorizationValue,
+                              NVRAM_POLICY_NONE));
+  const LocalData& local_data = mock_data_store_.GetFakeData();
+  EXPECT_EQ(1, local_data.nvram_policy_size());
+  EXPECT_EQ(index, local_data.nvram_policy(0).index());
+  EXPECT_EQ(NVRAM_POLICY_NONE, local_data.nvram_policy(0).policy());
 }
 
-TEST_F(Tpm2NvramTest, DefineNvramFailure) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, DefineSpaceFailure) {
+  SetupOwnerPassword();
   uint32_t index = 42;
-  size_t length = 20;
-  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(index, length, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_FALSE(tpm_nvram_->DefineNvram(index, length));
+  size_t size = 20;
+  std::vector<NvramSpaceAttribute> attributes{NVRAM_PERSISTENT_WRITE_LOCK};
+  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(_, _, _, _, _, _))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(
+      NVRAM_RESULT_SUCCESS,
+      tpm_nvram_->DefineSpace(index, size, attributes, "", NVRAM_POLICY_NONE));
 }
 
-TEST_F(Tpm2NvramTest, DestroyNvramSuccess) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, DefineSpaceNoClobberOnError) {
+  SetupOwnerPassword();
+  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(_, _, _, _, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->DefineSpace(0, 32, {}, "", NVRAM_POLICY_NONE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->DefineSpace(0, 32, {}, "", NVRAM_POLICY_PCR0));
+  const LocalData& local_data = mock_data_store_.GetFakeData();
+  EXPECT_EQ(1, local_data.nvram_policy_size());
+  EXPECT_EQ(0, local_data.nvram_policy(0).index());
+  EXPECT_EQ(NVRAM_POLICY_NONE, local_data.nvram_policy(0).policy());
+}
+
+TEST_F(Tpm2NvramTest, DefineSpaceWithPolicy) {
+  SetupOwnerPassword();
   EXPECT_CALL(mock_hmac_session_,
-              SetEntityAuthorizationValue(kTestOwnerPassword));
+              SetEntityAuthorizationValue(kTestOwnerPassword))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_trial_session_, PolicyAuthValue()).Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, ReadPCR(0, _))
+      .WillRepeatedly(
+          DoAll(SetArgPointee<1>(kFakePCRValue), Return(TPM_RC_SUCCESS)));
+  EXPECT_CALL(mock_trial_session_, PolicyPCR(0, kFakePCRValue))
+      .Times(AtLeast(1));
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, _))
+  size_t size = 20;
+  std::vector<NvramSpaceAttribute> attributes{NVRAM_WRITE_AUTHORIZATION};
+  EXPECT_CALL(
+      mock_tpm_utility_,
+      DefineNVSpace(index, size,
+                    trunks::TPMA_NV_POLICYWRITE | trunks::TPMA_NV_POLICYREAD,
+                    kFakeAuthorizationValue, kFakePolicyDigest, kHMACAuth))
       .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_TRUE(tpm_nvram_->DestroyNvram(index));
+  EXPECT_EQ(
+      NVRAM_RESULT_SUCCESS,
+      tpm_nvram_->DefineSpace(index, size, attributes, kFakeAuthorizationValue,
+                              NVRAM_POLICY_PCR0));
 }
 
-TEST_F(Tpm2NvramTest, DestroyNvramFailure) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, DefineSpaceWithExistingLocalData) {
+  SetupOwnerPassword();
+  LocalData& local_data = mock_data_store_.GetMutableFakeData();
+  local_data.add_nvram_policy()->set_index(0);
+  local_data.add_nvram_policy()->set_index(4);
+  local_data.add_nvram_policy()->set_index(1);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->DefineSpace(5, 32, {}, "", NVRAM_POLICY_NONE));
+  EXPECT_EQ(4, local_data.nvram_policy_size());
+  EXPECT_EQ(5, local_data.nvram_policy(3).index());
+}
+
+TEST_F(Tpm2NvramTest, DefineSpaceClobberExistingLocalData) {
+  SetupOwnerPassword();
+  LocalData& local_data = mock_data_store_.GetMutableFakeData();
+  local_data.add_nvram_policy()->set_index(0);
+  local_data.add_nvram_policy()->set_index(4);
+  local_data.add_nvram_policy()->set_index(1);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->DefineSpace(4, 32, {}, "", NVRAM_POLICY_NONE));
+  EXPECT_EQ(3, local_data.nvram_policy_size());
+  EXPECT_NE(local_data.nvram_policy(0).index(),
+            local_data.nvram_policy(1).index());
+  EXPECT_NE(local_data.nvram_policy(0).index(),
+            local_data.nvram_policy(2).index());
+  EXPECT_NE(local_data.nvram_policy(1).index(),
+            local_data.nvram_policy(2).index());
+}
+
+TEST_F(Tpm2NvramTest, DestroySpaceSuccess) {
+  SetupOwnerPassword();
+  LocalData& local_data = mock_data_store_.GetMutableFakeData();
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_FALSE(tpm_nvram_->DestroyNvram(index));
-}
-
-TEST_F(Tpm2NvramTest, WriteNvramSuccess) {
-  InitializeNvram(kTestOwnerPassword);
+  local_data.add_nvram_policy()->set_index(index);
   EXPECT_CALL(mock_hmac_session_,
-              SetEntityAuthorizationValue(kTestOwnerPassword));
+              SetEntityAuthorizationValue(kTestOwnerPassword))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, kHMACAuth))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, tpm_nvram_->DestroySpace(index));
+  EXPECT_EQ(0, local_data.nvram_policy_size());
+}
+
+TEST_F(Tpm2NvramTest, DestroySpaceFailure) {
+  SetupOwnerPassword();
   uint32_t index = 42;
+  LocalData& local_data = mock_data_store_.GetMutableFakeData();
+  local_data.add_nvram_policy()->set_index(index);
+  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, _))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->DestroySpace(index));
+  EXPECT_EQ(1, local_data.nvram_policy_size());
+}
+
+TEST_F(Tpm2NvramTest, DestroySpaceWithExistingLocalData) {
+  SetupOwnerPassword();
+  LocalData& local_data = mock_data_store_.GetMutableFakeData();
+  local_data.add_nvram_policy()->set_index(0);
+  local_data.add_nvram_policy()->set_index(1);
+  local_data.add_nvram_policy()->set_index(2);
+  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(1, kHMACAuth))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, tpm_nvram_->DestroySpace(1));
+  EXPECT_EQ(2, local_data.nvram_policy_size());
+  EXPECT_NE(1, local_data.nvram_policy(0).index());
+  EXPECT_NE(1, local_data.nvram_policy(1).index());
+}
+
+TEST_F(Tpm2NvramTest, WriteSpaceSuccess) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 20, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
   std::string data("data");
-  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, 0, data, _))
+  EXPECT_CALL(mock_tpm_utility_,
+              WriteNVSpace(index, 0, data, false, false, kHMACAuth))
       .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue(""));
-  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _))
-      .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_TRUE(tpm_nvram_->WriteNvram(index, data));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->WriteSpace(index, data, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, WriteNvramLockError) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, WriteSpaceExtend) {
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, _, _, _))
+  SetupExistingSpace(index, 20, trunks::TPMA_NV_EXTEND, EXPECT_AUTH,
+                     NORMAL_AUTH);
+  std::string data("data");
+  EXPECT_CALL(mock_tpm_utility_,
+              WriteNVSpace(index, 0, data, false, true, kHMACAuth))
       .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->WriteSpace(index, data, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, WriteNvramFailure) {
-  InitializeNvram(kTestOwnerPassword);
+TEST_F(Tpm2NvramTest, WriteSpaceNonexistant) {
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, _, _, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
-}
-
-TEST_F(Tpm2NvramTest, ReadNvramSuccess) {
-  uint32_t index = 42;
-  std::string tpm_data("data");
-  size_t size = tpm_data.size();
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  nvram_public.data_size = size;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(_, _))
-      .WillOnce(DoAll(SetArgPointee<1>(nvram_public), Return(TPM_RC_SUCCESS)));
-
-  EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue(""));
-  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, 0, size, _, _))
-      .WillOnce(DoAll(SetArgPointee<3>(tpm_data), Return(TPM_RC_SUCCESS)));
+  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
+      .WillRepeatedly(Return(TPM_RC_HANDLE));
   std::string read_data;
-  EXPECT_TRUE(tpm_nvram_->ReadNvram(index, &read_data));
+  EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST,
+            tpm_nvram_->WriteSpace(index, "data", kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, WriteSpaceFailure) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 20, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, _, _, _, _, _))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->WriteSpace(index, "data", kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, WriteSpacePolicy) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 20, kNoExtraAttributes, EXPECT_AUTH, POLICY_AUTH);
+  std::string data("data");
+  EXPECT_CALL(mock_tpm_utility_,
+              WriteNVSpace(index, 0, data, false, false, kPolicyAuth))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->WriteSpace(index, data, kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, WriteSpaceOwner) {
+  uint32_t index = 42;
+  SetupOwnerPassword();
+  SetupExistingSpace(index, 20, kNoExtraAttributes, EXPECT_AUTH, OWNER_AUTH);
+  std::string data("data");
+  EXPECT_CALL(mock_tpm_utility_,
+              WriteNVSpace(index, 0, data, true, false, kHMACAuth))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->WriteSpace(index, data, kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, ReadSpaceSuccess) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 32, trunks::TPMA_NV_WRITTEN, EXPECT_AUTH,
+                     NORMAL_AUTH);
+  std::string tpm_data("data");
+  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, 0, 32, false, _, kHMACAuth))
+      .WillOnce(DoAll(SetArgPointee<4>(tpm_data), Return(TPM_RC_SUCCESS)));
+  std::string read_data;
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->ReadSpace(index, &read_data, kFakeAuthorizationValue));
   EXPECT_EQ(read_data, tpm_data);
 }
 
-TEST_F(Tpm2NvramTest, ReadNvramNonexistant) {
+TEST_F(Tpm2NvramTest, ReadSpaceNonexistant) {
   uint32_t index = 42;
   EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
+      .WillRepeatedly(Return(TPM_RC_HANDLE));
   std::string read_data;
-  EXPECT_FALSE(tpm_nvram_->ReadNvram(index, &read_data));
+  EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST,
+            tpm_nvram_->ReadSpace(index, &read_data, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, ReadNvramFailure) {
+TEST_F(Tpm2NvramTest, ReadSpaceFailure) {
   uint32_t index = 42;
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(DoAll(SetArgPointee<1>(nvram_public), Return(TPM_RC_SUCCESS)));
-  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, _, _, _, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
+  SetupExistingSpace(index, 32, trunks::TPMA_NV_WRITTEN, EXPECT_AUTH,
+                     NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, _, _, _, _, _))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
   std::string read_data;
-  EXPECT_FALSE(tpm_nvram_->ReadNvram(index, &read_data));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->ReadSpace(index, &read_data, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, IsNvramDefinedSuccess) {
+TEST_F(Tpm2NvramTest, ReadSpacePolicy) {
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(Return(TPM_RC_SUCCESS));
-  bool defined;
-  EXPECT_TRUE(tpm_nvram_->IsNvramDefined(index, &defined));
-  EXPECT_TRUE(defined);
+  SetupExistingSpace(index, 32, trunks::TPMA_NV_WRITTEN, EXPECT_AUTH,
+                     POLICY_AUTH);
+  std::string tpm_data("data");
+  EXPECT_CALL(mock_tpm_utility_,
+              ReadNVSpace(index, 0, 32, false, _, kPolicyAuth))
+      .WillOnce(DoAll(SetArgPointee<4>(tpm_data), Return(TPM_RC_SUCCESS)));
+  std::string read_data;
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->ReadSpace(index, &read_data, kFakeAuthorizationValue));
+  EXPECT_EQ(read_data, tpm_data);
 }
 
-TEST_F(Tpm2NvramTest, IsNvramDefinedNonexistant) {
+TEST_F(Tpm2NvramTest, ReadSpaceOwner) {
+  uint32_t index = 42;
+  SetupOwnerPassword();
+  SetupExistingSpace(index, 32, trunks::TPMA_NV_WRITTEN, EXPECT_AUTH,
+                     OWNER_AUTH);
+  std::string tpm_data("data");
+  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, 0, 32, true, _, kHMACAuth))
+      .WillOnce(DoAll(SetArgPointee<4>(tpm_data), Return(TPM_RC_SUCCESS)));
+  std::string read_data;
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->ReadSpace(index, &read_data, kFakeAuthorizationValue));
+  EXPECT_EQ(read_data, tpm_data);
+}
+
+TEST_F(Tpm2NvramTest, LockSpaceSuccess) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, true, _, false, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _, true, false, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, true, true, kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, LockSpaceNonexistant) {
   uint32_t index = 42;
   EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
       .WillOnce(Return(trunks::TPM_RC_HANDLE));
-  bool defined;
-  EXPECT_TRUE(tpm_nvram_->IsNvramDefined(index, &defined));
-  EXPECT_FALSE(defined);
+  EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST,
+            tpm_nvram_->LockSpace(index, true, true, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, IsNvramDefinedFailure) {
+TEST_F(Tpm2NvramTest, LockSpaceFailure) {
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  bool defined;
-  EXPECT_FALSE(tpm_nvram_->IsNvramDefined(index, &defined));
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(_, _, _, _, _))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, true, true, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, IsNvramLockedSuccess) {
+TEST_F(Tpm2NvramTest, LockSpacePolicy) {
   uint32_t index = 42;
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  nvram_public.attributes = trunks::TPMA_NV_WRITELOCKED;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(DoAll(SetArgPointee<1>(nvram_public), Return(TPM_RC_SUCCESS)));
-  bool locked;
-  EXPECT_TRUE(tpm_nvram_->IsNvramLocked(index, &locked));
-  EXPECT_TRUE(locked);
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, POLICY_AUTH);
+  EXPECT_CALL(mock_tpm_utility_,
+              LockNVSpace(index, true, _, false, kPolicyAuth))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_,
+              LockNVSpace(index, _, true, false, kPolicyAuth))
+      .Times(AtLeast(1));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, true, true, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, IsNvramLockedUnlocked) {
+TEST_F(Tpm2NvramTest, LockSpaceOwner) {
   uint32_t index = 42;
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  nvram_public.attributes = 0;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(DoAll(SetArgPointee<1>(nvram_public), Return(TPM_RC_SUCCESS)));
-  bool locked;
-  EXPECT_TRUE(tpm_nvram_->IsNvramLocked(index, &locked));
-  EXPECT_FALSE(locked);
+  SetupOwnerPassword();
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, OWNER_AUTH);
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, true, _, true, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _, true, true, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, true, true, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, IsNvramLockedFailure) {
+TEST_F(Tpm2NvramTest, LockSpaceRead) {
   uint32_t index = 42;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(Return(TPM_RC_FAILURE));
-  bool locked;
-  EXPECT_FALSE(tpm_nvram_->IsNvramLocked(index, &locked));
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_,
+              LockNVSpace(index, true, false, false, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _, true, false, kHMACAuth))
+      .Times(0);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, true, false, kFakeAuthorizationValue));
 }
 
-TEST_F(Tpm2NvramTest, GetNvramSizeSuccess) {
+TEST_F(Tpm2NvramTest, LockSpaceWrite) {
   uint32_t index = 42;
-  size_t nvram_size = 20;
-  trunks::TPMS_NV_PUBLIC nvram_public;
-  nvram_public.data_size = nvram_size;
-  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
-      .WillOnce(DoAll(SetArgPointee<1>(nvram_public), Return(TPM_RC_SUCCESS)));
+  SetupExistingSpace(index, 32, kNoExtraAttributes, EXPECT_AUTH, NORMAL_AUTH);
+  EXPECT_CALL(mock_tpm_utility_,
+              LockNVSpace(index, false, true, false, kHMACAuth))
+      .Times(AtLeast(1));
+  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, true, _, false, kHMACAuth))
+      .Times(0);
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->LockSpace(index, false, true, kFakeAuthorizationValue));
+}
+
+TEST_F(Tpm2NvramTest, ListSpacesSuccess) {
+  std::vector<uint32_t> expected_spaces{1, 5, 42};
+  std::vector<uint32_t> spaces;
+  EXPECT_CALL(mock_tpm_utility_, ListNVSpaces(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(
+          DoAll(SetArgPointee<0>(expected_spaces), Return(TPM_RC_SUCCESS)));
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS, tpm_nvram_->ListSpaces(&spaces));
+  EXPECT_EQ(spaces, expected_spaces);
+}
+
+TEST_F(Tpm2NvramTest, ListSpacesFailure) {
+  std::vector<uint32_t> spaces;
+  EXPECT_CALL(mock_tpm_utility_, ListNVSpaces(_))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_NE(NVRAM_RESULT_SUCCESS, tpm_nvram_->ListSpaces(&spaces));
+}
+
+TEST_F(Tpm2NvramTest, GetSpaceInfoSuccess) {
+  uint32_t index = 42;
+  SetupExistingSpace(index, 100,
+                     trunks::TPMA_NV_READLOCKED | trunks::TPMA_NV_WRITELOCKED,
+                     NO_EXPECT_AUTH, POLICY_AUTH);
   size_t size;
-  EXPECT_TRUE(tpm_nvram_->GetNvramSize(index, &size));
-  EXPECT_EQ(size, nvram_size);
+  bool is_read_locked;
+  bool is_write_locked;
+  std::vector<NvramSpaceAttribute> attributes;
+  NvramSpacePolicy policy;
+  EXPECT_EQ(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->GetSpaceInfo(index, &size, &is_write_locked,
+                                     &is_read_locked, &attributes, &policy));
+  EXPECT_EQ(size, 100);
+  EXPECT_TRUE(is_read_locked);
+  EXPECT_TRUE(is_write_locked);
+  EXPECT_GE(attributes.size(), 1);
+  EXPECT_EQ(1, std::count(attributes.begin(), attributes.end(),
+                          NVRAM_WRITE_AUTHORIZATION));
+  EXPECT_EQ(NVRAM_POLICY_PCR0, policy);
 }
 
-TEST_F(Tpm2NvramTest, GetNvramSizeFailure) {
+TEST_F(Tpm2NvramTest, GetSpaceInfoFailure) {
   uint32_t index = 42;
   EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
       .WillOnce(Return(TPM_RC_FAILURE));
   size_t size;
-  EXPECT_FALSE(tpm_nvram_->GetNvramSize(index, &size));
+  bool is_read_locked;
+  bool is_write_locked;
+  std::vector<NvramSpaceAttribute> attributes;
+  NvramSpacePolicy policy;
+  EXPECT_NE(NVRAM_RESULT_SUCCESS,
+            tpm_nvram_->GetSpaceInfo(index, &size, &is_write_locked,
+                                     &is_read_locked, &attributes, &policy));
 }
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm2_status_impl.cc b/tpm_manager/server/tpm2_status_impl.cc
index 70c8e1f..9cd0a00 100644
--- a/tpm_manager/server/tpm2_status_impl.cc
+++ b/tpm_manager/server/tpm2_status_impl.cc
@@ -26,14 +26,9 @@
 
 namespace tpm_manager {
 
-Tpm2StatusImpl::Tpm2StatusImpl()
-    : default_trunks_factory_(new trunks::TrunksFactoryImpl()),
-      trunks_factory_(default_trunks_factory_.get()),
-      trunks_tpm_state_(trunks_factory_->GetTpmState()) {}
-
-Tpm2StatusImpl::Tpm2StatusImpl(trunks::TrunksFactory* factory)
+Tpm2StatusImpl::Tpm2StatusImpl(const trunks::TrunksFactory& factory)
     : trunks_factory_(factory),
-      trunks_tpm_state_(trunks_factory_->GetTpmState()) {}
+      trunks_tpm_state_(trunks_factory_.GetTpmState()) {}
 
 bool Tpm2StatusImpl::IsTpmEnabled() {
   if (!initialized_) {
diff --git a/tpm_manager/server/tpm2_status_impl.h b/tpm_manager/server/tpm2_status_impl.h
index a6b918a..6fe4218 100644
--- a/tpm_manager/server/tpm2_status_impl.h
+++ b/tpm_manager/server/tpm2_status_impl.h
@@ -29,9 +29,8 @@
 
 class Tpm2StatusImpl : public TpmStatus {
  public:
-  Tpm2StatusImpl();
   // Does not take ownership of |factory|.
-  explicit Tpm2StatusImpl(trunks::TrunksFactory* factory);
+  explicit Tpm2StatusImpl(const trunks::TrunksFactory& factory);
   ~Tpm2StatusImpl() override = default;
 
   // TpmState methods.
@@ -50,9 +49,8 @@
 
   bool initialized_{false};
   bool is_owned_{false};
-  std::unique_ptr<trunks::TrunksFactory> default_trunks_factory_;
-  trunks::TrunksFactory* trunks_factory_;
-  scoped_ptr<trunks::TpmState> trunks_tpm_state_;
+  const trunks::TrunksFactory& trunks_factory_;
+  std::unique_ptr<trunks::TpmState> trunks_tpm_state_;
 
   DISALLOW_COPY_AND_ASSIGN(Tpm2StatusImpl);
 };
diff --git a/tpm_manager/server/tpm2_status_test.cc b/tpm_manager/server/tpm2_status_test.cc
index d758649..813b80d 100644
--- a/tpm_manager/server/tpm2_status_test.cc
+++ b/tpm_manager/server/tpm2_status_test.cc
@@ -32,17 +32,17 @@
 
 class Tpm2StatusTest : public testing::Test {
  public:
-  Tpm2StatusTest() : factory_(new trunks::TrunksFactoryForTest()) {}
+  Tpm2StatusTest() = default;
   virtual ~Tpm2StatusTest() = default;
 
   void SetUp() {
-    factory_->set_tpm_state(&mock_tpm_state_);
-    tpm_status_.reset(new Tpm2StatusImpl(factory_.get()));
+    factory_.set_tpm_state(&mock_tpm_state_);
+    tpm_status_.reset(new Tpm2StatusImpl(factory_));
   }
 
  protected:
   NiceMock<trunks::MockTpmState> mock_tpm_state_;
-  std::unique_ptr<trunks::TrunksFactoryForTest> factory_;
+  trunks::TrunksFactoryForTest factory_;
   std::unique_ptr<TpmStatus> tpm_status_;
 };
 
diff --git a/tpm_manager/server/tpm_connection.cc b/tpm_manager/server/tpm_connection.cc
index 9ed8d86..7ef14e8 100644
--- a/tpm_manager/server/tpm_connection.cc
+++ b/tpm_manager/server/tpm_connection.cc
@@ -34,6 +34,9 @@
 
 namespace tpm_manager {
 
+TpmConnection::TpmConnection(const std::string& authorization_value)
+    : authorization_value_(authorization_value) {}
+
 TSS_HCONTEXT TpmConnection::GetContext() {
   if (!ConnectContextIfNeeded()) {
     return 0;
@@ -55,29 +58,6 @@
   return tpm_handle;
 }
 
-TSS_HTPM TpmConnection::GetTpmWithAuth(const std::string& owner_password) {
-  TSS_HTPM tpm_handle = GetTpm();
-  if (tpm_handle == 0) {
-    return 0;
-  }
-  TSS_RESULT result;
-  TSS_HPOLICY tpm_usage_policy;
-  if (TPM_ERROR(result = Tspi_GetPolicyObject(tpm_handle, TSS_POLICY_USAGE,
-                                              &tpm_usage_policy))) {
-    TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject";
-    return false;
-  }
-  if (TPM_ERROR(result = Tspi_Policy_SetSecret(
-                    tpm_usage_policy, TSS_SECRET_MODE_PLAIN,
-                    owner_password.size(),
-                    reinterpret_cast<BYTE*>(
-                        const_cast<char*>(owner_password.data()))))) {
-    TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
-    return false;
-  }
-  return tpm_handle;
-}
-
 bool TpmConnection::ConnectContextIfNeeded() {
   if (context_.value() != 0) {
     return true;
@@ -101,7 +81,39 @@
       break;
     }
   }
-  return (context_.value() != 0);
+  if (context_.value() == 0) {
+    LOG(ERROR) << "Unexpected NULL context.";
+    return false;
+  }
+  // If we don't need to set an authorization value, we're done.
+  if (authorization_value_.empty()) {
+    return true;
+  }
+
+  TSS_HTPM tpm_handle;
+  if (TPM_ERROR(result =
+                    Tspi_Context_GetTpmObject(context_.value(), &tpm_handle))) {
+    TPM_LOG(ERROR, result) << "Error getting a handle to the TPM.";
+    context_.reset();
+    return false;
+  }
+  TSS_HPOLICY tpm_usage_policy;
+  if (TPM_ERROR(result = Tspi_GetPolicyObject(tpm_handle, TSS_POLICY_USAGE,
+                                              &tpm_usage_policy))) {
+    TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject";
+    context_.reset();
+    return false;
+  }
+  if (TPM_ERROR(result = Tspi_Policy_SetSecret(
+                    tpm_usage_policy, TSS_SECRET_MODE_PLAIN,
+                    authorization_value_.size(),
+                    reinterpret_cast<BYTE*>(
+                        const_cast<char*>(authorization_value_.data()))))) {
+    TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
+    context_.reset();
+    return false;
+  }
+  return true;
 }
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_connection.h b/tpm_manager/server/tpm_connection.h
index 66c00e3..80486fe 100644
--- a/tpm_manager/server/tpm_connection.h
+++ b/tpm_manager/server/tpm_connection.h
@@ -27,6 +27,9 @@
 class TpmConnection {
  public:
   TpmConnection() = default;
+  // Create a TPM connection and set an |authorization_value| for the TPM object
+  // (e.g. the TPM owner password).
+  explicit TpmConnection(const std::string& authorization_value);
   ~TpmConnection() = default;
 
   // This method returns a handle to the current Tpm context.
@@ -37,15 +40,12 @@
   // This method tries to get a handle to the TPM. Returns 0 on failure.
   TSS_HTPM GetTpm();
 
-  // This method tries to get a handle to the TPM and with the given owner
-  // password. Returns 0 on failure.
-  TSS_HTPM GetTpmWithAuth(const std::string& owner_password);
-
  private:
   // This method connects to the Tpm. Returns true on success.
   bool ConnectContextIfNeeded();
 
   trousers::ScopedTssContext context_;
+  std::string authorization_value_;
 
   DISALLOW_COPY_AND_ASSIGN(TpmConnection);
 };
diff --git a/tpm_manager/server/tpm_initializer.h b/tpm_manager/server/tpm_initializer.h
index 85684b3..a1cad78 100644
--- a/tpm_manager/server/tpm_initializer.h
+++ b/tpm_manager/server/tpm_initializer.h
@@ -30,6 +30,14 @@
   // partially initialized, e.g. the process was previously interrupted, then
   // the process picks up where it left off.
   virtual bool InitializeTpm() = 0;
+
+  // This will be called when the service is initializing. It is an early
+  // opportunity to perform tasks related to verified boot.
+  virtual void VerifiedBootHelper() = 0;
+
+  // Reset the state of TPM dictionary attack protection. Returns true on
+  // success.
+  virtual bool ResetDictionaryAttackLock() = 0;
 };
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_initializer_impl.cc b/tpm_manager/server/tpm_initializer_impl.cc
index 4fed91e..e937bec 100644
--- a/tpm_manager/server/tpm_initializer_impl.cc
+++ b/tpm_manager/server/tpm_initializer_impl.cc
@@ -30,11 +30,16 @@
 
 namespace {
 
+// Don't use directly, use GetDefaultOwnerPassword().
 const char kDefaultOwnerPassword[] = TSS_WELL_KNOWN_SECRET;
 const size_t kDefaultPasswordSize = 20;
 const int kMaxOwnershipTimeoutRetries = 5;
 const char* kWellKnownSrkSecret = "well_known_srk_secret";
 
+std::string GetDefaultOwnerPassword() {
+  return std::string(kDefaultOwnerPassword, kDefaultPasswordSize);
+}
+
 }  // namespace
 
 namespace tpm_manager {
@@ -44,17 +49,14 @@
     : local_data_store_(local_data_store), tpm_status_(tpm_status) {}
 
 bool TpmInitializerImpl::InitializeTpm() {
-  if (tpm_status_->IsTpmOwned() && !TestTpmAuth(kDefaultOwnerPassword)) {
+  if (tpm_status_->IsTpmOwned() && !TestTpmAuth(GetDefaultOwnerPassword())) {
     // Tpm is already owned, so we do not need to do anything.
     VLOG(1) << "Tpm already owned.";
     return true;
   }
-  TSS_HTPM tpm_handle = tpm_connection_.GetTpm();
-  if (tpm_handle == 0) {
-    return false;
-  }
-  if (!InitializeEndorsementKey(tpm_handle) || !TakeOwnership(tpm_handle) ||
-      !InitializeSrk(tpm_handle)) {
+  TpmConnection connection(GetDefaultOwnerPassword());
+  if (!InitializeEndorsementKey(&connection) || !TakeOwnership(&connection) ||
+      !InitializeSrk(&connection)) {
     return false;
   }
   std::string owner_password;
@@ -71,46 +73,56 @@
     LOG(ERROR) << "Error saving local data.";
     return false;
   }
-  if (!ChangeOwnerPassword(tpm_handle, owner_password)) {
+  if (!ChangeOwnerPassword(&connection, owner_password)) {
     return false;
   }
   return true;
 }
 
-bool TpmInitializerImpl::InitializeEndorsementKey(TSS_HTPM tpm_handle) {
-  trousers::ScopedTssKey local_key_handle(tpm_connection_.GetContext());
-  TSS_RESULT result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, nullptr,
-                                                    local_key_handle.ptr());
+void TpmInitializerImpl::VerifiedBootHelper() {
+  // Nothing to do.
+}
+
+bool TpmInitializerImpl::ResetDictionaryAttackLock() {
+  LOG(WARNING) << __func__ << ": Not implemented.";
+  return false;
+}
+
+bool TpmInitializerImpl::InitializeEndorsementKey(TpmConnection* connection) {
+  trousers::ScopedTssKey local_key_handle(connection->GetContext());
+  TSS_RESULT result = Tspi_TPM_GetPubEndorsementKey(
+      connection->GetTpm(), false, nullptr, local_key_handle.ptr());
   if (TPM_ERROR(result) == TPM_SUCCESS) {
     // In this case the EK already exists, so we can return true here.
+    VLOG(1) << "EK already exists.";
     return true;
   }
   // At this point the EK does not exist, so we create it.
   TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_SIZE_2048;
   if (TPM_ERROR(result = Tspi_Context_CreateObject(
-                    tpm_connection_.GetContext(), TSS_OBJECT_TYPE_RSAKEY,
+                    connection->GetContext(), TSS_OBJECT_TYPE_RSAKEY,
                     init_flags, local_key_handle.ptr()))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
     return false;
   }
   if (TPM_ERROR(result = Tspi_TPM_CreateEndorsementKey(
-                    tpm_handle, local_key_handle, NULL))) {
+                    connection->GetTpm(), local_key_handle, NULL))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_CreateEndorsementKey";
     return false;
   }
   return true;
 }
 
-bool TpmInitializerImpl::TakeOwnership(TSS_HTPM tpm_handle) {
-  if (TestTpmAuth(kDefaultOwnerPassword)) {
+bool TpmInitializerImpl::TakeOwnership(TpmConnection* connection) {
+  if (TestTpmAuth(GetDefaultOwnerPassword())) {
     VLOG(1) << "The Tpm already has the default owner password.";
     return true;
   }
   TSS_RESULT result;
-  trousers::ScopedTssKey srk_handle(tpm_connection_.GetContext());
+  trousers::ScopedTssKey srk_handle(connection->GetContext());
   TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION;
   if (TPM_ERROR(result = Tspi_Context_CreateObject(
-                    tpm_connection_.GetContext(), TSS_OBJECT_TYPE_RSAKEY,
+                    connection->GetContext(), TSS_OBJECT_TYPE_RSAKEY,
                     init_flags, srk_handle.ptr()))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
     return false;
@@ -129,14 +141,14 @@
     TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
     return false;
   }
-  // Tspi_TPM_TakeOwnership can potentailly take a long time to complete,
+  // Tspi_TPM_TakeOwnership can potentially take a long time to complete,
   // so we retry if there is a timeout in any layer. I chose 5, because the
   // longest TakeOwnership call that I have seen took ~2min, and the default
   // TSS timeout is 30s. This means that after 5 calls, it is quite likely that
   // this call will succeed.
   int retry_count = 0;
   do {
-    result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0);
+    result = Tspi_TPM_TakeOwnership(connection->GetTpm(), srk_handle, 0);
     retry_count++;
   } while (((result == TDDL_E_TIMEOUT) ||
             (result == (TSS_LAYER_TDDL | TDDL_E_TIMEOUT)) ||
@@ -150,20 +162,20 @@
   return true;
 }
 
-bool TpmInitializerImpl::InitializeSrk(TSS_HTPM tpm_handle) {
+bool TpmInitializerImpl::InitializeSrk(TpmConnection* connection) {
   TSS_RESULT result;
-  trousers::ScopedTssKey srk_handle(tpm_connection_.GetContext());
+  trousers::ScopedTssKey srk_handle(connection->GetContext());
   TSS_UUID SRK_UUID = TSS_UUID_SRK;
   if (TPM_ERROR(result = Tspi_Context_LoadKeyByUUID(
-                    tpm_connection_.GetContext(), TSS_PS_TYPE_SYSTEM, SRK_UUID,
+                    connection->GetContext(), TSS_PS_TYPE_SYSTEM, SRK_UUID,
                     srk_handle.ptr()))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_LoadKeyByUUID";
     return false;
   }
 
-  trousers::ScopedTssPolicy policy_handle(tpm_connection_.GetContext());
+  trousers::ScopedTssPolicy policy_handle(connection->GetContext());
   if (TPM_ERROR(result = Tspi_Context_CreateObject(
-                    tpm_connection_.GetContext(), TSS_OBJECT_TYPE_POLICY,
+                    connection->GetContext(), TSS_OBJECT_TYPE_POLICY,
                     TSS_POLICY_USAGE, policy_handle.ptr()))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
     return false;
@@ -175,13 +187,13 @@
     return false;
   }
 
-  if (TPM_ERROR(result =
-                    Tspi_ChangeAuth(srk_handle, tpm_handle, policy_handle))) {
+  if (TPM_ERROR(result = Tspi_ChangeAuth(srk_handle, connection->GetTpm(),
+                                         policy_handle))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth";
     return false;
   }
   TSS_BOOL is_srk_restricted = false;
-  if (TPM_ERROR(result = Tspi_TPM_GetStatus(tpm_handle,
+  if (TPM_ERROR(result = Tspi_TPM_GetStatus(connection->GetTpm(),
                                             TSS_TPMSTATUS_DISABLEPUBSRKREAD,
                                             &is_srk_restricted))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetStatus";
@@ -189,8 +201,9 @@
   }
   // If the SRK is restricted, we unrestrict it.
   if (is_srk_restricted) {
-    if (TPM_ERROR(result = Tspi_TPM_SetStatus(
-                      tpm_handle, TSS_TPMSTATUS_DISABLEPUBSRKREAD, false))) {
+    if (TPM_ERROR(result = Tspi_TPM_SetStatus(connection->GetTpm(),
+                                              TSS_TPMSTATUS_DISABLEPUBSRKREAD,
+                                              false))) {
       TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_SetStatus";
       return false;
     }
@@ -199,12 +212,12 @@
 }
 
 bool TpmInitializerImpl::ChangeOwnerPassword(
-    TSS_HTPM tpm_handle,
+    TpmConnection* connection,
     const std::string& owner_password) {
   TSS_RESULT result;
-  trousers::ScopedTssPolicy policy_handle(tpm_connection_.GetContext());
+  trousers::ScopedTssPolicy policy_handle(connection->GetContext());
   if (TPM_ERROR(result = Tspi_Context_CreateObject(
-                    tpm_connection_.GetContext(), TSS_OBJECT_TYPE_POLICY,
+                    connection->GetContext(), TSS_OBJECT_TYPE_POLICY,
                     TSS_POLICY_USAGE, policy_handle.ptr()))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
     return false;
@@ -218,7 +231,8 @@
     return false;
   }
 
-  if (TPM_ERROR(result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) {
+  if (TPM_ERROR(result =
+                    Tspi_ChangeAuth(connection->GetTpm(), 0, policy_handle))) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth";
     return false;
   }
@@ -227,7 +241,8 @@
 }
 
 bool TpmInitializerImpl::TestTpmAuth(const std::string& owner_password) {
-  TSS_HTPM tpm_handle = tpm_connection_.GetTpmWithAuth(owner_password);
+  TpmConnection connection(owner_password);
+  TSS_HTPM tpm_handle = connection.GetTpm();
   if (tpm_handle == 0) {
     return false;
   }
diff --git a/tpm_manager/server/tpm_initializer_impl.h b/tpm_manager/server/tpm_initializer_impl.h
index 3e8df17..4a80b79 100644
--- a/tpm_manager/server/tpm_initializer_impl.h
+++ b/tpm_manager/server/tpm_initializer_impl.h
@@ -49,28 +49,30 @@
 
   // TpmInitializer methods.
   bool InitializeTpm() override;
+  void VerifiedBootHelper() override;
+  bool ResetDictionaryAttackLock() override;
 
  private:
   // This method checks if an EndorsementKey exists on the Tpm and creates it
-  // if not. Returns true on success, else false. |tpm_handle| is a handle to
-  // the Tpm with the owner_password injected.
-  bool InitializeEndorsementKey(TSS_HTPM tpm_handle);
+  // if not. Returns true on success, else false. The |connection| already has
+  // the owner password injected.
+  bool InitializeEndorsementKey(TpmConnection* connection);
 
   // This method takes ownership of the Tpm with the default TSS password.
-  // Returns true on success, else false. |tpm_handle| is a handle to the Tpm
-  // with the owner_password injected.
-  bool TakeOwnership(TSS_HTPM tpm_handle);
+  // Returns true on success, else false. The |connection| already has the
+  // default owner password injected.
+  bool TakeOwnership(TpmConnection* connection);
 
   // This method initializes the SRK if it does not exist, zero's the SRK
   // password and unrestricts its usage. Returns true on success, else false.
-  // |tpm_handle| is a handle to the Tpm with the owner_password injected.
-  bool InitializeSrk(TSS_HTPM tpm_handle);
+  // The |connection| already has the current owner password injected.
+  bool InitializeSrk(TpmConnection* connection);
 
   // This method changes the Tpm owner password from the default TSS password
   // to the password provided in the |owner_password| argument.
-  // Returns true on success, else false. |tpm_handle| is a handle to the Tpm
-  // with the old owner_password injected.
-  bool ChangeOwnerPassword(TSS_HTPM tpm_handle,
+  // Returns true on success, else false. The |connection| already has the old
+  // owner password injected.
+  bool ChangeOwnerPassword(TpmConnection* connection,
                            const std::string& owner_password);
 
   // This method return true iff the provided |owner_password| is the current
@@ -79,7 +81,6 @@
   bool TestTpmAuth(const std::string& owner_password);
 
   OpensslCryptoUtilImpl openssl_util_;
-  TpmConnection tpm_connection_;
   LocalDataStore* local_data_store_;
   TpmStatus* tpm_status_;
 
diff --git a/tpm_manager/server/tpm_manager_service.cc b/tpm_manager/server/tpm_manager_service.cc
index 2c410e7..f13f501 100644
--- a/tpm_manager/server/tpm_manager_service.cc
+++ b/tpm_manager/server/tpm_manager_service.cc
@@ -35,21 +35,23 @@
       weak_factory_(this) {}
 
 bool TpmManagerService::Initialize() {
-  LOG(INFO) << "TpmManager service started.";
   worker_thread_.reset(new base::Thread("TpmManager Service Worker"));
   worker_thread_->StartWithOptions(
       base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
   base::Closure task =
       base::Bind(&TpmManagerService::InitializeTask, base::Unretained(this));
   worker_thread_->task_runner()->PostNonNestableTask(FROM_HERE, task);
+  VLOG(1) << "Worker thread started.";
   return true;
 }
 
 void TpmManagerService::InitializeTask() {
+  VLOG(1) << "Initializing service...";
   if (!tpm_status_->IsTpmEnabled()) {
     LOG(WARNING) << __func__ << ": TPM is disabled.";
     return;
   }
+  tpm_initializer_->VerifiedBootHelper();
   if (!wait_for_ownership_) {
     VLOG(1) << "Initializing TPM.";
     if (!tpm_initializer_->InitializeTpm()) {
@@ -67,13 +69,13 @@
 
 void TpmManagerService::GetTpmStatusTask(
     const GetTpmStatusRequest& request,
-    const std::shared_ptr<GetTpmStatusReply>& result) {
+    const std::shared_ptr<GetTpmStatusReply>& reply) {
   VLOG(1) << __func__;
-  result->set_enabled(tpm_status_->IsTpmEnabled());
-  result->set_owned(tpm_status_->IsTpmOwned());
+  reply->set_enabled(tpm_status_->IsTpmEnabled());
+  reply->set_owned(tpm_status_->IsTpmOwned());
   LocalData local_data;
   if (local_data_store_ && local_data_store_->Read(&local_data)) {
-    *result->mutable_local_data() = local_data;
+    *reply->mutable_local_data() = local_data;
   }
   int counter;
   int threshold;
@@ -81,13 +83,13 @@
   int lockout_time_remaining;
   if (tpm_status_->GetDictionaryAttackInfo(&counter, &threshold, &lockout,
                                            &lockout_time_remaining)) {
-    result->set_dictionary_attack_counter(counter);
-    result->set_dictionary_attack_threshold(threshold);
-    result->set_dictionary_attack_lockout_in_effect(lockout);
-    result->set_dictionary_attack_lockout_seconds_remaining(
+    reply->set_dictionary_attack_counter(counter);
+    reply->set_dictionary_attack_threshold(threshold);
+    reply->set_dictionary_attack_lockout_in_effect(lockout);
+    reply->set_dictionary_attack_lockout_seconds_remaining(
         lockout_time_remaining);
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_status(STATUS_SUCCESS);
 }
 
 void TpmManagerService::TakeOwnership(const TakeOwnershipRequest& request,
@@ -98,17 +100,17 @@
 
 void TpmManagerService::TakeOwnershipTask(
     const TakeOwnershipRequest& request,
-    const std::shared_ptr<TakeOwnershipReply>& result) {
+    const std::shared_ptr<TakeOwnershipReply>& reply) {
   VLOG(1) << __func__;
   if (!tpm_status_->IsTpmEnabled()) {
-    result->set_status(STATUS_NOT_AVAILABLE);
+    reply->set_status(STATUS_NOT_AVAILABLE);
     return;
   }
   if (!tpm_initializer_->InitializeTpm()) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
+    reply->set_status(STATUS_DEVICE_ERROR);
     return;
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_status(STATUS_SUCCESS);
 }
 
 void TpmManagerService::RemoveOwnerDependency(
@@ -120,19 +122,19 @@
 
 void TpmManagerService::RemoveOwnerDependencyTask(
     const RemoveOwnerDependencyRequest& request,
-    const std::shared_ptr<RemoveOwnerDependencyReply>& result) {
+    const std::shared_ptr<RemoveOwnerDependencyReply>& reply) {
   VLOG(1) << __func__;
   LocalData local_data;
   if (!local_data_store_->Read(&local_data)) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
+    reply->set_status(STATUS_DEVICE_ERROR);
     return;
   }
   RemoveOwnerDependency(request.owner_dependency(), &local_data);
   if (!local_data_store_->Write(local_data)) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
+    reply->set_status(STATUS_DEVICE_ERROR);
     return;
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_status(STATUS_SUCCESS);
 }
 
 void TpmManagerService::RemoveOwnerDependency(
@@ -154,129 +156,160 @@
   }
 }
 
-void TpmManagerService::DefineNvram(const DefineNvramRequest& request,
-                                    const DefineNvramCallback& callback) {
-  PostTaskToWorkerThread<DefineNvramReply>(request, callback,
-                                           &TpmManagerService::DefineNvramTask);
+void TpmManagerService::DefineSpace(const DefineSpaceRequest& request,
+                                    const DefineSpaceCallback& callback) {
+  PostTaskToWorkerThread<DefineSpaceReply>(request, callback,
+                                           &TpmManagerService::DefineSpaceTask);
 }
 
-void TpmManagerService::DefineNvramTask(
-    const DefineNvramRequest& request,
-    const std::shared_ptr<DefineNvramReply>& result) {
+void TpmManagerService::DefineSpaceTask(
+    const DefineSpaceRequest& request,
+    const std::shared_ptr<DefineSpaceReply>& reply) {
   VLOG(1) << __func__;
-  if (!tpm_nvram_->DefineNvram(request.index(), request.length())) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::vector<NvramSpaceAttribute> attributes;
+  for (int i = 0; i < request.attributes_size(); ++i) {
+    attributes.push_back(request.attributes(i));
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_result(
+      tpm_nvram_->DefineSpace(request.index(), request.size(), attributes,
+                              request.authorization_value(), request.policy()));
 }
 
-void TpmManagerService::DestroyNvram(const DestroyNvramRequest& request,
-                                     const DestroyNvramCallback& callback) {
-  PostTaskToWorkerThread<DestroyNvramReply>(
-      request, callback, &TpmManagerService::DestroyNvramTask);
+void TpmManagerService::DestroySpace(const DestroySpaceRequest& request,
+                                     const DestroySpaceCallback& callback) {
+  PostTaskToWorkerThread<DestroySpaceReply>(
+      request, callback, &TpmManagerService::DestroySpaceTask);
 }
 
-void TpmManagerService::DestroyNvramTask(
-    const DestroyNvramRequest& request,
-    const std::shared_ptr<DestroyNvramReply>& result) {
+void TpmManagerService::DestroySpaceTask(
+    const DestroySpaceRequest& request,
+    const std::shared_ptr<DestroySpaceReply>& reply) {
   VLOG(1) << __func__;
-  if (!tpm_nvram_->DestroyNvram(request.index())) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
-  }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_result(tpm_nvram_->DestroySpace(request.index()));
 }
 
-void TpmManagerService::WriteNvram(const WriteNvramRequest& request,
-                                   const WriteNvramCallback& callback) {
-  PostTaskToWorkerThread<WriteNvramReply>(request, callback,
-                                          &TpmManagerService::WriteNvramTask);
+void TpmManagerService::WriteSpace(const WriteSpaceRequest& request,
+                                   const WriteSpaceCallback& callback) {
+  PostTaskToWorkerThread<WriteSpaceReply>(request, callback,
+                                          &TpmManagerService::WriteSpaceTask);
 }
 
-void TpmManagerService::WriteNvramTask(
-    const WriteNvramRequest& request,
-    const std::shared_ptr<WriteNvramReply>& result) {
+void TpmManagerService::WriteSpaceTask(
+    const WriteSpaceRequest& request,
+    const std::shared_ptr<WriteSpaceReply>& reply) {
   VLOG(1) << __func__;
-  if (!tpm_nvram_->WriteNvram(request.index(), request.data())) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::string authorization_value = request.authorization_value();
+  if (request.use_owner_authorization()) {
+    authorization_value = GetOwnerPassword();
+    if (authorization_value.empty()) {
+      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
+      return;
+    }
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_result(tpm_nvram_->WriteSpace(request.index(), request.data(),
+                                           authorization_value));
 }
 
-void TpmManagerService::ReadNvram(const ReadNvramRequest& request,
-                                  const ReadNvramCallback& callback) {
-  PostTaskToWorkerThread<ReadNvramReply>(request, callback,
-                                         &TpmManagerService::ReadNvramTask);
+void TpmManagerService::ReadSpace(const ReadSpaceRequest& request,
+                                  const ReadSpaceCallback& callback) {
+  PostTaskToWorkerThread<ReadSpaceReply>(request, callback,
+                                         &TpmManagerService::ReadSpaceTask);
 }
 
-void TpmManagerService::ReadNvramTask(
-    const ReadNvramRequest& request,
-    const std::shared_ptr<ReadNvramReply>& result) {
+void TpmManagerService::ReadSpaceTask(
+    const ReadSpaceRequest& request,
+    const std::shared_ptr<ReadSpaceReply>& reply) {
   VLOG(1) << __func__;
-  if (!tpm_nvram_->ReadNvram(request.index(), result->mutable_data())) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::string authorization_value = request.authorization_value();
+  if (request.use_owner_authorization()) {
+    authorization_value = GetOwnerPassword();
+    if (authorization_value.empty()) {
+      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
+      return;
+    }
   }
-  result->set_status(STATUS_SUCCESS);
+  reply->set_result(tpm_nvram_->ReadSpace(
+      request.index(), reply->mutable_data(), authorization_value));
 }
 
-void TpmManagerService::IsNvramDefined(const IsNvramDefinedRequest& request,
-                                       const IsNvramDefinedCallback& callback) {
-  PostTaskToWorkerThread<IsNvramDefinedReply>(
-      request, callback, &TpmManagerService::IsNvramDefinedTask);
+void TpmManagerService::LockSpace(const LockSpaceRequest& request,
+                                  const LockSpaceCallback& callback) {
+  PostTaskToWorkerThread<LockSpaceReply>(request, callback,
+                                         &TpmManagerService::LockSpaceTask);
 }
 
-void TpmManagerService::IsNvramDefinedTask(
-    const IsNvramDefinedRequest& request,
-    const std::shared_ptr<IsNvramDefinedReply>& result) {
+void TpmManagerService::LockSpaceTask(
+    const LockSpaceRequest& request,
+    const std::shared_ptr<LockSpaceReply>& reply) {
   VLOG(1) << __func__;
-  bool defined;
-  if (!tpm_nvram_->IsNvramDefined(request.index(), &defined)) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::string authorization_value = request.authorization_value();
+  if (request.use_owner_authorization()) {
+    authorization_value = GetOwnerPassword();
+    if (authorization_value.empty()) {
+      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
+      return;
+    }
   }
-  result->set_is_defined(defined);
-  result->set_status(STATUS_SUCCESS);
+  reply->set_result(tpm_nvram_->LockSpace(request.index(), request.lock_read(),
+                                          request.lock_write(),
+                                          authorization_value));
 }
 
-void TpmManagerService::IsNvramLocked(const IsNvramLockedRequest& request,
-                                      const IsNvramLockedCallback& callback) {
-  PostTaskToWorkerThread<IsNvramLockedReply>(
-      request, callback, &TpmManagerService::IsNvramLockedTask);
+void TpmManagerService::ListSpaces(const ListSpacesRequest& request,
+                                   const ListSpacesCallback& callback) {
+  PostTaskToWorkerThread<ListSpacesReply>(request, callback,
+                                          &TpmManagerService::ListSpacesTask);
 }
 
-void TpmManagerService::IsNvramLockedTask(
-    const IsNvramLockedRequest& request,
-    const std::shared_ptr<IsNvramLockedReply>& result) {
+void TpmManagerService::ListSpacesTask(
+    const ListSpacesRequest& request,
+    const std::shared_ptr<ListSpacesReply>& reply) {
   VLOG(1) << __func__;
-  bool locked;
-  if (!tpm_nvram_->IsNvramLocked(request.index(), &locked)) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::vector<uint32_t> index_list;
+  reply->set_result(tpm_nvram_->ListSpaces(&index_list));
+  if (reply->result() == NVRAM_RESULT_SUCCESS) {
+    for (auto index : index_list) {
+      reply->add_index_list(index);
+    }
   }
-  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::GetSpaceInfo(const GetSpaceInfoRequest& request,
+                                     const GetSpaceInfoCallback& callback) {
+  PostTaskToWorkerThread<GetSpaceInfoReply>(
+      request, callback, &TpmManagerService::GetSpaceInfoTask);
 }
 
-void TpmManagerService::GetNvramSizeTask(
-    const GetNvramSizeRequest& request,
-    const std::shared_ptr<GetNvramSizeReply>& result) {
+void TpmManagerService::GetSpaceInfoTask(
+    const GetSpaceInfoRequest& request,
+    const std::shared_ptr<GetSpaceInfoReply>& reply) {
   VLOG(1) << __func__;
-  size_t size;
-  if (!tpm_nvram_->GetNvramSize(request.index(), &size)) {
-    result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
-    return;
+  std::vector<NvramSpaceAttribute> attributes;
+  size_t size = 0;
+  bool is_read_locked = false;
+  bool is_write_locked = false;
+  NvramSpacePolicy policy = NVRAM_POLICY_NONE;
+  reply->set_result(tpm_nvram_->GetSpaceInfo(request.index(), &size,
+                                             &is_read_locked, &is_write_locked,
+                                             &attributes, &policy));
+  if (reply->result() == NVRAM_RESULT_SUCCESS) {
+    reply->set_size(size);
+    reply->set_is_read_locked(is_read_locked);
+    reply->set_is_write_locked(is_write_locked);
+    for (auto attribute : attributes) {
+      reply->add_attributes(attribute);
+    }
+    reply->set_policy(policy);
   }
-  result->set_size(size);
-  result->set_status(STATUS_SUCCESS);
+}
+
+std::string TpmManagerService::GetOwnerPassword() {
+  LocalData local_data;
+  if (local_data_store_ && local_data_store_->Read(&local_data)) {
+    return local_data.owner_password();
+  }
+  LOG(ERROR) << "TPM owner password requested but not available.";
+  return std::string();
 }
 
 template <typename ReplyProtobufType>
diff --git a/tpm_manager/server/tpm_manager_service.h b/tpm_manager/server/tpm_manager_service.h
index 12672cb..99f2aab 100644
--- a/tpm_manager/server/tpm_manager_service.h
+++ b/tpm_manager/server/tpm_manager_service.h
@@ -31,6 +31,7 @@
 #include "tpm_manager/server/tpm_initializer.h"
 #include "tpm_manager/server/tpm_nvram.h"
 #include "tpm_manager/server/tpm_status.h"
+#include "trunks/trunks_factory.h"
 
 namespace tpm_manager {
 
@@ -79,20 +80,20 @@
       const RemoveOwnerDependencyCallback& callback) override;
 
   // TpmNvramInterface methods.
-  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;
+  void DefineSpace(const DefineSpaceRequest& request,
+                   const DefineSpaceCallback& callback) override;
+  void DestroySpace(const DestroySpaceRequest& request,
+                    const DestroySpaceCallback& callback) override;
+  void WriteSpace(const WriteSpaceRequest& request,
+                  const WriteSpaceCallback& callback) override;
+  void ReadSpace(const ReadSpaceRequest& request,
+                 const ReadSpaceCallback& callback) override;
+  void LockSpace(const LockSpaceRequest& request,
+                 const LockSpaceCallback& callback) override;
+  void ListSpaces(const ListSpacesRequest& request,
+                  const ListSpacesCallback& callback) override;
+  void GetSpaceInfo(const GetSpaceInfoRequest& request,
+                    const GetSpaceInfoCallback& callback) override;
 
  private:
   // A relay callback which allows the use of weak pointer semantics for a reply
@@ -141,40 +142,44 @@
   static void RemoveOwnerDependency(const std::string& owner_dependency,
                                     LocalData* local_data);
 
-  // Blocking implementation of DefineNvram that can be executed on the
+  // Blocking implementation of DefineSpace that can be executed on the
   // background worker thread.
-  void DefineNvramTask(const DefineNvramRequest& request,
-                       const std::shared_ptr<DefineNvramReply>& result);
+  void DefineSpaceTask(const DefineSpaceRequest& request,
+                       const std::shared_ptr<DefineSpaceReply>& result);
 
-  // Blocking implementation of DestroyNvram that can be executed on the
+  // Blocking implementation of DestroySpace that can be executed on the
   // background worker thread.
-  void DestroyNvramTask(const DestroyNvramRequest& request,
-                        const std::shared_ptr<DestroyNvramReply>& result);
+  void DestroySpaceTask(const DestroySpaceRequest& request,
+                        const std::shared_ptr<DestroySpaceReply>& result);
 
-  // Blocking implementation of WriteNvram that can be executed on the
+  // Blocking implementation of WriteSpace that can be executed on the
   // background worker thread.
-  void WriteNvramTask(const WriteNvramRequest& request,
-                      const std::shared_ptr<WriteNvramReply>& result);
+  void WriteSpaceTask(const WriteSpaceRequest& request,
+                      const std::shared_ptr<WriteSpaceReply>& result);
 
-  // Blocking implementation of ReadNvram that can be executed on the
+  // Blocking implementation of ReadSpace that can be executed on the
   // background worker thread.
-  void ReadNvramTask(const ReadNvramRequest& request,
-                     const std::shared_ptr<ReadNvramReply>& result);
+  void ReadSpaceTask(const ReadSpaceRequest& request,
+                     const std::shared_ptr<ReadSpaceReply>& result);
 
-  // Blocking implementation of IsNvramDefined that can be executed on the
+  // Blocking implementation of LockSpace that can be executed on the
   // background worker thread.
-  void IsNvramDefinedTask(const IsNvramDefinedRequest& request,
-                          const std::shared_ptr<IsNvramDefinedReply>& result);
+  void LockSpaceTask(const LockSpaceRequest& request,
+                     const std::shared_ptr<LockSpaceReply>& result);
 
-  // Blocking implementation of IsNvramLocked that can be executed on the
+  // Blocking implementation of ListSpaces that can be executed on the
   // background worker thread.
-  void IsNvramLockedTask(const IsNvramLockedRequest& request,
-                         const std::shared_ptr<IsNvramLockedReply>& result);
+  void ListSpacesTask(const ListSpacesRequest& request,
+                      const std::shared_ptr<ListSpacesReply>& result);
 
-  // Blocking implementation of GetNvramSize that can be executed on the
+  // Blocking implementation of GetSpaceInfo that can be executed on the
   // background worker thread.
-  void GetNvramSizeTask(const GetNvramSizeRequest& request,
-                        const std::shared_ptr<GetNvramSizeReply>& result);
+  void GetSpaceInfoTask(const GetSpaceInfoRequest& request,
+                        const std::shared_ptr<GetSpaceInfoReply>& result);
+
+  // Gets the owner password from local storage. Returns an empty string if the
+  // owner password is not available.
+  std::string GetOwnerPassword();
 
   LocalDataStore* local_data_store_;
   TpmStatus* tpm_status_;
diff --git a/tpm_manager/server/tpm_manager_service_test.cc b/tpm_manager/server/tpm_manager_service_test.cc
index 9d720df..cd0d0f0 100644
--- a/tpm_manager/server/tpm_manager_service_test.cc
+++ b/tpm_manager/server/tpm_manager_service_test.cc
@@ -14,6 +14,7 @@
 // limitations under the License.
 //
 
+#include <base/at_exit.h>
 #include <base/run_loop.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -37,7 +38,10 @@
 const char kOwnerPassword[] = "owner";
 const char kOwnerDependency[] = "owner_dependency";
 const char kOtherDependency[] = "other_dependency";
-}
+
+base::AtExitManager dummy;
+
+}  // namespace
 
 namespace tpm_manager {
 
@@ -215,7 +219,7 @@
   EXPECT_CALL(mock_tpm_initializer_, InitializeTpm())
       .WillRepeatedly(Return(false));
   auto callback = [this](const TakeOwnershipReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+    EXPECT_EQ(STATUS_DEVICE_ERROR, reply.status());
     Quit();
   };
   TakeOwnershipRequest request;
@@ -237,7 +241,7 @@
 TEST_F(TpmManagerServiceTest, RemoveOwnerDependencyReadFailure) {
   EXPECT_CALL(mock_local_data_store_, Read(_)).WillRepeatedly(Return(false));
   auto callback = [this](const RemoveOwnerDependencyReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+    EXPECT_EQ(STATUS_DEVICE_ERROR, reply.status());
     Quit();
   };
   RemoveOwnerDependencyRequest request;
@@ -249,7 +253,7 @@
 TEST_F(TpmManagerServiceTest, RemoveOwnerDependencyWriteFailure) {
   EXPECT_CALL(mock_local_data_store_, Write(_)).WillRepeatedly(Return(false));
   auto callback = [this](const RemoveOwnerDependencyReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+    EXPECT_EQ(STATUS_DEVICE_ERROR, reply.status());
     Quit();
   };
   RemoveOwnerDependencyRequest request;
@@ -323,215 +327,193 @@
   Run();
 }
 
-TEST_F(TpmManagerServiceTest, DefineNvramFailure) {
+TEST_F(TpmManagerServiceTest, DefineSpaceFailure) {
   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());
+  size_t nvram_size = 32;
+  std::vector<NvramSpaceAttribute> attributes{NVRAM_BOOT_WRITE_LOCK};
+  NvramSpacePolicy policy = NVRAM_POLICY_PCR0;
+  std::string auth_value = "1234";
+  EXPECT_CALL(mock_tpm_nvram_, DefineSpace(nvram_index, nvram_size, attributes,
+                                           auth_value, policy))
+      .WillRepeatedly(Return(NVRAM_RESULT_INVALID_PARAMETER));
+  auto callback = [this](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_INVALID_PARAMETER, reply.result());
     Quit();
   };
-  DefineNvramRequest request;
+  DefineSpaceRequest request;
   request.set_index(nvram_index);
-  request.set_length(nvram_length);
-  service_->DefineNvram(request, base::Bind(callback));
+  request.set_size(nvram_size);
+  request.add_attributes(NVRAM_BOOT_WRITE_LOCK);
+  request.set_policy(policy);
+  request.set_authorization_value(auth_value);
+  service_->DefineSpace(request, base::Bind(callback));
   Run();
 }
 
-TEST_F(TpmManagerServiceTest, DefineNvramSuccess) {
+TEST_F(TpmManagerServiceTest, DefineSpaceSuccess) {
   uint32_t nvram_index = 5;
-  uint32_t nvram_length = 32;
-  auto define_callback = [this](const DefineNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  uint32_t nvram_size = 32;
+  auto define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto is_defined_callback = [this](const IsNvramDefinedReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
-    EXPECT_EQ(true, reply.is_defined());
+  auto list_callback = [nvram_index](const ListSpacesReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+    EXPECT_EQ(1, reply.index_list_size());
+    EXPECT_EQ(nvram_index, reply.index_list(0));
   };
-  auto size_callback = [this, nvram_length](const GetNvramSizeReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
-    EXPECT_EQ(nvram_length, reply.size());
+  auto info_callback = [nvram_size](const GetSpaceInfoReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
+    EXPECT_EQ(nvram_size, reply.size());
   };
-  DefineNvramRequest define_request;
+  DefineSpaceRequest 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));
+  define_request.set_size(nvram_size);
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  ListSpacesRequest list_request;
+  service_->ListSpaces(list_request, base::Bind(list_callback));
+  GetSpaceInfoRequest info_request;
+  info_request.set_index(nvram_index);
+  service_->GetSpaceInfo(info_request, base::Bind(info_callback));
   RunServiceWorkerAndQuit();
 }
 
 TEST_F(TpmManagerServiceTest, DestroyUnitializedNvram) {
-  auto callback = [this](const DestroyNvramReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+  auto callback = [this](const DestroySpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST, reply.result());
     Quit();
   };
-  DestroyNvramRequest request;
-  service_->DestroyNvram(request, base::Bind(callback));
+  DestroySpaceRequest request;
+  service_->DestroySpace(request, base::Bind(callback));
   Run();
 }
 
-TEST_F(TpmManagerServiceTest, DestroyNvramSuccess) {
+TEST_F(TpmManagerServiceTest, DestroySpaceSuccess) {
   uint32_t nvram_index = 5;
-  uint32_t nvram_length = 32;
-  auto define_callback = [this](const DefineNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  uint32_t nvram_size = 32;
+  auto define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto destroy_callback = [this](const DestroyNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  auto destroy_callback = [](const DestroySpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  DefineNvramRequest define_request;
+  DefineSpaceRequest 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;
+  define_request.set_size(nvram_size);
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  DestroySpaceRequest destroy_request;
   destroy_request.set_index(nvram_index);
-  service_->DestroyNvram(destroy_request, base::Bind(destroy_callback));
+  service_->DestroySpace(destroy_request, base::Bind(destroy_callback));
   RunServiceWorkerAndQuit();
 }
 
-TEST_F(TpmManagerServiceTest, DoubleDestroyNvram) {
+TEST_F(TpmManagerServiceTest, DoubleDestroySpace) {
   uint32_t nvram_index = 5;
-  uint32_t nvram_length = 32;
-  auto define_callback = [this](const DefineNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  uint32_t nvram_size = 32;
+  auto define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto destroy_callback_success = [this](const DestroyNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  auto destroy_callback_success = [](const DestroySpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto destroy_callback_failure = [this](const DestroyNvramReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+  auto destroy_callback_failure = [](const DestroySpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST, reply.result());
   };
-  DefineNvramRequest define_request;
+  DefineSpaceRequest 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;
+  define_request.set_size(nvram_size);
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  DestroySpaceRequest 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));
+  service_->DestroySpace(destroy_request, base::Bind(destroy_callback_success));
+  service_->DestroySpace(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) {
+TEST_F(TpmManagerServiceTest, WriteSpaceIncorrectSize) {
   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 define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto write_callback = [this](const WriteNvramReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+  auto write_callback = [](const WriteSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_INVALID_PARAMETER, reply.result());
   };
-  DefineNvramRequest define_request;
+  DefineSpaceRequest 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;
+  define_request.set_size(nvram_data.size() - 1);
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  WriteSpaceRequest write_request;
   write_request.set_index(nvram_index);
   write_request.set_data(nvram_data);
-  service_->WriteNvram(write_request, base::Bind(write_callback));
+  service_->WriteSpace(write_request, base::Bind(write_callback));
   RunServiceWorkerAndQuit();
 }
 
-TEST_F(TpmManagerServiceTest, DoubleWrite) {
+TEST_F(TpmManagerServiceTest, WriteBeforeAfterLock) {
   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 define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto write_callback_success = [this](const WriteNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  auto write_callback_success = [](const WriteSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto write_callback_failure = [this](const WriteNvramReply& reply) {
-    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
+  auto lock_callback = [](const LockSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  DefineNvramRequest define_request;
+  auto write_callback_failure = [](const WriteSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_OPERATION_DISABLED, reply.result());
+  };
+  DefineSpaceRequest 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;
+  define_request.set_size(nvram_data.size());
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  WriteSpaceRequest 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));
+  service_->WriteSpace(write_request, base::Bind(write_callback_success));
+  LockSpaceRequest lock_request;
+  lock_request.set_index(nvram_index);
+  lock_request.set_lock_write(true);
+  service_->LockSpace(lock_request, base::Bind(lock_callback));
+  service_->WriteSpace(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());
+  auto callback = [this](const ReadSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SPACE_DOES_NOT_EXIST, reply.result());
     Quit();
   };
-  ReadNvramRequest request;
-  service_->ReadNvram(request, base::Bind(callback));
+  ReadSpaceRequest request;
+  service_->ReadSpace(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) {
+TEST_F(TpmManagerServiceTest, ReadWriteSpaceSuccess) {
   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 define_callback = [](const DefineSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto write_callback = [this](const WriteNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  auto write_callback = [](const WriteSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
   };
-  auto read_callback = [this, nvram_data](const ReadNvramReply& reply) {
-    EXPECT_EQ(STATUS_SUCCESS, reply.status());
+  auto read_callback = [nvram_data](const ReadSpaceReply& reply) {
+    EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
     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;
+  DefineSpaceRequest 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;
+  define_request.set_size(nvram_data.size());
+  service_->DefineSpace(define_request, base::Bind(define_callback));
+  WriteSpaceRequest 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;
+  service_->WriteSpace(write_request, base::Bind(write_callback));
+  ReadSpaceRequest 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));
+  service_->ReadSpace(read_request, base::Bind(read_callback));
   RunServiceWorkerAndQuit();
 }
 
diff --git a/tpm_manager/server/tpm_manager-seccomp-amd64.policy b/tpm_manager/server/tpm_managerd-seccomp-amd64.policy
similarity index 100%
rename from tpm_manager/server/tpm_manager-seccomp-amd64.policy
rename to tpm_manager/server/tpm_managerd-seccomp-amd64.policy
diff --git a/tpm_manager/server/tpm_manager-seccomp-arm.policy b/tpm_manager/server/tpm_managerd-seccomp-arm.policy
similarity index 100%
rename from tpm_manager/server/tpm_manager-seccomp-arm.policy
rename to tpm_manager/server/tpm_managerd-seccomp-arm.policy
diff --git a/tpm_manager/server/tpm_manager-seccomp-x86.policy b/tpm_manager/server/tpm_managerd-seccomp-x86.policy
similarity index 100%
rename from tpm_manager/server/tpm_manager-seccomp-x86.policy
rename to tpm_manager/server/tpm_managerd-seccomp-x86.policy
diff --git a/tpm_manager/server/tpm_managerd.conf b/tpm_manager/server/tpm_managerd.conf
index 9509967..11d605e 100644
--- a/tpm_manager/server/tpm_managerd.conf
+++ b/tpm_manager/server/tpm_managerd.conf
@@ -29,8 +29,4 @@
   fi
 end script
 
-# Minijail forks off our process
-expect fork
-
-exec minijail0 -i -g tpm_manager -u tpm_manager -G -n \
-    -S /usr/share/policy/tpm_managerd-seccomp.policy /usr/sbin/tpm_managerd
+exec /usr/sbin/tpm_managerd --wait_for_ownership_trigger
diff --git a/tpm_manager/server/tpm_managerd.rc b/tpm_manager/server/tpm_managerd.rc
new file mode 100644
index 0000000..d15c97e
--- /dev/null
+++ b/tpm_manager/server/tpm_managerd.rc
@@ -0,0 +1,8 @@
+on post-fs-data
+    mkdir /data/misc/tpm_managerd 0700 root root
+
+service tpm_managerd /system/bin/tpm_managerd
+    class late_start
+    user root
+    group root
+    oneshot
diff --git a/tpm_manager/server/tpm_nvram.h b/tpm_manager/server/tpm_nvram.h
index 750d778..e454965 100644
--- a/tpm_manager/server/tpm_nvram.h
+++ b/tpm_manager/server/tpm_nvram.h
@@ -18,44 +18,59 @@
 #define TPM_MANAGER_SERVER_TPM_NVRAM_H_
 
 #include <string>
+#include <vector>
+
+#include "tpm_manager/common/tpm_manager.pb.h"
 
 namespace tpm_manager {
 
-// TpmNvram is an interface for accessing Nvram functionality on a Tpm.
+// TpmNvram is an interface for working with TPM NVRAM.
 class TpmNvram {
  public:
   TpmNvram() = default;
   virtual ~TpmNvram() = default;
 
-  // This method creates a NVRAM space in the TPM. Returns true iff
-  // the space was successfully created.
-  virtual bool DefineNvram(uint32_t index, size_t length) = 0;
+  // Creates an NVRAM space in the TPM. Returns true on success.
+  virtual NvramResult DefineSpace(
+      uint32_t index,
+      size_t size,
+      const std::vector<NvramSpaceAttribute>& attributes,
+      const std::string& authorization_value,
+      NvramSpacePolicy policy) = 0;
 
-  // This method destroys a defined NVRAM space. Returns true iff the NVRAM
-  // space was successfully destroyed.
-  virtual bool DestroyNvram(uint32_t index) = 0;
+  // Destroys an NVRAM space in the TPM. Returns true on success.
+  virtual NvramResult DestroySpace(uint32_t index) = 0;
 
-  // This method writes |data| to the NVRAM space defined by |index|. The size
-  // of |data| must be equal or less than the size of the NVRAM space. Returns
-  // true on success. Once written to, the NVRAM space is locked and cannot be
-  // written to again.
-  virtual bool WriteNvram(uint32_t index, const std::string& data) = 0;
+  // Writes |data| to the NVRAM space at |index|. The size of |data| must be
+  // equal or less than the size of the NVRAM space. Returns true on success.
+  virtual NvramResult WriteSpace(uint32_t index,
+                                 const std::string& data,
+                                 const std::string& authorization_value) = 0;
 
-  // This method reads all the contents of the NVRAM space at |index| and writes
-  // it into |data|. Returns true on success.
-  virtual bool ReadNvram(uint32_t index, std::string* data) = 0;
+  // Reads all the |data| in the NVRAM space at |index|. Returns true on
+  // success.
+  virtual NvramResult ReadSpace(uint32_t index,
+                                std::string* data,
+                                const std::string& authorization_value) = 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;
+  // Locks the NVRAM space at |index|. Returns true on success.
+  virtual NvramResult LockSpace(uint32_t index,
+                                bool lock_read,
+                                bool lock_write,
+                                const std::string& authorization_value) = 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;
+  // Lists all existing NVRAM spaces. Returns true on success.
+  virtual NvramResult ListSpaces(std::vector<uint32_t>* index_list) = 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;
+  // Provides basic information about a given space. All pointer are optional
+  // and may be NULL. Returns true on success.
+  virtual NvramResult GetSpaceInfo(
+      uint32_t index,
+      size_t* size,
+      bool* is_read_locked,
+      bool* is_write_locked,
+      std::vector<NvramSpaceAttribute>* attributes,
+      NvramSpacePolicy* policy) = 0;
 };
 
 }  // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_nvram_impl.cc b/tpm_manager/server/tpm_nvram_impl.cc
index d9a61a9..a7de668 100644
--- a/tpm_manager/server/tpm_nvram_impl.cc
+++ b/tpm_manager/server/tpm_nvram_impl.cc
@@ -24,10 +24,16 @@
 #include <base/stl_util.h>
 #include <trousers/scoped_tss_type.h>
 
-#include "tpm_manager/common/local_data.pb.h"
+#include "tpm_manager/common/tpm_manager.pb.h"
 #include "tpm_manager/server/local_data_store.h"
 #include "tpm_manager/server/tpm_util.h"
 
+namespace tpm_manager {
+
+using trousers::ScopedTssMemory;
+using trousers::ScopedTssNvStore;
+using trousers::ScopedTssPcrs;
+
 namespace {
 
 // PCR0 at locality 1 is used to differentiate between developed and normal
@@ -36,106 +42,234 @@
 const unsigned int kTpmBootPCR = 0;
 const unsigned int kTpmPCRLocality = 1;
 
+void MapAttributesFromTpm(TPM_NV_PER_ATTRIBUTES tpm_flags,
+                          std::vector<NvramSpaceAttribute>* attributes) {
+  if (tpm_flags & TPM_NV_PER_WRITEDEFINE)
+    attributes->push_back(NVRAM_PERSISTENT_WRITE_LOCK);
+  if (tpm_flags & TPM_NV_PER_WRITE_STCLEAR)
+    attributes->push_back(NVRAM_BOOT_WRITE_LOCK);
+  if (tpm_flags & TPM_NV_PER_READ_STCLEAR)
+    attributes->push_back(NVRAM_BOOT_READ_LOCK);
+  if (tpm_flags & TPM_NV_PER_AUTHWRITE)
+    attributes->push_back(NVRAM_WRITE_AUTHORIZATION);
+  if (tpm_flags & TPM_NV_PER_AUTHREAD)
+    attributes->push_back(NVRAM_READ_AUTHORIZATION);
+  if (tpm_flags & TPM_NV_PER_GLOBALLOCK)
+    attributes->push_back(NVRAM_GLOBAL_LOCK);
+  if (tpm_flags & TPM_NV_PER_PPWRITE)
+    attributes->push_back(NVRAM_PLATFORM_WRITE);
+  if (tpm_flags & TPM_NV_PER_OWNERWRITE)
+    attributes->push_back(NVRAM_OWNER_WRITE);
+  if (tpm_flags & TPM_NV_PER_OWNERREAD)
+    attributes->push_back(NVRAM_OWNER_READ);
+}
+
+TPM_NV_PER_ATTRIBUTES MapAttributesToTpm(
+    const std::vector<NvramSpaceAttribute>& attributes) {
+  TPM_NV_PER_ATTRIBUTES tpm_flags = 0;
+  for (auto attribute : attributes) {
+    switch (attribute) {
+      case NVRAM_PERSISTENT_WRITE_LOCK:
+        tpm_flags |= TPM_NV_PER_WRITEDEFINE;
+        break;
+      case NVRAM_BOOT_WRITE_LOCK:
+        tpm_flags |= TPM_NV_PER_WRITE_STCLEAR;
+        break;
+      case NVRAM_BOOT_READ_LOCK:
+        tpm_flags |= TPM_NV_PER_READ_STCLEAR;
+        break;
+      case NVRAM_WRITE_AUTHORIZATION:
+        tpm_flags |= TPM_NV_PER_AUTHWRITE;
+        break;
+      case NVRAM_READ_AUTHORIZATION:
+        tpm_flags |= TPM_NV_PER_AUTHREAD;
+        break;
+      case NVRAM_GLOBAL_LOCK:
+        tpm_flags |= TPM_NV_PER_GLOBALLOCK;
+        break;
+      case NVRAM_PLATFORM_WRITE:
+        tpm_flags |= TPM_NV_PER_PPWRITE;
+        break;
+      case NVRAM_OWNER_WRITE:
+        tpm_flags |= TPM_NV_PER_OWNERWRITE;
+        break;
+      case NVRAM_OWNER_READ:
+        tpm_flags |= TPM_NV_PER_OWNERREAD;
+        break;
+      default:
+        break;
+    }
+  }
+  return tpm_flags;
+}
+
+NvramResult MapTpmError(TSS_RESULT tpm_error) {
+  switch (TPM_ERROR(tpm_error)) {
+    case TPM_SUCCESS:
+      return NVRAM_RESULT_SUCCESS;
+    case TPM_E_BAD_PARAMETER:
+    case TPM_E_PER_NOWRITE:
+    case TPM_E_AUTH_CONFLICT:
+      return NVRAM_RESULT_INVALID_PARAMETER;
+    case TPM_E_AREA_LOCKED:
+    case TPM_E_READ_ONLY:
+    case TPM_E_WRITE_LOCKED:
+    case TPM_E_DISABLED_CMD:
+      return NVRAM_RESULT_OPERATION_DISABLED;
+    case TPM_E_AUTHFAIL:
+    case TPM_E_NO_NV_PERMISSION:
+    case TPM_E_WRONGPCRVAL:
+      return NVRAM_RESULT_ACCESS_DENIED;
+    case TPM_E_NOSPACE:
+    case TPM_E_RESOURCES:
+    case TPM_E_SIZE:
+      return NVRAM_RESULT_INSUFFICIENT_SPACE;
+    case TPM_E_BADINDEX:
+    case TPM_E_BAD_HANDLE:
+      return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
+  }
+  return NVRAM_RESULT_DEVICE_ERROR;
+}
+
 }  // namespace
 
-namespace tpm_manager {
-
-using trousers::ScopedTssMemory;
-using trousers::ScopedTssNvStore;
-using trousers::ScopedTssPcrs;
-
 TpmNvramImpl::TpmNvramImpl(LocalDataStore* local_data_store)
     : local_data_store_(local_data_store) {}
 
-bool TpmNvramImpl::DefineNvram(uint32_t index, size_t length) {
-  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
-  if (!(InitializeNvramHandle(&nv_handle, index) &&
-        SetOwnerPolicy(&nv_handle))) {
-    return false;
+NvramResult TpmNvramImpl::DefineSpace(
+    uint32_t index,
+    size_t size,
+    const std::vector<NvramSpaceAttribute>& attributes,
+    const std::string& authorization_value,
+    NvramSpacePolicy policy) {
+  std::string owner_password;
+  if (!GetOwnerPassword(&owner_password)) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
+  }
+  TpmConnection owner_connection(owner_password);
+  ScopedTssNvStore nv_handle(owner_connection.GetContext());
+  if (!InitializeNvramHandle(index, &nv_handle, &owner_connection)) {
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
   TSS_RESULT result;
-  result =
-      Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_DATASIZE, 0, length);
+  result = Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_DATASIZE, 0, size);
   if (TPM_ERROR(result)) {
-    TPM_LOG(ERROR, result) << "Could not set size on NVRAM object: " << length;
-    return false;
+    TPM_LOG(ERROR, result) << "Could not set size on NVRAM object: " << size;
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  // Restrict to only one write.
+  // Set permissions attributes.
   result = Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_PERMISSIONS, 0,
-                                TPM_NV_PER_WRITEDEFINE);
+                                MapAttributesToTpm(attributes));
   if (TPM_ERROR(result)) {
-    TPM_LOG(ERROR, result) << "Could not set PER_WRITEDEFINE on NVRAM object";
-    return false;
+    TPM_LOG(ERROR, result) << "Could not set permissions on NVRAM object";
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  // Restrict to writing only with owner authorization.
-  result = Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_PERMISSIONS, 0,
-                                TPM_NV_PER_OWNERWRITE);
-  if (TPM_ERROR(result)) {
-    TPM_LOG(ERROR, result) << "Could not set PER_OWNERWRITE on NVRAM object";
-    return false;
+  // Set authorization.
+  if (!authorization_value.empty() &&
+      !SetUsagePolicy(authorization_value, &nv_handle, &owner_connection)) {
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  ScopedTssPcrs pcr_handle(tpm_connection_.GetContext());
-  if (!SetCompositePcr0(&pcr_handle)) {
-    return false;
+  // Bind to PCR0.
+  TSS_HPCRS pcr_handle = 0;
+  ScopedTssPcrs scoped_pcr_handle(owner_connection.GetContext());
+  if (policy == NVRAM_POLICY_PCR0) {
+    if (!SetCompositePcr0(&scoped_pcr_handle, &owner_connection)) {
+      return NVRAM_RESULT_DEVICE_ERROR;
+    }
+    pcr_handle = scoped_pcr_handle;
   }
-  result = Tspi_NV_DefineSpace(nv_handle,
-                               pcr_handle /* ReadPCRs restricted to PCR0 */,
-                               pcr_handle /* WritePCRs restricted to PCR0 */);
+  result = Tspi_NV_DefineSpace(nv_handle, pcr_handle, /*Read*/
+                               pcr_handle /*Write*/);
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Could not define NVRAM space: " << index;
-    return false;
+    return MapTpmError(result);
   }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::DestroyNvram(uint32_t index) {
-  bool defined;
-  if (!IsNvramDefined(index, &defined)) {
-    return false;
+NvramResult TpmNvramImpl::DestroySpace(uint32_t index) {
+  std::string owner_password;
+  if (!GetOwnerPassword(&owner_password)) {
+    return NVRAM_RESULT_OPERATION_DISABLED;
   }
-  if (!defined) {
-    // If the nvram space is not defined, we don't need to destroy it.
-    return true;
-  }
-  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
-  if (!(InitializeNvramHandle(&nv_handle, index) &&
-        SetOwnerPolicy(&nv_handle))) {
-    return false;
+  TpmConnection owner_connection(owner_password);
+  ScopedTssNvStore nv_handle(owner_connection.GetContext());
+  if (!InitializeNvramHandle(index, &nv_handle, &owner_connection)) {
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
   TSS_RESULT result = Tspi_NV_ReleaseSpace(nv_handle);
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Could not release NVRAM space: " << index;
-    return false;
+    return MapTpmError(result);
   }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::WriteNvram(uint32_t index, const std::string& data) {
-  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
-  if (!(InitializeNvramHandle(&nv_handle, index) &&
-        SetOwnerPolicy(&nv_handle))) {
-    return false;
+NvramResult TpmNvramImpl::WriteSpace(uint32_t index,
+                                     const std::string& data,
+                                     const std::string& authorization_value) {
+  std::vector<NvramSpaceAttribute> attributes;
+  NvramResult result =
+      GetSpaceInfo(index, nullptr, nullptr, nullptr, &attributes, nullptr);
+  if (result != NVRAM_RESULT_SUCCESS) {
+    return result;
   }
-  TSS_RESULT result = Tspi_NV_WriteValue(
+  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
+  if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) {
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
+  for (const auto& attribute : attributes) {
+    if (attribute == NVRAM_OWNER_WRITE) {
+      if (!SetOwnerPolicy(&nv_handle)) {
+        return NVRAM_RESULT_OPERATION_DISABLED;
+      }
+      break;
+    }
+    if (attribute == NVRAM_WRITE_AUTHORIZATION) {
+      if (!SetUsagePolicy(authorization_value, &nv_handle, &tpm_connection_)) {
+        return NVRAM_RESULT_DEVICE_ERROR;
+      }
+      break;
+    }
+  }
+  TSS_RESULT tpm_result = Tspi_NV_WriteValue(
       nv_handle, 0 /* offset */, data.size(),
       reinterpret_cast<BYTE*>(const_cast<char*>(data.data())));
-  if (TPM_ERROR(result)) {
-    TPM_LOG(ERROR, result) << "Could not write to NVRAM space: " << index;
-    return false;
+  if (TPM_ERROR(tpm_result)) {
+    TPM_LOG(ERROR, tpm_result) << "Could not write to NVRAM space: " << index;
+    return MapTpmError(tpm_result);
   }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::ReadNvram(uint32_t index, std::string* data) {
+NvramResult TpmNvramImpl::ReadSpace(uint32_t index,
+                                    std::string* data,
+                                    const std::string& authorization_value) {
   CHECK(data);
-  TSS_RESULT result;
-  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
-  if (!InitializeNvramHandle(&nv_handle, index)) {
-    return false;
-  }
   size_t nvram_size;
-  if (!GetNvramSize(index, &nvram_size)) {
-    return false;
+  std::vector<NvramSpaceAttribute> attributes;
+  NvramResult result =
+      GetSpaceInfo(index, &nvram_size, nullptr, nullptr, &attributes, nullptr);
+  if (result != NVRAM_RESULT_SUCCESS) {
+    return result;
+  }
+  ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
+  if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) {
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
+  for (const auto& attribute : attributes) {
+    if (attribute == NVRAM_OWNER_READ) {
+      if (!SetOwnerPolicy(&nv_handle)) {
+        return NVRAM_RESULT_OPERATION_DISABLED;
+      }
+      break;
+    }
+    if (attribute == NVRAM_READ_AUTHORIZATION) {
+      if (!SetUsagePolicy(authorization_value, &nv_handle, &tpm_connection_)) {
+        return NVRAM_RESULT_DEVICE_ERROR;
+      }
+      break;
+    }
   }
   data->resize(nvram_size);
   // The Tpm1.2 Specification defines the maximum read size of 128 bytes.
@@ -143,76 +277,127 @@
   const size_t kMaxDataSize = 128;
   uint32_t offset = 0;
   while (offset < nvram_size) {
-    uint32_t chunk_size = std::max(nvram_size - offset, kMaxDataSize);
+    uint32_t chunk_size = std::min(nvram_size - offset, kMaxDataSize);
     ScopedTssMemory space_data(tpm_connection_.GetContext());
-    if ((result = Tspi_NV_ReadValue(nv_handle, offset, &chunk_size,
-                                    space_data.ptr()))) {
-      TPM_LOG(ERROR, result) << "Could not read from NVRAM space: " << index;
-      return false;
+    TSS_RESULT tpm_result =
+        Tspi_NV_ReadValue(nv_handle, offset, &chunk_size, space_data.ptr());
+    if (TPM_ERROR(tpm_result)) {
+      TPM_LOG(ERROR, tpm_result) << "Could not read from NVRAM space: "
+                                 << index;
+      data->clear();
+      return MapTpmError(tpm_result);
     }
     if (!space_data.value()) {
       LOG(ERROR) << "No data read from NVRAM space: " << index;
-      return false;
+      data->clear();
+      return NVRAM_RESULT_DEVICE_ERROR;
     }
     CHECK_LE((offset + chunk_size), data->size());
     data->replace(offset, chunk_size,
                   reinterpret_cast<char*>(space_data.value()), chunk_size);
     offset += chunk_size;
   }
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::IsNvramDefined(uint32_t index, bool* defined) {
-  CHECK(defined);
+NvramResult TpmNvramImpl::LockSpace(uint32_t index,
+                                    bool lock_read,
+                                    bool lock_write,
+                                    const std::string& authorization_value) {
+  std::vector<NvramSpaceAttribute> attributes;
+  NvramResult result =
+      GetSpaceInfo(index, nullptr, nullptr, nullptr, &attributes, nullptr);
+  if (result != NVRAM_RESULT_SUCCESS) {
+    return result;
+  }
+  if (lock_read) {
+    ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
+    if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) {
+      return NVRAM_RESULT_DEVICE_ERROR;
+    }
+    for (const auto& attribute : attributes) {
+      if (attribute == NVRAM_OWNER_READ) {
+        if (!SetOwnerPolicy(&nv_handle)) {
+          return NVRAM_RESULT_OPERATION_DISABLED;
+        }
+        break;
+      }
+      if (attribute == NVRAM_READ_AUTHORIZATION) {
+        if (!SetUsagePolicy(authorization_value, &nv_handle,
+                            &tpm_connection_)) {
+          return NVRAM_RESULT_DEVICE_ERROR;
+        }
+        break;
+      }
+    }
+    uint32_t size = 0;
+    ScopedTssMemory space_data(tpm_connection_.GetContext());
+    TSS_RESULT tpm_result =
+        Tspi_NV_ReadValue(nv_handle, 0, &size, space_data.ptr());
+    if (TPM_ERROR(tpm_result)) {
+      TPM_LOG(ERROR, tpm_result) << "Could not lock read for NVRAM space: "
+                                 << index;
+      return MapTpmError(tpm_result);
+    }
+  }
+  if (lock_write) {
+    ScopedTssNvStore nv_handle(tpm_connection_.GetContext());
+    if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) {
+      return NVRAM_RESULT_DEVICE_ERROR;
+    }
+    for (const auto& attribute : attributes) {
+      if (attribute == NVRAM_OWNER_WRITE) {
+        if (!SetOwnerPolicy(&nv_handle)) {
+          return NVRAM_RESULT_OPERATION_DISABLED;
+        }
+        break;
+      }
+      if (attribute == NVRAM_WRITE_AUTHORIZATION) {
+        if (!SetUsagePolicy(authorization_value, &nv_handle,
+                            &tpm_connection_)) {
+          return NVRAM_RESULT_DEVICE_ERROR;
+        }
+        break;
+      }
+    }
+    BYTE not_used;
+    TSS_RESULT tpm_result = Tspi_NV_WriteValue(nv_handle, 0, 0, &not_used);
+    if (TPM_ERROR(tpm_result)) {
+      TPM_LOG(ERROR, tpm_result) << "Could not lock write for NVRAM space: "
+                                 << index;
+      return MapTpmError(tpm_result);
+    }
+  }
+  return NVRAM_RESULT_SUCCESS;
+}
+
+NvramResult TpmNvramImpl::ListSpaces(std::vector<uint32_t>* index_list) {
   uint32_t nv_list_data_length = 0;
   ScopedTssMemory nv_list_data(tpm_connection_.GetContext());
   TSS_RESULT result =
       Tspi_TPM_GetCapability(tpm_connection_.GetTpm(), TSS_TPMCAP_NV_LIST, 0,
-                             NULL, &nv_list_data_length, nv_list_data.ptr());
+                             nullptr, &nv_list_data_length, nv_list_data.ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability";
-    return false;
+    return MapTpmError(result);
   }
   // Walk the list and check if the index exists.
   uint32_t* nv_list = reinterpret_cast<uint32_t*>(nv_list_data.value());
   uint32_t nv_list_length = nv_list_data_length / sizeof(uint32_t);
-  index = htonl(index);  // TPM data is network byte order.
   for (uint32_t i = 0; i < nv_list_length; ++i) {
-    if (index == nv_list[i]) {
-      *defined = true;
-      return true;
-    }
+    // TPM data is network byte order.
+    index_list->push_back(ntohl(nv_list[i]));
   }
-  *defined = false;
-  return true;
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::IsNvramLocked(uint32_t index, bool* locked) {
-  CHECK(locked);
-  uint32_t nv_index_data_length = 0;
-  ScopedTssMemory nv_index_data(tpm_connection_.GetContext());
-  TSS_RESULT result =
-      Tspi_TPM_GetCapability(tpm_connection_.GetTpm(), TSS_TPMCAP_NV_INDEX,
-                             sizeof(index), reinterpret_cast<BYTE*>(&index),
-                             &nv_index_data_length, nv_index_data.ptr());
-  if (TPM_ERROR(result)) {
-    TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability";
-    return false;
-  }
-  if (nv_index_data_length < (sizeof(uint32_t) + sizeof(TPM_BOOL))) {
-    return false;
-  }
-  // TPM_NV_DATA_PUBLIC->bWriteDefine is the second to last element in the
-  // struct.
-  uint32_t* nv_data_public =
-      reinterpret_cast<uint32_t*>(nv_index_data.value() + nv_index_data_length -
-                                  (sizeof(uint32_t) + sizeof(TPM_BOOL)));
-  *locked = (*nv_data_public != 0);
-  return true;
-}
-
-bool TpmNvramImpl::GetNvramSize(uint32_t index, size_t* size) {
-  CHECK(size);
+NvramResult TpmNvramImpl::GetSpaceInfo(
+    uint32_t index,
+    size_t* size,
+    bool* is_read_locked,
+    bool* is_write_locked,
+    std::vector<NvramSpaceAttribute>* attributes,
+    NvramSpacePolicy* policy) {
   UINT32 nv_index_data_length = 0;
   ScopedTssMemory nv_index_data(tpm_connection_.GetContext());
   TSS_RESULT result =
@@ -221,22 +406,50 @@
                              &nv_index_data_length, nv_index_data.ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability";
-    return false;
+    return MapTpmError(result);
   }
-  if (nv_index_data_length < sizeof(uint32_t)) {
-    return false;
+  UINT64 offset = 0;
+  Trspi_UnloadBlob_NV_DATA_PUBLIC(&offset, nv_index_data.value(), nullptr);
+  if (nv_index_data_length < offset) {
+    LOG(ERROR) << "Not enough data from Tspi_TPM_GetCapability.";
+    return NVRAM_RESULT_DEVICE_ERROR;
   }
-  // TPM_NV_DATA_PUBLIC->dataSize is the last element in the struct.
-  uint32_t* nv_data_public = reinterpret_cast<uint32_t*>(
-      nv_index_data.value() + nv_index_data_length - sizeof(uint32_t));
-  *size = htonl(*nv_data_public);
-  return true;
+  TPM_NV_DATA_PUBLIC info;
+  offset = 0;
+  result =
+      Trspi_UnloadBlob_NV_DATA_PUBLIC(&offset, nv_index_data.value(), &info);
+  if (TPM_ERROR(result)) {
+    TPM_LOG(ERROR, result) << "Error calling Trspi_UnloadBlob_NV_DATA_PUBLIC";
+    return NVRAM_RESULT_DEVICE_ERROR;
+  }
+  if (size) {
+    *size = info.dataSize;
+  }
+  if (is_read_locked) {
+    *is_read_locked = info.bReadSTClear;
+  }
+  if (is_write_locked) {
+    *is_write_locked = info.bWriteSTClear || info.bWriteDefine;
+  }
+  if (attributes) {
+    MapAttributesFromTpm(info.permission.attributes, attributes);
+  }
+  if (policy) {
+    if (info.pcrInfoWrite.pcrSelection.sizeOfSelect > 0 &&
+        (info.pcrInfoWrite.pcrSelection.pcrSelect[0] & 1) != 0) {
+      *policy = NVRAM_POLICY_PCR0;
+    } else {
+      *policy = NVRAM_POLICY_NONE;
+    }
+  }
+  return NVRAM_RESULT_SUCCESS;
 }
 
-bool TpmNvramImpl::InitializeNvramHandle(ScopedTssNvStore* nv_handle,
-                                         uint32_t index) {
+bool TpmNvramImpl::InitializeNvramHandle(uint32_t index,
+                                         ScopedTssNvStore* nv_handle,
+                                         TpmConnection* connection) {
   TSS_RESULT result = Tspi_Context_CreateObject(
-      tpm_connection_.GetContext(), TSS_OBJECT_TYPE_NV, 0, nv_handle->ptr());
+      connection->GetContext(), TSS_OBJECT_TYPE_NV, 0, nv_handle->ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Could not acquire an NVRAM object handle";
     return false;
@@ -251,22 +464,28 @@
 }
 
 bool TpmNvramImpl::SetOwnerPolicy(ScopedTssNvStore* nv_handle) {
-  trousers::ScopedTssPolicy policy_handle(tpm_connection_.GetContext());
+  std::string owner_password;
+  if (!GetOwnerPassword(&owner_password)) {
+    return false;
+  }
+  return SetUsagePolicy(owner_password, nv_handle, &tpm_connection_);
+}
+
+bool TpmNvramImpl::SetUsagePolicy(const std::string& authorization_value,
+                                  trousers::ScopedTssNvStore* nv_handle,
+                                  TpmConnection* connection) {
+  trousers::ScopedTssPolicy policy_handle(connection->GetContext());
   TSS_RESULT result;
-  result = Tspi_Context_CreateObject(tpm_connection_.GetContext(),
+  result = Tspi_Context_CreateObject(connection->GetContext(),
                                      TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE,
                                      policy_handle.ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
     return false;
   }
-  std::string owner_password;
-  if (!GetOwnerPassword(&owner_password)) {
-    return false;
-  }
   result = Tspi_Policy_SetSecret(
-      policy_handle, TSS_SECRET_MODE_PLAIN, owner_password.size(),
-      reinterpret_cast<BYTE*>(const_cast<char*>(owner_password.data())));
+      policy_handle, TSS_SECRET_MODE_PLAIN, authorization_value.size(),
+      reinterpret_cast<BYTE*>(const_cast<char*>(authorization_value.data())));
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
     return false;
@@ -280,22 +499,19 @@
   return true;
 }
 
-bool TpmNvramImpl::SetCompositePcr0(ScopedTssPcrs* pcr_handle) {
+bool TpmNvramImpl::SetCompositePcr0(ScopedTssPcrs* pcr_handle,
+                                    TpmConnection* connection) {
   TSS_RESULT result = Tspi_Context_CreateObject(
-      tpm_connection_.GetContext(), TSS_OBJECT_TYPE_PCRS,
+      connection->GetContext(), TSS_OBJECT_TYPE_PCRS,
       TSS_PCRS_STRUCT_INFO_SHORT, pcr_handle->ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Could not acquire PCR object handle";
     return false;
   }
   uint32_t pcr_len;
-  std::string owner_password;
-  if (!GetOwnerPassword(&owner_password)) {
-    return false;
-  }
-  ScopedTssMemory pcr_value(tpm_connection_.GetContext());
-  result = Tspi_TPM_PcrRead(tpm_connection_.GetTpmWithAuth(owner_password),
-                            kTpmBootPCR, &pcr_len, pcr_value.ptr());
+  ScopedTssMemory pcr_value(connection->GetContext());
+  result = Tspi_TPM_PcrRead(connection->GetTpm(), kTpmBootPCR, &pcr_len,
+                            pcr_value.ptr());
   if (TPM_ERROR(result)) {
     TPM_LOG(ERROR, result) << "Could not read PCR0 value";
     return false;
diff --git a/tpm_manager/server/tpm_nvram_impl.h b/tpm_manager/server/tpm_nvram_impl.h
index ebe379b..ed195c3 100644
--- a/tpm_manager/server/tpm_nvram_impl.h
+++ b/tpm_manager/server/tpm_nvram_impl.h
@@ -35,31 +35,55 @@
 
 class TpmNvramImpl : public TpmNvram {
  public:
-  TpmNvramImpl(LocalDataStore* local_data_store);
+  explicit TpmNvramImpl(LocalDataStore* local_data_store);
   ~TpmNvramImpl() override = default;
 
   // TpmNvram methods.
-  bool DefineNvram(uint32_t index, size_t length) override;
-  bool DestroyNvram(uint32_t index) override;
-  bool WriteNvram(uint32_t index, const std::string& data) override;
-  bool ReadNvram(uint32_t index, std::string* data) override;
-  bool IsNvramDefined(uint32_t index, bool* defined) override;
-  bool IsNvramLocked(uint32_t index, bool* locked) override;
-  bool GetNvramSize(uint32_t index, size_t* size) override;
+  NvramResult DefineSpace(uint32_t index,
+                          size_t size,
+                          const std::vector<NvramSpaceAttribute>& attributes,
+                          const std::string& authorization_value,
+                          NvramSpacePolicy policy) override;
+  NvramResult DestroySpace(uint32_t index) override;
+  NvramResult WriteSpace(uint32_t index,
+                         const std::string& data,
+                         const std::string& authorization_value) override;
+  NvramResult ReadSpace(uint32_t index,
+                        std::string* data,
+                        const std::string& authorization_value) override;
+  NvramResult LockSpace(uint32_t index,
+                        bool lock_read,
+                        bool lock_write,
+                        const std::string& authorization_value) override;
+  NvramResult ListSpaces(std::vector<uint32_t>* index_list) override;
+  NvramResult GetSpaceInfo(
+      uint32_t index,
+      size_t* size,
+      bool* is_read_locked,
+      bool* is_write_locked,
+      std::vector<NvramSpaceAttribute>* attributes,
+      NvramSpacePolicy* policy) override;
 
  private:
   // This method creates and initializes the nvram object associated with
   // |handle| at |index|. Returns true on success, else false.
-  bool InitializeNvramHandle(trousers::ScopedTssNvStore* nv_handle,
-                             uint32_t index);
+  bool InitializeNvramHandle(uint32_t index,
+                             trousers::ScopedTssNvStore* nv_handle,
+                             TpmConnection* connection);
 
   // This method injects a tpm policy with the owner password. Returns true
   // on success.
   bool SetOwnerPolicy(trousers::ScopedTssNvStore* nv_handle);
 
+  // Set a usage policy for the handle with the given authorization_value.
+  bool SetUsagePolicy(const std::string& authorization_value,
+                      trousers::ScopedTssNvStore* nv_handle,
+                      TpmConnection* connection);
+
   // This method sets up the composite pcr provided by |pcr_handle| with the
   // value of PCR0 at locality 1. Returns true on success.
-  bool SetCompositePcr0(trousers::ScopedTssPcrs* pcr_handle);
+  bool SetCompositePcr0(trousers::ScopedTssPcrs* pcr_handle,
+                        TpmConnection* connection);
 
   // This method gets the owner password stored on disk and returns it via the
   // out argument |owner_password|. Returns true if we were able to read a
@@ -67,6 +91,7 @@
   bool GetOwnerPassword(std::string* owner_password);
 
   LocalDataStore* local_data_store_;
+  // A default non-owner connection.
   TpmConnection tpm_connection_;
 
   DISALLOW_COPY_AND_ASSIGN(TpmNvramImpl);
diff --git a/tpm_manager/tpm_manager.gyp b/tpm_manager/tpm_manager.gyp
index 412ac10..deb272a 100644
--- a/tpm_manager/tpm_manager.gyp
+++ b/tpm_manager/tpm_manager.gyp
@@ -30,7 +30,11 @@
       # "tpm_manager/...".
       '<(platform2_root)/../aosp/system/tpm/',
     ],
-    'defines': [ 'USE_TPM2=<(USE_tpm2)' ],
+    'conditions': [
+      ['USE_tpm2 == 1', {
+        'defines': [ 'USE_TPM2' ],
+      }],
+    ],
   },
   'targets': [
     # A library for just the protobufs.
@@ -43,11 +47,9 @@
       },
       'sources': [
         '<(proto_in_dir)/local_data.proto',
-        '<(proto_in_dir)/tpm_manager_status.proto',
         '<(proto_in_dir)/tpm_nvram_interface.proto',
         '<(proto_in_dir)/tpm_ownership_interface.proto',
         'common/print_local_data_proto.cc',
-        'common/print_tpm_manager_status_proto.cc',
         'common/print_tpm_nvram_interface_proto.cc',
         'common/print_tpm_ownership_interface_proto.cc',
       ],