// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chaps/tpm_utility_impl.h"

#include <map>
#include <set>
#include <sstream>
#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/synchronization/lock.h>
#include <brillo/secure_blob.h>
#include <openssl/rand.h>
#include <trousers/scoped_tss_type.h>
#include <trousers/tss.h>

#include "chaps/chaps_utility.h"

using base::AutoLock;
using brillo::SecureBlob;
using std::hex;
using std::map;
using std::set;
using std::string;
using std::stringstream;
using trousers::ScopedTssContext;
using trousers::ScopedTssKey;
using trousers::ScopedTssObject;
using trousers::ScopedTssPolicy;

namespace chaps {

// TSSEncryptedData wraps a TSS encrypted data object. The underlying TSS object
// will be closed when this object falls out of scope.
typedef ScopedTssObject<TSS_HENCDATA> ScopedTssEncData;
class TSSEncryptedData {
 public:
  explicit TSSEncryptedData(TSS_HCONTEXT context)
      : context_(context), handle_(context) {}
  TSSEncryptedData(const TSSEncryptedData&) = delete;
  TSSEncryptedData& operator=(const TSSEncryptedData&) = delete;

  bool Create() {
    TSS_RESULT result = Tspi_Context_CreateObject(
        context_, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, handle_.ptr());
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Context_CreateObject - "
                 << TPMUtilityImpl::ResultToString(result);
      return false;
    }

    return true;
  }
  bool GetData(string* data) {
    UINT32 length = 0;
    BYTE* buffer = NULL;
    TSS_RESULT result =
        Tspi_GetAttribData(handle_, TSS_TSPATTRIB_ENCDATA_BLOB,
                           TSS_TSPATTRIB_ENCDATABLOB_BLOB, &length, &buffer);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_GetAttribData(ENCDATA_BLOB) - "
                 << TPMUtilityImpl::ResultToString(result);
      return false;
    }
    *data = ConvertByteBufferToString(buffer, length);
    Tspi_Context_FreeMemory(context_, buffer);
    return true;
  }
  bool SetData(const string& data) {
    TSS_RESULT result = Tspi_SetAttribData(
        handle_, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB,
        data.length(), ConvertStringToByteBuffer(data.data()));
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribData(ENCDATA_BLOB) - "
                 << TPMUtilityImpl::ResultToString(result);
      return false;
    }
    return true;
  }
  operator TSS_HENCDATA() { return handle_; }

 private:
  TSS_HCONTEXT context_;
  ScopedTssObject<TSS_HENCDATA> handle_;
};

// TSSHash wraps a TSS hash object. The underlying TSS object will be closed
// when this object falls out of scope.
class TSSHash {
 public:
  explicit TSSHash(TSS_HCONTEXT context)
      : context_(context), handle_(context) {}
  TSSHash(const TSSHash&) = delete;
  TSSHash& operator=(const TSSHash&) = delete;

  bool Create(const string& value) {
    TSS_RESULT result = Tspi_Context_CreateObject(
        context_, TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, handle_.ptr());
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Context_CreateObject - "
                 << TPMUtilityImpl::ResultToString(result);
      return false;
    }

    result = Tspi_Hash_SetHashValue(handle_, value.length(),
                                    ConvertStringToByteBuffer(value.data()));
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Hash_SetHashValue - "
                 << TPMUtilityImpl::ResultToString(result);
      return false;
    }
    return true;
  }
  operator TSS_HHASH() { return handle_; }

 private:
  TSS_HCONTEXT context_;
  ScopedTssObject<TSS_HHASH> handle_;
};

TPMUtilityImpl::TPMUtilityImpl(const string& srk_auth_data)
    : is_initialized_(false),
      is_srk_ready_(false),
      default_policy_(0),
      srk_(0),
      srk_auth_data_(srk_auth_data),
      srk_public_loaded_(false),
      default_exponent_("\x1\x0\x1", 3),
      last_handle_(0),
      tpm_manager_utility_(nullptr) {}

TPMUtilityImpl::TPMUtilityImpl(
    const string& srk_auth_data,
    tpm_manager::TpmManagerUtility* tpm_manager_utility)
    : is_initialized_(false),
      is_srk_ready_(false),
      default_policy_(0),
      srk_(0),
      srk_auth_data_(srk_auth_data),
      srk_public_loaded_(false),
      default_exponent_("\x1\x0\x1", 3),
      last_handle_(0),
      tpm_manager_utility_(tpm_manager_utility) {}

TPMUtilityImpl::~TPMUtilityImpl() {
  LOG(INFO) << "Unloading keys for all slots.";
  map<int, HandleInfo>::iterator it;
  set<int>::iterator it2;
  for (it = slot_handles_.begin(); it != slot_handles_.end(); ++it) {
    set<int>* slot_handles = &it->second.handles_;
    for (it2 = slot_handles->begin(); it2 != slot_handles->end(); ++it2) {
      Tspi_Key_UnloadKey(GetTssHandle(*it2));
      Tspi_Context_CloseObject(tsp_context_, GetTssHandle(*it2));
    }
  }
  // These can't use ScopedTssObject because they must be closed before the
  // context (tsp_context_) closes.
  if (srk_)
    Tspi_Context_CloseObject(tsp_context_, srk_);
  if (default_policy_)
    Tspi_Context_CloseObject(tsp_context_, default_policy_);
}

bool TPMUtilityImpl::Init() {
  if (is_initialized_)
    return true;
  VLOG(1) << "TPMUtilityImpl::Init enter";

  if (!tpm_manager_utility_) {
    tpm_manager_utility_ = tpm_manager::TpmManagerUtility::GetSingleton();
    if (!tpm_manager_utility_) {
      LOG(ERROR) << __func__ << ": Failed to get TpmManagerUtility singleton!";
      return false;
    }
  }

  AutoLock lock(lock_);
  TSS_RESULT result = TSS_SUCCESS;
  result = Tspi_Context_Create(tsp_context_.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_Create - " << ResultToString(result);
    return false;
  }
  result = Tspi_Context_Connect(tsp_context_, NULL);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_Connect - " << ResultToString(result);
    return false;
  }
  // Get the default policy so we can compare against it later.
  result = Tspi_Context_GetDefaultPolicy(tsp_context_, &default_policy_);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_GetDefaultPolicy - " << ResultToString(result);
    return false;
  }
  // Make sure we can communicate with the TPM.
  TSS_HTPM tpm;
  result = Tspi_Context_GetTpmObject(tsp_context_, &tpm);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_GetTpmObject - " << ResultToString(result);
    return false;
  }
  BYTE* random_bytes = NULL;
  result = Tspi_TPM_GetRandom(tpm, 4, &random_bytes);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_TPM_GetRandom - " << ResultToString(result);
    return false;
  }
  Tspi_Context_FreeMemory(tsp_context_, random_bytes);
  VLOG(1) << "TPMUtilityImpl::Init success";
  is_initialized_ = true;
  return true;
}

bool TPMUtilityImpl::IsTPMAvailable() {
  if (!tpm_manager_utility_) {
    LOG(ERROR) << "Accessing invalid tpm_manager utility.";
    return false;
  }
  bool is_enabled = false;
  bool is_owned = false;
  bool is_owner_password_present = false;
  bool has_reset_lock_permissions = false;
  if (!tpm_manager_utility_->GetTpmNonsensitiveStatus(
          &is_enabled, &is_owned, &is_owner_password_present,
          &has_reset_lock_permissions)) {
    LOG(ERROR) << ": failed to get TPM status from tpm_manager.";
    return false;
  }
  return is_enabled;
}

TPMVersion TPMUtilityImpl::GetTPMVersion() {
  return TPMVersion::TPM1_2;
}

bool TPMUtilityImpl::InitSRK() {
  if (!is_initialized_)
    return false;
  if (is_srk_ready_)
    return true;
  VLOG(1) << "TPMUtilityImpl::InitSRK enter";
  // Load the SRK and assign it a usage policy with authorization data.
  TSS_RESULT result = TSS_SUCCESS;
  TSS_UUID uuid = TSS_UUID_SRK;
  result =
      Tspi_Context_LoadKeyByUUID(tsp_context_, TSS_PS_TYPE_SYSTEM, uuid, &srk_);
  if (result != TSS_SUCCESS) {
    if (result == (TSS_LAYER_TCS | TSS_E_PS_KEY_NOTFOUND)) {
      LOG(WARNING) << "SRK does not exist - this is normal when the TPM is not "
                   << "yet owned.";
    } else {
      LOG(ERROR) << "Tspi_Context_LoadKeyByUUID - " << ResultToString(result);
    }
    return false;
  }
  ScopedTssPolicy srk_policy(tsp_context_);
  result = Tspi_Context_CreateObject(tsp_context_, TSS_OBJECT_TYPE_POLICY,
                                     TSS_POLICY_USAGE, srk_policy.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_CreateObject - " << ResultToString(result);
    return false;
  }
  if (srk_auth_data_.empty()) {
    result = Tspi_Policy_SetSecret(srk_policy, TSS_SECRET_MODE_PLAIN, 0, NULL);
  } else {
    LOG(INFO) << "Using non-empty secret for SRK policy.";
    // If the authorization data is 20 null bytes, use SHA1 mode for
    // compatibility with other tools that use this value.
    result = Tspi_Policy_SetSecret(
        srk_policy,
        srk_auth_data_ == string(20, 0) ? TSS_SECRET_MODE_SHA1
                                        : TSS_SECRET_MODE_PLAIN,
        srk_auth_data_.length(),
        ConvertStringToByteBuffer(srk_auth_data_.data()));
  }
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
    return false;
  }
  result = Tspi_Policy_AssignToObject(srk_policy.release(), srk_);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Policy_AssignToObject - " << ResultToString(result);
    return false;
  }
  VLOG(1) << "TPMUtilityImpl::InitSRK success";
  is_srk_ready_ = true;
  return true;
}

bool TPMUtilityImpl::Authenticate(int slot_id,
                                  const SecureBlob& auth_data,
                                  const string& auth_key_blob,
                                  const string& encrypted_master_key,
                                  SecureBlob* master_key) {
  VLOG(1) << "TPMUtilityImpl::Authenticate enter";
  int key_handle = 0;
  if (!LoadKey(slot_id, auth_key_blob, auth_data, &key_handle))
    return false;
  string master_key_str;
  if (!Unbind(key_handle, encrypted_master_key, &master_key_str))
    return false;
  *master_key = SecureBlob(master_key_str.begin(), master_key_str.end());
  brillo::SecureClearContainer(master_key_str);
  VLOG(1) << "TPMUtilityImpl::Authenticate success";
  return true;
}

bool TPMUtilityImpl::ChangeAuthData(int slot_id,
                                    const SecureBlob& old_auth_data,
                                    const SecureBlob& new_auth_data,
                                    const string& old_auth_key_blob,
                                    string* new_auth_key_blob) {
  VLOG(1) << "TPMUtilityImpl::ChangeAuthData enter";
  int key_handle = 0;
  if (!LoadKey(slot_id, old_auth_key_blob, old_auth_data, &key_handle))
    return false;
  // Make sure the old auth data is ok.
  string encrypted, decrypted;
  if (!Bind(key_handle, "testdata", &encrypted))
    return false;
  if (!Unbind(key_handle, encrypted, &decrypted))
    return false;
  // Change the secret.
  AutoLock lock(lock_);
  TSS_RESULT result = TSS_SUCCESS;
  ScopedTssPolicy policy(tsp_context_);
  result = Tspi_Context_CreateObject(tsp_context_, TSS_OBJECT_TYPE_POLICY,
                                     TSS_POLICY_USAGE, policy.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_CreateObject - " << ResultToString(result);
    return false;
  }
  result =
      Tspi_Policy_SetSecret(policy, TSS_SECRET_MODE_SHA1, new_auth_data.size(),
                            const_cast<BYTE*>(new_auth_data.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
    return false;
  }
  result = Tspi_ChangeAuth(GetTssHandle(key_handle), srk_, policy.release());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_ChangeAuth - " << ResultToString(result);
    return false;
  }
  if (!GetKeyBlob(GetTssHandle(key_handle), new_auth_key_blob))
    return false;
  VLOG(1) << "TPMUtilityImpl::ChangeAuthData success";
  return true;
}

bool TPMUtilityImpl::GenerateRandom(int num_bytes, string* random_data) {
  VLOG(1) << "TPMUtilityImpl::GenerateRandom enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSS_RESULT result = TSS_SUCCESS;
  TSS_HTPM tpm;
  BYTE* random_bytes = NULL;
  result = Tspi_Context_GetTpmObject(tsp_context_, &tpm);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_GetTpmObject - " << ResultToString(result);
    return false;
  }
  result = Tspi_TPM_GetRandom(tpm, num_bytes, &random_bytes);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_TPM_GetRandom - " << ResultToString(result);
    return false;
  }
  *random_data = ConvertByteBufferToString(random_bytes, num_bytes);
  Tspi_Context_FreeMemory(tsp_context_, random_bytes);
  VLOG(1) << "TPMUtilityImpl::GenerateRandom success";
  return true;
}

bool TPMUtilityImpl::StirRandom(const string& entropy_data) {
  VLOG(1) << "TPMUtilityImpl::StirRandom enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSS_RESULT result = TSS_SUCCESS;
  TSS_HTPM tpm;
  result = Tspi_Context_GetTpmObject(tsp_context_, &tpm);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_GetTpmObject - " << ResultToString(result);
    return false;
  }
  result = Tspi_TPM_StirRandom(tpm, entropy_data.length(),
                               ConvertStringToByteBuffer(entropy_data.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_TPM_StirRandom - " << ResultToString(result);
    return false;
  }
  VLOG(1) << "TPMUtilityImpl::StirRandom success";
  return true;
}

bool TPMUtilityImpl::GenerateRSAKey(int slot,
                                    int modulus_bits,
                                    const string& public_exponent,
                                    const SecureBlob& auth_data,
                                    string* key_blob,
                                    int* key_handle) {
  VLOG(1) << "TPMUtilityImpl::GenerateRSAKey enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSS_RESULT result = TSS_SUCCESS;
  ScopedTssKey key(tsp_context_);
  result = Tspi_Context_CreateObject(tsp_context_, TSS_OBJECT_TYPE_RSAKEY,
                                     GetKeyFlags(modulus_bits), key.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_CreateObject - " << ResultToString(result);
    return false;
  }
  if (public_exponent != default_exponent_) {
    LOG(WARNING) << "Non-Default Public Exponent: "
                 << PrintIntVector(ConvertByteStringToVector(public_exponent));
    result = Tspi_SetAttribData(
        key, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT,
        public_exponent.length(),
        ConvertStringToByteBuffer(public_exponent.data()));
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribData(EXPONENT) - " << ResultToString(result);
      return false;
    }
  }
  if (!CreateKeyPolicy(key, auth_data, false))
    return false;
  result = Tspi_Key_CreateKey(key, srk_, 0);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Key_CreateKey - " << ResultToString(result);
    return false;
  }
  result = Tspi_Key_LoadKey(key, srk_);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Key_LoadKey - " << ResultToString(result);
    return false;
  }
  if (!GetKeyBlob(key, key_blob))
    return false;
  *key_handle = CreateHandle(slot, key.release(), *key_blob, auth_data);
  VLOG(1) << "TPMUtilityImpl::GenerateRSAKey success";
  return true;
}

bool TPMUtilityImpl::GetRSAPublicKey(int key_handle,
                                     string* public_exponent,
                                     string* modulus) {
  VLOG(1) << "TPMUtilityImpl::GetRSAPublicKey enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  if (!GetKeyAttributeData(GetTssHandle(key_handle), TSS_TSPATTRIB_RSAKEY_INFO,
                           TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT, public_exponent))
    return false;
  if (!GetKeyAttributeData(GetTssHandle(key_handle), TSS_TSPATTRIB_RSAKEY_INFO,
                           TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, modulus))
    return false;
  VLOG(1) << "TPMUtilityImpl::GetRSAPublicKey success";
  return true;
}

bool TPMUtilityImpl::IsECCurveSupported(int curve_nid) {
  return false;
}

bool TPMUtilityImpl::GenerateECCKey(int slot,
                                    int nid,
                                    const brillo::SecureBlob& auth_data,
                                    std::string* key_blob,
                                    int* key_handle) {
  LOG(ERROR) << __func__ << "TPM 1.2 doesn't support ECC.";
  return false;
}

bool TPMUtilityImpl::GetECCPublicKey(int key_handle,
                                     std::string* public_point) {
  LOG(ERROR) << __func__ << "TPM 1.2 doesn't support ECC.";
  return false;
}

bool TPMUtilityImpl::WrapRSAKey(int slot,
                                const string& public_exponent,
                                const string& modulus,
                                const string& prime_factor,
                                const SecureBlob& auth_data,
                                string* key_blob,
                                int* key_handle) {
  VLOG(1) << "TPMUtilityImpl::WrapRSAKey enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  if (!GetSRKPublicKey())
    return false;
  ScopedTssKey key(tsp_context_);
  TSS_RESULT result =
      Tspi_Context_CreateObject(tsp_context_, TSS_OBJECT_TYPE_RSAKEY,
                                GetKeyFlags(modulus.length() * 8), key.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_CreateObject - " << ResultToString(result);
    return false;
  }
  if (public_exponent != default_exponent_) {
    LOG(WARNING) << "Non-Default Public Exponent: "
                 << PrintIntVector(ConvertByteStringToVector(public_exponent));
    result = Tspi_SetAttribData(
        key, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT,
        public_exponent.length(),
        ConvertStringToByteBuffer(public_exponent.data()));
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribData(EXPONENT) - " << ResultToString(result);
      return false;
    }
  }
  result = Tspi_SetAttribData(
      key, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
      modulus.length(), ConvertStringToByteBuffer(modulus.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_SetAttribData(MODULUS) - " << ResultToString(result);
    return false;
  }
  // The private parameter here is one of the prime factors (p or q). The reason
  // is that they are half the size of the modulus and from one factor (and the
  // modulus) the entire private key can be derived. The small size allows the
  // key to be wrapped in a single operation by another key of the same size.
  // See TPM_STORE_ASYMKEY in TPM Main Part 2 v1.2 r116 section 10.6 page 92.
  result = Tspi_SetAttribData(
      key, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY,
      prime_factor.length(), ConvertStringToByteBuffer(prime_factor.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_SetAttribData(FACTOR) - " << ResultToString(result);
    return false;
  }
  if (!CreateKeyPolicy(key, auth_data, false))
    return false;
  result = Tspi_Key_WrapKey(key, srk_, 0);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Key_WrapKey - " << ResultToString(result);
    return false;
  }
  result = Tspi_Key_LoadKey(key, srk_);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Key_LoadKey - " << ResultToString(result);
    return false;
  }
  if (!GetKeyBlob(key, key_blob))
    return false;
  *key_handle = CreateHandle(slot, key.release(), *key_blob, auth_data);
  VLOG(1) << "TPMUtilityImpl::WrapRSAKey success";
  return true;
}

bool TPMUtilityImpl::WrapECCKey(int slot,
                                int curve_nid,
                                const std::string& public_point_x,
                                const std::string& public_point_y,
                                const std::string& private_value,
                                const brillo::SecureBlob& auth_data,
                                std::string* key_blob,
                                int* key_handle) {
  LOG(ERROR) << __func__ << "TPM 1.2 doesn't support ECC.";
  return false;
}

bool TPMUtilityImpl::LoadKey(int slot,
                             const string& key_blob,
                             const SecureBlob& auth_data,
                             int* key_handle) {
  // Use the SRK as the parent. This is the normal case.
  return LoadKeyWithParent(slot, key_blob, auth_data, srk_, key_handle);
}

bool TPMUtilityImpl::LoadKeyWithParent(int slot,
                                       const string& key_blob,
                                       const SecureBlob& auth_data,
                                       int parent_key_handle,
                                       int* key_handle) {
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  if (IsAlreadyLoaded(slot, key_blob, key_handle))
    return true;
  VLOG(1) << "TPMUtilityImpl::LoadKeyWithParent enter";
  ScopedTssKey key(tsp_context_);
  if (!LoadKeyInternal(GetTssHandle(parent_key_handle), key_blob, auth_data,
                       key.ptr()))
    return false;
  *key_handle = CreateHandle(slot, key.release(), key_blob, auth_data);
  VLOG(1) << "TPMUtilityImpl::LoadKeyWithParent success";
  return true;
}

void TPMUtilityImpl::UnloadKeysForSlot(int slot) {
  VLOG(1) << "TPMUtilityImpl::UnloadKeysForSlot enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return;
  set<int>* handles = &slot_handles_[slot].handles_;
  set<int>::iterator it;
  for (it = handles->begin(); it != handles->end(); ++it) {
    Tspi_Key_UnloadKey(GetTssHandle(*it));
    Tspi_Context_CloseObject(tsp_context_, GetTssHandle(*it));
  }
  slot_handles_.erase(slot);
  LOG(INFO) << "Unloaded keys for slot " << slot;
  VLOG(1) << "TPMUtilityImpl::UnloadKeysForSlot success";
}

bool TPMUtilityImpl::Bind(int key_handle, const string& input, string* output) {
  VLOG(1) << "TPMUtilityImpl::Bind enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSSEncryptedData encrypted(tsp_context_);
  if (!encrypted.Create())
    return false;
  TSS_RESULT result =
      Tspi_Data_Bind(encrypted, GetTssHandle(key_handle), input.length(),
                     ConvertStringToByteBuffer(input.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Data_Bind - " << ResultToString(result);
    return false;
  }
  if (!encrypted.GetData(output))
    return false;
  VLOG(1) << "TPMUtilityImpl::Bind success";
  return true;
}

bool TPMUtilityImpl::Unbind(int key_handle,
                            const string& input,
                            string* output) {
  VLOG(1) << "TPMUtilityImpl::Unbind enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSSEncryptedData encrypted(tsp_context_);
  if (!encrypted.Create())
    return false;
  if (!encrypted.SetData(input))
    return false;
  UINT32 length = 0;
  BYTE* buffer = NULL;
  TSS_RESULT result =
      Tspi_Data_Unbind(encrypted, GetTssHandle(key_handle), &length, &buffer);
  if (result == (TSS_LAYER_TCS | TCS_E_KM_LOADFAILED)) {
    // On some TPMs, the TCS layer will fail to reload a key that has been
    // evicted. If this occurs, we can attempt to reload the key manually and
    // then try the operation again.
    LOG(WARNING) << "TCS load failure: attempting to reload key.";
    if (!ReloadKey(key_handle))
      return false;
    result =
        Tspi_Data_Unbind(encrypted, GetTssHandle(key_handle), &length, &buffer);
  }
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Data_Unbind - " << ResultToString(result);
    return false;
  }
  *output = ConvertByteBufferToString(buffer, length);
  Tspi_Context_FreeMemory(tsp_context_, buffer);
  VLOG(1) << "TPMUtilityImpl::Unbind success";
  return true;
}

bool TPMUtilityImpl::Sign(int key_handle,
                          CK_MECHANISM_TYPE signing_mechanism,
                          const std::string& mechanism_parameter,
                          const string& input,
                          string* signature) {
  VLOG(1) << "TPMUtilityImpl::Sign enter";
  AutoLock lock(lock_);
  DigestAlgorithm digest_algorithm = GetDigestAlgorithm(signing_mechanism);

  // Using the TSS_SS_RSASSAPKCS1V15_DER scheme, we need to manually
  // insert the hash OID.
  std::string data_to_sign =
      GetDigestAlgorithmEncoding(digest_algorithm) + input;
  if (!InitSRK())
    return false;
  TSSHash hash(tsp_context_);
  if (!hash.Create(data_to_sign))
    return false;

  // Tspi_Hash_Sign only do PKCS#1 v1.5, and only the mechanisms below match.
  if (GetSigningSchemeForMechanism(signing_mechanism) !=
      RsaPaddingScheme::RSASSA_PKCS1_V1_5) {
    LOG(ERROR) << "Unsupported mechanism for tpm1.2 key " << signing_mechanism;
    return false;
  }

  UINT32 length = 0;
  BYTE* buffer = NULL;
  TSS_RESULT result =
      Tspi_Hash_Sign(hash, GetTssHandle(key_handle), &length, &buffer);
  if (result == (TSS_LAYER_TCS | TCS_E_KM_LOADFAILED)) {
    // On some TPMs, the TCS layer will fail to reload a key that has been
    // evicted. If this occurs, we can attempt to reload the key manually and
    // then try the operation again.
    LOG(WARNING) << "TCS load failure: attempting to reload key.";
    if (!ReloadKey(key_handle))
      return false;
    result = Tspi_Hash_Sign(hash, GetTssHandle(key_handle), &length, &buffer);
  }
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Hash_Sign - " << ResultToString(result);
    return false;
  }
  *signature = ConvertByteBufferToString(buffer, length);
  Tspi_Context_FreeMemory(tsp_context_, buffer);
  VLOG(1) << "TPMUtilityImpl::Sign success";
  return true;
}

bool TPMUtilityImpl::IsSRKReady() {
  VLOG(1) << "TPMUtilityImpl::IsSRKReady";
  AutoLock lock(lock_);
  if (!tpm_manager_utility_) {
    LOG(ERROR) << "Accessing invalid tpm_manager utility.";
    return false;
  }
  bool is_enabled = false;
  bool is_owned = false;
  bool is_owner_password_present = false;
  bool has_reset_lock_permissions = false;
  if (!tpm_manager_utility_->GetTpmNonsensitiveStatus(
          &is_enabled, &is_owned, &is_owner_password_present,
          &has_reset_lock_permissions)) {
    LOG(ERROR) << ": failed to get TPM status from tpm_manager.";
    return false;
  }
  return is_enabled && is_owned && InitSRK();
}

int TPMUtilityImpl::CreateHandle(int slot,
                                 TSS_HKEY key,
                                 const string& key_blob,
                                 const SecureBlob& auth_data) {
  int handle = ++last_handle_;
  HandleInfo* handle_info = &slot_handles_[slot];
  handle_info->handles_.insert(handle);
  handle_info->blob_handle_[key_blob] = handle;
  KeyInfo* key_info = &handle_info_[handle];
  key_info->tss_handle = key;
  key_info->blob = key_blob;
  key_info->auth_data = auth_data;
  return handle;
}

bool TPMUtilityImpl::CreateKeyPolicy(TSS_HKEY key,
                                     const SecureBlob& auth_data,
                                     bool auth_only) {
  ScopedTssPolicy policy(tsp_context_);
  TSS_RESULT result = Tspi_Context_CreateObject(
      tsp_context_, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, policy.ptr());
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_CreateObject - " << ResultToString(result);
    return false;
  }
  if (auth_data.empty()) {
    result = Tspi_Policy_SetSecret(policy, TSS_SECRET_MODE_NONE, 0, NULL);
  } else {
    result =
        Tspi_Policy_SetSecret(policy, TSS_SECRET_MODE_SHA1, auth_data.size(),
                              const_cast<BYTE*>(auth_data.data()));
  }
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
    return false;
  }
  if (!auth_only) {
    result = Tspi_SetAttribUint32(key, TSS_TSPATTRIB_KEY_INFO,
                                  TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
                                  TSS_ES_RSAESPKCSV15);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribUint(ENCSCHEME) - "
                 << ResultToString(result);
      return false;
    }
    result = Tspi_SetAttribUint32(key, TSS_TSPATTRIB_KEY_INFO,
                                  TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
                                  TSS_SS_RSASSAPKCS1V15_DER);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribUint(SIGSCHEME) - "
                 << ResultToString(result);
      return false;
    }
    ScopedTssPolicy migration_policy(tsp_context_);
    result =
        Tspi_Context_CreateObject(tsp_context_, TSS_OBJECT_TYPE_POLICY,
                                  TSS_POLICY_MIGRATION, migration_policy.ptr());
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_SetAttribUint(SIGSCHEME) - "
                 << ResultToString(result);
      return false;
    }
    // We need to set a migration policy but we don't want the key to be
    // migratable. We'll set random authorization data and then discard it.
    const int kSha1OutputBytes = 20;
    unsigned char discard[kSha1OutputBytes];
    RAND_bytes(discard, kSha1OutputBytes);
    result = Tspi_Policy_SetSecret(migration_policy, TSS_SECRET_MODE_SHA1,
                                   kSha1OutputBytes, discard);
    brillo::SecureClearContainer(discard);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
      return false;
    }
    result = Tspi_Policy_AssignToObject(migration_policy.release(), key);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Policy_AssignToObject - " << ResultToString(result);
      return false;
    }
  }
  result = Tspi_Policy_AssignToObject(policy.release(), key);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Policy_AssignToObject - " << ResultToString(result);
    return false;
  }
  return true;
}

bool TPMUtilityImpl::GetKeyAttributeData(TSS_HKEY key,
                                         TSS_FLAG flag,
                                         TSS_FLAG sub_flag,
                                         string* data) {
  UINT32 length = 0;
  BYTE* buffer = NULL;
  TSS_RESULT result = Tspi_GetAttribData(key, flag, sub_flag, &length, &buffer);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_GetAttribData(" << flag << ", " << sub_flag << ") - "
               << ResultToString(result);
    return false;
  }
  *data = ConvertByteBufferToString(buffer, length);
  Tspi_Context_FreeMemory(tsp_context_, buffer);
  return true;
}

bool TPMUtilityImpl::GetKeyBlob(TSS_HKEY key, string* blob) {
  return GetKeyAttributeData(key, TSS_TSPATTRIB_KEY_BLOB,
                             TSS_TSPATTRIB_KEYBLOB_BLOB, blob);
}

TSS_FLAG TPMUtilityImpl::GetKeyFlags(int modulus_bits) {
  // We want the keys we create / wrap to be capable of signing and binding.
  // This means we need to use the 'legacy' key type. Keys of this type are
  // migratable by definition. See TCG Architecture Overview 1.4: 4.2.7.2.
  TSS_FLAG flags =
      TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
  if (modulus_bits == TSS_KEY_SIZEVAL_512BIT) {
    flags |= TSS_KEY_SIZE_512;
  } else if (modulus_bits == TSS_KEY_SIZEVAL_1024BIT) {
    flags |= TSS_KEY_SIZE_1024;
  } else if (modulus_bits == TSS_KEY_SIZEVAL_2048BIT) {
    flags |= TSS_KEY_SIZE_2048;
  } else if (modulus_bits == TSS_KEY_SIZEVAL_4096BIT) {
    flags |= TSS_KEY_SIZE_4096;
  } else if (modulus_bits == TSS_KEY_SIZEVAL_8192BIT) {
    flags |= TSS_KEY_SIZE_8192;
  } else if (modulus_bits == TSS_KEY_SIZEVAL_16384BIT) {
    flags |= TSS_KEY_SIZE_16384;
  } else {
    flags |= TSS_KEY_SIZE_DEFAULT;
  }
  return flags;
}

bool TPMUtilityImpl::GetSRKPublicKey() {
  // In order to wrap a key with the SRK we need access to the SRK public key
  // and we need to get it manually. Once it's in the key object, we don't need
  // to do this again.
  if (!srk_public_loaded_) {
    UINT32 length = 0;
    BYTE* buffer = NULL;
    TSS_RESULT result = Tspi_Key_GetPubKey(srk_, &length, &buffer);
    if (result != TSS_SUCCESS) {
      if (result == TPM_E_INVALID_KEYHANDLE) {
        LOG(ERROR) << "The TPM is not configured to allow reading the public "
                   << "SRK. Use 'tpm_restrictsrk -a' to allow this.";
      } else {
        LOG(ERROR) << "Tspi_Key_GetPubKey - " << ResultToString(result);
      }
      return false;
    }
    Tspi_Context_FreeMemory(tsp_context_, buffer);
    srk_public_loaded_ = true;
  }
  return true;
}

TSS_HKEY TPMUtilityImpl::GetTssHandle(int key_handle) {
  if (static_cast<TSS_HKEY>(key_handle) == srk_)
    return srk_;
  map<int, KeyInfo>::iterator it = handle_info_.find(key_handle);
  if (it == handle_info_.end())
    return 0;
  return it->second.tss_handle;
}

bool TPMUtilityImpl::IsAlreadyLoaded(int slot,
                                     const string& key_blob,
                                     int* key_handle) {
  HandleInfo* handle_info = &slot_handles_[slot];
  map<string, int>::iterator it = handle_info->blob_handle_.find(key_blob);
  if (it == handle_info->blob_handle_.end())
    return false;
  *key_handle = it->second;
  return true;
}

bool TPMUtilityImpl::LoadKeyInternal(TSS_HKEY parent,
                                     const string& key_blob,
                                     const SecureBlob& auth_data,
                                     TSS_HKEY* key) {
  TSS_RESULT result = Tspi_Context_LoadKeyByBlob(
      tsp_context_, parent, key_blob.length(),
      ConvertStringToByteBuffer(key_blob.data()), key);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Context_LoadKeyByBlob - " << ResultToString(result);
    return false;
  }
  TSS_HPOLICY policy;
  result = Tspi_GetPolicyObject(*key, TSS_POLICY_USAGE, &policy);
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_GetPolicyObject - " << ResultToString(result);
    return false;
  }
  if (policy == default_policy_) {
    if (!CreateKeyPolicy(*key, auth_data, true))
      return false;
  } else if (auth_data.empty()) {
    result = Tspi_Policy_SetSecret(policy, TSS_SECRET_MODE_NONE, 0, NULL);
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
      return false;
    }
  } else {
    result =
        Tspi_Policy_SetSecret(policy, TSS_SECRET_MODE_SHA1, auth_data.size(),
                              const_cast<BYTE*>(auth_data.data()));
    if (result != TSS_SUCCESS) {
      LOG(ERROR) << "Tspi_Policy_SetSecret - " << ResultToString(result);
      return false;
    }
  }
  return true;
}

bool TPMUtilityImpl::ReloadKey(int key_handle) {
  KeyInfo* key_info = &handle_info_[key_handle];
  // Unload the current handle.
  Tspi_Key_UnloadKey(key_info->tss_handle);
  Tspi_Context_CloseObject(tsp_context_, key_info->tss_handle);
  key_info->tss_handle = 0;
  // Load the same key blob again.
  ScopedTssKey scoped_key(tsp_context_);
  if (!LoadKeyInternal(srk_, key_info->blob, key_info->auth_data,
                       scoped_key.ptr())) {
    LOG(ERROR) << "Failed to reload key.";
    return false;
  }
  key_info->tss_handle = scoped_key.release();
  return true;
}

string TPMUtilityImpl::ResultToString(TSS_RESULT result) {
  if (result == TSS_SUCCESS)
    return "TSS_SUCCESS";
  TSS_RESULT layer = ERROR_LAYER(result);
  TSS_RESULT code = ERROR_CODE(result);
  if (layer == TSS_LAYER_TPM) {
    switch (code) {
      case TPM_E_AUTHFAIL:
        return "TPM_E_AUTHFAIL";
      case TPM_E_BADINDEX:
        return "TPM_E_BADINDEX";
      case TPM_E_BAD_PARAMETER:
        return "TPM_E_BAD_PARAMETER";
      case TPM_E_AUDITFAILURE:
        return "TPM_E_AUDITFAILURE";
      case TPM_E_CLEAR_DISABLED:
        return "TPM_E_CLEAR_DISABLED";
      case TPM_E_DEACTIVATED:
        return "TPM_E_DEACTIVATED";
      case TPM_E_DISABLED:
        return "TPM_E_DISABLED";
      case TPM_E_DISABLED_CMD:
        return "TPM_E_DISABLED_CMD";
      case TPM_E_FAIL:
        return "TPM_E_FAIL";
      case TPM_E_BAD_ORDINAL:
        return "TPM_E_BAD_ORDINAL";
      case TPM_E_INSTALL_DISABLED:
        return "TPM_E_INSTALL_DISABLED";
      case TPM_E_INVALID_KEYHANDLE:
        return "TPM_E_INVALID_KEYHANDLE";
      case TPM_E_KEYNOTFOUND:
        return "TPM_E_KEYNOTFOUND";
      case TPM_E_INAPPROPRIATE_ENC:
        return "TPM_E_INAPPROPRIATE_ENC";
      case TPM_E_MIGRATEFAIL:
        return "TPM_E_MIGRATEFAIL";
      case TPM_E_INVALID_PCR_INFO:
        return "TPM_E_INVALID_PCR_INFO";
      case TPM_E_NOSPACE:
        return "TPM_E_NOSPACE";
      case TPM_E_NOSRK:
        return "TPM_E_NOSRK";
      case TPM_E_NOTSEALED_BLOB:
        return "TPM_E_NOTSEALED_BLOB";
      case TPM_E_OWNER_SET:
        return "TPM_E_OWNER_SET";
      case TPM_E_RESOURCES:
        return "TPM_E_RESOURCES";
      case TPM_E_SHORTRANDOM:
        return "TPM_E_SHORTRANDOM";
      case TPM_E_SIZE:
        return "TPM_E_SIZE";
      case TPM_E_WRONGPCRVAL:
        return "TPM_E_WRONGPCRVAL";
      case TPM_E_BAD_PARAM_SIZE:
        return "TPM_E_BAD_PARAM_SIZE";
      case TPM_E_SHA_THREAD:
        return "TPM_E_SHA_THREAD";
      case TPM_E_SHA_ERROR:
        return "TPM_E_SHA_ERROR";
      case TPM_E_FAILEDSELFTEST:
        return "TPM_E_FAILEDSELFTEST";
      case TPM_E_AUTH2FAIL:
        return "TPM_E_AUTH2FAIL";
      case TPM_E_BADTAG:
        return "TPM_E_BADTAG";
      case TPM_E_IOERROR:
        return "TPM_E_IOERROR";
      case TPM_E_ENCRYPT_ERROR:
        return "TPM_E_ENCRYPT_ERROR";
      case TPM_E_DECRYPT_ERROR:
        return "TPM_E_DECRYPT_ERROR";
      case TPM_E_INVALID_AUTHHANDLE:
        return "TPM_E_INVALID_AUTHHANDLE";
      case TPM_E_NO_ENDORSEMENT:
        return "TPM_E_NO_ENDORSEMENT";
      case TPM_E_INVALID_KEYUSAGE:
        return "TPM_E_INVALID_KEYUSAGE";
      case TPM_E_WRONG_ENTITYTYPE:
        return "TPM_E_WRONG_ENTITYTYPE";
      case TPM_E_INVALID_POSTINIT:
        return "TPM_E_INVALID_POSTINIT";
      case TPM_E_INAPPROPRIATE_SIG:
        return "TPM_E_INAPPROPRIATE_SIG";
      case TPM_E_BAD_KEY_PROPERTY:
        return "TPM_E_BAD_KEY_PROPERTY";
      case TPM_E_BAD_MIGRATION:
        return "TPM_E_BAD_MIGRATION";
      case TPM_E_BAD_SCHEME:
        return "TPM_E_BAD_SCHEME";
      case TPM_E_BAD_DATASIZE:
        return "TPM_E_BAD_DATASIZE";
      case TPM_E_BAD_MODE:
        return "TPM_E_BAD_MODE";
      case TPM_E_BAD_PRESENCE:
        return "TPM_E_BAD_PRESENCE";
      case TPM_E_BAD_VERSION:
        return "TPM_E_BAD_VERSION";
      case TPM_E_NO_WRAP_TRANSPORT:
        return "TPM_E_NO_WRAP_TRANSPORT";
      case TPM_E_AUDITFAIL_UNSUCCESSFUL:
        return "TPM_E_AUDITFAIL_UNSUCCESSFUL";
      case TPM_E_AUDITFAIL_SUCCESSFUL:
        return "TPM_E_AUDITFAIL_SUCCESSFUL";
      case TPM_E_NOTRESETABLE:
        return "TPM_E_NOTRESETABLE";
      case TPM_E_NOTLOCAL:
        return "TPM_E_NOTLOCAL";
      case TPM_E_BAD_TYPE:
        return "TPM_E_BAD_TYPE";
      case TPM_E_INVALID_RESOURCE:
        return "TPM_E_INVALID_RESOURCE";
      case TPM_E_NOTFIPS:
        return "TPM_E_NOTFIPS";
      case TPM_E_INVALID_FAMILY:
        return "TPM_E_INVALID_FAMILY";
      case TPM_E_NO_NV_PERMISSION:
        return "TPM_E_NO_NV_PERMISSION";
      case TPM_E_REQUIRES_SIGN:
        return "TPM_E_REQUIRES_SIGN";
      case TPM_E_KEY_NOTSUPPORTED:
        return "TPM_E_KEY_NOTSUPPORTED";
      case TPM_E_AUTH_CONFLICT:
        return "TPM_E_AUTH_CONFLICT";
      case TPM_E_AREA_LOCKED:
        return "TPM_E_AREA_LOCKED";
      case TPM_E_BAD_LOCALITY:
        return "TPM_E_BAD_LOCALITY";
      case TPM_E_READ_ONLY:
        return "TPM_E_READ_ONLY";
      case TPM_E_PER_NOWRITE:
        return "TPM_E_PER_NOWRITE";
      case TPM_E_FAMILYCOUNT:
        return "TPM_E_FAMILYCOUNT";
      case TPM_E_WRITE_LOCKED:
        return "TPM_E_WRITE_LOCKED";
      case TPM_E_BAD_ATTRIBUTES:
        return "TPM_E_BAD_ATTRIBUTES";
      case TPM_E_INVALID_STRUCTURE:
        return "TPM_E_INVALID_STRUCTURE";
      case TPM_E_KEY_OWNER_CONTROL:
        return "TPM_E_KEY_OWNER_CONTROL";
      case TPM_E_BAD_COUNTER:
        return "TPM_E_BAD_COUNTER";
      case TPM_E_NOT_FULLWRITE:
        return "TPM_E_NOT_FULLWRITE";
      case TPM_E_CONTEXT_GAP:
        return "TPM_E_CONTEXT_GAP";
      case TPM_E_MAXNVWRITES:
        return "TPM_E_MAXNVWRITES";
      case TPM_E_NOOPERATOR:
        return "TPM_E_NOOPERATOR";
      case TPM_E_RESOURCEMISSING:
        return "TPM_E_RESOURCEMISSING";
      case TPM_E_DELEGATE_LOCK:
        return "TPM_E_DELEGATE_LOCK";
      case TPM_E_DELEGATE_FAMILY:
        return "TPM_E_DELEGATE_FAMILY";
      case TPM_E_DELEGATE_ADMIN:
        return "TPM_E_DELEGATE_ADMIN";
      case TPM_E_TRANSPORT_NOTEXCLUSIVE:
        return "TPM_E_TRANSPORT_NOTEXCLUSIVE";
      case TPM_E_OWNER_CONTROL:
        return "TPM_E_OWNER_CONTROL";
      case TPM_E_DAA_RESOURCES:
        return "TPM_E_DAA_RESOURCES";
      case TPM_E_DAA_INPUT_DATA0:
        return "TPM_E_DAA_INPUT_DATA0";
      case TPM_E_DAA_INPUT_DATA1:
        return "TPM_E_DAA_INPUT_DATA1";
      case TPM_E_DAA_ISSUER_SETTINGS:
        return "TPM_E_DAA_ISSUER_SETTINGS";
      case TPM_E_DAA_TPM_SETTINGS:
        return "TPM_E_DAA_TPM_SETTINGS";
      case TPM_E_DAA_STAGE:
        return "TPM_E_DAA_STAGE";
      case TPM_E_DAA_ISSUER_VALIDITY:
        return "TPM_E_DAA_ISSUER_VALIDITY";
      case TPM_E_DAA_WRONG_W:
        return "TPM_E_DAA_WRONG_W";
      case TPM_E_BAD_HANDLE:
        return "TPM_E_BAD_HANDLE";
      case TPM_E_BAD_DELEGATE:
        return "TPM_E_BAD_DELEGATE";
      case TPM_E_BADCONTEXT:
        return "TPM_E_BADCONTEXT";
      case TPM_E_TOOMANYCONTEXTS:
        return "TPM_E_TOOMANYCONTEXTS";
      case TPM_E_MA_TICKET_SIGNATURE:
        return "TPM_E_MA_TICKET_SIGNATURE";
      case TPM_E_MA_DESTINATION:
        return "TPM_E_MA_DESTINATION";
      case TPM_E_MA_SOURCE:
        return "TPM_E_MA_SOURCE";
      case TPM_E_MA_AUTHORITY:
        return "TPM_E_MA_AUTHORITY";
      case TPM_E_PERMANENTEK:
        return "TPM_E_PERMANENTEK";
      case TPM_E_BAD_SIGNATURE:
        return "TPM_E_BAD_SIGNATURE";
      case TPM_E_NOCONTEXTSPACE:
        return "TPM_E_NOCONTEXTSPACE";
      case TPM_E_RETRY:
        return "TPM_E_RETRY";
      case TPM_E_NEEDS_SELFTEST:
        return "TPM_E_NEEDS_SELFTEST";
      case TPM_E_DOING_SELFTEST:
        return "TPM_E_DOING_SELFTEST";
      case TPM_E_DEFEND_LOCK_RUNNING:
        return "TPM_E_DEFEND_LOCK_RUNNING";
    }
  } else if (layer == TSS_LAYER_TDDL) {
    switch (code) {
      case TDDL_E_FAIL:
        return "TDDL_E_FAIL";
      case TDDL_E_TIMEOUT:
        return "TDDL_E_TIMEOUT";
      case TDDL_E_ALREADY_OPENED:
        return "TDDL_E_ALREADY_OPENED";
      case TDDL_E_ALREADY_CLOSED:
        return "TDDL_E_ALREADY_CLOSED";
      case TDDL_E_INSUFFICIENT_BUFFER:
        return "TDDL_E_INSUFFICIENT_BUFFER";
      case TDDL_E_COMMAND_COMPLETED:
        return "TDDL_E_COMMAND_COMPLETED";
      case TDDL_E_COMMAND_ABORTED:
        return "TDDL_E_COMMAND_ABORTED";
      case TDDL_E_IOERROR:
        return "TDDL_E_IOERROR";
      case TDDL_E_BADTAG:
        return "TDDL_E_BADTAG";
      case TDDL_E_COMPONENT_NOT_FOUND:
        return "TDDL_E_COMPONENT_NOT_FOUND";
    }
  } else if (layer == TSS_LAYER_TCS) {
    switch (code) {
      case TCS_E_INVALID_CONTEXTHANDLE:
        return "TCS_E_INVALID_CONTEXTHANDLE";
      case TCS_E_INVALID_KEYHANDLE:
        return "TCS_E_INVALID_KEYHANDLE";
      case TCS_E_INVALID_AUTHHANDLE:
        return "TCS_E_INVALID_AUTHHANDLE";
      case TCS_E_INVALID_AUTHSESSION:
        return "TCS_E_INVALID_AUTHSESSION";
      case TCS_E_INVALID_KEY:
        return "TCS_E_INVALID_KEY";
      case TCS_E_KEY_MISMATCH:
        return "TCS_E_KEY_MISMATCH";
      case TCS_E_KM_LOADFAILED:
        return "TCS_E_KM_LOADFAILED";
      case TCS_E_KEY_CONTEXT_RELOAD:
        return "TCS_E_KEY_CONTEXT_RELOAD";
      case TCS_E_BAD_INDEX:
        return "TCS_E_BAD_INDEX";
      case TCS_E_KEY_ALREADY_REGISTERED:
        return "TCS_E_KEY_ALREADY_REGISTERED";
      case TCS_E_BAD_PARAMETER:
        return "TCS_E_BAD_PARAMETER";
      case TCS_E_OUTOFMEMORY:
        return "TCS_E_OUTOFMEMORY";
      case TCS_E_NOTIMPL:
        return "TCS_E_NOTIMPL";
      case TCS_E_INTERNAL_ERROR:
        return "TCS_E_INTERNAL_ERROR";
    }
  } else if (layer == TSS_LAYER_TSP) {
    switch (code) {
      case TSS_E_FAIL:
        return "TSS_E_FAIL";
      case TSS_E_BAD_PARAMETER:
        return "TSS_E_BAD_PARAMETER";
      case TSS_E_INTERNAL_ERROR:
        return "TSS_E_INTERNAL_ERROR";
      case TSS_E_OUTOFMEMORY:
        return "TSS_E_OUTOFMEMORY";
      case TSS_E_NOTIMPL:
        return "TSS_E_NOTIMPL";
      case TSS_E_KEY_ALREADY_REGISTERED:
        return "TSS_E_KEY_ALREADY_REGISTERED";
      case TSS_E_TPM_UNEXPECTED:
        return "TSS_E_TPM_UNEXPECTED";
      case TSS_E_COMM_FAILURE:
        return "TSS_E_COMM_FAILURE";
      case TSS_E_TIMEOUT:
        return "TSS_E_TIMEOUT";
      case TSS_E_TPM_UNSUPPORTED_FEATURE:
        return "TSS_E_TPM_UNSUPPORTED_FEATURE";
      case TSS_E_CANCELED:
        return "TSS_E_CANCELED";
      case TSS_E_PS_KEY_NOTFOUND:
        return "TSS_E_PS_KEY_NOTFOUND";
      case TSS_E_PS_KEY_EXISTS:
        return "TSS_E_PS_KEY_EXISTS";
      case TSS_E_PS_BAD_KEY_STATE:
        return "TSS_E_PS_BAD_KEY_STATE";
      case TSS_E_INVALID_OBJECT_TYPE:
        return "TSS_E_INVALID_OBJECT_TYPE";
      case TSS_E_NO_CONNECTION:
        return "TSS_E_NO_CONNECTION";
      case TSS_E_CONNECTION_FAILED:
        return "TSS_E_CONNECTION_FAILED";
      case TSS_E_CONNECTION_BROKEN:
        return "TSS_E_CONNECTION_BROKEN";
      case TSS_E_HASH_INVALID_ALG:
        return "TSS_E_HASH_INVALID_ALG";
      case TSS_E_HASH_INVALID_LENGTH:
        return "TSS_E_HASH_INVALID_LENGTH";
      case TSS_E_HASH_NO_DATA:
        return "TSS_E_HASH_NO_DATA";
      case TSS_E_INVALID_ATTRIB_FLAG:
        return "TSS_E_INVALID_ATTRIB_FLAG";
      case TSS_E_INVALID_ATTRIB_SUBFLAG:
        return "TSS_E_INVALID_ATTRIB_SUBFLAG";
      case TSS_E_INVALID_ATTRIB_DATA:
        return "TSS_E_INVALID_ATTRIB_DATA";
      case TSS_E_INVALID_OBJECT_INITFLAG:
        return "TSS_E_INVALID_OBJECT_INITFLAG";
      case TSS_E_NO_PCRS_SET:
        return "TSS_E_NO_PCRS_SET";
      case TSS_E_KEY_NOT_LOADED:
        return "TSS_E_KEY_NOT_LOADED";
      case TSS_E_KEY_NOT_SET:
        return "TSS_E_KEY_NOT_SET";
      case TSS_E_VALIDATION_FAILED:
        return "TSS_E_VALIDATION_FAILED";
      case TSS_E_TSP_AUTHREQUIRED:
        return "TSS_E_TSP_AUTHREQUIRED";
      case TSS_E_TSP_AUTH2REQUIRED:
        return "TSS_E_TSP_AUTH2REQUIRED";
      case TSS_E_TSP_AUTHFAIL:
        return "TSS_E_TSP_AUTHFAIL";
      case TSS_E_TSP_AUTH2FAIL:
        return "TSS_E_TSP_AUTH2FAIL";
      case TSS_E_KEY_NO_MIGRATION_POLICY:
        return "TSS_E_KEY_NO_MIGRATION_POLICY";
      case TSS_E_POLICY_NO_SECRET:
        return "TSS_E_POLICY_NO_SECRET";
      case TSS_E_INVALID_OBJ_ACCESS:
        return "TSS_E_INVALID_OBJ_ACCESS";
      case TSS_E_INVALID_ENCSCHEME:
        return "TSS_E_INVALID_ENCSCHEME";
      case TSS_E_INVALID_SIGSCHEME:
        return "TSS_E_INVALID_SIGSCHEME";
      case TSS_E_ENC_INVALID_LENGTH:
        return "TSS_E_ENC_INVALID_LENGTH";
      case TSS_E_ENC_NO_DATA:
        return "TSS_E_ENC_NO_DATA";
      case TSS_E_ENC_INVALID_TYPE:
        return "TSS_E_ENC_INVALID_TYPE";
      case TSS_E_INVALID_KEYUSAGE:
        return "TSS_E_INVALID_KEYUSAGE";
      case TSS_E_VERIFICATION_FAILED:
        return "TSS_E_VERIFICATION_FAILED";
      case TSS_E_HASH_NO_IDENTIFIER:
        return "TSS_E_HASH_NO_IDENTIFIER";
      case TSS_E_INVALID_HANDLE:
        return "TSS_E_INVALID_HANDLE";
      case TSS_E_SILENT_CONTEXT:
        return "TSS_E_SILENT_CONTEXT";
      case TSS_E_EK_CHECKSUM:
        return "TSS_E_EK_CHECKSUM";
      case TSS_E_DELEGATION_NOTSET:
        return "TSS_E_DELEGATION_NOTSET";
      case TSS_E_DELFAMILY_NOTFOUND:
        return "TSS_E_DELFAMILY_NOTFOUND";
      case TSS_E_DELFAMILY_ROWEXISTS:
        return "TSS_E_DELFAMILY_ROWEXISTS";
      case TSS_E_VERSION_MISMATCH:
        return "TSS_E_VERSION_MISMATCH";
      case TSS_E_DAA_AR_DECRYPTION_ERROR:
        return "TSS_E_DAA_AR_DECRYPTION_ERROR";
      case TSS_E_DAA_AUTHENTICATION_ERROR:
        return "TSS_E_DAA_AUTHENTICATION_ERROR";
      case TSS_E_DAA_CHALLENGE_RESPONSE_ERROR:
        return "TSS_E_DAA_CHALLENGE_RESPONSE_ERROR";
      case TSS_E_DAA_CREDENTIAL_PROOF_ERROR:
        return "TSS_E_DAA_CREDENTIAL_PROOF_ERROR";
      case TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR:
        return "TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR";
      case TSS_E_DAA_ISSUER_KEY_ERROR:
        return "TSS_E_DAA_ISSUER_KEY_ERROR";
      case TSS_E_DAA_PSEUDONYM_ERROR:
        return "TSS_E_DAA_PSEUDONYM_ERROR";
      case TSS_E_INVALID_RESOURCE:
        return "TSS_E_INVALID_RESOURCE";
      case TSS_E_NV_AREA_EXIST:
        return "TSS_E_NV_AREA_EXIST";
      case TSS_E_NV_AREA_NOT_EXIST:
        return "TSS_E_NV_AREA_NOT_EXIST";
      case TSS_E_TSP_TRANS_AUTHFAIL:
        return "TSS_E_TSP_TRANS_AUTHFAIL";
      case TSS_E_TSP_TRANS_AUTHREQUIRED:
        return "TSS_E_TSP_TRANS_AUTHREQUIRED";
      case TSS_E_TSP_TRANS_NOTEXCLUSIVE:
        return "TSS_E_TSP_TRANS_NOTEXCLUSIVE";
      case TSS_E_TSP_TRANS_FAIL:
        return "TSS_E_TSP_TRANS_FAIL";
      case TSS_E_TSP_TRANS_NO_PUBKEY:
        return "TSS_E_TSP_TRANS_NO_PUBKEY";
      case TSS_E_NO_ACTIVE_COUNTER:
        return "TSS_E_NO_ACTIVE_COUNTER";
    }
  }
  // Unknown value, just give the hex numeric value.
  stringstream ss;
  ss << "0x" << hex << result;
  return ss.str();
}

}  // namespace chaps
