tpm: add hmac checks to tpm2_pcr_extend()

tpm2_pcr_extend() is used by trusted keys to extend a PCR to prevent a
key from being re-loaded until the next reboot.  To use this
functionality securely, that extend must be protected by a session
hmac.  This patch adds HMAC protection so tampering with the
tpm2_pcr_extend() command in flight is detected.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
James Bottomley 2024-04-29 16:28:06 -04:00 committed by Jarkko Sakkinen
parent 1085b8276b
commit 6519fea6fd

View File

@ -216,13 +216,6 @@ out:
return rc;
}
struct tpm2_null_auth_area {
__be32 handle;
__be16 nonce_size;
u8 attributes;
__be16 auth_size;
} __packed;
/**
* tpm2_pcr_extend() - extend a PCR value
*
@ -236,24 +229,22 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
struct tpm_digest *digests)
{
struct tpm_buf buf;
struct tpm2_null_auth_area auth_area;
int rc;
int i;
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
rc = tpm2_start_auth_session(chip);
if (rc)
return rc;
tpm_buf_append_u32(&buf, pcr_idx);
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
if (rc) {
tpm2_end_auth_session(chip);
return rc;
}
auth_area.handle = cpu_to_be32(TPM2_RS_PW);
auth_area.nonce_size = 0;
auth_area.attributes = 0;
auth_area.auth_size = 0;
tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area));
tpm_buf_append(&buf, (const unsigned char *)&auth_area,
sizeof(auth_area));
tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
for (i = 0; i < chip->nr_allocated_banks; i++) {
@ -262,7 +253,9 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
chip->allocated_banks[i].digest_size);
}
tpm_buf_fill_hmac_session(chip, &buf);
rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value");
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
tpm_buf_destroy(&buf);