summaryrefslogtreecommitdiff
path: root/src/lib/tpm2_marshaling.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-03-22 16:01:53 -0700
committerVadim Bendebury <vbendeb@chromium.org>2017-03-23 23:49:58 +0100
commit021ec2819b2200eabbaca5b6873f7024c2bd9434 (patch)
tree2c4b65ed7901b30495d373961b208dfedb8e3842 /src/lib/tpm2_marshaling.c
parentc5168832cd5e8a052e835cbbfa702f0d5649a98c (diff)
cr50: add unmarshaling of vendor commands and process 'enable_update'
The upcoming Cr50 firmware changes will require the AP to enable the previously downloaded Cr50 firmware update(s). A new vendor command (TPM2_CR50_SUB_CMD_TURN_UPDATE_ON) is used for that. The command accepts one parameter - a timeout value in range of 0 to 1000 ms. When processing the command the Cr50 checks if the alternative RO or RW image(s) need to be enabled, and if so - enables them and returns to the host the number of enabled headers. If the vendor command requested a non-zero timeout, the Cr50 starts a timer to trigger system reboot after the requested timeout expires. The host acts on the number of enabled headers - if the number is nonzero, the host prepares the device to be reset and waits for the Cr50 to reboot the device after timeout expires. This patch also adds more formal vendor command marshaling/unmarshaling to make future additions easier. BRANCH=gru,reef BUG=b:35580805 TEST=with the actual user of this code in the next patch verified that the cr50 update is enabled as expected. Change-Id: Ic76d384d637c0eeaad206e0a8242cbb8e2b19b37 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://review.coreboot.org/18945 Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/lib/tpm2_marshaling.c')
-rw-r--r--src/lib/tpm2_marshaling.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/lib/tpm2_marshaling.c b/src/lib/tpm2_marshaling.c
index 6d4d622d91..52dac9c553 100644
--- a/src/lib/tpm2_marshaling.c
+++ b/src/lib/tpm2_marshaling.c
@@ -394,20 +394,16 @@ 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;
+ case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
+ marshal_u16(buffer, sub_command[0], buffer_space);
+ marshal_u16(buffer, sub_command[1], buffer_space);
+ break;
default:
/* Unsupported subcommand. */
printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
@@ -596,6 +592,25 @@ static void unmarshal_nv_read(void **buffer, int *size,
*size = 0;
}
+static void unmarshal_vendor_command(void **buffer, int *size,
+ struct vendor_command_response *vcr)
+{
+ vcr->vc_subcommand = unmarshal_u16(buffer, size);
+
+ switch (vcr->vc_subcommand) {
+ case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
+ break;
+ case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
+ vcr->num_restored_headers = unmarshal_u8(buffer, size);
+ break;
+ default:
+ printk(BIOS_ERR,
+ "%s:%d - unsupported vendor command %#04x!\n",
+ __func__, __LINE__, vcr->vc_subcommand);
+ break;
+ }
+}
+
struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
void *response_body,
size_t in_size)
@@ -648,8 +663,8 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
break;
case TPM2_CR50_VENDOR_COMMAND:
- /* Assume no other data returned for the time being. */
- cr_size = 0;
+ unmarshal_vendor_command(&response_body, &cr_size,
+ &tpm2_resp->vcr);
break;
default: