示例#1
0
int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
{
	uint32_t rv;
	printk(BIOS_INFO, "Clearing TPM owner\n");
	rv = tpm_clear_and_reenable();
	if (rv)
		return VB2_ERROR_EX_TPM_CLEAR_OWNER;
	return VB2_SUCCESS;
}
示例#2
0
uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
{
	uint32_t result = tlcl_define_space(index, perm, size);
	if (result == TPM_E_MAXNVWRITES) {
		RETURN_ON_FAILURE(tpm_clear_and_reenable());
		return tlcl_define_space(index, perm, size);
	} else {
		return result;
	}
}
示例#3
0
uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
{
	uint32_t result = tlcl_write(index, data, length);
	if (result == TPM_E_MAXNVWRITES) {
		RETURN_ON_FAILURE(tpm_clear_and_reenable());
		return tlcl_write(index, data, length);
	} else {
		return result;
	}
}
示例#4
0
uint32_t factory_initialize_tpm(struct vb2_context *ctx)
{
	TPM_PERMANENT_FLAGS pflags;
	uint32_t result;
	/* this is derived from rollback_index.h of vboot_reference. see struct
	 * RollbackSpaceKernel for details. */
	static const uint8_t secdata_kernel[] = {
			0x02,
			0x4C, 0x57, 0x52, 0x47,
			0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00,
			0xE8,
	};

	VBDEBUG("TPM: factory initialization\n");

	/*
	 * Do a full test.  This only happens the first time the device is
	 * turned on in the factory, so performance is not an issue.  This is
	 * almost certainly not necessary, but it gives us more confidence
	 * about some code paths below that are difficult to
	 * test---specifically the ones that set lifetime flags, and are only
	 * executed once per physical TPM.
	 */
	result = tlcl_self_test_full();
	if (result != TPM_SUCCESS)
		return result;

	result = tlcl_get_permanent_flags(&pflags);
	if (result != TPM_SUCCESS)
		return result;

	/*
	 * TPM may come from the factory without physical presence finalized.
	 * Fix if necessary.
	 */
	VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
		 pflags.physicalPresenceLifetimeLock);
	if (!pflags.physicalPresenceLifetimeLock) {
		VBDEBUG("TPM: Finalizing physical presence\n");
		RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
	}

	/*
	 * The TPM will not enforce the NV authorization restrictions until the
	 * execution of a TPM_NV_DefineSpace with the handle of
	 * TPM_NV_INDEX_LOCK.  Here we create that space if it doesn't already
	 * exist. */
	VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
	if (!pflags.nvLocked) {
		VBDEBUG("TPM: Enabling NV locking\n");
		RETURN_ON_FAILURE(tlcl_set_nv_locked());
	}

	/* Clear TPM owner, in case the TPM is already owned for some reason. */
	VBDEBUG("TPM: Clearing owner\n");
	RETURN_ON_FAILURE(tpm_clear_and_reenable());

	/* Define the backup space. No need to initialize it, though. */
	RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX,
					    TPM_NV_PER_PPWRITE,
					    VB2_NVDATA_SIZE));

	/* Define and initialize the kernel space */
	RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
					    TPM_NV_PER_PPWRITE,
					    sizeof(secdata_kernel)));
	RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
					secdata_kernel,
					sizeof(secdata_kernel)));

	/* Defines and sets vb2 secdata space */
	vb2api_secdata_create(ctx);
	RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
	                                    TPM_NV_PER_GLOBALLOCK |
	                                    TPM_NV_PER_PPWRITE,
	                                    VB2_SECDATA_SIZE));
	RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
					ctx->secdata,
					VB2_SECDATA_SIZE));

	VBDEBUG("TPM: factory initialization successful\n");

	return TPM_SUCCESS;
}