diff --git a/trustzone-awared-vm/deployment.md b/trustzone-awared-vm/deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..7118fc6ef8df64946bd0d1903aa77cf7c60f5757 --- /dev/null +++ b/trustzone-awared-vm/deployment.md @@ -0,0 +1,266 @@ +## 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +定义5个虚拟串口,socket的path、虚拟串口的name字段与上面保持一致。 + +host里socket路径""/tmp/vm_vtzb_sock[0-4]" + +VM 里虚拟串口路径"/dev/virtio-ports/vtzf_serialport[0-4]" + + + +**步骤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 /usr/bin/teecd +sudo ./vtzb_proxy +``` + +若host与VM通道正常,会打印信息 + +``` +open new socket +open new socket +``` + +VM: + +``` +sudo /usr/bin/teecd +``` + +``` +sudo /vendor/bin/testcase1 [1-9] +``` + diff --git a/trustzone-awared-vm/host/qemu.patch b/trustzone-awared-vm/host/qemu.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1f56caa66ca8aed53e02a5a3c48781913917f1d --- /dev/null +++ b/trustzone-awared-vm/host/qemu.patch @@ -0,0 +1,940 @@ +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_constants.h ./qemu_after/hw/char/tee_client_constants.h +--- ./qemu/hw/char/tee_client_constants.h 1970-01-01 08:00:00.000000000 +0800 ++++ ./qemu_after/hw/char/tee_client_constants.h 2023-08-09 15:39:42.324000000 +0800 +@@ -0,0 +1,126 @@ ++/* ++ * 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 -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-03 17:27:07.592000000 +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,115 @@ + 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_FS_REGISTER_AGENT 45 ++#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; ++ void *addr; ++ struct AgentIoctlArgs args; ++} struct_packet_cmd_regagent; ++ ++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 +174,223 @@ + 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_FS_REGISTER_AGENT: ++ debug(" command is VTZF_FS_REGISTER_AGENT \n"); ++ if (len >= sizeof(struct_packet_cmd_regagent)) { ++ struct_packet_cmd_regagent* vtzf_packet_cmd = (struct_packet_cmd_regagent *)buf01; ++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->addr); ++ ++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->addr; ++ 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 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->addr = (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 +637,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/host/tzdriver.patch b/trustzone-awared-vm/host/tzdriver.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d0c34a558c37f475ca2f3760a7ab2f566298cb9 --- /dev/null +++ b/trustzone-awared-vm/host/tzdriver.patch @@ -0,0 +1,1148 @@ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/agent.c ./itrustee_tzdriver_new/core/agent.c +--- ./itrustee_tzdriver/core/agent.c 2023-08-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/agent.c 2023-09-05 13:59:26.880000000 +0800 +@@ -256,13 +256,13 @@ + uint32_t buf_len = 0; + uint8_t *buf_to_tee = NULL; + struct mb_cmd_pack *mb_pack = NULL; +- ++/* + ret = check_teecd_auth(); + if (ret != 0) { + tloge("teecd or cadaemon auth failed, ret %d\n", ret); + return -EACCES; + } +- ++*/ + if (!inbuf) + return -EINVAL; + +@@ -945,6 +945,8 @@ + nsid = task_active_pid_ns(current)->ns.inum; + if (dev_file != NULL && dev_file->nsid == 0) + dev_file->nsid = nsid; ++ //if (dev_file->isVM) ++ // nsid = dev_file->nsid; + #endif + + if (is_agent_already_exist(agent_id, nsid, &event_data, dev_file, &find_flag)) +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-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/gp_ops.c 2023-09-05 13:59:26.872000000 +0800 +@@ -312,6 +312,84 @@ + 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; ++} ++ ++int write_to_VMclient(void __user *dest, size_t dest_size, ++ const void *src, size_t size, pid_t vm_pid) ++{ ++ struct task_struct *vmp_task; ++ int i_wtlen; ++ 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; ++ ++ 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; ++ } ++ ++ i_wtlen = access_process_vm(vmp_task, (unsigned long)(dest), src, size, FOLL_FORCE | FOLL_WRITE); ++ if (i_wtlen != size) { ++ tloge("only write %d of %ld bytes by access_process_vm \n", i_wtlen, size); ++ return -EFAULT; ++ } ++ tlogv("django verbose, write %d byes by access_process_vm succeed", ++ i_wtlen); ++ return 0; ++} ++ + static bool is_input_tempmem(unsigned int param_type) + { + if (param_type == TEEC_MEMREF_TEMP_INPUT || +@@ -321,7 +399,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 +410,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->vmpid) != 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 +451,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->vmpid) != 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 +494,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 +506,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->vmpid) != 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 +612,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; +@@ -546,17 +661,27 @@ + + #ifdef CONFIG_NOCOPY_SHAREDMEM + static int check_buffer_for_sharedmem(uint32_t *buffer_size, +- const union tc_ns_client_param *client_param, uint8_t kernel_params) ++ const union tc_ns_client_param *client_param, uint8_t kernel_params, struct tc_ns_dev_file *dev_file) + { + uint64_t size_addr = client_param->memref.size_addr | + ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM); + uint64_t buffer_addr = client_param->memref.buffer | + ((uint64_t)client_param->memref.buffer_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)) { +- tloge("copy size_addr failed\n"); +- return -EFAULT; ++ if (dev_file->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), dev_file->vmpid) != 0) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ } else { ++ if (read_from_client(buffer_size, sizeof(*buffer_size), ++ (uint32_t __user *)(uintptr_t)size_addr, ++ sizeof(uint32_t), kernel_params)) { ++ tloge("copy size_addr failed\n"); ++ return -EFAULT; ++ } + } + + if (*buffer_size == 0 || *buffer_size > SZ_256M) { +@@ -572,6 +697,96 @@ + return 0; + } + ++ ++void put_vm_pages(struct page **pages, uint32_t page_num) ++{ ++ int i; ++ for (i = 0; i < page_num; i++) { ++ if (pages[i]) { ++ put_page(pages[i]); ++ pages[i] = NULL; ++ } ++ } ++} ++ ++int fill_vm_shared_mem_info(uint64_t start_vaddr, uint32_t pages_no, ++ uint32_t offset, uint32_t buffer_size, uint64_t info_addr, pid_t vm_pid) ++{ ++ struct pagelist_info *page_info = NULL; ++ struct page **pages = NULL; ++ uint64_t *phys_addr = NULL; ++ uint32_t page_num; ++ uint32_t i; ++ struct task_struct *vmp_task; ++ ++ if (pages_no == 0) ++ return -EFAULT; ++ ++ pages = (struct page **)vmalloc(pages_no * sizeof(uint64_t)); ++ if (pages == NULL) ++ return -EFAULT; ++ ++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID); ++ if (vmp_task == NULL) { ++ tloge("no task for pid %d", vm_pid); ++ return -EFAULT; ++ } ++ ++#if (KERNEL_VERSION(6, 5, 0) <= LINUX_VERSION_CODE) ++ page_num = get_user_pages_remote(vmp_task->mm, start_vaddr, ++ (unsigned long)pages_no, ++ FOLL_FORCE, pages, NULL); ++#elif (KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE) ++ page_num = get_user_pages_remote(vmp_task->mm, start_vaddr, ++ (unsigned long)pages_no, ++ FOLL_FORCE, pages, ++ NULL, NULL); ++#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE) ++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm, ++ start_vaddr, (unsigned long)pages_no, FOLL_FORCE, ++ pages, NULL, NULL); ++#elif (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) ++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm, ++ start_vaddr, (unsigned long)pages_no, ++ FOLL_FORCE, pages, NULL); ++#else ++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm, ++ start_vaddr, (unsigned long)pages_no, ++ 1, 1, pages, NULL); ++ ++#endif ++ if (page_num != pages_no) { ++ tloge("get page phy addr failed\n"); ++ if (page_num > 0) ++ put_vm_pages(pages, page_num); ++ vfree(pages); ++ return -EFAULT; ++ } ++ tlogd("get_user pages remote success, page num = %u , page_size = %d \n", page_num, PAGE_SIZE); ++ ++ page_info = (struct pagelist_info *)(uintptr_t)info_addr; ++ page_info->page_num = pages_no; ++ page_info->page_size = PAGE_SIZE; ++ page_info->sharedmem_offset = offset; ++ page_info->sharedmem_size = buffer_size; ++ ++ phys_addr = (uint64_t *)(uintptr_t)info_addr + (sizeof(*page_info) / sizeof(uint64_t)); ++ for (i = 0; i < pages_no; i++) { ++ struct page *page = NULL; ++ page = pages[i]; ++ if (page == NULL) { ++ put_vm_pages(pages, page_num); ++ vfree(pages); ++ tloge("page == NULL \n"); ++ return -EFAULT; ++ } ++ phys_addr[i] = (uintptr_t)page_to_phys(page); ++ } ++ ++ vfree(pages); ++ return 0; ++} ++ + static int transfer_shared_mem(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +@@ -589,7 +804,7 @@ + return -EINVAL; + + client_param = &(call_params->context->params[index]); +- if (check_buffer_for_sharedmem(&buffer_size, client_param, kernel_params)) ++ if (check_buffer_for_sharedmem(&buffer_size, client_param, kernel_params, call_params->dev)) + return -EINVAL; + + buffer_addr = client_param->memref.buffer | +@@ -603,10 +818,18 @@ + buff = mailbox_alloc(buff_len, MB_FLAG_ZERO); + if (buff == NULL) + return -EFAULT; +- +- if (fill_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff)) { +- mailbox_free(buff); +- return -EFAULT; ++ if (call_params->dev->isVM) { ++ tlogd("pages_no = %u, buffer_addr = %lx, offset = %x \n", pages_no, buffer_addr, offset); ++ tlogd("PAGE_SIZE = %x , PAGE_MASK = %x \n", PAGE_SIZE, PAGE_MASK); ++ if (fill_vm_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff, call_params->dev->vmpid)) { ++ mailbox_free(buff); ++ return -EFAULT; ++ } ++ } else { ++ if (fill_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff)) { ++ mailbox_free(buff); ++ return -EFAULT; ++ } + } + + op_params->local_tmpbuf[index].temp_buffer = buff; +@@ -651,21 +874,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->vmpid) != 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->vmpid) != 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 +998,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->vmpid) != 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 +1031,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->vmpid) != 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 +1075,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->vmpid) != 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->vmpid) != 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 +1144,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->vmpid) != 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->vmpid) != 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 +1554,7 @@ + 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-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/gp_ops.h 2023-09-05 13:59:26.880000000 +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-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/session_manager.c 2023-09-05 13:59:26.872000000 +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->vmpid)) { ++ 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,126 @@ + 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 (!dev_file->isVM) ++ return 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->vmpid)) { ++ 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->vmpid)) { ++ 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); ++ return 0; ++} ++ ++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; ++ ++ if (!dev_file->isVM) ++ return 0; ++ ++ 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->vmpid)) { ++ 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->vmpid)) { ++ 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 +1520,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 +1650,6 @@ + mutex_unlock(&dev_list->dev_lock); + return; + } ++ ++ ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/smc_smp.c ./itrustee_tzdriver_new/core/smc_smp.c +--- ./itrustee_tzdriver/core/smc_smp.c 2023-08-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/smc_smp.c 2023-09-05 13:59:26.880000000 +0800 +@@ -1771,7 +1771,9 @@ + release_pending_entry(pe); + return TEEC_ERROR_GENERIC; + } +- ++ tlogd("---------------------------\n"); ++ tlogd("cmd.nsid = %d \n", cmd.nsid); ++ tlogd("---------------------------\n"); + if (smp_smc_send_process(&cmd, ops, &cmd_ret, info.cmd_index) == -1) + goto clean; + +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-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_client_driver.c 2023-09-05 14:28:58.236000000 +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; + +@@ -694,12 +694,55 @@ + return 0; + } + ++static int copy_buf_to_VM(unsigned int agent_id, unsigned int nsid, ++ unsigned long buffer_addr, unsigned int vmpid) ++{ ++ int ret = 0; ++ struct smc_event_data *event_data = NULL; ++ ++ event_data = find_event_control(agent_id, nsid); ++ if (!event_data) ++ return -EINVAL; ++ ++ if (write_to_VMclient((void *)(uintptr_t)buffer_addr, ++ event_data->agent_buff_size, ++ event_data->agent_buff_kernel, ++ event_data->agent_buff_size, ++ vmpid) != 0) { ++ tloge("copy agent buffer failed\n"); ++ return -ENOMEM; ++ } ++ return ret; ++} ++ ++static int copy_buf_from_VM(unsigned int agent_id, unsigned int nsid, ++ unsigned long buffer_addr, unsigned int vmpid) ++{ ++ int ret = 0; ++ struct smc_event_data *event_data = NULL; ++ ++ event_data = find_event_control(agent_id, nsid); ++ if (!event_data) ++ return -EINVAL; ++ ++ if (read_from_VMclient(event_data->agent_buff_kernel, ++ event_data->agent_buff_size, ++ (void *)(uintptr_t)buffer_addr, ++ event_data->agent_buff_size, ++ vmpid) != 0) { ++ tloge("copy agent buffer failed\n"); ++ return -EFAULT; ++ } ++ return ret; ++} ++ + /* ioctls for the secure storage daemon */ + int public_ioctl(const struct file *file, unsigned int cmd, unsigned long arg, bool is_from_client_node) + { + int ret = -EINVAL; + struct tc_ns_dev_file *dev_file = NULL; + uint32_t nsid = get_nsid(); ++ unsigned long tmp[2]; + void *argp = (void __user *)(uintptr_t)arg; + if (file == NULL || file->private_data == NULL) { + tloge("invalid params\n"); +@@ -707,18 +750,35 @@ + } + dev_file = file->private_data; + #ifdef CONFIG_CONFIDENTIAL_CONTAINER +- dev_file->nsid = nsid; ++ if (dev_file != NULL && dev_file->nsid == 0) ++ dev_file->nsid = nsid; ++ //if (dev_file->isVM) ++ // nsid = dev_file->nsid; + #endif + ++ if (dev_file->isVM) { ++ if (copy_from_user(tmp, (void *)(uintptr_t)arg, sizeof(tmp)) != 0) { ++ tloge("copy agent args failed\n"); ++ return -EFAULT; ++ } ++ arg = tmp[0]; ++ } ++ tlogd("nsid = %u, dev_file->nsid = %u \n", nsid, dev_file->nsid); + switch (cmd) { + case TC_NS_CLIENT_IOCTL_WAIT_EVENT: + if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0) + return -EINVAL; + ret = tc_ns_wait_event((unsigned int)arg, nsid); ++ if (!ret && dev_file->isVM) { ++ ret = copy_buf_to_VM(tmp[0], nsid, tmp[1], dev_file->vmpid); ++ } + break; + case TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE: + if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0) + return -EINVAL; ++ if (dev_file->isVM) { ++ ret = copy_buf_from_VM(tmp[0], nsid, tmp[1], dev_file->vmpid); ++ } + ret = tc_ns_send_event_response((unsigned int)arg, nsid); + break; + case TC_NS_CLIENT_IOCTL_REGISTER_AGENT: +@@ -796,12 +856,12 @@ + case TC_NS_CLIENT_IOCTL_WAIT_EVENT: + case TC_NS_CLIENT_IOCTL_REGISTER_AGENT: + case TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT: +- if (get_agent_id(arg, cmd, &agent_id) != 0) ++ /* if (get_agent_id(arg, cmd, &agent_id) != 0) + return ret; + if (check_ext_agent_access(agent_id) != 0) { + tloge("the agent is not access\n"); + return -EPERM; +- } ++ }*/ + ret = public_ioctl(file, cmd, arg, true); + break; + default: +@@ -812,6 +872,19 @@ + return ret; + } + ++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->vmpid = vmid; ++ tlogd(" dev_file->vmpid %d\n", (int)dev_file->vmpid); ++ tlogd("------------------\n"); ++ tlogd("task_active_pid_ns(current)->ns.inum = %u \n", task_active_pid_ns(current)->ns.inum); ++ tlogd("PROC_PID_INIT_INO = %u\n", PROC_PID_INIT_INO); ++ tlogd("------------------\n"); ++ return 0; ++} ++ + void handle_cmd_prepare(unsigned int cmd) + { + if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT && +@@ -831,6 +904,10 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; ++ 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: +@@ -866,7 +943,10 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; +- ++ 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: +@@ -899,13 +979,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) +@@ -1442,3 +1522,5 @@ + #endif + module_exit(tc_exit); + MODULE_LICENSE("GPL"); ++ ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/tc_client_driver.h ./itrustee_tzdriver_new/core/tc_client_driver.h +--- ./itrustee_tzdriver/core/tc_client_driver.h 2023-08-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_client_driver.h 2023-09-05 13:59:26.880000000 +0800 +@@ -38,6 +38,7 @@ + int tc_ns_client_close(struct tc_ns_dev_file *dev); + int is_agent_alive(unsigned int agent_id, unsigned int nsid); + int tc_ns_register_host_nsid(void); ++int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid); + + #if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) + const struct file_operations *get_cvm_fops(void); +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/tc_cvm_driver.c ./itrustee_tzdriver_new/core/tc_cvm_driver.c +--- ./itrustee_tzdriver/core/tc_cvm_driver.c 2023-08-03 17:22:25.908000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_cvm_driver.c 2023-09-05 14:23:42.804000000 +0800 +@@ -57,6 +57,10 @@ + { + int ret = -EFAULT; + void *argp = (void __user *)(uintptr_t)arg; ++ 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) { +@@ -137,3 +141,4 @@ + return &g_cvm_fops; + } + #endif ++ +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-03 17:22:25.912000000 +0800 ++++ ./itrustee_tzdriver_new/tc_ns_client.h 2023-09-05 13:59:26.864000000 +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-03 17:22:25.912000000 +0800 ++++ ./itrustee_tzdriver_new/tc_ns_log.h 2023-09-05 13:59:26.864000000 +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-03 17:22:25.912000000 +0800 ++++ ./itrustee_tzdriver_new/teek_ns_client.h 2023-09-05 13:59:26.860000000 +0800 +@@ -134,6 +134,8 @@ + #ifdef CONFIG_TEE_TELEPORT_SUPPORT + bool portal_enabled; + #endif ++ uint32_t vmpid; ++ bool isVM; + }; + + union tc_ns_parameter { +@@ -253,3 +255,4 @@ + }; + + #endif ++ diff --git a/trustzone-awared-vm/host/vtzb_proxy/Makefile b/trustzone-awared-vm/host/vtzb_proxy/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e73c794fbcc2ca1a427536fed78e1b7e936cc270 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/cloud/tee_client_log.h b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_client_log.h new file mode 100644 index 0000000000000000000000000000000000000000..59681ecdb2109e3f6001b800e5c7acb436abf6ce --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/cloud/tee_session_pool.h b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_session_pool.h new file mode 100644 index 0000000000000000000000000000000000000000..5812698b70756c576d5da81f314d742ddb3e9400 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tc_ns_client.h b/trustzone-awared-vm/host/vtzb_proxy/include/tc_ns_client.h new file mode 100644 index 0000000000000000000000000000000000000000..24e2cd6a582deab75332e477c8ee87ee328c4ac0 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tee_client_api.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_api.h new file mode 100644 index 0000000000000000000000000000000000000000..d68997907464646b715802c560da1962b9139867 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tee_client_constants.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_constants.h new file mode 100644 index 0000000000000000000000000000000000000000..2a7e31f678d2c9ad31a2ac44d9b4e7cc58b6700a --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tee_client_list.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_list.h new file mode 100644 index 0000000000000000000000000000000000000000..d14656c051631001ed5e82140489ae7614d36ee3 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tee_client_type.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_type.h new file mode 100644 index 0000000000000000000000000000000000000000..0ff7692b77c62efa87419f27535c60f40a40e38c --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/include/tee_sys_log.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_sys_log.h new file mode 100644 index 0000000000000000000000000000000000000000..1fa0c3deaa85c4f994bb149a742945a59f2684dc --- /dev/null +++ b/trustzone-awared-vm/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 + diff --git a/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c new file mode 100644 index 0000000000000000000000000000000000000000..86a6becff15081f6019071cbc403e2fff10c2155 --- /dev/null +++ b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c @@ -0,0 +1,124 @@ +#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); +} + +/* +// 示例任务函数 +void task_function(void* arg) { + int task_arg = *((int*)arg); + printf("Task argument: %d\n", task_arg); +} + +// 主函数 +int main() { + ThreadPool pool; + thread_pool_init(&pool); + + int tasks[10]; + for (int i = 0; i < 10; i++) { + tasks[i] = i + 1; + thread_pool_submit(&pool, task_function, &tasks[i]); + } + + // 等待一段时间,模拟其他工作 + sleep(3); + + // 销毁线程池 + thread_pool_destroy(&pool); + + return 0; +}*/ diff --git a/trustzone-awared-vm/host/vtzb_proxy/thread_pool.h b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.h new file mode 100644 index 0000000000000000000000000000000000000000..96ed32f22fe16695bff997e24edf0e926fda182e --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/virt.c b/trustzone-awared-vm/host/vtzb_proxy/virt.c new file mode 100644 index 0000000000000000000000000000000000000000..2521d4cb8d19e6604a9d071cbf39b8d2949b47d9 --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/virt.h b/trustzone-awared-vm/host/vtzb_proxy/virt.h new file mode 100644 index 0000000000000000000000000000000000000000..85913852e8ca9514388dcedcdcbeb7fb39bc9d3e --- /dev/null +++ b/trustzone-awared-vm/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/host/vtzb_proxy/vtzb_proxy.c b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.c new file mode 100644 index 0000000000000000000000000000000000000000..8252359c60bb55051be9faf02bb3bd1ad08d0635 --- /dev/null +++ b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.c @@ -0,0 +1,1074 @@ +/* + */ + +#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); +LIST_DECLARE(g_agent_buf_list); +pthread_mutex_t g_mutex_shrd_mem = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_mutex_agent_buf = 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() +{ + debug("释放串口资源\n"); + 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"); + 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"); + } + } else { + ret = access(serial_port->path, R_OK | W_OK); + if (ret) { + debug(" 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); + } else if (packet_cmd->flag == TC_CVM_DEV_FLAG) { + fd = open(TC_NS_CVM_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 free_agent_buf(int ptzfd) +{ + struct ListNode* ptr = NULL; + struct ListNode* n = NULL; + struct_agent_args* agent_args = NULL; + unsigned long buf[2]; + pthread_mutex_lock(&g_mutex_agent_buf); + debug(" free_agent_buf \n"); + if (!LIST_EMPTY(&g_agent_buf_list)) { + LIST_FOR_EACH_SAFE(ptr, n, &g_agent_buf_list) { + struct_agent_args* tmp = + CONTAINER_OF(ptr, struct_agent_args, node); + if (tmp->dev_fd == ptzfd) { + ListRemoveEntry(&(tmp->node)); + /*unregister*/ + //free(tmp); + agent_args = tmp; + } + } + } + pthread_mutex_unlock(&g_mutex_agent_buf); + if (agent_args) { + debug(" unregister \n"); + buf[0] = agent_args->args.id; + int ret = ioctl(ptzfd, TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT, buf); + if (ret) { + tloge("ioctl failed\n"); + debug(" ioctl unregister failed\n"); + } + free(agent_args); + } else { + debug(" not find!\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); + free_agent_buf(packet_cmd->ptzfd); + debug(" after free_agent_buf\n"); + 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); + 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 register_agent(struct_packet_cmd_regagent *packet_cmd, int serial_port_fd) +{ + debug("***** cmd is register_agent *****\n"); + int ret; + struct_packet_rsp_regagent packet_rsp; + unsigned long buf[2]; + buf[0] = (unsigned long)(&packet_cmd->args); + debug(" buf_size = %u\n", packet_cmd->args.bufferSize); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_REGISTER_AGENT, buf); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + if (!ret) { + /* 将agent buffer加入链表 */ + struct_agent_args* tmp = (struct_agent_args*)malloc(sizeof(struct_agent_args)); + ListInit(&tmp->node); + tmp->dev_fd = packet_cmd->ptzfd; + tmp->args = packet_cmd->args; + tmp->vmaddr = packet_cmd->vmaddr; + pthread_mutex_lock(&g_mutex_agent_buf); + ListInsertTail(&g_agent_buf_list, &tmp->node); + pthread_mutex_unlock(&g_mutex_agent_buf); + } + + 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 load_sec_file(struct_packet_cmd_load_sec *packet_cmd, int serial_port_fd) +{ + int ret; + struct_packet_rsp_load_sec packet_rsp; + //unsigned long buf[2]; + //buf[0] = (unsigned long)(&packet_cmd->ioctlArg); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + debug("***** cmd is load_sec_file *****\n"); + debug(" secFileInfo.fileSize = %d \n", packet_cmd->ioctlArg.secFileInfo.fileSize); + debug(" ioctlArg.fileBuffer = %p \n", packet_cmd->ioctlArg.fileBuffer); + debug(" ioctlArg.secFileInfo.fileType = %d \n",packet_cmd->ioctlArg.secFileInfo.fileType); + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOAD_APP_REQ, &packet_cmd->ioctlArg); + packet_rsp.ret = ret; + packet_rsp.ioctlArg = packet_cmd->ioctlArg; + 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 wait_event(struct_packet_cmd_event *packet_cmd, int serial_port_fd) +{ + debug("***** cmd is wait event *****\n"); + int ret = -EFAULT; + struct_packet_rsp_general packet_rsp; + unsigned long buf[2]; + struct ListNode* ptr = NULL; + bool bfind = false; + + buf[0] = packet_cmd->agent_id; + + pthread_mutex_lock(&g_mutex_agent_buf); + if (!LIST_EMPTY(&g_agent_buf_list)) { + LIST_FOR_EACH(ptr, &g_agent_buf_list) { + struct_agent_args* agent_args = + CONTAINER_OF(ptr, struct_agent_args, node); + if (agent_args->args.id == packet_cmd->agent_id) { + buf[1] = (unsigned long)agent_args->vmaddr; + bfind = true; + break; + } + } + } + pthread_mutex_unlock(&g_mutex_agent_buf); + if (bfind) { + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_WAIT_EVENT, buf); + } + debug(" after wait, ret = %d\n", ret); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + 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 = -EFAULT; + struct_packet_rsp_general packet_rsp; + unsigned long buf[2]; + bool bfind = false; + struct ListNode* ptr = NULL; + buf[0] = packet_cmd->agent_id; + pthread_mutex_lock(&g_mutex_agent_buf); + if (!LIST_EMPTY(&g_agent_buf_list)) { + LIST_FOR_EACH(ptr, &g_agent_buf_list) { + struct_agent_args* agent_args = + CONTAINER_OF(ptr, struct_agent_args, node); + if (agent_args->args.id == packet_cmd->agent_id) { + buf[1] = (unsigned long)agent_args->vmaddr; + bfind = true; + break; + } + } + } + pthread_mutex_unlock(&g_mutex_agent_buf); + + if (bfind) { + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, buf); + } + + debug(" after respomse, ret = %d\n", ret); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + 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 VTZF_LOAD_SEC: + if (buf_size >= (int)sizeof(struct_packet_cmd_load_sec)) { + (void)load_sec_file((struct_packet_cmd_load_sec *)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)register_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 process_event(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; + 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); + process_event(g_pollfd[i].fd); + } + } + } + + serial_port_list_destroy(); + return nr_failed; +} + + diff --git a/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..981cf944005ddc133e5a83ae6d86ad876d8e2c65 --- /dev/null +++ b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h @@ -0,0 +1,487 @@ +#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 5 +#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 TC_CVM_DEV_FLAG 5 + + +#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 VTZF_LOAD_SEC 53 +#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; + +typedef struct { + struct AgentIoctlArgs args; + int32_t dev_fd; + void *vmaddr; + struct ListNode node; +} struct_agent_args; + +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; + uint32_t seq_num; + int32_t ptzfd; + int32_t cpu_index; + struct SecLoadIoctlStruct ioctlArg; +} struct_packet_cmd_load_sec; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + struct SecLoadIoctlStruct ioctlArg; +} struct_packet_rsp_load_sec; + +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; + void *vmaddr; + 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__ */ + + diff --git a/trustzone-awared-vm/vm/vtzdriver/Makefile b/trustzone-awared-vm/vm/vtzdriver/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e640990b474cafb4c293fb15512a6d0233230e09 --- /dev/null +++ b/trustzone-awared-vm/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/vm/vtzdriver/inc/tc_ns_client.h b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_client.h new file mode 100644 index 0000000000000000000000000000000000000000..d88f4d315726d5def3ba7023b8d6c44bbe1d416f --- /dev/null +++ b/trustzone-awared-vm/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/vm/vtzdriver/inc/tc_ns_log.h b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_log.h new file mode 100644 index 0000000000000000000000000000000000000000..33a1e90ae5224885962f03d1f57d35f40cf2910a --- /dev/null +++ b/trustzone-awared-vm/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/vm/vtzdriver/inc/teek_client_constants.h b/trustzone-awared-vm/vm/vtzdriver/inc/teek_client_constants.h new file mode 100644 index 0000000000000000000000000000000000000000..6b0b32ac0854a06bc1825538d5f4710ccd4e8ce7 --- /dev/null +++ b/trustzone-awared-vm/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/vm/vtzdriver/inc/teek_ns_client.h b/trustzone-awared-vm/vm/vtzdriver/inc/teek_ns_client.h new file mode 100644 index 0000000000000000000000000000000000000000..7a6c008523657d20a9638bedccb3260699c78fd7 --- /dev/null +++ b/trustzone-awared-vm/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/vm/vtzdriver/vtzf.c b/trustzone-awared-vm/vm/vtzdriver/vtzf.c new file mode 100644 index 0000000000000000000000000000000000000000..08851dfb7492bf87772b3ea93611069ec3908b1a --- /dev/null +++ b/trustzone-awared-vm/vm/vtzdriver/vtzf.c @@ -0,0 +1,2126 @@ +#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 CONFIG_CONFIDENTIAL_CONTAINER + +#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; +#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT) +struct dev_node g_tc_cvm; +#endif +/* 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 +}; + +static const struct file_operations g_cvm_fops = { + .owner = THIS_MODULE, + .open = vtzf_cvm_open, + .release = vtzf_close, + .unlocked_ioctl = tc_cvm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tc_compat_cvm_ioctl, +#endif +}; + +const struct file_operations *get_cvm_fops(void) +{ + return &g_cvm_fops; +} + +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 < SERIAL_PORT_NUM;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 void tc_re_init(const struct device *class_dev) +{ + int ret; + //agent_init(); + //ret = tc_ns_register_ion_mem(); + //if (ret != 0) + // tloge("Failed to register ion mem in tee\n"); +#ifdef CONFIG_TZDRIVER_MODULE + ret = init_tlogger_service(); + if (ret != 0) + tloge("tlogger init failed\n"); +#endif +} +*/ +static int __init vtzf_init(void) +{ + int ret; + ret = tc_ns_client_init(); + if (ret != 0) + return ret; + + //tlogcat 相关 + //tc_re_init(g_tc_client.class_dev); + + 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(); +} + +int tc_ns_client_open(struct vtzf_dev_file **dev_file, uint32_t flag) +{ + struct vtzf_dev_file *dev = NULL; + tlogd("vtzf open \n"); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)dev)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + + mutex_lock(&g_tc_ns_dev_list.dev_lock); + list_add_tail(&dev->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->dev_file_id = g_device_file_cnt; + g_device_file_cnt++; + mutex_unlock(&g_device_file_cnt_lock); + + INIT_LIST_HEAD(&dev->shared_mem_list); + + mutex_init(&dev->shared_mem_lock); + + (void)open_tzdriver(dev, flag); + /* Once this device is opened, Tzdriver must be opened accordingly */ + + *dev_file = dev; + return 0; +} + +static int vtzf_client_open(struct inode *inode, struct file *file) +{ + int ret; + struct vtzf_dev_file *dev_file = NULL; + (void)inode; + file->private_data = NULL; + ret = tc_ns_client_open(&dev_file, TC_NS_CLIENT_DEV_FLAG); + if (!ret) + file->private_data = dev_file; + + 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 vtzf_cvm_open(struct inode *inode, struct file *file) +{ + int ret = -1; + struct vtzf_dev_file *dev = NULL; + (void)inode; + +#ifdef CONFIG_TEE_TELEPORT_AUTH + ret = check_tee_teleport_auth(); +#endif +#ifdef CONFIG_TEE_AGENTD_AUTH + if (ret != 0) + ret = check_tee_agentd_auth(); +#endif + //if (ret != 0) { + // tloge("teleport/agentd auth failed, ret %d\n", ret); + // return -EACCES; + //} + + file->private_data = NULL; + ret = tc_ns_client_open(&dev, TC_CVM_DEV_FLAG); + if (ret == 0) + file->private_data = dev; + return ret; +} + +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; +} + +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 void transfer_shared_mem() +{ + void; +} +*/ +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(); + */ + 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; +} + +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; + } + + 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); + + packet_cmd.cmd = VTZF_FS_REGISTER_AGENT; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.phyaddr = virt_to_phys(buffer); + + 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 send_wait_event(struct vtzf_dev_file *dev_file, unsigned int agent_id) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_event packet_cmd; + struct_packet_rsp_general 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 = VTZF_WAIT_EVENT; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.agent_id = agent_id; + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + tloge("sen to proxy failed\n"); + return -EFAULT; + } else { + ret = packet_rsp.ret; + } + return ret; +} + +static int send_event_response(struct vtzf_dev_file *dev_file, unsigned int agent_id) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_event packet_cmd; + struct_packet_rsp_general 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 = VTZF_SEND_EVENT_RESPONSE; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.agent_id = agent_id; + + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + tloge("sen to proxy failed\n"); + return -EFAULT; + } else { + ret = packet_rsp.ret; + } + return ret; +} + +static int tc_ns_load_secfile(struct vtzf_dev_file *dev_file, + struct load_secfile_ioctl_struct *ioctlArg) +{ + int ret; + uint32_t seq_num = get_seq_num(); + struct_packet_cmd_load_sec packet_cmd; + struct_packet_rsp_load_sec packet_rsp; + size_t file_size; + char *buffer = NULL, *tmp_buffer = NULL; + + if (!ioctlArg || !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_LOAD_SEC; + packet_cmd.ptzfd = dev_file->ptzfd; + + packet_cmd.ioctlArg = *ioctlArg; + //if (copy_from_user(&(packet_cmd.ioctlArg), argp, sizeof(packet_cmd.ioctlArg) != 0)) { + // return -EFAULT; + //} + /* 有Buffer地址需要转换char *cliContext.file_buffer */ + file_size = (size_t)packet_cmd.ioctlArg.sec_file_info.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.ioctlArg.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)ioctlArg->file_buffer, (unsigned long long)tmp_buffer); + packet_cmd.ioctlArg.file_buffer = virt_to_phys(buffer); + + + /* 将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); + + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + tlogd(" load_secfile ret =%d \n", ret); + if (ret) { + tloge("load_secfile failed ret is %d\n", ret); + } + /* 还原地址,并将返回的内容拷贝回 */ + packet_rsp.ioctlArg.file_buffer = tmp_buffer; + //if (copy_to_user(argp, &packet_rsp.ioctlArg, sizeof(struct load_secfile_ioctl_struct)) != 0){ + // ret = -EFAULT; + //} + *ioctlArg = packet_rsp.ioctlArg; + } else { + tloge("send to proxy failed ret is %d\n", ret); + } +END: + kfree(buffer); + return ret; +} + +int public_ioctl(const struct file *file, unsigned int cmd, + unsigned long arg, bool is_from_client_node) +{ + int ret = -EINVAL; + void *argp = (void __user *)(uintptr_t)arg; + struct vtzf_dev_file *dev_file = NULL; + struct load_secfile_ioctl_struct ioctlArg; + dev_file = file->private_data; + switch (cmd) { + case TC_NS_CLIENT_IOCTL_WAIT_EVENT: + ret = send_wait_event(dev_file, (unsigned int)arg); + + break; + case TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE: + ret = send_event_response(dev_file, (unsigned int)arg); + + 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: + if (copy_from_user(&ioctlArg, argp, sizeof(ioctlArg)) != 0) { + tloge("copy from user failed\n"); + return -EFAULT; + } + ret = tc_ns_load_secfile(file->private_data, &ioctlArg); + if (copy_to_user(argp, &ioctlArg, sizeof(ioctlArg)) != 0 && ret == 0) + ret = -EFAULT; + 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; +} + +static long tc_cvm_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_INFO: + ret = tc_ns_get_tee_info(file->private_data, argp); + break; + +#ifdef CONFIG_TEE_TELEPORT_SUPPORT + case TC_NS_CLIENT_IOCTL_PORTAL_REGISTER: + if (check_tee_teleport_auth() == 0) + ret = tee_portal_register(file->private_data, argp); + else + tloge("check tee_teleport path failed\n"); + break; + case TC_NS_CLIENT_IOCTL_PORTAL_WORK: + if (check_tee_teleport_auth() == 0) + ret = tee_portal_work(file->private_data); + else + tloge("check tee_teleport path failed\n"); + break; +#endif + default: + ret = public_ioctl(file, cmd, arg, false); + 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; +} + +long tc_compat_cvm_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret; + + if (!file) + return -EINVAL; + + ret = tc_cvm_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/vm/vtzdriver/vtzf.h b/trustzone-awared-vm/vm/vtzdriver/vtzf.h new file mode 100644 index 0000000000000000000000000000000000000000..1b9d5376405901dbbcbd8256d6da9f48b40cd57a --- /dev/null +++ b/trustzone-awared-vm/vm/vtzdriver/vtzf.h @@ -0,0 +1,414 @@ +#ifndef VTZF_H +#define VTZF_H + +#include +#include +//#include +#include "tc_ns_client.h" +#include "teek_ns_client.h" + +#define VTZF_DEV "vtzf" +#define CONFIG_CONFIDENTIAL_CONTAINER +#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 SERIAL_PORT_NUM 5 + +#define TC_NS_CLIENT_DEV_FLAG 3 +#define TC_PRIVATE_DEV_FLAG 4 +#define TC_CVM_DEV_FLAG 5 + +#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_WAIT_EVENT 49 +#define VTZF_SEND_EVENT_RESPONSE 51 +#define VTZF_LOAD_SEC 53 +#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; + uint32_t seq_num; + __s32 ptzfd; + void *phyaddr; + struct agent_ioctl_args args; +} struct_packet_cmd_regagent; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + struct agent_ioctl_args args; +} struct_packet_rsp_regagent; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + __s32 ptzfd; + uint32_t agent_id; +} struct_packet_cmd_event; + +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; + uint32_t seq_num; + __s32 ptzfd; + __s32 cpu_index; + struct load_secfile_ioctl_struct ioctlArg; +} struct_packet_cmd_load_sec; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + struct load_secfile_ioctl_struct ioctlArg; +} struct_packet_rsp_load_sec; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + __s32 ptzfd; + __s32 cpu_index; + struct tc_ns_client_context cliContext; +} struct_packet_cmd_session; + +typedef struct { + uint32_t seq_num; + uint32_t ret; + 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; + +int tc_ns_client_open(struct vtzf_dev_file **dev_file, uint32_t flag); +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_cvm_open(struct inode *inode, struct file *file); +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 long tc_cvm_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +static int public_ioctl(const struct file *file, unsigned int cmd, + unsigned long arg, bool is_from_client_node); +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); +long tc_compat_cvm_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); +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 + + +