summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2021-03-22 17:25:20 -0700
committerJulius Werner <jwerner@chromium.org>2021-03-30 21:07:56 +0000
commit74a0fad8a10ba401ce538fae9a4574e57fdff78d (patch)
treedcddcf8d61c6dad2239271e65ffe23ecb2b7e753
parentf040f759d9e1a8107473140eb0f4dc1c99d39a1a (diff)
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>
-rw-r--r--src/security/vboot/tpm_common.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/security/vboot/tpm_common.c b/src/security/vboot/tpm_common.c
index 783392c76d..7fb2a9d3c5 100644
--- a/src/security/vboot/tpm_common.c
+++ b/src/security/vboot/tpm_common.c
@@ -31,15 +31,30 @@ vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
if (size < TPM_PCR_MINIMUM_DIGEST_SIZE)
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) {
/* SHA1 of (devmode|recmode|keyblock) bits */
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);
/* SHA256 of HWID */
case HWID_DIGEST_PCR:
- return tpm_extend_pcr(pcr, VB2_HASH_SHA256, buffer,
- size, TPM_PCR_GBB_HWID_NAME);
+ return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
+ TPM_PCR_GBB_HWID_NAME);
default:
return VB2_ERROR_UNKNOWN;
}