/* 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.
 *
 * 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;
  uint32_t test_err = 0;
  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"));

  /* Handle test errors */
  VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err);
  if (VBNV_TEST_ERROR_LOAD_FIRMWARE == test_err) {
    /* Get error code */
    VbNvGet(vnc, VBNV_TEST_ERROR_NUM, &test_err);
    /* Clear test params so we don't repeat the error */
    VbNvSet(vnc, VBNV_TEST_ERROR_FUNC, 0);
    VbNvSet(vnc, VBNV_TEST_ERROR_NUM, 0);
    /* All error codes currently map to simulated error */
    if (test_err) {
      recovery = VBNV_RECOVERY_RO_TEST_LF;
      retval = VBERROR_SIMULATED;
      goto LoadFirmwareExit;
    }
  }

  /* 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 (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) {
      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;
}
