1 /* SPDX-License-Identifier: GPL-2.0-only */
7 #include <board_mboot.h>
10 * Get the list of currently active PCR banks in TPM.
12 * @retval A map of active PCR banks.
14 EFI_TCG2_EVENT_ALGORITHM_BITMAP
tpm2_get_active_pcrs(void)
17 TPML_PCR_SELECTION Pcrs
;
18 EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap
= 0;
19 uint32_t activePcrBanks
= 0;
22 rc
= tpm2_get_capability_pcrs(&Pcrs
);
23 if (rc
!= TPM_SUCCESS
) {
24 tpmHashAlgorithmBitmap
= EFI_TCG2_BOOT_HASH_ALG_SHA1
;
25 activePcrBanks
= EFI_TCG2_BOOT_HASH_ALG_SHA1
;
27 for (index
= 0; index
< Pcrs
.count
; index
++) {
28 switch (Pcrs
.pcrSelections
[index
].hash
) {
30 tpmHashAlgorithmBitmap
|=
31 EFI_TCG2_BOOT_HASH_ALG_SHA1
;
32 if (!is_zero_buffer(Pcrs
.pcrSelections
[index
].pcrSelect
,
33 Pcrs
.pcrSelections
[index
].sizeofSelect
))
35 EFI_TCG2_BOOT_HASH_ALG_SHA1
;
38 tpmHashAlgorithmBitmap
|=
39 EFI_TCG2_BOOT_HASH_ALG_SHA256
;
40 if (!is_zero_buffer(Pcrs
.pcrSelections
[index
].pcrSelect
,
41 Pcrs
.pcrSelections
[index
].sizeofSelect
))
43 EFI_TCG2_BOOT_HASH_ALG_SHA256
;
49 printk(BIOS_DEBUG
, "%s: unsupported algorithm "
50 "reported - %#x\n", __func__
,
51 Pcrs
.pcrSelections
[index
].hash
);
56 printk(BIOS_DEBUG
, "Tcg2 Capability values from TPM\n");
57 printk(BIOS_DEBUG
, "tpmHashAlgorithmBitmap - 0x%08x\n",
58 tpmHashAlgorithmBitmap
);
59 printk(BIOS_DEBUG
, "activePcrBanks - 0x%08x\n",
62 return activePcrBanks
;
66 * tpm2_get_capability_pcrs
68 * Return the TPM PCR information.
70 * This function parses the data got from tlcl2_get_capability and returns the
73 * @param[out] Pcrs The Pcr Selection
75 * @retval TPM_SUCCESS Operation completed successfully.
76 * @retval TPM_IOERROR The command was unsuccessful.
78 tpm_result_t
tpm2_get_capability_pcrs(TPML_PCR_SELECTION
*Pcrs
)
80 TPMS_CAPABILITY_DATA TpmCap
;
84 rc
= tlcl2_get_capability(TPM_CAP_PCRS
, 0, 1, &TpmCap
);
85 if (rc
== TPM_SUCCESS
) {
86 Pcrs
->count
= TpmCap
.data
.assignedPCR
.count
;
87 printk(BIOS_DEBUG
, "Pcrs->count = %d\n", Pcrs
->count
);
88 for (index
= 0; index
< Pcrs
->count
; index
++) {
89 Pcrs
->pcrSelections
[index
].hash
=
90 swab16(TpmCap
.data
.assignedPCR
.pcrSelections
[index
].hash
);
91 printk(BIOS_DEBUG
, "Pcrs->pcrSelections[%d].hash = %#x\n", index
,
92 Pcrs
->pcrSelections
[index
].hash
);
93 Pcrs
->pcrSelections
[index
].sizeofSelect
=
94 TpmCap
.data
.assignedPCR
.pcrSelections
[index
].sizeofSelect
;
95 memcpy(Pcrs
->pcrSelections
[index
].pcrSelect
,
96 TpmCap
.data
.assignedPCR
.pcrSelections
[index
].pcrSelect
,
97 Pcrs
->pcrSelections
[index
].sizeofSelect
);
104 * mboot_hash_extend_log
106 * Calculates the hash over the data and extends it in active PCR banks and
107 * then logs them in the event log.
109 * @param[in] flags flags associated with hash data.
110 * @param[in] hashData data to be hashed.
111 * @param[in] hashDataLen length of the data to be hashed.
112 * @param[in] newEventHdr event header in TCG_PCR_EVENT2 format.
113 * @param[in] eventLog description of the event.
115 * @retval TPM_SUCCESS Operation completed successfully.
116 * @retval TPM_IOERROR Unexpected device behavior.
118 tpm_result_t
mboot_hash_extend_log(uint64_t flags
, uint8_t *hashData
, uint32_t hashDataLen
,
119 TCG_PCR_EVENT2_HDR
*newEventHdr
, uint8_t *eventLog
)
121 TPMT_HA
*digest
= NULL
;
123 printk(BIOS_DEBUG
, "%s: Hash Data Length: %zu bytes\n", __func__
, (size_t)hashDataLen
);
125 /* Generate SHA256 */
126 digest
= &(newEventHdr
->digest
.digests
[0]);
127 if (flags
& MBOOT_HASH_PROVIDED
) {
128 /* The hash is provided as data */
129 memcpy(digest
->digest
.sha256
, (void *)hashData
, hashDataLen
);
132 if (vb2_hash_calculate(false, hashData
, hashDataLen
, VB2_HASH_SHA256
, &tmp
))
134 memcpy(digest
->digest
.sha256
, tmp
.sha256
, sizeof(tmp
.sha256
));
137 printk(BIOS_DEBUG
, "%s: SHA256 Hash Digest:\n", __func__
);
138 mboot_print_buffer(digest
->digest
.sha256
, VB2_SHA256_DIGEST_SIZE
);
140 return (tlcl_extend(newEventHdr
->pcrIndex
, (uint8_t *)&(newEventHdr
->digest
),
147 * Invalidate PCRs 0-7 with extending 1 after tpm failure.
149 void invalidate_pcrs(void)
154 TCG_PCR_EVENT2_HDR tcgEventHdr
;
155 uint8_t invalidate
= 1;
157 for (pcr
= 0; pcr
< 8; pcr
++) {
158 printk(BIOS_DEBUG
, "%s: Invalidating PCR %d\n", __func__
, pcr
);
159 memset(&tcgEventHdr
, 0, sizeof(tcgEventHdr
));
160 tcgEventHdr
.pcrIndex
= pcr
;
161 tcgEventHdr
.eventType
= EV_NO_ACTION
;
162 tcgEventHdr
.eventSize
= (uint32_t) sizeof(invalidate
);
164 rc
= mboot_hash_extend_log(0, (uint8_t *)&invalidate
,
165 tcgEventHdr
.eventSize
, &tcgEventHdr
,
166 (uint8_t *)"Invalidate PCR");
167 if (rc
!= TPM_SUCCESS
)
168 printk(BIOS_DEBUG
, "%s: invalidating pcr %d returned"
169 " %#x\n", __func__
, pcr
, rc
);
176 * Check if buffer is all zero.
178 * @param[in] buffer Buffer to be checked.
179 * @param[in] size Size of buffer to be checked.
181 * @retval TRUE buffer is all zero.
182 * @retval FALSE buffer is not all zero.
184 int is_zero_buffer(void *buffer
, unsigned int size
)
197 * Prints command or response buffer for debugging purposes.
199 * @param[in] Buffer Buffer to print.
200 * @param[in] BufferSize Buffer data length.
204 void mboot_print_buffer(uint8_t *buffer
, uint32_t bufferSize
)
208 printk(BIOS_DEBUG
, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n",
209 (unsigned int)*buffer
, bufferSize
);
210 for (index
= 0; index
< bufferSize
; index
++) {
211 printk(BIOS_DEBUG
, "%02x ", *(buffer
+ index
));
212 if ((index
+1) % 16 == 0)
213 printk(BIOS_DEBUG
, "\n");
215 printk(BIOS_DEBUG
, "\n");
219 * measures and logs the specified cbfs file.
221 * @param[in] name name of the cbfs file to measure
222 * @param[in] type data type of the cbfs file.
223 * @param[in] pcr pcr to extend.
224 * @param[in] evenType tcg event type.
225 * @param[in] event_msg description of the event.
227 * @retval TPM_SUCCESS Operation completed successfully.
228 * @retval TPM_IOERROR Unexpected device behavior.
230 tpm_result_t
mb_measure_log_worker(const char *name
, uint32_t type
, uint32_t pcr
,
231 TCG_EVENTTYPE eventType
, const char *event_msg
)
233 TCG_PCR_EVENT2_HDR tcgEventHdr
;
237 printk(BIOS_DEBUG
, "%s: Measure %s\n", __func__
, name
);
238 base
= cbfs_map(name
, &size
);
241 printk(BIOS_DEBUG
, "%s: CBFS locate fail: %s\n", __func__
, name
);
245 printk(BIOS_DEBUG
, "%s: CBFS locate success: %s\n", __func__
, name
);
246 memset(&tcgEventHdr
, 0, sizeof(tcgEventHdr
));
247 tcgEventHdr
.pcrIndex
= pcr
;
248 tcgEventHdr
.eventType
= eventType
;
250 tcgEventHdr
.eventSize
= (uint32_t) strlen(event_msg
);
252 return mboot_hash_extend_log(0, base
, size
, &tcgEventHdr
, (uint8_t *)event_msg
);
256 * Called from early romstage
260 * initializes measured boot mechanism, initializes the tpm library and starts the tpm called
263 * The function can be overridden at the mainboard level my simply creating a function with the
266 * @param[in] wake_from_s3 1 if we are waking from S3, 0 standard boot
268 * @retval TPM_SUCCESS Operation completed successfully.
269 * @retval TPM_IOERROR Unexpected device behavior.
272 __weak tpm_result_t
mb_entry(int wake_from_s3
)
276 /* Initialize TPM driver. */
277 printk(BIOS_DEBUG
, "%s: tlcl_lib_init\n", __func__
);
278 rc
= tlcl_lib_init();
279 if (rc
!= TPM_SUCCESS
) {
280 printk(BIOS_ERR
, "%s: TPM driver initialization failed with error %#x.\n",
286 printk(BIOS_DEBUG
, "%s: tlcl_resume\n", __func__
);
289 printk(BIOS_DEBUG
, "%s: tlcl_startup\n", __func__
);
294 printk(BIOS_ERR
, "%s: StartUp failed %#x!\n", __func__
, rc
);
303 * initial call to the measured boot mechanism, initializes the
304 * tpm library, starts the tpm and performs the measurements defined by
305 * the coreboot platform.
307 * The pcrs will be invalidated if the measurement fails
309 * The function can be overridden at the mainboard level my simply creating a
310 * function with the same name there.
312 * @param[in] wake_from_s3 1 if we are waking from S3, 0 standard boot
314 * @retval TPM_SUCCESS Operation completed successfully.
315 * @retval TPM_IOERROR Unexpected device behavior.
318 __weak tpm_result_t
mb_measure(int wake_from_s3
)
322 rc
= mb_entry(wake_from_s3
);
323 if (rc
== TPM_SUCCESS
) {
324 printk(BIOS_DEBUG
, "%s: StartUp, successful!\n", __func__
);
325 rc
= mb_measure_log_start();
326 if (rc
== TPM_SUCCESS
) {
327 printk(BIOS_DEBUG
, "%s: Measuring, successful!\n", __func__
);
330 printk(BIOS_ERR
, "%s: Measuring returned %#x unsuccessful! PCRs invalidated.\n",
335 printk(BIOS_ERR
, "%s: StartUp returned %#x, unsuccessful! PCRs invalidated.\n", __func__
,
343 * mb_measure_log_start
345 * performs the measurements defined by the board routines.
347 * The logging is defined by the mb_log_list structure
349 * These items need to be defined in the mainboard part of the mboot
352 * The function can be overridden at the mainboard level my simply creating a
353 * function with the same name there.
357 * @retval TPM_SUCCESS Operation completed successfully.
358 * @retval TPM_IOERROR Unexpected device behavior.
360 __weak tpm_result_t
mb_measure_log_start(void)
365 if ((tpm2_get_active_pcrs() & EFI_TCG2_BOOT_HASH_ALG_SHA256
) == 0x0) {
366 printk(BIOS_DEBUG
, "%s: SHA256 PCR Bank not active in TPM.\n",
373 printk(BIOS_DEBUG
, "%s: Fail! CRTM Version can't be measured."
374 " Received error %#x, ABORTING!!!\n", __func__
, rc
);
377 printk(BIOS_DEBUG
, "%s: Success! CRTM Version measured.\n", __func__
);
379 /* Log the items defined by the mainboard */
380 for (i
= 0; i
< ARRAY_SIZE(mb_log_list
); i
++) {
381 rc
= mb_measure_log_worker(
382 mb_log_list
[i
].cbfs_name
,
383 mb_log_list
[i
].cbfs_type
, mb_log_list
[i
].pcr
,
384 mb_log_list
[i
].eventType
,
385 mb_log_list
[i
].event_msg
);
386 if (rc
!= TPM_SUCCESS
) {
387 printk(BIOS_DEBUG
, "%s: Fail! %s can't be measured."
388 "ABORTING!!!\n", __func__
,
389 mb_log_list
[i
].cbfs_name
);
392 printk(BIOS_DEBUG
, "%s: Success! %s measured to pcr"
393 "%d.\n", __func__
, mb_log_list
[i
].cbfs_name
,
399 static const uint8_t crtm_version
[] =
400 CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING\
401 COREBOOT_VERSION COREBOOT_EXTRA_VERSION
" " COREBOOT_BUILD
;
407 * measures the crtm version. this consists of a string than can be
408 * defined using make menuconfig and automatically generated version
411 * The function can be overridden at the mainboard level my simply creating a
412 * function with the same name there.
414 * @retval TPM_SUCCESS Operation completed successfully.
415 * @retval TPM_IOERROR Unexpected device behavior.
417 __weak tpm_result_t
mb_crtm(void)
420 TCG_PCR_EVENT2_HDR tcgEventHdr
;
421 uint8_t hash
[VB2_SHA256_DIGEST_SIZE
];
424 /* Use FirmwareVersion string to represent CRTM version. */
425 printk(BIOS_DEBUG
, "%s: Measure CRTM Version\n", __func__
);
426 memset(&tcgEventHdr
, 0, sizeof(tcgEventHdr
));
427 tcgEventHdr
.pcrIndex
= MBOOT_PCR_INDEX_0
;
428 tcgEventHdr
.eventType
= EV_S_CRTM_VERSION
;
429 tcgEventHdr
.eventSize
= sizeof(crtm_version
);
430 printk(BIOS_DEBUG
, "%s: EventSize - %u\n", __func__
,
431 tcgEventHdr
.eventSize
);
433 rc
= mboot_hash_extend_log(0, (uint8_t *)crtm_version
, tcgEventHdr
.eventSize
,
434 &tcgEventHdr
, (uint8_t *)crtm_version
);
436 printk(BIOS_DEBUG
, "Measure CRTM Version returned %#x\n", rc
);
440 rc
= get_intel_me_hash(hash
);
442 printk(BIOS_DEBUG
, "get_intel_me_hash returned %#x\n", rc
);
447 /* Add the me hash */
448 printk(BIOS_DEBUG
, "%s: Add the hash returned by the ME\n",
450 memset(&tcgEventHdr
, 0, sizeof(tcgEventHdr
));
451 tcgEventHdr
.pcrIndex
= MBOOT_PCR_INDEX_0
;
452 tcgEventHdr
.eventType
= EV_S_CRTM_CONTENTS
;
455 tcgEventHdr
.eventSize
= 0;
456 rc
= mboot_hash_extend_log(MBOOT_HASH_PROVIDED
, hash
, sizeof(hash
), &tcgEventHdr
,
459 printk(BIOS_DEBUG
, "Add ME hash returned %#x\n", rc
);