/* Copyright (c) 2011 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.
 *
 * Host functions for signature generation.
 */

/* TODO: change all 'return 0', 'return 1' into meaningful return codes */

#define OPENSSL_NO_SHA
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "cryptolib.h"
#include "file_keys.h"
#include "host_common.h"
#include "vboot_common.h"


VbSignature* SignatureAlloc(uint64_t sig_size, uint64_t data_size) {
  VbSignature* sig = (VbSignature*)malloc(sizeof(VbSignature) + sig_size);
  if (!sig)
    return NULL;

  sig->sig_offset = sizeof(VbSignature);
  sig->sig_size = sig_size;
  sig->data_size = data_size;
  return sig;
}


void SignatureInit(VbSignature* sig, uint8_t* sig_data,
                   uint64_t sig_size, uint64_t data_size) {
  sig->sig_offset = OffsetOf(sig, sig_data);
  sig->sig_size = sig_size;
  sig->data_size = data_size;
}


int SignatureCopy(VbSignature* dest, const VbSignature* src) {
  if (dest->sig_size < src->sig_size)
    return 1;
  dest->sig_size = src->sig_size;
  dest->data_size = src->data_size;
  Memcpy(GetSignatureData(dest), GetSignatureDataC(src), src->sig_size);
  return 0;
}


VbSignature* CalculateChecksum(const uint8_t* data, uint64_t size) {

  uint8_t* header_checksum;
  VbSignature* sig;

  header_checksum = DigestBuf(data, size, SHA512_DIGEST_ALGORITHM);
  if (!header_checksum)
    return NULL;

  sig = SignatureAlloc(SHA512_DIGEST_SIZE, 0);
  if (!sig) {
    free(header_checksum);
    return NULL;
  }
  sig->sig_offset = sizeof(VbSignature);
  sig->sig_size = SHA512_DIGEST_SIZE;
  sig->data_size = size;

  /* Signature data immediately follows the header */
  Memcpy(GetSignatureData(sig), header_checksum, SHA512_DIGEST_SIZE);
  free(header_checksum);
  return sig;
}

VbSignature* CalculateHash(const uint8_t* data, uint64_t size,
                           const VbPrivateKey* key) {
  uint8_t* digest = NULL;
  int digest_size = hash_size_map[key->algorithm];
  VbSignature* sig = NULL;

  /* Calculate the digest */
  digest = DigestBuf(data, size, key->algorithm);
  if (!digest)
    return NULL;

  /* Allocate output signature */
  sig = SignatureAlloc(digest_size, size);
  if (!sig) {
    free(digest);
    return NULL;
  }

  /* The digest itself is the signature data */
  Memcpy(GetSignatureData(sig), digest, digest_size);
  free(digest);

  /* Return the signature */
  return sig;
}

VbSignature* CalculateSignature(const uint8_t* data, uint64_t size,
                                const VbPrivateKey* key) {

  uint8_t* digest;
  int digest_size = hash_size_map[key->algorithm];

  const uint8_t* digestinfo = hash_digestinfo_map[key->algorithm];
  int digestinfo_size = digestinfo_size_map[key->algorithm];

  uint8_t* signature_digest;
  int signature_digest_len = digest_size + digestinfo_size;

  VbSignature* sig;
  int rv;

  /* Calculate the digest */
  /* TODO: rename param 3 of DigestBuf to hash_type */
  digest = DigestBuf(data, size, hash_type_map[key->algorithm]);
  if (!digest)
    return NULL;

  /* Prepend the digest info to the digest */
  signature_digest = malloc(signature_digest_len);
  if (!signature_digest) {
    free(digest);
    return NULL;
  }
  Memcpy(signature_digest, digestinfo, digestinfo_size);
  Memcpy(signature_digest + digestinfo_size, digest, digest_size);
  free(digest);

  /* Allocate output signature */
  sig = SignatureAlloc(siglen_map[key->algorithm], size);
  if (!sig) {
    free(signature_digest);
    return NULL;
  }

  /* Sign the signature_digest into our output buffer */
  rv = RSA_private_encrypt(signature_digest_len,   /* Input length */
                           signature_digest,       /* Input data */
                           GetSignatureData(sig),  /* Output sig */
                           key->rsa_private_key,   /* Key to use */
                           RSA_PKCS1_PADDING);     /* Padding to use */
  free(signature_digest);

  if (-1 == rv) {
    VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
    free(sig);
    return NULL;
  }

  /* Return the signature */
  return sig;
}

/* Invoke [external_signer] command with [pem_file] as
 * an argument, contents of [inbuf] passed redirected to stdin,
 * and the stdout of the command is put back into [outbuf].
 * Returns -1 on error, 0 on success.
 */
int InvokeExternalSigner(uint64_t size,
                         const uint8_t* inbuf,
                         uint8_t* outbuf,
                         uint64_t outbufsize,
                         const char* pem_file,
                         const char* external_signer) {

  int rv = 0, n;
  int p_to_c[2], c_to_p[2];  /* pipe descriptors */
  pid_t pid;

  VBDEBUG(("Will invoke \"%s %s\" to perform signing.\n"
           "Input to the signer will be provided on standard in.\n"
           "Output of the signer will be read from standard out.\n",
           external_signer, pem_file));

  /* Need two pipes since we want to invoke the external_signer as
   * a co-process writing to its stdin and reading from its stdout. */
  if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0) {
    VBDEBUG(("pipe() error\n"));
    return -1;
  }
  if ((pid = fork()) < 0) {
    VBDEBUG(("fork() error"));
    return -1;
  }
  else if (pid > 0) {  /* Parent. */
    close(p_to_c[STDIN_FILENO]);
    close(c_to_p[STDOUT_FILENO]);

    /* We provide input to the child process (external signer). */
    if (write(p_to_c[STDOUT_FILENO], inbuf, size) != size) {
      VBDEBUG(("write() error while providing input to external signer\n"));
      rv = -1;
    } else {
      close(p_to_c[STDOUT_FILENO]);  /* Send EOF to child (signer process). */
      do {
        n = read(c_to_p[STDIN_FILENO], outbuf, outbufsize);
        outbuf += n;
        outbufsize -= n;
      } while (n > 0 && outbufsize);

      if (n < 0) {
        VBDEBUG(("read() error while reading output from external signer\n"));
        rv = -1;
      }
    }
    if (waitpid(pid, NULL, 0) < 0) {
      VBDEBUG(("waitpid() error\n"));
      rv = -1;
    }
  } else {  /* Child. */
    close (p_to_c[STDOUT_FILENO]);
    close (c_to_p[STDIN_FILENO]);
    /* Map the stdin to the first pipe (this pipe gets input
     * from the parent) */
    if (STDIN_FILENO != p_to_c[STDIN_FILENO]) {
      if (dup2(p_to_c[STDIN_FILENO], STDIN_FILENO) != STDIN_FILENO) {
        VBDEBUG(("stdin dup2() failed (external signer)\n"));
        close(p_to_c[0]);
        return -1;
      }
    }
    /* Map the stdout to the second pipe (this pipe sends back
     * signer output to the parent) */
    if (STDOUT_FILENO != c_to_p[STDOUT_FILENO]) {
      if (dup2(c_to_p[STDOUT_FILENO], STDOUT_FILENO) != STDOUT_FILENO) {
        VBDEBUG(("stdout dup2() failed (external signer)\n"));
        close(c_to_p[STDOUT_FILENO]);
        return -1;
      }
    }
    /* External signer is invoked here. */
    if (execl(external_signer, external_signer, pem_file, (char *) 0) < 0) {
      VBDEBUG(("execl() of external signer failed\n"));
    }
  }
  return rv;
}

/* TODO(gauravsh): This could easily be integrated into CalculateSignature()
 * since the code is almost a mirror - I have kept it as such to avoid changing
 * the existing interface. */
VbSignature* CalculateSignature_external(const uint8_t* data, uint64_t size,
                                         const char* key_file,
                                         uint64_t key_algorithm,
                                         const char* external_signer) {
  uint8_t* digest;
  uint64_t digest_size = hash_size_map[key_algorithm];

  const uint8_t* digestinfo = hash_digestinfo_map[key_algorithm];
  uint64_t digestinfo_size = digestinfo_size_map[key_algorithm];

  uint8_t* signature_digest;
  uint64_t signature_digest_len = digest_size + digestinfo_size;

  VbSignature* sig;
  int rv;

  /* Calculate the digest */
  /* TODO: rename param 3 of DigestBuf to hash_type */
  digest = DigestBuf(data, size, hash_type_map[key_algorithm]);
  if (!digest)
    return NULL;

  /* Prepend the digest info to the digest */
  signature_digest = malloc(signature_digest_len);
  if (!signature_digest) {
    free(digest);
    return NULL;
  }
  Memcpy(signature_digest, digestinfo, digestinfo_size);
  Memcpy(signature_digest + digestinfo_size, digest, digest_size);
  free(digest);

  /* Allocate output signature */
  sig = SignatureAlloc(siglen_map[key_algorithm], size);
  if (!sig) {
    free(signature_digest);
    return NULL;
  }

  /* Sign the signature_digest into our output buffer */
  rv = InvokeExternalSigner(signature_digest_len, /* Input length */
                            signature_digest,     /* Input data */
                            GetSignatureData(sig), /* Output sig */
                            siglen_map[key_algorithm], /* Max Output sig size */
                            key_file,             /* Key file to use */
                            external_signer);     /* External cmd to invoke */
  free(signature_digest);

  if (-1 == rv) {
    VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
    free(sig);
    return NULL;
  }

  /* Return the signature */
  return sig;
}
