1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "perm_srv_elf_verify_cmd.h"
13 #include <securec.h>
14 #include <tee_log.h>
15 #include <ta_framework.h>
16 #include "tee_elf_verify.h"
17 #include "permission_service.h"
18 #include "handle_anti_rollback.h"
19 #include "perm_srv_ta_ctrl.h"
20 #include "perm_srv_ta_config.h"
21 #include <ipclib_hal.h>
22
perm_srv_ta_run_authorization_check(const TEE_UUID * uuid,const ta_property_t * manifest,uint16_t target_version,bool mem_page_align)23 static TEE_Result perm_srv_ta_run_authorization_check(const TEE_UUID *uuid, const ta_property_t *manifest,
24 uint16_t target_version, bool mem_page_align)
25 {
26 TEE_Result ret;
27 struct config_info config;
28
29 (void)memset_s(&config, sizeof(config), 0, sizeof(config));
30 bool is_invalid = (uuid == NULL || manifest == NULL);
31 bool is_valid_device = true;
32 if (is_invalid)
33 return TEE_ERROR_BAD_PARAMETERS;
34
35 ret = perm_srv_check_ta_deactivated(uuid, target_version);
36 if (ret != TEE_SUCCESS) {
37 tloge("The TA version %u is not allowed\n", target_version);
38 return TEE_ERROR_GENERIC;
39 }
40
41 if (perm_srv_get_config_by_uuid(uuid, &config) != TEE_SUCCESS) {
42 tloge("Failed to get config by uuid\n");
43 return TEE_ERROR_GENERIC;
44 }
45
46 is_valid_device = config.control_info.debug_info.valid_device;
47
48 is_invalid = ((manifest->heap_size <= config.manifest_info.heap_size) &&
49 (manifest->stack_size <= config.manifest_info.stack_size) &&
50 (bool)manifest->instance_keep_alive == config.manifest_info.instance_keep_alive &&
51 (bool)manifest->multi_command == config.manifest_info.multi_command &&
52 (bool)manifest->multi_session == config.manifest_info.multi_session &&
53 (bool)manifest->single_instance == config.manifest_info.single_instance &&
54 is_valid_device && mem_page_align == config.manifest_info.mem_page_align);
55 if (is_invalid) {
56 return TEE_SUCCESS;
57 } else {
58 tloge("heap size 0x%x : 0x%x\n", manifest->heap_size, config.manifest_info.heap_size);
59 tloge("stack size 0x%x : 0x%x\n", manifest->stack_size, config.manifest_info.stack_size);
60 tloge("keep alive 0x%x : 0x%x\n", manifest->instance_keep_alive, config.manifest_info.instance_keep_alive);
61 tloge("multi command 0x%x : 0x%x\n", manifest->multi_command, config.manifest_info.multi_command);
62 tloge("multi session 0x%x : 0x%x\n", manifest->multi_session, config.manifest_info.multi_session);
63 tloge("single instance 0x%x : 0x%x\n", manifest->single_instance, config.manifest_info.single_instance);
64 tloge("is valid device 0x%x\n", is_valid_device);
65 tloge("mem page align 0x%x : 0x%x\n", mem_page_align, config.manifest_info.mem_page_align);
66 }
67
68 tloge("ta run authorization check manifest compare error\n");
69
70 return TEE_ERROR_GENERIC;
71 }
72
check_perm_srv_elf_verify(const perm_srv_req_msg_t * msg,uint32_t sndr_taskid)73 static TEE_Result check_perm_srv_elf_verify(const perm_srv_req_msg_t *msg, uint32_t sndr_taskid)
74 {
75 if (msg == NULL)
76 return TEE_ERROR_BAD_PARAMETERS;
77
78 if (sndr_taskid != GLOBAL_HANDLE) {
79 tloge("taload permission denied\n");
80 return TEE_ERROR_ACCESS_DENIED;
81 }
82
83 if (msg->header.send.msg_size != sizeof(elf_verify_req)) {
84 tloge("elf verify req msg size %u invalid\n", msg->header.send.msg_size);
85 return TEE_ERROR_BAD_PARAMETERS;
86 }
87
88 return TEE_SUCCESS;
89 }
90
perm_srv_elf_verify(const perm_srv_req_msg_t * msg,uint32_t sndr_taskid,const TEE_UUID * sndr_uuid,perm_srv_reply_msg_t * rsp)91 TEE_Result perm_srv_elf_verify(const perm_srv_req_msg_t *msg, uint32_t sndr_taskid,
92 const TEE_UUID *sndr_uuid, perm_srv_reply_msg_t *rsp)
93 {
94 elf_verify_req req;
95 elf_verify_reply reply;
96
97 (void)sndr_uuid;
98 (void)rsp;
99
100 if (check_perm_srv_elf_verify(msg, sndr_taskid) != TEE_SUCCESS)
101 return TEE_ERROR_BAD_PARAMETERS;
102
103 if (memcpy_s(&req, sizeof(req), &(msg->req_msg.verify_req),
104 msg->header.send.msg_size) != EOK) {
105 tloge("copy elf verify req failed\n");
106 return TEE_ERROR_GENERIC;
107 }
108
109 (void)memset_s(&reply, sizeof(reply), 0, sizeof(reply));
110
111 TEE_Result ret = secure_elf_verify(&req, &reply);
112 if (ret != TEE_SUCCESS) {
113 tloge("secure elf verify failed, ret=0x%x\n", ret);
114 } else {
115 if (reply.payload_hdr.ta_conf_size > 0)
116 ret = perm_srv_ta_run_authorization_check(&(reply.srv_uuid),
117 &(reply.ta_property), reply.mani_ext.target_version,
118 reply.mani_ext.mem_page_align);
119 if (ret == TEE_SUCCESS)
120 ret = anti_version_rollback(&reply);
121 }
122
123 reply.verify_result = ret;
124
125 uint32_t result = ipc_msg_snd(REGISTER_ELF_REQ, sndr_taskid, &reply, sizeof(reply));
126 if (result != SRE_OK) {
127 tloge("send reg elf req msg to failed, ret=0x%x\n", result);
128 return TEE_ERROR_COMMUNICATION;
129 }
130 return TEE_SUCCESS;
131 }
132