// Copyright 2017 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 "arc/setup/priv_code_verifier.h"

#include <fcntl.h>
#include <openssl/sha.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/threading/platform_thread.h>
#include <base/timer/elapsed_timer.h>
#include <chromeos/libminijail.h>
#include <crypto/secure_hash.h>
#include <crypto/sha2.h>

#include "arc/setup/arc_setup_util.h"
#include "arc/setup/art_container.h"

// Ported from Android art/runtime/base/macros.h.
#define PACKED(x) __attribute__((__aligned__(x), __packed__))

namespace arc {

namespace {

// Must be synced with <android_src>/art/runtime/digest.cc.
constexpr size_t kAlgorithmSha256DigestFilesize = 68;
constexpr char kMultiHashSha256Prefix[] = "1220";
constexpr size_t kBufferSize = 4096;
constexpr char kArtFilePrefix[] = "system@framework@";
constexpr char kDigestFileExtension[] = ".digest";
constexpr char kSignatureFilename[] = "digest.sig";
constexpr base::TimeDelta kCryptohomedTimeout = base::TimeDelta::FromSeconds(3);

// Converts to digest to string format.
std::string ToHex(const uint8_t* digest, size_t len) {
  std::string hex_str_upper_case = base::HexEncode(digest, len);
  return base::ToLowerASCII(hex_str_upper_case);
}

// Calculate the digest of a file.
bool CalculateSha256Digest(const base::FilePath& file_path,
                           std::string* digest_str) {
  std::unique_ptr<crypto::SecureHash> sha256(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
  std::vector<uint8_t> digest(crypto::kSHA256Length);

  base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file.IsValid())
    return false;

  std::vector<uint8_t> buffer(kBufferSize);
  while (true) {
    int bytes_read = file.ReadAtCurrentPos(
        reinterpret_cast<char*>(buffer.data()), buffer.size());
    if (bytes_read < 0)
      return false;

    if (bytes_read == 0)
      break;
    sha256->Update(buffer.data(), bytes_read);
  }
  sha256->Finish(digest.data(), digest.size());
  std::string hex_digest = ToHex(digest.data(), digest.size());
  // Use multihash format:  https://github.com/multiformats/multihash
  *digest_str = kMultiHashSha256Prefix + hex_digest;

  return true;
}

// Calculate the digest of all digest files.
bool GenerateHashList(const base::FilePath& cache_directory,
                      const std::vector<std::string>& art_file_list,
                      uint8_t* out_digest) {
  SHA256_CTX sha256_ctx;
  if (!SHA256_Init(&sha256_ctx)) {
    LOG(ERROR) << "Failed to initialize SHA256_CTX";
    return false;
  }
  for (const std::string& art_filename : art_file_list) {
    std::string digest_filename = art_filename + kDigestFileExtension;
    base::FilePath digest_filepath = cache_directory.Append(digest_filename);
    std::string digest;
    if (!base::ReadFileToStringWithMaxSize(digest_filepath, &digest,
                                           kAlgorithmSha256DigestFilesize)) {
      PLOG(ERROR) << "Failed to read digest file " << digest_filename;
      return false;
    }

    // Validates digest of art files before merging its digest.
    const base::FilePath art_filepath = cache_directory.Append(art_filename);
    std::string calculated_digest;
    if (!(CalculateSha256Digest(art_filepath, &calculated_digest))) {
      PLOG(ERROR) << "Cannot validate the digest for file: " << art_filename;
      return false;
    }
    if (calculated_digest != digest)
      return false;

    if (!SHA256_Update(&sha256_ctx, digest.c_str(),
                       kAlgorithmSha256DigestFilesize)) {
      LOG(ERROR) << "Failed to call SHA256_Update";
      return false;
    }
  }
  if (!SHA256_Final(out_digest, &sha256_ctx)) {
    LOG(ERROR) << "Failed to call SHA256_Final";
    return false;
  }
  return true;
}

// Partial image header to read the checksum. Need to be sync'ed with
// <Android>/art/runtime/image.h.
// TODO(xzhou): Check if P uses the same layout.
struct PACKED(4) ImagePartialHeader {
  uint8_t image_magic[4];
  uint8_t image_version[4];
  uint32_t image_begin;
  uint32_t image_size;
  uint32_t oat_checksum;
};

bool ReadImageChecksums(const std::string& image_filename,
                        uint32_t* out_oat_checksum) {
  base::ScopedFD scoped_fd(open(image_filename.c_str(), O_RDONLY));
  if (!scoped_fd.is_valid()) {
    LOG(ERROR) << "Failed to open image file: " << image_filename;
    return false;
  }
  ImagePartialHeader h;
  if (!base::ReadFromFD(scoped_fd.get(), reinterpret_cast<char*>(&h),
                        sizeof(ImagePartialHeader))) {
    PLOG(ERROR) << "Failed to read image header from " << image_filename;
    return false;
  }
  *out_oat_checksum = h.oat_checksum;
  return true;
}

bool ChecksumsMatch(const std::string& image_a, const std::string& image_b) {
  uint32_t oat_checksum_a;
  uint32_t oat_checksum_b;
  if (!ReadImageChecksums(image_a, &oat_checksum_a) ||
      !ReadImageChecksums(image_b, &oat_checksum_b)) {
    return false;
  }
  return oat_checksum_a == oat_checksum_b;
}

// Get a list of file that need to be verified.
std::vector<std::string> GetArtFileList(std::string isa) {
  std::vector<std::string> art_file_list;
  const base::FilePath isa_dir = base::FilePath(kFrameworkPath).Append(isa);
  base::FileEnumerator art_files(isa_dir, false /* recursive */,
                                 base::FileEnumerator::FILES, "*.art");
  for (auto src_file = art_files.Next(); !src_file.empty();
       src_file = art_files.Next()) {
    art_file_list.push_back(kArtFilePrefix + src_file.BaseName().value());
  }
  std::sort(art_file_list.begin(), art_file_list.end());
  return art_file_list;
}

// Checks whether host art files are in sync with system art files.
bool IsSynced(const base::FilePath system_isa_image_dir,
              const base::FilePath cache_isa_image_dir) {
  base::FileEnumerator art_files(system_isa_image_dir, false /* recursive */,
                                 base::FileEnumerator::FILES, "*.art");
  for (auto art_file = art_files.Next(); !art_file.empty();
       art_file = art_files.Next()) {
    const base::FilePath cache_art_file = cache_isa_image_dir.Append(
        kArtFilePrefix + art_file.BaseName().value());
    if (!ChecksumsMatch(art_file.value(), cache_art_file.value())) {
      LOG(ERROR) << "Art file out of sync: " << art_file.value()
                 << " != " << cache_art_file.value();
      return false;
    }
  }
  return true;
}

}  // namespace

std::unique_ptr<PrivCodeVerifier> CreatePrivCodeVerifier() {
  return std::make_unique<PrivCodeVerifier>(
      BootLockboxClient::CreateBootLockboxClient());
}

bool PrivCodeVerifier::WaitForCryptohomed() {
  base::ElapsedTimer timer;
  while (!boot_lockbox_client_->IsServiceReady()) {
    if (timer.Elapsed() > kCryptohomedTimeout) {
      LOG(ERROR) << "Giving up waiting on cryptohomed";
      return false;
    }
    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
  }
  LOG(INFO) << "Waiting for cryptohomed took "
            << timer.Elapsed().InMillisecondsRoundedUp() << "ms";
  return true;
}

PrivCodeVerifier::PrivCodeVerifier(
    std::unique_ptr<BootLockboxClient> boot_lockbox_client)
    : boot_lockbox_client_(std::move(boot_lockbox_client)) {}

PrivCodeVerifier::~PrivCodeVerifier() = default;

bool PrivCodeVerifier::Verify(const base::FilePath& cache_directory,
                              const std::string& isa) {
  // Make sure the cache is synced with system partition.
  base::FilePath system_isa_image_dir =
      base::FilePath(kFrameworkPath).Append(isa);
  base::FilePath cache_isa_image_dir = cache_directory.Append(isa);
  if (!IsSynced(system_isa_image_dir, cache_isa_image_dir))
    return false;

  auto files_to_verify = GetArtFileList(isa);

  uint8_t digest_buffer[SHA256_DIGEST_LENGTH];
  if (!GenerateHashList(cache_directory.Append(isa), files_to_verify,
                        digest_buffer)) {
    LOG(ERROR) << "Failed to merge digest files";
    return false;
  }
  std::string digest(reinterpret_cast<char*>(digest_buffer),
                     SHA256_DIGEST_LENGTH);
  std::string signature;
  const base::FilePath signature_filepath =
      cache_directory.Append(isa).Append(kSignatureFilename);
  if (!ReadFileToString(signature_filepath, &signature)) {
    LOG(ERROR) << "Failed to read digest file " << signature_filepath.value();
    return false;
  }
  return boot_lockbox_client_->Verify(digest, signature);
}

bool PrivCodeVerifier::CheckCodeIntegrity(
    const base::FilePath& dalvik_cache_dir) {
  if (!IsCodeValid(dalvik_cache_dir)) {
    LOG(ERROR) << "Check Code Integrity of " << dalvik_cache_dir.value()
               << " Failed";
    return false;
  }
  return true;
}

bool PrivCodeVerifier::IsCodeValid(const base::FilePath& dalvik_cache_dir) {
  for (const std::string& isa : ArtContainer::GetIsas()) {
    // TODO(xzhou): merge the digest for all isas and call Sign() just once.
    if (!Verify(dalvik_cache_dir, isa))
      return false;
  }
  return true;
}

bool PrivCodeVerifier::Sign(const base::FilePath& directory) {
  for (const std::string& isa : ArtContainer::GetIsas()) {
    const base::FilePath isa_dir = directory.Append(isa);
    auto files_to_verify = GetArtFileList(isa);
    uint8_t digest_buffer[SHA256_DIGEST_LENGTH];
    if (!GenerateHashList(isa_dir, files_to_verify, digest_buffer)) {
      LOG(ERROR) << "Failed to merge digest files";
      return false;
    }
    std::string digest(reinterpret_cast<char*>(digest_buffer),
                       SHA256_DIGEST_LENGTH);
    std::string signature;
    boot_lockbox_client_->Sign(digest, &signature);
    const base::FilePath signature_filepath =
        isa_dir.Append(kSignatureFilename);
    if (!WriteToFile(signature_filepath, 0644, signature)) {
      LOG(ERROR) << "Failed to write signature file";
      return false;
    }
  }
  return true;
}

bool PrivCodeVerifier::IsTpmReady() {
  return boot_lockbox_client_->IsTpmReady();
}

}  // namespace arc
