1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Decription: function for update crl.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14 #include "tz_update_crl.h"
15 #include <linux/namei.h>
16 #include <linux/dcache.h>
17 #include <linux/fs.h>
18 #include <linux/vmalloc.h>
19 #include <linux/uaccess.h>
20 #include "mailbox_mempool.h"
21 #include "smc_smp.h"
22
23 #define D_PATH_LEN 256
24
25 static DEFINE_MUTEX(g_cms_crl_update_lock);
26
send_crl_to_tee(const char *crl_buffer, uint32_t crl_len, const struct tc_ns_dev_file *dev_file)27 int send_crl_to_tee(const char *crl_buffer, uint32_t crl_len, const struct tc_ns_dev_file *dev_file)
28 {
29 int ret;
30 struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
31 struct mb_cmd_pack *mb_pack = NULL;
32 char *mb_param = NULL;
33
34 /* dev_file not need check null */
35 if (crl_buffer == NULL || crl_len == 0 || crl_len > DEVICE_CRL_MAX) {
36 tloge("invalid params\n");
37 return -EINVAL;
38 }
39
40 mb_pack = mailbox_alloc_cmd_pack();
41 if (!mb_pack) {
42 tloge("alloc mb pack failed\n");
43 return -ENOMEM;
44 }
45 mb_param = mailbox_copy_alloc(crl_buffer, crl_len);
46 if (!mb_param) {
47 tloge("alloc mb param failed\n");
48 ret = -ENOMEM;
49 goto clean;
50 }
51 mb_pack->operation.paramtypes = TEEC_MEMREF_TEMP_INPUT;
52 mb_pack->operation.params[0].memref.buffer = (unsigned int )mailbox_virt_to_phys((uintptr_t)mb_param);
53 mb_pack->operation.buffer_h_addr[0] =
54 (unsigned int)((uint64_t)mailbox_virt_to_phys((uintptr_t)mb_param) >> ADDR_TRANS_NUM);
55 mb_pack->operation.params[0].memref.size = crl_len;
56 smc_cmd.cmd_id = GLOBAL_CMD_ID_UPDATE_TA_CRL;
57 smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
58 if (dev_file != NULL)
59 smc_cmd.dev_file_id = dev_file->dev_file_id;
60 smc_cmd.context_id = 0;
61 smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
62 smc_cmd.operation_h_phys =
63 (unsigned int)((uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM);
64
65 mutex_lock(&g_cms_crl_update_lock);
66 ret = tc_ns_smc(&smc_cmd);
67 mutex_unlock(&g_cms_crl_update_lock);
68 if (ret != 0)
69 tloge("smc call returns error ret 0x%x\n", ret);
70 clean:
71 mailbox_free(mb_pack);
72 mb_pack = NULL;
73 if (mb_param)
74 mailbox_free(mb_param);
75
76 return ret;
77 }
78
tc_ns_update_ta_crl(const struct tc_ns_dev_file *dev_file, void __user *argp)79 int tc_ns_update_ta_crl(const struct tc_ns_dev_file *dev_file, void __user *argp)
80 {
81 int ret;
82 struct tc_ns_client_crl context = {0};
83 void *buffer_addr = NULL;
84 uint8_t *crl_buffer = NULL;
85
86 if (!dev_file || !argp) {
87 tloge("invalid params\n");
88 return -EINVAL;
89 }
90
91 if (copy_from_user(&context, argp, sizeof(context)) != 0) {
92 tloge("copy from user failed\n");
93 return -ENOMEM;
94 }
95
96 if (context.size > DEVICE_CRL_MAX) {
97 tloge("crl size is too long\n");
98 return -ENOMEM;
99 }
100
101 crl_buffer = kmalloc(context.size, GFP_KERNEL);
102 if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(crl_buffer))) {
103 tloge("failed to allocate crl buffer\n");
104 return -ENOMEM;
105 }
106
107 buffer_addr = (void *)(uintptr_t)(context.memref.buffer_addr |
108 (((uint64_t)context.memref.buffer_h_addr) << ADDR_TRANS_NUM));
109 if (copy_from_user(crl_buffer, buffer_addr, context.size) != 0) {
110 tloge("copy from user failed\n");
111 goto clean;
112 }
113
114 ret = send_crl_to_tee(crl_buffer, context.size, dev_file);
115 if (ret != 0) {
116 tloge("send crl to tee failed\n");
117 goto clean;
118 }
119
120 clean:
121 kfree(crl_buffer);
122 return ret;
123 }
124
crl_file_open(const char *file_path)125 static struct file *crl_file_open(const char *file_path)
126 {
127 struct file *fp = NULL;
128 int ret;
129 char *dpath = NULL;
130 char tmp_buf[D_PATH_LEN] = {0};
131 struct path base_path = {
132 .mnt = NULL,
133 .dentry = NULL
134 };
135
136 ret = kern_path(file_path, LOOKUP_FOLLOW, &base_path);
137 if (ret != 0)
138 return NULL;
139
140 dpath = d_path(&base_path, tmp_buf, D_PATH_LEN);
141 if (!dpath || IS_ERR(dpath))
142 goto clean;
143
144 fp = filp_open(dpath, O_RDONLY, 0);
145
146 clean:
147 path_put(&base_path);
148 return fp;
149 }
150
tz_update_crl(const char *file_path, const struct tc_ns_dev_file *dev_file)151 int tz_update_crl(const char *file_path, const struct tc_ns_dev_file *dev_file)
152 {
153 struct file *fp = NULL;
154 uint32_t crl_len;
155 char *crl_buffer = NULL;
156 uint32_t read_size;
157 loff_t pos = 0;
158 int ret = 0;
159
160 if (!dev_file || !file_path) {
161 tloge("invalid params\n");
162 return -EINVAL;
163 }
164
165 fp = crl_file_open(file_path);
166 if (!fp || IS_ERR(fp)) {
167 tloge("open crl file error, ret = %ld\n", PTR_ERR(fp));
168 return -ENOENT;
169 }
170 if (!fp->f_inode) {
171 tloge("node is NULL\n");
172 ret = -EINVAL;
173 goto clean;
174 }
175
176 crl_len = (uint32_t)(fp->f_inode->i_size);
177 if (crl_len > DEVICE_CRL_MAX) {
178 tloge("crl file len is invalid %u\n", crl_len);
179 ret = -EINVAL;
180 goto clean;
181 }
182
183 crl_buffer = vmalloc(crl_len);
184 if (!crl_buffer) {
185 tloge("alloc crl file buffer(size=%u) failed\n", crl_len);
186 ret = -ENOMEM;
187 goto clean;
188 }
189
190 read_size = (uint32_t)kernel_read(fp, crl_buffer, crl_len, &pos);
191 if (read_size != crl_len) {
192 tloge("read crl file failed, read size/total size=%u/%u\n", read_size, crl_len);
193 ret = -ENOENT;
194 goto clean;
195 }
196
197 ret = send_crl_to_tee(crl_buffer, crl_len, dev_file);
198 if (ret != 0) {
199 tloge("send crl to tee failed\n");
200 goto clean;
201 }
202
203 clean:
204 filp_close(fp, 0);
205 fp = NULL;
206 if (crl_buffer)
207 vfree(crl_buffer);
208 return ret;
209 }