treewide: convert to tpm_result_t

Convert TPM functions to return TPM error codes(referred to as
tpm_result_t) values to match the TCG standard.

BUG=b:296439237
TEST=build and boot to Skyrim
BRANCH=None

Change-Id: Ifdf9ff6c2a1f9b938dbb04d245799391115eb6b1
Signed-off-by: Jon Murphy <jpmurphy@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77666
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Jon Murphy
2023-09-05 11:36:43 -06:00
committed by Raul Rangel
parent 53fc667943
commit d7b8dc9cf5
44 changed files with 734 additions and 653 deletions

View File

@@ -35,50 +35,52 @@ static const char *tis_get_dev_name(struct tpm2_info *info)
return "Unknown"; return "Unknown";
} }
int tis_open(void) tpm_result_t tis_open(void)
{ {
if (tpm_is_open) { if (tpm_is_open) {
printk(BIOS_ERR, "%s called twice.\n", __func__); printk(BIOS_ERR, "%s called twice.\n", __func__);
return -1; return TPM_CB_FAIL;
} }
if (CONFIG(HAVE_INTEL_PTT)) { if (CONFIG(HAVE_INTEL_PTT)) {
if (!ptt_active()) { if (!ptt_active()) {
printk(BIOS_ERR, "%s: Intel PTT is not active.\n", __func__); printk(BIOS_ERR, "%s: Intel PTT is not active.\n", __func__);
return -1; return TPM_CB_FAIL;
} }
printk(BIOS_DEBUG, "%s: Intel PTT is active.\n", __func__); printk(BIOS_DEBUG, "%s: Intel PTT is active.\n", __func__);
} }
return 0; return TPM_SUCCESS;
} }
int tis_init(void) tpm_result_t tis_init(void)
{ {
struct tpm2_info info; struct tpm2_info info;
// Wake TPM up (if necessary) // Wake TPM up (if necessary)
if (tpm2_init() != 0) tpm_result_t rc = tpm2_init();
return -1; if (rc)
return rc;
tpm2_get_info(&info); tpm2_get_info(&info);
printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", tis_get_dev_name(&info), printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", tis_get_dev_name(&info),
info.revision); info.revision);
return 0; return TPM_SUCCESS;
} }
int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len) tpm_result_t tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
uint8_t *recvbuf, size_t *rbuf_len)
{ {
int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len);
if (len == 0) if (len == 0)
return -1; return TPM_CB_FAIL;
*rbuf_len = len; *rbuf_len = len;
return 0; return TPM_SUCCESS;
} }
static void crb_tpm_fill_ssdt(const struct device *dev) static void crb_tpm_fill_ssdt(const struct device *dev)
@@ -118,28 +120,28 @@ static const char *crb_tpm_acpi_name(const struct device *dev)
} }
#if CONFIG(GENERATE_SMBIOS_TABLES) && CONFIG(TPM2) #if CONFIG(GENERATE_SMBIOS_TABLES) && CONFIG(TPM2)
static int tpm_get_cap(uint32_t property, uint32_t *value) static tpm_result_t tpm_get_cap(uint32_t property, uint32_t *value)
{ {
TPMS_CAPABILITY_DATA cap_data; TPMS_CAPABILITY_DATA cap_data;
int i; int i;
uint32_t rc; tpm_result_t rc;
if (!value) if (!value)
return -1; return TPM_CB_INVALID_ARG;
rc = tlcl_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data); rc = tlcl_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data);
if (rc) if (rc)
return -1; return rc;
for (i = 0 ; i < cap_data.data.tpmProperties.count; i++) { for (i = 0 ; i < cap_data.data.tpmProperties.count; i++) {
if (cap_data.data.tpmProperties.tpmProperty[i].property == property) { if (cap_data.data.tpmProperties.tpmProperty[i].property == property) {
*value = cap_data.data.tpmProperties.tpmProperty[i].value; *value = cap_data.data.tpmProperties.tpmProperty[i].value;
return 0; return TPM_SUCCESS;
} }
} }
return -1; return TPM_CB_FAIL;
} }
static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned long *current) static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned long *current)

View File

@@ -67,7 +67,7 @@ static void crb_readControlArea(void)
} }
/* Wait for Reg to be expected Value */ /* Wait for Reg to be expected Value */
static int crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mask, static tpm_result_t crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mask,
uint32_t expectedValue) uint32_t expectedValue)
{ {
uint32_t regValue; uint32_t regValue;
@@ -81,13 +81,13 @@ static int crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mas
regValue = read32(addr); regValue = read32(addr);
if ((regValue & mask) == expectedValue) if ((regValue & mask) == expectedValue)
return 0; return TPM_SUCCESS;
if (stopwatch_expired(&sw)) { if (stopwatch_expired(&sw)) {
printk(BIOS_ERR, printk(BIOS_ERR,
"CRB_WAIT: Error - Timed out with RegValue: %08x, Mask: %08x, Expected: %08x\n", "CRB_WAIT: Error - Timed out with RegValue: %08x, Mask: %08x, Expected: %08x\n",
regValue, mask, expectedValue); regValue, mask, expectedValue);
return -1; return TPM_CB_TIMEOUT;
} }
} }
} }
@@ -96,27 +96,27 @@ static int crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mas
* *
* Checks if the CRB Interface is ready * Checks if the CRB Interface is ready
*/ */
static int crb_probe(void) static tpm_result_t crb_probe(void)
{ {
uint64_t tpmStatus = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID)); uint64_t tpmStatus = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID));
printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus); printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus);
if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) { if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) {
printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n"); printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n");
return -1; return TPM_CB_FAIL;
} }
if ((tpmStatus & (0xf)) != 1) { if ((tpmStatus & (0xf)) != 1) {
printk(BIOS_DEBUG, printk(BIOS_DEBUG,
"TPM: CRB Interface is not active. System needs reboot in order to active TPM.\n"); "TPM: CRB Interface is not active. System needs reboot in order to active TPM.\n");
write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL); write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
return -1; return TPM_CB_FAIL;
} }
write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL); write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_LOCK); write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_LOCK);
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -129,7 +129,7 @@ static uint8_t crb_activate_locality(void)
uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07; uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07;
printk(BIOS_SPEW, "Active locality: %i\n", locality); printk(BIOS_SPEW, "Active locality: %i\n", locality);
int rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, tpm_result_t rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750,
LOC_STATE_LOC_ASSIGN, LOC_STATE_LOC_ASSIGN); LOC_STATE_LOC_ASSIGN, LOC_STATE_LOC_ASSIGN);
if (!rc && (locality == 0)) if (!rc && (locality == 0))
@@ -141,15 +141,15 @@ static uint8_t crb_activate_locality(void)
rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, LOC_STATE_LOC_ASSIGN, rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, LOC_STATE_LOC_ASSIGN,
LOC_STATE_LOC_ASSIGN); LOC_STATE_LOC_ASSIGN);
if (rc) { if (rc) {
printk(BIOS_ERR, "TPM: Error - No Locality has been assigned TPM-wise.\n"); printk(BIOS_ERR, "TPM: Error (%#x) - No Locality has been assigned TPM-wise.\n", rc);
return 0; return 0;
} }
rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 1500, rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 1500,
LOC_STATE_REG_VALID_STS, LOC_STATE_REG_VALID_STS); LOC_STATE_REG_VALID_STS, LOC_STATE_REG_VALID_STS);
if (rc) { if (rc) {
printk(BIOS_ERR, "TPM: Error - LOC_STATE Register %u contains errors.\n", printk(BIOS_ERR, "TPM: Error (%#x) - LOC_STATE Register %u contains errors.\n",
locality); rc, locality);
return 0; return 0;
} }
@@ -157,27 +157,27 @@ static uint8_t crb_activate_locality(void)
} }
/* Switch Device into a Ready State */ /* Switch Device into a Ready State */
static int crb_switch_to_ready(void) static tpm_result_t crb_switch_to_ready(void)
{ {
/* Transition into ready state */ /* Transition into ready state */
write8(CRB_REG(cur_loc, CRB_REG_REQUEST), 0x1); write8(CRB_REG(cur_loc, CRB_REG_REQUEST), 0x1);
int rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_REQUEST), 200, tpm_result_t rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_REQUEST), 200,
CRB_REG_REQUEST_CMD_RDY, 0x0); CRB_REG_REQUEST_CMD_RDY, 0x0);
if (rc) { if (rc) {
printk(BIOS_ERR, printk(BIOS_ERR,
"TPM: Error - TPM did not transition into ready state in time.\n"); "TPM Error (%#x): TPM did not transition into ready state in time.\n", rc);
return -1; return rc;
} }
/* Check TPM_CRB_CTRL_STS[0] to be "0" - no unrecoverable error */ /* Check TPM_CRB_CTRL_STS[0] to be "0" - no unrecoverable error */
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 500, CRB_REG_STATUS_ERROR, rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 500, CRB_REG_STATUS_ERROR,
0x0); 0x0);
if (rc) { if (rc) {
printk(BIOS_ERR, "TPM: Fatal Error - Could not recover.\n"); printk(BIOS_ERR, "TPM Error (%#x): Could not recover.\n", rc);
return -1; return rc;
} }
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -188,11 +188,12 @@ static int crb_switch_to_ready(void)
* normal bring up mode. * normal bring up mode.
* *
*/ */
int tpm2_init(void) tpm_result_t tpm2_init(void)
{ {
if (crb_probe()) { tpm_result_t rc = crb_probe();
if (rc) {
printk(BIOS_ERR, "TPM: Probe failed.\n"); printk(BIOS_ERR, "TPM: Probe failed.\n");
return -1; return rc;
} }
/* Read back control area structure */ /* Read back control area structure */
@@ -211,7 +212,7 @@ int tpm2_init(void)
/* Good to go. */ /* Good to go. */
printk(BIOS_SPEW, "TPM: CRB TPM initialized successfully\n"); printk(BIOS_SPEW, "TPM: CRB TPM initialized successfully\n");
return 0; return TPM_SUCCESS;
} }
static void set_ptt_cmd_resp_buffers(void) static void set_ptt_cmd_resp_buffers(void)
@@ -231,7 +232,7 @@ static void set_ptt_cmd_resp_buffers(void)
size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void *tpm2_response, size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void *tpm2_response,
size_t max_response) size_t max_response)
{ {
int rc; tpm_result_t rc;
if (command_size > control_area.command_size) { if (command_size > control_area.command_size) {
printk(BIOS_ERR, "TPM: Command size is too big.\n"); printk(BIOS_ERR, "TPM: Command size is too big.\n");
@@ -248,12 +249,15 @@ size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void
// Check if CMD bit is cleared. // Check if CMD bit is cleared.
rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_START), 250, CRB_REG_START_START, 0x0); rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_START), 250, CRB_REG_START_START, 0x0);
if (rc) { if (rc) {
printk(BIOS_ERR, "TPM: Error - Cmd Bit not cleared.\n"); printk(BIOS_ERR, "TPM Error (%#x): Cmd Bit not cleared.\n", rc);
return -1; return -1;
} }
if (crb_switch_to_ready()) rc = crb_switch_to_ready();
if (rc) {
printk(BIOS_DEBUG, "TPM Error (%#x): Can not transition into ready state.\n", rc);
return -1; return -1;
}
// Write to Command Buffer // Write to Command Buffer
memcpy(control_area.command_bfr, tpm2_command, command_size); memcpy(control_area.command_bfr, tpm2_command, command_size);
@@ -272,14 +276,14 @@ size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void
// Poll for Response // Poll for Response
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_START), 3500, CRB_REG_START_START, 0); rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_START), 3500, CRB_REG_START_START, 0);
if (rc) { if (rc) {
printk(BIOS_DEBUG, "TPM: Command Timed out.\n"); printk(BIOS_DEBUG, "TPM Error (%#x): Command Timed out.\n", rc);
return -1; return -1;
} }
// Check for errors // Check for errors
rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 200, CRB_REG_STATUS_ERROR, 0); rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 200, CRB_REG_STATUS_ERROR, 0);
if (rc) { if (rc) {
printk(BIOS_DEBUG, "TPM: Command errored.\n"); printk(BIOS_DEBUG, "TPM Error (%#x): Command errored.\n", rc);
return -1; return -1;
} }
@@ -293,8 +297,9 @@ size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void
// Copy Response // Copy Response
memcpy(tpm2_response, control_area.response_bfr, length); memcpy(tpm2_response, control_area.response_bfr, length);
if (crb_switch_to_ready()) { rc = crb_switch_to_ready();
printk(BIOS_DEBUG, "TPM: Can not transition into ready state again.\n"); if (rc) {
printk(BIOS_DEBUG, "TPM Error (%#x): Can not transition into ready state again.\n", rc);
return -1; return -1;
} }

View File

@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause */ /* SPDX-License-Identifier: BSD-3-Clause */
/* This is a driver for a Command Response Buffer Interface */ /* This is a driver for a Command Response Buffer Interface */
#include <security/tpm/tss_errors.h>
/* CRB driver */ /* CRB driver */
/* address of locality 0 (CRB) */ /* address of locality 0 (CRB) */
#define TPM_CRB_BASE_ADDRESS CONFIG_CRB_TPM_BASE_ADDRESS #define TPM_CRB_BASE_ADDRESS CONFIG_CRB_TPM_BASE_ADDRESS
@@ -58,7 +60,7 @@ struct tpm2_info {
uint16_t revision; uint16_t revision;
}; };
int tpm2_init(void); tpm_result_t tpm2_init(void);
void tpm2_get_info(struct tpm2_info *tpm2_info); void tpm2_get_info(struct tpm2_info *tpm2_info);
size_t tpm2_process_command(const void *tpm2_command, size_t command_size, size_t tpm2_process_command(const void *tpm2_command, size_t command_size,
void *tpm2_response, size_t max_response); void *tpm2_response, size_t max_response);

View File

@@ -56,12 +56,12 @@ static struct tpm_inf_dev tpm_dev;
* 2) wait for TPM to indicate it is ready * 2) wait for TPM to indicate it is ready
* 3) read 'len' bytes of TPM response into the provided 'buffer' * 3) read 'len' bytes of TPM response into the provided 'buffer'
* *
* Return -1 on error, 0 on success. * Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
static int cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len) static tpm_result_t cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len)
{ {
if (tpm_dev.addr == 0) if (tpm_dev.addr == 0)
return -1; return TPM_CB_FAIL;
/* Clear interrupt before starting transaction */ /* Clear interrupt before starting transaction */
cr50_plat_irq_status(); cr50_plat_irq_status();
@@ -69,20 +69,20 @@ static int cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len)
/* Send the register address byte to the TPM */ /* Send the register address byte to the TPM */
if (i2c_write_raw(tpm_dev.bus, tpm_dev.addr, &addr, 1)) { if (i2c_write_raw(tpm_dev.bus, tpm_dev.addr, &addr, 1)) {
printk(BIOS_ERR, "%s: Address write failed\n", __func__); printk(BIOS_ERR, "%s: Address write failed\n", __func__);
return -1; return TPM_CB_FAIL;
} }
/* Wait for TPM to be ready with response data */ /* Wait for TPM to be ready with response data */
if (cr50_wait_tpm_ready() != CB_SUCCESS) if (cr50_wait_tpm_ready() != CB_SUCCESS)
return -1; return TPM_CB_FAIL;
/* Read response data from the TPM */ /* Read response data from the TPM */
if (i2c_read_raw(tpm_dev.bus, tpm_dev.addr, buffer, len)) { if (i2c_read_raw(tpm_dev.bus, tpm_dev.addr, buffer, len)) {
printk(BIOS_ERR, "%s: Read response failed\n", __func__); printk(BIOS_ERR, "%s: Read response failed\n", __func__);
return -1; return TPM_CB_FAIL;
} }
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -96,14 +96,14 @@ static int cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len)
* 2) send the address+data to the TPM * 2) send the address+data to the TPM
* 3) wait for TPM to indicate it is done writing * 3) wait for TPM to indicate it is done writing
* *
* Returns -1 on error, 0 on success. * Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
static int cr50_i2c_write(uint8_t addr, const uint8_t *buffer, size_t len) static tpm_result_t cr50_i2c_write(uint8_t addr, const uint8_t *buffer, size_t len)
{ {
if (tpm_dev.addr == 0) if (tpm_dev.addr == 0)
return -1; return TPM_CB_INVALID_ARG;
if (len > CR50_MAX_BUFSIZE) if (len > CR50_MAX_BUFSIZE)
return -1; return TPM_CB_INVALID_ARG;
/* Prepend the 'register address' to the buffer */ /* Prepend the 'register address' to the buffer */
tpm_dev.buf[0] = addr; tpm_dev.buf[0] = addr;
@@ -115,11 +115,11 @@ static int cr50_i2c_write(uint8_t addr, const uint8_t *buffer, size_t len)
/* Send write request buffer with address */ /* Send write request buffer with address */
if (i2c_write_raw(tpm_dev.bus, tpm_dev.addr, tpm_dev.buf, len + 1)) { if (i2c_write_raw(tpm_dev.bus, tpm_dev.addr, tpm_dev.buf, len + 1)) {
printk(BIOS_ERR, "%s: Error writing to TPM\n", __func__); printk(BIOS_ERR, "%s: Error writing to TPM\n", __func__);
return -1; return TPM_CB_FAIL;
} }
/* Wait for TPM to be ready */ /* Wait for TPM to be ready */
return cr50_wait_tpm_ready() == CB_SUCCESS ? 0 : -1; return cr50_wait_tpm_ready() == CB_SUCCESS ? TPM_SUCCESS : TPM_CB_FAIL;
} }
/* /*
@@ -128,11 +128,13 @@ static int cr50_i2c_write(uint8_t addr, const uint8_t *buffer, size_t len)
* *
* This function will make sure that the AP does not proceed with boot until * This function will make sure that the AP does not proceed with boot until
* TPM finished reset processing. * TPM finished reset processing.
*
* Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
static int process_reset(void) static tpm_result_t process_reset(void)
{ {
struct stopwatch sw; struct stopwatch sw;
int rc = 0; tpm_result_t rc = TPM_SUCCESS;
uint8_t access; uint8_t access;
/* /*
@@ -162,59 +164,72 @@ static int process_reset(void)
printk(BIOS_INFO, "TPM ready after %lld ms\n", printk(BIOS_INFO, "TPM ready after %lld ms\n",
stopwatch_duration_msecs(&sw)); stopwatch_duration_msecs(&sw));
return 0; return TPM_SUCCESS;
} while (!stopwatch_expired(&sw)); } while (!stopwatch_expired(&sw));
if (rc) if (rc) {
printk(BIOS_ERR, "Failed to read TPM\n"); printk(BIOS_ERR, "Failed to read TPM with error %d\n", rc);
else return rc;
} else
printk(BIOS_ERR, printk(BIOS_ERR,
"TPM failed to reset after %lld ms, status: %#x\n", "TPM failed to reset after %lld ms, status: %#x\n",
stopwatch_duration_msecs(&sw), access); stopwatch_duration_msecs(&sw), access);
return TPM_CB_FAIL;
return -1;
} }
/* /*
* Locality could be already claimed (if this is a later coreboot stage and * Locality could be already claimed (if this is a later coreboot stage and
* the RO did not release it), or not yet claimed, if this is verstage or the * the RO did not release it), or not yet claimed, if this is verstage or the
* older RO did release it. * older RO did release it.
*
* Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
static int claim_locality(void) static tpm_result_t claim_locality(void)
{ {
uint8_t access; uint8_t access;
const uint8_t mask = TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY; const uint8_t mask = TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;
tpm_result_t rc = TPM_SUCCESS;
if (cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access))) rc = cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access));
return -1; if (rc)
return rc;
if ((access & mask) == mask) { if ((access & mask) == mask) {
printk(BIOS_INFO, "Locality already claimed\n"); printk(BIOS_INFO, "Locality already claimed\n");
return 0; return TPM_SUCCESS;
} }
access = TPM_ACCESS_REQUEST_USE; access = TPM_ACCESS_REQUEST_USE;
if (cr50_i2c_write(TPM_ACCESS(0), rc = cr50_i2c_write(TPM_ACCESS(0),
&access, sizeof(access))) &access, sizeof(access));
return -1; if (rc)
return rc;
if (cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access))) rc = cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access));
return -1; if (rc)
return rc;
if ((access & mask) != mask) { if ((access & mask) != mask) {
printk(BIOS_INFO, "Failed to claim locality.\n"); printk(BIOS_INFO, "Failed to claim locality.\n");
return -1; return TPM_CB_FAIL;
} }
return 0; return TPM_SUCCESS;
} }
/* cr50 requires all 4 bytes of status register to be read */ /*
* cr50 requires all 4 bytes of status register to be read
*
* Returns lowest 8-bits of the TIS Status register value
* see tis_status bit mask enumerated type in tis.h.
* Return 0 on error.
*/
static uint8_t cr50_i2c_tis_status(void) static uint8_t cr50_i2c_tis_status(void)
{ {
uint8_t buf[4]; uint8_t buf[4];
if (cr50_i2c_read(TPM_STS(tpm_dev.locality), buf, sizeof(buf)) < 0) { tpm_result_t rc = cr50_i2c_read(TPM_STS(tpm_dev.locality), buf, sizeof(buf));
printk(BIOS_ERR, "%s: Failed to read status\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: Failed to read status with error %#x\n", __func__, rc);
return 0; return 0;
} }
return buf[0]; return buf[0];
@@ -229,16 +244,21 @@ static void cr50_i2c_tis_ready(void)
} }
/* cr50 uses bytes 3:2 of status register for burst count and /* cr50 uses bytes 3:2 of status register for burst count and
* all 4 bytes must be read */ * all 4 bytes must be read
static int cr50_i2c_wait_burststs(uint8_t mask, size_t *burst, int *status) *
* Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/
static tpm_result_t cr50_i2c_wait_burststs(uint8_t mask, size_t *burst, int *status)
{ {
uint8_t buf[4]; uint8_t buf[4];
struct stopwatch sw; struct stopwatch sw;
tpm_result_t rc = TPM_SUCCESS;
stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS); stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);
while (!stopwatch_expired(&sw)) { while (!stopwatch_expired(&sw)) {
if (cr50_i2c_read(TPM_STS(tpm_dev.locality), buf, sizeof(buf)) != 0) { rc = cr50_i2c_read(TPM_STS(tpm_dev.locality), buf, sizeof(buf));
if (rc) {
mdelay(CR50_TIMEOUT_SHORT_MS); mdelay(CR50_TIMEOUT_SHORT_MS);
continue; continue;
} }
@@ -249,13 +269,14 @@ static int cr50_i2c_wait_burststs(uint8_t mask, size_t *burst, int *status)
/* Check if mask matches and burst is valid */ /* Check if mask matches and burst is valid */
if ((*status & mask) == mask && if ((*status & mask) == mask &&
*burst > 0 && *burst <= CR50_MAX_BUFSIZE) *burst > 0 && *burst <= CR50_MAX_BUFSIZE)
return 0; return TPM_SUCCESS;
mdelay(CR50_TIMEOUT_SHORT_MS); mdelay(CR50_TIMEOUT_SHORT_MS);
} }
printk(BIOS_ERR, "%s: Timeout reading burst and status with error %#x\n", __func__, rc);
printk(BIOS_ERR, "%s: Timeout reading burst and status\n", __func__); if (rc)
return -1; return rc;
return TPM_CB_TIMEOUT;
} }
static int cr50_i2c_tis_recv(uint8_t *buf, size_t buf_len) static int cr50_i2c_tis_recv(uint8_t *buf, size_t buf_len)
@@ -264,18 +285,21 @@ static int cr50_i2c_tis_recv(uint8_t *buf, size_t buf_len)
uint8_t addr = TPM_DATA_FIFO(tpm_dev.locality); uint8_t addr = TPM_DATA_FIFO(tpm_dev.locality);
uint8_t mask = TPM_STS_VALID | TPM_STS_DATA_AVAIL; uint8_t mask = TPM_STS_VALID | TPM_STS_DATA_AVAIL;
int status; int status;
tpm_result_t rc = TPM_SUCCESS;
if (buf_len < TPM_HEADER_SIZE) if (buf_len < TPM_HEADER_SIZE)
goto out_err; goto out_err;
if (cr50_i2c_wait_burststs(mask, &burstcnt, &status) < 0) { rc = cr50_i2c_wait_burststs(mask, &burstcnt, &status);
printk(BIOS_ERR, "%s: First chunk not available\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: First chunk not available with error %#x\n", __func__, rc);
goto out_err; goto out_err;
} }
/* Read first chunk of burstcnt bytes */ /* Read first chunk of burstcnt bytes */
if (cr50_i2c_read(addr, buf, burstcnt) != 0) { rc = cr50_i2c_read(addr, buf, burstcnt);
printk(BIOS_ERR, "%s: Read failed\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: Read failed with error %#x\n", __func__, rc);
goto out_err; goto out_err;
} }
@@ -291,12 +315,13 @@ static int cr50_i2c_tis_recv(uint8_t *buf, size_t buf_len)
current = burstcnt; current = burstcnt;
while (current < expected) { while (current < expected) {
/* Read updated burst count and check status */ /* Read updated burst count and check status */
if (cr50_i2c_wait_burststs(mask, &burstcnt, &status) < 0) if (cr50_i2c_wait_burststs(mask, &burstcnt, &status))
goto out_err; goto out_err;
len = MIN(burstcnt, expected - current); len = MIN(burstcnt, expected - current);
if (cr50_i2c_read(addr, buf + current, len) != 0) { rc = cr50_i2c_read(addr, buf + current, len);
printk(BIOS_ERR, "%s: Read failed\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: Read failed with error %#x\n", __func__, rc);
goto out_err; goto out_err;
} }
@@ -304,7 +329,7 @@ static int cr50_i2c_tis_recv(uint8_t *buf, size_t buf_len)
} }
/* Ensure TPM is done reading data */ /* Ensure TPM is done reading data */
if (cr50_i2c_wait_burststs(TPM_STS_VALID, &burstcnt, &status) < 0) if (cr50_i2c_wait_burststs(TPM_STS_VALID, &burstcnt, &status))
goto out_err; goto out_err;
if (status & TPM_STS_DATA_AVAIL) { if (status & TPM_STS_DATA_AVAIL) {
printk(BIOS_ERR, "%s: Data still available\n", __func__); printk(BIOS_ERR, "%s: Data still available\n", __func__);
@@ -326,6 +351,7 @@ static int cr50_i2c_tis_send(uint8_t *buf, size_t len)
size_t burstcnt, limit, sent = 0; size_t burstcnt, limit, sent = 0;
uint8_t tpm_go[4] = { TPM_STS_GO }; uint8_t tpm_go[4] = { TPM_STS_GO };
struct stopwatch sw; struct stopwatch sw;
tpm_result_t rc = TPM_SUCCESS;
stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS); stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);
@@ -348,14 +374,15 @@ static int cr50_i2c_tis_send(uint8_t *buf, size_t len)
mask |= TPM_STS_DATA_EXPECT; mask |= TPM_STS_DATA_EXPECT;
/* Read burst count and check status */ /* Read burst count and check status */
if (cr50_i2c_wait_burststs(mask, &burstcnt, &status) < 0) if (cr50_i2c_wait_burststs(mask, &burstcnt, &status))
goto out_err; goto out_err;
/* Use burstcnt - 1 to account for the address byte /* Use burstcnt - 1 to account for the address byte
* that is inserted by cr50_i2c_write() */ * that is inserted by cr50_i2c_write() */
limit = MIN(burstcnt - 1, len); limit = MIN(burstcnt - 1, len);
if (cr50_i2c_write(TPM_DATA_FIFO(tpm_dev.locality), &buf[sent], limit) != 0) { rc = cr50_i2c_write(TPM_DATA_FIFO(tpm_dev.locality), &buf[sent], limit);
printk(BIOS_ERR, "%s: Write failed\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: Write failed with error %#x\n", __func__, rc);
goto out_err; goto out_err;
} }
@@ -364,7 +391,7 @@ static int cr50_i2c_tis_send(uint8_t *buf, size_t len)
} }
/* Ensure TPM is not expecting more data */ /* Ensure TPM is not expecting more data */
if (cr50_i2c_wait_burststs(TPM_STS_VALID, &burstcnt, &status) < 0) if (cr50_i2c_wait_burststs(TPM_STS_VALID, &burstcnt, &status))
goto out_err; goto out_err;
if (status & TPM_STS_DATA_EXPECT) { if (status & TPM_STS_DATA_EXPECT) {
printk(BIOS_ERR, "%s: Data still expected\n", __func__); printk(BIOS_ERR, "%s: Data still expected\n", __func__);
@@ -372,8 +399,9 @@ static int cr50_i2c_tis_send(uint8_t *buf, size_t len)
} }
/* Start the TPM command */ /* Start the TPM command */
if (cr50_i2c_write(TPM_STS(tpm_dev.locality), tpm_go, sizeof(tpm_go)) < 0) { rc = cr50_i2c_write(TPM_STS(tpm_dev.locality), tpm_go, sizeof(tpm_go));
printk(BIOS_ERR, "%s: Start command failed\n", __func__); if (rc) {
printk(BIOS_ERR, "%s: Start command failed with error %#x\n", __func__, rc);
goto out_err; goto out_err;
} }
return sent; return sent;
@@ -396,14 +424,15 @@ static void cr50_vendor_init(struct tpm_chip *chip)
chip->cancel = &cr50_i2c_tis_ready; chip->cancel = &cr50_i2c_tis_ready;
} }
int tpm_vendor_probe(unsigned int bus, uint32_t addr) tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr)
{ {
return 0; return TPM_SUCCESS;
} }
static int cr50_i2c_probe(uint32_t *did_vid) static tpm_result_t cr50_i2c_probe(uint32_t *did_vid)
{ {
int retries; int retries;
tpm_result_t rc = TPM_SUCCESS;
/* /*
* 1s should be enough to synchronize with the TPM even under the * 1s should be enough to synchronize with the TPM even under the
@@ -414,14 +443,13 @@ static int cr50_i2c_probe(uint32_t *did_vid)
printk(BIOS_INFO, "Probing TPM I2C: "); printk(BIOS_INFO, "Probing TPM I2C: ");
for (retries = 100; retries > 0; retries--) { for (retries = 100; retries > 0; retries--) {
int rc;
rc = cr50_i2c_read(TPM_DID_VID(0), (uint8_t *)did_vid, 4); rc = cr50_i2c_read(TPM_DID_VID(0), (uint8_t *)did_vid, 4);
/* Exit once DID and VID verified */ /* Exit once DID and VID verified */
if (!rc && (*did_vid == CR50_DID_VID || *did_vid == TI50_DID_VID)) { if (!rc && (*did_vid == CR50_DID_VID || *did_vid == TI50_DID_VID)) {
printk(BIOS_INFO, "done! DID_VID 0x%08x\n", *did_vid); printk(BIOS_INFO, "done! DID_VID 0x%08x\n", *did_vid);
return 0; return TPM_SUCCESS;
} }
/* TPM might be resetting, let's retry in a bit. */ /* TPM might be resetting, let's retry in a bit. */
@@ -432,17 +460,21 @@ static int cr50_i2c_probe(uint32_t *did_vid)
/* /*
* I2C reads failed, or the DID and VID didn't match * I2C reads failed, or the DID and VID didn't match
*/ */
printk(BIOS_ERR, "DID_VID 0x%08x not recognized\n", *did_vid); if (!rc) {
return -1; printk(BIOS_ERR, "DID_VID 0x%08x not recognized\n", *did_vid);
return TPM_CB_FAIL;
}
return rc;
} }
int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr) tpm_result_t tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
{ {
uint32_t did_vid = 0; uint32_t did_vid = 0;
tpm_result_t rc = TPM_SUCCESS;
if (dev_addr == 0) { if (dev_addr == 0) {
printk(BIOS_ERR, "%s: missing device address\n", __func__); printk(BIOS_ERR, "%s: missing device address\n", __func__);
return -1; return TPM_CB_FAIL;
} }
tpm_dev.bus = bus; tpm_dev.bus = bus;
@@ -450,15 +482,19 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
cr50_vendor_init(chip); cr50_vendor_init(chip);
if (cr50_i2c_probe(&did_vid)) rc = cr50_i2c_probe(&did_vid);
return -1; if (rc)
return rc;
if (ENV_SEPARATE_VERSTAGE || ENV_BOOTBLOCK) if (ENV_SEPARATE_VERSTAGE || ENV_BOOTBLOCK) {
if (process_reset()) rc = process_reset();
return -1; if (rc)
return rc;
}
if (claim_locality()) rc = claim_locality();
return -1; if (rc)
return rc;
printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id %#x)\n", printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id %#x)\n",
bus, dev_addr, did_vid >> 16); bus, dev_addr, did_vid >> 16);
@@ -470,7 +506,7 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
} }
chip->is_open = 1; chip->is_open = 1;
return 0; return TPM_SUCCESS;
} }
enum cb_err tis_vendor_write(unsigned int addr, const void *buffer, size_t bytes) enum cb_err tis_vendor_write(unsigned int addr, const void *buffer, size_t bytes)

View File

@@ -19,27 +19,24 @@ static struct tpm_chip chip;
#define TPM_CMD_COUNT_BYTE 2 #define TPM_CMD_COUNT_BYTE 2
#define TPM_CMD_ORDINAL_BYTE 6 #define TPM_CMD_ORDINAL_BYTE 6
int tis_open(void) tpm_result_t tis_open(void)
{ {
int rc; tpm_result_t rc;
if (chip.is_open) { if (chip.is_open) {
printk(BIOS_DEBUG, "%s() called twice.\n", __func__); printk(BIOS_DEBUG, "%s() called twice.\n", __func__);
return -1; return TPM_CB_FAIL;
} }
rc = tpm_vendor_init(&chip, CONFIG_DRIVER_TPM_I2C_BUS, rc = tpm_vendor_init(&chip, CONFIG_DRIVER_TPM_I2C_BUS,
CONFIG_DRIVER_TPM_I2C_ADDR); CONFIG_DRIVER_TPM_I2C_ADDR);
if (rc < 0) if (rc != TPM_SUCCESS)
chip.is_open = 0; chip.is_open = 0;
if (rc) return rc;
return -1;
return 0;
} }
int tis_init(void) tpm_result_t tis_init(void)
{ {
return tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS, return tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS,
CONFIG_DRIVER_TPM_I2C_ADDR); CONFIG_DRIVER_TPM_I2C_ADDR);
@@ -48,23 +45,23 @@ int tis_init(void)
static ssize_t tpm_transmit(const uint8_t *sbuf, size_t sbufsiz, void *rbuf, static ssize_t tpm_transmit(const uint8_t *sbuf, size_t sbufsiz, void *rbuf,
size_t rbufsiz) size_t rbufsiz)
{ {
int rc; int rc = -1;
uint32_t count; uint32_t count;
memcpy(&count, sbuf + TPM_CMD_COUNT_BYTE, sizeof(count)); memcpy(&count, sbuf + TPM_CMD_COUNT_BYTE, sizeof(count));
count = be32_to_cpu(count); count = be32_to_cpu(count);
if (!chip.send || !chip.status || !chip.cancel) if (!chip.send || !chip.status || !chip.cancel)
return -1; goto out;
if (count == 0) { if (count == 0) {
printk(BIOS_DEBUG, "%s: no data\n", __func__); printk(BIOS_DEBUG, "%s: no data\n", __func__);
return -1; goto out;
} }
if (count > sbufsiz) { if (count > sbufsiz) {
printk(BIOS_DEBUG, "%s: invalid count value %#x %zx\n", __func__, printk(BIOS_DEBUG, "%s: invalid count value %#x %zx\n", __func__,
count, sbufsiz); count, sbufsiz);
return -1; goto out;
} }
ASSERT(chip.send); ASSERT(chip.send);
@@ -95,11 +92,10 @@ static ssize_t tpm_transmit(const uint8_t *sbuf, size_t sbufsiz, void *rbuf,
ASSERT(chip.cancel); ASSERT(chip.cancel);
chip.cancel(); chip.cancel();
printk(BIOS_DEBUG, "%s: Operation Timed out\n", __func__); printk(BIOS_DEBUG, "%s: Operation Timed out\n", __func__);
rc = -1; //ETIME; rc = -1;
goto out; goto out;
out_recv: out_recv:
rc = chip.recv((uint8_t *)rbuf, rbufsiz); rc = chip.recv((uint8_t *)rbuf, rbufsiz);
if (rc < 0) if (rc < 0)
printk(BIOS_DEBUG, "%s: tpm_recv: error %d\n", __func__, rc); printk(BIOS_DEBUG, "%s: tpm_recv: error %d\n", __func__, rc);
@@ -107,7 +103,7 @@ out:
return rc; return rc;
} }
int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, tpm_result_t tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
uint8_t *recvbuf, size_t *rbuf_len) uint8_t *recvbuf, size_t *rbuf_len)
{ {
ASSERT(sbuf_size >= 10); ASSERT(sbuf_size >= 10);
@@ -124,12 +120,12 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
if (len < 10) { if (len < 10) {
*rbuf_len = 0; *rbuf_len = 0;
return -1; return TPM_CB_FAIL;
} }
if (len > *rbuf_len) { if (len > *rbuf_len) {
*rbuf_len = len; *rbuf_len = len;
return -1; return TPM_CB_FAIL;
} }
*rbuf_len = len; *rbuf_len = len;
@@ -142,5 +138,5 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
hexdump(recvbuf, *rbuf_len); hexdump(recvbuf, *rbuf_len);
} }
return 0; return TPM_SUCCESS;
} }

View File

@@ -22,17 +22,17 @@ struct tpm_output_header {
uint32_t return_code; uint32_t return_code;
} __packed; } __packed;
int tis_open(void) tpm_result_t tis_open(void)
{ {
return 0; return TPM_SUCCESS;
} }
int tis_init(void) tpm_result_t tis_init(void)
{ {
return 0; return TPM_SUCCESS;
} }
int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, tpm_result_t tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
uint8_t *recvbuf, size_t *rbuf_len) uint8_t *recvbuf, size_t *rbuf_len)
{ {
size_t hdr_bytes; size_t hdr_bytes;
@@ -60,8 +60,10 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
sbuf_size); sbuf_size);
if ((status < 0) && (!stopwatch_expired(&sw))) if ((status < 0) && (!stopwatch_expired(&sw)))
continue; continue;
if (status < 0) if (status < 0) {
return status; printk(BIOS_ERR, "I2C write error: %d\n", status);
return TPM_CB_COMMUNICATION_ERROR;
}
break; break;
} }
@@ -79,7 +81,7 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
udelay(SLEEP_DURATION); udelay(SLEEP_DURATION);
} while (!stopwatch_expired(&sw)); } while (!stopwatch_expired(&sw));
if (status != sizeof(*header)) if (status != sizeof(*header))
return -1; return TPM_CB_COMMUNICATION_ERROR;
/* Determine the number of bytes remaining */ /* Determine the number of bytes remaining */
recv_bytes = MIN(be32_to_cpu(*(uint32_t *)&header->length), recv_bytes = MIN(be32_to_cpu(*(uint32_t *)&header->length),
@@ -94,8 +96,10 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
/* Read the full TPM response */ /* Read the full TPM response */
status = i2c_read_raw(CONFIG_DRIVER_TPM_I2C_BUS, status = i2c_read_raw(CONFIG_DRIVER_TPM_I2C_BUS,
CONFIG_DRIVER_TPM_I2C_ADDR, recvbuf, recv_bytes); CONFIG_DRIVER_TPM_I2C_ADDR, recvbuf, recv_bytes);
if (status < 0) if (status < 0) {
return status; printk(BIOS_ERR, "I2C read error: %d\n", status);
return TPM_CB_COMMUNICATION_ERROR;
}
} }
/* Return the number of bytes received */ /* Return the number of bytes received */
@@ -110,5 +114,5 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
} }
/* Successful transfer */ /* Successful transfer */
return 0; return TPM_SUCCESS;
} }

View File

@@ -451,7 +451,7 @@ out_err:
/* Initialization of I2C TPM */ /* Initialization of I2C TPM */
int tpm_vendor_probe(unsigned int bus, uint32_t addr) tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr)
{ {
struct stopwatch sw; struct stopwatch sw;
uint8_t buf = 0; uint8_t buf = 0;
@@ -487,18 +487,18 @@ int tpm_vendor_probe(unsigned int bus, uint32_t addr)
* Claim failure if the ValidSts (bit 7) is clear. * Claim failure if the ValidSts (bit 7) is clear.
*/ */
if (!(buf & TPM_STS_VALID)) if (!(buf & TPM_STS_VALID))
return -1; return TPM_CB_FAIL;
return 0; return TPM_SUCCESS;
} }
int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr) tpm_result_t tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
{ {
uint32_t vendor; uint32_t vendor;
if (dev_addr == 0) { if (dev_addr == 0) {
printk(BIOS_ERR, "%s: missing device address\n", __func__); printk(BIOS_ERR, "%s: missing device address\n", __func__);
return -1; return TPM_CB_FAIL;
} }
tpm_dev.chip_type = UNKNOWN; tpm_dev.chip_type = UNKNOWN;
@@ -518,7 +518,7 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
chip->cancel = &tpm_tis_i2c_ready; chip->cancel = &tpm_tis_i2c_ready;
if (request_locality(0) != 0) if (request_locality(0) != 0)
return -1; return TPM_CB_FAIL;
/* Read four bytes from DID_VID register */ /* Read four bytes from DID_VID register */
if (iic_tpm_read(TPM_DID_VID(0), (uint8_t *)&vendor, 4) < 0) if (iic_tpm_read(TPM_DID_VID(0), (uint8_t *)&vendor, 4) < 0)
@@ -543,9 +543,9 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
* Standard timeout values are used so far * Standard timeout values are used so far
*/ */
return 0; return TPM_SUCCESS;
out_err: out_err:
release_locality(0, 1); release_locality(0, 1);
return -1; return TPM_CB_FAIL;
} }

View File

@@ -12,6 +12,7 @@
#ifndef __DRIVERS_TPM_SLB9635_I2C_TPM_H__ #ifndef __DRIVERS_TPM_SLB9635_I2C_TPM_H__
#define __DRIVERS_TPM_SLB9635_I2C_TPM_H__ #define __DRIVERS_TPM_SLB9635_I2C_TPM_H__
#include <security/tpm/tss_errors.h>
#include <stdint.h> #include <stdint.h>
enum tpm_timeout { enum tpm_timeout {
@@ -51,8 +52,8 @@ struct tpm_chip {
/* ---------- Interface for TPM vendor ------------ */ /* ---------- Interface for TPM vendor ------------ */
int tpm_vendor_probe(unsigned int bus, uint32_t addr); tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr);
int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr); tpm_result_t tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr);
#endif /* __DRIVERS_TPM_SLB9635_I2C_TPM_H__ */ #endif /* __DRIVERS_TPM_SLB9635_I2C_TPM_H__ */

View File

@@ -74,17 +74,6 @@
#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */ #define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */ #define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
/*
* Error value returned if a tpm register does not enter the expected state
* after continuous polling. No actual TPM register reading ever returns ~0,
* so this value is a safe error indication to be mixed with possible status
* register values.
*/
#define TPM_TIMEOUT_ERR (~0)
/* Error value returned on various TPM driver errors */
#define TPM_DRIVER_ERR (~0)
/* 1 second is plenty for anything TPM does.*/ /* 1 second is plenty for anything TPM does.*/
#define MAX_DELAY_US USECS_PER_SEC #define MAX_DELAY_US USECS_PER_SEC
@@ -248,9 +237,9 @@ static inline u32 tpm_read_int_polarity(int locality)
* @mask - bitmask for the bitfield(s) to watch * @mask - bitmask for the bitfield(s) to watch
* @expected - value the field(s) are supposed to be set to * @expected - value the field(s) are supposed to be set to
* *
* Returns 0 on success or TPM_TIMEOUT_ERR on timeout. * Returns TPM_SUCCESS on success or TPM_CB_TIMEOUT on timeout.
*/ */
static int tis_wait_sts(int locality, u8 mask, u8 expected) static tpm_result_t tis_wait_sts(int locality, u8 mask, u8 expected)
{ {
struct stopwatch sw; struct stopwatch sw;
@@ -258,24 +247,24 @@ static int tis_wait_sts(int locality, u8 mask, u8 expected)
do { do {
u8 value = tpm_read_status(locality); u8 value = tpm_read_status(locality);
if ((value & mask) == expected) if ((value & mask) == expected)
return 0; return TPM_SUCCESS;
udelay(1); udelay(1);
} while (!stopwatch_expired(&sw)); } while (!stopwatch_expired(&sw));
return TPM_TIMEOUT_ERR; return TPM_CB_TIMEOUT;
} }
static inline int tis_wait_ready(int locality) static inline tpm_result_t tis_wait_ready(int locality)
{ {
return tis_wait_sts(locality, TIS_STS_COMMAND_READY, return tis_wait_sts(locality, TIS_STS_COMMAND_READY,
TIS_STS_COMMAND_READY); TIS_STS_COMMAND_READY);
} }
static inline int tis_wait_valid(int locality) static inline tpm_result_t tis_wait_valid(int locality)
{ {
return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID); return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID);
} }
static inline int tis_wait_valid_data(int locality) static inline tpm_result_t tis_wait_valid_data(int locality)
{ {
const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID; const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
return tis_wait_sts(locality, has_data, has_data); return tis_wait_sts(locality, has_data, has_data);
@@ -302,9 +291,9 @@ static inline int tis_expect_data(int locality)
* @mask - bitmask for the bitfield(s) to watch * @mask - bitmask for the bitfield(s) to watch
* @expected - value the field(s) are supposed to be set to * @expected - value the field(s) are supposed to be set to
* *
* Returns 0 on success or TPM_TIMEOUT_ERR on timeout. * Returns TPM_SUCCESS on success or TPM_CB_TIMEOUT on timeout.
*/ */
static int tis_wait_access(int locality, u8 mask, u8 expected) static tpm_result_t tis_wait_access(int locality, u8 mask, u8 expected)
{ {
struct stopwatch sw; struct stopwatch sw;
@@ -312,13 +301,13 @@ static int tis_wait_access(int locality, u8 mask, u8 expected)
do { do {
u8 value = tpm_read_access(locality); u8 value = tpm_read_access(locality);
if ((value & mask) == expected) if ((value & mask) == expected)
return 0; return TPM_SUCCESS;
udelay(1); udelay(1);
} while (!stopwatch_expired(&sw)); } while (!stopwatch_expired(&sw));
return TPM_TIMEOUT_ERR; return TPM_CB_TIMEOUT;
} }
static inline int tis_wait_received_access(int locality) static inline tpm_result_t tis_wait_received_access(int locality)
{ {
return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY, return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY,
TIS_ACCESS_ACTIVE_LOCALITY); TIS_ACCESS_ACTIVE_LOCALITY);
@@ -345,10 +334,8 @@ static inline void tis_request_access(int locality)
* In practice not all TPMs behave the same so it is necessary to be * In practice not all TPMs behave the same so it is necessary to be
* flexible when trying to set command ready. * flexible when trying to set command ready.
* *
* Returns 0 on success if the TPM is ready for transactions.
* Returns TPM_TIMEOUT_ERR if the command ready bit does not get set.
*/ */
static int tis_command_ready(u8 locality) static tpm_result_t tis_command_ready(u8 locality)
{ {
u32 status; u32 status;
@@ -360,7 +347,7 @@ static int tis_command_ready(u8 locality)
/* Check if command ready is set yet */ /* Check if command ready is set yet */
if (status & TIS_STS_COMMAND_READY) if (status & TIS_STS_COMMAND_READY)
return 0; return TPM_SUCCESS;
/* 2nd attempt to set command ready */ /* 2nd attempt to set command ready */
tpm_write_status(TIS_STS_COMMAND_READY, locality); tpm_write_status(TIS_STS_COMMAND_READY, locality);
@@ -373,10 +360,10 @@ static int tis_command_ready(u8 locality)
* *
* Probe the TPM device and try determining its manufacturer/device name. * Probe the TPM device and try determining its manufacturer/device name.
* *
* Returns 0 on success (the device is found or was found during an earlier * Returns TPM_SUCCESS on success (the device is found or was found during
* invocation) or TPM_DRIVER_ERR if the device is not found. * an earlier invocation) or TPM_CB_FAIL if the device is not found.
*/ */
int tis_init(void) tpm_result_t tis_init(void)
{ {
const char *device_name = "unknown"; const char *device_name = "unknown";
const char *vendor_name = device_name; const char *vendor_name = device_name;
@@ -386,12 +373,12 @@ int tis_init(void)
int i; int i;
if (vendor_dev_id) if (vendor_dev_id)
return 0; /* Already probed. */ return TPM_SUCCESS; /* Already probed. */
didvid = tpm_read_did_vid(0); didvid = tpm_read_did_vid(0);
if (!didvid || (didvid == 0xffffffff)) { if (!didvid || (didvid == 0xffffffff)) {
printf("%s: No TPM device found\n", __func__); printf("%s: No TPM device found\n", __func__);
return TPM_DRIVER_ERR; return TPM_CB_FAIL;
} }
vendor_dev_id = didvid; vendor_dev_id = didvid;
@@ -419,7 +406,7 @@ int tis_init(void)
} }
/* this will have to be converted into debug printout */ /* this will have to be converted into debug printout */
printk(BIOS_INFO, "Found TPM %s by %s\n", device_name, vendor_name); printk(BIOS_INFO, "Found TPM %s by %s\n", device_name, vendor_name);
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -430,19 +417,21 @@ int tis_init(void)
* @data - address of the data to send, byte by byte * @data - address of the data to send, byte by byte
* @len - length of the data to send * @len - length of the data to send
* *
* Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does * Returns TPM_SUCCESS on success, TPM_CB_FAIL on error (in case the device does
* not accept the entire command). * not accept the entire command).
*/ */
static u32 tis_senddata(const u8 *const data, u32 len) static tpm_result_t tis_senddata(const u8 *const data, u32 len)
{ {
u32 offset = 0; u32 offset = 0;
u16 burst = 0; u16 burst = 0;
u8 locality = 0; u8 locality = 0;
tpm_result_t rc = TPM_SUCCESS;
if (tis_wait_ready(locality)) { rc = tis_wait_ready(locality);
printf("%s:%d - failed to get 'command_ready' status\n", if (rc) {
__FILE__, __LINE__); printf("%s:%d - failed to get 'command_ready' status with error %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, rc);
return rc;
} }
burst = tpm_read_burst_count(locality); burst = tpm_read_burst_count(locality);
@@ -456,7 +445,7 @@ static u32 tis_senddata(const u8 *const data, u32 len)
if (stopwatch_expired(&sw)) { if (stopwatch_expired(&sw)) {
printf("%s:%d failed to feed %u bytes of %u\n", printf("%s:%d failed to feed %u bytes of %u\n",
__FILE__, __LINE__, len - offset, len); __FILE__, __LINE__, len - offset, len);
return TPM_DRIVER_ERR; return TPM_CB_TIMEOUT;
} }
udelay(1); udelay(1);
burst = tpm_read_burst_count(locality); burst = tpm_read_burst_count(locality);
@@ -475,10 +464,11 @@ static u32 tis_senddata(const u8 *const data, u32 len)
while (count--) while (count--)
tpm_write_data(data[offset++], locality); tpm_write_data(data[offset++], locality);
if (tis_wait_valid(locality) || !tis_expect_data(locality)) { rc = tis_wait_valid(locality);
printf("%s:%d TPM command feed overflow\n", if (rc || !tis_expect_data(locality)) {
__FILE__, __LINE__); printf("%s:%d TPM command feed overflow with error %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, rc);
return rc ? rc : TPM_CB_FAIL;
} }
burst = tpm_read_burst_count(locality); burst = tpm_read_burst_count(locality);
@@ -498,16 +488,17 @@ static u32 tis_senddata(const u8 *const data, u32 len)
* Verify that TPM does not expect any more data as part of this * Verify that TPM does not expect any more data as part of this
* command. * command.
*/ */
if (tis_wait_valid(locality) || tis_expect_data(locality)) { rc = tis_wait_valid(locality);
printf("%s:%d unexpected TPM status %#x\n", if (rc || tis_expect_data(locality)) {
__FILE__, __LINE__, tpm_read_status(locality)); printf("%s:%d unexpected TPM error %#x with status %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, rc, tpm_read_status(locality));
return rc ? rc : TPM_CB_FAIL;
} }
/* OK, sitting pretty, let's start the command execution. */ /* OK, sitting pretty, let's start the command execution. */
tpm_write_status(TIS_STS_TPM_GO, locality); tpm_write_status(TIS_STS_TPM_GO, locality);
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -518,22 +509,25 @@ static u32 tis_senddata(const u8 *const data, u32 len)
* @buffer - address where to read the response, byte by byte. * @buffer - address where to read the response, byte by byte.
* @len - pointer to the size of buffer * @len - pointer to the size of buffer
* *
* On success stores the number of received bytes to len and returns 0. On * On success stores the number of received bytes to len and returns
* errors (misformatted TPM data or synchronization problems) returns * TPM_SUCCESS. On errors (misformatted TPM data or synchronization
* TPM_DRIVER_ERR. * problems) returns TPM_CB_FAIL.
*/ */
static u32 tis_readresponse(u8 *buffer, size_t *len) static tpm_result_t tis_readresponse(u8 *buffer, size_t *len)
{ {
u16 burst_count; u16 burst_count;
u32 offset = 0; u32 offset = 0;
u8 locality = 0; u8 locality = 0;
u32 expected_count = *len; u32 expected_count = *len;
int max_cycles = 0; int max_cycles = 0;
tpm_result_t rc = TPM_SUCCESS;
/* Wait for the TPM to process the command */ /* Wait for the TPM to process the command */
if (tis_wait_valid_data(locality)) { rc = tis_wait_valid_data(locality);
printf("%s:%d failed processing command\n", __FILE__, __LINE__); if (rc) {
return TPM_DRIVER_ERR; printf("%s:%d failed processing command with error %#x\n",
__FILE__, __LINE__, rc);
return rc;
} }
do { do {
@@ -541,7 +535,7 @@ static u32 tis_readresponse(u8 *buffer, size_t *len)
if (max_cycles++ == MAX_DELAY_US) { if (max_cycles++ == MAX_DELAY_US) {
printf("%s:%d TPM stuck on read\n", printf("%s:%d TPM stuck on read\n",
__FILE__, __LINE__); __FILE__, __LINE__);
return TPM_DRIVER_ERR; return TPM_CB_FAIL;
} }
udelay(1); udelay(1);
} }
@@ -569,16 +563,17 @@ static u32 tis_readresponse(u8 *buffer, size_t *len)
printf("%s:%d bad response size %u\n", printf("%s:%d bad response size %u\n",
__FILE__, __LINE__, __FILE__, __LINE__,
expected_count); expected_count);
return TPM_DRIVER_ERR; return TPM_CB_FAIL;
} }
} }
} }
/* Wait for the next portion */ /* Wait for the next portion */
if (tis_wait_valid(locality)) { rc = tis_wait_valid(locality);
printf("%s:%d failed to read response\n", if (rc) {
__FILE__, __LINE__); printf("%s:%d failed to read response with error %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, rc);
return rc;
} }
if (offset == expected_count) if (offset == expected_count)
@@ -599,15 +594,16 @@ static u32 tis_readresponse(u8 *buffer, size_t *len)
printf("%s:%d wrong receive status: %#x %u bytes left\n", printf("%s:%d wrong receive status: %#x %u bytes left\n",
__FILE__, __LINE__, tpm_read_status(locality), __FILE__, __LINE__, tpm_read_status(locality),
tpm_read_burst_count(locality)); tpm_read_burst_count(locality));
return TPM_DRIVER_ERR; return TPM_CB_FAIL;
} }
/* Tell the TPM that we are done. */ /* Tell the TPM that we are done. */
if (tis_command_ready(locality) == TPM_TIMEOUT_ERR) rc = tis_command_ready(locality);
return TPM_DRIVER_ERR; if (rc)
return rc;
*len = offset; *len = offset;
return 0; return TPM_SUCCESS;
} }
/* /*
@@ -615,31 +611,30 @@ static u32 tis_readresponse(u8 *buffer, size_t *len)
* *
* Requests access to locality 0 for the caller. * Requests access to locality 0 for the caller.
* *
* Returns 0 on success, TPM_DRIVER_ERR on failure. * Returns TPM_SUCCESS on success, TSS Error on failure.
*/ */
int tis_open(void) tpm_result_t tis_open(void)
{ {
u8 locality = 0; /* we use locality zero for everything */ u8 locality = 0; /* we use locality zero for everything */
tpm_result_t rc = TPM_SUCCESS;
if (!tis_has_access(locality)) { if (!tis_has_access(locality)) {
/* request access to locality */ /* request access to locality */
tis_request_access(locality); tis_request_access(locality);
/* did we get a lock? */ /* did we get a lock? */
if (tis_wait_received_access(locality)) { rc = tis_wait_received_access(locality);
printf("%s:%d - failed to lock locality %u\n", if (rc) {
__FILE__, __LINE__, locality); printf("%s:%d - failed to lock locality %u with error %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, locality, rc);
return rc;
} }
/* Certain TPMs seem to need some delay here or they hang... */ /* Certain TPMs seem to need some delay here or they hang... */
udelay(10); udelay(10);
} }
if (tis_command_ready(locality) == TPM_TIMEOUT_ERR) return tis_command_ready(locality);
return TPM_DRIVER_ERR;
return 0;
} }
/* /*
@@ -652,16 +647,17 @@ int tis_open(void)
* @recvbuf - memory to save the response to * @recvbuf - memory to save the response to
* @recv_len - pointer to the size of the response buffer * @recv_len - pointer to the size of the response buffer
* *
* Returns 0 on success (and places the number of response bytes at recv_len) * Returns TPM_SUCCESS on success (and places the number of response bytes
* or TPM_DRIVER_ERR on failure. * at recv_len) or TPM_CB_FAIL on failure.
*/ */
int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, tpm_result_t tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
uint8_t *recvbuf, size_t *recv_len) uint8_t *recvbuf, size_t *recv_len)
{ {
if (tis_senddata(sendbuf, send_size)) { tpm_result_t rc = tis_senddata(sendbuf, send_size);
printf("%s:%d failed sending data to TPM\n", if (rc) {
__FILE__, __LINE__); printf("%s:%d failed sending data to TPM with error %#x\n",
return TPM_DRIVER_ERR; __FILE__, __LINE__, rc);
return rc;
} }
return tis_readresponse(recvbuf, recv_len); return tis_readresponse(recvbuf, recv_len);
@@ -680,14 +676,15 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
* @vector - TPM interrupt vector * @vector - TPM interrupt vector
* @polarity - TPM interrupt polarity * @polarity - TPM interrupt polarity
* *
* Returns 0 on success, TPM_DRIVER_ERR on failure. * Returns TPM_SUCCESS on success, TPM_CB_FAIL on failure.
*/ */
static int tis_setup_interrupt(int vector, int polarity) static tpm_result_t tis_setup_interrupt(int vector, int polarity)
{ {
u8 locality = 0; u8 locality = 0;
tpm_result_t rc = tlcl_lib_init();
if (tlcl_lib_init()) if (rc)
return TPM_DRIVER_ERR; return rc;
/* Set TPM interrupt vector */ /* Set TPM interrupt vector */
tpm_write_int_vector(vector, locality); tpm_write_int_vector(vector, locality);
@@ -695,7 +692,7 @@ static int tis_setup_interrupt(int vector, int polarity)
/* Set TPM interrupt polarity and disable interrupts */ /* Set TPM interrupt polarity and disable interrupts */
tpm_write_int_polarity(polarity, locality); tpm_write_int_polarity(polarity, locality);
return 0; return TPM_SUCCESS;
} }
static void lpc_tpm_read_resources(struct device *dev) static void lpc_tpm_read_resources(struct device *dev)

View File

@@ -29,29 +29,31 @@ static const char *tis_get_dev_name(struct tpm2_info *info)
return "Unknown"; return "Unknown";
} }
int tis_open(void) tpm_result_t tis_open(void)
{ {
if (tpm_is_open) { if (tpm_is_open) {
printk(BIOS_ERR, "%s() called twice.\n", __func__); printk(BIOS_ERR, "%s() called twice.\n", __func__);
return -1; return TPM_CB_FAIL;
} }
return 0; return TPM_SUCCESS;
} }
int tis_init(void) tpm_result_t tis_init(void)
{ {
struct spi_slave spi; struct spi_slave spi;
struct tpm2_info info; struct tpm2_info info;
tpm_result_t rc = TPM_SUCCESS;
if (spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS, if (spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS,
CONFIG_DRIVER_TPM_SPI_CHIP, &spi)) { CONFIG_DRIVER_TPM_SPI_CHIP, &spi)) {
printk(BIOS_ERR, "Failed to setup TPM SPI slave\n"); printk(BIOS_ERR, "Failed to setup TPM SPI slave\n");
return -1; return TPM_CB_FAIL;
} }
if (tpm2_init(&spi)) { rc = tpm2_init(&spi);
if (rc) {
printk(BIOS_ERR, "Failed to initialize TPM SPI interface\n"); printk(BIOS_ERR, "Failed to initialize TPM SPI interface\n");
return -1; return rc;
} }
tpm2_get_info(&info); tpm2_get_info(&info);
@@ -59,18 +61,18 @@ int tis_init(void)
printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", printk(BIOS_INFO, "Initialized TPM device %s revision %d\n",
tis_get_dev_name(&info), info.revision); tis_get_dev_name(&info), info.revision);
return 0; return TPM_SUCCESS;
} }
int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, tpm_result_t tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
uint8_t *recvbuf, size_t *rbuf_len) uint8_t *recvbuf, size_t *rbuf_len)
{ {
int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len);
if (len == 0) if (len == 0)
return -1; return TPM_CB_FAIL;
*rbuf_len = len; *rbuf_len = len;
return 0; return TPM_SUCCESS;
} }

View File

@@ -394,7 +394,7 @@ static const uint32_t supported_did_vids[] = {
0x0000104a /* ST33HTPH2E32 */ 0x0000104a /* ST33HTPH2E32 */
}; };
int tpm2_init(struct spi_slave *spi_if) tpm_result_t tpm2_init(struct spi_slave *spi_if)
{ {
uint32_t did_vid, status, intf_id; uint32_t did_vid, status, intf_id;
uint8_t cmd; uint8_t cmd;
@@ -433,7 +433,7 @@ int tpm2_init(struct spi_slave *spi_if)
if (!retries) { if (!retries) {
printk(BIOS_ERR, "\n%s: Failed to connect to the TPM\n", printk(BIOS_ERR, "\n%s: Failed to connect to the TPM\n",
__func__); __func__);
return -1; return TPM_CB_FAIL;
} }
printk(BIOS_INFO, " done!\n"); printk(BIOS_INFO, " done!\n");
@@ -444,11 +444,11 @@ int tpm2_init(struct spi_slave *spi_if)
if (tpm2_read_reg(TPM_INTF_ID_REG, &intf_id, sizeof(intf_id)) != CB_SUCCESS) { if (tpm2_read_reg(TPM_INTF_ID_REG, &intf_id, sizeof(intf_id)) != CB_SUCCESS) {
printk(BIOS_ERR, "\n%s: Failed to read interface ID register\n", printk(BIOS_ERR, "\n%s: Failed to read interface ID register\n",
__func__); __func__);
return -1; return TPM_CB_FAIL;
} }
if ((be32toh(intf_id) & 0xF) == 0xF) { if ((be32toh(intf_id) & 0xF) == 0xF) {
printk(BIOS_DEBUG, "\n%s: Not a TPM2 device\n", __func__); printk(BIOS_DEBUG, "\n%s: Not a TPM2 device\n", __func__);
return -1; return TPM_CB_FAIL;
} }
} }
@@ -459,16 +459,16 @@ int tpm2_init(struct spi_slave *spi_if)
* initialization after reset. * initialization after reset.
*/ */
if (tpm2_claim_locality() != CB_SUCCESS) if (tpm2_claim_locality() != CB_SUCCESS)
return -1; return TPM_CB_FAIL;
if (read_tpm_sts(&status) != CB_SUCCESS) { if (read_tpm_sts(&status) != CB_SUCCESS) {
printk(BIOS_ERR, "Reading status reg failed\n"); printk(BIOS_ERR, "Reading status reg failed\n");
return -1; return TPM_CB_FAIL;
} }
if ((status & TPM_STS_FAMILY_MASK) != TPM_STS_FAMILY_TPM_2_0) { if ((status & TPM_STS_FAMILY_MASK) != TPM_STS_FAMILY_TPM_2_0) {
printk(BIOS_ERR, "unexpected TPM family value, status: %#x\n", printk(BIOS_ERR, "unexpected TPM family value, status: %#x\n",
status); status);
return -1; return TPM_CB_FAIL;
} }
/* /*
@@ -492,7 +492,7 @@ int tpm2_init(struct spi_slave *spi_if)
cr50_set_board_cfg(); cr50_set_board_cfg();
} }
} }
return 0; return TPM_SUCCESS;
} }
/* /*

View File

@@ -4,6 +4,7 @@
#define __COREBOOT_SRC_DRIVERS_SPI_TPM_TPM_H #define __COREBOOT_SRC_DRIVERS_SPI_TPM_TPM_H
#include <drivers/tpm/cr50.h> #include <drivers/tpm/cr50.h>
#include <security/tpm/tss_errors.h>
#include <stddef.h> #include <stddef.h>
#include <spi-generic.h> #include <spi-generic.h>
@@ -26,7 +27,7 @@ struct tpm2_info {
* *
* Return 0 on success, non-zero on failure. * Return 0 on success, non-zero on failure.
*/ */
int tpm2_init(struct spi_slave *spi_if); tpm_result_t tpm2_init(struct spi_slave *spi_if);
/* /*
* Each command processing consists of sending the command to the TPM, by * Each command processing consists of sending the command to the TPM, by

View File

@@ -7,6 +7,7 @@
#if CONFIG(VENDORCODE_ELTAN_MBOOT) #if CONFIG(VENDORCODE_ELTAN_MBOOT)
#include <mboot.h> #include <mboot.h>
#endif #endif
#include <security/tpm/tss_errors.h>
#include <soc/lpc.h> #include <soc/lpc.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/romstage.h> #include <soc/romstage.h>
@@ -71,9 +72,9 @@ static const uint8_t crtm_version[] =
CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING COREBOOT_VERSION COREBOOT_EXTRA_VERSION CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING COREBOOT_VERSION COREBOOT_EXTRA_VERSION
" " COREBOOT_BUILD; " " COREBOOT_BUILD;
int mb_crtm(void) tpm_result_t mb_crtm(void)
{ {
int rc = TPM_IOERROR; tpm_result_t rc = TPM_IOERROR;
TCG_PCR_EVENT2_HDR tcgEventHdr; TCG_PCR_EVENT2_HDR tcgEventHdr;
/* Use FirmwareVersion string to represent CRTM version. */ /* Use FirmwareVersion string to represent CRTM version. */

View File

@@ -34,10 +34,10 @@ static void mainboard_smbios_strings(struct device *dev, struct smbios_type11 *t
void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config) void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
{ {
int rc; tpm_result_t rc;
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc);
return; return;
} }

View File

@@ -14,10 +14,10 @@
static void mainboard_update_soc_chip_config(void) static void mainboard_update_soc_chip_config(void)
{ {
struct soc_intel_jasperlake_config *cfg = config_of_soc(); struct soc_intel_jasperlake_config *cfg = config_of_soc();
int rc; tpm_result_t rc;
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc);
return; return;
} }

View File

@@ -82,7 +82,7 @@ static void mainboard_enable(struct device *dev)
void mainboard_update_soc_chip_config(struct soc_intel_tigerlake_config *cfg) void mainboard_update_soc_chip_config(struct soc_intel_tigerlake_config *cfg)
{ {
int rc; tpm_result_t rc;
if (!CONFIG(TPM_GOOGLE_CR50) || !CONFIG(SPI_TPM)) { if (!CONFIG(TPM_GOOGLE_CR50) || !CONFIG(SPI_TPM)) {
/* /*
* Negotiation of long interrupt pulses is only supported via SPI. I2C is only * Negotiation of long interrupt pulses is only supported via SPI. I2C is only
@@ -94,7 +94,7 @@ void mainboard_update_soc_chip_config(struct soc_intel_tigerlake_config *cfg)
} }
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc);
return; return;
} }

View File

@@ -109,9 +109,9 @@
* Note: Only locality 0 registers are publicly accessible. * Note: Only locality 0 registers are publicly accessible.
*/ */
#define TPM_BASE 0xfed40000UL #define TPM_BASE_ADDR 0xfed40000UL
#define TPM_ACCESS_REG (TPM_BASE + 0x00) #define TPM_ACCESS_REG (TPM_BASE_ADDR + 0x00)
/* /*
* TXT Memory regions * TXT Memory regions

View File

@@ -3,6 +3,7 @@
#ifndef TIS_H_ #ifndef TIS_H_
#define TIS_H_ #define TIS_H_
#include <security/tpm/tss_errors.h>
#include <types.h> #include <types.h>
enum tis_access { enum tis_access {
@@ -34,19 +35,19 @@ enum tis_status {
/* /*
* tis_init() * tis_init()
* *
* Initialize the TPM device. Returns 0 on success or -1 on * Initialize the TPM device.
* failure (in case device probing did not succeed). * Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
int tis_init(void); tpm_result_t tis_init(void);
/* /*
* tis_open() * tis_open()
* *
* Requests access to locality 0 for the caller. * Requests access to locality 0 for the caller.
* *
* Returns 0 on success, -1 on failure. * Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
*/ */
int tis_open(void); tpm_result_t tis_open(void);
/* /*
* tis_sendrecv() * tis_sendrecv()
@@ -58,10 +59,9 @@ int tis_open(void);
* @recvbuf - memory to save the response to * @recvbuf - memory to save the response to
* @recv_len - pointer to the size of the response buffer * @recv_len - pointer to the size of the response buffer
* *
* Returns 0 on success (and places the number of response bytes at recv_len) * Returns TSS Return Code from TCG TPM Structures. See tss_errors.h
* or -1 on failure.
*/ */
int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf, tpm_result_t tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf,
size_t *recv_len); size_t *recv_len);
/* /*

View File

@@ -137,22 +137,22 @@ static inline void tpm_log_dump(void *unused)
* @param name sets additional info where the digest comes from * @param name sets additional info where the digest comes from
* @return TPM_SUCCESS on success. If not a tpm error is returned * @return TPM_SUCCESS on success. If not a tpm error is returned
*/ */
uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo, tpm_result_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
const uint8_t *digest, size_t digest_len, const uint8_t *digest, size_t digest_len,
const char *name); const char *name);
/** /**
* Issue a TPM_Clear and re-enable/reactivate the TPM. * Issue a TPM_Clear and re-enable/reactivate the TPM.
* @return TPM_SUCCESS on success. If not a tpm error is returned * @return TPM_SUCCESS on success. If not a tpm error is returned
*/ */
uint32_t tpm_clear_and_reenable(void); tpm_result_t tpm_clear_and_reenable(void);
/** /**
* Start the TPM and establish the root of trust. * Start the TPM and establish the root of trust.
* @param s3flag tells the tpm setup if we wake up from a s3 state on x86 * @param s3flag tells the tpm setup if we wake up from a s3 state on x86
* @return TPM_SUCCESS on success. If not a tpm error is returned * @return TPM_SUCCESS on success. If not a tpm error is returned
*/ */
uint32_t tpm_setup(int s3flag); tpm_result_t tpm_setup(int s3flag);
/** /**
* Measure a given region device and extend given PCR with the result. * Measure a given region device and extend given PCR with the result.
@@ -161,7 +161,7 @@ uint32_t tpm_setup(int s3flag);
* @param *rname Name of the region that is measured * @param *rname Name of the region that is measured
* @return TPM error code in case of error otherwise TPM_SUCCESS * @return TPM error code in case of error otherwise TPM_SUCCESS
*/ */
uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr, tpm_result_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
const char *rname); const char *rname);
#endif /* TSPI_H_ */ #endif /* TSPI_H_ */

View File

@@ -31,25 +31,27 @@ static inline int tpm_log_available(void)
* stage. * stage.
* *
* Takes the current vboot context as parameter for s3 checks. * Takes the current vboot context as parameter for s3 checks.
* returns on success VB2_SUCCESS, else a vboot error. * returns on success TPM_SUCCESS, else a TPM error.
*/ */
static uint32_t tspi_init_crtm(void) static tpm_result_t tspi_init_crtm(void)
{ {
tpm_result_t rc = TPM_SUCCESS;
/* Initialize TPM PRERAM log. */ /* Initialize TPM PRERAM log. */
if (!tpm_log_available()) { if (!tpm_log_available()) {
tpm_preram_log_clear(); tpm_preram_log_clear();
tpm_log_initialized = 1; tpm_log_initialized = 1;
} else { } else {
printk(BIOS_WARNING, "TSPI: CRTM already initialized!\n"); printk(BIOS_WARNING, "TSPI: CRTM already initialized!\n");
return VB2_SUCCESS; return TPM_SUCCESS;
} }
struct region_device fmap; struct region_device fmap;
if (fmap_locate_area_as_rdev("FMAP", &fmap) == 0) { if (fmap_locate_area_as_rdev("FMAP", &fmap) == 0) {
if (tpm_measure_region(&fmap, CONFIG_PCR_SRTM, "FMAP: FMAP")) { rc = tpm_measure_region(&fmap, CONFIG_PCR_SRTM, "FMAP: FMAP");
if (rc) {
printk(BIOS_ERR, printk(BIOS_ERR,
"TSPI: Couldn't measure FMAP into CRTM!\n"); "TSPI: Couldn't measure FMAP into CRTM! rc %#x\n", rc);
return VB2_ERROR_UNKNOWN; return rc;
} }
} else { } else {
printk(BIOS_ERR, "TSPI: Could not find FMAP!\n"); printk(BIOS_ERR, "TSPI: Could not find FMAP!\n");
@@ -59,10 +61,11 @@ static uint32_t tspi_init_crtm(void)
if (!CONFIG(ARCH_X86)) { if (!CONFIG(ARCH_X86)) {
struct region_device bootblock_fmap; struct region_device bootblock_fmap;
if (fmap_locate_area_as_rdev("BOOTBLOCK", &bootblock_fmap) == 0) { if (fmap_locate_area_as_rdev("BOOTBLOCK", &bootblock_fmap) == 0) {
if (tpm_measure_region(&bootblock_fmap, rc = tpm_measure_region(&bootblock_fmap,
CONFIG_PCR_SRTM, CONFIG_PCR_SRTM,
"FMAP: BOOTBLOCK")) "FMAP: BOOTBLOCK");
return VB2_ERROR_UNKNOWN; if (rc)
return rc;
} }
} else if (CONFIG(BOOTBLOCK_IN_CBFS)){ } else if (CONFIG(BOOTBLOCK_IN_CBFS)){
/* Mapping measures the file. We know we can safely map here because /* Mapping measures the file. We know we can safely map here because
@@ -72,7 +75,7 @@ static uint32_t tspi_init_crtm(void)
if (!mapping) { if (!mapping) {
printk(BIOS_INFO, printk(BIOS_INFO,
"TSPI: Couldn't measure bootblock into CRTM!\n"); "TSPI: Couldn't measure bootblock into CRTM!\n");
return VB2_ERROR_UNKNOWN; return TPM_CB_FAIL;
} }
cbfs_unmap(mapping); cbfs_unmap(mapping);
} else { } else {
@@ -82,11 +85,11 @@ static uint32_t tspi_init_crtm(void)
if (tspi_soc_measure_bootblock(CONFIG_PCR_SRTM)) { if (tspi_soc_measure_bootblock(CONFIG_PCR_SRTM)) {
printk(BIOS_INFO, printk(BIOS_INFO,
"TSPI: Couldn't measure bootblock into CRTM on SoC level!\n"); "TSPI: Couldn't measure bootblock into CRTM on SoC level!\n");
return VB2_ERROR_UNKNOWN; return TPM_CB_FAIL;
} }
} }
return VB2_SUCCESS; return TPM_SUCCESS;
} }
static bool is_runtime_data(const char *name) static bool is_runtime_data(const char *name)
@@ -108,16 +111,18 @@ static bool is_runtime_data(const char *name)
return !strcmp(allowlist, name); return !strcmp(allowlist, name);
} }
uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash) tpm_result_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash)
{ {
uint32_t pcr_index; uint32_t pcr_index;
tpm_result_t rc = TPM_SUCCESS;
char tpm_log_metadata[TPM_CB_LOG_PCR_HASH_NAME]; char tpm_log_metadata[TPM_CB_LOG_PCR_HASH_NAME];
if (!tpm_log_available()) { if (!tpm_log_available()) {
if (tspi_init_crtm() != VB2_SUCCESS) { rc = tspi_init_crtm();
if (rc) {
printk(BIOS_WARNING, printk(BIOS_WARNING,
"Initializing CRTM failed!\n"); "Initializing CRTM failed!\n");
return 0; return rc;
} }
printk(BIOS_DEBUG, "CRTM initialized.\n"); printk(BIOS_DEBUG, "CRTM initialized.\n");
} }
@@ -171,7 +176,7 @@ void *tpm_log_init(void)
return tclt; return tclt;
} }
int tspi_measure_cache_to_pcr(void) tpm_result_t tspi_measure_cache_to_pcr(void)
{ {
int i; int i;
int pcr; int pcr;
@@ -181,27 +186,27 @@ int tspi_measure_cache_to_pcr(void)
/* This means the table is empty. */ /* This means the table is empty. */
if (!tpm_log_available()) if (!tpm_log_available())
return VB2_SUCCESS; return TPM_SUCCESS;
if (tpm_log_init() == NULL) { if (tpm_log_init() == NULL) {
printk(BIOS_WARNING, "TPM LOG: log non-existent!\n"); printk(BIOS_WARNING, "TPM LOG: log non-existent!\n");
return VB2_ERROR_UNKNOWN; return TPM_CB_FAIL;
} }
printk(BIOS_DEBUG, "TPM: Write digests cached in TPM log to PCR\n"); printk(BIOS_DEBUG, "TPM: Write digests cached in TPM log to PCR\n");
i = 0; i = 0;
while (!tpm_log_get(i++, &pcr, &digest_data, &digest_algo, &event_name)) { while (!tpm_log_get(i++, &pcr, &digest_data, &digest_algo, &event_name)) {
printk(BIOS_DEBUG, "TPM: Write digest for %s into PCR %d\n", event_name, pcr); printk(BIOS_DEBUG, "TPM: Write digest for %s into PCR %d\n", event_name, pcr);
int rc = tlcl_extend(pcr, digest_data, digest_algo); tpm_result_t rc = tlcl_extend(pcr, digest_data, digest_algo);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, printk(BIOS_ERR,
"TPM: Writing digest of %s into PCR failed with error %d\n", "TPM: Writing digest of %s into PCR failed with error %d\n",
event_name, rc); event_name, rc);
return VB2_ERROR_UNKNOWN; return rc;
} }
} }
return VB2_SUCCESS; return TPM_SUCCESS;
} }
#if !CONFIG(VBOOT_RETURN_FROM_VERSTAGE) #if !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)

View File

@@ -5,6 +5,7 @@
#include <program_loading.h> #include <program_loading.h>
#include <security/tpm/tspi.h> #include <security/tpm/tspi.h>
#include <security/tpm/tss_errors.h>
#include <types.h> #include <types.h>
#include <vb2_sha.h> #include <vb2_sha.h>
@@ -40,12 +41,12 @@
/** /**
* Measure digests cached in TPM log entries into PCRs * Measure digests cached in TPM log entries into PCRs
*/ */
int tspi_measure_cache_to_pcr(void); tpm_result_t tspi_measure_cache_to_pcr(void);
/** /**
* Extend a measurement hash taken for a CBFS file into the appropriate PCR. * Extend a measurement hash taken for a CBFS file into the appropriate PCR.
*/ */
uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash); tpm_result_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash);
/* /*
* Provide a function on SoC level to measure the bootblock for cases where bootblock is * Provide a function on SoC level to measure the bootblock for cases where bootblock is

View File

@@ -11,16 +11,16 @@
#include <vb2_sha.h> #include <vb2_sha.h>
#if CONFIG(TPM1) #if CONFIG(TPM1)
static uint32_t tpm1_invoke_state_machine(void) static tpm_result_t tpm1_invoke_state_machine(void)
{ {
uint8_t disabled; uint8_t disabled;
uint8_t deactivated; uint8_t deactivated;
uint32_t rc = TPM_SUCCESS; tpm_result_t rc = TPM_SUCCESS;
/* Check that the TPM is enabled and activated. */ /* Check that the TPM is enabled and activated. */
rc = tlcl_get_flags(&disabled, &deactivated, NULL); rc = tlcl_get_flags(&disabled, &deactivated, NULL);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't read capabilities.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't read capabilities.\n", rc);
return rc; return rc;
} }
@@ -29,7 +29,7 @@ static uint32_t tpm1_invoke_state_machine(void)
rc = tlcl_set_enable(); rc = tlcl_set_enable();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't set enabled state.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc);
return rc; return rc;
} }
} }
@@ -40,7 +40,7 @@ static uint32_t tpm1_invoke_state_machine(void)
rc = tlcl_set_deactivated(!deactivated); rc = tlcl_set_deactivated(!deactivated);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, printk(BIOS_ERR,
"TPM: Can't toggle deactivated state.\n"); "TPM Error (%#x): Can't toggle deactivated state.\n", rc);
return rc; return rc;
} }
@@ -52,11 +52,9 @@ static uint32_t tpm1_invoke_state_machine(void)
} }
#endif #endif
static uint32_t tpm_setup_s3_helper(void) static tpm_result_t tpm_setup_s3_helper(void)
{ {
uint32_t rc; tpm_result_t rc = tlcl_resume();
rc = tlcl_resume();
switch (rc) { switch (rc) {
case TPM_SUCCESS: case TPM_SUCCESS:
break; break;
@@ -78,7 +76,7 @@ static uint32_t tpm_setup_s3_helper(void)
return rc; return rc;
} }
static uint32_t tpm_setup_epilogue(uint32_t rc) static tpm_result_t tpm_setup_epilogue(tpm_result_t rc)
{ {
if (rc != TPM_SUCCESS) if (rc != TPM_SUCCESS)
post_code(POSTCODE_TPM_FAILURE); post_code(POSTCODE_TPM_FAILURE);
@@ -133,13 +131,13 @@ static inline int tspi_tpm_is_setup(void)
* to the TPM flashram at every reboot or wake-up, because of concerns about * to the TPM flashram at every reboot or wake-up, because of concerns about
* the durability of the NVRAM. * the durability of the NVRAM.
*/ */
uint32_t tpm_setup(int s3flag) tpm_result_t tpm_setup(int s3flag)
{ {
uint32_t rc; tpm_result_t rc;
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't initialize.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't initialize.\n", rc);
return tpm_setup_epilogue(rc); return tpm_setup_epilogue(rc);
} }
@@ -152,11 +150,11 @@ uint32_t tpm_setup(int s3flag)
rc = tlcl_startup(); rc = tlcl_startup();
if (CONFIG(TPM_STARTUP_IGNORE_POSTINIT) if (CONFIG(TPM_STARTUP_IGNORE_POSTINIT)
&& rc == TPM_INVALID_POSTINIT) { && rc == TPM_INVALID_POSTINIT) {
printk(BIOS_DEBUG, "TPM: ignoring invalid POSTINIT\n"); printk(BIOS_DEBUG, "TPM Warn(%#x): ignoring invalid POSTINIT\n", rc);
rc = TPM_SUCCESS; rc = TPM_SUCCESS;
} }
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't run startup command.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't run startup command.\n", rc);
return tpm_setup_epilogue(rc); return tpm_setup_epilogue(rc);
} }
@@ -169,13 +167,13 @@ uint32_t tpm_setup(int s3flag)
*/ */
rc = tlcl_physical_presence_cmd_enable(); rc = tlcl_physical_presence_cmd_enable();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't enable physical presence command.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't enable physical presence command.\n", rc);
return tpm_setup_epilogue(rc); return tpm_setup_epilogue(rc);
} }
rc = tlcl_assert_physical_presence(); rc = tlcl_assert_physical_presence();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't assert physical presence.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't assert physical presence.\n", rc);
return tpm_setup_epilogue(rc); return tpm_setup_epilogue(rc);
} }
} }
@@ -190,27 +188,27 @@ uint32_t tpm_setup(int s3flag)
return tpm_setup_epilogue(rc); return tpm_setup_epilogue(rc);
} }
uint32_t tpm_clear_and_reenable(void) tpm_result_t tpm_clear_and_reenable(void)
{ {
uint32_t rc; tpm_result_t rc;
printk(BIOS_INFO, "TPM: Clear and re-enable\n"); printk(BIOS_INFO, "TPM: Clear and re-enable\n");
rc = tlcl_force_clear(); rc = tlcl_force_clear();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't initiate a force clear.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't initiate a force clear.\n", rc);
return rc; return rc;
} }
#if CONFIG(TPM1) #if CONFIG(TPM1)
rc = tlcl_set_enable(); rc = tlcl_set_enable();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't set enabled state.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc);
return rc; return rc;
} }
rc = tlcl_set_deactivated(0); rc = tlcl_set_deactivated(0);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't set deactivated state.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't set deactivated state.\n", rc);
return rc; return rc;
} }
#endif #endif
@@ -218,10 +216,10 @@ uint32_t tpm_clear_and_reenable(void)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo, tpm_result_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
const uint8_t *digest, size_t digest_len, const char *name) const uint8_t *digest, size_t digest_len, const char *name)
{ {
uint32_t rc; tpm_result_t rc;
if (!digest) if (!digest)
return TPM_IOERROR; return TPM_IOERROR;
@@ -229,15 +227,15 @@ uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
if (tspi_tpm_is_setup()) { if (tspi_tpm_is_setup()) {
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Can't initialize library.\n"); printk(BIOS_ERR, "TPM Error (%#x): Can't initialize library.\n", rc);
return rc; return rc;
} }
printk(BIOS_DEBUG, "TPM: Extending digest for `%s` into PCR %d\n", name, pcr); printk(BIOS_DEBUG, "TPM: Extending digest for `%s` into PCR %d\n", name, pcr);
rc = tlcl_extend(pcr, digest, digest_algo); rc = tlcl_extend(pcr, digest, digest_algo);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "TPM: Extending hash for `%s` into PCR %d failed.\n", printk(BIOS_ERR, "TPM Error (%#x): Extending hash for `%s` into PCR %d failed.\n",
name, pcr); rc, name, pcr);
return rc; return rc;
} }
} }
@@ -252,7 +250,7 @@ uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
} }
#if CONFIG(VBOOT_LIB) #if CONFIG(VBOOT_LIB)
uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr, tpm_result_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
const char *rname) const char *rname)
{ {
uint8_t digest[TPM_PCR_MAX_LEN], digest_len; uint8_t digest[TPM_PCR_MAX_LEN], digest_len;

View File

@@ -23,29 +23,29 @@
* Define a space with permission [perm]. [index] is the index for the space, * Define a space with permission [perm]. [index] is the index for the space,
* [size] the usable data size. The TPM error code is returned. * [size] the usable data size. The TPM error code is returned.
*/ */
uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size); tpm_result_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size);
/** /**
* Issue a PhysicalEnable. The TPM error code is returned. * Issue a PhysicalEnable. The TPM error code is returned.
*/ */
uint32_t tlcl_set_enable(void); tpm_result_t tlcl_set_enable(void);
/** /**
* Issue a SetDeactivated. Pass 0 to activate. Returns result code. * Issue a SetDeactivated. Pass 0 to activate. Returns result code.
*/ */
uint32_t tlcl_set_deactivated(uint8_t flag); tpm_result_t tlcl_set_deactivated(uint8_t flag);
/** /**
* Get flags of interest. Pointers for flags you aren't interested in may * Get flags of interest. Pointers for flags you aren't interested in may
* be NULL. The TPM error code is returned. * be NULL. The TPM error code is returned.
*/ */
uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, tpm_result_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
uint8_t *nvlocked); uint8_t *nvlocked);
/** /**
* Get the entire set of permanent flags. * Get the entire set of permanent flags.
*/ */
uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); tpm_result_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
#endif #endif
@@ -57,19 +57,19 @@ uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
* Define a TPM2 space. The define space command TPM command used by the tlcl * Define a TPM2 space. The define space command TPM command used by the tlcl
* layer offers the ability to use custom nv attributes and policies. * layer offers the ability to use custom nv attributes and policies.
*/ */
uint32_t tlcl_define_space(uint32_t space_index, size_t space_size, tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size,
const TPMA_NV nv_attributes, const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size); const uint8_t *nv_policy, size_t nv_policy_size);
/* /*
* Issue TPM2_GetCapability command * Issue TPM2_GetCapability command
*/ */
uint32_t tlcl_get_capability(TPM_CAP capability, uint32_t property, tpm_result_t tlcl_get_capability(TPM_CAP capability, uint32_t property,
uint32_t property_count, uint32_t property_count,
TPMS_CAPABILITY_DATA *capability_data); TPMS_CAPABILITY_DATA *capability_data);
/* Issue TPM2_NV_SetBits command */ /* Issue TPM2_NV_SetBits command */
uint32_t tlcl_set_bits(uint32_t index, uint64_t bits); tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits);
/* /*
* Makes tpm_process_command available for on top implementations of * Makes tpm_process_command available for on top implementations of
@@ -88,12 +88,12 @@ uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo);
/** /**
* Call this first. Returns 0 if success, nonzero if error. * Call this first. Returns 0 if success, nonzero if error.
*/ */
uint32_t tlcl_lib_init(void); tpm_result_t tlcl_lib_init(void);
/** /**
* Perform a raw TPM request/response transaction. * Perform a raw TPM request/response transaction.
*/ */
uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response, tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
int max_length); int max_length);
/* Commands */ /* Commands */
@@ -102,20 +102,20 @@ uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
* Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for * Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for
* success). * success).
*/ */
uint32_t tlcl_startup(void); tpm_result_t tlcl_startup(void);
/** /**
* Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned * Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned
* (0 for success). * (0 for success).
*/ */
uint32_t tlcl_resume(void); tpm_result_t tlcl_resume(void);
/** /**
* Save TPM state by sending either TPM_SaveState() (TPM1.2) or * Save TPM state by sending either TPM_SaveState() (TPM1.2) or
* TPM_Shutdown(ST_STATE) (TPM2.0). The TPM error code is returned (0 for * TPM_Shutdown(ST_STATE) (TPM2.0). The TPM error code is returned (0 for
* success). * success).
*/ */
uint32_t tlcl_save_state(void); tpm_result_t tlcl_save_state(void);
/** /**
* Run the self test. * Run the self test.
@@ -123,81 +123,81 @@ uint32_t tlcl_save_state(void);
* Note---this is synchronous. To run this in parallel with other firmware, * Note---this is synchronous. To run this in parallel with other firmware,
* use ContinueSelfTest(). The TPM error code is returned. * use ContinueSelfTest(). The TPM error code is returned.
*/ */
uint32_t tlcl_self_test_full(void); tpm_result_t tlcl_self_test_full(void);
/** /**
* Run the self test in the background. * Run the self test in the background.
*/ */
uint32_t tlcl_continue_self_test(void); tpm_result_t tlcl_continue_self_test(void);
/** /**
* Write [length] bytes of [data] to space at [index]. The TPM error code is * Write [length] bytes of [data] to space at [index]. The TPM error code is
* returned. * returned.
*/ */
uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length); tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length);
/** /**
* Read [length] bytes from space at [index] into [data]. The TPM error code * Read [length] bytes from space at [index] into [data]. The TPM error code
* is returned. * is returned.
*/ */
uint32_t tlcl_read(uint32_t index, void *data, uint32_t length); tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length);
/** /**
* Assert physical presence in software. The TPM error code is returned. * Assert physical presence in software. The TPM error code is returned.
*/ */
uint32_t tlcl_assert_physical_presence(void); tpm_result_t tlcl_assert_physical_presence(void);
/** /**
* Enable the physical presence command. The TPM error code is returned. * Enable the physical presence command. The TPM error code is returned.
*/ */
uint32_t tlcl_physical_presence_cmd_enable(void); tpm_result_t tlcl_physical_presence_cmd_enable(void);
/** /**
* Finalize the physical presence settings: software PP is enabled, hardware PP * Finalize the physical presence settings: software PP is enabled, hardware PP
* is disabled, and the lifetime lock is set. The TPM error code is returned. * is disabled, and the lifetime lock is set. The TPM error code is returned.
*/ */
uint32_t tlcl_finalize_physical_presence(void); tpm_result_t tlcl_finalize_physical_presence(void);
/** /**
* Set the nvLocked bit. The TPM error code is returned. * Set the nvLocked bit. The TPM error code is returned.
*/ */
uint32_t tlcl_set_nv_locked(void); tpm_result_t tlcl_set_nv_locked(void);
/** /**
* Issue a ForceClear. The TPM error code is returned. * Issue a ForceClear. The TPM error code is returned.
*/ */
uint32_t tlcl_force_clear(void); tpm_result_t tlcl_force_clear(void);
/** /**
* Set Clear Control. The TPM error code is returned. * Set Clear Control. The TPM error code is returned.
*/ */
uint32_t tlcl_clear_control(bool disable); tpm_result_t tlcl_clear_control(bool disable);
/** /**
* Set the bGlobalLock flag, which only a reboot can clear. The TPM error * Set the bGlobalLock flag, which only a reboot can clear. The TPM error
* code is returned. * code is returned.
*/ */
uint32_t tlcl_set_global_lock(void); tpm_result_t tlcl_set_global_lock(void);
/** /**
* Make an NV Ram location read_only. The TPM error code is returned. * Make an NV Ram location read_only. The TPM error code is returned.
*/ */
uint32_t tlcl_lock_nv_write(uint32_t index); tpm_result_t tlcl_lock_nv_write(uint32_t index);
/** /**
* Perform a TPM_Extend. * Perform a TPM_Extend.
*/ */
uint32_t tlcl_extend(int pcr_num, const uint8_t *digest_data, tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data,
enum vb2_hash_algorithm digest_algo); enum vb2_hash_algorithm digest_algo);
/** /**
* Disable platform hierarchy. Specific to TPM2. The TPM error code is returned. * Disable platform hierarchy. Specific to TPM2. The TPM error code is returned.
*/ */
uint32_t tlcl_disable_platform_hierarchy(void); tpm_result_t tlcl_disable_platform_hierarchy(void);
/** /**
* Get the permission bits for the NVRAM space with |index|. * Get the permission bits for the NVRAM space with |index|.
*/ */
uint32_t tlcl_get_permissions(uint32_t index, uint32_t *permissions); tpm_result_t tlcl_get_permissions(uint32_t index, uint32_t *permissions);
#endif /* TSS_H_ */ #endif /* TSS_H_ */

View File

@@ -24,19 +24,21 @@
#include <console/console.h> #include <console/console.h>
#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args) #define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
static int tpm_send_receive(const uint8_t *request, static tpm_result_t tpm_send_receive(const uint8_t *request,
uint32_t request_length, uint32_t request_length,
uint8_t *response, uint8_t *response,
uint32_t *response_length) uint32_t *response_length)
{ {
size_t len = *response_length; size_t len = *response_length;
if (tis_sendrecv(request, request_length, response, &len)) tpm_result_t rc = tis_sendrecv(request, request_length, response, &len);
return VB2_ERROR_UNKNOWN; if (rc)
return rc;
/* check 64->32bit overflow and (re)check response buffer overflow */ /* check 64->32bit overflow and (re)check response buffer overflow */
if (len > *response_length) if (len > *response_length)
return VB2_ERROR_UNKNOWN; rc = TPM_CB_FAIL;
*response_length = len; else
return VB2_SUCCESS; *response_length = len;
return rc;
} }
/* Sets the size field of a TPM command. */ /* Sets the size field of a TPM command. */
@@ -55,15 +57,15 @@ static inline int tpm_command_size(const uint8_t *buffer)
} }
/* Gets the code field of a TPM command. */ /* Gets the code field of a TPM command. */
static inline int tpm_command_code(const uint8_t *buffer) static inline tpm_result_t tpm_command_code(const uint8_t *buffer)
{ {
uint32_t rc; tpm_result_t rc;
from_tpm_uint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &rc); from_tpm_uint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &rc);
return rc; return rc;
} }
/* Gets the return code field of a TPM result. */ /* Gets the return code field of a TPM result. */
static inline int tpm_return_code(const uint8_t *buffer) static inline tpm_result_t tpm_return_code(const uint8_t *buffer)
{ {
return tpm_command_code(buffer); return tpm_command_code(buffer);
} }
@@ -72,15 +74,15 @@ static inline int tpm_return_code(const uint8_t *buffer)
* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or * Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
* DOING_SELFTEST errors are returned. * DOING_SELFTEST errors are returned.
*/ */
static uint32_t tlcl_send_receive_no_retry(const uint8_t *request, static tpm_result_t tlcl_send_receive_no_retry(const uint8_t *request,
uint8_t *response, int max_length) uint8_t *response, int max_length)
{ {
uint32_t response_length = max_length; uint32_t response_length = max_length;
uint32_t rc; tpm_result_t rc;
rc = tpm_send_receive(request, tpm_command_size(request), rc = tpm_send_receive(request, tpm_command_size(request),
response, &response_length); response, &response_length);
if (rc != 0) { if (rc != TPM_SUCCESS) {
/* Communication with TPM failed, so response is garbage */ /* Communication with TPM failed, so response is garbage */
VBDEBUG("TPM: command %#x send/receive failed: %#x\n", VBDEBUG("TPM: command %#x send/receive failed: %#x\n",
tpm_command_code(request), rc); tpm_command_code(request), rc);
@@ -96,15 +98,15 @@ static uint32_t tlcl_send_receive_no_retry(const uint8_t *request,
VBDEBUG("TPM: command %#x returned %#x\n", VBDEBUG("TPM: command %#x returned %#x\n",
tpm_command_code(request), rc); tpm_command_code(request), rc);
return rc; return rc;
} }
/* Sends a TPM command and gets a response. Returns 0 if success or the TPM /* Sends a TPM command and gets a response. Returns 0 if success or the TPM
* error code if error. Waits for the self test to complete if needed. */ * error code if error. Waits for the self test to complete if needed. */
uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response, tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
int max_length) int max_length)
{ {
uint32_t rc = tlcl_send_receive_no_retry(request, response, tpm_result_t rc = tlcl_send_receive_no_retry(request, response,
max_length); max_length);
/* If the command fails because the self test has not completed, try it /* If the command fails because the self test has not completed, try it
* again after attempting to ensure that the self test has completed. */ * again after attempting to ensure that the self test has completed. */
@@ -132,7 +134,7 @@ uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
} }
/* Sends a command and returns the error code. */ /* Sends a command and returns the error code. */
static uint32_t send(const uint8_t *command) static tpm_result_t send(const uint8_t *command)
{ {
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
return tlcl_send_receive(command, response, sizeof(response)); return tlcl_send_receive(command, response, sizeof(response));
@@ -142,46 +144,48 @@ static uint32_t send(const uint8_t *command)
static uint8_t tlcl_init_done; static uint8_t tlcl_init_done;
uint32_t tlcl_lib_init(void) tpm_result_t tlcl_lib_init(void)
{ {
tpm_result_t rc = TPM_SUCCESS;
if (tlcl_init_done) if (tlcl_init_done)
return VB2_SUCCESS; return rc;
rc = tis_init();
if (tis_init()) if (rc)
return VB2_ERROR_UNKNOWN; return rc;
if (tis_open()) rc = tis_open();
return VB2_ERROR_UNKNOWN; if (rc)
return rc;
tlcl_init_done = 1; tlcl_init_done = 1;
return VB2_SUCCESS; return rc;
} }
uint32_t tlcl_startup(void) tpm_result_t tlcl_startup(void)
{ {
VBDEBUG("TPM: Startup\n"); VBDEBUG("TPM: Startup\n");
return send(tpm_startup_cmd.buffer); return send(tpm_startup_cmd.buffer);
} }
uint32_t tlcl_resume(void) tpm_result_t tlcl_resume(void)
{ {
VBDEBUG("TPM: Resume\n"); VBDEBUG("TPM: Resume\n");
return send(tpm_resume_cmd.buffer); return send(tpm_resume_cmd.buffer);
} }
uint32_t tlcl_save_state(void) tpm_result_t tlcl_save_state(void)
{ {
VBDEBUG("TPM: Save state\n"); VBDEBUG("TPM: Save state\n");
return send(tpm_savestate_cmd.buffer); return send(tpm_savestate_cmd.buffer);
} }
uint32_t tlcl_self_test_full(void) tpm_result_t tlcl_self_test_full(void)
{ {
VBDEBUG("TPM: Self test full\n"); VBDEBUG("TPM: Self test full\n");
return send(tpm_selftestfull_cmd.buffer); return send(tpm_selftestfull_cmd.buffer);
} }
uint32_t tlcl_continue_self_test(void) tpm_result_t tlcl_continue_self_test(void)
{ {
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
VBDEBUG("TPM: Continue self test\n"); VBDEBUG("TPM: Continue self test\n");
@@ -190,7 +194,7 @@ uint32_t tlcl_continue_self_test(void)
response, sizeof(response)); response, sizeof(response));
} }
uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size) tpm_result_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
{ {
struct s_tpm_nv_definespace_cmd cmd; struct s_tpm_nv_definespace_cmd cmd;
VBDEBUG("TPM: TlclDefineSpace(%#x, %#x, %d)\n", index, perm, size); VBDEBUG("TPM: TlclDefineSpace(%#x, %#x, %d)\n", index, perm, size);
@@ -201,7 +205,7 @@ uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
return send(cmd.buffer); return send(cmd.buffer);
} }
uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length) tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length)
{ {
struct s_tpm_nv_write_cmd cmd; struct s_tpm_nv_write_cmd cmd;
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
@@ -221,12 +225,12 @@ uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length)
return tlcl_send_receive(cmd.buffer, response, sizeof(response)); return tlcl_send_receive(cmd.buffer, response, sizeof(response));
} }
uint32_t tlcl_read(uint32_t index, void *data, uint32_t length) tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length)
{ {
struct s_tpm_nv_read_cmd cmd; struct s_tpm_nv_read_cmd cmd;
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
uint32_t result_length; uint32_t result_length;
uint32_t rc; tpm_result_t rc;
VBDEBUG("TPM: %s(%#x, %d)\n", __func__, index, length); VBDEBUG("TPM: %s(%#x, %d)\n", __func__, index, length);
memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd)); memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
@@ -246,43 +250,43 @@ uint32_t tlcl_read(uint32_t index, void *data, uint32_t length)
return rc; return rc;
} }
uint32_t tlcl_assert_physical_presence(void) tpm_result_t tlcl_assert_physical_presence(void)
{ {
VBDEBUG("TPM: Asserting physical presence\n"); VBDEBUG("TPM: Asserting physical presence\n");
return send(tpm_ppassert_cmd.buffer); return send(tpm_ppassert_cmd.buffer);
} }
uint32_t tlcl_physical_presence_cmd_enable(void) tpm_result_t tlcl_physical_presence_cmd_enable(void)
{ {
VBDEBUG("TPM: Enable the physical presence command\n"); VBDEBUG("TPM: Enable the physical presence command\n");
return send(tpm_ppenable_cmd.buffer); return send(tpm_ppenable_cmd.buffer);
} }
uint32_t tlcl_finalize_physical_presence(void) tpm_result_t tlcl_finalize_physical_presence(void)
{ {
VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n"); VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n");
return send(tpm_finalizepp_cmd.buffer); return send(tpm_finalizepp_cmd.buffer);
} }
uint32_t tlcl_set_nv_locked(void) tpm_result_t tlcl_set_nv_locked(void)
{ {
VBDEBUG("TPM: Set NV locked\n"); VBDEBUG("TPM: Set NV locked\n");
return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0); return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0);
} }
uint32_t tlcl_force_clear(void) tpm_result_t tlcl_force_clear(void)
{ {
VBDEBUG("TPM: Force clear\n"); VBDEBUG("TPM: Force clear\n");
return send(tpm_forceclear_cmd.buffer); return send(tpm_forceclear_cmd.buffer);
} }
uint32_t tlcl_set_enable(void) tpm_result_t tlcl_set_enable(void)
{ {
VBDEBUG("TPM: Enabling TPM\n"); VBDEBUG("TPM: Enabling TPM\n");
return send(tpm_physicalenable_cmd.buffer); return send(tpm_physicalenable_cmd.buffer);
} }
uint32_t tlcl_set_deactivated(uint8_t flag) tpm_result_t tlcl_set_deactivated(uint8_t flag)
{ {
struct s_tpm_physicalsetdeactivated_cmd cmd; struct s_tpm_physicalsetdeactivated_cmd cmd;
VBDEBUG("TPM: SetDeactivated(%d)\n", flag); VBDEBUG("TPM: SetDeactivated(%d)\n", flag);
@@ -291,11 +295,11 @@ uint32_t tlcl_set_deactivated(uint8_t flag)
return send(cmd.buffer); return send(cmd.buffer);
} }
uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags) tpm_result_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags)
{ {
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
uint32_t size; uint32_t size;
uint32_t rc = tlcl_send_receive(tpm_getflags_cmd.buffer, response, tpm_result_t rc = tlcl_send_receive(tpm_getflags_cmd.buffer, response,
sizeof(response)); sizeof(response));
if (rc != TPM_SUCCESS) if (rc != TPM_SUCCESS)
return rc; return rc;
@@ -307,11 +311,11 @@ uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags)
return rc; return rc;
} }
uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, tpm_result_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
uint8_t *nvlocked) uint8_t *nvlocked)
{ {
TPM_PERMANENT_FLAGS pflags; TPM_PERMANENT_FLAGS pflags;
uint32_t rc = tlcl_get_permanent_flags(&pflags); tpm_result_t rc = tlcl_get_permanent_flags(&pflags);
if (rc == TPM_SUCCESS) { if (rc == TPM_SUCCESS) {
if (disable) if (disable)
*disable = pflags.disable; *disable = pflags.disable;
@@ -325,13 +329,13 @@ uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
return rc; return rc;
} }
uint32_t tlcl_set_global_lock(void) tpm_result_t tlcl_set_global_lock(void)
{ {
VBDEBUG("TPM: Set global lock\n"); VBDEBUG("TPM: Set global lock\n");
return tlcl_write(TPM_NV_INDEX0, NULL, 0); return tlcl_write(TPM_NV_INDEX0, NULL, 0);
} }
uint32_t tlcl_extend(int pcr_num, const uint8_t *digest_data, tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data,
enum vb2_hash_algorithm digest_algo) enum vb2_hash_algorithm digest_algo)
{ {
struct s_tpm_extend_cmd cmd; struct s_tpm_extend_cmd cmd;
@@ -347,12 +351,12 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *digest_data,
return tlcl_send_receive(cmd.buffer, response, sizeof(response)); return tlcl_send_receive(cmd.buffer, response, sizeof(response));
} }
uint32_t tlcl_get_permissions(uint32_t index, uint32_t *permissions) tpm_result_t tlcl_get_permissions(uint32_t index, uint32_t *permissions)
{ {
struct s_tpm_getpermissions_cmd cmd; struct s_tpm_getpermissions_cmd cmd;
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
uint8_t *nvdata; uint8_t *nvdata;
uint32_t rc; tpm_result_t rc;
uint32_t size; uint32_t size;
memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd));

View File

@@ -46,7 +46,7 @@ void *tpm_process_command(TPM_CC command, void *command_body)
return tpm_unmarshal_response(command, &ib); return tpm_unmarshal_response(command, &ib);
} }
static uint32_t tlcl_send_startup(TPM_SU type) static tpm_result_t tlcl_send_startup(TPM_SU type)
{ {
struct tpm2_startup startup; struct tpm2_startup startup;
struct tpm2_response *response; struct tpm2_response *response;
@@ -75,12 +75,12 @@ static uint32_t tlcl_send_startup(TPM_SU type)
return TPM_IOERROR; return TPM_IOERROR;
} }
uint32_t tlcl_resume(void) tpm_result_t tlcl_resume(void)
{ {
return tlcl_send_startup(TPM_SU_STATE); return tlcl_send_startup(TPM_SU_STATE);
} }
static uint32_t tlcl_send_shutdown(TPM_SU type) static tpm_result_t tlcl_send_shutdown(TPM_SU type)
{ {
struct tpm2_shutdown shutdown; struct tpm2_shutdown shutdown;
struct tpm2_response *response; struct tpm2_response *response;
@@ -104,12 +104,12 @@ static uint32_t tlcl_send_shutdown(TPM_SU type)
return TPM_IOERROR; return TPM_IOERROR;
} }
uint32_t tlcl_save_state(void) tpm_result_t tlcl_save_state(void)
{ {
return tlcl_send_shutdown(TPM_SU_STATE); return tlcl_send_shutdown(TPM_SU_STATE);
} }
uint32_t tlcl_assert_physical_presence(void) tpm_result_t tlcl_assert_physical_presence(void)
{ {
/* /*
* Nothing to do on TPM2 for this, use platform hierarchy availability * Nothing to do on TPM2 for this, use platform hierarchy availability
@@ -135,7 +135,7 @@ static TPM_ALG_ID tpmalg_from_vb2_hash(enum vb2_hash_algorithm hash_type)
} }
} }
uint32_t tlcl_extend(int pcr_num, const uint8_t *digest_data, tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data,
enum vb2_hash_algorithm digest_type) enum vb2_hash_algorithm digest_type)
{ {
struct tpm2_pcr_extend_cmd pcr_ext_cmd; struct tpm2_pcr_extend_cmd pcr_ext_cmd;
@@ -163,14 +163,14 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *digest_data,
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_finalize_physical_presence(void) tpm_result_t tlcl_finalize_physical_presence(void)
{ {
/* Nothing needs to be done with tpm2. */ /* Nothing needs to be done with tpm2. */
printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__); printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__);
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_force_clear(void) tpm_result_t tlcl_force_clear(void)
{ {
struct tpm2_response *response; struct tpm2_response *response;
@@ -184,7 +184,7 @@ uint32_t tlcl_force_clear(void)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_clear_control(bool disable) tpm_result_t tlcl_clear_control(bool disable)
{ {
struct tpm2_response *response; struct tpm2_response *response;
struct tpm2_clear_control_cmd cc = { struct tpm2_clear_control_cmd cc = {
@@ -204,33 +204,36 @@ uint32_t tlcl_clear_control(bool disable)
static uint8_t tlcl_init_done; static uint8_t tlcl_init_done;
/* This function is called directly by vboot, uses vboot return types. */ /* This function is called directly by vboot, uses vboot return types. */
uint32_t tlcl_lib_init(void) tpm_result_t tlcl_lib_init(void)
{ {
tpm_result_t rc = TPM_SUCCESS;
if (tlcl_init_done) if (tlcl_init_done)
return VB2_SUCCESS; return rc;
if (tis_init()) { rc = tis_init();
printk(BIOS_ERR, "%s: tis_init returned error\n", __func__); if (rc) {
return VB2_ERROR_UNKNOWN; printk(BIOS_ERR, "%s: tis_init returned error %d\n", __func__, rc);
return rc;
} }
rc = tis_open();
if (tis_open()) { if (rc) {
printk(BIOS_ERR, "%s: tis_open returned error\n", __func__); printk(BIOS_ERR, "%s: tis_open returned error %d\n"
return VB2_ERROR_UNKNOWN; , __func__, rc);
return rc;
} }
tlcl_init_done = 1; tlcl_init_done = 1;
return VB2_SUCCESS; return rc;
} }
uint32_t tlcl_physical_presence_cmd_enable(void) tpm_result_t tlcl_physical_presence_cmd_enable(void)
{ {
printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__); printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__);
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_read(uint32_t index, void *data, uint32_t length) tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length)
{ {
struct tpm2_nv_read_cmd nv_readc; struct tpm2_nv_read_cmd nv_readc;
struct tpm2_response *response; struct tpm2_response *response;
@@ -279,7 +282,7 @@ uint32_t tlcl_read(uint32_t index, void *data, uint32_t length)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_self_test_full(void) tpm_result_t tlcl_self_test_full(void)
{ {
struct tpm2_self_test st; struct tpm2_self_test st;
struct tpm2_response *response; struct tpm2_response *response;
@@ -292,7 +295,7 @@ uint32_t tlcl_self_test_full(void)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_lock_nv_write(uint32_t index) tpm_result_t tlcl_lock_nv_write(uint32_t index)
{ {
struct tpm2_response *response; struct tpm2_response *response;
/* TPM Will reject attempts to write at non-defined index. */ /* TPM Will reject attempts to write at non-defined index. */
@@ -311,12 +314,12 @@ uint32_t tlcl_lock_nv_write(uint32_t index)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_startup(void) tpm_result_t tlcl_startup(void)
{ {
return tlcl_send_startup(TPM_SU_CLEAR); return tlcl_send_startup(TPM_SU_CLEAR);
} }
uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length) tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length)
{ {
struct tpm2_nv_write_cmd nv_writec; struct tpm2_nv_write_cmd nv_writec;
struct tpm2_response *response; struct tpm2_response *response;
@@ -339,7 +342,7 @@ uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_set_bits(uint32_t index, uint64_t bits) tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits)
{ {
struct tpm2_nv_setbits_cmd nvsb_cmd; struct tpm2_nv_setbits_cmd nvsb_cmd;
struct tpm2_response *response; struct tpm2_response *response;
@@ -362,7 +365,7 @@ uint32_t tlcl_set_bits(uint32_t index, uint64_t bits)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_define_space(uint32_t space_index, size_t space_size, tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size,
const TPMA_NV nv_attributes, const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size) const uint8_t *nv_policy, size_t nv_policy_size)
{ {
@@ -437,7 +440,7 @@ uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo)
return value; return value;
} }
uint32_t tlcl_disable_platform_hierarchy(void) tpm_result_t tlcl_disable_platform_hierarchy(void)
{ {
struct tpm2_response *response; struct tpm2_response *response;
struct tpm2_hierarchy_control_cmd hc = { struct tpm2_hierarchy_control_cmd hc = {
@@ -453,7 +456,7 @@ uint32_t tlcl_disable_platform_hierarchy(void)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_get_capability(TPM_CAP capability, uint32_t property, tpm_result_t tlcl_get_capability(TPM_CAP capability, uint32_t property,
uint32_t property_count, uint32_t property_count,
TPMS_CAPABILITY_DATA *capability_data) TPMS_CAPABILITY_DATA *capability_data)
{ {

View File

@@ -9,7 +9,7 @@
#include "../../tcg-2.0/tss_marshaling.h" #include "../../tcg-2.0/tss_marshaling.h"
uint32_t tlcl_cr50_enable_nvcommits(void) tpm_result_t tlcl_cr50_enable_nvcommits(void)
{ {
uint16_t sub_command = TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS; uint16_t sub_command = TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS;
struct tpm2_response *response; struct tpm2_response *response;
@@ -29,8 +29,8 @@ uint32_t tlcl_cr50_enable_nvcommits(void)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_enable_update(uint16_t timeout_ms, tpm_result_t tlcl_cr50_enable_update(uint16_t timeout_ms,
uint8_t *num_restored_headers) uint8_t *num_restored_headers)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t command_body[] = { uint16_t command_body[] = {
@@ -48,7 +48,7 @@ uint32_t tlcl_cr50_enable_update(uint16_t timeout_ms,
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state) tpm_result_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t sub_command = TPM2_CR50_SUB_CMD_GET_REC_BTN; uint16_t sub_command = TPM2_CR50_SUB_CMD_GET_REC_BTN;
@@ -64,7 +64,7 @@ uint32_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode) tpm_result_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t mode_command = TPM2_CR50_SUB_CMD_TPM_MODE; uint16_t mode_command = TPM2_CR50_SUB_CMD_TPM_MODE;
@@ -105,7 +105,7 @@ uint32_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode) tpm_result_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t mode_command = TPM2_CR50_SUB_CMD_GET_BOOT_MODE; uint16_t mode_command = TPM2_CR50_SUB_CMD_GET_BOOT_MODE;
@@ -131,7 +131,7 @@ uint32_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_immediate_reset(uint16_t timeout_ms) tpm_result_t tlcl_cr50_immediate_reset(uint16_t timeout_ms)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t reset_command_body[] = { uint16_t reset_command_body[] = {
@@ -150,7 +150,7 @@ uint32_t tlcl_cr50_immediate_reset(uint16_t timeout_ms)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t tlcl_cr50_reset_ec(void) tpm_result_t tlcl_cr50_reset_ec(void)
{ {
struct tpm2_response *response; struct tpm2_response *response;
uint16_t reset_cmd = TPM2_CR50_SUB_CMD_RESET_EC; uint16_t reset_cmd = TPM2_CR50_SUB_CMD_RESET_EC;

View File

@@ -3,6 +3,7 @@
#define CR50_TSS_STRUCTURES_H_ #define CR50_TSS_STRUCTURES_H_
#include <stdint.h> #include <stdint.h>
#include <security/tpm/tss_errors.h>
/* FIXME: below is not enough to differentiate between vendors commands /* FIXME: below is not enough to differentiate between vendors commands
of numerous devices. However, the current tpm2 APIs aren't very amenable of numerous devices. However, the current tpm2 APIs aren't very amenable
@@ -45,7 +46,7 @@ enum cr50_tpm_mode {
* CR50 specific tpm command to enable nvmem commits before internal timeout * CR50 specific tpm command to enable nvmem commits before internal timeout
* expires. * expires.
*/ */
uint32_t tlcl_cr50_enable_nvcommits(void); tpm_result_t tlcl_cr50_enable_nvcommits(void);
/** /**
* CR50 specific tpm command to restore header(s) of the dormant RO/RW * CR50 specific tpm command to restore header(s) of the dormant RO/RW
@@ -56,8 +57,8 @@ uint32_t tlcl_cr50_enable_nvcommits(void);
* Return value indicates success or failure of accessing the TPM; in case of * Return value indicates success or failure of accessing the TPM; in case of
* success the number of restored headers is saved in num_restored_headers. * success the number of restored headers is saved in num_restored_headers.
*/ */
uint32_t tlcl_cr50_enable_update(uint16_t timeout_ms, tpm_result_t tlcl_cr50_enable_update(uint16_t timeout_ms,
uint8_t *num_restored_headers); uint8_t *num_restored_headers);
/** /**
* CR50 specific tpm command to get the latched state of the recovery button. * CR50 specific tpm command to get the latched state of the recovery button.
@@ -65,7 +66,7 @@ uint32_t tlcl_cr50_enable_update(uint16_t timeout_ms,
* Return value indicates success or failure of accessing the TPM; in case of * Return value indicates success or failure of accessing the TPM; in case of
* success the recovery button state is saved in recovery_button_state. * success the recovery button state is saved in recovery_button_state.
*/ */
uint32_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state); tpm_result_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state);
/** /**
* CR50 specific TPM command sequence to query the current TPM mode. * CR50 specific TPM command sequence to query the current TPM mode.
@@ -77,7 +78,7 @@ uint32_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state);
* Returns TPM_CB_NO_SUCH_COMMAND if the Cr50 does not support the command. * Returns TPM_CB_NO_SUCH_COMMAND if the Cr50 does not support the command.
* Other returns value indicate a failure accessing the TPM. * Other returns value indicate a failure accessing the TPM.
*/ */
uint32_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode); tpm_result_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode);
/** /**
* CR50 specific TPM command sequence to query the current boot mode. * CR50 specific TPM command sequence to query the current boot mode.
@@ -85,7 +86,7 @@ uint32_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode);
* Returns TPM_SUCCESS if boot mode is successfully retrieved. * Returns TPM_SUCCESS if boot mode is successfully retrieved.
* Returns TPM_* for errors. * Returns TPM_* for errors.
*/ */
uint32_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode); tpm_result_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode);
/** /**
* CR50 specific TPM command sequence to trigger an immediate reset to the Cr50 * CR50 specific TPM command sequence to trigger an immediate reset to the Cr50
@@ -94,7 +95,7 @@ uint32_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode);
* *
* Return value indicates success or failure of accessing the TPM. * Return value indicates success or failure of accessing the TPM.
*/ */
uint32_t tlcl_cr50_immediate_reset(uint16_t timeout_ms); tpm_result_t tlcl_cr50_immediate_reset(uint16_t timeout_ms);
/** /**
* CR50 specific TPM command sequence to issue an EC reset. * CR50 specific TPM command sequence to issue an EC reset.
@@ -102,6 +103,6 @@ uint32_t tlcl_cr50_immediate_reset(uint16_t timeout_ms);
* Returns TPM_* for errors. * Returns TPM_* for errors.
* On Success, this function invokes halt() and does not return. * On Success, this function invokes halt() and does not return.
*/ */
uint32_t tlcl_cr50_reset_ec(void); tpm_result_t tlcl_cr50_reset_ec(void);
#endif /* CR50_TSS_STRUCTURES_H_ */ #endif /* CR50_TSS_STRUCTURES_H_ */

View File

@@ -4,7 +4,7 @@
* TPM error codes. * TPM error codes.
* *
* Copy-pasted and lightly edited from TCG TPM Main Part 2 TPM Structures * Copy-pasted and lightly edited from TCG TPM Main Part 2 TPM Structures
* Version 1.2 Level 2 Revision 103 26 October 2006 Draft. * Version 1.2 Level 2 Revision 116 1 March 2011.
*/ */
#ifndef TSS_ERRORS_H_ #ifndef TSS_ERRORS_H_
@@ -17,11 +17,13 @@ typedef uint32_t tpm_result_t;
#define TPM_BASE 0x0 #define TPM_BASE 0x0
#define TPM_NON_FATAL 0x800 #define TPM_NON_FATAL (0x800 + TPM_BASE)
#define TPM_CB_ERROR TPM_Vendor_Specific32 #define TPM_CB_ERROR TPM_Vendor_Specific32
#define TPM_SUCCESS ((tpm_result_t) (TPM_BASE + 0x00)) #define TPM_SUCCESS ((tpm_result_t) (TPM_BASE + 0x00))
#define TPM_BADINDEX ((tpm_result_t) (TPM_BASE + 0x02)) #define TPM_BADINDEX ((tpm_result_t) (TPM_BASE + 0x02))
#define TPM_BAD_PARAMETER ((tpm_result_t) (TPM_BASE + 0x03))
#define TPM_FAIL ((tpm_result_t) (TPM_BASE + 0x09))
#define TPM_OWNER_SET ((tpm_result_t) (TPM_BASE + 0x14)) #define TPM_OWNER_SET ((tpm_result_t) (TPM_BASE + 0x14))
#define TPM_IOERROR ((tpm_result_t) (TPM_BASE + 0x1F)) #define TPM_IOERROR ((tpm_result_t) (TPM_BASE + 0x1F))
#define TPM_INVALID_POSTINIT ((tpm_result_t) (TPM_BASE + 0x26)) #define TPM_INVALID_POSTINIT ((tpm_result_t) (TPM_BASE + 0x26))
@@ -29,6 +31,7 @@ typedef uint32_t tpm_result_t;
#define TPM_AREA_LOCKED ((tpm_result_t) (TPM_BASE + 0x3C)) #define TPM_AREA_LOCKED ((tpm_result_t) (TPM_BASE + 0x3C))
#define TPM_MAXNVWRITES ((tpm_result_t) (TPM_BASE + 0x48)) #define TPM_MAXNVWRITES ((tpm_result_t) (TPM_BASE + 0x48))
#define TPM_RETRY ((tpm_result_t) (TPM_NON_FATAL + 0x00))
#define TPM_NEEDS_SELFTEST ((tpm_result_t) (TPM_NON_FATAL + 0x01)) #define TPM_NEEDS_SELFTEST ((tpm_result_t) (TPM_NON_FATAL + 0x01))
#define TPM_DOING_SELFTEST ((tpm_result_t) (TPM_NON_FATAL + 0x02)) #define TPM_DOING_SELFTEST ((tpm_result_t) (TPM_NON_FATAL + 0x02))
@@ -56,5 +59,7 @@ typedef uint32_t tpm_result_t;
#define TPM_CB_HASH_ERROR ((tpm_result_t) (TPM_CB_ERROR + 0x8D)) #define TPM_CB_HASH_ERROR ((tpm_result_t) (TPM_CB_ERROR + 0x8D))
#define TPM_CB_NO_SUCH_COMMAND ((tpm_result_t) (TPM_CB_ERROR + 0x8E)) #define TPM_CB_NO_SUCH_COMMAND ((tpm_result_t) (TPM_CB_ERROR + 0x8E))
#define TPM_CB_RANGE ((tpm_result_t) (TPM_CB_ERROR + 0x8F)) #define TPM_CB_RANGE ((tpm_result_t) (TPM_CB_ERROR + 0x8F))
#define TPM_CB_FAIL ((tpm_result_t) (TPM_CB_ERROR + 0x90))
#define TPM_CB_TIMEOUT ((tpm_result_t) (TPM_CB_ERROR + 0x91))
#endif /* TSS_ERRORS_H_ */ #endif /* TSS_ERRORS_H_ */

View File

@@ -10,6 +10,7 @@
#include <types.h> #include <types.h>
#include <security/tpm/tspi.h> #include <security/tpm/tspi.h>
#include <security/tpm/tss_errors.h>
#include <vb2_sha.h> #include <vb2_sha.h>
struct vb2_context; struct vb2_context;
@@ -52,23 +53,23 @@ enum vb2_pcr_digest;
/* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */ /* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */
uint32_t antirollback_read_space_firmware(struct vb2_context *ctx); tpm_result_t antirollback_read_space_firmware(struct vb2_context *ctx);
/** /**
* Write may be called if the versions change. * Write may be called if the versions change.
*/ */
uint32_t antirollback_write_space_firmware(struct vb2_context *ctx); tpm_result_t antirollback_write_space_firmware(struct vb2_context *ctx);
/** /**
* Read and write kernel space in TPM. * Read and write kernel space in TPM.
*/ */
uint32_t antirollback_read_space_kernel(struct vb2_context *ctx); tpm_result_t antirollback_read_space_kernel(struct vb2_context *ctx);
uint32_t antirollback_write_space_kernel(struct vb2_context *ctx); tpm_result_t antirollback_write_space_kernel(struct vb2_context *ctx);
/** /**
* Lock must be called. * Lock must be called.
*/ */
uint32_t antirollback_lock_space_firmware(void); tpm_result_t antirollback_lock_space_firmware(void);
/* /*
* Read MRC hash data from TPM. * Read MRC hash data from TPM.
@@ -79,7 +80,7 @@ uint32_t antirollback_lock_space_firmware(void);
* @param data pointer to buffer where hash from TPM read into * @param data pointer to buffer where hash from TPM read into
* @param size size of buffer * @param size size of buffer
*/ */
uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size); tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size);
/* /*
* Write new hash data to MRC space in TPM.\ * Write new hash data to MRC space in TPM.\
* @param index index into TPM NVRAM where hash is stored The index * @param index index into TPM NVRAM where hash is stored The index
@@ -89,7 +90,7 @@ uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_
* @param data pointer to buffer of hash value to be written * @param data pointer to buffer of hash value to be written
* @param size size of buffer * @param size size of buffer
*/ */
uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data,
uint32_t size); uint32_t size);
/* /*
* Lock down MRC hash space in TPM. * Lock down MRC hash space in TPM.
@@ -98,19 +99,19 @@ uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data,
* MRC_RW_HASH_NV_INDEX depending upon whether we are * MRC_RW_HASH_NV_INDEX depending upon whether we are
* booting in recovery or normal mode. * booting in recovery or normal mode.
*/ */
uint32_t antirollback_lock_space_mrc_hash(uint32_t index); tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index);
/* /*
* Read VBIOS hash data from TPM. * Read VBIOS hash data from TPM.
* @param data pointer to buffer where hash from TPM read into * @param data pointer to buffer where hash from TPM read into
* @param size size of buffer * @param size size of buffer
*/ */
uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size); tpm_result_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size);
/* /*
* Write new hash data to VBIOS space in TPM. * Write new hash data to VBIOS space in TPM.
* @param data pointer to buffer of hash value to be written * @param data pointer to buffer of hash value to be written
* @param size size of buffer * @param size size of buffer
*/ */
uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size); tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size);
#endif /* ANTIROLLBACK_H_ */ #endif /* ANTIROLLBACK_H_ */

View File

@@ -12,10 +12,12 @@
void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size) void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size)
{ {
struct vb2_hash hash; struct vb2_hash hash;
tpm_result_t rc = TPM_SUCCESS;
/* Initialize TPM driver. */ /* Initialize TPM driver. */
if (tlcl_lib_init() != VB2_SUCCESS) { rc = tlcl_lib_init();
printk(BIOS_ERR, "MRC: TPM driver initialization failed.\n"); if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "MRC: TPM driver initialization failed with error %#x.\n", rc);
return; return;
} }
@@ -35,9 +37,9 @@ void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size)
} }
/* Write hash of data to TPM space. */ /* Write hash of data to TPM space. */
if (antirollback_write_space_mrc_hash(index, hash.sha256, sizeof(hash.sha256)) rc = antirollback_write_space_mrc_hash(index, hash.sha256, sizeof(hash.sha256));
!= TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "MRC: Could not save hash to TPM.\n"); printk(BIOS_ERR, "MRC: Could not save hash to TPM with error %#x.\n", rc);
return; return;
} }
@@ -47,17 +49,19 @@ void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size)
int mrc_cache_verify_hash(uint32_t index, const uint8_t *data, size_t size) int mrc_cache_verify_hash(uint32_t index, const uint8_t *data, size_t size)
{ {
struct vb2_hash tpm_hash = { .algo = VB2_HASH_SHA256 }; struct vb2_hash tpm_hash = { .algo = VB2_HASH_SHA256 };
tpm_result_t rc = TPM_SUCCESS;
/* Initialize TPM driver. */ /* Initialize TPM driver. */
if (tlcl_lib_init() != VB2_SUCCESS) { rc = tlcl_lib_init();
printk(BIOS_ERR, "MRC: TPM driver initialization failed.\n"); if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "MRC: TPM driver initialization failed with error %#x.\n", rc);
return 0; return 0;
} }
/* Read hash of MRC data saved in TPM. */ /* Read hash of MRC data saved in TPM. */
if (antirollback_read_space_mrc_hash(index, tpm_hash.sha256, sizeof(tpm_hash.sha256)) rc = antirollback_read_space_mrc_hash(index, tpm_hash.sha256, sizeof(tpm_hash.sha256));
!= TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "MRC: Could not read hash from TPM.\n"); printk(BIOS_ERR, "MRC: Could not read hash from TPM with error %#x.\n", rc);
return 0; return 0;
} }

View File

@@ -6,6 +6,7 @@
*/ */
#include <security/tpm/tspi.h> #include <security/tpm/tspi.h>
#include <security/tpm/tss_errors.h>
#include <vb2_api.h> #include <vb2_api.h>
#include "antirollback.h" #include "antirollback.h"
@@ -15,18 +16,18 @@ vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx)
return VB2_SUCCESS; return VB2_SUCCESS;
} }
vb2_error_t antirollback_read_space_firmware(struct vb2_context *ctx) tpm_result_t antirollback_read_space_firmware(struct vb2_context *ctx)
{ {
vb2api_secdata_firmware_create(ctx); vb2api_secdata_firmware_create(ctx);
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_write_space_firmware(struct vb2_context *ctx) tpm_result_t antirollback_write_space_firmware(struct vb2_context *ctx)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_read_space_kernel(struct vb2_context *ctx) tpm_result_t antirollback_read_space_kernel(struct vb2_context *ctx)
{ {
/* /*
* The new kernel secdata v1 stores the last read EC hash, and reboots the * The new kernel secdata v1 stores the last read EC hash, and reboots the
@@ -41,41 +42,41 @@ vb2_error_t antirollback_read_space_kernel(struct vb2_context *ctx)
* v0 device when using MOCK_SECDATA. * v0 device when using MOCK_SECDATA.
*/ */
vb2api_secdata_kernel_create_v0(ctx); vb2api_secdata_kernel_create_v0(ctx);
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_write_space_kernel(struct vb2_context *ctx) tpm_result_t antirollback_write_space_kernel(struct vb2_context *ctx)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_lock_space_firmware(void) tpm_result_t antirollback_lock_space_firmware(void)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_lock_space_mrc_hash(uint32_t index) tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size) tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data,
uint32_t size) uint32_t size)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size) tpm_result_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }
vb2_error_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size) tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
{ {
return VB2_SUCCESS; return TPM_SUCCESS;
} }

View File

@@ -18,17 +18,17 @@
printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args) printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
#define RETURN_ON_FAILURE(tpm_cmd) do { \ #define RETURN_ON_FAILURE(tpm_cmd) do { \
uint32_t rc_; \ tpm_result_t rc_; \
if ((rc_ = (tpm_cmd)) != TPM_SUCCESS) { \ if ((rc_ = (tpm_cmd)) != TPM_SUCCESS) { \
VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \ VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
"\n", (int)rc_); \ "\n", (tpm_result_t)rc_); \
return rc_; \ return rc_; \
} \ } \
} while (0) } while (0)
static uint32_t safe_write(uint32_t index, const void *data, uint32_t length); static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length);
uint32_t antirollback_read_space_kernel(struct vb2_context *ctx) tpm_result_t antirollback_read_space_kernel(struct vb2_context *ctx)
{ {
if (!CONFIG(TPM2)) { if (!CONFIG(TPM2)) {
/* /*
@@ -51,7 +51,7 @@ uint32_t antirollback_read_space_kernel(struct vb2_context *ctx)
} }
uint8_t size = VB2_SECDATA_KERNEL_SIZE; uint8_t size = VB2_SECDATA_KERNEL_SIZE;
uint32_t rc; tpm_result_t rc;
/* Start with the version 1.0 size used by all modern Cr50/Ti50 boards. */ /* Start with the version 1.0 size used by all modern Cr50/Ti50 boards. */
rc = tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel, size); rc = tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel, size);
@@ -72,7 +72,7 @@ uint32_t antirollback_read_space_kernel(struct vb2_context *ctx)
#if CONFIG(TPM2) #if CONFIG(TPM2)
static uint32_t read_space_mrc_hash(uint32_t index, uint8_t *data) static tpm_result_t read_space_mrc_hash(uint32_t index, uint8_t *data)
{ {
RETURN_ON_FAILURE(tlcl_read(index, data, RETURN_ON_FAILURE(tlcl_read(index, data,
HASH_NV_SIZE)); HASH_NV_SIZE));
@@ -206,7 +206,7 @@ static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
const TPMA_NV nv_attributes, const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size) const uint8_t *nv_policy, size_t nv_policy_size)
{ {
uint32_t rc; tpm_result_t rc;
rc = tlcl_define_space(index, length, nv_attributes, nv_policy, rc = tlcl_define_space(index, length, nv_attributes, nv_policy,
nv_policy_size); nv_policy_size);
@@ -227,16 +227,16 @@ static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
} }
/* Nothing special in the TPM2 path yet. */ /* Nothing special in the TPM2 path yet. */
static uint32_t safe_write(uint32_t index, const void *data, uint32_t length) static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length)
{ {
return tlcl_write(index, data, length); return tlcl_write(index, data, length);
} }
static uint32_t setup_space(const char *name, uint32_t index, const void *data, static tpm_result_t setup_space(const char *name, uint32_t index, const void *data,
uint32_t length, const TPMA_NV nv_attributes, uint32_t length, const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size) const uint8_t *nv_policy, size_t nv_policy_size)
{ {
uint32_t rc; tpm_result_t rc;
rc = define_space(name, index, length, nv_attributes, nv_policy, rc = define_space(name, index, length, nv_attributes, nv_policy,
nv_policy_size); nv_policy_size);
@@ -246,7 +246,7 @@ static uint32_t setup_space(const char *name, uint32_t index, const void *data,
return safe_write(index, data, length); return safe_write(index, data, length);
} }
static uint32_t setup_firmware_space(struct vb2_context *ctx) static tpm_result_t setup_firmware_space(struct vb2_context *ctx)
{ {
uint32_t firmware_space_size = vb2api_secdata_firmware_create(ctx); uint32_t firmware_space_size = vb2api_secdata_firmware_create(ctx);
@@ -256,7 +256,7 @@ static uint32_t setup_firmware_space(struct vb2_context *ctx)
sizeof(pcr0_allowed_policy)); sizeof(pcr0_allowed_policy));
} }
static uint32_t setup_fwmp_space(struct vb2_context *ctx) static tpm_result_t setup_fwmp_space(struct vb2_context *ctx)
{ {
uint32_t fwmp_space_size = vb2api_secdata_fwmp_create(ctx); uint32_t fwmp_space_size = vb2api_secdata_fwmp_create(ctx);
@@ -264,7 +264,7 @@ static uint32_t setup_fwmp_space(struct vb2_context *ctx)
fwmp_attr, NULL, 0); fwmp_attr, NULL, 0);
} }
static uint32_t setup_kernel_space(struct vb2_context *ctx) static tpm_result_t setup_kernel_space(struct vb2_context *ctx)
{ {
uint32_t kernel_space_size = vb2api_secdata_kernel_create(ctx); uint32_t kernel_space_size = vb2api_secdata_kernel_create(ctx);
@@ -272,7 +272,7 @@ static uint32_t setup_kernel_space(struct vb2_context *ctx)
kernel_space_size, rw_space_attributes, NULL, 0); kernel_space_size, rw_space_attributes, NULL, 0);
} }
static uint32_t set_mrc_hash_space(uint32_t index, const uint8_t *data) static tpm_result_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
{ {
if (index == MRC_REC_HASH_NV_INDEX) { if (index == MRC_REC_HASH_NV_INDEX) {
return setup_space("RO MRC Hash", index, data, HASH_NV_SIZE, return setup_space("RO MRC Hash", index, data, HASH_NV_SIZE,
@@ -289,9 +289,9 @@ static uint32_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
* *
* These spaces are not used by firmware, but we do need to initialize them. * These spaces are not used by firmware, but we do need to initialize them.
*/ */
static uint32_t setup_zte_spaces(void) static tpm_result_t setup_zte_spaces(void)
{ {
uint32_t rc; tpm_result_t rc;
uint64_t rma_bytes_counter_default = 0; uint64_t rma_bytes_counter_default = 0;
uint8_t rma_sn_bits_default[16]; uint8_t rma_sn_bits_default[16];
uint8_t board_id_default[12]; uint8_t board_id_default[12];
@@ -307,7 +307,7 @@ static uint32_t setup_zte_spaces(void)
zte_attr, zte_attr,
unsatisfiable_policy, sizeof(unsatisfiable_policy)); unsatisfiable_policy, sizeof(unsatisfiable_policy));
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
VBDEBUG("%s: Failed to set up RMA + SN Bits space\n", __func__); VBDEBUG("%s: Failed to set up RMA + SN Bits space with error %#x\n", __func__, rc);
return rc; return rc;
} }
@@ -316,7 +316,7 @@ static uint32_t setup_zte_spaces(void)
zte_attr, zte_attr,
unsatisfiable_policy, sizeof(unsatisfiable_policy)); unsatisfiable_policy, sizeof(unsatisfiable_policy));
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
VBDEBUG("%s: Failed to set up Board ID space\n", __func__); VBDEBUG("%s: Failed to set up Board ID space with error %#x\n", __func__, rc);
return rc; return rc;
} }
@@ -326,7 +326,7 @@ static uint32_t setup_zte_spaces(void)
zte_rma_bytes_attr, zte_rma_bytes_attr,
unsatisfiable_policy, sizeof(unsatisfiable_policy)); unsatisfiable_policy, sizeof(unsatisfiable_policy));
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
VBDEBUG("%s: Failed to define RMA Bytes space\n", __func__); VBDEBUG("%s: Failed to define RMA Bytes space with error %#x\n", __func__, rc);
return rc; return rc;
} }
@@ -337,8 +337,8 @@ static uint32_t setup_zte_spaces(void)
rc = tlcl_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX, rc = tlcl_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX,
rma_bytes_counter_default); rma_bytes_counter_default);
if (rc != TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
VBDEBUG("%s: Failed to init RMA Bytes counter space\n", VBDEBUG("%s: Failed to init RMA Bytes counter space wit error %#x\n",
__func__); __func__, rc);
return rc; return rc;
} }
@@ -351,7 +351,7 @@ static uint32_t setup_zte_spaces(void)
* This space is not used by firmware but needs to survive owner clear. Thus, it * This space is not used by firmware but needs to survive owner clear. Thus, it
* needs to be created here. * needs to be created here.
*/ */
static uint32_t enterprise_rollback_create_space(void) static tpm_result_t enterprise_rollback_create_space(void)
{ {
uint8_t rollback_space_default[32] = {0}; uint8_t rollback_space_default[32] = {0};
@@ -361,9 +361,10 @@ static uint32_t enterprise_rollback_create_space(void)
unsatisfiable_policy, sizeof(unsatisfiable_policy)); unsatisfiable_policy, sizeof(unsatisfiable_policy));
} }
static uint32_t setup_widevine_counter_spaces(void) static tpm_result_t setup_widevine_counter_spaces(void)
{ {
uint32_t index, rc; uint32_t index;
tpm_result_t rc;
for (index = 0; index < NUM_WIDEVINE_COUNTERS; index++) { for (index = 0; index < NUM_WIDEVINE_COUNTERS; index++) {
rc = define_space(WIDEVINE_COUNTER_NAME, rc = define_space(WIDEVINE_COUNTER_NAME,
@@ -375,10 +376,10 @@ static uint32_t setup_widevine_counter_spaces(void)
if (rc != TPM_SUCCESS) if (rc != TPM_SUCCESS)
return rc; return rc;
} }
return TPM_SUCCESS; return rc;
} }
static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
{ {
RETURN_ON_FAILURE(tlcl_force_clear()); RETURN_ON_FAILURE(tlcl_force_clear());
@@ -428,12 +429,12 @@ static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t antirollback_lock_space_firmware(void) tpm_result_t antirollback_lock_space_firmware(void)
{ {
return tlcl_lock_nv_write(FIRMWARE_NV_INDEX); return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
} }
uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size) tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
{ {
if (size != HASH_NV_SIZE) { if (size != HASH_NV_SIZE) {
VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. " VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
@@ -444,10 +445,10 @@ uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_
return read_space_mrc_hash(index, data); return read_space_mrc_hash(index, data);
} }
uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size) tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size)
{ {
uint8_t spc_data[HASH_NV_SIZE]; uint8_t spc_data[HASH_NV_SIZE];
uint32_t rc; tpm_result_t rc;
if (size != HASH_NV_SIZE) { if (size != HASH_NV_SIZE) {
VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. " VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
@@ -472,18 +473,18 @@ uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data,
return safe_write(index, data, size); return safe_write(index, data, size);
} }
uint32_t antirollback_lock_space_mrc_hash(uint32_t index) tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index)
{ {
return tlcl_lock_nv_write(index); return tlcl_lock_nv_write(index);
} }
static uint32_t read_space_vbios_hash(uint8_t *data) static tpm_result_t read_space_vbios_hash(uint8_t *data)
{ {
RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE)); RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE));
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size) tpm_result_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
{ {
if (size != HASH_NV_SIZE) { if (size != HASH_NV_SIZE) {
VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. " VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
@@ -494,10 +495,10 @@ uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
return read_space_vbios_hash(data); return read_space_vbios_hash(data);
} }
uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size) tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
{ {
uint8_t spc_data[HASH_NV_SIZE]; uint8_t spc_data[HASH_NV_SIZE];
uint32_t rc; tpm_result_t rc;
if (size != HASH_NV_SIZE) { if (size != HASH_NV_SIZE) {
VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. " VBDEBUG("TPM: Incorrect buffer size for hash idx %#x. "
@@ -532,9 +533,9 @@ uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
* This is not expected to happen frequently, but it could happen. * This is not expected to happen frequently, but it could happen.
*/ */
static uint32_t safe_write(uint32_t index, const void *data, uint32_t length) static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length)
{ {
uint32_t rc = tlcl_write(index, data, length); tpm_result_t rc = tlcl_write(index, data, length);
if (rc == TPM_MAXNVWRITES) { if (rc == TPM_MAXNVWRITES) {
RETURN_ON_FAILURE(tpm_clear_and_reenable()); RETURN_ON_FAILURE(tpm_clear_and_reenable());
return tlcl_write(index, data, length); return tlcl_write(index, data, length);
@@ -549,9 +550,9 @@ static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
* writes because we only define spaces once at initialization, but we'd * writes because we only define spaces once at initialization, but we'd
* rather be paranoid about this. * rather be paranoid about this.
*/ */
static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size) static tpm_result_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
{ {
uint32_t rc = tlcl_define_space(index, perm, size); tpm_result_t rc = tlcl_define_space(index, perm, size);
if (rc == TPM_MAXNVWRITES) { if (rc == TPM_MAXNVWRITES) {
RETURN_ON_FAILURE(tpm_clear_and_reenable()); RETURN_ON_FAILURE(tpm_clear_and_reenable());
return tlcl_define_space(index, perm, size); return tlcl_define_space(index, perm, size);
@@ -560,10 +561,10 @@ static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
} }
} }
static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
{ {
TPM_PERMANENT_FLAGS pflags; TPM_PERMANENT_FLAGS pflags;
uint32_t rc; tpm_result_t rc;
vb2api_secdata_firmware_create(ctx); vb2api_secdata_firmware_create(ctx);
vb2api_secdata_kernel_create_v0(ctx); vb2api_secdata_kernel_create_v0(ctx);
@@ -618,7 +619,7 @@ static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t antirollback_lock_space_firmware(void) tpm_result_t antirollback_lock_space_firmware(void)
{ {
return tlcl_set_global_lock(); return tlcl_set_global_lock();
} }
@@ -632,9 +633,9 @@ uint32_t antirollback_lock_space_firmware(void)
* nvLocked bit and ensures the physical presence command is enabled and * nvLocked bit and ensures the physical presence command is enabled and
* locked. * locked.
*/ */
static uint32_t factory_initialize_tpm(struct vb2_context *ctx) static tpm_result_t factory_initialize_tpm(struct vb2_context *ctx)
{ {
uint32_t rc; tpm_result_t rc;
VBDEBUG("TPM: factory initialization\n"); VBDEBUG("TPM: factory initialization\n");
@@ -664,9 +665,9 @@ static uint32_t factory_initialize_tpm(struct vb2_context *ctx)
return TPM_SUCCESS; return TPM_SUCCESS;
} }
uint32_t antirollback_read_space_firmware(struct vb2_context *ctx) tpm_result_t antirollback_read_space_firmware(struct vb2_context *ctx)
{ {
uint32_t rc; tpm_result_t rc;
rc = tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata_firmware, VB2_SECDATA_FIRMWARE_SIZE); rc = tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata_firmware, VB2_SECDATA_FIRMWARE_SIZE);
if (rc == TPM_BADINDEX) { if (rc == TPM_BADINDEX) {
@@ -678,10 +679,10 @@ uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
return TPM_CB_CORRUPTED_STATE; return TPM_CB_CORRUPTED_STATE;
} }
return TPM_SUCCESS; return rc;
} }
uint32_t antirollback_write_space_firmware(struct vb2_context *ctx) tpm_result_t antirollback_write_space_firmware(struct vb2_context *ctx)
{ {
if (CONFIG(TPM_GOOGLE_IMMEDIATELY_COMMIT_FW_SECDATA)) if (CONFIG(TPM_GOOGLE_IMMEDIATELY_COMMIT_FW_SECDATA))
tlcl_cr50_enable_nvcommits(); tlcl_cr50_enable_nvcommits();
@@ -689,7 +690,7 @@ uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
VB2_SECDATA_FIRMWARE_SIZE); VB2_SECDATA_FIRMWARE_SIZE);
} }
uint32_t antirollback_write_space_kernel(struct vb2_context *ctx) tpm_result_t antirollback_write_space_kernel(struct vb2_context *ctx)
{ {
/* Learn the expected size. */ /* Learn the expected size. */
uint8_t size = VB2_SECDATA_KERNEL_MIN_SIZE; uint8_t size = VB2_SECDATA_KERNEL_MIN_SIZE;
@@ -710,10 +711,6 @@ uint32_t antirollback_write_space_kernel(struct vb2_context *ctx)
vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx) vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx)
{ {
uint32_t rc;
printk(BIOS_INFO, "Clearing TPM owner\n"); printk(BIOS_INFO, "Clearing TPM owner\n");
rc = tpm_clear_and_reenable(); return tpm_clear_and_reenable() == TPM_SUCCESS ? VB2_SUCCESS : VB2_ERROR_EX_TPM_CLEAR_OWNER;
if (rc)
return VB2_ERROR_EX_TPM_CLEAR_OWNER;
return VB2_SUCCESS;
} }

View File

@@ -2,6 +2,7 @@
#include <security/tpm/tspi.h> #include <security/tpm/tspi.h>
#include <security/vboot/tpm_common.h> #include <security/vboot/tpm_common.h>
#include <security/tpm/tss_errors.h>
#include <vb2_api.h> #include <vb2_api.h>
#include <vb2_sha.h> #include <vb2_sha.h>
@@ -9,9 +10,9 @@
#define TPM_PCR_GBB_HWID_NAME "VBOOT: GBB HWID" #define TPM_PCR_GBB_HWID_NAME "VBOOT: GBB HWID"
#define TPM_PCR_MINIMUM_DIGEST_SIZE 20 #define TPM_PCR_MINIMUM_DIGEST_SIZE 20
uint32_t vboot_setup_tpm(struct vb2_context *ctx) tpm_result_t vboot_setup_tpm(struct vb2_context *ctx)
{ {
uint32_t rc; tpm_result_t rc;
rc = tpm_setup(ctx->flags & VB2_CONTEXT_S3_RESUME); rc = tpm_setup(ctx->flags & VB2_CONTEXT_S3_RESUME);
if (rc == TPM_CB_MUST_REBOOT) if (rc == TPM_CB_MUST_REBOOT)
@@ -20,16 +21,14 @@ uint32_t vboot_setup_tpm(struct vb2_context *ctx)
return rc; return rc;
} }
vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr, tpm_result_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
enum vb2_pcr_digest which_digest) enum vb2_pcr_digest which_digest)
{ {
uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE]; uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
uint32_t size = sizeof(buffer); uint32_t size = sizeof(buffer);
vb2_error_t rv;
rv = vb2api_get_pcr_digest(ctx, which_digest, buffer, &size); if (vb2api_get_pcr_digest(ctx, which_digest, buffer, &size) != VB2_SUCCESS)
if (rv != VB2_SUCCESS) return TPM_CB_FAIL;
return rv;
/* /*
* On TPM 1.2, all PCRs are intended for use with SHA1. We truncate our * On TPM 1.2, all PCRs are intended for use with SHA1. We truncate our
@@ -56,6 +55,6 @@ vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo), return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
TPM_PCR_GBB_HWID_NAME); TPM_PCR_GBB_HWID_NAME);
default: default:
return VB2_ERROR_UNKNOWN; return TPM_CB_FAIL;
} }
} }

View File

@@ -3,16 +3,16 @@
#if CONFIG(TPM) #if CONFIG(TPM)
/* Start of the root of trust */ /* Start of the root of trust */
uint32_t vboot_setup_tpm(struct vb2_context *ctx); tpm_result_t vboot_setup_tpm(struct vb2_context *ctx);
/* vboot_extend_pcr function for vb2 context */ /* vboot_extend_pcr function for vb2 context */
vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr, tpm_result_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
enum vb2_pcr_digest which_digest); enum vb2_pcr_digest which_digest);
#else #else
#define vboot_setup_tpm(ctx) 0 #define vboot_setup_tpm(ctx) TPM_SUCCESS
#define vboot_extend_pcr(ctx, pcr, which_digest) 0 #define vboot_extend_pcr(ctx, pcr, which_digest) TPM_SUCCESS
#endif #endif

View File

@@ -12,10 +12,12 @@
void vbios_cache_update_hash(const uint8_t *data, size_t size) void vbios_cache_update_hash(const uint8_t *data, size_t size)
{ {
struct vb2_hash hash; struct vb2_hash hash;
tpm_result_t rc = TPM_SUCCESS;
/* Initialize TPM driver. */ /* Initialize TPM driver. */
if (tlcl_lib_init() != VB2_SUCCESS) { rc = tlcl_lib_init();
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed.\n"); if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed with error %#x.\n", rc);
return; return;
} }
@@ -35,9 +37,9 @@ void vbios_cache_update_hash(const uint8_t *data, size_t size)
} }
/* Write hash of data to TPM space. */ /* Write hash of data to TPM space. */
if (antirollback_write_space_vbios_hash(hash.sha256, sizeof(hash.sha256)) rc = antirollback_write_space_vbios_hash(hash.sha256, sizeof(hash.sha256));
!= TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "VBIOS_CACHE: Could not save hash to TPM.\n"); printk(BIOS_ERR, "VBIOS_CACHE: Could not save hash to TPM with error %#x.\n", rc);
return; return;
} }
@@ -48,17 +50,19 @@ void vbios_cache_update_hash(const uint8_t *data, size_t size)
enum cb_err vbios_cache_verify_hash(const uint8_t *data, size_t size) enum cb_err vbios_cache_verify_hash(const uint8_t *data, size_t size)
{ {
struct vb2_hash tpm_hash = { .algo = VB2_HASH_SHA256 }; struct vb2_hash tpm_hash = { .algo = VB2_HASH_SHA256 };
tpm_result_t rc = TPM_SUCCESS;
/* Initialize TPM driver. */ /* Initialize TPM driver. */
if (tlcl_lib_init() != VB2_SUCCESS) { rc = tlcl_lib_init();
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed.\n"); if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed with error %#x.\n", rc);
return CB_ERR; return CB_ERR;
} }
/* Read hash of VBIOS data saved in TPM. */ /* Read hash of VBIOS data saved in TPM. */
if (antirollback_read_space_vbios_hash(tpm_hash.sha256, sizeof(tpm_hash.sha256)) rc = antirollback_read_space_vbios_hash(tpm_hash.sha256, sizeof(tpm_hash.sha256));
!= TPM_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "VBIOS_CACHE: Could not read hash from TPM.\n"); printk(BIOS_ERR, "VBIOS_CACHE: Could not read hash from TPM with error %#x.\n", rc);
return CB_ERR; return CB_ERR;
} }

View File

@@ -2,6 +2,7 @@
#include <console/cbmem_console.h> #include <console/cbmem_console.h>
#include <reset.h> #include <reset.h>
#include <security/tpm/tss_errors.h>
#include <security/vboot/misc.h> #include <security/vboot/misc.h>
#include <security/vboot/vboot_common.h> #include <security/vboot/vboot_common.h>
#include <security/vboot/vbnv.h> #include <security/vboot/vbnv.h>
@@ -12,14 +13,14 @@
static void save_secdata(struct vb2_context *ctx) static void save_secdata(struct vb2_context *ctx)
{ {
if (ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED if (ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED
&& (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == VB2_SUCCESS)) { && (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == TPM_SUCCESS)) {
printk(BIOS_INFO, "Saving secdata firmware\n"); printk(BIOS_INFO, "Saving secdata firmware\n");
antirollback_write_space_firmware(ctx); antirollback_write_space_firmware(ctx);
ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED; ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
} }
if (ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED if (ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED
&& (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == VB2_SUCCESS)) { && (CONFIG(VBOOT_MOCK_SECDATA) || tlcl_lib_init() == TPM_SUCCESS)) {
printk(BIOS_INFO, "Saving secdata kernel\n"); printk(BIOS_INFO, "Saving secdata kernel\n");
antirollback_write_space_kernel(ctx); antirollback_write_space_kernel(ctx);
ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED; ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED;

View File

@@ -7,6 +7,7 @@
#include <fmap.h> #include <fmap.h>
#include <security/tpm/tspi/crtm.h> #include <security/tpm/tspi/crtm.h>
#include <security/tpm/tss/vendor/cr50/cr50.h> #include <security/tpm/tss/vendor/cr50/cr50.h>
#include <security/tpm/tss_errors.h>
#include <security/vboot/misc.h> #include <security/vboot/misc.h>
#include <security/vboot/vbnv.h> #include <security/vboot/vbnv.h>
#include <security/vboot/tpm_common.h> #include <security/vboot/tpm_common.h>
@@ -182,12 +183,12 @@ static vb2_error_t hash_body(struct vb2_context *ctx,
return handle_digest_result(hash_digest, hash_digest_sz); return handle_digest_result(hash_digest, hash_digest_sz);
} }
static vb2_error_t extend_pcrs(struct vb2_context *ctx) static tpm_result_t extend_pcrs(struct vb2_context *ctx)
{ {
vb2_error_t rv; tpm_result_t rc;
rv = vboot_extend_pcr(ctx, CONFIG_PCR_BOOT_MODE, BOOT_MODE_PCR); rc = vboot_extend_pcr(ctx, CONFIG_PCR_BOOT_MODE, BOOT_MODE_PCR);
if (rv) if (rc)
return rv; return rc;
return vboot_extend_pcr(ctx, CONFIG_PCR_HWID, HWID_DIGEST_PCR); return vboot_extend_pcr(ctx, CONFIG_PCR_HWID, HWID_DIGEST_PCR);
} }
@@ -210,7 +211,7 @@ static const char *get_boot_mode_string(uint8_t boot_mode)
static void check_boot_mode(struct vb2_context *ctx) static void check_boot_mode(struct vb2_context *ctx)
{ {
uint8_t boot_mode; uint8_t boot_mode;
int rc; tpm_result_t rc;
rc = tlcl_cr50_get_boot_mode(&boot_mode); rc = tlcl_cr50_get_boot_mode(&boot_mode);
switch (rc) { switch (rc) {
@@ -222,7 +223,7 @@ static void check_boot_mode(struct vb2_context *ctx)
break; break;
default: default:
printk(BIOS_ERR, printk(BIOS_ERR,
"Communication error in getting GSC boot mode.\n"); "Communication error(%#x) in getting GSC boot mode.\n", rc);
vb2api_fail(ctx, VB2_RECOVERY_GSC_BOOT_MODE, rc); vb2api_fail(ctx, VB2_RECOVERY_GSC_BOOT_MODE, rc);
return; return;
} }
@@ -240,6 +241,7 @@ static void check_boot_mode(struct vb2_context *ctx)
void verstage_main(void) void verstage_main(void)
{ {
struct vb2_context *ctx; struct vb2_context *ctx;
tpm_result_t tpm_rc;
vb2_error_t rv; vb2_error_t rv;
timestamp_add_now(TS_VBOOT_START); timestamp_add_now(TS_VBOOT_START);
@@ -363,10 +365,13 @@ void verstage_main(void)
/* Only extend PCRs once on boot. */ /* Only extend PCRs once on boot. */
if (!(ctx->flags & VB2_CONTEXT_S3_RESUME)) { if (!(ctx->flags & VB2_CONTEXT_S3_RESUME)) {
timestamp_add_now(TS_TPMPCR_START); timestamp_add_now(TS_TPMPCR_START);
rv = extend_pcrs(ctx); tpm_rc = extend_pcrs(ctx);
if (rv) { if (tpm_rc) {
printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv); printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n",
vboot_fail_and_reboot(ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv); tpm_rc);
vboot_fail_and_reboot(ctx,
VB2_RECOVERY_RO_TPM_U_ERROR,
tpm_rc);
} }
timestamp_add_now(TS_TPMPCR_END); timestamp_add_now(TS_TPMPCR_END);
} }
@@ -374,19 +379,21 @@ void verstage_main(void)
/* Lock TPM */ /* Lock TPM */
timestamp_add_now(TS_TPMLOCK_START); timestamp_add_now(TS_TPMLOCK_START);
rv = antirollback_lock_space_firmware(); tpm_rc = antirollback_lock_space_firmware();
if (rv) { if (tpm_rc) {
printk(BIOS_INFO, "Failed to lock TPM (%#x)\n", rv); printk(BIOS_INFO, "Failed to lock TPM (%#x)\n", tpm_rc);
vboot_fail_and_reboot(ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0); vboot_fail_and_reboot(ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
} }
timestamp_add_now(TS_TPMLOCK_END); timestamp_add_now(TS_TPMLOCK_END);
/* Lock rec hash space if available. */ /* Lock rec hash space if available. */
if (CONFIG(VBOOT_HAS_REC_HASH_SPACE)) { if (CONFIG(VBOOT_HAS_REC_HASH_SPACE)) {
rv = antirollback_lock_space_mrc_hash(MRC_REC_HASH_NV_INDEX); tpm_rc = antirollback_lock_space_mrc_hash(
if (rv) { MRC_REC_HASH_NV_INDEX);
printk(BIOS_INFO, "Failed to lock rec hash space(%#x)\n", rv); if (tpm_rc) {
vboot_fail_and_reboot(ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR, rv); printk(BIOS_INFO, "Failed to lock rec hash space(%#x)\n",
tpm_rc);
vboot_fail_and_reboot(ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR, tpm_rc);
} }
} }

View File

@@ -208,7 +208,7 @@ static uint32_t save_buffers(void)
*/ */
static void psp_verstage_s0i3_resume(void) static void psp_verstage_s0i3_resume(void)
{ {
uint32_t rc; tpm_result_t rc;
post_code(POSTCODE_VERSTAGE_S0I3_RESUME); post_code(POSTCODE_VERSTAGE_S0I3_RESUME);

View File

@@ -13,7 +13,7 @@
*/ */
EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void) EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void)
{ {
int rc; tpm_result_t rc;
TPML_PCR_SELECTION Pcrs; TPML_PCR_SELECTION Pcrs;
EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap = 0; EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap = 0;
uint32_t activePcrBanks = 0; uint32_t activePcrBanks = 0;
@@ -75,10 +75,10 @@ EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void)
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR The command was unsuccessful. * @retval TPM_IOERROR The command was unsuccessful.
*/ */
int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs) tpm_result_t tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs)
{ {
TPMS_CAPABILITY_DATA TpmCap; TPMS_CAPABILITY_DATA TpmCap;
int rc; tpm_result_t rc;
int index; int index;
rc = tlcl_get_capability(TPM_CAP_PCRS, 0, 1, &TpmCap); rc = tlcl_get_capability(TPM_CAP_PCRS, 0, 1, &TpmCap);
@@ -115,7 +115,7 @@ int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs)
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
*/ */
int mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLen, tpm_result_t mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLen,
TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog) TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog)
{ {
TPMT_HA *digest = NULL; TPMT_HA *digest = NULL;
@@ -149,7 +149,7 @@ int mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLe
void invalidate_pcrs(void) void invalidate_pcrs(void)
{ {
int pcr; int pcr;
int rc; tpm_result_t rc;
TCG_PCR_EVENT2_HDR tcgEventHdr; TCG_PCR_EVENT2_HDR tcgEventHdr;
uint8_t invalidate = 1; uint8_t invalidate = 1;
@@ -227,10 +227,9 @@ void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize)
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
*/ */
int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr, tpm_result_t mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
TCG_EVENTTYPE eventType, const char *event_msg) TCG_EVENTTYPE eventType, const char *event_msg)
{ {
int rc;
TCG_PCR_EVENT2_HDR tcgEventHdr; TCG_PCR_EVENT2_HDR tcgEventHdr;
uint8_t *base; uint8_t *base;
size_t size; size_t size;
@@ -240,7 +239,7 @@ int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
if (base == NULL) { if (base == NULL) {
printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __func__, name); printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __func__, name);
return VB2_ERROR_READ_FILE_OPEN; return TPM_IOERROR;
} }
printk(BIOS_DEBUG, "%s: CBFS locate success: %s\n", __func__, name); printk(BIOS_DEBUG, "%s: CBFS locate success: %s\n", __func__, name);
@@ -250,8 +249,7 @@ int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
if (event_msg) if (event_msg)
tcgEventHdr.eventSize = (uint32_t) strlen(event_msg); tcgEventHdr.eventSize = (uint32_t) strlen(event_msg);
rc = mboot_hash_extend_log(0, base, size, &tcgEventHdr, (uint8_t *)event_msg); return mboot_hash_extend_log(0, base, size, &tcgEventHdr, (uint8_t *)event_msg);
return rc;
} }
/* /*
@@ -271,15 +269,17 @@ int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
**/ **/
__weak int mb_entry(int wake_from_s3) __weak tpm_result_t mb_entry(int wake_from_s3)
{ {
int rc; tpm_result_t rc;
/* Initialize TPM driver. */ /* Initialize TPM driver. */
printk(BIOS_DEBUG, "%s: tlcl_lib_init\n", __func__); printk(BIOS_DEBUG, "%s: tlcl_lib_init\n", __func__);
if (tlcl_lib_init() != VB2_SUCCESS) { rc = tlcl_lib_init();
printk(BIOS_ERR, "%s: TPM driver initialization failed.\n", __func__); if (rc != TPM_SUCCESS) {
return TPM_IOERROR; printk(BIOS_ERR, "%s: TPM driver initialization failed with error %#x.\n",
__func__, rc);
return rc;
} }
if (wake_from_s3) { if (wake_from_s3) {
@@ -315,9 +315,9 @@ __weak int mb_entry(int wake_from_s3)
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
*/ */
__weak int mb_measure(int wake_from_s3) __weak tpm_result_t mb_measure(int wake_from_s3)
{ {
uint32_t rc; tpm_result_t rc;
rc = mb_entry(wake_from_s3); rc = mb_entry(wake_from_s3);
if (rc == TPM_SUCCESS) { if (rc == TPM_SUCCESS) {
@@ -357,9 +357,9 @@ __weak int mb_measure(int wake_from_s3)
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
*/ */
__weak int mb_measure_log_start(void) __weak tpm_result_t mb_measure_log_start(void)
{ {
int rc; tpm_result_t rc;
uint32_t i; uint32_t i;
if ((tpm2_get_active_pcrs() & EFI_TCG2_BOOT_HASH_ALG_SHA256) == 0x0) { if ((tpm2_get_active_pcrs() & EFI_TCG2_BOOT_HASH_ALG_SHA256) == 0x0) {
@@ -369,9 +369,9 @@ __weak int mb_measure_log_start(void)
} }
rc = mb_crtm(); rc = mb_crtm();
if (rc != TPM_SUCCESS) { if (rc) {
printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured." printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured."
" ABORTING!!!\n", __func__); " Received error %#x, ABORTING!!!\n", __func__, rc);
return rc; return rc;
} }
printk(BIOS_DEBUG, "%s: Success! CRTM Version measured.\n", __func__); printk(BIOS_DEBUG, "%s: Success! CRTM Version measured.\n", __func__);
@@ -414,9 +414,9 @@ static const uint8_t crtm_version[] =
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
**/ **/
__weak int mb_crtm(void) __weak tpm_result_t mb_crtm(void)
{ {
int rc; tpm_result_t rc;
TCG_PCR_EVENT2_HDR tcgEventHdr; TCG_PCR_EVENT2_HDR tcgEventHdr;
uint8_t hash[VB2_SHA256_DIGEST_SIZE]; uint8_t hash[VB2_SHA256_DIGEST_SIZE];
uint8_t *msgPtr; uint8_t *msgPtr;

View File

@@ -76,12 +76,12 @@ typedef uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP;
int is_zero_buffer(void *buffer, unsigned int size); int is_zero_buffer(void *buffer, unsigned int size);
int mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLen, tpm_result_t mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLen,
TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog); TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog);
void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize); void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize);
int mb_crtm(void); tpm_result_t mb_crtm(void);
typedef struct { typedef struct {
const char *cbfs_name; const char *cbfs_name;
@@ -91,18 +91,18 @@ typedef struct {
const char *event_msg; const char *event_msg;
} mboot_measure_item_t; } mboot_measure_item_t;
int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr, tpm_result_t mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
TCG_EVENTTYPE eventType, const char *event_msg); TCG_EVENTTYPE eventType, const char *event_msg);
int mb_measure_log_start(void); tpm_result_t mb_measure_log_start(void);
void invalidate_pcrs(void); void invalidate_pcrs(void);
EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void); EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void);
int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs); tpm_result_t tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs);
int mb_measure(int wake_from_s3); tpm_result_t mb_measure(int wake_from_s3);
int mb_entry(int wake_from_s3); tpm_result_t mb_entry(int wake_from_s3);
int log_efi_specid_event(void); int log_efi_specid_event(void);
int log_event_tcg_20_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog); int log_event_tcg_20_format(TCG_PCR_EVENT2_HDR *EventHdr, uint8_t *EventLog);

View File

@@ -5,6 +5,7 @@
#include <bootmode.h> #include <bootmode.h>
#include <cbfs.h> #include <cbfs.h>
#include <fmap_config.h> #include <fmap_config.h>
#include <security/tpm/tss_errors.h>
#include <vboot_check.h> #include <vboot_check.h>
#include <vboot_common.h> #include <vboot_common.h>
#include <vb2_internals_please_do_not_use.h> #include <vb2_internals_please_do_not_use.h>
@@ -115,24 +116,24 @@ fail:
* @retval TPM_SUCCESS Operation completed successfully. * @retval TPM_SUCCESS Operation completed successfully.
* @retval TPM_IOERROR Unexpected device behavior. * @retval TPM_IOERROR Unexpected device behavior.
*/ */
static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen, static tpm_result_t measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
int8_t *event_msg, TCG_EVENTTYPE eventType) int8_t *event_msg, TCG_EVENTTYPE eventType)
{ {
int status = TPM_SUCCESS; tpm_result_t rc = TPM_SUCCESS;
TCG_PCR_EVENT2_HDR tcgEventHdr; TCG_PCR_EVENT2_HDR tcgEventHdr;
memset(&tcgEventHdr, 0, sizeof(tcgEventHdr)); memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
tcgEventHdr.pcrIndex = pcr; tcgEventHdr.pcrIndex = pcr;
tcgEventHdr.eventType = eventType; tcgEventHdr.eventType = eventType;
if (event_msg) { if (event_msg) {
status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData, rc = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
hashDataLen, &tcgEventHdr, hashDataLen, &tcgEventHdr,
(uint8_t *)event_msg); (uint8_t *)event_msg);
if (status == TPM_SUCCESS) if (rc == TPM_SUCCESS)
printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__, printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
event_msg, pcr); event_msg, pcr);
} }
return status; return rc;
} }
static void verified_boot_check_buffer(const char *name, void *start, size_t size, static void verified_boot_check_buffer(const char *name, void *start, size_t size,
@@ -140,6 +141,7 @@ static void verified_boot_check_buffer(const char *name, void *start, size_t siz
{ {
uint8_t digest[DIGEST_SIZE]; uint8_t digest[DIGEST_SIZE];
vb2_error_t status; vb2_error_t status;
tpm_result_t rc = TPM_SUCCESS;
printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name, printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
start, (int)size); start, (int)size);
@@ -166,10 +168,11 @@ static void verified_boot_check_buffer(const char *name, void *start, size_t siz
if (pcr != -1) { if (pcr != -1) {
printk(BIOS_DEBUG, "%s: measuring %s\n", __func__, printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
name); name);
if (measure_item(pcr, digest, sizeof(digest), rc = measure_item(pcr, digest, sizeof(digest),
(int8_t *)name, 0)) (int8_t *)name, 0);
printk(BIOS_DEBUG, "%s: measuring failed!\n", if (rc)
__func__); printk(BIOS_DEBUG, "%s: measuring failed with error %#x!\n",
__func__, rc);
} }
} }
if (CONFIG(VENDORCODE_ELTAN_VBOOT)) if (CONFIG(VENDORCODE_ELTAN_VBOOT))

View File

@@ -25,7 +25,7 @@ void __weak mainboard_prepare_cr50_reset(void) {}
*/ */
static int cr50_is_reset_needed(void) static int cr50_is_reset_needed(void)
{ {
int rc; tpm_result_t rc;
uint8_t tpm_mode; uint8_t tpm_mode;
rc = tlcl_cr50_get_tpm_mode(&tpm_mode); rc = tlcl_cr50_get_tpm_mode(&tpm_mode);
@@ -70,7 +70,7 @@ static int cr50_is_reset_needed(void)
static void enable_update(void *unused) static void enable_update(void *unused)
{ {
int rc; tpm_result_t rc;
int cr50_reset_reqd = 0; int cr50_reset_reqd = 0;
uint8_t num_restored_headers; uint8_t num_restored_headers;
@@ -84,7 +84,7 @@ static void enable_update(void *unused)
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed for CR50 update: %#x\n", printk(BIOS_ERR, "tlcl_lib_init() failed for CR50 update: %#x\n",
rc); rc);
return; return;

View File

@@ -13,7 +13,7 @@
void cse_board_reset(void) void cse_board_reset(void)
{ {
int rc; tpm_result_t rc;
struct cr50_firmware_version version; struct cr50_firmware_version version;
if (CONFIG(CSE_RESET_CLEAR_EC_AP_IDLE_FLAG)) if (CONFIG(CSE_RESET_CLEAR_EC_AP_IDLE_FLAG))
@@ -22,7 +22,7 @@ void cse_board_reset(void)
if (CONFIG(TPM2) && CONFIG(TPM_GOOGLE_CR50)) { if (CONFIG(TPM2) && CONFIG(TPM_GOOGLE_CR50)) {
/* Initialize TPM and get the cr50 firmware version. */ /* Initialize TPM and get the cr50 firmware version. */
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc);
return; return;
} }

View File

@@ -7,7 +7,7 @@
static void disable_platform_hierarchy(void *unused) static void disable_platform_hierarchy(void *unused)
{ {
int rc; tpm_result_t rc;
if (!CONFIG(TPM2)) if (!CONFIG(TPM2))
return; return;
@@ -17,7 +17,7 @@ static void disable_platform_hierarchy(void *unused)
rc = tlcl_lib_init(); rc = tlcl_lib_init();
if (rc != VB2_SUCCESS) { if (rc != TPM_SUCCESS) {
printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc);
return; return;
} }