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