11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 250a81498SJens Wiklander /* 350a81498SJens Wiklander * Copyright (c) 2017, Linaro Limited 450a81498SJens Wiklander */ 550a81498SJens Wiklander 650a81498SJens Wiklander #ifndef __TEE_FS_HTREE_H 750a81498SJens Wiklander #define __TEE_FS_HTREE_H 850a81498SJens Wiklander 950a81498SJens Wiklander /* 1050a81498SJens Wiklander * The purpose of this API is to provide file integrity and confidentiality 1150a81498SJens Wiklander * in order to implement secure storage. On-disk data structures are 1250a81498SJens Wiklander * duplicated to make updates atomic, an update is finalized to disk with 1350a81498SJens Wiklander * tee_fs_htree_sync_to_storage(). 1450a81498SJens Wiklander * 1550a81498SJens Wiklander * This implementation doesn't provide rollback protection, it only 1650a81498SJens Wiklander * guarantees the integrity and confidentiality of the file. 1750a81498SJens Wiklander */ 1850a81498SJens Wiklander 19b4bfc9a9SJens Wiklander #include <stdint.h> 2050a81498SJens Wiklander #include <tee_api_types.h> 2150a81498SJens Wiklander #include <utee_defines.h> 2250a81498SJens Wiklander 2350a81498SJens Wiklander #define TEE_FS_HTREE_HASH_SIZE TEE_SHA256_HASH_SIZE 24b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_IV_SIZE U(16) 25b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_FEK_SIZE U(16) 26b4bfc9a9SJens Wiklander #define TEE_FS_HTREE_TAG_SIZE U(16) 2750a81498SJens Wiklander 2850a81498SJens Wiklander /* Internal struct provided to let the rpc callbacks know the size if needed */ 2950a81498SJens Wiklander struct tee_fs_htree_node_image { 3050a81498SJens Wiklander /* Note that calc_node_hash() depends on hash first in struct */ 3150a81498SJens Wiklander uint8_t hash[TEE_FS_HTREE_HASH_SIZE]; 3250a81498SJens Wiklander uint8_t iv[TEE_FS_HTREE_IV_SIZE]; 3350a81498SJens Wiklander uint8_t tag[TEE_FS_HTREE_TAG_SIZE]; 3450a81498SJens Wiklander uint16_t flags; 3550a81498SJens Wiklander }; 3650a81498SJens Wiklander 3750a81498SJens Wiklander /* 3850a81498SJens Wiklander * This struct is not interpreted by the hash tree, it's up to the user of 3950a81498SJens Wiklander * the interface to update etc if needed. 4050a81498SJens Wiklander */ 4150a81498SJens Wiklander struct tee_fs_htree_meta { 4250a81498SJens Wiklander uint64_t length; 4350a81498SJens Wiklander }; 4450a81498SJens Wiklander 4550a81498SJens Wiklander /* Internal struct needed by struct tee_fs_htree_image */ 4650a81498SJens Wiklander struct tee_fs_htree_imeta { 4750a81498SJens Wiklander struct tee_fs_htree_meta meta; 4850a81498SJens Wiklander uint32_t max_node_id; 4950a81498SJens Wiklander }; 5050a81498SJens Wiklander 5150a81498SJens Wiklander /* Internal struct provided to let the rpc callbacks know the size if needed */ 5250a81498SJens Wiklander struct tee_fs_htree_image { 5350a81498SJens Wiklander uint8_t iv[TEE_FS_HTREE_IV_SIZE]; 5450a81498SJens Wiklander uint8_t tag[TEE_FS_HTREE_TAG_SIZE]; 5550a81498SJens Wiklander uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE]; 5650a81498SJens Wiklander uint8_t imeta[sizeof(struct tee_fs_htree_imeta)]; 5750a81498SJens Wiklander uint32_t counter; 5850a81498SJens Wiklander }; 5950a81498SJens Wiklander 6050a81498SJens Wiklander /** 6150a81498SJens Wiklander * enum tee_fs_htree_type - type of hash tree element 6250a81498SJens Wiklander * @TEE_FS_HTREE_TYPE_HEAD: indicates a struct tee_fs_htree_image 6350a81498SJens Wiklander * @TEE_FS_HTREE_TYPE_NODE: indicates a struct tee_fs_htree_node_image 6450a81498SJens Wiklander * @TEE_FS_HTREE_TYPE_BLOCK: indicates a data block 6550a81498SJens Wiklander */ 6650a81498SJens Wiklander enum tee_fs_htree_type { 6750a81498SJens Wiklander TEE_FS_HTREE_TYPE_HEAD, 6850a81498SJens Wiklander TEE_FS_HTREE_TYPE_NODE, 6950a81498SJens Wiklander TEE_FS_HTREE_TYPE_BLOCK, 7050a81498SJens Wiklander }; 7150a81498SJens Wiklander 7250a81498SJens Wiklander struct tee_fs_rpc_operation; 7350a81498SJens Wiklander 7450a81498SJens Wiklander /** 7550a81498SJens Wiklander * struct tee_fs_htree_storage - storage description supplied by user of 7650a81498SJens Wiklander * this interface 7750a81498SJens Wiklander * @block_size: size of data blocks 7850a81498SJens Wiklander * @rpc_read_init: initialize a struct tee_fs_rpc_operation for an RPC read 7950a81498SJens Wiklander * operation 8050a81498SJens Wiklander * @rpc_write_init: initialize a struct tee_fs_rpc_operation for an RPC 8150a81498SJens Wiklander * write operation 8250a81498SJens Wiklander * 8350a81498SJens Wiklander * The @idx arguments starts counting from 0. The @vers arguments are either 8450a81498SJens Wiklander * 0 or 1. The @data arguments is a pointer to a buffer in non-secure shared 8550a81498SJens Wiklander * memory where the encrypted data is stored. 8650a81498SJens Wiklander */ 8750a81498SJens Wiklander struct tee_fs_htree_storage { 8850a81498SJens Wiklander size_t block_size; 8950a81498SJens Wiklander TEE_Result (*rpc_read_init)(void *aux, struct tee_fs_rpc_operation *op, 9050a81498SJens Wiklander enum tee_fs_htree_type type, size_t idx, 9150a81498SJens Wiklander uint8_t vers, void **data); 9264fa6c0aSJens Wiklander TEE_Result (*rpc_read_final)(struct tee_fs_rpc_operation *op, 9364fa6c0aSJens Wiklander size_t *bytes); 9450a81498SJens Wiklander TEE_Result (*rpc_write_init)(void *aux, struct tee_fs_rpc_operation *op, 9550a81498SJens Wiklander enum tee_fs_htree_type type, size_t idx, 9650a81498SJens Wiklander uint8_t vers, void **data); 9764fa6c0aSJens Wiklander TEE_Result (*rpc_write_final)(struct tee_fs_rpc_operation *op); 9850a81498SJens Wiklander }; 9950a81498SJens Wiklander 10050a81498SJens Wiklander struct tee_fs_htree; 10150a81498SJens Wiklander 10250a81498SJens Wiklander /** 10350a81498SJens Wiklander * tee_fs_htree_open() - opens/creates a hash tree 10450a81498SJens Wiklander * @create: true if a new hash tree is to be created, else the hash tree 10550a81498SJens Wiklander * is read in and verified 106f28e5060SJens Wiklander * @hash: hash of root node, ignored if NULL 107*623b9bd4SJens Wiklander * @min_counter: the smallest accepted value in struct htree_image.counter 1080c4e1284SJens Wiklander * @uuid: uuid of requesting TA, may be NULL if not from a TA 10950a81498SJens Wiklander * @stor: storage description 11050a81498SJens Wiklander * @stor_aux: auxilary pointer supplied to callbacks in struct 11150a81498SJens Wiklander * tee_fs_htree_storage 11250a81498SJens Wiklander * @ht: returned hash tree on success 11350a81498SJens Wiklander */ 114*623b9bd4SJens Wiklander TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, uint32_t min_counter, 115*623b9bd4SJens Wiklander const TEE_UUID *uuid, 11650a81498SJens Wiklander const struct tee_fs_htree_storage *stor, 11750a81498SJens Wiklander void *stor_aux, struct tee_fs_htree **ht); 11850a81498SJens Wiklander /** 11950a81498SJens Wiklander * tee_fs_htree_close() - close a hash tree 12050a81498SJens Wiklander * @ht: hash tree 12150a81498SJens Wiklander */ 12250a81498SJens Wiklander void tee_fs_htree_close(struct tee_fs_htree **ht); 12350a81498SJens Wiklander 12450a81498SJens Wiklander /** 12550a81498SJens Wiklander * tee_fs_htree_get_meta() - get a pointer to associated struct 12650a81498SJens Wiklander * tee_fs_htree_meta 12750a81498SJens Wiklander * @ht: hash tree 12850a81498SJens Wiklander */ 12950a81498SJens Wiklander struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht); 13050a81498SJens Wiklander 13150a81498SJens Wiklander /** 13233e4def6SJerome Forissier * tee_fs_htree_meta_set_dirty() - tell hash tree that meta were modified 13333e4def6SJerome Forissier */ 13433e4def6SJerome Forissier void tee_fs_htree_meta_set_dirty(struct tee_fs_htree *ht); 13533e4def6SJerome Forissier 13633e4def6SJerome Forissier /** 13750a81498SJens Wiklander * tee_fs_htree_sync_to_storage() - synchronize hash tree to storage 13850a81498SJens Wiklander * @ht: hash tree 139f28e5060SJens Wiklander * @hash: hash of root node is copied to this if not NULL 140*623b9bd4SJens Wiklander * @counter: ever increasing version counter is copied to this if not NULL 14150a81498SJens Wiklander * 14250a81498SJens Wiklander * Frees the hash tree and sets *ht to NULL on failure and returns an error code 14350a81498SJens Wiklander */ 144f28e5060SJens Wiklander TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht, 145*623b9bd4SJens Wiklander uint8_t *hash, uint32_t *counter); 14650a81498SJens Wiklander 14750a81498SJens Wiklander /** 14850a81498SJens Wiklander * tee_fs_htree_truncate() - truncate a hash tree 14950a81498SJens Wiklander * @ht: hash tree 15050a81498SJens Wiklander * @block_num: the number of nodes to truncate to 15150a81498SJens Wiklander * 15250a81498SJens Wiklander * Frees the hash tree and sets *ht to NULL on failure and returns an error code 15350a81498SJens Wiklander */ 15450a81498SJens Wiklander TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht, size_t block_num); 15550a81498SJens Wiklander 15650a81498SJens Wiklander /** 15750a81498SJens Wiklander * tee_fs_htree_write_block() - encrypt and write a data block to storage 15850a81498SJens Wiklander * @ht: hash tree 15950a81498SJens Wiklander * @block_num: block number 16050a81498SJens Wiklander * @block: pointer to a block of stor->block_size size 16150a81498SJens Wiklander * 16250a81498SJens Wiklander * Frees the hash tree and sets *ht to NULL on failure and returns an error code 16350a81498SJens Wiklander */ 16450a81498SJens Wiklander TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht, size_t block_num, 16550a81498SJens Wiklander const void *block); 16650a81498SJens Wiklander /** 16750a81498SJens Wiklander * tee_fs_htree_write_block() - read and decrypt a data block from storage 16850a81498SJens Wiklander * @ht: hash tree 16950a81498SJens Wiklander * @block_num: block number 17050a81498SJens Wiklander * @block: pointer to a block of stor->block_size size 17150a81498SJens Wiklander * 17250a81498SJens Wiklander * Frees the hash tree and sets *ht to NULL on failure and returns an error code 17350a81498SJens Wiklander */ 17450a81498SJens Wiklander TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht, size_t block_num, 17550a81498SJens Wiklander void *block); 17650a81498SJens Wiklander 17750a81498SJens Wiklander #endif /*__TEE_FS_HTREE_H*/ 178