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; };