trunks: Fixes and enhancements to support tpm_manager on brillo

- Enhanced NV utility methods
- Support PolicyRestart for policy sessions
- Support for read/extend PCR from trunks_client
- Cleanup scoped_ptr -> std::unique_ptr and other cleanup
- More robust factory semantics
- Support for setting dictionary attack parameters

BUG=b:25360511
TEST=builds on AOSP and chromiumos, unit tests, manual tests

Change-Id: I34fff802c0983b34e6d1ed082cb85ce57f08a54d
diff --git a/trunks/Android.mk b/trunks/Android.mk
index 86bf8ab..28d71ec 100644
--- a/trunks/Android.mk
+++ b/trunks/Android.mk
@@ -17,7 +17,12 @@
 # Common variables
 # ========================================================
 trunksCppExtension := .cc
-trunksCFlags := -Wall -Werror -Wno-unused-parameter -DUSE_BINDER_IPC
+trunksCFlags := \
+  -Wall -Werror \
+  -Wno-unused-parameter \
+  -DUSE_BINDER_IPC \
+  -fvisibility=hidden \
+
 trunksIncludes := $(LOCAL_PATH)/..
 trunksSharedLibraries := \
   libbinder \
@@ -60,7 +65,7 @@
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES := $(trunksIncludes)
 LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
-LOCAL_STATIC_LIBRARIES := libtrunks_generated libgtest_prod
+LOCAL_STATIC_LIBRARIES := libtrunks_generated
 LOCAL_SRC_FILES := \
   background_command_transceiver.cc \
   blob_parser.cc \
@@ -103,12 +108,10 @@
 LOCAL_SHARED_LIBRARIES += libtpm2
 endif
 LOCAL_STATIC_LIBRARIES := \
-  libgtest_prod \
   libtrunks_generated \
   libtrunks_common \
 
 LOCAL_REQUIRED_MODULES := \
-  com.android.Trunks.conf \
   trunksd-seccomp.policy \
 
 LOCAL_SRC_FILES := \
@@ -138,8 +141,8 @@
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES := $(trunksIncludes)
 LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
-LOCAL_STATIC_LIBRARIES := \
-  libgtest_prod \
+
+LOCAL_WHOLE_STATIC_LIBRARIES := \
   libtrunks_common \
   libtrunks_generated \
 
@@ -157,13 +160,39 @@
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES := $(trunksIncludes)
 LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries) libtrunks
-LOCAL_STATIC_LIBRARIES := libtrunks_common libgtest_prod
 LOCAL_SRC_FILES := \
   trunks_client.cc \
   trunks_client_test.cc \
 
 include $(BUILD_EXECUTABLE)
 
+# libtrunks_test
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtrunks_test
+LOCAL_MODULE_TAGS := eng
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
+LOCAL_SRC_FILES := \
+  mock_authorization_delegate.cc \
+  mock_blob_parser.cc \
+  mock_command_transceiver.cc \
+  mock_hmac_session.cc \
+  mock_policy_session.cc \
+  mock_session_manager.cc \
+  mock_tpm.cc \
+  mock_tpm_state.cc \
+  mock_tpm_utility.cc \
+  trunks_factory_for_test.cc \
+
+LOCAL_STATIC_LIBRARIES := \
+  libgmock \
+
+include $(BUILD_STATIC_LIBRARY)
+
 # Target unit tests
 # ========================================================
 include $(CLEAR_VARS)
@@ -178,15 +207,6 @@
   background_command_transceiver_test.cc \
   hmac_authorization_delegate_test.cc \
   hmac_session_test.cc \
-  mock_authorization_delegate.cc \
-  mock_blob_parser.cc \
-  mock_command_transceiver.cc \
-  mock_hmac_session.cc \
-  mock_policy_session.cc \
-  mock_session_manager.cc \
-  mock_tpm.cc \
-  mock_tpm_state.cc \
-  mock_tpm_utility.cc \
   password_authorization_delegate_test.cc \
   policy_session_test.cc \
   resource_manager.cc \
@@ -196,12 +216,12 @@
   tpm_generated_test.cc \
   tpm_state_test.cc \
   tpm_utility_test.cc \
-  trunks_factory_for_test.cc \
 
 LOCAL_STATIC_LIBRARIES := \
-  libgmock \
   libBionicGtestMain \
+  libgmock \
   libtrunks_common \
   libtrunks_generated \
+  libtrunks_test \
 
 include $(BUILD_NATIVE_TEST)
diff --git a/trunks/generator/generator.py b/trunks/generator/generator.py
index 06c7a40..6e50b9e 100755
--- a/trunks/generator/generator.py
+++ b/trunks/generator/generator.py
@@ -371,7 +371,7 @@
     value: The value of the constant (e.g. '7').
   """
 
-  _CONSTANT = 'const %(type)s %(name)s = %(value)s;\n'
+  _CONSTANT = 'constexpr %(type)s %(name)s = %(value)s;\n'
 
   def __init__(self, const_type, name, value):
     """Initializes a Constant instance.
@@ -904,7 +904,8 @@
       value: The value being assigned to the name.
     """
     self.name = name
-    self.value = value
+    # Prepend 'trunks::' to types.
+    self.value = re.sub(r'(TPM.?_|U?INT[0-9]{2})', r'trunks::\1', value)
 
   def Output(self, out_file):
     """Writes a preprocessor define to |out_file|.
diff --git a/trunks/mock_policy_session.h b/trunks/mock_policy_session.h
index 9edbfeb..243e84a 100644
--- a/trunks/mock_policy_session.h
+++ b/trunks/mock_policy_session.h
@@ -42,6 +42,7 @@
   MOCK_METHOD2(PolicyPCR, TPM_RC(uint32_t, const std::string&));
   MOCK_METHOD1(PolicyCommandCode, TPM_RC(TPM_CC));
   MOCK_METHOD0(PolicyAuthValue, TPM_RC());
+  MOCK_METHOD0(PolicyRestart, TPM_RC());
   MOCK_METHOD1(SetEntityAuthorizationValue, void(const std::string&));
 
  private:
diff --git a/trunks/mock_tpm_utility.h b/trunks/mock_tpm_utility.h
index 833e6b5..8a97443 100644
--- a/trunks/mock_tpm_utility.h
+++ b/trunks/mock_tpm_utility.h
@@ -114,17 +114,36 @@
   MOCK_METHOD1(StartSession, TPM_RC(HmacSession*));
   MOCK_METHOD3(GetPolicyDigestForPcrValue,
                TPM_RC(int, const std::string&, std::string*));
-  MOCK_METHOD3(DefineNVSpace, TPM_RC(uint32_t, size_t, AuthorizationDelegate*));
+  MOCK_METHOD6(DefineNVSpace,
+               TPM_RC(uint32_t,
+                      size_t,
+                      TPMA_NV,
+                      const std::string&,
+                      const std::string&,
+                      AuthorizationDelegate*));
   MOCK_METHOD2(DestroyNVSpace, TPM_RC(uint32_t, AuthorizationDelegate*));
-  MOCK_METHOD2(LockNVSpace, TPM_RC(uint32_t, AuthorizationDelegate*));
-  MOCK_METHOD4(
-      WriteNVSpace,
-      TPM_RC(uint32_t, uint32_t, const std::string&, AuthorizationDelegate*));
-  MOCK_METHOD5(
-      ReadNVSpace,
-      TPM_RC(uint32_t, uint32_t, size_t, std::string*, AuthorizationDelegate*));
+  MOCK_METHOD5(LockNVSpace,
+               TPM_RC(uint32_t, bool, bool, bool, AuthorizationDelegate*));
+  MOCK_METHOD6(WriteNVSpace,
+               TPM_RC(uint32_t,
+                      uint32_t,
+                      const std::string&,
+                      bool,
+                      bool,
+                      AuthorizationDelegate*));
+  MOCK_METHOD6(ReadNVSpace,
+               TPM_RC(uint32_t,
+                      uint32_t,
+                      size_t,
+                      bool,
+                      std::string*,
+                      AuthorizationDelegate*));
   MOCK_METHOD2(GetNVSpaceName, TPM_RC(uint32_t, std::string*));
   MOCK_METHOD2(GetNVSpacePublicArea, TPM_RC(uint32_t, TPMS_NV_PUBLIC*));
+  MOCK_METHOD1(ListNVSpaces, TPM_RC(std::vector<uint32_t>*));
+  MOCK_METHOD4(SetDictionaryAttackParameters,
+               TPM_RC(uint32_t, uint32_t, uint32_t, AuthorizationDelegate*));
+  MOCK_METHOD1(ResetDictionaryAttackLock, TPM_RC(AuthorizationDelegate*));
 };
 
 }  // namespace trunks
diff --git a/trunks/policy_session.h b/trunks/policy_session.h
index 14d8a81..e5ecafd 100644
--- a/trunks/policy_session.h
+++ b/trunks/policy_session.h
@@ -74,6 +74,9 @@
   // HMAC computation done by the AuthorizationDelegate.
   virtual TPM_RC PolicyAuthValue() = 0;
 
+  // Reset a policy session to its original state.
+  virtual TPM_RC PolicyRestart() = 0;
+
   // Sets the current entity authorization value. This can be safely called
   // while the session is active and subsequent commands will use the value.
   virtual void SetEntityAuthorizationValue(const std::string& value) = 0;
diff --git a/trunks/policy_session_impl.cc b/trunks/policy_session_impl.cc
index 8070c34..be9f781 100644
--- a/trunks/policy_session_impl.cc
+++ b/trunks/policy_session_impl.cc
@@ -170,6 +170,18 @@
   return TPM_RC_SUCCESS;
 }
 
+TPM_RC PolicySessionImpl::PolicyRestart() {
+  TPM_RC result = factory_.GetTpm()->PolicyAuthValueSync(
+      session_manager_->GetSessionHandle(),
+      "",  // No policy name is needed as we do no authorization checks.
+      nullptr);
+  if (result != TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Error performing PolicyRestart: " << GetErrorString(result);
+    return result;
+  }
+  return TPM_RC_SUCCESS;
+}
+
 void PolicySessionImpl::SetEntityAuthorizationValue(const std::string& value) {
   hmac_delegate_.set_entity_authorization_value(value);
 }
diff --git a/trunks/policy_session_impl.h b/trunks/policy_session_impl.h
index 7f78062..9810964 100644
--- a/trunks/policy_session_impl.h
+++ b/trunks/policy_session_impl.h
@@ -33,7 +33,6 @@
 // keeping track of the HmacAuthorizationDelegate used for commands, and to
 // provide authorization for commands that need it. It can also be used to
 // create custom policies to restrict the usage of keys.
-// TrunksFactoryImpl factory;
 // PolicySessionImpl session(factory);
 // session.StartBoundSession(bind_entity, bind_authorization, true);
 // session.PolicyPCR(pcr_index, pcr_value);
@@ -61,6 +60,7 @@
   TPM_RC PolicyPCR(uint32_t pcr_index, const std::string& pcr_value) override;
   TPM_RC PolicyCommandCode(TPM_CC command_code) override;
   TPM_RC PolicyAuthValue() override;
+  TPM_RC PolicyRestart() override;
   void SetEntityAuthorizationValue(const std::string& value) override;
 
  private:
diff --git a/trunks/resource_manager.cc b/trunks/resource_manager.cc
index 04cd7c5..bb7b37d 100644
--- a/trunks/resource_manager.cc
+++ b/trunks/resource_manager.cc
@@ -62,13 +62,10 @@
 ResourceManager::~ResourceManager() {}
 
 void ResourceManager::Initialize() {
-  TPM_RC result = factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr);
-  // Ignore TPM_RC_INITIALIZE, that means it was already started.
-  CHECK(result == TPM_RC_SUCCESS || result == TPM_RC_INITIALIZE)
-      << "TPM startup failure: " << GetErrorString(result);
-  result = factory_.GetTpm()->SelfTestSync(YES /* Full test. */, nullptr);
-  CHECK_EQ(result, TPM_RC_SUCCESS) << "TPM self-test failure: "
-                                   << GetErrorString(result);
+  // Abort if the TPM is not in a reasonable state and we can't get it into one.
+  std::unique_ptr<TpmUtility> tpm_utility = factory_.GetTpmUtility();
+  CHECK_EQ(tpm_utility->Startup(), TPM_RC_SUCCESS);
+  CHECK_EQ(tpm_utility->InitializeTpm(), TPM_RC_SUCCESS);
   // Full control of the TPM is assumed and required. Existing transient object
   // and session handles are mercilessly flushed.
   for (UINT32 handle_type :
@@ -77,7 +74,7 @@
     TPMS_CAPABILITY_DATA data;
     UINT32 handle_range = handle_type;
     while (more_data) {
-      result = factory_.GetTpm()->GetCapabilitySync(
+      TPM_RC result = factory_.GetTpm()->GetCapabilitySync(
           TPM_CAP_HANDLES, handle_range, MAX_CAP_HANDLES, &more_data, &data,
           nullptr);
       if (result != TPM_RC_SUCCESS) {
diff --git a/trunks/session_manager.h b/trunks/session_manager.h
index 3e0a14d..a90107b 100644
--- a/trunks/session_manager.h
+++ b/trunks/session_manager.h
@@ -22,7 +22,6 @@
 #include "trunks/hmac_authorization_delegate.h"
 #include "trunks/tpm_generated.h"
 #include "trunks/trunks_export.h"
-#include "trunks/trunks_factory.h"
 
 namespace trunks {
 
@@ -35,8 +34,8 @@
 // Note: This class is not intended to be used independently. However clients
 // who want to manually manage their sessions can use this class to Start and
 // Close TPM backed Sessions. Example usage:
-// trunks::TrunksFactoryImpl factory;
-// scoped_ptr<SessionManager> session_manager = factory.GetSessionManager();
+// std::unique_ptr<SessionManager> session_manager =
+//     factory.GetSessionManager();
 // session_manager->StartSession(...);
 // TPM_HANDLE session_handle = session_manager->GetSessionHandle();
 class TRUNKS_EXPORT SessionManager {
diff --git a/trunks/tpm_constants.h b/trunks/tpm_constants.h
index e06cc65..b8cf3bf 100644
--- a/trunks/tpm_constants.h
+++ b/trunks/tpm_constants.h
@@ -22,23 +22,41 @@
 namespace trunks {
 
 // TPM Object Attributes.
-const TPMA_OBJECT kFixedTPM = 1U << 1;
-const TPMA_OBJECT kFixedParent = 1U << 4;
-const TPMA_OBJECT kSensitiveDataOrigin = 1U << 5;
-const TPMA_OBJECT kUserWithAuth = 1U << 6;
-const TPMA_OBJECT kAdminWithPolicy = 1U << 7;
-const TPMA_OBJECT kNoDA = 1U << 10;
-const TPMA_OBJECT kRestricted = 1U << 16;
-const TPMA_OBJECT kDecrypt = 1U << 17;
-const TPMA_OBJECT kSign = 1U << 18;
+constexpr TPMA_OBJECT kFixedTPM = 1U << 1;
+constexpr TPMA_OBJECT kFixedParent = 1U << 4;
+constexpr TPMA_OBJECT kSensitiveDataOrigin = 1U << 5;
+constexpr TPMA_OBJECT kUserWithAuth = 1U << 6;
+constexpr TPMA_OBJECT kAdminWithPolicy = 1U << 7;
+constexpr TPMA_OBJECT kNoDA = 1U << 10;
+constexpr TPMA_OBJECT kRestricted = 1U << 16;
+constexpr TPMA_OBJECT kDecrypt = 1U << 17;
+constexpr TPMA_OBJECT kSign = 1U << 18;
 
 // TPM NV Index Attributes, defined in TPM Spec Part 2 section 13.2.
-const TPMA_NV TPMA_NV_OWNERWRITE = 1U << 1;
-const TPMA_NV TPMA_NV_WRITELOCKED = 1U << 11;
-const TPMA_NV TPMA_NV_WRITEDEFINE = 1U << 13;
-const TPMA_NV TPMA_NV_AUTHREAD = 1U << 18;
-const TPMA_NV TPMA_NV_NO_DA = 1U << 25;
-const TPMA_NV TPMA_NV_WRITTEN = 1U << 29;
+constexpr TPMA_NV TPMA_NV_PPWRITE = 1U << 0;
+constexpr TPMA_NV TPMA_NV_OWNERWRITE = 1U << 1;
+constexpr TPMA_NV TPMA_NV_AUTHWRITE = 1U << 2;
+constexpr TPMA_NV TPMA_NV_POLICYWRITE = 1U << 3;
+constexpr TPMA_NV TPMA_NV_COUNTER = 1U << 4;
+constexpr TPMA_NV TPMA_NV_BITS = 1U << 5;
+constexpr TPMA_NV TPMA_NV_EXTEND = 1U << 6;
+constexpr TPMA_NV TPMA_NV_POLICY_DELETE = 1U << 10;
+constexpr TPMA_NV TPMA_NV_WRITELOCKED = 1U << 11;
+constexpr TPMA_NV TPMA_NV_WRITEALL = 1U << 12;
+constexpr TPMA_NV TPMA_NV_WRITEDEFINE = 1U << 13;
+constexpr TPMA_NV TPMA_NV_WRITE_STCLEAR = 1U << 14;
+constexpr TPMA_NV TPMA_NV_GLOBALLOCK = 1U << 15;
+constexpr TPMA_NV TPMA_NV_PPREAD = 1U << 16;
+constexpr TPMA_NV TPMA_NV_OWNERREAD = 1U << 17;
+constexpr TPMA_NV TPMA_NV_AUTHREAD = 1U << 18;
+constexpr TPMA_NV TPMA_NV_POLICYREAD = 1U << 19;
+constexpr TPMA_NV TPMA_NV_NO_DA = 1U << 25;
+constexpr TPMA_NV TPMA_NV_ORDERLY = 1U << 26;
+constexpr TPMA_NV TPMA_NV_CLEAR_STCLEAR = 1U << 27;
+constexpr TPMA_NV TPMA_NV_READLOCKED = 1U << 28;
+constexpr TPMA_NV TPMA_NV_WRITTEN = 1U << 29;
+constexpr TPMA_NV TPMA_NV_PLATFORMCREATE = 1U << 30;
+constexpr TPMA_NV TPMA_NV_READ_STCLEAR = 1U << 31;
 
 }  // namespace trunks
 
diff --git a/trunks/tpm_generated.h b/trunks/tpm_generated.h
index 1044692..540ca3b 100644
--- a/trunks/tpm_generated.h
+++ b/trunks/tpm_generated.h
@@ -152,8 +152,11 @@
 #define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS + 7) / 8)
 #endif
 #if !defined(ECC_CURVES)
-#define ECC_CURVES \
-  { TPM_ECC_NIST_P256, TPM_ECC_BN_P256, TPM_ECC_SM2_P256 }
+#define ECC_CURVES                                      \
+  {                                                     \
+    trunks::TPM_ECC_NIST_P256, trunks::TPM_ECC_BN_P256, \
+        trunks::TPM_ECC_SM2_P256                        \
+  }
 #endif
 #if !defined(ECC_KEY_SIZES_BITS)
 #define ECC_KEY_SIZES_BITS \
@@ -204,7 +207,7 @@
 #define FIELD_UPGRADE_IMPLEMENTED NO
 #endif
 #if !defined(BSIZE)
-#define BSIZE UINT16
+#define BSIZE trunks::UINT16
 #endif
 #if !defined(BUFFER_ALIGNMENT)
 #define BUFFER_ALIGNMENT 4
@@ -231,10 +234,10 @@
 #define MAX_ACTIVE_SESSIONS 64
 #endif
 #if !defined(CONTEXT_SLOT)
-#define CONTEXT_SLOT UINT16
+#define CONTEXT_SLOT trunks::UINT16
 #endif
 #if !defined(CONTEXT_COUNTER)
-#define CONTEXT_COUNTER UINT64
+#define CONTEXT_COUNTER trunks::UINT64
 #endif
 #if !defined(MAX_LOADED_SESSIONS)
 #define MAX_LOADED_SESSIONS 3
@@ -291,7 +294,7 @@
 #define PRIMARY_SEED_SIZE 32
 #endif
 #if !defined(CONTEXT_ENCRYPT_ALG)
-#define CONTEXT_ENCRYPT_ALG TPM_ALG_AES
+#define CONTEXT_ENCRYPT_ALG trunks::TPM_ALG_AES
 #endif
 #if !defined(CONTEXT_ENCRYPT_KEY_BITS)
 #define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS
@@ -300,7 +303,7 @@
 #define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS + 7) / 8)
 #endif
 #if !defined(CONTEXT_INTEGRITY_HASH_ALG)
-#define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256
+#define CONTEXT_INTEGRITY_HASH_ALG trunks::TPM_ALG_SHA256
 #endif
 #if !defined(CONTEXT_INTEGRITY_HASH_SIZE)
 #define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE
@@ -327,10 +330,10 @@
 #define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1)
 #endif
 #if !defined(ALG_ID_FIRST)
-#define ALG_ID_FIRST TPM_ALG_FIRST
+#define ALG_ID_FIRST trunks::TPM_ALG_FIRST
 #endif
 #if !defined(ALG_ID_LAST)
-#define ALG_ID_LAST TPM_ALG_LAST
+#define ALG_ID_LAST trunks::TPM_ALG_LAST
 #endif
 #if !defined(MAX_SYM_DATA)
 #define MAX_SYM_DATA 128
@@ -355,25 +358,27 @@
   ((MAX_RSA_KEY_BYTES / 2) * (3 + CRT_FORMAT_RSA * 2))
 #endif
 #if !defined(MAX_CAP_DATA)
-#define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP) - sizeof(UINT32))
+#define MAX_CAP_DATA \
+  (MAX_CAP_BUFFER - sizeof(trunks::TPM_CAP) - sizeof(trunks::UINT32))
 #endif
 #if !defined(MAX_CAP_ALGS)
-#define MAX_CAP_ALGS (TPM_ALG_LAST - TPM_ALG_FIRST + 1)
+#define MAX_CAP_ALGS (trunks::TPM_ALG_LAST - trunks::TPM_ALG_FIRST + 1)
 #endif
 #if !defined(MAX_CAP_HANDLES)
-#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE))
+#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(trunks::TPM_HANDLE))
 #endif
 #if !defined(MAX_CAP_CC)
-#define MAX_CAP_CC ((TPM_CC_LAST - TPM_CC_FIRST) + 1)
+#define MAX_CAP_CC ((trunks::TPM_CC_LAST - trunks::TPM_CC_FIRST) + 1)
 #endif
 #if !defined(MAX_TPM_PROPERTIES)
-#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY))
+#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(trunks::TPMS_TAGGED_PROPERTY))
 #endif
 #if !defined(MAX_PCR_PROPERTIES)
-#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
+#define MAX_PCR_PROPERTIES \
+  (MAX_CAP_DATA / sizeof(trunks::TPMS_TAGGED_PCR_SELECT))
 #endif
 #if !defined(MAX_ECC_CURVES)
-#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
+#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(trunks::TPM_ECC_CURVE))
 #endif
 #if !defined(HASH_COUNT)
 #define HASH_COUNT 3
@@ -476,500 +481,501 @@
 typedef UINT32 TPM_RH;
 typedef TPM_HANDLE TPM_HC;
 
-const TPM_SPEC TPM_SPEC_FAMILY = 0x322E3000;
-const TPM_SPEC TPM_SPEC_LEVEL = 00;
-const TPM_SPEC TPM_SPEC_VERSION = 99;
-const TPM_SPEC TPM_SPEC_YEAR = 2013;
-const TPM_SPEC TPM_SPEC_DAY_OF_YEAR = 304;
-const TPM_GENERATED TPM_GENERATED_VALUE = 0xff544347;
-const TPM_ALG_ID TPM_ALG_ERROR = 0x0000;
-const TPM_ALG_ID TPM_ALG_FIRST = 0x0001;
-const TPM_ALG_ID TPM_ALG_RSA = 0x0001;
-const TPM_ALG_ID TPM_ALG_SHA = 0x0004;
-const TPM_ALG_ID TPM_ALG_SHA1 = 0x0004;
-const TPM_ALG_ID TPM_ALG_HMAC = 0x0005;
-const TPM_ALG_ID TPM_ALG_AES = 0x0006;
-const TPM_ALG_ID TPM_ALG_MGF1 = 0x0007;
-const TPM_ALG_ID TPM_ALG_KEYEDHASH = 0x0008;
-const TPM_ALG_ID TPM_ALG_XOR = 0x000A;
-const TPM_ALG_ID TPM_ALG_SHA256 = 0x000B;
-const TPM_ALG_ID TPM_ALG_SHA384 = 0x000C;
-const TPM_ALG_ID TPM_ALG_SHA512 = 0x000D;
-const TPM_ALG_ID TPM_ALG_NULL = 0x0010;
-const TPM_ALG_ID TPM_ALG_SM3_256 = 0x0012;
-const TPM_ALG_ID TPM_ALG_SM4 = 0x0013;
-const TPM_ALG_ID TPM_ALG_RSASSA = 0x0014;
-const TPM_ALG_ID TPM_ALG_RSAES = 0x0015;
-const TPM_ALG_ID TPM_ALG_RSAPSS = 0x0016;
-const TPM_ALG_ID TPM_ALG_OAEP = 0x0017;
-const TPM_ALG_ID TPM_ALG_ECDSA = 0x0018;
-const TPM_ALG_ID TPM_ALG_ECDH = 0x0019;
-const TPM_ALG_ID TPM_ALG_ECDAA = 0x001A;
-const TPM_ALG_ID TPM_ALG_SM2 = 0x001B;
-const TPM_ALG_ID TPM_ALG_ECSCHNORR = 0x001C;
-const TPM_ALG_ID TPM_ALG_ECMQV = 0x001D;
-const TPM_ALG_ID TPM_ALG_KDF1_SP800_56a = 0x0020;
-const TPM_ALG_ID TPM_ALG_KDF2 = 0x0021;
-const TPM_ALG_ID TPM_ALG_KDF1_SP800_108 = 0x0022;
-const TPM_ALG_ID TPM_ALG_ECC = 0x0023;
-const TPM_ALG_ID TPM_ALG_SYMCIPHER = 0x0025;
-const TPM_ALG_ID TPM_ALG_CTR = 0x0040;
-const TPM_ALG_ID TPM_ALG_OFB = 0x0041;
-const TPM_ALG_ID TPM_ALG_CBC = 0x0042;
-const TPM_ALG_ID TPM_ALG_CFB = 0x0043;
-const TPM_ALG_ID TPM_ALG_ECB = 0x0044;
-const TPM_ALG_ID TPM_ALG_LAST = 0x0044;
-const TPM_ECC_CURVE TPM_ECC_NONE = 0x0000;
-const TPM_ECC_CURVE TPM_ECC_NIST_P192 = 0x0001;
-const TPM_ECC_CURVE TPM_ECC_NIST_P224 = 0x0002;
-const TPM_ECC_CURVE TPM_ECC_NIST_P256 = 0x0003;
-const TPM_ECC_CURVE TPM_ECC_NIST_P384 = 0x0004;
-const TPM_ECC_CURVE TPM_ECC_NIST_P521 = 0x0005;
-const TPM_ECC_CURVE TPM_ECC_BN_P256 = 0x0010;
-const TPM_ECC_CURVE TPM_ECC_BN_P638 = 0x0011;
-const TPM_ECC_CURVE TPM_ECC_SM2_P256 = 0x0020;
-const TPM_CC TPM_CC_FIRST = 0x0000011F;
-const TPM_CC TPM_CC_PP_FIRST = 0x0000011F;
-const TPM_CC TPM_CC_NV_UndefineSpaceSpecial = 0x0000011F;
-const TPM_CC TPM_CC_EvictControl = 0x00000120;
-const TPM_CC TPM_CC_HierarchyControl = 0x00000121;
-const TPM_CC TPM_CC_NV_UndefineSpace = 0x00000122;
-const TPM_CC TPM_CC_ChangeEPS = 0x00000124;
-const TPM_CC TPM_CC_ChangePPS = 0x00000125;
-const TPM_CC TPM_CC_Clear = 0x00000126;
-const TPM_CC TPM_CC_ClearControl = 0x00000127;
-const TPM_CC TPM_CC_ClockSet = 0x00000128;
-const TPM_CC TPM_CC_HierarchyChangeAuth = 0x00000129;
-const TPM_CC TPM_CC_NV_DefineSpace = 0x0000012A;
-const TPM_CC TPM_CC_PCR_Allocate = 0x0000012B;
-const TPM_CC TPM_CC_PCR_SetAuthPolicy = 0x0000012C;
-const TPM_CC TPM_CC_PP_Commands = 0x0000012D;
-const TPM_CC TPM_CC_SetPrimaryPolicy = 0x0000012E;
-const TPM_CC TPM_CC_FieldUpgradeStart = 0x0000012F;
-const TPM_CC TPM_CC_ClockRateAdjust = 0x00000130;
-const TPM_CC TPM_CC_CreatePrimary = 0x00000131;
-const TPM_CC TPM_CC_NV_GlobalWriteLock = 0x00000132;
-const TPM_CC TPM_CC_PP_LAST = 0x00000132;
-const TPM_CC TPM_CC_GetCommandAuditDigest = 0x00000133;
-const TPM_CC TPM_CC_NV_Increment = 0x00000134;
-const TPM_CC TPM_CC_NV_SetBits = 0x00000135;
-const TPM_CC TPM_CC_NV_Extend = 0x00000136;
-const TPM_CC TPM_CC_NV_Write = 0x00000137;
-const TPM_CC TPM_CC_NV_WriteLock = 0x00000138;
-const TPM_CC TPM_CC_DictionaryAttackLockReset = 0x00000139;
-const TPM_CC TPM_CC_DictionaryAttackParameters = 0x0000013A;
-const TPM_CC TPM_CC_NV_ChangeAuth = 0x0000013B;
-const TPM_CC TPM_CC_PCR_Event = 0x0000013C;
-const TPM_CC TPM_CC_PCR_Reset = 0x0000013D;
-const TPM_CC TPM_CC_SequenceComplete = 0x0000013E;
-const TPM_CC TPM_CC_SetAlgorithmSet = 0x0000013F;
-const TPM_CC TPM_CC_SetCommandCodeAuditStatus = 0x00000140;
-const TPM_CC TPM_CC_FieldUpgradeData = 0x00000141;
-const TPM_CC TPM_CC_IncrementalSelfTest = 0x00000142;
-const TPM_CC TPM_CC_SelfTest = 0x00000143;
-const TPM_CC TPM_CC_Startup = 0x00000144;
-const TPM_CC TPM_CC_Shutdown = 0x00000145;
-const TPM_CC TPM_CC_StirRandom = 0x00000146;
-const TPM_CC TPM_CC_ActivateCredential = 0x00000147;
-const TPM_CC TPM_CC_Certify = 0x00000148;
-const TPM_CC TPM_CC_PolicyNV = 0x00000149;
-const TPM_CC TPM_CC_CertifyCreation = 0x0000014A;
-const TPM_CC TPM_CC_Duplicate = 0x0000014B;
-const TPM_CC TPM_CC_GetTime = 0x0000014C;
-const TPM_CC TPM_CC_GetSessionAuditDigest = 0x0000014D;
-const TPM_CC TPM_CC_NV_Read = 0x0000014E;
-const TPM_CC TPM_CC_NV_ReadLock = 0x0000014F;
-const TPM_CC TPM_CC_ObjectChangeAuth = 0x00000150;
-const TPM_CC TPM_CC_PolicySecret = 0x00000151;
-const TPM_CC TPM_CC_Rewrap = 0x00000152;
-const TPM_CC TPM_CC_Create = 0x00000153;
-const TPM_CC TPM_CC_ECDH_ZGen = 0x00000154;
-const TPM_CC TPM_CC_HMAC = 0x00000155;
-const TPM_CC TPM_CC_Import = 0x00000156;
-const TPM_CC TPM_CC_Load = 0x00000157;
-const TPM_CC TPM_CC_Quote = 0x00000158;
-const TPM_CC TPM_CC_RSA_Decrypt = 0x00000159;
-const TPM_CC TPM_CC_HMAC_Start = 0x0000015B;
-const TPM_CC TPM_CC_SequenceUpdate = 0x0000015C;
-const TPM_CC TPM_CC_Sign = 0x0000015D;
-const TPM_CC TPM_CC_Unseal = 0x0000015E;
-const TPM_CC TPM_CC_PolicySigned = 0x00000160;
-const TPM_CC TPM_CC_ContextLoad = 0x00000161;
-const TPM_CC TPM_CC_ContextSave = 0x00000162;
-const TPM_CC TPM_CC_ECDH_KeyGen = 0x00000163;
-const TPM_CC TPM_CC_EncryptDecrypt = 0x00000164;
-const TPM_CC TPM_CC_FlushContext = 0x00000165;
-const TPM_CC TPM_CC_LoadExternal = 0x00000167;
-const TPM_CC TPM_CC_MakeCredential = 0x00000168;
-const TPM_CC TPM_CC_NV_ReadPublic = 0x00000169;
-const TPM_CC TPM_CC_PolicyAuthorize = 0x0000016A;
-const TPM_CC TPM_CC_PolicyAuthValue = 0x0000016B;
-const TPM_CC TPM_CC_PolicyCommandCode = 0x0000016C;
-const TPM_CC TPM_CC_PolicyCounterTimer = 0x0000016D;
-const TPM_CC TPM_CC_PolicyCpHash = 0x0000016E;
-const TPM_CC TPM_CC_PolicyLocality = 0x0000016F;
-const TPM_CC TPM_CC_PolicyNameHash = 0x00000170;
-const TPM_CC TPM_CC_PolicyOR = 0x00000171;
-const TPM_CC TPM_CC_PolicyTicket = 0x00000172;
-const TPM_CC TPM_CC_ReadPublic = 0x00000173;
-const TPM_CC TPM_CC_RSA_Encrypt = 0x00000174;
-const TPM_CC TPM_CC_StartAuthSession = 0x00000176;
-const TPM_CC TPM_CC_VerifySignature = 0x00000177;
-const TPM_CC TPM_CC_ECC_Parameters = 0x00000178;
-const TPM_CC TPM_CC_FirmwareRead = 0x00000179;
-const TPM_CC TPM_CC_GetCapability = 0x0000017A;
-const TPM_CC TPM_CC_GetRandom = 0x0000017B;
-const TPM_CC TPM_CC_GetTestResult = 0x0000017C;
-const TPM_CC TPM_CC_Hash = 0x0000017D;
-const TPM_CC TPM_CC_PCR_Read = 0x0000017E;
-const TPM_CC TPM_CC_PolicyPCR = 0x0000017F;
-const TPM_CC TPM_CC_PolicyRestart = 0x00000180;
-const TPM_CC TPM_CC_ReadClock = 0x00000181;
-const TPM_CC TPM_CC_PCR_Extend = 0x00000182;
-const TPM_CC TPM_CC_PCR_SetAuthValue = 0x00000183;
-const TPM_CC TPM_CC_NV_Certify = 0x00000184;
-const TPM_CC TPM_CC_EventSequenceComplete = 0x00000185;
-const TPM_CC TPM_CC_HashSequenceStart = 0x00000186;
-const TPM_CC TPM_CC_PolicyPhysicalPresence = 0x00000187;
-const TPM_CC TPM_CC_PolicyDuplicationSelect = 0x00000188;
-const TPM_CC TPM_CC_PolicyGetDigest = 0x00000189;
-const TPM_CC TPM_CC_TestParms = 0x0000018A;
-const TPM_CC TPM_CC_Commit = 0x0000018B;
-const TPM_CC TPM_CC_PolicyPassword = 0x0000018C;
-const TPM_CC TPM_CC_ZGen_2Phase = 0x0000018D;
-const TPM_CC TPM_CC_EC_Ephemeral = 0x0000018E;
-const TPM_CC TPM_CC_PolicyNvWritten = 0x0000018F;
-const TPM_CC TPM_CC_LAST = 0x0000018F;
-const TPM_RC TPM_RC_SUCCESS = 0x000;
-const TPM_RC TPM_RC_BAD_TAG = 0x01E;
-const TPM_RC RC_VER1 = 0x100;
-const TPM_RC TPM_RC_INITIALIZE = RC_VER1 + 0x000;
-const TPM_RC TPM_RC_FAILURE = RC_VER1 + 0x001;
-const TPM_RC TPM_RC_SEQUENCE = RC_VER1 + 0x003;
-const TPM_RC TPM_RC_PRIVATE = RC_VER1 + 0x00B;
-const TPM_RC TPM_RC_HMAC = RC_VER1 + 0x019;
-const TPM_RC TPM_RC_DISABLED = RC_VER1 + 0x020;
-const TPM_RC TPM_RC_EXCLUSIVE = RC_VER1 + 0x021;
-const TPM_RC TPM_RC_AUTH_TYPE = RC_VER1 + 0x024;
-const TPM_RC TPM_RC_AUTH_MISSING = RC_VER1 + 0x025;
-const TPM_RC TPM_RC_POLICY = RC_VER1 + 0x026;
-const TPM_RC TPM_RC_PCR = RC_VER1 + 0x027;
-const TPM_RC TPM_RC_PCR_CHANGED = RC_VER1 + 0x028;
-const TPM_RC TPM_RC_UPGRADE = RC_VER1 + 0x02D;
-const TPM_RC TPM_RC_TOO_MANY_CONTEXTS = RC_VER1 + 0x02E;
-const TPM_RC TPM_RC_AUTH_UNAVAILABLE = RC_VER1 + 0x02F;
-const TPM_RC TPM_RC_REBOOT = RC_VER1 + 0x030;
-const TPM_RC TPM_RC_UNBALANCED = RC_VER1 + 0x031;
-const TPM_RC TPM_RC_COMMAND_SIZE = RC_VER1 + 0x042;
-const TPM_RC TPM_RC_COMMAND_CODE = RC_VER1 + 0x043;
-const TPM_RC TPM_RC_AUTHSIZE = RC_VER1 + 0x044;
-const TPM_RC TPM_RC_AUTH_CONTEXT = RC_VER1 + 0x045;
-const TPM_RC TPM_RC_NV_RANGE = RC_VER1 + 0x046;
-const TPM_RC TPM_RC_NV_SIZE = RC_VER1 + 0x047;
-const TPM_RC TPM_RC_NV_LOCKED = RC_VER1 + 0x048;
-const TPM_RC TPM_RC_NV_AUTHORIZATION = RC_VER1 + 0x049;
-const TPM_RC TPM_RC_NV_UNINITIALIZED = RC_VER1 + 0x04A;
-const TPM_RC TPM_RC_NV_SPACE = RC_VER1 + 0x04B;
-const TPM_RC TPM_RC_NV_DEFINED = RC_VER1 + 0x04C;
-const TPM_RC TPM_RC_BAD_CONTEXT = RC_VER1 + 0x050;
-const TPM_RC TPM_RC_CPHASH = RC_VER1 + 0x051;
-const TPM_RC TPM_RC_PARENT = RC_VER1 + 0x052;
-const TPM_RC TPM_RC_NEEDS_TEST = RC_VER1 + 0x053;
-const TPM_RC TPM_RC_NO_RESULT = RC_VER1 + 0x054;
-const TPM_RC TPM_RC_SENSITIVE = RC_VER1 + 0x055;
-const TPM_RC RC_MAX_FM0 = RC_VER1 + 0x07F;
-const TPM_RC RC_FMT1 = 0x080;
-const TPM_RC TPM_RC_ASYMMETRIC = RC_FMT1 + 0x001;
-const TPM_RC TPM_RC_ATTRIBUTES = RC_FMT1 + 0x002;
-const TPM_RC TPM_RC_HASH = RC_FMT1 + 0x003;
-const TPM_RC TPM_RC_VALUE = RC_FMT1 + 0x004;
-const TPM_RC TPM_RC_HIERARCHY = RC_FMT1 + 0x005;
-const TPM_RC TPM_RC_KEY_SIZE = RC_FMT1 + 0x007;
-const TPM_RC TPM_RC_MGF = RC_FMT1 + 0x008;
-const TPM_RC TPM_RC_MODE = RC_FMT1 + 0x009;
-const TPM_RC TPM_RC_TYPE = RC_FMT1 + 0x00A;
-const TPM_RC TPM_RC_HANDLE = RC_FMT1 + 0x00B;
-const TPM_RC TPM_RC_KDF = RC_FMT1 + 0x00C;
-const TPM_RC TPM_RC_RANGE = RC_FMT1 + 0x00D;
-const TPM_RC TPM_RC_AUTH_FAIL = RC_FMT1 + 0x00E;
-const TPM_RC TPM_RC_NONCE = RC_FMT1 + 0x00F;
-const TPM_RC TPM_RC_PP = RC_FMT1 + 0x010;
-const TPM_RC TPM_RC_SCHEME = RC_FMT1 + 0x012;
-const TPM_RC TPM_RC_SIZE = RC_FMT1 + 0x015;
-const TPM_RC TPM_RC_SYMMETRIC = RC_FMT1 + 0x016;
-const TPM_RC TPM_RC_TAG = RC_FMT1 + 0x017;
-const TPM_RC TPM_RC_SELECTOR = RC_FMT1 + 0x018;
-const TPM_RC TPM_RC_INSUFFICIENT = RC_FMT1 + 0x01A;
-const TPM_RC TPM_RC_SIGNATURE = RC_FMT1 + 0x01B;
-const TPM_RC TPM_RC_KEY = RC_FMT1 + 0x01C;
-const TPM_RC TPM_RC_POLICY_FAIL = RC_FMT1 + 0x01D;
-const TPM_RC TPM_RC_INTEGRITY = RC_FMT1 + 0x01F;
-const TPM_RC TPM_RC_TICKET = RC_FMT1 + 0x020;
-const TPM_RC TPM_RC_RESERVED_BITS = RC_FMT1 + 0x021;
-const TPM_RC TPM_RC_BAD_AUTH = RC_FMT1 + 0x022;
-const TPM_RC TPM_RC_EXPIRED = RC_FMT1 + 0x023;
-const TPM_RC TPM_RC_POLICY_CC = RC_FMT1 + 0x024;
-const TPM_RC TPM_RC_BINDING = RC_FMT1 + 0x025;
-const TPM_RC TPM_RC_CURVE = RC_FMT1 + 0x026;
-const TPM_RC TPM_RC_ECC_POINT = RC_FMT1 + 0x027;
-const TPM_RC RC_WARN = 0x900;
-const TPM_RC TPM_RC_CONTEXT_GAP = RC_WARN + 0x001;
-const TPM_RC TPM_RC_OBJECT_MEMORY = RC_WARN + 0x002;
-const TPM_RC TPM_RC_SESSION_MEMORY = RC_WARN + 0x003;
-const TPM_RC TPM_RC_MEMORY = RC_WARN + 0x004;
-const TPM_RC TPM_RC_SESSION_HANDLES = RC_WARN + 0x005;
-const TPM_RC TPM_RC_OBJECT_HANDLES = RC_WARN + 0x006;
-const TPM_RC TPM_RC_LOCALITY = RC_WARN + 0x007;
-const TPM_RC TPM_RC_YIELDED = RC_WARN + 0x008;
-const TPM_RC TPM_RC_CANCELED = RC_WARN + 0x009;
-const TPM_RC TPM_RC_TESTING = RC_WARN + 0x00A;
-const TPM_RC TPM_RC_REFERENCE_H0 = RC_WARN + 0x010;
-const TPM_RC TPM_RC_REFERENCE_H1 = RC_WARN + 0x011;
-const TPM_RC TPM_RC_REFERENCE_H2 = RC_WARN + 0x012;
-const TPM_RC TPM_RC_REFERENCE_H3 = RC_WARN + 0x013;
-const TPM_RC TPM_RC_REFERENCE_H4 = RC_WARN + 0x014;
-const TPM_RC TPM_RC_REFERENCE_H5 = RC_WARN + 0x015;
-const TPM_RC TPM_RC_REFERENCE_H6 = RC_WARN + 0x016;
-const TPM_RC TPM_RC_REFERENCE_S0 = RC_WARN + 0x018;
-const TPM_RC TPM_RC_REFERENCE_S1 = RC_WARN + 0x019;
-const TPM_RC TPM_RC_REFERENCE_S2 = RC_WARN + 0x01A;
-const TPM_RC TPM_RC_REFERENCE_S3 = RC_WARN + 0x01B;
-const TPM_RC TPM_RC_REFERENCE_S4 = RC_WARN + 0x01C;
-const TPM_RC TPM_RC_REFERENCE_S5 = RC_WARN + 0x01D;
-const TPM_RC TPM_RC_REFERENCE_S6 = RC_WARN + 0x01E;
-const TPM_RC TPM_RC_NV_RATE = RC_WARN + 0x020;
-const TPM_RC TPM_RC_LOCKOUT = RC_WARN + 0x021;
-const TPM_RC TPM_RC_RETRY = RC_WARN + 0x022;
-const TPM_RC TPM_RC_NV_UNAVAILABLE = RC_WARN + 0x023;
-const TPM_RC TPM_RC_NOT_USED = RC_WARN + 0x7F;
-const TPM_RC TPM_RC_H = 0x000;
-const TPM_RC TPM_RC_P = 0x040;
-const TPM_RC TPM_RC_S = 0x800;
-const TPM_RC TPM_RC_1 = 0x100;
-const TPM_RC TPM_RC_2 = 0x200;
-const TPM_RC TPM_RC_3 = 0x300;
-const TPM_RC TPM_RC_4 = 0x400;
-const TPM_RC TPM_RC_5 = 0x500;
-const TPM_RC TPM_RC_6 = 0x600;
-const TPM_RC TPM_RC_7 = 0x700;
-const TPM_RC TPM_RC_8 = 0x800;
-const TPM_RC TPM_RC_9 = 0x900;
-const TPM_RC TPM_RC_A = 0xA00;
-const TPM_RC TPM_RC_B = 0xB00;
-const TPM_RC TPM_RC_C = 0xC00;
-const TPM_RC TPM_RC_D = 0xD00;
-const TPM_RC TPM_RC_E = 0xE00;
-const TPM_RC TPM_RC_F = 0xF00;
-const TPM_RC TPM_RC_N_MASK = 0xF00;
-const TPM_CLOCK_ADJUST TPM_CLOCK_COARSE_SLOWER = -3;
-const TPM_CLOCK_ADJUST TPM_CLOCK_MEDIUM_SLOWER = -2;
-const TPM_CLOCK_ADJUST TPM_CLOCK_FINE_SLOWER = -1;
-const TPM_CLOCK_ADJUST TPM_CLOCK_NO_CHANGE = 0;
-const TPM_CLOCK_ADJUST TPM_CLOCK_FINE_FASTER = 1;
-const TPM_CLOCK_ADJUST TPM_CLOCK_MEDIUM_FASTER = 2;
-const TPM_CLOCK_ADJUST TPM_CLOCK_COARSE_FASTER = 3;
-const TPM_EO TPM_EO_EQ = 0x0000;
-const TPM_EO TPM_EO_NEQ = 0x0001;
-const TPM_EO TPM_EO_SIGNED_GT = 0x0002;
-const TPM_EO TPM_EO_UNSIGNED_GT = 0x0003;
-const TPM_EO TPM_EO_SIGNED_LT = 0x0004;
-const TPM_EO TPM_EO_UNSIGNED_LT = 0x0005;
-const TPM_EO TPM_EO_SIGNED_GE = 0x0006;
-const TPM_EO TPM_EO_UNSIGNED_GE = 0x0007;
-const TPM_EO TPM_EO_SIGNED_LE = 0x0008;
-const TPM_EO TPM_EO_UNSIGNED_LE = 0x0009;
-const TPM_EO TPM_EO_BITSET = 0x000A;
-const TPM_EO TPM_EO_BITCLEAR = 0x000B;
-const TPM_ST TPM_ST_RSP_COMMAND = 0x00C4;
-const TPM_ST TPM_ST_NULL = 0X8000;
-const TPM_ST TPM_ST_NO_SESSIONS = 0x8001;
-const TPM_ST TPM_ST_SESSIONS = 0x8002;
-const TPM_ST TPM_ST_ATTEST_NV = 0x8014;
-const TPM_ST TPM_ST_ATTEST_COMMAND_AUDIT = 0x8015;
-const TPM_ST TPM_ST_ATTEST_SESSION_AUDIT = 0x8016;
-const TPM_ST TPM_ST_ATTEST_CERTIFY = 0x8017;
-const TPM_ST TPM_ST_ATTEST_QUOTE = 0x8018;
-const TPM_ST TPM_ST_ATTEST_TIME = 0x8019;
-const TPM_ST TPM_ST_ATTEST_CREATION = 0x801A;
-const TPM_ST TPM_ST_CREATION = 0x8021;
-const TPM_ST TPM_ST_VERIFIED = 0x8022;
-const TPM_ST TPM_ST_AUTH_SECRET = 0x8023;
-const TPM_ST TPM_ST_HASHCHECK = 0x8024;
-const TPM_ST TPM_ST_AUTH_SIGNED = 0x8025;
-const TPM_ST TPM_ST_FU_MANIFEST = 0x8029;
-const TPM_SU TPM_SU_CLEAR = 0x0000;
-const TPM_SU TPM_SU_STATE = 0x0001;
-const TPM_SE TPM_SE_HMAC = 0x00;
-const TPM_SE TPM_SE_POLICY = 0x01;
-const TPM_SE TPM_SE_TRIAL = 0x03;
-const TPM_CAP TPM_CAP_FIRST = 0x00000000;
-const TPM_CAP TPM_CAP_ALGS = 0x00000000;
-const TPM_CAP TPM_CAP_HANDLES = 0x00000001;
-const TPM_CAP TPM_CAP_COMMANDS = 0x00000002;
-const TPM_CAP TPM_CAP_PP_COMMANDS = 0x00000003;
-const TPM_CAP TPM_CAP_AUDIT_COMMANDS = 0x00000004;
-const TPM_CAP TPM_CAP_PCRS = 0x00000005;
-const TPM_CAP TPM_CAP_TPM_PROPERTIES = 0x00000006;
-const TPM_CAP TPM_CAP_PCR_PROPERTIES = 0x00000007;
-const TPM_CAP TPM_CAP_ECC_CURVES = 0x00000008;
-const TPM_CAP TPM_CAP_LAST = 0x00000008;
-const TPM_CAP TPM_CAP_VENDOR_PROPERTY = 0x00000100;
-const TPM_PT TPM_PT_NONE = 0x00000000;
-const TPM_PT PT_GROUP = 0x00000100;
-const TPM_PT PT_FIXED = PT_GROUP * 1;
-const TPM_PT TPM_PT_FAMILY_INDICATOR = PT_FIXED + 0;
-const TPM_PT TPM_PT_LEVEL = PT_FIXED + 1;
-const TPM_PT TPM_PT_REVISION = PT_FIXED + 2;
-const TPM_PT TPM_PT_DAY_OF_YEAR = PT_FIXED + 3;
-const TPM_PT TPM_PT_YEAR = PT_FIXED + 4;
-const TPM_PT TPM_PT_MANUFACTURER = PT_FIXED + 5;
-const TPM_PT TPM_PT_VENDOR_STRING_1 = PT_FIXED + 6;
-const TPM_PT TPM_PT_VENDOR_STRING_2 = PT_FIXED + 7;
-const TPM_PT TPM_PT_VENDOR_STRING_3 = PT_FIXED + 8;
-const TPM_PT TPM_PT_VENDOR_STRING_4 = PT_FIXED + 9;
-const TPM_PT TPM_PT_VENDOR_TPM_TYPE = PT_FIXED + 10;
-const TPM_PT TPM_PT_FIRMWARE_VERSION_1 = PT_FIXED + 11;
-const TPM_PT TPM_PT_FIRMWARE_VERSION_2 = PT_FIXED + 12;
-const TPM_PT TPM_PT_INPUT_BUFFER = PT_FIXED + 13;
-const TPM_PT TPM_PT_HR_TRANSIENT_MIN = PT_FIXED + 14;
-const TPM_PT TPM_PT_HR_PERSISTENT_MIN = PT_FIXED + 15;
-const TPM_PT TPM_PT_HR_LOADED_MIN = PT_FIXED + 16;
-const TPM_PT TPM_PT_ACTIVE_SESSIONS_MAX = PT_FIXED + 17;
-const TPM_PT TPM_PT_PCR_COUNT = PT_FIXED + 18;
-const TPM_PT TPM_PT_PCR_SELECT_MIN = PT_FIXED + 19;
-const TPM_PT TPM_PT_CONTEXT_GAP_MAX = PT_FIXED + 20;
-const TPM_PT TPM_PT_NV_COUNTERS_MAX = PT_FIXED + 22;
-const TPM_PT TPM_PT_NV_INDEX_MAX = PT_FIXED + 23;
-const TPM_PT TPM_PT_MEMORY = PT_FIXED + 24;
-const TPM_PT TPM_PT_CLOCK_UPDATE = PT_FIXED + 25;
-const TPM_PT TPM_PT_CONTEXT_HASH = PT_FIXED + 26;
-const TPM_PT TPM_PT_CONTEXT_SYM = PT_FIXED + 27;
-const TPM_PT TPM_PT_CONTEXT_SYM_SIZE = PT_FIXED + 28;
-const TPM_PT TPM_PT_ORDERLY_COUNT = PT_FIXED + 29;
-const TPM_PT TPM_PT_MAX_COMMAND_SIZE = PT_FIXED + 30;
-const TPM_PT TPM_PT_MAX_RESPONSE_SIZE = PT_FIXED + 31;
-const TPM_PT TPM_PT_MAX_DIGEST = PT_FIXED + 32;
-const TPM_PT TPM_PT_MAX_OBJECT_CONTEXT = PT_FIXED + 33;
-const TPM_PT TPM_PT_MAX_SESSION_CONTEXT = PT_FIXED + 34;
-const TPM_PT TPM_PT_PS_FAMILY_INDICATOR = PT_FIXED + 35;
-const TPM_PT TPM_PT_PS_LEVEL = PT_FIXED + 36;
-const TPM_PT TPM_PT_PS_REVISION = PT_FIXED + 37;
-const TPM_PT TPM_PT_PS_DAY_OF_YEAR = PT_FIXED + 38;
-const TPM_PT TPM_PT_PS_YEAR = PT_FIXED + 39;
-const TPM_PT TPM_PT_SPLIT_MAX = PT_FIXED + 40;
-const TPM_PT TPM_PT_TOTAL_COMMANDS = PT_FIXED + 41;
-const TPM_PT TPM_PT_LIBRARY_COMMANDS = PT_FIXED + 42;
-const TPM_PT TPM_PT_VENDOR_COMMANDS = PT_FIXED + 43;
-const TPM_PT TPM_PT_NV_BUFFER_MAX = PT_FIXED + 44;
-const TPM_PT PT_VAR = PT_GROUP * 2;
-const TPM_PT TPM_PT_PERMANENT = PT_VAR + 0;
-const TPM_PT TPM_PT_STARTUP_CLEAR = PT_VAR + 1;
-const TPM_PT TPM_PT_HR_NV_INDEX = PT_VAR + 2;
-const TPM_PT TPM_PT_HR_LOADED = PT_VAR + 3;
-const TPM_PT TPM_PT_HR_LOADED_AVAIL = PT_VAR + 4;
-const TPM_PT TPM_PT_HR_ACTIVE = PT_VAR + 5;
-const TPM_PT TPM_PT_HR_ACTIVE_AVAIL = PT_VAR + 6;
-const TPM_PT TPM_PT_HR_TRANSIENT_AVAIL = PT_VAR + 7;
-const TPM_PT TPM_PT_HR_PERSISTENT = PT_VAR + 8;
-const TPM_PT TPM_PT_HR_PERSISTENT_AVAIL = PT_VAR + 9;
-const TPM_PT TPM_PT_NV_COUNTERS = PT_VAR + 10;
-const TPM_PT TPM_PT_NV_COUNTERS_AVAIL = PT_VAR + 11;
-const TPM_PT TPM_PT_ALGORITHM_SET = PT_VAR + 12;
-const TPM_PT TPM_PT_LOADED_CURVES = PT_VAR + 13;
-const TPM_PT TPM_PT_LOCKOUT_COUNTER = PT_VAR + 14;
-const TPM_PT TPM_PT_MAX_AUTH_FAIL = PT_VAR + 15;
-const TPM_PT TPM_PT_LOCKOUT_INTERVAL = PT_VAR + 16;
-const TPM_PT TPM_PT_LOCKOUT_RECOVERY = PT_VAR + 17;
-const TPM_PT TPM_PT_NV_WRITE_RECOVERY = PT_VAR + 18;
-const TPM_PT TPM_PT_AUDIT_COUNTER_0 = PT_VAR + 19;
-const TPM_PT TPM_PT_AUDIT_COUNTER_1 = PT_VAR + 20;
-const TPM_PT_PCR TPM_PT_PCR_FIRST = 0x00000000;
-const TPM_PT_PCR TPM_PT_PCR_SAVE = 0x00000000;
-const TPM_PT_PCR TPM_PT_PCR_EXTEND_L0 = 0x00000001;
-const TPM_PT_PCR TPM_PT_PCR_RESET_L0 = 0x00000002;
-const TPM_PT_PCR TPM_PT_PCR_EXTEND_L1 = 0x00000003;
-const TPM_PT_PCR TPM_PT_PCR_RESET_L1 = 0x00000004;
-const TPM_PT_PCR TPM_PT_PCR_EXTEND_L2 = 0x00000005;
-const TPM_PT_PCR TPM_PT_PCR_RESET_L2 = 0x00000006;
-const TPM_PT_PCR TPM_PT_PCR_EXTEND_L3 = 0x00000007;
-const TPM_PT_PCR TPM_PT_PCR_RESET_L3 = 0x00000008;
-const TPM_PT_PCR TPM_PT_PCR_EXTEND_L4 = 0x00000009;
-const TPM_PT_PCR TPM_PT_PCR_RESET_L4 = 0x0000000A;
-const TPM_PT_PCR TPM_PT_PCR_NO_INCREMENT = 0x00000011;
-const TPM_PT_PCR TPM_PT_PCR_DRTM_RESET = 0x00000012;
-const TPM_PT_PCR TPM_PT_PCR_POLICY = 0x00000013;
-const TPM_PT_PCR TPM_PT_PCR_AUTH = 0x00000014;
-const TPM_PT_PCR TPM_PT_PCR_LAST = 0x00000014;
-const TPM_PS TPM_PS_MAIN = 0x00000000;
-const TPM_PS TPM_PS_PC = 0x00000001;
-const TPM_PS TPM_PS_PDA = 0x00000002;
-const TPM_PS TPM_PS_CELL_PHONE = 0x00000003;
-const TPM_PS TPM_PS_SERVER = 0x00000004;
-const TPM_PS TPM_PS_PERIPHERAL = 0x00000005;
-const TPM_PS TPM_PS_TSS = 0x00000006;
-const TPM_PS TPM_PS_STORAGE = 0x00000007;
-const TPM_PS TPM_PS_AUTHENTICATION = 0x00000008;
-const TPM_PS TPM_PS_EMBEDDED = 0x00000009;
-const TPM_PS TPM_PS_HARDCOPY = 0x0000000A;
-const TPM_PS TPM_PS_INFRASTRUCTURE = 0x0000000B;
-const TPM_PS TPM_PS_VIRTUALIZATION = 0x0000000C;
-const TPM_PS TPM_PS_TNC = 0x0000000D;
-const TPM_PS TPM_PS_MULTI_TENANT = 0x0000000E;
-const TPM_PS TPM_PS_TC = 0x0000000F;
-const TPM_HT TPM_HT_PCR = 0x00;
-const TPM_HT TPM_HT_NV_INDEX = 0x01;
-const TPM_HT TPM_HT_HMAC_SESSION = 0x02;
-const TPM_HT TPM_HT_LOADED_SESSION = 0x02;
-const TPM_HT TPM_HT_POLICY_SESSION = 0x03;
-const TPM_HT TPM_HT_ACTIVE_SESSION = 0x03;
-const TPM_HT TPM_HT_PERMANENT = 0x40;
-const TPM_HT TPM_HT_TRANSIENT = 0x80;
-const TPM_HT TPM_HT_PERSISTENT = 0x81;
-const TPM_RH TPM_RH_FIRST = 0x40000000;
-const TPM_RH TPM_RH_SRK = 0x40000000;
-const TPM_RH TPM_RH_OWNER = 0x40000001;
-const TPM_RH TPM_RH_REVOKE = 0x40000002;
-const TPM_RH TPM_RH_TRANSPORT = 0x40000003;
-const TPM_RH TPM_RH_OPERATOR = 0x40000004;
-const TPM_RH TPM_RH_ADMIN = 0x40000005;
-const TPM_RH TPM_RH_EK = 0x40000006;
-const TPM_RH TPM_RH_NULL = 0x40000007;
-const TPM_RH TPM_RH_UNASSIGNED = 0x40000008;
-const TPM_RH TPM_RS_PW = 0x40000009;
-const TPM_RH TPM_RH_LOCKOUT = 0x4000000A;
-const TPM_RH TPM_RH_ENDORSEMENT = 0x4000000B;
-const TPM_RH TPM_RH_PLATFORM = 0x4000000C;
-const TPM_RH TPM_RH_PLATFORM_NV = 0x4000000D;
-const TPM_RH TPM_RH_LAST = 0x4000000D;
-const TPM_HC HR_HANDLE_MASK = 0x00FFFFFF;
-const TPM_HC HR_RANGE_MASK = 0xFF000000;
-const TPM_HC HR_SHIFT = 24;
-const TPM_HC HR_PCR = (TPM_HT_PCR << HR_SHIFT);
-const TPM_HC HR_HMAC_SESSION = (TPM_HT_HMAC_SESSION << HR_SHIFT);
-const TPM_HC HR_POLICY_SESSION = (TPM_HT_POLICY_SESSION << HR_SHIFT);
-const TPM_HC HR_TRANSIENT = (TPM_HT_TRANSIENT << HR_SHIFT);
-const TPM_HC HR_PERSISTENT = (TPM_HT_PERSISTENT << HR_SHIFT);
-const TPM_HC HR_NV_INDEX = (TPM_HT_NV_INDEX << HR_SHIFT);
-const TPM_HC HR_PERMANENT = (TPM_HT_PERMANENT << HR_SHIFT);
-const TPM_HC PCR_FIRST = (HR_PCR + 0);
-const TPM_HC PCR_LAST = (PCR_FIRST + IMPLEMENTATION_PCR - 1);
-const TPM_HC HMAC_SESSION_FIRST = (HR_HMAC_SESSION + 0);
-const TPM_HC HMAC_SESSION_LAST = (HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1);
-const TPM_HC LOADED_SESSION_LAST = HMAC_SESSION_LAST;
-const TPM_HC POLICY_SESSION_FIRST = (HR_POLICY_SESSION + 0);
-const TPM_HC POLICY_SESSION_LAST =
+constexpr TPM_SPEC TPM_SPEC_FAMILY = 0x322E3000;
+constexpr TPM_SPEC TPM_SPEC_LEVEL = 00;
+constexpr TPM_SPEC TPM_SPEC_VERSION = 99;
+constexpr TPM_SPEC TPM_SPEC_YEAR = 2013;
+constexpr TPM_SPEC TPM_SPEC_DAY_OF_YEAR = 304;
+constexpr TPM_GENERATED TPM_GENERATED_VALUE = 0xff544347;
+constexpr TPM_ALG_ID TPM_ALG_ERROR = 0x0000;
+constexpr TPM_ALG_ID TPM_ALG_FIRST = 0x0001;
+constexpr TPM_ALG_ID TPM_ALG_RSA = 0x0001;
+constexpr TPM_ALG_ID TPM_ALG_SHA = 0x0004;
+constexpr TPM_ALG_ID TPM_ALG_SHA1 = 0x0004;
+constexpr TPM_ALG_ID TPM_ALG_HMAC = 0x0005;
+constexpr TPM_ALG_ID TPM_ALG_AES = 0x0006;
+constexpr TPM_ALG_ID TPM_ALG_MGF1 = 0x0007;
+constexpr TPM_ALG_ID TPM_ALG_KEYEDHASH = 0x0008;
+constexpr TPM_ALG_ID TPM_ALG_XOR = 0x000A;
+constexpr TPM_ALG_ID TPM_ALG_SHA256 = 0x000B;
+constexpr TPM_ALG_ID TPM_ALG_SHA384 = 0x000C;
+constexpr TPM_ALG_ID TPM_ALG_SHA512 = 0x000D;
+constexpr TPM_ALG_ID TPM_ALG_NULL = 0x0010;
+constexpr TPM_ALG_ID TPM_ALG_SM3_256 = 0x0012;
+constexpr TPM_ALG_ID TPM_ALG_SM4 = 0x0013;
+constexpr TPM_ALG_ID TPM_ALG_RSASSA = 0x0014;
+constexpr TPM_ALG_ID TPM_ALG_RSAES = 0x0015;
+constexpr TPM_ALG_ID TPM_ALG_RSAPSS = 0x0016;
+constexpr TPM_ALG_ID TPM_ALG_OAEP = 0x0017;
+constexpr TPM_ALG_ID TPM_ALG_ECDSA = 0x0018;
+constexpr TPM_ALG_ID TPM_ALG_ECDH = 0x0019;
+constexpr TPM_ALG_ID TPM_ALG_ECDAA = 0x001A;
+constexpr TPM_ALG_ID TPM_ALG_SM2 = 0x001B;
+constexpr TPM_ALG_ID TPM_ALG_ECSCHNORR = 0x001C;
+constexpr TPM_ALG_ID TPM_ALG_ECMQV = 0x001D;
+constexpr TPM_ALG_ID TPM_ALG_KDF1_SP800_56a = 0x0020;
+constexpr TPM_ALG_ID TPM_ALG_KDF2 = 0x0021;
+constexpr TPM_ALG_ID TPM_ALG_KDF1_SP800_108 = 0x0022;
+constexpr TPM_ALG_ID TPM_ALG_ECC = 0x0023;
+constexpr TPM_ALG_ID TPM_ALG_SYMCIPHER = 0x0025;
+constexpr TPM_ALG_ID TPM_ALG_CTR = 0x0040;
+constexpr TPM_ALG_ID TPM_ALG_OFB = 0x0041;
+constexpr TPM_ALG_ID TPM_ALG_CBC = 0x0042;
+constexpr TPM_ALG_ID TPM_ALG_CFB = 0x0043;
+constexpr TPM_ALG_ID TPM_ALG_ECB = 0x0044;
+constexpr TPM_ALG_ID TPM_ALG_LAST = 0x0044;
+constexpr TPM_ECC_CURVE TPM_ECC_NONE = 0x0000;
+constexpr TPM_ECC_CURVE TPM_ECC_NIST_P192 = 0x0001;
+constexpr TPM_ECC_CURVE TPM_ECC_NIST_P224 = 0x0002;
+constexpr TPM_ECC_CURVE TPM_ECC_NIST_P256 = 0x0003;
+constexpr TPM_ECC_CURVE TPM_ECC_NIST_P384 = 0x0004;
+constexpr TPM_ECC_CURVE TPM_ECC_NIST_P521 = 0x0005;
+constexpr TPM_ECC_CURVE TPM_ECC_BN_P256 = 0x0010;
+constexpr TPM_ECC_CURVE TPM_ECC_BN_P638 = 0x0011;
+constexpr TPM_ECC_CURVE TPM_ECC_SM2_P256 = 0x0020;
+constexpr TPM_CC TPM_CC_FIRST = 0x0000011F;
+constexpr TPM_CC TPM_CC_PP_FIRST = 0x0000011F;
+constexpr TPM_CC TPM_CC_NV_UndefineSpaceSpecial = 0x0000011F;
+constexpr TPM_CC TPM_CC_EvictControl = 0x00000120;
+constexpr TPM_CC TPM_CC_HierarchyControl = 0x00000121;
+constexpr TPM_CC TPM_CC_NV_UndefineSpace = 0x00000122;
+constexpr TPM_CC TPM_CC_ChangeEPS = 0x00000124;
+constexpr TPM_CC TPM_CC_ChangePPS = 0x00000125;
+constexpr TPM_CC TPM_CC_Clear = 0x00000126;
+constexpr TPM_CC TPM_CC_ClearControl = 0x00000127;
+constexpr TPM_CC TPM_CC_ClockSet = 0x00000128;
+constexpr TPM_CC TPM_CC_HierarchyChangeAuth = 0x00000129;
+constexpr TPM_CC TPM_CC_NV_DefineSpace = 0x0000012A;
+constexpr TPM_CC TPM_CC_PCR_Allocate = 0x0000012B;
+constexpr TPM_CC TPM_CC_PCR_SetAuthPolicy = 0x0000012C;
+constexpr TPM_CC TPM_CC_PP_Commands = 0x0000012D;
+constexpr TPM_CC TPM_CC_SetPrimaryPolicy = 0x0000012E;
+constexpr TPM_CC TPM_CC_FieldUpgradeStart = 0x0000012F;
+constexpr TPM_CC TPM_CC_ClockRateAdjust = 0x00000130;
+constexpr TPM_CC TPM_CC_CreatePrimary = 0x00000131;
+constexpr TPM_CC TPM_CC_NV_GlobalWriteLock = 0x00000132;
+constexpr TPM_CC TPM_CC_PP_LAST = 0x00000132;
+constexpr TPM_CC TPM_CC_GetCommandAuditDigest = 0x00000133;
+constexpr TPM_CC TPM_CC_NV_Increment = 0x00000134;
+constexpr TPM_CC TPM_CC_NV_SetBits = 0x00000135;
+constexpr TPM_CC TPM_CC_NV_Extend = 0x00000136;
+constexpr TPM_CC TPM_CC_NV_Write = 0x00000137;
+constexpr TPM_CC TPM_CC_NV_WriteLock = 0x00000138;
+constexpr TPM_CC TPM_CC_DictionaryAttackLockReset = 0x00000139;
+constexpr TPM_CC TPM_CC_DictionaryAttackParameters = 0x0000013A;
+constexpr TPM_CC TPM_CC_NV_ChangeAuth = 0x0000013B;
+constexpr TPM_CC TPM_CC_PCR_Event = 0x0000013C;
+constexpr TPM_CC TPM_CC_PCR_Reset = 0x0000013D;
+constexpr TPM_CC TPM_CC_SequenceComplete = 0x0000013E;
+constexpr TPM_CC TPM_CC_SetAlgorithmSet = 0x0000013F;
+constexpr TPM_CC TPM_CC_SetCommandCodeAuditStatus = 0x00000140;
+constexpr TPM_CC TPM_CC_FieldUpgradeData = 0x00000141;
+constexpr TPM_CC TPM_CC_IncrementalSelfTest = 0x00000142;
+constexpr TPM_CC TPM_CC_SelfTest = 0x00000143;
+constexpr TPM_CC TPM_CC_Startup = 0x00000144;
+constexpr TPM_CC TPM_CC_Shutdown = 0x00000145;
+constexpr TPM_CC TPM_CC_StirRandom = 0x00000146;
+constexpr TPM_CC TPM_CC_ActivateCredential = 0x00000147;
+constexpr TPM_CC TPM_CC_Certify = 0x00000148;
+constexpr TPM_CC TPM_CC_PolicyNV = 0x00000149;
+constexpr TPM_CC TPM_CC_CertifyCreation = 0x0000014A;
+constexpr TPM_CC TPM_CC_Duplicate = 0x0000014B;
+constexpr TPM_CC TPM_CC_GetTime = 0x0000014C;
+constexpr TPM_CC TPM_CC_GetSessionAuditDigest = 0x0000014D;
+constexpr TPM_CC TPM_CC_NV_Read = 0x0000014E;
+constexpr TPM_CC TPM_CC_NV_ReadLock = 0x0000014F;
+constexpr TPM_CC TPM_CC_ObjectChangeAuth = 0x00000150;
+constexpr TPM_CC TPM_CC_PolicySecret = 0x00000151;
+constexpr TPM_CC TPM_CC_Rewrap = 0x00000152;
+constexpr TPM_CC TPM_CC_Create = 0x00000153;
+constexpr TPM_CC TPM_CC_ECDH_ZGen = 0x00000154;
+constexpr TPM_CC TPM_CC_HMAC = 0x00000155;
+constexpr TPM_CC TPM_CC_Import = 0x00000156;
+constexpr TPM_CC TPM_CC_Load = 0x00000157;
+constexpr TPM_CC TPM_CC_Quote = 0x00000158;
+constexpr TPM_CC TPM_CC_RSA_Decrypt = 0x00000159;
+constexpr TPM_CC TPM_CC_HMAC_Start = 0x0000015B;
+constexpr TPM_CC TPM_CC_SequenceUpdate = 0x0000015C;
+constexpr TPM_CC TPM_CC_Sign = 0x0000015D;
+constexpr TPM_CC TPM_CC_Unseal = 0x0000015E;
+constexpr TPM_CC TPM_CC_PolicySigned = 0x00000160;
+constexpr TPM_CC TPM_CC_ContextLoad = 0x00000161;
+constexpr TPM_CC TPM_CC_ContextSave = 0x00000162;
+constexpr TPM_CC TPM_CC_ECDH_KeyGen = 0x00000163;
+constexpr TPM_CC TPM_CC_EncryptDecrypt = 0x00000164;
+constexpr TPM_CC TPM_CC_FlushContext = 0x00000165;
+constexpr TPM_CC TPM_CC_LoadExternal = 0x00000167;
+constexpr TPM_CC TPM_CC_MakeCredential = 0x00000168;
+constexpr TPM_CC TPM_CC_NV_ReadPublic = 0x00000169;
+constexpr TPM_CC TPM_CC_PolicyAuthorize = 0x0000016A;
+constexpr TPM_CC TPM_CC_PolicyAuthValue = 0x0000016B;
+constexpr TPM_CC TPM_CC_PolicyCommandCode = 0x0000016C;
+constexpr TPM_CC TPM_CC_PolicyCounterTimer = 0x0000016D;
+constexpr TPM_CC TPM_CC_PolicyCpHash = 0x0000016E;
+constexpr TPM_CC TPM_CC_PolicyLocality = 0x0000016F;
+constexpr TPM_CC TPM_CC_PolicyNameHash = 0x00000170;
+constexpr TPM_CC TPM_CC_PolicyOR = 0x00000171;
+constexpr TPM_CC TPM_CC_PolicyTicket = 0x00000172;
+constexpr TPM_CC TPM_CC_ReadPublic = 0x00000173;
+constexpr TPM_CC TPM_CC_RSA_Encrypt = 0x00000174;
+constexpr TPM_CC TPM_CC_StartAuthSession = 0x00000176;
+constexpr TPM_CC TPM_CC_VerifySignature = 0x00000177;
+constexpr TPM_CC TPM_CC_ECC_Parameters = 0x00000178;
+constexpr TPM_CC TPM_CC_FirmwareRead = 0x00000179;
+constexpr TPM_CC TPM_CC_GetCapability = 0x0000017A;
+constexpr TPM_CC TPM_CC_GetRandom = 0x0000017B;
+constexpr TPM_CC TPM_CC_GetTestResult = 0x0000017C;
+constexpr TPM_CC TPM_CC_Hash = 0x0000017D;
+constexpr TPM_CC TPM_CC_PCR_Read = 0x0000017E;
+constexpr TPM_CC TPM_CC_PolicyPCR = 0x0000017F;
+constexpr TPM_CC TPM_CC_PolicyRestart = 0x00000180;
+constexpr TPM_CC TPM_CC_ReadClock = 0x00000181;
+constexpr TPM_CC TPM_CC_PCR_Extend = 0x00000182;
+constexpr TPM_CC TPM_CC_PCR_SetAuthValue = 0x00000183;
+constexpr TPM_CC TPM_CC_NV_Certify = 0x00000184;
+constexpr TPM_CC TPM_CC_EventSequenceComplete = 0x00000185;
+constexpr TPM_CC TPM_CC_HashSequenceStart = 0x00000186;
+constexpr TPM_CC TPM_CC_PolicyPhysicalPresence = 0x00000187;
+constexpr TPM_CC TPM_CC_PolicyDuplicationSelect = 0x00000188;
+constexpr TPM_CC TPM_CC_PolicyGetDigest = 0x00000189;
+constexpr TPM_CC TPM_CC_TestParms = 0x0000018A;
+constexpr TPM_CC TPM_CC_Commit = 0x0000018B;
+constexpr TPM_CC TPM_CC_PolicyPassword = 0x0000018C;
+constexpr TPM_CC TPM_CC_ZGen_2Phase = 0x0000018D;
+constexpr TPM_CC TPM_CC_EC_Ephemeral = 0x0000018E;
+constexpr TPM_CC TPM_CC_PolicyNvWritten = 0x0000018F;
+constexpr TPM_CC TPM_CC_LAST = 0x0000018F;
+constexpr TPM_RC TPM_RC_SUCCESS = 0x000;
+constexpr TPM_RC TPM_RC_BAD_TAG = 0x01E;
+constexpr TPM_RC RC_VER1 = 0x100;
+constexpr TPM_RC TPM_RC_INITIALIZE = RC_VER1 + 0x000;
+constexpr TPM_RC TPM_RC_FAILURE = RC_VER1 + 0x001;
+constexpr TPM_RC TPM_RC_SEQUENCE = RC_VER1 + 0x003;
+constexpr TPM_RC TPM_RC_PRIVATE = RC_VER1 + 0x00B;
+constexpr TPM_RC TPM_RC_HMAC = RC_VER1 + 0x019;
+constexpr TPM_RC TPM_RC_DISABLED = RC_VER1 + 0x020;
+constexpr TPM_RC TPM_RC_EXCLUSIVE = RC_VER1 + 0x021;
+constexpr TPM_RC TPM_RC_AUTH_TYPE = RC_VER1 + 0x024;
+constexpr TPM_RC TPM_RC_AUTH_MISSING = RC_VER1 + 0x025;
+constexpr TPM_RC TPM_RC_POLICY = RC_VER1 + 0x026;
+constexpr TPM_RC TPM_RC_PCR = RC_VER1 + 0x027;
+constexpr TPM_RC TPM_RC_PCR_CHANGED = RC_VER1 + 0x028;
+constexpr TPM_RC TPM_RC_UPGRADE = RC_VER1 + 0x02D;
+constexpr TPM_RC TPM_RC_TOO_MANY_CONTEXTS = RC_VER1 + 0x02E;
+constexpr TPM_RC TPM_RC_AUTH_UNAVAILABLE = RC_VER1 + 0x02F;
+constexpr TPM_RC TPM_RC_REBOOT = RC_VER1 + 0x030;
+constexpr TPM_RC TPM_RC_UNBALANCED = RC_VER1 + 0x031;
+constexpr TPM_RC TPM_RC_COMMAND_SIZE = RC_VER1 + 0x042;
+constexpr TPM_RC TPM_RC_COMMAND_CODE = RC_VER1 + 0x043;
+constexpr TPM_RC TPM_RC_AUTHSIZE = RC_VER1 + 0x044;
+constexpr TPM_RC TPM_RC_AUTH_CONTEXT = RC_VER1 + 0x045;
+constexpr TPM_RC TPM_RC_NV_RANGE = RC_VER1 + 0x046;
+constexpr TPM_RC TPM_RC_NV_SIZE = RC_VER1 + 0x047;
+constexpr TPM_RC TPM_RC_NV_LOCKED = RC_VER1 + 0x048;
+constexpr TPM_RC TPM_RC_NV_AUTHORIZATION = RC_VER1 + 0x049;
+constexpr TPM_RC TPM_RC_NV_UNINITIALIZED = RC_VER1 + 0x04A;
+constexpr TPM_RC TPM_RC_NV_SPACE = RC_VER1 + 0x04B;
+constexpr TPM_RC TPM_RC_NV_DEFINED = RC_VER1 + 0x04C;
+constexpr TPM_RC TPM_RC_BAD_CONTEXT = RC_VER1 + 0x050;
+constexpr TPM_RC TPM_RC_CPHASH = RC_VER1 + 0x051;
+constexpr TPM_RC TPM_RC_PARENT = RC_VER1 + 0x052;
+constexpr TPM_RC TPM_RC_NEEDS_TEST = RC_VER1 + 0x053;
+constexpr TPM_RC TPM_RC_NO_RESULT = RC_VER1 + 0x054;
+constexpr TPM_RC TPM_RC_SENSITIVE = RC_VER1 + 0x055;
+constexpr TPM_RC RC_MAX_FM0 = RC_VER1 + 0x07F;
+constexpr TPM_RC RC_FMT1 = 0x080;
+constexpr TPM_RC TPM_RC_ASYMMETRIC = RC_FMT1 + 0x001;
+constexpr TPM_RC TPM_RC_ATTRIBUTES = RC_FMT1 + 0x002;
+constexpr TPM_RC TPM_RC_HASH = RC_FMT1 + 0x003;
+constexpr TPM_RC TPM_RC_VALUE = RC_FMT1 + 0x004;
+constexpr TPM_RC TPM_RC_HIERARCHY = RC_FMT1 + 0x005;
+constexpr TPM_RC TPM_RC_KEY_SIZE = RC_FMT1 + 0x007;
+constexpr TPM_RC TPM_RC_MGF = RC_FMT1 + 0x008;
+constexpr TPM_RC TPM_RC_MODE = RC_FMT1 + 0x009;
+constexpr TPM_RC TPM_RC_TYPE = RC_FMT1 + 0x00A;
+constexpr TPM_RC TPM_RC_HANDLE = RC_FMT1 + 0x00B;
+constexpr TPM_RC TPM_RC_KDF = RC_FMT1 + 0x00C;
+constexpr TPM_RC TPM_RC_RANGE = RC_FMT1 + 0x00D;
+constexpr TPM_RC TPM_RC_AUTH_FAIL = RC_FMT1 + 0x00E;
+constexpr TPM_RC TPM_RC_NONCE = RC_FMT1 + 0x00F;
+constexpr TPM_RC TPM_RC_PP = RC_FMT1 + 0x010;
+constexpr TPM_RC TPM_RC_SCHEME = RC_FMT1 + 0x012;
+constexpr TPM_RC TPM_RC_SIZE = RC_FMT1 + 0x015;
+constexpr TPM_RC TPM_RC_SYMMETRIC = RC_FMT1 + 0x016;
+constexpr TPM_RC TPM_RC_TAG = RC_FMT1 + 0x017;
+constexpr TPM_RC TPM_RC_SELECTOR = RC_FMT1 + 0x018;
+constexpr TPM_RC TPM_RC_INSUFFICIENT = RC_FMT1 + 0x01A;
+constexpr TPM_RC TPM_RC_SIGNATURE = RC_FMT1 + 0x01B;
+constexpr TPM_RC TPM_RC_KEY = RC_FMT1 + 0x01C;
+constexpr TPM_RC TPM_RC_POLICY_FAIL = RC_FMT1 + 0x01D;
+constexpr TPM_RC TPM_RC_INTEGRITY = RC_FMT1 + 0x01F;
+constexpr TPM_RC TPM_RC_TICKET = RC_FMT1 + 0x020;
+constexpr TPM_RC TPM_RC_RESERVED_BITS = RC_FMT1 + 0x021;
+constexpr TPM_RC TPM_RC_BAD_AUTH = RC_FMT1 + 0x022;
+constexpr TPM_RC TPM_RC_EXPIRED = RC_FMT1 + 0x023;
+constexpr TPM_RC TPM_RC_POLICY_CC = RC_FMT1 + 0x024;
+constexpr TPM_RC TPM_RC_BINDING = RC_FMT1 + 0x025;
+constexpr TPM_RC TPM_RC_CURVE = RC_FMT1 + 0x026;
+constexpr TPM_RC TPM_RC_ECC_POINT = RC_FMT1 + 0x027;
+constexpr TPM_RC RC_WARN = 0x900;
+constexpr TPM_RC TPM_RC_CONTEXT_GAP = RC_WARN + 0x001;
+constexpr TPM_RC TPM_RC_OBJECT_MEMORY = RC_WARN + 0x002;
+constexpr TPM_RC TPM_RC_SESSION_MEMORY = RC_WARN + 0x003;
+constexpr TPM_RC TPM_RC_MEMORY = RC_WARN + 0x004;
+constexpr TPM_RC TPM_RC_SESSION_HANDLES = RC_WARN + 0x005;
+constexpr TPM_RC TPM_RC_OBJECT_HANDLES = RC_WARN + 0x006;
+constexpr TPM_RC TPM_RC_LOCALITY = RC_WARN + 0x007;
+constexpr TPM_RC TPM_RC_YIELDED = RC_WARN + 0x008;
+constexpr TPM_RC TPM_RC_CANCELED = RC_WARN + 0x009;
+constexpr TPM_RC TPM_RC_TESTING = RC_WARN + 0x00A;
+constexpr TPM_RC TPM_RC_REFERENCE_H0 = RC_WARN + 0x010;
+constexpr TPM_RC TPM_RC_REFERENCE_H1 = RC_WARN + 0x011;
+constexpr TPM_RC TPM_RC_REFERENCE_H2 = RC_WARN + 0x012;
+constexpr TPM_RC TPM_RC_REFERENCE_H3 = RC_WARN + 0x013;
+constexpr TPM_RC TPM_RC_REFERENCE_H4 = RC_WARN + 0x014;
+constexpr TPM_RC TPM_RC_REFERENCE_H5 = RC_WARN + 0x015;
+constexpr TPM_RC TPM_RC_REFERENCE_H6 = RC_WARN + 0x016;
+constexpr TPM_RC TPM_RC_REFERENCE_S0 = RC_WARN + 0x018;
+constexpr TPM_RC TPM_RC_REFERENCE_S1 = RC_WARN + 0x019;
+constexpr TPM_RC TPM_RC_REFERENCE_S2 = RC_WARN + 0x01A;
+constexpr TPM_RC TPM_RC_REFERENCE_S3 = RC_WARN + 0x01B;
+constexpr TPM_RC TPM_RC_REFERENCE_S4 = RC_WARN + 0x01C;
+constexpr TPM_RC TPM_RC_REFERENCE_S5 = RC_WARN + 0x01D;
+constexpr TPM_RC TPM_RC_REFERENCE_S6 = RC_WARN + 0x01E;
+constexpr TPM_RC TPM_RC_NV_RATE = RC_WARN + 0x020;
+constexpr TPM_RC TPM_RC_LOCKOUT = RC_WARN + 0x021;
+constexpr TPM_RC TPM_RC_RETRY = RC_WARN + 0x022;
+constexpr TPM_RC TPM_RC_NV_UNAVAILABLE = RC_WARN + 0x023;
+constexpr TPM_RC TPM_RC_NOT_USED = RC_WARN + 0x7F;
+constexpr TPM_RC TPM_RC_H = 0x000;
+constexpr TPM_RC TPM_RC_P = 0x040;
+constexpr TPM_RC TPM_RC_S = 0x800;
+constexpr TPM_RC TPM_RC_1 = 0x100;
+constexpr TPM_RC TPM_RC_2 = 0x200;
+constexpr TPM_RC TPM_RC_3 = 0x300;
+constexpr TPM_RC TPM_RC_4 = 0x400;
+constexpr TPM_RC TPM_RC_5 = 0x500;
+constexpr TPM_RC TPM_RC_6 = 0x600;
+constexpr TPM_RC TPM_RC_7 = 0x700;
+constexpr TPM_RC TPM_RC_8 = 0x800;
+constexpr TPM_RC TPM_RC_9 = 0x900;
+constexpr TPM_RC TPM_RC_A = 0xA00;
+constexpr TPM_RC TPM_RC_B = 0xB00;
+constexpr TPM_RC TPM_RC_C = 0xC00;
+constexpr TPM_RC TPM_RC_D = 0xD00;
+constexpr TPM_RC TPM_RC_E = 0xE00;
+constexpr TPM_RC TPM_RC_F = 0xF00;
+constexpr TPM_RC TPM_RC_N_MASK = 0xF00;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_COARSE_SLOWER = -3;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_MEDIUM_SLOWER = -2;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_FINE_SLOWER = -1;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_NO_CHANGE = 0;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_FINE_FASTER = 1;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_MEDIUM_FASTER = 2;
+constexpr TPM_CLOCK_ADJUST TPM_CLOCK_COARSE_FASTER = 3;
+constexpr TPM_EO TPM_EO_EQ = 0x0000;
+constexpr TPM_EO TPM_EO_NEQ = 0x0001;
+constexpr TPM_EO TPM_EO_SIGNED_GT = 0x0002;
+constexpr TPM_EO TPM_EO_UNSIGNED_GT = 0x0003;
+constexpr TPM_EO TPM_EO_SIGNED_LT = 0x0004;
+constexpr TPM_EO TPM_EO_UNSIGNED_LT = 0x0005;
+constexpr TPM_EO TPM_EO_SIGNED_GE = 0x0006;
+constexpr TPM_EO TPM_EO_UNSIGNED_GE = 0x0007;
+constexpr TPM_EO TPM_EO_SIGNED_LE = 0x0008;
+constexpr TPM_EO TPM_EO_UNSIGNED_LE = 0x0009;
+constexpr TPM_EO TPM_EO_BITSET = 0x000A;
+constexpr TPM_EO TPM_EO_BITCLEAR = 0x000B;
+constexpr TPM_ST TPM_ST_RSP_COMMAND = 0x00C4;
+constexpr TPM_ST TPM_ST_NULL = 0X8000;
+constexpr TPM_ST TPM_ST_NO_SESSIONS = 0x8001;
+constexpr TPM_ST TPM_ST_SESSIONS = 0x8002;
+constexpr TPM_ST TPM_ST_ATTEST_NV = 0x8014;
+constexpr TPM_ST TPM_ST_ATTEST_COMMAND_AUDIT = 0x8015;
+constexpr TPM_ST TPM_ST_ATTEST_SESSION_AUDIT = 0x8016;
+constexpr TPM_ST TPM_ST_ATTEST_CERTIFY = 0x8017;
+constexpr TPM_ST TPM_ST_ATTEST_QUOTE = 0x8018;
+constexpr TPM_ST TPM_ST_ATTEST_TIME = 0x8019;
+constexpr TPM_ST TPM_ST_ATTEST_CREATION = 0x801A;
+constexpr TPM_ST TPM_ST_CREATION = 0x8021;
+constexpr TPM_ST TPM_ST_VERIFIED = 0x8022;
+constexpr TPM_ST TPM_ST_AUTH_SECRET = 0x8023;
+constexpr TPM_ST TPM_ST_HASHCHECK = 0x8024;
+constexpr TPM_ST TPM_ST_AUTH_SIGNED = 0x8025;
+constexpr TPM_ST TPM_ST_FU_MANIFEST = 0x8029;
+constexpr TPM_SU TPM_SU_CLEAR = 0x0000;
+constexpr TPM_SU TPM_SU_STATE = 0x0001;
+constexpr TPM_SE TPM_SE_HMAC = 0x00;
+constexpr TPM_SE TPM_SE_POLICY = 0x01;
+constexpr TPM_SE TPM_SE_TRIAL = 0x03;
+constexpr TPM_CAP TPM_CAP_FIRST = 0x00000000;
+constexpr TPM_CAP TPM_CAP_ALGS = 0x00000000;
+constexpr TPM_CAP TPM_CAP_HANDLES = 0x00000001;
+constexpr TPM_CAP TPM_CAP_COMMANDS = 0x00000002;
+constexpr TPM_CAP TPM_CAP_PP_COMMANDS = 0x00000003;
+constexpr TPM_CAP TPM_CAP_AUDIT_COMMANDS = 0x00000004;
+constexpr TPM_CAP TPM_CAP_PCRS = 0x00000005;
+constexpr TPM_CAP TPM_CAP_TPM_PROPERTIES = 0x00000006;
+constexpr TPM_CAP TPM_CAP_PCR_PROPERTIES = 0x00000007;
+constexpr TPM_CAP TPM_CAP_ECC_CURVES = 0x00000008;
+constexpr TPM_CAP TPM_CAP_LAST = 0x00000008;
+constexpr TPM_CAP TPM_CAP_VENDOR_PROPERTY = 0x00000100;
+constexpr TPM_PT TPM_PT_NONE = 0x00000000;
+constexpr TPM_PT PT_GROUP = 0x00000100;
+constexpr TPM_PT PT_FIXED = PT_GROUP * 1;
+constexpr TPM_PT TPM_PT_FAMILY_INDICATOR = PT_FIXED + 0;
+constexpr TPM_PT TPM_PT_LEVEL = PT_FIXED + 1;
+constexpr TPM_PT TPM_PT_REVISION = PT_FIXED + 2;
+constexpr TPM_PT TPM_PT_DAY_OF_YEAR = PT_FIXED + 3;
+constexpr TPM_PT TPM_PT_YEAR = PT_FIXED + 4;
+constexpr TPM_PT TPM_PT_MANUFACTURER = PT_FIXED + 5;
+constexpr TPM_PT TPM_PT_VENDOR_STRING_1 = PT_FIXED + 6;
+constexpr TPM_PT TPM_PT_VENDOR_STRING_2 = PT_FIXED + 7;
+constexpr TPM_PT TPM_PT_VENDOR_STRING_3 = PT_FIXED + 8;
+constexpr TPM_PT TPM_PT_VENDOR_STRING_4 = PT_FIXED + 9;
+constexpr TPM_PT TPM_PT_VENDOR_TPM_TYPE = PT_FIXED + 10;
+constexpr TPM_PT TPM_PT_FIRMWARE_VERSION_1 = PT_FIXED + 11;
+constexpr TPM_PT TPM_PT_FIRMWARE_VERSION_2 = PT_FIXED + 12;
+constexpr TPM_PT TPM_PT_INPUT_BUFFER = PT_FIXED + 13;
+constexpr TPM_PT TPM_PT_HR_TRANSIENT_MIN = PT_FIXED + 14;
+constexpr TPM_PT TPM_PT_HR_PERSISTENT_MIN = PT_FIXED + 15;
+constexpr TPM_PT TPM_PT_HR_LOADED_MIN = PT_FIXED + 16;
+constexpr TPM_PT TPM_PT_ACTIVE_SESSIONS_MAX = PT_FIXED + 17;
+constexpr TPM_PT TPM_PT_PCR_COUNT = PT_FIXED + 18;
+constexpr TPM_PT TPM_PT_PCR_SELECT_MIN = PT_FIXED + 19;
+constexpr TPM_PT TPM_PT_CONTEXT_GAP_MAX = PT_FIXED + 20;
+constexpr TPM_PT TPM_PT_NV_COUNTERS_MAX = PT_FIXED + 22;
+constexpr TPM_PT TPM_PT_NV_INDEX_MAX = PT_FIXED + 23;
+constexpr TPM_PT TPM_PT_MEMORY = PT_FIXED + 24;
+constexpr TPM_PT TPM_PT_CLOCK_UPDATE = PT_FIXED + 25;
+constexpr TPM_PT TPM_PT_CONTEXT_HASH = PT_FIXED + 26;
+constexpr TPM_PT TPM_PT_CONTEXT_SYM = PT_FIXED + 27;
+constexpr TPM_PT TPM_PT_CONTEXT_SYM_SIZE = PT_FIXED + 28;
+constexpr TPM_PT TPM_PT_ORDERLY_COUNT = PT_FIXED + 29;
+constexpr TPM_PT TPM_PT_MAX_COMMAND_SIZE = PT_FIXED + 30;
+constexpr TPM_PT TPM_PT_MAX_RESPONSE_SIZE = PT_FIXED + 31;
+constexpr TPM_PT TPM_PT_MAX_DIGEST = PT_FIXED + 32;
+constexpr TPM_PT TPM_PT_MAX_OBJECT_CONTEXT = PT_FIXED + 33;
+constexpr TPM_PT TPM_PT_MAX_SESSION_CONTEXT = PT_FIXED + 34;
+constexpr TPM_PT TPM_PT_PS_FAMILY_INDICATOR = PT_FIXED + 35;
+constexpr TPM_PT TPM_PT_PS_LEVEL = PT_FIXED + 36;
+constexpr TPM_PT TPM_PT_PS_REVISION = PT_FIXED + 37;
+constexpr TPM_PT TPM_PT_PS_DAY_OF_YEAR = PT_FIXED + 38;
+constexpr TPM_PT TPM_PT_PS_YEAR = PT_FIXED + 39;
+constexpr TPM_PT TPM_PT_SPLIT_MAX = PT_FIXED + 40;
+constexpr TPM_PT TPM_PT_TOTAL_COMMANDS = PT_FIXED + 41;
+constexpr TPM_PT TPM_PT_LIBRARY_COMMANDS = PT_FIXED + 42;
+constexpr TPM_PT TPM_PT_VENDOR_COMMANDS = PT_FIXED + 43;
+constexpr TPM_PT TPM_PT_NV_BUFFER_MAX = PT_FIXED + 44;
+constexpr TPM_PT PT_VAR = PT_GROUP * 2;
+constexpr TPM_PT TPM_PT_PERMANENT = PT_VAR + 0;
+constexpr TPM_PT TPM_PT_STARTUP_CLEAR = PT_VAR + 1;
+constexpr TPM_PT TPM_PT_HR_NV_INDEX = PT_VAR + 2;
+constexpr TPM_PT TPM_PT_HR_LOADED = PT_VAR + 3;
+constexpr TPM_PT TPM_PT_HR_LOADED_AVAIL = PT_VAR + 4;
+constexpr TPM_PT TPM_PT_HR_ACTIVE = PT_VAR + 5;
+constexpr TPM_PT TPM_PT_HR_ACTIVE_AVAIL = PT_VAR + 6;
+constexpr TPM_PT TPM_PT_HR_TRANSIENT_AVAIL = PT_VAR + 7;
+constexpr TPM_PT TPM_PT_HR_PERSISTENT = PT_VAR + 8;
+constexpr TPM_PT TPM_PT_HR_PERSISTENT_AVAIL = PT_VAR + 9;
+constexpr TPM_PT TPM_PT_NV_COUNTERS = PT_VAR + 10;
+constexpr TPM_PT TPM_PT_NV_COUNTERS_AVAIL = PT_VAR + 11;
+constexpr TPM_PT TPM_PT_ALGORITHM_SET = PT_VAR + 12;
+constexpr TPM_PT TPM_PT_LOADED_CURVES = PT_VAR + 13;
+constexpr TPM_PT TPM_PT_LOCKOUT_COUNTER = PT_VAR + 14;
+constexpr TPM_PT TPM_PT_MAX_AUTH_FAIL = PT_VAR + 15;
+constexpr TPM_PT TPM_PT_LOCKOUT_INTERVAL = PT_VAR + 16;
+constexpr TPM_PT TPM_PT_LOCKOUT_RECOVERY = PT_VAR + 17;
+constexpr TPM_PT TPM_PT_NV_WRITE_RECOVERY = PT_VAR + 18;
+constexpr TPM_PT TPM_PT_AUDIT_COUNTER_0 = PT_VAR + 19;
+constexpr TPM_PT TPM_PT_AUDIT_COUNTER_1 = PT_VAR + 20;
+constexpr TPM_PT_PCR TPM_PT_PCR_FIRST = 0x00000000;
+constexpr TPM_PT_PCR TPM_PT_PCR_SAVE = 0x00000000;
+constexpr TPM_PT_PCR TPM_PT_PCR_EXTEND_L0 = 0x00000001;
+constexpr TPM_PT_PCR TPM_PT_PCR_RESET_L0 = 0x00000002;
+constexpr TPM_PT_PCR TPM_PT_PCR_EXTEND_L1 = 0x00000003;
+constexpr TPM_PT_PCR TPM_PT_PCR_RESET_L1 = 0x00000004;
+constexpr TPM_PT_PCR TPM_PT_PCR_EXTEND_L2 = 0x00000005;
+constexpr TPM_PT_PCR TPM_PT_PCR_RESET_L2 = 0x00000006;
+constexpr TPM_PT_PCR TPM_PT_PCR_EXTEND_L3 = 0x00000007;
+constexpr TPM_PT_PCR TPM_PT_PCR_RESET_L3 = 0x00000008;
+constexpr TPM_PT_PCR TPM_PT_PCR_EXTEND_L4 = 0x00000009;
+constexpr TPM_PT_PCR TPM_PT_PCR_RESET_L4 = 0x0000000A;
+constexpr TPM_PT_PCR TPM_PT_PCR_NO_INCREMENT = 0x00000011;
+constexpr TPM_PT_PCR TPM_PT_PCR_DRTM_RESET = 0x00000012;
+constexpr TPM_PT_PCR TPM_PT_PCR_POLICY = 0x00000013;
+constexpr TPM_PT_PCR TPM_PT_PCR_AUTH = 0x00000014;
+constexpr TPM_PT_PCR TPM_PT_PCR_LAST = 0x00000014;
+constexpr TPM_PS TPM_PS_MAIN = 0x00000000;
+constexpr TPM_PS TPM_PS_PC = 0x00000001;
+constexpr TPM_PS TPM_PS_PDA = 0x00000002;
+constexpr TPM_PS TPM_PS_CELL_PHONE = 0x00000003;
+constexpr TPM_PS TPM_PS_SERVER = 0x00000004;
+constexpr TPM_PS TPM_PS_PERIPHERAL = 0x00000005;
+constexpr TPM_PS TPM_PS_TSS = 0x00000006;
+constexpr TPM_PS TPM_PS_STORAGE = 0x00000007;
+constexpr TPM_PS TPM_PS_AUTHENTICATION = 0x00000008;
+constexpr TPM_PS TPM_PS_EMBEDDED = 0x00000009;
+constexpr TPM_PS TPM_PS_HARDCOPY = 0x0000000A;
+constexpr TPM_PS TPM_PS_INFRASTRUCTURE = 0x0000000B;
+constexpr TPM_PS TPM_PS_VIRTUALIZATION = 0x0000000C;
+constexpr TPM_PS TPM_PS_TNC = 0x0000000D;
+constexpr TPM_PS TPM_PS_MULTI_TENANT = 0x0000000E;
+constexpr TPM_PS TPM_PS_TC = 0x0000000F;
+constexpr TPM_HT TPM_HT_PCR = 0x00;
+constexpr TPM_HT TPM_HT_NV_INDEX = 0x01;
+constexpr TPM_HT TPM_HT_HMAC_SESSION = 0x02;
+constexpr TPM_HT TPM_HT_LOADED_SESSION = 0x02;
+constexpr TPM_HT TPM_HT_POLICY_SESSION = 0x03;
+constexpr TPM_HT TPM_HT_ACTIVE_SESSION = 0x03;
+constexpr TPM_HT TPM_HT_PERMANENT = 0x40;
+constexpr TPM_HT TPM_HT_TRANSIENT = 0x80;
+constexpr TPM_HT TPM_HT_PERSISTENT = 0x81;
+constexpr TPM_RH TPM_RH_FIRST = 0x40000000;
+constexpr TPM_RH TPM_RH_SRK = 0x40000000;
+constexpr TPM_RH TPM_RH_OWNER = 0x40000001;
+constexpr TPM_RH TPM_RH_REVOKE = 0x40000002;
+constexpr TPM_RH TPM_RH_TRANSPORT = 0x40000003;
+constexpr TPM_RH TPM_RH_OPERATOR = 0x40000004;
+constexpr TPM_RH TPM_RH_ADMIN = 0x40000005;
+constexpr TPM_RH TPM_RH_EK = 0x40000006;
+constexpr TPM_RH TPM_RH_NULL = 0x40000007;
+constexpr TPM_RH TPM_RH_UNASSIGNED = 0x40000008;
+constexpr TPM_RH TPM_RS_PW = 0x40000009;
+constexpr TPM_RH TPM_RH_LOCKOUT = 0x4000000A;
+constexpr TPM_RH TPM_RH_ENDORSEMENT = 0x4000000B;
+constexpr TPM_RH TPM_RH_PLATFORM = 0x4000000C;
+constexpr TPM_RH TPM_RH_PLATFORM_NV = 0x4000000D;
+constexpr TPM_RH TPM_RH_LAST = 0x4000000D;
+constexpr TPM_HC HR_HANDLE_MASK = 0x00FFFFFF;
+constexpr TPM_HC HR_RANGE_MASK = 0xFF000000;
+constexpr TPM_HC HR_SHIFT = 24;
+constexpr TPM_HC HR_PCR = (TPM_HT_PCR << HR_SHIFT);
+constexpr TPM_HC HR_HMAC_SESSION = (TPM_HT_HMAC_SESSION << HR_SHIFT);
+constexpr TPM_HC HR_POLICY_SESSION = (TPM_HT_POLICY_SESSION << HR_SHIFT);
+constexpr TPM_HC HR_TRANSIENT = (TPM_HT_TRANSIENT << HR_SHIFT);
+constexpr TPM_HC HR_PERSISTENT = (TPM_HT_PERSISTENT << HR_SHIFT);
+constexpr TPM_HC HR_NV_INDEX = (TPM_HT_NV_INDEX << HR_SHIFT);
+constexpr TPM_HC HR_PERMANENT = (TPM_HT_PERMANENT << HR_SHIFT);
+constexpr TPM_HC PCR_FIRST = (HR_PCR + 0);
+constexpr TPM_HC PCR_LAST = (PCR_FIRST + IMPLEMENTATION_PCR - 1);
+constexpr TPM_HC HMAC_SESSION_FIRST = (HR_HMAC_SESSION + 0);
+constexpr TPM_HC HMAC_SESSION_LAST =
+    (HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1);
+constexpr TPM_HC LOADED_SESSION_LAST = HMAC_SESSION_LAST;
+constexpr TPM_HC POLICY_SESSION_FIRST = (HR_POLICY_SESSION + 0);
+constexpr TPM_HC POLICY_SESSION_LAST =
     (POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1);
-const TPM_HC TRANSIENT_FIRST = (HR_TRANSIENT + 0);
-const TPM_HC ACTIVE_SESSION_FIRST = POLICY_SESSION_FIRST;
-const TPM_HC ACTIVE_SESSION_LAST = POLICY_SESSION_LAST;
-const TPM_HC TRANSIENT_LAST = (TRANSIENT_FIRST + MAX_LOADED_OBJECTS - 1);
-const TPM_HC PERSISTENT_FIRST = (HR_PERSISTENT + 0);
-const TPM_HC PERSISTENT_LAST = (PERSISTENT_FIRST + 0x00FFFFFF);
-const TPM_HC PLATFORM_PERSISTENT = (PERSISTENT_FIRST + 0x00800000);
-const TPM_HC NV_INDEX_FIRST = (HR_NV_INDEX + 0);
-const TPM_HC NV_INDEX_LAST = (NV_INDEX_FIRST + 0x00FFFFFF);
-const TPM_HC PERMANENT_FIRST = TPM_RH_FIRST;
-const TPM_HC PERMANENT_LAST = TPM_RH_LAST;
+constexpr TPM_HC TRANSIENT_FIRST = (HR_TRANSIENT + 0);
+constexpr TPM_HC ACTIVE_SESSION_FIRST = POLICY_SESSION_FIRST;
+constexpr TPM_HC ACTIVE_SESSION_LAST = POLICY_SESSION_LAST;
+constexpr TPM_HC TRANSIENT_LAST = (TRANSIENT_FIRST + MAX_LOADED_OBJECTS - 1);
+constexpr TPM_HC PERSISTENT_FIRST = (HR_PERSISTENT + 0);
+constexpr TPM_HC PERSISTENT_LAST = (PERSISTENT_FIRST + 0x00FFFFFF);
+constexpr TPM_HC PLATFORM_PERSISTENT = (PERSISTENT_FIRST + 0x00800000);
+constexpr TPM_HC NV_INDEX_FIRST = (HR_NV_INDEX + 0);
+constexpr TPM_HC NV_INDEX_LAST = (NV_INDEX_FIRST + 0x00FFFFFF);
+constexpr TPM_HC PERMANENT_FIRST = TPM_RH_FIRST;
+constexpr TPM_HC PERMANENT_LAST = TPM_RH_LAST;
 
 struct TPMS_ALGORITHM_DESCRIPTION {
   TPM_ALG_ID alg;
diff --git a/trunks/tpm_simulator_handle.cc b/trunks/tpm_simulator_handle.cc
index 4f4354d..d47b0ef 100644
--- a/trunks/tpm_simulator_handle.cc
+++ b/trunks/tpm_simulator_handle.cc
@@ -44,10 +44,10 @@
 #if defined(USE_SIMULATOR)
   // Initialize TPM.
   CHECK_EQ(chdir("/data/misc/trunksd"), 0);
+  TPM_Manufacture(TRUE);
+  _plat__SetNvAvail();
   _plat__Signal_PowerOn();
   _TPM_Init();
-  _plat__SetNvAvail();
-  CHECK_EQ(TPM_Manufacture(TRUE), 0);
   LOG(INFO) << "Simulator initialized.";
 #else
   LOG(FATAL) << "Simulator not configured.";
diff --git a/trunks/tpm_utility.h b/trunks/tpm_utility.h
index bb61cfe..b282fa3 100644
--- a/trunks/tpm_utility.h
+++ b/trunks/tpm_utility.h
@@ -18,6 +18,7 @@
 #define TRUNKS_TPM_UTILITY_H_
 
 #include <string>
+#include <vector>
 
 #include <base/macros.h>
 
@@ -110,7 +111,7 @@
                                    AuthorizationDelegate* delegate,
                                    std::string* ciphertext) = 0;
 
-  // This method performs a decyption operating using a loaded RSA key
+  // This method performs a decryption operating using a loaded RSA key
   // referenced by its handle |key_handle|. The |ciphertext| is then decrypted
   // to give us the |plaintext|. |scheme| refers to the decryption scheme
   // used. By default it is OAEP, but TPM_ALG_RSAES can be specified.
@@ -247,11 +248,15 @@
 
   // This method defines a non-volatile storage area in the TPM, referenced
   // by |index| of size |num_bytes|. This command needs owner authorization.
-  // By default non-volatile space created is unlocked and anyone can write to
-  // it. The space can be permanently locked for writing by calling the
-  // LockNVSpace method.
+  // The |attributes| of the space must be specified as a combination of
+  // TPMA_NV_* values. Optionally, an |authorization_value| and / or
+  // |policy_digest| can be specified which will be associated with the space.
+  // These values must either be a valid SHA256 digest (or empty).
   virtual TPM_RC DefineNVSpace(uint32_t index,
                                size_t num_bytes,
+                               TPMA_NV attributes,
+                               const std::string& authorization_value,
+                               const std::string& policy_digest,
                                AuthorizationDelegate* delegate) = 0;
 
   // This method destroys the non-volatile space referred to by |index|.
@@ -259,26 +264,34 @@
   virtual TPM_RC DestroyNVSpace(uint32_t index,
                                 AuthorizationDelegate* delegate) = 0;
 
-  // This method locks the non-volatile space referred to by |index|. After a
-  // non-volatile space has been locked, it cannot be written to. Locked spaces
-  // can still be freely read. This command needs owner authorization.
+  // This method locks the non-volatile space referred to by |index|. The caller
+  // needs indicate whether they want to |lock_read| and / or |lock_write|. They
+  // also need to indicate if they are |using_owner_authorization|.
   virtual TPM_RC LockNVSpace(uint32_t index,
+                             bool lock_read,
+                             bool lock_write,
+                             bool using_owner_authorization,
                              AuthorizationDelegate* delegate) = 0;
 
   // This method writes |nvram_data| to the non-volatile space referenced by
-  // |index|, at |offset| bytes from the start of the non-volatile space.
+  // |index|, at |offset| bytes from the start of the non-volatile space. The
+  // caller needs to indicate if they are |using_owner_authorization|. If
+  // |extend| is set, the value will be extended and offset ignored.
   virtual TPM_RC WriteNVSpace(uint32_t index,
                               uint32_t offset,
                               const std::string& nvram_data,
+                              bool using_owner_authorization,
+                              bool extend,
                               AuthorizationDelegate* delegate) = 0;
 
   // This method reads |num_bytes| of data from the |offset| located at the
   // non-volatile space defined by |index|. This method returns an error if
   // |length| + |offset| is larger than the size of the defined non-volatile
-  // space.
+  // space. The caller needs to indicate if they are |using_owner_authorization|
   virtual TPM_RC ReadNVSpace(uint32_t index,
                              uint32_t offset,
                              size_t num_bytes,
+                             bool using_owner_authorization,
                              std::string* nvram_data,
                              AuthorizationDelegate* delegate) = 0;
 
@@ -291,6 +304,21 @@
   virtual TPM_RC GetNVSpacePublicArea(uint32_t index,
                                       TPMS_NV_PUBLIC* public_data) = 0;
 
+  // Lists all defined NV indexes.
+  virtual TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) = 0;
+
+  // Sets dictionary attack parameters. Requires lockout authorization.
+  // Parameters map directly to TPM2_DictionaryAttackParameters in the TPM 2.0
+  // specification.
+  virtual TPM_RC SetDictionaryAttackParameters(
+      uint32_t max_tries,
+      uint32_t recovery_time,
+      uint32_t lockout_recovery,
+      AuthorizationDelegate* delegate) = 0;
+
+  // Reset dictionary attack lockout. Requires lockout authorization.
+  virtual TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) = 0;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TpmUtility);
 };
diff --git a/trunks/tpm_utility_impl.cc b/trunks/tpm_utility_impl.cc
index fe79d93..880f1ea 100644
--- a/trunks/tpm_utility_impl.cc
+++ b/trunks/tpm_utility_impl.cc
@@ -112,12 +112,14 @@
         TPM_RH_PLATFORM, NameFromHandle(TPM_RH_PLATFORM), authorization.get());
   }
   if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
-    LOG(INFO) << "Clear failed because of BAD_AUTH. This probably means "
+    LOG(INFO) << __func__
+              << ": Clear failed because of BAD_AUTH. This probably means "
               << "that the TPM was already initialized.";
     return result;
   }
   if (result) {
-    LOG(ERROR) << "Failed to clear the TPM: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Failed to clear the TPM: " << GetErrorString(result);
   }
   return result;
 }
@@ -126,7 +128,8 @@
   TPM_RC return_code = factory_.GetTpm()->ShutdownSync(TPM_SU_CLEAR, nullptr);
   if (return_code && return_code != TPM_RC_INITIALIZE) {
     // This should not happen, but if it does, there is nothing we can do.
-    LOG(ERROR) << "Error shutting down: " << GetErrorString(return_code);
+    LOG(ERROR) << __func__
+               << ": Error shutting down: " << GetErrorString(return_code);
   }
 }
 
@@ -140,10 +143,11 @@
   }
   // Warn about various unexpected conditions.
   if (!tpm_state->WasShutdownOrderly()) {
-    LOG(WARNING) << "WARNING: The last TPM shutdown was not orderly.";
+    LOG(WARNING) << __func__
+                 << ": WARNING: The last TPM shutdown was not orderly.";
   }
   if (tpm_state->IsInLockout()) {
-    LOG(WARNING) << "WARNING: The TPM is currently in lockout.";
+    LOG(WARNING) << __func__ << ": WARNING: The TPM is currently in lockout.";
   }
 
   // We expect the firmware has already locked down the platform hierarchy. If
@@ -185,7 +189,8 @@
       TPM_CAP_PCRS, 0 /*property (not used)*/, 1 /*property_count*/, &more_data,
       &capability_data, nullptr /*authorization_delegate*/);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error querying PCRs: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error querying PCRs: " << GetErrorString(result);
     return result;
   }
   TPML_PCR_SELECTION& existing_pcrs = capability_data.data.assigned_pcr;
@@ -229,11 +234,12 @@
       &allocation_success, &max_pcr, &size_needed, &size_available,
       platform_delegate.get());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error allocating PCRs: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error allocating PCRs: " << GetErrorString(result);
     return result;
   }
   if (allocation_success != YES) {
-    LOG(ERROR) << "PCR allocation unsuccessful.";
+    LOG(ERROR) << __func__ << ": PCR allocation unsuccessful.";
     return TPM_RC_FAILURE;
   }
   return TPM_RC_SUCCESS;
@@ -247,25 +253,28 @@
   TPM_RC result = TPM_RC_SUCCESS;
   result = SetKnownOwnerPassword(kWellKnownPassword);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error injecting known password: " << GetErrorString(result);
+    LOG(ERROR) << __func__ << ": Error injecting known password: "
+               << GetErrorString(result);
     return result;
   }
 
   result = CreateStorageRootKeys(kWellKnownPassword);
   if (result) {
-    LOG(ERROR) << "Error creating SRKs: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error creating SRKs: " << GetErrorString(result);
     return result;
   }
   result = CreateSaltingKey(kWellKnownPassword);
   if (result) {
-    LOG(ERROR) << "Error creating salting key: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error creating salting key: " << GetErrorString(result);
     return result;
   }
 
   std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   result = session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error initializing AuthorizationSession: "
+    LOG(ERROR) << __func__ << ": Error initializing AuthorizationSession: "
                << GetErrorString(result);
     return result;
   }
@@ -297,11 +306,12 @@
                                      session->GetDelegate());
   if ((GetFormatOneError(result) == TPM_RC_BAD_AUTH) &&
       tpm_state->IsOwnerPasswordSet()) {
-    LOG(WARNING) << "Error changing owner password. This probably because "
+    LOG(WARNING) << __func__
+                 << ": Error changing owner password. This probably because "
                  << "ownership is already taken.";
     return TPM_RC_SUCCESS;
   } else if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error changing owner authorization: "
+    LOG(ERROR) << __func__ << ": Error changing owner authorization: "
                << GetErrorString(result);
     return result;
   }
@@ -326,7 +336,7 @@
   while (bytes_left > 0) {
     rc = factory_.GetTpm()->GetRandomSync(bytes_left, &digest, delegate);
     if (rc) {
-      LOG(ERROR) << "Error getting random data from tpm.";
+      LOG(ERROR) << __func__ << ": Error getting random data from tpm.";
       return rc;
     }
     random_data->append(StringFrom_TPM2B_DIGEST(digest));
@@ -340,7 +350,7 @@
                                  const std::string& extend_data,
                                  AuthorizationDelegate* delegate) {
   if (pcr_index < 0 || pcr_index >= IMPLEMENTATION_PCR) {
-    LOG(ERROR) << "Using a PCR index that isnt implemented.";
+    LOG(ERROR) << __func__ << ": Using a PCR index that isn't implemented.";
     return TPM_RC_FAILURE;
   }
   TPM_HANDLE pcr_handle = HR_PCR + pcr_index;
@@ -350,6 +360,11 @@
   digests.digests[0].hash_alg = TPM_ALG_SHA256;
   crypto::SHA256HashString(extend_data, digests.digests[0].digest.sha256,
                            crypto::kSHA256Length);
+  std::unique_ptr<AuthorizationDelegate> empty_password_delegate =
+      factory_.GetPasswordAuthorization("");
+  if (!delegate) {
+    delegate = empty_password_delegate.get();
+  }
   return factory_.GetTpm()->PCR_ExtendSync(pcr_handle, pcr_name, digests,
                                            delegate);
 }
@@ -373,14 +388,15 @@
       factory_.GetTpm()->PCR_ReadSync(pcr_select_in, &pcr_update_counter,
                                       &pcr_select_out, &pcr_values, nullptr);
   if (rc) {
-    LOG(INFO) << "Error trying to read a pcr: " << GetErrorString(rc);
+    LOG(INFO) << __func__
+              << ": Error trying to read a pcr: " << GetErrorString(rc);
     return rc;
   }
   if (pcr_select_out.count != 1 ||
       pcr_select_out.pcr_selections[0].sizeof_select < (pcr_select_index + 1) ||
       pcr_select_out.pcr_selections[0].pcr_select[pcr_select_index] !=
           pcr_select_byte) {
-    LOG(ERROR) << "TPM did not return the requested PCR";
+    LOG(ERROR) << __func__ << ": TPM did not return the requested PCR";
     return TPM_RC_FAILURE;
   }
   CHECK_GE(pcr_values.count, 1U);
@@ -404,30 +420,31 @@
     in_scheme.scheme = TPM_ALG_OAEP;
     in_scheme.details.oaep.hash_alg = hash_alg;
   } else {
-    LOG(ERROR) << "Invalid Signing scheme used.";
+    LOG(ERROR) << __func__ << ": Invalid Signing scheme used.";
     return SAPI_RC_BAD_PARAMETER;
   }
 
   TPMT_PUBLIC public_area;
   TPM_RC result = GetKeyPublicArea(key_handle, &public_area);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error finding public area for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
     return result;
   } else if (public_area.type != TPM_ALG_RSA) {
-    LOG(ERROR) << "Key handle given is not an RSA key";
+    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kDecrypt) == 0) {
-    LOG(ERROR) << "Key handle given is not a decryption key";
+    LOG(ERROR) << __func__ << ": Key handle given is not a decryption key";
     return SAPI_RC_BAD_PARAMETER;
   }
   if ((public_area.object_attributes & kRestricted) != 0) {
-    LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
+    LOG(ERROR) << __func__
+               << ": Cannot use RSAES for encryption with a restricted key";
     return SAPI_RC_BAD_PARAMETER;
   }
   std::string key_name;
   result = ComputeKeyName(public_area, &key_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error computing key name for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
     return result;
   }
 
@@ -439,7 +456,8 @@
                                               in_scheme, label, &out_message,
                                               delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error performing RSA encrypt: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error performing RSA encrypt: " << GetErrorString(result);
     return result;
   }
   ciphertext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
@@ -462,36 +480,38 @@
     in_scheme.scheme = TPM_ALG_OAEP;
     in_scheme.details.oaep.hash_alg = hash_alg;
   } else {
-    LOG(ERROR) << "Invalid Signing scheme used.";
+    LOG(ERROR) << __func__ << ": Invalid Signing scheme used.";
     return SAPI_RC_BAD_PARAMETER;
   }
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   TPMT_PUBLIC public_area;
   result = GetKeyPublicArea(key_handle, &public_area);
   if (result) {
-    LOG(ERROR) << "Error finding public area for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
     return result;
   } else if (public_area.type != TPM_ALG_RSA) {
-    LOG(ERROR) << "Key handle given is not an RSA key";
+    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kDecrypt) == 0) {
-    LOG(ERROR) << "Key handle given is not a decryption key";
+    LOG(ERROR) << __func__ << ": Key handle given is not a decryption key";
     return SAPI_RC_BAD_PARAMETER;
   }
   if ((public_area.object_attributes & kRestricted) != 0) {
-    LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
+    LOG(ERROR) << __func__
+               << ": Cannot use RSAES for encryption with a restricted key";
     return SAPI_RC_BAD_PARAMETER;
   }
   std::string key_name;
   result = ComputeKeyName(public_area, &key_name);
   if (result) {
-    LOG(ERROR) << "Error computing key name for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
     return result;
   }
 
@@ -503,7 +523,8 @@
                                               in_scheme, label, &out_message,
                                               delegate);
   if (result) {
-    LOG(ERROR) << "Error performing RSA decrypt: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error performing RSA decrypt: " << GetErrorString(result);
     return result;
   }
   plaintext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
@@ -527,36 +548,37 @@
     in_scheme.scheme = TPM_ALG_RSASSA;
     in_scheme.details.rsassa.hash_alg = hash_alg;
   } else {
-    LOG(ERROR) << "Invalid Signing scheme used.";
+    LOG(ERROR) << __func__ << ": Invalid Signing scheme used.";
     return SAPI_RC_BAD_PARAMETER;
   }
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   TPMT_PUBLIC public_area;
   result = GetKeyPublicArea(key_handle, &public_area);
   if (result) {
-    LOG(ERROR) << "Error finding public area for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
     return result;
   } else if (public_area.type != TPM_ALG_RSA) {
-    LOG(ERROR) << "Key handle given is not an RSA key";
+    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kSign) == 0) {
-    LOG(ERROR) << "Key handle given is not a signging key";
+    LOG(ERROR) << __func__ << ": Key handle given is not a signging key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kRestricted) != 0) {
-    LOG(ERROR) << "Key handle references a restricted key";
+    LOG(ERROR) << __func__ << ": Key handle references a restricted key";
     return SAPI_RC_BAD_PARAMETER;
   }
 
   std::string key_name;
   result = ComputeKeyName(public_area, &key_name);
   if (result) {
-    LOG(ERROR) << "Error computing key name for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
     return result;
   }
   std::string digest = HashString(plaintext, hash_alg);
@@ -570,7 +592,8 @@
       factory_.GetTpm()->SignSync(key_handle, key_name, tpm_digest, in_scheme,
                                   validation, &signature_out, delegate);
   if (result) {
-    LOG(ERROR) << "Error signing digest: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error signing digest: " << GetErrorString(result);
     return result;
   }
   if (scheme == TPM_ALG_RSAPSS) {
@@ -594,16 +617,17 @@
   TPMT_PUBLIC public_area;
   TPM_RC return_code = GetKeyPublicArea(key_handle, &public_area);
   if (return_code) {
-    LOG(ERROR) << "Error finding public area for: " << key_handle;
+    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
     return return_code;
   } else if (public_area.type != TPM_ALG_RSA) {
-    LOG(ERROR) << "Key handle given is not an RSA key";
+    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kSign) == 0) {
-    LOG(ERROR) << "Key handle given is not a signing key";
+    LOG(ERROR) << __func__ << ": Key handle given is not a signing key";
     return SAPI_RC_BAD_PARAMETER;
   } else if ((public_area.object_attributes & kRestricted) != 0) {
-    LOG(ERROR) << "Cannot use RSAPSS for signing with a restricted key";
+    LOG(ERROR) << __func__
+               << ": Cannot use RSAPSS for signing with a restricted key";
     return SAPI_RC_BAD_PARAMETER;
   }
   if (hash_alg == TPM_ALG_NULL) {
@@ -620,7 +644,7 @@
     signature_in.signature.rsassa.hash = hash_alg;
     signature_in.signature.rsassa.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature);
   } else {
-    LOG(ERROR) << "Invalid scheme used to verify signature.";
+    LOG(ERROR) << __func__ << ": Invalid scheme used to verify signature.";
     return SAPI_RC_BAD_PARAMETER;
   }
   std::string key_name;
@@ -630,10 +654,11 @@
   return_code = factory_.GetTpm()->VerifySignatureSync(
       key_handle, key_name, tpm_digest, signature_in, &verified, delegate);
   if (return_code == TPM_RC_SIGNATURE) {
-    LOG(WARNING) << "Incorrect signature for given digest.";
+    LOG(WARNING) << __func__ << ": Incorrect signature for given digest.";
     return TPM_RC_SIGNATURE;
   } else if (return_code && return_code != TPM_RC_SIGNATURE) {
-    LOG(ERROR) << "Error verifying signature: " << GetErrorString(return_code);
+    LOG(ERROR) << __func__ << ": Error verifying signature: "
+               << GetErrorString(return_code);
     return return_code;
   }
   return TPM_RC_SUCCESS;
@@ -646,7 +671,7 @@
   TPMT_TK_CREATION creation_ticket;
   if (!factory_.GetBlobParser()->ParseCreationBlob(
           creation_blob, &creation_data, &creation_hash, &creation_ticket)) {
-    LOG(ERROR) << "Error parsing CreationBlob.";
+    LOG(ERROR) << __func__ << ": Error parsing CreationBlob.";
     return SAPI_RC_BAD_PARAMETER;
   }
   TPM2B_DATA qualifying_data;
@@ -661,7 +686,8 @@
       TPM_RH_NULL, "", key_handle, "", qualifying_data, creation_hash,
       in_scheme, creation_ticket, &certify_info, &signature, delegate.get());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error certifying key creation: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error certifying key creation: " << GetErrorString(result);
     return result;
   }
   return TPM_RC_SUCCESS;
@@ -675,7 +701,8 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
@@ -683,13 +710,13 @@
   std::string parent_name;
   result = GetKeyName(key_handle, &key_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for key_handle: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for key_handle: "
                << GetErrorString(result);
     return result;
   }
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for RSA-SRK: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
                << GetErrorString(result);
     return result;
   }
@@ -700,7 +727,7 @@
       key_handle, key_name, kRSAStorageRootKey, parent_name, new_auth,
       &new_private_data, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error changing object authorization data: "
+    LOG(ERROR) << __func__ << ": Error changing object authorization data: "
                << GetErrorString(result);
     return result;
   }
@@ -728,14 +755,15 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   std::string parent_name;
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for RSA-SRK: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
                << GetErrorString(result);
     return result;
   }
@@ -774,7 +802,7 @@
   result = EncryptPrivateData(in_sensitive, public_area, &private_data,
                               &encryption_key);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error creating encrypted private struct: "
+    LOG(ERROR) << __func__ << ": Error creating encrypted private struct: "
                << GetErrorString(result);
     return result;
   }
@@ -784,7 +812,8 @@
       kRSAStorageRootKey, parent_name, encryption_key, public_data,
       private_data, in_sym_seed, symmetric_alg, &tpm_private_data, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error importing key: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error importing key: " << GetErrorString(result);
     return result;
   }
   if (key_blob) {
@@ -810,14 +839,15 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   std::string parent_name;
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for RSA-SRK: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
                << GetErrorString(result);
     return result;
   }
@@ -847,7 +877,8 @@
     creation_pcrs.count = 0;
   } else if (creation_pcr_index < 0 ||
              creation_pcr_index > (PCR_SELECT_MIN * 8)) {
-    LOG(ERROR) << "Creation PCR index is not within the allocated bank.";
+    LOG(ERROR) << __func__
+               << ": Creation PCR index is not within the allocated bank.";
     return SAPI_RC_BAD_PARAMETER;
   } else {
     creation_pcrs.count = 1;
@@ -874,7 +905,8 @@
       Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
       &out_public, &creation_data, &creation_hash, &creation_ticket, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error creating RSA key: " << GetErrorString(result);
     return result;
   }
   if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private,
@@ -897,14 +929,16 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   std::string parent_name;
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting parent key name: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error getting parent key name: " << GetErrorString(result);
     return result;
   }
   TPM2B_PUBLIC in_public;
@@ -919,7 +953,7 @@
       factory_.GetTpm()->LoadSync(kRSAStorageRootKey, parent_name, in_private,
                                   in_public, key_handle, &key_name, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error loading key: " << GetErrorString(result);
+    LOG(ERROR) << __func__ << ": Error loading key: " << GetErrorString(result);
     return result;
   }
   return TPM_RC_SUCCESS;
@@ -931,12 +965,14 @@
   TPMT_PUBLIC public_data;
   result = GetKeyPublicArea(handle, &public_data);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error fetching public info: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error fetching public info: " << GetErrorString(result);
     return result;
   }
   result = ComputeKeyName(public_data, name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error computing key name: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error computing key name: " << GetErrorString(result);
     return TPM_RC_SUCCESS;
   }
   return TPM_RC_SUCCESS;
@@ -952,7 +988,8 @@
   TPM_RC return_code = factory_.GetTpm()->ReadPublicSync(
       handle, handle_name, &public_area, &out_name, &qualified_name, nullptr);
   if (return_code) {
-    LOG(ERROR) << "Error getting public area for object: " << handle;
+    LOG(ERROR) << __func__
+               << ": Error getting public area for object: " << handle;
     return return_code;
   }
   *public_data = public_area.public_area;
@@ -967,14 +1004,15 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
   std::string parent_name;
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for RSA-SRK: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
                << GetErrorString(result);
     return result;
   }
@@ -1003,7 +1041,8 @@
       Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
       &out_public, &creation_data, &creation_hash, &creation_ticket, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error creating sealed object: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error creating sealed object: " << GetErrorString(result);
     return result;
   }
   if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private,
@@ -1020,7 +1059,8 @@
   TPM_RC result;
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
@@ -1029,21 +1069,24 @@
       factory_.GetPasswordAuthorization("");
   result = LoadKey(sealed_data, password_delegate.get(), &object_handle);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error loading sealed object: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error loading sealed object: " << GetErrorString(result);
     return result;
   }
   ScopedKeyHandle sealed_object(factory_, object_handle);
   std::string object_name;
   result = GetKeyName(sealed_object.get(), &object_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting object name: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error getting object name: " << GetErrorString(result);
     return result;
   }
   TPM2B_SENSITIVE_DATA out_data;
   result = factory_.GetTpm()->UnsealSync(sealed_object.get(), object_name,
                                          &out_data, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error unsealing object: " << GetErrorString(result);
     return result;
   }
   *unsealed_data = StringFrom_TPM2B_SENSITIVE_DATA(out_data);
@@ -1053,7 +1096,8 @@
 TPM_RC TpmUtilityImpl::StartSession(HmacSession* session) {
   TPM_RC result = session->StartUnboundSession(true /* enable_encryption */);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error starting unbound session: " << GetErrorString(result);
+    LOG(ERROR) << __func__ << ": Error starting unbound session: "
+               << GetErrorString(result);
     return result;
   }
   session->SetEntityAuthorizationValue("");
@@ -1067,7 +1111,7 @@
   std::unique_ptr<PolicySession> session = factory_.GetTrialSession();
   TPM_RC result = session->StartUnboundSession(false);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error starting unbound trial session: "
+    LOG(ERROR) << __func__ << ": Error starting unbound trial session: "
                << GetErrorString(result);
     return result;
   }
@@ -1075,7 +1119,8 @@
   if (pcr_value.empty()) {
     result = ReadPCR(pcr_index, &mutable_pcr_value);
     if (result != TPM_RC_SUCCESS) {
-      LOG(ERROR) << "Error reading pcr_value: " << GetErrorString(result);
+      LOG(ERROR) << __func__
+                 << ": Error reading pcr_value: " << GetErrorString(result);
       return result;
     }
   } else {
@@ -1083,13 +1128,14 @@
   }
   result = session->PolicyPCR(pcr_index, mutable_pcr_value);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error restricting policy to PCR value: "
+    LOG(ERROR) << __func__ << ": Error restricting policy to PCR value: "
                << GetErrorString(result);
     return result;
   }
   result = session->GetDigest(policy_digest);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error getting policy digest: " << GetErrorString(result);
     return result;
   }
   return TPM_RC_SUCCESS;
@@ -1097,23 +1143,29 @@
 
 TPM_RC TpmUtilityImpl::DefineNVSpace(uint32_t index,
                                      size_t num_bytes,
+                                     TPMA_NV attributes,
+                                     const std::string& authorization_value,
+                                     const std::string& policy_digest,
                                      AuthorizationDelegate* delegate) {
   TPM_RC result;
   if (num_bytes > MAX_NV_INDEX_SIZE) {
     result = SAPI_RC_BAD_SIZE;
-    LOG(ERROR) << "Cannot define non-volatile space of given size: "
+    LOG(ERROR) << __func__
+               << ": Cannot define non-volatile space of given size: "
                << GetErrorString(result);
     return result;
   }
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot define non-volatile space with the given index: "
+    LOG(ERROR) << __func__
+               << ": Cannot define non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
@@ -1121,24 +1173,16 @@
   TPMS_NV_PUBLIC public_data;
   public_data.nv_index = nv_index;
   public_data.name_alg = TPM_ALG_SHA256;
-  // We define the following attributes for NVSpaces created:
-  // TPMA_NV_NO_DA: Dictionary attack does not trigger on authorization errors.
-  // TPMA_NV_OWNERWRITE: Owner authorization must be provided on write actions.
-  // TPMA_NV_WRITEDEFINE: NVSpace is write lockable, and lock persists across
-  //                      reboot.
-  // TPMA_NV_AUTHREAD: The index authValue (default: "") can be used to
-  //                   authorize read actions.
-  public_data.attributes = TPMA_NV_NO_DA | TPMA_NV_OWNERWRITE |
-                           TPMA_NV_WRITEDEFINE | TPMA_NV_AUTHREAD;
-  public_data.auth_policy = Make_TPM2B_DIGEST("");
+  public_data.attributes = attributes;
+  public_data.auth_policy = Make_TPM2B_DIGEST(policy_digest);
   public_data.data_size = num_bytes;
-  TPM2B_AUTH authorization = Make_TPM2B_DIGEST("");
+  TPM2B_AUTH authorization = Make_TPM2B_DIGEST(authorization_value);
   TPM2B_NV_PUBLIC public_area = Make_TPM2B_NV_PUBLIC(public_data);
   result = factory_.GetTpm()->NV_DefineSpaceSync(
       TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), authorization, public_area,
       delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error defining non-volatile space: "
+    LOG(ERROR) << __func__ << ": Error defining non-volatile space: "
                << GetErrorString(result);
     return result;
   }
@@ -1151,13 +1195,15 @@
   TPM_RC result;
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot undefine non-volatile space with the given index: "
+    LOG(ERROR) << __func__
+               << ": Cannot undefine non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
   if (delegate == nullptr) {
     result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": This method needs a valid authorization delegate: "
                << GetErrorString(result);
     return result;
   }
@@ -1170,7 +1216,7 @@
   result = factory_.GetTpm()->NV_UndefineSpaceSync(
       TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), nv_index, nv_name, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error undefining non-volatile space: "
+    LOG(ERROR) << __func__ << ": Error undefining non-volatile space: "
                << GetErrorString(result);
     return result;
   }
@@ -1179,17 +1225,15 @@
 }
 
 TPM_RC TpmUtilityImpl::LockNVSpace(uint32_t index,
+                                   bool lock_read,
+                                   bool lock_write,
+                                   bool using_owner_authorization,
                                    AuthorizationDelegate* delegate) {
   TPM_RC result;
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot lock non-volatile space with the given index: "
-               << GetErrorString(result);
-    return result;
-  }
-  if (delegate == nullptr) {
-    result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": Cannot lock non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
@@ -1199,16 +1243,36 @@
     return result;
   }
   uint32_t nv_index = NV_INDEX_FIRST + index;
-  result = factory_.GetTpm()->NV_WriteLockSync(
-      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), nv_index, nv_name, delegate);
-  if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error locking non-volatile spaces: "
-               << GetErrorString(result);
-    return result;
+  TPMI_RH_NV_AUTH auth_target = nv_index;
+  std::string auth_target_name = nv_name;
+  if (using_owner_authorization) {
+    auth_target = TPM_RH_OWNER;
+    auth_target_name = NameFromHandle(TPM_RH_OWNER);
   }
   auto it = nvram_public_area_map_.find(index);
-  if (it != nvram_public_area_map_.end()) {
-    it->second.attributes |= TPMA_NV_WRITELOCKED;
+  if (lock_read) {
+    result = factory_.GetTpm()->NV_ReadLockSync(auth_target, auth_target_name,
+                                                nv_index, nv_name, delegate);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << __func__ << ": Error locking non-volatile space read: "
+                 << GetErrorString(result);
+      return result;
+    }
+    if (it != nvram_public_area_map_.end()) {
+      it->second.attributes |= TPMA_NV_READLOCKED;
+    }
+  }
+  if (lock_write) {
+    result = factory_.GetTpm()->NV_WriteLockSync(auth_target, auth_target_name,
+                                                 nv_index, nv_name, delegate);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << __func__ << ": Error locking non-volatile space write: "
+                 << GetErrorString(result);
+      return result;
+    }
+    if (it != nvram_public_area_map_.end()) {
+      it->second.attributes |= TPMA_NV_WRITELOCKED;
+    }
   }
   return TPM_RC_SUCCESS;
 }
@@ -1216,23 +1280,20 @@
 TPM_RC TpmUtilityImpl::WriteNVSpace(uint32_t index,
                                     uint32_t offset,
                                     const std::string& nvram_data,
+                                    bool using_owner_authorization,
+                                    bool extend,
                                     AuthorizationDelegate* delegate) {
   TPM_RC result;
   if (nvram_data.size() > MAX_NV_BUFFER_SIZE) {
     result = SAPI_RC_BAD_SIZE;
-    LOG(ERROR) << "Insufficient buffer for non-volatile write: "
+    LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile write: "
                << GetErrorString(result);
     return result;
   }
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot write to non-volatile space with the given index: "
-               << GetErrorString(result);
-    return result;
-  }
-  if (delegate == nullptr) {
-    result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": Cannot write to non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
@@ -1242,11 +1303,23 @@
     return result;
   }
   uint32_t nv_index = NV_INDEX_FIRST + index;
-  result = factory_.GetTpm()->NV_WriteSync(
-      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), nv_index, nv_name,
-      Make_TPM2B_MAX_NV_BUFFER(nvram_data), offset, delegate);
+  TPMI_RH_NV_AUTH auth_target = nv_index;
+  std::string auth_target_name = nv_name;
+  if (using_owner_authorization) {
+    auth_target = TPM_RH_OWNER;
+    auth_target_name = NameFromHandle(TPM_RH_OWNER);
+  }
+  if (extend) {
+    result = factory_.GetTpm()->NV_ExtendSync(
+        auth_target, auth_target_name, nv_index, nv_name,
+        Make_TPM2B_MAX_NV_BUFFER(nvram_data), delegate);
+  } else {
+    result = factory_.GetTpm()->NV_WriteSync(
+        auth_target, auth_target_name, nv_index, nv_name,
+        Make_TPM2B_MAX_NV_BUFFER(nvram_data), offset, delegate);
+  }
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error writing to non-volatile space: "
+    LOG(ERROR) << __func__ << ": Error writing to non-volatile space: "
                << GetErrorString(result);
     return result;
   }
@@ -1260,24 +1333,20 @@
 TPM_RC TpmUtilityImpl::ReadNVSpace(uint32_t index,
                                    uint32_t offset,
                                    size_t num_bytes,
+                                   bool using_owner_authorization,
                                    std::string* nvram_data,
                                    AuthorizationDelegate* delegate) {
   TPM_RC result;
   if (num_bytes > MAX_NV_BUFFER_SIZE) {
     result = SAPI_RC_BAD_SIZE;
-    LOG(ERROR) << "Insufficient buffer for non-volatile read: "
+    LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile read: "
                << GetErrorString(result);
     return result;
   }
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
-               << GetErrorString(result);
-    return result;
-  }
-  if (delegate == nullptr) {
-    result = SAPI_RC_INVALID_SESSIONS;
-    LOG(ERROR) << "This method needs a valid authorization delegate: "
+    LOG(ERROR) << __func__
+               << ": Cannot read from non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
@@ -1287,13 +1356,19 @@
     return result;
   }
   uint32_t nv_index = NV_INDEX_FIRST + index;
+  TPMI_RH_NV_AUTH auth_target = nv_index;
+  std::string auth_target_name = nv_name;
+  if (using_owner_authorization) {
+    auth_target = TPM_RH_OWNER;
+    auth_target_name = NameFromHandle(TPM_RH_OWNER);
+  }
   TPM2B_MAX_NV_BUFFER data_buffer;
   data_buffer.size = 0;
-  result =
-      factory_.GetTpm()->NV_ReadSync(nv_index, nv_name, nv_index, nv_name,
-                                     num_bytes, offset, &data_buffer, delegate);
+  result = factory_.GetTpm()->NV_ReadSync(auth_target, auth_target_name,
+                                          nv_index, nv_name, num_bytes, offset,
+                                          &data_buffer, delegate);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error reading from non-volatile space: "
+    LOG(ERROR) << __func__ << ": Error reading from non-volatile space: "
                << GetErrorString(result);
     return result;
   }
@@ -1305,7 +1380,8 @@
   TPM_RC result;
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
+    LOG(ERROR) << __func__
+               << ": Cannot read from non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
@@ -1326,7 +1402,8 @@
   TPM_RC result;
   if (index > kMaxNVSpaceIndex) {
     result = SAPI_RC_BAD_PARAMETER;
-    LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
+    LOG(ERROR) << __func__
+               << ": Cannot read from non-volatile space with the given index: "
                << GetErrorString(result);
     return result;
   }
@@ -1342,7 +1419,8 @@
   result = factory_.GetTpm()->NV_ReadPublicSync(nv_index, "", &public_area,
                                                 &nvram_name, nullptr);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error reading non-volatile space public information: "
+    LOG(ERROR) << __func__
+               << ": Error reading non-volatile space public information: "
                << GetErrorString(result);
     return result;
   }
@@ -1351,6 +1429,49 @@
   return TPM_RC_SUCCESS;
 }
 
+TPM_RC TpmUtilityImpl::ListNVSpaces(std::vector<uint32_t>* index_list) {
+  TPM_RC result;
+  TPMI_YES_NO more_data = YES;
+  TPMS_CAPABILITY_DATA capability_data;
+  TPM_HANDLE handle_base = HR_NV_INDEX;
+  while (more_data == YES) {
+    result = factory_.GetTpm()->GetCapabilitySync(
+        TPM_CAP_HANDLES, handle_base, MAX_CAP_HANDLES, &more_data,
+        &capability_data, nullptr /*authorization_delegate*/);
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << __func__
+                 << ": Error querying NV spaces: " << GetErrorString(result);
+      return result;
+    }
+    if (capability_data.capability != TPM_CAP_HANDLES) {
+      LOG(ERROR) << __func__ << ": Invalid capability type.";
+      return SAPI_RC_MALFORMED_RESPONSE;
+    }
+    TPML_HANDLE& handles = capability_data.data.handles;
+    for (uint32_t i = 0; i < handles.count; ++i) {
+      index_list->push_back(handles.handle[i] & HR_HANDLE_MASK);
+      handle_base = handles.handle[i] + 1;
+    }
+  }
+  return TPM_RC_SUCCESS;
+}
+
+TPM_RC TpmUtilityImpl::SetDictionaryAttackParameters(
+    uint32_t max_tries,
+    uint32_t recovery_time,
+    uint32_t lockout_recovery,
+    AuthorizationDelegate* delegate) {
+  return factory_.GetTpm()->DictionaryAttackParametersSync(
+      TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), max_tries, recovery_time,
+      lockout_recovery, delegate);
+}
+
+TPM_RC TpmUtilityImpl::ResetDictionaryAttackLock(
+    AuthorizationDelegate* delegate) {
+  return factory_.GetTpm()->DictionaryAttackLockResetSync(
+      TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), delegate);
+}
+
 TPM_RC TpmUtilityImpl::SetKnownOwnerPassword(
     const std::string& known_owner_password) {
   std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
@@ -1362,14 +1483,14 @@
   std::unique_ptr<AuthorizationDelegate> delegate =
       factory_.GetPasswordAuthorization("");
   if (tpm_state->IsOwnerPasswordSet()) {
-    LOG(INFO) << "Owner password is already set. "
+    LOG(INFO) << __func__ << ": Owner password is already set. "
               << "This is normal if ownership is already taken.";
     return TPM_RC_SUCCESS;
   }
   result = SetHierarchyAuthorization(TPM_RH_OWNER, known_owner_password,
                                      delegate.get());
   if (result) {
-    LOG(ERROR) << "Error setting storage hierarchy authorization "
+    LOG(ERROR) << __func__ << ": Error setting storage hierarchy authorization "
                << "to its default value: " << GetErrorString(result);
     return result;
   }
@@ -1433,12 +1554,12 @@
         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
         return result;
       }
-      LOG(INFO) << "Created RSA SRK.";
+      LOG(INFO) << __func__ << ": Created RSA SRK.";
     } else {
-      LOG(INFO) << "Skip RSA SRK because it already exists.";
+      LOG(INFO) << __func__ << ": Skip RSA SRK because it already exists.";
     }
   } else {
-    LOG(INFO) << "Skip RSA SRK because RSA is not supported.";
+    LOG(INFO) << __func__ << ": Skip RSA SRK because RSA is not supported.";
   }
 
   // Do it again for ECC.
@@ -1476,12 +1597,12 @@
         LOG(ERROR) << __func__ << ": " << GetErrorString(result);
         return result;
       }
-      LOG(INFO) << "Created ECC SRK.";
+      LOG(INFO) << __func__ << ": Created ECC SRK.";
     } else {
-      LOG(INFO) << "Skip ECC SRK because it already exists.";
+      LOG(INFO) << __func__ << ": Skip ECC SRK because it already exists.";
     }
   } else {
-    LOG(INFO) << "Skip ECC SRK because ECC is not supported.";
+    LOG(INFO) << __func__ << ": Skip ECC SRK because ECC is not supported.";
   }
   return TPM_RC_SUCCESS;
 }
@@ -1493,13 +1614,13 @@
     return result;
   }
   if (exists) {
-    LOG(INFO) << "Salting key already exists.";
+    LOG(INFO) << __func__ << ": Salting key already exists.";
     return TPM_RC_SUCCESS;
   }
   std::string parent_name;
   result = GetKeyName(kRSAStorageRootKey, &parent_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error getting Key name for RSA-SRK: "
+    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
                << GetErrorString(result);
     return result;
   }
@@ -1534,7 +1655,8 @@
       &out_public, &creation_data, &creation_hash, &creation_ticket,
       delegate.get());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error creating salting key: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error creating salting key: " << GetErrorString(result);
     return result;
   }
   TPM2B_NAME key_name;
@@ -1544,7 +1666,8 @@
                                        out_private, out_public, &key_handle,
                                        &key_name, delegate.get());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error loading salting key: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error loading salting key: " << GetErrorString(result);
     return result;
   }
   ScopedKeyHandle key(factory_, key_handle);
@@ -1582,7 +1705,8 @@
     public_area.type = TPM_ALG_KEYEDHASH;
     public_area.parameters.keyed_hash_detail.scheme.scheme = TPM_ALG_NULL;
   } else {
-    LOG(WARNING) << "Unrecognized key_type. Not filling parameters.";
+    LOG(WARNING) << __func__
+                 << ": Unrecognized key_type. Not filling parameters.";
   }
   return public_area;
 }
@@ -1592,7 +1716,8 @@
     const std::string& password,
     AuthorizationDelegate* authorization) {
   if (password.size() > kMaxPasswordLength) {
-    LOG(ERROR) << "Hierarchy passwords can be at most " << kMaxPasswordLength
+    LOG(ERROR) << __func__ << ": Hierarchy passwords can be at most "
+               << kMaxPasswordLength
                << " bytes. Current password length is: " << password.size();
     return SAPI_RC_BAD_SIZE;
   }
@@ -1622,13 +1747,15 @@
   std::string serialized_public_area;
   TPM_RC result = Serialize_TPMT_PUBLIC(public_area, &serialized_public_area);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error serializing public area: " << GetErrorString(result);
     return result;
   }
   std::string serialized_name_alg;
   result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error serializing public area: " << GetErrorString(result);
     return result;
   }
   object_name->assign(serialized_name_alg +
@@ -1648,13 +1775,15 @@
   TPM_RC result =
       Serialize_TPMS_NV_PUBLIC(nv_public_area, &serialized_public_area);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error serializing public area: " << GetErrorString(result);
     return result;
   }
   std::string serialized_name_alg;
   result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error serializing public area: " << GetErrorString(result);
     return result;
   }
   nv_name->assign(serialized_name_alg +
@@ -1671,14 +1800,15 @@
   TPM_RC result =
       Serialize_TPM2B_SENSITIVE(sensitive_data, &serialized_sensitive_data);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing sensitive data: "
+    LOG(ERROR) << __func__ << ": Error serializing sensitive data: "
                << GetErrorString(result);
     return result;
   }
   std::string object_name;
   result = ComputeKeyName(public_area, &object_name);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error computing object name: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error computing object name: " << GetErrorString(result);
     return result;
   }
   TPM2B_DIGEST inner_integrity = Make_TPM2B_DIGEST(
@@ -1686,7 +1816,7 @@
   std::string serialized_inner_integrity;
   result = Serialize_TPM2B_DIGEST(inner_integrity, &serialized_inner_integrity);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error serializing inner integrity: "
+    LOG(ERROR) << __func__ << ": Error serializing inner integrity: "
                << GetErrorString(result);
     return result;
   }
@@ -1703,7 +1833,8 @@
       unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT);
   *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string);
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error making private area: " << GetErrorString(result);
+    LOG(ERROR) << __func__
+               << ": Error making private area: " << GetErrorString(result);
     return result;
   }
   return TPM_RC_SUCCESS;
diff --git a/trunks/tpm_utility_impl.h b/trunks/tpm_utility_impl.h
index eb71eeb..36058f5 100644
--- a/trunks/tpm_utility_impl.h
+++ b/trunks/tpm_utility_impl.h
@@ -21,6 +21,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include <base/macros.h>
 #include <gtest/gtest_prod.h>
@@ -121,22 +122,39 @@
                                     std::string* policy_digest) override;
   TPM_RC DefineNVSpace(uint32_t index,
                        size_t num_bytes,
+                       TPMA_NV attributes,
+                       const std::string& authorization_value,
+                       const std::string& policy_digest,
                        AuthorizationDelegate* delegate) override;
   TPM_RC DestroyNVSpace(uint32_t index,
                         AuthorizationDelegate* delegate) override;
-  TPM_RC LockNVSpace(uint32_t index, AuthorizationDelegate* delegate) override;
+  TPM_RC LockNVSpace(uint32_t index,
+                     bool lock_read,
+                     bool lock_write,
+                     bool using_owner_authorization,
+                     AuthorizationDelegate* delegate) override;
   TPM_RC WriteNVSpace(uint32_t index,
                       uint32_t offset,
                       const std::string& nvram_data,
+                      bool using_owner_authorization,
+                      bool extend,
                       AuthorizationDelegate* delegate) override;
   TPM_RC ReadNVSpace(uint32_t index,
                      uint32_t offset,
                      size_t num_bytes,
+                     bool using_owner_authorization,
                      std::string* nvram_data,
                      AuthorizationDelegate* delegate) override;
   TPM_RC GetNVSpaceName(uint32_t index, std::string* name) override;
   TPM_RC GetNVSpacePublicArea(uint32_t index,
                               TPMS_NV_PUBLIC* public_data) override;
+  TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) override;
+  TPM_RC SetDictionaryAttackParameters(
+      uint32_t max_tries,
+      uint32_t recovery_time,
+      uint32_t lockout_recovery,
+      AuthorizationDelegate* delegate) override;
+  TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) override;
 
  private:
   friend class TpmUtilityTest;
diff --git a/trunks/tpm_utility_test.cc b/trunks/tpm_utility_test.cc
index 335e923..8c9898d 100644
--- a/trunks/tpm_utility_test.cc
+++ b/trunks/tpm_utility_test.cc
@@ -51,7 +51,7 @@
     factory_.set_tpm_state(&mock_tpm_state_);
     factory_.set_tpm(&mock_tpm_);
     factory_.set_hmac_session(&mock_hmac_session_);
-    factory_.set_policy_session(&mock_policy_session_);
+    factory_.set_trial_session(&mock_trial_session_);
   }
 
   TPM_RC ComputeKeyName(const TPMT_PUBLIC& public_area,
@@ -140,7 +140,7 @@
   NiceMock<MockTpm> mock_tpm_;
   NiceMock<MockAuthorizationDelegate> mock_authorization_delegate_;
   NiceMock<MockHmacSession> mock_hmac_session_;
-  NiceMock<MockPolicySession> mock_policy_session_;
+  NiceMock<MockPolicySession> mock_trial_session_;
   TpmUtilityImpl utility_;
 };
 
@@ -1528,10 +1528,10 @@
       .WillOnce(DoAll(SetArgPointee<2>(pcr_select),
                       SetArgPointee<3>(pcr_values), Return(TPM_RC_SUCCESS)));
   std::string tpm_pcr_value;
-  EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _))
+  EXPECT_CALL(mock_trial_session_, PolicyPCR(index, _))
       .WillOnce(DoAll(SaveArg<1>(&tpm_pcr_value), Return(TPM_RC_SUCCESS)));
   std::string tpm_policy_digest("digest");
-  EXPECT_CALL(mock_policy_session_, GetDigest(_))
+  EXPECT_CALL(mock_trial_session_, GetDigest(_))
       .WillOnce(
           DoAll(SetArgPointee<0>(tpm_policy_digest), Return(TPM_RC_SUCCESS)));
   EXPECT_EQ(TPM_RC_SUCCESS,
@@ -1545,10 +1545,10 @@
   std::string pcr_value("pcr_value");
   std::string policy_digest;
   std::string tpm_pcr_value;
-  EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _))
+  EXPECT_CALL(mock_trial_session_, PolicyPCR(index, _))
       .WillOnce(DoAll(SaveArg<1>(&tpm_pcr_value), Return(TPM_RC_SUCCESS)));
   std::string tpm_policy_digest("digest");
-  EXPECT_CALL(mock_policy_session_, GetDigest(_))
+  EXPECT_CALL(mock_trial_session_, GetDigest(_))
       .WillOnce(
           DoAll(SetArgPointee<0>(tpm_policy_digest), Return(TPM_RC_SUCCESS)));
   EXPECT_EQ(TPM_RC_SUCCESS, utility_.GetPolicyDigestForPcrValue(
@@ -1561,7 +1561,7 @@
   int index = 5;
   std::string pcr_value("value");
   std::string policy_digest;
-  EXPECT_CALL(mock_policy_session_, StartUnboundSession(false))
+  EXPECT_CALL(mock_trial_session_, StartUnboundSession(false))
       .WillOnce(Return(TPM_RC_FAILURE));
   EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(
                                 index, pcr_value, &policy_digest));
@@ -1580,7 +1580,7 @@
   int index = 5;
   std::string pcr_value("value");
   std::string policy_digest;
-  EXPECT_CALL(mock_policy_session_, PolicyPCR(index, _))
+  EXPECT_CALL(mock_trial_session_, PolicyPCR(index, _))
       .WillOnce(Return(TPM_RC_FAILURE));
   EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(
                                 index, pcr_value, &policy_digest));
@@ -1590,7 +1590,7 @@
   int index = 5;
   std::string pcr_value("value");
   std::string policy_digest;
-  EXPECT_CALL(mock_policy_session_, GetDigest(&policy_digest))
+  EXPECT_CALL(mock_trial_session_, GetDigest(&policy_digest))
       .WillOnce(Return(TPM_RC_FAILURE));
   EXPECT_EQ(TPM_RC_FAILURE, utility_.GetPolicyDigestForPcrValue(
                                 index, pcr_value, &policy_digest));
@@ -1600,35 +1600,36 @@
   uint32_t index = 59;
   uint32_t nvram_index = NV_INDEX_FIRST + index;
   size_t length = 256;
+  TPMA_NV attributes = TPMA_NV_WRITEDEFINE;
   TPM2B_NV_PUBLIC public_data;
   EXPECT_CALL(mock_tpm_, NV_DefineSpaceSync(TPM_RH_OWNER, _, _, _, _))
       .WillOnce(DoAll(SaveArg<3>(&public_data), Return(TPM_RC_SUCCESS)));
-  EXPECT_EQ(TPM_RC_SUCCESS, utility_.DefineNVSpace(
-                                index, length, &mock_authorization_delegate_));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.DefineNVSpace(index, length, attributes, "", "",
+                                   &mock_authorization_delegate_));
   EXPECT_EQ(public_data.nv_public.nv_index, nvram_index);
   EXPECT_EQ(public_data.nv_public.name_alg, TPM_ALG_SHA256);
-  EXPECT_EQ(public_data.nv_public.attributes,
-            TPMA_NV_NO_DA | TPMA_NV_OWNERWRITE | TPMA_NV_WRITEDEFINE |
-                TPMA_NV_AUTHREAD);
+  EXPECT_EQ(public_data.nv_public.attributes, attributes);
   EXPECT_EQ(public_data.nv_public.data_size, length);
 }
 
 TEST_F(TpmUtilityTest, DefineNVSpaceBadLength) {
   size_t bad_length = 3000;
-  EXPECT_EQ(
-      SAPI_RC_BAD_SIZE,
-      utility_.DefineNVSpace(0, bad_length, &mock_authorization_delegate_));
+  EXPECT_EQ(SAPI_RC_BAD_SIZE,
+            utility_.DefineNVSpace(0, bad_length, 0, "", "",
+                                   &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, DefineNVSpaceBadIndex) {
   uint32_t bad_index = 1 << 29;
-  EXPECT_EQ(
-      SAPI_RC_BAD_PARAMETER,
-      utility_.DefineNVSpace(bad_index, 2, &mock_authorization_delegate_));
+  EXPECT_EQ(SAPI_RC_BAD_PARAMETER,
+            utility_.DefineNVSpace(bad_index, 2, 0, "", "",
+                                   &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, DefineNVSpaceBadSession) {
-  EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.DefineNVSpace(0, 2, nullptr));
+  EXPECT_EQ(SAPI_RC_INVALID_SESSIONS,
+            utility_.DefineNVSpace(0, 2, 0, "", "", nullptr));
 }
 
 TEST_F(TpmUtilityTest, DefineNVSpaceFail) {
@@ -1636,8 +1637,9 @@
   size_t length = 256;
   EXPECT_CALL(mock_tpm_, NV_DefineSpaceSync(TPM_RH_OWNER, _, _, _, _))
       .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_EQ(TPM_RC_FAILURE, utility_.DefineNVSpace(
-                                index, length, &mock_authorization_delegate_));
+  EXPECT_EQ(TPM_RC_FAILURE,
+            utility_.DefineNVSpace(index, length, 0, "", "",
+                                   &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, DestroyNVSpaceSuccess) {
@@ -1669,26 +1671,70 @@
             utility_.DestroyNVSpace(index, &mock_authorization_delegate_));
 }
 
-TEST_F(TpmUtilityTest, LockNVSpaceSuccess) {
+TEST_F(TpmUtilityTest, LockNVSpaceWriteSuccess) {
   uint32_t index = 53;
   uint32_t nvram_index = NV_INDEX_FIRST + index;
   EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
       .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_CALL(mock_tpm_, NV_ReadLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
+      .Times(0);
   EXPECT_EQ(TPM_RC_SUCCESS,
-            utility_.LockNVSpace(index, &mock_authorization_delegate_));
+            utility_.LockNVSpace(index, false, true, true,
+                                 &mock_authorization_delegate_));
   TPMS_NV_PUBLIC public_area;
   EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area));
-  EXPECT_EQ(public_area.attributes & TPMA_NV_WRITELOCKED, TPMA_NV_WRITELOCKED);
+  EXPECT_EQ(TPMA_NV_WRITELOCKED, public_area.attributes & TPMA_NV_WRITELOCKED);
+}
+
+TEST_F(TpmUtilityTest, LockNVSpaceReadSuccess) {
+  uint32_t index = 53;
+  uint32_t nvram_index = NV_INDEX_FIRST + index;
+  EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
+      .Times(0);
+  EXPECT_CALL(mock_tpm_, NV_ReadLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.LockNVSpace(index, true, false, true,
+                                 &mock_authorization_delegate_));
+  TPMS_NV_PUBLIC public_area;
+  EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area));
+  EXPECT_EQ(TPMA_NV_READLOCKED, public_area.attributes & TPMA_NV_READLOCKED);
+}
+
+TEST_F(TpmUtilityTest, LockNVSpaceBothSuccess) {
+  uint32_t index = 53;
+  uint32_t nvram_index = NV_INDEX_FIRST + index;
+  EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_CALL(mock_tpm_, NV_ReadLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.LockNVSpace(index, true, true, true,
+                                 &mock_authorization_delegate_));
+  TPMS_NV_PUBLIC public_area;
+  EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area));
+  EXPECT_EQ(
+      (TPMA_NV_READLOCKED | TPMA_NV_WRITELOCKED),
+      public_area.attributes & (TPMA_NV_READLOCKED | TPMA_NV_WRITELOCKED));
+}
+
+TEST_F(TpmUtilityTest, LockNVSpaceBothNotOwner) {
+  uint32_t index = 53;
+  uint32_t nvram_index = NV_INDEX_FIRST + index;
+  EXPECT_CALL(mock_tpm_, NV_WriteLockSync(nvram_index, _, nvram_index, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_CALL(mock_tpm_, NV_ReadLockSync(nvram_index, _, nvram_index, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.LockNVSpace(index, true, true, false,
+                                 &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, LockNVSpaceBadIndex) {
   uint32_t bad_index = 1 << 24;
   EXPECT_EQ(SAPI_RC_BAD_PARAMETER,
-            utility_.LockNVSpace(bad_index, &mock_authorization_delegate_));
-}
-
-TEST_F(TpmUtilityTest, LockNVSpaceBadSession) {
-  EXPECT_EQ(SAPI_RC_INVALID_SESSIONS, utility_.LockNVSpace(52, nullptr));
+            utility_.LockNVSpace(bad_index, true, true, true,
+                                 &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, LockNVSpaceFailure) {
@@ -1697,7 +1743,8 @@
   EXPECT_CALL(mock_tpm_, NV_WriteLockSync(TPM_RH_OWNER, _, nvram_index, _, _))
       .WillOnce(Return(TPM_RC_FAILURE));
   EXPECT_EQ(TPM_RC_FAILURE,
-            utility_.LockNVSpace(index, &mock_authorization_delegate_));
+            utility_.LockNVSpace(index, true, true, true,
+                                 &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, WriteNVSpaceSuccess) {
@@ -1707,32 +1754,50 @@
   EXPECT_CALL(mock_tpm_,
               NV_WriteSync(TPM_RH_OWNER, _, nvram_index, _, _, offset, _))
       .WillOnce(Return(TPM_RC_SUCCESS));
-  EXPECT_EQ(
-      TPM_RC_SUCCESS,
-      utility_.WriteNVSpace(index, offset, "", &mock_authorization_delegate_));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.WriteNVSpace(index, offset, "", true, false,
+                                  &mock_authorization_delegate_));
   TPMS_NV_PUBLIC public_area;
   EXPECT_EQ(TPM_RC_SUCCESS, GetNVRAMMap(index, &public_area));
   EXPECT_EQ(public_area.attributes & TPMA_NV_WRITTEN, TPMA_NV_WRITTEN);
 }
 
+TEST_F(TpmUtilityTest, WriteNVSpaceNotOwner) {
+  uint32_t index = 53;
+  uint32_t offset = 5;
+  uint32_t nvram_index = NV_INDEX_FIRST + index;
+  EXPECT_CALL(mock_tpm_,
+              NV_WriteSync(nvram_index, _, nvram_index, _, _, offset, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.WriteNVSpace(index, offset, "", false, false,
+                                  &mock_authorization_delegate_));
+}
+
+TEST_F(TpmUtilityTest, ExtendNVSpace) {
+  uint32_t index = 53;
+  uint32_t offset = 5;
+  uint32_t nvram_index = NV_INDEX_FIRST + index;
+  EXPECT_CALL(mock_tpm_, NV_ExtendSync(TPM_RH_OWNER, _, nvram_index, _, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.WriteNVSpace(index, offset, "", true, true,
+                                  &mock_authorization_delegate_));
+}
+
 TEST_F(TpmUtilityTest, WriteNVSpaceBadSize) {
   uint32_t index = 53;
   std::string nvram_data(1025, 0);
   EXPECT_EQ(SAPI_RC_BAD_SIZE,
-            utility_.WriteNVSpace(index, 0, nvram_data,
+            utility_.WriteNVSpace(index, 0, nvram_data, true, false,
                                   &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, WriteNVSpaceBadIndex) {
   uint32_t bad_index = 1 << 24;
-  EXPECT_EQ(
-      SAPI_RC_BAD_PARAMETER,
-      utility_.WriteNVSpace(bad_index, 0, "", &mock_authorization_delegate_));
-}
-
-TEST_F(TpmUtilityTest, WriteNVSpaceBadSessions) {
-  EXPECT_EQ(SAPI_RC_INVALID_SESSIONS,
-            utility_.WriteNVSpace(53, 0, "", nullptr));
+  EXPECT_EQ(SAPI_RC_BAD_PARAMETER,
+            utility_.WriteNVSpace(bad_index, 0, "", true, false,
+                                  &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, WriteNVSpaceFailure) {
@@ -1742,9 +1807,9 @@
   EXPECT_CALL(mock_tpm_,
               NV_WriteSync(TPM_RH_OWNER, _, nvram_index, _, _, offset, _))
       .WillOnce(Return(TPM_RC_FAILURE));
-  EXPECT_EQ(
-      TPM_RC_FAILURE,
-      utility_.WriteNVSpace(index, offset, "", &mock_authorization_delegate_));
+  EXPECT_EQ(TPM_RC_FAILURE,
+            utility_.WriteNVSpace(index, offset, "", true, false,
+                                  &mock_authorization_delegate_));
 }
 
 TEST_F(TpmUtilityTest, ReadNVSpaceSuccess) {
@@ -1757,7 +1822,21 @@
               NV_ReadSync(nv_index, _, nv_index, _, length, offset, _, _))
       .WillOnce(Return(TPM_RC_SUCCESS));
   EXPECT_EQ(TPM_RC_SUCCESS,
-            utility_.ReadNVSpace(index, offset, length, &nvram_data,
+            utility_.ReadNVSpace(index, offset, length, false, &nvram_data,
+                                 &mock_authorization_delegate_));
+}
+
+TEST_F(TpmUtilityTest, ReadNVSpaceOwner) {
+  uint32_t index = 53;
+  uint32_t offset = 5;
+  uint32_t nv_index = NV_INDEX_FIRST + index;
+  size_t length = 24;
+  std::string nvram_data;
+  EXPECT_CALL(mock_tpm_,
+              NV_ReadSync(TPM_RH_OWNER, _, nv_index, _, length, offset, _, _))
+      .WillOnce(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.ReadNVSpace(index, offset, length, true, &nvram_data,
                                  &mock_authorization_delegate_));
 }
 
@@ -1765,7 +1844,7 @@
   size_t length = 1025;
   std::string nvram_data;
   EXPECT_EQ(SAPI_RC_BAD_SIZE,
-            utility_.ReadNVSpace(52, 0, length, &nvram_data,
+            utility_.ReadNVSpace(52, 0, length, true, &nvram_data,
                                  &mock_authorization_delegate_));
 }
 
@@ -1773,16 +1852,10 @@
   uint32_t bad_index = 1 << 24;
   std::string nvram_data;
   EXPECT_EQ(SAPI_RC_BAD_PARAMETER,
-            utility_.ReadNVSpace(bad_index, 0, 5, &nvram_data,
+            utility_.ReadNVSpace(bad_index, 0, 5, true, &nvram_data,
                                  &mock_authorization_delegate_));
 }
 
-TEST_F(TpmUtilityTest, ReadNVSpaceBadSession) {
-  std::string nvram_data;
-  EXPECT_EQ(SAPI_RC_INVALID_SESSIONS,
-            utility_.ReadNVSpace(53, 0, 5, &nvram_data, nullptr));
-}
-
 TEST_F(TpmUtilityTest, ReadNVSpaceFailure) {
   uint32_t index = 53;
   uint32_t offset = 5;
@@ -1793,7 +1866,7 @@
               NV_ReadSync(nv_index, _, nv_index, _, length, offset, _, _))
       .WillOnce(Return(TPM_RC_FAILURE));
   EXPECT_EQ(TPM_RC_FAILURE,
-            utility_.ReadNVSpace(index, offset, length, &nvram_data,
+            utility_.ReadNVSpace(index, offset, length, false, &nvram_data,
                                  &mock_authorization_delegate_));
 }
 
@@ -1930,4 +2003,34 @@
   EXPECT_EQ(TPM_RC_SUCCESS, CreateSaltingKey("password"));
 }
 
+TEST_F(TpmUtilityTest, SetDictionaryAttackParametersSuccess) {
+  EXPECT_CALL(mock_tpm_, DictionaryAttackParametersSync(TPM_RH_LOCKOUT, _, 1, 2,
+                                                        3, nullptr))
+      .WillRepeatedly(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS,
+            utility_.SetDictionaryAttackParameters(1, 2, 3, nullptr));
+}
+
+TEST_F(TpmUtilityTest, SetDictionaryAttackParametersFailure) {
+  EXPECT_CALL(mock_tpm_, DictionaryAttackParametersSync(TPM_RH_LOCKOUT, _, 1, 2,
+                                                        3, nullptr))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_EQ(TPM_RC_FAILURE,
+            utility_.SetDictionaryAttackParameters(1, 2, 3, nullptr));
+}
+
+TEST_F(TpmUtilityTest, ResetDictionaryAttackLockSuccess) {
+  EXPECT_CALL(mock_tpm_,
+              DictionaryAttackLockResetSync(TPM_RH_LOCKOUT, _, nullptr))
+      .WillRepeatedly(Return(TPM_RC_SUCCESS));
+  EXPECT_EQ(TPM_RC_SUCCESS, utility_.ResetDictionaryAttackLock(nullptr));
+}
+
+TEST_F(TpmUtilityTest, ResetDictionaryAttackLockFailure) {
+  EXPECT_CALL(mock_tpm_,
+              DictionaryAttackLockResetSync(TPM_RH_LOCKOUT, _, nullptr))
+      .WillRepeatedly(Return(TPM_RC_FAILURE));
+  EXPECT_EQ(TPM_RC_FAILURE, utility_.ResetDictionaryAttackLock(nullptr));
+}
+
 }  // namespace trunks
diff --git a/trunks/trunks_client.cc b/trunks/trunks_client.cc
index ef5f0d0..156a564 100644
--- a/trunks/trunks_client.cc
+++ b/trunks/trunks_client.cc
@@ -23,7 +23,7 @@
 
 #include <base/command_line.h>
 #include <base/logging.h>
-#include <base/memory/ptr_util.h>
+#include <base/strings/string_number_conversions.h>
 #include <brillo/syslog_logging.h>
 
 #include "trunks/error_codes.h"
@@ -40,6 +40,7 @@
 
 using trunks::CommandTransceiver;
 using trunks::TrunksFactory;
+using trunks::TrunksFactoryImpl;
 
 void PrintUsage() {
   puts("Options:");
@@ -55,36 +56,43 @@
   puts("  --startup - Performs startup and self-tests.");
   puts("  --status - Prints TPM status information.");
   puts("  --stress_test - Runs some basic stress tests.");
+  puts("  --read_pcr --index=<N> - Reads a PCR and prints the value.");
+  puts("  --extend_pcr --index=<N> --value=<value> - Extends a PCR.");
 }
 
-int Startup(TrunksFactory* factory) {
-  factory->GetTpmUtility()->Shutdown();
-  return factory->GetTpmUtility()->Startup();
+std::string HexEncode(const std::string& bytes) {
+  return base::HexEncode(bytes.data(), bytes.size());
 }
 
-int Clear(TrunksFactory* factory) {
-  return factory->GetTpmUtility()->Clear();
+int Startup(const TrunksFactory& factory) {
+  factory.GetTpmUtility()->Shutdown();
+  return factory.GetTpmUtility()->Startup();
 }
 
-int InitializeTpm(TrunksFactory* factory) {
-  return factory->GetTpmUtility()->InitializeTpm();
+int Clear(const TrunksFactory& factory) {
+  return factory.GetTpmUtility()->Clear();
 }
 
-int AllocatePCR(TrunksFactory* factory) {
+int InitializeTpm(const TrunksFactory& factory) {
+  return factory.GetTpmUtility()->InitializeTpm();
+}
+
+int AllocatePCR(const TrunksFactory& factory) {
   trunks::TPM_RC result;
-  result = factory->GetTpmUtility()->AllocatePCR("");
+  result = factory.GetTpmUtility()->AllocatePCR("");
   if (result != trunks::TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error allocating PCR:" << trunks::GetErrorString(result);
     return result;
   }
-  factory->GetTpmUtility()->Shutdown();
-  return factory->GetTpmUtility()->Startup();
+  factory.GetTpmUtility()->Shutdown();
+  return factory.GetTpmUtility()->Startup();
 }
 
-int TakeOwnership(const std::string& owner_password, TrunksFactory* factory) {
+int TakeOwnership(const std::string& owner_password,
+                  const TrunksFactory& factory) {
   trunks::TPM_RC rc;
-  rc = factory->GetTpmUtility()->TakeOwnership(owner_password, owner_password,
-                                               owner_password);
+  rc = factory.GetTpmUtility()->TakeOwnership(owner_password, owner_password,
+                                              owner_password);
   if (rc) {
     LOG(ERROR) << "Error taking ownership: " << trunks::GetErrorString(rc);
     return rc;
@@ -92,8 +100,8 @@
   return 0;
 }
 
-int DumpStatus(TrunksFactory* factory) {
-  std::unique_ptr<trunks::TpmState> state = factory->GetTpmState();
+int DumpStatus(const TrunksFactory& factory) {
+  std::unique_ptr<trunks::TpmState> state = factory.GetTpmState();
   trunks::TPM_RC result = state->Initialize();
   if (result != trunks::TPM_RC_SUCCESS) {
     LOG(ERROR) << "Failed to read TPM state: "
@@ -126,6 +134,30 @@
   return 0;
 }
 
+int ReadPCR(const TrunksFactory& factory, int index) {
+  std::unique_ptr<trunks::TpmUtility> tpm_utility = factory.GetTpmUtility();
+  std::string value;
+  trunks::TPM_RC result = tpm_utility->ReadPCR(index, &value);
+  if (result) {
+    LOG(ERROR) << "ReadPCR: " << trunks::GetErrorString(result);
+    return result;
+  }
+  printf("PCR Value: %s\n", HexEncode(value).c_str());
+  return 0;
+}
+
+int ExtendPCR(const TrunksFactory& factory,
+              int index,
+              const std::string& value) {
+  std::unique_ptr<trunks::TpmUtility> tpm_utility = factory.GetTpmUtility();
+  trunks::TPM_RC result = tpm_utility->ExtendPCR(index, value, nullptr);
+  if (result) {
+    LOG(ERROR) << "ExtendPCR: " << trunks::GetErrorString(result);
+    return result;
+  }
+  return 0;
+}
+
 }  // namespace
 
 int main(int argc, char** argv) {
@@ -138,31 +170,30 @@
     return 0;
   }
 
-  std::unique_ptr<TrunksFactory> factory =
-      base::MakeUnique<trunks::TrunksFactoryImpl>(true /* failure_is_fatal */);
+  TrunksFactoryImpl factory;
+  CHECK(factory.Initialize()) << "Failed to initialize trunks factory.";
 
   if (cl->HasSwitch("status")) {
-    return DumpStatus(factory.get());
+    return DumpStatus(factory);
   }
   if (cl->HasSwitch("startup")) {
-    return Startup(factory.get());
+    return Startup(factory);
   }
   if (cl->HasSwitch("clear")) {
-    return Clear(factory.get());
+    return Clear(factory);
   }
   if (cl->HasSwitch("init_tpm")) {
-    return InitializeTpm(factory.get());
+    return InitializeTpm(factory);
   }
   if (cl->HasSwitch("allocate_pcr")) {
-    return AllocatePCR(factory.get());
+    return AllocatePCR(factory);
   }
 
   if (cl->HasSwitch("own")) {
-    return TakeOwnership(cl->GetSwitchValueASCII("owner_password"),
-                         factory.get());
+    return TakeOwnership(cl->GetSwitchValueASCII("owner_password"), factory);
   }
   if (cl->HasSwitch("regression_test")) {
-    trunks::TrunksClientTest test;
+    trunks::TrunksClientTest test(factory);
     LOG(INFO) << "Running RNG test.";
     if (!test.RNGTest()) {
       LOG(ERROR) << "Error running RNGtest.";
@@ -225,7 +256,7 @@
   }
   if (cl->HasSwitch("stress_test")) {
     LOG(INFO) << "Running stress tests.";
-    trunks::TrunksClientTest test;
+    trunks::TrunksClientTest test(factory);
     if (!test.ManyKeysTest()) {
       LOG(ERROR) << "Error running ManyKeysTest.";
       return -1;
@@ -236,6 +267,14 @@
     }
     return 0;
   }
+  if (cl->HasSwitch("read_pcr") && cl->HasSwitch("index")) {
+    return ReadPCR(factory, atoi(cl->GetSwitchValueASCII("index").c_str()));
+  }
+  if (cl->HasSwitch("extend_pcr") && cl->HasSwitch("index") &&
+      cl->HasSwitch("value")) {
+    return ExtendPCR(factory, atoi(cl->GetSwitchValueASCII("index").c_str()),
+                     cl->GetSwitchValueASCII("value"));
+  }
   puts("Invalid options!");
   PrintUsage();
   return -1;
diff --git a/trunks/trunks_client_test.cc b/trunks/trunks_client_test.cc
index 4b4f650..eb60b19 100644
--- a/trunks/trunks_client_test.cc
+++ b/trunks/trunks_client_test.cc
@@ -22,8 +22,10 @@
 #include <string>
 #include <vector>
 
+#include <base/callback.h>
 #include <base/logging.h>
 #include <base/stl_util.h>
+#include <brillo/bind_lambda.h>
 #include <crypto/openssl_util.h>
 #include <crypto/scoped_openssl_types.h>
 #include <crypto/sha2.h>
@@ -36,6 +38,7 @@
 #include "trunks/hmac_session.h"
 #include "trunks/policy_session.h"
 #include "trunks/scoped_key_handle.h"
+#include "trunks/tpm_constants.h"
 #include "trunks/tpm_generated.h"
 #include "trunks/tpm_state.h"
 #include "trunks/tpm_utility.h"
@@ -57,19 +60,16 @@
 
 namespace trunks {
 
-TrunksClientTest::TrunksClientTest()
-    : factory_(new TrunksFactoryImpl(true /* failure_is_fatal */)) {
+TrunksClientTest::TrunksClientTest(const TrunksFactory& factory)
+    : factory_(factory) {
   crypto::EnsureOpenSSLInit();
 }
 
-TrunksClientTest::TrunksClientTest(std::unique_ptr<TrunksFactory> factory)
-    : factory_(std::move(factory)) {}
-
 TrunksClientTest::~TrunksClientTest() {}
 
 bool TrunksClientTest::RNGTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -97,8 +97,8 @@
 }
 
 bool TrunksClientTest::SignTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -118,7 +118,7 @@
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error loading signing key: " << GetErrorString(result);
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), signing_key);
+  ScopedKeyHandle scoped_key(factory_, signing_key);
   session->SetEntityAuthorizationValue(key_authorization);
   std::string signature;
   result =
@@ -138,8 +138,8 @@
 }
 
 bool TrunksClientTest::DecryptTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -159,14 +159,14 @@
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result);
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), decrypt_key);
+  ScopedKeyHandle scoped_key(factory_, decrypt_key);
   return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
                                      session.get());
 }
 
 bool TrunksClientTest::ImportTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -189,14 +189,14 @@
     LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result);
     return false;
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
+  ScopedKeyHandle scoped_key(factory_, key_handle);
   return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
                                      session.get());
 }
 
 bool TrunksClientTest::AuthChangeTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -216,7 +216,7 @@
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result);
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
+  ScopedKeyHandle scoped_key(factory_, key_handle);
   session->SetEntityAuthorizationValue("old_pass");
   result = utility->ChangeKeyAuthorizationData(
       key_handle, key_authorization, session->GetDelegate(), &key_blob);
@@ -236,8 +236,8 @@
 }
 
 bool TrunksClientTest::VerifyKeyCreationTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -275,8 +275,8 @@
     LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result);
     return false;
   }
-  ScopedKeyHandle certify_key(*factory_.get(), key_handle);
-  ScopedKeyHandle alternate_key(*factory_.get(), alternate_key_handle);
+  ScopedKeyHandle certify_key(factory_, key_handle);
+  ScopedKeyHandle alternate_key(factory_, alternate_key_handle);
   result = utility->CertifyCreation(certify_key.get(), creation_blob);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error certifying key: " << GetErrorString(result);
@@ -291,8 +291,8 @@
 }
 
 bool TrunksClientTest::SealedDataTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -313,7 +313,7 @@
     LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result);
     return false;
   }
-  std::unique_ptr<PolicySession> policy_session = factory_->GetPolicySession();
+  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
   result = policy_session->StartUnboundSession(false);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
@@ -357,8 +357,8 @@
 }
 
 bool TrunksClientTest::PCRTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session.";
     return false;
@@ -394,8 +394,8 @@
 }
 
 bool TrunksClientTest::PolicyAuthValueTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<PolicySession> trial_session = factory_->GetTrialSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
   TPM_RC result;
   result = trial_session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
@@ -417,7 +417,7 @@
   // Now that we have the digest, we can close the trial session and use hmac.
   trial_session.reset();
 
-  std::unique_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
+  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
   result = hmac_session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
@@ -440,12 +440,12 @@
     LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
     return false;
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
+  ScopedKeyHandle scoped_key(factory_, key_handle);
 
   // Now we can reset the hmac_session.
   hmac_session.reset();
 
-  std::unique_ptr<PolicySession> policy_session = factory_->GetPolicySession();
+  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
   result = policy_session->StartUnboundSession(false);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
@@ -503,8 +503,8 @@
 }
 
 bool TrunksClientTest::PolicyAndTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<PolicySession> trial_session = factory_->GetTrialSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
   TPM_RC result;
   result = trial_session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
@@ -542,7 +542,7 @@
   // Now that we have the digest, we can close the trial session and use hmac.
   trial_session.reset();
 
-  std::unique_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
+  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
   result = hmac_session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
@@ -566,12 +566,12 @@
     LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
     return false;
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
+  ScopedKeyHandle scoped_key(factory_, key_handle);
 
   // Now we can reset the hmac_session.
   hmac_session.reset();
 
-  std::unique_ptr<PolicySession> policy_session = factory_->GetPolicySession();
+  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
   result = policy_session->StartUnboundSession(false);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
@@ -598,7 +598,7 @@
     return false;
   }
   std::unique_ptr<AuthorizationDelegate> delegate =
-      factory_->GetPasswordAuthorization("");
+      factory_.GetPasswordAuthorization("");
   result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
@@ -667,8 +667,8 @@
 }
 
 bool TrunksClientTest::PolicyOrTest() {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<PolicySession> trial_session = factory_->GetTrialSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
   TPM_RC result;
   // Specify a policy that asserts either TPM_CC_RSA_Encrypt or
   // TPM_CC_RSA_Decrypt. A key created under this policy can only be used
@@ -722,7 +722,7 @@
   // Now that we have the digest, we can close the trial session and use hmac.
   trial_session.reset();
 
-  std::unique_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
+  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
   result = hmac_session->StartUnboundSession(true);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
@@ -746,12 +746,12 @@
     LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
     return false;
   }
-  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
+  ScopedKeyHandle scoped_key(factory_, key_handle);
 
   // Now we can reset the hmac_session.
   hmac_session.reset();
 
-  std::unique_ptr<PolicySession> policy_session = factory_->GetPolicySession();
+  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
   result = policy_session->StartUnboundSession(false);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
@@ -813,8 +813,8 @@
 }
 
 bool TrunksClientTest::NvramTest(const std::string& owner_password) {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
-  std::unique_ptr<HmacSession> session = factory_->GetHmacSession();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
+  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
   TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
@@ -823,22 +823,47 @@
   uint32_t index = 1;
   session->SetEntityAuthorizationValue(owner_password);
   std::string nv_data("nv_data");
-  result =
-      utility->DefineNVSpace(index, nv_data.size(), session->GetDelegate());
+  TPMA_NV attributes = TPMA_NV_OWNERWRITE | TPMA_NV_AUTHREAD |
+                       TPMA_NV_WRITE_STCLEAR | TPMA_NV_READ_STCLEAR;
+  result = utility->DefineNVSpace(index, nv_data.size(), attributes, "", "",
+                                  session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error defining nvram: " << GetErrorString(result);
     return false;
   }
+  // Setup auto-cleanup of the NVRAM space.
+  auto cleanup = [&session, &owner_password, &utility, index]() {
+    session->SetEntityAuthorizationValue(owner_password);
+    TPM_RC result = utility->DestroyNVSpace(index, session->GetDelegate());
+    if (result != TPM_RC_SUCCESS) {
+      LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result);
+    }
+  };
+  class Scoper {
+   public:
+    Scoper(const base::Closure& callback) : callback_(callback) {}
+    ~Scoper() {
+      if (!cancel_)
+        callback_.Run();
+    }
+    void Cancel() { cancel_ = true; }
+
+   private:
+    base::Closure callback_;
+    bool cancel_ = false;
+  } scoper(base::Bind(cleanup));
+
   session->SetEntityAuthorizationValue(owner_password);
-  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
+  result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/,
+                                 false /*extend*/, session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error writing nvram: " << GetErrorString(result);
     return false;
   }
   std::string new_nvdata;
   session->SetEntityAuthorizationValue("");
-  result = utility->ReadNVSpace(index, 0, nv_data.size(), &new_nvdata,
-                                session->GetDelegate());
+  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
+                                &new_nvdata, session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
     return false;
@@ -848,14 +873,15 @@
     return false;
   }
   session->SetEntityAuthorizationValue(owner_password);
-  result = utility->LockNVSpace(index, session->GetDelegate());
+  result = utility->LockNVSpace(index, false /*lock_read*/, true /*lock_write*/,
+                                false /*owner*/, session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error locking nvram: " << GetErrorString(result);
+    LOG(ERROR) << "Error locking nvram write: " << GetErrorString(result);
     return false;
   }
   session->SetEntityAuthorizationValue("");
-  result = utility->ReadNVSpace(index, 0, nv_data.size(), &new_nvdata,
-                                session->GetDelegate());
+  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
+                                &new_nvdata, session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
     return false;
@@ -865,15 +891,22 @@
     return false;
   }
   session->SetEntityAuthorizationValue(owner_password);
-  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
+  result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/,
+                                 false /*extend*/, session->GetDelegate());
   if (result == TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Wrote nvram after locking: " << GetErrorString(result);
+    LOG(ERROR) << "Wrote nvram after locking!";
     return false;
   }
-  session->SetEntityAuthorizationValue(owner_password);
-  result = utility->DestroyNVSpace(index, session->GetDelegate());
+  result = utility->LockNVSpace(index, true /*lock_read*/, false /*lock_write*/,
+                                true /*owner*/, session->GetDelegate());
   if (result != TPM_RC_SUCCESS) {
-    LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result);
+    LOG(ERROR) << "Error locking nvram read: " << GetErrorString(result);
+    return false;
+  }
+  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
+                                &new_nvdata, session->GetDelegate());
+  if (result == TPM_RC_SUCCESS) {
+    LOG(ERROR) << "Read nvram after locking!";
     return false;
   }
   return true;
@@ -884,7 +917,7 @@
   std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles;
   std::map<TPM_HANDLE, std::string> public_key_map;
   for (size_t i = 0; i < kNumKeys; ++i) {
-    std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(*factory_));
+    std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(factory_));
     std::string public_key;
     if (!LoadSigningKey(key_handle.get(), &public_key)) {
       LOG(ERROR) << "Error loading key " << i << " into TPM.";
@@ -895,7 +928,7 @@
   CHECK_EQ(key_handles.size(), kNumKeys);
   CHECK_EQ(public_key_map.size(), kNumKeys);
   std::unique_ptr<AuthorizationDelegate> delegate =
-      factory_->GetPasswordAuthorization("");
+      factory_.GetPasswordAuthorization("");
   for (size_t i = 0; i < kNumKeys; ++i) {
     const ScopedKeyHandle& key_handle = *key_handles[i];
     const std::string& public_key = public_key_map[key_handle.get()];
@@ -916,10 +949,10 @@
 
 bool TrunksClientTest::ManySessionsTest() {
   const size_t kNumSessions = 20;
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
   std::vector<std::unique_ptr<HmacSession>> sessions;
   for (size_t i = 0; i < kNumSessions; ++i) {
-    std::unique_ptr<HmacSession> session(factory_->GetHmacSession().release());
+    std::unique_ptr<HmacSession> session(factory_.GetHmacSession().release());
     TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
     if (result != TPM_RC_SUCCESS) {
       LOG(ERROR) << "Error starting hmac session " << i << ": "
@@ -929,7 +962,7 @@
     sessions.push_back(std::move(session));
   }
   CHECK_EQ(sessions.size(), kNumSessions);
-  ScopedKeyHandle key_handle(*factory_);
+  ScopedKeyHandle key_handle(factory_);
   std::string public_key;
   if (!LoadSigningKey(&key_handle, &public_key)) {
     return false;
@@ -952,7 +985,7 @@
     TPM_HANDLE key_handle,
     const std::string& key_authorization,
     HmacSession* session) {
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
   std::string ciphertext;
   session->SetEntityAuthorizationValue("");
   TPM_RC result = utility->AsymmetricEncrypt(
@@ -1028,18 +1061,18 @@
   std::string prime_factor;
   GenerateRSAKeyPair(&modulus, &prime_factor, public_key);
   std::string key_blob;
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
   TPM_RC result = utility->ImportRSAKey(
       TpmUtility::AsymmetricKeyUsage::kSignKey, modulus, 0x10001, prime_factor,
       "",  // password
-      factory_->GetPasswordAuthorization("").get(), &key_blob);
+      factory_.GetPasswordAuthorization("").get(), &key_blob);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result);
     return false;
   }
   TPM_HANDLE raw_key_handle;
   result = utility->LoadKey(
-      key_blob, factory_->GetPasswordAuthorization("").get(), &raw_key_handle);
+      key_blob, factory_.GetPasswordAuthorization("").get(), &raw_key_handle);
   if (result != TPM_RC_SUCCESS) {
     LOG(ERROR) << "LoadKey: " << GetErrorString(result);
     return false;
@@ -1053,7 +1086,7 @@
                                      AuthorizationDelegate* delegate) {
   std::string signature;
   std::string data_to_sign("sign_this");
-  std::unique_ptr<TpmUtility> utility = factory_->GetTpmUtility();
+  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
   TPM_RC result =
       utility->Sign(key_handle.get(), TPM_ALG_RSASSA, TPM_ALG_SHA256,
                     data_to_sign, delegate, &signature);
diff --git a/trunks/trunks_client_test.h b/trunks/trunks_client_test.h
index b7aba79..80fd3e8 100644
--- a/trunks/trunks_client_test.h
+++ b/trunks/trunks_client_test.h
@@ -30,14 +30,13 @@
 // method defines a different test to perform.
 // NOTE: All these tests require that the TPM be owned, and SRKs exist.
 // Example usage:
-// TrunksClientTest test;
+// TrunksClientTest test(factory);
 // CHECK(test.RNGTest());
 // CHECK(test.SimplePolicyTest());
 class TrunksClientTest {
  public:
-  TrunksClientTest();
-  // Takes ownership of factory.
-  explicit TrunksClientTest(std::unique_ptr<TrunksFactory> factory);
+  // Does not take ownership of factory.
+  explicit TrunksClientTest(const TrunksFactory& factory);
   virtual ~TrunksClientTest();
 
   // This test verifies that the Random Number Generator on the TPM is working
@@ -136,7 +135,7 @@
                      AuthorizationDelegate* delegate);
 
   // Factory for instantiation of Tpm classes
-  std::unique_ptr<TrunksFactory> factory_;
+  const TrunksFactory& factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TrunksClientTest);
 };
diff --git a/trunks/trunks_factory.h b/trunks/trunks_factory.h
index cf6f76b..4f1e843 100644
--- a/trunks/trunks_factory.h
+++ b/trunks/trunks_factory.h
@@ -22,29 +22,28 @@
 
 #include <base/macros.h>
 
+#include "trunks/authorization_delegate.h"
+#include "trunks/blob_parser.h"
+#include "trunks/hmac_session.h"
+#include "trunks/policy_session.h"
+#include "trunks/session_manager.h"
+#include "trunks/tpm_state.h"
+#include "trunks/tpm_utility.h"
 #include "trunks/trunks_export.h"
 
 namespace trunks {
 
-class AuthorizationDelegate;
-class BlobParser;
-class CommandTransceiver;
-class HmacSession;
-class PolicySession;
-class SessionManager;
 class Tpm;
-class TpmState;
-class TpmUtility;
 
 // TrunksFactory is an interface to act as a factory for trunks objects. This
-// mechanism assists in injecting mocks for testing. This class is not
-// thread-safe.
+// mechanism assists in injecting mocks for testing.
 class TRUNKS_EXPORT TrunksFactory {
  public:
   TrunksFactory() {}
   virtual ~TrunksFactory() {}
 
-  // Returns a Tpm instance. The caller does not take ownership.
+  // Returns a Tpm instance. The caller does not take ownership. All calls to
+  // this method on a given TrunksFactory instance will return the same value.
   virtual Tpm* GetTpm() const = 0;
 
   // Returns an uninitialized TpmState instance. The caller takes ownership.
diff --git a/trunks/trunks_factory_for_test.cc b/trunks/trunks_factory_for_test.cc
index 0556cba..f18bb0d 100644
--- a/trunks/trunks_factory_for_test.cc
+++ b/trunks/trunks_factory_for_test.cc
@@ -269,8 +269,12 @@
 
   TPM_RC DefineNVSpace(uint32_t index,
                        size_t num_bytes,
+                       TPMA_NV attributes,
+                       const std::string& authorization_value,
+                       const std::string& policy_digest,
                        AuthorizationDelegate* delegate) override {
-    return target_->DefineNVSpace(index, num_bytes, delegate);
+    return target_->DefineNVSpace(index, num_bytes, attributes,
+                                  authorization_value, policy_digest, delegate);
   }
 
   TPM_RC DestroyNVSpace(uint32_t index,
@@ -278,23 +282,34 @@
     return target_->DestroyNVSpace(index, delegate);
   }
 
-  TPM_RC LockNVSpace(uint32_t index, AuthorizationDelegate* delegate) override {
-    return target_->LockNVSpace(index, delegate);
+  TPM_RC LockNVSpace(uint32_t index,
+                     bool lock_read,
+                     bool lock_write,
+                     bool using_owner_authorization,
+                     AuthorizationDelegate* delegate) override {
+    return target_->LockNVSpace(index, lock_read, lock_write,
+                                using_owner_authorization, delegate);
   }
 
   TPM_RC WriteNVSpace(uint32_t index,
                       uint32_t offset,
                       const std::string& nvram_data,
+                      bool using_owner_authorization,
+                      bool extend,
                       AuthorizationDelegate* delegate) override {
-    return target_->WriteNVSpace(index, offset, nvram_data, delegate);
+    return target_->WriteNVSpace(index, offset, nvram_data,
+                                 using_owner_authorization, extend, delegate);
   }
 
   TPM_RC ReadNVSpace(uint32_t index,
                      uint32_t offset,
                      size_t num_bytes,
+                     bool using_owner_authorization,
                      std::string* nvram_data,
                      AuthorizationDelegate* delegate) override {
-    return target_->ReadNVSpace(index, offset, num_bytes, nvram_data, delegate);
+    return target_->ReadNVSpace(index, offset, num_bytes,
+                                using_owner_authorization, nvram_data,
+                                delegate);
   }
 
   TPM_RC GetNVSpaceName(uint32_t index, std::string* name) override {
@@ -306,6 +321,23 @@
     return target_->GetNVSpacePublicArea(index, public_data);
   }
 
+  TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) override {
+    return target_->ListNVSpaces(index_list);
+  }
+
+  TPM_RC SetDictionaryAttackParameters(
+      uint32_t max_tries,
+      uint32_t recovery_time,
+      uint32_t lockout_recovery,
+      AuthorizationDelegate* delegate) override {
+    return target_->SetDictionaryAttackParameters(max_tries, recovery_time,
+                                                  lockout_recovery, delegate);
+  }
+
+  TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) override {
+    return target_->ResetDictionaryAttackLock(delegate);
+  }
+
  private:
   TpmUtility* target_;
 };
@@ -441,6 +473,8 @@
 
   TPM_RC PolicyAuthValue() override { return target_->PolicyAuthValue(); }
 
+  TPM_RC PolicyRestart() override { return target_->PolicyRestart(); }
+
   void SetEntityAuthorizationValue(const std::string& value) override {
     return target_->SetEntityAuthorizationValue(value);
   }
@@ -502,6 +536,8 @@
       hmac_session_(default_hmac_session_.get()),
       default_policy_session_(new NiceMock<MockPolicySession>()),
       policy_session_(default_policy_session_.get()),
+      default_trial_session_(new NiceMock<MockPolicySession>()),
+      trial_session_(default_trial_session_.get()),
       default_blob_parser_(new NiceMock<MockBlobParser>()),
       blob_parser_(default_blob_parser_.get()) {}
 
@@ -526,7 +562,8 @@
       password_authorization_delegate_);
 }
 
-std::unique_ptr<SessionManager> TrunksFactoryForTest::GetSessionManager() const {
+std::unique_ptr<SessionManager> TrunksFactoryForTest::GetSessionManager()
+    const {
   return base::MakeUnique<SessionManagerForwarder>(session_manager_);
 }
 
diff --git a/trunks/trunks_factory_for_test.h b/trunks/trunks_factory_for_test.h
index 01f96ba..5b2b00d 100644
--- a/trunks/trunks_factory_for_test.h
+++ b/trunks/trunks_factory_for_test.h
@@ -95,6 +95,10 @@
     policy_session_ = policy_session;
   }
 
+  void set_trial_session(PolicySession* trial_session) {
+    trial_session_ = trial_session;
+  }
+
   void set_blob_parser(BlobParser* blob_parser) { blob_parser_ = blob_parser; }
 
  private:
@@ -104,7 +108,8 @@
   TpmState* tpm_state_;
   std::unique_ptr<MockTpmUtility> default_tpm_utility_;
   TpmUtility* tpm_utility_;
-  std::unique_ptr<PasswordAuthorizationDelegate> default_authorization_delegate_;
+  std::unique_ptr<PasswordAuthorizationDelegate>
+      default_authorization_delegate_;
   AuthorizationDelegate* password_authorization_delegate_;
   std::unique_ptr<MockSessionManager> default_session_manager_;
   SessionManager* session_manager_;
@@ -112,6 +117,8 @@
   HmacSession* hmac_session_;
   std::unique_ptr<MockPolicySession> default_policy_session_;
   PolicySession* policy_session_;
+  std::unique_ptr<MockPolicySession> default_trial_session_;
+  PolicySession* trial_session_;
   std::unique_ptr<MockBlobParser> default_blob_parser_;
   BlobParser* blob_parser_;
 
diff --git a/trunks/trunks_factory_impl.cc b/trunks/trunks_factory_impl.cc
index f0b39cb..8dc7874 100644
--- a/trunks/trunks_factory_impl.cc
+++ b/trunks/trunks_factory_impl.cc
@@ -35,30 +35,38 @@
 
 namespace trunks {
 
-TrunksFactoryImpl::TrunksFactoryImpl(bool failure_is_fatal) {
+TrunksFactoryImpl::TrunksFactoryImpl() {
 #if defined(USE_BINDER_IPC)
   default_transceiver_.reset(new TrunksBinderProxy());
 #else
   default_transceiver_.reset(new TrunksDBusProxy());
 #endif
   transceiver_ = default_transceiver_.get();
-  tpm_.reset(new Tpm(transceiver_));
-  if (!transceiver_->Init()) {
-    if (failure_is_fatal) {
-      LOG(FATAL) << "Error initializing default IPC proxy.";
-    } else {
-      LOG(ERROR) << "Error initializing default IPC proxy.";
-    }
-  }
 }
 
 TrunksFactoryImpl::TrunksFactoryImpl(CommandTransceiver* transceiver) {
   transceiver_ = transceiver;
-  tpm_.reset(new Tpm(transceiver_));
 }
 
 TrunksFactoryImpl::~TrunksFactoryImpl() {}
 
+bool TrunksFactoryImpl::Initialize() {
+  if (initialized_) {
+    return true;
+  }
+  tpm_.reset(new Tpm(transceiver_));
+  if (transceiver_ != default_transceiver_.get()) {
+    initialized_ = true;
+  } else {
+    initialized_ = transceiver_->Init();
+    if (!initialized_) {
+      LOG(WARNING) << "Failed to initialize the trunks IPC proxy; "
+                   << "trunksd is not ready.";
+    }
+  }
+  return initialized_;
+}
+
 Tpm* TrunksFactoryImpl::GetTpm() const {
   return tpm_.get();
 }
diff --git a/trunks/trunks_factory_impl.h b/trunks/trunks_factory_impl.h
index b4c91d2..4b5f5f4 100644
--- a/trunks/trunks_factory_impl.h
+++ b/trunks/trunks_factory_impl.h
@@ -29,20 +29,27 @@
 
 namespace trunks {
 
-class Tpm;
-
-// TrunksFactoryImpl is the default TrunksFactory implementation.
+// TrunksFactoryImpl is the default TrunksFactory implementation. This class is
+// thread-safe with the exception of Initialize() but created objects are not
+// necessarily thread-safe. Example usage:
+//
+// TrunksFactoryImpl factory;
+// factory.Initialize(true /*failure_is_fatal*/);
+// Tpm* tpm = factory.GetTpm();
 class TRUNKS_EXPORT TrunksFactoryImpl : public TrunksFactory {
  public:
-  // Uses an IPC proxy as the default CommandTransceiver. If |failure_is_fatal|
-  // is set then a failure to initialize the proxy will abort.
-  explicit TrunksFactoryImpl(bool failure_is_fatal);
+  // Uses an IPC proxy as the default CommandTransceiver.
+  TrunksFactoryImpl();
   // TrunksFactoryImpl does not take ownership of |transceiver|. This
   // transceiver is forwarded down to the Tpm instance maintained by
-  // this factory.
+  // this factory. It is assumed that the |transceiver| is already initialized.
   explicit TrunksFactoryImpl(CommandTransceiver* transceiver);
   ~TrunksFactoryImpl() override;
 
+  // Initialize the factory. This must be called before any other methods.
+  // Returns true on success.
+  bool Initialize();
+
   // TrunksFactory methods.
   Tpm* GetTpm() const override;
   std::unique_ptr<TpmState> GetTpmState() const override;
@@ -59,6 +66,7 @@
   std::unique_ptr<CommandTransceiver> default_transceiver_;
   CommandTransceiver* transceiver_;
   std::unique_ptr<Tpm> tpm_;
+  bool initialized_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(TrunksFactoryImpl);
 };
diff --git a/trunks/trunksd.cc b/trunks/trunksd.cc
index 12cef73..25c2081 100644
--- a/trunks/trunksd.cc
+++ b/trunks/trunksd.cc
@@ -109,6 +109,7 @@
   base::Thread background_thread(kBackgroundThreadName);
   CHECK(background_thread.Start()) << "Failed to start background thread.";
   trunks::TrunksFactoryImpl factory(low_level_transceiver);
+  CHECK(factory.Initialize()) << "Failed to initialize trunks factory.";
   trunks::ResourceManager resource_manager(factory, low_level_transceiver);
   background_thread.task_runner()->PostNonNestableTask(
       FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
diff --git a/trunks/trunksd.rc b/trunks/trunksd.rc
index beea304..326a8f6 100644
--- a/trunks/trunksd.rc
+++ b/trunks/trunksd.rc
@@ -5,4 +5,3 @@
     class late_start
     user root
     group root
-    oneshot