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