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