xref: /aosp_15_r20/external/coreboot/src/security/vboot/tpm_common.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <security/tpm/tspi.h>
4 #include <security/tpm/tss.h>
5 #include <security/vboot/tpm_common.h>
6 #include <security/tpm/tss_errors.h>
7 #include <vb2_api.h>
8 #include <vb2_sha.h>
9 
10 #define TPM_PCR_BOOT_MODE "VBOOT: boot mode"
11 #define TPM_PCR_GBB_HWID_NAME "VBOOT: GBB HWID"
12 #define TPM_PCR_FIRMWARE_VERSION "VBOOT: firmware ver"
13 
vboot_setup_tpm(struct vb2_context * ctx)14 tpm_result_t vboot_setup_tpm(struct vb2_context *ctx)
15 {
16 	tpm_result_t rc;
17 
18 	rc = tpm_setup(ctx->flags & VB2_CONTEXT_S3_RESUME);
19 	if (rc == TPM_CB_MUST_REBOOT)
20 		ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
21 
22 	return rc;
23 }
24 
vboot_extend_pcr(struct vb2_context * ctx,int pcr,enum vb2_pcr_digest which_digest)25 tpm_result_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
26 			     enum vb2_pcr_digest which_digest)
27 {
28 	uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
29 	uint32_t size = sizeof(buffer);
30 
31 	if (vb2api_get_pcr_digest(ctx, which_digest, buffer, &size) != VB2_SUCCESS)
32 		return TPM_CB_FAIL;
33 
34 	/*
35 	 * On TPM 1.2, all PCRs are intended for use with SHA1. We truncate our
36 	 * SHA256 HWID hash to 20 bytes to make it fit. On TPM 2.0, we always
37 	 * want to use the SHA256 banks, even for the boot mode which is
38 	 * technically a SHA1 value for historical reasons. vboot has already
39 	 * zero-extended the buffer to 32 bytes for us, so we just take it like
40 	 * that and pretend it's a SHA256. In practice, this means we never care
41 	 * about the (*size) value returned from vboot (which indicates how many
42 	 * significant bytes vboot wrote, although it always extends zeroes up
43 	 * to the end of the buffer), we always use a hardcoded size instead.
44 	 */
45 	_Static_assert(sizeof(buffer) >= VB2_SHA256_DIGEST_SIZE,
46 		       "Buffer needs to be able to fit at least a SHA256");
47 	enum vb2_hash_algorithm algo = tlcl_get_family() == TPM_1 ?
48 		VB2_HASH_SHA1 : VB2_HASH_SHA256;
49 
50 	switch (which_digest) {
51 	/* SHA1 of (devmode|recmode|keyblock) bits */
52 	case BOOT_MODE_PCR:
53 		return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
54 				      TPM_PCR_BOOT_MODE);
55 	 /* SHA256 of HWID */
56 	case HWID_DIGEST_PCR:
57 		return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
58 				      TPM_PCR_GBB_HWID_NAME);
59 	/* firmware version */
60 	case FIRMWARE_VERSION_PCR:
61 		return tpm_extend_pcr(pcr, algo, buffer, vb2_digest_size(algo),
62 				      TPM_PCR_FIRMWARE_VERSION);
63 	default:
64 		return TPM_CB_FAIL;
65 	}
66 }
67