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
44 #ifndef _CUT_AUTHENTICATE_
GetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)45 static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
46 {
47 if (path != NULL) {
48 if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) {
49 return HKS_ERROR_INTERNAL_ERROR;
50 }
51
52 if (path[strlen(path) - 1] != '/') {
53 if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) {
54 return HKS_ERROR_INTERNAL_ERROR;
55 }
56 }
57
58 if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
59 return HKS_ERROR_INTERNAL_ERROR;
60 }
61 } else {
62 if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
63 return HKS_ERROR_INTERNAL_ERROR;
64 }
65 }
66
67 return HKS_SUCCESS;
68 }
69
GetFullFileName(const char * path,const char * fileName,char ** fullFileName)70 static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName)
71 {
72 uint32_t nameLen = HKS_MAX_FILE_NAME_LEN;
73 char *tmpFileName = (char *)HksMalloc(nameLen);
74 if (tmpFileName == NULL) {
75 return HKS_ERROR_MALLOC_FAIL;
76 }
77 (void)memset_s(tmpFileName, nameLen, 0, nameLen);
78
79 int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen);
80 if (ret != HKS_SUCCESS) {
81 HKS_LOG_E("get full fileName failed");
82 HKS_FREE_PTR(tmpFileName);
83 return ret;
84 }
85
86 *fullFileName = tmpFileName;
87 return HKS_SUCCESS;
88 }
89
90 #ifndef _STORAGE_LITE_
IsFileExist(const char * fileName)91 static int32_t IsFileExist(const char *fileName)
92 {
93 struct stat fileStat;
94 int32_t ret = stat(fileName, &fileStat);
95 if (ret == -1) {
96 if (errno == ENOENT) {
97 return HKS_ERROR_NOT_EXIST;
98 } else {
99 HKS_LOG_E("file stat failed, errno = 0x%x", errno);
100 return HKS_ERROR_OPEN_FILE_FAIL;
101 }
102 }
103
104 return HKS_SUCCESS;
105 }
106
FileRead(const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)107 static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
108 {
109 (void)offset;
110 int32_t fd = open(fileName, O_RDONLY);
111 if (fd < 0) {
112 HKS_LOG_E("failed to open file, errno = 0x%x", errno);
113 return 0;
114 }
115
116 int32_t size = read(fd, buf, len);
117 close(fd);
118 if (size < 0) {
119 HKS_LOG_E("failed to read file, errno = 0x%x", errno);
120 return 0;
121 }
122
123 return (uint32_t)size;
124 }
125
FileSize(const char * fileName)126 static uint32_t FileSize(const char *fileName)
127 {
128 struct stat fileStat;
129 (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
130 if (stat(fileName, &fileStat) != 0) {
131 HKS_LOG_E("file stat failed, errno = 0x%x", errno);
132 return 0;
133 }
134
135 return (uint32_t)fileStat.st_size;
136 }
137
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)138 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
139 {
140 (void)offset;
141 int32_t fd = open(fileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
142 if (fd < 0) {
143 HKS_LOG_E("open file failed, errno = 0x%x", errno);
144 return HKS_ERROR_OPEN_FILE_FAIL;
145 }
146
147 int32_t size = write(fd, buf, len);
148 if (size < 0) {
149 HKS_LOG_E("write file size failed, errno = 0x%x", errno);
150 close(fd);
151 return HKS_ERROR_WRITE_FILE_FAIL;
152 }
153 fsync(fd);
154 close(fd);
155 return HKS_SUCCESS;
156 }
157
FileRemove(const char * fileName)158 static int32_t FileRemove(const char *fileName)
159 {
160 struct stat fileStat;
161 int32_t ret = stat(fileName, &fileStat);
162 if (ret == -1) {
163 if (errno == ENOENT) {
164 return HKS_SUCCESS; /* if file not exist, return ok */
165 } else {
166 HKS_LOG_E("file stat failed, errno = 0x%x", errno);
167 return HKS_ERROR_OPEN_FILE_FAIL;
168 }
169 }
170
171 if (S_ISDIR(fileStat.st_mode)) {
172 return HKS_ERROR_INVALID_ARGUMENT; /* FileRemove func only care about files. */
173 }
174
175 if (unlink(fileName) != 0) {
176 HKS_LOG_E("remove file failed, errno = 0x%x", errno);
177 return HKS_ERROR_REMOVE_FILE_FAIL;
178 }
179
180 return HKS_SUCCESS;
181 }
182
HksIsDirExist(const char * path)183 int32_t HksIsDirExist(const char *path)
184 {
185 if (path == NULL) {
186 return HKS_ERROR_NULL_POINTER;
187 }
188 return IsFileExist(path);
189 }
190
HksMakeDir(const char * path)191 int32_t HksMakeDir(const char *path)
192 {
193 return mkdir(path, DEFAULT_FILE_PERMISSION);
194 }
195
HksOpenDir(const char * path)196 void *HksOpenDir(const char *path)
197 {
198 return (void *)opendir(path);
199 }
200
HksCloseDir(void * dirp)201 int32_t HksCloseDir(void *dirp)
202 {
203 return closedir((DIR *)dirp);
204 }
205
HksGetDirFile(void * dirp,struct HksFileDirentInfo * direntInfo)206 int32_t HksGetDirFile(void *dirp, struct HksFileDirentInfo *direntInfo)
207 {
208 DIR *dir = (DIR *)dirp;
209 struct dirent *dire = readdir(dir);
210
211 while (dire != NULL) {
212 if (dire->d_type != DT_REG) { /* only care about files. */
213 dire = readdir(dir);
214 continue;
215 }
216
217 uint32_t len = strlen(dire->d_name);
218 if (memcpy_s(direntInfo->fileName, sizeof(direntInfo->fileName) - 1, dire->d_name, len) != EOK) {
219 return HKS_ERROR_BAD_STATE;
220 }
221 direntInfo->fileName[len] = '\0';
222 return HKS_SUCCESS;
223 }
224
225 return HKS_ERROR_NOT_EXIST;
226 }
227
HksGetStoragePath(enum HksStoragePathType pathType,char * path,uint32_t * len)228 int32_t HksGetStoragePath(enum HksStoragePathType pathType, char *path, uint32_t *len)
229 {
230 if ((path == NULL) || (len == NULL) || (*len <= 1)) {
231 return HKS_ERROR_INVALID_ARGUMENT;
232 }
233 errno_t ret;
234 uint32_t pathLen;
235 if (pathType == HKS_STORAGE_MAIN_PATH) {
236 pathLen = strlen(HKS_KEY_STORE_PATH);
237 ret = memcpy_s(path, *len - 1, HKS_KEY_STORE_PATH, pathLen);
238 } else if (pathType == HKS_STORAGE_BACKUP_PATH) {
239 pathLen = strlen(HKS_KEY_STORE_BAK_PATH);
240 ret = memcpy_s(path, *len - 1, HKS_KEY_STORE_BAK_PATH, pathLen);
241 } else {
242 return HKS_ERROR_INVALID_ARGUMENT;
243 }
244 if (ret != EOK) {
245 HKS_LOG_E("memcpy failed");
246 return HKS_ERROR_BAD_STATE;
247 }
248 path[pathLen] = '\0';
249 *len = pathLen + 1;
250 return HKS_SUCCESS;
251 }
252
HksRemoveDir(const char * dirPath)253 int32_t HksRemoveDir(const char *dirPath)
254 {
255 struct stat fileStat;
256 int32_t ret = stat(dirPath, &fileStat);
257 if (ret != 0) {
258 HKS_LOG_E("file stat failed");
259 return HKS_FAILURE;
260 }
261
262 if (S_ISDIR(fileStat.st_mode) == false) {
263 HKS_LOG_E("path is not dir");
264 return HKS_FAILURE;
265 }
266
267 DIR *dir = opendir(dirPath);
268 if (dir == NULL) {
269 HKS_LOG_E("open dir failed");
270 return HKS_ERROR_OPEN_FILE_FAIL;
271 }
272
273 struct dirent *dire = readdir(dir);
274 while (dire != NULL) {
275 if (dire->d_type == DT_REG) { /* only care about files. */
276 ret = HksFileRemove(dirPath, dire->d_name);
277 if (ret != HKS_SUCCESS) { /* Continue to delete remaining files */
278 HKS_LOG_E("remove file failed when remove dir files, ret = %d.", ret);
279 }
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,uint8_t * buf,uint32_t len)298 static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
299 {
300 /* now offset is 0, but we maybe extend hi1131 file interfaces in the future */
301 if (offset != 0) {
302 return 0;
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%x", ret);
309 return 0;
310 }
311
312 if (len > fileSize) {
313 HKS_LOG_E("read data over file size!\n, file size = %d\n, buf len = %d\n", fileSize, len);
314 return 0;
315 }
316
317 int fd = UtilsFileOpen(fileName, O_RDONLY_FS, 0);
318 if (fd < 0) {
319 HKS_LOG_E("failed to open file, errno = 0x%x", fd);
320 return 0;
321 }
322
323 ret = UtilsFileRead(fd, (char *)buf, len);
324 UtilsFileClose(fd);
325 if (ret < 0) {
326 HKS_LOG_E("failed to read file, errno = 0x%x", ret);
327 return 0;
328 }
329
330 return len;
331 }
332
FileWrite(const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)333 static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
334 {
335 /* now offset is 0, but we may extend hi1131 file interfaces */
336 if (offset != 0) {
337 return HKS_ERROR_INVALID_ARGUMENT;
338 }
339
340 int fd = UtilsFileOpen(fileName, O_CREAT_FS | O_TRUNC_FS | O_RDWR_FS, 0);
341 if (fd < 0) {
342 HKS_LOG_E("failed to open key file, errno = 0x%x\n", fd);
343 return HKS_ERROR_OPEN_FILE_FAIL;
344 }
345
346 int32_t ret = UtilsFileWrite(fd, (const char*)buf, len);
347 (void)UtilsFileClose(fd);
348 if (ret < 0) {
349 HKS_LOG_E("failed to write key file, errno = 0x%x\n", ret);
350 return HKS_ERROR_WRITE_FILE_FAIL;
351 }
352
353 return HKS_SUCCESS;
354 }
355
FileSize(const char * fileName)356 static uint32_t FileSize(const char *fileName)
357 {
358 unsigned int fileSize;
359 int32_t ret = UtilsFileStat(fileName, &fileSize);
360 if (ret < 0) {
361 HKS_LOG_E("stat file failed, errno = 0x%x", ret);
362 return 0;
363 }
364 return fileSize;
365 }
366
FileRemove(const char * fileName)367 static int32_t FileRemove(const char *fileName)
368 {
369 int32_t ret = UtilsFileDelete(fileName);
370 if (ret < 0) {
371 HKS_LOG_E("remove file failed");
372 return HKS_ERROR_REMOVE_FILE_FAIL;
373 }
374 return HKS_SUCCESS;
375 }
376
377 #endif
378
HksFileRead(const char * path,const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)379 uint32_t HksFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
380 {
381 if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
382 return 0;
383 }
384
385 char *fullFileName = NULL;
386 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
387 if (ret != HKS_SUCCESS) {
388 return 0;
389 }
390
391 uint32_t size = FileRead(fullFileName, offset, buf, len);
392 HKS_FREE_PTR(fullFileName);
393 return size;
394 }
395
HksFileWrite(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)396 int32_t HksFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
397 {
398 if ((fileName == NULL) || (buf == NULL) || (len == 0)) {
399 return HKS_ERROR_INVALID_ARGUMENT;
400 }
401
402 char *fullFileName = NULL;
403 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
404 if (ret != HKS_SUCCESS) {
405 return ret;
406 }
407
408 ret = FileWrite(fullFileName, offset, buf, len);
409 HKS_FREE_PTR(fullFileName);
410 return ret;
411 }
412
HksFileSize(const char * path,const char * fileName)413 uint32_t HksFileSize(const char *path, const char *fileName)
414 {
415 if (fileName == NULL) {
416 return 0;
417 }
418
419 char *fullFileName = NULL;
420 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
421 if (ret != HKS_SUCCESS) {
422 return 0;
423 }
424
425 uint32_t size = FileSize(fullFileName);
426 HKS_FREE_PTR(fullFileName);
427 return size;
428 }
429
HksIsFileExist(const char * path,const char * fileName)430 int32_t HksIsFileExist(const char *path, const char *fileName)
431 {
432 if (fileName == NULL) {
433 return HKS_ERROR_NULL_POINTER;
434 }
435
436 char *fullFileName = NULL;
437 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
438 if (ret != HKS_SUCCESS) {
439 return ret;
440 }
441
442 ret = IsFileExist(fullFileName);
443 HKS_FREE_PTR(fullFileName);
444 return ret;
445 }
446
HksFileRemove(const char * path,const char * fileName)447 int32_t HksFileRemove(const char *path, const char *fileName)
448 {
449 if (fileName == NULL) {
450 return HKS_ERROR_INVALID_ARGUMENT;
451 }
452
453 char *fullFileName = NULL;
454 int32_t ret = GetFullFileName(path, fileName, &fullFileName);
455 if (ret != HKS_SUCCESS) {
456 return ret;
457 }
458
459 ret = FileRemove(fullFileName);
460 HKS_FREE_PTR(fullFileName);
461 return ret;
462 }
463
464 #ifdef HKS_SUPPORT_UPGRADE_STORAGE_DATA
465 /* return < 0 error; > 0 realFileSize; == 0 no data */
HksOldVersionFileRead(const char * fileName,uint32_t offset,uint8_t * buf,uint32_t len)466 int32_t HksOldVersionFileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
467 {
468 HKS_LOG_D("piling");
469 return HKS_ERROR_NOT_SUPPORTED;
470 }
471
HksOldVersionFileRemove(const char * fileName)472 int32_t HksOldVersionFileRemove(const char *fileName)
473 {
474 HKS_LOG_D("piling");
475 return HKS_ERROR_NOT_SUPPORTED;
476 }
477
478 /* return < 0 error; >= 0 realFileSize */
HksOldVersionFileSize(const char * fileName)479 int32_t HksOldVersionFileSize(const char *fileName)
480 {
481 HKS_LOG_D("piling");
482 return HKS_ERROR_NOT_SUPPORTED;
483 }
484
485 /* return true, exist; false not exist */
HksOldVersionIsFileExist(const char * fileName)486 bool HksOldVersionIsFileExist(const char *fileName)
487 {
488 HKS_LOG_D("piling");
489 return false;
490 }
491 #endif
492
HksGetFileName(const char * path,const char * fileName,char * fullFileName,uint32_t fullFileNameLen)493 int32_t HksGetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
494 {
495 return GetFileName(path, fileName, fullFileName, fullFileNameLen);
496 }
497
498 #endif /* _CUT_AUTHENTICATE_ */
499