xref: /optee_os/core/include/tee/fs_htree.h (revision 8e81e2f5366a971afdd2ac47fb8529d1def5feb0)
1 /*
2  * Copyright (c) 2017, Linaro Limited
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef __TEE_FS_HTREE_H
29 #define __TEE_FS_HTREE_H
30 
31 /*
32  * The purpose of this API is to provide file integrity and confidentiality
33  * in order to implement secure storage. On-disk data structures are
34  * duplicated to make updates atomic, an update is finalized to disk with
35  * tee_fs_htree_sync_to_storage().
36  *
37  * This implementation doesn't provide rollback protection, it only
38  * guarantees the integrity and confidentiality of the file.
39  */
40 
41 #include <tee_api_types.h>
42 #include <utee_defines.h>
43 
44 #define TEE_FS_HTREE_HASH_SIZE		TEE_SHA256_HASH_SIZE
45 #define TEE_FS_HTREE_IV_SIZE		16
46 #define TEE_FS_HTREE_FEK_SIZE		16
47 #define TEE_FS_HTREE_TAG_SIZE		16
48 
49 /* Internal struct provided to let the rpc callbacks know the size if needed */
50 struct tee_fs_htree_node_image {
51 	/* Note that calc_node_hash() depends on hash first in struct */
52 	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
53 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
54 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
55 	uint16_t flags;
56 };
57 
58 /*
59  * This struct is not interpreted by the hash tree, it's up to the user of
60  * the interface to update etc if needed.
61  */
62 struct tee_fs_htree_meta {
63 	uint64_t length;
64 };
65 
66 /* Internal struct needed by struct tee_fs_htree_image */
67 struct tee_fs_htree_imeta {
68 	struct tee_fs_htree_meta meta;
69 	uint32_t max_node_id;
70 };
71 
72 /* Internal struct provided to let the rpc callbacks know the size if needed */
73 struct tee_fs_htree_image {
74 	uint8_t iv[TEE_FS_HTREE_IV_SIZE];
75 	uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
76 	uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];
77 	uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];
78 	uint32_t counter;
79 };
80 
81 /**
82  * enum tee_fs_htree_type - type of hash tree element
83  * @TEE_FS_HTREE_TYPE_HEAD: indicates a struct tee_fs_htree_image
84  * @TEE_FS_HTREE_TYPE_NODE: indicates a struct tee_fs_htree_node_image
85  * @TEE_FS_HTREE_TYPE_BLOCK: indicates a data block
86  */
87 enum tee_fs_htree_type {
88 	TEE_FS_HTREE_TYPE_HEAD,
89 	TEE_FS_HTREE_TYPE_NODE,
90 	TEE_FS_HTREE_TYPE_BLOCK,
91 };
92 
93 struct tee_fs_rpc_operation;
94 
95 /**
96  * struct tee_fs_htree_storage - storage description supplied by user of
97  * this interface
98  * @block_size:		size of data blocks
99  * @rpc_read_init:	initialize a struct tee_fs_rpc_operation for an RPC read
100  *			operation
101  * @rpc_write_init:	initialize a struct tee_fs_rpc_operation for an RPC
102  *			write operation
103  *
104  * The @idx arguments starts counting from 0. The @vers arguments are either
105  * 0 or 1. The @data arguments is a pointer to a buffer in non-secure shared
106  * memory where the encrypted data is stored.
107  */
108 struct tee_fs_htree_storage {
109 	size_t block_size;
110 	TEE_Result (*rpc_read_init)(void *aux, struct tee_fs_rpc_operation *op,
111 				    enum tee_fs_htree_type type, size_t idx,
112 				    uint8_t vers, void **data);
113 	TEE_Result (*rpc_read_final)(struct tee_fs_rpc_operation *op,
114 				     size_t *bytes);
115 	TEE_Result (*rpc_write_init)(void *aux, struct tee_fs_rpc_operation *op,
116 				     enum tee_fs_htree_type type, size_t idx,
117 				     uint8_t vers, void **data);
118 	TEE_Result (*rpc_write_final)(struct tee_fs_rpc_operation *op);
119 };
120 
121 struct tee_fs_htree;
122 
123 /**
124  * tee_fs_htree_open() - opens/creates a hash tree
125  * @create:	true if a new hash tree is to be created, else the hash tree
126  *		is read in and verified
127  * @hash:	hash of root node, ignored if NULL
128  * @uuid:	uuid of requesting TA, may be NULL if not from a TA
129  * @stor:	storage description
130  * @stor_aux:	auxilary pointer supplied to callbacks in struct
131  *		tee_fs_htree_storage
132  * @ht:		returned hash tree on success
133  */
134 TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, const TEE_UUID *uuid,
135 			     const struct tee_fs_htree_storage *stor,
136 			     void *stor_aux, struct tee_fs_htree **ht);
137 /**
138  * tee_fs_htree_close() - close a hash tree
139  * @ht:		hash tree
140  */
141 void tee_fs_htree_close(struct tee_fs_htree **ht);
142 
143 /**
144  * tee_fs_htree_get_meta() - get a pointer to associated struct
145  * tee_fs_htree_meta
146  * @ht:		hash tree
147  */
148 struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht);
149 
150 /**
151  * tee_fs_htree_sync_to_storage() - synchronize hash tree to storage
152  * @ht:		hash tree
153  * @hash:	hash of root node is copied to this if not NULL
154  *
155  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
156  */
157 TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht,
158 					uint8_t *hash);
159 
160 /**
161  * tee_fs_htree_truncate() - truncate a hash tree
162  * @ht:		hash tree
163  * @block_num:	the number of nodes to truncate to
164  *
165  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
166  */
167 TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht, size_t block_num);
168 
169 /**
170  * tee_fs_htree_write_block() - encrypt and write a data block to storage
171  * @ht:		hash tree
172  * @block_num:	block number
173  * @block:	pointer to a block of stor->block_size size
174  *
175  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
176  */
177 TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht, size_t block_num,
178 				    const void *block);
179 /**
180  * tee_fs_htree_write_block() - read and decrypt a data block from storage
181  * @ht:		hash tree
182  * @block_num:	block number
183  * @block:	pointer to a block of stor->block_size size
184  *
185  * Frees the hash tree and sets *ht to NULL on failure and returns an error code
186  */
187 TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht, size_t block_num,
188 				   void *block);
189 
190 #endif /*__TEE_FS_HTREE_H*/
191