// 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.
//
// This is a program to set the various biometric managers with a TPM
// seed obtained from the TPM hardware. It is expected to execute once
// on every boot.
// This binary is expected to be called from the mount-encrypted utility
// during boot.
// It is expected to receive the tpm seed buffer from mount-encrypted via a
// file written to tmpfs. The FD for the tmpfs file is mapped to STDIN_FILENO
// by mount-encrypted. It is considered to have been unlinked by
// mount-encrypted. Consequently, closing the FD should be enough to delete
// the file.

#include "biod/tools/bio_crypto_init.h"

#include <fcntl.h>
#include <sys/stat.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 <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/daemons/daemon.h>
#include <brillo/flag_helper.h>
#include <brillo/secure_blob.h>
#include <brillo/syslog_logging.h>

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

namespace {

constexpr int64_t kTimeoutSeconds = 30;
constexpr int64_t kTpmSeedSize = FP_CONTEXT_TPM_BYTES;
// File where the TPM seed is stored, that we have to read from.
constexpr char kBioTpmSeedTmpFile[] = "/run/bio_crypto_init/seed";

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

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

  return ret;
}

bool WriteSeedToCrosFp(const brillo::SecureBlob& seed) {
  bool ret = true;
  auto fd =
      base::ScopedFD(open(biod::CrosFpDevice::kCrosFpPath, O_RDWR | O_CLOEXEC));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "Couldn't open FP device for ioctl.";
    return false;
  }

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

  biod::EcCommand<biod::EmptyParam, struct ec_response_fp_info> cmd_fp_info(
      EC_CMD_FP_INFO, biod::kVersionOne);
  if (!cmd_fp_info.RunWithMultipleAttempts(
          fd.get(), biod::CrosFpDevice::kMaxIoAttempts)) {
    LOG(ERROR) << "Checking template format compatibility: failed to get FP "
                  "information.";
    return false;
  }

  const uint32_t firmware_fp_template_format_version =
      cmd_fp_info.Resp()->template_version;
  if (!biod::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;
  }

  biod::EcCommand<struct ec_params_fp_seed, biod::EmptyParam> cmd_seed(
      EC_CMD_FP_SEED);
  struct ec_params_fp_seed* req = cmd_seed.Req();
  // We have ensured that the format versions of the firmware and biod are
  // compatible, so use the format version of the firmware.
  req->struct_version =
      static_cast<uint16_t>(firmware_fp_template_format_version);
  std::copy(seed.char_data(), seed.char_data() + sizeof(req->seed), req->seed);

  if (!cmd_seed.Run(fd.get())) {
    LOG(ERROR) << "Failed to set TPM seed.";
    ret = false;
  } else {
    LOG(INFO) << "Successfully set FP seed.";
  }
  std::fill(req->seed, req->seed + sizeof(req->seed), 0);
  // Clear intermediate buffers. We expect the command to fail since the SBP
  // will reject the new seed.
  cmd_seed.Run(fd.get());

  return ret;
}

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

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

  return ret;
}

}  // namespace

int main(int argc, char* argv[]) {
  // Set up logging settings.
  DEFINE_string(log_dir, "/var/log/bio_crypto_init",
                "Directory where logs are written.");

  brillo::FlagHelper::Init(argc, argv,
                           "bio_crypto_init, the Chromium OS binary to program "
                           "bio sensors with TPM secrets.");

  const auto log_dir_path = base::FilePath(FLAGS_log_dir);
  const auto log_file_path = log_dir_path.Append(base::StringPrintf(
      "bio_crypto_init.%s",
      brillo::GetTimeAsLogString(base::Time::Now()).c_str()));

  brillo::UpdateLogSymlinks(log_dir_path.Append("bio_crypto_init.LATEST"),
                            log_dir_path.Append("bio_crypto_init.PREVIOUS"),
                            log_file_path);

  logging::LoggingSettings logging_settings;
  logging_settings.logging_dest = logging::LOG_TO_FILE;
#if BASE_VER < 780000
  logging_settings.log_file = log_file_path.value().c_str();
#else
  logging_settings.log_file_path = log_file_path.value().c_str();
#endif
  logging_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
  logging_settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  logging::InitLogging(logging_settings);
  logging::SetLogItems(true,    // process ID
                       true,    // thread ID
                       true,    // timestamp
                       false);  // tickcount

  biod::LogVersion();

  // We fork the process so that can we program the seed in the child, and
  // terminate it if it hangs.
  pid_t pid = fork();
  if (pid == -1) {
    PLOG(ERROR) << "Failed to fork child process for bio_wash.";
    NukeFile(base::FilePath(kBioTpmSeedTmpFile));
    return -1;
  }

  if (pid == 0) {
    // The first thing we do is read the buffer, and delete the file.
    brillo::SecureBlob tpm_seed(kTpmSeedSize);
    int bytes_read = base::ReadFile(base::FilePath(kBioTpmSeedTmpFile),
                                    tpm_seed.char_data(), tpm_seed.size());
    NukeFile(base::FilePath(kBioTpmSeedTmpFile));

    if (bytes_read != kTpmSeedSize) {
      LOG(ERROR) << "Failed to read TPM seed from tmpfile: " << bytes_read;
      return -1;
    }
    return DoProgramSeed(tpm_seed) ? 0 : -1;
  }

  auto process = base::Process::Open(pid);
  int exit_code;
  if (!process.WaitForExitWithTimeout(
          base::TimeDelta::FromSeconds(kTimeoutSeconds), &exit_code)) {
    LOG(ERROR) << "bio_crypto_init timeout, exit code: " << exit_code;
    process.Terminate(-1, false);
  }

  return exit_code;
}
