// 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),
      is_enabled_(false),
      is_enabled_ready_(false) {}

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";
  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 (is_enabled_ready_) {
    return is_enabled_;
  }
  // If the TPM works, clearly it's available.
  if (is_initialized_) {
    is_enabled_ready_ = true;
    is_enabled_ = true;
    return true;
  }
  // If the system says there is an enabled TPM, expect to use it.
  const base::FilePath kMiscEnabledFile("/sys/class/misc/tpm0/device/enabled");
  const base::FilePath kTpmEnabledFile("/sys/class/tpm/tpm0/device/enabled");
  string file_content;
  if ((base::ReadFileToString(kMiscEnabledFile, &file_content) ||
       base::ReadFileToString(kTpmEnabledFile, &file_content)) &&
      !file_content.empty() && file_content[0] == '1') {
    is_enabled_ = true;
  }
  is_enabled_ready_ = true;
  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_);
  return 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
