// 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 "biod/crypto_init/bio_crypto_init.h"

#include <fcntl.h>
#include <sys/types.h>

#include <algorithm>
#include <vector>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/process/process.h>
#include <brillo/daemons/daemon.h>
#include <brillo/secure_blob.h>
#include <brillo/syslog_logging.h>

#include "biod/cros_fp_device.h"
#include "biod/ec_command.h"

namespace biod {

// Helper function to ensure data of a file is removed.
bool BioCryptoInit::NukeFile(const base::FilePath& filepath) {
  // Write all zeros to the FD.
  bool ret = true;
  std::vector<uint8_t> zero_vec(FpSeedCommand::kTpmSeedSize, 0);
  if (base::WriteFile(filepath, reinterpret_cast<const char*>(zero_vec.data()),
                      FpSeedCommand::kTpmSeedSize) !=
      FpSeedCommand::kTpmSeedSize) {
    PLOG(ERROR) << "Failed to write all-zero to tmpfs file.";
    ret = false;
  }

  if (!base::DeleteFile(filepath)) {
    PLOG(ERROR) << "Failed to delete TPM seed file: " << filepath.value();
    ret = false;
  }

  return ret;
}

bool BioCryptoInit::WriteSeedToCrosFp(const brillo::SecureVector& seed) {
  if (!InitCrosFp()) {
    return false;
  }

  base::Optional<uint32_t> firmware_fp_template_format_version =
      GetFirmwareTemplateVersion();
  if (!firmware_fp_template_format_version.has_value()) {
    return false;
  }

  if (!CrosFpTemplateVersionCompatible(*firmware_fp_template_format_version,
                                       FP_TEMPLATE_FORMAT_VERSION)) {
    LOG(ERROR) << "Incompatible template version between FPMCU ("
               << *firmware_fp_template_format_version << ") and biod ("
               << FP_TEMPLATE_FORMAT_VERSION << ").";
    return false;
  }

  auto fp_seed_cmd = ec_command_factory_->FpSeedCommand(
      seed, *firmware_fp_template_format_version);

  if (!fp_seed_cmd->Run(cros_fp_fd_.get())) {
    LOG(ERROR) << "Failed to set TPM seed.";
    return false;
  }

  LOG(INFO) << "Successfully set FP seed.";

  return true;
}

bool BioCryptoInit::DoProgramSeed(const brillo::SecureVector& tpm_seed) {
  bool ret = true;

  if (!WriteSeedToCrosFp(tpm_seed)) {
    LOG(ERROR) << "Failed to send seed to CrOS FP device.";
    ret = false;
  }

  return ret;
}

base::ScopedFD BioCryptoInit::OpenCrosFpDevice() {
  return base::ScopedFD(
      open(biod::CrosFpDevice::kCrosFpPath, O_RDWR | O_CLOEXEC));
}

bool BioCryptoInit::WaitOnEcBoot(const base::ScopedFD& cros_fp_fd,
                                 ec_image expected_image) {
  return biod::CrosFpDevice::WaitOnEcBoot(cros_fp_fd, expected_image);
}

bool BioCryptoInit::CrosFpTemplateVersionCompatible(
    const uint32_t firmware_fp_template_format_version,
    const uint32_t biod_fp_template_format_version) {
  // We should modify the rule here when we uprev the template format version.
  switch (firmware_fp_template_format_version) {
    case 3:
    case 4:
      break;
    default:
      return false;
  }
  switch (biod_fp_template_format_version) {
    case 3:
    case 4:
      break;
    default:
      return false;
  }
  // If biod has template version 4, firmware with version 3 is still
  // compatible until we deprecate it.
  if (firmware_fp_template_format_version == 3 &&
      biod_fp_template_format_version == 4)
    return true;
  return firmware_fp_template_format_version == biod_fp_template_format_version;
}

bool BioCryptoInit::InitCrosFp() {
  cros_fp_fd_ = OpenCrosFpDevice();
  if (!cros_fp_fd_.is_valid()) {
    PLOG(ERROR) << "Couldn't open FP device for ioctl.";
    return false;
  }

  if (!WaitOnEcBoot(cros_fp_fd_, EC_IMAGE_RW)) {
    LOG(ERROR) << "FP device did not boot to RW.";
    return false;
  }

  return true;
}

base::Optional<uint32_t> BioCryptoInit::GetFirmwareTemplateVersion() {
  auto fp_info_cmd = ec_command_factory_->FpInfoCommand();
  if (!fp_info_cmd->RunWithMultipleAttempts(
          cros_fp_fd_.get(), biod::CrosFpDevice::kMaxIoAttempts)) {
    LOG(ERROR) << "Checking template format compatibility: failed to get FP "
                  "information.";
    return base::nullopt;
  }

  return fp_info_cmd->template_info()->version;
}

}  // namespace biod
