// Copyright (c) 2011 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.
//
// Driver program for creating verity hash images.
#include <stdio.h>

#include "verity/file_hasher.h"
#include "verity/logging.h"
#include "verity/simple_file/env.h"
#include "verity/simple_file/file.h"
#include "verity/utils.h"

namespace {
void print_usage(const char *name) {
  fprintf(stderr,
"Usage:\n"
"  %s <arg>=<value>...\n"
"Options:\n"
"  mode              One of 'create' or 'verify'\n"
"  alg               Hash algorithm to use. One of:\n"
"                      sha512 sha384 sha256 sha224 sha1 sha\n"
"                      mdc2 ripemd160 md5 md4 md2\n"
"  payload           Path to the image to hash\n"
"  payload_blocks    Size of the image, in blocks (4096 bytes)\n"
"  hashtree          Path to a hash tree to create or read from\n"
"  root_hexdigest    Digest of the root node (in hex) for verification\n"
"  salt              Salt (in hex)\n"
"\n", name);
}

typedef enum { VERITY_NONE = 0, VERITY_CREATE, VERITY_VERIFY } verity_mode_t;

static unsigned int parse_blocks(const char *block_s) {
  return (unsigned int)strtoul(block_s, NULL, 0);
}
}  // namespace

static int verity_create(const char *alg,
                         const char *image_path,
                         unsigned int image_blocks,
                         const char *hash_path,
                         const char *salt);

void splitarg(char *arg, char **key, char **val) {
  char *sp = NULL;
  *key = strtok_r(arg, "=", &sp);
  *val = strtok_r(NULL, "=", &sp);
}

int main(int argc, char **argv) {
  verity_mode_t mode = VERITY_CREATE;
  const char *alg = NULL;
  const char *payload = NULL;
  const char *hashtree = NULL;
  const char *salt = NULL;
  unsigned int payload_blocks = 0;
  int i;
  char *key, *val;

  for (i = 1; i < argc; i++) {
    splitarg(argv[i], &key, &val);
    if (!key || !val)
      continue;
    if (!strcmp(key, "alg"))
      alg = val;
    else if (!strcmp(key, "payload"))
      payload = val;
    else if (!strcmp(key, "payload_blocks"))
      payload_blocks = parse_blocks(val);
    else if (!strcmp(key, "hashtree"))
      hashtree = val;
    else if (!strcmp(key, "root_hexdigest"))
      // Silently drop root_hexdigest for now...
      ;
    else if (!strcmp(key, "mode"))
      // Silently drop the mode for now...
      ;
    else if (!strcmp(key, "salt"))
      salt = val;
    else {
      fprintf(stderr, "bogus key: '%s'\n", key);
      print_usage(argv[0]);
      return -1;
    }
  }

  if (!alg || !payload || !hashtree) {
    fprintf(stderr, "missing data: %s%s%s\n",
            alg ? "" : "alg ",
            payload ? "" : "payload ",
            hashtree ? "" : "hashtree");
    print_usage(argv[0]);
    return -1;
  }

  if (mode == VERITY_CREATE) {
    return verity_create(alg, payload, payload_blocks, hashtree, salt);
  } else {
    LOG(FATAL) << "Verification not done yet";
  }
  return -1;
}

static int verity_create(const char *alg,
                         const char *image_path,
                         unsigned int image_blocks,
                         const char *hash_path,
                         const char *salt) {
  // Configure files
  simple_file::Env env;

  simple_file::File source;
  LOG_IF(FATAL, !source.Initialize(image_path, O_RDONLY, &env))
    << "Failed to open the source file: " << image_path;
  simple_file::File destination;
  LOG_IF(FATAL, !destination.Initialize(hash_path,
                                        O_CREAT|O_RDWR|O_TRUNC,
                                        &env))
    << "Failed to open destination file: " << hash_path;

  // Create the actual worker and create the hash image.
  verity::FileHasher hasher;
  LOG_IF(FATAL, !hasher.Initialize(&source,
                                   &destination,
                                   image_blocks,
                                   alg))
    << "Failed to initialize hasher";
  if (salt)
    hasher.set_salt(salt);
  LOG_IF(FATAL, !hasher.Hash());
  LOG_IF(FATAL, !hasher.Store());
  hasher.PrintTable(true);
  return 0;
}
