// 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 <chromeos/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 chromeos::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 kTpmEnabledFile("/sys/class/misc/tpm0/device/enabled");
  string file_content;
  if (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.data(), master_key_str.length());
  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.front()));
  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::GenerateKey(int slot,
                                 int modulus_bits,
                                 const string& public_exponent,
                                 const SecureBlob& auth_data,
                                 string* key_blob,
                                 int* key_handle) {
  VLOG(1) << "TPMUtilityImpl::GenerateKey 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::GenerateKey success";
  return true;
}

bool TPMUtilityImpl::GetPublicKey(int key_handle,
                                  string* public_exponent,
                                  string* modulus) {
  VLOG(1) << "TPMUtilityImpl::GetPublicKey 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::GetPublicKey success";
  return true;
}

bool TPMUtilityImpl::WrapKey(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::WrapKey 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::WrapKey success";
  return true;
}

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,
                          const string& input,
                          string* signature) {
  VLOG(1) << "TPMUtilityImpl::Sign enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSSHash hash(tsp_context_);
  if (!hash.Create(input))
    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::Verify(int key_handle,
                            const string& input,
                            const string& signature) {
  VLOG(1) << "TPMUtilityImpl::Verify enter";
  AutoLock lock(lock_);
  if (!InitSRK())
    return false;
  TSSHash hash(tsp_context_);
  if (!hash.Create(input))
    return false;
  TSS_RESULT result = Tspi_Hash_VerifySignature(
      hash,
      GetTssHandle(key_handle),
      signature.length(),
      ConvertStringToByteBuffer(signature.data()));
  if (result != TSS_SUCCESS) {
    LOG(ERROR) << "Tspi_Hash_VerifySignature - " << ResultToString(result);
    return false;
  }
  VLOG(1) << "TPMUtilityImpl::Verify 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.front()));
  }
  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);
    chromeos::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.front()));
    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
