summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/tpm2_marshaling.c37
-rw-r--r--src/lib/tpm2_tlcl.c20
-rw-r--r--src/lib/tpm2_tlcl_structures.h9
3 files changed, 66 insertions, 0 deletions
diff --git a/src/lib/tpm2_marshaling.c b/src/lib/tpm2_marshaling.c
index dd046d27a1..6d4d622d91 100644
--- a/src/lib/tpm2_marshaling.c
+++ b/src/lib/tpm2_marshaling.c
@@ -390,6 +390,33 @@ static void marshal_hierarchy_control(void **buffer,
marshal_u8(buffer, command_body->state, buffer_space);
}
+static void marshal_cr50_vendor_command(void **buffer, void *command_body,
+ size_t *buffer_space)
+{
+ uint16_t *sub_command;
+
+ /* Ensure at least the sub command can fit in the body and there's
+ valid pointer. Could be reading past the buffer... */
+ if (command_body == NULL || *buffer_space < sizeof(uint16_t)) {
+ *buffer_space = 0;
+ return;
+ }
+
+ sub_command = command_body;
+
+ switch (*sub_command) {
+ case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
+ marshal_u16(buffer, *sub_command, buffer_space);
+ break;
+ default:
+ /* Unsupported subcommand. */
+ printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
+ *sub_command);
+ *buffer_space = 0;
+ break;
+ }
+}
+
int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
void *buffer, size_t buffer_size)
{
@@ -444,6 +471,11 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
marshal_pcr_extend(&cmd_body, tpm_command_body, &body_size);
break;
+ case TPM2_CR50_VENDOR_COMMAND:
+ marshal_cr50_vendor_command(&cmd_body, tpm_command_body,
+ &body_size);
+ break;
+
default:
body_size = 0;
printk(BIOS_INFO, "%s:%d:Request to marshal unsupported command %#x\n",
@@ -615,6 +647,11 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
cr_size = 0;
break;
+ case TPM2_CR50_VENDOR_COMMAND:
+ /* Assume no other data returned for the time being. */
+ cr_size = 0;
+ break;
+
default:
{
int i;
diff --git a/src/lib/tpm2_tlcl.c b/src/lib/tpm2_tlcl.c
index 3d65a95e97..86cc74d425 100644
--- a/src/lib/tpm2_tlcl.c
+++ b/src/lib/tpm2_tlcl.c
@@ -385,3 +385,23 @@ uint32_t tlcl_disable_platform_hierarchy(void)
return TPM_SUCCESS;
}
+
+uint32_t tlcl_cr50_enable_nvcommits(void)
+{
+ uint16_t sub_command = TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS;
+ struct tpm2_response *response;
+
+ printk(BIOS_INFO, "Enabling cr50 nvmem commmits\n");
+
+ response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &sub_command);
+
+ if (response == NULL || (response && response->hdr.tpm_code)) {
+ if (response)
+ printk(BIOS_INFO, "%s: failed %x\n", __func__,
+ response->hdr.tpm_code);
+ else
+ printk(BIOS_INFO, "%s: failed\n", __func__);
+ return TPM_E_IOERROR;
+ }
+ return TPM_SUCCESS;
+}
diff --git a/src/lib/tpm2_tlcl_structures.h b/src/lib/tpm2_tlcl_structures.h
index c5c6d87985..ec5b674701 100644
--- a/src/lib/tpm2_tlcl_structures.h
+++ b/src/lib/tpm2_tlcl_structures.h
@@ -69,6 +69,15 @@ struct tpm_header {
#define TPM2_NV_Read ((TPM_CC)0x0000014E)
#define TPM2_GetCapability ((TPM_CC)0x0000017A)
#define TPM2_PCR_Extend ((TPM_CC)0x00000182)
+/* TPM2 specifies vendor commands need to have this bit set. Vendor command
+ space is defined by the lower 16 bits. */
+#define TPM_CC_VENDOR_BIT_MASK 0x20000000
+/* FIXME: below is not enough to differentiate between vendors commands
+ of numerous devices. However, the current tpm2 APIs aren't very amenable
+ to extending generically because the marshaling code is assuming all
+ knowledge of all commands. */
+#define TPM2_CR50_VENDOR_COMMAND ((TPM_CC)(TPM_CC_VENDOR_BIT_MASK | 0))
+#define TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS (21)
/* Startup values. */
#define TPM_SU_CLEAR 0