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