1 /* 2 * Copyright (c) 2025, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdarg.h> 9 #include <stdint.h> 10 11 #include <plat/arm/common/plat_arm.h> 12 #include <plat/common/platform.h> 13 #include <platform_def.h> 14 15 #include <common/desc_image_load.h> 16 #include <common/ep_info.h> 17 #include <drivers/auth/crypto_mod.h> 18 #include <drivers/gpio_spi.h> 19 #include <drivers/measured_boot/metadata.h> 20 #include <drivers/tpm/tpm2.h> 21 #include <drivers/tpm/tpm2_chip.h> 22 #include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h> 23 #include <event_measure.h> 24 #include <event_print.h> 25 #include <rpi_shared.h> 26 27 /* Event Log data */ 28 uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; 29 static const struct event_log_hash_info crypto_hash_info = { 30 .func = crypto_mod_calc_hash, 31 .ids = (const uint32_t[]){ CRYPTO_MD_ID }, 32 .count = 1U, 33 }; 34 35 /* RPI3 table with platform specific image IDs, names and PCRs */ 36 const event_log_metadata_t rpi3_event_log_metadata[] = { 37 { FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 }, 38 { TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 }, 39 { BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 }, 40 41 { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ 42 }; 43 44 #if DISCRETE_TPM 45 extern struct tpm_chip_data tpm_chip_data; 46 #if (TPM_INTERFACE == FIFO_SPI) 47 extern struct gpio_spi_data tpm_rpi3_gpio_data; 48 struct spi_plat *spidev; 49 #endif 50 51 static void rpi3_bl1_tpm_early_interface_setup(void) 52 { 53 #if (TPM_INTERFACE == FIFO_SPI) 54 tpm2_slb9670_gpio_init(&tpm_rpi3_gpio_data); 55 56 tpm2_slb9670_reset_chip(&tpm_rpi3_gpio_data); 57 58 spidev = gpio_spi_init(&tpm_rpi3_gpio_data); 59 #endif 60 } 61 #endif 62 63 void bl1_plat_mboot_init(void) 64 { 65 #if DISCRETE_TPM 66 int rc; 67 68 rpi3_bl1_tpm_early_interface_setup(); 69 rc = tpm_interface_init(&tpm_chip_data, 0); 70 if (rc != 0) { 71 ERROR("BL1: TPM interface init failed\n"); 72 panic(); 73 } 74 rc = tpm_startup(&tpm_chip_data, TPM_SU_CLEAR); 75 if (rc != 0) { 76 ERROR("BL1: TPM Startup failed\n"); 77 panic(); 78 } 79 #endif 80 81 rc = event_log_init_and_reg(event_log, event_log + sizeof(event_log), 82 &crypto_hash_info); 83 if (rc < 0) { 84 ERROR("Failed to initialize event log (%d).\n", rc); 85 panic(); 86 } 87 88 rc = event_log_write_header(); 89 if (rc < 0) { 90 ERROR("Failed to write event log header (%d).\n", rc); 91 panic(); 92 } 93 } 94 95 void bl1_plat_mboot_finish(void) 96 { 97 size_t event_log_cur_size; 98 image_desc_t *image_desc; 99 entry_point_info_t *ep_info; 100 101 event_log_cur_size = event_log_get_cur_size(event_log); 102 image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); 103 assert(image_desc != NULL); 104 105 /* Get the entry point info */ 106 ep_info = &image_desc->ep_info; 107 ep_info->args.arg2 = (uint64_t) event_log; 108 ep_info->args.arg3 = (uint32_t) event_log_cur_size; 109 110 #if DISCRETE_TPM 111 int rc; 112 113 /* relinquish control of TPM locality 0 and close interface */ 114 rc = tpm_interface_close(&tpm_chip_data, 0); 115 if (rc != 0) { 116 ERROR("BL1: TPM interface close failed\n"); 117 panic(); 118 } 119 #endif 120 } 121 122 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data) 123 { 124 int rc = 0; 125 unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 126 const event_log_metadata_t *metadata_ptr = rpi3_event_log_metadata; 127 128 rc = event_log_measure(image_data->image_base, image_data->image_size, hash_data); 129 if (rc != 0) { 130 return rc; 131 } 132 133 #if DISCRETE_TPM 134 rc = tpm_pcr_extend(&tpm_chip_data, 0, TPM_ALG_ID, hash_data, TCG_DIGEST_SIZE); 135 if (rc != 0) { 136 ERROR("BL1: TPM PCR-0 extend failed\n"); 137 panic(); 138 } 139 #endif 140 141 while ((metadata_ptr->id != EVLOG_INVALID_ID) && 142 (metadata_ptr->id != image_id)) { 143 metadata_ptr++; 144 } 145 assert(metadata_ptr->id != EVLOG_INVALID_ID); 146 147 event_log_record(hash_data, EV_POST_CODE, metadata_ptr); 148 149 /* Dump Event Log for user view */ 150 event_log_dump((uint8_t *)event_log, event_log_get_cur_size(event_log)); 151 152 return rc; 153 } 154