• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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