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

#include "cryptohome/mount_encrypted/tpm.h"

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <type_traits>

#include <base/files/file.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/strings/string_number_conversions.h>

#include <brillo/file_utils.h>
#include <brillo/process/process.h>

#include "cryptohome/cryptolib.h"
#include "cryptohome/mount_encrypted/mount_encrypted.h"

namespace mount_encrypted {
namespace {

const uint32_t kLockboxSaltOffset = 0x5;

// Attributes for the encstatful NVRAM space. Ideally, we'd set
// TPM_NV_PER_OWNERWRITE so the space gets automatically destroyed when the TPM
// gets cleared. That'd mean we'd have to recreate the NVRAM space on next boot
// though, which requires TPM ownership. Taking ownership is notoriously slow,
// so we can't afford to do this. Instead, we keep the space allocated and
// detect TPM clear to regenerate the system key.
const uint32_t kAttributes = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_READ_STCLEAR;

const uint32_t kAttributesMask =
    TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_AUTHREAD | TPM_NV_PER_OWNERREAD |
    TPM_NV_PER_PPREAD | TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_WRITE_STCLEAR |
    TPM_NV_PER_WRITEDEFINE | TPM_NV_PER_WRITEALL | TPM_NV_PER_AUTHWRITE |
    TPM_NV_PER_OWNERWRITE | TPM_NV_PER_PPWRITE;

// Key derivation labels.
const char kLabelSystemKey[] = "system_key";
const char kLabelLockboxMAC[] = "lockbox_mac";

// This is the well-known secret (SHA-1 hash of 20 zero bytes) that TrouSerS
// sets by default when taking ownership. We use the same value here to simplify
// the logic in cryptohomed.
const uint8_t kWellKnownSecret[TPM_AUTH_DATA_LEN] = {
    0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
    0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
};

// This struct defines the memory layout of the NVRAM area. Member sizes are
// chosen taking layout into consideration.
struct EncStatefulArea {
  enum class Flag {
    // The |lockbox_mac| field is valid and contains a MAC of the lockbox NVRAM
    // area contents.
    kLockboxMacValid = 0,
    // We are expecting another TPM clear to take place for which preservation
    // will be allowed. This is used to handle the TPM clear following a TPM
    // firmware update.
    kAnticipatingTPMClear = 1,
  };

  static constexpr uint32_t kMagic = 0x54504d31;

  static constexpr size_t kVersionShift = 8;
  static constexpr uint32_t kVersionMask = (1 << kVersionShift) - 1;

  static constexpr uint32_t kCurrentVersion = 1;

  uint32_t magic;
  uint32_t ver_flags;
  uint8_t key_material[DIGEST_LENGTH];
  uint8_t lockbox_mac[DIGEST_LENGTH];

  bool is_valid() const {
    return magic == kMagic && (ver_flags & kVersionMask) == kCurrentVersion;
  }

  static uint32_t flag_value(Flag flag) {
    return (1 << (static_cast<size_t>(flag) + kVersionShift));
  }

  bool test_flag(Flag flag) const { return ver_flags & flag_value(flag); }
  void set_flag(Flag flag) { ver_flags |= flag_value(flag); }
  void clear_flag(Flag flag) { ver_flags &= ~flag_value(flag); }

  result_code Init(const brillo::SecureBlob& new_key_material) {
    magic = kMagic;
    ver_flags = kCurrentVersion;

    size_t key_material_size = new_key_material.size();
    if (key_material_size != sizeof(key_material)) {
      LOG(ERROR) << "Invalid key material size " << key_material_size;
      return RESULT_FAIL_FATAL;
    }
    memcpy(key_material, new_key_material.data(), key_material_size);

    memset(lockbox_mac, 0, sizeof(lockbox_mac));
    return RESULT_SUCCESS;
  }

  brillo::SecureBlob DeriveKey(const std::string& label) const {
    return cryptohome::CryptoLib::HmacSha256(
        brillo::SecureBlob(key_material, key_material + sizeof(key_material)),
        brillo::Blob(label.data(), label.data() + label.size()));
  }
};

// We're using casts to map the EncStatefulArea struct to NVRAM contents, so
// make sure to keep this a POD type.
static_assert(std::is_pod<EncStatefulArea>(),
              "EncStatefulArea must be a POD type");

// Make sure that the EncStatefulArea struct fits the encstateful NVRAM space.
static_assert(kEncStatefulSize >= sizeof(EncStatefulArea),
              "EncStatefulArea must fit within encstateful NVRAM space");

}  // namespace

const uint8_t* kOwnerSecret = kWellKnownSecret;
const size_t kOwnerSecretSize = sizeof(kWellKnownSecret);

// System key loader implementation for TPM1 systems. This supports two
// different sources of obtaining system key material: A dedicated NVRAM space
// (called the "encstateful NVRAM space" below) and the "salt" in the lockbox
// space. We prefer the former if it is available.
class Tpm1SystemKeyLoader : public SystemKeyLoader {
 public:
  Tpm1SystemKeyLoader(Tpm* tpm, const base::FilePath& rootdir)
      : tpm_(tpm), rootdir_(rootdir) {}
  Tpm1SystemKeyLoader(const Tpm1SystemKeyLoader&) = delete;
  Tpm1SystemKeyLoader& operator=(const Tpm1SystemKeyLoader&) = delete;

  result_code Load(brillo::SecureBlob* key) override;
  result_code Initialize(const brillo::SecureBlob& key_material,
                         brillo::SecureBlob* derived_system_key) override;
  result_code Persist() override;
  void Lock() override;
  result_code SetupTpm() override;
  result_code GenerateForPreservation(brillo::SecureBlob* previous_key,
                                      brillo::SecureBlob* fresh_key) override;
  result_code CheckLockbox(bool* valid) override;
  bool UsingLockboxKey() override;

 private:
  // Gets a pointer to the EncStatefulArea structure backed by NVRAM.
  result_code LoadEncStatefulArea(const EncStatefulArea** area);

  // Loads the key from the encstateful NVRAM space.
  result_code LoadEncStatefulKey(brillo::SecureBlob* key);

  // Loads the key from the lockbox NVRAM space.
  result_code LoadLockboxKey(brillo::SecureBlob* key);

  // Validates the encstateful space is defined with correct parameters.
  result_code IsEncStatefulSpaceProperlyDefined(bool* result);

  // Obtains and formats TPM version info as key-value pairs.
  std::string FormatVersionInfo();

  // Obtains and formats IFX field upgrade status as key-value pairs.
  std::string FormatIFXFieldUpgradeInfo();

  // Check whether a TPM firmware update is pending. Returns true if there is an
  // update, false if no pending update and on errors.
  bool IsTPMFirmwareUpdatePending();

  Tpm* tpm_ = nullptr;
  base::FilePath rootdir_;

  // Provisional space contents that get initialized by Generate() and written
  // to the NVRAM space by Persist();
  std::unique_ptr<brillo::SecureBlob> provisional_contents_;

  // Whether we're using the lockbox salt as system key.
  bool using_lockbox_key_ = false;
};

// TPM cases:
//  - does not exist at all (disabled in test firmware or non-chrome device).
//  - exists (below).
//
// TPM ownership cases:
//  - unowned (OOBE):
//    - expect modern lockbox.
//  - owned: depends on NVRAM area (below).
//
// NVRAM area cases:
//  - no NVRAM area at all:
//    - interrupted install (cryptohome has the TPM password)
//    - ancient device (cr48, cryptohome has thrown away TPM password)
//    - broken device (cryptohome has thrown away/never had TPM password)
//      - must expect worst-case: no lockbox ever.
//  - defined NVRAM area, but not written to ("Finalized"); interrupted OOBE.
//  - written ("Finalized") NVRAM area.
//
// In case of success: (NVRAM area found and used)
//  - *system_key populated with NVRAM area entropy.
// In case of failure: (NVRAM missing or error)
//  - *system_key untouched.
result_code Tpm1SystemKeyLoader::Load(brillo::SecureBlob* system_key) {
  bool space_properly_defined = false;
  result_code rc = IsEncStatefulSpaceProperlyDefined(&space_properly_defined);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  // Prefer the encstateful space if it is set up correctly.
  if (space_properly_defined) {
    // Only load the key if we are sure that we have generated a fresh key after
    // the last TPM clear. After a clear, the TPM has no owner. In unowned state
    // we rely on a flag we store persistently in the TPM to indicate whether we
    // have generated a key already (note that the TPM automatically clears the
    // flag on TPM clear).
    bool system_key_initialized = false;
    rc = tpm_->HasSystemKeyInitializedFlag(&system_key_initialized);
    if (rc != RESULT_SUCCESS) {
      return rc;
    }

    if (system_key_initialized) {
      rc = LoadEncStatefulKey(system_key);
      if (rc == RESULT_SUCCESS) {
        return RESULT_SUCCESS;
      }
    }
  } else {
    // The lockbox NVRAM space is created by cryptohomed and only valid after
    // TPM ownership has been established.
    bool owned = false;
    result_code rc = tpm_->IsOwned(&owned);
    if (rc != RESULT_SUCCESS) {
      LOG(ERROR) << "Failed to determine TPM ownership.";
      return rc;
    }

    if (owned) {
      rc = LoadLockboxKey(system_key);
      if (rc == RESULT_SUCCESS) {
        using_lockbox_key_ = true;
        return RESULT_SUCCESS;
      }
    }
  }

  return RESULT_FAIL_FATAL;
}

result_code Tpm1SystemKeyLoader::Initialize(
    const brillo::SecureBlob& key_material,
    brillo::SecureBlob* derived_system_key) {
  provisional_contents_ =
      std::make_unique<brillo::SecureBlob>(sizeof(EncStatefulArea));
  EncStatefulArea* area =
      reinterpret_cast<EncStatefulArea*>(provisional_contents_->data());

  result_code rc = area->Init(key_material);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  if (derived_system_key) {
    *derived_system_key = area->DeriveKey(kLabelSystemKey);
  }

  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::Persist() {
  CHECK(provisional_contents_);

  bool space_defined_properly = false;
  result_code rc = IsEncStatefulSpaceProperlyDefined(&space_defined_properly);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  if (!space_defined_properly) {
    return RESULT_FAIL_FATAL;
  }

  NvramSpace* encstateful_space = tpm_->GetEncStatefulSpace();
  rc = encstateful_space->Write(*provisional_contents_);
  if (rc != RESULT_SUCCESS) {
    LOG(ERROR) << "Failed to write NVRAM area";
    return rc;
  }

  rc = tpm_->SetSystemKeyInitializedFlag();
  if (rc != RESULT_SUCCESS) {
    LOG(ERROR) << "Failed to create placeholder delegation entry.";
    return rc;
  }

  using_lockbox_key_ = false;
  return RESULT_SUCCESS;
}

void Tpm1SystemKeyLoader::Lock() {
  NvramSpace* encstateful_space = tpm_->GetEncStatefulSpace();
  if (!encstateful_space->is_valid()) {
    return;
  }

  if (encstateful_space->WriteLock() != RESULT_SUCCESS) {
    LOG(ERROR) << "Failed to write-lock NVRAM area.";
  }
  if (encstateful_space->ReadLock() != RESULT_SUCCESS) {
    LOG(ERROR) << "Failed to read-lock NVRAM area.";
  }
}

result_code Tpm1SystemKeyLoader::SetupTpm() {
  bool is_properly_defined = false;
  result_code rc = IsEncStatefulSpaceProperlyDefined(&is_properly_defined);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  if (is_properly_defined) {
    return RESULT_SUCCESS;
  }

  // We need to take ownership and redefine the space.
  LOG(INFO) << "Redefining encrypted stateful space.";

  bool owned = false;
  rc = tpm_->IsOwned(&owned);
  if (rc != RESULT_SUCCESS) {
    LOG(ERROR) << "Can't determine TPM ownership.";
    return RESULT_FAIL_FATAL;
  }

  if (!owned) {
    // Reset cryptohomed state so it re-initializes the TPM.
    base::FilePath tpm_status_path =
        rootdir_.AppendASCII(paths::cryptohome::kTpmStatus);
    base::FilePath tpm_owned_path =
        rootdir_.AppendASCII(paths::cryptohome::kTpmOwned);
    base::FilePath shall_initialize_path =
        rootdir_.AppendASCII(paths::cryptohome::kShallInitialize);
    base::FilePath attestation_database_path =
        rootdir_.AppendASCII(paths::cryptohome::kAttestationDatabase);
    if (!base::DeleteFile(tpm_status_path) ||
        !base::DeleteFile(tpm_owned_path) ||
        !brillo::SyncFileOrDirectory(tpm_status_path.DirName(), true, false) ||
        !brillo::WriteToFileAtomic(shall_initialize_path, nullptr, 0, 0644) ||
        !brillo::SyncFileOrDirectory(shall_initialize_path.DirName(), true,
                                     false) ||
        !base::DeleteFile(attestation_database_path)) {
      PLOG(ERROR) << "Failed to update cryptohomed state.";
      return RESULT_FAIL_FATAL;
    }

    result_code rc = tpm_->TakeOwnership();
    if (rc != RESULT_SUCCESS) {
      LOG(ERROR) << "Failed to ensure TPM ownership.";
      return rc;
    }
  }

  uint32_t pcr_selection = (1 << kPCRBootMode);
  rc = tpm_->GetEncStatefulSpace()->Define(kAttributes, sizeof(EncStatefulArea),
                                           pcr_selection);
  if (rc != RESULT_SUCCESS) {
    LOG(ERROR) << "Failed to define encrypted stateful NVRAM space.";
    return rc;
  }

  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::GenerateForPreservation(
    brillo::SecureBlob* previous_key, brillo::SecureBlob* fresh_key) {
  // Determine whether we may preserve the encryption key that was in use before
  // the TPM got cleared. Preservation is allowed if either (1) a TPM firmware
  // update is pending and has been requested for installation or (2) we've
  // taken a note in NVRAM space flags to anticipate a TPM clear. Condition (2)
  // covers the TPM clear that follows installation of the firmware update. We'd
  // prefer to handle that case by testing whether we actually just went through
  // an update, but there's no trustworthy post-factum signal to tell us.
  const EncStatefulArea* area = nullptr;
  bool tpm_firmware_update_pending = false;
  result_code rc = LoadEncStatefulArea(&area);
  if (rc != RESULT_SUCCESS ||
      !area->test_flag(EncStatefulArea::Flag::kAnticipatingTPMClear)) {
    tpm_firmware_update_pending = IsTPMFirmwareUpdatePending();
    if (!tpm_firmware_update_pending) {
      return RESULT_FAIL_FATAL;
    }
  }

  // Load the previous system key.
  rc = LoadEncStatefulKey(previous_key);
  if (rc != RESULT_SUCCESS) {
    rc = LoadLockboxKey(previous_key);
    if (rc != RESULT_SUCCESS) {
      return RESULT_FAIL_FATAL;
    }
  }

  // Generate new encstateful contents.
  provisional_contents_ =
      std::make_unique<brillo::SecureBlob>(sizeof(EncStatefulArea));
  EncStatefulArea* provisional_area =
      reinterpret_cast<EncStatefulArea*>(provisional_contents_->data());

  const auto key_material =
      cryptohome::CryptoLib::CreateSecureRandomBlob(DIGEST_LENGTH);
  rc = provisional_area->Init(key_material);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  // Set the flag to anticipate another TPM clear for the case where we're
  // preserving for the installation of a TPM firmware update.
  if (tpm_firmware_update_pending) {
    provisional_area->set_flag(EncStatefulArea::Flag::kAnticipatingTPMClear);
  }

  // We need to leave the TPM in a state with owner auth available. However,
  // when preserving the state of the system, we must guarantee lockbox
  // integrity. To achieve lockbox tamper evidence, we store a MAC of the
  // lockbox space in the encstateful space, which gets locked to prevent
  // further manipulation in Lock(). We can thus re-check lockbox contents are
  // legit at next reboot by verifying the MAC.
  provisional_area->set_flag(EncStatefulArea::Flag::kLockboxMacValid);
  NvramSpace* lockbox_space = tpm_->GetLockboxSpace();
  if (lockbox_space->is_valid()) {
    brillo::SecureBlob mac = cryptohome::CryptoLib::HmacSha256(
        provisional_area->DeriveKey(kLabelLockboxMAC),
        lockbox_space->contents());
    memcpy(provisional_area->lockbox_mac, mac.data(), mac.size());
  }

  *fresh_key = provisional_area->DeriveKey(kLabelSystemKey);
  using_lockbox_key_ = false;
  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::LoadEncStatefulArea(
    const EncStatefulArea** area) {
  NvramSpace* space = tpm_->GetEncStatefulSpace();
  if (!space->is_valid()) {
    LOG(ERROR) << "Invalid encstateful space.";
    return RESULT_FAIL_FATAL;
  }

  *area = reinterpret_cast<const EncStatefulArea*>(space->contents().data());
  if (!(*area)->is_valid()) {
    LOG(ERROR) << "Invalid encstateful contents.";
    return RESULT_FAIL_FATAL;
  }

  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::LoadEncStatefulKey(
    brillo::SecureBlob* system_key) {
  const EncStatefulArea* area = nullptr;
  result_code rc = LoadEncStatefulArea(&area);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  *system_key = area->DeriveKey(kLabelSystemKey);
  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::LoadLockboxKey(
    brillo::SecureBlob* system_key) {
  brillo::SecureBlob key_material;
  NvramSpace* lockbox_space = tpm_->GetLockboxSpace();
  const brillo::SecureBlob& lockbox_contents = lockbox_space->contents();
  if (!lockbox_space->is_valid()) {
    return RESULT_FAIL_FATAL;
  } else if (lockbox_contents.size() == kLockboxSizeV1) {
    key_material = lockbox_contents;
  } else if (kLockboxSaltOffset + DIGEST_LENGTH <= lockbox_contents.size()) {
    const uint8_t* begin = lockbox_contents.data() + kLockboxSaltOffset;
    key_material.assign(begin, begin + DIGEST_LENGTH);
  } else {
    LOG(INFO) << "Impossibly small NVRAM area size (" << lockbox_contents.size()
              << ").";
    return RESULT_FAIL_FATAL;
  }

  *system_key = cryptohome::CryptoLib::Sha256(key_material);
  return RESULT_SUCCESS;
}

result_code Tpm1SystemKeyLoader::IsEncStatefulSpaceProperlyDefined(
    bool* result) {
  *result = false;

  NvramSpace* encstateful_space = tpm_->GetEncStatefulSpace();
  if (!encstateful_space->is_valid() ||
      encstateful_space->contents().size() < sizeof(EncStatefulArea)) {
    LOG(ERROR) << "encstateful space contents absent or too short.";
    return RESULT_SUCCESS;
  }

  uint32_t attributes;
  result_code rc = encstateful_space->GetAttributes(&attributes);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  if ((attributes & kAttributesMask) != kAttributes) {
    LOG(ERROR) << "Bad encstateful space attributes.";
    return rc;
  }

  uint32_t pcr_selection = (1 << kPCRBootMode);
  bool pcr_binding_correct = false;
  rc = encstateful_space->CheckPCRBinding(pcr_selection, &pcr_binding_correct);
  if (rc != RESULT_SUCCESS) {
    LOG(ERROR) << "Bad encstateful PCR binding.";
    return rc;
  }

  *result = pcr_binding_correct;
  return RESULT_SUCCESS;
}

std::string Tpm1SystemKeyLoader::FormatVersionInfo() {
  uint32_t vendor;
  uint64_t firmware_version;
  std::vector<uint8_t> vendor_specific;
  if (!tpm_->GetVersionInfo(&vendor, &firmware_version, &vendor_specific)) {
    return std::string();
  }

  return base::StringPrintf(
      "vendor %08x\nfirmware_version %016" PRIx64 "\nvendor_specific %s",
      vendor, firmware_version,
      base::HexEncode(vendor_specific.data(), vendor_specific.size()).c_str());
}

std::string Tpm1SystemKeyLoader::FormatIFXFieldUpgradeInfo() {
  TPM_IFX_FIELDUPGRADEINFO info;
  if (!tpm_->GetIFXFieldUpgradeInfo(&info)) {
    return std::string();
  }

  auto format_fw_pkg = [](const TPM_IFX_FIRMWAREPACKAGE& firmware_package,
                          const char* prefix) {
    return base::StringPrintf(
        "%s_package_id %08x\n"
        "%s_version %08x\n"
        "%s_stale_version %08x\n",
        prefix, firmware_package.FwPackageIdentifier, prefix,
        firmware_package.Version, prefix, firmware_package.StaleVersion);
  };

  return base::StringPrintf(
      "max_data_size %u\n"
      "%s"
      "%s"
      "%s"
      "status %04x\n"
      "%s"
      "field_upgrade_counter %u\n",
      info.wMaxDataSize,
      format_fw_pkg(info.sBootloaderFirmwarePackage, "bootloader").c_str(),
      format_fw_pkg(info.sFirmwarePackages[0], "fw0").c_str(),
      format_fw_pkg(info.sFirmwarePackages[1], "fw1").c_str(),
      info.wSecurityModuleStatus,
      format_fw_pkg(info.sProcessFirmwarePackage, "process_fw").c_str(),
      info.wFieldUpgradeCounter);
}

bool Tpm1SystemKeyLoader::IsTPMFirmwareUpdatePending() {
  // Make sure a TPM firmware upgrade has been requested.
  if (!base::PathExists(rootdir_.AppendASCII(paths::kFirmwareUpdateRequest))) {
    LOG(ERROR) << "TPM firmware update wasn't requested.";
    return false;
  }

  // Obtain version and upgrade status information to pass to the locator tool.
  std::string version_info = FormatVersionInfo();
  std::string ifx_field_upgrade_info = FormatIFXFieldUpgradeInfo();
  if (version_info.empty() || ifx_field_upgrade_info.empty()) {
    return false;
  }

  // Launch the update locator script.
  brillo::ProcessImpl tpm_firmware_update_locator;
  tpm_firmware_update_locator.SetCloseUnusedFileDescriptors(true);
  tpm_firmware_update_locator.RedirectUsingPipe(STDOUT_FILENO, false);
  tpm_firmware_update_locator.AddArg(
      rootdir_.AppendASCII(paths::kFirmwareUpdateLocator).value());
  tpm_firmware_update_locator.AddArg(version_info);
  tpm_firmware_update_locator.AddArg(ifx_field_upgrade_info);
  if (!tpm_firmware_update_locator.Start()) {
    LOG(ERROR) << "Failed to start update locator child process";
    return false;
  }

  // Read the output.
  {
    base::File pipe(tpm_firmware_update_locator.GetPipe(STDOUT_FILENO));
    char update_location[PATH_MAX];
    int bytes_read =
        pipe.ReadAtCurrentPos(update_location, sizeof(update_location));
    if (bytes_read <= 0) {
      LOG(ERROR) << "Failed to read update location from pipe.";
      return false;
    }

    // Check that the update location file exists.
    char* newline_pos = strchr(update_location, '\n');
    if (newline_pos) {
      *newline_pos = '\0';
    }
    base::FilePath update_path(update_location);
    LOG(INFO) << "Checking whether "
              << rootdir_.AppendASCII(paths::kFirmwareDir) << " is a parent of "
              << update_path;
    if (!rootdir_.AppendASCII(paths::kFirmwareDir).IsParent(update_path) ||
        !base::PathExists(update_path)) {
      LOG(ERROR) << "Failure locating TPM firmware update file.";
      return false;
    }
  }

  // Make sure the locator script terminated cleanly.
  if (tpm_firmware_update_locator.Wait() != 0) {
    LOG(ERROR) << "TPM firmware update locator utility failed.";
    return false;
  }

  return true;
}

result_code Tpm1SystemKeyLoader::CheckLockbox(bool* valid) {
  *valid = false;

  bool space_properly_defined = false;
  result_code rc = IsEncStatefulSpaceProperlyDefined(&space_properly_defined);
  if (rc != RESULT_SUCCESS) {
    return rc;
  }

  if (space_properly_defined) {
    // Check whether the encstateful space contains a valid lockbox MAC. Check
    // the actual lockbox contents against the MAC, reset the lockbox space to
    // invalid so subsequent code won't use it (specifically, the lockbox space
    // won't get exported for OS consumption).
    //
    // This addresses the scenario where the TPM is left in unowned state or
    // owned with the well-known password after preservation. The requirement is
    // that the lockbox contents may only change at full device reset (e.g.
    // implying stateful file system loss). However, stateful preservation
    // carries over state, so it needs to ensure the lockbox stays locked. Due
    // to the TPM state, the lockbox space could get redefined and thus written
    // to after preservation. The MAC check here doesn't disallow this, but it
    // ensures tamper-evidence: Modified lockbox contents will cause MAC
    // validation failure, so the lockbox will be considered invalid. Note that
    // attempts at adjusting the MAC to match tampered lockbox contents are
    // prevented by locking the encstateful space after boot.
    const EncStatefulArea* area = nullptr;
    rc = LoadEncStatefulArea(&area);
    switch (rc) {
      case RESULT_SUCCESS:
        if (area->test_flag(EncStatefulArea::Flag::kLockboxMacValid)) {
          NvramSpace* lockbox_space = tpm_->GetLockboxSpace();
          if (lockbox_space->is_valid()) {
            brillo::SecureBlob mac = cryptohome::CryptoLib::HmacSha256(
                area->DeriveKey(kLabelLockboxMAC), lockbox_space->contents());
            *valid = brillo::SecureMemcmp(area->lockbox_mac, mac.data(),
                                          mac.size()) == 0;
            return RESULT_SUCCESS;
          }
        }
        break;
      case RESULT_FAIL_FATAL:
        // Encstateful contents invalid, so lockbox MAC doesn't apply.
        break;
      default:
        return rc;
    }
  }

  // In case there is no encstateful space, the lockbox space is only valid once
  // cryptohomed has taken TPM ownership and recreated the space.
  return tpm_->IsOwned(valid);
}

bool Tpm1SystemKeyLoader::UsingLockboxKey() {
  return using_lockbox_key_;
}

std::unique_ptr<SystemKeyLoader> SystemKeyLoader::Create(
    Tpm* tpm, const base::FilePath& rootdir) {
  return std::make_unique<Tpm1SystemKeyLoader>(tpm, rootdir);
}

}  // namespace mount_encrypted
