1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21
22 #include "hks_file_operator.h"
23
24 #ifndef _STORAGE_LITE_
25 #include <dirent.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30
31 /* use product definitions temporarily */
32 #define DEFAULT_FILE_PERMISSION 0700
33 #else
34
35 #include <utils_file.h>
36
37 #endif /* _STORAGE_LITE_ */
38
39 #include "securec.h"
40
41 #include "hks_log.h"
42 #include "hks_mem.h"
43 #include "hks_template.h"
44
45 #ifdef HUKS_LOG_MINI_EXT_ENABLED
46 #include "log.h"
47 #endif
48
49
50 #ifndef _CUT_AUTHENTICATE_
GetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)51 static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
52 {
53 if (path != NULL) {
54 if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) {
55 return HKS_ERROR_INTERNAL_ERROR;
56 }
57
58 if (path[strlen(path) - 1] != '/') {
59 if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) {
60 return HKS_ERROR_INTERNAL_ERROR;
61 }
62 }
63
64 if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
65 return HKS_ERROR_INTERNAL_ERROR;
66 }
67 } else {
68 if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
69 return HKS_ERROR_INTERNAL_ERROR;
70 }
71 }
72
73 return HKS_SUCCESS;
74 }
75
GetFullFileName(const char * path,const char * fileName,char ** fullFileName)76 static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName)
77 {
78 uint32_t nameLen = HKS_MAX_FILE_NAME_LEN;
79 char *tmpFileName = (char *)HksMalloc(nameLen);
80 HKS_IF_NULL_RETURN(tmpFileName, HKS_ERROR_MALLOC_FAIL)
81 (void)memset_s(tmpFileName, nameLen, 0, nameLen);
82
83 int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen);
84 if (ret != HKS_SUCCESS) {
85 HKS_LOG_E("get full fileName failed");
86 HKS_FREE(tmpFileName);
87 return ret;
88 }
89
90 *fullFileName = tmpFileName;
91 return HKS_SUCCESS;
92 }
93
94 #ifndef _STORAGE_LITE_
IsFileExist(const char * fileName)95 static int32_t IsFileExist(const char *fileName)
96 {
97 struct stat fileStat;
98 int32_t ret = stat(fileName, &fileStat);
99 if (ret == -1) {
100 if (errno == ENOENT) {
101 return HKS_ERROR_NOT_EXIST;
102 } else {
103 HKS_LOG_E("file stat failed, errno = 0x%" LOG_PUBLIC "x", errno);
104 return HKS_ERROR_OPEN_FILE_FAIL;
105 }
106 }
107
108 return HKS_SUCCESS;
109 }
110
FileRead(const char * fileName,uint32_t offset,struct HksBlob * blob,uint32_t * size)111 static int32_t FileRead(const char *fileName, uint32_t offset, struct HksBlob *blob, uint32_t *size)
112 {
113 (void)offset;
114 int32_t fd = open(fileName, O_RDONLY);
115 if (fd < 0) {
116 HKS_LOG_E("failed to open file, errno = 0x%" LOG_PUBLIC "x", errno);
117 #ifdef HUKS_LOG_MINI_EXT_ENABLED
118 HILOG_ERROR(HILOG_MODULE_SCY, "failed to open file, errno = 0x%{public}X", errno);
119 #endif
120 return HKS_ERROR_OPEN_FILE_FAIL;
121 }
122
123 int32_t len = read(fd, blob->data, blob->size);
124 close(fd);
125 if (len < 0) {
126 HKS_LOG_E("failed to read file, errno = 0x%" LOG_PUBLIC "x", errno);
127 #ifdef HUKS_LOG_MINI_EXT_ENABLED
128 HILOG_ERROR(HILOG_MODULE_SCY, "failed to read file, errno = 0x%{public}X", errno);
129 #endif
130 return HKS_ERROR_READ_FILE_FAIL;
131 }
132 *size = (uint32_t)len;
133 return HKS_SUCCESS;
134 }
135
FileSize(const char * fileName)136 static uint32_t FileSize(const char *fileName)
137 {
138 struct stat fileStat;
139 (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
140 if (stat(fileName, &fileStat) != 0) {
141 HKS_LOG_E("file stat failed, errno = 0x%" LOG_PUBLIC "x", errno);
142 return 0;
143 }
144
145 return (uint32_t)fileStat.st_size;
146 }
147
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)148 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
149 {
150 (void)offset;
151 int32_t fd = open(fileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
152 if (fd < 0) {
153 HKS_LOG_E("open file failed, errno = 0x%" LOG_PUBLIC "x", errno);
154 #ifdef HUKS_LOG_MINI_EXT_ENABLED
155 HILOG_ERROR(HILOG_MODULE_SCY, "open file failed, errno = 0x%{public}X", errno);
156 #endif
157 return HKS_ERROR_OPEN_FILE_FAIL;
158 }
159
160 int32_t size = write(fd, buf, len);
161 if (size < 0) {
162 HKS_LOG_E("write file size failed, errno = 0x%" LOG_PUBLIC "x", errno);
163 #ifdef HUKS_LOG_MINI_EXT_ENABLED
164 HILOG_ERROR(HILOG_MODULE_SCY, "write file size failed, errno = 0x%{public}X", errno);
165 #endif
166 close(fd);
167 return HKS_ERROR_WRITE_FILE_FAIL;
168 }
169
170 fsync(fd);
171 close(fd);
172 return HKS_SUCCESS;
173 }
174
FileRemove(const char * fileName)175 static int32_t FileRemove(const char *fileName)
176 {
177 struct stat fileStat;
178 int32_t ret = stat(fileName, &fileStat);
179 if (ret == -1) {
180 if (errno == ENOENT) {
181 return HKS_SUCCESS; /* if file not exist, return ok */
182 } else {
183 HKS_LOG_E("file stat failed, errno = 0x%" LOG_PUBLIC "x", errno);
184 return HKS_ERROR_OPEN_FILE_FAIL;
185 }
186 }
187
188 if (S_ISDIR(fileStat.st_mode)) {
189 return HKS_ERROR_INVALID_ARGUMENT; /* FileRemove func only care about files. */
190 }
191
192 if (unlink(fileName) != 0) {
193 HKS_LOG_E("remove file failed, errno = 0x%" LOG_PUBLIC "x", errno);
194 return HKS_ERROR_REMOVE_FILE_FAIL;
195 }
196
197 return HKS_SUCCESS;
198 }
199
HksIsDirExist(const char * path)200 int32_t HksIsDirExist(const char *path)
201 {
202 HKS_IF_NULL_RETURN(path, HKS_ERROR_NULL_POINTER)
203 return IsFileExist(path);
204 }
205
HksMakeDir(const char * path)206 int32_t HksMakeDir(const char *path)
207 {
208 int result = mkdir(path, DEFAULT_FILE_PERMISSION);
209 if (result == 0) {
210 return HKS_SUCCESS;
211 } else {
212 switch (errno) {
213 case EEXIST:
214 return HKS_ERROR_ALREADY_EXISTS;
215 default:
216 HKS_LOG_E("mkdir failed, errno = 0x%" LOG_PUBLIC "x", errno);
217 #ifdef HUKS_LOG_MINI_EXT_ENABLED
218 HILOG_ERROR(HILOG_MODULE_SCY, "mkdir failed, errno = 0x%{public}X", errno);
219 #endif
220 return HKS_ERROR_MAKE_DIR_FAIL;
221 }
222 }
223 }
224
HksOpenDir(const char * path)225 void *HksOpenDir(const char *path)
226 {
227 return (void *)opendir(path);
228 }
229
HksCloseDir(void * dirp)230 int32_t HksCloseDir(void *dirp)
231 {
232 return closedir((DIR *)dirp);
233 }
234
HksGetDirFile(void * dirp,struct HksFileDirentInfo * direntInfo)235 int32_t HksGetDirFile(void *dirp, struct HksFileDirentInfo *direntInfo)
236 {
237 DIR *dir = (DIR *)dirp;
238 struct dirent *dire = readdir(dir);
239
240 while (dire != NULL) {
241 if (dire->d_type != DT_REG) { /* only care about files. */
242 dire = readdir(dir);
243 continue;
244 }
245
246 uint32_t len = strlen(dire->d_name);
247 if (memcpy_s(direntInfo->fileName, sizeof(direntInfo->fileName) - 1, dire->d_name, len) != EOK) {
248 return HKS_ERROR_INSUFFICIENT_MEMORY;
249 }
250 direntInfo->fileName[len] = '\0';
251 return HKS_SUCCESS;
252 }
253
254 return HKS_ERROR_NOT_EXIST;
255 }
256
HksRemoveDir(const char * dirPath)257 int32_t HksRemoveDir(const char *dirPath)
258 {
259 struct stat fileStat;
260 int32_t ret = stat(dirPath, &fileStat);
261 if (ret != 0) {
262 HKS_LOG_E("file stat failed");
263 return HKS_FAILURE;
264 }
265
266 if (!S_ISDIR(fileStat.st_mode)) {
267 HKS_LOG_E("path is not dir");
268 return HKS_FAILURE;
269 }
270
271 DIR *dir = opendir(dirPath);
272 HKS_IF_NULL_LOGE_RETURN(dir, HKS_ERROR_OPEN_FILE_FAIL, "open dir failed")
273
274 struct dirent *dire = readdir(dir);
275 while (dire != NULL) {
276 if (dire->d_type == DT_REG) { /* only care about files. */
277 ret = HksFileRemove(dirPath, dire->d_name);
278 /* Continue to delete remaining files */
279 HKS_IF_NOT_SUCC_LOGE(ret, "remove file failed when remove dir files, ret = %" LOG_PUBLIC "d.", ret)
280 }
281 dire = readdir(dir);
282 }
283
284 closedir(dir);
285 return HKS_SUCCESS;
286 }
287 #else
IsFileExist(const char * fileName)288 static int32_t IsFileExist(const char *fileName)
289 {
290 unsigned int fileSize;
291 int32_t ret = UtilsFileStat(fileName, &fileSize);
292 if (ret < 0) {
293 return HKS_ERROR_NOT_EXIST;
294 }
295 return HKS_SUCCESS;
296 }
297
FileRead(const char * fileName,uint32_t offset,struct HksBlob * blob,uint32_t * size)298 static int32_t FileRead(const char *fileName, uint32_t offset, struct HksBlob *blob, uint32_t *size)
299 {
300 /* now offset is 0, but we maybe extend hi1131 file interfaces in the future */
301 if (offset != 0) {
302 return HKS_ERROR_INVALID_ARGUMENT;
303 }
304
305 unsigned int fileSize;
306 int32_t ret = UtilsFileStat(fileName, &fileSize);
307 if (ret < 0) {
308 HKS_LOG_E("stat file failed, errno = 0x%" LOG_PUBLIC "x", ret);
309 return HKS_ERROR_INVALID_ARGUMENT;
310 }
311
312 if (blob->size > fileSize) {
313 HKS_LOG_E("read data over file size!\n, file size = %" LOG_PUBLIC "d\n, buf len = %" LOG_PUBLIC "d\n",
314 fileSize, blob->size);
315 return HKS_ERROR_INVALID_ARGUMENT;
316 }
317
318 int fd = UtilsFileOpen(fileName, O_RDONLY_FS, 0);
319 if (fd < 0) {
320 HKS_LOG_E("failed to open file, errno = 0x%" LOG_PUBLIC "x", fd);
321 return HKS_ERROR_OPEN_FILE_FAIL;
322 }
323
324 ret = UtilsFileRead(fd, (char *)blob->data, blob->size);
325 UtilsFileClose(fd);
326 if (ret < 0) {
327 HKS_LOG_E("failed to read file, errno = 0x%" LOG_PUBLIC "x", ret);
328 return HKS_ERROR_READ_FILE_FAIL;
329 }
330 *size = blob->size;
331 return HKS_SUCCESS;
332 }
333
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)334 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
335 {
336 /* now offset is 0, but we may extend hi1131 file interfaces */
337 if (offset != 0) {
338 return HKS_ERROR_INVALID_ARGUMENT;
339 }
340
341 int fd = UtilsFileOpen(fileName, O_CREAT_FS | O_TRUNC_FS | O_RDWR_FS, 0);
342 if (fd < 0) {
343 HKS_LOG_E("failed to open key file, errno = 0x%" LOG_PUBLIC "x\n", fd);
344 return HKS_ERROR_OPEN_FILE_FAIL;
345 }
346
347 int32_t ret = UtilsFileWrite(fd, (const char*)buf, len);
348 (void)UtilsFileClose(fd);
349 if (ret < 0) {
350 HKS_LOG_E("failed to write key file, errno = 0x%" LOG_PUBLIC "x\n", ret);
351 return HKS_ERROR_WRITE_FILE_FAIL;
352 }
353
354 return HKS_SUCCESS;
355 }
356
FileSize(const char * fileName)357 static uint32_t FileSize(const char *fileName)
358 {
359 unsigned int fileSize;
360 int32_t ret = UtilsFileStat(fileName, &fileSize);
361 if (ret < 0) {
362 HKS_LOG_E("stat file failed, errno = 0x%" LOG_PUBLIC "x", ret);
363 return 0;
364 }
365 return fileSize;
366 }
367
FileRemove(const char * fileName)368 static int32_t FileRemove(const char *fileName)
369 {
370 int32_t ret = UtilsFileDelete(fileName);
371 if (ret < 0) {
372 HKS_LOG_E("remove file failed");
373 return HKS_ERROR_REMOVE_FILE_FAIL;
374 }
375 return HKS_SUCCESS;
376 }
377
378 #endif
379
HksFileRead(const char * path,const char * fileName,uint32_t offset,struct HksBlob * blob,uint32_t * size)380 int32_t HksFileRead(const char *path, const char *fileName, uint32_t offset, struct HksBlob *blob, uint32_t *size)
381 {
382 if ((fileName == NULL) || (blob == NULL) || (blob->data == NULL) || (blob->size == 0) || (size == NULL)) {
383 return HKS_ERROR_INVALID_ARGUMENT;
384 }
385
386 char *fullFileName = NULL;
387 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
388 HKS_IF_NOT_SUCC_RETURN(ret, ret)
389
390 ret = FileRead(fullFileName, offset, blob, size);
391 HKS_FREE(fullFileName);
392 return ret;
393 }
394
HksFileWrite(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)395 int32_t HksFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
396 {
397 if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
398 return HKS_ERROR_INVALID_ARGUMENT;
399 }
400
401 char *fullFileName = NULL;
402 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
403 HKS_IF_NOT_SUCC_RETURN(ret, ret)
404
405 ret = FileWrite(fullFileName, offset, buf, len);
406 HKS_FREE(fullFileName);
407 return ret;
408 }
409
HksFileSize(const char * path,const char * fileName)410 uint32_t HksFileSize(const char *path, const char *fileName)
411 {
412 HKS_IF_NULL_RETURN(fileName, 0)
413
414 char *fullFileName = NULL;
415 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
416 HKS_IF_NOT_SUCC_RETURN(ret, 0)
417
418 uint32_t size = FileSize(fullFileName);
419 HKS_FREE(fullFileName);
420 return size;
421 }
422
HksIsFileExist(const char * path,const char * fileName)423 int32_t HksIsFileExist(const char *path, const char *fileName)
424 {
425 HKS_IF_NULL_RETURN(fileName, HKS_ERROR_NULL_POINTER)
426
427 char *fullFileName = NULL;
428 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
429 HKS_IF_NOT_SUCC_RETURN(ret, ret)
430
431 ret = IsFileExist(fullFileName);
432 HKS_FREE(fullFileName);
433 return ret;
434 }
435
HksFileRemove(const char * path,const char * fileName)436 int32_t HksFileRemove(const char *path, const char *fileName)
437 {
438 HKS_IF_NULL_RETURN(fileName, HKS_ERROR_INVALID_ARGUMENT)
439
440 char *fullFileName = NULL;
441 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
442 HKS_IF_NOT_SUCC_RETURN(ret, ret)
443
444 ret = FileRemove(fullFileName);
445 HKS_FREE(fullFileName);
446 return ret;
447 }
448
HksGetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)449 int32_t HksGetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
450 {
451 return GetFileName(path, fileName, fullFileName, fullFileNameLen);
452 }
453
454 #endif /* _CUT_AUTHENTICATE_ */
455