// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by the GPL v2 license that can
// be found in the LICENSE file.
//
// Implementation of FileHasher

#define __STDC_LIMIT_MACROS 1
#define __STDC_FORMAT_MACROS 1
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>

#include <asm/page.h>
#include <linux/device-mapper.h>
#include <linux/kernel.h>
#include "verity/file_hasher.h"
#include "verity/logging.h"

namespace verity {

// Simple helper for Initialize.
template <typename T>
static inline bool power_of_two(T num) {
  if (num == 0)
    return false;
  if (!(num & (num - 1)))
    return true;
  return false;
}

bool FileHasher::Initialize(simple_file::File* source,
                            simple_file::File* destination,
                            unsigned int blocks,
                            const char* alg) {
  if (!alg || !source || !destination) {
    LOG(ERROR) << "Invalid arguments supplied to Initialize";
    LOG(INFO) << "s: " << source << " d: " << destination;
    return false;
  }
  if (source_ || destination_) {
    LOG(ERROR) << "Initialize called more than once";
    return false;
  }
  if (blocks > source->Size() / PAGE_SIZE) {
    LOG(ERROR) << blocks << " blocks exceeds image size of " << source->Size();
    return false;
  } else if (blocks == 0) {
    blocks = source->Size() / PAGE_SIZE;
    if (source->Size() % PAGE_SIZE) {
      LOG(ERROR) << "The source file size must be divisible by the block size";
      LOG(ERROR) << "Size: " << source->Size();
      LOG(INFO) << "Suggested size: " << ALIGN(source->Size(), PAGE_SIZE);
      return false;
    }
  }
  alg_ = alg;
  source_ = source;
  destination_ = destination;
  block_limit_ = blocks;

  // Now we initialize the tree
  if (dm_bht_create(&tree_, block_limit_, alg_)) {
    LOG(ERROR) << "Could not create the BH tree";
    return false;
  }

  sectors_ = dm_bht_sectors(&tree_);
  hash_data_ = new u8[verity_to_bytes(sectors_)];

  // No reading is needed.
  dm_bht_set_read_cb(&tree_, dm_bht_zeroread_callback);
  dm_bht_set_buffer(&tree_, hash_data_);
  return true;
}

bool FileHasher::Store() {
  return destination_->WriteAt(verity_to_bytes(sectors_), hash_data_, 0);
}

bool FileHasher::Hash() {
  // TODO(wad) abstract size when dm-bht needs to do break from PAGE_SIZE
  u8 block_data[PAGE_SIZE];
  uint32_t block = 0;

  while (block < block_limit_) {
    if (!source_->Read(PAGE_SIZE, block_data)) {
      LOG(ERROR) << "Failed to read for block: " << block;
      return false;
    }
    if (dm_bht_store_block(&tree_, block, block_data)) {
      LOG(ERROR) << "Failed to store block " << block;
      return false;
    }
    ++block;
  }
  return !dm_bht_compute(&tree_);
}

const char* FileHasher::RandomSalt() {
  uint8_t buf[DM_BHT_SALT_SIZE];
  const char urandom_path[] = "/dev/urandom";
  simple_file::File source;

  LOG_IF(FATAL, !source.Initialize(urandom_path, O_RDONLY, NULL))
      << "Failed to open the random source: " << urandom_path;
  PLOG_IF(FATAL, !source.Read(sizeof(buf), buf))
      << "Failed to read the random source";

  for (size_t i = 0; i < sizeof(buf); ++i) {
    // NOLINTNEXTLINE(runtime/printf)
    sprintf(&random_salt_[i * 2], "%02x", buf[i]);
  }
  random_salt_[sizeof(random_salt_) - 1] = '\0';

  return random_salt_;
}

void FileHasher::PrintTable(bool colocated) {
  // Grab the digest (up to 1kbit supported)
  uint8_t digest[128];
  char hexsalt[DM_BHT_SALT_SIZE * 2 + 1];
  bool have_salt;

  dm_bht_root_hexdigest(&tree_, digest, sizeof(digest));
  have_salt = dm_bht_salt(&tree_, hexsalt) == 0;

  // TODO(wad) later support sizes that need 64-bit sectors.
  unsigned int hash_start = 0;
  unsigned int root_end = to_sector(block_limit_ << PAGE_SHIFT);
  if (colocated)
    hash_start = root_end;
  printf(
      "0 %u verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=%u alg=%s "
      "root_hexdigest=%s",
      root_end, hash_start, alg_, digest);
  if (have_salt)
    printf(" salt=%s", hexsalt);
  printf("\n");
}

}  // namespace verity
