/* 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.
 *
 * Functions for querying, manipulating and locking rollback indices
 * stored in the TPM NVRAM.
 */

#include "2sysincludes.h"
#include "2common.h"
#include "2crc8.h"

#include "sysincludes.h"
#include "rollback_index.h"
#include "tlcl.h"
#include "tss_constants.h"
#include "utility.h"
#include "vboot_api.h"

#ifndef offsetof
#define offsetof(A,B) __builtin_offsetof(A,B)
#endif

/*
 * Provide protoypes for functions not in the header file. These prototypes
 * fix -Wmissing-prototypes warnings.
 */
uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf);
uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf);
uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk);
uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk);

#ifdef FOR_TEST
/*
 * Compiling for unit test, so we need the real implementations of
 * rollback functions.  The unit test mocks the underlying tlcl
 * functions, so this is ok to run on the host.
 */
#undef CHROMEOS_ENVIRONMENT
#undef DISABLE_ROLLBACK_TPM
#endif

#define RETURN_ON_FAILURE(tpm_command) do {				\
		uint32_t result_;					\
		if ((result_ = (tpm_command)) != TPM_SUCCESS) {		\
			VB2_DEBUG("Rollback: %08x returned by " #tpm_command \
				  "\n", (int)result_);			\
			return result_;					\
		}							\
	} while (0)


uint32_t TPMClearAndReenable(void)
{
	VB2_DEBUG("TPM: Clear and re-enable\n");
	RETURN_ON_FAILURE(TlclForceClear());
	RETURN_ON_FAILURE(TlclSetEnable());
	RETURN_ON_FAILURE(TlclSetDeactivated(0));

	return TPM_SUCCESS;
}

uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length)
{
	uint32_t result = TlclWrite(index, data, length);
	if (result == TPM_E_MAXNVWRITES) {
		RETURN_ON_FAILURE(TPMClearAndReenable());
		return TlclWrite(index, data, length);
	} else {
		return result;
	}
}

/* Functions to read and write firmware and kernel spaces. */
uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf)
{
	uint32_t r;
	int attempts = 3;

	while (attempts--) {
		r = TlclRead(FIRMWARE_NV_INDEX, rsf,
			     sizeof(RollbackSpaceFirmware));
		if (r != TPM_SUCCESS)
			return r;

		/*
		 * No CRC in this version, so we'll create one when we write
		 * it. Note that we're marking this as version 2, not
		 * ROLLBACK_SPACE_FIRMWARE_VERSION, because version 2 just
		 * added the CRC. Later versions will need to set default
		 * values for any extra fields explicitly (probably here).
		 */
		if (rsf->struct_version < 2) {
			/* Danger Will Robinson! Danger! */
			rsf->struct_version = 2;
			return TPM_SUCCESS;
		}

		/*
		 * If the CRC is good, we're done. If it's bad, try a couple
		 * more times to see if it gets better before we give up. It
		 * could just be noise.
		 */
		if (rsf->crc8 == vb2_crc8(rsf,
				      offsetof(RollbackSpaceFirmware, crc8)))
			return TPM_SUCCESS;

		VB2_DEBUG("TPM: bad CRC\n");
	}

	VB2_DEBUG("TPM: too many bad CRCs, giving up\n");
	return TPM_E_CORRUPTED_STATE;
}

uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf)
{
	RollbackSpaceFirmware rsf2;
	uint32_t r;
	int attempts = 3;

	/* All writes should use struct_version 2 or greater. */
	if (rsf->struct_version < 2)
		rsf->struct_version = 2;
	rsf->crc8 = vb2_crc8(rsf, offsetof(RollbackSpaceFirmware, crc8));

	while (attempts--) {
		r = SafeWrite(FIRMWARE_NV_INDEX, rsf,
			      sizeof(RollbackSpaceFirmware));
		/* Can't write, not gonna try again */
		if (r != TPM_SUCCESS)
			return r;

		/* Read it back to be sure it got the right values. */
		r = ReadSpaceFirmware(&rsf2);    /* This checks the CRC */
		if (r == TPM_SUCCESS)
			return r;

		VB2_DEBUG("TPM: bad CRC\n");
		/* Try writing it again. Maybe it was garbled on the way out. */
	}

	VB2_DEBUG("TPM: too many bad CRCs, giving up\n");
	return TPM_E_CORRUPTED_STATE;
}

uint32_t SetVirtualDevMode(int val)
{
	RollbackSpaceFirmware rsf;

	VB2_DEBUG("TPM: Entering\n");
	if (TPM_SUCCESS != ReadSpaceFirmware(&rsf))
		return VBERROR_TPM_FIRMWARE_SETUP;

	VB2_DEBUG("TPM: flags were 0x%02x\n", rsf.flags);
	if (val)
		rsf.flags |= FLAG_VIRTUAL_DEV_MODE_ON;
	else
		rsf.flags &= ~FLAG_VIRTUAL_DEV_MODE_ON;
	/*
	 * NOTE: This doesn't update the FLAG_LAST_BOOT_DEVELOPER bit.  That
	 * will be done on the next boot.
	 */
	VB2_DEBUG("TPM: flags are now 0x%02x\n", rsf.flags);

	if (TPM_SUCCESS != WriteSpaceFirmware(&rsf))
		return VBERROR_TPM_SET_BOOT_MODE_STATE;

	VB2_DEBUG("TPM: Leaving\n");
	return VBERROR_SUCCESS;
}

uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk)
{
	uint32_t r;
	int attempts = 3;

	while (attempts--) {
		r = TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
		if (r != TPM_SUCCESS)
			return r;

		/*
		 * No CRC in this version, so we'll create one when we write
		 * it. Note that we're marking this as version 2, not
		 * ROLLBACK_SPACE_KERNEL_VERSION, because version 2 just added
		 * the CRC. Later versions will need to set default values for
		 * any extra fields explicitly (probably here).
		 */
		if (rsk->struct_version < 2) {
			/* Danger Will Robinson! Danger! */
			rsk->struct_version = 2;
			return TPM_SUCCESS;
		}

		/*
		 * If the CRC is good, we're done. If it's bad, try a couple
		 * more times to see if it gets better before we give up. It
		 * could just be noise.
		 */
		if (rsk->crc8 ==
		    vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8)))
			return TPM_SUCCESS;

		VB2_DEBUG("TPM: bad CRC\n");
	}

	VB2_DEBUG("TPM: too many bad CRCs, giving up\n");
	return TPM_E_CORRUPTED_STATE;
}

uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk)
{
	RollbackSpaceKernel rsk2;
	uint32_t r;
	int attempts = 3;

	/* All writes should use struct_version 2 or greater. */
	if (rsk->struct_version < 2)
		rsk->struct_version = 2;
	rsk->crc8 = vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8));

	while (attempts--) {
		r = SafeWrite(KERNEL_NV_INDEX, rsk,
			      sizeof(RollbackSpaceKernel));
		/* Can't write, not gonna try again */
		if (r != TPM_SUCCESS)
			return r;

		/* Read it back to be sure it got the right values. */
		r = ReadSpaceKernel(&rsk2);    /* This checks the CRC */
		if (r == TPM_SUCCESS)
			return r;

		VB2_DEBUG("TPM: bad CRC\n");
		/* Try writing it again. Maybe it was garbled on the way out. */
	}

	VB2_DEBUG("TPM: too many bad CRCs, giving up\n");
	return TPM_E_CORRUPTED_STATE;
}

#ifdef DISABLE_ROLLBACK_TPM
/* Dummy implementations which don't support TPM rollback protection */

uint32_t RollbackKernelRead(uint32_t* version)
{
	*version = 0;
	return TPM_SUCCESS;
}

uint32_t RollbackKernelWrite(uint32_t version)
{
	return TPM_SUCCESS;
}

uint32_t RollbackKernelLock(int recovery_mode)
{
	return TPM_SUCCESS;
}

uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp)
{
	memset(fwmp, 0, sizeof(*fwmp));
	return TPM_SUCCESS;
}

#else

uint32_t RollbackKernelRead(uint32_t* version)
{
	RollbackSpaceKernel rsk;

	/*
	 * Read the kernel space and verify its permissions.  If the kernel
	 * space has the wrong permission, or it doesn't contain the right
	 * identifier, we give up.  This will need to be fixed by the
	 * recovery kernel.  We have to worry about this because at any time
	 * (even with PP turned off) the TPM owner can remove and redefine a
	 * PP-protected space (but not write to it).
	 */
	RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
#ifndef TPM2_MODE
	/*
	 * TODO(vbendeb): restore this when it is defined how the kernel space
	 * gets protected.
	 */
	{
		uint32_t perms, uid;

		RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
		memcpy(&uid, &rsk.uid, sizeof(uid));
		if (TPM_NV_PER_PPWRITE != perms ||
		    ROLLBACK_SPACE_KERNEL_UID != uid)
			return TPM_E_CORRUPTED_STATE;
	}
#endif
	memcpy(version, &rsk.kernel_versions, sizeof(*version));
	VB2_DEBUG("TPM: RollbackKernelRead %x\n", (int)*version);
	return TPM_SUCCESS;
}

uint32_t RollbackKernelWrite(uint32_t version)
{
	RollbackSpaceKernel rsk;
	uint32_t old_version;
	RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
	memcpy(&old_version, &rsk.kernel_versions, sizeof(old_version));
	VB2_DEBUG("TPM: RollbackKernelWrite %x --> %x\n",
		  (int)old_version, (int)version);
	memcpy(&rsk.kernel_versions, &version, sizeof(version));
	return WriteSpaceKernel(&rsk);
}

uint32_t RollbackKernelLock(int recovery_mode)
{
	static int kernel_locked = 0;
	uint32_t r;

	if (recovery_mode || kernel_locked)
		return TPM_SUCCESS;

	r = TlclLockPhysicalPresence();
	if (TPM_SUCCESS == r)
		kernel_locked = 1;
	return r;
}

uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp)
{
	union {
		/*
		 * Use a union for buf and bf, rather than making bf a pointer
		 * to a bare uint8_t[] buffer.  This ensures bf will be aligned
		 * if necesssary for the target platform.
		 */
		uint8_t buf[FWMP_NV_MAX_SIZE];
		struct RollbackSpaceFwmp bf;
	} u;
	uint32_t r;
	int attempts = 3;

	/* Clear destination in case error or FWMP not present */
	memset(fwmp, 0, sizeof(*fwmp));

	while (attempts--) {
		/* Try to read entire 1.0 struct */
		r = TlclRead(FWMP_NV_INDEX, u.buf, sizeof(u.bf));
		if (r == TPM_E_BADINDEX) {
			/* Missing space is not an error; use defaults */
			VB2_DEBUG("TPM: no FWMP space\n");
			return TPM_SUCCESS;
		} else if (r != TPM_SUCCESS) {
			VB2_DEBUG("TPM: read returned 0x%x\n", r);
			return r;
		}

		/*
		 * Struct must be at least big enough for 1.0, but not bigger
		 * than our buffer size.
		 */
		if (u.bf.struct_size < sizeof(u.bf) ||
		    u.bf.struct_size > sizeof(u.buf))
			return TPM_E_STRUCT_SIZE;

		/*
		 * If space is bigger than we expect, re-read so we properly
		 * compute the CRC.
		 */
		if (u.bf.struct_size > sizeof(u.bf)) {
			r = TlclRead(FWMP_NV_INDEX, u.buf, u.bf.struct_size);
			if (r != TPM_SUCCESS)
				return r;
		}

		/* Verify CRC */
		if (u.bf.crc != vb2_crc8(u.buf + 2, u.bf.struct_size - 2)) {
			VB2_DEBUG("TPM: bad CRC\n");
			continue;
		}

		/* Verify major version is compatible */
		if ((u.bf.struct_version >> 4) !=
		    (ROLLBACK_SPACE_FWMP_VERSION >> 4))
			return TPM_E_STRUCT_VERSION;

		/*
		 * Copy to destination.  Note that if the space is bigger than
		 * we expect (due to a minor version change), we only copy the
		 * part of the FWMP that we know what to do with.
		 *
		 * If this were a 1.1+ reader and the source was a 1.0 struct,
		 * we would need to take care of initializing the extra fields
		 * added in 1.1+.  But that's not an issue yet.
		 */
		memcpy(fwmp, &u.bf, sizeof(*fwmp));
		return TPM_SUCCESS;
	}

	VB2_DEBUG("TPM: too many bad CRCs, giving up\n");
	return TPM_E_CORRUPTED_STATE;
}

#endif /* DISABLE_ROLLBACK_TPM */
