//
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "trunks/tpm_utility_impl.h"

#include <memory>

#include <base/logging.h>
#include <base/sha1.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/sys_byteorder.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"

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;
// 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 kCr50SubcmdManageCCDPwd = 33;
const uint16_t kCr50SubcmdGetAlertsData = 35;
const uint16_t kCr50SubcmdPinWeaver = 37;

// 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");

// The index in NVRAM space where RSA EK certificate is stored.
const uint32_t kRSAEndorsementCertificateIndex = 0xC00000;

// 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__ << ": " << GetErrorString(result);
    return result;
  }
  result = tpm->SelfTestSync(YES /* Full test. */, nullptr);
  if (result) {
    LOG(ERROR) << __func__ << ": " << 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__ << ": " << 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__ << ": " << 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__ << ": " << 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__ << ": " << GetErrorString(result);
      return result;
    }
    result = AllocatePCR(kPlatformPassword);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": " << GetErrorString(result);
      return result;
    }
    std::unique_ptr<AuthorizationDelegate> authorization(
        factory_.GetPasswordAuthorization(kPlatformPassword));
    result = DisablePlatformHierarchy(authorization.get());
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << __func__ << ": " << 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::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::CreateStorageAndSaltingKeys() {
  // First we set the storage hierarchy authorization to the well know default
  // password.
  TPM_RC 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();

  session->SetEntityAuthorizationValue("");
  if (!tpm_state->IsEndorsementPasswordSet()) {
    session->SetFutureAuthorizationValue(endorsement_password);
    result = SetHierarchyAuthorization(TPM_RH_ENDORSEMENT, endorsement_password,
                                       session->GetDelegate());
    if (result) {
      LOG(ERROR) << __func__ << ": " << 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__ << ": " << 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::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;
  }
  CHECK_GE(pcr_values.count, 1U);
  pcr_value->assign(StringFrom_TPM2B_DIGEST(pcr_values.digests[0]));
  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::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;
  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;
  }

  // Simply check key type and scheme and select the unpack helper for parsing
  // the output from TPM.
  std::function<std::string(const TPMT_SIGNATURE&)> unpack_helper;
  if (public_area.type == TPM_ALG_RSA) {
    if (scheme == TPM_ALG_RSAPSS) {
      unpack_helper = [](const TPMT_SIGNATURE& signature_out) {
        return StringFrom_TPM2B_PUBLIC_KEY_RSA(
            signature_out.signature.rsapss.sig);
      };
    } else if (scheme == TPM_ALG_RSASSA) {
      unpack_helper = [](const TPMT_SIGNATURE& signature_out) {
        return StringFrom_TPM2B_PUBLIC_KEY_RSA(
            signature_out.signature.rsassa.sig);
      };
    } else {
      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) {
      unpack_helper = [](const TPMT_SIGNATURE& signature_out) {
        std::string output;
        Serialize_TPMT_SIGNATURE(signature_out, &output);
        return output;
      };
    } else {
      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_SIGNATURE signature_out;
  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, &signature_out, delegate);
  if (result) {
    LOG(ERROR) << __func__
               << ": Error signing digest: " << GetErrorString(result);
    return result;
  }

  *signature = unpack_helper(signature_out);
  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::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 return_code = factory_.GetTpm()->ReadPublicSync(
      handle, handle_name, &public_area, &out_name, &qualified_name, nullptr);
  if (return_code) {
    LOG(ERROR) << __func__
               << ": Error getting public area for object: " << handle;
    return return_code;
  }
  *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);
  std::string object_name;
  result = GetKeyName(sealed_object.get(), &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(sealed_object.get(), 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 (nvram_data.size() > MAX_NV_BUFFER_SIZE) {
    result = SAPI_RC_BAD_SIZE;
    LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile write: "
               << GetErrorString(result);
    return 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) {
    result = factory_.GetTpm()->NV_ExtendSync(
        auth_target, auth_target_name, nv_index, nv_name,
        Make_TPM2B_MAX_NV_BUFFER(nvram_data), delegate);
  } else {
    result = factory_.GetTpm()->NV_WriteSync(
        auth_target, auth_target_name, nv_index, nv_name,
        Make_TPM2B_MAX_NV_BUFFER(nvram_data), offset, delegate);
  }
  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 (num_bytes > MAX_NV_BUFFER_SIZE) {
    result = SAPI_RC_BAD_SIZE;
    LOG(ERROR) << __func__ << ": Insufficient buffer for non-volatile read: "
               << GetErrorString(result);
    return 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);
  }
  TPM2B_MAX_NV_BUFFER data_buffer;
  data_buffer.size = 0;
  result = factory_.GetTpm()->NV_ReadSync(auth_target, auth_target_name,
                                          nv_index, nv_name, num_bytes, offset,
                                          &data_buffer, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Error reading from non-volatile space: "
               << GetErrorString(result);
    return result;
  }
  nvram_data->assign(StringFrom_TPM2B_MAX_NV_BUFFER(data_buffer));
  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::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 = kRSAEndorsementCertificateIndex;
  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 || pubkey->type != EVP_PKEY_RSA) {
    LOG(ERROR) << "Failed to get EK public key from NVRAM";
    return SAPI_RC_CORRUPTED_DATA;
  }

  RSA* rsa = pubkey->pkey.rsa;
  if (!rsa) {
    LOG(ERROR) << "Failed to get RSA from NVRAM";
    return SAPI_RC_CORRUPTED_DATA;
  }

  BIGNUM* bn = rsa->n;
  size_t buf_len = (size_t) BN_num_bytes(bn);
  if (buf_len == 0) {
    LOG(ERROR) << "Invalid buffer size";
    return SAPI_RC_CORRUPTED_DATA;
  }

  std::vector<unsigned char> key(buf_len);
  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__ << ": " << 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_RC result = TPM_RC_SUCCESS;
  std::unique_ptr<TpmState> tpm_state(factory_.GetTpmState());
  result = tpm_state->Initialize();
  if (result) {
    LOG(ERROR) << __func__ << ": " << GetErrorString(result);
    return result;
  }
  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;
  result = DoesPersistentKeyExist(kStorageRootKey, &exists);
  if (result) {
    return result;
  }
  if (exists) {
    LOG(INFO) << __func__ << ": Skip SRK generation because it already exists.";
    return TPM_RC_SUCCESS;
  }

  // Decide the SRK key type, the priority is
  // 1. ECC
  // 2. RSA
  TPM_ALG_ID key_type;
  std::string key_type_str;
  if (tpm_state->IsECCSupported()) {
    key_type = TPM_ALG_ECC;
    key_type_str = "ECC";
  } else if (tpm_state->IsRSASupported()) {
    key_type = TPM_ALG_RSA;
    key_type_str = "RSA";
  } else {
    LOG(INFO) << __func__
              << ": Skip SRK generation because RSA and ECC are not supported.";
    return TPM_RC_SUCCESS;
  }

  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__ << ": " << GetErrorString(result);
    return result;
  }
  ScopedKeyHandle tpm_key(factory_, object_handle);

  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__ << ": " << 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 RSA-SRK: "
               << GetErrorString(result);
    return result;
  }
  TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
  public_area.name_alg = TPM_ALG_SHA256;
  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;
  }
  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__ << ": " << 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::string_as_array(&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;
}

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) {
  if (!IsCr50()) {
    LOG(ERROR) << tag << ": Called a Cr50 only function without Cr50.";
    return TPM_RC_FAILURE;
  }

  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;
  rc = Cr50VendorCommand(kCr50SubcmdPinWeaver, in, &out);
  if (rc != TPM_RC_SUCCESS) {
    LOG(WARNING) << tag << ": command failed: 0x" << std::hex << rc << " " <<
                 GetErrorString(rc);
  } else {
    rc = parse(out);
  }
  return rc;
}

}  // namespace trunks
