xref: /optee_os/core/include/kernel/ts_store.h (revision ef44161f847bb1f17e6c803e70047d749e7b394e)
16cb02818SJelle Sels /* SPDX-License-Identifier: BSD-2-Clause */
26cb02818SJelle Sels /*
36cb02818SJelle Sels  * Copyright (c) 2015-2019, Linaro Limited
46cb02818SJelle Sels  * Copyright (c) 2020, Arm Limited.
56cb02818SJelle Sels  */
66cb02818SJelle Sels #ifndef __KERNEL_TS_STORE_H
76cb02818SJelle Sels #define __KERNEL_TS_STORE_H
86cb02818SJelle Sels 
96cb02818SJelle Sels #include <tee_api_types.h>
106cb02818SJelle Sels 
116cb02818SJelle Sels struct ts_store_handle;
126cb02818SJelle Sels struct ts_store_ops {
136cb02818SJelle Sels 	/*
146cb02818SJelle Sels 	 * Human-readable string to describe where the TS comes from.
156cb02818SJelle Sels 	 * For debug purposes only.
166cb02818SJelle Sels 	 */
176cb02818SJelle Sels 	const char *description;
186cb02818SJelle Sels 	/*
196cb02818SJelle Sels 	 * Open a TS. Does not guarantee that the TS is valid or even exists.
206cb02818SJelle Sels 	 */
216cb02818SJelle Sels 	TEE_Result (*open)(const TEE_UUID *uuid,
226cb02818SJelle Sels 			   struct ts_store_handle **h);
236cb02818SJelle Sels 	/*
246cb02818SJelle Sels 	 * Return the size of the unencrypted TS binary, that is: the TS
25dea46be3SJelle Sels 	 * header (struct ta_head or sp_head) plus the ELF data.
266cb02818SJelle Sels 	 */
276cb02818SJelle Sels 	TEE_Result (*get_size)(const struct ts_store_handle *h,
286cb02818SJelle Sels 			       size_t *size);
296cb02818SJelle Sels 
306cb02818SJelle Sels 	/*
316cb02818SJelle Sels 	 * Return the tag or hash of the TS binary. Used to uniquely
326cb02818SJelle Sels 	 * identify the binary also if the binary happens to be updated.
336cb02818SJelle Sels 	 */
346cb02818SJelle Sels 	TEE_Result (*get_tag)(const struct ts_store_handle *h,
356cb02818SJelle Sels 			      uint8_t *tag, unsigned int *tag_len);
366cb02818SJelle Sels 	/*
376cb02818SJelle Sels 	 * Read the TS sequentially, from the start of the TS header (struct
38dea46be3SJelle Sels 	 * ta_head or sp_head) up to the end of the ELF.
396cb02818SJelle Sels 	 * The TEE core is expected to read *exactly* get_size() bytes in total
406cb02818SJelle Sels 	 * unless an error occurs. Therefore, an implementation may rely on the
416cb02818SJelle Sels 	 * condition (current offset == total size) to detect the last call to
426cb02818SJelle Sels 	 * this function.
43*ef44161fSJens Wiklander 	 * @data_core: pointer to secure memory where the TS bytes should be
44*ef44161fSJens Wiklander 	 *             copied.
45*ef44161fSJens Wiklander 	 * @data_user: pointer to user memory where the TS bytes should be
46*ef44161fSJens Wiklander 	 *             copied.
47*ef44161fSJens Wiklander 	 * At least one of @data_core and @data_user are normally NULL, but
48*ef44161fSJens Wiklander 	 * both are also permitted to be non-NULL.
49*ef44161fSJens Wiklander 	 * If @data_core == NULL and @data_user == NULL and @len != 0, the
50*ef44161fSJens Wiklander 	 * function should just skip @len bytes.
516cb02818SJelle Sels 	 */
52*ef44161fSJens Wiklander 	TEE_Result (*read)(struct ts_store_handle *h, void *data_core,
53*ef44161fSJens Wiklander 			   void *data_user, size_t len);
546cb02818SJelle Sels 	/*
556cb02818SJelle Sels 	 * Close a TS handle. Do nothing if @h == NULL.
566cb02818SJelle Sels 	 */
576cb02818SJelle Sels 	void (*close)(struct ts_store_handle *h);
586cb02818SJelle Sels };
596cb02818SJelle Sels 
606cb02818SJelle Sels /*
616cb02818SJelle Sels  * Registers a TA storage.
626cb02818SJelle Sels  *
636cb02818SJelle Sels  * A TA is loaded from the first TA storage in which the TA can be found.
646cb02818SJelle Sels  * TA storage is searched in order of priority, where lower values are
656cb02818SJelle Sels  * tried first.
666cb02818SJelle Sels  *
676cb02818SJelle Sels  * Note prio must be unique per storage in order to avoid dependency on
686cb02818SJelle Sels  * registration order. This is enforced by a deliberate linker error in
696cb02818SJelle Sels  * case of conflict.
706cb02818SJelle Sels  *
716cb02818SJelle Sels  * Also note that TA storage is sorted lexicographically instead of
726cb02818SJelle Sels  * numerically.
736cb02818SJelle Sels  */
746cb02818SJelle Sels #define REGISTER_TA_STORE(prio) \
756cb02818SJelle Sels 	int __tee_ta_store_##prio __unused; \
766cb02818SJelle Sels 	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(ta_stores, prio, \
776cb02818SJelle Sels 					       struct ts_store_ops)
786cb02818SJelle Sels 
79dea46be3SJelle Sels /*
80dea46be3SJelle Sels  * Registers a SP storage.
81dea46be3SJelle Sels  *
82dea46be3SJelle Sels  * The SP store is separate from the TA store. The user of the stores knows if
83dea46be3SJelle Sels  * it needs to access the TA store or if it needs to access the SP one.
84dea46be3SJelle Sels  */
85dea46be3SJelle Sels #define REGISTER_SP_STORE(prio) \
86dea46be3SJelle Sels 	int __tee_sp_store_##prio __unused; \
87dea46be3SJelle Sels 	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(sp_stores, prio, \
88dea46be3SJelle Sels 					       struct ts_store_ops)
896cb02818SJelle Sels #endif /*__KERNEL_TS_STORE_H*/
90