xref: /optee_os/core/include/tee/fs_htree.h (revision 623b9bd4ec219aa5d6a4eaec16d341e54ff658a9)
11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
250a81498SJens Wiklander /*
350a81498SJens Wiklander  * Copyright (c) 2017, Linaro Limited
450a81498SJens Wiklander  */
550a81498SJens Wiklander 
650a81498SJens Wiklander #ifndef __TEE_FS_HTREE_H
750a81498SJens Wiklander #define __TEE_FS_HTREE_H
850a81498SJens Wiklander 
950a81498SJens Wiklander /*
1050a81498SJens Wiklander  * The purpose of this API is to provide file integrity and confidentiality
1150a81498SJens Wiklander  * in order to implement secure storage. On-disk data structures are
1250a81498SJens Wiklander  * duplicated to make updates atomic, an update is finalized to disk with
1350a81498SJens Wiklander  * tee_fs_htree_sync_to_storage().
1450a81498SJens Wiklander  *
1550a81498SJens Wiklander  * This implementation doesn't provide rollback protection, it only
1650a81498SJens Wiklander  * guarantees the integrity and confidentiality of the file.
1750a81498SJens Wiklander  */
1850a81498SJens Wiklander 
19b4bfc9a9SJens Wiklander #include <stdint.h>
2050a81498SJens Wiklander #include <tee_api_types.h>
2150a81498SJens Wiklander #include <utee_defines.h>
2250a81498SJens Wiklander 
2350a81498SJens Wiklander #define TEE_FS_HTREE_HASH_SIZE		TEE_SHA256_HASH_SIZE
24b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_IV_SIZE		U(16)
25b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_FEK_SIZE		U(16)
26b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_TAG_SIZE		U(16)
2750a81498SJens Wiklander 
2850a81498SJens Wiklander /* Internal struct provided to let the rpc callbacks know the size if needed */
2950a81498SJens Wiklander struct tee_fs_htree_node_image {
3050a81498SJens Wiklander 	/* Note that calc_node_hash() depends on hash first in struct */
3150a81498SJens Wiklander 	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
3250a81498SJens Wiklander 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
3350a81498SJens Wiklander 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
3450a81498SJens Wiklander 	uint16_t flags;
3550a81498SJens Wiklander };
3650a81498SJens Wiklander 
3750a81498SJens Wiklander /*
3850a81498SJens Wiklander  * This struct is not interpreted by the hash tree, it's up to the user of
3950a81498SJens Wiklander  * the interface to update etc if needed.
4050a81498SJens Wiklander  */
4150a81498SJens Wiklander struct tee_fs_htree_meta {
4250a81498SJens Wiklander 	uint64_t length;
4350a81498SJens Wiklander };
4450a81498SJens Wiklander 
4550a81498SJens Wiklander /* Internal struct needed by struct tee_fs_htree_image */
4650a81498SJens Wiklander struct tee_fs_htree_imeta {
4750a81498SJens Wiklander 	struct tee_fs_htree_meta meta;
4850a81498SJens Wiklander 	uint32_t max_node_id;
4950a81498SJens Wiklander };
5050a81498SJens Wiklander 
5150a81498SJens Wiklander /* Internal struct provided to let the rpc callbacks know the size if needed */
5250a81498SJens Wiklander struct tee_fs_htree_image {
5350a81498SJens Wiklander 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
5450a81498SJens Wiklander 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
5550a81498SJens Wiklander 	uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];
5650a81498SJens Wiklander 	uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];
5750a81498SJens Wiklander 	uint32_t counter;
5850a81498SJens Wiklander };
5950a81498SJens Wiklander 
6050a81498SJens Wiklander /**
6150a81498SJens Wiklander  * enum tee_fs_htree_type - type of hash tree element
6250a81498SJens Wiklander  * @TEE_FS_HTREE_TYPE_HEAD: indicates a struct tee_fs_htree_image
6350a81498SJens Wiklander  * @TEE_FS_HTREE_TYPE_NODE: indicates a struct tee_fs_htree_node_image
6450a81498SJens Wiklander  * @TEE_FS_HTREE_TYPE_BLOCK: indicates a data block
6550a81498SJens Wiklander  */
6650a81498SJens Wiklander enum tee_fs_htree_type {
6750a81498SJens Wiklander 	TEE_FS_HTREE_TYPE_HEAD,
6850a81498SJens Wiklander 	TEE_FS_HTREE_TYPE_NODE,
6950a81498SJens Wiklander 	TEE_FS_HTREE_TYPE_BLOCK,
7050a81498SJens Wiklander };
7150a81498SJens Wiklander 
7250a81498SJens Wiklander struct tee_fs_rpc_operation;
7350a81498SJens Wiklander 
7450a81498SJens Wiklander /**
7550a81498SJens Wiklander  * struct tee_fs_htree_storage - storage description supplied by user of
7650a81498SJens Wiklander  * this interface
7750a81498SJens Wiklander  * @block_size:		size of data blocks
7850a81498SJens Wiklander  * @rpc_read_init:	initialize a struct tee_fs_rpc_operation for an RPC read
7950a81498SJens Wiklander  *			operation
8050a81498SJens Wiklander  * @rpc_write_init:	initialize a struct tee_fs_rpc_operation for an RPC
8150a81498SJens Wiklander  *			write operation
8250a81498SJens Wiklander  *
8350a81498SJens Wiklander  * The @idx arguments starts counting from 0. The @vers arguments are either
8450a81498SJens Wiklander  * 0 or 1. The @data arguments is a pointer to a buffer in non-secure shared
8550a81498SJens Wiklander  * memory where the encrypted data is stored.
8650a81498SJens Wiklander  */
8750a81498SJens Wiklander struct tee_fs_htree_storage {
8850a81498SJens Wiklander 	size_t block_size;
8950a81498SJens Wiklander 	TEE_Result (*rpc_read_init)(void *aux, struct tee_fs_rpc_operation *op,
9050a81498SJens Wiklander 				    enum tee_fs_htree_type type, size_t idx,
9150a81498SJens Wiklander 				    uint8_t vers, void **data);
9264fa6c0aSJens Wiklander 	TEE_Result (*rpc_read_final)(struct tee_fs_rpc_operation *op,
9364fa6c0aSJens Wiklander 				     size_t *bytes);
9450a81498SJens Wiklander 	TEE_Result (*rpc_write_init)(void *aux, struct tee_fs_rpc_operation *op,
9550a81498SJens Wiklander 				     enum tee_fs_htree_type type, size_t idx,
9650a81498SJens Wiklander 				     uint8_t vers, void **data);
9764fa6c0aSJens Wiklander 	TEE_Result (*rpc_write_final)(struct tee_fs_rpc_operation *op);
9850a81498SJens Wiklander };
9950a81498SJens Wiklander 
10050a81498SJens Wiklander struct tee_fs_htree;
10150a81498SJens Wiklander 
10250a81498SJens Wiklander /**
10350a81498SJens Wiklander  * tee_fs_htree_open() - opens/creates a hash tree
10450a81498SJens Wiklander  * @create:	true if a new hash tree is to be created, else the hash tree
10550a81498SJens Wiklander  *		is read in and verified
106f28e5060SJens Wiklander  * @hash:	hash of root node, ignored if NULL
107*623b9bd4SJens Wiklander  * @min_counter: the smallest accepted value in struct htree_image.counter
1080c4e1284SJens Wiklander  * @uuid:	uuid of requesting TA, may be NULL if not from a TA
10950a81498SJens Wiklander  * @stor:	storage description
11050a81498SJens Wiklander  * @stor_aux:	auxilary pointer supplied to callbacks in struct
11150a81498SJens Wiklander  *		tee_fs_htree_storage
11250a81498SJens Wiklander  * @ht:		returned hash tree on success
11350a81498SJens Wiklander  */
114*623b9bd4SJens Wiklander TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, uint32_t min_counter,
115*623b9bd4SJens Wiklander 			     const TEE_UUID *uuid,
11650a81498SJens Wiklander 			     const struct tee_fs_htree_storage *stor,
11750a81498SJens Wiklander 			     void *stor_aux, struct tee_fs_htree **ht);
11850a81498SJens Wiklander /**
11950a81498SJens Wiklander  * tee_fs_htree_close() - close a hash tree
12050a81498SJens Wiklander  * @ht:		hash tree
12150a81498SJens Wiklander  */
12250a81498SJens Wiklander void tee_fs_htree_close(struct tee_fs_htree **ht);
12350a81498SJens Wiklander 
12450a81498SJens Wiklander /**
12550a81498SJens Wiklander  * tee_fs_htree_get_meta() - get a pointer to associated struct
12650a81498SJens Wiklander  * tee_fs_htree_meta
12750a81498SJens Wiklander  * @ht:		hash tree
12850a81498SJens Wiklander  */
12950a81498SJens Wiklander struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht);
13050a81498SJens Wiklander 
13150a81498SJens Wiklander /**
13233e4def6SJerome Forissier  * tee_fs_htree_meta_set_dirty() - tell hash tree that meta were modified
13333e4def6SJerome Forissier  */
13433e4def6SJerome Forissier void tee_fs_htree_meta_set_dirty(struct tee_fs_htree *ht);
13533e4def6SJerome Forissier 
13633e4def6SJerome Forissier /**
13750a81498SJens Wiklander  * tee_fs_htree_sync_to_storage() - synchronize hash tree to storage
13850a81498SJens Wiklander  * @ht:		hash tree
139f28e5060SJens Wiklander  * @hash:	hash of root node is copied to this if not NULL
140*623b9bd4SJens Wiklander  * @counter:	ever increasing version counter is copied to this if not NULL
14150a81498SJens Wiklander  *
14250a81498SJens Wiklander  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
14350a81498SJens Wiklander  */
144f28e5060SJens Wiklander TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht,
145*623b9bd4SJens Wiklander 					uint8_t *hash, uint32_t *counter);
14650a81498SJens Wiklander 
14750a81498SJens Wiklander /**
14850a81498SJens Wiklander  * tee_fs_htree_truncate() - truncate a hash tree
14950a81498SJens Wiklander  * @ht:		hash tree
15050a81498SJens Wiklander  * @block_num:	the number of nodes to truncate to
15150a81498SJens Wiklander  *
15250a81498SJens Wiklander  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
15350a81498SJens Wiklander  */
15450a81498SJens Wiklander TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht, size_t block_num);
15550a81498SJens Wiklander 
15650a81498SJens Wiklander /**
15750a81498SJens Wiklander  * tee_fs_htree_write_block() - encrypt and write a data block to storage
15850a81498SJens Wiklander  * @ht:		hash tree
15950a81498SJens Wiklander  * @block_num:	block number
16050a81498SJens Wiklander  * @block:	pointer to a block of stor->block_size size
16150a81498SJens Wiklander  *
16250a81498SJens Wiklander  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
16350a81498SJens Wiklander  */
16450a81498SJens Wiklander TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht, size_t block_num,
16550a81498SJens Wiklander 				    const void *block);
16650a81498SJens Wiklander /**
16750a81498SJens Wiklander  * tee_fs_htree_write_block() - read and decrypt a data block from storage
16850a81498SJens Wiklander  * @ht:		hash tree
16950a81498SJens Wiklander  * @block_num:	block number
17050a81498SJens Wiklander  * @block:	pointer to a block of stor->block_size size
17150a81498SJens Wiklander  *
17250a81498SJens Wiklander  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
17350a81498SJens Wiklander  */
17450a81498SJens Wiklander TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht, size_t block_num,
17550a81498SJens Wiklander 				   void *block);
17650a81498SJens Wiklander 
17750a81498SJens Wiklander #endif /*__TEE_FS_HTREE_H*/
178