/* 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.
 *
 * Common functions between firmware and kernel verified boot.
 * (Firmware portion)
 */


#include "vboot_api.h"
#include "vboot_common.h"
#include "utility.h"


char* kVbootErrors[VBOOT_ERROR_MAX] = {
  "Success.",
  "Key block invalid.",
  "Key block signature failed.",
  "Key block hash failed.",
  "Public key invalid.",
  "Preamble invalid.",
  "Preamble signature check failed.",
  "Shared data invalid."
};


uint64_t OffsetOf(const void *base, const void *ptr) {
  return (uint64_t)(size_t)ptr - (uint64_t)(size_t)base;
}


/* Helper functions to get data pointed to by a public key or signature. */
uint8_t* GetPublicKeyData(VbPublicKey* key) {
  return (uint8_t*)key + key->key_offset;
}

const uint8_t* GetPublicKeyDataC(const VbPublicKey* key) {
  return (const uint8_t*)key + key->key_offset;
}

uint8_t* GetSignatureData(VbSignature* sig) {
  return (uint8_t*)sig + sig->sig_offset;
}

const uint8_t* GetSignatureDataC(const VbSignature* sig) {
  return (const uint8_t*)sig + sig->sig_offset;
}


/* Helper functions to verify the data pointed to by a subfield is inside
 * the parent data.  Returns 0 if inside, 1 if error. */
int VerifyMemberInside(const void* parent, uint64_t parent_size,
                       const void* member, uint64_t member_size,
                       uint64_t member_data_offset,
                       uint64_t member_data_size) {
  uint64_t end = OffsetOf(parent, member);

  if (end > parent_size)
    return 1;

  if (UINT64_MAX - end < member_size)
    return 1;  /* Detect wraparound in integer math */
  if (end + member_size > parent_size)
    return 1;

  if (UINT64_MAX - end < member_data_offset)
    return 1;
  end += member_data_offset;
  if (end > parent_size)
    return 1;

  if (UINT64_MAX - end < member_data_size)
    return 1;
  if (end + member_data_size > parent_size)
    return 1;

  return 0;
}


int VerifyPublicKeyInside(const void* parent, uint64_t parent_size,
                          const VbPublicKey* key) {
  return VerifyMemberInside(parent, parent_size,
                            key, sizeof(VbPublicKey),
                            key->key_offset, key->key_size);
}


int VerifySignatureInside(const void* parent, uint64_t parent_size,
                          const VbSignature* sig) {
  return VerifyMemberInside(parent, parent_size,
                            sig, sizeof(VbSignature),
                            sig->sig_offset, sig->sig_size);
}


void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size) {
  key->key_offset = OffsetOf(key, key_data);
  key->key_size = key_size;
  key->algorithm = kNumAlgorithms; /* Key not present yet */
  key->key_version = 0;
}


int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) {
  if (dest->key_size < src->key_size)
    return 1;

  dest->key_size = src->key_size;
  dest->algorithm = src->algorithm;
  dest->key_version = src->key_version;
  Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size);
  return 0;
}


RSAPublicKey* PublicKeyToRSA(const VbPublicKey* key) {
  RSAPublicKey *rsa;
  uint64_t key_size;

  if (kNumAlgorithms <= key->algorithm) {
    VBDEBUG(("Invalid algorithm.\n"));
    return NULL;
  }
  if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
      key_size != key->key_size) {
    VBDEBUG(("Wrong key size for algorithm\n"));
    return NULL;
  }

  rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), key->key_size);
  if (!rsa)
    return NULL;

  rsa->algorithm = (unsigned int)key->algorithm;
  return rsa;
}


int VerifyData(const uint8_t* data, uint64_t size, const VbSignature *sig,
               const RSAPublicKey* key) {

  if (sig->sig_size != siglen_map[key->algorithm]) {
    VBDEBUG(("Wrong signature size for algorithm.\n"));
    return 1;
  }
  if (sig->data_size > size) {
    VBDEBUG(("Data buffer smaller than length of signed data.\n"));
    return 1;
  }

  if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size,
                         GetSignatureDataC(sig), key->algorithm))
    return 1;

  return 0;
}


int VerifyDigest(const uint8_t* digest, const VbSignature *sig,
                 const RSAPublicKey* key) {

  if (sig->sig_size != siglen_map[key->algorithm]) {
    VBDEBUG(("Wrong signature size for algorithm.\n"));
    return 1;
  }

  if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest,
                         GetSignatureDataC(sig), key->algorithm))
    return 1;

  return 0;
}


int EqualData(const uint8_t* data, uint64_t size, const VbSignature *hash,
              const RSAPublicKey* key) {
  uint8_t* digest = NULL;
  int rv;

  if (hash->sig_size != hash_size_map[key->algorithm]) {
    VBDEBUG(("Wrong hash size for algorithm.\n"));
    return 1;
  }
  if (hash->data_size > size) {
    VBDEBUG(("Data buffer smaller than length of signed data.\n"));
    return 1;
  }

  digest = DigestBuf(data, hash->data_size, key->algorithm);

  rv = SafeMemcmp(digest, GetSignatureDataC(hash), hash->sig_size);
  VbExFree(digest);
  return rv;
}


int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
                   const VbPublicKey *key, int hash_only) {

  const VbSignature* sig;

  /* Sanity checks before attempting signature of data */
  if(size < sizeof(VbKeyBlockHeader)) {
    VBDEBUG(("Not enough space for key block header.\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }
  if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
    VBDEBUG(("Not a valid verified boot key block.\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }
  if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
    VBDEBUG(("Incompatible key block header version.\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }
  if (size < block->key_block_size) {
    VBDEBUG(("Not enough data for key block.\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }
  if (!hash_only && !key) {
    VBDEBUG(("Missing required public key.\n"));
    return VBOOT_PUBLIC_KEY_INVALID;
  }

  /* Check signature or hash, depending on the hash_only parameter. Note that
   * we don't require a key even if the keyblock has a signature, because the
   * caller may not care if the keyblock itself is signed (for example, booting
   * a Google-signed kernel in developer mode).
   */
  if (hash_only) {
    /* Check hash */
    uint8_t* header_checksum = NULL;
    int rv;

    sig = &block->key_block_checksum;

    if (VerifySignatureInside(block, block->key_block_size, sig)) {
      VBDEBUG(("Key block hash off end of block\n"));
      return VBOOT_KEY_BLOCK_INVALID;
    }
    if (sig->sig_size != SHA512_DIGEST_SIZE) {
      VBDEBUG(("Wrong hash size for key block.\n"));
      return VBOOT_KEY_BLOCK_INVALID;
    }

    /* Make sure advertised signature data sizes are sane. */
    if (block->key_block_size < sig->data_size) {
      VBDEBUG(("Signature calculated past end of the block\n"));
      return VBOOT_KEY_BLOCK_INVALID;
    }

    VBDEBUG(("Checking key block hash only...\n"));
    header_checksum = DigestBuf((const uint8_t*)block, sig->data_size,
                                SHA512_DIGEST_ALGORITHM);
    rv = SafeMemcmp(header_checksum, GetSignatureDataC(sig),
                    SHA512_DIGEST_SIZE);
    VbExFree(header_checksum);
    if (rv) {
      VBDEBUG(("Invalid key block hash.\n"));
      return VBOOT_KEY_BLOCK_HASH;
    }
  } else {
    /* Check signature */
    RSAPublicKey* rsa;
    int rv;

    sig = &block->key_block_signature;

    if (VerifySignatureInside(block, block->key_block_size, sig)) {
      VBDEBUG(("Key block signature off end of block\n"));
      return VBOOT_KEY_BLOCK_INVALID;
    }

    rsa = PublicKeyToRSA(key);
    if (!rsa) {
      VBDEBUG(("Invalid public key\n"));
      return VBOOT_PUBLIC_KEY_INVALID;
    }

    /* Make sure advertised signature data sizes are sane. */
    if (block->key_block_size < sig->data_size) {
      VBDEBUG(("Signature calculated past end of the block\n"));
      RSAPublicKeyFree(rsa);
      return VBOOT_KEY_BLOCK_INVALID;
    }

    VBDEBUG(("Checking key block signature...\n"));
    rv = VerifyData((const uint8_t*)block, size, sig, rsa);
    RSAPublicKeyFree(rsa);
    if (rv) {
      VBDEBUG(("Invalid key block signature.\n"));
      return VBOOT_KEY_BLOCK_SIGNATURE;
    }
  }

  /* Verify we signed enough data */
  if (sig->data_size < sizeof(VbKeyBlockHeader)) {
    VBDEBUG(("Didn't sign enough data\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }

  /* Verify data key is inside the block and inside signed data */
  if (VerifyPublicKeyInside(block, block->key_block_size, &block->data_key)) {
    VBDEBUG(("Data key off end of key block\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }
  if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) {
    VBDEBUG(("Data key off end of signed data\n"));
    return VBOOT_KEY_BLOCK_INVALID;
  }

  /* Success */
  return VBOOT_SUCCESS;
}


int VerifyECPreamble(const VbECPreambleHeader* preamble,
                           uint64_t size, const RSAPublicKey* key) {

  const VbSignature* sig = &preamble->preamble_signature;

  /* Sanity checks before attempting signature of data */
  if(size < EXPECTED_VB_EC_PREAMBLE_HEADER1_0_SIZE) {
    VBDEBUG(("Not enough data for EC preamble header.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (preamble->header_version_major !=
      EC_PREAMBLE_HEADER_VERSION_MAJOR) {
    VBDEBUG(("Incompatible EC preamble header version (%d, not %d).\n",
             preamble->header_version_major,
             EC_PREAMBLE_HEADER_VERSION_MAJOR));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (size < preamble->preamble_size) {
    VBDEBUG(("Not enough data for EC preamble.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Check signature */
  if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
    VBDEBUG(("EC preamble signature off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Make sure advertised signature data sizes are sane. */
  if (preamble->preamble_size < sig->data_size) {
    VBDEBUG(("EC signature calculated past end of the block\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  if (VerifyData((const uint8_t*)preamble, size, sig, key)) {
    VBDEBUG(("EC preamble signature validation failed\n"));
    return VBOOT_PREAMBLE_SIGNATURE;
  }

  /* Verify we signed enough data */
  if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
    VBDEBUG(("Didn't sign enough data\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Verify body digest is inside the signed data */
  if (VerifySignatureInside(preamble, sig->data_size,
                            &preamble->body_digest)) {
    VBDEBUG(("EC body digest off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Success */
  return VBOOT_SUCCESS;
}

int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble,
                           uint64_t size, const RSAPublicKey* key) {

  const VbSignature* sig = &preamble->preamble_signature;

  /* Sanity checks before attempting signature of data */
  if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE) {
    VBDEBUG(("Not enough data for preamble header 2.0.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (preamble->header_version_major !=
      FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
    VBDEBUG(("Incompatible firmware preamble header version.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (size < preamble->preamble_size) {
    VBDEBUG(("Not enough data for preamble.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Check signature */
  if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
    VBDEBUG(("Preamble signature off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Make sure advertised signature data sizes are sane. */
  if (preamble->preamble_size < sig->data_size) {
    VBDEBUG(("Signature calculated past end of the block\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  if (VerifyData((const uint8_t*)preamble, size, sig, key)) {
    VBDEBUG(("Preamble signature validation failed\n"));
    return VBOOT_PREAMBLE_SIGNATURE;
  }

  /* Verify we signed enough data */
  if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
    VBDEBUG(("Didn't sign enough data\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Verify body signature is inside the signed data */
  if (VerifySignatureInside(preamble, sig->data_size,
                            &preamble->body_signature)) {
    VBDEBUG(("Firmware body signature off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Verify kernel subkey is inside the signed data */
  if (VerifyPublicKeyInside(preamble, sig->data_size,
                            &preamble->kernel_subkey)) {
    VBDEBUG(("Kernel subkey off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* If the preamble header version is at least 2.1, verify we have
   * space for the added fields from 2.1. */
  if (preamble->header_version_minor >= 1) {
    if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE) {
      VBDEBUG(("Not enough data for preamble header 2.1.\n"));
      return VBOOT_PREAMBLE_INVALID;
    }
  }

  /* Success */
  return VBOOT_SUCCESS;
}


uint32_t VbGetFirmwarePreambleFlags(const VbFirmwarePreambleHeader* preamble) {
  if (preamble->header_version_minor < 1) {
    /* Old structure; return default flags.  (Note that we don't need
     * to check header_version_major; if that's not 2 then
     * VerifyFirmwarePreamble() would have already failed. */
    return 0;
  }

  return preamble->flags;
}


int VerifyKernelPreamble(const VbKernelPreambleHeader* preamble,
                         uint64_t size, const RSAPublicKey* key) {

  const VbSignature* sig = &preamble->preamble_signature;

  /* Sanity checks before attempting signature of data */
  if(size < sizeof(VbKernelPreambleHeader)) {
    VBDEBUG(("Not enough data for preamble header.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (preamble->header_version_major != KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
    VBDEBUG(("Incompatible kernel preamble header version.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (size < preamble->preamble_size) {
    VBDEBUG(("Not enough data for preamble.\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Check signature */
  if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
    VBDEBUG(("Preamble signature off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }
  if (VerifyData((const uint8_t*)preamble, size, sig, key)) {
    VBDEBUG(("Preamble signature validation failed\n"));
    return VBOOT_PREAMBLE_SIGNATURE;
  }

  /* Verify we signed enough data */
  if (sig->data_size < sizeof(VbKernelPreambleHeader)) {
    VBDEBUG(("Didn't sign enough data\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Verify body signature is inside the signed data */
  if (VerifySignatureInside(preamble, sig->data_size,
                            &preamble->body_signature)) {
    VBDEBUG(("Kernel body signature off end of preamble\n"));
    return VBOOT_PREAMBLE_INVALID;
  }

  /* Success */
  return VBOOT_SUCCESS;
}


int VbSharedDataInit(VbSharedDataHeader* header, uint64_t size) {

  VBDEBUG(("VbSharedDataInit, %d bytes, header %d bytes\n", (int)size,
           sizeof(VbSharedDataHeader)));

  if (size < sizeof(VbSharedDataHeader)) {
    VBDEBUG(("Not enough data for header.\n"));
    return VBOOT_SHARED_DATA_INVALID;
  }
  if (size < VB_SHARED_DATA_MIN_SIZE) {
    VBDEBUG(("Shared data buffer too small.\n"));
    return VBOOT_SHARED_DATA_INVALID;
  }

  if (!header)
    return VBOOT_SHARED_DATA_INVALID;

  /* Zero the header */
  Memset(header, 0, sizeof(VbSharedDataHeader));

  /* Initialize fields */
  header->magic = VB_SHARED_DATA_MAGIC;
  header->struct_version = VB_SHARED_DATA_VERSION;
  header->struct_size = sizeof(VbSharedDataHeader);
  header->data_size = size;
  header->data_used = sizeof(VbSharedDataHeader);
  header->firmware_index = 0xFF;

  /* Success */
  return VBOOT_SUCCESS;
}


uint64_t VbSharedDataReserve(VbSharedDataHeader* header, uint64_t size) {
  uint64_t offs = header->data_used;

  VBDEBUG(("VbSharedDataReserve %d bytes at %d\n", (int)size, (int)offs));

  if (!header || size > header->data_size - header->data_used) {
    VBDEBUG(("VbSharedData buffer out of space.\n"));
    return 0;  /* Not initialized, or not enough space left. */
  }
  header->data_used += size;
  return offs;
}


int VbSharedDataSetKernelKey(VbSharedDataHeader* header,
                             const VbPublicKey* src) {

  VbPublicKey *kdest = &header->kernel_subkey;

  if (!header)
    return VBOOT_SHARED_DATA_INVALID;

  /* Attempt to allocate space for the key, if it hasn't been allocated yet */
  if (!header->kernel_subkey_data_offset) {
    header->kernel_subkey_data_offset = VbSharedDataReserve(header,
                                                          src->key_size);
    if (!header->kernel_subkey_data_offset)
      return VBOOT_SHARED_DATA_INVALID;
    header->kernel_subkey_data_size = src->key_size;
  }

  /* Copy the kernel sign key blob into the destination buffer */
  PublicKeyInit(kdest, (uint8_t*)header + header->kernel_subkey_data_offset,
                header->kernel_subkey_data_size);

  return PublicKeyCopy(kdest, src);
}
