Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35467 )
Change subject: security/tpm: Add TPM2_NV_ReadPublic ......................................................................
security/tpm: Add TPM2_NV_ReadPublic
Fixme
Change-Id: Ia819f0e1b1ebd2c2d82f953272c8932d733ed229 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/security/tpm/tss.h M src/security/tpm/tss/tcg-2.0/tss.c M src/security/tpm/tss/tcg-2.0/tss_marshaling.c M src/security/tpm/tss/tcg-2.0/tss_structures.h 4 files changed, 116 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/67/35467/1
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h index 30e2a7b..b7eb97f 100644 --- a/src/security/tpm/tss.h +++ b/src/security/tpm/tss.h @@ -179,6 +179,12 @@ uint32_t tlcl_lock_nv_write(uint32_t index);
/** + * Read the public attributes of a defined NV index. + */ +uint32_t tlcl_nv_read_public(uint32_t index, + struct nv_read_public_response *resp); + +/** * Perform a TPM_Extend. */ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c index 08a7caa..bc0ce6c 100644 --- a/src/security/tpm/tss/tcg-2.0/tss.c +++ b/src/security/tpm/tss/tcg-2.0/tss.c @@ -281,6 +281,28 @@ return TPM_SUCCESS; }
+uint32_t tlcl_nv_read_public(uint32_t index, + struct nv_read_public_response *resp) +{ + struct tpm2_response *response; + /* TPM Wll reject attempts to write at non-defined index. */ + struct tpm2_nv_read_public_cmd nv_rp = { + .nvIndex = HR_NV_INDEX + index, + }; + + response = tpm_process_command(TPM2_NV_ReadPublic, &nv_rp); + + printk(BIOS_INFO, "%s: response is %x\n", + __func__, response ? response->hdr.tpm_code : -1); + + if (!response || response->hdr.tpm_code) + return TPM_E_IOERROR; + + memcpy(resp, &response->nv_read_public, sizeof(*resp)); + + return TPM_SUCCESS; +} + uint32_t tlcl_startup(void) { return tlcl_send_startup(TPM_SU_CLEAR); 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 345aec5..8e768d5 100644 --- a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c +++ b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c @@ -21,6 +21,7 @@ #define unmarshal_TPM_CC(a, b) ibuf_read_be32(a, b) #define unmarshal_TPM_PT(a, b) ibuf_read_be32(a, b) #define unmarshal_TPM_HANDLE(a, b) ibuf_read_be32(a, b) +#define unmarshal_TPMI_ALG_HASH(a, b) ibuf_read_be16(a, b)
#define marshal_TPM_HANDLE(a, b) obuf_write_be32(a, b) #define marshal_TPMI_ALG_HASH(a, b) obuf_write_be16(a, b) @@ -204,6 +205,12 @@ return marshal_common_session_header(ob, handles, ARRAY_SIZE(handles)); }
+static int marshal_nv_read_public(struct obuf *ob, + struct tpm2_nv_read_public_cmd *command_body) +{ + return marshal_TPM_HANDLE(ob, command_body->nvIndex); +} + static int marshal_pcr_extend(struct obuf *ob, struct tpm2_pcr_extend_cmd *command_body) { @@ -356,6 +363,10 @@ rc |= marshal_nv_write_lock(ob, tpm_command_body); break;
+ case TPM2_NV_ReadPublic: + rc |= marshal_nv_read_public(ob, tpm_command_body); + break; + case TPM2_SelfTest: rc |= marshal_selftest(ob, tpm_command_body); break; @@ -502,6 +513,51 @@ return 0; }
+static int unmarshal_TPMA_NV(struct ibuf *ib, TPMA_NV *v) +{ + uint32_t tmp; + + if (ibuf_read_be32(ib, &tmp)) + return -1; + + memcpy(v, &tmp, sizeof(tmp)); + return 0; +} + +static int unmarshal_nv_read_public(struct ibuf *ib, struct nv_read_public_response *resp) +{ + uint16_t size; + + if (ibuf_read_be16(ib, &size)) + return -1; + + if (unmarshal_TPM_HANDLE(ib, &resp->nvPublic.nvIndex)) + return -1; + if (unmarshal_TPMI_ALG_HASH(ib, &resp->nvPublic.nameAlg)) + return -1; + if (unmarshal_TPMA_NV(ib, &resp->nvPublic.attributes)) + return -1; + if (ibuf_read_be16(ib, &resp->nvPublic.authPolicy.size)) + return -1; + if (resp->nvPublic.authPolicy.size > sizeof(resp->nvPublic.authPolicy.buffer)) + return -1; + if (ibuf_read(ib, &resp->nvPublic.authPolicy.buffer, resp->nvPublic.authPolicy.size)) + return -1; + if (ibuf_read_be16(ib, &resp->nvPublic.dataSize)) + return -1; + if (ibuf_read_be16(ib, &resp->nvName.size)) + return -1; + printk(BIOS_ERR, "resp->nvName.size %x\n", resp->nvName.size); + + if (resp->nvName.size > sizeof(resp->nvName.buffer)) + return -1; + if (ibuf_read(ib, &resp->nvName.buffer, resp->nvName.size)) + return -1; + ibuf_oob_drain(ib, ibuf_remaining(ib)); + + return 0; +} + static int unmarshal_vendor_command(struct ibuf *ib, struct vendor_command_response *vcr) { @@ -563,6 +619,10 @@ rc |= unmarshal_nv_read(ib, &tpm2_resp->nvr); break;
+ case TPM2_NV_ReadPublic: + rc |= unmarshal_nv_read_public(ib, &tpm2_resp->nv_read_public); + break; + case TPM2_Hierarchy_Control: case TPM2_Clear: case TPM2_NV_DefineSpace: 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 7332739..92c6a3f 100644 --- a/src/security/tpm/tss/tcg-2.0/tss_structures.h +++ b/src/security/tpm/tss/tcg-2.0/tss_structures.h @@ -66,6 +66,7 @@ } __packed;
/* TPM command codes. */ +#define TPM2_NV_UndefineSpaceSpecial ((TPM_CC)0x0000011F) #define TPM2_Hierarchy_Control ((TPM_CC)0x00000121) #define TPM2_Clear ((TPM_CC)0x00000126) #define TPM2_NV_DefineSpace ((TPM_CC)0x0000012A) @@ -75,6 +76,7 @@ #define TPM2_Startup ((TPM_CC)0x00000144) #define TPM2_Shutdown ((TPM_CC)0x00000145) #define TPM2_NV_Read ((TPM_CC)0x0000014E) +#define TPM2_NV_ReadPublic ((TPM_CC)0x00000169) #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 @@ -353,6 +355,27 @@ uint8_t *auth; };
+typedef struct { + uint16_t size; + uint8_t buffer[64]; +} TPM2B_NAME; + +typedef struct { + TPMI_RH_NV_INDEX nvIndex; + TPMI_ALG_HASH nameAlg; + TPMA_NV attributes; + struct { + uint16_t size; + TPMU_HA buffer; + } authPolicy; + uint16_t dataSize; +} TPM2B_PUBLIC; + +struct nv_read_public_response { + TPM2B_PUBLIC nvPublic; + TPM2B_NAME nvName; +} __packed; + struct tpm2_response { struct tpm_header hdr; union { @@ -360,6 +383,7 @@ struct nv_read_response nvr; struct tpm2_session_header def_space; struct vendor_command_response vcr; + struct nv_read_public_response nv_read_public; }; };
@@ -384,6 +408,10 @@ uint16_t offset; };
+struct tpm2_nv_read_public_cmd { + TPMI_RH_NV_INDEX nvIndex; +}; + struct tpm2_nv_write_lock_cmd { TPMI_RH_NV_INDEX nvIndex; };