// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Contains the implementation of class Tpm

#include "cryptohome/tpm2_impl.h"

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/message_loop/message_pump_type.h>
#include <base/notreached.h>
#include <base/numerics/safe_conversions.h>
#include <crypto/libcrypto-compat.h>
#include <crypto/scoped_openssl_types.h>
#include <libhwsec/error/tpm2_error.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <tpm_manager-client/tpm_manager/dbus-constants.h>
#include <trunks/authorization_delegate.h>
#include <trunks/blob_parser.h>
#include <trunks/error_codes.h>
#include <trunks/policy_session.h>
#include <trunks/tpm_alerts.h>
#include <trunks/tpm_constants.h>
#include <trunks/trunks_dbus_proxy.h>
#include <trunks/trunks_factory.h>
#include <trunks/trunks_factory_impl.h>

#include "cryptohome/crypto/aes.h"
#include "cryptohome/crypto/rsa.h"
#include "cryptohome/crypto/sha.h"

using brillo::Blob;
using brillo::BlobFromString;
using brillo::BlobToString;
using brillo::SecureBlob;
using hwsec::error::TPM2Error;
using hwsec::error::TPMError;
using hwsec::error::TPMErrorBase;
using hwsec::error::TPMRetryAction;
using hwsec_foundation::error::CreateError;
using hwsec_foundation::error::CreateErrorWrap;
using trunks::GetErrorString;
using trunks::TPM_RC_SUCCESS;
using trunks::TrunksFactory;

namespace cryptohome {

namespace {

// Returns the total number of bits set in the first |size| elements from
// |array|.
int CountSetBits(const uint8_t* array, size_t size) {
  int res = 0;
  for (size_t i = 0; i < size; ++i) {
    for (int bit_position = 0; bit_position < 8; ++bit_position) {
      if ((array[i] & (1 << bit_position)) != 0) {
        ++res;
      }
    }
  }
  return res;
}

std::string OwnerDependencyEnumClassToString(
    Tpm::TpmOwnerDependency dependency) {
  switch (dependency) {
    case Tpm::TpmOwnerDependency::kInstallAttributes:
      return tpm_manager::kTpmOwnerDependency_Nvram;
    case Tpm::TpmOwnerDependency::kAttestation:
      return tpm_manager::kTpmOwnerDependency_Attestation;
    default:
      NOTREACHED() << __func__ << ": Unexpected enum class value: "
                   << static_cast<int>(dependency);
      return "";
  }
}

trunks::TpmUtility::AsymmetricKeyUsage ConvertAsymmetricKeyUsage(
    AsymmetricKeyUsage usage) {
  switch (usage) {
    case AsymmetricKeyUsage::kDecryptKey:
      return trunks::TpmUtility::AsymmetricKeyUsage::kDecryptKey;
    case AsymmetricKeyUsage::kSignKey:
      return trunks::TpmUtility::AsymmetricKeyUsage::kSignKey;
    case AsymmetricKeyUsage::kDecryptAndSignKey:
      return trunks::TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey;
    default:
      NOTREACHED() << __func__ << ": Unexpected enum class value: "
                   << static_cast<int>(usage);
      return trunks::TpmUtility::AsymmetricKeyUsage::kDecryptKey;
  }
}

}  // namespace

// Keep it with sync to UMA enum list
// https://chromium.googlesource.com/chromium/src/+/HEAD/tools/metrics/histograms/enums.xml
// These values are persisted to logs, and should therefore never be renumbered
// nor reused.
enum TpmAlerts {
  kCamoBreach = 1,
  kDmemParity = 2,
  kDrfParity = 3,
  kImemParity = 4,
  kPgmFault = 5,
  kCpuDIfBusError = 6,
  kCpuDIfUpdateWatchdog = 7,
  kCpuIIfBusError = 8,
  kCpuIIfUpdateWatchdog = 9,
  kCpuSIfBusError = 10,
  kCpuSIfUpdateWatchdog = 11,
  kDmaIfBusErr = 12,
  kDmaIfUpdateWatchdog = 13,
  kSpsIfBusErr = 14,
  kSpsIfUpdateWatchdog = 15,
  kUsbIfBusErr = 16,
  kUsbIfUpdateWatchdog = 17,
  kFuseDefaults = 18,
  kDiffFail = 19,
  kSoftwareAlert0 = 20,
  kSoftwareAlert1 = 21,
  kSoftwareAlert2 = 22,
  kSoftwareAlert3 = 23,
  kHearbitFail = 24,
  kProcOpcodeHash = 25,
  kSramParityScrub = 26,
  kAesExecCtrMax = 27,
  kAesHkey = 28,
  kCertLookup = 29,
  kFlashEntry = 30,
  kPw = 31,
  kShaExecCtrMax = 32,
  kShaFault = 33,
  kShaHkey = 34,
  kPmuBatteryMon = 35,
  kPmuWatchdog = 36,
  kRtcDead = 37,
  kTempMax = 38,
  kTempMaxDiff = 39,
  kTempMin = 40,
  kRngOutOfSpec = 41,
  kRngTimeout = 42,
  kVoltageError = 43,
  kXoJitteryTrim = 44,

  kTPMAlertNumBuckets,  // Must be the last entry.
};
static_assert(kTPMAlertNumBuckets <= trunks::kAlertsMaxSize + 1,
              "Number of UMA enums less than alerts set size");

// Maps alerts identifiers received from TMP firmware to UMA identifiers
const TpmAlerts h1AlertsMap[trunks::kH1AlertsSize] = {
    kCamoBreach,
    kDmemParity,
    kDrfParity,
    kImemParity,
    kPgmFault,
    kCpuDIfBusError,
    kCpuDIfUpdateWatchdog,
    kCpuIIfBusError,
    kCpuIIfUpdateWatchdog,
    kCpuSIfBusError,
    kCpuSIfUpdateWatchdog,
    kDmaIfBusErr,
    kDmaIfUpdateWatchdog,
    kSpsIfBusErr,
    kSpsIfUpdateWatchdog,
    kUsbIfBusErr,
    kUsbIfUpdateWatchdog,
    kFuseDefaults,
    kDiffFail,
    kSoftwareAlert0,
    kSoftwareAlert1,
    kSoftwareAlert2,
    kSoftwareAlert3,
    kHearbitFail,
    kProcOpcodeHash,
    kSramParityScrub,
    kAesExecCtrMax,
    kAesHkey,
    kCertLookup,
    kFlashEntry,
    kPw,
    kShaExecCtrMax,
    kShaFault,
    kShaHkey,
    kPmuBatteryMon,
    kPmuWatchdog,
    kRtcDead,
    kTempMax,
    kTempMaxDiff,
    kTempMin,
    kRngOutOfSpec,
    kRngTimeout,
    kVoltageError,
    kXoJitteryTrim,
};

Tpm2Impl::Tpm2Impl(TrunksFactory* factory,
                   tpm_manager::TpmManagerUtility* tpm_manager_utility)
    : tpm_manager_utility_(tpm_manager_utility),
      has_external_trunks_context_(true) {
  external_trunks_context_.factory = factory;
  external_trunks_context_.tpm_state = factory->GetTpmState();
  external_trunks_context_.tpm_utility = factory->GetTpmUtility();
}

bool Tpm2Impl::GetOwnerPassword(brillo::SecureBlob* owner_password) {
  if (IsOwned()) {
    *owner_password =
        brillo::SecureBlob(last_tpm_manager_data_.owner_password());
    if (owner_password->empty()) {
      LOG(WARNING) << __func__
                   << ": Trying to get owner password after it is cleared.";
    }
  } else {
    LOG(ERROR)
        << __func__
        << ": Cannot get owner password until TPM is confirmed to be owned.";
    owner_password->clear();
  }
  return !owner_password->empty();
}

bool Tpm2Impl::InitializeTpmManagerUtility() {
  if (!tpm_manager_utility_) {
    tpm_manager_utility_ = tpm_manager::TpmManagerUtility::GetSingleton();
    if (!tpm_manager_utility_) {
      LOG(ERROR) << __func__ << ": Failed to get TpmManagerUtility singleton!";
    }
  }
  return tpm_manager_utility_ && tpm_manager_utility_->Initialize();
}

bool Tpm2Impl::CacheTpmManagerStatus() {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->GetTpmStatus(&is_enabled_, &is_owned_,
                                            &last_tpm_manager_data_);
}

bool Tpm2Impl::IsEnabled() {
  if (!is_enabled_) {
    if (!CacheTpmManagerStatus()) {
      LOG(ERROR) << __func__ << ": Failed to call |UpdateTpmStatus|.";
      return false;
    }
  }
  return is_enabled_;
}

bool Tpm2Impl::IsOwned() {
  if (!is_owned_) {
    if (!UpdateTpmStatus(RefreshType::REFRESH_IF_NEEDED)) {
      LOG(ERROR) << __func__ << ": Failed to call |UpdateTpmStatus|.";
      return false;
    }
  }
  return is_owned_;
}

bool Tpm2Impl::IsOwnerPasswordPresent() {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": failed to initialize |TpmManagerUtility|.";
    return false;
  }
  bool is_owner_password_present = false;
  if (!tpm_manager_utility_->GetTpmNonsensitiveStatus(
          nullptr, nullptr, &is_owner_password_present, nullptr)) {
    LOG(ERROR) << __func__ << ": Failed to get |is_owner_password_present|.";
    return false;
  }
  return is_owner_password_present;
}

bool Tpm2Impl::HasResetLockPermissions() {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": failed to initialize |TpmManagerUtility|.";
    return false;
  }
  bool has_reset_lock_permissions = false;
  if (!tpm_manager_utility_->GetTpmNonsensitiveStatus(
          nullptr, nullptr, nullptr, &has_reset_lock_permissions)) {
    LOG(ERROR) << __func__ << ": Failed to get |has_reset_lock_permissions|.";
    return false;
  }
  return has_reset_lock_permissions;
}

bool Tpm2Impl::PerformEnabledOwnedCheck(bool* enabled, bool* owned) {
  if (!UpdateTpmStatus(RefreshType::REFRESH_IF_NEEDED)) {
    return false;
  }
  if (enabled) {
    *enabled = is_enabled_;
  }
  if (owned) {
    *owned = is_owned_;
  }
  return true;
}

bool Tpm2Impl::GetRandomDataBlob(size_t length, brillo::Blob* data) {
  brillo::SecureBlob blob(length);
  if (!this->GetRandomDataSecureBlob(length, &blob)) {
    LOG(ERROR) << "GetRandomDataBlob failed";
    return false;
  }
  data->assign(blob.begin(), blob.end());
  return true;
}

bool Tpm2Impl::GetRandomDataSecureBlob(size_t length,
                                       brillo::SecureBlob* data) {
  CHECK(data);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::string random_data;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->GenerateRandom(
          length, /* delegate */ nullptr, &random_data))) {
    LOG(ERROR) << "Error getting random data: " << *err;
    return false;
  }
  if (random_data.size() != length) {
    LOG(ERROR) << "Error getting random data: requested length " << length
               << ", received length " << random_data.size();
    return false;
  }
  data->assign(random_data.begin(), random_data.end());
  return true;
}

bool Tpm2Impl::GetAlertsData(Tpm::AlertsData* alerts) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return true;
  }

  trunks::TpmAlertsData trunks_alerts;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->GetAlertsData(&trunks_alerts))) {
    if (err->ErrorCode() == trunks::TPM_RC_NO_SUCH_COMMAND) {
      LOG(INFO) << "TPM GetAlertsData vendor command is not implemented";
      return false;
    } else {
      LOG(ERROR) << "Error getting alerts data: " << *err;
      memset(alerts, 0, sizeof(Tpm::AlertsData));
      return true;
    }
  } else if (trunks_alerts.chip_family != trunks::kFamilyH1) {
    // Currently we support only H1 alerts
    LOG(ERROR) << "Unknown alerts family: " << trunks_alerts.chip_family;
    return false;
  }

  memset(alerts, 0, sizeof(Tpm::AlertsData));
  for (int i = 0; i < trunks_alerts.alerts_num; i++) {
    size_t uma_idx = h1AlertsMap[i];
    if (uma_idx <= 0 || uma_idx >= kTPMAlertNumBuckets) {
      LOG(ERROR) << "Alert index " << i << " maps into invalid UMA enum index "
                 << uma_idx;
    } else {
      alerts->counters[uma_idx] = trunks_alerts.counters[i];
    }
  }

  return true;
}

bool Tpm2Impl::DefineNvram(uint32_t index, size_t length, uint32_t flags) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  const bool write_define = flags & Tpm::kTpmNvramWriteDefine;
  const bool bind_to_pcr0 = flags & Tpm::kTpmNvramBindToPCR0;
  const bool firmware_readable = flags & Tpm::kTpmNvramFirmwareReadable;

  return tpm_manager_utility_->DefineSpace(index, length, write_define,
                                           bind_to_pcr0, firmware_readable);
}

bool Tpm2Impl::DestroyNvram(uint32_t index) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->DestroySpace(index);
}

bool Tpm2Impl::WriteNvram(uint32_t index, const SecureBlob& blob) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->WriteSpace(index, blob.to_string(),
                                          /*use_owner_auth=*/false);
}

bool Tpm2Impl::OwnerWriteNvram(uint32_t index, const SecureBlob& blob) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->WriteSpace(index, blob.to_string(),
                                          /*use_owner_auth=*/true);
}

bool Tpm2Impl::ReadNvram(uint32_t index, SecureBlob* blob) {
  if (!InitializeTpmManagerUtility()) {
    return false;
  }

  std::string output;
  const bool result = tpm_manager_utility_->ReadSpace(index, false, &output);
  SecureBlob tmp(output);
  blob->swap(tmp);
  return result;
}

bool Tpm2Impl::IsNvramDefined(uint32_t index) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  std::vector<uint32_t> spaces;
  if (!tpm_manager_utility_->ListSpaces(&spaces)) {
    return false;
  }
  for (uint32_t space : spaces) {
    if (index == space) {
      return true;
    }
  }
  return false;
}

bool Tpm2Impl::IsNvramLocked(uint32_t index) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  uint32_t size;
  bool is_read_locked;
  bool is_write_locked;
  if (!tpm_manager_utility_->GetSpaceInfo(index, &size, &is_read_locked,
                                          &is_write_locked,
                                          /*attributes=*/nullptr)) {
    return false;
  }
  return is_write_locked;
}

bool Tpm2Impl::WriteLockNvram(uint32_t index) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->LockSpace(index);
}

unsigned int Tpm2Impl::GetNvramSize(uint32_t index) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  uint32_t size;
  bool is_read_locked;
  bool is_write_locked;
  if (!tpm_manager_utility_->GetSpaceInfo(index, &size, &is_read_locked,
                                          &is_write_locked,
                                          /*attributes=*/nullptr)) {
    return 0;
  }
  return size;
}

bool Tpm2Impl::IsEndorsementKeyAvailable() {
  LOG(ERROR) << __func__ << ": Not implemented.";
  return true;
}

bool Tpm2Impl::CreateEndorsementKey() {
  LOG(ERROR) << __func__ << ": Not implemented.";
  return false;
}

bool Tpm2Impl::SealToPCR0(const brillo::SecureBlob& value,
                          brillo::SecureBlob* sealed_value) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::string policy_digest;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->GetPolicyDigestForPcrValues(
              std::map<uint32_t, std::string>({{0, ""}}),
              false /* use_auth_value */, &policy_digest))) {
    LOG(ERROR) << "Error getting policy digest: " << *err;
    return false;
  }
  std::unique_ptr<trunks::HmacSession> session =
      trunks->factory->GetHmacSession();
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->StartSession(session.get()))) {
    LOG(ERROR) << "Error starting hmac session: " << *err;
    return false;
  }
  std::string data_to_seal(value.begin(), value.end());
  std::string sealed_data;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->SealData(
          data_to_seal, policy_digest, "", session->GetDelegate(),
          &sealed_data))) {
    LOG(ERROR) << "Error sealing data to PCR0: " << *err;
    return false;
  }
  sealed_value->assign(sealed_data.begin(), sealed_data.end());
  return true;
}

bool Tpm2Impl::Unseal(const brillo::SecureBlob& sealed_value,
                      brillo::SecureBlob* value) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::unique_ptr<trunks::PolicySession> policy_session =
      trunks->factory->GetPolicySession();
  if (auto err = CreateError<TPM2Error>(
          policy_session->StartUnboundSession(true, false))) {
    LOG(ERROR) << "Error starting policy session: " << *err;
    return false;
  }
  if (auto err = CreateError<TPM2Error>(policy_session->PolicyPCR(
          std::map<uint32_t, std::string>({{0, ""}})))) {
    LOG(ERROR) << "Error restricting policy to pcr 0: " << *err;
    return false;
  }
  std::string sealed_data(sealed_value.begin(), sealed_value.end());
  std::string unsealed_data;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->UnsealData(
          sealed_data, policy_session->GetDelegate(), &unsealed_data))) {
    LOG(ERROR) << "Error unsealing object: " << *err;
    return false;
  }
  value->assign(unsealed_data.begin(), unsealed_data.end());
  return true;
}

bool Tpm2Impl::CreateDelegate(const std::set<uint32_t>& bound_pcrs,
                              uint8_t delegate_family_label,
                              uint8_t delegate_label,
                              Blob* delegate_blob,
                              Blob* delegate_secret) {
  LOG(ERROR) << __func__ << ": Not implemented.";
  return false;
}

bool Tpm2Impl::TakeOwnership(int /*max_timeout_tries*/,
                             const SecureBlob& /*owner_password*/) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  if (IsOwned()) {
    LOG(INFO) << __func__ << ": TPM is already owned.";
    return true;
  }
  return tpm_manager_utility_->TakeOwnership();
}

bool Tpm2Impl::Sign(const SecureBlob& key_blob,
                    const SecureBlob& input,
                    uint32_t bound_pcr_index,
                    SecureBlob* signature) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  trunks::AuthorizationDelegate* delegate;
  std::unique_ptr<trunks::PolicySession> policy_session;
  std::unique_ptr<trunks::HmacSession> hmac_session;
  if (bound_pcr_index != kNotBoundToPCR) {
    policy_session = trunks->factory->GetPolicySession();
    if (auto err = CreateError<TPM2Error>(
            policy_session->StartUnboundSession(true, false))) {
      LOG(ERROR) << "Error starting policy session: " << *err;
      return false;
    }
    if (auto err = CreateError<TPM2Error>(policy_session->PolicyPCR(
            std::map<uint32_t, std::string>({{bound_pcr_index, ""}})))) {
      LOG(ERROR) << "Error creating PCR policy: " << *err;
      return false;
    }
    delegate = policy_session->GetDelegate();
  } else {
    hmac_session = trunks->factory->GetHmacSession();
    if (auto err = CreateError<TPM2Error>(
            hmac_session->StartUnboundSession(true, true))) {
      LOG(ERROR) << "Error starting hmac session: " << *err;
      return false;
    }
    hmac_session->SetEntityAuthorizationValue("");
    delegate = hmac_session->GetDelegate();
  }

  ScopedKeyHandle handle;
  if (TPMErrorBase err = LoadWrappedKey(key_blob, &handle)) {
    LOG(ERROR) << "Error loading pcr bound key: " << *err;
    return false;
  }
  std::string tpm_signature;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->Sign(
          handle.value(), trunks::TPM_ALG_RSASSA, trunks::TPM_ALG_SHA256,
          input.to_string(), true /* generate_hash */, delegate,
          &tpm_signature))) {
    LOG(ERROR) << "Error signing: " << *err;
    return false;
  }
  signature->assign(tpm_signature.begin(), tpm_signature.end());
  return true;
}

bool Tpm2Impl::CreatePCRBoundKey(const std::map<uint32_t, std::string>& pcr_map,
                                 AsymmetricKeyUsage key_type,
                                 SecureBlob* key_blob,
                                 SecureBlob* public_key_der,
                                 SecureBlob* creation_blob) {
  CHECK(key_blob) << "No key blob argument provided.";
  CHECK(creation_blob) << "No creation blob argument provided.";
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::string policy_digest;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->GetPolicyDigestForPcrValues(
              pcr_map, false /* use_auth_value */, &policy_digest))) {
    LOG(ERROR) << "Error getting policy digest: " << *err;
    return false;
  }
  std::vector<uint32_t> pcr_list;
  for (const auto& map_pair : pcr_map) {
    pcr_list.push_back(map_pair.first);
  }
  std::string tpm_key_blob;
  std::string tpm_creation_blob;
  std::unique_ptr<trunks::AuthorizationDelegate> delegate =
      trunks->factory->GetPasswordAuthorization("");
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->CreateRSAKeyPair(
          ConvertAsymmetricKeyUsage(key_type), kDefaultTpmRsaModulusSize,
          kDefaultTpmPublicExponent,
          "",  // No authorization
          policy_digest,
          true,  // use_only_policy_authorization
          pcr_list, delegate.get(), &tpm_key_blob,
          &tpm_creation_blob /* No creation_blob */))) {
    LOG(ERROR) << "Error creating a pcr bound key: " << *err;
    return false;
  }
  key_blob->assign(tpm_key_blob.begin(), tpm_key_blob.end());
  creation_blob->assign(tpm_creation_blob.begin(), tpm_creation_blob.end());

  // if |public_key_der| is present, create and assign it.
  if (public_key_der) {
    trunks::TPM2B_PUBLIC public_data;
    trunks::TPM2B_PRIVATE private_data;
    if (!trunks->factory->GetBlobParser()->ParseKeyBlob(
            key_blob->to_string(), &public_data, &private_data)) {
      return false;
    }
    if (!PublicAreaToPublicKeyDER(public_data.public_area, public_key_der)) {
      return false;
    }
  }
  return true;
}

bool Tpm2Impl::VerifyPCRBoundKey(const std::map<uint32_t, std::string>& pcr_map,
                                 const SecureBlob& key_blob,
                                 const SecureBlob& creation_blob) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  // First we verify that the PCR were in a known good state at the time of
  // Key creation.
  trunks::TPM2B_CREATION_DATA creation_data;
  trunks::TPM2B_DIGEST creation_hash;
  trunks::TPMT_TK_CREATION creation_ticket;
  if (!trunks->factory->GetBlobParser()->ParseCreationBlob(
          creation_blob.to_string(), &creation_data, &creation_hash,
          &creation_ticket)) {
    LOG(ERROR) << "Error parsing creation_blob.";
    return false;
  }
  trunks::TPML_PCR_SELECTION& pcr_select =
      creation_data.creation_data.pcr_select;
  if (pcr_select.count != 1) {
    LOG(ERROR) << "Creation data missing creation PCR value.";
    return false;
  }
  if (pcr_select.pcr_selections[0].hash != trunks::TPM_ALG_SHA256) {
    LOG(ERROR) << "Creation PCR extended with wrong hash algorithm.";
    return false;
  }
  uint8_t* pcr_selections = pcr_select.pcr_selections[0].pcr_select;
  if (pcr_map.size() != CountSetBits(pcr_selections, PCR_SELECT_MIN)) {
    LOG(ERROR) << "Incorrect creation PCR specified.";
    return false;
  }
  std::string concatenated_pcr_values;
  for (const auto& map_pair : pcr_map) {
    uint32_t pcr_index = map_pair.first;
    const std::string pcr_value = map_pair.second;
    if (pcr_index >= 8 * PCR_SELECT_MIN ||
        (pcr_selections[pcr_index / 8] & (1 << (pcr_index % 8))) == 0) {
      LOG(ERROR) << "Incorrect creation PCR specified.";
      return false;
    }
    concatenated_pcr_values += pcr_value;
  }
  Blob expected_pcr_digest = Sha256(BlobFromString(concatenated_pcr_values));
  if (creation_data.creation_data.pcr_digest.size !=
      expected_pcr_digest.size()) {
    LOG(ERROR) << "Incorrect PCR digest size.";
    return false;
  }
  if (memcmp(creation_data.creation_data.pcr_digest.buffer,
             expected_pcr_digest.data(), expected_pcr_digest.size()) != 0) {
    LOG(ERROR) << "Incorrect PCR digest value.";
    return false;
  }
  // Then we certify that the key was created by the TPM.
  ScopedKeyHandle scoped_handle;
  if (TPMErrorBase err = LoadWrappedKey(key_blob, &scoped_handle)) {
    LOG(ERROR) << "Failed to load wrapped key: " << *err;
    return false;
  }
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->CertifyCreation(
          scoped_handle.value(), creation_blob.to_string()))) {
    LOG(ERROR) << "Error certifying that key was created by TPM: " << *err;
    return false;
  }
  // Finally we verify that the key's policy_digest is the expected value.
  std::unique_ptr<trunks::PolicySession> trial_session =
      trunks->factory->GetTrialSession();
  if (auto err = CreateError<TPM2Error>(
          trial_session->StartUnboundSession(true, true))) {
    LOG(ERROR) << "Error starting a trial session: " << *err;
    return false;
  }
  if (auto err = CreateError<TPM2Error>(trial_session->PolicyPCR(pcr_map))) {
    LOG(ERROR) << "Error restricting trial policy to pcr value: " << *err;
    return false;
  }
  std::string policy_digest;
  if (auto err =
          CreateError<TPM2Error>(trial_session->GetDigest(&policy_digest))) {
    LOG(ERROR) << "Error getting policy digest: " << *err;
    return false;
  }
  trunks::TPMT_PUBLIC public_area;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->GetKeyPublicArea(
          scoped_handle.value(), &public_area))) {
    LOG(ERROR) << "Error getting key public area: " << *err;
    return false;
  }
  if (public_area.auth_policy.size != policy_digest.size()) {
    LOG(ERROR) << "Key auth policy and policy digest are of different length."
               << public_area.auth_policy.size << "," << policy_digest.size();
    return false;
  } else if (memcmp(public_area.auth_policy.buffer, policy_digest.data(),
                    policy_digest.size()) != 0) {
    LOG(ERROR) << "Key auth policy is different from policy digest.";
    return false;
  } else if (public_area.object_attributes & trunks::kUserWithAuth) {
    LOG(ERROR) << "Key authorization is not restricted to policy.";
    return false;
  }
  return true;
}

bool Tpm2Impl::ExtendPCR(uint32_t pcr_index, const Blob& extension) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::unique_ptr<trunks::AuthorizationDelegate> delegate =
      trunks->factory->GetPasswordAuthorization("");
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->ExtendPCR(
          pcr_index, BlobToString(extension), delegate.get()))) {
    LOG(ERROR) << "Error extending PCR: " << *err;
    return false;
  }
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->ExtendPCRForCSME(
          pcr_index, BlobToString(extension)))) {
    LOG(ERROR) << "Error extending PCR for CSME: " << *err;
    return false;
  }
  return true;
}

bool Tpm2Impl::ReadPCR(uint32_t pcr_index, Blob* pcr_value) {
  CHECK(pcr_value);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::string pcr_digest;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->ReadPCR(pcr_index, &pcr_digest))) {
    LOG(ERROR) << "Error reading from PCR: " << *err;
    return false;
  }
  *pcr_value = BlobFromString(pcr_digest);
  return true;
}

bool Tpm2Impl::WrapRsaKey(const SecureBlob& public_modulus,
                          const SecureBlob& prime_factor,
                          SecureBlob* wrapped_key) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  std::string key_blob;
  std::unique_ptr<trunks::AuthorizationDelegate> delegate =
      trunks->factory->GetPasswordAuthorization("");
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->ImportRSAKey(
          trunks::TpmUtility::AsymmetricKeyUsage::kDecryptKey,
          public_modulus.to_string(), kDefaultTpmPublicExponent,
          prime_factor.to_string(),
          "",  // No authorization,
          delegate.get(), &key_blob))) {
    LOG(ERROR) << "Error creating SRK wrapped key: " << *err;
    return false;
  }
  wrapped_key->assign(key_blob.begin(), key_blob.end());
  return true;
}

TPMErrorBase Tpm2Impl::LoadWrappedKey(const SecureBlob& wrapped_key,
                                      ScopedKeyHandle* key_handle) {
  CHECK(key_handle);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }
  trunks::TPM_HANDLE handle;
  std::unique_ptr<trunks::AuthorizationDelegate> delegate =
      trunks->factory->GetPasswordAuthorization("");
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->LoadKey(
          wrapped_key.to_string(), delegate.get(), &handle))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error loading SRK wrapped key");
  }
  key_handle->reset(this, handle);
  return nullptr;
}

bool Tpm2Impl::LegacyLoadCryptohomeKey(ScopedKeyHandle* key_handle,
                                       SecureBlob* key_blob) {
  // This doesn't apply to devices with TPM 2.0.
  return false;
}

void Tpm2Impl::CloseHandle(TpmKeyHandle key_handle) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return;
  }
  trunks->factory->GetTpm()->FlushContext(
      key_handle, nullptr,
      base::BindRepeating(
          [](TpmKeyHandle key_handle, trunks::TPM_RC result) {
            if (auto err = CreateError<TPM2Error>(result)) {
              LOG(WARNING) << "Error flushing tpm handle " << key_handle << ": "
                           << *err;
            }
          },
          key_handle));
}

TPMErrorBase Tpm2Impl::EncryptBlob(TpmKeyHandle key_handle,
                                   const SecureBlob& plaintext,
                                   const SecureBlob& key,
                                   SecureBlob* ciphertext) {
  CHECK(ciphertext);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }
  std::string tpm_ciphertext;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->AsymmetricEncrypt(
          key_handle, trunks::TPM_ALG_OAEP, trunks::TPM_ALG_SHA256,
          plaintext.to_string(), nullptr, &tpm_ciphertext))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error encrypting plaintext");
  }
  if (!ObscureRsaMessage(SecureBlob(tpm_ciphertext), key, ciphertext)) {
    return CreateError<TPMError>("Error obscuring tpm encrypted blob",
                                 TPMRetryAction::kNoRetry);
  }
  return nullptr;
}

TPMErrorBase Tpm2Impl::DecryptBlob(
    TpmKeyHandle key_handle,
    const SecureBlob& ciphertext,
    const SecureBlob& key,
    const std::map<uint32_t, std::string>& pcr_map,
    SecureBlob* plaintext) {
  CHECK(plaintext);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }
  SecureBlob local_data;
  if (!UnobscureRsaMessage(ciphertext, key, &local_data)) {
    return CreateError<TPMError>("Error unobscureing message",
                                 TPMRetryAction::kNoRetry);
  }
  trunks::AuthorizationDelegate* delegate;
  std::unique_ptr<trunks::PolicySession> policy_session;
  std::unique_ptr<trunks::AuthorizationDelegate> default_delegate;
  if (!pcr_map.empty()) {
    policy_session = trunks->factory->GetPolicySession();
    if (auto err = CreateError<TPM2Error>(
            policy_session->StartUnboundSession(true, true))) {
      return CreateErrorWrap<TPMError>(std::move(err),
                                       "Error starting policy session",
                                       TPMRetryAction::kNoRetry);
    }
    if (auto err = CreateError<TPM2Error>(policy_session->PolicyPCR(pcr_map))) {
      return CreateErrorWrap<TPMError>(std::move(err),
                                       "Error creating PCR policy",
                                       TPMRetryAction::kNoRetry);
    }
    delegate = policy_session->GetDelegate();
  } else {
    default_delegate = trunks->factory->GetPasswordAuthorization("");
    delegate = default_delegate.get();
  }

  std::string tpm_plaintext;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->AsymmetricDecrypt(
          key_handle, trunks::TPM_ALG_OAEP, trunks::TPM_ALG_SHA256,
          local_data.to_string(), delegate, &tpm_plaintext))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error decrypting plaintext");
  }
  plaintext->assign(tpm_plaintext.begin(), tpm_plaintext.end());
  return nullptr;
}

TPMErrorBase Tpm2Impl::SealToPcrWithAuthorization(
    const SecureBlob& plaintext,
    const SecureBlob& auth_value,
    const std::map<uint32_t, std::string>& pcr_map,
    SecureBlob* sealed_data) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }

  // Get the policy digest for PCR.
  std::string policy_digest;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->GetPolicyDigestForPcrValues(
              pcr_map, true /* use_auth_value */, &policy_digest))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error getting policy digest");
  }

  std::unique_ptr<trunks::HmacSession> session =
      trunks->factory->GetHmacSession();
  if (auto err =
          CreateError<TPM2Error>(session->StartUnboundSession(true, true))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error starting hmac session");
  }

  std::string sealed_str;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->SealData(
          plaintext.to_string(), policy_digest, auth_value.to_string(),
          session->GetDelegate(), &sealed_str))) {
    return CreateErrorWrap<TPMError>(
        std::move(err), "Error sealing data to PCR with authorization");
  }
  sealed_data->assign(sealed_str.begin(), sealed_str.end());

  return nullptr;
}

TPMErrorBase Tpm2Impl::PreloadSealedData(const brillo::SecureBlob& sealed_data,
                                         ScopedKeyHandle* preload_handle) {
  if (TPMErrorBase err = LoadWrappedKey(sealed_data, preload_handle)) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Failed to load sealed data");
  }
  return nullptr;
}

TPMErrorBase Tpm2Impl::UnsealWithAuthorization(
    base::Optional<TpmKeyHandle> preload_handle,
    const SecureBlob& sealed_data,
    const SecureBlob& auth_value,
    const std::map<uint32_t, std::string>& pcr_map,
    SecureBlob* plaintext) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }

  std::unique_ptr<trunks::PolicySession> policy_session =
      trunks->factory->GetPolicySession();
  // Use unsalted session here, to unseal faster.
  if (auto err = CreateError<TPM2Error>(
          policy_session->StartUnboundSession(false, false))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error starting policy session");
  }
  if (auto err = CreateError<TPM2Error>(policy_session->PolicyAuthValue())) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error setting session to use auth_value");
  }
  if (auto err = CreateError<TPM2Error>(policy_session->PolicyPCR(pcr_map))) {
    return CreateErrorWrap<TPMError>(std::move(err), "Error in PolicyPCR");
  }
  policy_session->SetEntityAuthorizationValue(auth_value.to_string());
  std::string unsealed_data;
  if (preload_handle) {
    if (auto err =
            CreateError<TPM2Error>(trunks->tpm_utility->UnsealDataWithHandle(
                *preload_handle, policy_session->GetDelegate(),
                &unsealed_data))) {
      return CreateErrorWrap<TPMError>(
          std::move(err), "Error unsealing data with authorization");
    }
  } else {
    if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->UnsealData(
            sealed_data.to_string(), policy_session->GetDelegate(),
            &unsealed_data))) {
      return CreateErrorWrap<TPMError>(
          std::move(err), "Error unsealing data with authorization");
    }
  }
  plaintext->assign(unsealed_data.begin(), unsealed_data.end());

  return nullptr;
}

TPMErrorBase Tpm2Impl::GetPublicKeyHash(TpmKeyHandle key_handle,
                                        SecureBlob* hash) {
  CHECK(hash);
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }
  trunks::TPMT_PUBLIC public_data;
  if (auto err = CreateError<TPM2Error>(
          trunks->tpm_utility->GetKeyPublicArea(key_handle, &public_data))) {
    return CreateErrorWrap<TPMError>(std::move(err),
                                     "Error getting key public area");
  }
  std::string public_modulus =
      trunks::StringFrom_TPM2B_PUBLIC_KEY_RSA(public_data.unique.rsa);
  *hash = Sha256(SecureBlob(public_modulus));
  return nullptr;
}

void Tpm2Impl::GetStatus(base::Optional<TpmKeyHandle> key,
                         TpmStatusInfo* status) {
  memset(status, 0, sizeof(TpmStatusInfo));
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return;
  }
  status->this_instance_has_context = true;
  status->this_instance_has_key_handle = key.has_value();
  status->last_tpm_error = trunks->tpm_state->Initialize();
  if (status->last_tpm_error != TPM_RC_SUCCESS) {
    return;
  }
  status->can_connect = true;
  trunks::TPMT_PUBLIC public_srk;
  status->last_tpm_error = trunks->tpm_utility->GetKeyPublicArea(
      trunks::kStorageRootKey, &public_srk);
  if (status->last_tpm_error != TPM_RC_SUCCESS) {
    return;
  }
  status->can_load_srk = true;
  status->can_load_srk_public_key = true;
  status->srk_vulnerable_roca = false;

  // Check the Cryptohome key by using what we have been told.
  status->has_cryptohome_key = key.has_value();

  if (status->has_cryptohome_key) {
    // Check encryption (we don't care about the contents, just whether or not
    // there was an error)
    SecureBlob data(16);
    SecureBlob password(16);
    SecureBlob salt(8);
    SecureBlob data_out(16);
    memset(data.data(), 'A', data.size());
    memset(password.data(), 'B', password.size());
    memset(salt.data(), 'C', salt.size());
    memset(data_out.data(), 'D', data_out.size());
    SecureBlob aes_key;
    PasskeyToAesKey(password, salt, 13, &aes_key, NULL);
    if (TPMErrorBase err = EncryptBlob(key.value(), data, aes_key, &data_out)) {
      LOG(ERROR) << __func__ << ": Failed to encrypt blob: " << *err;
      return;
    }
    status->can_encrypt = true;

    // Check decryption (we don't care about the contents, just whether or not
    // there was an error)
    if (TPMErrorBase err =
            DecryptBlob(key.value(), data_out, aes_key,
                        std::map<uint32_t, std::string>(), &data)) {
      LOG(ERROR) << __func__ << ": Failed to decrypt blob: " << *err;
      return;
    }
    status->can_decrypt = true;
  }
}

base::Optional<bool> Tpm2Impl::IsSrkRocaVulnerable() {
  // This doesn't apply to devices with TPM 2.0.
  return false;
}

bool Tpm2Impl::GetDictionaryAttackInfo(int* counter,
                                       int* threshold,
                                       bool* lockout,
                                       int* seconds_remaining) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->GetDictionaryAttackInfo(
      counter, threshold, lockout, seconds_remaining);
}

bool Tpm2Impl::ResetDictionaryAttackMitigation(
    const Blob& /* delegate_blob */, const Blob& /* delegate_secret */) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->ResetDictionaryAttackLock();
}

void Tpm2Impl::DeclareTpmFirmwareStable() {
  TrunksClientContext* trunks;
  if (!fw_declared_stable_ && GetTrunksContext(&trunks)) {
    auto err =
        CreateError<TPM2Error>(trunks->tpm_utility->DeclareTpmFirmwareStable());
    fw_declared_stable_ = (err == nullptr);
  }
}

bool Tpm2Impl::GetTrunksContext(TrunksClientContext** trunks) {
  if (has_external_trunks_context_) {
    *trunks = &external_trunks_context_;
    return true;
  }
  base::PlatformThreadId thread_id = base::PlatformThread::CurrentId();
  std::map<base::PlatformThreadId,
           std::unique_ptr<Tpm2Impl::TrunksClientContext>>::iterator iter;
  {
    base::AutoLock lock(trunks_contexts_lock_);
    iter = trunks_contexts_.find(thread_id);
    if (iter == trunks_contexts_.end()) {
      auto result = trunks_contexts_.emplace(thread_id, nullptr);
      iter = std::move(result.first);
    }
  }

  // Different elements in the same container can be modified concurrently by
  // different threads, so we don't need to lock this block.
  if (!iter->second) {
    std::unique_ptr<TrunksClientContext> new_context(new TrunksClientContext);
    new_context->factory_impl = std::make_unique<trunks::TrunksFactoryImpl>();
    if (!new_context->factory_impl->Initialize()) {
      LOG(ERROR) << "Failed to initialize trunks factory.";
      return false;
    }
    new_context->factory = new_context->factory_impl.get();
    new_context->tpm_state = new_context->factory->GetTpmState();
    new_context->tpm_utility = new_context->factory->GetTpmUtility();
    iter->second = std::move(new_context);
  }
  *trunks = iter->second.get();
  return true;
}

bool Tpm2Impl::LoadPublicKeyFromSpki(
    const Blob& public_key_spki_der,
    AsymmetricKeyUsage key_type,
    trunks::TPM_ALG_ID scheme,
    trunks::TPM_ALG_ID hash_alg,
    trunks::AuthorizationDelegate* session_delegate,
    ScopedKeyHandle* key_handle) {
  // Parse the SPKI.
  const unsigned char* asn1_ptr = public_key_spki_der.data();
  const crypto::ScopedEVP_PKEY pkey(
      d2i_PUBKEY(nullptr, &asn1_ptr, public_key_spki_der.size()));
  if (!pkey) {
    LOG(ERROR) << "Error parsing Subject Public Key Info DER";
    return false;
  }
  const crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
  if (!rsa) {
    LOG(ERROR) << "Error: non-RSA key was supplied";
    return false;
  }
  SecureBlob key_modulus(RSA_size(rsa.get()));
  const BIGNUM* n;
  const BIGNUM* e;
  RSA_get0_key(rsa.get(), &n, &e, nullptr);
  if (BN_bn2bin(n, key_modulus.data()) != key_modulus.size()) {
    LOG(ERROR) << "Error extracting public key modulus";
    return false;
  }
  constexpr BN_ULONG kInvalidBnWord = ~static_cast<BN_ULONG>(0);
  const BN_ULONG exponent_word = BN_get_word(e);
  if (exponent_word == kInvalidBnWord ||
      !base::IsValueInRangeForNumericType<uint32_t>(exponent_word)) {
    LOG(ERROR) << "Error extracting public key exponent";
    return false;
  }
  const uint32_t key_exponent = static_cast<uint32_t>(exponent_word);
  // Load the key into the TPM.
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks))
    return false;
  trunks::TPM_HANDLE key_handle_raw = 0;
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->LoadRSAPublicKey(
          ConvertAsymmetricKeyUsage(key_type), scheme, hash_alg,
          key_modulus.to_string(), key_exponent, session_delegate,
          &key_handle_raw))) {
    LOG(ERROR) << "Error loading public key: " << *err;
    return false;
  }
  key_handle->reset(this, key_handle_raw);
  return true;
}

bool Tpm2Impl::PublicAreaToPublicKeyDER(const trunks::TPMT_PUBLIC& public_area,
                                        brillo::SecureBlob* public_key_der) {
  crypto::ScopedRSA rsa(RSA_new());
  crypto::ScopedBIGNUM e(BN_new()), n(BN_new());
  if (!rsa || !e || !n) {
    LOG(ERROR) << "Failed to allocate RSA or BIGNUM for public key.";
    return false;
  }
  if (!BN_set_word(e.get(), kDefaultTpmPublicExponent) ||
      !BN_bin2bn(public_area.unique.rsa.buffer, public_area.unique.rsa.size,
                 n.get()) ||
      !RSA_set0_key(rsa.get(), n.release(), e.release(), nullptr)) {
    LOG(ERROR) << "Failed to set up RSA.";
    return false;
  }
  int der_length = i2d_RSAPublicKey(rsa.get(), nullptr);
  if (der_length < 0) {
    LOG(ERROR) << "Failed to get DER-encoded public key length.";
    return false;
  }
  public_key_der->resize(der_length);
  unsigned char* der_buffer = public_key_der->data();
  der_length = i2d_RSAPublicKey(rsa.get(), &der_buffer);
  if (der_length < 0) {
    LOG(ERROR) << "Failed to DER-encode public key.";
    return false;
  }
  return true;
}

TPMErrorBase Tpm2Impl::GetAuthValue(base::Optional<TpmKeyHandle> key_handle,
                                    const SecureBlob& pass_blob,
                                    SecureBlob* auth_value) {
  if (!key_handle) {
    LOG(DFATAL) << "TPM2.0 needs a key_handle to get auth value.";
    return CreateError<TPMError>("TPM2.0 needs a key_handle to get auth value",
                                 TPMRetryAction::kNoRetry);
  }
  if (pass_blob.size() != kDefaultTpmRsaModulusSize / 8) {
    return CreateError<TPMError>(
        "Unexpected pass_blob size: " + std::to_string(pass_blob.size()),
        TPMRetryAction::kNoRetry);
  }

  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return CreateError<TPMError>("Failed to get trunks context",
                                 TPMRetryAction::kNoRetry);
  }

  // To guarantee that pass_blob is lower that public key modulus, just set the
  // first byte to 0.
  std::string value_to_decrypt = pass_blob.to_string();
  value_to_decrypt[0] = 0;
  std::string decrypted_value;
  std::unique_ptr<trunks::AuthorizationDelegate> delegate =
      trunks->factory->GetPasswordAuthorization("");
  if (auto err = CreateError<TPM2Error>(trunks->tpm_utility->AsymmetricDecrypt(
          key_handle.value(), trunks::TPM_ALG_NULL, trunks::TPM_ALG_NULL,
          value_to_decrypt, delegate.get(), &decrypted_value))) {
    return CreateErrorWrap<TPMError>(
        std::move(err), "Error decrypting pass_blob", TPMRetryAction::kNoRetry);
  }
  *auth_value = Sha256(SecureBlob(decrypted_value));

  return nullptr;
}

bool Tpm2Impl::UpdateTpmStatus(RefreshType refresh_type) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }

  bool is_successful = false;
  bool has_received = false;

  // Repeats data copy into |last_tpm_manager_data_|; reasonable trade-off due
  // to low ROI to avoid that.
  const bool is_connected = tpm_manager_utility_->GetOwnershipTakenSignalStatus(
      &is_successful, &has_received, &last_tpm_manager_data_);

  // When we need explicitly query tpm status either because the signal is not
  // ready for any reason, or because the signal is not received yet so we need
  // to run it once in case the signal is sent by tpm_manager before already.
  if (refresh_type == RefreshType::FORCE_REFRESH || !is_connected ||
      !is_successful || (!has_received && shall_cache_tpm_manager_status_)) {
    // Retains |shall_cache_tpm_manager_status_| to be |true| if the signal
    // cannot be relied on (yet). Actually |!is_successful| suffices to update
    // |shall_cache_tpm_manager_status_|; by design, uses the redundancy just to
    // avoid confusion.
    shall_cache_tpm_manager_status_ &= (!is_connected || !is_successful);
    return CacheTpmManagerStatus();
  } else if (has_received) {
    is_enabled_ = true;
    is_owned_ = true;
  }
  return true;
}

bool Tpm2Impl::RemoveOwnerDependency(Tpm::TpmOwnerDependency dependency) {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->RemoveOwnerDependency(
      OwnerDependencyEnumClassToString(dependency));
}

bool Tpm2Impl::ClearStoredPassword() {
  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": Failed to initialize |TpmManagerUtility|.";
    return false;
  }
  return tpm_manager_utility_->ClearStoredOwnerPassword();
}

bool Tpm2Impl::GetVersionInfo(TpmVersionInfo* version_info) {
  if (!version_info) {
    LOG(ERROR) << __func__ << "version_info is not initialized.";
    return false;
  }

  // Version info on a device never changes. Returns from cache directly if we
  // have the cache.
  if (version_info_) {
    *version_info = *version_info_;
    return true;
  }

  if (!InitializeTpmManagerUtility()) {
    LOG(ERROR) << __func__ << ": failed to initialize |TpmManagerUtility|.";
    return false;
  }

  if (!tpm_manager_utility_->GetVersionInfo(
          &version_info->family, &version_info->spec_level,
          &version_info->manufacturer, &version_info->tpm_model,
          &version_info->firmware_version, &version_info->vendor_specific)) {
    LOG(ERROR) << __func__ << ": failed to get version info from tpm_manager.";
    return false;
  }

  version_info_ = *version_info;
  return true;
}

bool Tpm2Impl::GetIFXFieldUpgradeInfo(IFXFieldUpgradeInfo* info) {
  return false;
}

bool Tpm2Impl::GetRsuDeviceId(std::string* device_id) {
  TrunksClientContext* trunks;
  if (!GetTrunksContext(&trunks)) {
    return false;
  }
  return trunks->tpm_utility->GetRsuDeviceId(device_id) == TPM_RC_SUCCESS;
}

LECredentialBackend* Tpm2Impl::GetLECredentialBackend() {
#if USE_PINWEAVER
  return &le_credential_backend_;
#else
  return nullptr;
#endif
}

SignatureSealingBackend* Tpm2Impl::GetSignatureSealingBackend() {
  return &signature_sealing_backend_;
}

bool Tpm2Impl::GetDelegate(brillo::Blob* /*blob*/,
                           brillo::Blob* /*secret*/,
                           bool* has_reset_lock_permissions) {
  LOG(WARNING) << __func__ << ": No-ops to |blob| and |secret|.";
  *has_reset_lock_permissions = true;
  return true;
}

base::Optional<bool> Tpm2Impl::IsDelegateBoundToPcr() {
  return false;
}

bool Tpm2Impl::DelegateCanResetDACounter() {
  return true;
}

std::map<uint32_t, std::string> Tpm2Impl::GetPcrMap(
    const std::string& obfuscated_username, bool use_extended_pcr) const {
  std::map<uint32_t, std::string> pcr_map;
  if (use_extended_pcr) {
    brillo::SecureBlob starting_value(SHA256_DIGEST_LENGTH, 0);
    brillo::SecureBlob digest_value = Sha256(brillo::SecureBlob::Combine(
        starting_value, Sha256(brillo::SecureBlob(obfuscated_username))));
    pcr_map[kTpmSingleUserPCR] = digest_value.to_string();
  } else {
    pcr_map[kTpmSingleUserPCR] = std::string(SHA256_DIGEST_LENGTH, 0);
  }

  return pcr_map;
}

}  // namespace cryptohome
