// Copyright 2014 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 "trunks/tpm_utility_impl.h"

#include <algorithm>
#include <cstdint>
#include <memory>

#include <base/check.h>
#include <base/check_op.h>
#include <base/hash/sha1.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/sys_byteorder.h>
#include <crypto/libcrypto-compat.h>
#include <crypto/openssl_util.h>
#include <crypto/scoped_openssl_types.h>
#include <crypto/secure_hash.h>
#include <crypto/sha2.h>
#include <openssl/aes.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

#include "trunks/authorization_delegate.h"
#include "trunks/blob_parser.h"
#include "trunks/command_transceiver.h"
#include "trunks/error_codes.h"
#include "trunks/hmac_authorization_delegate.h"
#include "trunks/hmac_session.h"
#include "trunks/policy_session.h"
#include "trunks/tpm_constants.h"
#include "trunks/tpm_pinweaver.h"
#include "trunks/tpm_state.h"
#include "trunks/trunks_factory.h"

#include "trunks/csme/mei_client_factory.h"
#include "trunks/csme/pinweaver_core_client.h"
#include "trunks/csme/pinweaver_provision_client.h"

namespace {

const char kPlatformPassword[] = "cros-platform";
const size_t kMaxPasswordLength = 32;
// The below maximum is defined in TPM 2.0 Library Spec Part 2 Section 13.1
const uint32_t kMaxNVSpaceIndex = (1 << 24) - 1;
// Cr50 Vendor ID ("CROS").
const uint32_t kVendorIdCr50 = 0x43524f53;
// Simulator Vendor ID ("SIMU").
const uint32_t kVendorIdSimulator = 0x53494d55;
// Command code for Cr50 vendor-specific commands,
const uint32_t kCr50VendorCC = 0x20000000 | 0; /* Vendor Bit Set + 0 */
// Vendor-specific subcommand codes.
const uint16_t kCr50SubcmdInvalidateInactiveRW = 20;
const uint16_t kCr50GetRmaChallenge = 30;
const uint16_t kCr50SubcmdManageCCDPwd = 33;
const uint16_t kCr50SubcmdGetAlertsData = 35;
const uint16_t kCr50SubcmdPinWeaver = 37;
const uint16_t kCr50SubcmdGetRoStatus = 57;

// Auth policy used in RSA and ECC templates for EK keys generation.
// From TCG Credential Profile EK 2.0. Section 2.1.5.
const std::string kEKTemplateAuthPolicy(
    "\x83\x71\x97\x67\x44\x84\xB3\xF8\x1A\x90\xCC\x8D\x46\xA5\xD7\x24"
    "\xFD\x52\xD7\x6E\x06\x52\x0B\x64\xF2\xA1\xDA\x1B\x33\x14\x69\xAA");

// Salt used exclusively for the Remote Server Unlock process due to the privacy
// reasons.
const char kRsuSalt[] = "Wu8oGt0uu0H8uSGxfo75uSDrGcRk2BXh";

// Returns a serialized representation of the unmodified handle. This is useful
// for predefined handle values, like TPM_RH_OWNER. For details on what types of
// handles use this name formula see Table 3 in the TPM 2.0 Library Spec Part 1
// (Section 16 - Names).
std::string NameFromHandle(trunks::TPM_HANDLE handle) {
  std::string name;
  trunks::Serialize_TPM_HANDLE(handle, &name);
  return name;
}

std::string HashString(const std::string& plaintext,
                       trunks::TPM_ALG_ID hash_alg) {
  switch (hash_alg) {
    case trunks::TPM_ALG_SHA1:
      return base::SHA1HashString(plaintext);
    case trunks::TPM_ALG_SHA256:
      return crypto::SHA256HashString(plaintext);
  }
  NOTREACHED();
  return std::string();
}

}  // namespace

namespace trunks {

TpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory)
    : factory_(factory), vendor_id_(0) {
  crypto::EnsureOpenSSLInit();
}

TpmUtilityImpl::~TpmUtilityImpl() {}

TPM_RC TpmUtilityImpl::Startup() {
  TPM_RC result = TPM_RC_SUCCESS;
  Tpm* tpm = factory_.GetTpm();
  result = tpm->StartupSync(TPM_SU_CLEAR, nullptr);
  // Ignore TPM_RC_INITIALIZE, that means it was already started.
  if (result && result != TPM_RC_INITIALIZE) {
    LOG(ERROR) << __func__
               << ": Failed to startup sync: " << GetErrorString(result);
    return result;
  }
  result = tpm->SelfTestSync(YES /* Full test. */, nullptr);
  if (result) {
    LOG(ERROR) << __func__
               << ": Failed self test sync: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::Clear() {
  TPM_RC result = TPM_RC_SUCCESS;
  std::unique_ptr<AuthorizationDelegate> password_delegate(
      factory_.GetPasswordAuthorization(""));
  result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM,
                                        NameFromHandle(TPM_RH_PLATFORM),
                                        password_delegate.get());
  // If there was an error in the initialization, platform auth is in a bad
  // state.
  if (result == TPM_RC_AUTH_MISSING) {
    std::unique_ptr<AuthorizationDelegate> authorization(
        factory_.GetPasswordAuthorization(kPlatformPassword));
    result = factory_.GetTpm()->ClearSync(
        TPM_RH_PLATFORM, NameFromHandle(TPM_RH_PLATFORM), authorization.get());
  }
  if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
    LOG(INFO) << __func__
              << ": Clear failed because of BAD_AUTH. This probably means "
              << "that the TPM was already initialized.";
    return result;
  }
  if (result) {
    LOG(ERROR) << __func__
               << ": Failed to clear the TPM: " << GetErrorString(result);
  }
  return result;
}

void TpmUtilityImpl::Shutdown() {
  TPM_RC return_code = factory_.GetTpm()->ShutdownSync(TPM_SU_CLEAR, nullptr);
  if (return_code && return_code != TPM_RC_INITIALIZE) {
    // This should not happen, but if it does, there is nothing we can do.
    LOG(ERROR) << __func__
               << ": Error shutting down: " << GetErrorString(return_code);
  }
}

TPM_RC TpmUtilityImpl::TpmBasicInit(std::unique_ptr<TpmState>* tpm_state) {
  TPM_RC result = TPM_RC_SUCCESS;

  *tpm_state = factory_.GetTpmState();
  result = (*tpm_state)->Initialize();
  if (result) {
    LOG(ERROR) << __func__ << ": Failed to initialize TPM state: "
               << GetErrorString(result);
    return result;
  }
  // Warn about various unexpected conditions.
  if (!(*tpm_state)->WasShutdownOrderly()) {
    LOG(WARNING) << __func__
                 << ": WARNING: The last TPM shutdown was not orderly.";
  }
  if ((*tpm_state)->IsInLockout()) {
    LOG(WARNING) << __func__ << ": WARNING: The TPM is currently in lockout.";
  }

  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CheckState() {
  TPM_RC result;
  std::unique_ptr<TpmState> tpm_state;

  result = TpmBasicInit(&tpm_state);

  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Failed TPM basic init: " << GetErrorString(result);
    return result;
  }

  if (tpm_state->IsPlatformHierarchyEnabled())
    LOG(WARNING) << __func__ << ": Platform Hierarchy Enabled!";

  if (!tpm_state->IsStorageHierarchyEnabled())
    LOG(WARNING) << __func__ << ": Storage Hierarchy Disabled!";

  if (!tpm_state->IsEndorsementHierarchyEnabled())
    LOG(WARNING) << __func__ << ": Endorsement Hierarchy Disabled!";

  LOG(INFO) << __func__ << ": TPM State verified.";
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::InitializeTpm() {
  TPM_RC result;
  std::unique_ptr<TpmState> tpm_state;

  result = TpmBasicInit(&tpm_state);
  if (result) {
    LOG(ERROR) << __func__
               << ": Failed TPM basic init: " << GetErrorString(result);
    return result;
  }

  // We expect the firmware has already locked down the platform hierarchy. If
  // it hasn't, do it now.
  if (tpm_state->IsPlatformHierarchyEnabled()) {
    std::unique_ptr<AuthorizationDelegate> empty_password(
        factory_.GetPasswordAuthorization(""));
    result = SetHierarchyAuthorization(TPM_RH_PLATFORM, kPlatformPassword,
                                       empty_password.get());
    if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
      // Most likely the platform password has already been set.
      result = TPM_RC_SUCCESS;
    }
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Failed to set hierarchy authorization: "
                 << GetErrorString(result);
      return result;
    }
    result = AllocatePCR(kPlatformPassword);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__
                 << ": Failed to alocate PCR: " << GetErrorString(result);
      return result;
    }
    std::unique_ptr<AuthorizationDelegate> authorization(
        factory_.GetPasswordAuthorization(kPlatformPassword));
    result = DisablePlatformHierarchy(authorization.get());
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Failed to disable platform hierarchy: "
                 << GetErrorString(result);
      return result;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::AllocatePCR(const std::string& platform_password) {
  TPM_RC result;
  TPMI_YES_NO more_data = YES;
  TPMS_CAPABILITY_DATA capability_data;
  result = factory_.GetTpm()->GetCapabilitySync(
      TPM_CAP_PCRS, 0 /*property (not used)*/, 1 /*property_count*/, &more_data,
      &capability_data, nullptr /*authorization_delegate*/);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error querying PCRs: " << GetErrorString(result);
    return result;
  }
  TPML_PCR_SELECTION& existing_pcrs = capability_data.data.assigned_pcr;
  bool sha256_needed = true;
  std::vector<TPMI_ALG_HASH> pcr_banks_to_remove;
  for (uint32_t i = 0; i < existing_pcrs.count; ++i) {
    if (existing_pcrs.pcr_selections[i].hash == TPM_ALG_SHA256) {
      sha256_needed = false;
    } else {
      pcr_banks_to_remove.push_back(existing_pcrs.pcr_selections[i].hash);
    }
  }
  if (!sha256_needed && pcr_banks_to_remove.empty()) {
    return TPM_RC_SUCCESS;
  }
  TPML_PCR_SELECTION pcr_allocation;
  memset(&pcr_allocation, 0, sizeof(pcr_allocation));
  if (sha256_needed) {
    pcr_allocation.pcr_selections[pcr_allocation.count].hash = TPM_ALG_SHA256;
    pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
        PCR_SELECT_MIN;
    for (int i = 0; i < PCR_SELECT_MIN; ++i) {
      pcr_allocation.pcr_selections[pcr_allocation.count].pcr_select[i] = 0xff;
    }
    ++pcr_allocation.count;
  }
  for (auto pcr_type : pcr_banks_to_remove) {
    pcr_allocation.pcr_selections[pcr_allocation.count].hash = pcr_type;
    pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
        PCR_SELECT_MAX;
    ++pcr_allocation.count;
  }
  std::unique_ptr<AuthorizationDelegate> platform_delegate(
      factory_.GetPasswordAuthorization(platform_password));
  TPMI_YES_NO allocation_success;
  uint32_t max_pcr;
  uint32_t size_needed;
  uint32_t size_available;
  result = factory_.GetTpm()->PCR_AllocateSync(
      TPM_RH_PLATFORM, NameFromHandle(TPM_RH_PLATFORM), pcr_allocation,
      &allocation_success, &max_pcr, &size_needed, &size_available,
      platform_delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error allocating PCRs: " << GetErrorString(result);
    return result;
  }
  if (allocation_success != YES) {
    LOG(ERROR) << __func__ << ": PCR allocation unsuccessful.";
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::PrepareForPinWeaver() {
  return CreateCsmeSaltingKey();
}

TPM_RC TpmUtilityImpl::PrepareForOwnership() {
  std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
  TPM_RC result = tpm_state->Initialize();
  if (result) {
    LOG(ERROR) << __func__
               << ": Error initializing state: " << GetErrorString(result);
    return result;
  }
  if (tpm_state->IsOwnerPasswordSet()) {
    VLOG(1) << __func__ << ": Nothing to do. Owner password is already set.";
    return TPM_RC_SUCCESS;
  }
  result = CreateStorageAndSaltingKeys();
  LOG_IF(INFO, result == TPM_RC_SUCCESS) << __func__ << ": done.";
  return result;
}

TPM_RC TpmUtilityImpl::InitializeOwnerForCsme() {
  // For cr50 case, we don't have to create salting key for CSME.
  if (IsCr50()) {
    return true;
  }
  uint8_t protocol_version = 0;
  TPM_RC result = PinWeaverIsSupported(0, &protocol_version);
  // If pinweaver is not supported at all, skip the initialization.
  if (result) {
    return true;
  }
  result = CreateCsmeSaltingKey();
  if (result) {
    LOG(WARNING) << __func__ << ": Failed to create CSME Salting Key:"
                 << GetErrorString(result);
    return false;
  }
  csme::MeiClientFactory mei_client_factory;
  csme::PinWeaverProvisionClient client(&mei_client_factory);
  if (!client.InitOwner()) {
    LOG(WARNING) << "Failed to call `InitOwner()`";
    return false;
  }
  return true;
}

TPM_RC TpmUtilityImpl::CreateStorageAndSaltingKeys() {
  // Perform tasks that have to be done when owner auth is still empty.
  TPM_RC result = InitializeOwnerForCsme();
  if (result != TPM_RC_SUCCESS) {
    // By design, don't hard-fail the TPM initialization flow.
    LOG(WARNING) << __func__ << ": Failed to initialize owner for csme.";
  }

  // First we set the storage hierarchy authorization to the well know default
  // password.
  result = SetKnownOwnerPassword(kWellKnownPassword);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error injecting known password: "
               << GetErrorString(result);
    return result;
  }

  result = CreateStorageRootKeys(kWellKnownPassword);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error creating SRKs: " << GetErrorString(result);
    return result;
  }

  result = CreateSaltingKey(kWellKnownPassword);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error creating salting key: " << GetErrorString(result);
    return result;
  }

  return result;
}

TPM_RC TpmUtilityImpl::TakeOwnership(const std::string& owner_password,
                                     const std::string& endorsement_password,
                                     const std::string& lockout_password) {
  TPM_RC result = CreateStorageAndSaltingKeys();
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
  result = session->StartUnboundSession(true, true);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error initializing AuthorizationSession: "
               << GetErrorString(result);
    return result;
  }
  std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
  result = tpm_state->Initialize();
  if (result != TPM_RC_SUCCESS) {
    return result;
  }

  session->SetEntityAuthorizationValue("");
  if (!tpm_state->IsEndorsementPasswordSet()) {
    session->SetFutureAuthorizationValue(endorsement_password);
    result = SetHierarchyAuthorization(TPM_RH_ENDORSEMENT, endorsement_password,
                                       session->GetDelegate());
    if (result) {
      LOG(ERROR) << __func__ << ": Failed to set hierarchy authorization, "
                 << "endorsement password not set: " << GetErrorString(result);
      return result;
    }
  }
  if (!tpm_state->IsLockoutPasswordSet()) {
    session->SetFutureAuthorizationValue(lockout_password);
    result = SetHierarchyAuthorization(TPM_RH_LOCKOUT, lockout_password,
                                       session->GetDelegate());
    if (result) {
      LOG(ERROR) << __func__ << ": Failed to set hierarchy authorization, "
                 << "lockout password not set: " << GetErrorString(result);
      return result;
    }
  }
  // We take ownership of owner hierarchy last.
  session->SetEntityAuthorizationValue(kWellKnownPassword);
  session->SetFutureAuthorizationValue(owner_password);
  result = SetHierarchyAuthorization(TPM_RH_OWNER, owner_password,
                                     session->GetDelegate());
  if ((GetFormatOneError(result) == TPM_RC_BAD_AUTH) &&
      tpm_state->IsOwnerPasswordSet()) {
    LOG(WARNING) << __func__
                 << ": Error changing owner password. This probably because "
                 << "ownership is already taken.";
    return TPM_RC_SUCCESS;
  } else if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error changing owner authorization: "
               << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::StirRandom(const std::string& entropy_data,
                                  AuthorizationDelegate* delegate) {
  std::string digest = crypto::SHA256HashString(entropy_data);
  TPM2B_SENSITIVE_DATA random_bytes = Make_TPM2B_SENSITIVE_DATA(digest);
  return factory_.GetTpm()->StirRandomSync(random_bytes, delegate);
}

TPM_RC TpmUtilityImpl::GenerateRandom(size_t num_bytes,
                                      AuthorizationDelegate* delegate,
                                      std::string* random_data) {
  CHECK(random_data);
  size_t bytes_left = num_bytes;
  random_data->clear();
  TPM_RC rc;
  TPM2B_DIGEST digest;
  while (bytes_left > 0) {
    rc = factory_.GetTpm()->GetRandomSync(bytes_left, &digest, delegate);
    if (rc) {
      LOG(ERROR) << __func__ << ": Error getting random data from tpm.";
      return rc;
    }
    random_data->append(StringFrom_TPM2B_DIGEST(digest));
    bytes_left -= digest.size;
  }
  CHECK_EQ(random_data->size(), num_bytes);
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ExtendPCR(int pcr_index,
                                 const std::string& extend_data,
                                 AuthorizationDelegate* delegate) {
  if (pcr_index < 0 || pcr_index >= IMPLEMENTATION_PCR) {
    LOG(ERROR) << __func__ << ": Using a PCR index that isn't implemented.";
    return TPM_RC_FAILURE;
  }
  TPM_HANDLE pcr_handle = HR_PCR + pcr_index;
  std::string pcr_name = NameFromHandle(pcr_handle);
  TPML_DIGEST_VALUES digests;
  digests.count = 1;
  digests.digests[0].hash_alg = TPM_ALG_SHA256;
  crypto::SHA256HashString(extend_data, digests.digests[0].digest.sha256,
                           crypto::kSHA256Length);
  std::unique_ptr<AuthorizationDelegate> empty_password_delegate =
      factory_.GetPasswordAuthorization("");
  if (!delegate) {
    delegate = empty_password_delegate.get();
  }
  return factory_.GetTpm()->PCR_ExtendSync(pcr_handle, pcr_name, digests,
                                           delegate);
}

TPM_RC TpmUtilityImpl::ExtendPCRForCSME(int pcr_index,
                                        const std::string& extend_data) {
  // If csme is not applicable, just pretend it to be successful.
  if (GetPinwWeaverBackendType() != PinWeaverBackendType::kCsme) {
    return TPM_RC_SUCCESS;
  }

  csme::MeiClientFactory mei_client_factory;
  csme::PinWeaverCoreClient client(&mei_client_factory);
  const std::string digest = crypto::SHA256HashString(extend_data);
  if (!client.ExtendPcr(pcr_index, TPM_ALG_SHA256, digest)) {
    LOG(ERROR) << __func__ << ": Failed to extend PCR " << pcr_index
               << " for CSME.";
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ReadPCR(int pcr_index, std::string* pcr_value) {
  TPML_PCR_SELECTION pcr_select_in;
  uint32_t pcr_update_counter;
  TPML_PCR_SELECTION pcr_select_out;
  TPML_DIGEST pcr_values;
  // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec
  // Part 2 (Section 10.5 - PCR structures).
  uint8_t pcr_select_index = pcr_index / 8;
  uint8_t pcr_select_byte = 1 << (pcr_index % 8);
  memset(&pcr_select_in, 0, sizeof(pcr_select_in));
  pcr_select_in.count = 1;
  pcr_select_in.pcr_selections[0].hash = TPM_ALG_SHA256;
  pcr_select_in.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
  pcr_select_in.pcr_selections[0].pcr_select[pcr_select_index] =
      pcr_select_byte;

  TPM_RC rc =
      factory_.GetTpm()->PCR_ReadSync(pcr_select_in, &pcr_update_counter,
                                      &pcr_select_out, &pcr_values, nullptr);
  if (rc) {
    LOG(INFO) << __func__
              << ": Error trying to read a pcr: " << GetErrorString(rc);
    return rc;
  }
  if (pcr_select_out.count != 1 ||
      pcr_select_out.pcr_selections[0].sizeof_select < (pcr_select_index + 1) ||
      pcr_select_out.pcr_selections[0].pcr_select[pcr_select_index] !=
          pcr_select_byte) {
    LOG(ERROR) << __func__ << ": TPM did not return the requested PCR";
    return TPM_RC_FAILURE;
  }
  if (pcr_values.count < 1U) {
    LOG(ERROR) << __func__ << ": Unexpected TPM reply";
    return TPM_RC_FAILURE;
  }
  pcr_value->assign(StringFrom_TPM2B_DIGEST(pcr_values.digests[0]));
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ReadPCRFromCSME(int pcr_index, std::string* pcr_value) {
  csme::MeiClientFactory mei_client_factory;
  csme::PinWeaverCoreClient client(&mei_client_factory);
  uint32_t pcr_index_out, hash_alg_out;
  if (!client.ReadPcr(pcr_index, TPM_ALG_SHA256, &pcr_index_out, &hash_alg_out,
                      pcr_value)) {
    LOG(ERROR) << __func__ << ": Failed to read PCR " << pcr_index
               << " from CSME.";
    return TPM_RC_FAILURE;
  }
  if (pcr_index != pcr_index_out) {
    LOG(ERROR) << __func__
               << ": Output PCR index mismatched: input=" << pcr_index
               << ", output=" << pcr_index_out << ".";
    return TPM_RC_FAILURE;
  }
  if (hash_alg_out != TPM_ALG_SHA256) {
    LOG(ERROR) << __func__ << ": Unsupported algorithm ID: " << hash_alg_out
               << ".";
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::AsymmetricEncrypt(TPM_HANDLE key_handle,
                                         TPM_ALG_ID scheme,
                                         TPM_ALG_ID hash_alg,
                                         const std::string& plaintext,
                                         AuthorizationDelegate* delegate,
                                         std::string* ciphertext) {
  TPMT_RSA_DECRYPT in_scheme;
  if (hash_alg == TPM_ALG_NULL) {
    hash_alg = TPM_ALG_SHA256;
  }
  if (scheme == TPM_ALG_RSAES) {
    in_scheme.scheme = TPM_ALG_RSAES;
  } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) {
    in_scheme.scheme = TPM_ALG_OAEP;
    in_scheme.details.oaep.hash_alg = hash_alg;
  } else {
    LOG(ERROR) << __func__ << ": Invalid encryption scheme used.";
    return SAPI_RC_BAD_PARAMETER;
  }

  TPMT_PUBLIC public_area;
  TPM_RC result = GetKeyPublicArea(key_handle, &public_area);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
    return result;
  } else if (public_area.type != TPM_ALG_RSA) {
    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
    return SAPI_RC_BAD_PARAMETER;
  } else if ((public_area.object_attributes & kDecrypt) == 0) {
    LOG(ERROR) << __func__ << ": Key handle given is not a decryption key";
    return SAPI_RC_BAD_PARAMETER;
  }
  if ((public_area.object_attributes & kRestricted) != 0) {
    LOG(ERROR) << __func__
               << ": Cannot use RSAES for encryption with a restricted key";
    return SAPI_RC_BAD_PARAMETER;
  }
  std::string key_name;
  result = ComputeKeyName(public_area, &key_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
    return result;
  }

  TPM2B_DATA label;
  label.size = 0;
  TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(plaintext);
  TPM2B_PUBLIC_KEY_RSA out_message;
  result = factory_.GetTpm()->RSA_EncryptSync(key_handle, key_name, in_message,
                                              in_scheme, label, &out_message,
                                              delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error performing RSA encrypt: " << GetErrorString(result);
    return result;
  }
  ciphertext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::AsymmetricDecrypt(TPM_HANDLE key_handle,
                                         TPM_ALG_ID scheme,
                                         TPM_ALG_ID hash_alg,
                                         const std::string& ciphertext,
                                         AuthorizationDelegate* delegate,
                                         std::string* plaintext) {
  TPMT_RSA_DECRYPT in_scheme;
  if (scheme == TPM_ALG_RSAES || scheme == TPM_ALG_NULL) {
    in_scheme.scheme = scheme;
  } else if (scheme == TPM_ALG_OAEP) {
    in_scheme.scheme = TPM_ALG_OAEP;
    if (hash_alg == TPM_ALG_NULL) {
      hash_alg = TPM_ALG_SHA256;
    }
    in_scheme.details.oaep.hash_alg = hash_alg;
  } else {
    LOG(ERROR) << __func__ << ": Invalid decryption scheme used.";
    return SAPI_RC_BAD_PARAMETER;
  }
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  TPMT_PUBLIC public_area;
  result = GetKeyPublicArea(key_handle, &public_area);
  if (result) {
    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
    return result;
  } else if (public_area.type != TPM_ALG_RSA) {
    LOG(ERROR) << __func__ << ": Key handle given is not an RSA key";
    return SAPI_RC_BAD_PARAMETER;
  } else if ((public_area.object_attributes & kDecrypt) == 0) {
    LOG(ERROR) << __func__ << ": Key handle given is not a decryption key";
    return SAPI_RC_BAD_PARAMETER;
  }
  if ((public_area.object_attributes & kRestricted) != 0) {
    LOG(ERROR) << __func__
               << ": Cannot use RSAES for encryption with a restricted key";
    return SAPI_RC_BAD_PARAMETER;
  }
  std::string key_name;
  result = ComputeKeyName(public_area, &key_name);
  if (result) {
    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
    return result;
  }

  TPM2B_DATA label;
  label.size = 0;
  TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(ciphertext);
  TPM2B_PUBLIC_KEY_RSA out_message;
  result = factory_.GetTpm()->RSA_DecryptSync(key_handle, key_name, in_message,
                                              in_scheme, label, &out_message,
                                              delegate);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error performing RSA decrypt: " << GetErrorString(result);
    return result;
  }
  plaintext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ECDHZGen(TPM_HANDLE key_handle,
                                const TPM2B_ECC_POINT& in_point,
                                AuthorizationDelegate* delegate,
                                TPM2B_ECC_POINT* out_point) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  TPMT_PUBLIC public_area;
  result = GetKeyPublicArea(key_handle, &public_area);
  if (result) {
    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle
               << ", error: " << GetErrorString(result);
    return result;
  } else if (public_area.type != TPM_ALG_ECC) {
    LOG(ERROR) << __func__ << ": Key handle given is not an ECC key";
    return SAPI_RC_BAD_PARAMETER;
  } else if ((public_area.object_attributes & kDecrypt) == 0) {
    LOG(ERROR) << __func__ << ": Key handle given is not a decryption key";
    return SAPI_RC_BAD_PARAMETER;
  }
  if ((public_area.object_attributes & kRestricted) != 0) {
    LOG(ERROR) << __func__
               << ": Cannot use ECDH for ZGen with a restricted key";
    return SAPI_RC_BAD_PARAMETER;
  }
  std::string key_name;
  result = ComputeKeyName(public_area, &key_name);
  if (result) {
    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle
               << ", error: " << GetErrorString(result);
    return result;
  }

  result = factory_.GetTpm()->ECDH_ZGenSync(key_handle, key_name, in_point,
                                            out_point, delegate);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error performing ECDH ZGen: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::RawSign(TPM_HANDLE key_handle,
                               TPM_ALG_ID scheme,
                               TPM_ALG_ID hash_alg,
                               const std::string& plaintext,
                               bool generate_hash,
                               AuthorizationDelegate* delegate,
                               TPMT_SIGNATURE* auth) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }

  // Get public information of the key handle
  TPMT_PUBLIC public_area;
  result = GetKeyPublicArea(key_handle, &public_area);
  if (result) {
    LOG(ERROR) << __func__ << ": Error finding public area for: " << key_handle;
    return result;
  } else if (public_area.type != TPM_ALG_RSA &&
             public_area.type != TPM_ALG_ECC) {
    LOG(ERROR) << __func__
               << ": Key handle given is not a supported key (RSA, ECC)";
    return SAPI_RC_BAD_PARAMETER;
  } else if ((public_area.object_attributes & kSign) == 0) {
    LOG(ERROR) << __func__ << ": Key handle given is not a signging key";
    return SAPI_RC_BAD_PARAMETER;
  } else if ((public_area.object_attributes & kRestricted) != 0) {
    LOG(ERROR) << __func__ << ": Key handle references a restricted key";
    return SAPI_RC_BAD_PARAMETER;
  }

  // Default scheme is TPM_ALG_RSASSA
  if (scheme == TPM_ALG_NULL) {
    scheme = TPM_ALG_RSASSA;
  }

  // Default hash algorithm is SHA256, except TPM_ALG_RSASSA
  // For RSASSA, we allow TPM_ALG_NULL since TPMs can support padding-only
  // scheme for RSASSA which is indicated by passing TPM_ALG_NULL as a hashing
  // algorithm to TPM2_Sign.
  if (scheme != TPM_ALG_RSASSA && hash_alg == TPM_ALG_NULL) {
    hash_alg = TPM_ALG_SHA256;
  }

  // Check key type and scheme.
  std::function<std::string(const TPMT_SIGNATURE&)> unpack_helper;
  if (public_area.type == TPM_ALG_RSA) {
    if (scheme != TPM_ALG_RSAPSS && scheme != TPM_ALG_RSASSA) {
      LOG(ERROR) << __func__ << ": Invalid signing scheme used for RSA key.";
      return SAPI_RC_BAD_PARAMETER;
    }
  } else if (public_area.type == TPM_ALG_ECC) {
    if (scheme != TPM_ALG_ECDSA) {
      LOG(ERROR) << __func__ << ": Invalid signing scheme used for ECC key.";
      return SAPI_RC_BAD_PARAMETER;
    }
  }

  // Fill the checked parameters
  TPMT_SIG_SCHEME in_scheme;
  in_scheme.scheme = scheme;
  in_scheme.details.any.hash_alg = hash_alg;

  // Compute key name
  std::string key_name;
  result = ComputeKeyName(public_area, &key_name);
  if (result) {
    LOG(ERROR) << __func__ << ": Error computing key name for: " << key_handle;
    return result;
  }

  // Call TPM
  std::string digest =
      generate_hash ? HashString(plaintext, hash_alg) : plaintext;
  if (digest.size() > sizeof(TPMU_HA)) {
    LOG(ERROR) << __func__
               << ": digest is too long for TPM signing command. Input length: "
               << digest.size() << ", the limit: " << sizeof(TPMU_HA);
    return SAPI_RC_BAD_PARAMETER;
  }

  TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest);
  TPMT_TK_HASHCHECK validation;
  validation.tag = TPM_ST_HASHCHECK;
  validation.hierarchy = TPM_RH_NULL;
  validation.digest.size = 0;
  result = factory_.GetTpm()->SignSync(key_handle, key_name, tpm_digest,
                                       in_scheme, validation, auth, delegate);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error signing digest: " << GetErrorString(result);
    return result;
  }

  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::Sign(TPM_HANDLE key_handle,
                            TPM_ALG_ID scheme,
                            TPM_ALG_ID hash_alg,
                            const std::string& plaintext,
                            bool generate_hash,
                            AuthorizationDelegate* delegate,
                            std::string* signature) {
  TPM_RC result;
  TPMT_SIGNATURE signature_out;

  // Default scheme is TPM_ALG_RSASSA
  if (scheme == TPM_ALG_NULL)
    scheme = TPM_ALG_RSASSA;

  result = RawSign(key_handle, scheme, hash_alg, plaintext, generate_hash,
                   delegate, &signature_out);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error from RawSign(): " << GetErrorString(result);
    return result;
  }

  // Simply check scheme and parse the output from TPM.
  switch (scheme) {
    case TPM_ALG_RSAPSS:
      *signature =
          StringFrom_TPM2B_PUBLIC_KEY_RSA(signature_out.signature.rsapss.sig);
      break;
    case TPM_ALG_RSASSA:
      *signature =
          StringFrom_TPM2B_PUBLIC_KEY_RSA(signature_out.signature.rsassa.sig);
      break;
    case TPM_ALG_ECDSA:
      Serialize_TPMT_SIGNATURE(signature_out, signature);
      break;
    default:
      LOG(ERROR) << __func__ << ": Invalid signing scheme used for the key.";
      return SAPI_RC_BAD_PARAMETER;
  }

  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CertifyCreation(TPM_HANDLE key_handle,
                                       const std::string& creation_blob) {
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_hash;
  TPMT_TK_CREATION creation_ticket;
  if (!factory_.GetBlobParser()->ParseCreationBlob(
          creation_blob, &creation_data, &creation_hash, &creation_ticket)) {
    LOG(ERROR) << __func__ << ": Error parsing CreationBlob.";
    return SAPI_RC_BAD_PARAMETER;
  }
  TPM2B_DATA qualifying_data;
  qualifying_data.size = 0;
  TPMT_SIG_SCHEME in_scheme;
  in_scheme.scheme = TPM_ALG_NULL;
  TPM2B_ATTEST certify_info;
  TPMT_SIGNATURE signature;
  std::unique_ptr<AuthorizationDelegate> delegate =
      factory_.GetPasswordAuthorization("");
  TPM_RC result = factory_.GetTpm()->CertifyCreationSync(
      TPM_RH_NULL, "", key_handle, "", qualifying_data, creation_hash,
      in_scheme, creation_ticket, &certify_info, &signature, delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error certifying key creation: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ChangeKeyAuthorizationData(
    TPM_HANDLE key_handle,
    const std::string& new_password,
    AuthorizationDelegate* delegate,
    std::string* key_blob) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  std::string key_name;
  std::string parent_name;
  result = GetKeyName(key_handle, &key_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for key_handle: "
               << GetErrorString(result);
    return result;
  }
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
               << GetErrorString(result);
    return result;
  }
  TPM2B_AUTH new_auth = Make_TPM2B_DIGEST(new_password);
  TPM2B_PRIVATE new_private_data;
  new_private_data.size = 0;
  result = factory_.GetTpm()->ObjectChangeAuthSync(
      key_handle, key_name, kStorageRootKey, parent_name, new_auth,
      &new_private_data, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error changing object authorization data: "
               << GetErrorString(result);
    return result;
  }
  if (key_blob) {
    TPMT_PUBLIC public_data;
    result = GetKeyPublicArea(key_handle, &public_data);
    if (result != TPM_RC_SUCCESS) {
      return result;
    }
    if (!factory_.GetBlobParser()->SerializeKeyBlob(
            Make_TPM2B_PUBLIC(public_data), new_private_data, key_blob)) {
      return SAPI_RC_BAD_TCTI_STRUCTURE;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ImportRSAKey(AsymmetricKeyUsage key_type,
                                    const std::string& modulus,
                                    uint32_t public_exponent,
                                    const std::string& prime_factor,
                                    const std::string& password,
                                    AuthorizationDelegate* delegate,
                                    std::string* key_blob) {
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
  public_area.parameters.rsa_detail.key_bits = modulus.size() * 8;
  public_area.parameters.rsa_detail.exponent = public_exponent;
  public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(modulus);

  TPMT_SENSITIVE in_sensitive;
  in_sensitive.sensitive_type = TPM_ALG_RSA;
  in_sensitive.sensitive.rsa = Make_TPM2B_PRIVATE_KEY_RSA(prime_factor);

  return ImportKeyInner(key_type, public_area, in_sensitive, password, delegate,
                        key_blob);
}

TPM_RC TpmUtilityImpl::ImportECCKey(AsymmetricKeyUsage key_type,
                                    TPMI_ECC_CURVE curve_id,
                                    const std::string& public_point_x,
                                    const std::string& public_point_y,
                                    const std::string& private_value,
                                    const std::string& password,
                                    AuthorizationDelegate* delegate,
                                    std::string* key_blob) {
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
  public_area.parameters.ecc_detail.curve_id = curve_id;
  public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER(public_point_x);
  public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER(public_point_y);

  TPMT_SENSITIVE in_sensitive;
  in_sensitive.sensitive_type = TPM_ALG_ECC;
  in_sensitive.sensitive.ecc = Make_TPM2B_ECC_PARAMETER(private_value);

  return ImportKeyInner(key_type, public_area, in_sensitive, password, delegate,
                        key_blob);
}

TPM_RC TpmUtilityImpl::ImportKeyInner(AsymmetricKeyUsage key_type,
                                      TPMT_PUBLIC public_area,
                                      TPMT_SENSITIVE in_sensitive,
                                      const std::string& password,
                                      AuthorizationDelegate* delegate,
                                      std::string* key_blob) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }

  std::string parent_name;
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for SRK: "
               << GetErrorString(result);
    return result;
  }

  public_area.object_attributes = kUserWithAuth | kNoDA;
  switch (key_type) {
    case AsymmetricKeyUsage::kDecryptKey:
      public_area.object_attributes |= kDecrypt;
      break;
    case AsymmetricKeyUsage::kSignKey:
      public_area.object_attributes |= kSign;
      break;
    case AsymmetricKeyUsage::kDecryptAndSignKey:
      public_area.object_attributes |= (kSign | kDecrypt);
      break;
  }

  TPM2B_ENCRYPTED_SECRET in_sym_seed = Make_TPM2B_ENCRYPTED_SECRET("");

  TPMT_SYM_DEF_OBJECT symmetric_alg;
  symmetric_alg.algorithm = TPM_ALG_AES;
  symmetric_alg.key_bits.aes = kAesKeySize * 8;
  symmetric_alg.mode.aes = TPM_ALG_CFB;

  in_sensitive.auth_value = Make_TPM2B_DIGEST(password);
  in_sensitive.seed_value = Make_TPM2B_DIGEST("");

  TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area);

  TPM2B_DATA encryption_key;
  encryption_key.size = kAesKeySize;
  CHECK_EQ(RAND_bytes(encryption_key.buffer, encryption_key.size), 1)
      << "Error generating a cryptographically random AES Key.";
  TPM2B_PRIVATE private_data;
  result = EncryptPrivateData(in_sensitive, public_area, &private_data,
                              &encryption_key);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error creating encrypted private struct: "
               << GetErrorString(result);
    return result;
  }

  TPM2B_PRIVATE tpm_private_data;
  tpm_private_data.size = 0;
  result = factory_.GetTpm()->ImportSync(
      kStorageRootKey, parent_name, encryption_key, public_data, private_data,
      in_sym_seed, symmetric_alg, &tpm_private_data, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error importing key: " << GetErrorString(result);
    return result;
  }

  if (key_blob) {
    if (!factory_.GetBlobParser()->SerializeKeyBlob(
            public_data, tpm_private_data, key_blob)) {
      return SAPI_RC_BAD_TCTI_STRUCTURE;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CreateRSAKeyPair(
    AsymmetricKeyUsage key_type,
    int modulus_bits,
    uint32_t public_exponent,
    const std::string& password,
    const std::string& policy_digest,
    bool use_only_policy_authorization,
    const std::vector<uint32_t>& creation_pcr_indexes,
    AuthorizationDelegate* delegate,
    std::string* key_blob,
    std::string* creation_blob) {
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
  public_area.parameters.rsa_detail.key_bits = modulus_bits;
  public_area.parameters.rsa_detail.exponent = public_exponent;

  return CreateKeyPairInner(key_type, public_area, password, policy_digest,
                            use_only_policy_authorization, creation_pcr_indexes,
                            delegate, key_blob, creation_blob);
}

TPM_RC TpmUtilityImpl::CreateECCKeyPair(
    AsymmetricKeyUsage key_type,
    TPMI_ECC_CURVE curve_id,
    const std::string& password,
    const std::string& policy_digest,
    bool use_only_policy_authorization,
    const std::vector<uint32_t>& creation_pcr_indexes,
    AuthorizationDelegate* delegate,
    std::string* key_blob,
    std::string* creation_blob) {
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
  public_area.parameters.ecc_detail.curve_id = curve_id;

  return CreateKeyPairInner(key_type, public_area, password, policy_digest,
                            use_only_policy_authorization, creation_pcr_indexes,
                            delegate, key_blob, creation_blob);
}

TPM_RC TpmUtilityImpl::CreateKeyPairInner(
    AsymmetricKeyUsage key_type,
    TPMT_PUBLIC public_area,
    const std::string& password,
    const std::string& policy_digest,
    bool use_only_policy_authorization,
    const std::vector<uint32_t>& creation_pcr_indexes,
    AuthorizationDelegate* delegate,
    std::string* key_blob,
    std::string* creation_blob) {
  CHECK(key_blob);

  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }

  std::string parent_name;
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for SRK: "
               << GetErrorString(result);
    return result;
  }

  // Fill the rest part of public area of the key
  // Notice that the |object_attributes| field may be prefilled, so just add
  // new setting by OR, but don't overwrite it
  public_area.object_attributes |=
      (kSensitiveDataOrigin | kUserWithAuth | kNoDA);
  switch (key_type) {
    case AsymmetricKeyUsage::kDecryptKey:
      public_area.object_attributes |= kDecrypt;
      break;
    case AsymmetricKeyUsage::kSignKey:
      public_area.object_attributes |= kSign;
      if (public_area.type == TPM_ALG_RSA &&
          !SupportsPaddingOnlySigningScheme()) {
        public_area.object_attributes |= kDecrypt;
      }
      break;
    case AsymmetricKeyUsage::kDecryptAndSignKey:
      public_area.object_attributes |= (kSign | kDecrypt);
      break;
  }
  public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
  if (use_only_policy_authorization && !policy_digest.empty()) {
    public_area.object_attributes |= kAdminWithPolicy;
    public_area.object_attributes &= (~kUserWithAuth);
  }

  TPML_PCR_SELECTION creation_pcrs = {};
  if (creation_pcr_indexes.empty()) {
    creation_pcrs.count = 0;
  } else {
    creation_pcrs.count = 1;
    creation_pcrs.pcr_selections[0].hash = TPM_ALG_SHA256;
    creation_pcrs.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
    for (uint32_t creation_pcr_index : creation_pcr_indexes) {
      if (creation_pcr_index >= 8 * PCR_SELECT_MIN) {
        LOG(ERROR) << __func__
                   << ": Creation PCR index is not within the allocated bank.";
        return SAPI_RC_BAD_PARAMETER;
      }
      creation_pcrs.pcr_selections[0].pcr_select[creation_pcr_index / 8] |=
          1 << (creation_pcr_index % 8);
    }
  }

  // allow to use this key with `password`
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST(password);
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM2B_SENSITIVE_CREATE sensitive_create =
      Make_TPM2B_SENSITIVE_CREATE(sensitive);

  // use empty outside_info
  TPM2B_DATA outside_info = Make_TPM2B_DATA("");

  // returned data
  TPM2B_PUBLIC out_public;
  out_public.size = 0;
  TPM2B_PRIVATE out_private;
  out_private.size = 0;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_hash;
  TPMT_TK_CREATION creation_ticket;

  result = factory_.GetTpm()->CreateSync(
      kStorageRootKey, parent_name, sensitive_create,
      Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
      &out_public, &creation_data, &creation_hash, &creation_ticket, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error creating key: " << GetErrorString(result);
    return result;
  }

  // serialize the output
  if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private,
                                                  key_blob)) {
    return SAPI_RC_BAD_TCTI_STRUCTURE;
  }
  if (creation_blob) {
    if (!factory_.GetBlobParser()->SerializeCreationBlob(
            creation_data, creation_hash, creation_ticket, creation_blob)) {
      return SAPI_RC_BAD_TCTI_STRUCTURE;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::LoadKey(const std::string& key_blob,
                               AuthorizationDelegate* delegate,
                               TPM_HANDLE* key_handle) {
  CHECK(key_handle);
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  std::string parent_name;
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error getting parent key name: " << GetErrorString(result);
    return result;
  }
  TPM2B_PUBLIC in_public;
  TPM2B_PRIVATE in_private;
  if (!factory_.GetBlobParser()->ParseKeyBlob(key_blob, &in_public,
                                              &in_private)) {
    return SAPI_RC_BAD_TCTI_STRUCTURE;
  }
  TPM2B_NAME key_name;
  key_name.size = 0;
  result =
      factory_.GetTpm()->LoadSync(kStorageRootKey, parent_name, in_private,
                                  in_public, key_handle, &key_name, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error loading key: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::LoadRSAPublicKey(AsymmetricKeyUsage key_type,
                                        TPM_ALG_ID scheme,
                                        TPM_ALG_ID hash_alg,
                                        const std::string& modulus,
                                        uint32_t public_exponent,
                                        AuthorizationDelegate* delegate,
                                        TPM_HANDLE* key_handle) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
  switch (key_type) {
    case AsymmetricKeyUsage::kDecryptKey:
      public_area.object_attributes |= kDecrypt;
      if (scheme == TPM_ALG_NULL || scheme == TPM_ALG_OAEP) {
        public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_OAEP;
        public_area.parameters.rsa_detail.scheme.details.oaep.hash_alg =
            hash_alg;
      } else if (scheme == TPM_ALG_RSAES) {
        public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_RSAES;
      } else {
        LOG(ERROR) << __func__ << ": Invalid encryption scheme used.";
        return SAPI_RC_BAD_PARAMETER;
      }
      break;
    case AsymmetricKeyUsage::kSignKey:
      public_area.object_attributes |= kSign;
      if (scheme == TPM_ALG_NULL || scheme == TPM_ALG_RSASSA) {
        public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_RSASSA;
        public_area.parameters.rsa_detail.scheme.details.rsassa.hash_alg =
            hash_alg;
      } else if (scheme == TPM_ALG_RSAPSS) {
        public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_RSAPSS;
        public_area.parameters.rsa_detail.scheme.details.rsapss.hash_alg =
            hash_alg;
      } else {
        LOG(ERROR) << __func__ << ": Invalid signing scheme used.";
        return SAPI_RC_BAD_PARAMETER;
      }
      break;
    case AsymmetricKeyUsage::kDecryptAndSignKey:
      public_area.object_attributes |= (kSign | kDecrypt);
      // Note: The specs require the scheme to be TPM_ALG_NULL when the key is
      // both signing and decrypting.
      if (scheme != TPM_ALG_NULL) {
        LOG(ERROR) << __func__ << ": Scheme has to be null.";
        return SAPI_RC_BAD_PARAMETER;
      }
      if (hash_alg != TPM_ALG_NULL) {
        LOG(ERROR) << __func__ << ": Hashing algorithm has to be null.";
        return SAPI_RC_BAD_PARAMETER;
      }
      break;
  }
  public_area.parameters.rsa_detail.key_bits = modulus.size() * 8;
  public_area.parameters.rsa_detail.exponent = public_exponent;
  public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(modulus);
  const TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area);
  TPM2B_SENSITIVE private_data;
  private_data.size = 0;
  const TPMI_RH_HIERARCHY hierarchy = TPM_RH_NULL;
  TPM2B_NAME name;
  result = factory_.GetTpm()->LoadExternalSync(
      private_data, public_data, hierarchy, key_handle, &name, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error loading external key: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::LoadECPublicKey(AsymmetricKeyUsage key_type,
                                       TPM_ECC_CURVE curve_id,
                                       TPM_ALG_ID scheme,
                                       TPM_ALG_ID hash_alg,
                                       const std::string& x,
                                       const std::string& y,
                                       AuthorizationDelegate* delegate,
                                       TPM_HANDLE* key_handle) {
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }

  // Create public area.
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
  public_area.parameters.ecc_detail.curve_id = curve_id;
  public_area.parameters.ecc_detail.kdf.scheme = hash_alg;
  public_area.parameters.ecc_detail.scheme.scheme = scheme;
  public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER(x);
  public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER(y);
  const TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area);

  // Empty sensitive area.
  TPM2B_SENSITIVE private_data;
  private_data.size = 0;
  const TPMI_RH_HIERARCHY hierachy = TPM_RH_NULL;
  TPM2B_NAME name;

  // Load the key to tpm.
  result = factory_.GetTpm()->LoadExternalSync(
      private_data, public_data, hierachy, key_handle, &name, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error Loading external key: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetKeyName(TPM_HANDLE handle, std::string* name) {
  CHECK(name);
  TPM_RC result;
  TPMT_PUBLIC public_data;
  result = GetKeyPublicArea(handle, &public_data);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error fetching public info: " << GetErrorString(result);
    return result;
  }
  result = ComputeKeyName(public_data, name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error computing key name: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetKeyPublicArea(TPM_HANDLE handle,
                                        TPMT_PUBLIC* public_data) {
  CHECK(public_data);
  TPM2B_NAME out_name;
  TPM2B_PUBLIC public_area;
  TPM2B_NAME qualified_name;
  std::string handle_name;  // Unused
  TPM_RC result = factory_.GetTpm()->ReadPublicSync(
      handle, handle_name, &public_area, &out_name, &qualified_name, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error getting public area for object: " << handle;
    return result;
  }
  if (!public_area.size) {
    LOG(ERROR) << __func__
               << ": Error reading key public information - empty data";
    return TPM_RC_FAILURE;
  }
  *public_data = public_area.public_area;
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::SealData(const std::string& data_to_seal,
                                const std::string& policy_digest,
                                const std::string& auth_value,
                                AuthorizationDelegate* delegate,
                                std::string* sealed_data) {
  CHECK(sealed_data);
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  std::string parent_name;
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for RSA-SRK: "
               << GetErrorString(result);
    return result;
  }
  // We seal data to the TPM by creating a KEYEDHASH object with sign and
  // decrypt attributes disabled.
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_KEYEDHASH);
  public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
  public_area.object_attributes = kAdminWithPolicy | kNoDA;
  public_area.unique.keyed_hash.size = 0;
  TPML_PCR_SELECTION creation_pcrs = {};
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST(auth_value);
  sensitive.data = Make_TPM2B_SENSITIVE_DATA(data_to_seal);
  TPM2B_SENSITIVE_CREATE sensitive_create =
      Make_TPM2B_SENSITIVE_CREATE(sensitive);
  TPM2B_DATA outside_info = Make_TPM2B_DATA("");
  TPM2B_PUBLIC out_public;
  out_public.size = 0;
  TPM2B_PRIVATE out_private;
  out_private.size = 0;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_hash;
  TPMT_TK_CREATION creation_ticket;
  result = factory_.GetTpm()->CreateSync(
      kStorageRootKey, parent_name, sensitive_create,
      Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
      &out_public, &creation_data, &creation_hash, &creation_ticket, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error creating sealed object: " << GetErrorString(result);
    return result;
  }
  if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private,
                                                  sealed_data)) {
    return SAPI_RC_BAD_TCTI_STRUCTURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::UnsealData(const std::string& sealed_data,
                                  AuthorizationDelegate* delegate,
                                  std::string* unsealed_data) {
  CHECK(unsealed_data);
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  TPM_HANDLE object_handle;
  std::unique_ptr<AuthorizationDelegate> password_delegate =
      factory_.GetPasswordAuthorization("");
  result = LoadKey(sealed_data, password_delegate.get(), &object_handle);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error loading sealed object: " << GetErrorString(result);
    return result;
  }
  ScopedKeyHandle sealed_object(factory_, object_handle);

  return UnsealDataWithHandle(sealed_object.get(), delegate, unsealed_data);
}

TPM_RC TpmUtilityImpl::UnsealDataWithHandle(TPM_HANDLE object_handle,
                                            AuthorizationDelegate* delegate,
                                            std::string* unsealed_data) {
  CHECK(unsealed_data);
  TPM_RC result;
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }

  std::string object_name;
  result = GetKeyName(object_handle, &object_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error getting object name: " << GetErrorString(result);
    return result;
  }
  TPM2B_SENSITIVE_DATA out_data;
  result = factory_.GetTpm()->UnsealSync(object_handle, object_name, &out_data,
                                         delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error unsealing object: " << GetErrorString(result);
    return result;
  }
  *unsealed_data = StringFrom_TPM2B_SENSITIVE_DATA(out_data);
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::StartSession(HmacSession* session) {
  TPM_RC result = session->StartUnboundSession(true /* salted */,
                                               true /* enable_encryption */);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error starting unbound session: "
               << GetErrorString(result);
    return result;
  }
  session->SetEntityAuthorizationValue("");
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetPolicyDigestForPcrValues(
    const std::map<uint32_t, std::string>& pcr_map,
    bool use_auth_value,
    std::string* policy_digest) {
  CHECK(policy_digest);
  std::unique_ptr<PolicySession> session = factory_.GetTrialSession();
  TPM_RC result = session->StartUnboundSession(true, false);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error starting unbound trial session: "
               << GetErrorString(result);
    return result;
  }

  // the construction of `pcr_map_with_values` can be in O(n)
  std::map<uint32_t, std::string> pcr_map_with_values = pcr_map;
  for (const auto& map_pair : pcr_map) {
    uint32_t pcr_index = map_pair.first;
    const std::string& pcr_value = map_pair.second;
    if (!pcr_value.empty()) {
      continue;
    }

    std::string mutable_pcr_value;
    result = ReadPCR(pcr_index, &mutable_pcr_value);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__
                 << ": Error reading pcr_value: " << GetErrorString(result);
      return result;
    }
    pcr_map_with_values[pcr_index] = mutable_pcr_value;
  }
  if (use_auth_value) {
    result = session->PolicyAuthValue();
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Error setting session to use auth_value: "
                 << GetErrorString(result);
      return result;
    }
  }
  result = session->PolicyPCR(pcr_map_with_values);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error restricting policy to PCR value: "
               << GetErrorString(result);
    return result;
  }
  result = session->GetDigest(policy_digest);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error getting policy digest: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::DefineNVSpace(uint32_t index,
                                     size_t num_bytes,
                                     TPMA_NV attributes,
                                     const std::string& authorization_value,
                                     const std::string& policy_digest,
                                     AuthorizationDelegate* delegate) {
  TPM_RC result;
  if (num_bytes > MAX_NV_INDEX_SIZE) {
    result = SAPI_RC_BAD_SIZE;
    LOG(ERROR) << __func__
               << ": Cannot define non-volatile space of given size: "
               << GetErrorString(result);
    return result;
  }
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot define non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  TPMS_NV_PUBLIC public_data;
  public_data.nv_index = nv_index;
  public_data.name_alg = TPM_ALG_SHA256;
  public_data.attributes = attributes;
  public_data.auth_policy = Make_TPM2B_DIGEST(policy_digest);
  public_data.data_size = num_bytes;
  TPM2B_AUTH authorization = Make_TPM2B_DIGEST(authorization_value);
  TPM2B_NV_PUBLIC public_area = Make_TPM2B_NV_PUBLIC(public_data);
  result = factory_.GetTpm()->NV_DefineSpaceSync(
      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), authorization, public_area,
      delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error defining non-volatile space: "
               << GetErrorString(result);
    return result;
  }
  nvram_public_area_map_[index] = public_data;
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::DestroyNVSpace(uint32_t index,
                                      AuthorizationDelegate* delegate) {
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot undefine non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  if (delegate == nullptr) {
    result = SAPI_RC_INVALID_SESSIONS;
    LOG(ERROR) << __func__
               << ": This method needs a valid authorization delegate: "
               << GetErrorString(result);
    return result;
  }
  std::string nv_name;
  result = GetNVSpaceName(index, &nv_name);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  result = factory_.GetTpm()->NV_UndefineSpaceSync(
      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), nv_index, nv_name, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error undefining non-volatile space: "
               << GetErrorString(result);
    return result;
  }
  nvram_public_area_map_.erase(index);
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::LockNVSpace(uint32_t index,
                                   bool lock_read,
                                   bool lock_write,
                                   bool using_owner_authorization,
                                   AuthorizationDelegate* delegate) {
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot lock non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  std::string nv_name;
  result = GetNVSpaceName(index, &nv_name);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  TPMI_RH_NV_AUTH auth_target = nv_index;
  std::string auth_target_name = nv_name;
  if (using_owner_authorization) {
    auth_target = TPM_RH_OWNER;
    auth_target_name = NameFromHandle(TPM_RH_OWNER);
  }
  auto it = nvram_public_area_map_.find(index);
  if (lock_read) {
    result = factory_.GetTpm()->NV_ReadLockSync(auth_target, auth_target_name,
                                                nv_index, nv_name, delegate);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Error locking non-volatile space read: "
                 << GetErrorString(result);
      return result;
    }
    if (it != nvram_public_area_map_.end()) {
      it->second.attributes |= TPMA_NV_READLOCKED;
    }
  }
  if (lock_write) {
    result = factory_.GetTpm()->NV_WriteLockSync(auth_target, auth_target_name,
                                                 nv_index, nv_name, delegate);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Error locking non-volatile space write: "
                 << GetErrorString(result);
      return result;
    }
    if (it != nvram_public_area_map_.end()) {
      it->second.attributes |= TPMA_NV_WRITELOCKED;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::WriteNVSpace(uint32_t index,
                                    uint32_t offset,
                                    const std::string& nvram_data,
                                    bool using_owner_authorization,
                                    bool extend,
                                    AuthorizationDelegate* delegate) {
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot write to non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  std::string nv_name;
  result = GetNVSpaceName(index, &nv_name);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  TPMI_RH_NV_AUTH auth_target = nv_index;
  std::string auth_target_name = nv_name;
  if (using_owner_authorization) {
    auth_target = TPM_RH_OWNER;
    auth_target_name = NameFromHandle(TPM_RH_OWNER);
  }
  if (extend) {
    if (nvram_data.size() > MAX_NV_BUFFER_SIZE) {
      result = SAPI_RC_BAD_SIZE;
      LOG(ERROR) << __func__
                 << ": Insufficient buffer for non-volatile extend: "
                 << GetErrorString(result);
      return result;
    }
    result = factory_.GetTpm()->NV_ExtendSync(
        auth_target, auth_target_name, nv_index, nv_name,
        Make_TPM2B_MAX_NV_BUFFER(nvram_data), delegate);
  } else {
    size_t max_chunk_size;
    result = GetMaxNVChunkSize(&max_chunk_size);
    if (result) {
      LOG(ERROR) << __func__ << ": Failed to obtain max NV chunk size: "
                 << GetErrorString(result);
      return result;
    }
    for (size_t pos = 0; pos < nvram_data.size() && result == TPM_RC_SUCCESS;) {
      std::string chunk = nvram_data.substr(pos, max_chunk_size);
      result = factory_.GetTpm()->NV_WriteSync(
          auth_target, auth_target_name, nv_index, nv_name,
          Make_TPM2B_MAX_NV_BUFFER(chunk), offset + pos, delegate);
      pos += chunk.size();
    }
  }
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error writing to non-volatile space: "
               << GetErrorString(result);
    return result;
  }
  auto it = nvram_public_area_map_.find(index);
  if (it != nvram_public_area_map_.end()) {
    it->second.attributes |= TPMA_NV_WRITTEN;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ReadNVSpace(uint32_t index,
                                   uint32_t offset,
                                   size_t num_bytes,
                                   bool using_owner_authorization,
                                   std::string* nvram_data,
                                   AuthorizationDelegate* delegate) {
  CHECK(nvram_data);
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot read from non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  std::string nv_name;
  result = GetNVSpaceName(index, &nv_name);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  TPMI_RH_NV_AUTH auth_target = nv_index;
  std::string auth_target_name = nv_name;
  if (using_owner_authorization) {
    auth_target = TPM_RH_OWNER;
    auth_target_name = NameFromHandle(TPM_RH_OWNER);
  }
  size_t max_chunk_size;
  result = GetMaxNVChunkSize(&max_chunk_size);
  if (result) {
    LOG(ERROR) << __func__ << ": Failed to obtain max NV chunk size: "
               << GetErrorString(result);
    return result;
  }
  nvram_data->clear();
  for (uint32_t chunk_offset = offset; num_bytes > 0;) {
    size_t chunk_size = std::min(num_bytes, max_chunk_size);
    TPM2B_MAX_NV_BUFFER data_buffer;
    data_buffer.size = 0;
    result = factory_.GetTpm()->NV_ReadSync(
        auth_target, auth_target_name, nv_index, nv_name, chunk_size,
        chunk_offset, &data_buffer, delegate);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Error reading from non-volatile space: "
                 << GetErrorString(result);
      return result;
    }
    nvram_data->append(StringFrom_TPM2B_MAX_NV_BUFFER(data_buffer));
    num_bytes -= chunk_size;
    chunk_offset += chunk_size;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetNVSpaceName(uint32_t index, std::string* name) {
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot read from non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  TPMS_NV_PUBLIC nv_public_data;
  result = GetNVSpacePublicArea(index, &nv_public_data);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  result = ComputeNVSpaceName(nv_public_data, name);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetNVSpacePublicArea(uint32_t index,
                                            TPMS_NV_PUBLIC* public_data) {
  TPM_RC result;
  if (index > kMaxNVSpaceIndex) {
    result = SAPI_RC_BAD_PARAMETER;
    LOG(ERROR) << __func__
               << ": Cannot read from non-volatile space with the given index: "
               << GetErrorString(result);
    return result;
  }
  auto it = nvram_public_area_map_.find(index);
  if (it != nvram_public_area_map_.end()) {
    *public_data = it->second;
    return TPM_RC_SUCCESS;
  }
  TPM2B_NAME nvram_name;
  TPM2B_NV_PUBLIC public_area;
  public_area.nv_public.nv_index = 0;
  uint32_t nv_index = NV_INDEX_FIRST + index;
  result = factory_.GetTpm()->NV_ReadPublicSync(nv_index, "", &public_area,
                                                &nvram_name, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error reading non-volatile space public information: "
               << GetErrorString(result);
    return result;
  }
  if (!public_area.size) {
    LOG(ERROR)
        << __func__
        << ": Error reading non-volatile space public information - empty data";
    return TPM_RC_FAILURE;
  }
  *public_data = public_area.nv_public;
  nvram_public_area_map_[index] = public_area.nv_public;
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ListNVSpaces(std::vector<uint32_t>* index_list) {
  TPM_RC result;
  TPMI_YES_NO more_data = YES;
  TPMS_CAPABILITY_DATA capability_data;
  TPM_HANDLE handle_base = HR_NV_INDEX;
  while (more_data == YES) {
    result = factory_.GetTpm()->GetCapabilitySync(
        TPM_CAP_HANDLES, handle_base, MAX_CAP_HANDLES, &more_data,
        &capability_data, nullptr /*authorization_delegate*/);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__
                 << ": Error querying NV spaces: " << GetErrorString(result);
      return result;
    }
    if (capability_data.capability != TPM_CAP_HANDLES) {
      LOG(ERROR) << __func__ << ": Invalid capability type.";
      return SAPI_RC_MALFORMED_RESPONSE;
    }
    TPML_HANDLE& handles = capability_data.data.handles;
    for (uint32_t i = 0; i < handles.count; ++i) {
      index_list->push_back(handles.handle[i] & HR_HANDLE_MASK);
      handle_base = handles.handle[i] + 1;
    }
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::SetDictionaryAttackParameters(
    uint32_t max_tries,
    uint32_t recovery_time,
    uint32_t lockout_recovery,
    AuthorizationDelegate* delegate) {
  return factory_.GetTpm()->DictionaryAttackParametersSync(
      TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), max_tries, recovery_time,
      lockout_recovery, delegate);
}

TPM_RC TpmUtilityImpl::ResetDictionaryAttackLock(
    AuthorizationDelegate* delegate) {
  return factory_.GetTpm()->DictionaryAttackLockResetSync(
      TPM_RH_LOCKOUT, NameFromHandle(TPM_RH_LOCKOUT), delegate);
}

TPM_RC TpmUtilityImpl::GetEndorsementKey(
    TPM_ALG_ID key_type,
    AuthorizationDelegate* endorsement_delegate,
    AuthorizationDelegate* owner_delegate,
    TPM_HANDLE* key_handle) {
  if (key_type != TPM_ALG_RSA && key_type != TPM_ALG_ECC) {
    return SAPI_RC_BAD_PARAMETER;
  }
  // The RSA EK may have already been generated and made persistent. The ECC EK
  // is always generated on demand.
  if (key_type == TPM_ALG_RSA) {
    bool exists = false;
    TPM_RC result = DoesPersistentKeyExist(kRSAEndorsementKey, &exists);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": Check Peristent RSA Key failed: "
                 << GetErrorString(result);
      return result;
    }
    if (exists) {
      *key_handle = kRSAEndorsementKey;
      return TPM_RC_SUCCESS;
    }
  }

  Tpm* tpm = factory_.GetTpm();
  TPML_PCR_SELECTION creation_pcrs;
  creation_pcrs.count = 0;
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST("");
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM_HANDLE object_handle;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_digest;
  TPMT_TK_CREATION creation_ticket;
  TPM2B_NAME object_name;
  object_name.size = 0;
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(key_type);
  public_area.object_attributes = kFixedTPM | kFixedParent |
                                  kSensitiveDataOrigin | kAdminWithPolicy |
                                  kRestricted | kDecrypt;
  public_area.auth_policy = Make_TPM2B_DIGEST(kEKTemplateAuthPolicy);
  if (key_type == TPM_ALG_RSA) {
    public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_AES;
    public_area.parameters.rsa_detail.symmetric.key_bits.aes = 128;
    public_area.parameters.rsa_detail.symmetric.mode.aes = TPM_ALG_CFB;
    public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_NULL;
    public_area.parameters.rsa_detail.key_bits = 2048;
    public_area.parameters.rsa_detail.exponent = 0;
    public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(std::string(256, 0));
  } else {
    public_area.parameters.ecc_detail.symmetric.algorithm = TPM_ALG_AES;
    public_area.parameters.ecc_detail.symmetric.key_bits.aes = 128;
    public_area.parameters.ecc_detail.symmetric.mode.aes = TPM_ALG_CFB;
    public_area.parameters.ecc_detail.scheme.scheme = TPM_ALG_NULL;
    public_area.parameters.ecc_detail.curve_id = TPM_ECC_NIST_P256;
    public_area.parameters.ecc_detail.kdf.scheme = TPM_ALG_NULL;
    public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER(std::string(32, 0));
    public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER(std::string(32, 0));
  }
  TPM2B_PUBLIC rsa_public_area = Make_TPM2B_PUBLIC(public_area);
  TPM_RC result = tpm->CreatePrimarySync(
      TPM_RH_ENDORSEMENT, NameFromHandle(TPM_RH_ENDORSEMENT),
      Make_TPM2B_SENSITIVE_CREATE(sensitive), rsa_public_area,
      Make_TPM2B_DATA(""), creation_pcrs, &object_handle, &rsa_public_area,
      &creation_data, &creation_digest, &creation_ticket, &object_name,
      endorsement_delegate);
  if (result) {
    LOG(ERROR) << __func__
               << ": CreatePrimarySync failed: " << GetErrorString(result);
    return result;
  }

  // Only make RSA key persistent.
  if (key_type == TPM_ALG_RSA) {
    ScopedKeyHandle rsa_key(factory_, object_handle);
    result = tpm->EvictControlSync(
        TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), object_handle,
        StringFrom_TPM2B_NAME(object_name), kRSAEndorsementKey, owner_delegate);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__
                 << ": EvictControlSync failed: " << GetErrorString(result);
      return result;
    }
    *key_handle = kRSAEndorsementKey;
    return TPM_RC_SUCCESS;
  }

  *key_handle = object_handle;
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CreateCsmeSaltingKey() {
  bool exists = false;
  TPM_RC result = DoesPersistentKeyExist(kCsmeSaltingKey, &exists);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Check Peristent CSME Salting Key failed: "
               << GetErrorString(result);
    return result;
  }
  if (exists) {
    return TPM_RC_SUCCESS;
  }

  Tpm* tpm = factory_.GetTpm();
  TPML_PCR_SELECTION creation_pcrs = {};
  creation_pcrs.count = 0;
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST("");
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM_HANDLE object_handle;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_digest;
  TPMT_TK_CREATION creation_ticket;
  TPM2B_NAME object_name;
  object_name.size = 0;
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
  public_area.object_attributes = kFixedTPM | kFixedParent | kDecrypt |
                                  kSensitiveDataOrigin | kUserWithAuth | kNoDA;
  TPM2B_PUBLIC tpm2b_public = Make_TPM2B_PUBLIC(public_area);

  std::unique_ptr<AuthorizationDelegate> endorsement_delegate =
      factory_.GetPasswordAuthorization("");
  result = tpm->CreatePrimarySync(
      TPM_RH_ENDORSEMENT, NameFromHandle(TPM_RH_ENDORSEMENT),
      Make_TPM2B_SENSITIVE_CREATE(sensitive), tpm2b_public, Make_TPM2B_DATA(""),
      creation_pcrs, &object_handle, &tpm2b_public, &creation_data,
      &creation_digest, &creation_ticket, &object_name,
      endorsement_delegate.get());
  if (result) {
    LOG(ERROR) << __func__
               << ": CreatePrimarySync failed: " << GetErrorString(result);
    return result;
  }

  ScopedKeyHandle key(factory_, object_handle);

  std::unique_ptr<AuthorizationDelegate> owner_delegate =
      factory_.GetPasswordAuthorization("");
  result =
      tpm->EvictControlSync(TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER),
                            object_handle, StringFrom_TPM2B_NAME(object_name),
                            kCsmeSaltingKey, owner_delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": EvictControlSync failed: " << GetErrorString(result);
    return result;
  }
  LOG(INFO) << __func__ << ": Created CSME Salting Key.";
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CreateIdentityKey(TPM_ALG_ID key_type,
                                         AuthorizationDelegate* delegate,
                                         std::string* key_blob) {
  CHECK(key_blob);
  if (key_type != TPM_ALG_RSA && key_type != TPM_ALG_ECC) {
    return SAPI_RC_BAD_PARAMETER;
  }
  std::string parent_name;
  TPM_RC result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting key name for SRK: "
               << GetErrorString(result);
    return result;
  }
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(key_type);
  public_area.object_attributes |=
      (kSensitiveDataOrigin | kUserWithAuth | kNoDA | kRestricted | kSign);
  if (key_type == TPM_ALG_RSA) {
    public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_RSASSA;
    public_area.parameters.rsa_detail.scheme.details.rsassa.hash_alg =
        TPM_ALG_SHA256;
  } else {
    public_area.parameters.ecc_detail.scheme.scheme = TPM_ALG_ECDSA;
    public_area.parameters.ecc_detail.scheme.details.ecdsa.hash_alg =
        TPM_ALG_SHA256;
  }
  TPML_PCR_SELECTION creation_pcrs = {};
  creation_pcrs.count = 0;
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST("");
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM2B_SENSITIVE_CREATE sensitive_create =
      Make_TPM2B_SENSITIVE_CREATE(sensitive);
  TPM2B_DATA outside_info = Make_TPM2B_DATA("");
  TPM2B_PUBLIC out_public;
  out_public.size = 0;
  TPM2B_PRIVATE out_private;
  out_private.size = 0;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_hash;
  TPMT_TK_CREATION creation_ticket;
  result = factory_.GetTpm()->CreateSync(
      kStorageRootKey, parent_name, sensitive_create,
      Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
      &out_public, &creation_data, &creation_hash, &creation_ticket, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error creating identity key: " << GetErrorString(result);
    return result;
  }
  if (!factory_.GetBlobParser()->SerializeKeyBlob(out_public, out_private,
                                                  key_blob)) {
    return SAPI_RC_BAD_TCTI_STRUCTURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::DeclareTpmFirmwareStable() {
  if (!IsCr50()) {
    return TPM_RC_SUCCESS;
  }
  std::string response_payload;
  TPM_RC rc = Cr50VendorCommand(kCr50SubcmdInvalidateInactiveRW, std::string(),
                                &response_payload);
  if (rc == TPM_RC_SUCCESS) {
    LOG(INFO) << "Successfully invalidated inactive Cr50 RW";
  } else {
    LOG(WARNING) << "Invalidating inactive Cr50 RW failed: 0x" << std::hex
                 << rc;
  }
  return rc;
}

TPM_RC TpmUtilityImpl::GetPublicRSAEndorsementKeyModulus(std::string* ekm) {
  uint32_t index = kRsaEndorsementCertificateNonRealIndex;
  trunks::TPMS_NV_PUBLIC nvram_public;
  TPM_RC result = GetNVSpacePublicArea(index, &nvram_public);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading NV space for index " << index
               << " with error: " << GetErrorString(result);
    return result;
  }

  std::unique_ptr<AuthorizationDelegate> password_delegate(
      factory_.GetPasswordAuthorization(""));
  std::string nvram_data;
  result = ReadNVSpace(index, 0, nvram_public.data_size, false, &nvram_data,
                       password_delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading NV space for index " << index
               << " with error: " << GetErrorString(result);
    return result;
  }

  // Get the X509 object.
  const unsigned char* cert_data =
      reinterpret_cast<const unsigned char*>(nvram_data.c_str());
  crypto::ScopedOpenSSL<X509, X509_free> xcert(
      d2i_X509(nullptr, &cert_data, nvram_data.size()));
  if (!xcert) {
    LOG(ERROR) << "Failed to get EK certificate from NVRAM";
    return SAPI_RC_CORRUPTED_DATA;
  }

  // Get the public key.
  crypto::ScopedEVP_PKEY pubkey(X509_get_pubkey(xcert.get()));
  if (!pubkey || EVP_PKEY_base_id(pubkey.get()) != EVP_PKEY_RSA) {
    LOG(ERROR) << "Failed to get EK public key from NVRAM";
    return SAPI_RC_CORRUPTED_DATA;
  }

  crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pubkey.get()));
  if (!rsa) {
    LOG(ERROR) << "Failed to get RSA from NVRAM";
    return SAPI_RC_CORRUPTED_DATA;
  }

  size_t buf_len = RSA_size(rsa.get());
  if (buf_len == 0) {
    LOG(ERROR) << "Invalid buffer size";
    return SAPI_RC_CORRUPTED_DATA;
  }

  std::vector<unsigned char> key(buf_len);
  const BIGNUM* bn;
  RSA_get0_key(rsa.get(), &bn, nullptr, nullptr);
  BN_bn2bin(bn, key.data());
  ekm->assign(reinterpret_cast<const char*>(key.data()), buf_len);

  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ManageCCDPwd(bool allow_pwd) {
  if (!IsCr50()) {
    return TPM_RC_SUCCESS;
  }
  std::string command_payload(1, allow_pwd ? 1 : 0);
  std::string response_payload;
  return Cr50VendorCommand(kCr50SubcmdManageCCDPwd, command_payload,
                           &response_payload);
}

TPM_RC TpmUtilityImpl::SetKnownOwnerPassword(
    const std::string& known_owner_password) {
  std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
  TPM_RC result = tpm_state->Initialize();
  if (result) {
    LOG(ERROR) << __func__ << ": Failed to initialize TPM state: "
               << GetErrorString(result);
    return result;
  }
  std::unique_ptr<AuthorizationDelegate> delegate =
      factory_.GetPasswordAuthorization("");
  if (tpm_state->IsOwnerPasswordSet()) {
    LOG(INFO) << __func__ << ": Owner password is already set. "
              << "This is normal if ownership is already taken.";
    return TPM_RC_SUCCESS;
  }
  result = SetHierarchyAuthorization(TPM_RH_OWNER, known_owner_password,
                                     delegate.get());
  if (result) {
    LOG(ERROR) << __func__ << ": Error setting storage hierarchy authorization "
               << "to its default value: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CreateStorageRootKeys(
    const std::string& owner_password) {
  Tpm* tpm = factory_.GetTpm();
  TPML_PCR_SELECTION creation_pcrs;
  creation_pcrs.count = 0;
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST("");
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM_HANDLE object_handle;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_digest;
  TPMT_TK_CREATION creation_ticket;
  TPM2B_NAME object_name;
  object_name.size = 0;
  std::unique_ptr<AuthorizationDelegate> delegate =
      factory_.GetPasswordAuthorization(owner_password);

  bool exists = false;
  TPM_RC result = DoesPersistentKeyExist(kStorageRootKey, &exists);
  if (result) {
    return result;
  }
  if (exists) {
    LOG(INFO) << __func__ << ": Skip SRK generation because it already exists.";
    return TPM_RC_SUCCESS;
  }

  TPM_ALG_ID key_type = factory_.GetTpmCache()->GetBestSupportedKeyType();
  if (key_type != TPM_ALG_ECC && key_type != TPM_ALG_RSA) {
    LOG(ERROR) << __func__ << ": Failed to get the best supported key type.";
    return TPM_RC_FAILURE;
  }

  TPMT_PUBLIC public_area = CreateDefaultPublicArea(key_type);

  // SRK specific settings
  public_area.object_attributes |=
      (kSensitiveDataOrigin | kUserWithAuth | kNoDA | kRestricted | kDecrypt);
  public_area.parameters.asym_detail.symmetric.algorithm = TPM_ALG_AES;
  public_area.parameters.asym_detail.symmetric.key_bits.aes = 128;
  public_area.parameters.asym_detail.symmetric.mode.aes = TPM_ALG_CFB;

  TPM2B_PUBLIC tpm2b_public_area = Make_TPM2B_PUBLIC(public_area);
  result = tpm->CreatePrimarySync(
      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER),
      Make_TPM2B_SENSITIVE_CREATE(sensitive), tpm2b_public_area,
      Make_TPM2B_DATA(""), creation_pcrs, &object_handle, &tpm2b_public_area,
      &creation_data, &creation_digest, &creation_ticket, &object_name,
      delegate.get());
  if (result) {
    LOG(ERROR) << __func__ << ": Failed to create TPM primary sync: "
               << GetErrorString(result);
    return result;
  }
  ScopedKeyHandle tpm_key(factory_, object_handle);

  const std::string key_type_str = key_type == TPM_ALG_ECC ? "ECC" : "RSA";
  LOG(INFO) << __func__ << ": Created " << key_type_str << " SRK.";

  // This will make the key persistent.
  result = tpm->EvictControlSync(
      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), object_handle,
      StringFrom_TPM2B_NAME(object_name), kStorageRootKey, delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Failed to evict control sync: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::CreateSaltingKey(const std::string& owner_password) {
  bool exists = false;
  TPM_RC result = DoesPersistentKeyExist(kSaltingKey, &exists);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  if (exists) {
    LOG(INFO) << __func__ << ": Salting key already exists.";
    return TPM_RC_SUCCESS;
  }
  std::string parent_name;
  result = GetKeyName(kStorageRootKey, &parent_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error getting Key name for SRK: "
               << GetErrorString(result);
    return result;
  }

  TPM_ALG_ID key_type = factory_.GetTpmCache()->GetBestSupportedKeyType();
  if (key_type != TPM_ALG_ECC && key_type != TPM_ALG_RSA) {
    LOG(ERROR) << __func__ << ": Failed to get the best supported key type.";
    return TPM_RC_FAILURE;
  }

  TPMT_PUBLIC public_area = CreateDefaultPublicArea(key_type);
  public_area.object_attributes |=
      kSensitiveDataOrigin | kUserWithAuth | kNoDA | kDecrypt;
  TPML_PCR_SELECTION creation_pcrs;
  creation_pcrs.count = 0;
  TPMS_SENSITIVE_CREATE sensitive;
  sensitive.user_auth = Make_TPM2B_DIGEST("");
  sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
  TPM2B_SENSITIVE_CREATE sensitive_create =
      Make_TPM2B_SENSITIVE_CREATE(sensitive);
  TPM2B_DATA outside_info = Make_TPM2B_DATA("");

  TPM2B_PRIVATE out_private;
  out_private.size = 0;
  TPM2B_PUBLIC out_public;
  out_public.size = 0;
  TPM2B_CREATION_DATA creation_data;
  TPM2B_DIGEST creation_hash;
  TPMT_TK_CREATION creation_ticket;
  // TODO(usanghi): MITM vulnerability with SaltingKey creation.
  // Currently we cannot verify the key returned by the TPM.
  // crbug.com/442331
  std::unique_ptr<AuthorizationDelegate> delegate =
      factory_.GetPasswordAuthorization("");
  result = factory_.GetTpm()->CreateSync(
      kStorageRootKey, parent_name, sensitive_create,
      Make_TPM2B_PUBLIC(public_area), outside_info, creation_pcrs, &out_private,
      &out_public, &creation_data, &creation_hash, &creation_ticket,
      delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error creating salting key: " << GetErrorString(result);
    return result;
  }

  const std::string key_type_str = key_type == TPM_ALG_ECC ? "ECC" : "RSA";
  LOG(INFO) << __func__ << ": Created " << key_type_str << " salting key.";

  TPM2B_NAME key_name;
  key_name.size = 0;
  TPM_HANDLE key_handle;
  result = factory_.GetTpm()->LoadSync(kStorageRootKey, parent_name,
                                       out_private, out_public, &key_handle,
                                       &key_name, delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error loading salting key: " << GetErrorString(result);
    return result;
  }

  ScopedKeyHandle key(factory_, key_handle);
  std::unique_ptr<AuthorizationDelegate> owner_delegate =
      factory_.GetPasswordAuthorization(owner_password);
  result = factory_.GetTpm()->EvictControlSync(
      TPM_RH_OWNER, NameFromHandle(TPM_RH_OWNER), key_handle,
      StringFrom_TPM2B_NAME(key_name), kSaltingKey, owner_delegate.get());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Failed to evict control sync: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPMT_PUBLIC TpmUtilityImpl::CreateDefaultPublicArea(TPM_ALG_ID key_alg) {
  TPMT_PUBLIC public_area;
  memset(&public_area, 0, sizeof(public_area));
  public_area.type = key_alg;
  public_area.name_alg = TPM_ALG_SHA256;
  public_area.auth_policy = Make_TPM2B_DIGEST("");
  public_area.object_attributes = kFixedTPM | kFixedParent;
  if (key_alg == TPM_ALG_RSA) {
    public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_NULL;
    public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_NULL;
    public_area.parameters.rsa_detail.key_bits = 2048;
    public_area.parameters.rsa_detail.exponent = 0;
    public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA("");
  } else if (key_alg == TPM_ALG_ECC) {
    public_area.parameters.ecc_detail.scheme.scheme = TPM_ALG_NULL;
    public_area.parameters.ecc_detail.symmetric.algorithm = TPM_ALG_NULL;
    public_area.parameters.ecc_detail.curve_id = TPM_ECC_NIST_P256;
    public_area.parameters.ecc_detail.kdf.scheme = TPM_ALG_NULL;
    public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER("");
    public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER("");
  } else if (key_alg == TPM_ALG_KEYEDHASH) {
    public_area.parameters.keyed_hash_detail.scheme.scheme = TPM_ALG_NULL;
  } else {
    LOG(WARNING) << __func__
                 << ": Unrecognized key_type. Not filling parameters.";
  }
  return public_area;
}

TPM_RC TpmUtilityImpl::SetHierarchyAuthorization(
    TPMI_RH_HIERARCHY_AUTH hierarchy,
    const std::string& password,
    AuthorizationDelegate* authorization) {
  if (password.size() > kMaxPasswordLength) {
    LOG(ERROR) << __func__ << ": Hierarchy passwords can be at most "
               << kMaxPasswordLength
               << " bytes. Current password length is: " << password.size();
    return SAPI_RC_BAD_SIZE;
  }
  return factory_.GetTpm()->HierarchyChangeAuthSync(
      hierarchy, NameFromHandle(hierarchy), Make_TPM2B_DIGEST(password),
      authorization);
}

TPM_RC TpmUtilityImpl::DisablePlatformHierarchy(
    AuthorizationDelegate* authorization) {
  return factory_.GetTpm()->HierarchyControlSync(
      TPM_RH_PLATFORM,  // The authorizing entity.
      NameFromHandle(TPM_RH_PLATFORM),
      TPM_RH_PLATFORM,  // The target hierarchy.
      0,                // Disable.
      authorization);
}

TPM_RC TpmUtilityImpl::ComputeKeyName(const TPMT_PUBLIC& public_area,
                                      std::string* object_name) {
  CHECK(object_name);
  if (public_area.type == TPM_ALG_ERROR) {
    // We do not compute a name for empty public area.
    object_name->clear();
    return TPM_RC_SUCCESS;
  }
  std::string serialized_public_area;
  TPM_RC result = Serialize_TPMT_PUBLIC(public_area, &serialized_public_area);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error serializing public area: " << GetErrorString(result);
    return result;
  }
  std::string serialized_name_alg;
  result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error serializing public area: " << GetErrorString(result);
    return result;
  }
  object_name->assign(serialized_name_alg +
                      crypto::SHA256HashString(serialized_public_area));
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ComputeNVSpaceName(const TPMS_NV_PUBLIC& nv_public_area,
                                          std::string* nv_name) {
  CHECK(nv_name);
  if ((nv_public_area.nv_index & NV_INDEX_FIRST) == 0) {
    // If the index is not an nvram index, we do not compute a name.
    nv_name->clear();
    return TPM_RC_SUCCESS;
  }
  std::string serialized_public_area;
  TPM_RC result =
      Serialize_TPMS_NV_PUBLIC(nv_public_area, &serialized_public_area);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error serializing public area: " << GetErrorString(result);
    return result;
  }
  std::string serialized_name_alg;
  result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error serializing public area: " << GetErrorString(result);
    return result;
  }
  nv_name->assign(serialized_name_alg +
                  crypto::SHA256HashString(serialized_public_area));
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::EncryptPrivateData(const TPMT_SENSITIVE& sensitive_area,
                                          const TPMT_PUBLIC& public_area,
                                          TPM2B_PRIVATE* encrypted_private_data,
                                          TPM2B_DATA* encryption_key) {
  TPM2B_SENSITIVE sensitive_data = Make_TPM2B_SENSITIVE(sensitive_area);
  std::string serialized_sensitive_data;
  TPM_RC result =
      Serialize_TPM2B_SENSITIVE(sensitive_data, &serialized_sensitive_data);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error serializing sensitive data: "
               << GetErrorString(result);
    return result;
  }
  std::string object_name;
  result = ComputeKeyName(public_area, &object_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error computing object name: " << GetErrorString(result);
    return result;
  }
  TPM2B_DIGEST inner_integrity = Make_TPM2B_DIGEST(
      crypto::SHA256HashString(serialized_sensitive_data + object_name));
  std::string serialized_inner_integrity;
  result = Serialize_TPM2B_DIGEST(inner_integrity, &serialized_inner_integrity);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error serializing inner integrity: "
               << GetErrorString(result);
    return result;
  }
  std::string unencrypted_private_data =
      serialized_inner_integrity + serialized_sensitive_data;
  AES_KEY key;
  AES_set_encrypt_key(encryption_key->buffer, kAesKeySize * 8, &key);
  std::string private_data_string(unencrypted_private_data.size(), 0);
  int iv_in = 0;
  unsigned char iv[MAX_AES_BLOCK_SIZE_BYTES] = {0};
  AES_cfb128_encrypt(
      reinterpret_cast<const unsigned char*>(unencrypted_private_data.data()),
      reinterpret_cast<unsigned char*>(base::data(private_data_string)),
      unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT);
  *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error making private area: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,
                                              bool* exists) {
  TPM_RC result;
  TPMI_YES_NO more_data = YES;
  TPMS_CAPABILITY_DATA capability_data;
  result = factory_.GetTpm()->GetCapabilitySync(
      TPM_CAP_HANDLES, key_handle, 1 /*property_count*/, &more_data,
      &capability_data, nullptr /*authorization_delegate*/);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__
               << ": Error querying handles: " << GetErrorString(result);
    return result;
  }
  TPML_HANDLE& handles = capability_data.data.handles;
  *exists = (handles.count == 1 && handles.handle[0] == key_handle);
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::GetAlertsData(TpmAlertsData* alerts) {
  memset(alerts, 0, sizeof(TpmAlertsData));

  if (!IsCr50()) {
    alerts->chip_family = kFamilyUndefined;
    return TPM_RC_SUCCESS;
  }
  std::string out;
  TPM_RC rc = Cr50VendorCommand(kCr50SubcmdGetAlertsData, std::string(), &out);
  if (rc != TPM_RC_SUCCESS) {
    LOG(WARNING) << "Unable to read alerts data: 0x" << std::hex << rc;
    return rc;
  }

  if (out.size() < 2 * sizeof(uint16_t)) {
    // 2 * sizeof represents TpmAlertsData first 2 required fields
    LOG(WARNING) << "TPM AlertsData response is too short";
    return TPM_RC_FAILURE;
  }

  const TpmAlertsData* received_alerts =
      reinterpret_cast<const TpmAlertsData*>(out.data());

  // convert byte-order from one specified by TPM specification to host order
  alerts->chip_family = base::NetToHost16(received_alerts->chip_family);
  if (alerts->chip_family != kFamilyH1) {
    LOG(WARNING) << "TPM AlertsData unsupported TPM family identifier "
                 << alerts->chip_family;

    // return kFamilyUndefined to tell CrOS to stop querying alerts data
    alerts->chip_family = kFamilyUndefined;
    return TPM_RC_SUCCESS;
  }

  alerts->alerts_num = base::NetToHost16(received_alerts->alerts_num);
  if (alerts->alerts_num > kAlertsMaxSize) {
    LOG(WARNING) << "TPM AlertsData response is too long";
    return TPM_RC_FAILURE;
  }

  size_t expected_size =
      2 * sizeof(uint16_t) + alerts->alerts_num * sizeof(uint16_t);
  if (out.size() != expected_size) {
    LOG(WARNING) << "TPM AlertsData response size does not match alerts_num "
                 << out.size() << " vs " << expected_size;
    return TPM_RC_FAILURE;
  }

  for (int i = 0; i < alerts->alerts_num; i++) {
    alerts->counters[i] = base::NetToHost16(received_alerts->counters[i]);
  }

  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::PinWeaverIsSupported(uint8_t request_version,
                                            uint8_t* protocol_version) {
  return PinWeaverCommand(
      __func__,
      [request_version](std::string* in) -> TPM_RC {
        return Serialize_pw_ping_t(request_version, in);
      },
      [protocol_version](const std::string& out) -> TPM_RC {
        return Parse_pw_pong_t(out, protocol_version);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverResetTree(uint8_t protocol_version,
                                          uint8_t bits_per_level,
                                          uint8_t height,
                                          uint32_t* result_code,
                                          std::string* root_hash) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, bits_per_level, height](std::string* in) -> TPM_RC {
        return Serialize_pw_reset_tree_t(protocol_version, bits_per_level,
                                         height, in);
      },
      [result_code, root_hash](const std::string& out) -> TPM_RC {
        return Parse_pw_short_message(out, result_code, root_hash);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverInsertLeaf(
    uint8_t protocol_version,
    uint64_t label,
    const std::string& h_aux,
    const brillo::SecureBlob& le_secret,
    const brillo::SecureBlob& he_secret,
    const brillo::SecureBlob& reset_secret,
    const std::map<uint32_t, uint32_t>& delay_schedule,
    const ValidPcrCriteria& valid_pcr_criteria,
    uint32_t* result_code,
    std::string* root_hash,
    std::string* cred_metadata,
    std::string* mac) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, label, h_aux, le_secret, he_secret, reset_secret,
       delay_schedule, valid_pcr_criteria](std::string* in) -> TPM_RC {
        return Serialize_pw_insert_leaf_t(
            protocol_version, label, h_aux, le_secret, he_secret, reset_secret,
            delay_schedule, valid_pcr_criteria, in);
      },
      [result_code, root_hash, cred_metadata,
       mac](const std::string& out) -> TPM_RC {
        return Parse_pw_insert_leaf_t(out, result_code, root_hash,
                                      cred_metadata, mac);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverRemoveLeaf(uint8_t protocol_version,
                                           uint64_t label,
                                           const std::string& h_aux,
                                           const std::string& mac,
                                           uint32_t* result_code,
                                           std::string* root_hash) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, label, h_aux, mac](std::string* in) -> TPM_RC {
        return Serialize_pw_remove_leaf_t(protocol_version, label, h_aux, mac,
                                          in);
      },
      [result_code, root_hash](const std::string& out) -> TPM_RC {
        return Parse_pw_short_message(out, result_code, root_hash);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverTryAuth(uint8_t protocol_version,
                                        const brillo::SecureBlob& le_secret,
                                        const std::string& h_aux,
                                        const std::string& cred_metadata,
                                        uint32_t* result_code,
                                        std::string* root_hash,
                                        uint32_t* seconds_to_wait,
                                        brillo::SecureBlob* he_secret,
                                        brillo::SecureBlob* reset_secret,
                                        std::string* cred_metadata_out,
                                        std::string* mac_out) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, le_secret, h_aux,
       cred_metadata](std::string* in) -> TPM_RC {
        return Serialize_pw_try_auth_t(protocol_version, le_secret, h_aux,
                                       cred_metadata, in);
      },
      [result_code, root_hash, seconds_to_wait, he_secret, reset_secret,
       cred_metadata_out, mac_out](const std::string& out) -> TPM_RC {
        return Parse_pw_try_auth_t(out, result_code, root_hash, seconds_to_wait,
                                   he_secret, reset_secret, cred_metadata_out,
                                   mac_out);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverResetAuth(
    uint8_t protocol_version,
    const brillo::SecureBlob& reset_secret,
    const std::string& h_aux,
    const std::string& cred_metadata,
    uint32_t* result_code,
    std::string* root_hash,
    brillo::SecureBlob* he_secret,
    std::string* cred_metadata_out,
    std::string* mac_out) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, reset_secret, h_aux,
       cred_metadata](std::string* in) -> TPM_RC {
        return Serialize_pw_reset_auth_t(protocol_version, reset_secret, h_aux,
                                         cred_metadata, in);
      },
      [result_code, root_hash, he_secret, cred_metadata_out,
       mac_out](const std::string& out) -> TPM_RC {
        return Parse_pw_reset_auth_t(out, result_code, root_hash, he_secret,
                                     cred_metadata_out, mac_out);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverGetLog(
    uint8_t protocol_version,
    const std::string& root,
    uint32_t* result_code,
    std::string* root_hash,
    std::vector<trunks::PinWeaverLogEntry>* log) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, root](std::string* in) -> TPM_RC {
        return Serialize_pw_get_log_t(protocol_version, root, in);
      },
      [result_code, root_hash, log](const std::string& out) -> TPM_RC {
        return Parse_pw_get_log_t(out, result_code, root_hash, log);
      });
}

TPM_RC TpmUtilityImpl::PinWeaverLogReplay(uint8_t protocol_version,
                                          const std::string& log_root,
                                          const std::string& h_aux,
                                          const std::string& cred_metadata,
                                          uint32_t* result_code,
                                          std::string* root_hash,
                                          std::string* cred_metadata_out,
                                          std::string* mac_out) {
  return PinWeaverCommand(
      __func__,
      [protocol_version, log_root, h_aux,
       cred_metadata](std::string* in) -> TPM_RC {
        return Serialize_pw_log_replay_t(protocol_version, log_root, h_aux,
                                         cred_metadata, in);
      },
      [result_code, root_hash, cred_metadata_out,
       mac_out](const std::string& out) -> TPM_RC {
        return Parse_pw_log_replay_t(out, result_code, root_hash,
                                     cred_metadata_out, mac_out);
      });
}

uint32_t TpmUtilityImpl::VendorId() {
  if (!vendor_id_) {
    std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
    TPM_RC result = tpm_state->Initialize();
    if (result) {
      LOG(ERROR) << __func__ << ": TpmState initialization failed: "
                 << GetErrorString(result);
      return 0;
    }
    if (!tpm_state->GetTpmProperty(TPM_PT_MANUFACTURER, &vendor_id_)) {
      LOG(WARNING) << __func__
                   << ": Error getting TPM_PT_MANUFACTURER property";
      return 0;
    }
    VLOG(1) << __func__ << ": TPM_PT_MANUFACTURER = 0x" << std::hex
            << vendor_id_;
  }
  return vendor_id_;
}

bool TpmUtilityImpl::IsCr50() {
  return VendorId() == kVendorIdCr50;
}

bool TpmUtilityImpl::IsSimulator() {
  return VendorId() == kVendorIdSimulator;
}

std::string TpmUtilityImpl::SendCommandAndWait(const std::string& command) {
  return factory_.GetTpm()->get_transceiver()->SendCommandAndWait(command);
}

TPM_RC TpmUtilityImpl::SerializeCommand_Cr50Vendor(
    uint16_t subcommand,
    const std::string& command_payload,
    std::string* serialized_command) {
  VLOG(3) << __func__;

  UINT32 command_size = 12 + command_payload.size();
  Serialize_TPMI_ST_COMMAND_TAG(TPM_ST_NO_SESSIONS, serialized_command);
  Serialize_UINT32(command_size, serialized_command);
  Serialize_TPM_CC(kCr50VendorCC, serialized_command);
  Serialize_UINT16(subcommand, serialized_command);
  serialized_command->append(command_payload);
  VLOG(2) << "Command: "
          << base::HexEncode(serialized_command->data(),
                             serialized_command->size());

  // We didn't check the return statuses of Serialize_Xxx routines above, which
  // in practice always succeed. Let's at least check the resulting command
  // size to make sure all fields were indeed serialized in.
  if (serialized_command->size() != command_size) {
    LOG(ERROR) << "Bad cr50 vendor command size: expected = " << command_size
               << ", actual = " << serialized_command->size();
    return TPM_RC_INSUFFICIENT;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::ParseResponse_Cr50Vendor(const std::string& response,
                                                std::string* response_payload) {
  VLOG(3) << __func__;
  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
  response_payload->assign(response);

  TPM_ST tag;
  TPM_RC rc = Parse_TPM_ST(response_payload, &tag, nullptr);
  if (rc != TPM_RC_SUCCESS) {
    return rc;
  }
  if (tag != TPM_ST_NO_SESSIONS) {
    LOG(ERROR) << "Bad cr50 vendor response tag: 0x" << std::hex << tag;
    return TPM_RC_AUTH_CONTEXT;
  }

  UINT32 response_size;
  rc = Parse_UINT32(response_payload, &response_size, nullptr);
  if (rc != TPM_RC_SUCCESS) {
    return rc;
  }
  if (response_size != response.size()) {
    LOG(ERROR) << "Bad cr50 vendor response size: expected = " << response_size
               << ", actual = " << response.size();
    return TPM_RC_SIZE;
  }

  TPM_RC response_code;
  rc = Parse_TPM_RC(response_payload, &response_code, nullptr);
  if (rc != TPM_RC_SUCCESS) {
    return rc;
  }

  UINT16 subcommand_code;
  rc = Parse_UINT16(response_payload, &subcommand_code, nullptr);
  if (rc != TPM_RC_SUCCESS) {
    return rc;
  }

  return response_code;
}

TPM_RC TpmUtilityImpl::Cr50VendorCommand(uint16_t subcommand,
                                         const std::string& command_payload,
                                         std::string* response_payload) {
  VLOG(1) << __func__ << "(subcommand: " << subcommand << ")";
  std::string command;
  TPM_RC rc =
      SerializeCommand_Cr50Vendor(subcommand, command_payload, &command);
  if (rc != TPM_RC_SUCCESS) {
    return rc;
  }
  std::string response = SendCommandAndWait(command);
  rc = ParseResponse_Cr50Vendor(response, response_payload);
  return rc;
}

template <typename S, typename P>
TPM_RC TpmUtilityImpl::PinWeaverCommand(const std::string& tag,
                                        S serialize,
                                        P parse) {
  std::string in;
  TPM_RC rc = serialize(&in);
  if (rc) {
    LOG(ERROR) << tag << ": Serialize failed: 0x" << std::hex << rc
               << GetErrorString(rc) << std::dec;
    return rc;
  }

  std::string out;
  if (IsCr50()) {
    rc = Cr50VendorCommand(kCr50SubcmdPinWeaver, in, &out);
  } else {
    rc = PinWeaverCsmeCommand(in, &out);
  }

  if (rc != TPM_RC_SUCCESS) {
    LOG(WARNING) << tag << ": command failed: 0x" << std::hex << rc << " "
                 << GetErrorString(rc);
  } else {
    rc = parse(out);
  }
  return rc;
}

// Should copy the logic of ec/common/base32.c
static const unsigned char crc5_table1[] = {0x00, 0x0E, 0x1C, 0x12, 0x11, 0x1F,
                                            0x0D, 0x03, 0x0B, 0x05, 0x17, 0x19,
                                            0x1A, 0x14, 0x06, 0x08};

static const unsigned char crc5_table0[] = {0x00, 0x16, 0x05, 0x13, 0x0A, 0x1C,
                                            0x0F, 0x19, 0x14, 0x02, 0x11, 0x07,
                                            0x1E, 0x08, 0x1B, 0x0D};

uint8_t crc5_sym(uint8_t sym, uint8_t previous_crc) {
  uint8_t tmp = sym ^ previous_crc;
  return crc5_table1[tmp & 0x0F] ^ crc5_table0[(tmp >> 4) & 0x0F];
}

// This should be exactly the same as platform/ec/common/base32.c

// A-Z0-9 with I,O,0,1 removed
// const char base32_map[33] = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";

// Decodes a base32 symbol.
// Returns the symbol value or -1 if error.
static int decode_sym(int sym) {
  if (sym >= 'A' && sym <= 'H') {
    return sym - 'A';
  }
  if (sym >= 'J' && sym <= 'N') {
    return sym - 'J' + 8;
  }
  if (sym >= 'P' && sym <= 'Z') {
    return sym - 'P' + 13;
  }
  if (sym >= '2' && sym <= '9') {
    return sym - '2' + 24;
  }
  return -1;
}

int base32_decode(uint8_t* dest,
                  int destlen_bits,
                  const char* src,
                  int crc_after_every) {
  int crc = 0, crc_count = 0;
  int out_bits = 0;

  for (; *src; src++) {
    int sym, sbits, dbits, b;

    if (isspace(*src) || *src == '-')
      continue;

    sym = decode_sym(*src);
    if (sym < 0)
      return -1; /* Bad input symbol */

    /* Check CRC if needed */
    if (crc_after_every) {
      if (crc_count == crc_after_every) {
        if (crc != sym)
          return -1;
        crc_count = crc = 0;
        continue;
      } else {
        crc = crc5_sym(sym, crc);
        crc_count++;
      }
    }

    /*
     * Stop if we're out of space. Have to do this after checking
     * the CRC, or we might not check the last CRC.
     */
    if (out_bits >= destlen_bits)
      break;

    /* See how many bits we get to use from this symbol */
    sbits = MIN(5, destlen_bits - out_bits);
    if (sbits < 5)
      sym >>= (5 - sbits);

    /* Fill up the rest of the current byte */
    dbits = 8 - (out_bits & 7);
    b = MIN(dbits, sbits);
    if (dbits == 8)
      dest[out_bits / 8] = 0; /* Starting a new byte */
    dest[out_bits / 8] |= (sym << (dbits - b)) >> (sbits - b);
    out_bits += b;
    sbits -= b;

    /* Start the next byte if there's space */
    if (sbits > 0) {
      dest[out_bits / 8] = sym << (8 - sbits);
      out_bits += sbits;
    }
  }

  /* If we have CRCs, should have a full group */
  if (crc_after_every && crc_count)
    return -1;

  return out_bits;
}

TPM_RC TpmUtilityImpl::GetRsuDeviceIdInternal(std::string* device_id) {
  if (!IsCr50()) {
    return TPM_RC_FAILURE;
  }
  struct __packed rma_challenge {
    uint8_t version_key_id;
    uint8_t device_pub_key[32];
    uint8_t board_id[4];
    uint8_t device_id[8];
  } c;
  uint8_t* cptr = reinterpret_cast<uint8_t*>(&c);

  std::string res;
  TPM_RC result = Cr50VendorCommand(kCr50GetRmaChallenge, std::string(), &res);
  if (result != TPM_RC_SUCCESS) {
    return result;
  }
  if (base32_decode(cptr, 8 * sizeof(c), res.data(), 9) != 8 * sizeof(c)) {
    return TPM_RC_FAILURE;
  }
  *device_id = crypto::SHA256HashString(
      std::string(reinterpret_cast<const char*>(c.device_id),
                  base::size(c.device_id)) +
      kRsuSalt);
  return result;
}

TPM_RC TpmUtilityImpl::GetRsuDeviceId(std::string* device_id) {
  TPM_RC result = TPM_RC_SUCCESS;
  if (cached_rsu_device_id_.empty())
    result = GetRsuDeviceIdInternal(&cached_rsu_device_id_);
  *device_id = cached_rsu_device_id_;
  return result;
}

TPM_RC TpmUtilityImpl::GetRoVerificationStatus(ApRoStatus* status) {
  if (!IsCr50()) {
    *status = ApRoStatus::kApRoUnsupported;
    return TPM_RC_SUCCESS;
  }
  std::string res;
  TPM_RC result =
      Cr50VendorCommand(kCr50SubcmdGetRoStatus, std::string(), &res);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Cr50VendorCommand failed";
    return result;
  }
  if (res.size() < 1) {
    LOG(ERROR) << __func__ << ": empty response";
    return TPM_RC_FAILURE;
  }
  *status = static_cast<ApRoStatus>(res[0]);
  return TPM_RC_SUCCESS;
}

TPM_RC TpmUtilityImpl::PinWeaverCsmeCommand(const std::string& in,
                                            std::string* out) {
  csme::MeiClientFactory mei_client_factory;
  csme::PinWeaverCoreClient client(&mei_client_factory);
  if (!client.PinWeaverCommand(in, out)) {
    LOG(ERROR) << __func__ << ": Failed to call pinweaver-csme.";
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

TpmUtilityImpl::PinWeaverBackendType
TpmUtilityImpl::GetPinwWeaverBackendType() {
  if (pinweaver_backend_type_ != PinWeaverBackendType::kUnknown) {
    return pinweaver_backend_type_;
  }
  uint8_t protocol_version;
  if (PinWeaverIsSupported(0, &protocol_version) != TPM_RC_SUCCESS) {
    pinweaver_backend_type_ = PinWeaverBackendType::kNotSupported;
  } else {
    pinweaver_backend_type_ =
        IsCr50() ? PinWeaverBackendType::kCr50 : PinWeaverBackendType::kCsme;
  }
  return pinweaver_backend_type_;
}

TPM_RC TpmUtilityImpl::GetMaxNVChunkSize(size_t* size) {
  CHECK(size);
  if (!max_nv_chunk_size_) {
    std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
    TPM_RC result = tpm_state->Initialize();
    if (result) {
      LOG(ERROR) << __func__ << ": Failed to initialize TPM state: "
                 << GetErrorString(result);
      return result;
    }
    max_nv_chunk_size_ =
        std::min((size_t)tpm_state->GetMaxNVSize(), (size_t)MAX_NV_BUFFER_SIZE);
  }
  *size = max_nv_chunk_size_;
  return TPM_RC_SUCCESS;
}

}  // namespace trunks
