mb/google/brya: Create rull variant
[coreboot2.git] / src / vendorcode / eltan / security / mboot / mboot.c
blob9cdd0de2fe83c542dbb8b93daae3cbec36bf605b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <mboot.h>
4 #include <assert.h>
5 #include <build.h>
6 #include <vb2_api.h>
7 #include <board_mboot.h>
9 /*
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)
16 tpm_result_t rc;
17 TPML_PCR_SELECTION Pcrs;
18 EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap = 0;
19 uint32_t activePcrBanks = 0;
20 uint32_t index;
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;
26 } else {
27 for (index = 0; index < Pcrs.count; index++) {
28 switch (Pcrs.pcrSelections[index].hash) {
29 case TPM_ALG_SHA1:
30 tpmHashAlgorithmBitmap |=
31 EFI_TCG2_BOOT_HASH_ALG_SHA1;
32 if (!is_zero_buffer(Pcrs.pcrSelections[index].pcrSelect,
33 Pcrs.pcrSelections[index].sizeofSelect))
34 activePcrBanks |=
35 EFI_TCG2_BOOT_HASH_ALG_SHA1;
36 break;
37 case TPM_ALG_SHA256:
38 tpmHashAlgorithmBitmap |=
39 EFI_TCG2_BOOT_HASH_ALG_SHA256;
40 if (!is_zero_buffer(Pcrs.pcrSelections[index].pcrSelect,
41 Pcrs.pcrSelections[index].sizeofSelect))
42 activePcrBanks |=
43 EFI_TCG2_BOOT_HASH_ALG_SHA256;
44 break;
45 case TPM_ALG_SHA384:
46 case TPM_ALG_SHA512:
47 case TPM_ALG_SM3_256:
48 default:
49 printk(BIOS_DEBUG, "%s: unsupported algorithm "
50 "reported - %#x\n", __func__,
51 Pcrs.pcrSelections[index].hash);
52 break;
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",
60 activePcrBanks);
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
71 * PcrSelection.
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;
81 tpm_result_t rc;
82 int index;
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);
100 return rc;
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);
130 } else {
131 struct vb2_hash tmp;
132 if (vb2_hash_calculate(false, hashData, hashDataLen, VB2_HASH_SHA256, &tmp))
133 return TPM_IOERROR;
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),
141 VB2_HASH_SHA256));
145 * invalidate_pcrs
147 * Invalidate PCRs 0-7 with extending 1 after tpm failure.
149 void invalidate_pcrs(void)
151 int pcr;
152 tpm_result_t rc;
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);
174 * is_zero_buffer
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)
186 uint8_t *ptr;
188 ptr = buffer;
189 while (size--) {
190 if (*(ptr++) != 0)
191 return false;
193 return true;
197 * Prints command or response buffer for debugging purposes.
199 * @param[in] Buffer Buffer to print.
200 * @param[in] BufferSize Buffer data length.
202 * @retval None
204 void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize)
206 uint32_t index;
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;
234 uint8_t *base;
235 size_t size;
237 printk(BIOS_DEBUG, "%s: Measure %s\n", __func__, name);
238 base = cbfs_map(name, &size);
240 if (base == NULL) {
241 printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __func__, name);
242 return TPM_IOERROR;
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;
249 if (event_msg)
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
258 *mb_entry
260 * initializes measured boot mechanism, initializes the tpm library and starts the tpm called
261 * by mb_measure
263 * The function can be overridden at the mainboard level my simply creating a function with the
264 * same name there.
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)
274 tpm_result_t rc;
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",
281 __func__, rc);
282 return rc;
285 if (wake_from_s3) {
286 printk(BIOS_DEBUG, "%s: tlcl_resume\n", __func__);
287 rc = tlcl_resume();
288 } else {
289 printk(BIOS_DEBUG, "%s: tlcl_startup\n", __func__);
290 rc = tlcl_startup();
293 if (rc)
294 printk(BIOS_ERR, "%s: StartUp failed %#x!\n", __func__, rc);
296 return rc;
301 * mb_measure
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)
320 tpm_result_t rc;
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__);
328 } else {
329 invalidate_pcrs();
330 printk(BIOS_ERR, "%s: Measuring returned %#x unsuccessful! PCRs invalidated.\n",
331 __func__, rc);
333 } else {
334 invalidate_pcrs();
335 printk(BIOS_ERR, "%s: StartUp returned %#x, unsuccessful! PCRs invalidated.\n", __func__,
336 rc);
338 return rc;
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
350 * implementation
352 * The function can be overridden at the mainboard level my simply creating a
353 * function with the same name there.
355 * @param[in] none
357 * @retval TPM_SUCCESS Operation completed successfully.
358 * @retval TPM_IOERROR Unexpected device behavior.
360 __weak tpm_result_t mb_measure_log_start(void)
362 tpm_result_t rc;
363 uint32_t i;
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",
367 __func__);
368 return TPM_IOERROR;
371 rc = mb_crtm();
372 if (rc) {
373 printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured."
374 " Received error %#x, ABORTING!!!\n", __func__, rc);
375 return 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);
390 return rc;
392 printk(BIOS_DEBUG, "%s: Success! %s measured to pcr"
393 "%d.\n", __func__, mb_log_list[i].cbfs_name,
394 mb_log_list[i].pcr);
396 return rc;
399 static const uint8_t crtm_version[] =
400 CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING\
401 COREBOOT_VERSION COREBOOT_EXTRA_VERSION " " COREBOOT_BUILD;
405 * mb_crtm
407 * measures the crtm version. this consists of a string than can be
408 * defined using make menuconfig and automatically generated version
409 * information.
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)
419 tpm_result_t rc;
420 TCG_PCR_EVENT2_HDR tcgEventHdr;
421 uint8_t hash[VB2_SHA256_DIGEST_SIZE];
422 uint8_t *msgPtr;
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);
435 if (rc) {
436 printk(BIOS_DEBUG, "Measure CRTM Version returned %#x\n", rc);
437 return rc;
440 rc = get_intel_me_hash(hash);
441 if (rc) {
442 printk(BIOS_DEBUG, "get_intel_me_hash returned %#x\n", rc);
443 rc = TPM_IOERROR;
444 return rc;
447 /* Add the me hash */
448 printk(BIOS_DEBUG, "%s: Add the hash returned by the ME\n",
449 __func__);
450 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
451 tcgEventHdr.pcrIndex = MBOOT_PCR_INDEX_0;
452 tcgEventHdr.eventType = EV_S_CRTM_CONTENTS;
454 msgPtr = NULL;
455 tcgEventHdr.eventSize = 0;
456 rc = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hash, sizeof(hash), &tcgEventHdr,
457 msgPtr);
458 if (rc)
459 printk(BIOS_DEBUG, "Add ME hash returned %#x\n", rc);
461 return rc;