xref: /optee_os/core/include/tee/fs_htree.h (revision b1d7375c01ec8bcbf3561d27425d320afed23bce)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2017, Linaro Limited
4  */
5 
6 #ifndef __TEE_FS_HTREE_H
7 #define __TEE_FS_HTREE_H
8 
9 /*
10  * The purpose of this API is to provide file integrity and confidentiality
11  * in order to implement secure storage. On-disk data structures are
12  * duplicated to make updates atomic, an update is finalized to disk with
13  * tee_fs_htree_sync_to_storage().
14  *
15  * This implementation doesn't provide rollback protection, it only
16  * guarantees the integrity and confidentiality of the file.
17  */
18 
19 #include <tee_api_types.h>
20 #include <utee_defines.h>
21 
22 #define TEE_FS_HTREE_HASH_SIZE		TEE_SHA256_HASH_SIZE
23 #define TEE_FS_HTREE_IV_SIZE		16
24 #define TEE_FS_HTREE_FEK_SIZE		16
25 #define TEE_FS_HTREE_TAG_SIZE		16
26 
27 /* Internal struct provided to let the rpc callbacks know the size if needed */
28 struct tee_fs_htree_node_image {
29 	/* Note that calc_node_hash() depends on hash first in struct */
30 	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
31 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
32 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
33 	uint16_t flags;
34 };
35 
36 /*
37  * This struct is not interpreted by the hash tree, it's up to the user of
38  * the interface to update etc if needed.
39  */
40 struct tee_fs_htree_meta {
41 	uint64_t length;
42 };
43 
44 /* Internal struct needed by struct tee_fs_htree_image */
45 struct tee_fs_htree_imeta {
46 	struct tee_fs_htree_meta meta;
47 	uint32_t max_node_id;
48 };
49 
50 /* Internal struct provided to let the rpc callbacks know the size if needed */
51 struct tee_fs_htree_image {
52 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
53 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
54 	uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];
55 	uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];
56 	uint32_t counter;
57 };
58 
59 /**
60  * enum tee_fs_htree_type - type of hash tree element
61  * @TEE_FS_HTREE_TYPE_HEAD: indicates a struct tee_fs_htree_image
62  * @TEE_FS_HTREE_TYPE_NODE: indicates a struct tee_fs_htree_node_image
63  * @TEE_FS_HTREE_TYPE_BLOCK: indicates a data block
64  */
65 enum tee_fs_htree_type {
66 	TEE_FS_HTREE_TYPE_HEAD,
67 	TEE_FS_HTREE_TYPE_NODE,
68 	TEE_FS_HTREE_TYPE_BLOCK,
69 };
70 
71 struct tee_fs_rpc_operation;
72 
73 /**
74  * struct tee_fs_htree_storage - storage description supplied by user of
75  * this interface
76  * @block_size:		size of data blocks
77  * @rpc_read_init:	initialize a struct tee_fs_rpc_operation for an RPC read
78  *			operation
79  * @rpc_write_init:	initialize a struct tee_fs_rpc_operation for an RPC
80  *			write operation
81  *
82  * The @idx arguments starts counting from 0. The @vers arguments are either
83  * 0 or 1. The @data arguments is a pointer to a buffer in non-secure shared
84  * memory where the encrypted data is stored.
85  */
86 struct tee_fs_htree_storage {
87 	size_t block_size;
88 	TEE_Result (*rpc_read_init)(void *aux, struct tee_fs_rpc_operation *op,
89 				    enum tee_fs_htree_type type, size_t idx,
90 				    uint8_t vers, void **data);
91 	TEE_Result (*rpc_read_final)(struct tee_fs_rpc_operation *op,
92 				     size_t *bytes);
93 	TEE_Result (*rpc_write_init)(void *aux, struct tee_fs_rpc_operation *op,
94 				     enum tee_fs_htree_type type, size_t idx,
95 				     uint8_t vers, void **data);
96 	TEE_Result (*rpc_write_final)(struct tee_fs_rpc_operation *op);
97 };
98 
99 struct tee_fs_htree;
100 
101 /**
102  * tee_fs_htree_open() - opens/creates a hash tree
103  * @create:	true if a new hash tree is to be created, else the hash tree
104  *		is read in and verified
105  * @hash:	hash of root node, ignored if NULL
106  * @uuid:	uuid of requesting TA, may be NULL if not from a TA
107  * @stor:	storage description
108  * @stor_aux:	auxilary pointer supplied to callbacks in struct
109  *		tee_fs_htree_storage
110  * @ht:		returned hash tree on success
111  */
112 TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, const TEE_UUID *uuid,
113 			     const struct tee_fs_htree_storage *stor,
114 			     void *stor_aux, struct tee_fs_htree **ht);
115 /**
116  * tee_fs_htree_close() - close a hash tree
117  * @ht:		hash tree
118  */
119 void tee_fs_htree_close(struct tee_fs_htree **ht);
120 
121 /**
122  * tee_fs_htree_get_meta() - get a pointer to associated struct
123  * tee_fs_htree_meta
124  * @ht:		hash tree
125  */
126 struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht);
127 
128 /**
129  * tee_fs_htree_sync_to_storage() - synchronize hash tree to storage
130  * @ht:		hash tree
131  * @hash:	hash of root node is copied to this if not NULL
132  *
133  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
134  */
135 TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht,
136 					uint8_t *hash);
137 
138 /**
139  * tee_fs_htree_truncate() - truncate a hash tree
140  * @ht:		hash tree
141  * @block_num:	the number of nodes to truncate to
142  *
143  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
144  */
145 TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht, size_t block_num);
146 
147 /**
148  * tee_fs_htree_write_block() - encrypt and write a data block to storage
149  * @ht:		hash tree
150  * @block_num:	block number
151  * @block:	pointer to a block of stor->block_size size
152  *
153  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
154  */
155 TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht, size_t block_num,
156 				    const void *block);
157 /**
158  * tee_fs_htree_write_block() - read and decrypt a data block from storage
159  * @ht:		hash tree
160  * @block_num:	block number
161  * @block:	pointer to a block of stor->block_size size
162  *
163  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
164  */
165 TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht, size_t block_num,
166 				   void *block);
167 
168 #endif /*__TEE_FS_HTREE_H*/
169