blob: f05a231f701d29fe044ab7b774bd99d856f2d7e2 [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"
Manish Pandeyfa2eb052022-06-20 17:42:41 +010022#include <lib/psci/psci_lib.h>
johpow01baa3e6c2022-03-11 17:50:58 -060023#include <lib/xlat_tables/xlat_tables_v2.h>
24#include <plat/common/platform.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000025#include <services/drtm_svc.h>
johpow01baa3e6c2022-03-11 17:50:58 -060026#include <platform_def.h>
Manish V Badarkhe8a766032022-02-23 11:26:53 +000027
johpow01baa3e6c2022-03-11 17:50:58 -060028/* Structure to store DRTM features specific to the platform. */
29static drtm_features_t plat_drtm_features;
30
31/* DRTM-formatted memory map. */
32static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000033
Manish V Badarkhe8a766032022-02-23 11:26:53 +000034int drtm_setup(void)
35{
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000036 bool rc;
johpow01baa3e6c2022-03-11 17:50:58 -060037 const plat_drtm_tpm_features_t *plat_tpm_feat;
38 const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
39 uint64_t dlme_data_min_size;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000040
Manish V Badarkhe8a766032022-02-23 11:26:53 +000041 INFO("DRTM service setup\n");
42
johpow01baa3e6c2022-03-11 17:50:58 -060043 /* Read boot PE ID from MPIDR */
44 plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
Manish V Badarkhecc2c7432022-02-24 20:22:39 +000045
46 rc = drtm_dma_prot_init();
47 if (rc) {
48 return INTERNAL_ERROR;
49 }
50
51 /*
52 * initialise the platform supported crypto module that will
53 * be used by the DRTM-service to calculate hash of DRTM-
54 * implementation specific components
55 */
56 crypto_mod_init();
57
johpow01baa3e6c2022-03-11 17:50:58 -060058 /* Build DRTM-compatible address map. */
59 plat_drtm_mem_map = drtm_build_address_map();
60 if (plat_drtm_mem_map == NULL) {
61 return INTERNAL_ERROR;
62 }
63
64 /* Get DRTM features from platform hooks. */
65 plat_tpm_feat = plat_drtm_get_tpm_features();
66 if (plat_tpm_feat == NULL) {
67 return INTERNAL_ERROR;
68 }
69
70 plat_dma_prot_feat = plat_drtm_get_dma_prot_features();
71 if (plat_dma_prot_feat == NULL) {
72 return INTERNAL_ERROR;
73 }
74
75 /*
76 * Add up minimum DLME data memory.
77 *
78 * For systems with complete DMA protection there is only one entry in
79 * the protected regions table.
80 */
81 if (plat_dma_prot_feat->dma_protection_support ==
82 ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE) {
83 dlme_data_min_size =
84 sizeof(drtm_memory_region_descriptor_table_t) +
85 sizeof(drtm_mem_region_t);
86 } else {
87 /*
88 * TODO set protected regions table size based on platform DMA
89 * protection configuration
90 */
91 panic();
92 }
93
94 dlme_data_min_size += (drtm_get_address_map_size() +
95 PLAT_DRTM_EVENT_LOG_MAX_SIZE +
96 plat_drtm_get_tcb_hash_table_size() +
97 plat_drtm_get_imp_def_dlme_region_size());
98
99 dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE;
100
101 /* Fill out platform DRTM features structure */
102 /* Only support default PCR schema (0x1) in this implementation. */
103 ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(plat_drtm_features.tpm_features,
104 ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT);
105 ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(plat_drtm_features.tpm_features,
106 plat_tpm_feat->tpm_based_hash_support);
107 ARM_DRTM_TPM_FEATURES_SET_FW_HASH(plat_drtm_features.tpm_features,
108 plat_tpm_feat->firmware_hash_algorithm);
109 ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(plat_drtm_features.minimum_memory_requirement,
110 dlme_data_min_size);
111 ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(plat_drtm_features.minimum_memory_requirement,
112 plat_drtm_get_min_size_normal_world_dce());
113 ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(plat_drtm_features.dma_prot_features,
114 plat_dma_prot_feat->max_num_mem_prot_regions);
115 ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(plat_drtm_features.dma_prot_features,
116 plat_dma_prot_feat->dma_protection_support);
117 ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features,
118 plat_drtm_get_tcb_hash_features());
119
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000120 return 0;
121}
122
Manish V Badarkhe8401e1a2022-06-16 13:46:43 +0100123static inline uint64_t drtm_features_tpm(void *ctx)
124{
125 SMC_RET2(ctx, 1ULL, /* TPM feature is supported */
126 plat_drtm_features.tpm_features);
127}
128
129static inline uint64_t drtm_features_mem_req(void *ctx)
130{
131 SMC_RET2(ctx, 1ULL, /* memory req Feature is supported */
132 plat_drtm_features.minimum_memory_requirement);
133}
134
135static inline uint64_t drtm_features_boot_pe_id(void *ctx)
136{
137 SMC_RET2(ctx, 1ULL, /* Boot PE feature is supported */
138 plat_drtm_features.boot_pe_id);
139}
140
141static inline uint64_t drtm_features_dma_prot(void *ctx)
142{
143 SMC_RET2(ctx, 1ULL, /* DMA protection feature is supported */
144 plat_drtm_features.dma_prot_features);
145}
146
147static inline uint64_t drtm_features_tcb_hashes(void *ctx)
148{
149 SMC_RET2(ctx, 1ULL, /* TCB hash feature is supported */
150 plat_drtm_features.tcb_hash_features);
151}
152
Manish Pandeyfa2eb052022-06-20 17:42:41 +0100153static enum drtm_retc drtm_dl_check_caller_el(void *ctx)
154{
155 uint64_t spsr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
156 uint64_t dl_caller_el;
157 uint64_t dl_caller_aarch;
158
159 dl_caller_el = spsr_el3 >> MODE_EL_SHIFT & MODE_EL_MASK;
160 dl_caller_aarch = spsr_el3 >> MODE_RW_SHIFT & MODE_RW_MASK;
161
162 /* Caller's security state is checked from drtm_smc_handle function */
163
164 /* Caller can be NS-EL2/EL1 */
165 if (dl_caller_el == MODE_EL3) {
166 ERROR("DRTM: invalid launch from EL3\n");
167 return DENIED;
168 }
169
170 if (dl_caller_aarch != MODE_RW_64) {
171 ERROR("DRTM: invalid launch from non-AArch64 execution state\n");
172 return DENIED;
173 }
174
175 return SUCCESS;
176}
177
178static enum drtm_retc drtm_dl_check_cores(void)
179{
180 bool running_on_single_core;
181 uint64_t this_pe_aff_value = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
182
183 if (this_pe_aff_value != plat_drtm_features.boot_pe_id) {
184 ERROR("DRTM: invalid launch on a non-boot PE\n");
185 return DENIED;
186 }
187
188 running_on_single_core = psci_is_last_on_cpu_safe();
189 if (!running_on_single_core) {
190 ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
191 return DENIED;
192 }
193
194 return SUCCESS;
195}
196
197static uint64_t drtm_dynamic_launch(uint64_t x1, void *handle)
198{
199 enum drtm_retc ret = SUCCESS;
200
201 /* Ensure that only boot PE is powered on */
202 ret = drtm_dl_check_cores();
203 if (ret != SUCCESS) {
204 SMC_RET1(handle, ret);
205 }
206
207 /*
208 * Ensure that execution state is AArch64 and the caller
209 * is highest non-secure exception level
210 */
211 ret = drtm_dl_check_caller_el(handle);
212 if (ret != SUCCESS) {
213 SMC_RET1(handle, ret);
214 }
215
216 SMC_RET1(handle, ret);
217}
218
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000219uint64_t drtm_smc_handler(uint32_t smc_fid,
220 uint64_t x1,
221 uint64_t x2,
222 uint64_t x3,
223 uint64_t x4,
224 void *cookie,
225 void *handle,
226 uint64_t flags)
227{
228 /* Check that the SMC call is from the Normal World. */
229 if (!is_caller_non_secure(flags)) {
230 SMC_RET1(handle, NOT_SUPPORTED);
231 }
232
233 switch (smc_fid) {
234 case ARM_DRTM_SVC_VERSION:
235 INFO("DRTM service handler: version\n");
236 /* Return the version of current implementation */
237 SMC_RET1(handle, ARM_DRTM_VERSION);
238 break; /* not reached */
239
240 case ARM_DRTM_SVC_FEATURES:
241 if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) ==
242 ARM_DRTM_FUNC_ID) {
243 /* Dispatch function-based queries. */
244 switch (x1 & FUNCID_MASK) {
245 case ARM_DRTM_SVC_VERSION:
246 SMC_RET1(handle, SUCCESS);
247 break; /* not reached */
248
249 case ARM_DRTM_SVC_FEATURES:
250 SMC_RET1(handle, SUCCESS);
251 break; /* not reached */
252
253 case ARM_DRTM_SVC_UNPROTECT_MEM:
254 SMC_RET1(handle, SUCCESS);
255 break; /* not reached */
256
257 case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
258 SMC_RET1(handle, SUCCESS);
259 break; /* not reached */
260
261 case ARM_DRTM_SVC_CLOSE_LOCALITY:
262 WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s",
263 "is not supported\n");
264 SMC_RET1(handle, NOT_SUPPORTED);
265 break; /* not reached */
266
267 case ARM_DRTM_SVC_GET_ERROR:
268 SMC_RET1(handle, SUCCESS);
269 break; /* not reached */
270
271 case ARM_DRTM_SVC_SET_ERROR:
272 SMC_RET1(handle, SUCCESS);
273 break; /* not reached */
274
275 case ARM_DRTM_SVC_SET_TCB_HASH:
276 WARN("ARM_DRTM_SVC_TCB_HASH feature %s",
277 "is not supported\n");
278 SMC_RET1(handle, NOT_SUPPORTED);
279 break; /* not reached */
280
281 case ARM_DRTM_SVC_LOCK_TCB_HASH:
282 WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s",
283 "is not supported\n");
284 SMC_RET1(handle, NOT_SUPPORTED);
285 break; /* not reached */
286
287 default:
288 ERROR("Unknown DRTM service function\n");
289 SMC_RET1(handle, NOT_SUPPORTED);
290 break; /* not reached */
291 }
Manish V Badarkhe8401e1a2022-06-16 13:46:43 +0100292 } else {
293 /* Dispatch feature-based queries. */
294 switch (x1 & ARM_DRTM_FEAT_ID_MASK) {
295 case ARM_DRTM_FEATURES_TPM:
296 INFO("++ DRTM service handler: TPM features\n");
297 return drtm_features_tpm(handle);
298 break; /* not reached */
299
300 case ARM_DRTM_FEATURES_MEM_REQ:
301 INFO("++ DRTM service handler: Min. mem."
302 " requirement features\n");
303 return drtm_features_mem_req(handle);
304 break; /* not reached */
305
306 case ARM_DRTM_FEATURES_DMA_PROT:
307 INFO("++ DRTM service handler: "
308 "DMA protection features\n");
309 return drtm_features_dma_prot(handle);
310 break; /* not reached */
311
312 case ARM_DRTM_FEATURES_BOOT_PE_ID:
313 INFO("++ DRTM service handler: "
314 "Boot PE ID features\n");
315 return drtm_features_boot_pe_id(handle);
316 break; /* not reached */
317
318 case ARM_DRTM_FEATURES_TCB_HASHES:
319 INFO("++ DRTM service handler: "
320 "TCB-hashes features\n");
321 return drtm_features_tcb_hashes(handle);
322 break; /* not reached */
323
324 default:
325 ERROR("Unknown ARM DRTM service feature\n");
326 SMC_RET1(handle, NOT_SUPPORTED);
327 break; /* not reached */
328 }
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000329 }
330
331 case ARM_DRTM_SVC_UNPROTECT_MEM:
332 INFO("DRTM service handler: unprotect mem\n");
333 SMC_RET1(handle, SMC_OK);
334 break; /* not reached */
335
336 case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
337 INFO("DRTM service handler: dynamic launch\n");
Manish Pandeyfa2eb052022-06-20 17:42:41 +0100338 return drtm_dynamic_launch(x1, handle);
Manish V Badarkhe8a766032022-02-23 11:26:53 +0000339 break; /* not reached */
340
341 case ARM_DRTM_SVC_CLOSE_LOCALITY:
342 WARN("DRTM service handler: close locality %s\n",
343 "is not supported");
344 SMC_RET1(handle, NOT_SUPPORTED);
345 break; /* not reached */
346
347 case ARM_DRTM_SVC_GET_ERROR:
348 INFO("DRTM service handler: get error\n");
349 SMC_RET2(handle, SMC_OK, 0);
350 break; /* not reached */
351
352 case ARM_DRTM_SVC_SET_ERROR:
353 INFO("DRTM service handler: set error\n");
354 SMC_RET1(handle, SMC_OK);
355 break; /* not reached */
356
357 case ARM_DRTM_SVC_SET_TCB_HASH:
358 WARN("DRTM service handler: set TCB hash %s\n",
359 "is not supported");
360 SMC_RET1(handle, NOT_SUPPORTED);
361 break; /* not reached */
362
363 case ARM_DRTM_SVC_LOCK_TCB_HASH:
364 WARN("DRTM service handler: lock TCB hash %s\n",
365 "is not supported");
366 SMC_RET1(handle, NOT_SUPPORTED);
367 break; /* not reached */
368
369 default:
370 ERROR("Unknown DRTM service function: 0x%x\n", smc_fid);
371 SMC_RET1(handle, SMC_UNK);
372 break; /* not reached */
373 }
374
375 /* not reached */
376 SMC_RET1(handle, SMC_UNK);
377}