1 /* 2 * Copyright (c) 2022 Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * DRTM service 7 * 8 * Authors: 9 * Lucian Paul-Trifu <lucian.paultrifu@gmail.com> 10 * Brian Nezvadovitz <brinez@microsoft.com> 2021-02-01 11 */ 12 13 #include <stdint.h> 14 15 #include <arch.h> 16 #include <arch_helpers.h> 17 #include <common/bl_common.h> 18 #include <common/debug.h> 19 #include <common/runtime_svc.h> 20 #include <drivers/auth/crypto_mod.h> 21 #include "drtm_main.h" 22 #include <lib/xlat_tables/xlat_tables_v2.h> 23 #include <plat/common/platform.h> 24 #include <services/drtm_svc.h> 25 #include <platform_def.h> 26 27 /* Structure to store DRTM features specific to the platform. */ 28 static drtm_features_t plat_drtm_features; 29 30 /* DRTM-formatted memory map. */ 31 static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map; 32 33 int drtm_setup(void) 34 { 35 bool rc; 36 const plat_drtm_tpm_features_t *plat_tpm_feat; 37 const plat_drtm_dma_prot_features_t *plat_dma_prot_feat; 38 uint64_t dlme_data_min_size; 39 40 INFO("DRTM service setup\n"); 41 42 /* Read boot PE ID from MPIDR */ 43 plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK; 44 45 rc = drtm_dma_prot_init(); 46 if (rc) { 47 return INTERNAL_ERROR; 48 } 49 50 /* 51 * initialise the platform supported crypto module that will 52 * be used by the DRTM-service to calculate hash of DRTM- 53 * implementation specific components 54 */ 55 crypto_mod_init(); 56 57 /* Build DRTM-compatible address map. */ 58 plat_drtm_mem_map = drtm_build_address_map(); 59 if (plat_drtm_mem_map == NULL) { 60 return INTERNAL_ERROR; 61 } 62 63 /* Get DRTM features from platform hooks. */ 64 plat_tpm_feat = plat_drtm_get_tpm_features(); 65 if (plat_tpm_feat == NULL) { 66 return INTERNAL_ERROR; 67 } 68 69 plat_dma_prot_feat = plat_drtm_get_dma_prot_features(); 70 if (plat_dma_prot_feat == NULL) { 71 return INTERNAL_ERROR; 72 } 73 74 /* 75 * Add up minimum DLME data memory. 76 * 77 * For systems with complete DMA protection there is only one entry in 78 * the protected regions table. 79 */ 80 if (plat_dma_prot_feat->dma_protection_support == 81 ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE) { 82 dlme_data_min_size = 83 sizeof(drtm_memory_region_descriptor_table_t) + 84 sizeof(drtm_mem_region_t); 85 } else { 86 /* 87 * TODO set protected regions table size based on platform DMA 88 * protection configuration 89 */ 90 panic(); 91 } 92 93 dlme_data_min_size += (drtm_get_address_map_size() + 94 PLAT_DRTM_EVENT_LOG_MAX_SIZE + 95 plat_drtm_get_tcb_hash_table_size() + 96 plat_drtm_get_imp_def_dlme_region_size()); 97 98 dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE; 99 100 /* Fill out platform DRTM features structure */ 101 /* Only support default PCR schema (0x1) in this implementation. */ 102 ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(plat_drtm_features.tpm_features, 103 ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT); 104 ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(plat_drtm_features.tpm_features, 105 plat_tpm_feat->tpm_based_hash_support); 106 ARM_DRTM_TPM_FEATURES_SET_FW_HASH(plat_drtm_features.tpm_features, 107 plat_tpm_feat->firmware_hash_algorithm); 108 ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(plat_drtm_features.minimum_memory_requirement, 109 dlme_data_min_size); 110 ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(plat_drtm_features.minimum_memory_requirement, 111 plat_drtm_get_min_size_normal_world_dce()); 112 ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(plat_drtm_features.dma_prot_features, 113 plat_dma_prot_feat->max_num_mem_prot_regions); 114 ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(plat_drtm_features.dma_prot_features, 115 plat_dma_prot_feat->dma_protection_support); 116 ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features, 117 plat_drtm_get_tcb_hash_features()); 118 119 return 0; 120 } 121 122 uint64_t drtm_smc_handler(uint32_t smc_fid, 123 uint64_t x1, 124 uint64_t x2, 125 uint64_t x3, 126 uint64_t x4, 127 void *cookie, 128 void *handle, 129 uint64_t flags) 130 { 131 /* Check that the SMC call is from the Normal World. */ 132 if (!is_caller_non_secure(flags)) { 133 SMC_RET1(handle, NOT_SUPPORTED); 134 } 135 136 switch (smc_fid) { 137 case ARM_DRTM_SVC_VERSION: 138 INFO("DRTM service handler: version\n"); 139 /* Return the version of current implementation */ 140 SMC_RET1(handle, ARM_DRTM_VERSION); 141 break; /* not reached */ 142 143 case ARM_DRTM_SVC_FEATURES: 144 if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) == 145 ARM_DRTM_FUNC_ID) { 146 /* Dispatch function-based queries. */ 147 switch (x1 & FUNCID_MASK) { 148 case ARM_DRTM_SVC_VERSION: 149 SMC_RET1(handle, SUCCESS); 150 break; /* not reached */ 151 152 case ARM_DRTM_SVC_FEATURES: 153 SMC_RET1(handle, SUCCESS); 154 break; /* not reached */ 155 156 case ARM_DRTM_SVC_UNPROTECT_MEM: 157 SMC_RET1(handle, SUCCESS); 158 break; /* not reached */ 159 160 case ARM_DRTM_SVC_DYNAMIC_LAUNCH: 161 SMC_RET1(handle, SUCCESS); 162 break; /* not reached */ 163 164 case ARM_DRTM_SVC_CLOSE_LOCALITY: 165 WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s", 166 "is not supported\n"); 167 SMC_RET1(handle, NOT_SUPPORTED); 168 break; /* not reached */ 169 170 case ARM_DRTM_SVC_GET_ERROR: 171 SMC_RET1(handle, SUCCESS); 172 break; /* not reached */ 173 174 case ARM_DRTM_SVC_SET_ERROR: 175 SMC_RET1(handle, SUCCESS); 176 break; /* not reached */ 177 178 case ARM_DRTM_SVC_SET_TCB_HASH: 179 WARN("ARM_DRTM_SVC_TCB_HASH feature %s", 180 "is not supported\n"); 181 SMC_RET1(handle, NOT_SUPPORTED); 182 break; /* not reached */ 183 184 case ARM_DRTM_SVC_LOCK_TCB_HASH: 185 WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s", 186 "is not supported\n"); 187 SMC_RET1(handle, NOT_SUPPORTED); 188 break; /* not reached */ 189 190 default: 191 ERROR("Unknown DRTM service function\n"); 192 SMC_RET1(handle, NOT_SUPPORTED); 193 break; /* not reached */ 194 } 195 } 196 197 case ARM_DRTM_SVC_UNPROTECT_MEM: 198 INFO("DRTM service handler: unprotect mem\n"); 199 SMC_RET1(handle, SMC_OK); 200 break; /* not reached */ 201 202 case ARM_DRTM_SVC_DYNAMIC_LAUNCH: 203 INFO("DRTM service handler: dynamic launch\n"); 204 SMC_RET1(handle, SMC_OK); 205 break; /* not reached */ 206 207 case ARM_DRTM_SVC_CLOSE_LOCALITY: 208 WARN("DRTM service handler: close locality %s\n", 209 "is not supported"); 210 SMC_RET1(handle, NOT_SUPPORTED); 211 break; /* not reached */ 212 213 case ARM_DRTM_SVC_GET_ERROR: 214 INFO("DRTM service handler: get error\n"); 215 SMC_RET2(handle, SMC_OK, 0); 216 break; /* not reached */ 217 218 case ARM_DRTM_SVC_SET_ERROR: 219 INFO("DRTM service handler: set error\n"); 220 SMC_RET1(handle, SMC_OK); 221 break; /* not reached */ 222 223 case ARM_DRTM_SVC_SET_TCB_HASH: 224 WARN("DRTM service handler: set TCB hash %s\n", 225 "is not supported"); 226 SMC_RET1(handle, NOT_SUPPORTED); 227 break; /* not reached */ 228 229 case ARM_DRTM_SVC_LOCK_TCB_HASH: 230 WARN("DRTM service handler: lock TCB hash %s\n", 231 "is not supported"); 232 SMC_RET1(handle, NOT_SUPPORTED); 233 break; /* not reached */ 234 235 default: 236 ERROR("Unknown DRTM service function: 0x%x\n", smc_fid); 237 SMC_RET1(handle, SMC_UNK); 238 break; /* not reached */ 239 } 240 241 /* not reached */ 242 SMC_RET1(handle, SMC_UNK); 243 } 244