#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
#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
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
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)
{
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;
}