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