/* Copyright (c) 2012 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.
 *
 * High-level firmware API for loading and verifying rewritable firmware.
 * (Firmware portion)
 */

#include "gbb_header.h"
#include "load_firmware_fw.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_nvstorage.h"

/* Static variables for UpdateFirmwareBodyHash().  It's less than
 * optimal to have static variables in a library, but in UEFI the
 * caller is deep inside a different firmware stack and doesn't have a
 * good way to pass the params struct back to us. */
typedef struct VbLoadFirmwareInternal {
  DigestContext body_digest_context;
  uint32_t body_size_accum;
} VbLoadFirmwareInternal;


void VbUpdateFirmwareBodyHash(VbCommonParams* cparams,
                              uint8_t* data, uint32_t size) {
  VbLoadFirmwareInternal* lfi =
      (VbLoadFirmwareInternal*)cparams->vboot_context;

  DigestUpdate(&lfi->body_digest_context, data, size);
  lfi->body_size_accum += size;
}


int LoadFirmware(VbCommonParams* cparams, VbSelectFirmwareParams* fparams,
                 VbNvContext* vnc) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
  VbPublicKey* root_key;
  VbLoadFirmwareInternal* lfi;

  uint32_t try_b_count;
  uint32_t lowest_version = 0xFFFFFFFF;
  int good_index = -1;
  int is_dev;
  int index;
  int i;

  int retval = VBERROR_UNKNOWN;
  int recovery = VBNV_RECOVERY_RO_UNSPECIFIED;

  /* Clear output params in case we fail */
  shared->firmware_index = 0xFF;

  VBDEBUG(("LoadFirmware started...\n"));

  /* Must have a root key from the GBB */
  if (!gbb) {
    VBDEBUG(("No GBB\n"));
    retval = VBERROR_INVALID_GBB;
    goto LoadFirmwareExit;
  }
  root_key = (VbPublicKey*)((uint8_t*)gbb + gbb->rootkey_offset);

  /* Parse flags */
  is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
  if (is_dev)
    shared->flags |= VBSD_LF_DEV_SWITCH_ON;

  /* Read try-b count and decrement if necessary */
  VbNvGet(vnc, VBNV_TRY_B_COUNT, &try_b_count);
  if (0 != try_b_count) {
    VbNvSet(vnc, VBNV_TRY_B_COUNT, try_b_count - 1);
    shared->flags |= VBSD_FWB_TRIED;
  }

  /* Allocate our internal data */
  lfi = (VbLoadFirmwareInternal*)VbExMalloc(sizeof(VbLoadFirmwareInternal));
  cparams->vboot_context = (void*)lfi;

  /* Loop over indices */
  for (i = 0; i < 2; i++) {
    VbKeyBlockHeader* key_block;
    uint32_t vblock_size;
    VbFirmwarePreambleHeader* preamble;
    RSAPublicKey* data_key;
    uint64_t key_version;
    uint32_t combined_version;
    uint8_t* body_digest;
    uint8_t* check_result;

    /* If try B count is non-zero try firmware B first */
    index = (try_b_count ? 1 - i : i);
    if (0 == index) {
      key_block = (VbKeyBlockHeader*)fparams->verification_block_A;
      vblock_size = fparams->verification_size_A;
      check_result = &shared->check_fw_a_result;
    } else {
      key_block = (VbKeyBlockHeader*)fparams->verification_block_B;
      vblock_size = fparams->verification_size_B;
      check_result = &shared->check_fw_b_result;
    }

    /* Check the key block flags against the current boot mode.  Do this
     * before verifying the key block, since flags are faster to check than
     * the RSA signature. */
    if (!(key_block->key_block_flags &
          (is_dev ? KEY_BLOCK_FLAG_DEVELOPER_1 :
           KEY_BLOCK_FLAG_DEVELOPER_0))) {
      VBDEBUG(("Developer flag mismatch.\n"));
      *check_result = VBSD_LF_CHECK_DEV_MISMATCH;
      continue;
    }
    /* RW firmware never runs in recovery mode. */
    if (!(key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)) {
      VBDEBUG(("Recovery flag mismatch.\n"));
      *check_result = VBSD_LF_CHECK_REC_MISMATCH;
      continue;
    }

    /* Verify the key block */
    VBPERFSTART("VB_VKB");
    if ((0 != KeyBlockVerify(key_block, vblock_size, root_key, 0))) {
      VBDEBUG(("Key block verification failed.\n"));
      *check_result = VBSD_LF_CHECK_VERIFY_KEYBLOCK;
      VBPERFEND("VB_VKB");
      continue;
    }
    VBPERFEND("VB_VKB");

    /* Check for rollback of key version. */
    key_version = key_block->data_key.key_version;
    if (!(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) {
      if (key_version < (shared->fw_version_tpm >> 16)) {
        VBDEBUG(("Key rollback detected.\n"));
        *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
        continue;
      }
      if (key_version > 0xFFFF) {
        /* Key version is stored in 16 bits in the TPM, so key versions greater
         * than 0xFFFF can't be stored properly. */
        VBDEBUG(("Key version > 0xFFFF.\n"));
        *check_result = VBSD_LF_CHECK_KEY_ROLLBACK;
        continue;
      }
    }

    /* Get the key for preamble/data verification from the key block. */
    data_key = PublicKeyToRSA(&key_block->data_key);
    if (!data_key) {
      VBDEBUG(("Unable to parse data key.\n"));
      *check_result = VBSD_LF_CHECK_DATA_KEY_PARSE;
      continue;
    }

    /* Verify the preamble, which follows the key block. */
    VBPERFSTART("VB_VPB");
    preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block +
                                           key_block->key_block_size);
    if ((0 != VerifyFirmwarePreamble(preamble,
                                     vblock_size - key_block->key_block_size,
                                     data_key))) {
      VBDEBUG(("Preamble verfication failed.\n"));
      *check_result = VBSD_LF_CHECK_VERIFY_PREAMBLE;
      RSAPublicKeyFree(data_key);
      VBPERFEND("VB_VPB");
      continue;
    }
    VBPERFEND("VB_VPB");

    /* Check for rollback of firmware version. */
    combined_version = (uint32_t)((key_version << 16) |
                                  (preamble->firmware_version & 0xFFFF));
    if (combined_version < shared->fw_version_tpm &&
        !(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) {
      VBDEBUG(("Firmware version rollback detected.\n"));
      *check_result = VBSD_LF_CHECK_FW_ROLLBACK;
      RSAPublicKeyFree(data_key);
      continue;
    }

    /* Header for this firmware is valid */
    *check_result = VBSD_LF_CHECK_HEADER_VALID;

    /* Check for lowest key version from a valid header. */
    if (lowest_version > combined_version)
      lowest_version = combined_version;

    /* If we already have good firmware, no need to read another one;
     * we only needed to look at the versions to check for
     * rollback. */
    if (-1 != good_index) {
      RSAPublicKeyFree(data_key);
      continue;
    }

    /* Handle preamble flag for using the RO normal/dev code path */
    if (VbGetFirmwarePreambleFlags(preamble) &
        VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {

      /* Fail if calling firmware doesn't support RO normal */
      if (!(shared->flags & VBSD_BOOT_RO_NORMAL_SUPPORT)) {
        *check_result = VBSD_LF_CHECK_NO_RO_NORMAL;
        RSAPublicKeyFree(data_key);
        continue;
      }

      /* Indicate that we should use the RO normal code path */
      shared->flags |= VBSD_LF_USE_RO_NORMAL;

    } else {
      VbError_t rv;

      /* Read the firmware data */
      VBPERFSTART("VB_RFD");
      DigestInit(&lfi->body_digest_context, data_key->algorithm);
      lfi->body_size_accum = 0;
      rv = VbExHashFirmwareBody(cparams, (index ? VB_SELECT_FIRMWARE_B :
                                          VB_SELECT_FIRMWARE_A));
      if (VBERROR_SUCCESS != rv) {
        VBDEBUG(("VbExHashFirmwareBody() failed for index %d\n", index));
        *check_result = VBSD_LF_CHECK_GET_FW_BODY;
        RSAPublicKeyFree(data_key);
        VBPERFEND("VB_RFD");
        continue;
      }
      if (lfi->body_size_accum != preamble->body_signature.data_size) {
        VBDEBUG(("Hash updated %d bytes but expected %d\n",
                 (int)lfi->body_size_accum,
                 (int)preamble->body_signature.data_size));
        *check_result = VBSD_LF_CHECK_HASH_WRONG_SIZE;
        RSAPublicKeyFree(data_key);
        VBPERFEND("VB_RFD");
        continue;
      }
      VBPERFEND("VB_RFD");

      /* Verify firmware data */
      VBPERFSTART("VB_VFD");
      body_digest = DigestFinal(&lfi->body_digest_context);
      if (0 != VerifyDigest(body_digest, &preamble->body_signature,
                            data_key)) {
        VBDEBUG(("Firmware body verification failed.\n"));
        *check_result = VBSD_LF_CHECK_VERIFY_BODY;
        RSAPublicKeyFree(data_key);
        VbExFree(body_digest);
        VBPERFEND("VB_VFD");
        continue;
      }
      VbExFree(body_digest);
      VBPERFEND("VB_VFD");
    }

    /* Done with the data key, so can free it now */
    RSAPublicKeyFree(data_key);

    /* If we're still here, the firmware is valid. */
    VBDEBUG(("Firmware %d is valid.\n", index));
    *check_result = VBSD_LF_CHECK_VALID;
    if (-1 == good_index) {
      /* Save the key we actually used */
      if (0 != VbSharedDataSetKernelKey(shared, &preamble->kernel_subkey)) {
        VBDEBUG(("Unable to save kernel subkey to shared data.\n"));
        continue;  /* The firmware signature was good, but the public
                    * key was bigger that the caller can handle. */
      }

      /* Save the good index, now that we're sure we can actually use
       * this firmware.  That's the one we'll boot. */
      good_index = index;
      shared->firmware_index = (uint8_t)index;
      shared->fw_keyblock_flags = key_block->key_block_flags;

      /* If the good firmware's key version is the same as the tpm,
       * then the TPM doesn't need updating; we can stop now.
       * Otherwise, we'll check all the other headers to see if they
       * contain a newer key. */
      if (combined_version == shared->fw_version_tpm)
        break;
    }
  }

  /* Free internal data */
  VbExFree(lfi);
  cparams->vboot_context = NULL;

  /* Handle finding good firmware */
  if (good_index >= 0) {

    /* Save versions we found */
    shared->fw_version_lowest = lowest_version;
    if (lowest_version > shared->fw_version_tpm)
      shared->fw_version_tpm = lowest_version;

    /* Success */
    VBDEBUG(("Will boot firmware index %d\n", (int)shared->firmware_index));
    retval = VBERROR_SUCCESS;
  } else {
    uint8_t a = shared->check_fw_a_result;
    uint8_t b = shared->check_fw_b_result;
    uint8_t best_check;

    /* No good firmware, so go to recovery mode. */
    VBDEBUG(("Alas, no good firmware.\n"));
    recovery = VBNV_RECOVERY_RO_INVALID_RW;
    retval = VBERROR_LOAD_FIRMWARE;

    /* If the best check result fits in the range of recovery reasons, provide
     * more detail on how far we got in validation. */
    best_check = (a > b ? a : b) + VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN;
    if (best_check >= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN &&
        best_check <= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX)
      recovery = best_check;
  }

LoadFirmwareExit:
  /* Store recovery request, if any */
  VbNvSet(vnc, VBNV_RECOVERY_REQUEST, VBERROR_SUCCESS != retval ?
          recovery : VBNV_RECOVERY_NOT_REQUESTED);

  return retval;
}
