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