diff --git a/.travis.yml b/.travis.yml index fd5209a8cca..c835f34fd58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -161,16 +161,15 @@ script: - $make CFG_REE_FS=n CFG_RPMB_FS=y - $make CFG_WITH_USER_TA=n CFG_CRYPTO=n CFG_SE_API=n CFG_PCSC_PASSTHRU_READER_DRV=n - $make CFG_SMALL_PAGE_USER_TA=n - - $make CFG_SQL_FS=y - - $make CFG_WITH_PAGER=y CFG_WITH_LPAE=y CFG_RPMB_FS=y CFG_SQL_FS=y CFG_DT=y CFG_PS2MOUSE=y CFG_PL050=y CFG_PL111=y CFG_TEE_CORE_LOG_LEVEL=1 CFG_TEE_CORE_DEBUG=y DEBUG=1 - - $make CFG_WITH_PAGER=y CFG_WITH_LPAE=y CFG_RPMB_FS=y CFG_SQL_FS=y CFG_DT=y CFG_PS2MOUSE=y CFG_PL050=y CFG_PL111=y CFG_TEE_CORE_LOG_LEVEL=0 CFG_TEE_CORE_DEBUG=n DEBUG=0 + - $make CFG_WITH_PAGER=y CFG_WITH_LPAE=y CFG_RPMB_FS=y CFG_DT=y CFG_PS2MOUSE=y CFG_PL050=y CFG_PL111=y CFG_TEE_CORE_LOG_LEVEL=1 CFG_TEE_CORE_DEBUG=y DEBUG=1 + - $make CFG_WITH_PAGER=y CFG_WITH_LPAE=y CFG_RPMB_FS=y CFG_DT=y CFG_PS2MOUSE=y CFG_PL050=y CFG_PL111=y CFG_TEE_CORE_LOG_LEVEL=0 CFG_TEE_CORE_DEBUG=n DEBUG=0 - $make CFG_BUILT_IN_ARGS=y CFG_PAGEABLE_ADDR=0 CFG_NS_ENTRY_ADDR=0 CFG_DT_ADDR=0 CFG_DT=y - $make CFG_TA_GPROF_SUPPORT=y CFG_ULIBS_GPROF=y - $make CFG_SECURE_DATA_PATH=y # QEMU-ARMv8A - $make PLATFORM=vexpress-qemu_armv8a CFG_ARM64_core=y - - $make PLATFORM=vexpress-qemu_armv8a CFG_ARM64_core=y CFG_RPMB_FS=y CFG_SQL_FS=y + - $make PLATFORM=vexpress-qemu_armv8a CFG_ARM64_core=y CFG_RPMB_FS=y - $make PLATFORM=vexpress-qemu_armv8a CFG_ARM64_core=y CFG_TA_GPROF_SUPPORT=y CFG_ULIBS_GPROF=y # SUNXI(Allwinner A80) diff --git a/core/include/optee_msg_supplicant.h b/core/include/optee_msg_supplicant.h index e54dac0bf0f..003104ec013 100644 --- a/core/include/optee_msg_supplicant.h +++ b/core/include/optee_msg_supplicant.h @@ -43,19 +43,16 @@ */ #define OPTEE_MSG_RPC_CMD_FS 2 -/* - * Values 3-7 are reserved in optee_msg.h for use by the kernel driver - */ +/* Was OPTEE_MSG_RPC_CMD_SQL_FS, which isn't supported any longer */ +#define OPTEE_MSG_RPC_CMD_SQL_FS_RESERVED 8 /* - * SQLite file system access + * Values 3-7 are reserved in optee_msg.h for use by the kernel driver */ -#define OPTEE_MSG_RPC_CMD_SQL_FS 8 /* - * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_FS or - * .cmd == OPTEE_MSG_RPC_CMD_SQL_FS and first parameter has the attribute - * OPTEE_MSG_ATTR_TYPE_VALUE_INPUT. + * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_FS and first + * parameter has the attribute OPTEE_MSG_ATTR_TYPE_VALUE_INPUT. */ /* @@ -159,24 +156,9 @@ #define OPTEE_MRF_READDIR 10 /* - * Begins a new transaction (only valid for SQL FS) - * - * [in] param[0].u.value.a OPTEE_MRF_BEGIN_TRANSACTION + * End of definitions for messages with .cmd == OPTEE_MSG_RPC_CMD_FS */ -#define OPTEE_MRF_BEGIN_TRANSACTION 11 -/* - * Ends a transaction (only valid for SQL FS) - * - * [in] param[0].u.value.a OPTEE_MRF_END_TRANSACTION - * [in] param[0].u.value.b true if rolling back to previous state - */ -#define OPTEE_MRF_END_TRANSACTION 12 - -/* - * End of definitions for messages with .cmd == OPTEE_MSG_RPC_CMD_FS or - * .cmd == OPTEE_MSG_RPC_CMD_SQL_FS - */ /* * Send TA profiling information to normal world * diff --git a/core/include/tee/tee_fs.h b/core/include/tee/tee_fs.h index 22046aaf62e..3c982671e83 100644 --- a/core/include/tee/tee_fs.h +++ b/core/include/tee/tee_fs.h @@ -78,8 +78,5 @@ extern const struct tee_file_operations ree_fs_ops; #ifdef CFG_RPMB_FS extern const struct tee_file_operations rpmb_fs_ops; #endif -#ifdef CFG_SQL_FS -extern const struct tee_file_operations sql_fs_ops; -#endif -#endif +#endif /*TEE_FS_H*/ diff --git a/core/include/tee/tee_fs_rpc.h b/core/include/tee/tee_fs_rpc.h index d10b3b559f4..5e3aaea1039 100644 --- a/core/include/tee/tee_fs_rpc.h +++ b/core/include/tee/tee_fs_rpc.h @@ -80,12 +80,8 @@ TEE_Result tee_fs_rpc_closedir(uint32_t id, struct tee_fs_dir *d); TEE_Result tee_fs_rpc_readdir(uint32_t id, struct tee_fs_dir *d, struct tee_fs_dirent **ent); -TEE_Result tee_fs_rpc_begin_transaction(uint32_t id); -TEE_Result tee_fs_rpc_end_transaction(uint32_t id, bool rollback); - struct thread_specific_data; -#if defined(CFG_WITH_USER_TA) && \ - (defined(CFG_REE_FS) || defined(CFG_SQL_FS) || defined(CFG_RPMB_FS)) +#if defined(CFG_WITH_USER_TA) && (defined(CFG_REE_FS) || defined(CFG_RPMB_FS)) /* Frees the cache of allocated FS RPC memory */ void tee_fs_rpc_cache_clear(struct thread_specific_data *tsd); #else diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk index e1cfa65e78b..25f5a12288c 100644 --- a/core/lib/libtomcrypt/sub.mk +++ b/core/lib/libtomcrypt/sub.mk @@ -79,7 +79,6 @@ endif cryp-enable-all-depends = $(call cfg-enable-all-depends,$(strip $(1)),$(foreach v,$(2),CFG_CRYPTO_$(v))) $(eval $(call cryp-enable-all-depends,CFG_REE_FS, AES ECB CTR HMAC SHA256 GCM)) -$(eval $(call cryp-enable-all-depends,CFG_SQL_FS, AES ECB CTR HMAC SHA256 GCM)) $(eval $(call cryp-enable-all-depends,CFG_RPMB_FS, AES ECB CTR HMAC SHA256 GCM)) # Dependency checks: warn and disable some features if dependencies are not met diff --git a/core/tee/fs_htree.c b/core/tee/fs_htree.c index 10a8b0e0451..ce1bb9cd62b 100644 --- a/core/tee/fs_htree.c +++ b/core/tee/fs_htree.c @@ -92,9 +92,7 @@ * block 0 is represented by node 1. * * Where different elements are stored in the file is managed by the file - * system. In the case of SQL FS the version of the node/block is ignored - * as the atomic update is finalized with a call to - * tee_fs_rpc_end_transaction(). + * system. */ #define HTREE_NODE_COMMITTED_BLOCK BIT32(0) diff --git a/core/tee/sub.mk b/core/tee/sub.mk index 02d2443550f..deae77ee27d 100644 --- a/core/tee/sub.mk +++ b/core/tee/sub.mk @@ -30,13 +30,11 @@ srcs-y += tee_svc_cryp.c srcs-y += tee_svc_storage.c srcs-$(CFG_RPMB_FS) += tee_rpmb_fs.c srcs-$(CFG_REE_FS) += tee_ree_fs.c -srcs-$(CFG_SQL_FS) += tee_sql_fs.c -srcs-$(call cfg-one-enabled,CFG_REE_FS CFG_SQL_FS \ - CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += fs_htree.c +srcs-$(call cfg-one-enabled,CFG_REE_FS CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += \ + fs_htree.c srcs-$(CFG_REE_FS) += fs_dirfile.c -srcs-$(call cfg-one-enabled,CFG_REE_FS CFG_SQL_FS) += tee_fs_rpc.c -srcs-$(call cfg-one-enabled,CFG_REE_FS CFG_SQL_FS CFG_RPMB_FS) += \ - tee_fs_rpc_cache.c +srcs-$(CFG_REE_FS) += tee_fs_rpc.c +srcs-$(call cfg-one-enabled,CFG_REE_FS CFG_RPMB_FS) += tee_fs_rpc_cache.c srcs-y += tee_fs_key_manager.c srcs-y += tee_obj.c srcs-y += tee_pobj.c diff --git a/core/tee/tee_fs_rpc.c b/core/tee/tee_fs_rpc.c index 3eb572b1ee5..a510bcbe630 100644 --- a/core/tee/tee_fs_rpc.c +++ b/core/tee/tee_fs_rpc.c @@ -451,24 +451,3 @@ TEE_Result tee_fs_rpc_readdir(uint32_t id, struct tee_fs_dir *d, *ent = &d->d; return TEE_SUCCESS; } - -TEE_Result tee_fs_rpc_begin_transaction(uint32_t id) -{ - struct tee_fs_rpc_operation op = { .id = id, .num_params = 1 }; - - op.params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; - op.params[0].u.value.a = OPTEE_MRF_BEGIN_TRANSACTION; - - return operation_commit(&op); -} - -TEE_Result tee_fs_rpc_end_transaction(uint32_t id, bool rollback) -{ - struct tee_fs_rpc_operation op = { .id = id, .num_params = 1 }; - - op.params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; - op.params[0].u.value.a = OPTEE_MRF_END_TRANSACTION; - op.params[0].u.value.b = rollback; - - return operation_commit(&op); -} diff --git a/core/tee/tee_sql_fs.c b/core/tee/tee_sql_fs.c deleted file mode 100644 index fca5673485a..00000000000 --- a/core/tee/tee_sql_fs.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This file implements the tee_file_operations structure for a secure - * filesystem based on an SQLite database in normal world. - * The atomicity of each operation is ensured by using SQL transactions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Block size for encryption */ -#define BLOCK_SHIFT 12 -#define BLOCK_SIZE (1 << BLOCK_SHIFT) - -/* File descriptor */ -struct sql_fs_fd { - struct tee_fs_htree *ht; - int fd; /* returned by normal world */ -}; - -static struct mutex sql_fs_mutex = MUTEX_INITIALIZER; - -/* - * Interface with tee-supplicant - */ - -static TEE_Result sql_fs_begin_transaction_rpc(void) -{ - return tee_fs_rpc_begin_transaction(OPTEE_MSG_RPC_CMD_SQL_FS); -} - -static TEE_Result sql_fs_end_transaction_rpc(bool rollback) -{ - return tee_fs_rpc_end_transaction(OPTEE_MSG_RPC_CMD_SQL_FS, - rollback); -} - -static TEE_Result sql_fs_opendir_rpc(const TEE_UUID *uuid, - struct tee_fs_dir **d) -{ - return tee_fs_rpc_opendir(OPTEE_MSG_RPC_CMD_SQL_FS, uuid, d); -} - -static TEE_Result sql_fs_readdir_rpc(struct tee_fs_dir *d, - struct tee_fs_dirent **ent) -{ - return tee_fs_rpc_readdir(OPTEE_MSG_RPC_CMD_SQL_FS, d, ent); -} - -static TEE_Result sql_fs_remove_rpc(struct tee_pobj *po) -{ - return tee_fs_rpc_remove(OPTEE_MSG_RPC_CMD_SQL_FS, po); -} - -static TEE_Result sql_fs_rename_rpc(struct tee_pobj *old, struct tee_pobj *new, - bool overwrite) -{ - return tee_fs_rpc_rename(OPTEE_MSG_RPC_CMD_SQL_FS, old, new, overwrite); -} - -static void sql_fs_closedir_rpc(struct tee_fs_dir *d) -{ - if (d) - tee_fs_rpc_closedir(OPTEE_MSG_RPC_CMD_SQL_FS, d); -} - -/* - * End of interface with tee-supplicant - */ - - -/* Return the block number from a position in the user data */ -static ssize_t block_num(tee_fs_off_t pos) -{ - return pos / BLOCK_SIZE; -} - -static TEE_Result get_offs_size(enum tee_fs_htree_type type, size_t idx, - size_t *offs, size_t *size) -{ - const size_t node_size = sizeof(struct tee_fs_htree_node_image); - const size_t block_nodes = BLOCK_SIZE / node_size; - size_t pbn; - size_t bidx; - - - /* - * File layout - * - * phys block 0: - * tee_fs_htree_image @ offs = 0 - * - * phys block 1: - * tee_fs_htree_node_image 0 @ offs = 0 - * tee_fs_htree_node_image 1 @ offs = node_size * 2 - * ... - * tee_fs_htree_node_image 61 @ offs = node_size * 122 - * - * phys block 2: - * data block 0 - * - * ... - * - * phys block 64: - * data block 61 - * - * phys block 65: - * tee_fs_htree_node_image 62 @ offs = 0 - * tee_fs_htree_node_image 63 @ offs = node_size * 2 - * ... - * tee_fs_htree_node_image 121 @ offs = node_size * 123 - * - * ... - */ - - switch (type) { - case TEE_FS_HTREE_TYPE_HEAD: - *offs = 0; - *size = sizeof(struct tee_fs_htree_image); - return TEE_SUCCESS; - case TEE_FS_HTREE_TYPE_NODE: - pbn = 1 + ((idx / block_nodes) * block_nodes); - *offs = pbn * BLOCK_SIZE + node_size * (idx % block_nodes); - *size = node_size; - return TEE_SUCCESS; - case TEE_FS_HTREE_TYPE_BLOCK: - bidx = idx; - pbn = 2 + bidx + bidx / (block_nodes - 1); - *offs = pbn * BLOCK_SIZE; - *size = BLOCK_SIZE; - return TEE_SUCCESS; - default: - return TEE_ERROR_GENERIC; - } -} - -static TEE_Result sql_fs_rpc_read_init(void *aux, - struct tee_fs_rpc_operation *op, - enum tee_fs_htree_type type, size_t idx, - uint8_t vers __unused, void **data) -{ - struct sql_fs_fd *fdp = aux; - TEE_Result res; - size_t offs; - size_t size; - - res = get_offs_size(type, idx, &offs, &size); - if (res != TEE_SUCCESS) - return res; - - return tee_fs_rpc_read_init(op, OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, - offs, size, data); -} - -static TEE_Result sql_fs_rpc_write_init(void *aux, - struct tee_fs_rpc_operation *op, - enum tee_fs_htree_type type, size_t idx, - uint8_t vers __unused, void **data) -{ - struct sql_fs_fd *fdp = aux; - TEE_Result res; - size_t offs; - size_t size; - - res = get_offs_size(type, idx, &offs, &size); - if (res != TEE_SUCCESS) - return res; - - return tee_fs_rpc_write_init(op, OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, - offs, size, data); -} - -static const struct tee_fs_htree_storage sql_fs_storage_ops = { - .block_size = BLOCK_SIZE, - .rpc_read_init = sql_fs_rpc_read_init, - .rpc_read_final = tee_fs_rpc_read_final, - .rpc_write_init = sql_fs_rpc_write_init, - .rpc_write_final = tee_fs_rpc_write_final, -}; - -/* - * Partial write (< BLOCK_SIZE) into a block: read/update/write - * To save memory, passing data == NULL is equivalent to passing a buffer - * filled with zeroes. - */ -static TEE_Result write_block_partial(struct sql_fs_fd *fdp, size_t bnum, - const uint8_t *data, size_t len, - size_t offset) -{ - TEE_Result res; - size_t buf_size = BLOCK_SIZE; - uint8_t *buf = NULL; - - if ((offset >= buf_size) || (offset + len > buf_size)) - return TEE_ERROR_BAD_PARAMETERS; - - buf = malloc(buf_size); - if (!buf) - return TEE_ERROR_OUT_OF_MEMORY; - - if (bnum * BLOCK_SIZE < - ROUNDUP(tee_fs_htree_get_meta(fdp->ht)->length, BLOCK_SIZE)) { - res = tee_fs_htree_read_block(&fdp->ht, bnum, buf); - if (res != TEE_SUCCESS) - goto exit; - } else { - memset(buf, 0, BLOCK_SIZE); - } - - if (data) - memcpy(buf + offset, data, len); - else - memset(buf + offset, 0, len); - - res = tee_fs_htree_write_block(&fdp->ht, bnum, buf); -exit: - free(buf); - return res; -} - -static TEE_Result sql_fs_ftruncate_internal(struct sql_fs_fd *fdp, - tee_fs_off_t new_length) -{ - TEE_Result res; - struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht); - - if ((size_t)new_length == meta->length) - return TEE_SUCCESS; - - sql_fs_begin_transaction_rpc(); - - if ((size_t)new_length < meta->length) { - /* Trim unused blocks */ - int old_last_block = block_num(meta->length); - int last_block = block_num(new_length); - - if (last_block < old_last_block) { - size_t offs; - size_t sz; - - res = get_offs_size(TEE_FS_HTREE_TYPE_BLOCK, - ROUNDUP(new_length, BLOCK_SIZE) / - BLOCK_SIZE, &offs, &sz); - if (res != TEE_SUCCESS) - goto exit; - - res = tee_fs_htree_truncate(&fdp->ht, - new_length / BLOCK_SIZE); - if (res != TEE_SUCCESS) - goto exit; - - res = tee_fs_rpc_truncate(OPTEE_MSG_RPC_CMD_SQL_FS, - fdp->fd, offs + sz); - if (res != TEE_SUCCESS) - goto exit; - } - } else { - /* Extend file with zeroes */ - tee_fs_off_t off = meta->length % BLOCK_SIZE; - size_t bnum = block_num(meta->length); - size_t end_bnum = block_num(new_length); - - while (bnum <= end_bnum) { - size_t len = (size_t)BLOCK_SIZE - (size_t)off; - - res = write_block_partial(fdp, bnum, NULL, len, off); - if (res != TEE_SUCCESS) - goto exit; - off = 0; - bnum++; - } - } - - meta->length = new_length; - res = TEE_SUCCESS; -exit: - if (res == TEE_SUCCESS) - res = tee_fs_htree_sync_to_storage(&fdp->ht, NULL); - sql_fs_end_transaction_rpc(res != TEE_SUCCESS); - return res; -} - -static TEE_Result sql_fs_read(struct tee_file_handle *fh, size_t pos, - void *buf, size_t *len) -{ - TEE_Result res; - struct sql_fs_fd *fdp = (struct sql_fs_fd *)fh; - size_t remain_bytes = *len; - uint8_t *data_ptr = buf; - uint8_t *block = NULL; - int start_block_num; - int end_block_num; - size_t file_size; - - mutex_lock(&sql_fs_mutex); - - file_size = tee_fs_htree_get_meta(fdp->ht)->length; - if ((pos + remain_bytes) < remain_bytes || pos > file_size) - remain_bytes = 0; - else if (pos + remain_bytes > file_size) - remain_bytes = file_size - pos; - - *len = remain_bytes; - - if (!remain_bytes) { - res = TEE_SUCCESS; - goto exit; - } - - start_block_num = block_num(pos); - end_block_num = block_num(pos + remain_bytes - 1); - - block = malloc(BLOCK_SIZE); - if (!block) { - res = TEE_ERROR_OUT_OF_MEMORY; - goto exit; - } - - while (start_block_num <= end_block_num) { - size_t offset = pos % BLOCK_SIZE; - size_t size_to_read = MIN(remain_bytes, (size_t)BLOCK_SIZE); - - if (size_to_read + offset > BLOCK_SIZE) - size_to_read = BLOCK_SIZE - offset; - - res = tee_fs_htree_read_block(&fdp->ht, start_block_num, block); - if (res != TEE_SUCCESS) - goto exit; - - memcpy(data_ptr, block + offset, size_to_read); - - data_ptr += size_to_read; - remain_bytes -= size_to_read; - pos += size_to_read; - - start_block_num++; - } - res = TEE_SUCCESS; -exit: - free(block); - mutex_unlock(&sql_fs_mutex); - return res; -} - -static TEE_Result sql_fs_write_primitive(struct tee_file_handle *fh, size_t pos, - const void *buf, size_t len) -{ - TEE_Result res; - struct sql_fs_fd *fdp = (struct sql_fs_fd *)fh; - struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht); - size_t remain_bytes = len; - const uint8_t *data_ptr = buf; - int start_block_num; - int end_block_num; - - if (!len) - return TEE_SUCCESS; - - if (meta->length < pos) { - /* Fill hole */ - res = sql_fs_ftruncate_internal(fdp, pos); - if (res != TEE_SUCCESS) - return res; - } - - start_block_num = block_num(pos); - end_block_num = block_num(pos + len - 1); - - while (start_block_num <= end_block_num) { - size_t offset = pos % BLOCK_SIZE; - size_t size_to_write = MIN(remain_bytes, (size_t)BLOCK_SIZE); - - if (size_to_write + offset > BLOCK_SIZE) - size_to_write = BLOCK_SIZE - offset; - - res = write_block_partial(fdp, start_block_num, data_ptr, - size_to_write, offset); - if (res != TEE_SUCCESS) - return res; - - data_ptr += size_to_write; - remain_bytes -= size_to_write; - pos += size_to_write; - - start_block_num++; - } - - if (pos > meta->length) - meta->length = pos; - - return TEE_SUCCESS; -} -static TEE_Result sql_fs_write(struct tee_file_handle *fh, size_t pos, - const void *buf, size_t len) -{ - TEE_Result res; - struct sql_fs_fd *fdp = (struct sql_fs_fd *)fh; - - mutex_lock(&sql_fs_mutex); - sql_fs_begin_transaction_rpc(); - - res = sql_fs_write_primitive(fh, pos, buf, len); - - if (res == TEE_SUCCESS) - res = tee_fs_htree_sync_to_storage(&fdp->ht, NULL); - - sql_fs_end_transaction_rpc(res != TEE_SUCCESS); - mutex_unlock(&sql_fs_mutex); - return res; -} - -static void sql_fs_close(struct tee_file_handle **fh) -{ - struct sql_fs_fd *fdp = (struct sql_fs_fd *)*fh; - - if (fdp) { - tee_fs_htree_close(&fdp->ht); - tee_fs_rpc_close(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd); - free(fdp); - *fh = NULL; - } -} - -static TEE_Result open_internal(struct tee_pobj *po, bool create, - struct tee_file_handle **fh) -{ - TEE_Result res; - struct sql_fs_fd *fdp; - - fdp = calloc(1, sizeof(*fdp)); - if (!fdp) - return TEE_ERROR_OUT_OF_MEMORY; - fdp->fd = -1; - - if (create) - res = tee_fs_rpc_create(OPTEE_MSG_RPC_CMD_SQL_FS, po, &fdp->fd); - else - res = tee_fs_rpc_open(OPTEE_MSG_RPC_CMD_SQL_FS, po, &fdp->fd); - if (res != TEE_SUCCESS) - goto out; - - res = tee_fs_htree_open(create, NULL, &po->uuid, &sql_fs_storage_ops, - fdp, &fdp->ht); -out: - if (res == TEE_SUCCESS) { - *fh = (struct tee_file_handle *)fdp; - } else { - if (fdp && fdp->fd != -1) - tee_fs_rpc_close(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd); - if (create) - tee_fs_rpc_remove(OPTEE_MSG_RPC_CMD_SQL_FS, po); - free(fdp); - } - - return res; -} - -static TEE_Result sql_fs_open(struct tee_pobj *po, size_t *size, - struct tee_file_handle **fh) -{ - TEE_Result res; - - mutex_lock(&sql_fs_mutex); - res = open_internal(po, false, fh); - if (!res && size) { - struct sql_fs_fd *fdp = (struct sql_fs_fd *)*fh; - - *size = tee_fs_htree_get_meta(fdp->ht)->length; - } - mutex_unlock(&sql_fs_mutex); - - return res; -} - -static TEE_Result sql_fs_create(struct tee_pobj *po, bool overwrite, - const void *head, size_t head_size, - const void *attr, size_t attr_size, - const void *data, size_t data_size, - struct tee_file_handle **fh) -{ - struct sql_fs_fd *fdp; - TEE_Result res; - size_t pos = 0; - - *fh = NULL; - mutex_lock(&sql_fs_mutex); - sql_fs_begin_transaction_rpc(); - - res = open_internal(po, true, fh); - if (res) - goto out; - - if (head && head_size) { - res = sql_fs_write_primitive(*fh, pos, head, head_size); - if (res) - goto out; - pos += head_size; - } - - if (attr && attr_size) { - res = sql_fs_write_primitive(*fh, pos, attr, attr_size); - if (res) - goto out; - pos += attr_size; - } - - if (data && data_size) { - res = sql_fs_write_primitive(*fh, pos, data, data_size); - if (res) - goto out; - } - - fdp = (struct sql_fs_fd *)*fh; - res = tee_fs_htree_sync_to_storage(&fdp->ht, NULL); - if (res) - goto out; - - if (po->temporary) { - /* - * If it's a temporary filename (which it normally is) - * rename into the final filename now that the file is - * fully initialized. - */ - po->temporary = false; - res = sql_fs_rename_rpc(po, NULL, overwrite); - if (res) { - po->temporary = true; - goto out; - } - - /* - * Workaround for a bug in tee-supplicant SQL-FS - * implementation where renaming an open file doesn't - * update the "file descriptor" which still refers to the - * old file name. - */ - res = tee_fs_rpc_close(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd); - if (res) - goto out; - fdp->fd = -1; - res = tee_fs_rpc_open(OPTEE_MSG_RPC_CMD_SQL_FS, po, &fdp->fd); - } - -out: - if (res && *fh) - sql_fs_close(fh); - - sql_fs_end_transaction_rpc(res != TEE_SUCCESS); - mutex_unlock(&sql_fs_mutex); - - return res; -} - -static TEE_Result sql_fs_truncate(struct tee_file_handle *fh, size_t len) -{ - TEE_Result res; - struct sql_fs_fd *fdp = (struct sql_fs_fd *)fh; - - mutex_lock(&sql_fs_mutex); - res = sql_fs_ftruncate_internal(fdp, len); - mutex_unlock(&sql_fs_mutex); - - return res; -} - -const struct tee_file_operations sql_fs_ops = { - .open = sql_fs_open, - .create = sql_fs_create, - .close = sql_fs_close, - .read = sql_fs_read, - .write = sql_fs_write, - .truncate = sql_fs_truncate, - - .opendir = sql_fs_opendir_rpc, - .closedir = sql_fs_closedir_rpc, - .readdir = sql_fs_readdir_rpc, - .rename = sql_fs_rename_rpc, - .remove = sql_fs_remove_rpc, -}; diff --git a/core/tee/tee_svc_storage.c b/core/tee/tee_svc_storage.c index c2be3d488ca..939bd78de9a 100644 --- a/core/tee/tee_svc_storage.c +++ b/core/tee/tee_svc_storage.c @@ -55,8 +55,6 @@ static const struct tee_file_operations *file_ops(uint32_t storage_id) return &ree_fs_ops; #elif defined(CFG_RPMB_FS) return &rpmb_fs_ops; -#elif defined(CFG_SQL_FS) - return &sql_fs_ops; #else #error At least one filesystem must be enabled. #endif @@ -67,10 +65,6 @@ static const struct tee_file_operations *file_ops(uint32_t storage_id) #ifdef CFG_RPMB_FS case TEE_STORAGE_PRIVATE_RPMB: return &rpmb_fs_ops; -#endif -#ifdef CFG_SQL_FS - case TEE_STORAGE_PRIVATE_SQL: - return &sql_fs_ops; #endif default: return NULL; diff --git a/documentation/secure_storage.md b/documentation/secure_storage.md index 91a552c896a..5de64ab6352 100644 --- a/documentation/secure_storage.md +++ b/documentation/secure_storage.md @@ -10,7 +10,7 @@ integrity of the data stored and the atomicity of the operations that modifies the storage (atomicity here means that either the entire operation completes successfully or no write is done). -There are currently three secure storage implementations in OP-TEE: +There are currently two secure storage implementations in OP-TEE: - The first one relies on the normal world (REE) file system. It is described in this document and is the default implementation. It is enabled at compile time @@ -18,16 +18,13 @@ by CFG_REE_FS=y. - The second one makes use of the Replay Protected Memory Block (RPMB) partition of an eMMC device, and is enabled by setting `CFG_RPMB_FS=y`. It is described in [secure_storage_rpmb.md](secure_storage_rpmb.md). -- The third one stores objects in a SQLite database in normal world. It is -enabled by `CFG_SQL_FS=y`. See [secure_storage_sql.md](secure_storage_sql.md). It is possible to use the normal world filesystems and the RPMB implementations -simultaneously. For this, three OP-TEE specific storage identifiers have been -defined: TEE_STORAGE_PRIVATE_REE, TEE_STORAGE_PRIVATE_RPMB and -TEE_STORAGE_PRIVATE_SQL. Depending on the +simultaneously. For this, two OP-TEE specific storage identifiers have been +defined: TEE_STORAGE_PRIVATE_REE and TEE_STORAGE_PRIVATE_RPMB. Depending on the compile-time configuration, one or several values may be used. The value TEE_STORAGE_PRIVATE selects the REE FS when available, otherwise the -RPMB FS if available, otherwise the SQL FS (in this order). +RPMB FS (in this order). The rest of this document describes the REE FS only. diff --git a/documentation/secure_storage_sql.md b/documentation/secure_storage_sql.md deleted file mode 100644 index 620e4777a7b..00000000000 --- a/documentation/secure_storage_sql.md +++ /dev/null @@ -1,74 +0,0 @@ -# SQL DB Secure Storage - -## Introduction - -This document describes the SQL DB secure storage in OP-TEE, which is enabled -by setting CFG_SQL_FS=y. Trusted Applications may use this implementation by -passing a storage ID equal to TEE_STORAGE_PRIVATE_SQL, or TEE_STORAGE_PRIVATE -if CFG_REE_FS and CFG_RPMB_FS are disabled. -With this filesystem, the secure object are stored as individual files in a -SQLite database (which is a file by itself in the REE filesystem). -This implementation may be viewed as a simplified version of the REE FS, because -it uses a single file per persistent object. This is possible because SQLite has -a transaction API which allows atomic updates (and rollback in case of error). - -Files are created in the database by the **libsqlfs** library [[1]](#libsqlfs). -For details about **SQLite**, please refer to [[2]](#SQLite). - -The architecture is depicted below. - -``` - NORMAL WORLD : SECURE WORLD - : - U tee-supplicant : Trusted application - S (sql_fs.c) : (secure storage API) - E libsqlfs ^ : ^ - R SQLite | :~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~: v - K | | : OP-TEE - E v v : (tee_svc_storage.c) - R REE filesystem OP-TEE driver : (tee_sql_fs.c, tee_fs_key_manager.c) - N ^ : ^ - E | : | - L | : | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~ - v v - Secure monitor / EL3 firmware -``` - -## The Secure Storage API - -This part is common with the other filesystems. The interface between the -system calls in [core/tee/tee_svc_storage.c](../core/tee/tee_svc_storage.c) and -the SQL filesystem is the **tee_file_operations** structure `sql_fs_ops`. - -## The SQL filesystem - -The secure side of the SQL FS implementation is mostly in -[core/tee/tee_sql_fs.c](../core/tee/tee_sql_fs.c). This file maps the -operations in `sql_fs_ops` such as `open`, `truncate`, `read`, `write` -and so on, to similar operations on a file that is a container for -the encrypted data and associated meta-data. This container is created and -manipulated by `tee-supplicant` on request from the secure OS. Its logical -layout is similar to REE FS except that there's only a single version of -each field as atomic updates are ensured by **libsqlfs** instead. - -How this file is stored in the SQLite database is private to **libsqlfs**. From -the point of view of OP-TEE, it is a byte-addressable linear file on which -atomic updates can be performed through a standard interface (`open`, -`truncate`, `read`, `write`...) with the addition of `begin_transaction` -and `end_transaction`. - -## Encryption - -The encryption is the same as for REE FS, so you can find more details in the -encryption section of [secure_storage.md](secure_storage.md). Bear in mind that -the only difference lies in the data storage: one single file for the SQL -implementation, versus multiple `meta` and `block` files for the REE FS. - -## References - -- [1] **libsqlfs** -[http://www.nongnu.org/libsqlfs/](http://www.nongnu.org/libsqlfs/), -[https://github.com/guardianproject/libsqlfs](https://github.com/guardianproject/libsqlfs) -- [2] **SQLite** [https://www.sqlite.org/](https://www.sqlite.org/) diff --git a/lib/libutee/include/tee_api_defines_extensions.h b/lib/libutee/include/tee_api_defines_extensions.h index 9a35b2a5362..d21a0ae128e 100644 --- a/lib/libutee/include/tee_api_defines_extensions.h +++ b/lib/libutee/include/tee_api_defines_extensions.h @@ -86,8 +86,8 @@ #define TEE_STORAGE_PRIVATE_REE 0x80000000 /* Storage is the Replay Protected Memory Block partition of an eMMC device */ #define TEE_STORAGE_PRIVATE_RPMB 0x80000100 -/* Storage is provided by a SQLite database in the normal world filesystem */ -#define TEE_STORAGE_PRIVATE_SQL 0x80000200 +/* Was TEE_STORAGE_PRIVATE_SQL, which isn't supported any longer */ +#define TEE_STORAGE_PRIVATE_SQL_RESERVED 0x80000200 /* * Extension of "Memory Access Rights Constants" diff --git a/mk/config.mk b/mk/config.mk index 6fe90f1ee1f..82f713388ed 100644 --- a/mk/config.mk +++ b/mk/config.mk @@ -137,9 +137,6 @@ CFG_RPMB_FS_DEV_ID ?= 0 # - RPMB key provisioning in a controlled environment (factory setup) CFG_RPMB_WRITE_KEY ?= n -# SQL FS stores its data in a SQLite database, accessed by normal world -CFG_SQL_FS ?= n - # Embed public part of this key in OP-TEE OS TA_SIGN_KEY ?= keys/default_ta.pem