// 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 (!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;
}
