From: Stefan Berger stefanb@linux.vnet.ibm.com
Implement the tpm20_extend function. We use it with only SHA1.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/std/tcg.h | 17 +++++++++++++++++ src/tcgbios.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h index e0d6f30..d45c7f6 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -375,6 +375,8 @@ struct tpm_res_sha1complete { #define TPM2_RS_PW 0x40000009 #define TPM2_RH_PLATFORM 0x4000000c
+#define TPM2_ALG_SHA1 0x0004 + /* TPM 2 command tags */ #define TPM2_ST_NO_SESSIONS 0x8001 #define TPM2_ST_SESSIONS 0x8002 @@ -385,6 +387,7 @@ struct tpm_res_sha1complete { #define TPM2_CC_Startup 0x144 #define TPM2_CC_StirRandom 0x146 #define TPM2_CC_GetRandom 0x17b +#define TPM2_CC_PCR_Extend 0x182
/* TPM 2 error codes */ #define TPM2_RC_INITIALIZE 0x100 @@ -426,4 +429,18 @@ struct tpm2_req_hierarchychangeauth { struct tpm2b_20 newAuth; } PACKED;
+struct tpm2_digest_value { + u32 count; /* 1 entry only */ + u16 hashalg; /* TPM2_ALG_SHA1 */ + u8 sha1[SHA1_BUFSIZE]; +} PACKED; + +struct tpm2_req_extend { + struct tpm_req_header hdr; + u32 pcrindex; + u32 authblocksize; + struct tpm2_authblock authblock; + struct tpm2_digest_value digest; +} PACKED; + #endif // tcg.h diff --git a/src/tcgbios.c b/src/tcgbios.c index 87269ee..e1baaa7 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -367,6 +367,37 @@ tpm12_extend(u32 pcrindex, const u8 *digest) return 0; }
+static int tpm20_extend(u32 pcrindex, const u8 *digest) +{ + struct tpm2_req_extend tre = { + .hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS), + .hdr.totlen = cpu_to_be32(sizeof(tre)), + .hdr.ordinal = cpu_to_be32(TPM2_CC_PCR_Extend), + .pcrindex = cpu_to_be32(pcrindex), + .authblocksize = cpu_to_be32(sizeof(tre.authblock)), + .authblock = { + .handle = cpu_to_be32(TPM2_RS_PW), + .noncesize = cpu_to_be16(0), + .contsession = TPM2_YES, + .pwdsize = cpu_to_be16(0), + }, + .digest = { + .count = cpu_to_be32(1), + .hashalg = cpu_to_be16(TPM2_ALG_SHA1), + }, + }; + memcpy(tre.digest.sha1, digest, sizeof(tre.digest.sha1)); + + struct tpm_rsp_header rsp; + u32 resp_length = sizeof(rsp); + int ret = tpmhw_transmit(0, &tre.hdr, &rsp, &resp_length, + TPM_DURATION_TYPE_SHORT); + if (ret || resp_length != sizeof(rsp) || rsp.errcode) + return -1; + + return 0; +} + static int tpm_extend(u32 pcrindex, const u8 *digest) { @@ -379,8 +410,7 @@ tpm_extend(u32 pcrindex, const u8 *digest) case TPM_VERSION_1_2: return tpm12_extend(pcrindex, digest); case TPM_VERSION_2: - // FIXME: missing code - return -1; + return tpm20_extend(pcrindex, digest); } return -1; }