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