diff --git a/trustzone-awared-vm/Host/qemu.patch b/trustzone-awared-vm/Host/qemu.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e14f7b3c2dd088b1d129c613aa9b8295100211d --- /dev/null +++ b/trustzone-awared-vm/Host/qemu.patch @@ -0,0 +1,874 @@ +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-10-07 15:07:43.808000000 +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-10-07 15:07:43.808000000 +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-10-07 15:07:43.808000000 +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-10-07 15:07:43.808000000 +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-10-07 15:05:08.288000000 +0800 ++++ qemu_after/hw/char/virtio-console.c 2023-10-07 15:08:46.344000000 +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) +@@ -44,6 +52,113 @@ + virtio_serial_throttle_port(VIRTIO_SERIAL_PORT(vcon), false); + 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, +@@ -57,6 +172,158 @@ + return 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, 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 *)buf; ++ 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 *)buf; ++ 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 *)buf; ++ 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 *)buf; ++ 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 *)buf; ++ ++ 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; ++ } ++ } else if (IS_PARTIAL_MEM(param_type) || param_type == TEEC_MEMREF_SHARED_INOUT) { ++ 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; ++ } ++ } else if (IS_VALUE_MEM(param_type) || check_value) { ++ /* do nothing */ ++ } 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, buf, len); + trace_virtio_console_flush_buf(port->id, len, ret); + +@@ -304,3 +571,6 @@ + } + + 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-10-07 15:05:08.392000000 +0800 ++++ qemu_after/include/monitor/monitor.h 2023-10-07 15:07:43.808000000 +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-10-07 15:05:08.428000000 +0800 ++++ qemu_after/monitor/misc.c 2023-10-07 15:07:43.808000000 +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..1a1df3a13be8d4433617610a551983c735416bf4 --- /dev/null +++ b/trustzone-awared-vm/Host/tzdriver.patch @@ -0,0 +1,1313 @@ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/auth/auth_base_impl.c ./itrustee_tzdriver_new/auth/auth_base_impl.c +--- ./itrustee_tzdriver/auth/auth_base_impl.c 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/auth/auth_base_impl.c 2023-10-07 14:38:55.572000000 +0800 +@@ -332,11 +332,28 @@ + + return CHECK_ACCESS_SUCC; + } ++ ++int check_proxy_auth(void) ++{ ++ int ret = check_proc_uid_path(PROXY_PATH_UID_AUTH_CTX); ++ if (ret != 0) { ++ tloge("check proxy path failed, ret %d\n", ret); ++ return ret; ++ } ++ ++ return CHECK_ACCESS_SUCC; ++} + #else + int check_teecd_auth(void) + { + return 0; + } ++ ++int check_proxy_auth(void) ++{ ++ return 0; ++} ++ + #endif + + #ifdef CONFIG_TEE_TELEPORT_AUTH +@@ -362,3 +379,4 @@ + return CHECK_ACCESS_SUCC; + } + #endif ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/auth/auth_base_impl.h ./itrustee_tzdriver_new/auth/auth_base_impl.h +--- ./itrustee_tzdriver/auth/auth_base_impl.h 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/auth/auth_base_impl.h 2023-10-07 14:38:55.564000000 +0800 +@@ -84,6 +84,7 @@ + void mutex_crypto_hash_unlock(void); + int check_hidl_auth(void); + int check_teecd_auth(void); ++int check_proxy_auth(void); + #else + + static inline void free_shash_handle(void) +@@ -101,6 +102,11 @@ + return 0; + } + ++int check_proxy_auth(void) ++{ ++ return 0; ++} ++ + #endif /* CLIENT_AUTH || TEECD_AUTH */ + + #ifdef CONFIG_TEE_TELEPORT_AUTH +@@ -112,3 +118,4 @@ + #endif + + #endif ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/agent.c ./itrustee_tzdriver_new/core/agent.c +--- ./itrustee_tzdriver/core/agent.c 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/core/agent.c 2023-10-07 14:38:55.616000000 +0800 +@@ -240,6 +240,7 @@ + smc_cmd->operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd->operation_h_phys = + (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; ++ tlogd("smc_cmd->nsid = %u\n", smc_cmd->nsid); + if (tc_ns_smc(smc_cmd) != 0) { + ret = -EPERM; + tloge("set native hash failed\n"); +@@ -256,13 +257,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; + +@@ -295,7 +296,8 @@ + return ret; + } + +-int tc_ns_late_init(unsigned long arg) ++int tc_ns_late_init(const struct tc_ns_dev_file *dev_file, ++ unsigned long arg) + { + int ret = 0; + struct tc_ns_smc_cmd smc_cmd = { {0}, 0 }; +@@ -316,7 +318,8 @@ + smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = + (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; +- ++ if (dev_file->isVM) ++ smc_cmd.nsid = dev_file->nsid; + if (tc_ns_smc(&smc_cmd)) { + ret = -EPERM; + tloge("late int failed\n"); +@@ -583,7 +586,6 @@ + put_agent_event(event_data); + return ret; + } +- + ret = wait_event_interruptible(event_data->wait_event_wq, + event_data->ret_flag); + put_agent_event(event_data); +@@ -594,7 +596,8 @@ + return ret; + } + +-int tc_ns_sync_sys_time(const struct tc_ns_client_time *tc_ns_time) ++int tc_ns_sync_sys_time(const struct tc_ns_dev_file *dev_file, ++ const struct tc_ns_client_time *tc_ns_time) + { + struct tc_ns_smc_cmd smc_cmd = { {0}, 0 }; + int ret = 0; +@@ -620,6 +623,8 @@ + smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = + (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; ++ if (dev_file && dev_file->isVM) ++ smc_cmd.nsid = dev_file->nsid; + if (tc_ns_smc(&smc_cmd)) { + tloge("tee adjust time failed, return error\n"); + ret = -EPERM; +@@ -629,7 +634,8 @@ + return ret; + } + +-int sync_system_time_from_user(const struct tc_ns_client_time *user_time) ++int sync_system_time_from_user(const struct tc_ns_dev_file *dev_file, ++ const struct tc_ns_client_time *user_time) + { + int ret = 0; + struct tc_ns_client_time time = { 0 }; +@@ -644,7 +650,7 @@ + return -EFAULT; + } + +- ret = tc_ns_sync_sys_time(&time); ++ ret = tc_ns_sync_sys_time(dev_file, &time); + if (ret != 0) + tloge("sync system time from user failed, ret = 0x%x\n", ret); + +@@ -662,7 +668,7 @@ + time.seconds = (uint32_t)kernel_time.ts.tv_sec; + time.millis = (uint32_t)(kernel_time.ts.tv_nsec / MS_TO_NS); + +- ret = tc_ns_sync_sys_time(&time); ++ ret = tc_ns_sync_sys_time(NULL, &time); + if (ret != 0) + tloge("sync system time from kernel failed, ret = 0x%x\n", ret); + +@@ -945,6 +951,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)) +@@ -1382,3 +1390,5 @@ + put_agent_event(event_data); + } + } ++ ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/agent.h ./itrustee_tzdriver_new/core/agent.h +--- ./itrustee_tzdriver/core/agent.h 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/core/agent.h 2023-10-07 14:38:55.572000000 +0800 +@@ -118,7 +118,8 @@ + unsigned int agent_id, unsigned int nsid); + int is_agent_alive(unsigned int agent_id, unsigned int nsid); + int tc_ns_set_native_hash(unsigned long arg, unsigned int cmd_id); +-int tc_ns_late_init(unsigned long arg); ++int tc_ns_late_init(const struct tc_ns_dev_file *dev_file, ++ unsigned long arg); + int tc_ns_register_agent(struct tc_ns_dev_file *dev_file, unsigned int agent_id, + unsigned int buffer_size, void **buffer, bool user_agent); + int tc_ns_unregister_agent(unsigned int agent_id, unsigned int nsid); +@@ -126,7 +127,8 @@ + int tc_ns_wait_event(unsigned int agent_id, unsigned int nsid); + int tc_ns_send_event_response(unsigned int agent_id, unsigned int nsid); + void send_crashed_event_response_single(const struct tc_ns_dev_file *dev_file); +-int sync_system_time_from_user(const struct tc_ns_client_time *user_time); ++int sync_system_time_from_user(const struct tc_ns_dev_file *dev_file, ++ const struct tc_ns_client_time *user_time); + void sync_system_time_from_kernel(void); + int tee_agent_clear_work(struct tc_ns_client_context *context, + unsigned int dev_file_id); +@@ -138,3 +140,4 @@ + void free_agent_list(void); + + #endif ++ +diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/gp_ops.c ./itrustee_tzdriver_new/core/gp_ops.c +--- ./itrustee_tzdriver/core/gp_ops.c 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/core/gp_ops.c 2023-10-07 14:38:55.580000000 +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,6 +451,7 @@ + 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) { +@@ -393,7 +484,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 +496,20 @@ + 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 (*buffer_size == 0) { + tloge("buffer_size from user is 0\n"); + return -ENOMEM; +@@ -497,7 +591,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,12 +640,13 @@ + + #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)) { +@@ -572,6 +667,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 +774,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 +788,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; +@@ -775,13 +968,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; + } +@@ -1231,7 +1437,7 @@ + ret = config_smc_cmd_context(call_params, &op_params); + if (ret != 0) + goto free_src; +- ++ tlogd("op_params.smc_cmd->nsid %u\n", op_params.smc_cmd->nsid); + tee_ret = tc_ns_smc(op_params.smc_cmd); + + reset_session_id(call_params, &op_params, tee_ret); +@@ -1248,3 +1454,8 @@ + 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-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/core/gp_ops.h 2023-10-07 14:38:55.580000000 +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-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/core/session_manager.c 2023-10-07 14:38:55.592000000 +0800 +@@ -595,7 +595,7 @@ + } + + static int tc_ns_service_init(const unsigned char *uuid, uint32_t uuid_len, +- struct tc_ns_service **new_service) ++ struct tc_ns_service **new_service, uint32_t nsid) + { + int ret = 0; + struct tc_ns_service *service = NULL; +@@ -615,11 +615,8 @@ + return -EFAULT; + } + +-#ifdef CONFIG_CONFIDENTIAL_CONTAINER +- service->nsid = task_active_pid_ns(current)->ns.inum; +-#else +- service->nsid = PROC_PID_INIT_INO; +-#endif ++ service->nsid = nsid; ++ + INIT_LIST_HEAD(&service->session_list); + mutex_init(&service->session_lock); + list_add_tail(&service->head, &g_service_list); +@@ -655,6 +652,8 @@ + bool is_full = false; + #ifdef CONFIG_CONFIDENTIAL_CONTAINER + unsigned int nsid = task_active_pid_ns(current)->ns.inum; ++ if (dev_file->isVM) ++ nsid = dev_file->nsid; + #else + unsigned int nsid = PROC_PID_INIT_INO; + #endif +@@ -683,7 +682,7 @@ + goto add_service; + } + /* Create a new service if we couldn't find it in list */ +- ret = tc_ns_service_init(context->uuid, UUID_LEN, &service); ++ ret = tc_ns_service_init(context->uuid, UUID_LEN, &service, nsid); + /* unlock after init to make sure find service from all is correct */ + mutex_unlock(&g_service_list_lock); + if (ret != 0) { +@@ -792,16 +791,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 +843,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 +856,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 +869,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 +1391,122 @@ + 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) ++{ ++ 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 (copy_from_user(&buffer_size, size_addr, sizeof(uint32_t))) { ++ 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]; ++ } ++ } ++ } ++ 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) ++{ ++ int ret = 0; ++ 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; ++ ++ if (!dev_file->isVM) ++ return 0; ++ ++ 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 (copy_from_user(&buffer_size, size_addr, sizeof(uint32_t))) { ++ tloge("copy memref.size_addr failed\n"); ++ return -EFAULT; ++ } ++ tlogv("<--------------------\n"); ++ tlogv(" buffer_size = %d \n", buffer_size); ++ tlogv(" vm_buffers[index] = 0x%16.16lx", (long unsigned int)(vm_buffers[index])); ++ tlogv(" buffer_addr + offset = 0x%16.16lx \n", (long unsigned int)(buffer_addr + offset)); ++ //tlogv(" *(buffer_addr + offset) = %s \n", (char*)(buffer_addr + 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)(buffer_addr + offset), ++ buffer_size, dev_file->vmpid)) { ++ tloge("copy buf size failed\n"); ++ return -EFAULT; ++ } ++ } ++ } ++ } ++ mutex_unlock(&dev_file->shared_mem_lock); ++ 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 (dev_file->isVM && ++ process_vm_ref(dev_file, context, vm_buffers)) { ++ tloge("copy from VM memref failed\n"); ++ return -EFAULT; ++ } + + ret = tc_ns_send_cmd(dev_file, context); + if (ret != 0) +@@ -1391,6 +1515,12 @@ + if (ret == 0) + ret = -EFAULT; + } ++ ++ if (ret ==0 && dev_file->isVM && ++ process_vm_ref_end(dev_file, context, vm_buffers)) { ++ tloge("copy to VM memref failed\n"); ++ return -EFAULT; ++ } + return ret; + } + +@@ -1516,3 +1646,7 @@ + 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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/core/smc_smp.c 2023-10-07 14:38:55.600000000 +0800 +@@ -1771,7 +1771,9 @@ + release_pending_entry(pe); + return TEEC_ERROR_GENERIC; + } +- ++ tlogd("---------------------------\n"); ++ tlogd("cmd.nsid = %u \n", cmd.nsid); ++ tlogd("---------------------------\n"); + if (smp_smc_send_process(&cmd, ops, &cmd_ret, info.cmd_index) == -1) + goto clean; + +@@ -1878,11 +1880,13 @@ + + int tc_ns_smc(struct tc_ns_smc_cmd *cmd) + { ++ tlogd("cmd->nsid = %u\n", cmd->nsid); + return proc_tc_ns_smc(cmd, false); + } + + int tc_ns_smc_with_no_nr(struct tc_ns_smc_cmd *cmd) + { ++ tlogd("cmd->nsid = %u\n", cmd->nsid); + return proc_tc_ns_smc(cmd, true); + } + +@@ -2107,3 +2111,4 @@ + } + spin_unlock(&g_pend_lock); + } ++ +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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_client_driver.c 2023-10-07 14:38:55.616000000 +0800 +@@ -181,6 +181,8 @@ + smc_cmd.operation_h_phys = + (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; + ++ if (dev_file->isVM) ++ smc_cmd.nsid = dev_file->nsid; + if (tc_ns_smc(&smc_cmd) != 0) { + ret = -EPERM; + tloge("smc call returns error ret 0x%x\n", smc_cmd.ret_val); +@@ -307,12 +309,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 +696,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,30 +752,54 @@ + } + 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) { ++ tlogd("agent copy to vm \n"); ++ ret = copy_buf_to_VM(tmp[0], nsid, tmp[1], dev_file->vmpid); ++ tlogd("agent copy to vm ret =%d\n",ret); ++ } ++ tlogd("wait event ret = %d\n", ret); + 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); ++ tlogd("event_rsp ret = %d\n", ret); + break; + case TC_NS_CLIENT_IOCTL_REGISTER_AGENT: + ret = ioctl_register_agent(dev_file, arg); ++ tlogd("reg ret = %d\n", 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); ++ tlogd("unreg ret = %d\n", ret); + break; + case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ: + ret = tc_ns_load_secfile(file->private_data, argp, NULL, is_from_client_node); ++ tlogd("sec load ret = %d\n", ret); + break; + default: + tloge("invalid cmd!"); +@@ -812,6 +881,15 @@ + return ret; + } + ++int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid) ++{ ++ dev_file->isVM = true; ++ dev_file->nsid = vmid; ++ dev_file->vmpid = vmid; ++ tlogd(" dev_file->vmpid %d\n", (int)dev_file->vmpid); ++ return 0; ++} ++ + void handle_cmd_prepare(unsigned int cmd) + { + if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT && +@@ -831,6 +909,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: +@@ -845,10 +927,10 @@ + mutex_unlock(&g_set_ca_hash_lock); + break; + case TC_NS_CLIENT_IOCTL_LATEINIT: +- ret = tc_ns_late_init(arg); ++ ret = tc_ns_late_init(file->private_data, arg); + break; + case TC_NS_CLIENT_IOCTL_SYC_SYS_TIME: +- ret = sync_system_time_from_user( ++ ret = sync_system_time_from_user(file->private_data, + (struct tc_ns_client_time *)(uintptr_t)arg); + break; + default: +@@ -866,7 +948,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: +@@ -897,11 +982,13 @@ + static int tc_client_open(struct inode *inode, struct file *file) + { + int ret; +- struct tc_ns_dev_file *dev = NULL; ++ int ret1; ++ struct tc_ns_dev_file *dev = NULL; + (void)inode; + + ret = check_teecd_auth(); +- if (ret != 0) { ++ ret1 = check_proxy_auth(); ++ if (ret != 0 && ret1 != 0) { + tloge("teec auth failed, ret %d\n", ret); + return -EACCES; + } +@@ -911,7 +998,8 @@ + if (ret == 0) + file->private_data = dev; + #ifdef CONFIG_TEE_REBOOT +- get_teecd_pid(); ++ if (check_teecd_auth() == 0) ++ get_teecd_pid(); + #endif + return ret; + } +@@ -1442,3 +1530,6 @@ + #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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_client_driver.h 2023-10-07 14:38:55.608000000 +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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/core/tc_cvm_driver.c 2023-10-07 14:38:55.608000000 +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/Makefile ./itrustee_tzdriver_new/Makefile +--- ./itrustee_tzdriver/Makefile 2023-10-07 14:43:43.044000000 +0800 ++++ ./itrustee_tzdriver_new/Makefile 2023-10-07 14:39:52.228000000 +0800 +@@ -15,13 +15,13 @@ + + ifeq ($(CONFIG_TEE_TELEPORT_SUPPORT), y) + tzdriver-objs += core/tee_portal.o +-EXTRA_CFLAGS += -DCONFIG_TEE_TELEPORT_SUPPORT -DCONFIG_TEE_TELEPORT_AUTH ++EXTRA_CFLAGS += -DCONFIG_TEE_TELEPORT_SUPPORT -DCONFIG_TEE_TELEPORT_AUTH + EXTRA_CFLAGS += -DTEE_TELEPORT_PATH_UID_AUTH_CTX=\"/usr/bin/tee_teleport:0\" + tzdriver-objs += core/tc_cvm_driver.o + endif + + ifeq ($(CONFIG_CONFIDENTIAL_CONTAINER), y) +-EXTRA_CFLAGS += -DCONFIG_CONFIDENTIAL_CONTAINER -DCONFIG_TEE_AGENTD_AUTH ++EXTRA_CFLAGS += -DCONFIG_CONFIDENTIAL_CONTAINER -DCONFIG_TEE_AGENTD_AUTH + EXTRA_CFLAGS += -DTEE_AGENTD_PATH_UID_AUTH_CTX=\"/usr/bin/agentd:0\" + tzdriver-objs += core/tc_cvm_driver.o + endif +@@ -48,6 +48,7 @@ + EXTRA_CFLAGS += -DCONFIG_TEE_LOG_ACHIVE_PATH=\"/var/log/tee/last_teemsg\" + EXTRA_CFLAGS += -DNOT_TRIGGER_AP_RESET -DLAST_TEE_MSG_ROOT_GID -DCONFIG_NOCOPY_SHAREDMEM -DCONFIG_TA_AFFINITY=y -DCONFIG_TA_AFFINITY_CPU_NUMS=128 + EXTRA_CFLAGS += -DTEECD_PATH_UID_AUTH_CTX=\"/usr/bin/teecd:0\" ++EXTRA_CFLAGS += -DPROXY_PATH_UID_AUTH_CTX=\"/usr/bin/vtz_proxy:0\" + EXTRA_CFLAGS += -DCONFIG_AUTH_SUPPORT_UNAME -DCONFIG_AUTH_HASH -std=gnu99 + EXTRA_CFLAGS += -DCONFIG_TEE_UPGRADE -DCONFIG_TEE_REBOOT -DCONFIG_CONFIDENTIAL_TEE + EXTRA_CFLAGS += -I$(PWD)/tzdriver_internal/tee_reboot +diff -Naur '--exclude=.git' ./itrustee_tzdriver/tc_ns_client.h ./itrustee_tzdriver_new/tc_ns_client.h +--- ./itrustee_tzdriver/tc_ns_client.h 2023-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/tc_ns_client.h 2023-10-07 14:38:55.928000000 +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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/tc_ns_log.h 2023-10-07 14:38:55.996000000 +0800 +@@ -32,7 +32,7 @@ + }; + #define MOD_TEE "tzdriver" + +-#define TEE_LOG_MASK TZ_DEBUG_INFO ++#define TEE_LOG_MASK 2 + + #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-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/teek_ns_client.h 2023-10-07 14:38:55.928000000 +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 -Naur '--exclude=.git' ./itrustee_tzdriver/tlogger/tlogger.c ./itrustee_tzdriver_new/tlogger/tlogger.c +--- ./itrustee_tzdriver/tlogger/tlogger.c 2023-10-07 14:43:43.048000000 +0800 ++++ ./itrustee_tzdriver_new/tlogger/tlogger.c 2023-10-07 14:38:55.932000000 +0800 +@@ -61,6 +61,7 @@ + #define SET_TLOGCAT_STAT_BASE 7 + #define GET_TLOGCAT_STAT_BASE 8 + #define GET_TEE_INFO_BASE 9 ++#define SET_VM_FLAG 10 + + /* get tee verison */ + #define MAX_TEE_VERSION_LEN 256 +@@ -75,6 +76,8 @@ + _IO(LOGGERIOCTL, GET_TLOGCAT_STAT_BASE) + #define TEELOGGER_GET_TEE_INFO \ + _IOR(LOGGERIOCTL, GET_TEE_INFO_BASE, struct tc_ns_tee_info) ++#define TEELOGGER_SET_VM_FLAG \ ++ _IOR(LOGGERIOCTL, SET_VM_FLAG, int) + + int g_tlogcat_f = 0; + +@@ -233,6 +236,7 @@ + + static bool check_group_compat(struct tlogger_group *group, struct log_item *item) + { ++ tloge("item nsid = %u\n", item->nsid); + if (group->nsid == item->nsid) + return true; + +@@ -515,7 +519,7 @@ + } + #endif + +-static struct tlogger_group *get_tlogger_group(void) ++static struct tlogger_group *get_tlogger_group(uint32_t vmpid) + { + struct tlogger_group *group = NULL; + #ifdef CONFIG_CONFIDENTIAL_CONTAINER +@@ -524,6 +528,9 @@ + uint32_t nsid = PROC_PID_INIT_INO; + #endif + ++ if (vmpid) ++ nsid = vmpid; ++ + list_for_each_entry(group, &g_reader_group_list, node) { + if (group->nsid == nsid) + return group; +@@ -596,7 +603,7 @@ + return -ENODEV; + + mutex_lock(&g_reader_group_mutex); +- group = get_tlogger_group(); ++ group = get_tlogger_group(0); + if (group == NULL) { + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)group)) { +@@ -828,6 +835,38 @@ + return 0; + } + ++int set_tlog_vm_flag(struct file *file, uint32_t vmpid) ++{ ++ struct tlogger_reader *reader = NULL; ++ struct tlogger_group *group = NULL; ++ ++ if (file == NULL) { ++ return -1; ++ } ++ ++ reader = file->private_data; ++ if (reader == NULL) { ++ return -1; ++ } ++ ++ mutex_lock(&g_reader_group_mutex); ++ group = get_tlogger_group(vmpid); ++ if (group == NULL) { ++ group = kzalloc(sizeof(*group), GFP_KERNEL); ++ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)group)) { ++ mutex_unlock(&g_reader_group_mutex); ++ return -ENOMEM; ++ } ++ init_tlogger_group(group); ++ group->nsid = vmpid; ++ list_add_tail(&group->node, &g_reader_group_list); ++ } else { ++ group->reader_cnt++; ++ } ++ mutex_unlock(&g_reader_group_mutex); ++ reader->group = group; ++} ++ + static long process_tlogger_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) + { +@@ -865,6 +904,9 @@ + case TEELOGGER_GET_TEE_INFO: + ret = tc_ns_get_tee_info(file, (void *)(uintptr_t)arg); + break; ++ case TEELOGGER_SET_VM_FLAG: ++ ret = set_tlog_vm_flag(file, (int)arg); ++ break; + default: + tloge("ioctl error default\n"); + break; +@@ -1450,3 +1492,4 @@ + MODULE_DESCRIPTION("TrustCore Logger"); + MODULE_VERSION("3.00"); + #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..f70a3ab6827f3ca7ac0802e800ef93298c5d1792 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/Makefile @@ -0,0 +1,36 @@ +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 \ + ./serial_port.c \ + ./debug.c \ + ./agent.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/agent.c b/trustzone-awared-vm/Host/vtzb_proxy/agent.c new file mode 100644 index 0000000000000000000000000000000000000000..d349bfe02076d8b7e1dd056c47381935211f6011 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/agent.c @@ -0,0 +1,186 @@ +#include "agent.h" +#include "comm_structs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "serial_port.h" + +#include "tee_client_log.h" +#include "tee_sys_log.h" +#include "debug.h" +#include "thread_pool.h" +#include "vtzb_proxy.h" + +extern ThreadPool g_pool; + +void free_agent_buf(int ptzfd, struct vm_file *vm_fp) +{ + int ret; + struct ListNode* ptr = NULL; + struct ListNode* n = NULL; + struct_agent_args* agent_args = NULL; + unsigned long buf[2]; + pthread_mutex_lock(&vm_fp->agents_lock); + if (LIST_EMPTY(&vm_fp->agents_head)) + goto END; + + LIST_FOR_EACH_SAFE(ptr, n, &vm_fp->agents_head) { + struct_agent_args* tmp = + CONTAINER_OF(ptr, struct_agent_args, node); + if (tmp->dev_fd == ptzfd) { + ListRemoveEntry(&(tmp->node)); + agent_args = tmp; + if (agent_args) { + debug(" unregister \n"); + buf[0] = agent_args->args.id; + ret = ioctl(ptzfd, TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT, buf); + if (ret) { + tloge("ioctl failed\n"); + debug(" ioctl unregister failed\n"); + } else { + debug("unregister success\n"); + } + if (agent_args->thd!= 0) { + debug(" kill agent thread \n"); + thread_pool_submit(&g_pool, kill_Zombie, (void *)(agent_args->thd)); + } + pthread_spin_destroy(&agent_args->spinlock); + free(agent_args); + } else { + debug("not find!\n"); + } + } + } +END: + pthread_mutex_unlock(&vm_fp->agents_lock); +} + +void register_agent(struct_packet_cmd_regagent *packet_cmd, + struct serial_port_file *serial_port) +{ + 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) { + /* Add the agent buffer to the linked list. */ + struct_agent_args* tmp = (struct_agent_args*)malloc(sizeof(struct_agent_args)); + if (!tmp) { + tloge("Failed to allocate memory for agent buffer\n"); + ret = -ENOMEM; + goto END; + } + pthread_spin_init(&tmp->spinlock, PTHREAD_PROCESS_PRIVATE); + ListInit(&tmp->node); + tmp->dev_fd = packet_cmd->ptzfd; + tmp->args = packet_cmd->args; + tmp->vmaddr = packet_cmd->vmaddr; + pthread_mutex_lock(&serial_port->vm_file->agents_lock); + ListInsertTail(&serial_port->vm_file->agents_head, &tmp->node); + pthread_mutex_unlock(&serial_port->vm_file->agents_lock); + } +END: + packet_rsp.packet_size = sizeof(packet_rsp); + packet_rsp.ret = ret; + packet_rsp.args = packet_cmd->args; + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +void wait_event(struct_packet_cmd_event *packet_cmd, + struct serial_port_file *serial_port) +{ + 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; + struct_agent_args* agent_args; + buf[0] = packet_cmd->agent_id; + + pthread_mutex_lock(&serial_port->vm_file->agents_lock); + if (!LIST_EMPTY(&serial_port->vm_file->agents_head)) { + LIST_FOR_EACH(ptr, &serial_port->vm_file->agents_head) { + 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(&serial_port->vm_file->agents_lock); + if (bfind) { + agent_args->thd = pthread_self(); + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_WAIT_EVENT, buf); + agent_args->thd = 0; + } + debug(" after wait, ret = %d\n", ret); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + packet_rsp.packet_size = sizeof(packet_rsp); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.ret = ret; + + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +void sent_event_response(struct_packet_cmd_event *packet_cmd, + struct serial_port_file *serial_port) +{ + 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(&serial_port->vm_file->agents_lock); + if (!LIST_EMPTY(&serial_port->vm_file->agents_head)) { + LIST_FOR_EACH(ptr, &serial_port->vm_file->agents_head) { + 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(&serial_port->vm_file->agents_lock); + + 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.packet_size = sizeof(packet_rsp); + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.ret = ret; + + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} \ No newline at end of file diff --git a/trustzone-awared-vm/Host/vtzb_proxy/agent.h b/trustzone-awared-vm/Host/vtzb_proxy/agent.h new file mode 100644 index 0000000000000000000000000000000000000000..f7ee9b676c51a75155c5eab1961df5bce1a11a37 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/agent.h @@ -0,0 +1,24 @@ +#ifndef __AGENT_H__ +#define __AGENT_H__ + +#include "tc_ns_client.h" +#include "tee_client_list.h" +#include "comm_structs.h" +#include "serial_port.h" +#include "vm.h" + +typedef struct { + struct AgentIoctlArgs args; + int32_t dev_fd; + void *vmaddr; + struct ListNode node; + pthread_spinlock_t spinlock; + pthread_t thd; +} struct_agent_args; + +void free_agent_buf(int ptzfd, struct vm_file *vm_fp); +void register_agent(struct_packet_cmd_regagent *packet_cmd, struct serial_port_file *serial_port); +void wait_event(struct_packet_cmd_event *packet_cmd, struct serial_port_file *serial_port); +void sent_event_response(struct_packet_cmd_event *packet_cmd, struct serial_port_file *serial_port); + +#endif \ No newline at end of file diff --git a/trustzone-awared-vm/Host/vtzb_proxy/comm_structs.h b/trustzone-awared-vm/Host/vtzb_proxy/comm_structs.h new file mode 100644 index 0000000000000000000000000000000000000000..5d9d107a10589f3968fd5cb0442ebe27013d2339 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/comm_structs.h @@ -0,0 +1,267 @@ +#ifndef COMM_STRUCTS_H +#define COMM_STRUCTS_H + +#include +#include "tc_ns_client.h" + +#define CERT_BUF_MAX_SIZE 2048 + +#define TC_NS_CLIENT_DEV_FLAG 3 +#define TC_PRIVATE_DEV_FLAG 4 +#define TC_CVM_DEV_FLAG 5 +#define TLOG_DEV_FLAG 6 + +#define VTZ_OPEN_TZD 15 +#define VTZ_CLOSE_TZD 17 +#define VTZ_LOG_IN_NHIDL 19 +#define VTZ_GET_TEE_VERSION 21 +#define VTZ_GET_TEE_INFO 23 +#define VTZ_LATE_INIT 25 +#define VTZ_SYNC_TIME 27 +#define VTZ_LOG_IN 29 +#define VTZ_OPEN_SESSION 31 +#define VTZ_SEND_CMD 33 +#define VTZ_CANCEL_CMD 35 +#define VTZ_MMAP 37 +#define VTZ_MUNMAP 39 +#define VTZ_CLOSE_SESSION 41 +#define VTZ_CLOSE_PTZDEV 43 +#define VTZ_FS_REGISTER_AGENT 45 +#define VTZ_WAIT_EVENT 49 +#define VTZ_SEND_EVENT_RESPONSE 51 +#define VTZ_LOAD_SEC 53 +#define VTZ_TEST 47 + +#define VTZ_GET_TEEOS_VER 55 +#define VTZ_SET_READER_CUR 57 +#define VTZ_SET_TLOGCAT_STAT 59 +#define VTZ_GET_TLOGCAT_STAT 61 +#define VTZ_GET_LOG 63 + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_general; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; +} struct_packet_cmd_test; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_test; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + uint32_t vmid; + uint32_t flag; +} struct_packet_cmd_open_tzd; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + int32_t ptzfd; +} struct_packet_rsp_open_tzd; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_close_tzd; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_close_tzd; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_getteever; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + uint32_t tee_ver; +} struct_packet_rsp_getteever; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + bool istlog; +} struct_packet_cmd_getteeinfo; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + TC_NS_TEE_Info info; +} struct_packet_rsp_getteeinfo; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + void *vmaddr; + struct AgentIoctlArgs args; +} struct_packet_cmd_regagent; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + 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 { + uint32_t cmd; + uint32_t seq_num; + uint32_t index; +} struct_packet_cmd_lateinit; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_lateinit; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + TC_NS_Time tcNsTime; +} struct_packet_cmd_synctime; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_synctime; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + uint8_t cert_buffer[CERT_BUF_MAX_SIZE]; +} struct_packet_cmd_login; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_login_non; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_login; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + __s32 cpu_index; + struct SecLoadIoctlStruct ioctlArg; +} struct_packet_cmd_load_sec; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + struct SecLoadIoctlStruct ioctlArg; +} struct_packet_rsp_load_sec; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; + __s32 cpu_index; + TC_NS_ClientContext cliContext; +} struct_packet_cmd_session; + +typedef struct { + uint32_t packet_size; + 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; + __s32 cpu_index; + unsigned long long addrs[4]; + TC_NS_ClientContext cliContext; +} struct_packet_cmd_send_cmd; + +typedef struct { + uint32_t packet_size; + 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; + __s32 cpu_index; + TC_NS_ClientContext cliContext; + pid_t pid; +} struct_packet_cmd_cancel_cmd; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + TC_NS_ClientContext cliContext; +} struct_packet_rsp_cancel_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 packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_mmap; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_vtzf_packet_cmd_closeptz; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_vtzf_packet_rsp_closeptz; + +#endif + diff --git a/trustzone-awared-vm/Host/vtzb_proxy/debug.c b/trustzone-awared-vm/Host/vtzb_proxy/debug.c new file mode 100644 index 0000000000000000000000000000000000000000..3d8acf81f2ee6adee7d6e45e66bf512ade68faf3 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/debug.c @@ -0,0 +1,43 @@ +#include "debug.h" +#include +#include +//#include +//#include +#include +//#include +#include + +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; +} +#endif \ No newline at end of file diff --git a/trustzone-awared-vm/Host/vtzb_proxy/debug.h b/trustzone-awared-vm/Host/vtzb_proxy/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..a26068f0353a0eb490d8189d94db806eba26eb15 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/debug.h @@ -0,0 +1,23 @@ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include +#include + +//#define DEBUG 1 + +double __get_us(struct timeval t); +#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 + +#endif \ No newline at end of file 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/serial_port.c b/trustzone-awared-vm/Host/vtzb_proxy/serial_port.c new file mode 100644 index 0000000000000000000000000000000000000000..d4388b30a0ce742bf6b8e4b4ca3520a26e209b65 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/serial_port.c @@ -0,0 +1,173 @@ +#include "serial_port.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "tc_ns_client.h" +#include "tee_client_list.h" +#include "tee_client_log.h" +#include "tee_sys_log.h" +#include "comm_structs.h" +#include "debug.h" + +struct serial_port_list g_serial_list; +struct pollfd g_pollfd[SERIAL_PORT_NUM]; +int g_pollfd_len = 0; + +int serial_port_list_init() +{ + int i; + struct serial_port_file *serial_port; + 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)); + if (!serial_port) { + tloge("Failed to allocate memory for serial_port\n"); + goto ERR; + } + 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->offset = 0; + serial_port->rd_buf = (char *)malloc(BUF_LEN_MAX_RD); + serial_port->vm_file = NULL; + if (!serial_port->rd_buf) { + tloge("Failed to allocate memory for rd_buf\n"); + free(serial_port); + goto ERR; + } + pthread_mutex_init(&serial_port->lock, NULL); + ListInsertTail(&g_serial_list.head, &serial_port->head); + } + + return 0; +ERR: + serial_port_list_destroy(); + return -ENOMEM; +} + +void serial_port_list_destroy() +{ + debug("free serialports\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); + (void)pthread_mutex_destroy(&serial_port->lock); + free(serial_port); + } + (void)pthread_mutex_unlock(&g_serial_list.lock); + (void)pthread_mutex_destroy(&g_serial_list.lock); +} + +int send_to_vm(struct serial_port_file *serial_port, void *packet_rsp, size_t size_rsp) +{ + int ret = 0; + pthread_mutex_lock(&serial_port->lock); + ret = write(serial_port->sock, packet_rsp, size_rsp); + pthread_mutex_unlock(&serial_port->lock); + return ret; +} + +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 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; + if (memcpy_s(&sock_addr.sun_path, sizeof(sock_addr.sun_path), dev_path, + sizeof(sock_addr.sun_path))) { + tloge("memcpy_s err\n"); + debug("memcpy_s err\n"); + } + ret = connect(*sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); + if (ret < 0) { + tloge("connect domain socket %s failed \n", dev_path); + } + + return ret; +} + +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; + serial_port->vm_file = NULL; + } + } + } + (void)pthread_mutex_unlock(&g_serial_list.lock); +} \ No newline at end of file diff --git a/trustzone-awared-vm/Host/vtzb_proxy/serial_port.h b/trustzone-awared-vm/Host/vtzb_proxy/serial_port.h new file mode 100644 index 0000000000000000000000000000000000000000..a4982cc4f600ad61218e77523aa2774115a3622d --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/serial_port.h @@ -0,0 +1,40 @@ +#ifndef __SERIAL_PORT_H__ +#define __SERIAL_PORT_H__ +#include +#include +#include +#include +#include "tee_client_list.h" +#include "vm.h" + +#define VTZB_CHAR_DEV "/tmp/vm_vtzb_sock" + +#define SERIAL_PORT_NUM 11 +#define BUF_LEN_MAX_RD 1000 *4 +#define UNIX_PATH_MAX 108 + +struct serial_port_list { + pthread_mutex_t lock; + struct ListNode head; +}; + +struct serial_port_file { + pthread_mutex_t lock; + char path[UNIX_PATH_MAX]; + int sock; + bool opened; + int index; + struct ListNode head; + char *rd_buf; + int buf_size; + off_t offset; + struct vm_file *vm_file; +}; + +int serial_port_list_init(); +void serial_port_list_destroy(); +int send_to_vm(struct serial_port_file *serial_port, void *packet_rsp, size_t size_rsp); +void *get_rd_buf(int serial_port_fd); +void *get_serial_port_file(int serial_port_fd); +void check_stat_serial_port(); +#endif \ No newline at end of file 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..09da0a45c202d818708df884a916ed98ce917ccb --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/thread_pool.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include "thread_pool.h" + +/* Custom signal handler for killing zombie threads. */ +void signal_handler(int signum) { + printf("Received user-defined signal (%d)\n", signum); + + pthread_exit(NULL); +} + +/* Initialize the thread pool. */ +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); + } +} + +/* Recreate a new thread to fill the gap in the thread pool after killing a zombie thread. */ +void replenish_thread_pool(ThreadPool* pool, pthread_t thd) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + pthread_create(&pool->threads[i], NULL, thread_func, pool); + printf("creat new thread\n"); + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +/* Thread function */ +void *thread_func(void* arg) +{ + ThreadPool* pool = (ThreadPool*)arg; + if (signal(SIGUSR1, signal_handler) == SIG_ERR) { + printf("Error registering signal handler"); + return NULL; + } + + while (1) { + pthread_mutex_lock(&pool->mutex); + + /* Wait for the task queue to become non-empty. */ + while (pool->task_count == 0 && !pool->destroying) { + pthread_cond_wait(&pool->cond, &pool->mutex); + } + + /* If the thread pool is being destroyed, exit the thread. */ + if (pool->destroying) { + pthread_mutex_unlock(&pool->mutex); + break; + } + + /* Retrieve the task and execute it. */ + 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; +} + +/* Submit the task to the thread pool. */ +void thread_pool_submit(ThreadPool* pool, void* (*task_func)(void*), void* arg) +{ + pthread_mutex_lock(&pool->mutex); + + /* Wait for the task queue to become non-full. */ + while (pool->task_count == TASK_QUEUE_SIZE && !pool->destroying) { + pthread_cond_wait(&pool->cond, &pool->mutex); + } + + /* If the thread pool is being destroyed, no longer accept new tasks. */ + if (pool->destroying) { + pthread_mutex_unlock(&pool->mutex); + return; + } + + /* Add the task to the queue. */ + 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++; + /* Notify waiting threads of a new task. */ + pthread_cond_signal(&pool->cond); + + pthread_mutex_unlock(&pool->mutex); +} + +/* Destroy the thread pool. */ +void thread_pool_destroy(ThreadPool* pool) +{ + /* Stop accepting new tasks. */ + 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); +} + +bool check_if_thd_exist(pthread_t thd) +{ + int kill_rc = pthread_kill(thd, 0); + if(kill_rc != 0) + return false; + return true; +} + +void set_kill_flag(ThreadPool* pool, pthread_t thd) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + pool->kill_flag[i] = true; + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +void set_thread_session_id(ThreadPool* pool, pthread_t thd, unsigned int id) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + pool->session_ids[i] = id; + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +void set_thread_kill_session_id(ThreadPool* pool, pthread_t thd, unsigned int id) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + pool->kill_session_ids[i] = id; + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +unsigned int get_thread_session_id(ThreadPool* pool, pthread_t thd) +{ + unsigned int id = 0; + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + id = pool->session_ids[i]; + break; + } + } + pthread_mutex_unlock(&pool->mutex); + return id; +} + +void set_thread_seq_num(ThreadPool* pool, pthread_t thd, unsigned int seq_num) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + pool->seqs[i] = seq_num; + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +void remove_thread_seq_num(ThreadPool* pool, pthread_t thd, unsigned int seq_num) +{ + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + if (pool->seqs[i] == seq_num) + pool->seqs[i] = 0; + break; + } + } + pthread_mutex_unlock(&pool->mutex); +} + +unsigned int get_thread_seq_num(ThreadPool* pool, pthread_t thd) +{ + unsigned int id = 0; + pthread_mutex_lock(&pool->mutex); + for (int i = 0; i < THREAD_POOL_SIZE; i++) { + if (pthread_equal(pool->threads[i], thd)) { + id = pool->seqs[i]; + break; + } + } + pthread_mutex_unlock(&pool->mutex); + return id; +} + 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..781f4299e27f6d93b519253d5d58f2cca4b78d97 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/thread_pool.h @@ -0,0 +1,49 @@ +#ifndef __THREAD_POLL_H__ +#define __THREAD_POLL_H__ + +#include +#include +#include +#include +#include +#include + +#define THREAD_POOL_SIZE 128 +#define TASK_QUEUE_SIZE 128 + +/* task structure */ +typedef struct { + void* (*task_func)(void*); // Task function pointer + void* arg; // Task argument +} Task; + +/* the thread pool structure */ +typedef struct { + pthread_t threads[THREAD_POOL_SIZE]; // Thread array + unsigned int session_ids[THREAD_POOL_SIZE]; // Session ID of the ongoing command + unsigned int kill_session_ids[THREAD_POOL_SIZE]; + bool kill_flag[THREAD_POOL_SIZE]; + unsigned int seqs[THREAD_POOL_SIZE]; + Task task_queue[TASK_QUEUE_SIZE]; // Task queue + int task_count; // Number of tasks in the task queue + int front; // Queue head index + int rear; // Queue tail index + int destroying; // Destruction flag + pthread_mutex_t mutex; // Mutex + pthread_cond_t cond; // Condition variable +} 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); +void replenish_thread_pool(ThreadPool* pool, pthread_t thd); +void set_kill_flag(ThreadPool* pool, pthread_t thd); +void set_thread_session_id(ThreadPool* pool, pthread_t thd, unsigned int id); +unsigned int get_thread_session_id(ThreadPool* pool, pthread_t thd); +void set_thread_seq_num(ThreadPool* pool, pthread_t thd, unsigned int seq_num); +void remove_thread_seq_num(ThreadPool* pool, pthread_t thd, unsigned int seq_num); +unsigned int get_thread_seq_num(ThreadPool* pool, pthread_t thd); +#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/vm.h b/trustzone-awared-vm/Host/vtzb_proxy/vm.h new file mode 100644 index 0000000000000000000000000000000000000000..e4310b7ecda58951b7e94e05ba43d586fd02ffd8 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/vm.h @@ -0,0 +1,18 @@ +#ifndef __VM_H__ +#define __VM_H__ +#include +#include +#include "tc_ns_client.h" +#include "tee_sys_log.h" +#include "tee_client_list.h" + +struct vm_file { + uint32_t vmpid; + struct ListNode head; + pthread_mutex_t fd_lock; + struct ListNode fds_head; + pthread_mutex_t agents_lock; + struct ListNode agents_head; +}; + +#endif \ No newline at end of file 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..54ac4f6f904f0b5525c9a9626ab4eafd9896d9f5 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/vtzb_proxy.c @@ -0,0 +1,1227 @@ +/* + */ + +#include "vtzb_proxy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "tc_ns_client.h" +#include "tee_client_list.h" +#include "comm_structs.h" +#include "virt.h" +#include "thread_pool.h" +#include "debug.h" +#include "agent.h" +#include "serial_port.h" + +//#define DEBUG 1 +ThreadPool g_pool; +LIST_DECLARE(g_shrd_mem_list); + +LIST_DECLARE(g_vm_list); +pthread_mutex_t g_mutex_shrd_mem = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_mutex_vm = PTHREAD_MUTEX_INITIALIZER; + +static char g_log_teeVersion[MAX_TEE_VERSION_LEN]; +pthread_mutex_t g_mutex_log_ver = PTHREAD_MUTEX_INITIALIZER; +int g_count = 0; + + +extern int g_pollfd_len; +extern struct pollfd g_pollfd[SERIAL_PORT_NUM]; +static void *g_log_buffer = NULL; + +static struct vm_file *get_vm_file(uint32_t vmid) +{ + bool isfind = false; + struct ListNode *ptr = NULL; + struct vm_file *tmp = NULL; + pthread_mutex_lock(&g_mutex_vm); + if (!LIST_EMPTY(&g_vm_list)) { + LIST_FOR_EACH(ptr, &g_vm_list) { + tmp = CONTAINER_OF(ptr, struct vm_file, head); + if (tmp->vmpid == vmid) { + isfind = true; + break; + } + } + } + + if (!isfind) { + tmp = (struct vm_file *)malloc(sizeof(struct vm_file)); + if (!tmp) { + tloge("Failed to allocate memory for vm_file\n"); + goto END; + } + pthread_mutex_init(&tmp->fd_lock, NULL); + pthread_mutex_init(&tmp->agents_lock, NULL); + ListInit(&tmp->head); + ListInit(&tmp->fds_head); + ListInit(&tmp->agents_head); + tmp->vmpid = vmid; + ListInsertTail(&g_vm_list, &tmp->head); + } +END: + pthread_mutex_unlock(&g_mutex_vm); + return tmp; +} + +static void add_fd_list(int fd, struct vm_file *vm_fp) +{ + struct fd_file *tmp = (struct fd_file *)malloc(sizeof(struct fd_file)); + if (!tmp) + return ; + tmp->ptzfd = fd; + pthread_mutex_init(&tmp->session_lock, NULL); + ListInit(&tmp->session_head); + ListInit(&tmp->head); + + pthread_mutex_lock(&vm_fp->fd_lock); + ListInsertTail(&vm_fp->fds_head, &tmp->head); + pthread_mutex_unlock(&vm_fp->fd_lock); +} + +static struct fd_file *find_fd_file(int ptzfd, struct vm_file *vm_fp) +{ + struct ListNode *ptr = NULL; + struct fd_file *fd_p = NULL; + struct fd_file *result = NULL; + if (!vm_fp) + return NULL; + pthread_mutex_lock(&vm_fp->fd_lock); + if (!LIST_EMPTY(&vm_fp->fds_head)) { + LIST_FOR_EACH(ptr, &vm_fp->fds_head) { + fd_p = CONTAINER_OF(ptr, struct fd_file, head); + if (fd_p->ptzfd == ptzfd) { + result = fd_p; + break; + } + } + } + pthread_mutex_unlock(&vm_fp->fd_lock); + return result; +} + +void *kill_Zombie(void *args) +{ + pthread_t tid = (pthread_t)args; + debug("before handle kill|cncel thread \n"); + pthread_detach(tid); + int result = pthread_kill(tid, SIGUSR1); + debug("result = %d \n", result); + if (result == 0) { + pthread_join(tid, NULL); + replenish_thread_pool(&g_pool, tid); + } else { + debug("pthread_kill fail \n"); + } + debug("after handle kill|cncel thread \n"); + return NULL; +} + +static void close_remove_session(struct fd_file *fd_p) +{ + struct ListNode *ptr = NULL; + struct ListNode *n = NULL; + unsigned int session_id; + if (!fd_p) + return ; + debug(" will close_remove_session\n "); + pthread_mutex_lock(&fd_p->session_lock); + if (!LIST_EMPTY(&fd_p->session_head)) { + LIST_FOR_EACH_SAFE(ptr, n, &fd_p->session_head) { + struct session *sp = CONTAINER_OF(ptr, struct session, head); + ListRemoveEntry(&(sp->head)); + + if (sp->thread_id != 0) { + session_id = get_thread_session_id(&g_pool, sp->thread_id); + debug("close_remove_session session_id = %u , th_session_id = %u \n", sp->session_id, session_id); + if (session_id == sp->session_id) + thread_pool_submit(&g_pool, kill_Zombie, (void *)(sp->thread_id)); + } + free(sp); + } + } + pthread_mutex_unlock(&fd_p->session_lock); + +} + +static void remove_fd_list(int ptzfd, struct vm_file *vm_fp) +{ + struct fd_file *fd_p = find_fd_file(ptzfd, vm_fp); + if (fd_p) { + close_remove_session(fd_p); + } +} + +static void open_tzdriver(struct_packet_cmd_open_tzd *packet_cmd, + struct serial_port_file *serial_port) +{ + debug("*****cmd is open_tzdriver*****\n"); + int fd = -1; + int ret; + struct_packet_rsp_open_tzd packet_rsp; + struct vm_file* vm_fp = NULL; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + debug("packet_cmd->flag =%d \n",packet_cmd->flag); + if (packet_cmd->flag == TLOG_DEV_FLAG) { + fd = open(TC_LOGGER_DEV_NAME, O_RDONLY); + ret = ioctl(fd, TEELOGGER_SET_VM_FLAG, packet_cmd->vmid); + } else { + switch (packet_cmd->flag) + { + case TC_NS_CLIENT_DEV_FLAG: + fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR); + break; + case TC_PRIVATE_DEV_FLAG: + fd = open(TC_TEECD_PRIVATE_DEV_NAME, O_RDWR); + break; + case TC_CVM_DEV_FLAG: + fd = open(TC_NS_CVM_DEV_NAME, O_RDWR); + break; + default: + break; + } + if (fd != -1) + ret = ioctl(fd, TC_NS_CLIENT_IOCTL_SET_VM_FLAG, packet_cmd->vmid); + } + + 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); + +END: + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + if (fd > 0) + (void)close(fd); + } + if (fd > 0 && ret == sizeof(packet_rsp)) { + if (!serial_port->vm_file) { + vm_fp = get_vm_file(packet_cmd->vmid); + serial_port->vm_file = vm_fp; + } else { + vm_fp = serial_port->vm_file; + } + add_fd_list(fd, vm_fp); + } +} + + +static void close_tzdriver(struct_packet_cmd_close_tzd *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = -1; + debug("*****cmd is close TZdriver***** \n"); + struct_packet_rsp_close_tzd packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + packet_rsp.ret = 0; + (void)ret; + + if (packet_cmd->ptzfd > 2){ + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + + free_agent_buf(packet_cmd->ptzfd, serial_port->vm_file); + debug(" after free_agent_buf\n"); + + ret = close(packet_cmd->ptzfd); + debug("close ret = %d \n", ret); + + remove_fd_list(packet_cmd->ptzfd, serial_port->vm_file); + } + + if (send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)) != sizeof(packet_rsp)) { + tloge("close ptzfd send to VM failed \n"); + } +} + +static void log_in_NonHidl(struct_packet_cmd_login_non *packet_cmd, + struct serial_port_file *serial_port) +{ + debug("*****cmd is log_in_nonhidl \n"); + int ret; + struct_packet_rsp_login packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOGIN, NULL); + packet_rsp.ret = ret; + + ret = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + int ret; + struct_packet_rsp_login packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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 = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + + int ret; + struct_packet_rsp_getteever packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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 = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + int ret; + struct_packet_rsp_getteeinfo packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + if (packet_cmd->istlog) { + ret = ioctl(packet_cmd->ptzfd, TEELOGGER_GET_TEE_INFO, &packet_rsp.info); + } else{ + 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 = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + int ret; + struct_packet_rsp_synctime packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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 = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void add_session_list(int ptzfd, TC_NS_ClientContext *clicontext) +{ + bool isfind = false; + struct ListNode *ptr = NULL; + struct ListNode *ptr1 = NULL; + struct vm_file *tmp = NULL; + struct fd_file *fd_p = NULL; + + struct session *sessionp = (struct session *)malloc(sizeof(struct session)); + if (!sessionp) + return ; + sessionp->session_id = clicontext->session_id; + sessionp->cliContext = *clicontext; + debug("uuid = %x \n", sessionp->cliContext.uuid); + ListInit(&sessionp->head); + + pthread_mutex_lock(&g_mutex_vm); + if (!LIST_EMPTY(&g_vm_list)) { + LIST_FOR_EACH(ptr, &g_vm_list) { + tmp = CONTAINER_OF(ptr, struct vm_file, head); + pthread_mutex_lock(&tmp->fd_lock); + if (!LIST_EMPTY(&tmp->fds_head)) { + LIST_FOR_EACH(ptr1, &tmp->fds_head) { + fd_p = CONTAINER_OF(ptr1, struct fd_file, head); + if (fd_p->ptzfd == ptzfd) { + isfind = true; + debug("add session \n"); + ListInsertTail(&fd_p->session_head, &sessionp->head); + break; + } + } + } + pthread_mutex_unlock(&tmp->fd_lock); + if (isfind) + break; + } + } + pthread_mutex_unlock(&g_mutex_vm); +} + +static void doremove_session(unsigned int session_id, struct fd_file *fd_p) +{ + struct ListNode *ptr = NULL; + struct ListNode *n = NULL; + if (!fd_p) + return ; + pthread_mutex_lock(&fd_p->session_lock); + if (!LIST_EMPTY(&fd_p->session_head)) { + LIST_FOR_EACH_SAFE(ptr, n, &fd_p->session_head) { + struct session *sp = CONTAINER_OF(ptr, struct session, head); + if (sp->session_id == session_id) { + debug("remove session \n"); + ListRemoveEntry(&(sp->head)); + free(sp); + } + } + } + pthread_mutex_unlock(&fd_p->session_lock); +} + +static void remove_session_list(int ptzfd, int session_id, struct vm_file *vm_fp) +{ + struct fd_file *fd_p = find_fd_file(ptzfd, vm_fp); + if (fd_p) { + doremove_session(session_id, fd_p); + } +} + +static void open_session(struct_packet_cmd_session *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret; + struct_packet_rsp_session packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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); + + if (ret == 0) + add_session_list(packet_cmd->ptzfd, &packet_rsp.cliContext); + + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + return ; + } +} + +static void close_session(struct_packet_cmd_session *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret; + struct_packet_rsp_general packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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); + debug(" uuid = %x \n",packet_cmd->cliContext.uuid); + + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } + remove_session_list(packet_cmd->ptzfd, packet_cmd->cliContext.session_id, serial_port->vm_file); +} + +static int process_address(struct_packet_cmd_send_cmd *packet_cmd, ClientParam params[]) +{ + 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; + + params[index].memref.buf_size = packet_cmd->cliContext.params[index].memref.size_addr; + packet_cmd->cliContext.params[index].memref.size_addr = + (unsigned int)((uintptr_t)¶ms[index].memref.buf_size); + packet_cmd->cliContext.params[index].memref.size_h_addr = + (unsigned int)((uint64_t)¶ms[index].memref.buf_size >> H_OFFSET); + + 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; + /* Switch to the user address corresponding to the mmap space on the 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 %p \n", vm_buffer); + debug("can't find mmap buffer %p \n", vm_buffer); + ret = -1; + return ret; + } + } else if (IS_TEMP_MEM(paramTypes[index]) || IS_SHARED_MEM(paramTypes[index])) { + params[index].memref.buf_size = packet_cmd->cliContext.params[index].memref.size_addr; + packet_cmd->cliContext.params[index].memref.size_addr = + (unsigned int)((uintptr_t)¶ms[index].memref.buf_size); + packet_cmd->cliContext.params[index].memref.size_h_addr = + (unsigned int)((uint64_t)¶ms[index].memref.buf_size >> H_OFFSET); + } else if (IS_VALUE_MEM(paramTypes[index])) { + params[index].value.val_a = packet_cmd->cliContext.params[index].value.a_addr; + params[index].value.val_b = packet_cmd->cliContext.params[index].value.b_addr; + + packet_cmd->cliContext.params[index].value.a_addr = + (unsigned int)(uintptr_t)¶ms[index].value.val_a; + packet_cmd->cliContext.params[index].value.a_h_addr = + (unsigned int)((uint64_t)¶ms[index].value.val_a >> H_OFFSET); + packet_cmd->cliContext.params[index].value.b_addr = + (unsigned int)(uintptr_t)¶ms[index].value.val_b; + packet_cmd->cliContext.params[index].value.b_h_addr = + (unsigned int)((uint64_t)¶ms[index].value.val_b >> H_OFFSET); + } + }// end for + if (icount ==0) { + packet_cmd->cliContext.file_buffer = NULL; + } + return ret; +} + +static void process_address_end(struct_packet_cmd_send_cmd *packet_cmd, ClientParam params[]) +{ + int index; + uint32_t paramTypes[TEEC_PARAM_NUM]; + + 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])) { + packet_cmd->cliContext.params[index].memref.size_addr = params[index].memref.buf_size; + } else if (IS_TEMP_MEM(paramTypes[index])) { + packet_cmd->cliContext.params[index].memref.size_addr = params[index].memref.buf_size; + } else if (IS_VALUE_MEM(paramTypes[index])) { + packet_cmd->cliContext.params[index].value.a_addr = params[index].value.val_a; + packet_cmd->cliContext.params[index].value.b_addr = params[index].value.val_b; + } + } +} + +static void do_set_thread_id(struct fd_file *fd_p, unsigned int session_id, int flag) +{ + struct ListNode *ptr = NULL; + if (!fd_p) + return ; + pthread_t current_thread; + current_thread = flag > 0 ? pthread_self() : 0; + pthread_mutex_lock(&fd_p->session_lock); + if (!LIST_EMPTY(&fd_p->session_head)) { + LIST_FOR_EACH(ptr, &fd_p->session_head) { + struct session *sp = CONTAINER_OF(ptr, struct session, head); + if (sp->session_id == session_id) { + sp->thread_id = current_thread; + debug("set thread_id = %u \n", current_thread); + break; + } + } + } + pthread_mutex_unlock(&fd_p->session_lock); + if (flag) + set_thread_session_id(&g_pool, pthread_self(), session_id); + else + set_thread_session_id(&g_pool, pthread_self(), 0); +} + +static void set_thread_id(int ptzfd, unsigned int session_id, int flag, struct vm_file *vm_fp) +{ + struct fd_file *fd_p = find_fd_file(ptzfd, vm_fp); + if (fd_p) { + do_set_thread_id(fd_p, session_id, flag); + } +} + +static void send_cmd(struct_packet_cmd_send_cmd *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = -1; + struct timeval start, end; + uint32_t cost = 0; + struct_packet_rsp_send_cmd packet_rsp; + ClientParam params[TEEC_PARAM_NUM]; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + void *vm_hvas = (void *)malloc(sizeof(void *)*TEEC_PARAM_NUM); + if (!vm_hvas) { + tloge("Failed to allocate memory for serial_port\n"); + ret = -ENOMEM; + goto END; + } + 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, params)) { + debug(" process addrs success \n"); + set_thread_id(packet_cmd->ptzfd, packet_cmd->cliContext.session_id, 1, serial_port->vm_file); + ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_CMD_REQ, &packet_cmd->cliContext); + set_thread_id(packet_cmd->ptzfd, packet_cmd->cliContext.session_id, 0, serial_port->vm_file); + debug(" send cmd ret = %d \n", ret); + process_address_end(packet_cmd, params); + } + 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); +END: + packet_rsp.packet_size = sizeof(packet_rsp); + packet_rsp.ret = ret; + packet_rsp.cliContext = packet_cmd->cliContext; + ret = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + 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.packet_size = sizeof(packet_rsp); + packet_rsp.ret = ret; + packet_rsp.ioctlArg = packet_cmd->ioctlArg; + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + debug(" ret = %d \n", ret); + + ret = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + int ret = 0; + struct_packet_rsp_mmap packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + 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)); + if (buffer == MAP_FAILED) { + tloge("mmap failed\n"); + debug("mmap failed \n"); + ret = -ENOMEM; + } + + debug(" mmap ret = %d \n", ret); + packet_rsp.ret = ret; + + 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); + + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + pthread_mutex_lock(&g_mutex_shrd_mem); + ListRemoveEntry(&(tmp->node)); + pthread_mutex_unlock(&g_mutex_shrd_mem); + (void)munmap(tmp->buffer, tmp->buffer_size); + free(tmp); + } +} + +static void vtz_dounmmap(struct_packet_cmd_mmap *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = 0; + struct_packet_rsp_mmap packet_rsp; + void* buffer = NULL; + uint32_t buffer_size; + struct ListNode* ptr = NULL; + struct ListNode* n = NULL; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + packet_rsp.ret = ret; + ret = send_to_vm(serial_port, &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, + struct serial_port_file *serial_port) +{ + debug("*****cmd is mmap*****\n"); + debug(" ptzfd = %d \n", packet_cmd->ptzfd); + if (packet_cmd->cmd == VTZ_MMAP) { + vtz_dommap(packet_cmd, serial_port); + } else { + vtz_dounmmap(packet_cmd, serial_port); + } + +} + +static void tlog_get_teever(struct_packet_cmd_get_ver *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = 0; + struct_packet_rsp_get_ver packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + /* */ + ret = ioctl(packet_cmd->ptzfd, TEELOGGER_GET_VERSION, g_log_teeVersion); + packet_rsp.ret = ret; + if (memcpy_s(packet_rsp.version_info, MAX_TEE_VERSION_LEN, + g_log_teeVersion, MAX_TEE_VERSION_LEN)) { + tloge("memcpy_s err \n"); + debug("memcpy_s err\n"); + } + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void tlog_set_reader_cur( + struct_packet_cmd_set_reader_cur *packet_cmd, + struct serial_port_file *serial_port) +{ + + int ret = 0; + struct_packet_rsp_set_reader_cur packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + ret = ioctl(packet_cmd->ptzfd, TEELOGGER_SET_READERPOS_CUR, 0); + packet_rsp.ret = ret; + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void tlog_set_stat(struct_packet_cmd_set_tlogcat_stat *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = 0; + struct_packet_rsp_set_tlogcat_stat packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + ret = ioctl(packet_cmd->ptzfd, TEELOGGER_SET_TLOGCAT_STAT, 0); + packet_rsp.ret = ret; + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void tlog_get_stat(struct_packet_cmd_get_tlogcat_stat *packet_cmd, + struct serial_port_file *serial_port) +{ + int ret = 0; + struct_packet_rsp_get_tlogcat_stat packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + ret = ioctl(packet_cmd->ptzfd, TEELOGGER_GET_TLOGCAT_STAT, 0); + packet_rsp.ret = ret; + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } +} + +static void tlog_get_log(struct_packet_cmd_get_log *packet_cmd, + struct serial_port_file *serial_port) +{ + int32_t result; + int32_t ret = 0; + fd_set readset; + struct_packet_rsp_get_log packet_rsp; + packet_rsp.seq_num = packet_cmd->seq_num + 1; + packet_rsp.packet_size = sizeof(packet_rsp); + while(1){ + do { + FD_ZERO(&readset); + FD_SET(packet_cmd->ptzfd, &readset); + tlogd("while select\n"); + result = select((packet_cmd->ptzfd + 1), &readset, NULL, NULL, NULL); + } while (result == -1 && errno == EINTR); + if (result < 0) { + continue; + } + ret = read(packet_cmd->ptzfd, g_log_buffer, LOG_BUFFER_LEN); + debug("log length = %d \n", ret); + packet_rsp.length = ret; + dump_buff(g_log_buffer, 32); + if(memcpy_s(packet_rsp.buffer, sizeof(packet_rsp.buffer), g_log_buffer, ret)) { + tloge("memcpy_s err\n"); + debug("memcpy_s err\n"); + break; + } + //packet_rsp.ret = ret; + //dump_buff(packet_rsp.buffer, 32); + ret = send_to_vm(serial_port, &packet_rsp, sizeof(packet_rsp)); + if (ret != sizeof(packet_rsp)) { + tloge("send to VM failed \n"); + } + break; + } +} + +static void tlog(uint32_t cmd, void *packet_cmd,struct serial_port_file *serial_port) +{ + switch (cmd) + { + case VTZ_GET_TEEOS_VER: + (void)tlog_get_teever((struct_packet_cmd_get_ver *)packet_cmd, + serial_port); + break; + case VTZ_SET_READER_CUR: + (void)tlog_set_reader_cur((struct_packet_cmd_set_reader_cur *)packet_cmd, + serial_port); + break; + case VTZ_SET_TLOGCAT_STAT: + (void)tlog_set_stat((struct_packet_cmd_set_tlogcat_stat *)packet_cmd, + serial_port); + break; + case VTZ_GET_TLOGCAT_STAT: + (void)tlog_get_stat((struct_packet_cmd_get_tlogcat_stat *)packet_cmd, + serial_port); + break; + case VTZ_GET_LOG: + (void)tlog_get_log((struct_packet_cmd_get_log *)packet_cmd, + serial_port); + default: + break; + } +} + +void *thread_entry(void *args) +{ + uint32_t ui32_cmd; + //int serial_port_fd = *(uint64_t*)(args); + //struct serial_port_file *serial_port = get_serial_port_file(serial_port_fd); + + uint64_t u64 = *(uint64_t*)(args); + struct serial_port_file *serial_port = (struct serial_port_file *)u64; + char* rd_buf = (char*)(args) + sizeof(uint64_t); + + uint32_t seq_num = *(uint32_t*)(rd_buf + sizeof(uint32_t)); + set_thread_seq_num(&g_pool, pthread_self(), seq_num); + 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 VTZ_OPEN_TZD: + debug("before open tz \n"); + (void)open_tzdriver((struct_packet_cmd_open_tzd *)rd_buf, serial_port); + break; + case VTZ_CLOSE_TZD: + (void)close_tzdriver((struct_packet_cmd_close_tzd *)rd_buf, serial_port); + break; + case VTZ_LOG_IN_NHIDL: + (void)log_in_NonHidl((struct_packet_cmd_login_non *)rd_buf, serial_port); + break; + case VTZ_GET_TEE_VERSION: + (void)get_tee_ver((struct_packet_cmd_getteever *)rd_buf, serial_port); + break; + case VTZ_GET_TEE_INFO: + (void)get_tee_info((struct_packet_cmd_getteeinfo *)rd_buf, serial_port); + break; + case VTZ_LATE_INIT: + break; + case VTZ_SYNC_TIME: + (void)SyncSysTime((struct_packet_cmd_synctime *)rd_buf, serial_port); + break; + case VTZ_LOG_IN: + (void)log_in((struct_packet_cmd_login *)rd_buf, serial_port); + break; + case VTZ_LOAD_SEC: + (void)load_sec_file((struct_packet_cmd_load_sec *)rd_buf, serial_port); + break; + case VTZ_OPEN_SESSION: + (void)open_session((struct_packet_cmd_session *)rd_buf, serial_port); + break; + case VTZ_CLOSE_SESSION: + (void)close_session((struct_packet_cmd_session *)rd_buf, serial_port); + break; + case VTZ_SEND_CMD: + (void)send_cmd((struct_packet_cmd_send_cmd *)rd_buf, serial_port); + break; + case VTZ_FS_REGISTER_AGENT: + (void)register_agent((struct_packet_cmd_regagent *)rd_buf, serial_port); + break; + case VTZ_WAIT_EVENT: + (void)wait_event((struct_packet_cmd_event *)rd_buf, serial_port); + break; + case VTZ_SEND_EVENT_RESPONSE: + (void)sent_event_response((struct_packet_cmd_event *)rd_buf, serial_port); + break; + case VTZ_MMAP: + case VTZ_MUNMAP: + (void)vtz_mmap((struct_packet_cmd_mmap *)rd_buf, serial_port); + break; + case VTZ_GET_TEEOS_VER: + case VTZ_SET_READER_CUR: + case VTZ_SET_TLOGCAT_STAT: + case VTZ_GET_TLOGCAT_STAT: + case VTZ_GET_LOG: + (void)tlog(ui32_cmd, (void *)rd_buf, serial_port); + break; + default: + break; + } + + remove_thread_seq_num(&g_pool, pthread_self(), seq_num); + free(args); + return NULL; +} + +struct test +{ + int cmd; + int seq; + char name[256]; + int seq2; +}; + +struct test2 +{ + int cmd; + int seq; + char name[256]; + int seq2; + char tmp[256]; +}; + +void *malloc_copy(void *buf, int buf_len , int size, int *poffset) +{ + void *res; + void *tmp; + int offset = *poffset; + if (buf_len < offset + size || size < 4) { + tmp = malloc(buf_len - offset); + if (memcpy_s(tmp, buf_len - offset, buf + offset, buf_len - offset)) { + tloge("memcpy_s err \n"); + debug("memcpy_s err\n"); + free(tmp); + return NULL; + } + if (memcpy_s(buf, buf_len - offset, tmp, buf_len - offset)) { + tloge("memcpy_s err \n"); + debug("memcpy_s err\n"); + free(tmp); + return NULL; + } + free(tmp); + *poffset = buf_len - offset; + return NULL; + } + res = malloc(size + sizeof(uint64_t)); + if (!res) { + tloge("failed malloc\n"); + return NULL; + } + if (memcpy_s(res + sizeof(uint64_t), size, buf + offset, size)) { + tloge("memcpy_s err\n"); + debug("memcpy_s err\n"); + } + *poffset = offset + size; + return res; +} + +void *get_packet_item(void *buf, int buf_len, int *poffset) +{ + uint32_t ui32_cmd; + void *res = NULL; + if (buf_len == *poffset) { + *poffset = 0; + return NULL; + } + /* sizeof(cmd) == sizeof(int) */ + if (buf_len < *poffset + (int)sizeof(int)) { + return malloc_copy(buf, buf_len, buf_len - *poffset, poffset); + } + ui32_cmd = *(uint32_t*)(buf + *poffset); + switch (ui32_cmd) + { + case VTZ_OPEN_TZD: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_open_tzd), poffset); + break; + case VTZ_CLOSE_TZD: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_close_tzd), poffset); + break; + case VTZ_LOG_IN_NHIDL: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_login_non), poffset); + break; + case VTZ_GET_TEE_VERSION: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_getteever), poffset); + break; + case VTZ_GET_TEE_INFO: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_getteeinfo), poffset); + break; + case VTZ_LATE_INIT: + break; + case VTZ_SYNC_TIME: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_synctime), poffset); + break; + case VTZ_LOG_IN: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_login), poffset); + break; + case VTZ_LOAD_SEC: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_load_sec), poffset); + break; + case VTZ_OPEN_SESSION: + case VTZ_CLOSE_SESSION: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_session), poffset); + break; + case VTZ_SEND_CMD: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_send_cmd), poffset); + break; + case VTZ_FS_REGISTER_AGENT: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_regagent), poffset); + break; + case VTZ_WAIT_EVENT: + case VTZ_SEND_EVENT_RESPONSE: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_event), poffset); + break; + case VTZ_MMAP: + case VTZ_MUNMAP: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_mmap), poffset); + break; + + case VTZ_GET_TEEOS_VER: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_get_ver), poffset); + break; + case VTZ_SET_READER_CUR: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_set_reader_cur), poffset); + break; + case VTZ_SET_TLOGCAT_STAT: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_set_tlogcat_stat), poffset); + break; + case VTZ_GET_TLOGCAT_STAT: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_get_tlogcat_stat), poffset); + break; + case VTZ_GET_LOG: + res = malloc_copy(buf, buf_len, sizeof(struct_packet_cmd_get_log), poffset); + break; + + case 999: + res = malloc_copy(buf, buf_len, sizeof(struct test), poffset); + break; + case 911: + res = malloc_copy(buf, buf_len, sizeof(struct test2), poffset); + break; + default: + //some err happened + + break; + } + return res; +} + +struct timeval g_start, g_end; +uint32_t g_cost = 0; +int icount = 0; +void process_event(int fd) +{ + int ret; + int offset = 0; + struct serial_port_file *serial_port; + + int buf_len; + serial_port = get_serial_port_file(fd); + if (!serial_port || !serial_port->rd_buf){ + tloge(" rd_buf is NULL \n"); + return ; + } + pthread_mutex_lock(&serial_port->lock); + ret = read(fd, serial_port->rd_buf + serial_port->offset, BUF_LEN_MAX_RD - serial_port->offset); + if (ret < 0) { + tloge("read domain socket failed \n"); + debug("read domain socket failed \n"); + goto END; + } + if (ret == 0) { + goto END; + } + buf_len = ret + serial_port->offset; + if (g_cost == 0) + gettimeofday(&g_start, NULL); + while(1){ + void *packet = NULL; + packet = get_packet_item(serial_port->rd_buf, buf_len, &offset); + if (packet == NULL) { + break; + } + *(uint64_t*)(packet) = (uint64_t)serial_port; + if (*(int*)(packet+sizeof(uint64_t))==999 || *(int*)(packet+sizeof(uint64_t))==911){ + int seq = ((struct test*)(packet+4))->seq; + int seq2 = ((struct test*)(packet+4))->seq2; + if (seq %10000 == 0) { + printf("seq = %d, buf_size = %d serial_port->offset= %ld\n", ((struct test*)(packet+4))->seq, ret, serial_port->offset); + gettimeofday(&g_end, NULL); + g_cost = (1000000 * g_end.tv_sec + g_end.tv_usec) - (1000000 * g_start.tv_sec + g_start.tv_usec); + printf("serial cost : %f us data total size = %ld KB, speed = %ld B/ms\n", g_cost * 1.0, + seq * sizeof(struct test)/1024, + seq * sizeof(struct test)/(g_cost/1000)); + } + if (icount != seq || seq*seq != seq2) { + printf("err\n"); + dump_buff(packet, 160); + exit(0); + } + icount++; + if(icount == 500000) + icount = 0; + free(packet); + continue; + } + thread_pool_submit(&g_pool, thread_entry, (void *)((uint64_t)packet)); + } + serial_port->offset = offset; + +END: + pthread_mutex_unlock(&serial_port->lock); +} + +int main() { + int ret = 0; + int i; + g_log_buffer = malloc(LOG_BUFFER_LEN); + if (!g_log_buffer) { + tloge("Failed to allocate memory\n"); + return -ENOMEM; + } + thread_pool_init(&g_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) { + process_event(g_pollfd[i].fd); + } + } + } + + serial_port_list_destroy(); + return 0; +} + + + + + 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..092697eb2b7c14b705ed88e3f4493f2a358afb15 --- /dev/null +++ b/trustzone-awared-vm/Host/vtzb_proxy/vtzb_proxy.h @@ -0,0 +1,214 @@ +#ifndef __VTZB_PROXY_H__ +#define __VTZB_PROXY_H__ + +#include +#include +#include "tc_ns_client.h" +#include "tee_sys_log.h" +#include "tee_client_list.h" + +#define TC_LOGGER_DEV_NAME "/dev/teelog" + +//#define VM_NUM_MAX 2 + +#define H_OFFSET 32 + +#define VTZB_RSP_UNKOWN 0xfffffffe + +/* for tlog ioctl */ +/* LOG_BUFFER_LEN: The maximum transmission size for one serial communication is 2048 bytes. + * If the data size exceeds this limit, it may need to be sent in multiple segments. + * The receiving end might find it inconvenient to handle these segments individually. + */ +#define LOG_BUFFER_LEN 2000 +#define TEELOGGERIO 0xBE +#define GET_VERSION_BASE 5 +#define SET_READERPOS_CUR_BASE 6 +#define SET_TLOGCAT_STAT_BASE 7 +#define GET_TLOGCAT_STAT_BASE 8 +#define GET_TEE_INFO_BASE 9 +#define SET_VM_FLAG 10 +#define MAX_TEE_VERSION_LEN 256U +#define TEELOGGER_GET_VERSION _IOR(TEELOGGERIO, GET_VERSION_BASE, char[MAX_TEE_VERSION_LEN]) +/* set the log reader pos to current pos */ +#define TEELOGGER_SET_READERPOS_CUR _IO(TEELOGGERIO, SET_READERPOS_CUR_BASE) +#define TEELOGGER_SET_TLOGCAT_STAT _IO(TEELOGGERIO, SET_TLOGCAT_STAT_BASE) +#define TEELOGGER_GET_TLOGCAT_STAT _IO(TEELOGGERIO, GET_TLOGCAT_STAT_BASE) +#define TEELOGGER_GET_TEE_INFO _IOR(TEELOGGERIO, GET_TEE_INFO_BASE, TC_NS_TEE_Info) +#define TEELOGGER_SET_VM_FLAG _IOR(TEELOGGERIO, SET_VM_FLAG, int) + +#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ + (((paramTypes) >> (4 * (index))) & 0x0F) + +#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 IS_SHARED_MEM(paramType) \ + ((paramType) == TEEC_MEMREF_SHARED_INOUT) + +#define PAGE_SIZE getpagesize() + +typedef union { + struct { + uint32_t buf_size; + } memref; + struct { + uint32_t val_a; + uint32_t val_b; + } value; +} ClientParam; + +typedef struct { + void* vm_buffer; + void* buffer; + uint32_t buffer_size; + int32_t dev_fd; + struct ListNode node; +} struct_shrd_mem; + +/* +typedef struct { + char path[UNIX_PATH_MAX]; + int sock; +} char_dev; + +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 session { + struct ListNode head; + unsigned int session_id; + TC_NS_ClientContext cliContext; + pthread_t thread_id; +}; + +struct fd_file { + int32_t ptzfd; + struct ListNode head; + pthread_mutex_t session_lock; + struct ListNode session_head; +}; + +struct vm_list { + pthread_mutex_t lock; + struct ListNode head; +}; + + +/* + * Structure related to log + */ +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_ver; + +#define VERSION_INFO_LEN 156U +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + unsigned char version_info[MAX_TEE_VERSION_LEN]; +} struct_packet_rsp_get_ver; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_set_reader_cur; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_set_reader_cur; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_set_tlogcat_stat; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_set_tlogcat_stat; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_tlogcat_stat; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_get_tlogcat_stat; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_log; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + int length; + char buffer[LOG_BUFFER_LEN]; +} struct_packet_rsp_get_log; + +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; + +int connect_domsock_chardev(char* dev_path, int* sock); +void *kill_Zombie(void *args); + +#endif /* __VTZB_PROXY_H__ */ + + + + + 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..3f31d2505bcb4448e893eeae9bd09371e630b350 --- /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 3 + +#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/process_data.c b/trustzone-awared-vm/VM/vtzdriver/process_data.c new file mode 100644 index 0000000000000000000000000000000000000000..0a1ba369a9fb32cef69e2baed6a327a8e9c9a46c --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/process_data.c @@ -0,0 +1,52 @@ +#include +#include +#include "process_data.h" +#include "comm_structs.h" +#include "tlogger.h" + +void *malloc_copy(void *buf, int buf_len , int size, int *poffset, int *psize) +{ + void *res; + int offset = *poffset; + if (buf_len < offset + size || size < 4) { + memmove_s(buf, buf_len, buf + offset, buf_len - offset); + *poffset = buf_len - offset; + return NULL; + } + res = kzalloc(size, GFP_KERNEL); + if (!res) { + tloge("failed malloc\n"); + return NULL; + } + if (memcpy_s(res, size, buf + offset, size)) { + tloge("memcpy err\n"); + } + *poffset = offset + size; + *psize = size; + return res; +} + +void *get_packet_item(void *buf, int buf_len, int *poffset, int *psize) +{ + uint32_t packet_size; + void *res = NULL; + uint32_t cmd; + if (buf_len == *poffset) { + *poffset = 0; + return NULL; + } + if (buf_len < *poffset + 4) { + return malloc_copy(buf, buf_len, buf_len - *poffset, poffset, psize); + } + packet_size = *(uint32_t*)(buf + *poffset); + if (packet_size > 1024*8) { + tloge("packet_size err\n"); + } + cmd = *(uint32_t*)(buf + 4 + *poffset); + tlogd("cmd = %d \n", cmd); + res = malloc_copy(buf, buf_len, packet_size, poffset, psize); + + return res; +} + + diff --git a/trustzone-awared-vm/VM/vtzdriver/process_data.h b/trustzone-awared-vm/VM/vtzdriver/process_data.h new file mode 100644 index 0000000000000000000000000000000000000000..fc480e67130fceeb98516cc918ccf872d89dba92 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/process_data.h @@ -0,0 +1,6 @@ +#ifndef PROCESS_DATA_H +#define PROCESS_DATA_H + +void *get_packet_item(void *buf, int buf_len, int *poffset, int *psize); + +#endif diff --git a/trustzone-awared-vm/VM/vtzdriver/reserved_shm.c b/trustzone-awared-vm/VM/vtzdriver/reserved_shm.c new file mode 100644 index 0000000000000000000000000000000000000000..b149423d144b0877259f31be725219a5f66469b0 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/reserved_shm.c @@ -0,0 +1,118 @@ +#include "reserved_shm.h" +#include +#include +#include +#include "tc_ns_log.h" + +struct reserved_shm_list g_res_shm_list; +struct mutex g_lock; +size_t g_alloc_size; +size_t g_relese_size; + +void put_alloc(size_t size) +{ + mutex_lock(&g_lock); + g_alloc_size += size; + mutex_unlock(&g_lock); +} + +void put_relese(size_t size) +{ + mutex_lock(&g_lock); + g_relese_size += size; + mutex_unlock(&g_lock); +} + + +void init_res_shm_list(void) +{ + INIT_LIST_HEAD(&g_res_shm_list.head); + mutex_init(&g_res_shm_list.lock); + mutex_init(&g_lock); + g_alloc_size = 0; + g_relese_size = 0; +} + +void destroy_res_shm_list(void) +{ + struct reserved_shm *shm = NULL; + struct reserved_shm *temp = NULL; + mutex_lock(&g_res_shm_list.lock); + list_for_each_entry_safe(shm, temp, &g_res_shm_list.head, head) { + if (shm->kernel_addr) + kfree(shm->kernel_addr); + list_del(&shm->head); + kfree(shm); + } + mutex_unlock(&g_res_shm_list.lock); + mutex_destroy(&g_res_shm_list.lock); +} + +void *alloc_res_shm(size_t len) +{ + size_t size = 0; + struct reserved_shm *shm = NULL; + struct reserved_shm *temp = NULL; + struct reserved_shm *result = NULL; + + mutex_lock(&g_res_shm_list.lock); + list_for_each_entry_safe(shm, temp, &g_res_shm_list.head, head) { + if (!shm->using && shm->buf_len >= len) { + shm->using = 1; + result = shm; + break; + } + } + mutex_unlock(&g_res_shm_list.lock); + + if (result) { + return result->kernel_addr; + } + size = ALIGN(len, PAGE_SIZE); + if (size > MAILBOX_POOL_SIZE) { + tloge("vtzf alloc sharemem buffer size %zu is too large \n", len); + return NULL; + } + result = kzalloc(sizeof(struct reserved_shm), GFP_KERNEL); + if (!result) { + tloge("failed to alloc mem for struct reserved_shm\n"); + return NULL; + } + result->kernel_addr = kzalloc(size, GFP_KERNEL); + if (!result->kernel_addr) { + tloge("failed to alloc mem for struct reserved_shm buffer\n"); + kfree(result); + return NULL; + } + result->using = 1; + result->buf_len = size; + INIT_LIST_HEAD(&result->head); + mutex_lock(&g_res_shm_list.lock); + list_add_tail(&result->head, &g_res_shm_list.head); + mutex_unlock(&g_res_shm_list.lock); + return result->kernel_addr; +} + +void dealloc_res_shm(void *kernel_buffer) +{ + int bfind= 0; + struct reserved_shm *shm = NULL; + struct reserved_shm *temp = NULL; + mutex_lock(&g_res_shm_list.lock); + list_for_each_entry_safe(shm, temp, &g_res_shm_list.head, head) { + if (shm->kernel_addr == kernel_buffer) { + shm->using = 0; + memset(shm->kernel_addr, 0, shm->buf_len); + bfind = 1; + list_del(&shm->head); + list_add_tail(&shm->head, &g_res_shm_list.head); + tlogd("dealloc res shm \n"); + break; + } + } + mutex_unlock(&g_res_shm_list.lock); + if (!bfind) + tloge("can't find res mem\n"); +} + + diff --git a/trustzone-awared-vm/VM/vtzdriver/reserved_shm.h b/trustzone-awared-vm/VM/vtzdriver/reserved_shm.h new file mode 100644 index 0000000000000000000000000000000000000000..3a24d552e2868083d8a6f15639dad6dc309ca941 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/reserved_shm.h @@ -0,0 +1,51 @@ +#ifndef RESERVED_SHM_H +#define RESERVED_SHM_H + +#include +#include + +#define MAILBOX_POOL_SIZE SZ_4M + +struct reserved_shm_list +{ + struct mutex lock; + struct list_head head; +}; + + +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; +}; + +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 reserved_shm +{ + void *kernel_addr; + size_t buf_len; + struct list_head head; + int using; +}; + +void init_res_shm_list(void); +void destroy_res_shm_list(void); +void *alloc_res_shm(size_t len); +void dealloc_res_shm(void *kernel_buffer); +#endif + diff --git a/trustzone-awared-vm/VM/vtzdriver/serialport.c b/trustzone-awared-vm/VM/vtzdriver/serialport.c new file mode 100644 index 0000000000000000000000000000000000000000..e5f2dd338e3e54f43b9109bb855873246dd4e0a7 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/serialport.c @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include +#include "serialport.h" +#include "comm_structs.h" +#include "process_data.h" +#include "tc_ns_log.h" + +#define SEQ_NUM_AGENT_MAX 65536u +uint32_t g_seq_num_normal; +uint32_t g_seq_num_fs_agent; +uint32_t g_seq_num_sec_agent; +uint32_t g_seq_num_misc_agent; +struct mutex g_seq_lock; +struct vtzf_serial_port_list g_serial_port_list; +struct vtzf_event_data_list g_event_data_list; +struct task_struct **g_threads; +struct mutex g_threads_lock; + +char *g_name[SERIAL_PORT_NUM]; + +uint32_t get_seq_num(int agent_id) +{ + uint32_t ret; + if (agent_id == AGENT_FS_ID) { + return 10; + } else if (agent_id == SECFILE_LOAD_AGENT_ID) { + return 20; + } else if (agent_id ==AGENT_MISC_ID) { + return 30; + } + mutex_lock(&g_seq_lock); + g_seq_num_normal = (g_seq_num_normal + 2u) % 0xfffffff0; + if (g_seq_num_normal < SEQ_NUM_AGENT_MAX) + g_seq_num_normal = SEQ_NUM_AGENT_MAX; + ret = g_seq_num_normal; + mutex_unlock(&g_seq_lock); + return ret; +} + +void seq_num_init(void) +{ + mutex_init(&g_seq_lock); + g_seq_num_normal = SEQ_NUM_AGENT_MAX; + g_seq_num_fs_agent = 10; + g_seq_num_sec_agent = 20; + g_seq_num_misc_agent = 30; +} + +struct vtzf_serial_port_list *get_serial_port_list(void) +{ + return &g_serial_port_list; +} + +void free_threads(void) +{ + int i; + for (i = 0; i < SERIAL_PORT_NUM; i++) + { + (void)kthread_stop(g_threads[i]); + } + kfree(g_threads); +} + +void free_serial_port_list(void) +{ + struct vtzf_serial_port_file *dev_file = NULL; + struct vtzf_serial_port_file *tmp = NULL; + + free_threads(); + mutex_destroy(&g_event_data_list.lock); + mutex_destroy(&g_event_data_list.destroy_lock); + + mutex_lock(&g_serial_port_list.lock); + list_for_each_entry_safe(dev_file, tmp, &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); + mutex_destroy(&dev_file->flag_lock); + kfree(dev_file); + } + mutex_unlock(&g_serial_port_list.lock); + mutex_destroy(&g_serial_port_list.lock); +} + +struct vhc_event_data *find_event_data(uint32_t seq_num) +{ + int isfind = 0; + struct vhc_event_data *event_data; + struct vhc_event_data *tmp; + mutex_lock(&g_event_data_list.lock); + list_for_each_entry_safe(event_data, tmp, &g_event_data_list.head, head) { + if (event_data->seq_num == seq_num) { + isfind = 1; + break; + } + } + mutex_unlock(&g_event_data_list.lock); + if (isfind) + return event_data; + return NULL; +} + +static inline void increment(struct vtzf_serial_port_file *file) { + mutex_lock(&file->flag_lock); + file->flag += 1; + tlogd("increment wait flag = %d \n", file->flag); + mutex_unlock(&file->flag_lock); +} + +static inline void decrement(struct vtzf_serial_port_file *file) { + mutex_lock(&file->flag_lock); + file->flag -= 1 ; + if (file->flag < 0) + file->flag = 0; + tlogd("decrement wait flag = %d \n", file->flag); + mutex_unlock(&file->flag_lock); +} + +int thread_func(void *arg) +{ + struct vtzf_serial_port_file *file = (struct vtzf_serial_port_file *)arg; + loff_t off_vtzf_serialport = 0; + int ssize_ret = 0; + int ret = 0; + uint32_t seq_num; + int buf_len; + int offset = 0; + struct vhc_event_data *event_data; + while (!kthread_should_stop()) { + ret = wait_event_interruptible(file->wait_event_wq, file->flag); + if (ret != 0) { + tloge("wait event interruptible failed!\n"); + ret = -EINTR; + } + off_vtzf_serialport = 0; + ssize_ret = kernel_read(file->filep, file->buffer + file->offset, SERIAL_PORT_BUF_LEN - file->offset, &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); + decrement(file); + } else if(ssize_ret < 4 ){ + continue; + } else{ + buf_len = ssize_ret + file->offset; + tlogd("buf_len = %d\n", buf_len); + while(1) { + void *packet = NULL; + int packet_size = 0; + packet = get_packet_item(file->buffer, buf_len, &offset, &packet_size); + if (packet == NULL) { + break; + } + decrement(file); + seq_num = *(int *)(packet+4); + mutex_lock(&g_event_data_list.destroy_lock); + event_data = find_event_data(seq_num); + if (event_data && !event_data->destroy) { + tlogd("read succeed, ssize_ret =%d, size_rd_buf =%d \n", (int)ssize_ret, (int)event_data->size_rd_buf); + if (memcpy_s(event_data->rd_buf, event_data->size_rd_buf, packet, packet_size) != 0) { + ret = -EFAULT; + event_data->rd_ret = ret; + } + event_data->rd_ret = 0; + event_data->ret_flag = 1; + wake_up(&event_data->wait_event_wq); + } + mutex_unlock(&g_event_data_list.destroy_lock); + kfree(packet); + + } + file->offset = offset; + } + + schedule(); + } + return 0; +} + +int create_thread(int pos, struct vtzf_serial_port_file *file) +{ + struct task_struct *tmp_thread; + char *thread_name = kmalloc(32, GFP_KERNEL); + if (!thread_name) { + tloge("Failed to allocate memory for thread name\n"); + return -ENOMEM; + } + g_name[pos] = thread_name; + (void)snprintf(thread_name, 32, "thread_%d", pos); + tmp_thread = kthread_run(thread_func, file, thread_name); + if (tmp_thread) { + tlogi("Kernel thread created successfully\n"); + } else { + tloge("Failed to create kernel thread\n"); + return -EFAULT; + } + return 0; +} + +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]; + + void *threads = kzalloc(sizeof(struct task_struct) * SERIAL_PORT_NUM, GFP_KERNEL); + if (!threads) { + tloge("Failed to allocate memory for threads\n"); + return -ENOMEM; + } + g_threads = threads; + INIT_LIST_HEAD(&g_serial_port_list.head); + mutex_init(&g_serial_port_list.lock); + INIT_LIST_HEAD(&g_event_data_list.head); + mutex_init(&g_event_data_list.lock); + mutex_init(&g_event_data_list.destroy_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; + serial_port_file->flag = 0; + mutex_init(&serial_port_file->lock); + mutex_init(&serial_port_file->flag_lock); + init_waitqueue_head(&(serial_port_file->wait_event_wq)); + list_add_tail(&serial_port_file->head, &g_serial_port_list.head); + + if (!file->f_op->read_iter) { + tlogw("undefine!\n"); + } + if (create_thread(i, serial_port_file)) + goto err; + } + tlogi(" open serial port success\n"); + return 0; +err: + free_serial_port_list(); + return ret; +} + +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; + list_del(&dev_file->head); + list_add_tail(&dev_file->head, &g_serial_port_list.head); + mutex_unlock(&g_serial_port_list.lock); + tlogi(" alloc serial port \n"); + return dev_file; + } + } + mutex_unlock(&g_serial_port_list.lock); + } + return NULL; +} + +void free_serial_port(struct vtzf_serial_port_file *dev_file, ssize_t ssize_ret) +{ + if (dev_file){ + dev_file->using = false; + tlogi(" free serial port \n"); + mutex_unlock(&dev_file->lock); + } + if (ssize_ret<=0){ + tloge(" ------------Unexpected exit of user program serial_port free--------------- \n"); + } +} + +struct vhc_event_data *creat_event_data(void) +{ + struct vhc_event_data * event_data = kzalloc(sizeof(struct vhc_event_data), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)event_data)) { + tloge("alloc event_data failed\n"); + return NULL; + } + event_data->ret_flag = 0; + event_data->rd_ret = 0; + event_data->destroy = 0; + INIT_LIST_HEAD(&(event_data->head)); + init_waitqueue_head(&(event_data->wait_event_wq)); + + mutex_lock(&g_event_data_list.lock); + list_add_tail(&event_data->head, &g_event_data_list.head); + mutex_unlock(&g_event_data_list.lock); + return event_data; +} + +void destroy_event_data(struct vhc_event_data *event_data) +{ + if (event_data == NULL) + return ; + + mutex_lock(&g_event_data_list.lock); + list_del(&event_data->head); + event_data->destroy = 1; + mutex_unlock(&g_event_data_list.lock); + + mutex_lock(&g_event_data_list.destroy_lock); + kfree(event_data); + mutex_unlock(&g_event_data_list.destroy_lock); + return ; +} + +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 = -1; + loff_t off_vtzf_serialport = 0; + ssize_t ssize_ret = 0; + struct vtzf_serial_port_file *file; + struct file *fp_serialport; + struct vhc_event_data *event_data; + + file = alloc_serial_port(); + if (file == NULL) { + return -EFAULT; + } + fp_serialport = file->filep; + if (fp_serialport == NULL) { + ret = -EFAULT; + goto err; + } + if ( !(fp_serialport->f_mode & FMODE_CAN_READ) ) { + tloge("%s is not readable \n", VTZF_SERIALPORT); + ret = -EFAULT; + goto err; + } + event_data = creat_event_data(); + if (event_data == NULL) + goto err; + + event_data->seq_num = seq_num + 1; + event_data->rd_buf = rd_buf; + event_data->size_rd_buf = size_rd_buf; + 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); + free_serial_port(file, ssize_ret); + increment(file); + wake_up(&file->wait_event_wq); + + ret = wait_event_interruptible(event_data->wait_event_wq, + event_data->ret_flag); + if (ret != 0) { + tloge("wait event interruptible failed!\n"); + ret = -EINTR; + } + destroy_event_data(event_data); + return ret; + +err: + free_serial_port(file, ssize_ret); + return ret; +} + + + + + + diff --git a/trustzone-awared-vm/VM/vtzdriver/serialport.h b/trustzone-awared-vm/VM/vtzdriver/serialport.h new file mode 100644 index 0000000000000000000000000000000000000000..fabc9831a59fbbf29b3c943ef37df01e661fe48b --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/serialport.h @@ -0,0 +1,66 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#include +#include +#include + +#define SERIAL_PORT_BUF_LEN 1024*8 +#define VTZF_SERIALPORT "/dev/virtio-ports/vtzf_serialport" +#define SERIAL_PORT_NUM 1 + +#define AGENT_FS_ID 0x46536673 +#define SECFILE_LOAD_AGENT_ID 0x4c4f4144 +#define AGENT_MISC_ID 0x4d495343 + +struct vtzf_serial_port_list { + struct mutex lock; + struct list_head head; +}; + +struct vtzf_event_data_list { + struct mutex lock; + struct list_head head; + struct mutex destroy_lock; +}; + +struct vtzf_serial_port_file +{ + struct file *filep; + struct list_head head; + struct mutex lock; + wait_queue_head_t wait_event_wq; + int flag; + struct mutex flag_lock; + bool using; + void *buffer; + int buf_size; + int offset; +}; + +struct vhc_event_data { + struct list_head head; + wait_queue_head_t wait_event_wq; + int ret_flag; + uint32_t seq_num; + void *rd_buf; + size_t size_rd_buf; + int rd_ret; + int destroy; +}; + +int serial_port_init(void); +void free_serial_port_list(void); +void seq_num_init(void); +uint32_t get_seq_num(int agent_id); +struct vtzf_serial_port_list *get_serial_port_list(void); +struct vtzf_serial_port_file *alloc_serial_port(void); +void free_serial_port(struct vtzf_serial_port_file *file, ssize_t ssize_ret); +int send_to_proxy(void * wrt_buf, size_t size_wrt_buf, void * rd_buf, size_t size_rd_buf, uint32_t seq_num); + +#endif + + + + + diff --git a/trustzone-awared-vm/VM/vtzdriver/tee_info.c b/trustzone-awared-vm/VM/vtzdriver/tee_info.c new file mode 100644 index 0000000000000000000000000000000000000000..bdd395a537a6ef33ce736fbacd3fbdb11b110763 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/tee_info.c @@ -0,0 +1,40 @@ +#include "tee_info.h" +#include "tc_ns_log.h" +#include "comm_structs.h" +#include "serialport.h" + +int tc_ns_get_tee_info(int ptzfd, void __user *argp, bool flag) +{ + int ret; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_getteeinfo packet_cmd; + struct_packet_rsp_getteeinfo packet_rsp; + tlogd("**********cmd is get info**********\n"); + if (!argp) { + tloge("invalid params\n"); + return -EINVAL; + } + + if (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 = ptzfd; + packet_cmd.istlog = flag; + + 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; +} + diff --git a/trustzone-awared-vm/VM/vtzdriver/tee_info.h b/trustzone-awared-vm/VM/vtzdriver/tee_info.h new file mode 100644 index 0000000000000000000000000000000000000000..91cd3ed0403fb97c32de01b0b0e480321a67b3b8 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/tee_info.h @@ -0,0 +1,8 @@ +#ifndef TEE_INFO_H +#define TEE_INFO_H + +#include + +int tc_ns_get_tee_info(int ptzfd, void __user *argp, bool flag); + +#endif diff --git a/trustzone-awared-vm/VM/vtzdriver/tlogger.c b/trustzone-awared-vm/VM/vtzdriver/tlogger.c new file mode 100644 index 0000000000000000000000000000000000000000..3515c5be93704128b1175b8b6df395f24c6c6564 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/tlogger.c @@ -0,0 +1,683 @@ +#include "tlogger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "comm_structs.h" +#include "serialport.h" +#include "tee_info.h" +#include "teek_client_constants.h" +#include "tc_ns_client.h" +#include "teek_ns_client.h" +#include +static struct log_buffer *g_log_buffer = NULL; +static int g_buff_len = 0; +static LIST_HEAD(m_log_list); +static uint32_t g_log_mem_len = 0; +static uint32_t g_tlogcat_count = 0; +static struct tlogger_log *g_log; + +static struct mutex g_reader_group_mutex; +static LIST_HEAD(g_reader_group_list); + +static struct tlogger_log *get_reader_log(const struct file *file) +{ + struct tlogger_reader *reader = NULL; + + reader = file->private_data; + if (!reader) + return NULL; + + return reader->log; +} + +static struct tlogger_group *get_tlogger_group(void) +{ + struct tlogger_group *group = NULL; +#ifdef CONFIG_CONFIDENTIAL_CONTAINER + uint32_t nsid = task_active_pid_ns(current)->ns.inum; +#else + uint32_t nsid = PROC_PID_INIT_INO; +#endif + + list_for_each_entry(group, &g_reader_group_list, node) { + if (group->nsid == nsid) + return group; + } + + return NULL; +} + +static struct tlogger_log *get_tlogger_log_by_minor(int minor) +{ + struct tlogger_log *log = NULL; + + list_for_each_entry(log, &m_log_list, logs) { + if (log->misc_device.minor == minor) + return log; + } + + return NULL; +} + +static void init_tlogger_reader(struct tlogger_reader *reader, struct tlogger_log *log, struct tlogger_group *group) +{ + reader->log = log; + reader->group = group; + + get_task_struct(current); + reader->pid = get_task_pid(current, PIDTYPE_PID); + put_task_struct(current); + + reader->r_all = true; + reader->r_off = 0; + reader->r_loops = 0; + reader->r_sn = 0; + reader->r_failtimes = 0; + reader->r_is_tlogf = 0; + reader->r_from_cur = 0; + + INIT_LIST_HEAD(&reader->list); + init_waitqueue_head(&reader->wait_queue_head); +} + +static void init_tlogger_group(struct tlogger_group *group) +{ + group->reader_cnt = 1; +#ifdef CONFIG_CONFIDENTIAL_CONTAINER + group->nsid = task_active_pid_ns(current)->ns.inum; +#else + group->nsid = PROC_PID_INIT_INO; +#endif + group->tlogf_stat = 0; +} + +static int open_tzdriver_tlogger(struct tlogger_reader *dev_file, uint32_t flag) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_open_tzd packet_cmd; + struct_packet_rsp_open_tzd packet_rsp; + + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + dev_file->ptzfd = -1; + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_OPEN_TZD; + packet_cmd.vmid = 0; + /* if flag==0, open tc_ns_client; if flag==1, open tc_private */ + packet_cmd.flag = flag; + + ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num); + if (!ret) { + ret = packet_rsp.ret; + if (ret) { + tloge("open TZdriver failed ret is %d\n", ret); + goto END; + } + dev_file->ptzfd = packet_rsp.ptzfd; + } else { + tloge("send to proxy failed ret is %d\n", ret); + } + +END: + return ret; +} + +static int process_tlogger_open(struct inode *inode, + struct file *file) +{ + struct tlogger_log *log = NULL; + int ret; + struct tlogger_reader *reader = NULL; + struct tlogger_group *group = NULL; + + tlogd("open logger open ++\n"); + /* not support seek */ + ret = nonseekable_open(inode, file); + if (ret != 0) + return ret; + + tlogd("Before get log from minor\n"); + log = get_tlogger_log_by_minor(MINOR(inode->i_rdev)); + if (!log) + return -ENODEV; + + mutex_lock(&g_reader_group_mutex); + group = get_tlogger_group(); + if (group == NULL) { + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)group)) { + mutex_unlock(&g_reader_group_mutex); + return -ENOMEM; + } + init_tlogger_group(group); + list_add_tail(&group->node, &g_reader_group_list); + } else { + group->reader_cnt++; + } + mutex_unlock(&g_reader_group_mutex); + + reader = kmalloc(sizeof(*reader), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)reader)) { + mutex_lock(&g_reader_group_mutex); + if (--group->reader_cnt == 0) { + list_del(&group->node); + kfree(group); + } + mutex_unlock(&g_reader_group_mutex); + return -ENOMEM; + } + init_tlogger_reader(reader, log, group); + + mutex_lock(&log->mutex_log_chnl); + list_add_tail(&reader->list, &log->readers); + g_tlogcat_count++; + mutex_unlock(&log->mutex_log_chnl); + + file->private_data = reader; + (void)open_tzdriver_tlogger(reader, TLOG_DEV_FLAG); + tlogd("tlogcat count %u\n", g_tlogcat_count); + return 0; +} + +static int close_tzdriver_tlogger(struct tlogger_reader *dev_file) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(0); + 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; +} + +static int process_tlogger_release(struct inode *ignored, + struct file *file) +{ + struct tlogger_reader *reader = NULL; + struct tlogger_log *log = NULL; + struct tlogger_group *group = NULL; + + (void)ignored; + + tlogd("logger_release ++\n"); + + if (!file) + return -1; + + reader = file->private_data; + if (!reader) { + tloge("reader is null\n"); + return -1; + } + + log = reader->log; + if (!log) { + tloge("log is null\n"); + return -1; + } + + mutex_lock(&log->mutex_log_chnl); + list_del(&reader->list); + if (g_tlogcat_count >= 1) + g_tlogcat_count--; + mutex_unlock(&log->mutex_log_chnl); + + group = reader->group; + if (group != NULL) { + mutex_lock(&g_reader_group_mutex); + if (reader->r_is_tlogf != 0) + group->tlogf_stat = 0; + if (--group->reader_cnt == 0) { + list_del(&group->node); + kfree(group); + } + mutex_unlock(&g_reader_group_mutex); + } + (void)close_tzdriver_tlogger(reader); + kfree(reader); + tlogd("tlogcat count %u\n", g_tlogcat_count); + return 0; +} + +void dump_buff_log(const char* buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + pr_info("--------------------------------------------------\n"); + pr_info("bufLen = %d\n", (int)bufLen); + for (i = 0; i < bufLen; i++) { + if (i % 16 == 0 && i != 0) { + pr_info("\n"); + } + pr_info("%02x ", *(buffer + i)); + } + pr_info("\n--------------------------------------------------\n"); + return; +} + +static int get_log_from_host(struct tlogger_reader *dev_file) +{ + int ret; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_get_log packet_cmd; + struct_packet_rsp_get_log* packet_rsp; + packet_rsp= kzalloc(sizeof(*packet_rsp) + LOG_BUFFER_LEN, GFP_KERNEL); + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_GET_LOG; + packet_cmd.ptzfd = dev_file->ptzfd; + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), packet_rsp, + sizeof(*packet_rsp) + LOG_BUFFER_LEN, seq_num)) { + tloge("sen to proxy failed\n"); + return -EFAULT; + } else { + ret = packet_rsp->ret; + g_buff_len = packet_rsp->length; + memcpy_s(g_log_buffer, packet_rsp->length, packet_rsp->buffer, packet_rsp->length); + //dump_buff_log(packet_rsp->buffer, 256); + } + tlogd("-----------get_log_from_host-------\n"); + kfree((void *)(packet_rsp)); + return ret; +} + +static ssize_t process_tlogger_read(struct file *file, + char __user *buf, size_t count, loff_t *pos) +{ + int ret = g_buff_len; + (void)buf; + (void)count; + (void)pos; + tlogd("--------------log-------------\n"); + if (copy_to_user(buf, (void *)g_log_buffer, g_buff_len) != 0) + tloge("copy failed, item len %u\n", g_buff_len); + g_buff_len = 0; + return ret; +} + +static unsigned int process_tlogger_poll(struct file *file, + poll_table *wait) +{ + struct tlogger_reader *reader = NULL; + struct tlogger_log *log = NULL; + struct log_buffer *buffer = NULL; + uint32_t ret = POLLOUT | POLLWRNORM; + + tlogd("logger_poll ++\n"); + if (!file) { + tloge("file is null\n"); + return ret; + } + + reader = file->private_data; + if (!reader) { + tloge("the private data is null\n"); + return ret; + } + + log = reader->log; + if (!log) { + tloge("log is null\n"); + return ret; + } + + buffer = (struct log_buffer*)log->buffer_info; + if (!buffer) { + tloge("buffer is null\n"); + return ret; + } + + (void)get_log_from_host(reader); + ret |= POLLIN | POLLRDNORM; + tlogd("before return \n"); + return ret; +} + +static int check_user_arg(unsigned long arg, size_t arg_len) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 18) || \ + LINUX_VERSION_CODE == KERNEL_VERSION(4, 19, 71)) + return (int)access_ok(VERIFY_READ, + (void __user *)(uintptr_t)arg, arg_len); +#else + return (int)access_ok((void __user *)(uintptr_t)arg, arg_len); +#endif +} + +static int get_teeos_version(struct tlogger_reader *dev_file, + uint32_t cmd, unsigned long arg) +{ + int ret; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_get_ver packet_cmd; + struct_packet_rsp_get_ver packet_rsp; + + if ((_IOC_DIR(cmd) & _IOC_READ) == 0) { + tloge("check get version cmd failed\n"); + return -1; + } + + ret = check_user_arg(arg, + sizeof(g_log_buffer->flag.version_info)); + if (ret == 0) { + tloge("check version info arg failed\n"); + return -1; + } + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_GET_TEEOS_VER; + packet_cmd.ptzfd = dev_file->ptzfd; + + 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; + if (copy_to_user((void __user *)(uintptr_t)arg, + (void *)packet_rsp.version_info, + sizeof(packet_rsp.version_info)) != 0) { + tloge("version info copy failed\n"); + return -1; + } + } + return ret; +} + +#define SET_READ_POS 1U +static int set_reader_cur_pos(const struct file *file) +{ + int ret = 0; + struct tlogger_reader *dev_file = NULL; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_set_reader_cur packet_cmd; + struct_packet_rsp_set_reader_cur packet_rsp; + dev_file = file->private_data; + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_SET_READER_CUR; + packet_cmd.ptzfd = dev_file->ptzfd; + + 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 set_tlogcat_f_stat(const struct file *file) +{ + int ret = 0; + struct tlogger_reader *dev_file = NULL; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_set_tlogcat_stat packet_cmd; + struct_packet_rsp_set_tlogcat_stat packet_rsp; + + if (file == NULL) + return -EINVAL; + + dev_file = file->private_data; + if (dev_file == NULL) + return -EINVAL; + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_SET_TLOGCAT_STAT; + packet_cmd.ptzfd = dev_file->ptzfd; + + 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 get_tlogcat_f_stat(const struct file *file) +{ + struct tlogger_reader *dev_file = NULL; + int tlogf_stat = 0; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_get_tlogcat_stat packet_cmd; + struct_packet_rsp_get_tlogcat_stat packet_rsp; + + if (file == NULL) + return tlogf_stat; + + dev_file = file->private_data; + if (dev_file == NULL) + return tlogf_stat; + + packet_cmd.seq_num = seq_num; + packet_cmd.cmd = VTZF_GET_TLOGCAT_STAT; + packet_cmd.ptzfd = dev_file->ptzfd; + 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 { + tlogf_stat = packet_rsp.ret; + } + return tlogf_stat; +} + +static long process_tlogger_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct tlogger_log *log = NULL; + long ret = -EINVAL; + struct tlogger_reader *dev_file = NULL; + if (!file) + return -1; + + log = get_reader_log(file); + if (!log) { + tloge("log is null\n"); + return -1; + } + dev_file = file->private_data; + if (dev_file == NULL) { + return -1; + } + + tlogd("logger_ioctl start ++\n"); + mutex_lock(&log->mutex_info); + + switch (cmd) { + case TEELOGGER_GET_VERSION: + if (get_teeos_version(dev_file, cmd, arg) == 0) + ret = 0; + break; + case TEELOGGER_SET_READERPOS_CUR: + (void)set_reader_cur_pos(file); + ret = 0; + break; + case TEELOGGER_SET_TLOGCAT_STAT: + (void)set_tlogcat_f_stat(file); + ret = 0; + break; + case TEELOGGER_GET_TLOGCAT_STAT: + ret = get_tlogcat_f_stat(file); + break; + case TEELOGGER_GET_TEE_INFO: + ret = tc_ns_get_tee_info(dev_file->ptzfd, (void *)(uintptr_t)arg, true); + break; + default: + tloge("ioctl error default\n"); + break; + } + + mutex_unlock(&log->mutex_info); + return ret; +} + +#ifdef CONFIG_COMPAT +static long process_tlogger_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + tlogd("logger_compat_ioctl ++\n"); + arg = (unsigned long)(uintptr_t)compat_ptr(arg); + return process_tlogger_ioctl(file, cmd, arg); +} +#endif + +static const struct file_operations g_logger_fops = { + .owner = THIS_MODULE, + .read = process_tlogger_read, + .poll = process_tlogger_poll, + .unlocked_ioctl = process_tlogger_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = process_tlogger_compat_ioctl, +#endif + .open = process_tlogger_open, + .release = process_tlogger_release, +}; + +static int register_device(const char *log_name, + uintptr_t addr, int size) +{ + int ret; + struct tlogger_log *log = NULL; + unsigned char *buffer = (unsigned char *)addr; + (void)size; + + log = kzalloc(sizeof(*log), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)log)) { + tloge("kzalloc is failed\n"); + return -ENOMEM; + } + log->buffer_info = buffer; + log->misc_device.minor = MISC_DYNAMIC_MINOR; + log->misc_device.name = kstrdup(log_name, GFP_KERNEL); + if (!log->misc_device.name) { + ret = -ENOMEM; + tloge("kstrdup is failed\n"); + goto out_free_log; + } + log->misc_device.fops = &g_logger_fops; + log->misc_device.parent = NULL; + + INIT_LIST_HEAD(&log->readers); + mutex_init(&log->mutex_info); + mutex_init(&log->mutex_log_chnl); + INIT_LIST_HEAD(&log->logs); + list_add_tail(&log->logs, &m_log_list); + + /* register misc device for this log */ + ret = misc_register(&log->misc_device); + if (unlikely(ret)) { + tloge("failed to register misc device:%s\n", + log->misc_device.name); + goto out_free_log; + } + g_log = log; + return 0; + +out_free_log: + if (log->misc_device.name) + kfree(log->misc_device.name); + + kfree(log); + return ret; +} + +static int alloc_log_mem(void) +{ + int ret = 0; + void *tmp = kzalloc(TEMP_LOG_MEM_SIZE, GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)tmp)) { + tloge("alloc serial_port_file failed\n"); + ret = -ENOMEM; + goto END; + } + g_log_buffer = (struct log_buffer *)tmp; + g_log_mem_len = TEMP_LOG_MEM_SIZE; + g_log_buffer->flag.max_len = g_log_mem_len - sizeof(*g_log_buffer); +END: + return ret; +} + +int register_tloger_device(void) +{ + int ret; + ret = alloc_log_mem(); + if (ret) + return ret; + ret = register_device(LOGGER_LOG_TEEOS, (uintptr_t)g_log_buffer, + g_log_mem_len); + if (ret != 0) { + kfree((void *)g_log_buffer); + g_log_buffer = NULL; + g_log_mem_len = 0; + } + + return ret; +} + +static void unregister_tlogger(void) +{ + struct tlogger_log *current_log = NULL; + struct tlogger_log *next_log = NULL; + + list_for_each_entry_safe(current_log, next_log, &m_log_list, logs) { + /* we have to delete all the entry inside m_log_list */ + misc_deregister(¤t_log->misc_device); + kfree(current_log->misc_device.name); + list_del(¤t_log->logs); + kfree(current_log); + } + + kfree((void *)g_log_buffer); + g_log_buffer = NULL; + g_log_mem_len = 0; +} + +void tlogger_exit(void) +{ + unregister_tlogger(); +} + +int tlogger_init(void) +{ + return register_tloger_device(); +} + + + + diff --git a/trustzone-awared-vm/VM/vtzdriver/tlogger.h b/trustzone-awared-vm/VM/vtzdriver/tlogger.h new file mode 100644 index 0000000000000000000000000000000000000000..aa8e07f1c08d2ed13e82e26585e4fde39d47ffc7 --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/tlogger.h @@ -0,0 +1,213 @@ +/* + * tlogger.h + * + * TEE Logging Subsystem, read the tee os log from rdr memory + */ +#ifndef TLOGGER_H +#define TLOGGER_H + +#include +#include +#include "tc_ns_client.h" + +#define OPEN_FILE_MODE 0640U +#define ROOT_UID 0 +#define ROOT_GID 0 +#define SYSTEM_GID 1000 +#ifdef LAST_TEE_MSG_ROOT_GID +#define FILE_CHOWN_GID 0 +#else +/* system gid for last_teemsg file sys chown */ +#define FILE_CHOWN_GID 1000 +#endif + +#define UINT64_MAX (uint64_t)(~((uint64_t)0)) /* 0xFFFFFFFFFFFFFFFF */ + +/* for log item ----------------------------------- */ +#define LOG_ITEM_MAGIC 0x5A5A +#define LOG_ITEM_LEN_ALIGN 64 +#define LOG_ITEM_MAX_LEN 1024 +#define LOG_READ_STATUS_ERROR 0x000FFFF + +/* =================================================== */ +#define LOGGER_LOG_TEEOS "teelog" /* tee os log */ +#define LOGGERIOCTL 0xBE /* for ioctl */ + +#define DUMP_START_MAGIC "Dump SPI notification" +#define DUMP_END_MAGIC "Dump task states END" + +#define GET_VERSION_BASE 5 +#define SET_READERPOS_CUR_BASE 6 +#define SET_TLOGCAT_STAT_BASE 7 +#define GET_TLOGCAT_STAT_BASE 8 +#define GET_TEE_INFO_BASE 9 + +/* get tee verison */ +#define MAX_TEE_VERSION_LEN 256 +#define TEELOGGER_GET_VERSION \ + _IOR(LOGGERIOCTL, GET_VERSION_BASE, char[MAX_TEE_VERSION_LEN]) +/* set the log reader pos to current pos */ +#define TEELOGGER_SET_READERPOS_CUR \ + _IO(LOGGERIOCTL, SET_READERPOS_CUR_BASE) +#define TEELOGGER_SET_TLOGCAT_STAT \ + _IO(LOGGERIOCTL, SET_TLOGCAT_STAT_BASE) +#define TEELOGGER_GET_TLOGCAT_STAT \ + _IO(LOGGERIOCTL, GET_TLOGCAT_STAT_BASE) +#define TEELOGGER_GET_TEE_INFO \ + _IOR(LOGGERIOCTL, GET_TEE_INFO_BASE, struct tc_ns_tee_info) + +#define NEVER_USED_LEN 28U +#define LOG_ITEM_RESERVED_LEN 1U + +/* 64 byte head + user log */ +struct log_item { + unsigned char never_used[NEVER_USED_LEN]; + unsigned int nsid; + unsigned short magic; + unsigned short reserved0; + uint32_t serial_no; + unsigned short real_len; /* log real len */ + unsigned short buffer_len; /* log buffer's len, multiple of 32 bytes */ + unsigned char uuid[UUID_LEN]; + unsigned char log_source_type; + unsigned char reserved[LOG_ITEM_RESERVED_LEN]; + unsigned char log_level; + unsigned char new_line; /* '\n' char, easy viewing log in bbox.bin file */ + unsigned char log_buffer[]; +}; + +/* --- for log mem --------------------------------- */ +#define TEMP_LOG_MEM_SIZE (64 * SZ_1K) + +#define LOG_BUFFER_RESERVED_LEN 11U +#define VERSION_INFO_LEN 256U + +#define LOG_BUFFER_LEN 2000 + +/* + * Log's buffer flag info, size: 64 bytes head + 156 bytes's version info. + * For filed description: + * last_pos : current log's end position, last log's start position. + * write_loops: Write cyclically. Init value is 0, when memory is used + * up, the value add 1. + */ +struct log_buffer_flag { + uint32_t reserved0; + uint32_t last_pos; + uint32_t write_loops; + uint32_t log_level; + /* [0] is magic failed, [1] is serial_no failed, used fior log retention feature */ + uint32_t reserved[LOG_BUFFER_RESERVED_LEN]; + uint32_t max_len; + unsigned char version_info[VERSION_INFO_LEN]; +}; + +struct log_buffer { + struct log_buffer_flag flag; + unsigned char buffer_start[]; +}; + +struct tlogger_log { + unsigned char *buffer_info; /* ring buffer info */ + struct mutex mutex_info; /* this mutex protects buffer_info */ + struct list_head logs; /* log channels list */ + struct mutex mutex_log_chnl; /* this mutex protects log channels */ + struct miscdevice misc_device; /* misc device log */ + struct list_head readers; /* log's readers */ +}; + +struct tlogger_group { + struct list_head node; + uint32_t nsid; + volatile uint32_t reader_cnt; + volatile uint32_t tlogf_stat; +}; + +struct tlogger_reader { + struct tlogger_log *log; /* tlogger_log info data */ + struct tlogger_group *group; /* tlogger_group info data */ + struct pid *pid; /* current process pid */ + struct list_head list; /* log entry in tlogger_log's list */ + wait_queue_head_t wait_queue_head; /* wait queue head for reader */ + /* Current reading position, start position of next read again */ + uint32_t r_off; + uint32_t r_loops; + uint32_t r_sn; + uint32_t r_failtimes; + uint32_t r_from_cur; + uint32_t r_is_tlogf; + bool r_all; /* whether this reader can read all entries */ + uint32_t r_ver; + int32_t ptzfd; +}; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_ver; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + unsigned char version_info[VERSION_INFO_LEN]; +} struct_packet_rsp_get_ver; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_set_reader_cur; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_set_reader_cur; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_set_tlogcat_stat; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_set_tlogcat_stat; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_tlogcat_stat; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; +} struct_packet_rsp_get_tlogcat_stat; + +typedef struct { + uint32_t cmd; + uint32_t seq_num; + int32_t ptzfd; +} struct_packet_cmd_get_log; + +typedef struct { + uint32_t packet_size; + uint32_t seq_num; + uint32_t ret; + int length; + char buffer[]; +} struct_packet_rsp_get_log; + +int tlogger_init(void); +void tlogger_exit(void); +#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..9b846116ca752390a8186881a8363cdb96d1568d --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/vtzf.c @@ -0,0 +1,1722 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include "vtzf.h" +#include "tlogger.h" +#include "serialport.h" +#include "tee_info.h" +#include "comm_structs.h" +#include "reserved_shm.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; + } + 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; +} + +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; + +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; +} + +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 int __init vtzf_init(void) +{ + int ret; + ret = tc_ns_client_init(); + if (ret != 0) + return ret; + init_res_shm_list(); + ret = tlogger_init(); + if (ret != 0) + tloge("tlogger init failed\n"); + 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); + tlogger_exit(); + 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); + + tlogger_exit(); + free_dev_list(); + free_serial_port_list(); + destroy_res_shm_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); + + *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; + + 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); + return 0; +} + +static int vtzf_cvm_open(struct inode *inode, struct file *file) +{ + int ret = -1; + struct vtzf_dev_file *dev = NULL; + (void)inode; + + 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(0); + 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); + + (void)close_tzdriver(dev_file); + + kfree(dev_file); + 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(0); + 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; + + 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) { + dealloc_res_shm(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(0); + 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, 1 << PAGE_SHIFT); + if (len > MAILBOX_POOL_SIZE) { + tloge("vtzf alloc sharemem buffer size %zu is too large \n", len); + kfree(shared_mem); + return -EINVAL; + } + + addr = alloc_res_shm(len); + 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)); + + (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 long vtzf_ser_test(struct file *file, unsigned int cmd, void *argp) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(0); + 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; + + 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; + } + + 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(0); + 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; + + file_size = (size_t)packet_cmd.cliContext.file_size; + tlogd("file_size = %lu \n", file_size); + buffer = (char *)alloc_res_shm(file_size); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + + 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 = (char *)virt_to_phys(buffer); + + if (copy_from_user(buffer, (const void __user *)tmp_buffer, file_size)) { + tloge("file buf get failed \n"); + ret = -EFAULT; + goto END; + } + + 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; + + *clicontext = packet_rsp.cliContext; + + } else { + tloge("send to proxy failed ret is %d\n", ret); + } +END: + dealloc_res_shm(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(0); + 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]) +{ + uint32_t buf_size; + uintptr_t buffer; + uintptr_t user_buf_size, user_buf; + + 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); + + if (copy_from_user(&buf_size, (void *)user_buf_size, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + return -EFAULT; + } + + tlogd(" buffer size = %u\n", buf_size); + buffer = (uintptr_t)alloc_res_shm(buf_size); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("buffer malloc failed\n"); + return -ENOMEM; + } + if (copy_from_user((void *)buffer, (void *)user_buf, buf_size) != 0) { + tloge("copy from user failed\n"); + dealloc_res_shm((void *)buffer); + return -EFAULT; + } + + addrs[index][1] = buffer; + 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 = buf_size; + return 0; +} + +static int alloc_for_val_mem(struct tc_ns_client_context *clicontext, + int index, uintptr_t addrs[][3]) +{ + uint32_t val_a, val_b; + uintptr_t user_val_a, user_val_b; + + 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(&val_a, (void *)user_val_a, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + return -EFAULT; + } + if (copy_from_user(&val_b, (void *)user_val_b, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + return -EFAULT; + } + + clicontext->params[index].value.a_addr = val_a; + clicontext->params[index].value.b_addr = val_b; + 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 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; + uint32_t buf_size; + + 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(&buf_size, (void *)user_size_addr, sizeof(uint32_t)) != 0) { + tloge("copy from user failed\n"); + 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) { + tloge("can't found the mapped shared_mem for cliContext.params[index].memref.buffer \n"); + return -EFAULT; + } + clicontext->params[index].memref.size_addr = buf_size; + return 0; +} + +static int alloc_for_params(struct vtzf_dev_file *dev_file, + struct_packet_cmd_send_cmd *packet_cmd, uintptr_t addrs[][3]) +{ + int ret; + int index; + uint32_t param_type; + bool checkValue; + for (index = 0; index < TEE_PARAM_NUM; index++) { + param_type = teec_param_type_get(packet_cmd->cliContext.param_types, index); + checkValue = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT); + tlogd("param %u type is %x\n", index, param_type); + if (teec_tmpmem_type(param_type, INOUT)) + ret = alloc_for_tmp_mem(&packet_cmd->cliContext, index, addrs); + else if (teec_memref_type(param_type, INOUT)) + 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 = alloc_for_ref_mem(dev_file , packet_cmd, index, addrs); + 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 buf; + uintptr_t user_addr_size, user_addr_buf; + uintptr_t user_addr_val_a, user_addr_val_b; + uint32_t buf_size; + uint32_t val_a, val_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)) { + buf_size = clicontext->params[index].memref.size_addr; + buf = addrs[index][1]; + + user_addr_size = (uintptr_t)(context->params[index].memref.size_addr + | (uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM); + user_addr_buf = (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_size, &buf_size, sizeof(uint32_t)) != 0) + ret = -EFAULT; + if (copy_to_user((void *)user_addr_buf, (void *)buf, buf_size) != 0) + ret = -EFAULT; + dealloc_res_shm((void *)buf); + + } else if(teec_memref_type(param_type, INOUT)) { + buf_size = clicontext->params[index].memref.size_addr; + + user_addr_size = (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_size, &buf_size, sizeof(uint32_t)) != 0) + ret = -EFAULT; + } else if(teec_value_type(param_type, INOUT) || checkValue) { + val_a = clicontext->params[index].value.a_addr; + val_b = clicontext->params[index].value.b_addr; + + user_addr_val_a = (uintptr_t)(context->params[index].value.a_addr + | (uint64_t)context->params[index].value.a_h_addr << ADDR_TRANS_NUM); + user_addr_val_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_val_a, &val_a, sizeof(uint32_t)) != 0) + ret = -EFAULT; + if (copy_to_user((void *)user_addr_val_b, &val_b, sizeof(uint32_t)) != 0) + ret = -EFAULT; + } 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(0); + 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; + + 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); + free_for_params(&packet_rsp.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; + } + + 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: + tlogd(" CMD is TC_NS_CLIENT_IOCTL_SEND_CMD_REQ\n"); + ret = ioctl_session_send_cmd(dev_file, &context, argp); + 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(0); + 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(0); + 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; + } + + 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; + + if (copy_from_user(&packet_cmd.cert_buffer, buffer, CERT_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(0); + struct_packet_cmd_getteever packet_cmd; + struct_packet_rsp_getteever packet_rsp; + packet_cmd.cmd = VTZF_GET_TEE_VERSION; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + /* There is no ptzfd, the TZdriver is opened and close immediately after use */ + if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) { + ret = -EFAULT; + goto END; + } else { + ret = packet_rsp.ret; + if (copy_to_user(argp, &packet_rsp.tee_ver, sizeof(uint32_t)) != 0) + ret = -EFAULT; + } +END: + return ret; +} + +static int tc_ns_late_init(unsigned long arg) +{ + int ret; + uint32_t seq_num = get_seq_num(0); + 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(0); + 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(0); + 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 || dev_file->ptzfd <= 0) { + tloge("invalid params\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; + } + if (!is_valid_agent(packet_cmd.args.buffer_size)) { + return -EINVAL; + } + size = (size_t)packet_cmd.args.buffer_size; + size = ALIGN(size, 1 << PAGE_SHIFT); + 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; + 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 = VTZ_REGISTER_AGENT; + packet_cmd.seq_num = seq_num; + packet_cmd.ptzfd = dev_file->ptzfd; + packet_cmd.phyaddr = (void *)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) { + tloge("copy to user failed\n"); + ret = -EFAULT; + } + } + +END: + return ret; +} + +static int tc_ns_unregister_agent(struct vtzf_dev_file * dev_file, unsigned int agent_id) +{ + int ret = 0; + uint32_t seq_num = get_seq_num(0); + struct_packet_cmd_unregagent packet_cmd; + struct_packet_rsp_unregagent packet_rsp; + + if (!agent_id || !dev_file || dev_file->ptzfd <= 0) { + tloge("invalid params\n"); + return -EINVAL; + } + packet_cmd.cmd = VTZ_UNREGISTER_AGENT; + 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; + } + 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(agent_id); + 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(0); + 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(0); + 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; + file_size = (size_t)packet_cmd.ioctlArg.sec_file_info.file_size; + tlogd("file_size = %lu \n", file_size); + buffer = (char *)alloc_res_shm(file_size); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + tloge("vtzf_dev_file malloc failed\n"); + return -ENOMEM; + } + tmp_buffer = packet_cmd.ioctlArg.file_buffer; + packet_cmd.ioctlArg.file_buffer = (char *)virt_to_phys(buffer); + + if (copy_from_user(buffer, (const void __user *)tmp_buffer, file_size)) { + tloge("file buf get failed \n"); + ret = -EFAULT; + goto END; + } + + 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; + *ioctlArg = packet_rsp.ioctlArg; + } else { + tloge("send to proxy failed ret is %d\n", ret); + } +END: + dealloc_res_shm((void *)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: + ret = tc_ns_unregister_agent(dev_file, (unsigned int)arg); + 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; + struct vtzf_dev_file *dev_file = file->private_data; + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + 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(dev_file->ptzfd, argp, false); + break; + //case TC_NS_CLIENT_IOCTL_SET_NATIVECA_IDENTITY: + //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); + break; + } + + 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; + struct vtzf_dev_file *dev_file = file->private_data; + if (!dev_file) { + tloge("invalid params\n"); + return -EINVAL; + } + + switch (cmd) { + case TC_NS_CLIENT_IOCTL_GET_TEE_INFO: + ret = tc_ns_get_tee_info(dev_file->ptzfd, argp, false); + 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; + } + + 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 + + +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..e2a32ba13f2c5521a7fc5504341ee7efb05168db --- /dev/null +++ b/trustzone-awared-vm/VM/vtzdriver/vtzf.h @@ -0,0 +1,124 @@ +#ifndef VTZF_H +#define VTZF_H + +#include +#include +//#include +#include "tc_ns_client.h" +#include "teek_ns_client.h" +#include "comm_structs.h" +#include "reserved_shm.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 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_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 */ +}; + +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); + +int tc_ns_open_session(struct vtzf_dev_file *dev_file, + struct tc_ns_client_context *clicontext); +int tc_client_session_ioctl(struct vtzf_dev_file *dev_file, + unsigned int cmd, unsigned long arg); +static int tc_ns_send_cancel_cmd(struct vtzf_dev_file *dev_file, void *argp); +static int tc_ns_client_login_func(struct vtzf_dev_file *dev_file, + const void __user *buffer); +static int tc_ns_get_tee_version(struct vtzf_dev_file *dev_file, + void __user *argp); +static int tc_ns_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 + + + + + + diff --git a/trustzone-awared-vm/deployment.docx b/trustzone-awared-vm/deployment.docx new file mode 100644 index 0000000000000000000000000000000000000000..68d14998c6c8bd18484991692ae7cecc7889ae1c Binary files /dev/null and b/trustzone-awared-vm/deployment.docx differ