vboot2: factory-initialize kernel space in tpm
this change makes coreboot initialize kernel space and backup space in the tpm when no firmware space is found in the tpm. BUG=chrome-os-partner:32410 TEST=Forced factory initialization and verified it went through without errors. BRANCH=None Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Original-Change-Id: I777e3cb7004870c769163827543c83665d3732b9 Original-Reviewed-on: https://chromium-review.googlesource.com/220412 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Randall Spangler <rspangler@chromium.org> Original-Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Original-Tested-by: Daisuke Nojiri <dnojiri@chromium.org> (cherry picked from commit d8c0c407bf0fed60d76441ada7bedd36f6fc3a38) Change-Id: Icc3779125262b4499e47781991ebbf584abf074a Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/8885 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
6abe7c6996
commit
97ea9c0516
|
@ -15,6 +15,9 @@
|
||||||
|
|
||||||
/* TPM NVRAM location indices. */
|
/* TPM NVRAM location indices. */
|
||||||
#define FIRMWARE_NV_INDEX 0x1007
|
#define FIRMWARE_NV_INDEX 0x1007
|
||||||
|
#define KERNEL_NV_INDEX 0x1008
|
||||||
|
/* This is just an opaque space for backup purposes */
|
||||||
|
#define BACKUP_NV_INDEX 0x1009
|
||||||
|
|
||||||
/* Structure definitions for TPM spaces */
|
/* Structure definitions for TPM spaces */
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
uint32_t tpm_clear_and_reenable(void)
|
uint32_t tpm_clear_and_reenable(void)
|
||||||
{
|
{
|
||||||
VBDEBUG("TPM: Clear and re-enable\n");
|
VBDEBUG("TPM: Clear and re-enable\n");
|
||||||
|
@ -85,30 +84,36 @@ static uint32_t read_space_firmware(struct vb2_context *ctx)
|
||||||
return TPM_E_CORRUPTED_STATE;
|
return TPM_E_CORRUPTED_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t write_space_firmware(struct vb2_context *ctx)
|
static uint32_t write_secdata(uint32_t index,
|
||||||
|
const uint8_t *secdata,
|
||||||
|
uint32_t len)
|
||||||
{
|
{
|
||||||
uint8_t secdata[VB2_SECDATA_SIZE];
|
uint8_t sd[32];
|
||||||
uint32_t r;
|
uint32_t rv;
|
||||||
int attempts = 3;
|
int attempts = 3;
|
||||||
|
|
||||||
memcpy(secdata, ctx->secdata, VB2_SECDATA_SIZE);
|
if (len > sizeof(sd)) {
|
||||||
|
VBDEBUG("TPM: %s() - data is too large\n", __func__);
|
||||||
|
return TPM_E_WRITE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
while (attempts--) {
|
while (attempts--) {
|
||||||
r = safe_write(FIRMWARE_NV_INDEX, secdata, VB2_SECDATA_SIZE);
|
rv = safe_write(index, secdata, len);
|
||||||
/* Can't write, not gonna try again */
|
/* Can't write, not gonna try again */
|
||||||
if (r != TPM_SUCCESS)
|
if (rv != TPM_SUCCESS)
|
||||||
return r;
|
return rv;
|
||||||
|
|
||||||
/* Read it back to be sure it got the right values. */
|
/* Read it back to be sure it got the right values. */
|
||||||
r = read_space_firmware(ctx);
|
rv = tlcl_read(index, sd, len);
|
||||||
if (r == TPM_SUCCESS && memcmp(secdata, ctx->secdata,
|
if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
|
||||||
VB2_SECDATA_SIZE) == 0)
|
return rv;
|
||||||
return r;
|
|
||||||
|
|
||||||
VBDEBUG("TPM: %s() failed\n", __func__);
|
VBDEBUG("TPM: %s() failed. trying again\n", __func__);
|
||||||
/* Try writing it again. Maybe it was garbled on the way out. */
|
/* Try writing it again. Maybe it was garbled on the way out. */
|
||||||
}
|
}
|
||||||
|
|
||||||
VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
|
VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
|
||||||
|
|
||||||
return TPM_E_CORRUPTED_STATE;
|
return TPM_E_CORRUPTED_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +121,15 @@ uint32_t factory_initialize_tpm(struct vb2_context *ctx)
|
||||||
{
|
{
|
||||||
TPM_PERMANENT_FLAGS pflags;
|
TPM_PERMANENT_FLAGS pflags;
|
||||||
uint32_t result;
|
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");
|
VBDEBUG("TPM: factory initialization\n");
|
||||||
|
|
||||||
|
@ -161,13 +175,30 @@ uint32_t factory_initialize_tpm(struct vb2_context *ctx)
|
||||||
VBDEBUG("TPM: Clearing owner\n");
|
VBDEBUG("TPM: Clearing owner\n");
|
||||||
RETURN_ON_FAILURE(tpm_clear_and_reenable());
|
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 */
|
/* Defines and sets vb2 secdata space */
|
||||||
vb2api_secdata_create(ctx);
|
vb2api_secdata_create(ctx);
|
||||||
RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
|
RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
|
||||||
TPM_NV_PER_GLOBALLOCK |
|
TPM_NV_PER_GLOBALLOCK |
|
||||||
TPM_NV_PER_PPWRITE,
|
TPM_NV_PER_PPWRITE,
|
||||||
VB2_SECDATA_SIZE));
|
VB2_SECDATA_SIZE));
|
||||||
RETURN_ON_FAILURE(write_space_firmware(ctx));
|
RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
|
||||||
|
ctx->secdata,
|
||||||
|
VB2_SECDATA_SIZE));
|
||||||
|
|
||||||
|
VBDEBUG("TPM: factory initialization successful\n");
|
||||||
|
|
||||||
return TPM_SUCCESS;
|
return TPM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -289,7 +320,7 @@ uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
|
||||||
|
|
||||||
uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
|
uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
|
||||||
{
|
{
|
||||||
return write_space_firmware(ctx);
|
return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t antirollback_lock_space_firmware()
|
uint32_t antirollback_lock_space_firmware()
|
||||||
|
|
Loading…
Reference in New Issue