blob: 867870bb5f4f74bd84f5fe51367a37e74e86d472 [file] [log] [blame]
Manish V Badarkhe8a766032022-02-23 11:26:53 +00001/*
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
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000015#include <arch.h>
16#include <arch_helpers.h>
johpow01baa3e6c2022-03-11 17:50:58 -060017#include <common/bl_common.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000018#include <common/debug.h>
19#include <common/runtime_svc.h>
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000020#include <drivers/auth/crypto_mod.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000021#include "drtm_main.h"
johpow01baa3e6c2022-03-11 17:50:58 -060022#include <lib/xlat_tables/xlat_tables_v2.h>
23#include <plat/common/platform.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000024#include <services/drtm_svc.h>
johpow01baa3e6c2022-03-11 17:50:58 -060025#include <platform_def.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000026
johpow01baa3e6c2022-03-11 17:50:58 -060027/* Structure to store DRTM features specific to the platform. */
28static drtm_features_t plat_drtm_features;
29
30/* DRTM-formatted memory map. */
31static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000032
Manish V Badarkhe8a766032022-02-23 11:26:53 +000033int drtm_setup(void)
34{
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000035 bool rc;
johpow01baa3e6c2022-03-11 17:50:58 -060036 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;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000039
Manish V Badarkhe8a766032022-02-23 11:26:53 +000040 INFO("DRTM service setup\n");
41
johpow01baa3e6c2022-03-11 17:50:58 -060042 /* Read boot PE ID from MPIDR */
43 plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000044
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
johpow01baa3e6c2022-03-11 17:50:58 -060057 /* 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
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000119 return 0;
120}
121
Manish V Badarkhe8401e1a2022-06-16 13:46:43 +0100122static inline uint64_t drtm_features_tpm(void *ctx)
123{
124 SMC_RET2(ctx, 1ULL, /* TPM feature is supported */
125 plat_drtm_features.tpm_features);
126}
127
128static inline uint64_t drtm_features_mem_req(void *ctx)
129{
130 SMC_RET2(ctx, 1ULL, /* memory req Feature is supported */
131 plat_drtm_features.minimum_memory_requirement);
132}
133
134static inline uint64_t drtm_features_boot_pe_id(void *ctx)
135{
136 SMC_RET2(ctx, 1ULL, /* Boot PE feature is supported */
137 plat_drtm_features.boot_pe_id);
138}
139
140static inline uint64_t drtm_features_dma_prot(void *ctx)
141{
142 SMC_RET2(ctx, 1ULL, /* DMA protection feature is supported */
143 plat_drtm_features.dma_prot_features);
144}
145
146static inline uint64_t drtm_features_tcb_hashes(void *ctx)
147{
148 SMC_RET2(ctx, 1ULL, /* TCB hash feature is supported */
149 plat_drtm_features.tcb_hash_features);
150}
151
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000152uint64_t drtm_smc_handler(uint32_t smc_fid,
153 uint64_t x1,
154 uint64_t x2,
155 uint64_t x3,
156 uint64_t x4,
157 void *cookie,
158 void *handle,
159 uint64_t flags)
160{
161 /* Check that the SMC call is from the Normal World. */
162 if (!is_caller_non_secure(flags)) {
163 SMC_RET1(handle, NOT_SUPPORTED);
164 }
165
166 switch (smc_fid) {
167 case ARM_DRTM_SVC_VERSION:
168 INFO("DRTM service handler: version\n");
169 /* Return the version of current implementation */
170 SMC_RET1(handle, ARM_DRTM_VERSION);
171 break; /* not reached */
172
173 case ARM_DRTM_SVC_FEATURES:
174 if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) ==
175 ARM_DRTM_FUNC_ID) {
176 /* Dispatch function-based queries. */
177 switch (x1 & FUNCID_MASK) {
178 case ARM_DRTM_SVC_VERSION:
179 SMC_RET1(handle, SUCCESS);
180 break; /* not reached */
181
182 case ARM_DRTM_SVC_FEATURES:
183 SMC_RET1(handle, SUCCESS);
184 break; /* not reached */
185
186 case ARM_DRTM_SVC_UNPROTECT_MEM:
187 SMC_RET1(handle, SUCCESS);
188 break; /* not reached */
189
190 case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
191 SMC_RET1(handle, SUCCESS);
192 break; /* not reached */
193
194 case ARM_DRTM_SVC_CLOSE_LOCALITY:
195 WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s",
196 "is not supported\n");
197 SMC_RET1(handle, NOT_SUPPORTED);
198 break; /* not reached */
199
200 case ARM_DRTM_SVC_GET_ERROR:
201 SMC_RET1(handle, SUCCESS);
202 break; /* not reached */
203
204 case ARM_DRTM_SVC_SET_ERROR:
205 SMC_RET1(handle, SUCCESS);
206 break; /* not reached */
207
208 case ARM_DRTM_SVC_SET_TCB_HASH:
209 WARN("ARM_DRTM_SVC_TCB_HASH feature %s",
210 "is not supported\n");
211 SMC_RET1(handle, NOT_SUPPORTED);
212 break; /* not reached */
213
214 case ARM_DRTM_SVC_LOCK_TCB_HASH:
215 WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s",
216 "is not supported\n");
217 SMC_RET1(handle, NOT_SUPPORTED);
218 break; /* not reached */
219
220 default:
221 ERROR("Unknown DRTM service function\n");
222 SMC_RET1(handle, NOT_SUPPORTED);
223 break; /* not reached */
224 }
Manish V Badarkhe8401e1a2022-06-16 13:46:43 +0100225 } else {
226 /* Dispatch feature-based queries. */
227 switch (x1 & ARM_DRTM_FEAT_ID_MASK) {
228 case ARM_DRTM_FEATURES_TPM:
229 INFO("++ DRTM service handler: TPM features\n");
230 return drtm_features_tpm(handle);
231 break; /* not reached */
232
233 case ARM_DRTM_FEATURES_MEM_REQ:
234 INFO("++ DRTM service handler: Min. mem."
235 " requirement features\n");
236 return drtm_features_mem_req(handle);
237 break; /* not reached */
238
239 case ARM_DRTM_FEATURES_DMA_PROT:
240 INFO("++ DRTM service handler: "
241 "DMA protection features\n");
242 return drtm_features_dma_prot(handle);
243 break; /* not reached */
244
245 case ARM_DRTM_FEATURES_BOOT_PE_ID:
246 INFO("++ DRTM service handler: "
247 "Boot PE ID features\n");
248 return drtm_features_boot_pe_id(handle);
249 break; /* not reached */
250
251 case ARM_DRTM_FEATURES_TCB_HASHES:
252 INFO("++ DRTM service handler: "
253 "TCB-hashes features\n");
254 return drtm_features_tcb_hashes(handle);
255 break; /* not reached */
256
257 default:
258 ERROR("Unknown ARM DRTM service feature\n");
259 SMC_RET1(handle, NOT_SUPPORTED);
260 break; /* not reached */
261 }
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000262 }
263
264 case ARM_DRTM_SVC_UNPROTECT_MEM:
265 INFO("DRTM service handler: unprotect mem\n");
266 SMC_RET1(handle, SMC_OK);
267 break; /* not reached */
268
269 case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
270 INFO("DRTM service handler: dynamic launch\n");
271 SMC_RET1(handle, SMC_OK);
272 break; /* not reached */
273
274 case ARM_DRTM_SVC_CLOSE_LOCALITY:
275 WARN("DRTM service handler: close locality %s\n",
276 "is not supported");
277 SMC_RET1(handle, NOT_SUPPORTED);
278 break; /* not reached */
279
280 case ARM_DRTM_SVC_GET_ERROR:
281 INFO("DRTM service handler: get error\n");
282 SMC_RET2(handle, SMC_OK, 0);
283 break; /* not reached */
284
285 case ARM_DRTM_SVC_SET_ERROR:
286 INFO("DRTM service handler: set error\n");
287 SMC_RET1(handle, SMC_OK);
288 break; /* not reached */
289
290 case ARM_DRTM_SVC_SET_TCB_HASH:
291 WARN("DRTM service handler: set TCB hash %s\n",
292 "is not supported");
293 SMC_RET1(handle, NOT_SUPPORTED);
294 break; /* not reached */
295
296 case ARM_DRTM_SVC_LOCK_TCB_HASH:
297 WARN("DRTM service handler: lock TCB hash %s\n",
298 "is not supported");
299 SMC_RET1(handle, NOT_SUPPORTED);
300 break; /* not reached */
301
302 default:
303 ERROR("Unknown DRTM service function: 0x%x\n", smc_fid);
304 SMC_RET1(handle, SMC_UNK);
305 break; /* not reached */
306 }
307
308 /* not reached */
309 SMC_RET1(handle, SMC_UNK);
310}