security: vboot: Clarify PCR extension algorithms/sizes

The PCR algorithms used for vboot are frequently causing confusion (e.g.
see CB:35645) because depending on the circumstances sometimes a
(zero-extended) SHA1 value is interpreted as a SHA256, and sometimes a
SHA256 is interpreted as a SHA1. We can't really "fix" anything here
because the resulting digests are hardcoded in many generations of
Chromebooks, but we can document and isolate it better to reduce
confusion. This patch adds an explanatory comment and fixes both
algorithms and size passed into the lower-level TPM APIs to their actual
values (whereas it previously still relied on the TPM 1.2 TSS not
checking the algorithm type, and the TPM 2.0 TSS only using the size
value for the TCPA log and not the actual TPM operation).

Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ib0b6ecb8c7e9a405ae966f1049158f1d3820f7e2
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51720
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Julius Werner 2021-03-22 17:25:20 -07:00
parent f040f759d9
commit 74a0fad8a1
1 changed files with 18 additions and 3 deletions

View File

@ -31,15 +31,30 @@ vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
if (size < TPM_PCR_MINIMUM_DIGEST_SIZE) if (size < TPM_PCR_MINIMUM_DIGEST_SIZE)
return VB2_ERROR_UNKNOWN; return VB2_ERROR_UNKNOWN;
/*
* On TPM 1.2, all PCRs are intended for use with SHA1. We truncate our
* SHA256 HWID hash to 20 bytes to make it fit. On TPM 2.0, we always
* want to use the SHA256 banks, even for the boot mode which is
* technically a SHA1 value for historical reasons. vboot has already
* zero-extended the buffer to 32 bytes for us, so we just take it like
* that and pretend it's a SHA256. In practice, this means we never care
* about the (*size) value returned from vboot (which indicates how many
* significant bytes vboot wrote, although it always extends zeroes up
* to the end of the buffer), we always use a hardcoded size instead.
*/
_Static_assert(sizeof(buffer) >= VB2_SHA256_DIGEST_SIZE,
"Buffer needs to be able to fit at least a SHA256");
enum vb2_hash_algorithm algo = CONFIG(TPM1) ? VB2_HASH_SHA1 : VB2_HASH_SHA256;
switch (which_digest) { switch (which_digest) {
/* SHA1 of (devmode|recmode|keyblock) bits */ /* SHA1 of (devmode|recmode|keyblock) bits */
case BOOT_MODE_PCR: case BOOT_MODE_PCR:
return tpm_extend_pcr(pcr, VB2_HASH_SHA256, buffer, size, return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
TPM_PCR_BOOT_MODE); TPM_PCR_BOOT_MODE);
/* SHA256 of HWID */ /* SHA256 of HWID */
case HWID_DIGEST_PCR: case HWID_DIGEST_PCR:
return tpm_extend_pcr(pcr, VB2_HASH_SHA256, buffer, return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
size, TPM_PCR_GBB_HWID_NAME); TPM_PCR_GBB_HWID_NAME);
default: default:
return VB2_ERROR_UNKNOWN; return VB2_ERROR_UNKNOWN;
} }