// 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 trousers::ScopedTssContext;
using trousers::ScopedTssKey;
using trousers::ScopedTssObject;
using trousers::ScopedTssPolicy;
using std::hex;
using std::map;
using std::set;
using std::string;
using std::stringstream;

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) {}
  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_;

  DISALLOW_COPY_AND_ASSIGN(TSSEncryptedData);
};

// 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) {}
  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_;

  DISALLOW_COPY_AND_ASSIGN(TSSHash);
};

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_;
}

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());
  ClearString(&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,
                          DigestAlgorithm digest_algorithm,
                          const string& input,
                          string* signature) {
  VLOG(1) << "TPMUtilityImpl::Sign enter";
  AutoLock lock(lock_);
  // 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;
  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::SecureMemset(discard, 0, kSha1OutputBytes);
    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
