xref: /optee_os/core/kernel/tpm.c (revision bce2f88ab347b28f4149dacef2ad48ac67a500b6)
1dd333f03SJavier Almansa Sobrino // SPDX-License-Identifier: BSD-3-Clause
2dd333f03SJavier Almansa Sobrino /*
315483bdeSBalint Dobszay  * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
4dd333f03SJavier Almansa Sobrino  */
5dd333f03SJavier Almansa Sobrino 
6dd333f03SJavier Almansa Sobrino #include <compiler.h>
7dd333f03SJavier Almansa Sobrino #include <kernel/dt.h>
8a2fc83d1SJerome Forissier #include <kernel/tpm.h>
9dd333f03SJavier Almansa Sobrino #include <libfdt.h>
10a2fc83d1SJerome Forissier #include <mm/core_memprot.h>
11a2fc83d1SJerome Forissier #include <string.h>
12dd333f03SJavier Almansa Sobrino 
13dd333f03SJavier Almansa Sobrino static void *tpm_log_addr;
14dd333f03SJavier Almansa Sobrino static size_t tpm_log_size;
15dd333f03SJavier Almansa Sobrino 
16dd333f03SJavier Almansa Sobrino /*
17dd333f03SJavier Almansa Sobrino  * Check whether the node at @offs contains TPM Event Log information or not.
18dd333f03SJavier Almansa Sobrino  *
19dd333f03SJavier Almansa Sobrino  * @offs is the offset of the node that describes the device in @fdt.
20dd333f03SJavier Almansa Sobrino  * @buf will contain the phy address of the TPM Event log.
21dd333f03SJavier Almansa Sobrino  * @size will contain the size of the mapped area.
22dd333f03SJavier Almansa Sobrino  *
23dd333f03SJavier Almansa Sobrino  * Returns the size of the mapped area or < 0 on failure.
24dd333f03SJavier Almansa Sobrino  */
25dd333f03SJavier Almansa Sobrino #ifdef CFG_DT
26dd333f03SJavier Almansa Sobrino static int read_dt_tpm_log_info(void *fdt, int node, paddr_t *buf,
27dd333f03SJavier Almansa Sobrino 				size_t *size)
28dd333f03SJavier Almansa Sobrino {
29dd333f03SJavier Almansa Sobrino 	const uint32_t *property = NULL;
30dd333f03SJavier Almansa Sobrino 	const uint64_t zero_addr = 0;
31dd333f03SJavier Almansa Sobrino 	int len_prop = 0;
32dd333f03SJavier Almansa Sobrino 	paddr_t log_addr = 0;
33dd333f03SJavier Almansa Sobrino 	int err = 0;
34bf31bf10SImre Kis #ifdef CFG_MAP_EXT_DT_SECURE
35bf31bf10SImre Kis 	const char *dt_tpm_event_log_addr = "tpm_event_log_addr";
36bf31bf10SImre Kis #else
37bf31bf10SImre Kis 	const char *dt_tpm_event_log_addr = "tpm_event_log_sm_addr";
38bf31bf10SImre Kis #endif
39dd333f03SJavier Almansa Sobrino 
40dd333f03SJavier Almansa Sobrino 	/*
41dd333f03SJavier Almansa Sobrino 	 * Get the TPM Log address.
42dd333f03SJavier Almansa Sobrino 	 */
43bf31bf10SImre Kis 	property = fdt_getprop(fdt, node, dt_tpm_event_log_addr, &len_prop);
44dd333f03SJavier Almansa Sobrino 
45dd333f03SJavier Almansa Sobrino 	if (!property  || len_prop != sizeof(uint32_t) * 2)
46dd333f03SJavier Almansa Sobrino 		return -1;
47dd333f03SJavier Almansa Sobrino 
48dd333f03SJavier Almansa Sobrino 	log_addr = fdt32_to_cpu(property[1]);
49dd333f03SJavier Almansa Sobrino 
5015483bdeSBalint Dobszay 	if (!IS_ENABLED(CFG_CORE_SEL1_SPMC)) {
51bf31bf10SImre Kis 		err = fdt_setprop(fdt, node, dt_tpm_event_log_addr, &zero_addr,
52dd333f03SJavier Almansa Sobrino 				  sizeof(uint32_t) * 2);
53dd333f03SJavier Almansa Sobrino 		if (err < 0) {
54*bce2f88aSVincent Mailhol 			EMSG("Error setting property DTB to zero");
55dd333f03SJavier Almansa Sobrino 			return err;
56dd333f03SJavier Almansa Sobrino 		}
5715483bdeSBalint Dobszay 	}
58dd333f03SJavier Almansa Sobrino 
59dd333f03SJavier Almansa Sobrino 	/*
60dd333f03SJavier Almansa Sobrino 	 * Get the TPM Log size.
61dd333f03SJavier Almansa Sobrino 	 */
62dd333f03SJavier Almansa Sobrino 	property = fdt_getprop(fdt, node, "tpm_event_log_size", &len_prop);
63dd333f03SJavier Almansa Sobrino 
64dd333f03SJavier Almansa Sobrino 	if (!property || len_prop != sizeof(uint32_t))
65dd333f03SJavier Almansa Sobrino 		return -1;
66dd333f03SJavier Almansa Sobrino 
67dd333f03SJavier Almansa Sobrino 	*size = fdt32_to_cpu(property[0]);
68dd333f03SJavier Almansa Sobrino 	*buf = log_addr;
69dd333f03SJavier Almansa Sobrino 
70dd333f03SJavier Almansa Sobrino 	return *size;
71dd333f03SJavier Almansa Sobrino }
72dd333f03SJavier Almansa Sobrino #endif
73dd333f03SJavier Almansa Sobrino 
74dd333f03SJavier Almansa Sobrino static void get_tpm_phys_params(void *fdt __maybe_unused,
75dd333f03SJavier Almansa Sobrino 				paddr_t *addr, size_t *size)
76dd333f03SJavier Almansa Sobrino {
77dd333f03SJavier Almansa Sobrino #ifdef CFG_DT
78dd333f03SJavier Almansa Sobrino 	int node = 0;
79dd333f03SJavier Almansa Sobrino 	const char *dt_tpm_match_table = {
801554a779SJavier Almansa Sobrino 		"arm,tpm_event_log",
81dd333f03SJavier Almansa Sobrino 	};
82dd333f03SJavier Almansa Sobrino 
83dd333f03SJavier Almansa Sobrino 	if (!fdt) {
84dd333f03SJavier Almansa Sobrino 		EMSG("TPM: No DTB found");
85dd333f03SJavier Almansa Sobrino 		return;
86dd333f03SJavier Almansa Sobrino 	}
87dd333f03SJavier Almansa Sobrino 
88dd333f03SJavier Almansa Sobrino 	node = fdt_node_offset_by_compatible(fdt, -1, dt_tpm_match_table);
89dd333f03SJavier Almansa Sobrino 
90dd333f03SJavier Almansa Sobrino 	if (node < 0) {
91dd333f03SJavier Almansa Sobrino 		EMSG("TPM: Fail to find TPM node %i", node);
92dd333f03SJavier Almansa Sobrino 		return;
93dd333f03SJavier Almansa Sobrino 	}
94dd333f03SJavier Almansa Sobrino 
95dd333f03SJavier Almansa Sobrino 	if (read_dt_tpm_log_info((void *)fdt, node, addr, size) < 0) {
96dd333f03SJavier Almansa Sobrino 		EMSG("TPM: Fail to retrieve DTB properties from node %i",
97dd333f03SJavier Almansa Sobrino 		     node);
98dd333f03SJavier Almansa Sobrino 		return;
99dd333f03SJavier Almansa Sobrino 	}
100dd333f03SJavier Almansa Sobrino #else
101dd333f03SJavier Almansa Sobrino 	*size = CFG_TPM_MAX_LOG_SIZE;
102dd333f03SJavier Almansa Sobrino 	*addr = CFG_TPM_LOG_BASE_ADDR;
103dd333f03SJavier Almansa Sobrino #endif /* CFG_DT */
104dd333f03SJavier Almansa Sobrino }
105dd333f03SJavier Almansa Sobrino 
106dd333f03SJavier Almansa Sobrino TEE_Result tpm_get_event_log(void *buf, size_t *size)
107dd333f03SJavier Almansa Sobrino {
108dd333f03SJavier Almansa Sobrino 	const size_t buf_size = *size;
109dd333f03SJavier Almansa Sobrino 
110dd333f03SJavier Almansa Sobrino 	*size = tpm_log_size;
111dd333f03SJavier Almansa Sobrino 	if (!buf) {
112dd333f03SJavier Almansa Sobrino 		EMSG("TPM: Invalid buffer");
113dd333f03SJavier Almansa Sobrino 		return TEE_ERROR_BAD_PARAMETERS;
114dd333f03SJavier Almansa Sobrino 	}
115dd333f03SJavier Almansa Sobrino 
116dd333f03SJavier Almansa Sobrino 	if (buf_size < tpm_log_size) {
11797db86ceSEtienne Carriere 		EMSG("TPM: Not enough space for the log: %zu, %zu",
118dd333f03SJavier Almansa Sobrino 		     buf_size, tpm_log_size);
119dd333f03SJavier Almansa Sobrino 		return TEE_ERROR_SHORT_BUFFER;
120dd333f03SJavier Almansa Sobrino 	}
121dd333f03SJavier Almansa Sobrino 
122dd333f03SJavier Almansa Sobrino 	memcpy(buf, tpm_log_addr, tpm_log_size);
123dd333f03SJavier Almansa Sobrino 
124dd333f03SJavier Almansa Sobrino 	return TEE_SUCCESS;
125dd333f03SJavier Almansa Sobrino }
126dd333f03SJavier Almansa Sobrino 
127145035ffSImre Kis TEE_Result tpm_get_event_log_size(size_t *size)
128145035ffSImre Kis {
129145035ffSImre Kis 	*size = tpm_log_size;
130145035ffSImre Kis 
131145035ffSImre Kis 	return TEE_SUCCESS;
132145035ffSImre Kis }
133145035ffSImre Kis 
134dd333f03SJavier Almansa Sobrino void tpm_map_log_area(void *fdt)
135dd333f03SJavier Almansa Sobrino {
136dd333f03SJavier Almansa Sobrino 	paddr_t log_addr = 0;
137dd333f03SJavier Almansa Sobrino 	unsigned int rounded_size = 0;
138dd333f03SJavier Almansa Sobrino 
139dd333f03SJavier Almansa Sobrino 	get_tpm_phys_params(fdt, &log_addr, &tpm_log_size);
140dd333f03SJavier Almansa Sobrino 
141dd333f03SJavier Almansa Sobrino 	DMSG("TPM Event log PA: %#" PRIxPA, log_addr);
142dd333f03SJavier Almansa Sobrino 	DMSG("TPM Event log size: %zu Bytes", tpm_log_size);
143dd333f03SJavier Almansa Sobrino 
144dd333f03SJavier Almansa Sobrino 	rounded_size = ROUNDUP(tpm_log_size, SMALL_PAGE_SIZE);
145dd333f03SJavier Almansa Sobrino 
146bc9618c0SAnton Rybakov 	tpm_log_addr = core_mmu_add_mapping(MEM_AREA_RAM_SEC, log_addr,
147bc9618c0SAnton Rybakov 					    rounded_size);
148bc9618c0SAnton Rybakov 	if (!tpm_log_addr) {
149dd333f03SJavier Almansa Sobrino 		EMSG("TPM: Failed to map TPM log memory");
150dd333f03SJavier Almansa Sobrino 		return;
151dd333f03SJavier Almansa Sobrino 	}
152dd333f03SJavier Almansa Sobrino }
153