/* Copyright (c) 2013 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 = 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 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;
			}

			/* 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(("Hashed %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(("FW 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)) {
				/*
				 * The firmware signature was good, but the
				 * public key was bigger that the caller can
				 * handle.
				 */
				VBDEBUG(("Unable to save kernel subkey.\n"));
				continue;
			}

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