• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 
13 #include "tcu_authentication.h"
14 #include <unistd.h>
15 #include <errno.h> /* for errno */
16 #include <fcntl.h>
17 #include <sys/types.h> /* for open close */
18 #include <sys/ioctl.h> /* for ioctl */
19 #include <sys/stat.h> /* for stat */
20 #include <linux/limits.h>
21 #include "securec.h"
22 #include "tee_log.h"
23 #include "tc_ns_client.h"
24 #include "tee_client_type.h"
25 #include "tee_file.h"
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29 #define LOG_TAG            "tcu_authentication"
30 #define HASH_FILE_MAX_SIZE (16 * 1024)
31 #define ERR_SIZE           (-1)
32 #define XML_HEADER         4
33 #define MAX_HASHFILE_PATHLEN 256
34 
35 static const char *g_vendorCaHashFileList[] = {
36     "/vendor/etc/native_packages.xml",
37     "/vendor/root/res/native_packages.xml",
38     "/vendor/etc/passthrough/teeos/source/native_packages.xml",
39 };
40 
41 static const char *g_systemCaHashFileList[] = {
42     "/system/etc/native_packages.xml",
43 };
44 
45 static const char *g_wholeCaHashFileList[] = {
46     "/vendor/etc/native_packages.xml",
47     "/system/etc/native_packages.xml",
48     "/vendor/root/res/native_packages.xml",
49     "/vendor/etc/passthrough/teeos/source/native_packages.xml",
50 };
51 
GetCaHashFileList(uint8_t * num,uint8_t hash_type)52 static const char **GetCaHashFileList(uint8_t *num, uint8_t hash_type)
53 {
54     if (num == NULL) {
55         tloge("input parameter error\n");
56         return NULL;
57     }
58 
59     if (hash_type == HASH_TYPE_SYSTEM) {
60         *num = sizeof(g_systemCaHashFileList) / sizeof(intptr_t);
61         return g_systemCaHashFileList;
62     } else if (hash_type == HASH_TYPE_VENDOR) {
63         *num = sizeof(g_vendorCaHashFileList) / sizeof(intptr_t);
64         return g_vendorCaHashFileList;
65     } else {
66         *num = sizeof(g_wholeCaHashFileList) / sizeof(intptr_t);
67         return g_wholeCaHashFileList;
68     }
69 }
70 
IsNotValidFname(const char * path)71 static int IsNotValidFname(const char *path)
72 {
73     if (path == NULL) {
74         tloge("filename is invalid ...\n");
75         return 1;
76     }
77 
78     /* filter the .. dir in the pname: */
79     if (strstr(path, "..") != NULL) {
80         tloge("filename should not include .. dir\n");
81         return 1;
82     }
83 
84     return 0;
85 }
86 
GetFileSize(const char * path,int * realSize)87 static int GetFileSize(const char *path, int *realSize)
88 {
89     FILE *fp = NULL;
90     int ret;
91     int fileSize                = -1;
92     int xmlHeader               = 0;
93     char realPath[PATH_MAX + 1] = { 0 };
94 
95     bool paramInvlid = ((path == NULL) || (IsNotValidFname(path) != 0) || (strlen(path) > PATH_MAX) ||
96                         (realpath(path, realPath) == NULL));
97     if (paramInvlid) {
98         return fileSize;
99     }
100 
101     fp = fopen(realPath, "r");
102     if (fp == NULL) {
103         return fileSize;
104     }
105 
106     ret = fseek(fp, 0L, SEEK_END);
107     if (ret < 0) {
108         fclose(fp);
109         fp = NULL;
110         return fileSize;
111     }
112 
113     fileSize = (int)ftell(fp);
114 
115     ret = fseek(fp, 0L, SEEK_SET);
116     if (ret < 0 || fileSize < XML_HEADER) {
117         fclose(fp);
118         fp = NULL;
119         return ERR_SIZE;
120     }
121     int len = (int)fread(&xmlHeader, 1, sizeof(int), fp);
122     if (len != sizeof(int) || xmlHeader < fileSize) {
123         tloge("size read is invalid\n");
124         fclose(fp);
125         fp = NULL;
126         return ERR_SIZE;
127     }
128 
129     (void)fclose(fp);
130     fp = NULL;
131     *realSize = fileSize;
132     return xmlHeader;
133 }
134 
GetFileInfo(int bufLen,uint8_t * buffer,const char * path)135 static int GetFileInfo(int bufLen, uint8_t *buffer, const char *path)
136 {
137     FILE *fp = NULL;
138     int fileSize;
139     char realPath[PATH_MAX + 1] = { 0 };
140 
141     bool paramInvlid = ((buffer == NULL) || (path == NULL) || (IsNotValidFname(path) != 0) ||
142                         (strlen(path) > PATH_MAX) || (realpath(path, realPath) == NULL) ||
143                         (bufLen == 0));
144     if (paramInvlid) {
145         return -1;
146     }
147 
148     fp = fopen(realPath, "rb");
149     if (fp == NULL) {
150         tloge("open file failed\n");
151         return -1;
152     }
153 
154     fileSize = (int)fread(buffer, sizeof(char), (unsigned int)bufLen, fp);
155     if (fileSize != bufLen) {
156         tloge("read file read number:%" PUBLIC "d\n", fileSize);
157         fclose(fp);
158         fp = NULL;
159         return -1;
160     }
161 
162     (void)fclose(fp);
163     fp = NULL;
164     return 0;
165 }
166 
InitTempBuf(int bufLen)167 static uint8_t *InitTempBuf(int bufLen)
168 {
169     errno_t ret;
170     uint8_t *buffer = NULL;
171 
172     bool variablesCheck = ((bufLen <= 0) || (bufLen > HASH_FILE_MAX_SIZE));
173     if (variablesCheck) {
174         tloge("wrong buflen\n");
175         return buffer;
176     }
177 
178     buffer = (uint8_t *)malloc((unsigned int)bufLen);
179     if (buffer == NULL) {
180         tloge("malloc failed!\n");
181         return buffer;
182     }
183 
184     ret = memset_s(buffer, (unsigned int)bufLen, 0, (unsigned int)bufLen);
185     if (ret != EOK) {
186         tloge("memset failed!\n");
187         free(buffer);
188         buffer = NULL;
189         return buffer;
190     }
191 
192     return buffer;
193 }
194 
ReadXmlFile(const char * xmlFile)195 static uint8_t *ReadXmlFile(const char *xmlFile)
196 {
197     int ret;
198     int bufLen;
199     uint8_t *buffer = NULL;
200     int realSize = 0;
201 
202     bufLen = GetFileSize(xmlFile, &realSize);
203     buffer = InitTempBuf(bufLen);
204     if (buffer == NULL) {
205         tloge("init temp buffer failed\n");
206         return buffer;
207     }
208 
209     ret = GetFileInfo(realSize, buffer, xmlFile);
210     if (ret != 0) {
211         tloge("get xml file info failed\n");
212         free(buffer);
213         buffer = NULL;
214         return buffer;
215     }
216 
217     return buffer;
218 }
219 
TeeSetNativeCaHash(const char * xmlFlie)220 static int TeeSetNativeCaHash(const char *xmlFlie)
221 {
222     int ret;
223     int fd          = -1;
224     uint8_t *buffer = NULL;
225 
226     buffer = ReadXmlFile(xmlFlie);
227     if (buffer == NULL) {
228         tloge("read xml file failed\n");
229         return fd;
230     }
231 
232     fd = tee_open(TC_PRIVATE_DEV_NAME, O_RDWR, 0);
233     if (fd < 0) {
234         tloge("Failed to open dev node: %" PUBLIC "d\n", errno);
235         free(buffer);
236         buffer = NULL;
237         return -1;
238     }
239     ret = ioctl(fd, (int)(TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY), buffer);
240     if (ret != 0) {
241         tloge("ioctl fail %" PUBLIC "d\n", ret);
242     }
243 
244     free(buffer);
245     buffer = NULL;
246     tee_close(&fd);
247     return ret;
248 }
249 
IsFileExist(const char * name)250 static bool IsFileExist(const char *name)
251 {
252     struct stat statbuf;
253 
254     if (name == NULL) {
255         return false;
256     }
257     if (stat(name, &statbuf) != 0) {
258         if (errno == ENOENT) { /* file not exist */
259             tlogi("file not exist: %" PUBLIC "s\n", name);
260             return false;
261         }
262         return true;
263     }
264 
265     return true;
266 }
267 
TcuAuthentication(uint8_t hash_type)268 int TcuAuthentication(uint8_t hash_type)
269 {
270     uint8_t listLen;
271     const char **hashFileList = GetCaHashFileList(&listLen, hash_type);
272     if (hashFileList == NULL) {
273         tloge("get hashFileList failed\n");
274         return -1;
275     }
276     if (listLen == 0) {
277         tloge("list num is 0, please set hashfile\n");
278         return -1;
279     }
280     static int gHashXmlSetted;
281     uint8_t count = 0;
282     if (gHashXmlSetted == 0) {
283         for (uint8_t index = 0; index < listLen; index++) {
284             if (hashFileList[index] == NULL) {
285                 tloge("get hashFile failed, index is %" PUBLIC "d\n", index);
286                 continue;
287             }
288             if (!IsFileExist(hashFileList[index])) {
289                 continue;
290             }
291             int setRet = TeeSetNativeCaHash(hashFileList[index]);
292             if (setRet != 0) {
293                 tloge("hashfile read failed, index is %" PUBLIC "d\n", index);
294                 continue;
295             }
296             count++;
297         }
298     }
299 
300     if (count == listLen) {
301         gHashXmlSetted = 1;
302         return 0;
303     }
304 
305     return -1;
306 }
307