summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2021-05-24 16:47:09 -0700
committerJulius Werner <jwerner@chromium.org>2021-06-10 23:38:47 +0000
commit4ad0420e82f46b2d92e318019a89842f28e6c08a (patch)
tree6b73c4df32b712707bdbe79433899adfe06b95c0 /src
parent455e07e7f3f42b2ce866ae6a8f243361a77dd5e5 (diff)
security/tpm/tss/tcg-2.0: Add `tlcl_set_bits()`
This commit adds support for the TPM2_NV_SetBits command to the TLCL. This command is used to set bits in an NV index that was created as a bit field. Any number of bits from 0 to 64 may be set. The contents of bits are ORed with the current contents of the NV index. The following is an excerpt from lalala undergoing TPM factory initialization which exercises this function in a child commit: ``` antirollback_read_space_firmware():566: TPM: Not initialized yet. factory_initialize_tpm():530: TPM: factory initialization tlcl_self_test_full: response is 0 tlcl_force_clear: response is 0 tlcl_define_space: response is 14c define_space():197: define_space: kernel space already exists tlcl_write: response is 0 tlcl_define_space: response is 14c define_space():197: define_space: RO MRC Hash space already exists tlcl_write: response is 0 tlcl_define_space: response is 14c define_space():197: define_space: FWMP space already exists tlcl_write: response is 0 tlcl_define_space: response is 0 tlcl_write: response is 0 tlcl_define_space: response is 0 tlcl_write: response is 0 tlcl_define_space: response is 0 tlcl_set_bits: response is 0 tlcl_define_space: response is 0 tlcl_write: response is 0 factory_initialize_tpm():553: TPM: factory initialization successful ``` BUG=b:184676425 BRANCH=None TEST=With other changes, create a NVMEM space in a TPM 2.0 TPM with the bits attribute. Issue the command and verify that the TPM command succeeds. Signed-off-by: Aseda Aboagye <aaboagye@google.com> Change-Id: I6ca6376bb9f7ed8fd1167c2c80f1e8d3c3f46653 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55241 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Bob Moragues <moragues@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r--src/security/tpm/tss.h3
-rw-r--r--src/security/tpm/tss/tcg-2.0/tss.c23
-rw-r--r--src/security/tpm/tss/tcg-2.0/tss_marshaling.c17
-rw-r--r--src/security/tpm/tss/tcg-2.0/tss_structures.h6
4 files changed, 49 insertions, 0 deletions
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h
index 4a8206d056..f68e1f47ba 100644
--- a/src/security/tpm/tss.h
+++ b/src/security/tpm/tss.h
@@ -68,6 +68,9 @@ uint32_t tlcl_get_capability(TPM_CAP capability, uint32_t property,
uint32_t property_count,
TPMS_CAPABILITY_DATA *capability_data);
+/* Issue TPM2_NV_SetBits command */
+uint32_t tlcl_set_bits(uint32_t index, uint64_t bits);
+
/*
* Makes tpm_process_command available for on top implementations of
* custom tpm standards like cr50
diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c
index 79d8eb91b4..f464fe19e7 100644
--- a/src/security/tpm/tss/tcg-2.0/tss.c
+++ b/src/security/tpm/tss/tcg-2.0/tss.c
@@ -317,6 +317,29 @@ uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length)
return TPM_SUCCESS;
}
+uint32_t tlcl_set_bits(uint32_t index, uint64_t bits)
+{
+ struct tpm2_nv_setbits_cmd nvsb_cmd;
+ struct tpm2_response *response;
+
+ /* Prepare the command structure */
+ memset(&nvsb_cmd, 0, sizeof(nvsb_cmd));
+
+ nvsb_cmd.nvIndex = HR_NV_INDEX + index;
+ nvsb_cmd.bits = bits;
+
+ response = tpm_process_command(TPM2_NV_SetBits, &nvsb_cmd);
+
+ printk(BIOS_INFO, "%s: response is %x\n",
+ __func__, response ? response->hdr.tpm_code : -1);
+
+ /* Need to map tpm error codes into internal values. */
+ if (!response || response->hdr.tpm_code)
+ return TPM_E_WRITE_FAILURE;
+
+ return TPM_SUCCESS;
+}
+
uint32_t tlcl_define_space(uint32_t space_index, size_t space_size,
const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size)
diff --git a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
index f21fe3d315..83fff5fb40 100644
--- a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
+++ b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c
@@ -197,6 +197,18 @@ static int marshal_nv_define_space(struct obuf *ob,
return rc;
}
+static int marshal_nv_setbits(struct obuf *ob,
+ const struct tpm2_nv_setbits_cmd *command_body)
+{
+ int rc = 0;
+ const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
+
+ rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
+ rc |= obuf_write_be64(ob, command_body->bits);
+
+ return rc;
+}
+
static int marshal_nv_write(struct obuf *ob,
const struct tpm2_nv_write_cmd *command_body)
{
@@ -386,6 +398,10 @@ int tpm_marshal_command(TPM_CC command, const void *tpm_command_body, struct obu
rc |= marshal_nv_define_space(ob, tpm_command_body);
break;
+ case TPM2_NV_SetBits:
+ rc |= marshal_nv_setbits(ob, tpm_command_body);
+ break;
+
case TPM2_NV_Write:
rc |= marshal_nv_write(ob, tpm_command_body);
break;
@@ -618,6 +634,7 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command, struct ibuf *ib)
case TPM2_Clear:
case TPM2_ClearControl:
case TPM2_NV_DefineSpace:
+ case TPM2_NV_SetBits:
case TPM2_NV_Write:
case TPM2_NV_WriteLock:
case TPM2_PCR_Extend:
diff --git a/src/security/tpm/tss/tcg-2.0/tss_structures.h b/src/security/tpm/tss/tcg-2.0/tss_structures.h
index 1c7aa4b48f..cb8b4f9f9e 100644
--- a/src/security/tpm/tss/tcg-2.0/tss_structures.h
+++ b/src/security/tpm/tss/tcg-2.0/tss_structures.h
@@ -81,6 +81,7 @@ struct tpm_header {
#define TPM2_Clear ((TPM_CC)0x00000126)
#define TPM2_ClearControl ((TPM_CC)0x00000127)
#define TPM2_NV_DefineSpace ((TPM_CC)0x0000012A)
+#define TPM2_NV_SetBits ((TPM_CC)0x00000135)
#define TPM2_NV_Write ((TPM_CC)0x00000137)
#define TPM2_NV_WriteLock ((TPM_CC)0x00000138)
#define TPM2_SelfTest ((TPM_CC)0x00000143)
@@ -395,6 +396,11 @@ struct tpm2_nv_write_cmd {
uint16_t offset;
};
+struct tpm2_nv_setbits_cmd {
+ TPMI_RH_NV_INDEX nvIndex;
+ uint64_t bits;
+};
+
struct tpm2_self_test {
TPMI_YES_NO yes_no;
};