From 5af64e3a6e6a6a74ede444082cf8e513a45cefcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:35:00 +0000 Subject: [PATCH 01/12] deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- trustzone-awared-vm/demo/deployment.md | 265 +++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 trustzone-awared-vm/demo/deployment.md diff --git a/trustzone-awared-vm/demo/deployment.md b/trustzone-awared-vm/demo/deployment.md new file mode 100644 index 0000000..d142a5d --- /dev/null +++ b/trustzone-awared-vm/demo/deployment.md @@ -0,0 +1,265 @@ +## Host + +**步骤1**.获取vtzb_proxy源码 + +**步骤2** 获取itrustee_tzdriver源码。 + +下载地址:**https://gitee.com/openeuler/itrustee_tzdriver** + +代码分支:master + +**步骤3**. 获取libboundscheck源码。 + +* 下载地址:**https://gitee.com/openeuler/libboundscheck** + +* 代码分支:master + +**步骤4**. + +将下载、解压缩后libboundscheck源码放置在“vtzb_proxy/”目录与“itrustee_tzdriver”目录下,并修改文件夹名称为libboundscheck + +**步骤5**. 编译vtzb_proxy + +``` +cd vtzb_proxy && make +``` + +**步骤6**.Patch Application + +进入目标目录 itrustee_tzdriver的父级目录,确保补丁文件和目标目录在同一级目录下 + +``` +cd itrustee_tzdriver +patch -p1 <../tzdriver.patch + +``` + +**步骤7**.编译itrustee_tzdriver + +``` +cd itrustee_tzdriver && make +``` + +**步骤8**.加载tzdriver.ko + +``` +sudo insmod tzdriver.ko +``` + + + +## QEMU + +**步骤1**.获取qemuv5.0.0源码 + +``` +git clone -b v5.0.0 https://git.qemu.org/git/qemu.git +``` + +**步骤2**.Patch Application + +进入目标目录 `qemu` 的父级目录,确保补丁文件和目标目录在同一级目录下 + +``` +cd qemu +patch -p1 <../qemu.patch +``` + +**步骤3**.编译qemu + +``` +cd qemu +mkdir build +cd build +../configure --target-list=aarch64-softmmu +make -j$(nproc) + +``` + +**步骤4**.修改虚拟机vm.xml配置文件 + +``` + + openEulerVM03 + 8 + 4 + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/openEulerVM.fd + + + + + + + + + 1 + + destroy + restart + restart + + /home/vmuser/tools/qemu/build/aarch64-softmmu/qemu-system-aarch64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + + + +``` + + + + + + + + + + + +``` + +host里socket路径""/tmp/vm_vtzb_sock0" "/tmp/vm_vtzb_sock1" + +VM 里虚拟串口路径"/dev/virtio-ports/vtzf_serialport0" "/dev/virtio-ports/vtzf_serialport1" + +**步骤5**.定义并启动虚拟机 + +``` +virsh define vm.xml +virsh start openEulerVM03 +``` + + + +## VM + +##### 步骤1. 获取itrustee_client源码。 + +* 下载地址:**https://gitee.com/openeuler/itrustee_client** + +* 代码分支:master + +##### 步骤2. 获取vtzdriver源码。 + +##### 步骤3. 获取libboundscheck源码。 + +* 下载地址:**https://gitee.com/openeuler/libboundscheck** + +* 代码分支:master + +##### 步骤4. + +将下载、解压缩后libboundscheck源码放置在“itrustee_client/”目录以及“vtzdriver”目录下,并修改文件夹名称为libboundscheck + +##### 步骤5. 修改itrustee_client目录下的Makefile + +``` + 82 #APP_CFLAGS += -DCONFIG_KUNPENG_PLATFORM -DCONFIG_AUTH_USERNAME -DCONFIG_AGENT_FS -DCONFIG_AGENT_MISC -DCONFIG_AGENT_SECLOAD + 83 APP_CFLAGS += -DCONFIG_KUNPENG_PLATFORM -DCONFIG_AUTH_USERNAME + +``` + +* 去除teecd宏定义 -DCONFIG_AGENT_FS -DCONFIG_AGENT_MISC -DCONFIG_AGENT_SECLOAD。(agent及其相关功能还未实现) + +##### 步骤6. 编译itrustee_client。 + +``` +cd itrustee_client && make +``` + +##### 步骤7. 部署itrustee_client。 + +``` +cp -rf dist/\*.so /usr/lib64 && ldconfig +cp -rf dist/teecd /usr/bin +cp -rf dist/tlogcat /usr/bin +\# 可选 +cp -rf dist/tee_teleport /usr/bin +cp -rf dist/agentd /usr/bin +``` + +##### 步骤8. 编译vtzdriver + +``` +cd vtzdriver && make +``` + +##### 步骤9.加载 vtzfdriver.ko + +``` +sudo insmod vtzfdriver.ko +``` + + + +## RUN + +VM上的agent功能还未实现,物理机重启后重新加载驱动,host需运行teecd加载kunpeng_sec_drv.sec。 + +host: + +``` +sudo ./vtzb_proxy +``` + +若host与VM通道正常,会打印信息 + +``` +open new socket +open new socket +``` + +VM: + +``` +sudo /usr/bin/teecd +``` + +``` +sudo /vendor/bin/testcase1 [1-9] +``` + -- Gitee From 1d6a6686b99180697767425b7985ea9f49b98dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:50:13 +0000 Subject: [PATCH 02/12] vtzdriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/VM/vtzdriver/Makefile | 32 + .../demo/VM/vtzdriver/inc/tc_ns_client.h | 213 ++ .../demo/VM/vtzdriver/inc/tc_ns_log.h | 69 + .../VM/vtzdriver/inc/teek_client_constants.h | 211 ++ .../demo/VM/vtzdriver/inc/teek_ns_client.h | 256 +++ trustzone-awared-vm/demo/VM/vtzdriver/test | Bin 0 -> 71000 bytes trustzone-awared-vm/demo/VM/vtzdriver/test.c | 140 ++ trustzone-awared-vm/demo/VM/vtzdriver/vtzf.c | 1867 +++++++++++++++++ trustzone-awared-vm/demo/VM/vtzdriver/vtzf.h | 372 ++++ 9 files changed, 3160 insertions(+) create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/Makefile create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_client.h create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_log.h create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_client_constants.h create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_ns_client.h create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/test create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/test.c create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/vtzf.c create mode 100644 trustzone-awared-vm/demo/VM/vtzdriver/vtzf.h diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/Makefile b/trustzone-awared-vm/demo/VM/vtzdriver/Makefile new file mode 100644 index 0000000..e640990 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/Makefile @@ -0,0 +1,32 @@ +#Makefile +obj-m := vtzfdriver.o + +vtzfdriver-objs := vtzf.o + +RESULT := $(shell cat /proc/kallsyms | grep vsnprintf_s) + +STATUS := $(findstring vsnprintf_s, $(RESULT)) + +# ifneq ($(STATUS), vsnprintf_s) +vtzfdriver-objs += libboundscheck/src/memcpy_s.o libboundscheck/src/memset_s.o libboundscheck/src/strcpy_s.o libboundscheck/src/strncpy_s.o \ +libboundscheck/src/memmove_s.o libboundscheck/src/strcat_s.o libboundscheck/src/strncat_s.o libboundscheck/src/strtok_s.o \ +libboundscheck/src/securecutil.o libboundscheck/src/secureprintoutput_a.o libboundscheck/src/snprintf_s.o libboundscheck/src/vsnprintf_s.o +# endif + +KERN_VER = $(shell uname -r) +KERN_DIR = /lib/modules/$(KERN_VER)/build + +EXTRA_CFLAGS += -fstack-protector-strong -DCONFIG_AUTH_ENHANCE +EXTRA_CFLAGS += -I$(PWD)/libboundscheck/include/ +EXTRA_CFLAGS += -I$(PWD)/inc/ + +all: + make -C $(KERN_DIR) M=`pwd` modules + + +.PHONY: clean +clean: + # make -C $(KERN_DIR) M=`pwd` modules clean + -rm -vrf *.o *.ko + -rm -vrf *.order *.symvers *.mod.c *.mod.o .tmp_versions .*o.cmd .*.o.d + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_client.h b/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_client.h new file mode 100644 index 0000000..d88f4d3 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_client.h @@ -0,0 +1,213 @@ +/* + * tc_ns_client.h + * + * data structure declaration for nonsecure world + * + * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef TC_NS_CLIENT_H +#define TC_NS_CLIENT_H + +#include +#include + +#define UUID_LEN 16 +#define PARAM_NUM 4 +#define ADDR_TRANS_NUM 32 + +#define teec_param_types(param0_type, param1_type, param2_type, param3_type) \ + ((param3_type) << 12 | (param2_type) << 8 | \ + (param1_type) << 4 | (param0_type)) + +#define teec_param_type_get(param_types, index) \ + (((param_types) >> ((index) << 2)) & 0x0F) + +#ifndef ZERO_SIZE_PTR +#define ZERO_SIZE_PTR ((void *)16) +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) +#endif + +#if (KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE) +#define mm_sem_lock(mm) (mm)->mmap_lock +#else +#define mm_sem_lock(mm) (mm)->mmap_sem +#endif + +struct tc_ns_client_login { + __u32 method; + __u32 mdata; +}; + +union tc_ns_client_param { + struct { + __u32 buffer; + __u32 buffer_h_addr; + __u32 offset; + __u32 h_offset; + __u32 size_addr; + __u32 size_h_addr; + } memref; + struct { + __u32 a_addr; + __u32 a_h_addr; + __u32 b_addr; + __u32 b_h_addr; + } value; +}; + +struct tc_ns_client_return { + int code; + __u32 origin; +}; + +struct tc_ns_client_context { + unsigned char uuid[UUID_LEN]; + __u32 session_id; + __u32 cmd_id; + struct tc_ns_client_return returns; + struct tc_ns_client_login login; + union tc_ns_client_param params[PARAM_NUM]; + __u32 param_types; + __u8 started; + __u32 calling_pid; + unsigned int file_size; + union { + char *file_buffer; + struct { + uint32_t file_addr; + uint32_t file_h_addr; + } memref; + }; +}; + +struct tc_ns_client_time { + uint32_t seconds; + uint32_t millis; +}; + +struct tc_ns_tee_info { + uint16_t tzdriver_version_major; + uint16_t tzdriver_version_minor; + uint32_t reserved[15]; +}; + +enum secfile_type_t { + LOAD_TA = 0, + LOAD_SERVICE, + LOAD_LIB, + LOAD_DYNAMIC_DRV, + LOAD_PATCH, + LOAD_TYPE_MAX, +}; + +struct sec_file_info { + enum secfile_type_t secfile_type; + uint32_t file_size; + int32_t sec_load_err; +}; + +struct load_secfile_ioctl_struct { + struct sec_file_info sec_file_info; + unsigned char uuid[UUID_LEN]; + union { + char *file_buffer; + struct { + uint32_t file_addr; + uint32_t file_h_addr; + } memref; + }; +}__attribute__((packed)); + +struct agent_ioctl_args { + uint32_t id; + uint32_t buffer_size; + union { + void *buffer; + unsigned long long addr; + }; +}; + +struct tc_ns_client_crl { + union { + uint8_t *buffer; + struct { + uint32_t buffer_addr; + uint32_t buffer_h_addr; + } memref; + }; + uint32_t size; +}; + +#ifdef CONFIG_LOG_POOL_ENABLE +struct tc_ns_log_pool { + uint64_t addr; + uint64_t size; +}; +#endif + +#define MAX_SHA_256_SZ 32 + +#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ \ + _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, struct tc_ns_client_context) +#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, struct tc_ns_client_context) +#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, struct tc_ns_client_context) +#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int) +#define TC_NS_CLIENT_IOCTL_WAIT_EVENT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int) +#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int) +#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct agent_ioctl_args) +#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int) +#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct load_secfile_ioctl_struct) +#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, struct tc_ns_client_context) +#define TC_NS_CLIENT_IOCTL_ALLOC_EXCEPTING_MEM \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 12, unsigned int) +#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, struct tc_ns_client_context) +#define TC_NS_CLIENT_IOCTL_LOGIN \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int) +#define TC_NS_CLIENT_IOCTL_TUI_EVENT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int) +#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, struct tc_ns_client_time) +#define TC_NS_CLIENT_IOCTL_SET_NATIVECA_IDENTITY \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int) +#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int) +#define TC_NS_CLIENT_IOCTL_LATEINIT \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int) +#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int) +#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL\ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct tc_ns_client_crl) +#ifdef CONFIG_LOG_POOL_ENABLE +#define TC_NS_CLIENT_IOCTL_GET_LOG_POOL \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 23, struct tc_ns_log_pool) +#endif +#ifdef CONFIG_TEE_TELEPORT_SUPPORT +#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct agent_ioctl_args) +#define TC_NS_CLIENT_IOCTL_PORTAL_WORK \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct agent_ioctl_args) +#endif +#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info) +#endif + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_log.h b/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_log.h new file mode 100644 index 0000000..33a1e90 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/inc/tc_ns_log.h @@ -0,0 +1,69 @@ +/* + * tc_ns_log.h + * + * log func declaration + * + * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef TC_NS_LOG_H +#define TC_NS_LOG_H + +#include +#if (KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE) +#include +#endif +#include +enum { + TZ_DEBUG_VERBOSE = 0, + TZ_DEBUG_DEBUG, + TZ_DEBUG_INFO, + TZ_DEBUG_WARN, + TZ_DEBUG_ERROR, +}; +#define MOD_TEE "tzdriver" + +#define TEE_LOG_MASK TZ_DEBUG_WARN + +#define tlogv(fmt, args...) \ +do { \ + if (TZ_DEBUG_VERBOSE >= TEE_LOG_MASK) \ + pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \ +} while (0) + + +#define tlogd(fmt, args...) \ +do { \ + if (TZ_DEBUG_DEBUG >= TEE_LOG_MASK) \ + pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \ +} while (0) + + +#define tlogi(fmt, args...) \ +do { \ + if (TZ_DEBUG_INFO >= TEE_LOG_MASK) \ + pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \ +} while (0) + + +#define tlogw(fmt, args...) \ +do { \ + if (TZ_DEBUG_WARN >= TEE_LOG_MASK) \ + pr_warn("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \ +} while (0) + + +#define tloge(fmt, args...) \ + pr_err("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args) + +#endif + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_client_constants.h b/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_client_constants.h new file mode 100644 index 0000000..6b0b32a --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_client_constants.h @@ -0,0 +1,211 @@ +/* + * teek_client_constants.h + * + * macro declaration for libteec interface for kernel CA. + * + * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef TEEK_CLIENT_CONSTANTS_H +#define TEEK_CLIENT_CONSTANTS_H + +enum global_service_cmd_id { + GLOBAL_CMD_ID_INVALID = 0x0, + GLOBAL_CMD_ID_BOOT_ACK = 0x1, + GLOBAL_CMD_ID_OPEN_SESSION = 0x2, + GLOBAL_CMD_ID_CLOSE_SESSION = 0x3, + GLOBAL_CMD_ID_LOAD_SECURE_APP = 0x4, + GLOBAL_CMD_ID_NEED_LOAD_APP = 0x5, + GLOBAL_CMD_ID_REGISTER_AGENT = 0x6, + GLOBAL_CMD_ID_UNREGISTER_AGENT = 0x7, + GLOBAL_CMD_ID_REGISTER_NOTIFY_MEMORY = 0x8, + GLOBAL_CMD_ID_UNREGISTER_NOTIFY_MEMORY = 0x9, + GLOBAL_CMD_ID_INIT_CONTENT_PATH = 0xa, + GLOBAL_CMD_ID_TERMINATE_CONTENT_PATH = 0xb, + GLOBAL_CMD_ID_ALLOC_EXCEPTION_MEM = 0xc, + GLOBAL_CMD_ID_TEE_TIME = 0xd, + GLOBAL_CMD_ID_TEE_INFO = 0xe, + GLOBAL_CMD_ID_REGISTER_LOG_MEM = 0xf, + GLOBAL_CMD_ID_KILL_TASK = 0x10, + GLOBAL_CMD_ID_TUI_EXCEPTION = 0x11, + GLOBAL_CMD_ID_ADJUST_TIME = 0x12, + GLOBAL_CMD_ID_SET_CA_HASH = 0x13, + /* set the Android's build version */ + GLOBAL_CMD_ID_SET_BUILD_VERSION = 0x14, + GLOBAL_CMD_ID_REGISTER_TTF_MEM = 0x15, + /* get session key for encrypting dialog */ + GLOBAL_CMD_ID_GET_SESSION_SECURE_PARAMS = 0x16, + GLOBAL_CMD_ID_REGISTER_MAILBOX = 0x17, + GLOBAL_CMD_ID_REGISTER_UNUSUAL_TTF_MEM = 0x18, + GLOBAL_CMD_ID_REGISTER_ION_MEM = 0x19, + GLOBAL_CMD_ID_DUMP_MEMINFO = 0x1a, + /* this cmd will be used to service no ca handle cmd */ + GLOBAL_CMD_ID_SET_SERVE_CMD = 0x1b, + GLOBAL_CMD_ID_ADD_DYNAMIC_ION = 0x1c, + GLOBAL_CMD_ID_DEL_DYNAMIC_ION = 0x1d, + GLOBAL_CMD_ID_RELEASE_ION_SRV = 0x1e, + /* this cmd for tui to get notch_size */ + GLOBAL_CMD_ID_TUI_NOTCH = 0x1f, + GLOBAL_CMD_ID_LATE_INIT = 0x20, + /* this cmd for tui to get information of foldable screen */ + GLOBAL_CMD_ID_TUI_FOLD = 0x21, + GLOBAL_CMD_ID_GET_TEE_VERSION = 0x22, + GLOBAL_CMD_ID_REGISTER_RESMEM = 0x24, + GLOBAL_CMD_ID_DUMP_SRV_SESS = 0x25, + GLOBAL_CMD_ID_TRACE_ENABLE = 0x26, +#ifdef CONFIG_TEE_TELEPORT_SUPPORT + GLOBAL_CMD_ID_PORTAL_WORK = 0x2b, +#endif + GLOBAL_CMD_ID_REGISTER_HOST_NSID = 0x2d, + GLOBAL_CMD_ID_UNKNOWN = 0x7FFFFFFE, + GLOBAL_CMD_ID_MAX = 0x7FFFFFFF +}; + +enum teec_result { + TEEC_SUCCESS = 0x0, + TEEC_ERROR_INVALID_CMD = 0x1, + TEEC_ERROR_SERVICE_NOT_EXIST = 0x2, + TEEC_ERROR_SESSION_NOT_EXIST = 0x3, + TEEC_ERROR_SESSION_MAXIMUM, + TEEC_ERROR_REGISTER_EXIST_SERVICE, + TEEC_ERROR_TAGET_DEAD_FATAL, + TEEC_ERROR_READ_DATA, + TEEC_ERROR_WRITE_DATA, + TEEC_ERROR_TRUNCATE_OBJECT, + TEEC_ERROR_SEEK_DATA, + TEEC_ERROR_RENAME_OBJECT, + TEEC_ERROR_TRUSTED_APP_LOAD_ERROR, + TEEC_ERROR_GENERIC = 0xFFFF0000, + TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001, + TEEC_ERROR_CANCEL = 0xFFFF0002, + TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003, + TEEC_ERROR_EXCESS_DATA = 0xFFFF0004, + TEEC_ERROR_BAD_FORMAT = 0xFFFF0005, + TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006, + TEEC_ERROR_BAD_STATE = 0xFFFF0007, + TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008, + TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009, + TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A, + TEEC_ERROR_NO_DATA = 0xFFFF000B, + TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C, + TEEC_ERROR_BUSY = 0xFFFF000D, + TEEC_ERROR_COMMUNICATION = 0xFFFF000E, + TEEC_ERROR_SECURITY = 0xFFFF000F, + TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010, + TEEC_PENDING = 0xFFFF2000, + TEEC_PENDING2 = 0xFFFF2001, + TEE_ERROR_TAGET_DEAD = 0xFFFF3024, + TEE_ERROR_GT_DEAD = 0xFFFF3124, + TEEC_ERROR_MAC_INVALID = 0xFFFF3071, + TEEC_CLIENT_INTR = 0xFFFF4000, + TEEC_ERROR_TUI_IN_USE = 0xFFFF7110, + TEEC_ERROR_TUI_SWITCH_CHANNAL, + TEEC_ERROR_TUI_CFG_DRIVER, + TEEC_ERROR_TUI_INVALID_EVENT, + TEEC_ERROR_TUI_POLL_EVENT, + TEEC_ERROR_TUI_CANCELED, + TEEC_ERROR_TUI_EXIT, + TEEC_ERROR_TUI_NOT_AVAILABLE, + TEEC_ERROR_SEC_FLASH_NOT_AVAILABLE, + TEEC_ERROR_CA_AUTH_FAIL = 0xFFFFCFE5, + TEE_ERROR_AUDIT_FAIL = 0xFFFF9112, + TEE_ERROR_IS_DEAD = 0xFFFFABAB, +}; + +enum TEEC_ReturnCodeOrigin { + TEEC_ORIGIN_API = 0x1, + TEEC_ORIGIN_COMMS = 0x2, + TEEC_ORIGIN_TEE = 0x3, + TEEC_ORIGIN_TRUSTED_APP = 0x4, +}; + +enum TEEC_SharedMemCtl { + TEEC_MEM_INPUT = 0x1, + TEEC_MEM_OUTPUT = 0x2, + TEEC_MEM_INOUT = 0x3, +}; + +enum TEEC_ParamType { + TEEC_NONE = 0x0, + TEEC_VALUE_INPUT = 0x01, + TEEC_VALUE_OUTPUT = 0x02, + TEEC_VALUE_INOUT = 0x03, + TEEC_MEMREF_TEMP_INPUT = 0x05, + TEEC_MEMREF_TEMP_OUTPUT = 0x06, + TEEC_MEMREF_TEMP_INOUT = 0x07, + TEEC_ION_INPUT = 0x08, + TEEC_ION_SGLIST_INPUT = 0x09, + TEEC_MEMREF_SHARED_INOUT = 0x0a, + TEEC_MEMREF_WHOLE = 0xc, + TEEC_MEMREF_PARTIAL_INPUT = 0xd, + TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, + TEEC_MEMREF_PARTIAL_INOUT = 0xf +}; + +enum TEE_ParamType { + TEE_PARAM_TYPE_NONE = 0x0, + TEE_PARAM_TYPE_VALUE_INPUT = 0x1, + TEE_PARAM_TYPE_VALUE_OUTPUT = 0x2, + TEE_PARAM_TYPE_VALUE_INOUT = 0x3, + TEE_PARAM_TYPE_MEMREF_INPUT = 0x5, + TEE_PARAM_TYPE_MEMREF_OUTPUT = 0x6, + TEE_PARAM_TYPE_MEMREF_INOUT = 0x7, + TEE_PARAM_TYPE_ION_INPUT = 0x8, + TEE_PARAM_TYPE_ION_SGLIST_INPUT = 0x9, + TEE_PARAM_TYPE_MEMREF_SHARED_INOUT = 0x0a, + TEE_PARAM_TYPE_RESMEM_INPUT = 0xc, + TEE_PARAM_TYPE_RESMEM_OUTPUT = 0xd, + TEE_PARAM_TYPE_RESMEM_INOUT = 0xe +}; + +enum TEEC_LoginMethod { + TEEC_LOGIN_PUBLIC = 0x0, + TEEC_LOGIN_USER, + TEEC_LOGIN_GROUP, + TEEC_LOGIN_APPLICATION = 0x4, + TEEC_LOGIN_USER_APPLICATION = 0x5, + TEEC_LOGIN_GROUP_APPLICATION = 0x6, + TEEC_LOGIN_IDENTIFY = 0x7, + TEEK_LOGIN_IDENTIFY = 0x80000001, +}; + +/* Add event id's name in 'view_state[]' in same order */ +enum tee_event_id { + INVOKE_CMD_START, + INVOKE_CMD_END, + SMC_SEND, + SMC_DONE, + SMC_IN, + SMC_OUT, + SMC_SLEEP, + SMC_PREEMPT, + GTASK_GET_CMD, + GTASK_PUT_CMD, + GTASK_REQ_TA, + GTASK_RESP_TA, + SPI_WAKEUP, + SCHED_IN, + SCHED_OUT, + INTERRUPT_HANDLE_SPI_START, + INTERRUPT_HANDLE_SPI_REE_RESPONSE, + INTERRUPT_HANDLE_SPI_REE_MISS, + INTERRUPT_HANDLE_SPI_REE_SCHEDULED, + INTERRUPT_HANDLE_SPI_END, + INTERRUPT_HANDLE_START, + INTERRUPT_HANDLE_END, + TEE_EVENT_MAX +}; + +#define TZ_WQ_MAX_ACTIVE 1 +#endif + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_ns_client.h b/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_ns_client.h new file mode 100644 index 0000000..7a6c008 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/inc/teek_ns_client.h @@ -0,0 +1,256 @@ +/* + * teek_ns_client.h + * + * define structures and IOCTLs. + * + * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef TEEK_NS_CLIENT_H +#define TEEK_NS_CLIENT_H + +#include +#include +#include +#include +#include "tc_ns_client.h" +#include "tc_ns_log.h" + +#define TC_NS_CLIENT_IOC_MAGIC 't' +#define TC_NS_CLIENT_DEV "tc_ns_client" +#define TC_PRIV_DEV "tc_private" +#define TC_NS_CVM_DEV "tc_ns_cvm" +#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" + +#define EXCEPTION_MEM_SIZE (8*1024) /* mem for exception handling */ + +#define TSP_REQUEST 0xB2000008 +#define TSP_RESPONSE 0xB2000009 + +#define TSP_REE_SIQ 0xB200000A +#define TSP_CRASH 0xB200000B + +#ifdef CONFIG_TEE_UPGRADE +#define TSP_REBOOT 0xB2000012 +#define TSP_CPU_ON 0xB2000013 +#define TSP_REBOOT_DONE 0xB2000015 +#else +#define TSP_REBOOT 0xB200000E +#define TSP_CPU_ON 0xB200000F +#define TSP_REBOOT_DONE 0xB2000010 +#endif + +#define TSP_PREEMPTED 0xB2000005 +#define TC_CALL_GLOBAL 0x01 +#define TC_CALL_SYNC 0x02 +#define TC_CALL_LOGIN 0x04 +#define TEE_REQ_FROM_USER_MODE 0U +#define TEE_REQ_FROM_KERNEL_MODE 1U +#define TEE_PARAM_NUM 4 +#define VMALLOC_TYPE 0 +#define RESERVED_TYPE 1 + +/* Max sizes for login info buffer comming from teecd */ +#define MAX_PACKAGE_NAME_LEN 255 +/* The apk certificate format is as follows: + * modulus_size(4 bytes) + modulus buffer(512 bytes) + * + exponent size(4 bytes) + exponent buffer(1 bytes) + */ +#define MAX_PUBKEY_LEN 1024 + +struct tc_ns_dev_list { + struct mutex dev_lock; /* for dev_file_list */ + struct list_head dev_file_list; +}; + +struct tc_uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t timehi_and_version; + uint8_t clockseq_and_node[8]; /* clock len is 8 */ +}; + +#define INVALID_MAP_ADDR ((void*)-1) +struct tc_ns_shared_mem { + void *kernel_addr; + void *user_addr; + void *user_addr_ca; /* for ca alloc share mem */ + unsigned int len; + int mem_type; + struct list_head head; + atomic_t usage; + atomic_t offset; +}; + +struct tc_ns_service { + unsigned char uuid[UUID_LEN]; + struct mutex session_lock; /* for session_list */ + struct list_head session_list; + struct list_head head; + struct mutex operation_lock; /* for session's open/close */ + atomic_t usage; + unsigned int nsid; +}; + +#define SERVICES_MAX_COUNT 32 /* service limit can opened on 1 fd */ +struct tc_ns_dev_file { + unsigned int dev_file_id; + struct mutex service_lock; /* for service_ref[], services[] */ + uint8_t service_ref[SERVICES_MAX_COUNT]; /* a judge if set services[i]=NULL */ + struct tc_ns_service *services[SERVICES_MAX_COUNT]; + struct mutex shared_mem_lock; /* for shared_mem_list */ + struct list_head shared_mem_list; + struct list_head head; + /* Device is linked to call from kernel */ + uint8_t kernel_api; + /* client login info provided by teecd, can be either package name and public + * key or uid(for non android services/daemons) + * login information can only be set once, dont' allow subsequent calls + */ + bool login_setup; + struct mutex login_setup_lock; /* for login_setup */ +#ifdef CONFIG_AUTH_HASH + bool cainfo_hash_setup; + struct mutex cainfo_hash_setup_lock; +#endif + uint32_t pkg_name_len; + uint8_t pkg_name[MAX_PACKAGE_NAME_LEN]; + uint32_t pub_key_len; + uint8_t pub_key[MAX_PUBKEY_LEN]; + int load_app_flag; +#ifdef CONFIG_CONFIDENTIAL_CONTAINER + uint32_t nsid; +#endif + struct completion close_comp; /* for kthread close unclosed session */ +#ifdef CONFIG_TEE_TELEPORT_SUPPORT + bool portal_enabled; +#endif +}; + +union tc_ns_parameter { + struct { + unsigned int buffer; + unsigned int size; + } memref; + struct { + unsigned int a; + unsigned int b; + } value; +}; + +struct tc_ns_login { + unsigned int method; + unsigned int mdata; +}; + +struct tc_ns_operation { + unsigned int paramtypes; + union tc_ns_parameter params[TEE_PARAM_NUM]; + unsigned int buffer_h_addr[TEE_PARAM_NUM]; + struct tc_ns_shared_mem *sharemem[TEE_PARAM_NUM]; + void *mb_buffer[TEE_PARAM_NUM]; +}; + +struct tc_ns_temp_buf { + void *temp_buffer; + unsigned int size; +}; + +enum smc_cmd_type { + CMD_TYPE_GLOBAL, + CMD_TYPE_TA, + CMD_TYPE_TA_AGENT, + CMD_TYPE_TA2TA_AGENT, /* compatible with TA2TA2TA->AGENT etc. */ + CMD_TYPE_BUILDIN_AGENT, + CMD_TYPE_RELEASE_AGENT, /* only for release agent */ +}; + +struct tc_ns_smc_cmd { + uint8_t uuid[sizeof(struct tc_uuid)]; + unsigned int cmd_type; + unsigned int cmd_id; + unsigned int dev_file_id; + unsigned int context_id; + unsigned int agent_id; + unsigned int operation_phys; + unsigned int operation_h_phys; + unsigned int login_method; + unsigned int login_data_phy; + unsigned int login_data_h_addr; + unsigned int login_data_len; + unsigned int err_origin; + int ret_val; + unsigned int event_nr; + unsigned int uid; + unsigned int ca_pid; /* pid */ + unsigned int pid; /* tgid */ + unsigned int nsid; + unsigned int eventindex; /* tee audit event index for upload */ + bool started; +} __attribute__((__packed__)); + +/* + * @brief + */ +struct tc_wait_data { + wait_queue_head_t send_cmd_wq; + int send_wait_flag; +}; + +#define NUM_OF_SO 1 +#ifdef CONFIG_CMS_CAHASH_AUTH +#define KIND_OF_SO 1 +#else +#define KIND_OF_SO 2 +#endif +struct tc_ns_session { + unsigned int session_id; + struct list_head head; + struct tc_wait_data wait_data; + struct mutex ta_session_lock; /* for open/close/invoke on 1 session */ + struct tc_ns_dev_file *owner; + uint8_t auth_hash_buf[MAX_SHA_256_SZ * NUM_OF_SO + MAX_SHA_256_SZ]; + atomic_t usage; +}; + +struct mb_cmd_pack { + struct tc_ns_operation operation; + unsigned char login_data[MAX_SHA_256_SZ * NUM_OF_SO + MAX_SHA_256_SZ]; +}; + +struct load_img_params { + struct tc_ns_dev_file *dev_file; + const char *file_buffer; + unsigned int file_size; + struct mb_cmd_pack *mb_pack; + char *mb_load_mem; + struct tc_uuid *uuid_return; + unsigned int mb_load_size; +}; + +struct tc_call_params { + struct tc_ns_dev_file *dev; + struct tc_ns_client_context *context; + struct tc_ns_session *sess; + uint8_t flags; +}; + +struct tc_op_params { + struct mb_cmd_pack *mb_pack; + struct tc_ns_smc_cmd *smc_cmd; + struct tc_ns_temp_buf local_tmpbuf[TEE_PARAM_NUM]; + uint32_t trans_paramtype[TEE_PARAM_NUM]; + bool op_inited; +}; + +#endif + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/test b/trustzone-awared-vm/demo/VM/vtzdriver/test new file mode 100644 index 0000000000000000000000000000000000000000..4bc1e56c225562671365ff22cdd2aff85adec4a1 GIT binary patch literal 71000 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 N65sRYP(Y|k{|1JO19boZ literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/test.c b/trustzone-awared-vm/demo/VM/vtzdriver/test.c new file mode 100644 index 0000000..40549ab --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/test.c @@ -0,0 +1,140 @@ +#include +#include /* for errno */ +#include +#include /* for open close */ +#include +#include +#include +#include +#include + +#define VTZF_SERIALPORT "/dev/virtio-ports/vtzf_serialport0" +#define VTZF_DEV_NAME "/dev/vtzf" +#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" +#define VTZF_IOC_MAGIC 'v' +#define VTZF_IOCTL_SER_TEST _IOWR(VTZF_IOC_MAGIC, 10, int) +#define TC_NS_CLIENT_IOC_MAGIC 't' +#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext) + +typedef struct { + unsigned int method; + unsigned int mdata; +} TC_NS_ClientLogin; + +typedef union { + struct { + unsigned int buffer; + unsigned int buffer_h_addr; + unsigned int offset; + unsigned int h_offset; + unsigned int size_addr; + unsigned int size_h_addr; + } memref; + struct { + unsigned int a_addr; + unsigned int a_h_addr; + unsigned int b_addr; + unsigned int b_h_addr; + } value; +} TC_NS_ClientParam; + +typedef struct { + unsigned int code; + unsigned int origin; +} TC_NS_ClientReturn; + +typedef struct { + unsigned char uuid[16]; + unsigned int session_id; + unsigned int cmd_id; + TC_NS_ClientReturn returns; + TC_NS_ClientLogin login; + TC_NS_ClientParam params[4]; + unsigned int paramTypes; + bool started; + unsigned int callingPid; + unsigned int file_size; + union { + char *file_buffer; + struct { + unsigned int file_addr; + unsigned int file_h_addr; + } memref; + }; +} TC_NS_ClientContext; + + +int main() +{ + int vtzf_dev_fd; + vtzf_dev_fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR); + if (vtzf_dev_fd!=-1){ + printf("open tzdriver success \n"); + } else{ + printf("open tzdriver failed \n"); + return 0; + } + + TC_NS_ClientContext cliContext; + cliContext.login.method = 7U; + cliContext.file_size = 10086U; + int ret = ioctl(vtzf_dev_fd, (int)TC_NS_CLIENT_IOCTL_SES_OPEN_REQ, &cliContext); + printf(" ret = %d \n", ret); +} + +/* +int main(){ + int vtzf_dev_fd; + //int fd = open(VTZF_SERIALPORT, O_RDWR); + //printf("serial_port_fd =%d \n", fd); + + vtzf_dev_fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR); + if (vtzf_dev_fd!=-1){ + printf("open tzdriver success \n"); + } else{ + printf("open tzdriver failed \n"); + return 0; + } + int cmd = 1; + + int ret; + int val = 251; + for(int i = 0;i<100;i++){ + cmd = 3; + ret = ioctl(vtzf_dev_fd, (int)VTZF_IOCTL_SER_TEST, &cmd); + if (ret == 0){ + printf("rsp =%d , val =%d \n", cmd, val++); + } else{ + printf(" send to proxy failed \n"); + } + } + + close(vtzf_dev_fd); +} +*/ +/* +int main(){ + int vtzf_dev_fd; + vtzf_dev_fd = open(VTZF_DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR); + if (vtzf_dev_fd!=-1){ + printf("open tzdriver success \n"); + } else{ + return 1; + } + + int cmd = 3; + int ret = ioctl(vtzf_dev_fd, (int)VTZF_IOCTL_SER_TEST, &cmd); + if (ret == 0){ + printf("rsp =%d \n", cmd); + } + + cmd = 2; + + ret = ioctl(vtzf_dev_fd, (int)VTZF_IOCTL_SER_TEST, &cmd); + if(ret == 0){ + printf("close serial success \n"); + } + + close(vtzf_dev_fd); +} +*/ diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.c b/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.c new file mode 100644 index 0000000..3e81764 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.c @@ -0,0 +1,1867 @@ +#include +#include +#include +#include +// #include +#include +// #include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include + +#include "vtzf.h" + +#include "securec.h" +#include "tc_ns_client.h" +#include "tc_ns_log.h" +#include "teek_client_constants.h" + +#define PRINTF_SIZE 16 +void dump_buff(const char* buffer, size_t bufLen) { + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + // printf("\n--------------------------------------------------\n"); + tlogd("--------------------------------------------------\n"); + tlogd("bufLen = %d\n", (int)bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0 && i != 0) { + tlogd("\n"); + } + tlogd("%02x ", *(buffer + i)); + } + tlogd("\n--------------------------------------------------\n"); + return; +} + +struct mutex g_seq_lock; +uint32_t g_seq_num; +static struct class *g_driver_class; +static struct device_node *g_dev_node; + +struct dev_node g_tc_client; +struct dev_node g_tc_private; +/* dev node list and itself has mutex to avoid race */ +struct vtzf_dev_list g_tc_ns_dev_list; +struct vtzf_serial_port_list g_serial_port_list; + +static unsigned int g_device_file_cnt = 1; +static DEFINE_MUTEX(g_device_file_cnt_lock); + +static struct vm_operations_struct g_shared_remap_vm_ops = { + .open = shared_vma_open, + .close = shared_vma_close, +}; + + +static const struct file_operations g_tc_ns_client_fops = { + .owner = THIS_MODULE, + .open = vtzf_client_open, + .release = vtzf_close, + .unlocked_ioctl = tc_client_ioctl, + .mmap = vtzf_mmap, +#ifdef CONFIG_COMPAT + .compat_ioctl = tc_compat_client_ioctl, +#endif +}; + +static const struct file_operations g_teecd_fops = { + .owner = THIS_MODULE, + .open = vtzf_private_open, + .release = vtzf_close, + .unlocked_ioctl = tc_private_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tc_compat_private_ioctl, +#endif +}; + +struct vtzf_dev_list *get_dev_list(void) +{ + return &g_tc_ns_dev_list; +} + +struct vtzf_serial_port_list *get_serial_port_list(void) +{ + return &g_serial_port_list; +} + +static uint32_t get_seq_num(void) +{ + uint32_t ret; + mutex_lock(&g_seq_lock); + g_seq_num = (g_seq_num + 2) % 65536; + ret = g_seq_num; + mutex_unlock(&g_seq_lock); + return ret; +} + +static int create_dev_node(struct dev_node *node) +{ + int ret; + if (!node || !(node->node_name)) { + tloge("node or member is null\n"); + return -EFAULT; + } + if (alloc_chrdev_region(&(node->devt), 0, 1, + node->node_name) != 0) { + tloge("alloc chrdev region failed"); + ret = -EFAULT; + return ret; + } + node->class_dev = device_create(node->driver_class, NULL, node->devt, + NULL, node->node_name); + if (IS_ERR_OR_NULL(node->class_dev)) { + tloge("class device create failed"); + ret = -ENOMEM; + goto chrdev_region_unregister; + } + node->class_dev->of_node = g_dev_node; + + cdev_init(&(node->char_dev), node->fops); + (node->char_dev).owner = THIS_MODULE; + + return 0; + +chrdev_region_unregister: + unregister_chrdev_region(node->devt, 1); + return ret; +} + +static int init_dev_node(struct dev_node *node, char *node_name, + struct class *driver_class, const struct file_operations *fops) +{ + int ret = -1; + if (!node) { + tloge("node is NULL\n"); + return ret; + } + node->node_name = node_name; + node->driver_class = driver_class; + node->fops = fops; + + ret = create_dev_node(node); + return ret; +} + +static void destory_dev_node(struct dev_node *node, struct class *driver_class) +{ + device_destroy(driver_class, node->devt); + unregister_chrdev_region(node->devt, 1); + return; +} + +static int tc_ns_client_init(void) +{ + int ret; + + g_driver_class = class_create(THIS_MODULE, TC_NS_CLIENT_DEV); + if (IS_ERR_OR_NULL(g_driver_class)) { + tloge("class create failed"); + ret = -ENOMEM; + return ret; + } + + ret = init_dev_node(&g_tc_client, TC_NS_CLIENT_DEV, g_driver_class, &g_tc_ns_client_fops); + if (ret != 0) { + class_destroy(g_driver_class); + return ret; + } + ret = init_dev_node(&g_tc_private, TC_PRIV_DEV, g_driver_class, &g_teecd_fops); + if (ret != 0) { + destory_dev_node(&g_tc_client, g_driver_class); + class_destroy(g_driver_class); + return ret; + } +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + ret = init_dev_node(&g_tc_cvm, TC_NS_CVM_DEV, g_driver_class, get_cvm_fops()); + if (ret != 0) { + destory_dev_node(&g_tc_private, g_driver_class); + destory_dev_node(&g_tc_client, g_driver_class); + class_destroy(g_driver_class); + return ret; + } +#endif + INIT_LIST_HEAD(&g_tc_ns_dev_list.dev_file_list); + mutex_init(&g_tc_ns_dev_list.dev_lock); + return ret; +} + +static int enable_dev_nodes(void) +{ + int ret; + + ret = cdev_add(&(g_tc_private.char_dev), + MKDEV(MAJOR(g_tc_private.devt), 0), 1); + if (ret < 0) { + tloge("cdev add failed %d", ret); + return ret; + } + + ret = cdev_add(&(g_tc_client.char_dev), + MKDEV(MAJOR(g_tc_client.devt), 0), 1); + if (ret < 0) { + tloge("cdev add failed %d", ret); + cdev_del(&(g_tc_private.char_dev)); + return ret; + } + +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + ret = cdev_add(&(g_tc_cvm.char_dev), + MKDEV(MAJOR(g_tc_cvm.devt), 0), 1); + if (ret < 0) { + tloge("cdev add failed %d", ret); + cdev_del(&(g_tc_client.char_dev)); + cdev_del(&(g_tc_private.char_dev)); + return ret; + } +#endif + return 0; +} + +static void free_serial_port_list(void) +{ + struct vtzf_serial_port_file *dev_file = NULL, *temp = NULL; + + mutex_lock(&g_serial_port_list.lock); + list_for_each_entry_safe(dev_file, temp, &g_serial_port_list.head, head) { + list_del(&dev_file->head); + if (dev_file->filep) { + filp_close(dev_file->filep, NULL); + } + if (dev_file->buffer) { + kfree(dev_file->buffer); + } + mutex_destroy(&dev_file->lock); + kfree(dev_file); + } + mutex_unlock(&g_serial_port_list.lock); +} + +static int serial_port_init(void) +{ + int ret = 0; + int i; + int size_written; + struct file *file; + struct vtzf_serial_port_file *serial_port_file = NULL; + void *buffer = NULL; + char device_path[256];// = "/dev/virtio-ports/vtzf_serialport1"; + INIT_LIST_HEAD(&g_serial_port_list.head); + mutex_init(&g_serial_port_list.lock); + + for(i=0;i < 2;i++) { + size_written = snprintf(device_path, sizeof(device_path), "%s%d", VTZF_SERIALPORT, i); + + serial_port_file = kzalloc(sizeof(*serial_port_file), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)serial_port_file)) { + tloge("alloc serial_port_file failed\n"); + ret = -ENOMEM; + goto err; + } + buffer = kzalloc(SERIAL_PORT_BUF_LEN, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("alloc serial_port_file failed\n"); + ret = -ENOMEM; + kfree(serial_port_file); + goto err; + } + // 打开设备文件 + file = filp_open(device_path, O_RDWR, 0); + if (IS_ERR(file)) { + tloge("open serial_pore failed \n"); + ret = -EFAULT; + kfree(serial_port_file); + kfree(buffer); + goto err; + } + serial_port_file->filep = file; + serial_port_file->buffer = buffer; + mutex_init(&serial_port_file->lock); + list_add_tail(&serial_port_file->head, &g_serial_port_list.head); + } + tlogd(" open serial success -----------\n"); + return 0; +err: + mutex_destroy(&g_serial_port_list.lock); + free_serial_port_list(); + return ret; +} + +static void seq_num_init(void) +{ + mutex_init(&g_seq_lock); + g_seq_num = 0; +} + +static int __init vtzf_init(void) +{ + int ret; + ret = tc_ns_client_init(); + if (ret != 0) + return ret; + + ret = enable_dev_nodes(); + if (ret != 0) { + tloge("enable dev nodes failed\n"); + goto class_device_destroy; + } + ret = serial_port_init(); + if (ret != 0) { + goto class_device_destroy; + } + seq_num_init(); + return 0; + +class_device_destroy: +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + destory_dev_node(&g_tc_cvm, g_driver_class); +#endif + destory_dev_node(&g_tc_client, g_driver_class); + destory_dev_node(&g_tc_private, g_driver_class); + class_destroy(g_driver_class); + //platform_driver_unregister(&g_tz_platform_driver); + return ret; +} + +static void free_dev_list(void) +{ + struct vtzf_dev_file *dev_file = NULL, *temp = NULL; + + mutex_lock(&g_tc_ns_dev_list.dev_lock); + list_for_each_entry_safe(dev_file, temp, &g_tc_ns_dev_list.dev_file_list, head) { + list_del(&dev_file->head); + kfree(dev_file); + } + mutex_unlock(&g_tc_ns_dev_list.dev_lock); +} + +static void __exit vtzf_exit(void) +{ +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + cdev_del(&(g_tc_cvm.char_dev)); +#endif + cdev_del(&(g_tc_private.char_dev)); + cdev_del(&(g_tc_client.char_dev)); +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + destory_dev_node(&g_tc_cvm, g_driver_class); +#endif + + destory_dev_node(&g_tc_client, g_driver_class); + destory_dev_node(&g_tc_private, g_driver_class); + class_destroy(g_driver_class); + //free_all_session(); + free_dev_list(); + free_serial_port_list(); +} + +static int vtzf_client_open(struct inode *inode, struct file *file) +{ + struct vtzf_dev_file *dev_file = NULL; + + tlogd("vtzf open \n"); + + dev_file = kzalloc(sizeof(*dev_file), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)dev_file)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + + mutex_lock(&g_tc_ns_dev_list.dev_lock); + list_add_tail(&dev_file->head, &g_tc_ns_dev_list.dev_file_list); + mutex_unlock(&g_tc_ns_dev_list.dev_lock); + + mutex_lock(&g_device_file_cnt_lock); + dev_file->dev_file_id = g_device_file_cnt; + g_device_file_cnt++; + mutex_unlock(&g_device_file_cnt_lock); + + INIT_LIST_HEAD(&dev_file->shared_mem_list); + + mutex_init(&dev_file->shared_mem_lock); + + file->private_data = dev_file; + + (void)open_tzdriver(dev_file, TC_NS_CLIENT_DEV_FLAG); + /* Once this device is opened, Tzdriver must be opened accordingly */ + + return 0; +} + +static int vtzf_private_open(struct inode *inode, struct file *file) +{ + struct vtzf_dev_file *dev_file = NULL; + + tlogd("vtzf open \n"); + + dev_file = kzalloc(sizeof(*dev_file), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)dev_file)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + + mutex_lock(&g_tc_ns_dev_list.dev_lock); + list_add_tail(&dev_file->head, &g_tc_ns_dev_list.dev_file_list); + mutex_unlock(&g_tc_ns_dev_list.dev_lock); + + mutex_lock(&g_device_file_cnt_lock); + dev_file->dev_file_id = g_device_file_cnt; + g_device_file_cnt++; + mutex_unlock(&g_device_file_cnt_lock); + + INIT_LIST_HEAD(&dev_file->shared_mem_list); + + mutex_init(&dev_file->shared_mem_lock); + + file->private_data = dev_file; + + (void)open_tzdriver(dev_file, TC_PRIVATE_DEV_FLAG); + /* Once this device is opened, Tzdriver must be opened accordingly */ + + return 0; +} + +static int open_tzdriver(struct vtzf_dev_file *dev_file, uint32_t flag) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_open_tzd packet_cmd; + struct_packet_rsp_open_tzd packet_rsp; + + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + dev_file->ptzfd = -1; + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_OPEN_TZD; + packet_cmd.vmid = 0; + /* if flag==0, open tc_ns_client; if flag==1, open tc_private */ + packet_cmd.flag = flag; + + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + if (ret) { + tloge("open TZdriver failed ret is %d\n", ret); + goto END; + } + dev_file->ptzfd = packet_rsp.ptzfd; + } else { + tloge("send to proxy failed ret is %d\n", ret); + } + +END: + return ret; +} + +static int vtzf_close(struct inode *inode, struct file *file) +{ + int ret = 0; + struct vtzf_dev_file *dev_file = file->private_data; + + mutex_destroy(&dev_file->shared_mem_lock); + + mutex_lock(&g_tc_ns_dev_list.dev_lock); + list_del(&dev_file->head); + mutex_unlock(&g_tc_ns_dev_list.dev_lock); + /* 这里应该给Proxy发送消息close对应的TZdriver */ + (void)close_tzdriver(dev_file); + + + if (memset_s(dev_file, sizeof(*dev_file), 0, sizeof(*dev_file))) + tloge("memset_s dev file fail \n"); + kfree(dev_file); +// 在这里把dev_file之前分配的空间清理一下?先给Proxy发送关闭的消息再释放免得下面访问VM被释放的内存而崩溃 + mutex_lock(&g_device_file_cnt_lock); + g_device_file_cnt--; + mutex_unlock(&g_device_file_cnt_lock); + + file->private_data = NULL; + + + + return ret; +} + +static int close_tzdriver(struct vtzf_dev_file *dev_file) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_close_tzd packet_cmd; + struct_packet_rsp_close_tzd packet_rsp; + + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + if (dev_file->ptzfd <= 0) { + tlogd("The TZdriver on the host has not been opened yet\n"); + return 0; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_CLOSE_TZD; + packet_cmd.ptzfd = dev_file->ptzfd; + tlogd("close ptzfd = %d\n", dev_file->ptzfd); + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + if (ret) { + tloge("close TZdriver failed ret is %d\n", ret); + goto END; + } + } else { + tloge("send to proxy failed ret is %d\n", ret); + } +END: + return ret; +} + +void shared_vma_open(struct vm_area_struct *vma) +{ + (void)vma; +} + +void shared_vma_close(struct vm_area_struct *vma) +{ + struct vtzf_dev_file *dev_file = NULL; + struct vtzf_shared_mem *shared_mem = NULL; + struct vtzf_shared_mem *shared_mem_temp = NULL; + bool find = false; + uintptr_t user_addr = NULL; + + + if (!vma) { + tloge("virtual memory area is null \n"); + return; + } + dev_file = vma->vm_private_data; + if (!dev_file) { + tloge("virtual memory area private data is null \n"); + return; + } + + mutex_lock(&dev_file->shared_mem_lock); + list_for_each_entry_safe(shared_mem, shared_mem_temp, + &dev_file->shared_mem_list, head) { + if (shared_mem) { + if (shared_mem->user_virt_addr == + (void *)(uintptr_t)vma->vm_start) { + shared_mem->user_virt_addr = NULL; + list_del(&shared_mem->head); + + if (shared_mem->kernel_virt_addr) { + + kfree(shared_mem->kernel_virt_addr); + shared_mem->kernel_virt_addr = NULL; + } + kfree(shared_mem); + find = true; + break; + } + } + } + mutex_unlock(&dev_file->shared_mem_lock); + if (find) { + (void)proxy_mmap(dev_file, (void *)(uintptr_t)vma->vm_start, 0 ,0, true); + } +} + +static int proxy_mmap(struct vtzf_dev_file *dev_file, + void * user_buffer, uint32_t buffer_size, + uint32_t pgoff, uint8_t unmap) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_mmap packet_cmd; + struct_packet_rsp_mmap packet_rsp; + + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.cmd = unmap ? VTZF_MUNMAP : VTZF_MMAP; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.buffer = (uint64_t)user_buffer; + packet_cmd.size = buffer_size; + packet_cmd.offset = pgoff; + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + } +END: + return ret; +} + +static int vtzf_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct vtzf_dev_file *dev_file = NULL; + struct vtzf_shared_mem *shared_mem = NULL; + void *addr = NULL; + size_t len; + + if (!filp || !vma || !filp->private_data) { + tloge("vtzf invalid args for mmap \n"); + return -EINVAL; + } + dev_file = filp->private_data; + + shared_mem = kmalloc(sizeof(*shared_mem), GFP_KERNEL | __GFP_ZERO); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)shared_mem)) { + tloge("vtzf shared_mem kmalloc failed \n"); + return -ENOMEM; + } + + len = vma->vm_end - vma->vm_start; + len = ALIGN(len, SZ_4K); + if (len > MAILBOX_POOL_SIZE) { + tloge("vtzf alloc sharemem buffer size %zu is too large \n", len); + kfree(shared_mem); + return -EINVAL; + } + + addr = kmalloc(len, GFP_KERNEL | __GFP_ZERO); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)addr)) { + tloge("kmalloc shared_mem buffer failed \n"); + return -ENOMEM; + } + + shared_mem->kernel_virt_addr = addr; + shared_mem->len = len; + shared_mem->user_virt_addr =(void *)vma->vm_start; + shared_mem->phy_addr = (void *)virt_to_phys(addr); + + tlogv("shared_mem user virtual address = 0x%016llx \n", (uint64_t)shared_mem->user_virt_addr); + tlogv("shared_mem kernel virtual address = 0x%016llx \n", (uint64_t)shared_mem->kernel_virt_addr); + tlogv("shared_mem physical address = 0x%016llx \n", (uint64_t)shared_mem->phy_addr); + tlogv("shared_mem allocated buffer len = 0x%08x, %d \n", (int)len, (int)len); + + vma->vm_flags |= VM_USERMAP; + + if (remap_pfn_range(vma, vma->vm_start, + virt_to_phys(addr)>>PAGE_SHIFT, len, vma->vm_page_prot)) { + tloge("shared_mem buffer remap failed \n"); + return -EAGAIN; + } + + vma->vm_flags |= VM_DONTCOPY; + vma->vm_ops = &g_shared_remap_vm_ops; + shared_vma_open(vma); + vma->vm_private_data = (void *)dev_file; + + shared_mem->user_virt_addr = (void *)(uintptr_t)vma->vm_start; + atomic_set(&shared_mem->offset, vma->vm_pgoff); + mutex_lock(&dev_file->shared_mem_lock); + list_add_tail(&shared_mem->head, &dev_file->shared_mem_list); + mutex_unlock(&dev_file->shared_mem_lock); + tlogd("************ offset *************\n "); + tlogd(" = %lu \n", (unsigned long)atomic_read(&shared_mem->offset)); + /* proxy 对应mmap */ + (void)proxy_mmap(filp->private_data, shared_mem->user_virt_addr, + shared_mem->len, (uint32_t)atomic_read(&shared_mem->offset), false); + + return 0; +} + +static struct vtzf_serial_port_file *alloc_serial_port(void) +{ + struct vtzf_serial_port_file *dev_file = NULL; + + while(1){ + mutex_lock(&g_serial_port_list.lock); + list_for_each_entry(dev_file, &g_serial_port_list.head, head) { + if (dev_file->using == false) { + mutex_lock(&dev_file->lock); + dev_file->using = true; + tlogi(" alloc serial port \n"); + mutex_unlock(&g_serial_port_list.lock); + return dev_file; + } + } + mutex_unlock(&g_serial_port_list.lock); + } + return NULL; +} + +static void free_serial_port(struct vtzf_serial_port_file *file, ssize_t ssize_ret) +{ + if (file){ + file->using = false; + tlogi(" free serial port \n"); + mutex_unlock(&file->lock); + } + if (ssize_ret<=0){ + tloge(" ------------Unexpected exit of user program serial_port free--------------- \n"); + } +} + +static long vtzf_ser_test(struct file *file, unsigned int cmd, void *argp) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + int ioctl_args; + struct_packet_cmd_test packet_cmd; + struct_packet_rsp_test packet_rsp; + + if (copy_from_user(&ioctl_args, argp, sizeof(int))) { + tloge("copy ioctl_args_opensession from user failed \n"); + ret = -ENOMEM; + return ret; + } + if (ioctl_args == 1) { + ; + } else if(ioctl_args == 2) { + packet_cmd.cmd = 618; + packet_cmd.seq_num = seq_num; + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (ret) { + return ret; + } + tlogd(" packet_rsp.seq_num =%d \n", packet_rsp.seq_num); + tlogd(" packet_rsp.ret =%d \n", packet_rsp.ret); + if(copy_to_user(argp, &(packet_rsp.ret) ,sizeof(int))){ + ret = -EFAULT; + } + } else if (ioctl_args == 3){ + packet_cmd.cmd = 520; + packet_cmd.seq_num = seq_num; + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (ret) { + return ret; + } + tlogd(" packet_rsp.seq_num =%d \n", packet_rsp.seq_num); + tlogd(" packet_rsp.ret =%d \n", packet_rsp.ret); + if(copy_to_user(argp, &(packet_rsp.ret) ,sizeof(int))){ + ret = -EFAULT; + } + } + return ret; +} + + +#define INPUT 0 +#define OUTPUT 1 +#define INOUT 2 + +static inline bool is_input_type(int dir) +{ + if (dir == INPUT || dir == INOUT) + return true; + + return false; +} + +static inline bool is_output_type(int dir) +{ + if (dir == OUTPUT || dir == INOUT) + return true; + + return false; +} + +static inline bool teec_value_type(unsigned int type, int dir) +{ + return ((is_input_type(dir) && type == TEEC_VALUE_INPUT) || + (is_output_type(dir) && type == TEEC_VALUE_OUTPUT) || + type == TEEC_VALUE_INOUT) ? true : false; +} + +static inline bool teec_tmpmem_type(unsigned int type, int dir) +{ + return ((is_input_type(dir) && type == TEEC_MEMREF_TEMP_INPUT) || + (is_output_type(dir) && type == TEEC_MEMREF_TEMP_OUTPUT) || + type == TEEC_MEMREF_TEMP_INOUT) ? true : false; +} + +static inline bool teec_memref_type(unsigned int type, int dir) +{ + return ((is_input_type(dir) && type == TEEC_MEMREF_PARTIAL_INPUT) || + (is_output_type(dir) && type == TEEC_MEMREF_PARTIAL_OUTPUT) || + type == TEEC_MEMREF_PARTIAL_INOUT) ? true : false; +} + + +static long tc_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; + + //handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ: + case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ: + case TC_NS_CLIENT_IOCTL_SEND_CMD_REQ: + ret = tc_client_session_ioctl(file->private_data, cmd, arg); + break; + case TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ: + /* TZdriver don't support send cancel cmd now */ + ret = tc_ns_send_cancel_cmd(file->private_data, argp); + break; + case TC_NS_CLIENT_IOCTL_LOGIN: + ret = tc_ns_client_login_func(file->private_data, argp); + break; + case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: + //ret = public_ioctl(file, cmd, arg, true); + break; + default: + tlogd(" default ----------------------------------\n"); + ret =vtzf_ser_test(file, cmd, argp); + //ret = tc_client_agent_ioctl(file, cmd, arg); + break; + } + + //handle_cmd_finish(cmd); + + tlogd("tc client ioctl ret = 0x%x\n", ret); + return (long)ret; +} + +int tc_ns_open_session(struct vtzf_dev_file *dev_file, + struct tc_ns_client_context *clicontext) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_session packet_cmd; + struct_packet_rsp_session packet_rsp; + size_t file_size; + char *buffer = NULL, *tmp_buffer = NULL; + + if (!clicontext || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_OPEN_SESSION; + packet_cmd.ptzfd = dev_file->ptzfd; + tlogd(" sizeof(packet_cmd.cliContext) =%lu \n", sizeof(packet_cmd.cliContext)); + packet_cmd.cliContext = *clicontext; + //if (copy_from_user(&(packet_cmd.cliContext), clicontext, sizeof(packet_cmd.cliContext) != 0)) { + // return -EFAULT; + //} + /* 有Buffer地址需要转换char *cliContext.file_buffer */ + file_size = (size_t)packet_cmd.cliContext.file_size; + tlogd("file_size = %lu \n", file_size); + buffer = (char *)kzalloc(file_size, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + /* 保存原地址并返回给用户,libteec会释放这个地址 */ + tmp_buffer = packet_cmd.cliContext.file_buffer; + tlogd("sizeof(char *) = %lu, sizeof(void*) =%lu ,sizeof(unsigned long) =%lu\n", sizeof(char *), sizeof(void*), sizeof(unsigned long)); + tlogd("buffer addr = %016llx ,tmp_buffer =%016llx \n", + (unsigned long long)clicontext->file_buffer, (unsigned long long)tmp_buffer); + packet_cmd.cliContext.file_buffer = virt_to_phys(buffer); + //dump_buff((void *)(&packet_cmd.cliContext), sizeof(packet_cmd.cliContext)); + + /* 将image数据从用户拷贝到内核 */ + + if (copy_from_user(buffer, (const void __user *)tmp_buffer, file_size)) { + tloge("file buf get failed \n"); + ret = -EFAULT; + goto END; + } + tlogd("------------image\n"); + //dump_buff((void *)(buffer), 32); + + tlogd("***** packet_cmd.cliContext.login.method = %u *****\n", packet_cmd.cliContext.login.method); + + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + tlogd(" opensession ret =%d \n", ret); + if (ret) { + tloge("open session failed ret is %d\n", ret); + } + /* 还原地址,并将返回的内容拷贝回 */ + packet_rsp.cliContext.file_buffer = tmp_buffer; + //if (copy_to_user(argp, &packet_rsp.cliContext, sizeof(struct tc_ns_client_context)) != 0){ + // ret = -EFAULT; + //} + *clicontext = packet_rsp.cliContext; + + } else { + tloge("send to proxy failed ret is %d\n", ret); + } +END: + kfree(buffer); + return ret; +} + +int tc_ns_close_session(struct vtzf_dev_file *dev_file, void __user *argp) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_session packet_cmd; + struct_packet_rsp_general packet_rsp; + + if (!argp || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_CLOSE_SESSION; + packet_cmd.ptzfd = dev_file->ptzfd; + + if (copy_from_user(&packet_cmd.cliContext, argp, sizeof(packet_cmd.cliContext)) != 0) { + tloge("copy from user failed\n"); + return -ENOMEM; + } + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + if (ret) { + tloge("close session failed ret is %d\n", ret); + } + } else { + tloge("send to proxy failed ret is %d\n", ret); + } + + return ret; +} + +static int alloc_for_tmp_mem(struct tc_ns_client_context *clicontext, + int index, uintptr_t addrs[][3]) +{ + uintptr_t buf_size, buffer; + uintptr_t user_buf_size, user_buf; + + buf_size = (uintptr_t)kzalloc(sizeof(uint32_t), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buf_size)) { + tloge("buf_size malloc failed\n"); + return -ENOMEM; + } + user_buf = (uintptr_t)(clicontext->params[index].memref.buffer + | (uint64_t)clicontext->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM); + user_buf_size = (uintptr_t)(clicontext->params[index].memref.size_addr + | (uint64_t)clicontext->params[index].memref.size_h_addr << ADDR_TRANS_NUM); + + /* 原bufsize是传的地址,这里把size从用户态拷贝下来,分配空间把地址传下去 */ + if (copy_from_user((void *)buf_size, (void *)user_buf_size, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + kfree((void *)buf_size); + return -EFAULT; + } + + tlogd(" buffer size = %u\n", *(uint32_t *)buf_size); + + buffer = (uintptr_t)kzalloc(*(uint32_t *)buf_size, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("buffer malloc failed\n"); + kfree((void *)buf_size); + return -ENOMEM; + } + + /* 拷贝buffer数据 */ + if (copy_from_user((void *)buffer, (void *)user_buf, *(uint32_t *)buf_size) != 0) { + tloge("copy from user failed\n"); + kfree((void *)buf_size); + kfree((void *)buffer); + return -EFAULT; + } + + /* 地址替换 */ + addrs[index][0] = buf_size; + addrs[index][1] = buffer; + buf_size = (uintptr_t)virt_to_phys((void *)buf_size); + buffer = (uintptr_t)virt_to_phys((void *)buffer); + clicontext->params[index].memref.buffer = (unsigned int)(uintptr_t)buffer; + clicontext->params[index].memref.buffer_h_addr = ((unsigned long long)(uintptr_t)buffer) >> ADDR_TRANS_NUM; + + clicontext->params[index].memref.size_addr = (unsigned int)(uintptr_t)buf_size; + clicontext->params[index].memref.size_h_addr = ((unsigned long long)(uintptr_t)buf_size) >> ADDR_TRANS_NUM; + + return 0; +} + +static int alloc_for_val_mem(struct tc_ns_client_context *clicontext, + int index, uintptr_t addrs[][3]) +{ + uintptr_t val_a, val_b; + uintptr_t user_val_a, user_val_b; + val_a = (uintptr_t)kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)val_a)) { + tloge("val_a malloc failed\n"); + return -ENOMEM; + } + val_b = val_a + sizeof(uint32_t); + + user_val_a = (uintptr_t)(clicontext->params[index].value.a_addr + | (uint64_t)clicontext->params[index].value.a_h_addr << ADDR_TRANS_NUM); + user_val_b = (uintptr_t)(clicontext->params[index].value.b_addr + | (uint64_t)clicontext->params[index].value.b_h_addr << ADDR_TRANS_NUM); + /* 数据拷贝 */ + if (copy_from_user((void *)val_a, (void *)user_val_a, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + kfree((void *)val_a); + return -EFAULT; + } + if (copy_from_user((void *)val_b, (void *)user_val_b, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + kfree((void *)val_a); + return -EFAULT; + } + /* 地址替换 */ + addrs[index][0] = val_a; + addrs[index][1] = val_b; + val_a = (uintptr_t)virt_to_phys((void *)val_a); + val_b = (uintptr_t)virt_to_phys((void *)val_b); + clicontext->params[index].value.a_addr = + (unsigned int)(uintptr_t)val_a; + clicontext->params[index].value.a_h_addr = + ((unsigned long long)(uintptr_t)val_a) >> ADDR_TRANS_NUM; + + clicontext->params[index].value.b_addr = + (unsigned int)(uintptr_t)val_b; + clicontext->params[index].value.b_h_addr = + ((unsigned long long)(uintptr_t)val_b) >> ADDR_TRANS_NUM; + + return 0; +} + +static int alloc_for_ref_mem(struct vtzf_dev_file *dev_file, + struct_packet_cmd_send_cmd *packet_cmd, int index, uintptr_t addrs[][3]) +{ + uintptr_t size_addr, user_size_addr; + struct tc_ns_client_context *clicontext = &packet_cmd->cliContext; + bool b_found = false; + struct vtzf_shared_mem *shared_mem = NULL; + struct vtzf_shared_mem *shared_mem_temp = NULL; + void *user_buffer = NULL; + uintptr_t phy_buffer; + + size_addr = (uintptr_t)kzalloc(sizeof(uint32_t), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)size_addr)) { + tloge("size_addr malloc failed\n"); + return -ENOMEM; + } + + user_size_addr = (uintptr_t)(clicontext->params[index].memref.size_addr + | (uint64_t)clicontext->params[index].memref.size_h_addr << ADDR_TRANS_NUM); + user_buffer = (void *)(clicontext->params[index].memref.buffer + | (uint64_t)clicontext->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM); + + if (copy_from_user((void *)size_addr, (void *)user_size_addr, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + kfree((void *)size_addr); + return -EFAULT; + } + + mutex_lock(&dev_file->shared_mem_lock); + list_for_each_entry_safe(shared_mem, shared_mem_temp, &dev_file->shared_mem_list, head) { + if (shared_mem) { + if (shared_mem->user_virt_addr == user_buffer) { + tlogv("found the mapped shared_mem for cliContext.params[index].memref.buffer\n"); + phy_buffer = (uintptr_t)shared_mem->phy_addr; + clicontext->params[index].memref.buffer = + (unsigned int)(uintptr_t)phy_buffer; + clicontext->params[index].memref.buffer_h_addr = + ((unsigned long long)(uintptr_t)phy_buffer) >> ADDR_TRANS_NUM; + + packet_cmd->addrs[index] = (unsigned long long)user_buffer; + b_found = true; + break; + } + } + } + mutex_unlock(&dev_file->shared_mem_lock); + if (!b_found) { + kfree((void *)size_addr); + tloge("can't found the mapped shared_mem for cliContext.params[index].memref.buffer \n"); + return -EFAULT; + } + addrs[index][0] = size_addr; + size_addr = (uintptr_t)virt_to_phys((void *)size_addr); + /* 地址替换 */ + clicontext->params[index].memref.size_addr = + (unsigned int)(uintptr_t)size_addr; + clicontext->params[index].memref.size_h_addr = + ((unsigned long long)(uintptr_t)size_addr) >> ADDR_TRANS_NUM; + + return 0; +} + +static int alloc_for_params(struct vtzf_dev_file *dev_file, + struct_packet_cmd_send_cmd *packet_cmd, uintptr_t addrs[][3]) +{ + int ret; + int index; + uint32_t param_type; + bool checkValue; + for (index = 0; index < TEE_PARAM_NUM; index++) { + param_type = teec_param_type_get(packet_cmd->cliContext.param_types, index); + checkValue = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); + tlogd("param %u type is %x\n", index, param_type); + if (teec_tmpmem_type(param_type, INOUT)) + /* 分配空间,把数据从用户拷贝进来,将物理地址传下去 */ + ret = alloc_for_tmp_mem(&packet_cmd->cliContext, index, addrs); + + else if (teec_memref_type(param_type, INOUT)) + /* mmap 已经分配过空间了,找到物理地址传下去*/ + ret = alloc_for_ref_mem(dev_file , packet_cmd, index, addrs); + + else if (teec_value_type(param_type, INOUT) || checkValue) + /* 分配空间,把数据从用户拷贝进来,将物理地址传下去 */ + ret = alloc_for_val_mem(&packet_cmd->cliContext, index, addrs); + /* + else if (param_type == TEEC_MEMREF_SHARED_INOUT) + ret = transfer_shared_mem(call_params, op_params, + kernel_params, param_type, index); + */ + else + tlogd("param type = TEEC_NONE\n"); + + if (ret != 0) { + goto ERR; + } + } + + return 0; +ERR: + /* 释放空间 */ + return ret; + +} + +static void free_for_params(struct tc_ns_client_context *clicontext, + struct tc_ns_client_context *context, uintptr_t addrs[4][3]) +{ + int ret = 0; + int index; + uint32_t param_type; + bool checkValue; + uintptr_t addr_a, addr_b; + uintptr_t user_addr_a, user_addr_b; + + for (index = 0; index < TEE_PARAM_NUM; index++) { + param_type = teec_param_type_get(clicontext->param_types, index); + checkValue = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); + if (teec_tmpmem_type(param_type, INOUT)) { + addr_a = addrs[index][0]; + addr_b = addrs[index][1]; + + user_addr_a = (uintptr_t)(context->params[index].memref.size_addr + | (uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM); + user_addr_b = (uintptr_t)(context->params[index].memref.buffer + | (uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM); + + if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) { + ret = -EFAULT; + } + if (copy_to_user((void *)user_addr_b, (void *)addr_b, *(uint32_t *)addr_a) != 0) { + ret = -EFAULT; + } + kfree((void *)addr_a); + kfree((void *)addr_b); + + } else if(teec_memref_type(param_type, INOUT)) { + addr_a = addrs[index][0]; + + user_addr_a = (uintptr_t)(context->params[index].memref.size_addr + | (uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM); + if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) { + ret = -EFAULT; + } + kfree((void *)addr_a); + } else if(teec_value_type(param_type, INOUT) || checkValue) { + addr_a = addrs[index][0]; + addr_b = addrs[index][1]; + tlogd("val_a = %d\n", *(int *)addr_a); + tlogd("val_b = %d\n", *(int *)addr_b); + user_addr_a = (uintptr_t)(context->params[index].value.a_addr + | (uint64_t)context->params[index].value.a_h_addr << ADDR_TRANS_NUM); + user_addr_b = (uintptr_t)(context->params[index].value.b_addr + | (uint64_t)context->params[index].value.b_h_addr << ADDR_TRANS_NUM); + + if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) { + ret = -EFAULT; + } + if (copy_to_user((void *)user_addr_b, (void *)addr_b, sizeof(uint32_t)) != 0) { + ret = -EFAULT; + } + kfree((void *)addr_a); + //kfree(addr_b); + } else { + /* nothing */ + } + + if (ret) { + tloge(" ret =%d \n", ret); + } + } +} + +int tc_ns_send_cmd(struct vtzf_dev_file *dev_file, + struct tc_ns_client_context *context) +{ + int ret = -EINVAL; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_send_cmd packet_cmd; + struct_packet_rsp_send_cmd packet_rsp; + uintptr_t addrs[4][3]; + if (!dev_file || !context) { + tloge("invalid dev_file or context\n"); + return ret; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_SEND_CMD; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.cliContext = *context; + /* 重新给param分配空间 */ + + ret = alloc_for_params(dev_file, &packet_cmd, addrs); + if (ret) { + tloge("alloc for params failed \n"); + return ret; + } + + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + tlogd(" invoke cmd ret =%d \n", ret); + if (ret) { + tloge("invoke cmd failed ret is %d\n", ret); + } + /* 将数据拷贝回 */ + /* 根据返回值写回*/ + /* + if (tee_ret != 0) { + tloge("smc call ret 0x%x, cmd ret val 0x%x, origin %u\n", tee_ret, + op_params->smc_cmd->ret_val, op_params->smc_cmd->err_origin); + + ret = EFAULT; + if (tee_ret == (int)TEEC_CLIENT_INTR) + ret = -ERESTARTSYS; + + if (tee_ret == (int)TEEC_ERROR_SHORT_BUFFER) + (void)update_client_operation(call_params, op_params, false); + } else { + tz_log_write(); + ret = update_client_operation(call_params, op_params, true); + } + */ + free_for_params(&packet_cmd.cliContext, context, addrs); + context->returns = packet_cmd.cliContext.returns; + + } else { + tloge("send to proxy failed ret is %d\n", ret); + } + + return ret; +} + +static int ioctl_session_send_cmd(struct vtzf_dev_file *dev_file, + struct tc_ns_client_context *context, void *argp) +{ + int ret; + ret = tc_ns_send_cmd(dev_file, context); + if (ret != 0) + tloge("send cmd failed ret is %d\n", ret); + if (copy_to_user(argp, context, sizeof(*context)) != 0) { + if (ret == 0) + ret = -EFAULT; + } + return ret; +} + +int tc_client_session_ioctl(struct vtzf_dev_file *dev_file, unsigned int cmd, + unsigned long arg) +{ + int ret = -EINVAL; + void *argp = (void __user *)(uintptr_t)arg; + struct tc_ns_client_context context; + + + if (!argp || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + if (copy_from_user(&context, argp, sizeof(context)) != 0) { + tloge("copy from user failed\n"); + return -EFAULT; + } + //dump_buff((void *)(&context), sizeof(context)); + + switch (cmd) { + case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ: + ret = tc_ns_open_session(dev_file, &context); + tlogd("opensession session_id =%d\n", context.session_id); + if (copy_to_user(argp, &context, sizeof(context)) != 0 && ret == 0) + ret = -EFAULT; + break; + + case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ: + ret = tc_ns_close_session(dev_file, argp); + break; + + case TC_NS_CLIENT_IOCTL_SEND_CMD_REQ: + //tee_trace_add_event(INVOKE_CMD_START, 0); + tlogd(" CMD is TC_NS_CLIENT_IOCTL_SEND_CMD_REQ\n"); + ret = ioctl_session_send_cmd(dev_file, &context, argp); + //tee_trace_add_event(INVOKE_CMD_END, 0); + break; + + default: + tloge("invalid cmd:0x%x!\n", cmd); + return ret; + } + + return ret; +} + +static int tc_ns_send_cancel_cmd(struct vtzf_dev_file *dev_file, void *argp) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_cancel_cmd packet_cmd; + struct_packet_rsp_cancel_cmd packet_rsp; + (void)dev_file; + if (!argp || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_CANCEL_CMD; + packet_cmd.ptzfd = dev_file->ptzfd; + + if (copy_from_user(&packet_cmd.cliContext, argp, sizeof(packet_cmd.cliContext)) != 0) { + tloge("copy from user failed\n"); + return -ENOMEM; + } + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + if (copy_to_user(argp, &packet_rsp.cliContext, sizeof(packet_rsp.cliContext)) != 0) + ret = -EFAULT; + } + +END: + return ret; +} + +static int tc_ns_client_login_func(struct vtzf_dev_file *dev_file, + const void __user *buffer) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_login_non packet_cmd_non; + struct_packet_cmd_login packet_cmd; + struct_packet_rsp_login packet_rsp; + + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + /* 这里登录信息buffer有两种情况,一种为NULL */ + if (!buffer) { + packet_cmd_non.seq_num = seq_num; + packet_cmd_non.cmd = VTZF_LOG_IN_NHIDL; + packet_cmd_non.ptzfd = dev_file->ptzfd; + if (send_to_proxy(&packet_cmd_non, sizeof(packet_cmd_non), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } + ret = packet_rsp.ret; + goto END; + } + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_LOG_IN; + packet_cmd.ptzfd = dev_file->ptzfd; + + /* 发送地址,让TZdriver 去读会更快???*/ + if (copy_from_user(&packet_cmd.cert_buffer, buffer, BUF_MAX_SIZE) != 0) { + tloge("copy from user failed\n"); + ret = -EFAULT; + goto END; + } + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + } + +END: + return ret; +} + + +static int tc_ns_get_tee_version(struct vtzf_dev_file *dev_file, void __user *argp) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_getteever packet_cmd; + struct_packet_rsp_getteever packet_rsp; + tlogd("**********cmd is get ver **********\n"); + packet_cmd.cmd = VTZF_GET_TEE_VERSION; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + /* There is no ptzfd, the TZdriver is opened and close immediately after use */ + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + if (copy_to_user(argp, &packet_rsp.tee_ver, sizeof(uint32_t)) != 0) + ret = -EFAULT; + } + +END: + return ret; +} + +static int tc_ns_get_tee_info(struct vtzf_dev_file *dev_file, void __user *argp) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_getteeinfo packet_cmd; + struct_packet_rsp_getteeinfo packet_rsp; + tlogd("**********cmd is get info**********\n"); + if (!argp || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.cmd = VTZF_GET_TEE_INFO; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + if (copy_to_user(argp, &packet_rsp.info, sizeof(struct tc_ns_tee_info)) != 0) + ret = -EFAULT; + } + +END: + return ret; +} + +static int tc_ns_late_init(unsigned long arg) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_lateinit packet_cmd; + struct_packet_rsp_lateinit packet_rsp; + + packet_cmd.cmd = VTZF_LATE_INIT; + packet_cmd.seq_num = seq_num; + packet_cmd.index = (uint32_t)arg; + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + } + +END: + return ret; +} + +static int sync_system_time_from_user(struct vtzf_dev_file *dev_file, + const struct tc_ns_client_time *user_time) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_synctime packet_cmd; + struct_packet_rsp_synctime packet_rsp; + struct tc_ns_client_time time = { 0 }; + + if (!user_time) { + tloge("user time is NULL input buffer\n"); + return -EINVAL; + } + + if (copy_from_user(&packet_cmd.tcNsTime, user_time, sizeof(time))) { + tloge("copy from user failed\n"); + return -EFAULT; + } + packet_cmd.cmd = VTZF_SYNC_TIME; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + /* There is no ptzfd, the TZdriver is opened and close immediately after use */ + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + } +END: + return ret; +} + + +static bool is_valid_agent(unsigned int buffer_size) +{ + if (buffer_size > SZ_4K) { + tloge("size: %u of user agent's shared mem is invalid\n", buffer_size); + return false; + } + + return true; +} + +static unsigned long agent_buffer_map(unsigned long phy_buffer, uint32_t size) +{ + struct vm_area_struct *vma = NULL; + unsigned long user_addr; + int ret; + + user_addr = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, 0); + if (IS_ERR_VALUE((uintptr_t)user_addr)) { + tloge("vm mmap failed\n"); + return user_addr; + } + + down_read(&mm_sem_lock(current->mm)); + vma = find_vma(current->mm, user_addr); + if (!vma) { + tloge("user_addr is not valid in vma"); + goto err_out; + } + + ret = remap_pfn_range(vma, user_addr, phy_buffer >> PAGE_SHIFT, size, + vma->vm_page_prot); + if (ret != 0) { + tloge("remap agent buffer failed, err=%d", ret); + goto err_out; + } + + up_read(&mm_sem_lock(current->mm)); + return user_addr; +err_out: + up_read(&mm_sem_lock(current->mm)); + if (vm_munmap(user_addr, size)) + tloge("munmap failed\n"); + return 0; +} + +static int ioctl_register_agent(struct vtzf_dev_file *dev_file, void __user *argp) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_regagent packet_cmd; + struct_packet_rsp_regagent packet_rsp; + struct vtz_shared_mem *shared_mem = NULL; + size_t size; + void *buffer; + void *user_addr; + tlogd("********** cmd is reg_agent **********"); + + if (!argp || !dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (dev_file->ptzfd <= 0) { + tloge("The TZdriver on the host has not been opened yet\n"); + return -EINVAL; + } + + packet_cmd.cmd = VTZF_FS_REGISTER_AGENT; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + + if (copy_from_user(&packet_cmd.args, (void *)(uintptr_t)argp, sizeof(packet_cmd.args)) != 0) { + tloge("copy agent args failed\n"); + return -EFAULT; + } + + /* 分配空间,维护对应关packet_cmd系*/ + if (!is_valid_agent(packet_cmd.args.buffer_size)) { + return -EINVAL; + } + size = (size_t)packet_cmd.args.buffer_size; + size = ALIGN(size, SZ_4K); + shared_mem = kzalloc(sizeof(*shared_mem), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)shared_mem)) { + tloge("shared_mem malloc failed\n"); + return -ENOMEM; + } + buffer = kzalloc(size, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("buffer malloc failed\n"); + kfree(shared_mem); + return -ENOMEM; + } + user_addr = (void*)agent_buffer_map(virt_to_phys(buffer), size); + if (!user_addr) { + kfree(shared_mem); + kfree(buffer); + return -ENOMEM; + } + shared_mem->kernel_addr = buffer; + shared_mem->user_addr = user_addr; + shared_mem->len = size; + *(int*)buffer = 985; + + mutex_lock(&dev_file->shared_mem_lock); + list_add_tail(&shared_mem->head, &dev_file->shared_mem_list); + mutex_unlock(&dev_file->shared_mem_lock); + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + if (!ret) { + shared_mem->user_addr_host = packet_rsp.args.buffer; + packet_rsp.args.buffer = user_addr; + } else{ + kfree(shared_mem); + kfree(buffer); + } + tlogd("packet_rsp.ret = %d \n", packet_rsp.ret); + if (copy_to_user(argp, &packet_rsp.args, sizeof(packet_rsp.args)) != 0) { + ret = -EFAULT; + } + + } + +END: + return ret; +} + +static int public_ioctl(const struct file *file, unsigned int cmd, unsigned long arg, bool is_from_client_node) +{ + int ret = -EINVAL; + struct vtzf_dev_file *dev_file = NULL; + dev_file = file->private_data; + switch (cmd) { + case TC_NS_CLIENT_IOCTL_WAIT_EVENT: + //ret = send_wait_event(dev_file, (void *)arg); + /* + if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0) + return -EINVAL; + ret = tc_ns_wait_event((unsigned int)arg, nsid); + */ + break; + case TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE: + /* + if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0) + return -EINVAL; + ret = tc_ns_send_event_response((unsigned int)arg, nsid); + */ + break; + case TC_NS_CLIENT_IOCTL_REGISTER_AGENT: + ret = ioctl_register_agent(dev_file, (void *)arg); + tlogd("****ioctl_register_agent ret=%d****",ret); + break; + case TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT: + /* + if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0) + return -EINVAL; + ret = tc_ns_unregister_agent((unsigned int)arg, nsid); + */ + break; + case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: + //ret = tc_ns_load_secfile(file->private_data, argp, NULL, is_from_client_node); + break; + default: + tloge("invalid cmd!"); + return ret; + } + return ret; +} + +static long tc_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; + //handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION: + ret = tc_ns_get_tee_version(file->private_data, argp); + break; + case TC_NS_CLIENT_IOCTL_GET_TEE_INFO: + ret = tc_ns_get_tee_info(file->private_data, argp); + break; + //case TC_NS_CLIENT_IOCTL_SET_NATIVECA_IDENTITY: + // 涉及到一个大的Buffer + //mutex_lock(&g_set_ca_hash_lock); + //ret = tc_ns_set_native_hash((unsigned long)(uintptr_t)argp, GLOBAL_CMD_ID_SET_CA_HASH); + //mutex_unlock(&g_set_ca_hash_lock); + // break; + case TC_NS_CLIENT_IOCTL_LATEINIT: + ret = tc_ns_late_init(arg); + break; + case TC_NS_CLIENT_IOCTL_SYC_SYS_TIME: + ret = sync_system_time_from_user(file->private_data, (struct tc_ns_client_time *)(uintptr_t)arg); + break; + default: + // 安全存储相关 + ret = public_ioctl(file, cmd, arg, false); + tlogd("***** public ret = %d ******", ret); + break; + } + + //handle_cmd_finish(cmd); + + return ret; +} + +#ifdef CONFIG_COMPAT +long tc_compat_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!file) + return -EINVAL; + + ret = tc_client_ioctl(file, cmd, (unsigned long)(uintptr_t)compat_ptr(arg)); + return ret; +} + +long tc_compat_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!file) + return -EINVAL; + + ret = tc_private_ioctl(file, cmd, (unsigned long)(uintptr_t)compat_ptr(arg)); + return ret; +} +#endif + + + +static int send_to_proxy(void * wrt_buf, size_t size_wrt_buf, void * rd_buf, size_t size_rd_buf, uint32_t seq_num) +{ + int ret = 0; + loff_t off_vtzf_serialport = 0; + ssize_t ssize_ret = 0; + struct vtzf_serial_port_file *file; + struct file *fp_serialport; + + file = alloc_serial_port(); + if (file == NULL) { + return -EFAULT; + } + fp_serialport = file->filep; + if (fp_serialport == NULL) { + ret = -EFAULT; + goto END; + } + if ( !(fp_serialport->f_mode & FMODE_CAN_READ) ) { + tloge("%s is not readable \n", VTZF_SERIALPORT); + ret = -EFAULT; + goto END; + } + + ssize_ret = kernel_write( fp_serialport, wrt_buf, size_wrt_buf, &off_vtzf_serialport ); + tlogd("after write vtzf_packet_cmd to %s, ret value = %d, offset = %ld \n", + VTZF_SERIALPORT, (int)ssize_ret, (long)off_vtzf_serialport); + + while(1) { + off_vtzf_serialport = 0; + ssize_ret = kernel_read(fp_serialport, file->buffer, SERIAL_PORT_BUF_LEN, &off_vtzf_serialport); + tlogd("after read vtzf_packet_rsp from %s, ret value = %d, offset = %ld \n", + VTZF_SERIALPORT, (int)ssize_ret, (long)off_vtzf_serialport); + if (ssize_ret <= 0) { + tloge("Failed to read vtzf_packet_rsp from %s, ret value = %d \n", VTZF_SERIALPORT, (int)ssize_ret); + ret = ssize_ret; + goto END; + } else if(ssize_ret < 4 ){ + continue; + } else{ + if (*(int *)(file->buffer) == seq_num +1) { + tlogd("read vtzf_packet_rsp succeed, ssize_ret =%d, size_rd_buf =%d \n", (int)ssize_ret, (int)size_rd_buf); + if (memcpy_s(rd_buf, size_rd_buf, file->buffer, size_rd_buf) != 0) { + ret = -EFAULT; + goto END; + } + break; + } + /* old data, continue */ + } + } + + ret = 0; + +END: + free_serial_port(file, ssize_ret); + return ret; +} + + + +MODULE_DESCRIPTION("virtual trustzone frontend driver"); +MODULE_VERSION("1.00"); +MODULE_AUTHOR("TrustCute"); + +module_init(vtzf_init); +module_exit(vtzf_exit); + +MODULE_LICENSE("GPL"); + + + + + + diff --git a/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.h b/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.h new file mode 100644 index 0000000..a634703 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/vtzdriver/vtzf.h @@ -0,0 +1,372 @@ +#ifndef VTZF_H +#define VTZF_H + +#include +#include +//#include +#include "tc_ns_client.h" +#include "teek_ns_client.h" + +#define VTZF_DEV "vtzf" +#ifndef SECURITY_AUTH_ENHANCE +#define SECURITY_AUTH_ENHANCE +#endif + +#ifndef ZERO_SIZE_PTR +#define ZERO_SIZE_PTR ((void *)16) +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) +#endif + +#define INVALID_MAP_ADDR ((void*)-1) +#define MAILBOX_POOL_SIZE SZ_4M +#define BUF_MAX_SIZE 2048 +#define SERIAL_PORT_BUF_LEN 1024 +#define VTZF_SERIALPORT "/dev/virtio-ports/vtzf_serialport" + +#define TC_NS_CLIENT_DEV_FLAG 3 +#define TC_PRIVATE_DEV_FLAG 4 + +#define VTZF_OPEN_TZD 15 +#define VTZF_CLOSE_TZD 17 +#define VTZF_LOG_IN_NHIDL 19 +#define VTZF_GET_TEE_VERSION 21 +#define VTZF_GET_TEE_INFO 23 +#define VTZF_LATE_INIT 25 +#define VTZF_SYNC_TIME 27 +#define VTZF_LOG_IN 29 +#define VTZF_OPEN_SESSION 31 +#define VTZF_SEND_CMD 33 +#define VTZF_CANCEL_CMD 35 +#define VTZF_MMAP 37 +#define VTZF_MUNMAP 39 +#define VTZF_CLOSE_SESSION 41 +#define VTZF_CLOSE_PTZDEV 43 +#define VTZF_FS_REGISTER_AGENT 45 +#define VTZF_TEST 47 + +#define IS_TEMP_MEM(paramType) \ + (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \ + ((paramType) == TEEC_MEMREF_TEMP_INOUT)) + +#define IS_PARTIAL_MEM(paramType) \ + (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \ + ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT)) + +#define IS_VALUE_MEM(paramType) \ + (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT)) + +/* Use during device initialization */ +struct dev_node { + struct class *driver_class; + struct cdev char_dev; + dev_t devt; + struct device *class_dev; + const struct file_operations *fops; + char *node_name; +}; + +/* List of devices that have already been opened*/ +struct vtzf_dev_list { + struct mutex dev_lock; /* for dev_file_list */ + struct list_head dev_file_list; +}; + +struct vtzf_serial_port_list { + struct mutex lock; /* for dev_file_list */ + struct list_head head; +}; + +struct vtzf_serial_port_file +{ + struct file *filep; + struct list_head head; + struct mutex lock; + bool using; + void *buffer; +}; + +struct vtz_shared_mem { + void *kernel_addr; + void *user_addr; + void *user_addr_host; + unsigned int len; + int mem_type; + struct list_head head; + atomic_t usage; + atomic_t offset; +}; + +struct vtzf_dev_file { + unsigned int dev_file_id; + int32_t ptzfd; + // struct mutex service_lock; /* for service_ref[], services[] */ + // uint8_t service_ref[SERVICES_MAX_COUNT]; /* a judge if set services[i]=NULL */ + // struct tc_ns_service *services[SERVICES_MAX_COUNT]; + struct list_head head; + struct mutex shared_mem_lock; /* for shared_mem_list */ + struct list_head shared_mem_list; + /* Device is linked to call from kernel */ + // uint8_t kernel_api; + /* client login info provided by teecd, can be either package name and public + * key or uid(for non android services/daemons) + * login information can only be set once, dont' allow subsequent calls + */ + // bool login_setup; + // struct mutex login_setup_lock; /* for login_setup */ + // uint32_t pkg_name_len; + // uint8_t pkg_name[MAX_PACKAGE_NAME_LEN]; + // uint32_t pub_key_len; + // uint8_t pub_key[MAX_PUBKEY_LEN]; + // int load_app_flag; + // struct completion close_comp; /* for kthread close unclosed session */ +}; + +struct vtzf_shared_mem { + void *kernel_virt_addr; + void *user_virt_addr; + void *phy_addr; + // void *user_addr_ca; /* for ca alloc share mem */ + unsigned int len; + struct list_head head; + // atomic_t usage; + atomic_t offset; +}; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_general; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; // second +} struct_packet_cmd_test; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_test; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; // second + uint32_t vmid; + uint32_t flag; +} struct_packet_cmd_open_tzd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + __s32 ptzfd; +} struct_packet_rsp_open_tzd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; // second + __s32 ptzfd; +} struct_packet_cmd_close_tzd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_close_tzd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; +} struct_packet_cmd_getteever; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + uint32_t tee_ver; // 4, 12 bytes +} struct_packet_rsp_getteever; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; +} struct_packet_cmd_getteeinfo; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct tc_ns_tee_info info; +} struct_packet_rsp_getteeinfo; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; + struct agent_ioctl_args args; +} struct_packet_cmd_regagent; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct agent_ioctl_args args; +} struct_packet_rsp_regagent; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + uint32_t index; +} struct_packet_cmd_lateinit; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_lateinit; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; + struct tc_ns_client_time tcNsTime; +} struct_packet_cmd_synctime; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_synctime; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; + uint8_t cert_buffer[BUF_MAX_SIZE]; +} struct_packet_cmd_login; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; +} struct_packet_cmd_login_non; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_login; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; // 4, 8 bytes + __s32 cpu_index; // 4, 12 bytes + struct tc_ns_client_context cliContext; +} struct_packet_cmd_session; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct tc_ns_client_context cliContext; +} struct_packet_rsp_session; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; // 4, 8 bytes + __s32 cpu_index; // 4, 12 bytes + unsigned long long addrs[TEE_PARAM_NUM]; + struct tc_ns_client_context cliContext; +} struct_packet_cmd_send_cmd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct tc_ns_client_context cliContext; +} struct_packet_rsp_send_cmd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; // 4, 8 bytes + __s32 cpu_index; // 4, 12 bytes + struct tc_ns_client_context cliContext; + pid_t pid; +} struct_packet_cmd_cancel_cmd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct tc_ns_client_context cliContext; +} struct_packet_rsp_cancel_cmd; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + __s32 ptzfd; + uint64_t buffer; + uint32_t size; + uint32_t offset; +} struct_packet_cmd_mmap; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_mmap; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + __s32 ptzfd; +} struct_vtzf_packet_cmd_closeptz; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzf_packet_rsp_closeptz; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + void* buffer; + struct agent_ioctl_args args; +} struct_vtzf_packet_cmd_fs_reg; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + __s32 ptzfd; // 4, 12 bytes + struct agent_ioctl_args args; +} struct_vtzf_packet_rsp_fs_reg; + +static int vtzf_client_open(struct inode *inode, struct file *file); +static int vtzf_private_open(struct inode *inode, struct file *file); +static int vtzf_close(struct inode *inode, struct file *file); +void shared_vma_open(struct vm_area_struct *vma); +void shared_vma_close(struct vm_area_struct *vma); +static int vtzf_mmap(struct file *filp, struct vm_area_struct *vma); +static long tc_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +static long tc_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +static int open_tzdriver(struct vtzf_dev_file *dev_file, uint32_t flag); +static int close_tzdriver(struct vtzf_dev_file *dev_file); +#ifdef CONFIG_COMPAT +long tc_compat_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +long tc_compat_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#endif + +static int proxy_mmap(struct vtzf_dev_file *dev_file, void * user_buffer, + uint32_t buffer_size, uint32_t pgoff, uint8_t unmap); +static int send_to_proxy(void * wrt_buf, size_t size_wrt_buf, + void * rd_buf, size_t size_rd_buf, uint32_t seq_num); +static struct vtzf_serial_port_file *alloc_serial_port(void); +static void free_serial_port(struct vtzf_serial_port_file *file, ssize_t ssize_ret); +static uint32_t get_seq_num(void); +int tc_ns_open_session(struct vtzf_dev_file *dev_file, + struct tc_ns_client_context *clicontext); +int tc_client_session_ioctl(struct vtzf_dev_file *dev_file, + unsigned int cmd, unsigned long arg); +static int tc_ns_send_cancel_cmd(struct vtzf_dev_file *dev_file, void *argp); + +static int tc_ns_client_login_func(struct vtzf_dev_file *dev_file, const void __user *buffer); +static int tc_ns_get_tee_version(struct vtzf_dev_file *dev_file, void __user *argp); +static int tc_ns_get_tee_info(struct vtzf_dev_file *dev_file, void __user *argp); +static int tc_ns_late_init(unsigned long arg); +static int sync_system_time_from_user(struct vtzf_dev_file *dev_file, + const struct tc_ns_client_time *user_time); +#endif // VTZF_H + + + -- Gitee From 63b0ca80fc6967a308d4f785bc69e6dd3d25b9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:51:54 +0000 Subject: [PATCH 03/12] testcase TA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/VM/test/TA/test-case/config.mk | 11 + .../demo/VM/test/TA/test-case/configs.xml | 16 + .../demo/VM/test/TA/test-case/manifest.txt | 7 + .../demo/VM/test/TA/test-case/testcase.c | 430 ++++++++++++++++++ .../demo/VM/test/TA/test-case/testcase.h | 47 ++ .../demo/VM/test/TA/test-case/testcase.o | Bin 0 -> 9616 bytes 6 files changed, 511 insertions(+) create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/config.mk create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/configs.xml create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.c create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.h create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.o diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/config.mk b/trustzone-awared-vm/demo/VM/test/TA/test-case/config.mk new file mode 100644 index 0000000..d9e9bc0 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/config.mk @@ -0,0 +1,11 @@ +# +# Copyright 2017, Huawei Co. Ltd. +# +# +# API_LEVEL which indicates the GP API version of TA +# API_LEVEL=1 indicates GP 1.0 which is the current version of itrustee +# API_LEVEL=2 indicates GP 1.1.1 which is the current version of the partner +# API_LEVEL=3 indicates GP 1.2 which is the version we both going to support +# If no API_LEVEL is specified, API of GP 1.0 will be taked +CFLAGS += -DAPI_LEVEL=1 +TARGET_IS_ARM64=y diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/configs.xml b/trustzone-awared-vm/demo/VM/test/TA/test-case/configs.xml new file mode 100644 index 0000000..814088a --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/configs.xml @@ -0,0 +1,16 @@ + + + + virt-test1 + b8ff9049-9cbb-46b0-bcae-7aaa02530001 + + + false + 40960 + 67928064 + false + true + true + + + diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/manifest.txt new file mode 100644 index 0000000..008f6f7 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530001 +gpd.ta.service_name: testcase1 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.c b/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.c new file mode 100644 index 0000000..dc79298 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: RSA signing using multi-core + */ + +#include "testcase.h" +#include +#include "tee_core_api.h" +#include "tee_log.h" +#include "tee_ext_api.h" +#include "tee_defines.h" +#include "tee_object_api.h" +#include "tee_crypto_api.h" + +#if TESTCASE == 2 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase2" +#elif TESTCASE == 3 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase3" +#elif TESTCASE == 4 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase4" +#elif TESTCASE == 5 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase5" +#elif TESTCASE == 6 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase6" +#elif TESTCASE == 7 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase7" +#elif TESTCASE == 8 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase8" +#elif TESTCASE == 9 +#define TEST_CASE_CA_PATH "/vendor/bin/testcase9" +#else +#define TEST_CASE_CA_PATH "/vendor/bin/testcase1" +#endif + +TEE_Result TA_CreateEntryPoint(void) +{ + if (addcaller_ca_exec(TEST_CASE_CA_PATH, "root") != 0) { + SLogError("TA_CreateEntryPoint: AddCaller_CA_exec testcase failed."); + return TEE_ERROR_GENERIC; + } + + if (addcaller_ca_exec(GPWORKER_CA_PATH, "root") != 0) { + SLogError("TA_CreateEntryPoint: AddCaller_CA_exec gpworker failed."); + return TEE_ERROR_GENERIC; + } + return TEE_SUCCESS; +} + +TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT], void **sessionContext) +{ + (void)paramTypes; + (void)params; + (void)sessionContext; + + return TEE_SUCCESS; +} + +static TEE_Result testcase_1(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + TEE_Result ret = TEE_SUCCESS; + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_VALUE_INPUT) { + if (params[0].value.a != VALUE_A || params[0].value.b != VALUE_B) + ret = TEE_FAIL; + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) { + params[0].value.a = VALUE_A; + params[0].value.b = VALUE_B; + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_VALUE_INOUT) { + if (params[0].value.a != VALUE_A || params[0].value.b != VALUE_B) + ret = TEE_FAIL; + params[0].value.a = VALUE_B; + params[0].value.b = VALUE_A; + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_INPUT) { + if (strcmp(params[0].memref.buffer, REE_TEMP_BUF) || params[0].memref.size != TEMP_BUF_SIZE) + ret = TEE_FAIL; + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { + if (params[0].memref.size != TEMP_BUF_SIZE) + ret = TEE_FAIL; + memset(params[0].memref.buffer, 0, TEMP_BUF_SIZE); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) { + if (strcmp(params[0].memref.buffer, REE_TEMP_BUF) || params[0].memref.size != TEMP_BUF_SIZE) + ret = TEE_FAIL; + memset(params[0].memref.buffer, 0, TEMP_BUF_SIZE); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + goto exit; + } + +exit: + return ret; +} + +static TEE_Result testcase_2_full(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + TEE_Result ret = TEE_SUCCESS; + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) { + if (strcmp(params[0].memref.buffer, REE_TEMP_BUF) || params[0].memref.size != TEMP_BUF_SIZE) + ret = TEE_FAIL; + memset(params[0].memref.buffer, 0, TEMP_BUF_SIZE); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + goto exit; + } + +exit: + return ret; +} + +static TEE_Result testcase_2_part(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + TEE_Result ret = TEE_SUCCESS; + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_INPUT) { + if (strcmp(params[0].memref.buffer, REE_TEMP_BUF) || params[0].memref.size != TEMP_BUF_SIZE - 1) + ret = TEE_FAIL; + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { + if (params[0].memref.size != TEMP_BUF_SIZE - 1) + ret = TEE_FAIL; + memset(params[0].memref.buffer, 0, params[0].memref.size); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + goto exit; + } + + if (TEE_PARAM_TYPE_GET(paramTypes, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) { + if (strcmp(params[0].memref.buffer, REE_TEMP_BUF) || params[0].memref.size != TEMP_BUF_SIZE - 1) + ret = TEE_FAIL; + memset(params[0].memref.buffer, 0, params[0].memref.size); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + goto exit; + } + +exit: + return ret; +} + +static TEE_Result test_mul_thread(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + TEE_Result ret = TEE_SUCCESS; + if (paramTypes != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_VALUE_INOUT, \ + TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)) { + SLogError("param invalid"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (params[0].memref.size != TEMP_BUF_SIZE || strcmp(params[0].memref.buffer, REE_TEMP_BUF)) { + return TEE_ERROR_BAD_PARAMETERS; + } + + memset(params[0].memref.buffer, 0, TEMP_BUF_SIZE); + memcpy(params[0].memref.buffer, TEE_TEMP_BUF, strlen(TEE_TEMP_BUF)); + params[1].value.b = params[1].value.a; + params[1].value.a = 0; + SLogTrace("thread finished"); + + return ret; +} + +TEE_ObjectHandle g_rsaKeyObj1; + +static TEE_Result FreeOperationHandleParam(TEE_OperationHandle Operation1, TEE_OperationHandle Operation2, + TEE_Result ret) +{ + if (Operation1) { + TEE_FreeOperation(Operation1); + } + if (Operation2) { + TEE_FreeOperation(Operation2); + } + return ret; +} + +static TEE_Result CheckRsaSha256Mode(TEE_Result TEE_AsymmetricSignDigest, TEE_Result TEE_AsymmetricVerifyDigest, + size_t *buf2_len, size_t outlen, uint32_t mode) +{ + if (mode == TEE_MODE_SIGN) { + if (TEE_AsymmetricSignDigest != TEE_SUCCESS) { + SLogError("CmdRSASignVerify TEE_AsymmetricSignDigest failed."); + return TEE_AsymmetricSignDigest; + } + *buf2_len = outlen; + } else if (mode == TEE_MODE_VERIFY) { + if (TEE_AsymmetricVerifyDigest != TEE_SUCCESS) { + SLogError("CmdRSASignVerify TEE_AsymmetricVerifyDigest failed."); + return TEE_AsymmetricVerifyDigest; + } + } else { + SLogError("CmdRSASignVerify unkown mode: %d", mode); + return TEE_ERROR_BAD_PARAMETERS; + } + return TEE_SUCCESS; +} + +static TEE_Result CheckRsaSha256Init(TEE_Result Sha256Result, TEE_Result TEE_DigestDoFinalResult, + TEE_Result returTEE_AllocateOperationnVlue2Result) +{ + if (Sha256Result != TEE_SUCCESS) { + SLogError("TEE_AllocateOperation sha256 failed, ret %x\n", Sha256Result); + return Sha256Result; + } + if (TEE_DigestDoFinalResult != TEE_SUCCESS) { + SLogError("TEE_DigestDoFinal failed, ret %x\n", TEE_DigestDoFinalResult); + return TEE_DigestDoFinalResult; + } + if (returTEE_AllocateOperationnVlue2Result != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_AllocateOperation failed."); + return returTEE_AllocateOperationnVlue2Result; + } + return TEE_SUCCESS; +} + +static TEE_Result CmdRSASignVerify(uint32_t numKey, uint32_t alg, Buffer *buf1, Buffer *buf2, uint32_t mode) +{ + TEE_Result ret, retSign, retVer; + TEE_OperationHandle Operation1 = NULL; + TEE_OperationHandle Operation2 = NULL; + size_t outlen; + uint32_t algorithm = alg; + char *buf[DIGEST_BUF_LEN] = {0}; + size_t bufLen = DIGEST_BUF_LEN; + + if ((buf1->buffer == NULL) || (buf1->size == 0) || (buf2->buffer == NULL) || (buf2->size == 0)) { + SLogError("CmdRSACrypto: buf is null, or bufLen is 0."); + return TEE_ERROR_BAD_PARAMETERS; + } + outlen = buf2->size; + buf2->size = 0; + /* SHA 256 签名初始化 */ + ret = CheckRsaSha256Init(TEE_AllocateOperation(&Operation1, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0), + TEE_DigestDoFinal(Operation1, buf1->buffer, buf1->size, buf, &bufLen), + TEE_AllocateOperation(&Operation2, algorithm, mode, RSA_KEY_SIZE)); + if (ret != TEE_SUCCESS) { + goto clear; + } + switch (numKey) { + case RSA_KEY_1: + ret = TEE_SetOperationKey(Operation2, g_rsaKeyObj1); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_SetOperationKey failed."); + goto clear; + } + break; + default: + SLogError("CmdRSACrypto: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + goto clear; + } + if (mode == TEE_MODE_SIGN) { + retSign = TEE_AsymmetricSignDigest(Operation2, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, &outlen); + retVer = TEE_SUCCESS; + } else if (mode == TEE_MODE_VERIFY) { + retSign = TEE_SUCCESS; + retVer = TEE_AsymmetricVerifyDigest(Operation2, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, outlen); + } else { + SLogError("invalid mode=%x for Sign or Verify", mode); + goto clear; + } + ret = CheckRsaSha256Mode(retSign, retVer, &buf2->size, outlen, mode); + if (ret != TEE_SUCCESS) { + goto clear; + } +clear: + return FreeOperationHandleParam(Operation1, Operation2, ret); +} + +static TEE_Result PssMgf1SHA256SLogError(uint32_t signatureSize, char *input, int rc, int errKey) +{ + switch (errKey) { + case NUM_VALUE_0: + SLogError("memcpy_s failed, rc %d", rc); + TEE_Free(input); + return TEE_ERROR_OUT_OF_MEMORY; + case NUM_VALUE_1: + SLogError("signatureSize %d invalid", signatureSize); + TEE_Free(input); + return TEE_ERROR_BAD_PARAMETERS; + case NUM_VALUE_2: + SLogError("signature malloc failed"); + TEE_Free(input); + return TEE_ERROR_OUT_OF_MEMORY; + default: + break; + } + return TEE_SUCCESS; +} + +static TEE_Result ParamCheckSignPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT], int numkey) +{ + switch (numkey) { + case NUM_VALUE_0: + if ((TEE_PARAM_TYPE_GET(paramTypes, PARAMS_INDEX_0) != TEE_PARAM_TYPE_VALUE_INPUT) || + (TEE_PARAM_TYPE_GET(paramTypes, PARAMS_INDEX_2) != TEE_PARAM_TYPE_MEMREF_INPUT) || + (TEE_PARAM_TYPE_GET(paramTypes, PARAMS_INDEX_3)) != TEE_PARAM_TYPE_MEMREF_OUTPUT) { + SLogError("CMD_SIGN_PSS_MGF1_SHA256: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + case NUM_VALUE_1: + if (params[PARAMS_INDEX_0].value.b != RSA_ALG_PSS_SHA256) { + SLogError("algorithm is invalid %d", params[PARAMS_INDEX_0].value.b); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + default: + break; + } + return TEE_SUCCESS; +} + +static TEE_Result CmdSignPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + TEE_Result ret; + Buffer input = {NULL, 0}; + Buffer signature = {NULL, 0}; + + if ((ret = ParamCheckSignPssMgf1SHA256(paramTypes, params, 0)) != TEE_SUCCESS || + (ret = ParamCheckSignPssMgf1SHA256(paramTypes, params, 1)) != TEE_SUCCESS) { + return ret; + } + + uint32_t keyIndex = params[PARAMS_INDEX_0].value.a; + input.size = params[PARAMS_INDEX_2].memref.size; + input.buffer = (char *)TEE_Malloc(input.size, 0); + if (input.buffer == NULL) { + SLogError("CmdSignPssMgf1SHA256 input malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(input.buffer, params[PARAMS_INDEX_2].memref.buffer, params[PARAMS_INDEX_2].memref.size); + signature.size = params[PARAMS_INDEX_3].memref.size; + if (signature.size < RSA_2048_OUTPUT_SIZE) { + return (PssMgf1SHA256SLogError(signature.size, input.buffer, 0, NUM_VALUE_1)); + } + signature.buffer = (char *)TEE_Malloc(signature.size, 0); + if (signature.buffer == NULL) { + return (PssMgf1SHA256SLogError(0, input.buffer, 0, NUM_VALUE_2)); + } + ret = CmdRSASignVerify(keyIndex, TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, &input, &signature, TEE_MODE_SIGN); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSASignVerify failed, ret %x", ret); + } else { + TEE_MemMove(params[PARAMS_INDEX_3].memref.buffer, signature.buffer, signature.size); + params[PARAMS_INDEX_3].memref.size = signature.size; + } + + TEE_Free(input.buffer); + TEE_Free(signature.buffer); + return ret; +} + +static TEE_Result GenRSAKeypair(void) +{ + TEE_Result ret; + + ret = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, RSA_KEY_SIZE, &g_rsaKeyObj1); + if (ret) { + SLogError("alloca rsa key failed."); + return ret; + } + + ret = TEE_GenerateKey(g_rsaKeyObj1, RSA_KEY_SIZE, NULL, 0); + if (ret) { + SLogError("generate rsa key failed."); + TEE_FreeTransientObject(g_rsaKeyObj1); + } + + return ret; +} + +TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t cmdId, + uint32_t paramTypes, TEE_Param params[PARAMS_COUNT]) +{ + (void)sessionContext; + TEE_Result ret = TEE_SUCCESS; + + switch (cmdId) { + case CMD_NULL: + ret = testcase_1(paramTypes, params); + break; + case CMD_SHARE_MEM_FULL: + ret = testcase_2_full(paramTypes, params); + break; + case CMD_SHARE_MEM_PATR: + ret = testcase_2_part(paramTypes, params); + break; + case CMD_MUL_THREAD: + ret = test_mul_thread(paramTypes, params); + break; + case CMD_SIGN_PSS_MGF1_SHA256: + ret = GenRSAKeypair(); + if (ret) { + return ret; + } + ret = CmdSignPssMgf1SHA256(paramTypes, params); + TEE_FreeTransientObject(g_rsaKeyObj1); + break; + default: + SLogError("the Invalid cmdId=%x", cmdId); + ret = TEE_ERROR_INVALID_CMD; + } + + return ret; +} + +void TA_CloseSessionEntryPoint(void *sessionContext) +{ + (void)sessionContext; + SLogTrace("TA_CloseSessionEntryPoint"); +} + +void TA_DestroyEntryPoint(void) +{ + SLogTrace("TA_DestroyEntryPoint"); +} diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.h b/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.h new file mode 100644 index 0000000..0a81874 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: RSA signing using multi-core + */ + +#ifndef __MULTI_CORE_TA_H +#define __MULTI_CORE_TA_H + +#include + +#define PARAMS_COUNT 4 +#define PARAMS_INDEX_0 0 +#define PARAMS_INDEX_1 1 +#define PARAMS_INDEX_2 2 +#define PARAMS_INDEX_3 3 +#define GPWORKER_CA_PATH "/vendor/bin/gpworker" + +#define VALUE_A 55 +#define VALUE_B 33 + +#define NUM_VALUE_0 0 // 参数下标索引 1 +#define NUM_VALUE_1 1 // 参数下标索引 1 +#define NUM_VALUE_2 2 // 参数下标索引 2 +#define RSA_2048_OUTPUT_SIZE 256 +#define RSA_KEY_1 1 +#define RSA_KEY_SIZE 256 // 2048bits +#define DIGEST_BUF_LEN 32 +#define RSA_ALG_PSS_SHA256 2 // 用 TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 模式去签名 + +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +typedef struct { + char *buffer; + size_t size; +} Buffer; + +#endif \ No newline at end of file diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.o b/trustzone-awared-vm/demo/VM/test/TA/test-case/testcase.o new file mode 100644 index 0000000000000000000000000000000000000000..a1edd2a6e5dffb6c88add1eb69909c4c0b315314 GIT binary patch literal 9616 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 Date: Tue, 1 Aug 2023 08:53:58 +0000 Subject: [PATCH 04/12] testcase TA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/VM/test/TA/test-case/cloud/Makefile | 29 ++++++++++ .../test-case/cloud/TA_cert/private_key.pem | 51 ++++++++++++++++++ .../demo/VM/test/TA/test-case/cloud/b.sh | 12 +++++ .../b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec | Bin 0 -> 71184 bytes .../test/TA/test-case/cloud/config_cloud.ini | 49 +++++++++++++++++ .../VM/test/TA/test-case/cloud/libcombine.so | Bin 0 -> 66688 bytes .../VM/test/TA/test-case/cloud/manifest.txt | 7 +++ .../TA/test-case/cloud/signed_config/config | Bin 0 -> 3481 bytes 8 files changed, 148 insertions(+) create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/Makefile create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/TA_cert/private_key.pem create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b.sh create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/config_cloud.ini create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/libcombine.so create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/signed_config/config diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/Makefile b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/Makefile new file mode 100644 index 0000000..4e91584 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/Makefile @@ -0,0 +1,29 @@ +include ../config.mk +include ../../../../build/mk/cloud/common.mk + +SRC += $(wildcard ../*.c) + +# set header directory +INCLUDEDIR += -I./include +CFLAGS += '-Wno-implicit-fallthrough' +# set target +COBJS := $(SRC:%.c=%.o) +TARGET = $(COBJS) + +sec_binary:combine + cp ../manifest.txt ./ + python3 -B ${SIGNTOOL_DIR}/signtool_v3.py ${CUR_DIR} ${CUR_DIR} --config ./config_cloud.ini + +combine: $(TARGET) + $(LD) $(LDFLAGS) $(TARGET) $(EXTRAO) -o libcombine.so + +src/%.o: ./src/%.c + $(CC) $(CFLAGS) $(MY_CFLAGS) $(INCLUDEDIR) -c $< -o $@ + +%.o: %.c + $(CC) $(CFLAGS) $(MY_CFLAGS) $(INCLUDEDIR) -c $< -o $@ + +clean: + rm -f $(COBJS) *.so + rm -f ./manifest.txt + rm -f ./*.sec diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/TA_cert/private_key.pem b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/TA_cert/private_key.pem new file mode 100644 index 0000000..272e13a --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/TA_cert/private_key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b.sh b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b.sh new file mode 100644 index 0000000..ae9d80f --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b.sh @@ -0,0 +1,12 @@ +dir_basename="testcase" + +for i in {1..1} +do + cp -rf compile_file/${dir_basename}${i}/config signed_config/ + cp -rf compile_file/${dir_basename}${i}/manifest.txt ../ + make MY_CFLAGS=-DTESTCASE=${i} + # cp -rf *.sec ${output}/${dir_basename}${i} + sudo cp -rf *.sec /data/vtz/ + + # make clean +done diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec new file mode 100644 index 0000000000000000000000000000000000000000..3dd1794c39eef535fd381efd437b3d5ca6b5d464 GIT binary patch literal 71184 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 aKnN^CL(SVti9E{y;1Hazr;6eXbj9`@&Ou-R literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/config_cloud.ini b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/config_cloud.ini new file mode 100644 index 0000000..2c935f6 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/config_cloud.ini @@ -0,0 +1,49 @@ +[config] +;0 means debug +;1 means release +;[fixed value] +releaseType = 1 +;;; +;0 means TA not installed by OTRP +;1 means TA installed by OTRP +otrpFlag = 0 +;;; +;server address for signing TA +serverIp= +;;; +;public key for encrypt TA +;[fixed value] +encryptKey = cloud/rsa_public_key_cloud.pem +;;; +;public key length +;[fixed value] +encryptKeyLen = 3072 +;;; +;0 means not sign +;1 means signed by local private +;2 means signed using native sign tool; +;3 means signed by CI +;[fixed value] +signType = 1 +;;; +;private key for signing TA +;[private key owned by yourself] +signKey = ../../test/TA/test-case/cloud/TA_cert/private_key.pem +;;; +;private key length for signing TA +;[key length should be 4096 for security enhance] +signKeyLen = 4096 +;;; +;0 means SHA256 hash type +;1 means SHA512 hash type +;[set value to 0 by default] +hashType = 0 +;;; +;0 means padding type is pkcs1v15 +;1 means padding type is PSS +;[set value to 0 by default] +paddingType = 0 +;;; +;config file +;[signed config file by Huawei] +configPath= ../../test/TA/test-case/cloud/signed_config/config diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/libcombine.so b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/libcombine.so new file mode 100644 index 0000000000000000000000000000000000000000..e2f586740debc8ddbe2af0424284a156cfce504b GIT binary patch literal 66688 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 F?*PFI?OXr= literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/manifest.txt new file mode 100644 index 0000000..008f6f7 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530001 +gpd.ta.service_name: testcase1 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/signed_config/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/signed_config/config new file mode 100644 index 0000000000000000000000000000000000000000..bfb150ca215c320b7cf1666a7036cebfeb1e4476 GIT binary patch literal 3481 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 literal 0 HcmV?d00001 -- Gitee From 119a2ac2109cc38bff78d073f6bd6e84bf8c4512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:54:23 +0000 Subject: [PATCH 05/12] testcase TA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../cloud/compile_file/testcase1/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase1/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase2/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase2/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase3/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase3/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase4/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase4/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase5/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase5/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase6/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase6/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase7/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase7/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase8/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase8/manifest.txt | 7 +++++++ .../cloud/compile_file/testcase9/config | Bin 0 -> 1945 bytes .../cloud/compile_file/testcase9/manifest.txt | 7 +++++++ 18 files changed, 63 insertions(+) create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase3/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase3/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase4/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase4/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase7/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase7/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase8/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase8/manifest.txt create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase9/config create mode 100644 trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase9/manifest.txt diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/config new file mode 100644 index 0000000000000000000000000000000000000000..b124892a08dfdc8dcbbe1d8926111d3c458f52d1 GIT binary patch literal 1945 zcma)63pAVA7XJS~5mL{HqMnf$%`lNaK_aP!qOFuZR=n#n=jz2~fT_W8cO&pzkuwfBBp z^SA~AKtP}h0K-TCI0*oN2Bcj6%K()eEJ60e62#xj5fBJL7|ix%BEAbHPfLh7*Y_~v zD_d9-g|<%fNL$ndL3I@X-bzu2(I|v35`~4__E5BydL`I^MR~;W62c-Wrm*okfxznh zM&Q^!xP7rPp>ZK1oZB|o%s`V$g&iq0m_l{1r*PLHg+j6a1mUFr;hq3nth-mo8hvsf z=@T0#6orNTeo16ZG{q67{q_bj-!VL#0oyZ3j1WGbWKZM6Bz_1lj6~=0crew$4u)Y$ zP<&*ph$IRViYTxI!vFQdpbCJHK-$V6K^q_m1Og-epPy#+iG!0oskCfPg>Bxm()Na` z&rB0))K~5a+S>y?XTq$n8q9j5bC^x%oQ(S6gRB>JA8m^`^2sultSOU~1|BX0)zw4j zK1_WtA4VCJ=(SL--~Uh*Xv_53Aeab$=8B98=$?TnO%_#JjnW~8rTUf5yw{aMa)g}9 zu`(dlvuP)G_P3RGcgC-bT`M_1aS+X!?D4|+Z(QUCwVCTqjgTAeJr!(4Y28vJNx#Um zBf%Y0edz{q;rZ>%<-&#R(dUu+W~!FDDJ+R@&A^c>V@5eek*-KFhC|@J@f2;Tukbjz zJDVTTV6(e`#}AIKR_*?#wQa2HcBd&Ws-v`9!KJwPhF33leY{sRDGR*ecIQ&oFQF}i z>^uKRx@Ru-8^hA$n%<%FJ;q&C19DyDmWw}qyQ`jAwtIVVsP%dWC*Cdu9 zRy>!&Bn_sUmY~1ad*}%iOCbaZfED6gSey-;D|5`0fHZ{lll647=+hsB{?Eoznxrv^ z>ERogJx^fubpvfA5&rv9+#0cEic(>!+vkF#{kbeMFovN~2GbH@;;^DPk zOzVS_F7p;eRRg-!`^nd2HK(2$l8%s`zE3YWnkNvWmxC{RMZXhe_|pbYGh*G1DydQq z=^|3j)y#8$7H#Peg8ESxS0rz ziWoh_FN@t%B8F|tJ@;2@(G70`UzawfQ&_?J=yA^KIMeNy9x^=_I!7N+R{Vr9YV0L~ByVgW5kDgG>U1VB_0 z!2i=8bO463GlGDM^1wy_0@RdJ4*<$PZLvs=WM#Wu*Xn+f7-jU=vCevb1(bHb4)=U% zb*lsF;sv|2b-#GJa59+CbLnthUgm4l0IReaXKvM*M88)iH*!_jU8y@qZoPNF-7K4* z)%{^?jtz2C61_7!@NHL&9G#5xoeBaQs7`A1mnkgQM?;vnct|H%#x6gDF!;_V(I#ec z)yoS%ZuF9FS4et`_D;yS7I?_Ju-3Wh=vB6cW0yr^w886c$I@NxAqztXmugcTC^efE zD^0CWs_UVH>UBhRrr>Y=_%ILhfV>N(KGB@m9M1inq0@*bhwR8E93kd_uTJL literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/manifest.txt new file mode 100644 index 0000000..9ca8ed4 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase1/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530001 +gpd.ta.service_name: virt-test1 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/config new file mode 100644 index 0000000000000000000000000000000000000000..e479e7039d9e8f27d739ee52573d3686d6a584a0 GIT binary patch literal 1945 zcma)62~?9;7XI^Rfq<+Di(o=941^`*&(9hZP@sykhzK&WCSj3C0VM%CN~#HN>{LV{ zFd!lVr4&#BNi)zg$WoD_f`WjEht)8k9Vx4%p|zc!IdjhRy>s4u-*@l3@4b8Oy^m@h z)qns3h*bc9F%$rt2LNCjC|~}^K*%{rh#G{1$bZ~Gf(Q`Q(1=Koxu=emmRdMh*ApI=@iNpU& zkPi5fd=la#62o~U*S!!?M+Jryhtt&hJ@hGKYkd229QEfO&%mr2^4||;AMbmmeYWM$@hS5Gkwb~bDxX4nydao zNUl-dXpQaa3ieotG`p>{cm$j6ATHRgHwc|@dS$h4neQu^D@LbFcWgAXNS86a{p7yS z;CGTSj7}lG9X5OSxGLDv!A~i6HtM+xDki9J0i=r!t5jPWM;S)Sw|a7?E5am53G8dE zL%nmr_U!(_PElV^(#GVMg+;R`u)cHso}>V+<-o8`15N2mT662OSVxR%{W!nTBG-xv zbxQ{>=_E#7>2g@R`aW}Fh@(wZFw#tQ5^B~A|LxYKUUojm1trk%C9~dm@OIrPcR%ly z$&PL|_sV0jnQ_$$eWyA)CwuSq5J)lIqQ3D!`X2wN>b2hW*8I8q!C$-HD@*?n(f;DV zy?^ps4FpFgadwH~x7aK0GcF22IeR2V%daaB-f<}Q`s8|qnyd$VKLzhk>H0L#a&E_1 z;C&0N%FcX}dJ4w1(3GWY!=rS}XTRU~=H^UavY`DcMKPkIJT{VxqmX%BDi>agDZqe! zDA~Cv->_}9J^2ud)Pdw?* zC-^bdf%@VSp%B}K|K0<*-UuQQ0HR!w0|_!A19^@S$S7S%`y5^~-EMxB8}NKGRoobl zoFDsI!}|wFdCNczg+hYJ6(|^^XpTXk(FzCz$_Mg>D8FF{ytpHp$2;jjqtRhIOGrNH zv~U)O%T0{5jON8cJAb!CT-5$=O9vRTwzm3X&dQ4vDMTOu?`uoUFtpE?{mj*VpOdN0 z3(1bPjzEHvdEmIqP&VuO(-t+=HIMUXZ+yn*nck9>s%QFjEQpNnSwe>Dec-3mCGVLt zTG;2#&}>jOO8rLT_(-q&8igpky80xkHoYQl`Ul89{IlrR=GntjCQbj+E#eoXTb4_k32%cDn>=iXWif?jOjZwVzUBiBQ?8;`7RHT>GVC1^2z(r{ty>4$x-0zjO>vn+o*_)$AI>q&B z-wrmOJ)fhgcjpUuB5VEFA^+nyPDGiXGdP@Pxg_wftBrfD4hZB0s}4AW2m}sL1?A#D zg^mO$asv1>?Li%2$U7qfK+6wk0U)3#mv{iU@o|eoZ96A#w_94xk5WS({VlA%)n5U* z-7mxG6Vr;kvQv4vo^c;mrX&=PpZfBG-fvQ~=+2&n1+x#d&Ulk#6KfA#wa<~Tb9N!S zrO|VpIXgCCH`eBEw~eay4oB(w+IXzvDD(N_G@HwR&$}gBw5$g&sS%eS&h+RKHi4Q9 zKam9tRlc2XuF(&O@O1mP@XC_%h=pfKyp+&Zd6RKOBAYHN%1wRXj<>+}DwYkTT<+T4 z-R%GmrBI9C{Pj@Y-D=U;nn%Nj&G0$(ZoU^UrwtcEdO}=0H7b)#=N}LQlZ0ui$%OC9 z&HiXfyPIvgEZ?v!d1e(T97$^a{%FJ_TU(WxI&o0J1+DcJGg(l3TrgKj7vU zde??@$U9{Xj;KzY^r@TSibGTJBeUTX=FTM*k8enq0>by5I$6gVE}^x|KMUPVU=|$A wH#TTe3DD(xkTag1SW#dO;nsD*rvV-gXIA$!c@Z$p)OUPCbaJ4;@ZA~K&+=UQsQ>@~ literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/manifest.txt new file mode 100644 index 0000000..af8f00c --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase2/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530002 +gpd.ta.service_name: virt-test2 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase3/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase3/config new file mode 100644 index 0000000000000000000000000000000000000000..681f97c4c157164ea266c2bb3ddc84f79ebed47d GIT binary patch literal 1945 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 literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase4/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase4/manifest.txt new file mode 100644 index 0000000..ae41d66 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase4/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530004 +gpd.ta.service_name: virt-test4 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/config new file mode 100644 index 0000000000000000000000000000000000000000..1be5c9b1635b78046f5b4e7a2426e763acac5eca GIT binary patch literal 1945 zcma)62~d+s7XJSv1VR)D3E%*Ma3c`%{~-_oK_I9&s33yWawh>KaycXs6tYXgH6jAT zC5Nl7$gPYJkt={Ag3JI5801(H$3+1_RCGt=&+gH7Uw6NH?+w-s z)*%28h?WO{X%qmY0sycLAzS{-0A(B`LXANpWXBaG0z@EiIL&`3m?Z*#J3yDeQc%M) zdI)VtW6aXs(m!kmL984AIlx#5gGTzG(0BynFsv-o%YY&t?Z#)uhjCycq_ssL@q}Lq z(gAOhXIyM3pUopNoFN^J?NlnX3$}q^sx=Mv+k!9*)4o7R@ITxeKzdv5v3Sid?m6CZ zd@e66?6*reu`%#2$mZ8KP*}Ud!)+m&E!mdMVv%V!EQrivGsDPqCX)$Kt*sykvJO7Q ziQ|!ZVO*XyBtq!_{==XgfD|E=WkEtHB18xfc;dVByrWbYB5}H%e`;g4wxn$S1jcJ&_#nww?So%%udeFi6H0UEqi6@T(#;t`lSQr- z8G5iN&CuY7=k?jG6}->-X@aA!BX6jh;wVzBn>>AORx`Vh1+y|ZwkC7_;h>o1v`q1{sl zZru}f>I#p|;_3XhH<&!PITv~V94Cq4hi6q^H`-l1wD&@&^5=d`OA^7yv@gofazT6A zuf;;Gs<)7&l7wcI>||oCd8R!}+3)wgygD}&FYGQbRS4}Vj}GJFO$~T`+tZ%3nF3O+ zAcH++g?e2dyW>4jq#h*qJiVxL`O}z_kZg7XRk4I?SfS)_6(s6sjB(B}xJjR}Zk<+O z^{XL$sX-vd=4{z@(F<4C8T9BMSlec#pPmB6jv|9{Im(1SML@S@sG3hX9#7PA5jgI^ z3s+L?$Ws}_5=PykxN91Y6J$%7!u6FLl;{)Qn$x^@JQchZhRfvI#$NH$># zo5|sF`C*n3yl6=OUzT9H`hQy5Q6U=5>i0P-D^jEg1Oc`^Hgok}P}g{1KO|Cb*Cqy$ zA4T|sM>O6&O0+n#qP8ILN=p*Cup;pz{L zg0WF>)eF{Z6fi%eLm1JzRvT}VopI4e?MM0VzqwFqd+UcAlh2|hfp=VrO&^C&5!fBN z(?{lT#-#DPG^b6qc$?jlF;=n@sa>k>Gf}PGTUp+&X?OML;(*)!@+LLCZAbnXF0P>x>{ECp(}9AOHoKBmlsbFIzlnTe7U(ZfRA&NSrMCTUceQzXCG5e-4<{ ztjoiS9W};M@vriz*#X$nOrDp;n;W^8mhV5_8L?ov8C5iZy{nje!8=k+5VSdad8eIm zzg)AczB{ickn43a;;>oiVsIUINKN~BHn&M9IAL5Ni&m6WJg^Ch^)>7p+|49(LzvSz8r@LBC zpY!w&E*$Ki(6?xdU^k2FBIiF%vd$$qhrk_sI-!b%ddGc{IlJv&CGw709(8y#WwJ(= z8^mU3$V*PHC|z!My$nl8N!}z}OulA!>qR5u<3_j>oB+0ekkKY3&6Cr>dn)f3S{t+0 zGc$UdUpEEw4M;tahF4y{)@w~wjC3>n z-(4kETu{;QeC~1TsX~uSKhZOeIVT%>v~#(hnFpVrk^a4wCeH1=mY_zsn&0|l4dXVj u&gmnNX5&_qzQZV=2|PY=PN%rF25xvcAFPbC;@vsB_fAv2?yDHaX#Fo8@9cp9 literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/manifest.txt new file mode 100644 index 0000000..1cb7705 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase5/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530005 +gpd.ta.service_name: virt-test5 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/config new file mode 100644 index 0000000000000000000000000000000000000000..d52f30aa5ab7b22678904133bbdef4983792d102 GIT binary patch literal 1945 zcma)62~?9;7XJS~At6N8uv8#y0fqvBKOuyr?9l;AK}C=fQ!#-6(E>se!%-TUr)@1A?_ zy~cZu5C8&6XaJZ*0ze)B0NWtd@?Qq1;$SgS4vP_;RR{=#AYI-46D?={w%71f0s3^P z%{ZO}Yoajr1wjR`H9-)o2Eg7VEQ~=RB9SN@L<=KntMn?MfkOrHnF2P4gojPG2n0_5 zH^L$~!eVz?N*q6yXF>Ca&5Sh3WZ0cVg-K*r3W>f2NhA{G1B8YD!#x4E+;We_8Gmrk ziAdvfd2IIYmvB;&N$xQ9w>LPm+~eatV2TIPBbLP?Qm8DL$ckmMiEd0L6DGU5z%WdW zIm$`n5qWGbj|z(+t3Q4iR09xVNLv*oNCOf>AfSl)xY%b@bWj*Vrk)J1b}AdI=#yTv z!3!F(8?vOnK1RqA+y1K2@?K1dXZr;&V>x`tXWHehlO()Dc~R~7g6W2oX;Fl_J4_f# zC$Dr&qKwM*yUF$|53VtsJR>xcevTgtKpx&dv;>jbEw5>{wM=+eV`~P=W@}?Q5FO-j zTO;DlU}{dFytiU#;ONFoLwV)ThcMyF;m<6h3|`Y?dd>9~6wXrF!z6E%){QA)i({D! z5$<0YEi~fCpYHQ~bN1!Q$B#IMW@u}@TpzJs<4+kiGsYznP5@G*8%|)(hwwhRSsj!Y zdXkkWbqGDfWF1VdM-Qd;^v>M9HGsD`++Q&?MJM@1#@D~O`&K4VwlbP%-(5Mr8P`1? z{M{X)%v`i@2It0ae}Oq2G#7y0U+ULk{rXAWr#C$>hVDEcr~Q5a)0(XxY1j89-AQRW zNpE#DsOyzj=wzd4i%2n?$%(T_@PuBe@Qr>OW z2K>5x$ZC}E1%~>U%Io6U9XqB_BhjpFQ={*ufeSujLbaOnBP(a2n+HwLVcaJn%OpVP z^AS$8n(Ij%FT|H)y7UJ_fb%U70tCQnQ7J4s37e~O3{OCQ1REaH*E{aExXz6lo5^i& zNkJ@5HtB}lhp}4*+DIe%)7;N`DhM@w}L>}*mr?WGO?B)ck zCdoOL$>DPOY^OwC5^VJ^OR&K3KP^4UFoojs$DCCaDMAc_fI4qV^J?XdmE~HE_xlXc z3U|$nhlNEoF4%_hD-9(hjgi0j#M7FxWOIq!s4ng*#Qh=1x2eZ>;FvEl(sb8IcirnY z-g(J%KF#m`j!i(m#0yw z3PZig(aoF+I-+0V^&s6^nmLHpcw`@9{48WY_A@F!hJCwQEGQ^XeZw}9Jjz^(#!JI4 zZ?+v;U+?RR_|k;_?0`4%m+SNXbmRGEla~cX+~Cel9YCZiSRKF@0zn+01*ycp3mpO2 zsR-czX%9MphpIDzfST%n0RRE&Dya_uRUfuE)KFZvmbhKX_v+DXzOw_FYYq;@B6|Bh2Yyg$N9S(&K6rrtH#=L z_Dw6P-fftJw22dUhBh`Or`+WO0`sD%6vhaD_Q8(kTd(d39-aea7d~hHV4$}?J|`Wq ziP2;P8ryfg`QGrwTw{mCiO+-E%SUGE1m6ETaukqevCRA02hBYa` zRO2tmy`_w%IarD8|Mo|H^}?VFwGPcUzotKZlbev8&JCE@iS@&ng>0tRKfwOp*0+&Qk*U>7=VAe~dxg4>tO^2_A^09zdPGynhq literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/manifest.txt new file mode 100644 index 0000000..800e872 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase6/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530006 +gpd.ta.service_name: virt-test6 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase7/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase7/config new file mode 100644 index 0000000000000000000000000000000000000000..d293371494804ee714a8568200b3da9c3050cee6 GIT binary patch literal 1945 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 literal 0 HcmV?d00001 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase8/manifest.txt b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase8/manifest.txt new file mode 100644 index 0000000..eae7b84 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase8/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: b8ff9049-9cbb-46b0-bcae-7aaa02530008 +gpd.ta.service_name: virt-test8 +gpd.ta.singleInstance: true +gpd.ta.multiSession: true +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase9/config b/trustzone-awared-vm/demo/VM/test/TA/test-case/cloud/compile_file/testcase9/config new file mode 100644 index 0000000000000000000000000000000000000000..c84dc177f8d60653619ffdf568193ad7a2c49093 GIT binary patch literal 1945 zcma)62~?9;7XJS~3j{<6iGVB;2txyrlyI;RIRpz44{sqL5Q4DS7_;xH!i9yH*&V!}tu8wk zmP2FoQ|(eW}bR^9bX8igFD%Uh9hzT1p4VVF3u7MGQ3mb3)I6MOr4u=ENjSXQKW}b)( zjpiHhc`+^_!?L~GHi+}qsnf~h0>bx-cx?GvqtR=T^c zvO%3a(Sj|L(9hm!tDUz(+7P}RHM_igzLP5yV;^R8vEKP?QD|7Q=TDG~2U>OSR5Sx_JM zZ92HGqAQ=Ekceg%>v3d_`J~R}>~)*PvX}kwg7#}9>A=qN2wn`1MC5nNU7Tnk0fTCv z6D>;fwH|G?$Gaj4orsvrCIxq1?F?B84D`Q6-d@Jmu2FMhq+6B#s*61mi5>MEYCq5n zZ0_&Z9wZ*eFfvL-!Z~Z}N%S)x?w-lPohhKmTu3ZOQJ-s5lT4UwMe>+=@HsWBBy$y< zU@e7ZFqWoKjCq9r(Ge(YfDj-6mJ4!VK^Ckj$uSKgQUz8@#w%u;EN{hlkBC!R8crjY z$M0fYeu8Cp4djtX1ccax{n657G>Ae;fgsWic7aL1VHiqP58?BpSX3&FZbE@2lSU2T zgvP|g@+cwv2w3|+mSC#V|5~!>u#u7B?{ijCqzEAh0;YF-c=(e)@%zLfek%v3*T9e} zldWg9(9ltbs+-4u8KszA@n}HZW0iI-66(A~zF;foX6@#|6(dM!sXo1P#N`9VB+ARo;(mVfwqxS)7tfY#q7qk(qdqx? zA0qlM&8pkA%#r8$BeCnHk0Rn;H~0)gsqDUIZC{Wpi?5VEb?Lo-%B@Jo`P;V>bG>S3 za@XSi(H5~%hQ48I7%4jJ8dagU9Qox z5Wt^l4+;QN(iuSjB{{GUfB8yWb6C%7#;jxu?m$XE(HE8FXz|2`vuA0yN}M|eGp>>Bh0e#|LA{_w z*VpI?=HFMRW(uhHy;-h~rk@HB*mQjQtFo4YZxVz(C~Il`Kn5$W%*4Z0^A|9D5cNec0MUH@meuY(Dioza{ZIS zBJ%h>t&n8((W^UF;guQ{Z>g5ouy3OFmC&zrDom)nSzpY%JvnB`q;J~?tc0-}yi7yw zJr(-~5=E?HZNDr}StmhC%@+l?nu)Jd!UTL$rOcw*k4N7>QYfQ5-%5@qXR1Y=;Of1* z7kuf?bw^!xSWHIv;(pNLU4r#e9U1>L?o#r_DL1;~gGRNRq6`oF$o{O%ND$?`LCCH5 zD;4$HZw(AaEH9AA9ZIU_e6|a|&k?D)&YYQ-nF;^-E}F`H!bE$gsn>Q@%+A-Jl=|6j z^@Dz^T-xl8f>&95$d%1G$_w=Jq$4hKm2JBSY#7VF*ds; Date: Tue, 1 Aug 2023 08:55:30 +0000 Subject: [PATCH 06/12] testcase CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/VM/test/CA/test-case/Makefile | 28 + .../demo/VM/test/CA/test-case/b.sh | 15 + .../demo/VM/test/CA/test-case/testcase.c | 790 ++++++++++++++++++ .../demo/VM/test/CA/test-case/testcase.h | 38 + 4 files changed, 871 insertions(+) create mode 100644 trustzone-awared-vm/demo/VM/test/CA/test-case/Makefile create mode 100644 trustzone-awared-vm/demo/VM/test/CA/test-case/b.sh create mode 100644 trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.c create mode 100644 trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.h diff --git a/trustzone-awared-vm/demo/VM/test/CA/test-case/Makefile b/trustzone-awared-vm/demo/VM/test/CA/test-case/Makefile new file mode 100644 index 0000000..9eca1ea --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/CA/test-case/Makefile @@ -0,0 +1,28 @@ +CUR_DIR=$(shell pwd) +iTrustee_SDK_PATH=${CUR_DIR}/../../../ + +TARGET_APP := testcase1 + +APP_SOURCES := testcase.c + +APP_SOURCES += $(iTrustee_SDK_PATH)/src/CA/cloud/libteec_adaptor.c + +APP_CFLAGS += -fstack-protector-strong -fPIC -g + +APP_CFLAGS += -I$(iTrustee_SDK_PATH)/include/CA -I$(iTrustee_SDK_PATH)/thirdparty/huawei_secure_c/include + +APP_CFLAGS += -D _GNU_SOURCE + +APP_LDFLAGS += -ldl -lpthread -lteec -lssl -lcrypto +# APP_LDFLAGS += -ldl -lpthread -lboundscheck -lteecc -lm -lssl -lcrypto + +APP_LDFLAGS += -z text -z now -z relro -z noexecstack -pie + +APP_OBJECTS := $(APP_SOURCES:.c=.o) + +$(TARGET_APP): $(APP_SOURCES) + @$(CC) $(APP_CFLAGS) $(MY_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS) + +clean: + rm -rf *.o $(TARGET_APP) + diff --git a/trustzone-awared-vm/demo/VM/test/CA/test-case/b.sh b/trustzone-awared-vm/demo/VM/test/CA/test-case/b.sh new file mode 100644 index 0000000..e98340e --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/CA/test-case/b.sh @@ -0,0 +1,15 @@ +ca_basename="testcase" + +for i in {1..1} +do + make TARGET_APP=${ca_basename}${i} MY_CFLAGS=-DTESTCASE=${i} + if [ ! -f "${ca_basename}${i}" ]; then + echo "build ca failed." + exit 1 + fi + # mkdir -p ${output}/${ca_basename}${i} + # cp -rf ${ca_basename}${i} ${output}/${ca_basename}${i} + sudo cp -rf ${ca_basename}${i} /vendor/bin/ + + # make clean TARGET_APP=${ca_basename}${i} +done diff --git a/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.c b/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.c new file mode 100644 index 0000000..023d80b --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.c @@ -0,0 +1,790 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include "tee_client_api.h" + +#include +#include +// #include "../../../libteec/teec.h" +#include + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/vtz/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +// #define TEST_CASE_TA_PATH "/data/vtz/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} + // 0xebc87fc2, 0x05dc, 0x41b3, + // {0x85, 0xb9, 0xf9, 0xf0, 0xef, 0x48, 0x1b, 0xad} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + + struct timespec tp_start, tp_stop; + clock_gettime(CLOCK_REALTIME, &tp_start); + + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + + clock_gettime(CLOCK_REALTIME, &tp_stop); + printf("\ndebug, %s %s %d \n", __FILE__, __FUNCTION__, __LINE__); + printf(" TEEC_OpenSession used time: %ld us\n", + (tp_stop.tv_sec - tp_start.tv_sec) * 1000 * 1000 + + (tp_stop.tv_nsec - tp_start.tv_nsec) / 1000); + + assert(!ret); + printf("open session success \n"); + //Interface_Function-003 -- no param + operation.started = 1; + + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + printf("invoke value no param success \n"); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + printf("invoke value INPUT success\n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + printf("invoke value OUTPUT success\n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + printf("invoke value INOUT success \n"); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + printf("invoke temp INPUT success \n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + printf("invoke temp OUTPUT success \n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + printf("invoke temp INOUT success \n"); + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + + + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + //printf("buffer = %p\n", sharebuf->buffer); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + printf("mem ref whole success\n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + printf("mem ref partial INPUT success\n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + printf("mem ref partial OUTPUT success \n"); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + printf("mem ref partial INOUT success \n"); + +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + printf("alloc sharemem success \n"); + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + printf("after release \n"); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + printf("after reg mem\n"); + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + int int_exit; + + ret = TEEC_InitializeContext(NULL, &context); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + //printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + //printf("please press any key and enter to exit \n"); + //scanf("%d", &int_exit); + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_ACCESS_DENIED); + // assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + //printf("please press any key and enter to exit \n"); + //scanf("%d", &int_exit); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + //printf("please press any key and enter to exit \n"); + //scanf("%d", &int_exit); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + //printf("ret = 0x%d \n", ret); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + //printf("please press any key and enter to exit \n"); + //scanf("%d", &int_exit); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + //printf("please press any key and enter to exit \n"); + //scanf("%d", &int_exit); + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + } + + if (!ret) { + printf("TEEC_InitializeContext cost : %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + } + + if (!ret) { + printf("TEEC_OpenSession cost : %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + } + + if (!ret) { + printf("TEEC_InvokeCommand cost : %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} + diff --git a/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.h b/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.h new file mode 100644 index 0000000..d34fbb0 --- /dev/null +++ b/trustzone-awared-vm/demo/VM/test/CA/test-case/testcase.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif \ No newline at end of file -- Gitee From 31dcbd2043f4f6bcc3f8fb6572b829dbcc852432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:57:44 +0000 Subject: [PATCH 07/12] vtz_proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/Host/vtzb_proxy/Makefile | 33 + .../demo/Host/vtzb_proxy/thread_pool.c | 98 ++ .../demo/Host/vtzb_proxy/thread_pool.h | 33 + .../demo/Host/vtzb_proxy/virt.c | 92 ++ .../demo/Host/vtzb_proxy/virt.h | 20 + .../demo/Host/vtzb_proxy/vtzb_proxy.c | 950 ++++++++++++++++++ .../demo/Host/vtzb_proxy/vtzb_proxy.h | 461 +++++++++ 7 files changed, 1687 insertions(+) create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/Makefile create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.c create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/virt.c create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/virt.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.c create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.h diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/Makefile b/trustzone-awared-vm/demo/Host/vtzb_proxy/Makefile new file mode 100644 index 0000000..e73c794 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/Makefile @@ -0,0 +1,33 @@ +TARGET_APP := vtzb_proxy +LIBC_SEC := libboundscheck +TARGET_LIBSEC := libboundscheck.so + +all: $(TARGET_LIBSEC) $(TARGET_APP) + @cd $(LIBC_SEC) && $(MAKE) clean + +$(TARGET_LIBSEC): + @echo "compile libboundscheck ..." + @$(MAKE) -C $(LIBC_SEC) + sudo cp -rf $(LIBC_SEC)/lib/libboundscheck.so /usr/lib64 + @echo "compile libboundscheck done" + +APP_CFLAGS += -DSECURITY_AUTH_ENHANCE +APP_CFLAGS += -Ilibboundscheck/include +APP_CFLAGS += -Iinclude -Iinclude/cloud +APP_CFLAGS += -Werror -Wall -Wextra -fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie -D_FORTIFY_SOURCE=2 -O2 +APP_LDFLAGS += -lboundscheck -Llibboundscheck/lib -lpthread + +APP_SOURCES := ./vtzb_proxy.c \ + ./thread_pool.c \ + ./virt.c + +APP_OBJECTS := $(APP_SOURCES:.c=.o) + +$(TARGET_APP): $(TARGET_LIBSEC) $(APP_SOURCES) + @echo "compile vtzb_proxy ..." + @$(CC) $(APP_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS) + @echo "compile vtzb_proxy done" + +clean: + @cd $(LIBC_SEC) && $(MAKE) clean + @rm -rf vtzb_proxy diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.c b/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.c new file mode 100644 index 0000000..5b10989 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include "thread_pool.h" + +// 初始化线程池 +void thread_pool_init(ThreadPool* pool) +{ + pool->task_count = 0; + pool->front = pool->rear = 0; + pool->destroying = 0; + pthread_mutex_init(&pool->mutex, NULL); + pthread_cond_init(&pool->cond, NULL); + + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + pthread_create(&pool->threads[i], NULL, thread_func, pool); + } +} + +// 线程函数 +void* thread_func(void* arg) +{ + ThreadPool* pool = (ThreadPool*)arg; + + while (1) { + pthread_mutex_lock(&pool->mutex); + + // 等待任务队列非空 + while (pool->task_count == 0 && !pool->destroying) { + pthread_cond_wait(&pool->cond, &pool->mutex); + } + + // 如果正在销毁线程池,则退出线程 + if (pool->destroying) { + pthread_mutex_unlock(&pool->mutex); + break; + } + + // 取出任务并执行 + Task task = pool->task_queue[pool->front]; + pool->front = (pool->front + 1) % TASK_QUEUE_SIZE; + pool->task_count--; + pthread_mutex_unlock(&pool->mutex); + + task.task_func(task.arg); + } + + return NULL; +} + +// 提交任务到线程池 +void thread_pool_submit(ThreadPool* pool, void* (*task_func)(void*), void* arg) +{ + pthread_mutex_lock(&pool->mutex); + + // 等待任务队列非满 + while (pool->task_count == TASK_QUEUE_SIZE && !pool->destroying) { + pthread_cond_wait(&pool->cond, &pool->mutex); + } + + // 如果正在销毁线程池,则不再接收新任务 + if (pool->destroying) { + pthread_mutex_unlock(&pool->mutex); + return; + } + + // 添加任务到队列 + pool->task_queue[pool->rear].task_func = task_func; + pool->task_queue[pool->rear].arg = arg; + pool->rear = (pool->rear + 1) % TASK_QUEUE_SIZE; + pool->task_count++; + // 通知等待中的线程有新任务 + pthread_cond_signal(&pool->cond); + + pthread_mutex_unlock(&pool->mutex); +} + +// 销毁线程池 +void thread_pool_destroy(ThreadPool* pool) +{ + // 停止接收新的任务 + pthread_mutex_lock(&pool->mutex); + pool->destroying = 1; // 设置标志,表示正在销毁线程池 + pthread_mutex_unlock(&pool->mutex); + + // 通知所有等待中的线程有新任务(用于唤醒正在等待任务的线程,让它们检查销毁标志) + pthread_cond_broadcast(&pool->cond); + + // 等待所有线程执行完成 + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + pthread_join(pool->threads[i], NULL); + } + + // 销毁互斥锁和条件变量 + pthread_mutex_destroy(&pool->mutex); + pthread_cond_destroy(&pool->cond); +} + diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.h new file mode 100644 index 0000000..96ed32f --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/thread_pool.h @@ -0,0 +1,33 @@ +#ifndef __THREAD_POLL_H__ +#define __THREAD_POLL_H__ + +#include +#include +#include + +#define THREAD_POOL_SIZE 5 +#define TASK_QUEUE_SIZE 10 + +// 定义任务结构 +typedef struct { + void* (*task_func)(void*); // 任务函数指针 + void* arg; // 任务参数 +} Task; + +// 定义线程池结构 +typedef struct { + pthread_t threads[THREAD_POOL_SIZE]; // 线程数组 + Task task_queue[TASK_QUEUE_SIZE]; // 任务队列 + int task_count; // 任务队列中任务数量 + int front; // 队列头索引 + int rear; // 队列尾索引 + int destroying; // 销毁标志 + pthread_mutex_t mutex; // 互斥锁 + pthread_cond_t cond; // 条件变量 +} ThreadPool; + +void thread_pool_init(ThreadPool* pool); +void thread_pool_destroy(ThreadPool* pool); +void* thread_func(void* arg); +void thread_pool_submit(ThreadPool* pool, void* (*task_func)(void*), void* arg); +#endif diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.c b/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.c new file mode 100644 index 0000000..2521d4c --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.c @@ -0,0 +1,92 @@ +#include "virt.h" + +// static int safepoll(struct pollfd *fds, nfds_t nfds, int timeout) +int safepoll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + int ret; + + do { + // debug("Debug %s %s %d \n", __FILE__, __FUNCTION__, __LINE__); + ret = poll(fds, nfds, timeout); + // debug("Debug %s %s %d \n", __FILE__, __FUNCTION__, __LINE__); + // debug(" poll ret = %d, errno = %d \n", ret, errno); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) + ret = -errno; + + return ret; +} + +ssize_t safewrite(int fd, const void *buf, size_t count, bool eagain_ret) +{ + ssize_t ret; + size_t len; + int flags; + bool nonblock; + + nonblock = false; + flags = fcntl(fd, F_GETFL); + if (flags > 0 && flags & O_NONBLOCK) + nonblock = true; + + len = count; + while (len > 0) { + ret = write(fd, buf, len); + if (ret == -1) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN) { + if (nonblock && eagain_ret) { + return -EAGAIN; + } else { + continue; + } + } + return -errno; + } else if (ret == 0) { + break; + } else { + buf += ret; + len -= ret; + } + } + return count - len; +} + +ssize_t saferead(int fd, void *buf, size_t count, bool eagain_ret) +{ + size_t ret, len; + int flags; + bool nonblock; + + nonblock = false; + flags = fcntl(fd, F_GETFL); + if (flags > 0 && flags & O_NONBLOCK) + nonblock = true; + + len = count; + while (len > 0) { + ret = read(fd, buf, len); + if ((int)ret == -1) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN) { + if (nonblock && eagain_ret) { + return -EAGAIN; + } else { + continue; + } + } + return -errno; + } else if (ret == 0) { + break; + } else { + buf += ret; + len -= ret; + } + } + return count - len; +} diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.h new file mode 100644 index 0000000..8591385 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/virt.h @@ -0,0 +1,20 @@ +#ifndef VTZB_VIRT_H +#define VTZB_VIRT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int safepoll(struct pollfd *fds, nfds_t nfds, int timeout); +ssize_t safewrite(int fd, const void *buf, size_t count, bool eagain_ret); +ssize_t saferead(int fd, void *buf, size_t count, bool eagain_ret); + +#endif // VTZB_VIRT_H diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.c b/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.c new file mode 100644 index 0000000..cefedad --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.c @@ -0,0 +1,950 @@ +/* + */ + +#include "vtzb_proxy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for mmap */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "tc_ns_client.h" +#include "tee_client_list.h" +#include "virt.h" +#include "thread_pool.h" + +//#define DEBUG 1 +ThreadPool pool; +LIST_DECLARE(g_shrd_mem_list); +pthread_mutex_t g_mutex_shrd_mem = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_mutex_mmap = PTHREAD_MUTEX_INITIALIZER; + +double __get_us(struct timeval t) +{ + return (t.tv_sec * 1000000 + t.tv_usec); +} + +#ifdef DEBUG +void debug(const char* fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +#define PRINTF_SIZE 16 +void dump_buff(const char* buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + printf("--------------------------------------------------\n"); + printf("bufLen = %d\n", (int)bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0 && i != 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} +#else +#define debug(fmt, ...) \ + do { \ + } while (0) + +#define dump_buff(buffer, bufLen) \ + do { \ + } while (0) +#endif + +#define BUF_LENGTH 4080 + +static unsigned int nr_failed; + +int connect_domsock_chardev(char* dev_path, int* sock) +{ + int ret; + ret = socket(AF_UNIX, SOCK_STREAM, 0); + if (ret == -1) { + tloge("execute socket() failed \n"); + return -1; + } + + *sock = ret; + + struct sockaddr_un sock_addr; + sock_addr.sun_family = AF_UNIX; + memcpy_s(&sock_addr.sun_path, sizeof(sock_addr.sun_path), dev_path, + sizeof(sock_addr.sun_path)); + ret = connect(*sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); + if (ret < 0) { + tloge("connect domain socket %s failed \n", dev_path); + } + + return ret; +} + +//////////////////// +// static int g_fsFd = -1; +// static struct SecStorageType *g_fsControl = NULL; +#define TRANS_BUFF_SIZE (4 * 1024) /* agent transfer share buffer size */ +#define AGENT_FS_ID 0x46536673 /* FSfs */ +/* +static int AgentInit(unsigned int id, void **control) +{ + int ret; + struct AgentIoctlArgs args = { 0 }; + + if (control == NULL) { + return -1; + } + int fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR); + if (fd < 0) { + debug("open tee client dev failed, fd is %d\n", fd); + return -1; + } + + // register agent + args.id = id; + args.bufferSize = TRANS_BUFF_SIZE; + ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_REGISTER_AGENT, &args); + if (ret) { + (void)close(fd); + debug(" TC_NS_CLIENT_IOCTL_REGISTER_AGENT failed\n"); + return -1; + } + + *control = args.buffer; + return fd; +} + +static int ProcessAgentInit() +{ + int ret = 0; + g_fsFd = AgentInit(AGENT_FS_ID, (void **)(&g_fsControl)); + if (g_fsFd < 0) { + debug("fs agent init failed\n"); + ret = -1; + } else { + //debug("<------------------ \n"); + //debug("before TC_NS_CLIENT_IOCTL__EVENT\n"); + //ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_WAIT_EVENT, +AGENT_FS_ID); + //ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, +AGENT_FS_ID); + //debug("after TC_NS_CLIENT_IOCTL__EVENT, ret = %d\n", ret); + //debug("------------------> \n"); + } + return ret; +} + + +void* fs_test(){ + //(void)ProcessAgentInit(); + int ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_WAIT_EVENT, +AGENT_FS_ID); debug("after wait ret = %d\n", ret); ret = ioctl(g_fsFd, +(int32_t)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, AGENT_FS_ID); debug("after rsp +ret = %d\n",ret); return NULL; +} +*/ + +/* +void* serial_test() { + uint8_t ui8p_rd_buf[512]; + struct pollfd pollfd[1]; + char g_teeVersion[256U]; + int i = 1000; + // int data = 1000; + int sock; + int ret = connect_domsock_chardev("/tmp/vm03_vtzb_sock1", &sock); + if (ret <0 ){ + debug("open socket failed! \n"); + return NULL; + } + + pollfd[0].fd = sock; + pollfd[0].events = POLLIN; + while(i--){ + + // ret = write(sock, &data, sizeof(int)); + // debug(" write to VM ,data = %d", data); + // data++; + // debug(" before poll \n"); + + ret = safepoll(pollfd, 1, -1); + //debug(" after poll \n"); + if (ret == -1) { + debug("pollfd failed, ret = %d \n", ret); + return NULL; + } + if (ret == 0) { + debug("pollfd timeout \n"); + continue; + } + if (pollfd[0].revents & POLLIN) { + ret = read(pollfd[0].fd, ui8p_rd_buf, 512); + if (*((uint32_t*)ui8p_rd_buf) == VTZF_TLOG_GET_VER) { + int fd = open("/dev/teelog", O_RDONLY); + if (fd < 0) { + tloge("open log device error\n"); + return NULL; + } + + tlogd("open dev success Fd=%d\n", fd); + ret = ioctl(fd, TEELOGGER_GET_VERSION, g_teeVersion); + if (ret != 0) { + tloge("get tee verison failed %d\n", ret); + } + g_teeVersion[255] = 0; + debug("tlog fd = %d \n",fd); + debug(" tver = %s \n ", g_teeVersion); + struct_vtzf_packet_rsp_tlog args_rsp; + args_rsp.fd = fd; + args_rsp.ret = ret; + args_rsp.rsp = VTZF_TLOG_GET_VER + 1; + strcpy(args_rsp.teeVersion, g_teeVersion); + ret = write(sock, &args_rsp, sizeof(args_rsp)); + } + } + } + + return NULL; +} +*/ + +int g_rsp = 250; +int rsp2 = 315; + +void serial_testA(void* argp) { + struct_testA* sa = (struct_testA*)argp; + struct_vtzb_packet_cmd_test* vtzbp_cmd_test = sa->vtzbp_cmd; + struct_vtzb_packet_rsp_test packet_rsp1; + sleep(2); + packet_rsp1.ret = g_rsp++; + packet_rsp1.rsp = vtzbp_cmd_test->seq_num + 1; + debug(" packet_rsp1.rsp = %d , packet_rsp1.ret =%d \n", packet_rsp1.rsp, + packet_rsp1.ret); + int ret = write(sa->fd, &packet_rsp1, sizeof(struct_vtzb_packet_rsp_test)); + if (ret) { + } + +} + + +struct serial_port_list g_serial_list; +struct pollfd g_pollfd[SERIAL_PORT_NUM]; +int g_pollfd_len = 0; + +void serial_port_list_destroy() +{ + struct serial_port_file *serial_port = NULL; + struct serial_port_file *tmp = NULL; + (void)pthread_mutex_lock(&g_serial_list.lock); + LIST_FOR_EACH_ENTRY_SAFE(serial_port, tmp, &g_serial_list.head, head) { + if (serial_port->rd_buf) { + free(serial_port->rd_buf); + serial_port->rd_buf = NULL; + } + if (serial_port->opened) { + close(serial_port->sock); + } + ListRemoveEntry(&serial_port->head); + free(serial_port); + } + + (void)pthread_mutex_unlock(&g_serial_list.lock); +} + +static int serial_port_list_init() +{ + int i; + struct serial_port_file *serial_port; +// g_serial_list.lock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&g_serial_list.lock, NULL); + ListInit(&g_serial_list.head); + for ( i = 0; i < SERIAL_PORT_NUM; i++) + { + serial_port = (struct serial_port_file *)malloc(sizeof(struct serial_port_file)); + memset_s(serial_port, sizeof(struct serial_port_file), 0, sizeof(struct serial_port_file)); + sprintf(serial_port->path, "%s%d", VTZB_CHAR_DEV, i); + debug("path = %s \n", serial_port->path); + serial_port->opened = false; + serial_port->rd_buf = (char *)malloc(BUF_LEN_MAX_RD); + if (!serial_port->rd_buf) { + tloge("Failed to allocate memory for rd_buf\n"); + free(serial_port); + goto ERR; + } + ListInsertTail(&g_serial_list.head, &serial_port->head); + } + + return 0; +ERR: + serial_port_list_destroy(); + return -ENOMEM; +} + +void check_stat_serial_port() +{ + int ret; + struct serial_port_file *serial_port; + (void)pthread_mutex_lock(&g_serial_list.lock); + LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){ + if (serial_port->opened == false) { + ret = access(serial_port->path, R_OK | W_OK); + if (ret == 0) { + ret = connect_domsock_chardev(serial_port->path, &(serial_port->sock)); + if (ret < 0) { + debug("connect_domsock_chardev(%s) failed, ret = %d \n", serial_port->path, ret); + } else { + debug("open new socket \n"); + printf("open new socket \n"); + serial_port->opened = true; + g_pollfd[g_pollfd_len].fd = serial_port->sock; + g_pollfd[g_pollfd_len].events = POLLIN; + serial_port->index = g_pollfd_len; + g_pollfd_len++; + } + } else{ + debug(" can't access \n"); + printf(" can't access \n"); + } + } else { + ret = access(serial_port->path, R_OK | W_OK); + if (ret) { + debug(" disconnetc socket \n"); + printf(" disconnetc socket \n"); + close(serial_port->sock); + g_pollfd[serial_port->index] = g_pollfd[g_pollfd_len - 1]; + g_pollfd_len--; + serial_port->opened = false; + } + } + } + (void)pthread_mutex_unlock(&g_serial_list.lock); +} + +void *get_rd_buf(int serial_port_fd) +{ + struct serial_port_file *serial_port; + LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){ + if (serial_port->sock == serial_port_fd) { + return serial_port->rd_buf; + } + } + return NULL; +} + +void *get_serial_port_file(int serial_port_fd) +{ + struct serial_port_file *serial_port; + LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){ + if (serial_port->sock == serial_port_fd) { + return serial_port; + } + } + return NULL; +} + +static void open_tzdriver(struct_packet_cmd_open_tzd *packet_cmd, int serial_port_fd) +{ + debug("*****cmd is open_tzdriver*****\n"); + int fd = -1; + int ret; + struct_packet_rsp_open_tzd packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + + debug("packet_cmd->flag =%d \n",packet_cmd->flag); + + if (packet_cmd->flag == TC_NS_CLIENT_DEV_FLAG) { + fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR); + + } else if(packet_cmd->flag == TC_PRIVATE_DEV_FLAG) { + fd = open(TC_TEECD_PRIVATE_DEV_NAME, O_RDWR); + } + packet_rsp.ptzfd = fd; + if (fd < 0) { + tloge("open tee client dev failed, fd is %d\n", fd); + packet_rsp.ret = fd; + goto END; + } + packet_rsp.ret = 0; + debug(" ptzfd = %d \n", packet_rsp.ptzfd); + debug(" qemu_pid|vmid = %d \n", packet_cmd->vmid); + + ret = ioctl(fd, TC_NS_CLIENT_IOCTL_SET_VM_FLAG, packet_cmd->vmid); + + if (ret) { + debug("set VM flag failed, ret = %d\n", ret); + } +END: + if(serial_port_fd == 999){ + return ; + } + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void close_tzdriver(struct_packet_cmd_close_tzd *packet_cmd, int serial_port_fd) +{ + debug("*****cmd is close TZdriver***** \n"); + struct_packet_rsp_close_tzd packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.ret = 0; + + if (write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)) != sizeof(packet_rsp)) { + tloge("close ptzfd send to VM failed \n"); + } +/* 应建立一个链表,qemu_pid 与 ptzfd相对应,防止冒充关闭ptzfd*/ + if (packet_cmd->ptzfd > 2){ + /*释放内存资源*/ + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + close(packet_cmd->ptzfd); + + } + + +} + +static void log_in_NonHidl(struct_packet_cmd_login_non *packet_cmd, int serial_port_fd) +{ + debug("*****cmd is log_in_nonhidl \n"); + int ret; + struct_packet_rsp_login packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOGIN, NULL); + packet_rsp.ret = ret; + + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void log_in(struct_packet_cmd_login *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_login packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOGIN, packet_cmd->cert_buffer); + packet_rsp.ret = ret; + debug("***** cmd is login ***** \n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void get_tee_ver(struct_packet_cmd_getteever *packet_cmd, int serial_port_fd) +{ + + int ret; + struct_packet_rsp_getteever packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_GET_TEE_VERSION, &packet_rsp.tee_ver); + debug("***** cmd is get ver ***** \n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.ret = ret; + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void get_tee_info(struct_packet_cmd_getteeinfo *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_getteeinfo packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_GET_TEE_INFO, &packet_rsp.info); + debug("***** cmd is get tee info ***** \n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.ret = ret; + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void SyncSysTime(struct_packet_cmd_synctime *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_synctime packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SYC_SYS_TIME, &packet_cmd->tcNsTime); + packet_rsp.ret = ret; + debug("***** cmd is SyncSysTime *****\n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void open_session(struct_packet_cmd_session *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_session packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + debug("***** cmd is open session *****\n"); + debug(" cliContext.login.method = %d\n",packet_cmd->cliContext.login.method); + debug(" cliContext.file_size = %d \n ", packet_cmd->cliContext.file_size); + debug(" cliContext.file_buffer = %p \n ", packet_cmd->cliContext.file_buffer); + + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SES_OPEN_REQ, &packet_cmd->cliContext); + packet_rsp.ret = ret; + packet_rsp.cliContext = packet_cmd->cliContext; + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + debug(" session_id = %d \n",packet_rsp.cliContext.session_id); + + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void close_session(struct_packet_cmd_session *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_general packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ, &packet_cmd->cliContext); + packet_rsp.ret = ret; + debug("***** cmd is close session *****\n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n"); + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static int process_address(struct_packet_cmd_send_cmd *packet_cmd) +{ + int index; + int icount = 0; + int ret = 0; + uint32_t paramTypes[TEEC_PARAM_NUM]; + uint64_t *vm_hvas = (uint64_t *)packet_cmd->cliContext.file_buffer; + + for (index = 0; index < TEEC_PARAM_NUM; index++) { + paramTypes[index] = + TEEC_PARAM_TYPE_GET(packet_cmd->cliContext.paramTypes, index); + if (IS_PARTIAL_MEM(paramTypes[index])) { + void* vm_buffer = (void*)packet_cmd->addrs[index]; + + bool b_found = false; + struct ListNode* ptr = NULL; + pthread_mutex_lock(&g_mutex_shrd_mem); + if (!LIST_EMPTY(&g_shrd_mem_list)) { + LIST_FOR_EACH(ptr, &g_shrd_mem_list) { + struct_shrd_mem* shrd_mem = + CONTAINER_OF(ptr, struct_shrd_mem, node); + if (shrd_mem->vm_buffer == vm_buffer) { + vm_hvas[index] = packet_cmd->cliContext.params[index].memref.buffer + | (uint64_t)packet_cmd->cliContext.params[index].memref.buffer_h_addr << H_OFFSET; + /* 切换为host上的用户地址 */ + packet_cmd->cliContext.params[index].memref.buffer = + (unsigned int)(uintptr_t)shrd_mem->buffer; + packet_cmd->cliContext.params[index].memref.buffer_h_addr = + ((unsigned long long)(uintptr_t)shrd_mem->buffer) >> H_OFFSET; + icount++; + b_found = true; + break; + } + } + } + pthread_mutex_unlock(&g_mutex_shrd_mem); + if (b_found == false) { + tloge("can't find mmap buffer \n"); + debug("can't find mmap buffer \n"); + ret = -1; + return ret; + } + } + } + if (icount ==0) { + packet_cmd->cliContext.file_buffer = NULL; + } + return ret; +} + +static void send_cmd(struct_packet_cmd_send_cmd *packet_cmd, int serial_port_fd) +{ + //debug("***** cmd is invoke cmd *****\n"); + int ret = -1; + struct timeval start, end; + uint32_t cost = 0; + struct_packet_rsp_send_cmd packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + void *vm_hvas = (void *)malloc(sizeof(void *)*TEEC_PARAM_NUM); + packet_cmd->cliContext.file_buffer = vm_hvas; + packet_cmd->cliContext.file_size = sizeof(void *)*TEEC_PARAM_NUM; + /* mmap */ + gettimeofday(&start, NULL); + if (!process_address(packet_cmd)) { + debug(" process addrs success \n"); + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_CMD_REQ, &packet_cmd->cliContext); + } + gettimeofday(&end, NULL); + cost = (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + (void)cost; + //printf("invoke cmd cost : %f us\n", cost * 1.0); + free(vm_hvas); + packet_rsp.ret = ret; + packet_rsp.cliContext = packet_cmd->cliContext; + //debug(" ptzfd = %d \n", packet_cmd->ptzfd); + //debug(" ret = %d \n", ret); + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void reg_agent(struct_packet_cmd_regagent *packet_cmd, int serial_port_fd) +{ + debug("***** cmd is reg_agent *****\n"); + int ret; + struct_packet_rsp_regagent packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_REGISTER_AGENT, &packet_cmd->args); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.ret = ret; + packet_rsp.args = packet_cmd->args; + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void wait_event(struct_packet_cmd_event *packet_cmd, int serial_port_fd) +{ + debug("***** cmd is wait event *****\n"); + int ret; + struct_packet_rsp_general packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_WAIT_EVENT, packet_cmd->agent_id); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.ret = ret; + + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void sent_event_response(struct_packet_cmd_event *packet_cmd, int serial_port_fd) +{ + debug("***** cmd is sent_event_response *****\n"); + int ret; + struct_packet_rsp_general packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, packet_cmd->agent_id); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.ret = ret; + + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + + +static void vtz_dommap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd) +{ + int ret = 0; + struct_packet_rsp_mmap packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + + void *buffer = mmap(0, (unsigned long)packet_cmd->size, (PROT_READ | PROT_WRITE), MAP_SHARED, + packet_cmd->ptzfd, (long)(packet_cmd->offset * (uint32_t)PAGE_SIZE)); + //printf("mmap buffer = %p \n", buffer); + if (buffer == MAP_FAILED) { + tloge("mmap failed\n"); + debug("mmap failed \n"); + ret = -ENOMEM; + } + + debug(" mmap ret = %d \n", ret); + packet_rsp.ret = ret; + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } + debug("vm_buffer = %p\n", packet_cmd->buffer); + struct_shrd_mem* tmp = (struct_shrd_mem*)malloc(sizeof(struct_shrd_mem)); + ListInit(&tmp->node); + tmp->buffer = buffer; + tmp->vm_buffer = (void*)packet_cmd->buffer; + tmp->buffer_size = (size_t)packet_cmd->size; + tmp->dev_fd = packet_cmd->ptzfd; + + pthread_mutex_lock(&g_mutex_shrd_mem); + ListInsertTail(&g_shrd_mem_list, &tmp->node); + pthread_mutex_unlock(&g_mutex_shrd_mem); + +} + +static void vtz_dounmmap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd) +{ + int ret = 0; + struct_packet_rsp_mmap packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + + void* buffer = NULL; + uint32_t buffer_size; + struct ListNode* ptr = NULL; + struct ListNode* n = NULL; + + packet_rsp.ret = ret; + ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } + pthread_mutex_lock(&g_mutex_shrd_mem); + if (!LIST_EMPTY(&g_shrd_mem_list)) { + LIST_FOR_EACH_SAFE(ptr, n, &g_shrd_mem_list) { + struct_shrd_mem* shrd_mem = + CONTAINER_OF(ptr, struct_shrd_mem, node); + if (shrd_mem->vm_buffer == (void*)packet_cmd->buffer) { + ListRemoveEntry(&(shrd_mem->node)); + buffer = shrd_mem->buffer; + buffer_size = shrd_mem->buffer_size; + free(shrd_mem); + } + } + } + pthread_mutex_unlock(&g_mutex_shrd_mem); + if (buffer != NULL) { + debug(" munmap buffer = %p \n", buffer); + ret = munmap(buffer, (size_t)buffer_size); + if (ret) { + tloge("Release SharedMemory failed, munmap error\n"); + debug("Release SharedMemory failed, munmap error\n"); + } + } +} + +static void vtz_mmap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd) +{ + debug("*****cmd is mmap*****\n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + if (packet_cmd->cmd == VTZB_MMAP) { + vtz_dommap(packet_cmd, serial_port_fd); + } else { + vtz_dounmmap(packet_cmd, serial_port_fd); + } + +} + +void *thread_entry(void *args) +{ + uint32_t ui32_cmd; + int serial_port_fd = (int)((uint64_t)args); + struct serial_port_file *serial_port = get_serial_port_file(serial_port_fd); + char* rd_buf = serial_port->rd_buf; + int buf_size = serial_port->buf_size; + + if (buf_size >= 4) { + ui32_cmd = *(uint32_t*)rd_buf; + } else { + return NULL; + } + + ui32_cmd = *(uint32_t*)rd_buf; + debug("received message packet from guest: \n"); + debug(" cmd = %d, 0x%8.8x \n", ui32_cmd, ui32_cmd); + + switch (ui32_cmd) + { + case VTZB_OPEN_TZD: + debug("before \n"); + if (buf_size >= (int)sizeof(struct_packet_cmd_open_tzd)) { + debug("before open tz \n"); + (void)open_tzdriver((struct_packet_cmd_open_tzd *)rd_buf, serial_port_fd); + } + break; + case VTZB_CLOSE_TZD: + if (buf_size >= (int)sizeof(struct_packet_cmd_close_tzd)) { + (void)close_tzdriver((struct_packet_cmd_close_tzd *)rd_buf, serial_port_fd); + } + break; + case VTZB_LOG_IN_NHIDL: + if (buf_size >= (int)sizeof(struct_packet_cmd_login_non)) { + (void)log_in_NonHidl((struct_packet_cmd_login_non *)rd_buf, serial_port_fd); + } + break; + case VTZB_GET_TEE_VERSION: + if (buf_size >= (int)sizeof(struct_packet_cmd_getteever)) { + (void)get_tee_ver((struct_packet_cmd_getteever *)rd_buf, serial_port_fd); + } + break; + case VTZB_GET_TEE_INFO: + if (buf_size >= (int)sizeof(struct_packet_cmd_getteeinfo)) { + (void)get_tee_info((struct_packet_cmd_getteeinfo *)rd_buf, serial_port_fd); + } + break; + case VTZB_LATE_INIT: + break; + case VTZB_SYNC_TIME: + if (buf_size >= (int)sizeof(struct_packet_cmd_synctime)) { + (void)SyncSysTime((struct_packet_cmd_synctime *)rd_buf, serial_port_fd); + } + break; + case VTZB_LOG_IN: + if (buf_size >= (int)sizeof(struct_packet_cmd_login)) { + (void)log_in((struct_packet_cmd_login *)rd_buf, serial_port_fd); + } + break; + case VTZB_OPEN_SESSION: + if (buf_size >= (int)sizeof(struct_packet_cmd_session)) { + (void)open_session((struct_packet_cmd_session *)rd_buf, serial_port_fd); + } + break; + case VTZB_CLOSE_SESSION: + if (buf_size >= (int)sizeof(struct_packet_cmd_session)) { + (void)close_session((struct_packet_cmd_session *)rd_buf, serial_port_fd); + } + break; + case VTZB_SEND_CMD: + if (buf_size >= (int)sizeof(struct_packet_cmd_send_cmd)) { + (void)send_cmd((struct_packet_cmd_send_cmd *)rd_buf, serial_port_fd); + } + break; + case VTZB_FS_REGISTER_AGENT: + if (buf_size >= (int)sizeof(struct_packet_cmd_regagent)) { + (void)reg_agent((struct_packet_cmd_regagent *)rd_buf, serial_port_fd); + } + break; + case VTZF_WAIT_EVENT: + if (buf_size >= (int)sizeof(struct_packet_cmd_event)) { + (void)wait_event((struct_packet_cmd_event *)rd_buf, serial_port_fd); + } + break; + case VTZF_SEND_EVENT_RESPONSE: + if (buf_size >= (int)sizeof(struct_packet_cmd_event)) { + (void)sent_event_response((struct_packet_cmd_event *)rd_buf, serial_port_fd); + } + break; + case VTZB_MMAP: + case VTZB_MUNMAP: + if (buf_size >= (int)sizeof(struct_packet_cmd_mmap)) { + (void)vtz_mmap((struct_packet_cmd_mmap *)rd_buf, serial_port_fd); + } + break; + + case 520: + debug(" \n"); + struct_testA ssa; + ssa.fd = serial_port_fd; + ssa.vtzbp_cmd = (struct_vtzb_packet_cmd_test*)rd_buf; + serial_testA(&ssa); + break; + case 618: + debug(" \n"); + struct_vtzb_packet_cmd_test *vtzbp_cmd_test = (struct_vtzb_packet_cmd_test*)rd_buf; + struct_vtzb_packet_rsp_test packet_rsp2; + packet_rsp2.ret = rsp2++; + packet_rsp2.rsp = vtzbp_cmd_test->seq_num + 1; + // sleep(2); + debug(" packet_rsp2.rsp = %d , packet_rsp2.ret =%d \n", + packet_rsp2.rsp, packet_rsp2.ret); + buf_size = write(serial_port_fd, &packet_rsp2, + sizeof(struct_vtzb_packet_rsp_test)); + break; + default: + break; + } + + return NULL; +} + +void ProcessEvent(int fd) +{ + int ret; + //char* rd_buf = (char *)get_rd_buf(fd); + struct serial_port_file *serial_port = get_serial_port_file(fd); + if (!serial_port || !serial_port->rd_buf){ + tloge(" rd_buf is NULL \n"); + return ; + } + ret = read(fd, serial_port->rd_buf, BUF_LEN_MAX_RD); + if (ret < 0) { + tloge("read domain socket failed \n"); + debug("read domain socket failed \n"); + return ; + } + if (ret == 0) { + return ; + } + serial_port->buf_size = ret; + debug("\n received message from guest, len = %d \n", ret); + thread_pool_submit(&pool, thread_entry, (void *)((uint64_t)fd)); +} + +// int main(int argc, const char *argv[]) +int main() { + int ret = 0; + int i; + + thread_pool_init(&pool); + + serial_port_list_init(); + + while (1) { + check_stat_serial_port(); + + ret = safepoll(g_pollfd, g_pollfd_len, -1); + if (ret == -1) { + tloge("pollfd failed, ret = %d \n", ret); + return -1; + } + if (ret == 0) { + tloge("pollfd timeout \n"); + continue; + } + + for (i = 0; i < g_pollfd_len; i++) { + if (g_pollfd[i].revents & POLLIN) { + //pthread_t ntid; + //pthread_create(&ntid, NULL, thread_entry, &g_pollfd[i].fd); + //(void)thread_entry(&g_pollfd[i].fd); + ProcessEvent(g_pollfd[i].fd); + } + } + } + + serial_port_list_destroy(); + return nr_failed; +} + diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.h new file mode 100644 index 0000000..f0faae0 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/vtzb_proxy.h @@ -0,0 +1,461 @@ +#ifndef __VTZB_PROXY_H__ +#define __VTZB_PROXY_H__ + +/* + */ + +#include +#include +#include "tc_ns_client.h" +#include "tee_sys_log.h" +// #include "tee_auth_common.h" +#include "tee_client_list.h" + +//#define DEBUG 1 + +#define VTZB_CHAR_DEV "/tmp/vm_vtzb_sock" +//#define VM_NUM_MAX 2 +#define SERIAL_PORT_NUM 2 +#define UNIX_PATH_MAX 108 +#define H_OFFSET 32 + +#define BUF_MAX_SIZE 2048 +#define BUF_LENGTH 4080 +#define BUF_LEN_MAX_RD 1024 * 8 + +#define TC_NS_CLIENT_DEV_FLAG 3 +#define TC_PRIVATE_DEV_FLAG 4 + +#define VTZB_OPEN_TZD 15 +#define VTZB_CLOSE_TZD 17 +#define VTZB_LOG_IN_NHIDL 19 +#define VTZB_GET_TEE_VERSION 21 +#define VTZB_GET_TEE_INFO 23 +#define VTZB_LATE_INIT 25 +#define VTZB_SYNC_TIME 27 +#define VTZB_LOG_IN 29 +#define VTZB_OPEN_SESSION 31 +#define VTZB_SEND_CMD 33 +#define VTZB_CANCEL_CMD 35 +#define VTZB_MMAP 37 +#define VTZB_MUNMAP 39 +#define VTZB_CLOSE_SESSION 41 +#define VTZB_CLOSE_PTZDEV 43 +#define VTZB_FS_REGISTER_AGENT 45 +#define VTZF_WAIT_EVENT 49 +#define VTZF_SEND_EVENT_RESPONSE 51 +#define VTZB_TEST 47 + +#define VTZB_RSP_UNKOWN 0xfffffffe + +// for tlog +#define TEELOGGERIO 0xBE +#define GET_VERSION_BASE 5 +#define TEELOGGER_GET_VERSION _IOR(TEELOGGERIO, GET_VERSION_BASE, char[256U]) + +#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ + (((paramTypes) >> (4 * (index))) & 0x0F) + +#define IS_PARTIAL_MEM(paramType) \ + (((paramType) == TEEC_MEMREF_WHOLE) || \ + ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \ + ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || \ + ((paramType) == TEEC_MEMREF_PARTIAL_INOUT)) + +#define PAGE_SIZE getpagesize() + +typedef struct { + char path[UNIX_PATH_MAX]; + int sock; +} char_dev; + +typedef struct { + void* vm_buffer; + void* buffer; + uint32_t buffer_size; + int32_t dev_fd; + struct ListNode node; +} struct_shrd_mem; + +struct char_dev_list { + char_dev char_dev_vtzb; + bool opened; + int index; +}; + +typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint16_t clock_seq; + uint16_t node0; + uint16_t node1; + uint16_t node2; +} struct_uuid; + +////////////////////// + +struct serial_port_list { + pthread_mutex_t lock; + struct ListNode head; +}; + +struct serial_port_file { + char path[UNIX_PATH_MAX]; + int sock; + bool opened; + int index; + struct ListNode head; + char *rd_buf; + int buf_size; +}; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_general; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; // second + uint32_t vmid; + uint32_t flag; +} struct_packet_cmd_open_tzd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + int32_t ptzfd; +} struct_packet_rsp_open_tzd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; // second + int32_t ptzfd; +} struct_packet_cmd_close_tzd; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_close_tzd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_getteeinfo; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + TC_NS_TEE_Info info; +} struct_packet_rsp_getteeinfo; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_getteever; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + uint32_t tee_ver; // 4, 12 bytes +} struct_packet_rsp_getteever; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; + TC_NS_Time tcNsTime; +} struct_packet_cmd_synctime; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_synctime; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; + uint8_t cert_buffer[BUF_MAX_SIZE]; +} struct_packet_cmd_login; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_login_non; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_packet_rsp_login; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; // 4, 8 bytes + int32_t cpu_index; // 4, 12 bytes + TC_NS_ClientContext cliContext; +} struct_packet_cmd_session; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + TC_NS_ClientContext cliContext; +} struct_packet_rsp_session; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + int32_t cpu_index; + unsigned long long addrs[TEEC_PARAM_NUM]; + TC_NS_ClientContext cliContext; +} struct_packet_cmd_send_cmd; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + TC_NS_ClientContext cliContext; +} struct_packet_rsp_send_cmd; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + uint64_t buffer; + uint32_t size; + uint32_t offset; +} struct_packet_cmd_mmap; + +typedef struct { + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_mmap; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t seq_num; + int32_t ptzfd; + struct AgentIoctlArgs args; +} struct_packet_cmd_regagent; + +typedef struct { + uint32_t seq_num; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + struct AgentIoctlArgs args; +} struct_packet_rsp_regagent; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + uint32_t agent_id; +} struct_packet_cmd_event; + +////////////////// +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t cmd; // 4, 4 bytes + int32_t seq_num; +} struct_vtzb_packet_cmd_test; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzb_packet_rsp_test; + +typedef struct { + struct_vtzb_packet_cmd_test* vtzbp_cmd; + int fd; +} struct_testA; + +/* +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzb_packet_rsp_general; + +typedef struct { + uint32_t cmd; // 4, 4 bytes +} struct_vtzb_packet_cmd_getteever; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + uint32_t tee_ver; // 4, 12 bytes +} struct_vtzb_packet_rsp_getteever; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t cmd; // 4, 4 bytes + TC_NS_Time tcNsTime; // 8, 12 bytes +} struct_vtzb_packet_cmd_synctime; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzb_packet_rsp_synctime; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t cmd; // 4, 4 bytes + uint32_t cert_buffer_size; // 4, 8 bytes + uint8_t cert_buffer[BUF_MAX_SIZE]; +} struct_vtzb_packet_cmd_login; + +typedef struct { + // struct_uuid vm_uuid; + // uint64_t qemu_process_id; + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + int32_t fd; +} struct_vtzb_packet_rsp_login; + + + +typedef struct { + uint32_t cmd; // 4, 4 bytes + int32_t ptzfd; // 4, 8 bytes + int cpu_index; // 4, 12 bytes + TC_NS_ClientContext cliContext; + pid_t pid; +} struct_vtzb_packet_cmd_session; + +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + TC_NS_ClientContext cliContext; +} struct_vtzb_packet_rsp_session; + +typedef struct { + pid_t pid; + unsigned long long buffers[TEEC_PARAM_NUM]; + TC_NS_ClientContext cliContext; +} struct_clicontext_pid; + +typedef struct { + pid_t pid; + unsigned long long buffers[TEEC_PARAM_NUM]; + TC_NS_ClientContext cliContext; +} struct_clicontext_pid_send_cmd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + int32_t ptzfd; // 4, 8 bytes + int cpu_index; // 4, 12 bytes + unsigned long long addrs[TEEC_PARAM_NUM]; + TC_NS_ClientContext cliContext; + pid_t pid; +} struct_vtzb_packet_cmd_send_cmd; + +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + TC_NS_ClientContext cliContext; +} struct_vtzb_packet_rsp_send_cmd; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + int32_t ptzfd; // 4, 8 bytes + uint64_t buffer; + uint32_t size; + uint32_t offset; + pid_t pid; +} struct_vtzb_packet_cmd_mmap; + +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzb_packet_rsp_mmap; + +typedef struct { + uint32_t cmd; // 4, 4 bytes + int32_t ptzfd; // 4, 8 bytes +} struct_vtzb_packet_cmd_closeptz; + +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes +} struct_vtzb_packet_rsp_closeptz; + +typedef struct { + struct_vtzb_packet_cmd_login* vtzbp_cmd_login; + int fd; +} struct_log_in; + +typedef struct { + struct_vtzb_packet_cmd_session* vtzbp_cmd_session; + int fd; +} struct_session; + +typedef struct { + struct_vtzb_packet_cmd_send_cmd* vtzbp_cmd_send_cmd; + int fd; +} struct_send_cmd; + +typedef struct { + struct_vtzb_packet_cmd_mmap* vtzbp_cmd_mmap; + int fd; +} struct_mmap; + +typedef struct { + struct_vtzb_packet_cmd_closeptz* vtzbp_cmd_closeptz; + int fd; +} struct_closeptz; + +// for tlog +typedef struct { + uint32_t cmd; // 4, 4 bytes + uint32_t tmp; +} struct_vtzf_packet_cmd_tlog; + +typedef struct { + uint32_t rsp; // 4, 4 bytes + uint32_t ret; // 4, 8 bytes + int32_t fd; // 4, 12 bytes + char teeVersion[256U]; +} struct_vtzf_packet_rsp_tlog; +*/ + +#ifdef DEBUG +void debug(const char* fmt, ...); +void dump_buff(const char* buffer, size_t bufLen); +#else +#define debug(fmt, ...) \ + do { \ + } while (0) + +#define dump_buff(buffer, bufLen) \ + do { \ + } while (0) +#endif + +double __get_us(struct timeval t); +int connect_domsock_chardev(char* dev_path, int* sock); + +/* +void* vtzb_get_tee_version(void* args); +void* vtzb_sync_time(void* args); +void* vtzb_log_in(void* args); +void* vtzb_opensession(void* args); +void* vtzb_closesession(void* args); +void* vtzb_mmap(void* args); +void* vtzb_munmap(void* args); +void* vtzb_closeptz(void* args); +*/ + +#endif /* __VTZB_PROXY_H__ */ + -- Gitee From aa50b50e811131998fccad2b866cdc2eaf3606a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:58:07 +0000 Subject: [PATCH 08/12] patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../demo/Host/vtzb_proxy/qemu.patch | 779 +++++++++++++++ .../demo/Host/vtzb_proxy/tzdriver.patch | 889 ++++++++++++++++++ 2 files changed, 1668 insertions(+) create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch b/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch new file mode 100644 index 0000000..3a8656b --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch @@ -0,0 +1,779 @@ +diff -Naur '--exclude=.git' qemu/hw/char/tc_ns_client.h qemu_after/hw/char/tc_ns_client.h +--- qemu/hw/char/tc_ns_client.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tc_ns_client.h 2023-08-01 15:09:17.724000000 +0800 +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved. ++ * Licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef _TC_NS_CLIENT_H_ ++#define _TC_NS_CLIENT_H_ ++#include "tee_client_type.h" ++#define TC_DEBUG ++ ++#define INVALID_TYPE 0x00 ++#define TEECD_CONNECT 0x01 ++#ifndef ZERO_SIZE_PTR ++#define ZERO_SIZE_PTR ((void *)16) ++#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) ++#endif ++ ++#define UUID_SIZE 16 ++ ++#define TC_NS_CLIENT_IOC_MAGIC 't' ++#define TC_NS_CLIENT_DEV "tc_ns_client" ++#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" ++#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private" ++#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm" ++ ++enum ConnectCmd { ++ GET_FD, ++ GET_TEEVERSION, ++ SET_SYS_XML, ++ GET_TEECD_VERSION, ++}; ++ ++typedef struct { ++ unsigned int method; ++ unsigned int mdata; ++} TC_NS_ClientLogin; ++ ++typedef union { ++ struct { ++ unsigned long long buffer; ++ unsigned long long offset; ++ unsigned long long size_addr; ++ } memref; ++ struct { ++ unsigned long long a_addr; ++ unsigned long long b_addr; ++ } value; ++} TC_NS_ClientParam; ++ ++typedef struct { ++ unsigned int code; ++ unsigned int origin; ++} TC_NS_ClientReturn; ++ ++typedef struct { ++ unsigned char uuid[UUID_SIZE]; ++ unsigned int session_id; ++ unsigned int cmd_id; ++ TC_NS_ClientReturn returns; ++ TC_NS_ClientLogin login; ++ TC_NS_ClientParam params[TEEC_PARAM_NUM]; ++ unsigned int paramTypes; ++ bool started; ++ unsigned int callingPid; ++ unsigned int file_size; ++ union { ++ char *file_buffer; ++ struct { ++ uint32_t file_addr; ++ uint32_t file_h_addr; ++ } memref; ++ }; ++} TC_NS_ClientContext; ++ ++typedef struct { ++ uint32_t seconds; ++ uint32_t millis; ++} TC_NS_Time; ++ ++typedef struct { ++ uint16_t tzdriver_version_major; ++ uint16_t tzdriver_version_minor; ++ uint32_t reserved[15]; ++} TC_NS_TEE_Info; ++ ++enum SecFileType { ++ LOAD_TA = 0, ++ LOAD_SERVICE, ++ LOAD_LIB, ++ LOAD_DYNAMIC_DRV, ++ LOAD_PATCH, ++ LOAD_TYPE_MAX ++}; ++ ++struct SecFileInfo { ++ enum SecFileType fileType; ++ uint32_t fileSize; ++ int32_t secLoadErr; ++}; ++ ++struct SecLoadIoctlStruct { ++ struct SecFileInfo secFileInfo; ++ TEEC_UUID uuid; ++ union { ++ char *fileBuffer; ++ struct { ++ uint32_t file_addr; ++ uint32_t file_h_addr; ++ } memref; ++ }; ++}__attribute__((packed)); ++ ++struct AgentIoctlArgs { ++ uint32_t id; ++ uint32_t bufferSize; ++ union { ++ void *buffer; ++ unsigned long long addr; ++ }; ++}; ++ ++#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int) ++#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int) ++#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int) ++#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs) ++#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int) ++#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct) ++#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int) ++#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int) ++#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int) ++#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int) ++#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time) ++#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int) ++#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int) ++#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int) ++#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int) ++#ifdef CONFIG_CMS_SIGNATURE ++#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl) ++#endif ++#ifdef CONFIG_TEE_TELEPORT_SUPPORT ++#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs) ++#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs) ++#endif ++#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info) ++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) ++ ++TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation); ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/tee_client_list.h qemu_after/hw/char/tee_client_list.h +--- qemu/hw/char/tee_client_list.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tee_client_list.h 2023-08-01 14:18:18.616000000 +0800 +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved. ++ * iTrustee licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef TEE_CLIENT_LIST_H ++#define TEE_CLIENT_LIST_H ++ ++struct ListNode { ++ struct ListNode *next; /* point to next node */ ++ struct ListNode *prev; /* point to prev node */ ++}; ++ ++#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member)) ++#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member)) ++ ++#define LIST_DECLARE(name) \ ++ struct ListNode name = { \ ++ .next = &name, \ ++ .prev = &name, \ ++ } ++ ++static inline void ListInit(struct ListNode *list) ++{ ++ list->next = list; ++ list->prev = list; ++} ++ ++#define LIST_HEAD(list) ((list)->next) ++#define LIST_TAIL(list) ((list)->prev) ++#define LIST_EMPTY(list) ((list) == (list)->next) ++ ++static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry) ++{ ++ list->next->prev = entry; ++ entry->next = list->next; ++ entry->prev = list; ++ list->next = entry; ++} ++ ++static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry) ++{ ++ entry->next = list; ++ entry->prev = list->prev; ++ list->prev->next = entry; ++ list->prev = entry; ++} ++ ++static inline void ListRemoveEntry(struct ListNode *entry) ++{ ++ entry->prev->next = entry->next; ++ entry->next->prev = entry->prev; ++} ++ ++static inline struct ListNode *ListRemoveHead(struct ListNode *list) ++{ ++ struct ListNode *entry = NULL; ++ if (!LIST_EMPTY(list)) { ++ entry = list->next; ++ ListRemoveEntry(entry); ++ } ++ return entry; ++} ++ ++static inline struct ListNode *ListRemoveTail(struct ListNode *list) ++{ ++ struct ListNode *entry = NULL; ++ if (!LIST_EMPTY(list)) { ++ entry = list->prev; ++ ListRemoveEntry(entry); ++ } ++ return entry; ++} ++ ++#define LIST_ENTRY(ptr, type, member) \ ++ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) ++ ++#define LIST_FOR_EACH(pos, list) \ ++ for (pos = (list)->next; pos != (list); pos = pos->next) ++ ++#define LIST_FOR_EACH_SAFE(pos, n, list) \ ++ for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next) ++ ++#define LIST_FOR_EACH_ENTRY(pos, list, member) \ ++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \ ++ pos = LIST_ENTRY(pos->member.next, typeof(*pos), member)) ++ ++#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \ ++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \ ++ member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member)) ++ ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/tee_client_type.h qemu_after/hw/char/tee_client_type.h +--- qemu/hw/char/tee_client_type.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tee_client_type.h 2023-08-01 14:32:33.296000000 +0800 +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved. ++ * Licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef _TEE_CLIENT_TYPE_H_ ++#define _TEE_CLIENT_TYPE_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include "tee_client_list.h" ++#include "tee_client_constants.h" ++ ++typedef enum TEEC_ReturnCode TEEC_Result; ++ ++typedef struct { ++ uint32_t timeLow; ++ uint16_t timeMid; ++ uint16_t timeHiAndVersion; ++ uint8_t clockSeqAndNode[8]; ++} TEEC_UUID; ++ ++typedef struct { ++ int32_t fd; ++ uint8_t *ta_path; ++ struct ListNode session_list; ++ struct ListNode shrd_mem_list; ++ union { ++ struct { ++ void *buffer; ++ sem_t buffer_barrier; ++ } share_buffer; ++ uint64_t imp; /* for adapt */ ++ }; ++} TEEC_Context; ++ ++typedef struct { ++ uint32_t session_id; ++ TEEC_UUID service_id; ++ uint32_t ops_cnt; ++ union { ++ struct ListNode head; ++ uint64_t imp; /* for adapt */ ++ }; ++ TEEC_Context *context; ++} TEEC_Session; ++ ++typedef struct { ++ void *buffer; ++ uint32_t size; ++ uint32_t flags; /* reference to TEEC_SharedMemCtl */ ++ uint32_t ops_cnt; ++ bool is_allocated; /* identify whether the memory is registered or allocated */ ++ union { ++ struct ListNode head; ++ void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */ ++ }; ++ TEEC_Context *context; ++} TEEC_SharedMemory; ++ ++/* ++ * the corresponding param types are ++ * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT ++ */ ++typedef struct { ++ void *buffer; ++ uint32_t size; ++} TEEC_TempMemoryReference; ++ ++/* ++ * the corresponding param types are ++ * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT ++ * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT ++ */ ++typedef struct { ++ TEEC_SharedMemory *parent; ++ uint32_t size; ++ uint32_t offset; ++} TEEC_RegisteredMemoryReference; ++ ++/* ++ * the corresponding param types are ++ * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT ++ */ ++typedef struct { ++ uint32_t a; ++ uint32_t b; ++} TEEC_Value; ++ ++typedef struct { ++ int ion_share_fd; ++ uint32_t ion_size; ++} TEEC_IonReference; ++ ++typedef union { ++ TEEC_TempMemoryReference tmpref; ++ TEEC_RegisteredMemoryReference memref; ++ TEEC_Value value; ++ TEEC_IonReference ionref; ++} TEEC_Parameter; ++ ++typedef struct { ++ uint32_t event_type; /* Tui event type */ ++ uint32_t value; /* return value, is keycode if tui event is getKeycode */ ++ uint32_t notch; /* notch size of the screen for tui */ ++ uint32_t width; /* width of foldable screen */ ++ uint32_t height; /* height of foldable screen */ ++ uint32_t fold_state; /* state of foldable screen */ ++ uint32_t display_state; /* one state of folded state */ ++ uint32_t phy_width; /* real width of the mobile */ ++ uint32_t phy_height; /* real height of the mobile */ ++} TEEC_TUI_Parameter; ++ ++typedef struct { ++ uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */ ++ uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */ ++ TEEC_Parameter params[TEEC_PARAM_NUM]; ++ TEEC_Session *session; ++ bool cancel_flag; ++} TEEC_Operation; ++ ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/virtio-console.c qemu_after/hw/char/virtio-console.c +--- qemu/hw/char/virtio-console.c 2023-08-01 14:07:32.320000000 +0800 ++++ qemu_after/hw/char/virtio-console.c 2023-08-01 14:18:18.616000000 +0800 +@@ -20,6 +20,14 @@ + #include "qapi/error.h" + #include "qapi/qapi-events-char.h" + ++#include "qom/object.h" ++#include "hw/core/cpu.h" ++#include "sysemu/hw_accel.h" ++#include "monitor/monitor.h" ++#include ++#include ++#include "tc_ns_client.h" ++ + #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport" + #define VIRTIO_CONSOLE(obj) \ + OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT) +@@ -45,6 +53,106 @@ + return FALSE; + } + ++ ++#define DEBUG 1 ++ ++#ifdef DEBUG ++static void debug(const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ vfprintf(stderr, fmt, args); ++ va_end(args); ++} ++ ++#define PRINTF_SIZE 16 ++static void dump_buff(const char *buffer, size_t bufLen) ++{ ++ size_t i; ++ if (buffer == NULL || bufLen == 0) { ++ return; ++ } ++ ++ // printf("\n--------------------------------------------------\n"); ++ printf("--------------------------------------------------\n"); ++ printf("bufLen = %d\n", (int)bufLen); ++ for (i = 0; i < bufLen; i++) { ++ if (i % PRINTF_SIZE == 0 && i != 0) { ++ printf("\n"); ++ } ++ printf("%02x ", *(buffer + i)); ++ } ++ printf("\n--------------------------------------------------\n"); ++ return; ++} ++#else ++#define debug(fmt, ...) do { } while (0) ++ ++#define dump_buff(buffer, bufLen) do { } while (0) ++#endif ++ ++#define VTZF_OPEN_TZD 15 ++#define VTZF_OPEN_SESSION 31 ++#define VTZF_SEND_CMD 33 ++#define VTZF_LOAD_SEC 53 ++ ++#define TEEC_PARAM_NUM 4 /* teec param max number */ ++ ++#define IS_TEMP_MEM(paramType) \ ++ (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \ ++ ((paramType) == TEEC_MEMREF_TEMP_INOUT)) ++ ++#define IS_PARTIAL_MEM(paramType) \ ++ (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \ ++ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT)) ++ ++#define IS_VALUE_MEM(paramType) \ ++ (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT)) ++ ++#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ ++ (((paramTypes) >> (4*(index))) & 0x0F) ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ uint32_t seq_num; // second ++ uint32_t vmid; ++ uint32_t flag; ++} struct_packet_cmd_open_tzd; ++ ++typedef struct { ++ uint32_t cmd; ++ uint32_t seq_num; ++ __s32 ptzfd; ++ __s32 cpu_index; ++ struct SecLoadIoctlStruct ioctlArg; ++} struct_packet_cmd_load_sec; ++ ++typedef struct { ++ uint32_t cmd; ++ uint32_t seq_num; ++ int32_t ptzfd; ++ int32_t cpu_index; ++ TC_NS_ClientContext cliContext; ++} struct_packet_cmd_session; ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ int32_t ptzfd; // 4, 8 bytes ++ int32_t cpu_index; // 4, 12 bytes ++ unsigned long long addrs[TEEC_PARAM_NUM]; ++ TC_NS_ClientContext cliContext; ++} struct_vtzf_packet_cmd_send_cmd; ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ __s32 ptzfd; // 4, 8 bytes ++ uint64_t buffer; // 8, 16 bytes ++ uint32_t size; // 4, 20 bytes ++ uint32_t offset; // 4, 24 bytes ++}struct_vtzf_packet_cmd_mmap; ++ ++ + /* Callback function that's called when the guest sends us data */ + static ssize_t flush_buf(VirtIOSerialPort *port, + const uint8_t *buf, ssize_t len) +@@ -57,7 +165,201 @@ + return len; + } + +- ret = qemu_chr_fe_write(&vcon->chr, buf, len); ++ uint8_t buf01[90 * 1024]; ++ memcpy(buf01, buf, len); ++ ++ debug("\n"); ++ debug("debug, %s, %s, %d \n", __FILE__, __func__, __LINE__); ++ debug(" virtio-console virtserialport name = %s, id = %d \n", port->name, (int)port->id); ++ debug(" have_data flush_buf, buflen = %d \n", len); ++ // dump_buff((char *)buf, len); ++ dump_buff((char *)buf, 0); ++ ++ if ( len >= 4 ) { ++ uint32_t ui32_cmd; ++ ui32_cmd = 0; ++ //struct_vtzf_packet_cmd *vtzf_packet_cmd; ++ ++ uint32_t ui32_tmp; ++ int i; ++ for (i = 0; i < 4; i++) ++ { ++ ui32_tmp = buf[i]; ++ ui32_tmp = ui32_tmp << (i * 8); ++ ui32_cmd = ui32_cmd | ui32_tmp; ++ } ++ ++ switch( ui32_cmd ) ++ { ++ case VTZF_OPEN_TZD: ++ debug(" command is VTZF_OPEN_TZD \n"); ++ if ( len >= sizeof(struct_packet_cmd_open_tzd)) { ++ struct_packet_cmd_open_tzd* vtzf_packet_cmd = (struct_packet_cmd_open_tzd *)buf01; ++ pid_t qemu_pid = getpid(); ++ debug(" qemu_pid = 0x%016lx, %d \n",qemu_pid, qemu_pid); ++ vtzf_packet_cmd->vmid = qemu_pid; ++ } ++ break; ++ case VTZF_LOAD_SEC: ++ debug(" command is VTZF_LOAD_SEC \n"); ++ if (len >= sizeof(struct_packet_cmd_load_sec)) { ++ struct_packet_cmd_load_sec* vtzf_packet_cmd = (struct_packet_cmd_load_sec *)buf01; ++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->ioctlArg.fileBuffer); ++ ++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->ioctlArg.fileBuffer; ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ ptr_hva = gpa2hva(&mr, gpa, &local_err); ++ if (local_err) { ++ debug(" gpa2hva failed \n"); ++ } else { ++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ ++ memory_region_unref(mr); ++ ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->ioctlArg.fileBuffer = (void *)ui64_hva; ++ } ++ } ++ break; ++ case VTZF_OPEN_SESSION: ++ debug(" command is VTZF_OPEN_SESSION \n"); ++ debug("sizeof(struct_packet_cmd_session) =%d \n", sizeof(struct_packet_cmd_session)); ++ debug("sizeof(TC_NS_ClientContext) =%d \n", sizeof(TC_NS_ClientContext)); ++ if ( len >= sizeof(struct_packet_cmd_session) ) { ++ struct_packet_cmd_session* vtzf_packet_cmd = (struct_packet_cmd_session *)buf01; ++ ++ debug(" vtzf_packet_cmd->cliContext.file_size = 0x%08x, %d \n", vtzf_packet_cmd->cliContext.file_size, ++ vtzf_packet_cmd->cliContext.file_size); ++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->cliContext.file_buffer); ++ ++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->cliContext.file_buffer; ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ ptr_hva = gpa2hva(&mr, gpa, &local_err); ++ if (local_err) { ++ debug(" gpa2hva failed \n"); ++ } else { ++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ ++ memory_region_unref(mr); ++ ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.file_buffer = (void *)ui64_hva; ++ } ++ } ++ break; ++ case VTZF_SEND_CMD: ++ debug(" command is VTZF_SEND_CMD \n"); ++ if ( len >= sizeof(struct_vtzf_packet_cmd_send_cmd) ) { ++ struct_vtzf_packet_cmd_send_cmd* vtzf_packet_cmd = (struct_vtzf_packet_cmd_send_cmd *)buf01; ++ ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ uint32_t param_type; ++ bool check_value; ++ hwaddr gpa_param; ++ ++ for (i = 0; i < TEEC_PARAM_NUM; i++) { ++ param_type = TEEC_PARAM_TYPE_GET(vtzf_packet_cmd->cliContext.paramTypes, i); ++ check_value = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); ++ if (IS_TEMP_MEM(param_type)) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.buffer failed \n", i); ++ } else { ++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); ++ } else { ++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; ++ } ++ ++ } else if (IS_PARTIAL_MEM(param_type)) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.buffer failed \n", i); ++ } else { ++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); ++ } else { ++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; ++ } ++ ++ } else if (IS_VALUE_MEM(param_type) || check_value) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.a_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].value.a_addr failed \n", i); ++ } else { ++ debug(" host virtual address of value.a_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].value.a_addr = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.b_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].value.b_addr failed \n", i); ++ } else { ++ debug(" host virtual address of value.b_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].value.b_addr = ui64_hva; ++ } ++ ++ } else { ++ /* if type is none, ignore it */ ++ } ++ }// end for ++ ++ }//end if ++ break; ++ default: ++ debug(" other command \n"); ++ } ++ ++ } // end of if ( len >= 4 ) ++ ++ ret = qemu_chr_fe_write(&vcon->chr, buf01, len); + trace_virtio_console_flush_buf(port->id, len, ret); + + if (ret < len) { +@@ -304,3 +606,4 @@ + } + + type_init(virtconsole_register_types) ++ +diff -Naur '--exclude=.git' qemu/include/monitor/monitor.h qemu_after/include/monitor/monitor.h +--- qemu/include/monitor/monitor.h 2023-08-01 14:07:32.384000000 +0800 ++++ qemu_after/include/monitor/monitor.h 2023-08-01 14:18:18.664000000 +0800 +@@ -4,6 +4,7 @@ + #include "block/block.h" + #include "qapi/qapi-types-misc.h" + #include "qemu/readline.h" ++#include "exec/hwaddr.h" + + extern __thread Monitor *cur_mon; + typedef struct MonitorHMP MonitorHMP; +@@ -36,6 +37,8 @@ + int monitor_set_cpu(int cpu_index); + int monitor_get_cpu_index(void); + ++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp); ++ + void monitor_read_command(MonitorHMP *mon, int show_prompt); + int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func, + void *opaque); +@@ -49,3 +52,4 @@ + int64_t monitor_fdset_dup_fd_find(int dup_fd); + + #endif /* MONITOR_H */ ++ +diff -Naur '--exclude=.git' qemu/monitor/misc.c qemu_after/monitor/misc.c +--- qemu/monitor/misc.c 2023-08-01 14:07:32.404000000 +0800 ++++ qemu_after/monitor/misc.c 2023-08-01 14:18:18.684000000 +0800 +@@ -674,7 +674,7 @@ + memory_dump(mon, count, format, size, addr, 1); + } + +-static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) ++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) + { + MemoryRegionSection mrs = memory_region_find(get_system_memory(), + addr, 1); diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch b/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch new file mode 100644 index 0000000..7066b16 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch @@ -0,0 +1,889 @@ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.c itrustee_tzdriver_new/core/gp_ops.c +--- itrustee_tzdriver/core/gp_ops.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/gp_ops.c 2023-08-01 13:16:56.800000000 +0800 +@@ -312,6 +312,148 @@ + return 0; + } + ++ ++int read_from_VMclient(void *dest, size_t dest_size, ++ const void __user *src, size_t size, pid_t vm_pid) ++{ ++ struct task_struct *vmp_task; ++ int i_rdlen; ++ int i_index; ++ int ret; ++ ++ if (!dest || !src) { ++ tloge("src or dest is NULL input buffer\n"); ++ return -EINVAL; ++ } ++ ++ if (size > dest_size) { ++ tloge("size is larger than dest_size or size is 0\n"); ++ return -EINVAL; ++ } ++ if (!size) ++ return 0; ++ ++ tlogv("django verbose, execute access_process_vm"); ++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID); ++ if (vmp_task == NULL) { ++ tloge("no task for pid %d \n", vm_pid); ++ return -EFAULT; ++ } ++ tlogv("django verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); ++ ++ i_rdlen = access_process_vm(vmp_task, (unsigned long)(src), dest, size, FOLL_FORCE); ++ if (i_rdlen != size) { ++ tloge("only read %d of %ld bytes by access_process_vm \n", i_rdlen, size); ++ return -EFAULT; ++ } ++ tlogv("django verbose, read %d byes by access_process_vm succeed", ++ i_rdlen); ++ for (i_index = 0; i_index < 32 && i_index < size; i_index ++) { ++ tlogv("django verbose, *(dest + i_index) + %d) = %2.2x", ++ i_index, *((char*)dest + i_index)); ++ } ++ return 0; ++} ++ ++#define PINED_PAGE_NUMBER 1 ++ ++int write_to_VMclient(void __user *dest, size_t dest_size, ++ const void *src, size_t size, pid_t vm_pid) ++{ ++ int ret = 0; ++ ++ struct task_struct *vmp_task; ++ struct pid *pid; ++ struct mm_struct *mm; ++ ++ unsigned long ul_offset; ++ ++ unsigned long user_addr; ++ struct page *ptr_page; ++ struct vm_area_struct *vmap_01; ++ void *kern_addr; ++ ++ tlogv("wcz verbose, start execute vtz_write_to_client \n"); ++ ++ if (!dest || !src) { ++ tloge("src or dest is NULL input buffer\n"); ++ return -EINVAL; ++ } ++ ++ if (size > dest_size) { ++ tloge("size is larger than dest_size\n"); ++ return -EINVAL; ++ } ++ ++ if (!size) ++ return 0; ++ ++ pid = find_get_pid(vm_pid); ++ vmp_task = get_pid_task(pid, PIDTYPE_PID); ++ if (vmp_task == NULL) { ++ tloge("no task for pid %d", vm_pid); ++ return -EFAULT; ++ } ++ tlogv("wcz verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); ++ ++ mm = vmp_task->mm; ++ user_addr = (unsigned long)dest; ++ ++ #if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) ++ ret = get_user_pages_remote(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, ++ &ptr_page, &vmap_01, NULL); ++ #elif (KERNEL_VERSION(4, 4, 197) <= LINUX_VERSION_CODE) ++ ret = get_user_pages_locked(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, &ptr_page, &vmap_01); ++ #else ++ ret = get_user_pages_locked(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, 1, 1, &ptr_page, &vmap_01); ++ #endif ++ if (ret != PINED_PAGE_NUMBER) { ++ tloge("get user pages failed, ret = %d\n", ret); ++ ret = -EFAULT; ++ goto putpid; ++ } ++ ++ ul_offset = user_addr & (PAGE_SIZE - 1); ++ tlogv("django verbose, offset in the physical page for user address 0x%016lx is 0x%016lx \n", user_addr, ul_offset); ++ ++ if (ul_offset >= PAGE_SIZE) { ++ ul_offset = 0; ++ } ++ ++ tlogv("django verbose, ul_offset = %ld, 0x%016lx \n", ul_offset, ul_offset); ++ ++ kern_addr = kmap_atomic(ptr_page); ++ ++ if (!kern_addr) { ++ tloge("failed to kmap page 0x%016lx \n", (unsigned long)ptr_page); ++ ret = -EFAULT; ++ goto putpage; ++ } ++ tlogv("succeed to kmap page 0x%016lx, kern virtual address = 0x%016lx \n", ++ (unsigned long)ptr_page, (unsigned long)kern_addr); ++ ++ ret = memcpy_s(kern_addr + ul_offset, dest_size, src, size); ++ if (ret != EOK) { ++ tloge("vtz_write to client, memcpy_s fail, ret=%d\n", ret); ++ goto kunmappage; ++ } ++ ++kunmappage: ++ kunmap_atomic(kern_addr); ++ ++putpage: ++ set_page_dirty_lock(ptr_page); ++ put_page(ptr_page); ++ ++putpid: ++ put_pid(pid); ++ ++ return ret; ++} ++ + static bool is_input_tempmem(unsigned int param_type) + { + if (param_type == TEEC_MEMREF_TEMP_INPUT || +@@ -321,7 +463,8 @@ + return false; + } + +-static int update_input_data(const union tc_ns_client_param *client_param, ++static int update_input_data(const struct tc_call_params *call_params, ++ const union tc_ns_client_param *client_param, + uint32_t buffer_size, void *temp_buf, + unsigned int param_type, uint8_t kernel_params) + { +@@ -331,11 +474,22 @@ + + buffer_addr = client_param->memref.buffer | + ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(temp_buf, buffer_size, +- (void *)(uintptr_t)buffer_addr, +- buffer_size, kernel_params) != 0) { +- tloge("copy memref buffer failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM\n"); ++ if (read_from_VMclient(temp_buf, buffer_size, ++ (void *)(uintptr_t)buffer_addr, ++ buffer_size, call_params->dev->nsid) != 0) { ++ tloge("copy memref buffer failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (read_from_client(temp_buf, buffer_size, ++ (void *)(uintptr_t)buffer_addr, ++ buffer_size, kernel_params) != 0) { ++ tloge("copy memref buffer failed\n"); ++ return -EFAULT; ++ } + } + return 0; + } +@@ -361,11 +515,22 @@ + client_param = &(call_params->context->params[index]); + size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(&buffer_size, sizeof(buffer_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(uint32_t), kernel_params) != 0) { +- tloge("copy memref.size_addr failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd(" is VM\n "); ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), call_params->dev->nsid) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ } else{ ++ tlogd(" is not VM "); ++ if (read_from_client(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), kernel_params) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } + } + + if (buffer_size > MAX_SHARED_SIZE) { +@@ -393,7 +558,7 @@ + op_params->local_tmpbuf[index].temp_buffer = temp_buf; + op_params->local_tmpbuf[index].size = buffer_size; + +- if (update_input_data(client_param, buffer_size, temp_buf, ++ if (update_input_data(call_params, client_param, buffer_size, temp_buf, + param_type, kernel_params) != 0) + return -EFAULT; + +@@ -405,17 +570,31 @@ + return 0; + } + +-static int check_buffer_for_ref(uint32_t *buffer_size, +- const union tc_ns_client_param *client_param, uint8_t kernel_params) ++static int check_buffer_for_ref(const struct tc_call_params *call_params, ++ uint32_t *buffer_size, const union tc_ns_client_param *client_param, ++ uint8_t kernel_params) + { + uint64_t size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(buffer_size, sizeof(*buffer_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(uint32_t), kernel_params) != 0) { +- tloge("copy memref.size_addr failed\n"); +- return -EFAULT; ++ ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM\n"); ++ if (read_from_VMclient(buffer_size, sizeof(*buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), call_params->dev->nsid) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (read_from_client(buffer_size, sizeof(*buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), kernel_params) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } + } ++ + if (*buffer_size == 0) { + tloge("buffer_size from user is 0\n"); + return -ENOMEM; +@@ -497,7 +676,7 @@ + return -EINVAL; + + client_param = &(call_params->context->params[index]); +- if (check_buffer_for_ref(&buffer_size, client_param, kernel_params) != 0) ++ if (check_buffer_for_ref(call_params, &buffer_size, client_param, kernel_params) != 0) + return -EINVAL; + + op_params->mb_pack->operation.params[index].memref.buffer = 0; +@@ -651,21 +830,42 @@ + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + +- if (read_from_client(&operation->params[index].value.a, +- sizeof(operation->params[index].value.a), +- (void *)(uintptr_t)a_addr, +- sizeof(operation->params[index].value.a), +- kernel_params) != 0) { +- tloge("copy valuea failed\n"); +- return -EFAULT; +- } +- if (read_from_client(&operation->params[index].value.b, +- sizeof(operation->params[index].value.b), +- (void *)(uintptr_t)b_addr, +- sizeof(operation->params[index].value.b), +- kernel_params) != 0) { +- tloge("copy valueb failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM \n"); ++ if (read_from_VMclient(&operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ (void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->nsid) != 0) { ++ tloge("copy valuea failed\n"); ++ return -EFAULT; ++ } ++ if (read_from_VMclient(&operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ (void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->nsid) != 0) { ++ tloge("copy valueb failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM \n"); ++ if (read_from_client(&operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ (void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ kernel_params) != 0) { ++ tloge("copy valuea failed\n"); ++ return -EFAULT; ++ } ++ if (read_from_client(&operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ (void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ kernel_params) != 0) { ++ tloge("copy valueb failed\n"); ++ return -EFAULT; ++ } + } + + /* TEEC_VALUE_INPUT equal to TEE_PARAM_TYPE_VALUE_INPUT */ +@@ -754,12 +954,24 @@ + buffer_addr = client_param->memref.buffer | + ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); + /* Size is updated all the time */ +- if (write_to_client((void *)(uintptr_t)size_addr, +- sizeof(buffer_size), +- &buffer_size, sizeof(buffer_size), +- call_params->dev->kernel_api) != 0) { +- tloge("copy tempbuf size failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM\n"); ++ if (write_to_VMclient((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->nsid) != 0) { ++ tloge("copy tempbuf size failed\n"); ++ return -EFAULT; ++ } ++ }else{ ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy tempbuf size failed\n"); ++ return -EFAULT; ++ } + } + if (buffer_size > op_params->local_tmpbuf[index].size) { + /* incomplete case, when the buffer size is invalid see next param */ +@@ -775,13 +987,26 @@ + if (buffer_size == 0) + return 0; + /* Only update the buffer when the buffer size is valid in complete case */ +- if (write_to_client((void *)(uintptr_t)buffer_addr, +- operation->params[index].memref.size, +- op_params->local_tmpbuf[index].temp_buffer, +- operation->params[index].memref.size, +- call_params->dev->kernel_api) != 0) { +- tloge("copy tempbuf failed\n"); +- return -ENOMEM; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM\n"); ++ if (write_to_VMclient((void *)(uintptr_t)buffer_addr, ++ operation->params[index].memref.size, ++ op_params->local_tmpbuf[index].temp_buffer, ++ operation->params[index].memref.size, ++ call_params->dev->nsid) != 0) { ++ tloge("copy tempbuf failed\n"); ++ return -ENOMEM; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)buffer_addr, ++ operation->params[index].memref.size, ++ op_params->local_tmpbuf[index].temp_buffer, ++ operation->params[index].memref.size, ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy tempbuf failed\n"); ++ return -ENOMEM; ++ } + } + return 0; + } +@@ -806,22 +1031,38 @@ + size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); + +- if (read_from_client(&orig_size, +- sizeof(orig_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(orig_size), call_params->dev->kernel_api) != 0) { +- tloge("copy orig memref.size_addr failed\n"); +- return -EFAULT; +- } ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ if (read_from_VMclient(&orig_size, sizeof(orig_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(orig_size), call_params->dev->nsid) != 0) { ++ tloge("copy orig memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ ++ if (write_to_VMclient((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->nsid) != 0) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ if (read_from_client(&orig_size, ++ sizeof(orig_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(orig_size), call_params->dev->kernel_api) != 0) { ++ tloge("copy orig memref.size_addr failed\n"); ++ return -EFAULT; ++ } + +- if (write_to_client((void *)(uintptr_t)size_addr, +- sizeof(buffer_size), +- &buffer_size, sizeof(buffer_size), +- call_params->dev->kernel_api) != 0) { +- tloge("copy buf size failed\n"); +- return -EFAULT; ++ if (write_to_client((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } + } +- + /* reserved memory no need to copy */ + if (operation->sharemem[index]->mem_type == RESERVED_TYPE) + return 0; +@@ -859,21 +1100,42 @@ + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + +- if (write_to_client((void *)(uintptr_t)a_addr, +- sizeof(operation->params[index].value.a), +- &operation->params[index].value.a, +- sizeof(operation->params[index].value.a), +- call_params->dev->kernel_api) != 0) { +- tloge("inc copy value.a_addr failed\n"); +- return -EFAULT; +- } +- if (write_to_client((void *)(uintptr_t)b_addr, +- sizeof(operation->params[index].value.b), +- &operation->params[index].value.b, +- sizeof(operation->params[index].value.b), +- call_params->dev->kernel_api) != 0) { +- tloge("inc copy value.b_addr failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM \n"); ++ if (write_to_VMclient((void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ &operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->nsid) != 0) { ++ tloge("inc copy value.a_addr failed\n"); ++ return -EFAULT; ++ } ++ if (write_to_VMclient((void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ &operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->nsid) != 0) { ++ tloge("inc copy value.b_addr failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ &operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->kernel_api) != 0) { ++ tloge("inc copy value.a_addr failed\n"); ++ return -EFAULT; ++ } ++ if (write_to_client((void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ &operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->kernel_api) != 0) { ++ tloge("inc copy value.b_addr failed\n"); ++ return -EFAULT; ++ } + } + return 0; + } +@@ -1248,3 +1510,5 @@ + release_tc_call_resource(call_params, &op_params, tee_ret); + return ret; + } ++ ++ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.h itrustee_tzdriver_new/core/gp_ops.h +--- itrustee_tzdriver/core/gp_ops.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/gp_ops.h 2023-08-01 13:16:56.848000000 +0800 +@@ -30,5 +30,9 @@ + bool is_tmp_mem(uint32_t param_type); + bool is_ref_mem(uint32_t param_type); + bool is_val_param(uint32_t param_type); ++int write_to_VMclient(void __user *dest, size_t dest_size, ++ const void *src, size_t size, pid_t vm_pid); ++int read_from_VMclient(void *dest, size_t dest_size, ++ const void __user *src, size_t size, pid_t vm_pid); + + #endif +diff -Naur '--exclude=.git' itrustee_tzdriver/core/session_manager.c itrustee_tzdriver_new/core/session_manager.c +--- itrustee_tzdriver/core/session_manager.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/session_manager.c 2023-08-01 13:16:56.748000000 +0800 +@@ -792,16 +792,30 @@ + if (memcpy_s(params->mb_load_mem + sizeof(load_flag), + params->mb_load_size - sizeof(load_flag), + params->file_buffer + loaded_size, load_size) != 0) { +- tloge("memcpy file buf get fail\n"); ++ tloge("memcpy file buf get failed \n"); + return -EFAULT; + } + return 0; + } +- if (copy_from_user(params->mb_load_mem + sizeof(load_flag), +- (const void __user *)params->file_buffer + loaded_size, load_size)) { +- tloge("file buf get fail\n"); +- return -EFAULT; ++ ++ if (params->dev_file->isVM) { ++ tlogd("is VM \n"); ++ if (read_from_VMclient(params->mb_load_mem + sizeof(load_flag), ++ load_size, (const void __user *)params->file_buffer + loaded_size, ++ load_size, (pid_t)params->dev_file->nsid)) { ++ tloge("file buf get failed \n"); ++ tlogd("file buf get failed \n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM \n"); ++ if (copy_from_user(params->mb_load_mem + sizeof(load_flag), ++ (const void __user *)params->file_buffer + loaded_size, load_size)) { ++ tloge("file buf get failed \n"); ++ return -EFAULT; ++ } + } ++ + return 0; + } + +@@ -830,10 +844,8 @@ + params->mb_load_size); + return -EINVAL; + } +- + if (load_image_copy_file(params, load_size, load_flag, loaded_size) != 0) + return -EFAULT; +- + pack_load_frame_cmd(load_size, params, &smc_cmd); + params->mb_pack->operation.params[3].value.a = index; + params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type; +@@ -845,8 +857,9 @@ + tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n", + params->mb_pack->operation.params[1].value.a, smc_ret, + load_flag, index); +- ++ tlogd("after tc_ns_smc \n"); + if (smc_ret != 0) { ++ tloge("smc_ret = %d \n",smc_ret); + if (tee_ret != NULL) { + tee_ret->code = smc_ret; + tee_ret->origin = smc_cmd.err_origin; +@@ -857,7 +870,7 @@ + + if (!smc_ret && !load_flag && load_image_for_ion(params, tee_ret ? &tee_ret->origin : NULL)) + return -EPERM; +- ++ tlogd("before return \n"); + loaded_size += load_size; + } + return 0; +@@ -1379,10 +1392,119 @@ + return ret; + } + ++static int process_vm_ref(struct tc_ns_dev_file *dev_file, ++ struct tc_ns_client_context *context, unsigned long long *vm_buffers, ++ unsigned long long *kn_buffers) ++{ ++ struct tc_ns_shared_mem *shared_mem = NULL; ++ int index = 0; ++ uint32_t buffer_size; ++ unsigned int offset = 0; ++ void *buffer_addr = NULL; ++ void *size_addr = NULL; ++ unsigned long long vm_hvas[TEE_PARAM_NUM]={0}; ++ ++ if (!context->file_buffer) { ++ return 0; ++ } ++ ++ if (copy_from_user(vm_hvas, context->file_buffer, context->file_size) != 0) { ++ tloge("copy from user failed\n"); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&dev_file->shared_mem_lock); ++ list_for_each_entry(shared_mem, &dev_file->shared_mem_list, head) { ++ for (index = 0; index < TEE_PARAM_NUM; index++) { ++ buffer_addr = (void *)(uintptr_t)(context->params[index].memref.buffer | ++ ((uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM)); ++ if (shared_mem->user_addr == buffer_addr) { ++ buffer_addr = (void *)(uintptr_t)(shared_mem->kernel_addr); ++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | ++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); ++ offset = context->params[index].memref.offset; ++ ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), dev_file->nsid)) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ tlogv(" buffer_size = %d \n", buffer_size); ++ tlogv(" "); ++ ++ if (read_from_VMclient(buffer_addr + offset, buffer_size, ++ (uint32_t __user *)(uintptr_t)(vm_hvas[index] + offset), ++ buffer_size, dev_file->nsid)) { ++ tloge("copy memref.buffer failed\n"); ++ return -EFAULT; ++ } ++ vm_buffers[index] = vm_hvas[index]; ++ kn_buffers[index] = (unsigned long long)buffer_addr; ++ } ++ } ++ } ++ mutex_unlock(&dev_file->shared_mem_lock); ++} ++ ++static int process_vm_ref_end(struct tc_ns_dev_file *dev_file, ++ struct tc_ns_client_context *context, unsigned long long *vm_buffers, ++ unsigned long long *kn_buffers) ++{ ++ int ret = 0; ++ int index = 0; ++ uint32_t buffer_size; ++ unsigned int offset = 0; ++ void *size_addr = NULL; ++ for (index = 0; index < TEE_PARAM_NUM; index++) ++ { ++ if (kn_buffers[index] != 0 && vm_buffers[index] != 0) { ++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | ++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); ++ ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), dev_file->nsid)) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ offset = context->params[index].memref.offset; ++ ++ tlogv("<--------------------\n"); ++ tlogv(" buffer_size = %d \n", buffer_size); ++ tlogv(" vm_buffers[index] = 0x%16.16lx", (long unsigned int)(vm_buffers[index])); ++ tlogv(" *(kn_buffers[index] + offset) = %s \n", (char*)(kn_buffers[index] + offset)); ++ tlogv(" offset = %ld \n", (long unsigned int)offset); ++ tlogv("-------------------->\n"); ++ ++ if (write_to_VMclient((void *)(uintptr_t)(vm_buffers[index] + offset), ++ buffer_size, (void *)(uintptr_t)(kn_buffers[index] + offset), ++ buffer_size, dev_file->nsid)) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } ++ ++ } else if (kn_buffers[index] == 0 && vm_buffers[index] == 0) { ++ /* do nothing*/ ++ ; ++ } else { ++ return -EFAULT; ++ } ++ } ++ return ret; ++} ++ + static int ioctl_session_send_cmd(struct tc_ns_dev_file *dev_file, + struct tc_ns_client_context *context, void *argp) + { + int ret; ++ unsigned long long vm_buffers[TEE_PARAM_NUM]={0}; ++ unsigned long long kn_buffers[TEE_PARAM_NUM]={0}; ++ ++ if (process_vm_ref(dev_file, context, vm_buffers, kn_buffers)) { ++ tloge("copy VM memref failed\n"); ++ return -EFAULT; ++ } + + ret = tc_ns_send_cmd(dev_file, context); + if (ret != 0) +@@ -1391,6 +1513,11 @@ + if (ret == 0) + ret = -EFAULT; + } ++ ++ if (process_vm_ref_end(dev_file, context, vm_buffers, kn_buffers)) { ++ tloge("copy VM memref failed\n"); ++ return -EFAULT; ++ } + return ret; + } + +@@ -1516,3 +1643,4 @@ + mutex_unlock(&dev_list->dev_lock); + return; + } ++ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/tc_client_driver.c itrustee_tzdriver_new/core/tc_client_driver.c +--- itrustee_tzdriver/core/tc_client_driver.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/tc_client_driver.c 2023-08-01 13:16:56.856000000 +0800 +@@ -307,12 +307,12 @@ + + static int tc_login_check(const struct tc_ns_dev_file *dev_file) + { +- int ret = check_teecd_auth(); ++/* int ret = check_teecd_auth(); + if (ret != 0) { + tloge("teec auth failed, ret %d\n", ret); + return -EACCES; + } +- ++*/ + if (!dev_file) + return -EINVAL; + +@@ -812,6 +812,15 @@ + return ret; + } + ++static int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid) ++{ ++ dev_file->isVM = true; ++ tlogd(" dev_file->isVM %d\n", (int)dev_file->isVM); ++ dev_file->nsid = vmid; ++ tlogd(" dev_file->nsid %d\n", (int)dev_file->nsid); ++ return 0; ++} ++ + void handle_cmd_prepare(unsigned int cmd) + { + if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT && +@@ -831,7 +840,11 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; +- handle_cmd_prepare(cmd); ++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { ++ tlogd(" before set_vm_flag \n"); ++ return set_vm_flag(file->private_data, (int)arg); ++ } ++ handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION: + ret = tc_ns_get_tee_version(file->private_data, argp); +@@ -851,7 +864,7 @@ + ret = sync_system_time_from_user( + (struct tc_ns_client_time *)(uintptr_t)arg); + break; +- default: ++ default: + ret = public_ioctl(file, cmd, arg, false); + break; + } +@@ -866,8 +879,11 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; +- +- handle_cmd_prepare(cmd); ++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { ++ tlogd(" before set_vm_flag \n"); ++ return set_vm_flag(file->private_data, (int)arg); ++ } ++ handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ: + case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ: +@@ -883,7 +899,7 @@ + case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: + ret = public_ioctl(file, cmd, arg, true); + break; +- default: ++ default: + ret = tc_client_agent_ioctl(file, cmd, arg); + break; + } +@@ -899,13 +915,13 @@ + int ret; + struct tc_ns_dev_file *dev = NULL; + (void)inode; +- ++/* + ret = check_teecd_auth(); + if (ret != 0) { + tloge("teec auth failed, ret %d\n", ret); + return -EACCES; + } +- ++*/ + file->private_data = NULL; + ret = tc_ns_client_open(&dev, TEE_REQ_FROM_USER_MODE); + if (ret == 0) +diff -Naur '--exclude=.git' itrustee_tzdriver/Makefile itrustee_tzdriver_new/Makefile +--- itrustee_tzdriver/Makefile 2023-08-01 13:44:04.248000000 +0800 ++++ itrustee_tzdriver_new/Makefile 2023-08-01 13:16:56.692000000 +0800 +@@ -37,8 +37,10 @@ + endif + + # you should config right path according to your run-time environment +-KPATH := /usr/src/kernels +-KDIR := $(KPATH)/$(shell ls $(KPATH)) ++#KPATH := /usr/src/kernels ++#KDIR := $(KPATH)/$(shell ls $(KPATH)) ++KERN_VER = $(shell uname -r) ++KERN_DIR = /lib/modules/$(KERN_VER)/build + + EXTRA_CFLAGS += -isystem /usr/lib/gcc/aarch64-linux-gnu/10.3.1/include + EXTRA_CFLAGS += -fstack-protector-strong -DCONFIG_TEELOG -DCONFIG_TZDRIVER_MODULE -DCONFIG_TEECD_AUTH -DCONFIG_PAGES_MEM=y -DCONFIG_CLOUDSERVER_TEECD_AUTH +@@ -53,7 +55,7 @@ + EXTRA_CFLAGS += -I$(PWD)/tzdriver_internal/tee_reboot + EXTRA_CFLAGS += -DMAILBOX_POOL_COUNT=8 + all: +- make -C $(KDIR) M=$(PWD) modules ++ make -C $(KERN_DIR) M=$(PWD) modules + clean: + -rm -vrf *.o *.ko auth/*.o core/*.o tlogger/*.o + -rm -vrf *.order *.symvers *.mod.c .tmp_versions .*o.cmd auth/.*o.cmd core/.*o.cmd tlogger/.*o.cmd +diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_client.h itrustee_tzdriver_new/tc_ns_client.h +--- itrustee_tzdriver/tc_ns_client.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/tc_ns_client.h 2023-08-01 13:16:56.696000000 +0800 +@@ -209,4 +209,7 @@ + #endif + #define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info) ++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG \ ++ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) ++ + #endif +diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_log.h itrustee_tzdriver_new/tc_ns_log.h +--- itrustee_tzdriver/tc_ns_log.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/tc_ns_log.h 2023-08-01 13:16:57.032000000 +0800 +@@ -32,7 +32,7 @@ + }; + #define MOD_TEE "tzdriver" + +-#define TEE_LOG_MASK TZ_DEBUG_INFO ++#define TEE_LOG_MASK TZ_DEBUG_WARN + + #define tlogv(fmt, args...) \ + do { \ +diff -Naur '--exclude=.git' itrustee_tzdriver/teek_ns_client.h itrustee_tzdriver_new/teek_ns_client.h +--- itrustee_tzdriver/teek_ns_client.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/teek_ns_client.h 2023-08-01 13:16:56.692000000 +0800 +@@ -133,6 +133,7 @@ + struct completion close_comp; /* for kthread close unclosed session */ + #ifdef CONFIG_TEE_TELEPORT_SUPPORT + bool portal_enabled; ++ bool isVM; + #endif + }; + -- Gitee From e4b8528aeaddfc0546c843a984151e0dce6884ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:58:28 +0000 Subject: [PATCH 09/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20tr?= =?UTF-8?q?ustzone-awared-vm/demo/Host/vtzb=5Fproxy/qemu.patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/Host/vtzb_proxy/qemu.patch | 779 ------------------ 1 file changed, 779 deletions(-) delete mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch b/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch deleted file mode 100644 index 3a8656b..0000000 --- a/trustzone-awared-vm/demo/Host/vtzb_proxy/qemu.patch +++ /dev/null @@ -1,779 +0,0 @@ -diff -Naur '--exclude=.git' qemu/hw/char/tc_ns_client.h qemu_after/hw/char/tc_ns_client.h ---- qemu/hw/char/tc_ns_client.h 1970-01-01 08:00:00.000000000 +0800 -+++ qemu_after/hw/char/tc_ns_client.h 2023-08-01 15:09:17.724000000 +0800 -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved. -+ * Licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ */ -+ -+#ifndef _TC_NS_CLIENT_H_ -+#define _TC_NS_CLIENT_H_ -+#include "tee_client_type.h" -+#define TC_DEBUG -+ -+#define INVALID_TYPE 0x00 -+#define TEECD_CONNECT 0x01 -+#ifndef ZERO_SIZE_PTR -+#define ZERO_SIZE_PTR ((void *)16) -+#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) -+#endif -+ -+#define UUID_SIZE 16 -+ -+#define TC_NS_CLIENT_IOC_MAGIC 't' -+#define TC_NS_CLIENT_DEV "tc_ns_client" -+#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" -+#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private" -+#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm" -+ -+enum ConnectCmd { -+ GET_FD, -+ GET_TEEVERSION, -+ SET_SYS_XML, -+ GET_TEECD_VERSION, -+}; -+ -+typedef struct { -+ unsigned int method; -+ unsigned int mdata; -+} TC_NS_ClientLogin; -+ -+typedef union { -+ struct { -+ unsigned long long buffer; -+ unsigned long long offset; -+ unsigned long long size_addr; -+ } memref; -+ struct { -+ unsigned long long a_addr; -+ unsigned long long b_addr; -+ } value; -+} TC_NS_ClientParam; -+ -+typedef struct { -+ unsigned int code; -+ unsigned int origin; -+} TC_NS_ClientReturn; -+ -+typedef struct { -+ unsigned char uuid[UUID_SIZE]; -+ unsigned int session_id; -+ unsigned int cmd_id; -+ TC_NS_ClientReturn returns; -+ TC_NS_ClientLogin login; -+ TC_NS_ClientParam params[TEEC_PARAM_NUM]; -+ unsigned int paramTypes; -+ bool started; -+ unsigned int callingPid; -+ unsigned int file_size; -+ union { -+ char *file_buffer; -+ struct { -+ uint32_t file_addr; -+ uint32_t file_h_addr; -+ } memref; -+ }; -+} TC_NS_ClientContext; -+ -+typedef struct { -+ uint32_t seconds; -+ uint32_t millis; -+} TC_NS_Time; -+ -+typedef struct { -+ uint16_t tzdriver_version_major; -+ uint16_t tzdriver_version_minor; -+ uint32_t reserved[15]; -+} TC_NS_TEE_Info; -+ -+enum SecFileType { -+ LOAD_TA = 0, -+ LOAD_SERVICE, -+ LOAD_LIB, -+ LOAD_DYNAMIC_DRV, -+ LOAD_PATCH, -+ LOAD_TYPE_MAX -+}; -+ -+struct SecFileInfo { -+ enum SecFileType fileType; -+ uint32_t fileSize; -+ int32_t secLoadErr; -+}; -+ -+struct SecLoadIoctlStruct { -+ struct SecFileInfo secFileInfo; -+ TEEC_UUID uuid; -+ union { -+ char *fileBuffer; -+ struct { -+ uint32_t file_addr; -+ uint32_t file_h_addr; -+ } memref; -+ }; -+}__attribute__((packed)); -+ -+struct AgentIoctlArgs { -+ uint32_t id; -+ uint32_t bufferSize; -+ union { -+ void *buffer; -+ unsigned long long addr; -+ }; -+}; -+ -+#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext) -+#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext) -+#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext) -+#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int) -+#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int) -+#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int) -+#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs) -+#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int) -+#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct) -+#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext) -+#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int) -+#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext) -+#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int) -+#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int) -+#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int) -+#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time) -+#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int) -+#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int) -+#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int) -+#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int) -+#ifdef CONFIG_CMS_SIGNATURE -+#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl) -+#endif -+#ifdef CONFIG_TEE_TELEPORT_SUPPORT -+#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs) -+#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs) -+#endif -+#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info) -+#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) -+ -+TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation); -+#endif -+ -+ -diff -Naur '--exclude=.git' qemu/hw/char/tee_client_list.h qemu_after/hw/char/tee_client_list.h ---- qemu/hw/char/tee_client_list.h 1970-01-01 08:00:00.000000000 +0800 -+++ qemu_after/hw/char/tee_client_list.h 2023-08-01 14:18:18.616000000 +0800 -@@ -0,0 +1,101 @@ -+/* -+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved. -+ * iTrustee licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ */ -+ -+#ifndef TEE_CLIENT_LIST_H -+#define TEE_CLIENT_LIST_H -+ -+struct ListNode { -+ struct ListNode *next; /* point to next node */ -+ struct ListNode *prev; /* point to prev node */ -+}; -+ -+#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member)) -+#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member)) -+ -+#define LIST_DECLARE(name) \ -+ struct ListNode name = { \ -+ .next = &name, \ -+ .prev = &name, \ -+ } -+ -+static inline void ListInit(struct ListNode *list) -+{ -+ list->next = list; -+ list->prev = list; -+} -+ -+#define LIST_HEAD(list) ((list)->next) -+#define LIST_TAIL(list) ((list)->prev) -+#define LIST_EMPTY(list) ((list) == (list)->next) -+ -+static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry) -+{ -+ list->next->prev = entry; -+ entry->next = list->next; -+ entry->prev = list; -+ list->next = entry; -+} -+ -+static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry) -+{ -+ entry->next = list; -+ entry->prev = list->prev; -+ list->prev->next = entry; -+ list->prev = entry; -+} -+ -+static inline void ListRemoveEntry(struct ListNode *entry) -+{ -+ entry->prev->next = entry->next; -+ entry->next->prev = entry->prev; -+} -+ -+static inline struct ListNode *ListRemoveHead(struct ListNode *list) -+{ -+ struct ListNode *entry = NULL; -+ if (!LIST_EMPTY(list)) { -+ entry = list->next; -+ ListRemoveEntry(entry); -+ } -+ return entry; -+} -+ -+static inline struct ListNode *ListRemoveTail(struct ListNode *list) -+{ -+ struct ListNode *entry = NULL; -+ if (!LIST_EMPTY(list)) { -+ entry = list->prev; -+ ListRemoveEntry(entry); -+ } -+ return entry; -+} -+ -+#define LIST_ENTRY(ptr, type, member) \ -+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) -+ -+#define LIST_FOR_EACH(pos, list) \ -+ for (pos = (list)->next; pos != (list); pos = pos->next) -+ -+#define LIST_FOR_EACH_SAFE(pos, n, list) \ -+ for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next) -+ -+#define LIST_FOR_EACH_ENTRY(pos, list, member) \ -+ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \ -+ pos = LIST_ENTRY(pos->member.next, typeof(*pos), member)) -+ -+#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \ -+ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \ -+ member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member)) -+ -+#endif -+ -+ -diff -Naur '--exclude=.git' qemu/hw/char/tee_client_type.h qemu_after/hw/char/tee_client_type.h ---- qemu/hw/char/tee_client_type.h 1970-01-01 08:00:00.000000000 +0800 -+++ qemu_after/hw/char/tee_client_type.h 2023-08-01 14:32:33.296000000 +0800 -@@ -0,0 +1,134 @@ -+/* -+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved. -+ * Licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ */ -+ -+#ifndef _TEE_CLIENT_TYPE_H_ -+#define _TEE_CLIENT_TYPE_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include "tee_client_list.h" -+#include "tee_client_constants.h" -+ -+typedef enum TEEC_ReturnCode TEEC_Result; -+ -+typedef struct { -+ uint32_t timeLow; -+ uint16_t timeMid; -+ uint16_t timeHiAndVersion; -+ uint8_t clockSeqAndNode[8]; -+} TEEC_UUID; -+ -+typedef struct { -+ int32_t fd; -+ uint8_t *ta_path; -+ struct ListNode session_list; -+ struct ListNode shrd_mem_list; -+ union { -+ struct { -+ void *buffer; -+ sem_t buffer_barrier; -+ } share_buffer; -+ uint64_t imp; /* for adapt */ -+ }; -+} TEEC_Context; -+ -+typedef struct { -+ uint32_t session_id; -+ TEEC_UUID service_id; -+ uint32_t ops_cnt; -+ union { -+ struct ListNode head; -+ uint64_t imp; /* for adapt */ -+ }; -+ TEEC_Context *context; -+} TEEC_Session; -+ -+typedef struct { -+ void *buffer; -+ uint32_t size; -+ uint32_t flags; /* reference to TEEC_SharedMemCtl */ -+ uint32_t ops_cnt; -+ bool is_allocated; /* identify whether the memory is registered or allocated */ -+ union { -+ struct ListNode head; -+ void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */ -+ }; -+ TEEC_Context *context; -+} TEEC_SharedMemory; -+ -+/* -+ * the corresponding param types are -+ * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT -+ */ -+typedef struct { -+ void *buffer; -+ uint32_t size; -+} TEEC_TempMemoryReference; -+ -+/* -+ * the corresponding param types are -+ * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT -+ * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT -+ */ -+typedef struct { -+ TEEC_SharedMemory *parent; -+ uint32_t size; -+ uint32_t offset; -+} TEEC_RegisteredMemoryReference; -+ -+/* -+ * the corresponding param types are -+ * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT -+ */ -+typedef struct { -+ uint32_t a; -+ uint32_t b; -+} TEEC_Value; -+ -+typedef struct { -+ int ion_share_fd; -+ uint32_t ion_size; -+} TEEC_IonReference; -+ -+typedef union { -+ TEEC_TempMemoryReference tmpref; -+ TEEC_RegisteredMemoryReference memref; -+ TEEC_Value value; -+ TEEC_IonReference ionref; -+} TEEC_Parameter; -+ -+typedef struct { -+ uint32_t event_type; /* Tui event type */ -+ uint32_t value; /* return value, is keycode if tui event is getKeycode */ -+ uint32_t notch; /* notch size of the screen for tui */ -+ uint32_t width; /* width of foldable screen */ -+ uint32_t height; /* height of foldable screen */ -+ uint32_t fold_state; /* state of foldable screen */ -+ uint32_t display_state; /* one state of folded state */ -+ uint32_t phy_width; /* real width of the mobile */ -+ uint32_t phy_height; /* real height of the mobile */ -+} TEEC_TUI_Parameter; -+ -+typedef struct { -+ uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */ -+ uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */ -+ TEEC_Parameter params[TEEC_PARAM_NUM]; -+ TEEC_Session *session; -+ bool cancel_flag; -+} TEEC_Operation; -+ -+#endif -+ -+ -diff -Naur '--exclude=.git' qemu/hw/char/virtio-console.c qemu_after/hw/char/virtio-console.c ---- qemu/hw/char/virtio-console.c 2023-08-01 14:07:32.320000000 +0800 -+++ qemu_after/hw/char/virtio-console.c 2023-08-01 14:18:18.616000000 +0800 -@@ -20,6 +20,14 @@ - #include "qapi/error.h" - #include "qapi/qapi-events-char.h" - -+#include "qom/object.h" -+#include "hw/core/cpu.h" -+#include "sysemu/hw_accel.h" -+#include "monitor/monitor.h" -+#include -+#include -+#include "tc_ns_client.h" -+ - #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport" - #define VIRTIO_CONSOLE(obj) \ - OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT) -@@ -45,6 +53,106 @@ - return FALSE; - } - -+ -+#define DEBUG 1 -+ -+#ifdef DEBUG -+static void debug(const char *fmt, ...) -+{ -+ va_list args; -+ -+ va_start(args, fmt); -+ vfprintf(stderr, fmt, args); -+ va_end(args); -+} -+ -+#define PRINTF_SIZE 16 -+static void dump_buff(const char *buffer, size_t bufLen) -+{ -+ size_t i; -+ if (buffer == NULL || bufLen == 0) { -+ return; -+ } -+ -+ // printf("\n--------------------------------------------------\n"); -+ printf("--------------------------------------------------\n"); -+ printf("bufLen = %d\n", (int)bufLen); -+ for (i = 0; i < bufLen; i++) { -+ if (i % PRINTF_SIZE == 0 && i != 0) { -+ printf("\n"); -+ } -+ printf("%02x ", *(buffer + i)); -+ } -+ printf("\n--------------------------------------------------\n"); -+ return; -+} -+#else -+#define debug(fmt, ...) do { } while (0) -+ -+#define dump_buff(buffer, bufLen) do { } while (0) -+#endif -+ -+#define VTZF_OPEN_TZD 15 -+#define VTZF_OPEN_SESSION 31 -+#define VTZF_SEND_CMD 33 -+#define VTZF_LOAD_SEC 53 -+ -+#define TEEC_PARAM_NUM 4 /* teec param max number */ -+ -+#define IS_TEMP_MEM(paramType) \ -+ (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \ -+ ((paramType) == TEEC_MEMREF_TEMP_INOUT)) -+ -+#define IS_PARTIAL_MEM(paramType) \ -+ (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \ -+ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT)) -+ -+#define IS_VALUE_MEM(paramType) \ -+ (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT)) -+ -+#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ -+ (((paramTypes) >> (4*(index))) & 0x0F) -+ -+typedef struct { -+ uint32_t cmd; // 4, 4 bytes -+ uint32_t seq_num; // second -+ uint32_t vmid; -+ uint32_t flag; -+} struct_packet_cmd_open_tzd; -+ -+typedef struct { -+ uint32_t cmd; -+ uint32_t seq_num; -+ __s32 ptzfd; -+ __s32 cpu_index; -+ struct SecLoadIoctlStruct ioctlArg; -+} struct_packet_cmd_load_sec; -+ -+typedef struct { -+ uint32_t cmd; -+ uint32_t seq_num; -+ int32_t ptzfd; -+ int32_t cpu_index; -+ TC_NS_ClientContext cliContext; -+} struct_packet_cmd_session; -+ -+typedef struct { -+ uint32_t cmd; // 4, 4 bytes -+ int32_t ptzfd; // 4, 8 bytes -+ int32_t cpu_index; // 4, 12 bytes -+ unsigned long long addrs[TEEC_PARAM_NUM]; -+ TC_NS_ClientContext cliContext; -+} struct_vtzf_packet_cmd_send_cmd; -+ -+typedef struct { -+ uint32_t cmd; // 4, 4 bytes -+ __s32 ptzfd; // 4, 8 bytes -+ uint64_t buffer; // 8, 16 bytes -+ uint32_t size; // 4, 20 bytes -+ uint32_t offset; // 4, 24 bytes -+}struct_vtzf_packet_cmd_mmap; -+ -+ - /* Callback function that's called when the guest sends us data */ - static ssize_t flush_buf(VirtIOSerialPort *port, - const uint8_t *buf, ssize_t len) -@@ -57,7 +165,201 @@ - return len; - } - -- ret = qemu_chr_fe_write(&vcon->chr, buf, len); -+ uint8_t buf01[90 * 1024]; -+ memcpy(buf01, buf, len); -+ -+ debug("\n"); -+ debug("debug, %s, %s, %d \n", __FILE__, __func__, __LINE__); -+ debug(" virtio-console virtserialport name = %s, id = %d \n", port->name, (int)port->id); -+ debug(" have_data flush_buf, buflen = %d \n", len); -+ // dump_buff((char *)buf, len); -+ dump_buff((char *)buf, 0); -+ -+ if ( len >= 4 ) { -+ uint32_t ui32_cmd; -+ ui32_cmd = 0; -+ //struct_vtzf_packet_cmd *vtzf_packet_cmd; -+ -+ uint32_t ui32_tmp; -+ int i; -+ for (i = 0; i < 4; i++) -+ { -+ ui32_tmp = buf[i]; -+ ui32_tmp = ui32_tmp << (i * 8); -+ ui32_cmd = ui32_cmd | ui32_tmp; -+ } -+ -+ switch( ui32_cmd ) -+ { -+ case VTZF_OPEN_TZD: -+ debug(" command is VTZF_OPEN_TZD \n"); -+ if ( len >= sizeof(struct_packet_cmd_open_tzd)) { -+ struct_packet_cmd_open_tzd* vtzf_packet_cmd = (struct_packet_cmd_open_tzd *)buf01; -+ pid_t qemu_pid = getpid(); -+ debug(" qemu_pid = 0x%016lx, %d \n",qemu_pid, qemu_pid); -+ vtzf_packet_cmd->vmid = qemu_pid; -+ } -+ break; -+ case VTZF_LOAD_SEC: -+ debug(" command is VTZF_LOAD_SEC \n"); -+ if (len >= sizeof(struct_packet_cmd_load_sec)) { -+ struct_packet_cmd_load_sec* vtzf_packet_cmd = (struct_packet_cmd_load_sec *)buf01; -+ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->ioctlArg.fileBuffer); -+ -+ hwaddr gpa = (uint64_t)vtzf_packet_cmd->ioctlArg.fileBuffer; -+ Error *local_err = NULL; -+ MemoryRegion *mr = NULL; -+ void *ptr_hva; -+ -+ ptr_hva = gpa2hva(&mr, gpa, &local_err); -+ if (local_err) { -+ debug(" gpa2hva failed \n"); -+ } else { -+ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ -+ memory_region_unref(mr); -+ -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->ioctlArg.fileBuffer = (void *)ui64_hva; -+ } -+ } -+ break; -+ case VTZF_OPEN_SESSION: -+ debug(" command is VTZF_OPEN_SESSION \n"); -+ debug("sizeof(struct_packet_cmd_session) =%d \n", sizeof(struct_packet_cmd_session)); -+ debug("sizeof(TC_NS_ClientContext) =%d \n", sizeof(TC_NS_ClientContext)); -+ if ( len >= sizeof(struct_packet_cmd_session) ) { -+ struct_packet_cmd_session* vtzf_packet_cmd = (struct_packet_cmd_session *)buf01; -+ -+ debug(" vtzf_packet_cmd->cliContext.file_size = 0x%08x, %d \n", vtzf_packet_cmd->cliContext.file_size, -+ vtzf_packet_cmd->cliContext.file_size); -+ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->cliContext.file_buffer); -+ -+ hwaddr gpa = (uint64_t)vtzf_packet_cmd->cliContext.file_buffer; -+ Error *local_err = NULL; -+ MemoryRegion *mr = NULL; -+ void *ptr_hva; -+ -+ ptr_hva = gpa2hva(&mr, gpa, &local_err); -+ if (local_err) { -+ debug(" gpa2hva failed \n"); -+ } else { -+ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ -+ memory_region_unref(mr); -+ -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.file_buffer = (void *)ui64_hva; -+ } -+ } -+ break; -+ case VTZF_SEND_CMD: -+ debug(" command is VTZF_SEND_CMD \n"); -+ if ( len >= sizeof(struct_vtzf_packet_cmd_send_cmd) ) { -+ struct_vtzf_packet_cmd_send_cmd* vtzf_packet_cmd = (struct_vtzf_packet_cmd_send_cmd *)buf01; -+ -+ Error *local_err = NULL; -+ MemoryRegion *mr = NULL; -+ void *ptr_hva; -+ -+ uint32_t param_type; -+ bool check_value; -+ hwaddr gpa_param; -+ -+ for (i = 0; i < TEEC_PARAM_NUM; i++) { -+ param_type = TEEC_PARAM_TYPE_GET(vtzf_packet_cmd->cliContext.paramTypes, i); -+ check_value = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); -+ if (IS_TEMP_MEM(param_type)) { -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].memref.buffer failed \n", i); -+ } else { -+ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; -+ } -+ -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); -+ } else { -+ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; -+ } -+ -+ } else if (IS_PARTIAL_MEM(param_type)) { -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].memref.buffer failed \n", i); -+ } else { -+ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; -+ } -+ -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); -+ } else { -+ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; -+ } -+ -+ } else if (IS_VALUE_MEM(param_type) || check_value) { -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.a_addr; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].value.a_addr failed \n", i); -+ } else { -+ debug(" host virtual address of value.a_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].value.a_addr = ui64_hva; -+ } -+ -+ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.b_addr; -+ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); -+ if (local_err) { -+ debug(" gpa2hva params[%d].value.b_addr failed \n", i); -+ } else { -+ debug(" host virtual address of value.b_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); -+ memory_region_unref(mr); -+ uint64_t ui64_hva; -+ ui64_hva = (uint64_t)ptr_hva; -+ vtzf_packet_cmd->cliContext.params[i].value.b_addr = ui64_hva; -+ } -+ -+ } else { -+ /* if type is none, ignore it */ -+ } -+ }// end for -+ -+ }//end if -+ break; -+ default: -+ debug(" other command \n"); -+ } -+ -+ } // end of if ( len >= 4 ) -+ -+ ret = qemu_chr_fe_write(&vcon->chr, buf01, len); - trace_virtio_console_flush_buf(port->id, len, ret); - - if (ret < len) { -@@ -304,3 +606,4 @@ - } - - type_init(virtconsole_register_types) -+ -diff -Naur '--exclude=.git' qemu/include/monitor/monitor.h qemu_after/include/monitor/monitor.h ---- qemu/include/monitor/monitor.h 2023-08-01 14:07:32.384000000 +0800 -+++ qemu_after/include/monitor/monitor.h 2023-08-01 14:18:18.664000000 +0800 -@@ -4,6 +4,7 @@ - #include "block/block.h" - #include "qapi/qapi-types-misc.h" - #include "qemu/readline.h" -+#include "exec/hwaddr.h" - - extern __thread Monitor *cur_mon; - typedef struct MonitorHMP MonitorHMP; -@@ -36,6 +37,8 @@ - int monitor_set_cpu(int cpu_index); - int monitor_get_cpu_index(void); - -+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp); -+ - void monitor_read_command(MonitorHMP *mon, int show_prompt); - int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func, - void *opaque); -@@ -49,3 +52,4 @@ - int64_t monitor_fdset_dup_fd_find(int dup_fd); - - #endif /* MONITOR_H */ -+ -diff -Naur '--exclude=.git' qemu/monitor/misc.c qemu_after/monitor/misc.c ---- qemu/monitor/misc.c 2023-08-01 14:07:32.404000000 +0800 -+++ qemu_after/monitor/misc.c 2023-08-01 14:18:18.684000000 +0800 -@@ -674,7 +674,7 @@ - memory_dump(mon, count, format, size, addr, 1); - } - --static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) -+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) - { - MemoryRegionSection mrs = memory_region_find(get_system_memory(), - addr, 1); -- Gitee From e2986af2abe5215cac22832541e9e6a4d072f7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:58:35 +0000 Subject: [PATCH 10/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20tr?= =?UTF-8?q?ustzone-awared-vm/demo/Host/vtzb=5Fproxy/tzdriver.patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/Host/vtzb_proxy/tzdriver.patch | 889 ------------------ 1 file changed, 889 deletions(-) delete mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch b/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch deleted file mode 100644 index 7066b16..0000000 --- a/trustzone-awared-vm/demo/Host/vtzb_proxy/tzdriver.patch +++ /dev/null @@ -1,889 +0,0 @@ -diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.c itrustee_tzdriver_new/core/gp_ops.c ---- itrustee_tzdriver/core/gp_ops.c 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/core/gp_ops.c 2023-08-01 13:16:56.800000000 +0800 -@@ -312,6 +312,148 @@ - return 0; - } - -+ -+int read_from_VMclient(void *dest, size_t dest_size, -+ const void __user *src, size_t size, pid_t vm_pid) -+{ -+ struct task_struct *vmp_task; -+ int i_rdlen; -+ int i_index; -+ int ret; -+ -+ if (!dest || !src) { -+ tloge("src or dest is NULL input buffer\n"); -+ return -EINVAL; -+ } -+ -+ if (size > dest_size) { -+ tloge("size is larger than dest_size or size is 0\n"); -+ return -EINVAL; -+ } -+ if (!size) -+ return 0; -+ -+ tlogv("django verbose, execute access_process_vm"); -+ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID); -+ if (vmp_task == NULL) { -+ tloge("no task for pid %d \n", vm_pid); -+ return -EFAULT; -+ } -+ tlogv("django verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); -+ -+ i_rdlen = access_process_vm(vmp_task, (unsigned long)(src), dest, size, FOLL_FORCE); -+ if (i_rdlen != size) { -+ tloge("only read %d of %ld bytes by access_process_vm \n", i_rdlen, size); -+ return -EFAULT; -+ } -+ tlogv("django verbose, read %d byes by access_process_vm succeed", -+ i_rdlen); -+ for (i_index = 0; i_index < 32 && i_index < size; i_index ++) { -+ tlogv("django verbose, *(dest + i_index) + %d) = %2.2x", -+ i_index, *((char*)dest + i_index)); -+ } -+ return 0; -+} -+ -+#define PINED_PAGE_NUMBER 1 -+ -+int write_to_VMclient(void __user *dest, size_t dest_size, -+ const void *src, size_t size, pid_t vm_pid) -+{ -+ int ret = 0; -+ -+ struct task_struct *vmp_task; -+ struct pid *pid; -+ struct mm_struct *mm; -+ -+ unsigned long ul_offset; -+ -+ unsigned long user_addr; -+ struct page *ptr_page; -+ struct vm_area_struct *vmap_01; -+ void *kern_addr; -+ -+ tlogv("wcz verbose, start execute vtz_write_to_client \n"); -+ -+ if (!dest || !src) { -+ tloge("src or dest is NULL input buffer\n"); -+ return -EINVAL; -+ } -+ -+ if (size > dest_size) { -+ tloge("size is larger than dest_size\n"); -+ return -EINVAL; -+ } -+ -+ if (!size) -+ return 0; -+ -+ pid = find_get_pid(vm_pid); -+ vmp_task = get_pid_task(pid, PIDTYPE_PID); -+ if (vmp_task == NULL) { -+ tloge("no task for pid %d", vm_pid); -+ return -EFAULT; -+ } -+ tlogv("wcz verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); -+ -+ mm = vmp_task->mm; -+ user_addr = (unsigned long)dest; -+ -+ #if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) -+ ret = get_user_pages_remote(vmp_task, mm, user_addr, -+ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, -+ &ptr_page, &vmap_01, NULL); -+ #elif (KERNEL_VERSION(4, 4, 197) <= LINUX_VERSION_CODE) -+ ret = get_user_pages_locked(vmp_task, mm, user_addr, -+ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, &ptr_page, &vmap_01); -+ #else -+ ret = get_user_pages_locked(vmp_task, mm, user_addr, -+ (unsigned long)PINED_PAGE_NUMBER, 1, 1, &ptr_page, &vmap_01); -+ #endif -+ if (ret != PINED_PAGE_NUMBER) { -+ tloge("get user pages failed, ret = %d\n", ret); -+ ret = -EFAULT; -+ goto putpid; -+ } -+ -+ ul_offset = user_addr & (PAGE_SIZE - 1); -+ tlogv("django verbose, offset in the physical page for user address 0x%016lx is 0x%016lx \n", user_addr, ul_offset); -+ -+ if (ul_offset >= PAGE_SIZE) { -+ ul_offset = 0; -+ } -+ -+ tlogv("django verbose, ul_offset = %ld, 0x%016lx \n", ul_offset, ul_offset); -+ -+ kern_addr = kmap_atomic(ptr_page); -+ -+ if (!kern_addr) { -+ tloge("failed to kmap page 0x%016lx \n", (unsigned long)ptr_page); -+ ret = -EFAULT; -+ goto putpage; -+ } -+ tlogv("succeed to kmap page 0x%016lx, kern virtual address = 0x%016lx \n", -+ (unsigned long)ptr_page, (unsigned long)kern_addr); -+ -+ ret = memcpy_s(kern_addr + ul_offset, dest_size, src, size); -+ if (ret != EOK) { -+ tloge("vtz_write to client, memcpy_s fail, ret=%d\n", ret); -+ goto kunmappage; -+ } -+ -+kunmappage: -+ kunmap_atomic(kern_addr); -+ -+putpage: -+ set_page_dirty_lock(ptr_page); -+ put_page(ptr_page); -+ -+putpid: -+ put_pid(pid); -+ -+ return ret; -+} -+ - static bool is_input_tempmem(unsigned int param_type) - { - if (param_type == TEEC_MEMREF_TEMP_INPUT || -@@ -321,7 +463,8 @@ - return false; - } - --static int update_input_data(const union tc_ns_client_param *client_param, -+static int update_input_data(const struct tc_call_params *call_params, -+ const union tc_ns_client_param *client_param, - uint32_t buffer_size, void *temp_buf, - unsigned int param_type, uint8_t kernel_params) - { -@@ -331,11 +474,22 @@ - - buffer_addr = client_param->memref.buffer | - ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); -- if (read_from_client(temp_buf, buffer_size, -- (void *)(uintptr_t)buffer_addr, -- buffer_size, kernel_params) != 0) { -- tloge("copy memref buffer failed\n"); -- return -EFAULT; -+ if (call_params->dev->isVM && !kernel_params) { -+ tlogd("is VM\n"); -+ if (read_from_VMclient(temp_buf, buffer_size, -+ (void *)(uintptr_t)buffer_addr, -+ buffer_size, call_params->dev->nsid) != 0) { -+ tloge("copy memref buffer failed\n"); -+ return -EFAULT; -+ } -+ } else { -+ tlogd("is not VM\n"); -+ if (read_from_client(temp_buf, buffer_size, -+ (void *)(uintptr_t)buffer_addr, -+ buffer_size, kernel_params) != 0) { -+ tloge("copy memref buffer failed\n"); -+ return -EFAULT; -+ } - } - return 0; - } -@@ -361,11 +515,22 @@ - client_param = &(call_params->context->params[index]); - size_addr = client_param->memref.size_addr | - ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); -- if (read_from_client(&buffer_size, sizeof(buffer_size), -- (uint32_t __user *)(uintptr_t)size_addr, -- sizeof(uint32_t), kernel_params) != 0) { -- tloge("copy memref.size_addr failed\n"); -- return -EFAULT; -+ if (call_params->dev->isVM && !kernel_params) { -+ tlogd(" is VM\n "); -+ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), call_params->dev->nsid) != 0) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } -+ } else{ -+ tlogd(" is not VM "); -+ if (read_from_client(&buffer_size, sizeof(buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), kernel_params) != 0) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } - } - - if (buffer_size > MAX_SHARED_SIZE) { -@@ -393,7 +558,7 @@ - op_params->local_tmpbuf[index].temp_buffer = temp_buf; - op_params->local_tmpbuf[index].size = buffer_size; - -- if (update_input_data(client_param, buffer_size, temp_buf, -+ if (update_input_data(call_params, client_param, buffer_size, temp_buf, - param_type, kernel_params) != 0) - return -EFAULT; - -@@ -405,17 +570,31 @@ - return 0; - } - --static int check_buffer_for_ref(uint32_t *buffer_size, -- const union tc_ns_client_param *client_param, uint8_t kernel_params) -+static int check_buffer_for_ref(const struct tc_call_params *call_params, -+ uint32_t *buffer_size, const union tc_ns_client_param *client_param, -+ uint8_t kernel_params) - { - uint64_t size_addr = client_param->memref.size_addr | - ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); -- if (read_from_client(buffer_size, sizeof(*buffer_size), -- (uint32_t __user *)(uintptr_t)size_addr, -- sizeof(uint32_t), kernel_params) != 0) { -- tloge("copy memref.size_addr failed\n"); -- return -EFAULT; -+ -+ if (call_params->dev->isVM && !kernel_params) { -+ tlogd("is VM\n"); -+ if (read_from_VMclient(buffer_size, sizeof(*buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), call_params->dev->nsid) != 0) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } -+ } else { -+ tlogd("is not VM\n"); -+ if (read_from_client(buffer_size, sizeof(*buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), kernel_params) != 0) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } - } -+ - if (*buffer_size == 0) { - tloge("buffer_size from user is 0\n"); - return -ENOMEM; -@@ -497,7 +676,7 @@ - return -EINVAL; - - client_param = &(call_params->context->params[index]); -- if (check_buffer_for_ref(&buffer_size, client_param, kernel_params) != 0) -+ if (check_buffer_for_ref(call_params, &buffer_size, client_param, kernel_params) != 0) - return -EINVAL; - - op_params->mb_pack->operation.params[index].memref.buffer = 0; -@@ -651,21 +830,42 @@ - b_addr = client_param->value.b_addr | - ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); - -- if (read_from_client(&operation->params[index].value.a, -- sizeof(operation->params[index].value.a), -- (void *)(uintptr_t)a_addr, -- sizeof(operation->params[index].value.a), -- kernel_params) != 0) { -- tloge("copy valuea failed\n"); -- return -EFAULT; -- } -- if (read_from_client(&operation->params[index].value.b, -- sizeof(operation->params[index].value.b), -- (void *)(uintptr_t)b_addr, -- sizeof(operation->params[index].value.b), -- kernel_params) != 0) { -- tloge("copy valueb failed\n"); -- return -EFAULT; -+ if (call_params->dev->isVM && !kernel_params) { -+ tlogd("is VM \n"); -+ if (read_from_VMclient(&operation->params[index].value.a, -+ sizeof(operation->params[index].value.a), -+ (void *)(uintptr_t)a_addr, -+ sizeof(operation->params[index].value.a), -+ call_params->dev->nsid) != 0) { -+ tloge("copy valuea failed\n"); -+ return -EFAULT; -+ } -+ if (read_from_VMclient(&operation->params[index].value.b, -+ sizeof(operation->params[index].value.b), -+ (void *)(uintptr_t)b_addr, -+ sizeof(operation->params[index].value.b), -+ call_params->dev->nsid) != 0) { -+ tloge("copy valueb failed\n"); -+ return -EFAULT; -+ } -+ } else { -+ tlogd("is not VM \n"); -+ if (read_from_client(&operation->params[index].value.a, -+ sizeof(operation->params[index].value.a), -+ (void *)(uintptr_t)a_addr, -+ sizeof(operation->params[index].value.a), -+ kernel_params) != 0) { -+ tloge("copy valuea failed\n"); -+ return -EFAULT; -+ } -+ if (read_from_client(&operation->params[index].value.b, -+ sizeof(operation->params[index].value.b), -+ (void *)(uintptr_t)b_addr, -+ sizeof(operation->params[index].value.b), -+ kernel_params) != 0) { -+ tloge("copy valueb failed\n"); -+ return -EFAULT; -+ } - } - - /* TEEC_VALUE_INPUT equal to TEE_PARAM_TYPE_VALUE_INPUT */ -@@ -754,12 +954,24 @@ - buffer_addr = client_param->memref.buffer | - ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); - /* Size is updated all the time */ -- if (write_to_client((void *)(uintptr_t)size_addr, -- sizeof(buffer_size), -- &buffer_size, sizeof(buffer_size), -- call_params->dev->kernel_api) != 0) { -- tloge("copy tempbuf size failed\n"); -- return -EFAULT; -+ if (call_params->dev->isVM && !call_params->dev->kernel_api) { -+ tlogd("is VM\n"); -+ if (write_to_VMclient((void *)(uintptr_t)size_addr, -+ sizeof(buffer_size), -+ &buffer_size, sizeof(buffer_size), -+ call_params->dev->nsid) != 0) { -+ tloge("copy tempbuf size failed\n"); -+ return -EFAULT; -+ } -+ }else{ -+ tlogd("is not VM\n"); -+ if (write_to_client((void *)(uintptr_t)size_addr, -+ sizeof(buffer_size), -+ &buffer_size, sizeof(buffer_size), -+ call_params->dev->kernel_api) != 0) { -+ tloge("copy tempbuf size failed\n"); -+ return -EFAULT; -+ } - } - if (buffer_size > op_params->local_tmpbuf[index].size) { - /* incomplete case, when the buffer size is invalid see next param */ -@@ -775,13 +987,26 @@ - if (buffer_size == 0) - return 0; - /* Only update the buffer when the buffer size is valid in complete case */ -- if (write_to_client((void *)(uintptr_t)buffer_addr, -- operation->params[index].memref.size, -- op_params->local_tmpbuf[index].temp_buffer, -- operation->params[index].memref.size, -- call_params->dev->kernel_api) != 0) { -- tloge("copy tempbuf failed\n"); -- return -ENOMEM; -+ if (call_params->dev->isVM && !call_params->dev->kernel_api) { -+ tlogd("is VM\n"); -+ if (write_to_VMclient((void *)(uintptr_t)buffer_addr, -+ operation->params[index].memref.size, -+ op_params->local_tmpbuf[index].temp_buffer, -+ operation->params[index].memref.size, -+ call_params->dev->nsid) != 0) { -+ tloge("copy tempbuf failed\n"); -+ return -ENOMEM; -+ } -+ } else { -+ tlogd("is not VM\n"); -+ if (write_to_client((void *)(uintptr_t)buffer_addr, -+ operation->params[index].memref.size, -+ op_params->local_tmpbuf[index].temp_buffer, -+ operation->params[index].memref.size, -+ call_params->dev->kernel_api) != 0) { -+ tloge("copy tempbuf failed\n"); -+ return -ENOMEM; -+ } - } - return 0; - } -@@ -806,22 +1031,38 @@ - size_addr = client_param->memref.size_addr | - ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); - -- if (read_from_client(&orig_size, -- sizeof(orig_size), -- (uint32_t __user *)(uintptr_t)size_addr, -- sizeof(orig_size), call_params->dev->kernel_api) != 0) { -- tloge("copy orig memref.size_addr failed\n"); -- return -EFAULT; -- } -+ if (call_params->dev->isVM && !call_params->dev->kernel_api) { -+ if (read_from_VMclient(&orig_size, sizeof(orig_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(orig_size), call_params->dev->nsid) != 0) { -+ tloge("copy orig memref.size_addr failed\n"); -+ return -EFAULT; -+ } -+ -+ if (write_to_VMclient((void *)(uintptr_t)size_addr, -+ sizeof(buffer_size), -+ &buffer_size, sizeof(buffer_size), -+ call_params->dev->nsid) != 0) { -+ tloge("copy buf size failed\n"); -+ return -EFAULT; -+ } -+ } else { -+ if (read_from_client(&orig_size, -+ sizeof(orig_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(orig_size), call_params->dev->kernel_api) != 0) { -+ tloge("copy orig memref.size_addr failed\n"); -+ return -EFAULT; -+ } - -- if (write_to_client((void *)(uintptr_t)size_addr, -- sizeof(buffer_size), -- &buffer_size, sizeof(buffer_size), -- call_params->dev->kernel_api) != 0) { -- tloge("copy buf size failed\n"); -- return -EFAULT; -+ if (write_to_client((void *)(uintptr_t)size_addr, -+ sizeof(buffer_size), -+ &buffer_size, sizeof(buffer_size), -+ call_params->dev->kernel_api) != 0) { -+ tloge("copy buf size failed\n"); -+ return -EFAULT; -+ } - } -- - /* reserved memory no need to copy */ - if (operation->sharemem[index]->mem_type == RESERVED_TYPE) - return 0; -@@ -859,21 +1100,42 @@ - b_addr = client_param->value.b_addr | - ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); - -- if (write_to_client((void *)(uintptr_t)a_addr, -- sizeof(operation->params[index].value.a), -- &operation->params[index].value.a, -- sizeof(operation->params[index].value.a), -- call_params->dev->kernel_api) != 0) { -- tloge("inc copy value.a_addr failed\n"); -- return -EFAULT; -- } -- if (write_to_client((void *)(uintptr_t)b_addr, -- sizeof(operation->params[index].value.b), -- &operation->params[index].value.b, -- sizeof(operation->params[index].value.b), -- call_params->dev->kernel_api) != 0) { -- tloge("inc copy value.b_addr failed\n"); -- return -EFAULT; -+ if (call_params->dev->isVM && !call_params->dev->kernel_api) { -+ tlogd("is VM \n"); -+ if (write_to_VMclient((void *)(uintptr_t)a_addr, -+ sizeof(operation->params[index].value.a), -+ &operation->params[index].value.a, -+ sizeof(operation->params[index].value.a), -+ call_params->dev->nsid) != 0) { -+ tloge("inc copy value.a_addr failed\n"); -+ return -EFAULT; -+ } -+ if (write_to_VMclient((void *)(uintptr_t)b_addr, -+ sizeof(operation->params[index].value.b), -+ &operation->params[index].value.b, -+ sizeof(operation->params[index].value.b), -+ call_params->dev->nsid) != 0) { -+ tloge("inc copy value.b_addr failed\n"); -+ return -EFAULT; -+ } -+ } else { -+ tlogd("is not VM\n"); -+ if (write_to_client((void *)(uintptr_t)a_addr, -+ sizeof(operation->params[index].value.a), -+ &operation->params[index].value.a, -+ sizeof(operation->params[index].value.a), -+ call_params->dev->kernel_api) != 0) { -+ tloge("inc copy value.a_addr failed\n"); -+ return -EFAULT; -+ } -+ if (write_to_client((void *)(uintptr_t)b_addr, -+ sizeof(operation->params[index].value.b), -+ &operation->params[index].value.b, -+ sizeof(operation->params[index].value.b), -+ call_params->dev->kernel_api) != 0) { -+ tloge("inc copy value.b_addr failed\n"); -+ return -EFAULT; -+ } - } - return 0; - } -@@ -1248,3 +1510,5 @@ - release_tc_call_resource(call_params, &op_params, tee_ret); - return ret; - } -+ -+ -diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.h itrustee_tzdriver_new/core/gp_ops.h ---- itrustee_tzdriver/core/gp_ops.h 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/core/gp_ops.h 2023-08-01 13:16:56.848000000 +0800 -@@ -30,5 +30,9 @@ - bool is_tmp_mem(uint32_t param_type); - bool is_ref_mem(uint32_t param_type); - bool is_val_param(uint32_t param_type); -+int write_to_VMclient(void __user *dest, size_t dest_size, -+ const void *src, size_t size, pid_t vm_pid); -+int read_from_VMclient(void *dest, size_t dest_size, -+ const void __user *src, size_t size, pid_t vm_pid); - - #endif -diff -Naur '--exclude=.git' itrustee_tzdriver/core/session_manager.c itrustee_tzdriver_new/core/session_manager.c ---- itrustee_tzdriver/core/session_manager.c 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/core/session_manager.c 2023-08-01 13:16:56.748000000 +0800 -@@ -792,16 +792,30 @@ - if (memcpy_s(params->mb_load_mem + sizeof(load_flag), - params->mb_load_size - sizeof(load_flag), - params->file_buffer + loaded_size, load_size) != 0) { -- tloge("memcpy file buf get fail\n"); -+ tloge("memcpy file buf get failed \n"); - return -EFAULT; - } - return 0; - } -- if (copy_from_user(params->mb_load_mem + sizeof(load_flag), -- (const void __user *)params->file_buffer + loaded_size, load_size)) { -- tloge("file buf get fail\n"); -- return -EFAULT; -+ -+ if (params->dev_file->isVM) { -+ tlogd("is VM \n"); -+ if (read_from_VMclient(params->mb_load_mem + sizeof(load_flag), -+ load_size, (const void __user *)params->file_buffer + loaded_size, -+ load_size, (pid_t)params->dev_file->nsid)) { -+ tloge("file buf get failed \n"); -+ tlogd("file buf get failed \n"); -+ return -EFAULT; -+ } -+ } else { -+ tlogd("is not VM \n"); -+ if (copy_from_user(params->mb_load_mem + sizeof(load_flag), -+ (const void __user *)params->file_buffer + loaded_size, load_size)) { -+ tloge("file buf get failed \n"); -+ return -EFAULT; -+ } - } -+ - return 0; - } - -@@ -830,10 +844,8 @@ - params->mb_load_size); - return -EINVAL; - } -- - if (load_image_copy_file(params, load_size, load_flag, loaded_size) != 0) - return -EFAULT; -- - pack_load_frame_cmd(load_size, params, &smc_cmd); - params->mb_pack->operation.params[3].value.a = index; - params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type; -@@ -845,8 +857,9 @@ - tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n", - params->mb_pack->operation.params[1].value.a, smc_ret, - load_flag, index); -- -+ tlogd("after tc_ns_smc \n"); - if (smc_ret != 0) { -+ tloge("smc_ret = %d \n",smc_ret); - if (tee_ret != NULL) { - tee_ret->code = smc_ret; - tee_ret->origin = smc_cmd.err_origin; -@@ -857,7 +870,7 @@ - - if (!smc_ret && !load_flag && load_image_for_ion(params, tee_ret ? &tee_ret->origin : NULL)) - return -EPERM; -- -+ tlogd("before return \n"); - loaded_size += load_size; - } - return 0; -@@ -1379,10 +1392,119 @@ - return ret; - } - -+static int process_vm_ref(struct tc_ns_dev_file *dev_file, -+ struct tc_ns_client_context *context, unsigned long long *vm_buffers, -+ unsigned long long *kn_buffers) -+{ -+ struct tc_ns_shared_mem *shared_mem = NULL; -+ int index = 0; -+ uint32_t buffer_size; -+ unsigned int offset = 0; -+ void *buffer_addr = NULL; -+ void *size_addr = NULL; -+ unsigned long long vm_hvas[TEE_PARAM_NUM]={0}; -+ -+ if (!context->file_buffer) { -+ return 0; -+ } -+ -+ if (copy_from_user(vm_hvas, context->file_buffer, context->file_size) != 0) { -+ tloge("copy from user failed\n"); -+ return -EFAULT; -+ } -+ -+ mutex_lock(&dev_file->shared_mem_lock); -+ list_for_each_entry(shared_mem, &dev_file->shared_mem_list, head) { -+ for (index = 0; index < TEE_PARAM_NUM; index++) { -+ buffer_addr = (void *)(uintptr_t)(context->params[index].memref.buffer | -+ ((uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM)); -+ if (shared_mem->user_addr == buffer_addr) { -+ buffer_addr = (void *)(uintptr_t)(shared_mem->kernel_addr); -+ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | -+ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); -+ offset = context->params[index].memref.offset; -+ -+ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), dev_file->nsid)) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } -+ tlogv(" buffer_size = %d \n", buffer_size); -+ tlogv(" "); -+ -+ if (read_from_VMclient(buffer_addr + offset, buffer_size, -+ (uint32_t __user *)(uintptr_t)(vm_hvas[index] + offset), -+ buffer_size, dev_file->nsid)) { -+ tloge("copy memref.buffer failed\n"); -+ return -EFAULT; -+ } -+ vm_buffers[index] = vm_hvas[index]; -+ kn_buffers[index] = (unsigned long long)buffer_addr; -+ } -+ } -+ } -+ mutex_unlock(&dev_file->shared_mem_lock); -+} -+ -+static int process_vm_ref_end(struct tc_ns_dev_file *dev_file, -+ struct tc_ns_client_context *context, unsigned long long *vm_buffers, -+ unsigned long long *kn_buffers) -+{ -+ int ret = 0; -+ int index = 0; -+ uint32_t buffer_size; -+ unsigned int offset = 0; -+ void *size_addr = NULL; -+ for (index = 0; index < TEE_PARAM_NUM; index++) -+ { -+ if (kn_buffers[index] != 0 && vm_buffers[index] != 0) { -+ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | -+ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); -+ -+ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), -+ (uint32_t __user *)(uintptr_t)size_addr, -+ sizeof(uint32_t), dev_file->nsid)) { -+ tloge("copy memref.size_addr failed\n"); -+ return -EFAULT; -+ } -+ offset = context->params[index].memref.offset; -+ -+ tlogv("<--------------------\n"); -+ tlogv(" buffer_size = %d \n", buffer_size); -+ tlogv(" vm_buffers[index] = 0x%16.16lx", (long unsigned int)(vm_buffers[index])); -+ tlogv(" *(kn_buffers[index] + offset) = %s \n", (char*)(kn_buffers[index] + offset)); -+ tlogv(" offset = %ld \n", (long unsigned int)offset); -+ tlogv("-------------------->\n"); -+ -+ if (write_to_VMclient((void *)(uintptr_t)(vm_buffers[index] + offset), -+ buffer_size, (void *)(uintptr_t)(kn_buffers[index] + offset), -+ buffer_size, dev_file->nsid)) { -+ tloge("copy buf size failed\n"); -+ return -EFAULT; -+ } -+ -+ } else if (kn_buffers[index] == 0 && vm_buffers[index] == 0) { -+ /* do nothing*/ -+ ; -+ } else { -+ return -EFAULT; -+ } -+ } -+ return ret; -+} -+ - static int ioctl_session_send_cmd(struct tc_ns_dev_file *dev_file, - struct tc_ns_client_context *context, void *argp) - { - int ret; -+ unsigned long long vm_buffers[TEE_PARAM_NUM]={0}; -+ unsigned long long kn_buffers[TEE_PARAM_NUM]={0}; -+ -+ if (process_vm_ref(dev_file, context, vm_buffers, kn_buffers)) { -+ tloge("copy VM memref failed\n"); -+ return -EFAULT; -+ } - - ret = tc_ns_send_cmd(dev_file, context); - if (ret != 0) -@@ -1391,6 +1513,11 @@ - if (ret == 0) - ret = -EFAULT; - } -+ -+ if (process_vm_ref_end(dev_file, context, vm_buffers, kn_buffers)) { -+ tloge("copy VM memref failed\n"); -+ return -EFAULT; -+ } - return ret; - } - -@@ -1516,3 +1643,4 @@ - mutex_unlock(&dev_list->dev_lock); - return; - } -+ -diff -Naur '--exclude=.git' itrustee_tzdriver/core/tc_client_driver.c itrustee_tzdriver_new/core/tc_client_driver.c ---- itrustee_tzdriver/core/tc_client_driver.c 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/core/tc_client_driver.c 2023-08-01 13:16:56.856000000 +0800 -@@ -307,12 +307,12 @@ - - static int tc_login_check(const struct tc_ns_dev_file *dev_file) - { -- int ret = check_teecd_auth(); -+/* int ret = check_teecd_auth(); - if (ret != 0) { - tloge("teec auth failed, ret %d\n", ret); - return -EACCES; - } -- -+*/ - if (!dev_file) - return -EINVAL; - -@@ -812,6 +812,15 @@ - return ret; - } - -+static int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid) -+{ -+ dev_file->isVM = true; -+ tlogd(" dev_file->isVM %d\n", (int)dev_file->isVM); -+ dev_file->nsid = vmid; -+ tlogd(" dev_file->nsid %d\n", (int)dev_file->nsid); -+ return 0; -+} -+ - void handle_cmd_prepare(unsigned int cmd) - { - if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT && -@@ -831,7 +840,11 @@ - { - int ret = -EFAULT; - void *argp = (void __user *)(uintptr_t)arg; -- handle_cmd_prepare(cmd); -+ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { -+ tlogd(" before set_vm_flag \n"); -+ return set_vm_flag(file->private_data, (int)arg); -+ } -+ handle_cmd_prepare(cmd); - switch (cmd) { - case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION: - ret = tc_ns_get_tee_version(file->private_data, argp); -@@ -851,7 +864,7 @@ - ret = sync_system_time_from_user( - (struct tc_ns_client_time *)(uintptr_t)arg); - break; -- default: -+ default: - ret = public_ioctl(file, cmd, arg, false); - break; - } -@@ -866,8 +879,11 @@ - { - int ret = -EFAULT; - void *argp = (void __user *)(uintptr_t)arg; -- -- handle_cmd_prepare(cmd); -+ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { -+ tlogd(" before set_vm_flag \n"); -+ return set_vm_flag(file->private_data, (int)arg); -+ } -+ handle_cmd_prepare(cmd); - switch (cmd) { - case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ: - case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ: -@@ -883,7 +899,7 @@ - case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: - ret = public_ioctl(file, cmd, arg, true); - break; -- default: -+ default: - ret = tc_client_agent_ioctl(file, cmd, arg); - break; - } -@@ -899,13 +915,13 @@ - int ret; - struct tc_ns_dev_file *dev = NULL; - (void)inode; -- -+/* - ret = check_teecd_auth(); - if (ret != 0) { - tloge("teec auth failed, ret %d\n", ret); - return -EACCES; - } -- -+*/ - file->private_data = NULL; - ret = tc_ns_client_open(&dev, TEE_REQ_FROM_USER_MODE); - if (ret == 0) -diff -Naur '--exclude=.git' itrustee_tzdriver/Makefile itrustee_tzdriver_new/Makefile ---- itrustee_tzdriver/Makefile 2023-08-01 13:44:04.248000000 +0800 -+++ itrustee_tzdriver_new/Makefile 2023-08-01 13:16:56.692000000 +0800 -@@ -37,8 +37,10 @@ - endif - - # you should config right path according to your run-time environment --KPATH := /usr/src/kernels --KDIR := $(KPATH)/$(shell ls $(KPATH)) -+#KPATH := /usr/src/kernels -+#KDIR := $(KPATH)/$(shell ls $(KPATH)) -+KERN_VER = $(shell uname -r) -+KERN_DIR = /lib/modules/$(KERN_VER)/build - - EXTRA_CFLAGS += -isystem /usr/lib/gcc/aarch64-linux-gnu/10.3.1/include - EXTRA_CFLAGS += -fstack-protector-strong -DCONFIG_TEELOG -DCONFIG_TZDRIVER_MODULE -DCONFIG_TEECD_AUTH -DCONFIG_PAGES_MEM=y -DCONFIG_CLOUDSERVER_TEECD_AUTH -@@ -53,7 +55,7 @@ - EXTRA_CFLAGS += -I$(PWD)/tzdriver_internal/tee_reboot - EXTRA_CFLAGS += -DMAILBOX_POOL_COUNT=8 - all: -- make -C $(KDIR) M=$(PWD) modules -+ make -C $(KERN_DIR) M=$(PWD) modules - clean: - -rm -vrf *.o *.ko auth/*.o core/*.o tlogger/*.o - -rm -vrf *.order *.symvers *.mod.c .tmp_versions .*o.cmd auth/.*o.cmd core/.*o.cmd tlogger/.*o.cmd -diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_client.h itrustee_tzdriver_new/tc_ns_client.h ---- itrustee_tzdriver/tc_ns_client.h 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/tc_ns_client.h 2023-08-01 13:16:56.696000000 +0800 -@@ -209,4 +209,7 @@ - #endif - #define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \ - _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info) -+#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG \ -+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) -+ - #endif -diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_log.h itrustee_tzdriver_new/tc_ns_log.h ---- itrustee_tzdriver/tc_ns_log.h 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/tc_ns_log.h 2023-08-01 13:16:57.032000000 +0800 -@@ -32,7 +32,7 @@ - }; - #define MOD_TEE "tzdriver" - --#define TEE_LOG_MASK TZ_DEBUG_INFO -+#define TEE_LOG_MASK TZ_DEBUG_WARN - - #define tlogv(fmt, args...) \ - do { \ -diff -Naur '--exclude=.git' itrustee_tzdriver/teek_ns_client.h itrustee_tzdriver_new/teek_ns_client.h ---- itrustee_tzdriver/teek_ns_client.h 2023-08-01 13:44:04.252000000 +0800 -+++ itrustee_tzdriver_new/teek_ns_client.h 2023-08-01 13:16:56.692000000 +0800 -@@ -133,6 +133,7 @@ - struct completion close_comp; /* for kthread close unclosed session */ - #ifdef CONFIG_TEE_TELEPORT_SUPPORT - bool portal_enabled; -+ bool isVM; - #endif - }; - -- Gitee From 12584b4ea0eb69a74737c5e49b058b695fab2c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:58:59 +0000 Subject: [PATCH 11/12] patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- trustzone-awared-vm/demo/Host/qemu.patch | 779 ++++++++++++++++ trustzone-awared-vm/demo/Host/tzdriver.patch | 889 +++++++++++++++++++ 2 files changed, 1668 insertions(+) create mode 100644 trustzone-awared-vm/demo/Host/qemu.patch create mode 100644 trustzone-awared-vm/demo/Host/tzdriver.patch diff --git a/trustzone-awared-vm/demo/Host/qemu.patch b/trustzone-awared-vm/demo/Host/qemu.patch new file mode 100644 index 0000000..3a8656b --- /dev/null +++ b/trustzone-awared-vm/demo/Host/qemu.patch @@ -0,0 +1,779 @@ +diff -Naur '--exclude=.git' qemu/hw/char/tc_ns_client.h qemu_after/hw/char/tc_ns_client.h +--- qemu/hw/char/tc_ns_client.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tc_ns_client.h 2023-08-01 15:09:17.724000000 +0800 +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved. ++ * Licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef _TC_NS_CLIENT_H_ ++#define _TC_NS_CLIENT_H_ ++#include "tee_client_type.h" ++#define TC_DEBUG ++ ++#define INVALID_TYPE 0x00 ++#define TEECD_CONNECT 0x01 ++#ifndef ZERO_SIZE_PTR ++#define ZERO_SIZE_PTR ((void *)16) ++#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) ++#endif ++ ++#define UUID_SIZE 16 ++ ++#define TC_NS_CLIENT_IOC_MAGIC 't' ++#define TC_NS_CLIENT_DEV "tc_ns_client" ++#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" ++#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private" ++#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm" ++ ++enum ConnectCmd { ++ GET_FD, ++ GET_TEEVERSION, ++ SET_SYS_XML, ++ GET_TEECD_VERSION, ++}; ++ ++typedef struct { ++ unsigned int method; ++ unsigned int mdata; ++} TC_NS_ClientLogin; ++ ++typedef union { ++ struct { ++ unsigned long long buffer; ++ unsigned long long offset; ++ unsigned long long size_addr; ++ } memref; ++ struct { ++ unsigned long long a_addr; ++ unsigned long long b_addr; ++ } value; ++} TC_NS_ClientParam; ++ ++typedef struct { ++ unsigned int code; ++ unsigned int origin; ++} TC_NS_ClientReturn; ++ ++typedef struct { ++ unsigned char uuid[UUID_SIZE]; ++ unsigned int session_id; ++ unsigned int cmd_id; ++ TC_NS_ClientReturn returns; ++ TC_NS_ClientLogin login; ++ TC_NS_ClientParam params[TEEC_PARAM_NUM]; ++ unsigned int paramTypes; ++ bool started; ++ unsigned int callingPid; ++ unsigned int file_size; ++ union { ++ char *file_buffer; ++ struct { ++ uint32_t file_addr; ++ uint32_t file_h_addr; ++ } memref; ++ }; ++} TC_NS_ClientContext; ++ ++typedef struct { ++ uint32_t seconds; ++ uint32_t millis; ++} TC_NS_Time; ++ ++typedef struct { ++ uint16_t tzdriver_version_major; ++ uint16_t tzdriver_version_minor; ++ uint32_t reserved[15]; ++} TC_NS_TEE_Info; ++ ++enum SecFileType { ++ LOAD_TA = 0, ++ LOAD_SERVICE, ++ LOAD_LIB, ++ LOAD_DYNAMIC_DRV, ++ LOAD_PATCH, ++ LOAD_TYPE_MAX ++}; ++ ++struct SecFileInfo { ++ enum SecFileType fileType; ++ uint32_t fileSize; ++ int32_t secLoadErr; ++}; ++ ++struct SecLoadIoctlStruct { ++ struct SecFileInfo secFileInfo; ++ TEEC_UUID uuid; ++ union { ++ char *fileBuffer; ++ struct { ++ uint32_t file_addr; ++ uint32_t file_h_addr; ++ } memref; ++ }; ++}__attribute__((packed)); ++ ++struct AgentIoctlArgs { ++ uint32_t id; ++ uint32_t bufferSize; ++ union { ++ void *buffer; ++ unsigned long long addr; ++ }; ++}; ++ ++#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int) ++#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int) ++#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int) ++#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs) ++#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int) ++#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct) ++#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int) ++#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext) ++#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int) ++#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int) ++#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int) ++#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time) ++#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int) ++#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int) ++#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int) ++#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int) ++#ifdef CONFIG_CMS_SIGNATURE ++#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl) ++#endif ++#ifdef CONFIG_TEE_TELEPORT_SUPPORT ++#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs) ++#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs) ++#endif ++#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info) ++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) ++ ++TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation); ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/tee_client_list.h qemu_after/hw/char/tee_client_list.h +--- qemu/hw/char/tee_client_list.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tee_client_list.h 2023-08-01 14:18:18.616000000 +0800 +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved. ++ * iTrustee licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef TEE_CLIENT_LIST_H ++#define TEE_CLIENT_LIST_H ++ ++struct ListNode { ++ struct ListNode *next; /* point to next node */ ++ struct ListNode *prev; /* point to prev node */ ++}; ++ ++#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member)) ++#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member)) ++ ++#define LIST_DECLARE(name) \ ++ struct ListNode name = { \ ++ .next = &name, \ ++ .prev = &name, \ ++ } ++ ++static inline void ListInit(struct ListNode *list) ++{ ++ list->next = list; ++ list->prev = list; ++} ++ ++#define LIST_HEAD(list) ((list)->next) ++#define LIST_TAIL(list) ((list)->prev) ++#define LIST_EMPTY(list) ((list) == (list)->next) ++ ++static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry) ++{ ++ list->next->prev = entry; ++ entry->next = list->next; ++ entry->prev = list; ++ list->next = entry; ++} ++ ++static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry) ++{ ++ entry->next = list; ++ entry->prev = list->prev; ++ list->prev->next = entry; ++ list->prev = entry; ++} ++ ++static inline void ListRemoveEntry(struct ListNode *entry) ++{ ++ entry->prev->next = entry->next; ++ entry->next->prev = entry->prev; ++} ++ ++static inline struct ListNode *ListRemoveHead(struct ListNode *list) ++{ ++ struct ListNode *entry = NULL; ++ if (!LIST_EMPTY(list)) { ++ entry = list->next; ++ ListRemoveEntry(entry); ++ } ++ return entry; ++} ++ ++static inline struct ListNode *ListRemoveTail(struct ListNode *list) ++{ ++ struct ListNode *entry = NULL; ++ if (!LIST_EMPTY(list)) { ++ entry = list->prev; ++ ListRemoveEntry(entry); ++ } ++ return entry; ++} ++ ++#define LIST_ENTRY(ptr, type, member) \ ++ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) ++ ++#define LIST_FOR_EACH(pos, list) \ ++ for (pos = (list)->next; pos != (list); pos = pos->next) ++ ++#define LIST_FOR_EACH_SAFE(pos, n, list) \ ++ for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next) ++ ++#define LIST_FOR_EACH_ENTRY(pos, list, member) \ ++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \ ++ pos = LIST_ENTRY(pos->member.next, typeof(*pos), member)) ++ ++#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \ ++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \ ++ member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member)) ++ ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/tee_client_type.h qemu_after/hw/char/tee_client_type.h +--- qemu/hw/char/tee_client_type.h 1970-01-01 08:00:00.000000000 +0800 ++++ qemu_after/hw/char/tee_client_type.h 2023-08-01 14:32:33.296000000 +0800 +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved. ++ * Licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef _TEE_CLIENT_TYPE_H_ ++#define _TEE_CLIENT_TYPE_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include "tee_client_list.h" ++#include "tee_client_constants.h" ++ ++typedef enum TEEC_ReturnCode TEEC_Result; ++ ++typedef struct { ++ uint32_t timeLow; ++ uint16_t timeMid; ++ uint16_t timeHiAndVersion; ++ uint8_t clockSeqAndNode[8]; ++} TEEC_UUID; ++ ++typedef struct { ++ int32_t fd; ++ uint8_t *ta_path; ++ struct ListNode session_list; ++ struct ListNode shrd_mem_list; ++ union { ++ struct { ++ void *buffer; ++ sem_t buffer_barrier; ++ } share_buffer; ++ uint64_t imp; /* for adapt */ ++ }; ++} TEEC_Context; ++ ++typedef struct { ++ uint32_t session_id; ++ TEEC_UUID service_id; ++ uint32_t ops_cnt; ++ union { ++ struct ListNode head; ++ uint64_t imp; /* for adapt */ ++ }; ++ TEEC_Context *context; ++} TEEC_Session; ++ ++typedef struct { ++ void *buffer; ++ uint32_t size; ++ uint32_t flags; /* reference to TEEC_SharedMemCtl */ ++ uint32_t ops_cnt; ++ bool is_allocated; /* identify whether the memory is registered or allocated */ ++ union { ++ struct ListNode head; ++ void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */ ++ }; ++ TEEC_Context *context; ++} TEEC_SharedMemory; ++ ++/* ++ * the corresponding param types are ++ * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT ++ */ ++typedef struct { ++ void *buffer; ++ uint32_t size; ++} TEEC_TempMemoryReference; ++ ++/* ++ * the corresponding param types are ++ * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT ++ * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT ++ */ ++typedef struct { ++ TEEC_SharedMemory *parent; ++ uint32_t size; ++ uint32_t offset; ++} TEEC_RegisteredMemoryReference; ++ ++/* ++ * the corresponding param types are ++ * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT ++ */ ++typedef struct { ++ uint32_t a; ++ uint32_t b; ++} TEEC_Value; ++ ++typedef struct { ++ int ion_share_fd; ++ uint32_t ion_size; ++} TEEC_IonReference; ++ ++typedef union { ++ TEEC_TempMemoryReference tmpref; ++ TEEC_RegisteredMemoryReference memref; ++ TEEC_Value value; ++ TEEC_IonReference ionref; ++} TEEC_Parameter; ++ ++typedef struct { ++ uint32_t event_type; /* Tui event type */ ++ uint32_t value; /* return value, is keycode if tui event is getKeycode */ ++ uint32_t notch; /* notch size of the screen for tui */ ++ uint32_t width; /* width of foldable screen */ ++ uint32_t height; /* height of foldable screen */ ++ uint32_t fold_state; /* state of foldable screen */ ++ uint32_t display_state; /* one state of folded state */ ++ uint32_t phy_width; /* real width of the mobile */ ++ uint32_t phy_height; /* real height of the mobile */ ++} TEEC_TUI_Parameter; ++ ++typedef struct { ++ uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */ ++ uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */ ++ TEEC_Parameter params[TEEC_PARAM_NUM]; ++ TEEC_Session *session; ++ bool cancel_flag; ++} TEEC_Operation; ++ ++#endif ++ ++ +diff -Naur '--exclude=.git' qemu/hw/char/virtio-console.c qemu_after/hw/char/virtio-console.c +--- qemu/hw/char/virtio-console.c 2023-08-01 14:07:32.320000000 +0800 ++++ qemu_after/hw/char/virtio-console.c 2023-08-01 14:18:18.616000000 +0800 +@@ -20,6 +20,14 @@ + #include "qapi/error.h" + #include "qapi/qapi-events-char.h" + ++#include "qom/object.h" ++#include "hw/core/cpu.h" ++#include "sysemu/hw_accel.h" ++#include "monitor/monitor.h" ++#include ++#include ++#include "tc_ns_client.h" ++ + #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport" + #define VIRTIO_CONSOLE(obj) \ + OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT) +@@ -45,6 +53,106 @@ + return FALSE; + } + ++ ++#define DEBUG 1 ++ ++#ifdef DEBUG ++static void debug(const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ vfprintf(stderr, fmt, args); ++ va_end(args); ++} ++ ++#define PRINTF_SIZE 16 ++static void dump_buff(const char *buffer, size_t bufLen) ++{ ++ size_t i; ++ if (buffer == NULL || bufLen == 0) { ++ return; ++ } ++ ++ // printf("\n--------------------------------------------------\n"); ++ printf("--------------------------------------------------\n"); ++ printf("bufLen = %d\n", (int)bufLen); ++ for (i = 0; i < bufLen; i++) { ++ if (i % PRINTF_SIZE == 0 && i != 0) { ++ printf("\n"); ++ } ++ printf("%02x ", *(buffer + i)); ++ } ++ printf("\n--------------------------------------------------\n"); ++ return; ++} ++#else ++#define debug(fmt, ...) do { } while (0) ++ ++#define dump_buff(buffer, bufLen) do { } while (0) ++#endif ++ ++#define VTZF_OPEN_TZD 15 ++#define VTZF_OPEN_SESSION 31 ++#define VTZF_SEND_CMD 33 ++#define VTZF_LOAD_SEC 53 ++ ++#define TEEC_PARAM_NUM 4 /* teec param max number */ ++ ++#define IS_TEMP_MEM(paramType) \ ++ (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \ ++ ((paramType) == TEEC_MEMREF_TEMP_INOUT)) ++ ++#define IS_PARTIAL_MEM(paramType) \ ++ (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \ ++ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT)) ++ ++#define IS_VALUE_MEM(paramType) \ ++ (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT)) ++ ++#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ ++ (((paramTypes) >> (4*(index))) & 0x0F) ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ uint32_t seq_num; // second ++ uint32_t vmid; ++ uint32_t flag; ++} struct_packet_cmd_open_tzd; ++ ++typedef struct { ++ uint32_t cmd; ++ uint32_t seq_num; ++ __s32 ptzfd; ++ __s32 cpu_index; ++ struct SecLoadIoctlStruct ioctlArg; ++} struct_packet_cmd_load_sec; ++ ++typedef struct { ++ uint32_t cmd; ++ uint32_t seq_num; ++ int32_t ptzfd; ++ int32_t cpu_index; ++ TC_NS_ClientContext cliContext; ++} struct_packet_cmd_session; ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ int32_t ptzfd; // 4, 8 bytes ++ int32_t cpu_index; // 4, 12 bytes ++ unsigned long long addrs[TEEC_PARAM_NUM]; ++ TC_NS_ClientContext cliContext; ++} struct_vtzf_packet_cmd_send_cmd; ++ ++typedef struct { ++ uint32_t cmd; // 4, 4 bytes ++ __s32 ptzfd; // 4, 8 bytes ++ uint64_t buffer; // 8, 16 bytes ++ uint32_t size; // 4, 20 bytes ++ uint32_t offset; // 4, 24 bytes ++}struct_vtzf_packet_cmd_mmap; ++ ++ + /* Callback function that's called when the guest sends us data */ + static ssize_t flush_buf(VirtIOSerialPort *port, + const uint8_t *buf, ssize_t len) +@@ -57,7 +165,201 @@ + return len; + } + +- ret = qemu_chr_fe_write(&vcon->chr, buf, len); ++ uint8_t buf01[90 * 1024]; ++ memcpy(buf01, buf, len); ++ ++ debug("\n"); ++ debug("debug, %s, %s, %d \n", __FILE__, __func__, __LINE__); ++ debug(" virtio-console virtserialport name = %s, id = %d \n", port->name, (int)port->id); ++ debug(" have_data flush_buf, buflen = %d \n", len); ++ // dump_buff((char *)buf, len); ++ dump_buff((char *)buf, 0); ++ ++ if ( len >= 4 ) { ++ uint32_t ui32_cmd; ++ ui32_cmd = 0; ++ //struct_vtzf_packet_cmd *vtzf_packet_cmd; ++ ++ uint32_t ui32_tmp; ++ int i; ++ for (i = 0; i < 4; i++) ++ { ++ ui32_tmp = buf[i]; ++ ui32_tmp = ui32_tmp << (i * 8); ++ ui32_cmd = ui32_cmd | ui32_tmp; ++ } ++ ++ switch( ui32_cmd ) ++ { ++ case VTZF_OPEN_TZD: ++ debug(" command is VTZF_OPEN_TZD \n"); ++ if ( len >= sizeof(struct_packet_cmd_open_tzd)) { ++ struct_packet_cmd_open_tzd* vtzf_packet_cmd = (struct_packet_cmd_open_tzd *)buf01; ++ pid_t qemu_pid = getpid(); ++ debug(" qemu_pid = 0x%016lx, %d \n",qemu_pid, qemu_pid); ++ vtzf_packet_cmd->vmid = qemu_pid; ++ } ++ break; ++ case VTZF_LOAD_SEC: ++ debug(" command is VTZF_LOAD_SEC \n"); ++ if (len >= sizeof(struct_packet_cmd_load_sec)) { ++ struct_packet_cmd_load_sec* vtzf_packet_cmd = (struct_packet_cmd_load_sec *)buf01; ++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->ioctlArg.fileBuffer); ++ ++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->ioctlArg.fileBuffer; ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ ptr_hva = gpa2hva(&mr, gpa, &local_err); ++ if (local_err) { ++ debug(" gpa2hva failed \n"); ++ } else { ++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ ++ memory_region_unref(mr); ++ ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->ioctlArg.fileBuffer = (void *)ui64_hva; ++ } ++ } ++ break; ++ case VTZF_OPEN_SESSION: ++ debug(" command is VTZF_OPEN_SESSION \n"); ++ debug("sizeof(struct_packet_cmd_session) =%d \n", sizeof(struct_packet_cmd_session)); ++ debug("sizeof(TC_NS_ClientContext) =%d \n", sizeof(TC_NS_ClientContext)); ++ if ( len >= sizeof(struct_packet_cmd_session) ) { ++ struct_packet_cmd_session* vtzf_packet_cmd = (struct_packet_cmd_session *)buf01; ++ ++ debug(" vtzf_packet_cmd->cliContext.file_size = 0x%08x, %d \n", vtzf_packet_cmd->cliContext.file_size, ++ vtzf_packet_cmd->cliContext.file_size); ++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->cliContext.file_buffer); ++ ++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->cliContext.file_buffer; ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ ptr_hva = gpa2hva(&mr, gpa, &local_err); ++ if (local_err) { ++ debug(" gpa2hva failed \n"); ++ } else { ++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ ++ memory_region_unref(mr); ++ ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.file_buffer = (void *)ui64_hva; ++ } ++ } ++ break; ++ case VTZF_SEND_CMD: ++ debug(" command is VTZF_SEND_CMD \n"); ++ if ( len >= sizeof(struct_vtzf_packet_cmd_send_cmd) ) { ++ struct_vtzf_packet_cmd_send_cmd* vtzf_packet_cmd = (struct_vtzf_packet_cmd_send_cmd *)buf01; ++ ++ Error *local_err = NULL; ++ MemoryRegion *mr = NULL; ++ void *ptr_hva; ++ ++ uint32_t param_type; ++ bool check_value; ++ hwaddr gpa_param; ++ ++ for (i = 0; i < TEEC_PARAM_NUM; i++) { ++ param_type = TEEC_PARAM_TYPE_GET(vtzf_packet_cmd->cliContext.paramTypes, i); ++ check_value = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); ++ if (IS_TEMP_MEM(param_type)) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.buffer failed \n", i); ++ } else { ++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); ++ } else { ++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; ++ } ++ ++ } else if (IS_PARTIAL_MEM(param_type)) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.buffer failed \n", i); ++ } else { ++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i); ++ } else { ++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva; ++ } ++ ++ } else if (IS_VALUE_MEM(param_type) || check_value) { ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.a_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].value.a_addr failed \n", i); ++ } else { ++ debug(" host virtual address of value.a_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].value.a_addr = ui64_hva; ++ } ++ ++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.b_addr; ++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err); ++ if (local_err) { ++ debug(" gpa2hva params[%d].value.b_addr failed \n", i); ++ } else { ++ debug(" host virtual address of value.b_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva); ++ memory_region_unref(mr); ++ uint64_t ui64_hva; ++ ui64_hva = (uint64_t)ptr_hva; ++ vtzf_packet_cmd->cliContext.params[i].value.b_addr = ui64_hva; ++ } ++ ++ } else { ++ /* if type is none, ignore it */ ++ } ++ }// end for ++ ++ }//end if ++ break; ++ default: ++ debug(" other command \n"); ++ } ++ ++ } // end of if ( len >= 4 ) ++ ++ ret = qemu_chr_fe_write(&vcon->chr, buf01, len); + trace_virtio_console_flush_buf(port->id, len, ret); + + if (ret < len) { +@@ -304,3 +606,4 @@ + } + + type_init(virtconsole_register_types) ++ +diff -Naur '--exclude=.git' qemu/include/monitor/monitor.h qemu_after/include/monitor/monitor.h +--- qemu/include/monitor/monitor.h 2023-08-01 14:07:32.384000000 +0800 ++++ qemu_after/include/monitor/monitor.h 2023-08-01 14:18:18.664000000 +0800 +@@ -4,6 +4,7 @@ + #include "block/block.h" + #include "qapi/qapi-types-misc.h" + #include "qemu/readline.h" ++#include "exec/hwaddr.h" + + extern __thread Monitor *cur_mon; + typedef struct MonitorHMP MonitorHMP; +@@ -36,6 +37,8 @@ + int monitor_set_cpu(int cpu_index); + int monitor_get_cpu_index(void); + ++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp); ++ + void monitor_read_command(MonitorHMP *mon, int show_prompt); + int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func, + void *opaque); +@@ -49,3 +52,4 @@ + int64_t monitor_fdset_dup_fd_find(int dup_fd); + + #endif /* MONITOR_H */ ++ +diff -Naur '--exclude=.git' qemu/monitor/misc.c qemu_after/monitor/misc.c +--- qemu/monitor/misc.c 2023-08-01 14:07:32.404000000 +0800 ++++ qemu_after/monitor/misc.c 2023-08-01 14:18:18.684000000 +0800 +@@ -674,7 +674,7 @@ + memory_dump(mon, count, format, size, addr, 1); + } + +-static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) ++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) + { + MemoryRegionSection mrs = memory_region_find(get_system_memory(), + addr, 1); diff --git a/trustzone-awared-vm/demo/Host/tzdriver.patch b/trustzone-awared-vm/demo/Host/tzdriver.patch new file mode 100644 index 0000000..7066b16 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/tzdriver.patch @@ -0,0 +1,889 @@ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.c itrustee_tzdriver_new/core/gp_ops.c +--- itrustee_tzdriver/core/gp_ops.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/gp_ops.c 2023-08-01 13:16:56.800000000 +0800 +@@ -312,6 +312,148 @@ + return 0; + } + ++ ++int read_from_VMclient(void *dest, size_t dest_size, ++ const void __user *src, size_t size, pid_t vm_pid) ++{ ++ struct task_struct *vmp_task; ++ int i_rdlen; ++ int i_index; ++ int ret; ++ ++ if (!dest || !src) { ++ tloge("src or dest is NULL input buffer\n"); ++ return -EINVAL; ++ } ++ ++ if (size > dest_size) { ++ tloge("size is larger than dest_size or size is 0\n"); ++ return -EINVAL; ++ } ++ if (!size) ++ return 0; ++ ++ tlogv("django verbose, execute access_process_vm"); ++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID); ++ if (vmp_task == NULL) { ++ tloge("no task for pid %d \n", vm_pid); ++ return -EFAULT; ++ } ++ tlogv("django verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); ++ ++ i_rdlen = access_process_vm(vmp_task, (unsigned long)(src), dest, size, FOLL_FORCE); ++ if (i_rdlen != size) { ++ tloge("only read %d of %ld bytes by access_process_vm \n", i_rdlen, size); ++ return -EFAULT; ++ } ++ tlogv("django verbose, read %d byes by access_process_vm succeed", ++ i_rdlen); ++ for (i_index = 0; i_index < 32 && i_index < size; i_index ++) { ++ tlogv("django verbose, *(dest + i_index) + %d) = %2.2x", ++ i_index, *((char*)dest + i_index)); ++ } ++ return 0; ++} ++ ++#define PINED_PAGE_NUMBER 1 ++ ++int write_to_VMclient(void __user *dest, size_t dest_size, ++ const void *src, size_t size, pid_t vm_pid) ++{ ++ int ret = 0; ++ ++ struct task_struct *vmp_task; ++ struct pid *pid; ++ struct mm_struct *mm; ++ ++ unsigned long ul_offset; ++ ++ unsigned long user_addr; ++ struct page *ptr_page; ++ struct vm_area_struct *vmap_01; ++ void *kern_addr; ++ ++ tlogv("wcz verbose, start execute vtz_write_to_client \n"); ++ ++ if (!dest || !src) { ++ tloge("src or dest is NULL input buffer\n"); ++ return -EINVAL; ++ } ++ ++ if (size > dest_size) { ++ tloge("size is larger than dest_size\n"); ++ return -EINVAL; ++ } ++ ++ if (!size) ++ return 0; ++ ++ pid = find_get_pid(vm_pid); ++ vmp_task = get_pid_task(pid, PIDTYPE_PID); ++ if (vmp_task == NULL) { ++ tloge("no task for pid %d", vm_pid); ++ return -EFAULT; ++ } ++ tlogv("wcz verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task); ++ ++ mm = vmp_task->mm; ++ user_addr = (unsigned long)dest; ++ ++ #if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) ++ ret = get_user_pages_remote(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, ++ &ptr_page, &vmap_01, NULL); ++ #elif (KERNEL_VERSION(4, 4, 197) <= LINUX_VERSION_CODE) ++ ret = get_user_pages_locked(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, FOLL_FORCE, &ptr_page, &vmap_01); ++ #else ++ ret = get_user_pages_locked(vmp_task, mm, user_addr, ++ (unsigned long)PINED_PAGE_NUMBER, 1, 1, &ptr_page, &vmap_01); ++ #endif ++ if (ret != PINED_PAGE_NUMBER) { ++ tloge("get user pages failed, ret = %d\n", ret); ++ ret = -EFAULT; ++ goto putpid; ++ } ++ ++ ul_offset = user_addr & (PAGE_SIZE - 1); ++ tlogv("django verbose, offset in the physical page for user address 0x%016lx is 0x%016lx \n", user_addr, ul_offset); ++ ++ if (ul_offset >= PAGE_SIZE) { ++ ul_offset = 0; ++ } ++ ++ tlogv("django verbose, ul_offset = %ld, 0x%016lx \n", ul_offset, ul_offset); ++ ++ kern_addr = kmap_atomic(ptr_page); ++ ++ if (!kern_addr) { ++ tloge("failed to kmap page 0x%016lx \n", (unsigned long)ptr_page); ++ ret = -EFAULT; ++ goto putpage; ++ } ++ tlogv("succeed to kmap page 0x%016lx, kern virtual address = 0x%016lx \n", ++ (unsigned long)ptr_page, (unsigned long)kern_addr); ++ ++ ret = memcpy_s(kern_addr + ul_offset, dest_size, src, size); ++ if (ret != EOK) { ++ tloge("vtz_write to client, memcpy_s fail, ret=%d\n", ret); ++ goto kunmappage; ++ } ++ ++kunmappage: ++ kunmap_atomic(kern_addr); ++ ++putpage: ++ set_page_dirty_lock(ptr_page); ++ put_page(ptr_page); ++ ++putpid: ++ put_pid(pid); ++ ++ return ret; ++} ++ + static bool is_input_tempmem(unsigned int param_type) + { + if (param_type == TEEC_MEMREF_TEMP_INPUT || +@@ -321,7 +463,8 @@ + return false; + } + +-static int update_input_data(const union tc_ns_client_param *client_param, ++static int update_input_data(const struct tc_call_params *call_params, ++ const union tc_ns_client_param *client_param, + uint32_t buffer_size, void *temp_buf, + unsigned int param_type, uint8_t kernel_params) + { +@@ -331,11 +474,22 @@ + + buffer_addr = client_param->memref.buffer | + ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(temp_buf, buffer_size, +- (void *)(uintptr_t)buffer_addr, +- buffer_size, kernel_params) != 0) { +- tloge("copy memref buffer failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM\n"); ++ if (read_from_VMclient(temp_buf, buffer_size, ++ (void *)(uintptr_t)buffer_addr, ++ buffer_size, call_params->dev->nsid) != 0) { ++ tloge("copy memref buffer failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (read_from_client(temp_buf, buffer_size, ++ (void *)(uintptr_t)buffer_addr, ++ buffer_size, kernel_params) != 0) { ++ tloge("copy memref buffer failed\n"); ++ return -EFAULT; ++ } + } + return 0; + } +@@ -361,11 +515,22 @@ + client_param = &(call_params->context->params[index]); + size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(&buffer_size, sizeof(buffer_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(uint32_t), kernel_params) != 0) { +- tloge("copy memref.size_addr failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd(" is VM\n "); ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), call_params->dev->nsid) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ } else{ ++ tlogd(" is not VM "); ++ if (read_from_client(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), kernel_params) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } + } + + if (buffer_size > MAX_SHARED_SIZE) { +@@ -393,7 +558,7 @@ + op_params->local_tmpbuf[index].temp_buffer = temp_buf; + op_params->local_tmpbuf[index].size = buffer_size; + +- if (update_input_data(client_param, buffer_size, temp_buf, ++ if (update_input_data(call_params, client_param, buffer_size, temp_buf, + param_type, kernel_params) != 0) + return -EFAULT; + +@@ -405,17 +570,31 @@ + return 0; + } + +-static int check_buffer_for_ref(uint32_t *buffer_size, +- const union tc_ns_client_param *client_param, uint8_t kernel_params) ++static int check_buffer_for_ref(const struct tc_call_params *call_params, ++ uint32_t *buffer_size, const union tc_ns_client_param *client_param, ++ uint8_t kernel_params) + { + uint64_t size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); +- if (read_from_client(buffer_size, sizeof(*buffer_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(uint32_t), kernel_params) != 0) { +- tloge("copy memref.size_addr failed\n"); +- return -EFAULT; ++ ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM\n"); ++ if (read_from_VMclient(buffer_size, sizeof(*buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), call_params->dev->nsid) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (read_from_client(buffer_size, sizeof(*buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), kernel_params) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } + } ++ + if (*buffer_size == 0) { + tloge("buffer_size from user is 0\n"); + return -ENOMEM; +@@ -497,7 +676,7 @@ + return -EINVAL; + + client_param = &(call_params->context->params[index]); +- if (check_buffer_for_ref(&buffer_size, client_param, kernel_params) != 0) ++ if (check_buffer_for_ref(call_params, &buffer_size, client_param, kernel_params) != 0) + return -EINVAL; + + op_params->mb_pack->operation.params[index].memref.buffer = 0; +@@ -651,21 +830,42 @@ + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + +- if (read_from_client(&operation->params[index].value.a, +- sizeof(operation->params[index].value.a), +- (void *)(uintptr_t)a_addr, +- sizeof(operation->params[index].value.a), +- kernel_params) != 0) { +- tloge("copy valuea failed\n"); +- return -EFAULT; +- } +- if (read_from_client(&operation->params[index].value.b, +- sizeof(operation->params[index].value.b), +- (void *)(uintptr_t)b_addr, +- sizeof(operation->params[index].value.b), +- kernel_params) != 0) { +- tloge("copy valueb failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !kernel_params) { ++ tlogd("is VM \n"); ++ if (read_from_VMclient(&operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ (void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->nsid) != 0) { ++ tloge("copy valuea failed\n"); ++ return -EFAULT; ++ } ++ if (read_from_VMclient(&operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ (void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->nsid) != 0) { ++ tloge("copy valueb failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM \n"); ++ if (read_from_client(&operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ (void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ kernel_params) != 0) { ++ tloge("copy valuea failed\n"); ++ return -EFAULT; ++ } ++ if (read_from_client(&operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ (void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ kernel_params) != 0) { ++ tloge("copy valueb failed\n"); ++ return -EFAULT; ++ } + } + + /* TEEC_VALUE_INPUT equal to TEE_PARAM_TYPE_VALUE_INPUT */ +@@ -754,12 +954,24 @@ + buffer_addr = client_param->memref.buffer | + ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM); + /* Size is updated all the time */ +- if (write_to_client((void *)(uintptr_t)size_addr, +- sizeof(buffer_size), +- &buffer_size, sizeof(buffer_size), +- call_params->dev->kernel_api) != 0) { +- tloge("copy tempbuf size failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM\n"); ++ if (write_to_VMclient((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->nsid) != 0) { ++ tloge("copy tempbuf size failed\n"); ++ return -EFAULT; ++ } ++ }else{ ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy tempbuf size failed\n"); ++ return -EFAULT; ++ } + } + if (buffer_size > op_params->local_tmpbuf[index].size) { + /* incomplete case, when the buffer size is invalid see next param */ +@@ -775,13 +987,26 @@ + if (buffer_size == 0) + return 0; + /* Only update the buffer when the buffer size is valid in complete case */ +- if (write_to_client((void *)(uintptr_t)buffer_addr, +- operation->params[index].memref.size, +- op_params->local_tmpbuf[index].temp_buffer, +- operation->params[index].memref.size, +- call_params->dev->kernel_api) != 0) { +- tloge("copy tempbuf failed\n"); +- return -ENOMEM; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM\n"); ++ if (write_to_VMclient((void *)(uintptr_t)buffer_addr, ++ operation->params[index].memref.size, ++ op_params->local_tmpbuf[index].temp_buffer, ++ operation->params[index].memref.size, ++ call_params->dev->nsid) != 0) { ++ tloge("copy tempbuf failed\n"); ++ return -ENOMEM; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)buffer_addr, ++ operation->params[index].memref.size, ++ op_params->local_tmpbuf[index].temp_buffer, ++ operation->params[index].memref.size, ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy tempbuf failed\n"); ++ return -ENOMEM; ++ } + } + return 0; + } +@@ -806,22 +1031,38 @@ + size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); + +- if (read_from_client(&orig_size, +- sizeof(orig_size), +- (uint32_t __user *)(uintptr_t)size_addr, +- sizeof(orig_size), call_params->dev->kernel_api) != 0) { +- tloge("copy orig memref.size_addr failed\n"); +- return -EFAULT; +- } ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ if (read_from_VMclient(&orig_size, sizeof(orig_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(orig_size), call_params->dev->nsid) != 0) { ++ tloge("copy orig memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ ++ if (write_to_VMclient((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->nsid) != 0) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ if (read_from_client(&orig_size, ++ sizeof(orig_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(orig_size), call_params->dev->kernel_api) != 0) { ++ tloge("copy orig memref.size_addr failed\n"); ++ return -EFAULT; ++ } + +- if (write_to_client((void *)(uintptr_t)size_addr, +- sizeof(buffer_size), +- &buffer_size, sizeof(buffer_size), +- call_params->dev->kernel_api) != 0) { +- tloge("copy buf size failed\n"); +- return -EFAULT; ++ if (write_to_client((void *)(uintptr_t)size_addr, ++ sizeof(buffer_size), ++ &buffer_size, sizeof(buffer_size), ++ call_params->dev->kernel_api) != 0) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } + } +- + /* reserved memory no need to copy */ + if (operation->sharemem[index]->mem_type == RESERVED_TYPE) + return 0; +@@ -859,21 +1100,42 @@ + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + +- if (write_to_client((void *)(uintptr_t)a_addr, +- sizeof(operation->params[index].value.a), +- &operation->params[index].value.a, +- sizeof(operation->params[index].value.a), +- call_params->dev->kernel_api) != 0) { +- tloge("inc copy value.a_addr failed\n"); +- return -EFAULT; +- } +- if (write_to_client((void *)(uintptr_t)b_addr, +- sizeof(operation->params[index].value.b), +- &operation->params[index].value.b, +- sizeof(operation->params[index].value.b), +- call_params->dev->kernel_api) != 0) { +- tloge("inc copy value.b_addr failed\n"); +- return -EFAULT; ++ if (call_params->dev->isVM && !call_params->dev->kernel_api) { ++ tlogd("is VM \n"); ++ if (write_to_VMclient((void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ &operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->nsid) != 0) { ++ tloge("inc copy value.a_addr failed\n"); ++ return -EFAULT; ++ } ++ if (write_to_VMclient((void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ &operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->nsid) != 0) { ++ tloge("inc copy value.b_addr failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM\n"); ++ if (write_to_client((void *)(uintptr_t)a_addr, ++ sizeof(operation->params[index].value.a), ++ &operation->params[index].value.a, ++ sizeof(operation->params[index].value.a), ++ call_params->dev->kernel_api) != 0) { ++ tloge("inc copy value.a_addr failed\n"); ++ return -EFAULT; ++ } ++ if (write_to_client((void *)(uintptr_t)b_addr, ++ sizeof(operation->params[index].value.b), ++ &operation->params[index].value.b, ++ sizeof(operation->params[index].value.b), ++ call_params->dev->kernel_api) != 0) { ++ tloge("inc copy value.b_addr failed\n"); ++ return -EFAULT; ++ } + } + return 0; + } +@@ -1248,3 +1510,5 @@ + release_tc_call_resource(call_params, &op_params, tee_ret); + return ret; + } ++ ++ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/gp_ops.h itrustee_tzdriver_new/core/gp_ops.h +--- itrustee_tzdriver/core/gp_ops.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/gp_ops.h 2023-08-01 13:16:56.848000000 +0800 +@@ -30,5 +30,9 @@ + bool is_tmp_mem(uint32_t param_type); + bool is_ref_mem(uint32_t param_type); + bool is_val_param(uint32_t param_type); ++int write_to_VMclient(void __user *dest, size_t dest_size, ++ const void *src, size_t size, pid_t vm_pid); ++int read_from_VMclient(void *dest, size_t dest_size, ++ const void __user *src, size_t size, pid_t vm_pid); + + #endif +diff -Naur '--exclude=.git' itrustee_tzdriver/core/session_manager.c itrustee_tzdriver_new/core/session_manager.c +--- itrustee_tzdriver/core/session_manager.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/session_manager.c 2023-08-01 13:16:56.748000000 +0800 +@@ -792,16 +792,30 @@ + if (memcpy_s(params->mb_load_mem + sizeof(load_flag), + params->mb_load_size - sizeof(load_flag), + params->file_buffer + loaded_size, load_size) != 0) { +- tloge("memcpy file buf get fail\n"); ++ tloge("memcpy file buf get failed \n"); + return -EFAULT; + } + return 0; + } +- if (copy_from_user(params->mb_load_mem + sizeof(load_flag), +- (const void __user *)params->file_buffer + loaded_size, load_size)) { +- tloge("file buf get fail\n"); +- return -EFAULT; ++ ++ if (params->dev_file->isVM) { ++ tlogd("is VM \n"); ++ if (read_from_VMclient(params->mb_load_mem + sizeof(load_flag), ++ load_size, (const void __user *)params->file_buffer + loaded_size, ++ load_size, (pid_t)params->dev_file->nsid)) { ++ tloge("file buf get failed \n"); ++ tlogd("file buf get failed \n"); ++ return -EFAULT; ++ } ++ } else { ++ tlogd("is not VM \n"); ++ if (copy_from_user(params->mb_load_mem + sizeof(load_flag), ++ (const void __user *)params->file_buffer + loaded_size, load_size)) { ++ tloge("file buf get failed \n"); ++ return -EFAULT; ++ } + } ++ + return 0; + } + +@@ -830,10 +844,8 @@ + params->mb_load_size); + return -EINVAL; + } +- + if (load_image_copy_file(params, load_size, load_flag, loaded_size) != 0) + return -EFAULT; +- + pack_load_frame_cmd(load_size, params, &smc_cmd); + params->mb_pack->operation.params[3].value.a = index; + params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type; +@@ -845,8 +857,9 @@ + tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n", + params->mb_pack->operation.params[1].value.a, smc_ret, + load_flag, index); +- ++ tlogd("after tc_ns_smc \n"); + if (smc_ret != 0) { ++ tloge("smc_ret = %d \n",smc_ret); + if (tee_ret != NULL) { + tee_ret->code = smc_ret; + tee_ret->origin = smc_cmd.err_origin; +@@ -857,7 +870,7 @@ + + if (!smc_ret && !load_flag && load_image_for_ion(params, tee_ret ? &tee_ret->origin : NULL)) + return -EPERM; +- ++ tlogd("before return \n"); + loaded_size += load_size; + } + return 0; +@@ -1379,10 +1392,119 @@ + return ret; + } + ++static int process_vm_ref(struct tc_ns_dev_file *dev_file, ++ struct tc_ns_client_context *context, unsigned long long *vm_buffers, ++ unsigned long long *kn_buffers) ++{ ++ struct tc_ns_shared_mem *shared_mem = NULL; ++ int index = 0; ++ uint32_t buffer_size; ++ unsigned int offset = 0; ++ void *buffer_addr = NULL; ++ void *size_addr = NULL; ++ unsigned long long vm_hvas[TEE_PARAM_NUM]={0}; ++ ++ if (!context->file_buffer) { ++ return 0; ++ } ++ ++ if (copy_from_user(vm_hvas, context->file_buffer, context->file_size) != 0) { ++ tloge("copy from user failed\n"); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&dev_file->shared_mem_lock); ++ list_for_each_entry(shared_mem, &dev_file->shared_mem_list, head) { ++ for (index = 0; index < TEE_PARAM_NUM; index++) { ++ buffer_addr = (void *)(uintptr_t)(context->params[index].memref.buffer | ++ ((uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM)); ++ if (shared_mem->user_addr == buffer_addr) { ++ buffer_addr = (void *)(uintptr_t)(shared_mem->kernel_addr); ++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | ++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); ++ offset = context->params[index].memref.offset; ++ ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), dev_file->nsid)) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ tlogv(" buffer_size = %d \n", buffer_size); ++ tlogv(" "); ++ ++ if (read_from_VMclient(buffer_addr + offset, buffer_size, ++ (uint32_t __user *)(uintptr_t)(vm_hvas[index] + offset), ++ buffer_size, dev_file->nsid)) { ++ tloge("copy memref.buffer failed\n"); ++ return -EFAULT; ++ } ++ vm_buffers[index] = vm_hvas[index]; ++ kn_buffers[index] = (unsigned long long)buffer_addr; ++ } ++ } ++ } ++ mutex_unlock(&dev_file->shared_mem_lock); ++} ++ ++static int process_vm_ref_end(struct tc_ns_dev_file *dev_file, ++ struct tc_ns_client_context *context, unsigned long long *vm_buffers, ++ unsigned long long *kn_buffers) ++{ ++ int ret = 0; ++ int index = 0; ++ uint32_t buffer_size; ++ unsigned int offset = 0; ++ void *size_addr = NULL; ++ for (index = 0; index < TEE_PARAM_NUM; index++) ++ { ++ if (kn_buffers[index] != 0 && vm_buffers[index] != 0) { ++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr | ++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM)); ++ ++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), dev_file->nsid)) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ offset = context->params[index].memref.offset; ++ ++ tlogv("<--------------------\n"); ++ tlogv(" buffer_size = %d \n", buffer_size); ++ tlogv(" vm_buffers[index] = 0x%16.16lx", (long unsigned int)(vm_buffers[index])); ++ tlogv(" *(kn_buffers[index] + offset) = %s \n", (char*)(kn_buffers[index] + offset)); ++ tlogv(" offset = %ld \n", (long unsigned int)offset); ++ tlogv("-------------------->\n"); ++ ++ if (write_to_VMclient((void *)(uintptr_t)(vm_buffers[index] + offset), ++ buffer_size, (void *)(uintptr_t)(kn_buffers[index] + offset), ++ buffer_size, dev_file->nsid)) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } ++ ++ } else if (kn_buffers[index] == 0 && vm_buffers[index] == 0) { ++ /* do nothing*/ ++ ; ++ } else { ++ return -EFAULT; ++ } ++ } ++ return ret; ++} ++ + static int ioctl_session_send_cmd(struct tc_ns_dev_file *dev_file, + struct tc_ns_client_context *context, void *argp) + { + int ret; ++ unsigned long long vm_buffers[TEE_PARAM_NUM]={0}; ++ unsigned long long kn_buffers[TEE_PARAM_NUM]={0}; ++ ++ if (process_vm_ref(dev_file, context, vm_buffers, kn_buffers)) { ++ tloge("copy VM memref failed\n"); ++ return -EFAULT; ++ } + + ret = tc_ns_send_cmd(dev_file, context); + if (ret != 0) +@@ -1391,6 +1513,11 @@ + if (ret == 0) + ret = -EFAULT; + } ++ ++ if (process_vm_ref_end(dev_file, context, vm_buffers, kn_buffers)) { ++ tloge("copy VM memref failed\n"); ++ return -EFAULT; ++ } + return ret; + } + +@@ -1516,3 +1643,4 @@ + mutex_unlock(&dev_list->dev_lock); + return; + } ++ +diff -Naur '--exclude=.git' itrustee_tzdriver/core/tc_client_driver.c itrustee_tzdriver_new/core/tc_client_driver.c +--- itrustee_tzdriver/core/tc_client_driver.c 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/core/tc_client_driver.c 2023-08-01 13:16:56.856000000 +0800 +@@ -307,12 +307,12 @@ + + static int tc_login_check(const struct tc_ns_dev_file *dev_file) + { +- int ret = check_teecd_auth(); ++/* int ret = check_teecd_auth(); + if (ret != 0) { + tloge("teec auth failed, ret %d\n", ret); + return -EACCES; + } +- ++*/ + if (!dev_file) + return -EINVAL; + +@@ -812,6 +812,15 @@ + return ret; + } + ++static int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid) ++{ ++ dev_file->isVM = true; ++ tlogd(" dev_file->isVM %d\n", (int)dev_file->isVM); ++ dev_file->nsid = vmid; ++ tlogd(" dev_file->nsid %d\n", (int)dev_file->nsid); ++ return 0; ++} ++ + void handle_cmd_prepare(unsigned int cmd) + { + if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT && +@@ -831,7 +840,11 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; +- handle_cmd_prepare(cmd); ++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { ++ tlogd(" before set_vm_flag \n"); ++ return set_vm_flag(file->private_data, (int)arg); ++ } ++ handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION: + ret = tc_ns_get_tee_version(file->private_data, argp); +@@ -851,7 +864,7 @@ + ret = sync_system_time_from_user( + (struct tc_ns_client_time *)(uintptr_t)arg); + break; +- default: ++ default: + ret = public_ioctl(file, cmd, arg, false); + break; + } +@@ -866,8 +879,11 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; +- +- handle_cmd_prepare(cmd); ++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) { ++ tlogd(" before set_vm_flag \n"); ++ return set_vm_flag(file->private_data, (int)arg); ++ } ++ handle_cmd_prepare(cmd); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ: + case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ: +@@ -883,7 +899,7 @@ + case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: + ret = public_ioctl(file, cmd, arg, true); + break; +- default: ++ default: + ret = tc_client_agent_ioctl(file, cmd, arg); + break; + } +@@ -899,13 +915,13 @@ + int ret; + struct tc_ns_dev_file *dev = NULL; + (void)inode; +- ++/* + ret = check_teecd_auth(); + if (ret != 0) { + tloge("teec auth failed, ret %d\n", ret); + return -EACCES; + } +- ++*/ + file->private_data = NULL; + ret = tc_ns_client_open(&dev, TEE_REQ_FROM_USER_MODE); + if (ret == 0) +diff -Naur '--exclude=.git' itrustee_tzdriver/Makefile itrustee_tzdriver_new/Makefile +--- itrustee_tzdriver/Makefile 2023-08-01 13:44:04.248000000 +0800 ++++ itrustee_tzdriver_new/Makefile 2023-08-01 13:16:56.692000000 +0800 +@@ -37,8 +37,10 @@ + endif + + # you should config right path according to your run-time environment +-KPATH := /usr/src/kernels +-KDIR := $(KPATH)/$(shell ls $(KPATH)) ++#KPATH := /usr/src/kernels ++#KDIR := $(KPATH)/$(shell ls $(KPATH)) ++KERN_VER = $(shell uname -r) ++KERN_DIR = /lib/modules/$(KERN_VER)/build + + EXTRA_CFLAGS += -isystem /usr/lib/gcc/aarch64-linux-gnu/10.3.1/include + EXTRA_CFLAGS += -fstack-protector-strong -DCONFIG_TEELOG -DCONFIG_TZDRIVER_MODULE -DCONFIG_TEECD_AUTH -DCONFIG_PAGES_MEM=y -DCONFIG_CLOUDSERVER_TEECD_AUTH +@@ -53,7 +55,7 @@ + EXTRA_CFLAGS += -I$(PWD)/tzdriver_internal/tee_reboot + EXTRA_CFLAGS += -DMAILBOX_POOL_COUNT=8 + all: +- make -C $(KDIR) M=$(PWD) modules ++ make -C $(KERN_DIR) M=$(PWD) modules + clean: + -rm -vrf *.o *.ko auth/*.o core/*.o tlogger/*.o + -rm -vrf *.order *.symvers *.mod.c .tmp_versions .*o.cmd auth/.*o.cmd core/.*o.cmd tlogger/.*o.cmd +diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_client.h itrustee_tzdriver_new/tc_ns_client.h +--- itrustee_tzdriver/tc_ns_client.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/tc_ns_client.h 2023-08-01 13:16:56.696000000 +0800 +@@ -209,4 +209,7 @@ + #endif + #define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \ + _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info) ++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG \ ++ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) ++ + #endif +diff -Naur '--exclude=.git' itrustee_tzdriver/tc_ns_log.h itrustee_tzdriver_new/tc_ns_log.h +--- itrustee_tzdriver/tc_ns_log.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/tc_ns_log.h 2023-08-01 13:16:57.032000000 +0800 +@@ -32,7 +32,7 @@ + }; + #define MOD_TEE "tzdriver" + +-#define TEE_LOG_MASK TZ_DEBUG_INFO ++#define TEE_LOG_MASK TZ_DEBUG_WARN + + #define tlogv(fmt, args...) \ + do { \ +diff -Naur '--exclude=.git' itrustee_tzdriver/teek_ns_client.h itrustee_tzdriver_new/teek_ns_client.h +--- itrustee_tzdriver/teek_ns_client.h 2023-08-01 13:44:04.252000000 +0800 ++++ itrustee_tzdriver_new/teek_ns_client.h 2023-08-01 13:16:56.692000000 +0800 +@@ -133,6 +133,7 @@ + struct completion close_comp; /* for kthread close unclosed session */ + #ifdef CONFIG_TEE_TELEPORT_SUPPORT + bool portal_enabled; ++ bool isVM; + #endif + }; + -- Gitee From e22275b990e1dc0eb4ca280ed0bab80a7b8cadf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9C=9D=E5=B7=9E?= Date: Tue, 1 Aug 2023 08:59:40 +0000 Subject: [PATCH 12/12] vtz_proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王朝州 --- .../vtzb_proxy/include/cloud/tee_client_log.h | 26 +++ .../include/cloud/tee_session_pool.h | 45 +++++ .../Host/vtzb_proxy/include/tc_ns_client.h | 165 ++++++++++++++++ .../Host/vtzb_proxy/include/tee_client_api.h | 179 ++++++++++++++++++ .../vtzb_proxy/include/tee_client_constants.h | 127 +++++++++++++ .../Host/vtzb_proxy/include/tee_client_list.h | 99 ++++++++++ .../Host/vtzb_proxy/include/tee_client_type.h | 133 +++++++++++++ .../Host/vtzb_proxy/include/tee_sys_log.h | 58 ++++++ 8 files changed, 832 insertions(+) create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_client_log.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_session_pool.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tc_ns_client.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_api.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_constants.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_list.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_type.h create mode 100644 trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_sys_log.h diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_client_log.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_client_log.h new file mode 100644 index 0000000..59681ec --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_client_log.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef TEE_CLIENT_LOG_H +#define TEE_CLIENT_LOG_H + +#include + +#ifdef TEEC_DEBUG +#define TEEC_Debug(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__); +#else +#define TEEC_Debug(...) +#endif + +#define TEEC_Error(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__); + +#endif diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_session_pool.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_session_pool.h new file mode 100644 index 0000000..5812698 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/cloud/tee_session_pool.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef _TEE_SESSION_POOL_H_ +#define _TEE_SESSION_POOL_H_ + +#include +#include "tee_client_api.h" + +struct SessionInfo { + TEEC_Session session; + bool isDead; +}; + +struct SessionPool { + TEEC_Context *context; /* context owner */ + TEEC_UUID uuid; + uint32_t poolSize; /* expected count of sessions to open */ + struct SessionInfo *sessionsInfo; + uint32_t opened; /* counf of sessions opend successfully */ + uint32_t inuse; /* count of sessions in using */ + sem_t keys; /* keys value equal opend - inuse */ + uint8_t *usage; /* a bitmap mark session in-use */ + uint32_t usageSize; /* bitmap size in bytes */ + pthread_mutex_t usageLock; +}; + +TEEC_Result TEEC_SessionPoolCreate(TEEC_Context *context, const TEEC_UUID *destination, + struct SessionPool **sessionPool, uint32_t poolSize); +TEEC_Result TEEC_SessionPoolInvoke(struct SessionPool *sessionPool, uint32_t commandID, + TEEC_Operation *operation, uint32_t *returnOrigin); +void TEEC_SessionPoolDestroy(struct SessionPool *sessionPool); +void TEEC_SessionPoolQuery(struct SessionPool *sessionPool, uint32_t *size, + uint32_t *opened, uint32_t *inuse, bool showBitmap); + +#endif diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tc_ns_client.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tc_ns_client.h new file mode 100644 index 0000000..24e2cd6 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tc_ns_client.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef _TC_NS_CLIENT_H_ +#define _TC_NS_CLIENT_H_ +#include "tee_client_type.h" +#define TC_DEBUG + +#define INVALID_TYPE 0x00 +#define TEECD_CONNECT 0x01 +#ifndef ZERO_SIZE_PTR +#define ZERO_SIZE_PTR ((void *)16) +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR) +#endif + +#define UUID_SIZE 16 + +#define TC_NS_CLIENT_IOC_MAGIC 't' +#define TC_NS_CLIENT_DEV "tc_ns_client" +#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client" +#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private" +#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm" + +enum ConnectCmd { + GET_FD, + GET_TEEVERSION, + SET_SYS_XML, + GET_TEECD_VERSION, +}; + +typedef struct { + unsigned int method; + unsigned int mdata; +} TC_NS_ClientLogin; + +typedef union { + struct { + unsigned int buffer; + unsigned int buffer_h_addr; + unsigned int offset; + unsigned int h_offset; + unsigned int size_addr; + unsigned int size_h_addr; + } memref; + struct { + unsigned int a_addr; + unsigned int a_h_addr; + unsigned int b_addr; + unsigned int b_h_addr; + } value; +} TC_NS_ClientParam; + +typedef struct { + unsigned int code; + unsigned int origin; +} TC_NS_ClientReturn; + +typedef struct { + unsigned char uuid[UUID_SIZE]; + unsigned int session_id; + unsigned int cmd_id; + TC_NS_ClientReturn returns; + TC_NS_ClientLogin login; + TC_NS_ClientParam params[TEEC_PARAM_NUM]; + unsigned int paramTypes; + bool started; + unsigned int callingPid; + unsigned int file_size; + union { + char *file_buffer; + struct { + uint32_t file_addr; + uint32_t file_h_addr; + } memref; + }; +} TC_NS_ClientContext; + +typedef struct { + uint32_t seconds; + uint32_t millis; +} TC_NS_Time; + +typedef struct { + uint16_t tzdriver_version_major; + uint16_t tzdriver_version_minor; + uint32_t reserved[15]; +} TC_NS_TEE_Info; + +enum SecFileType { + LOAD_TA = 0, + LOAD_SERVICE, + LOAD_LIB, + LOAD_DYNAMIC_DRV, + LOAD_PATCH, + LOAD_TYPE_MAX +}; + +struct SecFileInfo { + enum SecFileType fileType; + uint32_t fileSize; + int32_t secLoadErr; +}; + +struct SecLoadIoctlStruct { + struct SecFileInfo secFileInfo; + TEEC_UUID uuid; + union { + char *fileBuffer; + struct { + uint32_t file_addr; + uint32_t file_h_addr; + } memref; + }; +}__attribute__((packed)); + +struct AgentIoctlArgs { + uint32_t id; + uint32_t bufferSize; + union { + void *buffer; + unsigned long long addr; + }; +}; + +#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext) +#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext) +#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext) +#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int) +#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int) +#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int) +#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs) +#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int) +#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct) +#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext) +#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int) +#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext) +#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int) +#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int) +#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int) +#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time) +#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int) +#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int) +#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int) +#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int) +#ifdef CONFIG_CMS_SIGNATURE +#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl) +#endif +#ifdef CONFIG_TEE_TELEPORT_SUPPORT +#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs) +#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs) +#endif +#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info) +#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int) +TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation); +#endif + diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_api.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_api.h new file mode 100644 index 0000000..d689979 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_api.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef _TEE_CLIENT_API_H_ +#define _TEE_CLIENT_API_H_ + +#ifndef LOG_TAG +#define LOG_TAG NULL +#endif + +#include +#include "tee_client_type.h" +#include "tee_client_ext_api.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define S_VAR_NOT_USED(variable) do { (void)(variable); } while (0) + +#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \ + ((param3Type) << 12 | (param2Type) << 8 | (param1Type) << 4 | (param0Type)) + +#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ + (((paramTypes) >> (4*(index))) & 0x0F) + +#define TEEC_VALUE_UNDEF 0xFFFFFFFF + +/* + * initializes a new TEE Context, forming a connection between this Client Application and the TEE + * + * @param name [IN] TEE name (unused) + * @param context [OUT] pointer to TEEC_Context to be initialized + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter + * @return TEEC_ERROR_GENERIC system error unhandled + */ +TEEC_Result TEEC_InitializeContext( + const char *name, + TEEC_Context *context); + +/* + * finalizes an initialized TEE Context, closing the connection between the Client Application and the TEE + * + * @param context [IN/OUT] pointer to TEEC_Context initialized by TEEC_InitializeContext + * + * @return void + */ +void TEEC_FinalizeContext( + TEEC_Context *context); + +/* + * opens a new Session between the Client Application and the specified Trusted Application + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param session [OUT] a pointer to a Session structure to be opened + * @param destination [IN] a pointer to a structure containing the UUID of the destination Trusted Application + * @param connectionMethod [IN] the method of connection to use + * @param connectionData [IN] any necessary data required to support the connection method + * @param operation [IN/OUT] a pointer to an Operation containing a set of Parameters to exchange with the + * Trusted Application + * @param returnOrigin [OUT] a pointer to a variable which will contain the return origin, This field may be NULL + * if the return origin is not needed + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or session or destination is NULL + * @return TEEC_ERROR_ACCESS_DENIED client Application's connection request is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return TEEC_ERROR_TRUSTED_APP_LOAD_ERROR load Trusted Application failed + * @return others refer TEEC_ReturnCode + */ +TEEC_Result TEEC_OpenSession( + TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connectionMethod, + const void *connectionData, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/* + * closes a Session which has been opened with a Trusted Application + * + * @param session [IN/OUT] pointer to a session to be closed + * + * @return void + */ +void TEEC_CloseSession( + TEEC_Session *session); + +/* + * invokes a Command within the specified Session + * + * @param session [IN/OUT] the open Session in which the command will be invoked + * @param commandID [IN] the identifier of the Command within the Trusted Application to invoke + * @param operation [IN/OUT] a pointer to a Client Application initialized TEEC_Operation structure + * @param returnOrigin [OUT] a pointer to a variable which will contain the return origin + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, session is NULL or operation data invalid + * @return TEEC_ERROR_ACCESS_DENIED invoke command operation is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return others refer TEEC_ReturnCode + */ +TEEC_Result TEEC_InvokeCommand( + TEEC_Session *session, + uint32_t commandID, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/* + * registers a block of existing Client Application memory as a block of Shared Memory within + * the scope of the specified TEE Context, in accordance with the parameters which have been set by the + * Client Application inside the sharedMem structure (don't support 0 size data) + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to register + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + */ +TEEC_Result TEEC_RegisterSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/* + * allocates a new block of memory as a block of Shared Memory within the scope of the specified TEE Context + * size of sharedMem should not be 0 + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to allocate + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + */ +TEEC_Result TEEC_AllocateSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/* + * deregisters or deallocates a previously initialized block of Shared Memory + * if memory is allocated by TEEC_AllocateSharedMemory, system will free this memory + * if memory is registered by TEEC_RegisterSharedMemory, system will not free this memory + * + * @param sharedMem [IN/OUT] a pointer to a valid Shared Memory structure + * + * @return void + */ +void TEEC_ReleaseSharedMemory( + TEEC_SharedMemory *sharedMem); + +/* + * requests the cancellation of a pending open Session operation or a Command invocation operation + * this operation is not supported currently + * + * @param operation [IN/OUT] a pointer to a Client Application instantiated Operation structure + * + * @return void + */ +void TEEC_RequestCancellation( + TEEC_Operation *operation); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_constants.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_constants.h new file mode 100644 index 0000000..2a7e31f --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_constants.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef _TEE_CLIENT_CONSTANTS_H_ +#define _TEE_CLIENT_CONSTANTS_H_ + +enum TEEC_ReturnCode { + TEEC_SUCCESS = 0x0, /* success */ + TEEC_ERROR_INVALID_CMD, /* invalid command */ + TEEC_ERROR_SERVICE_NOT_EXIST, /* target service is not exist */ + TEEC_ERROR_SESSION_NOT_EXIST, /* session between client and service is not exist */ + TEEC_ERROR_SESSION_MAXIMUM, /* exceed max num of sessions */ + TEEC_ERROR_REGISTER_EXIST_SERVICE, /* cannot register the service which already exist */ + TEEC_ERROR_TAGET_DEAD_FATAL, /* system error occurs in TEE */ + TEEC_ERROR_READ_DATA, /* failed to read data in file */ + TEEC_ERROR_WRITE_DATA, /* failed to write data to file */ + TEEC_ERROR_TRUNCATE_OBJECT, /* data is truncated */ + TEEC_ERROR_SEEK_DATA, /* failed to seek data in file */ + TEEC_ERROR_FSYNC_DATA, /* failed to sync data in file */ + TEEC_ERROR_RENAME_OBJECT, /* failed to rename file */ + TEEC_ERROR_TRUSTED_APP_LOAD_ERROR, /* failed to load Trusted Application */ + TEEC_ERROR_GENERIC = 0xFFFF0000, /* generic error occurs */ + TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001, /* permission check failed, in initilize context or + open session or invoke commnad */ + TEEC_ERROR_CANCEL = 0xFFFF0002, /* operation is already canceled */ + TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003, /* confilct occurs in concurrent access to data, + error occurs in file operaions generally */ + TEEC_ERROR_EXCESS_DATA = 0xFFFF0004, /* exceed max data to be handled by system */ + TEEC_ERROR_BAD_FORMAT = 0xFFFF0005, /* data format is invalid, Trusted Application cannot + handle it */ + TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006, /* invalid parameters */ + TEEC_ERROR_BAD_STATE = 0xFFFF0007, /* operation failed in current state, when try to access + storage without initilize storage service */ + TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008, /* cannot find target item */ + TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009, /* request operation is not implemented */ + TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A, /* request operation is not supported */ + TEEC_ERROR_NO_DATA = 0xFFFF000B, /* no data present for current operation */ + TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C, /* system resource if out of use */ + TEEC_ERROR_BUSY = 0xFFFF000D, /* system is too busy to handle current operation */ + TEEC_ERROR_COMMUNICATION = 0xFFFF000E, /* error occurs when client try to communicate + with Trusted Application */ + TEEC_ERROR_SECURITY = 0xFFFF000F, /* security error occurs */ + TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010, /* out buffer is not enough for current request */ + TEEC_ERROR_MAC_INVALID = 0xFFFF3071, /* MAC value check failed */ + TEEC_ERROR_TARGET_DEAD = 0xFFFF3024, /* Trusted Application is crashed */ + TEEC_FAIL = 0xFFFF5002, /* common error */ + TEEC_ERROR_EXTERNAL_CANCEL = 0xFFFF0011, /* used by adapt only, event caused User Interface operation aborted */ + TEEC_ERROR_OVERFLOW = 0xFFFF300F, /* used by adapt only */ + TEEC_ERROR_STORAGE_NO_SPACE = 0xFFFF3041, /* used by adapt only */ + TEEC_ERROR_SIGNATURE_INVALID = 0xFFFF3072, /* used by adapt only */ + TEEC_ERROR_TIME_NOT_SET = 0xFFFF5000, /* used by adapt only */ + TEEC_ERROR_TIME_NEEDS_RESET = 0xFFFF5001, /* used by adapt only */ + TEEC_ERROR_IPC_OVERFLOW = 0xFFFF9114 /* ipc overflow */ +}; + +enum TEEC_ReturnCodeOrigin { + TEEC_ORIGIN_API = 0x1, /* error occurs in handling client API */ + TEEC_ORIGIN_COMMS = 0x2, /* error occurs in communicating between REE and TEE */ + TEEC_ORIGIN_TEE = 0x3, /* error occurs in TEE */ + TEEC_ORIGIN_TRUSTED_APP = 0x4, /* error occurs in Trusted Application */ +}; + +enum TEEC_SharedMemCtl { + TEEC_MEM_INPUT = 0x1, /* input type of memroy */ + TEEC_MEM_OUTPUT = 0x2, /* output type of memory */ + TEEC_MEM_INOUT = 0x3, /* memory is used as both input and output */ + TEEC_MEM_SHARED_INOUT = 0x4, /* no copy shared memory */ +}; + +enum TEEC_ParamType { + TEEC_NONE = 0x0, /* unused parameter */ + TEEC_VALUE_INPUT = 0x01, /* input type of value, refer TEEC_Value */ + TEEC_VALUE_OUTPUT = 0x02, /* output type of value, refer TEEC_Value */ + TEEC_VALUE_INOUT = 0x03, /* value is used as both input and output, refer TEEC_Value */ + TEEC_MEMREF_TEMP_INPUT = 0x05, /* input type of temp memory reference, refer TEEC_TempMemoryReference */ + TEEC_MEMREF_TEMP_OUTPUT = 0x06, /* output type of temp memory reference, refer TEEC_TempMemoryReference */ + TEEC_MEMREF_TEMP_INOUT = 0x07, /* temp memory reference used as both input and output, + refer TEEC_TempMemoryReference */ + TEEC_ION_INPUT = 0x08, /* input type of icon memory reference, refer TEEC_IonReference */ + TEEC_ION_SGLIST_INPUT = 0x09, /* input type of ion memory block reference, refer TEEC_IonSglistReference */ + TEEC_MEMREF_SHARED_INOUT = 0x0a, /* no copy mem */ + TEEC_MEMREF_WHOLE = 0xc, /* use whole memory block, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_INPUT = 0xd, /* input type of memory reference, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, /* output type of memory reference, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_INOUT = 0xf /* memory reference used as both input and output, + refer TEEC_RegisteredMemoryReference */ +}; + +/**************************************************** + * Session Login Methods + ****************************************************/ +enum TEEC_LoginMethod { + TEEC_LOGIN_PUBLIC = 0x0, /* no Login data is provided */ + TEEC_LOGIN_USER, /* Login data about the user running the + Client Application process is provided */ + TEEC_LOGIN_GROUP, /* Login data about the group running + the Client Application process is provided */ + TEEC_LOGIN_APPLICATION = 0x4, /* Login data about the running Client + Application itself is provided */ + TEEC_LOGIN_USER_APPLICATION = 0x5, /* Login data about the user running the + Client Application and about the + Client Application itself is provided */ + TEEC_LOGIN_GROUP_APPLICATION = 0x6, /* Login data about the group running + the Client Application and about the + Client Application itself is provided */ + TEEC_LOGIN_IDENTIFY = 0x7, /* Login data is provided by REE system */ +}; +enum TST_CMD_ID { + TST_CMD_ID_01 = 1, + TST_CMD_ID_02, + TST_CMD_ID_03, + TST_CMD_ID_04, + TST_CMD_ID_05 +}; + +#define TEEC_PARAM_NUM 4 /* teec param max number */ +#endif + diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_list.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_list.h new file mode 100644 index 0000000..d14656c --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_list.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef TEE_CLIENT_LIST_H +#define TEE_CLIENT_LIST_H + +struct ListNode { + struct ListNode *next; /* point to next node */ + struct ListNode *prev; /* point to prev node */ +}; + +#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member)) +#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member)) + +#define LIST_DECLARE(name) \ + struct ListNode name = { \ + .next = &name, \ + .prev = &name, \ + } + +static inline void ListInit(struct ListNode *list) +{ + list->next = list; + list->prev = list; +} + +#define LIST_HEAD(list) ((list)->next) +#define LIST_TAIL(list) ((list)->prev) +#define LIST_EMPTY(list) ((list) == (list)->next) + +static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry) +{ + list->next->prev = entry; + entry->next = list->next; + entry->prev = list; + list->next = entry; +} + +static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry) +{ + entry->next = list; + entry->prev = list->prev; + list->prev->next = entry; + list->prev = entry; +} + +static inline void ListRemoveEntry(struct ListNode *entry) +{ + entry->prev->next = entry->next; + entry->next->prev = entry->prev; +} + +static inline struct ListNode *ListRemoveHead(struct ListNode *list) +{ + struct ListNode *entry = NULL; + if (!LIST_EMPTY(list)) { + entry = list->next; + ListRemoveEntry(entry); + } + return entry; +} + +static inline struct ListNode *ListRemoveTail(struct ListNode *list) +{ + struct ListNode *entry = NULL; + if (!LIST_EMPTY(list)) { + entry = list->prev; + ListRemoveEntry(entry); + } + return entry; +} + +#define LIST_ENTRY(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +#define LIST_FOR_EACH(pos, list) \ + for (pos = (list)->next; pos != (list); pos = pos->next) + +#define LIST_FOR_EACH_SAFE(pos, n, list) \ + for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next) + +#define LIST_FOR_EACH_ENTRY(pos, list, member) \ + for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \ + pos = LIST_ENTRY(pos->member.next, typeof(*pos), member)) + +#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \ + for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \ + member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member)) + +#endif diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_type.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_type.h new file mode 100644 index 0000000..0ff7692 --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_client_type.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef _TEE_CLIENT_TYPE_H_ +#define _TEE_CLIENT_TYPE_H_ + +#include +#include +#include +#include +#include +#include "tee_client_list.h" +#include "tee_client_constants.h" + +typedef enum TEEC_ReturnCode TEEC_Result; + +typedef struct { + uint32_t timeLow; + uint16_t timeMid; + uint16_t timeHiAndVersion; + uint8_t clockSeqAndNode[8]; +} TEEC_UUID; + +typedef struct { + int32_t fd; + uint8_t *ta_path; + struct ListNode session_list; + struct ListNode shrd_mem_list; + union { + struct { + void *buffer; + sem_t buffer_barrier; + } share_buffer; + uint64_t imp; /* for adapt */ + }; +} TEEC_Context; + +typedef struct { + uint32_t session_id; + TEEC_UUID service_id; + uint32_t ops_cnt; + union { + struct ListNode head; + uint64_t imp; /* for adapt */ + }; + TEEC_Context *context; +} TEEC_Session; + +typedef struct { + void *buffer; + uint32_t size; + uint32_t flags; /* reference to TEEC_SharedMemCtl */ + uint32_t ops_cnt; + bool is_allocated; /* identify whether the memory is registered or allocated */ + union { + struct ListNode head; + void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */ + }; + TEEC_Context *context; +} TEEC_SharedMemory; + +/* + * the corresponding param types are + * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT + */ +typedef struct { + void *buffer; + uint32_t size; +} TEEC_TempMemoryReference; + +/* + * the corresponding param types are + * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT + * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT + */ +typedef struct { + TEEC_SharedMemory *parent; + uint32_t size; + uint32_t offset; +} TEEC_RegisteredMemoryReference; + +/* + * the corresponding param types are + * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT + */ +typedef struct { + uint32_t a; + uint32_t b; +} TEEC_Value; + +typedef struct { + int ion_share_fd; + uint32_t ion_size; +} TEEC_IonReference; + +typedef union { + TEEC_TempMemoryReference tmpref; + TEEC_RegisteredMemoryReference memref; + TEEC_Value value; + TEEC_IonReference ionref; +} TEEC_Parameter; + +typedef struct { + uint32_t event_type; /* Tui event type */ + uint32_t value; /* return value, is keycode if tui event is getKeycode */ + uint32_t notch; /* notch size of the screen for tui */ + uint32_t width; /* width of foldable screen */ + uint32_t height; /* height of foldable screen */ + uint32_t fold_state; /* state of foldable screen */ + uint32_t display_state; /* one state of folded state */ + uint32_t phy_width; /* real width of the mobile */ + uint32_t phy_height; /* real height of the mobile */ +} TEEC_TUI_Parameter; + +typedef struct { + uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */ + uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */ + TEEC_Parameter params[TEEC_PARAM_NUM]; + TEEC_Session *session; + bool cancel_flag; +} TEEC_Operation; + +#endif + diff --git a/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_sys_log.h b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_sys_log.h new file mode 100644 index 0000000..1fa0c3d --- /dev/null +++ b/trustzone-awared-vm/demo/Host/vtzb_proxy/include/tee_sys_log.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef TEEC_SYS_LOG_H +#define TEEC_SYS_LOG_H + +#include + +// #define TEE_LOG_MASK TZ_LOG_ERROR +#define TEE_LOG_MASK TZ_LOG_VERBOSE + +#define TZ_LOG_VERBOSE 0 +#define TZ_LOG_INFO 1 +#define TZ_LOG_WARN 2 +#define TZ_LOG_DEBUG 3 +#define TZ_LOG_ERROR 4 + +#define tlogv(...) \ + do { \ + if (TZ_LOG_VERBOSE == TEE_LOG_MASK) \ + syslog(LOG_USER | LOG_NOTICE, __VA_ARGS__); \ + } while (0) + +#define tlogd(...) \ + do { \ + if (TZ_LOG_DEBUG >= TEE_LOG_MASK) \ + syslog(LOG_USER | LOG_DEBUG, __VA_ARGS__); \ + } while (0) + +#define tlogi(...) \ + do { \ + if (TZ_LOG_INFO >= TEE_LOG_MASK) \ + syslog(LOG_USER | LOG_INFO, __VA_ARGS__); \ + } while (0) + +#define tlogw(...) \ + do { \ + if (TZ_LOG_WARN >= TEE_LOG_MASK) \ + syslog(LOG_USER | LOG_WARNING, __VA_ARGS__); \ + } while (0) + +#define tloge(...) \ + do { \ + if (TZ_LOG_ERROR >= TEE_LOG_MASK) \ + syslog(LOG_USER | LOG_ERR, __VA_ARGS__); \ + } while (0) + +#endif + -- Gitee