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