security/tpm: Retrieve factory configuration for device w/ Google TPM
This patch enables retrieval of factory configuration data from Google TPM devices (both Cr50 and Ti50). This patch utilizes vendor-specific command TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG (68). The factory config space is a 64-bit, one-time programmable. For the unprovisioned one, the read will be 0x0. BUG=b:317880956 TEST=Able to retrieve the factory config from google/screebo. Change-Id: Ifd0e850770152a03aa46d7f8bbb76f7520a59081 Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/79736 Reviewed-by: Kapil Porwal <kapilporwal@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
acf10d6096
commit
0f90c5d5f9
|
@ -348,6 +348,9 @@ static int marshal_cr50_vendor_command(struct obuf *ob, const void *command_body
|
|||
case TPM2_CR50_SUB_CMD_RESET_EC:
|
||||
rc |= obuf_write_be16(ob, *sub_command);
|
||||
break;
|
||||
case TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG:
|
||||
rc |= obuf_write_be16(ob, *sub_command);
|
||||
break;
|
||||
default:
|
||||
/* Unsupported subcommand. */
|
||||
printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
|
||||
|
@ -581,6 +584,8 @@ static int unmarshal_vendor_command(struct ibuf *ib,
|
|||
return ibuf_read_be8(ib, &vcr->boot_mode);
|
||||
case TPM2_CR50_SUB_CMD_RESET_EC:
|
||||
break;
|
||||
case TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG:
|
||||
return ibuf_read_be64(ib, &vcr->factory_config);
|
||||
default:
|
||||
printk(BIOS_ERR,
|
||||
"%s:%d - unsupported vendor command %#04x!\n",
|
||||
|
|
|
@ -352,6 +352,11 @@ struct vendor_command_response {
|
|||
uint8_t recovery_button_state;
|
||||
uint8_t tpm_mode;
|
||||
uint8_t boot_mode;
|
||||
/*
|
||||
* bits 63..8 : reserved
|
||||
* bits 7..0 : factory config
|
||||
*/
|
||||
uint64_t factory_config;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -176,3 +176,31 @@ tpm_result_t tlcl_cr50_reset_ec(void)
|
|||
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
tpm_result_t tlcl_cr50_get_factory_config(uint64_t *factory_config)
|
||||
{
|
||||
struct tpm2_response *response;
|
||||
uint16_t factory_config_command = TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG;
|
||||
*factory_config = 0;
|
||||
|
||||
response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &factory_config_command);
|
||||
|
||||
if (!response)
|
||||
return TPM_IOERROR;
|
||||
|
||||
/* Explicitly inform caller when command is not supported */
|
||||
if (response->hdr.tpm_code == VENDOR_RC_NO_SUCH_COMMAND ||
|
||||
response->hdr.tpm_code == VENDOR_RC_NO_SUCH_SUBCOMMAND)
|
||||
return TPM_CB_NO_SUCH_COMMAND;
|
||||
|
||||
/* Unexpected return code from TPM */
|
||||
if (response->hdr.tpm_code)
|
||||
return TPM_IOERROR;
|
||||
|
||||
/* TPM command completed without error */
|
||||
*factory_config = response->vcr.factory_config;
|
||||
|
||||
printk(BIOS_INFO, "Reading factory config = %016" PRIX64 "\n", *factory_config);
|
||||
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define TPM2_CR50_SUB_CMD_TPM_MODE (40)
|
||||
#define TPM2_CR50_SUB_CMD_GET_BOOT_MODE (52)
|
||||
#define TPM2_CR50_SUB_CMD_RESET_EC (53)
|
||||
#define TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG (68)
|
||||
|
||||
/* Cr50 vendor-specific error codes. */
|
||||
#define VENDOR_RC_ERR 0x00000500
|
||||
|
@ -105,4 +106,12 @@ tpm_result_t tlcl_cr50_immediate_reset(uint16_t timeout_ms);
|
|||
*/
|
||||
tpm_result_t tlcl_cr50_reset_ec(void);
|
||||
|
||||
/**
|
||||
* TPM command to get the factory config.
|
||||
*
|
||||
* Returns TPM_* for errors.
|
||||
* On Success, TPM_SUCCESS if factory config is successfully retrieved.
|
||||
*/
|
||||
tpm_result_t tlcl_cr50_get_factory_config(uint64_t *factory_config);
|
||||
|
||||
#endif /* CR50_TSS_STRUCTURES_H_ */
|
||||
|
|
Loading…
Reference in New Issue