1 /*
2  * Copyright (c) 2021-2024 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 #include "hks_type_enum.h"
17 #ifndef _CUT_AUTHENTICATE_
18 
19 #ifdef HKS_CONFIG_FILE
20 #include HKS_CONFIG_FILE
21 #else
22 #include "hks_config.h"
23 #endif
24 
25 #include "hks_storage.h"
26 
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <string.h>
31 
32 #include "hks_file_operator.h"
33 #include "hks_log.h"
34 #include "hks_mem.h"
35 #include "hks_storage_file_lock.h"
36 #include "hks_template.h"
37 #include "huks_access.h"
38 #include "securec.h"
39 #include "hks_storage_utils.h"
40 
41 #ifdef HKS_SUPPORT_THREAD
CreateStorageFileLock(const char * path,const char * fileName)42 static HksStorageFileLock *CreateStorageFileLock(const char *path, const char *fileName)
43 {
44     char *fullPath = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
45     HKS_IF_NULL_RETURN(fullPath, NULL)
46 
47     int32_t ret = HksGetFileName(path, fileName, fullPath, HKS_MAX_FILE_NAME_LEN);
48     if (ret != HKS_SUCCESS) {
49         HKS_LOG_E("get full path failed, ret = %" LOG_PUBLIC "d.", ret);
50         HKS_FREE(fullPath);
51         return NULL;
52     }
53 
54     HksStorageFileLock *lock = HksStorageFileLockCreate(fullPath);
55     HKS_FREE(fullPath);
56     return lock;
57 }
58 #endif
59 
HksStorageWriteFile(const char * path,const char * fileName,uint32_t offset,const uint8_t * buf,uint32_t len)60 int32_t HksStorageWriteFile(
61     const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
62 {
63 #ifdef HKS_SUPPORT_THREAD
64     HksStorageFileLock *lock = CreateStorageFileLock(path, fileName);
65     HksStorageFileLockWrite(lock);
66     int32_t ret = HksFileWrite(path, fileName, offset, buf, len);
67     HksStorageFileUnlockWrite(lock);
68     HksStorageFileLockRelease(lock);
69     return ret;
70 #else
71     return HksFileWrite(path, fileName, offset, buf, len);
72 #endif
73 }
74 
HksStorageReadFile(const char * path,const char * fileName,uint32_t offset,struct HksBlob * blob,uint32_t * size)75 static int32_t HksStorageReadFile(
76     const char *path, const char *fileName, uint32_t offset, struct HksBlob *blob, uint32_t *size)
77 {
78 #ifdef HKS_SUPPORT_THREAD
79     HksStorageFileLock *lock = CreateStorageFileLock(path, fileName);
80     HksStorageFileLockRead(lock);
81     int32_t ret = HksFileRead(path, fileName, offset, blob, size);
82     HksStorageFileUnlockRead(lock);
83     HksStorageFileLockRelease(lock);
84 #else
85     int32_t ret = HksFileRead(path, fileName, offset, blob, size);
86 #endif
87     return ret;
88 }
89 
90 #ifdef HKS_ENABLE_CLEAN_FILE
CleanFile(const char * path,const char * fileName)91 static int32_t CleanFile(const char *path, const char *fileName)
92 {
93     uint32_t size = HksFileSize(path, fileName);
94     if (size == 0 || size > HKS_MAX_FILE_SIZE) {
95         HKS_LOG_E("get file size failed, ret = %" LOG_PUBLIC "u.", size);
96         return HKS_ERROR_FILE_SIZE_FAIL;
97     }
98 
99     int32_t ret = HKS_SUCCESS;
100     uint8_t *buf;
101     do {
102         buf = (uint8_t *)HksMalloc(size);
103         if (buf == NULL) {
104             HKS_LOG_E("malloc buf failed!");
105             ret = HKS_ERROR_MALLOC_FAIL;
106             break;
107         }
108 
109         (void)memset_s(buf, size, 0, size);
110         ret = HksStorageWriteFile(path, fileName, 0, buf, size);
111         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file 0 failed!")
112 
113         (void)memset_s(buf, size, 1, size);
114         ret = HksStorageWriteFile(path, fileName, 0, buf, size);
115         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file 1 failed!")
116 
117         struct HksBlob bufBlob = { .size = size, .data = buf };
118         ret = HuksAccessGenerateRandom(NULL, &bufBlob);
119         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "fill buf random failed!")
120 
121         ret = HksStorageWriteFile(path, fileName, 0, buf, size);
122         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file random failed!")
123     } while (0);
124 
125     HKS_FREE(buf);
126 
127     return ret;
128 }
129 #endif
130 
HksStorageRemoveFile(const char * path,const char * fileName)131 static int32_t HksStorageRemoveFile(const char *path, const char *fileName)
132 {
133     int32_t ret;
134 #ifdef HKS_ENABLE_CLEAN_FILE
135     ret = CleanFile(path, fileName);
136     if (ret != HKS_SUCCESS) {
137         HKS_LOG_E("clean file failed!");
138     }
139 #endif
140 #ifdef HKS_SUPPORT_THREAD
141     HksStorageFileLock *lock = CreateStorageFileLock(path, fileName);
142     HksStorageFileLockWrite(lock);
143     ret = HksFileRemove(path, fileName);
144     HksStorageFileUnlockWrite(lock);
145     HksStorageFileLockRelease(lock);
146 #else
147     ret = HksFileRemove(path, fileName);
148 #endif
149     return ret;
150 }
151 
CopyKeyBlobFromSrc(const char * srcPath,const char * srcFileName,const char * destPath,const char * destFileName)152 static int32_t CopyKeyBlobFromSrc(const char *srcPath, const char *srcFileName,
153     const char *destPath, const char *destFileName)
154 {
155     uint32_t size = HksFileSize(srcPath, srcFileName);
156     if (size == 0) {
157         HKS_LOG_E("get file size failed, ret = %" LOG_PUBLIC "u.", size);
158         return HKS_ERROR_FILE_SIZE_FAIL;
159     }
160 
161     uint8_t *buffer = (uint8_t *)HksMalloc(size);
162     HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
163 
164     (void)memset_s(buffer, size, 0, size);
165 
166     struct HksBlob blob = { .size = size, .data = buffer };
167 
168     int32_t ret;
169     do {
170         ret = HksStorageReadFile(srcPath, srcFileName, 0, &blob, &size);
171         if (ret != HKS_SUCCESS) {
172             if (ret == HKS_ERROR_NO_PERMISSION) {
173                 HKS_LOG_E("Check Permission failed, ret = %" LOG_PUBLIC "d.", ret);
174                 break;
175             }
176             HKS_LOG_E("read file failed, ret = %" LOG_PUBLIC "d.", ret);
177             ret = HKS_ERROR_READ_FILE_FAIL;
178             break;
179         }
180 
181         ret = HksStorageWriteFile(destPath, destFileName, 0, buffer, size);
182         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "file write destPath failed, ret = %" LOG_PUBLIC "d.", ret)
183     } while (0);
184 
185     HKS_FREE(buffer);
186     return ret;
187 }
188 
GetKeyBlobFromFile(const char * path,const char * fileName,struct HksBlob * keyBlob)189 static int32_t GetKeyBlobFromFile(const char *path, const char *fileName, struct HksBlob *keyBlob)
190 {
191     uint32_t size = HksFileSize(path, fileName);
192     if (size == 0) {
193         return HKS_ERROR_FILE_SIZE_FAIL;
194     }
195 
196     if (keyBlob->size < size) {
197         return HKS_ERROR_INSUFFICIENT_DATA;
198     }
199 
200     int32_t ret = HksStorageReadFile(path, fileName, 0, keyBlob, &size);
201     if (ret != HKS_SUCCESS) {
202         if (ret == HKS_ERROR_NO_PERMISSION) {
203             HKS_LOG_E("Check Permission failed, ret = %" LOG_PUBLIC "d.", ret);
204             return ret;
205         }
206         HKS_LOG_E("read file failed, ret = %" LOG_PUBLIC "d.", ret);
207         return HKS_ERROR_READ_FILE_FAIL;
208     }
209     keyBlob->size = size;
210     return HKS_SUCCESS;
211 }
212 
DeleteKeyBlob(const struct HksStoreFileInfo * fileInfo)213 static int32_t DeleteKeyBlob(const struct HksStoreFileInfo *fileInfo)
214 {
215     int32_t isMainFileExist = HksIsFileExist(fileInfo->mainPath.path, fileInfo->mainPath.fileName);
216     int32_t ret = HKS_SUCCESS;
217 #ifdef SUPPORT_STORAGE_BACKUP
218     int32_t isBakFileExist = HksIsFileExist(fileInfo->bakPath.path, fileInfo->bakPath.fileName);
219     if ((isMainFileExist != HKS_SUCCESS) && (isBakFileExist != HKS_SUCCESS)) {
220         return HKS_ERROR_NOT_EXIST;
221     }
222 
223     if (isBakFileExist == HKS_SUCCESS) {
224         ret = HksStorageRemoveFile(fileInfo->bakPath.path, fileInfo->bakPath.fileName);
225         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "delete key remove bakfile failed, ret = %" LOG_PUBLIC "d.", ret)
226     }
227 #endif
228     if (isMainFileExist == HKS_SUCCESS) {
229         ret = HksStorageRemoveFile(fileInfo->mainPath.path, fileInfo->mainPath.fileName);
230         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "delete key remove file failed, ret = %" LOG_PUBLIC "d.", ret)
231     } else {
232         return HKS_ERROR_NOT_EXIST;
233     }
234 
235     return ret;
236 }
237 
GetKeyBlob(const struct HksStoreInfo * fileInfoPath,struct HksBlob * keyBlob)238 static int32_t GetKeyBlob(const struct HksStoreInfo *fileInfoPath, struct HksBlob *keyBlob)
239 {
240     int32_t isFileExist = HksIsFileExist(fileInfoPath->path, fileInfoPath->fileName);
241     HKS_IF_NOT_SUCC_RETURN(isFileExist, HKS_ERROR_NOT_EXIST)
242 
243     int32_t ret = GetKeyBlobFromFile(fileInfoPath->path, fileInfoPath->fileName, keyBlob);
244     return ret;
245 }
246 
GetKeyBlobSize(const struct HksStoreInfo * fileInfoPath,uint32_t * keyBlobSize)247 static int32_t GetKeyBlobSize(const struct HksStoreInfo *fileInfoPath, uint32_t *keyBlobSize)
248 {
249     int32_t isFileExist = HksIsFileExist(fileInfoPath->path, fileInfoPath->fileName);
250     HKS_IF_NOT_SUCC_RETURN(isFileExist, HKS_ERROR_NOT_EXIST)
251 
252     uint32_t size = HksFileSize(fileInfoPath->path, fileInfoPath->fileName);
253     if (size == 0) {
254         return HKS_ERROR_FILE_SIZE_FAIL;
255     }
256     *keyBlobSize = size;
257     return HKS_SUCCESS;
258 }
259 
IsKeyBlobExist(const struct HksStoreFileInfo * fileInfo)260 static int32_t IsKeyBlobExist(const struct HksStoreFileInfo *fileInfo)
261 {
262     int32_t isMainFileExist = HksIsFileExist(fileInfo->mainPath.path, fileInfo->mainPath.fileName);
263 #ifndef SUPPORT_STORAGE_BACKUP
264     HKS_IF_NOT_SUCC_RETURN(isMainFileExist, HKS_ERROR_NOT_EXIST)
265 #else
266     if (isMainFileExist != HKS_SUCCESS) {
267         int32_t isBakFileExist = HksIsFileExist(fileInfo->bakPath.path, fileInfo->bakPath.fileName);
268         HKS_IF_NOT_SUCC_LOGE_RETURN(isBakFileExist, HKS_ERROR_NOT_EXIST, "hks mainkey and backupkey not exist")
269 
270         if (CopyKeyBlobFromSrc(fileInfo->bakPath.path, fileInfo->bakPath.fileName,
271             fileInfo->mainPath.path, fileInfo->mainPath.fileName) != HKS_SUCCESS) {
272                 HKS_LOG_E("hks copy bak key to main key failed");
273             }
274     }
275 #endif
276     return HKS_SUCCESS;
277 }
278 
HksStoreKeyBlob(const struct HksStoreFileInfo * fileInfo,const struct HksBlob * keyBlob)279 int32_t HksStoreKeyBlob(const struct HksStoreFileInfo *fileInfo, const struct HksBlob *keyBlob)
280 {
281     int32_t ret;
282     do {
283         ret = RecordKeyOperation(KEY_OPERATION_SAVE, fileInfo->mainPath.path, fileInfo->mainPath.fileName);
284         HKS_IF_NOT_SUCC_BREAK(ret)
285 
286         ret = HksStorageWriteFile(fileInfo->mainPath.path, fileInfo->mainPath.fileName, 0,
287             keyBlob->data, keyBlob->size);
288         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "hks save main key blob failed, ret = %" LOG_PUBLIC "d.", ret)
289 
290 #ifdef SUPPORT_STORAGE_BACKUP
291         if (HksStorageWriteFile(fileInfo->bakPath.path, fileInfo->bakPath.fileName, 0,
292             keyBlob->data, keyBlob->size) != HKS_SUCCESS) {
293                 HKS_LOG_E("hks save backup key blob failed");
294             }
295 #endif
296     } while (0);
297 
298     return ret;
299 }
300 
HksStoreDeleteKeyBlob(const struct HksStoreFileInfo * fileInfo)301 int32_t HksStoreDeleteKeyBlob(const struct HksStoreFileInfo *fileInfo)
302 {
303     int32_t ret;
304     do {
305         ret = RecordKeyOperation(KEY_OPERATION_DELETE, fileInfo->mainPath.path, fileInfo->mainPath.fileName);
306         HKS_IF_NOT_SUCC_BREAK(ret)
307 
308         ret = DeleteKeyBlob(fileInfo);
309     } while (0);
310 
311     return ret;
312 }
313 
HksStoreIsKeyBlobExist(const struct HksStoreFileInfo * fileInfo)314 int32_t HksStoreIsKeyBlobExist(const struct HksStoreFileInfo *fileInfo)
315 {
316     int32_t ret;
317     do {
318         ret = IsKeyBlobExist(fileInfo);
319         HKS_IF_NOT_SUCC_LOGE(ret, "check is key exist, ret = %" LOG_PUBLIC "d.", ret)
320     } while (0);
321 
322     return ret;
323 }
324 
HksStoreGetKeyBlob(const struct HksStoreInfo * fileInfoPath,struct HksBlob * keyBlob)325 int32_t HksStoreGetKeyBlob(const struct HksStoreInfo *fileInfoPath, struct HksBlob *keyBlob)
326 {
327     int32_t ret;
328     do {
329         ret = RecordKeyOperation(KEY_OPERATION_GET, fileInfoPath->path, fileInfoPath->fileName);
330         HKS_IF_NOT_SUCC_BREAK(ret)
331 
332         ret = GetKeyBlob(fileInfoPath, keyBlob);
333         HKS_IF_NOT_SUCC_LOGE(ret, "hks get keyblob failed, ret = %" LOG_PUBLIC "d.", ret)
334     } while (0);
335 
336     return ret;
337 }
338 
HksStoreGetKeyBlobSize(const struct HksStoreInfo * fileInfoPath,uint32_t * keyBlobSize)339 int32_t HksStoreGetKeyBlobSize(const struct HksStoreInfo *fileInfoPath, uint32_t *keyBlobSize)
340 {
341     int32_t ret;
342     do {
343         ret = GetKeyBlobSize(fileInfoPath, keyBlobSize);
344         HKS_IF_NOT_SUCC_LOGE(ret, "hks get keyblob size failed, ret = %" LOG_PUBLIC "d.", ret)
345     } while (0);
346 
347     return ret;
348 }
349 
GetFileCount(const char * path,uint32_t * fileCount)350 static int32_t GetFileCount(const char *path, uint32_t *fileCount)
351 {
352     if ((path == NULL) || (fileCount == NULL)) {
353         return HKS_ERROR_NULL_POINTER;
354     }
355 
356     void *dir = HksOpenDir(path);
357     if (dir == NULL) {
358         HKS_LOG_W("can't open directory");
359         *fileCount = 0;
360         return HKS_SUCCESS;
361     }
362 
363     uint32_t count = 0;
364     struct HksFileDirentInfo dire = {{0}};
365     int32_t ret = HksGetDirFile(dir, &dire);
366     while (ret == HKS_SUCCESS) {
367         count++;
368         ret = HksGetDirFile(dir, &dire);
369     }
370     (void)HksCloseDir(dir);
371     *fileCount = count;
372 
373     return HKS_SUCCESS;
374 }
375 
GetFileNameList(const char * path,struct HksFileEntry * fileNameList,uint32_t * fileCount)376 static int32_t GetFileNameList(const char *path, struct HksFileEntry *fileNameList, uint32_t *fileCount)
377 {
378     if ((path == NULL) || (fileCount == NULL) || (fileNameList == NULL)) {
379         return HKS_ERROR_NULL_POINTER;
380     }
381 
382     void *dir = HksOpenDir(path);
383     if (dir == NULL) {
384         HKS_LOG_W("can't open directory");
385         *fileCount = 0;
386         return HKS_SUCCESS;
387     }
388 
389     struct HksFileDirentInfo dire = {{0}};
390     int32_t ret = HksGetDirFile(dir, &dire);
391     uint32_t count = 0;
392     while (ret == HKS_SUCCESS) {
393         count++;
394         uint32_t nameLen = strlen(dire.fileName);
395         if ((*fileCount < count) || (fileNameList[count - 1].fileNameLen < (nameLen + 1))) {
396             HKS_LOG_E("the input params are wrong and too small");
397             break;
398         }
399 
400         if (strncpy_s(fileNameList[count - 1].fileName, fileNameList[count - 1].fileNameLen,
401             dire.fileName, nameLen) != EOK) {
402             HKS_LOG_E("failed to copy the string");
403             break;
404         }
405         fileNameList[count - 1].fileName[nameLen] = '\0';
406         ret = HksGetDirFile(dir, &dire);
407     }
408     (void)HksCloseDir(dir);
409     *fileCount = count;
410 
411     return HKS_SUCCESS;
412 }
413 
GetAndCheckFileCount(const char * path,uint32_t * fileCount,const uint32_t * inputCount)414 static int32_t GetAndCheckFileCount(const char *path, uint32_t *fileCount, const uint32_t *inputCount)
415 {
416     int32_t ret = GetFileCount(path, fileCount);
417     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get storage file count, ret = %" LOG_PUBLIC "d.", ret)
418 
419     if (*inputCount < *fileCount) {
420         HKS_LOG_E("listCount space not enough");
421         ret = HKS_ERROR_BUFFER_TOO_SMALL;
422     }
423 
424     return ret;
425 }
426 
GetKeyAliasByProcessName(const struct HksStoreFileInfo * fileInfo,struct HksKeyInfo * keyInfoList,uint32_t * listCount)427 static int32_t GetKeyAliasByProcessName(const struct HksStoreFileInfo *fileInfo, struct HksKeyInfo *keyInfoList,
428     uint32_t *listCount)
429 {
430     uint32_t fileCount;
431     int32_t ret = GetAndCheckFileCount(fileInfo->mainPath.path, &fileCount, listCount);
432     HKS_IF_NOT_SUCC_RETURN(ret, ret)
433 
434     if (fileCount == 0) {
435         *listCount = 0;
436         return HKS_SUCCESS;
437     }
438 
439     struct HksFileEntry *fileNameList = NULL;
440     ret = FileNameListInit(&fileNameList, fileCount);
441     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init file name list failed.")
442 
443     uint32_t realFileCount = fileCount;
444     do {
445         ret = GetFileNameList(fileInfo->mainPath.path, fileNameList, &realFileCount);
446         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get file name list failed, ret = %" LOG_PUBLIC "d", ret)
447 
448         for (uint32_t i = 0; i < realFileCount; ++i) {
449             ret = ConstructBlob(fileNameList[i].fileName, &(keyInfoList[i].alias));
450             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "construct blob failed, ret = %" LOG_PUBLIC "d", ret)
451         }
452     } while (0);
453 
454     FileNameListFree(&fileNameList, fileCount);
455     HKS_IF_NOT_SUCC_RETURN(ret, ret)
456 
457     *listCount = realFileCount;
458     return ret;
459 }
460 
HksGetKeyAliasByProcessName(const struct HksStoreFileInfo * fileInfo,struct HksKeyInfo * keyInfoList,uint32_t * listCount)461 int32_t HksGetKeyAliasByProcessName(const struct HksStoreFileInfo *fileInfo, struct HksKeyInfo *keyInfoList,
462     uint32_t *listCount)
463 {
464     int32_t ret;
465     do {
466         ret = GetKeyAliasByProcessName(fileInfo, keyInfoList, listCount);
467         HKS_IF_NOT_SUCC_LOGE(ret, "get key alias by processName failed, ret = %" LOG_PUBLIC "d.", ret)
468     } while (0);
469 
470     return ret;
471 }
472 
HksGetKeyCountByProcessName(const struct HksStoreFileInfo * fileInfo,uint32_t * fileCount)473 int32_t HksGetKeyCountByProcessName(const struct HksStoreFileInfo *fileInfo, uint32_t *fileCount)
474 {
475     int32_t ret;
476     do {
477         ret = GetFileCount(fileInfo->mainPath.path, fileCount);
478         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get storage file count failed, ret = %" LOG_PUBLIC "d.", ret)
479     } while (0);
480 
481     return ret;
482 }
483 
DestroyType(const char * storePath,const char * typePath,uint32_t bakFlag)484 static int32_t DestroyType(const char *storePath, const char *typePath, uint32_t bakFlag)
485 {
486     char *destroyPath = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
487     HKS_IF_NULL_RETURN(destroyPath, HKS_ERROR_MALLOC_FAIL)
488 
489     (void)memset_s(destroyPath, HKS_MAX_FILE_NAME_LEN, 0, HKS_MAX_FILE_NAME_LEN);
490 
491     int32_t ret = GetPath(storePath, typePath, destroyPath, HKS_MAX_FILE_NAME_LEN, bakFlag);
492     if (ret != HKS_SUCCESS) {
493         HKS_LOG_E("Get Path failed! ret = 0x%" LOG_PUBLIC "X", ret);
494         HKS_FREE(destroyPath);
495         return ret;
496     }
497 
498     ret = HksIsDirExist(destroyPath);
499     if (ret != HKS_SUCCESS) {
500         HKS_FREE(destroyPath);
501         return HKS_SUCCESS;
502     }
503 
504     ret = HksRemoveDir(destroyPath);
505     HKS_IF_NOT_SUCC_LOGE(ret, "Destroy dir failed! ret = 0x%" LOG_PUBLIC "X", ret)
506 
507     HKS_FREE(destroyPath);
508     return ret;
509 }
510 
StoreDestroy(const char * processNameEncoded,uint32_t bakFlag)511 static int32_t StoreDestroy(const char *processNameEncoded, uint32_t bakFlag)
512 {
513     char *rootPath = NULL;
514     if (bakFlag == HKS_STORAGE_BAK_FLAG_TRUE) {
515         rootPath = HKS_KEY_STORE_BAK_PATH;
516     } else {
517         rootPath = HKS_KEY_STORE_PATH;
518     }
519 
520     char *storePath = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
521     HKS_IF_NULL_RETURN(storePath, HKS_ERROR_MALLOC_FAIL)
522 
523     int32_t ret = GetPath(rootPath, processNameEncoded, storePath, HKS_MAX_FILE_NAME_LEN, bakFlag);
524     if (ret != HKS_SUCCESS) {
525         HKS_LOG_E("Get Path failed! ret = 0x%" LOG_PUBLIC "X", ret);
526         HKS_FREE(storePath);
527         return ret;
528     }
529 
530     ret = DestroyType(storePath, HKS_KEY_STORE_ROOT_KEY_PATH, bakFlag);
531     if (ret != HKS_SUCCESS) {
532         HKS_LOG_I("Destroy info dir failed! ret = 0x%" LOG_PUBLIC "X", ret); /* continue delete */
533     }
534 
535     ret = DestroyType(storePath, HKS_KEY_STORE_KEY_PATH, bakFlag);
536     if (ret != HKS_SUCCESS) {
537         HKS_LOG_I("Destroy key dir failed! ret = 0x%" LOG_PUBLIC "X", ret); /* continue delete */
538     }
539 
540     HKS_FREE(storePath);
541     return HKS_SUCCESS;
542 }
543 
HksStoreDestroy(const struct HksBlob * processName)544 int32_t HksStoreDestroy(const struct HksBlob *processName)
545 {
546     char *name = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
547     HKS_IF_NULL_RETURN(name, HKS_ERROR_MALLOC_FAIL)
548 
549     int32_t ret;
550     do {
551         ret = ConstructName(processName, name, HKS_MAX_FILE_NAME_LEN);
552         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Construct process name failed! ret = 0x%" LOG_PUBLIC "X.", ret)
553 
554         ret = StoreDestroy(name, HKS_STORAGE_BAK_FLAG_FLASE);
555         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Hks destroy dir failed! ret = 0x%" LOG_PUBLIC "X.", ret)
556 
557 #ifdef SUPPORT_STORAGE_BACKUP
558         ret = StoreDestroy(name, HKS_STORAGE_BAK_FLAG_TRUE);
559         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Hks destroy back dir failed! ret = 0x%" LOG_PUBLIC "X.", ret)
560 #endif
561     } while (0);
562 
563     HKS_FREE(name);
564     return ret;
565 }
566 
567 #ifdef HKS_ENABLE_SMALL_TO_SERVICE
HksIsOldKeyPathCleared(uint32_t * keyCount)568 int32_t HksIsOldKeyPathCleared(uint32_t *keyCount)
569 {
570     return GetFileCount(HKS_KEY_STORE_PATH "/hks_client/key", keyCount);
571 }
572 #endif
573 
574 #ifdef HKS_ENABLE_EVENT_DELETE
575 #ifdef L2_STANDARD
DeleteUserIdMainPathAndBakPath(const char * userData,const char * deDataPath,const char * ceOrEceDataPath)576 static void DeleteUserIdMainPathAndBakPath(const char *userData, const char *deDataPath, const char *ceOrEceDataPath)
577 {
578     char dePath[HKS_MAX_DIRENT_FILE_LEN] = "";
579     int32_t offset = sprintf_s(dePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s",
580         deDataPath, userData);
581     if (offset > 0) {
582         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", dePath);
583         (void)HksDeleteDir(dePath);
584     } else {
585         HKS_LOG_E("get de path failed");
586     }
587 
588     char cePath[HKS_MAX_DIRENT_FILE_LEN] = "";
589     offset = sprintf_s(cePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s",
590         HKS_CE_ROOT_PATH, userData, ceOrEceDataPath);
591     if (offset > 0) {
592         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", cePath);
593         (void)HksDeleteDir(cePath);
594     } else {
595         HKS_LOG_E("get ce path failed");
596     }
597 
598     char ecePath[HKS_MAX_DIRENT_FILE_LEN] = "";
599     offset = sprintf_s(ecePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s",
600         HKS_ECE_ROOT_PATH, userData, ceOrEceDataPath);
601     if (offset > 0) {
602         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", ecePath);
603         (void)HksDeleteDir(ecePath);
604     } else {
605         HKS_LOG_E("get ece path failed");
606     }
607 }
608 
DeleteUserIdPath(const struct HksBlob * userId)609 static void DeleteUserIdPath(const struct HksBlob *userId)
610 {
611     int32_t ret;
612     char *userData = NULL;
613     do {
614         userData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
615         HKS_IF_NULL_LOGE_BREAK(userData, "malloc user data failed")
616 
617         ret = ConstructPlainName(userId, userData, HKS_MAX_FILE_NAME_LEN);
618         HKS_IF_NOT_SUCC_BREAK(ret, "construct user id name failed, ret = %" LOG_PUBLIC "d", ret)
619 
620         (void)DeleteUserIdMainPathAndBakPath(userData, HKS_KEY_STORE_PATH, HKS_STORE_SERVICE_PATH);
621 #ifdef SUPPORT_STORAGE_BACKUP
622         (void)DeleteUserIdMainPathAndBakPath(userData, HKS_KEY_STORE_BAK_PATH, HKS_STORE_SERVICE_BAK_PATH);
623 #endif
624     } while (0);
625     HKS_FREE(userData);
626     return;
627 }
628 
DeleteUidMainPathAndBakPath(const char * userData,const char * uidData,const char * deDataPath,const char * ceOrEceDataPath)629 static void DeleteUidMainPathAndBakPath(const char *userData, const char *uidData,
630     const char *deDataPath, const char *ceOrEceDataPath)
631 {
632     char dePath[HKS_MAX_DIRENT_FILE_LEN] = "";
633     int32_t offset = sprintf_s(dePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s",
634         deDataPath, userData, uidData);
635     if (offset > 0) {
636         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", dePath);
637         (void)HksDeleteDir(dePath);
638     } else {
639         HKS_LOG_E("get de path failed");
640     }
641 
642     char cePath[HKS_MAX_DIRENT_FILE_LEN] = "";
643     offset = sprintf_s(cePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s/%s",
644         HKS_CE_ROOT_PATH, userData, ceOrEceDataPath, uidData);
645     if (offset > 0) {
646         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", cePath);
647         (void)HksDeleteDir(cePath);
648     } else {
649         HKS_LOG_E("get ce path failed");
650     }
651 
652     char ecePath[HKS_MAX_DIRENT_FILE_LEN] = "";
653     offset = sprintf_s(ecePath, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s/%s",
654         HKS_ECE_ROOT_PATH, userData, ceOrEceDataPath, uidData);
655     if (offset > 0) {
656         HKS_LOG_I("delete path: %" LOG_PUBLIC "s", ecePath);
657         (void)HksDeleteDir(ecePath);
658     } else {
659         HKS_LOG_E("get ece path failed");
660     }
661 }
662 
DeleteUidPath(const struct HksProcessInfo * processInfo)663 static void DeleteUidPath(const struct HksProcessInfo *processInfo)
664 {
665     int32_t ret;
666     char *userData = NULL;
667     char *uidData = NULL;
668     do {
669         userData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
670         HKS_IF_NULL_LOGE_BREAK(userData, "malloc user data failed")
671 
672         uidData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
673         HKS_IF_NULL_LOGE_BREAK(uidData, "malloc uid data failed")
674 
675         ret = ConstructPlainName(&processInfo->userId, userData, HKS_MAX_FILE_NAME_LEN);
676         HKS_IF_NOT_SUCC_BREAK(ret, "construct user id name failed, ret = %" LOG_PUBLIC "d", ret)
677 
678         ret = ConstructPlainName(&processInfo->processName, uidData, HKS_MAX_FILE_NAME_LEN);
679         HKS_IF_NOT_SUCC_BREAK(ret, "construct uid name failed, ret = %" LOG_PUBLIC "d", ret)
680 
681         (void)DeleteUidMainPathAndBakPath(userData, uidData, HKS_KEY_STORE_PATH, HKS_STORE_SERVICE_PATH);
682 #ifdef SUPPORT_STORAGE_BACKUP
683         (void)DeleteUidMainPathAndBakPath(userData, uidData, HKS_KEY_STORE_BAK_PATH, HKS_STORE_SERVICE_BAK_PATH);
684 #endif
685     } while (0);
686     HKS_FREE(userData);
687     HKS_FREE(uidData);
688     return;
689 }
690 #endif
691 
HksServiceDeleteUserIDKeyAliasFile(const struct HksBlob * userId)692 void HksServiceDeleteUserIDKeyAliasFile(const struct HksBlob *userId)
693 {
694     char *userData = NULL;
695     int32_t ret;
696     do {
697         userData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
698         HKS_IF_NULL_LOGE_BREAK(userData, "malloc user data failed")
699 
700         // construct non-plain name for de path
701         ret = ConstructName(userId, userData, HKS_MAX_FILE_NAME_LEN);
702         HKS_IF_NOT_SUCC_BREAK(ret, "construct user id name failed, ret = %" LOG_PUBLIC "d", ret)
703 
704         char userProcess[HKS_MAX_DIRENT_FILE_LEN] = "";
705         int32_t offset = sprintf_s(userProcess, HKS_MAX_DIRENT_FILE_LEN, "%s/%s", HKS_KEY_STORE_PATH, userData);
706         if (offset < 0) {
707             HKS_LOG_E("concatenate UserIdPath failed.");
708             ret = HKS_ERROR_BUFFER_TOO_SMALL;
709             break;
710         }
711 
712         // ignore these results for ensure to clear data as most as possible
713         ret = HksDeleteDir(userProcess);
714         HKS_IF_NOT_SUCC_LOGE(ret, "delete de path: %" LOG_PUBLIC "s failed, ret = %" LOG_PUBLIC "d", userProcess, ret)
715 #ifdef L2_STANDARD
716         (void)DeleteUserIdPath(userId);
717 #endif
718     } while (0);
719     HKS_FREE(userData);
720 }
721 
HksServiceDeleteUIDKeyAliasFile(const struct HksProcessInfo * processInfo)722 void HksServiceDeleteUIDKeyAliasFile(const struct HksProcessInfo *processInfo)
723 {
724     char *userData = NULL;
725     char *uidData = NULL;
726     int32_t ret;
727     do {
728         userData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
729         HKS_IF_NULL_LOGE_BREAK(userData, "malloc user data failed")
730 
731         // construct non-plain name for de path, and skip user path for user 0
732         if (processInfo->userIdInt != 0) {
733             ret = ConstructName(&processInfo->userId, userData, HKS_MAX_FILE_NAME_LEN);
734             HKS_IF_NOT_SUCC_BREAK(ret, "construct user id name failed, ret = %" LOG_PUBLIC "d", ret)
735         }
736 
737         uidData = (char *)HksMalloc(HKS_MAX_FILE_NAME_LEN);
738         if (uidData == NULL) {
739             HKS_LOG_E("malloc user data failed");
740             ret = HKS_ERROR_MALLOC_FAIL;
741             break;
742         }
743 
744         ret = ConstructName(&processInfo->processName, uidData, HKS_MAX_FILE_NAME_LEN);
745         HKS_IF_NOT_SUCC_BREAK(ret, "construct uid name failed, ret = %" LOG_PUBLIC "d", ret)
746 
747         char userProcess[HKS_MAX_DIRENT_FILE_LEN] = "";
748         int32_t offset = sprintf_s(userProcess, HKS_MAX_DIRENT_FILE_LEN, "%s/%s/%s",
749             HKS_KEY_STORE_PATH, userData, uidData);
750         if (offset < 0) {
751             HKS_LOG_E("concatenate uidPath failed.");
752             ret = HKS_ERROR_BUFFER_TOO_SMALL;
753             break;
754         }
755 
756         HKS_LOG_I("delete path : %" LOG_PUBLIC "s", userProcess);
757 
758         // ignore these results for ensure to clear data as most as possible
759         ret = HksDeleteDir(userProcess);
760         HKS_IF_NOT_SUCC_LOGE(ret, "delete de path: %" LOG_PUBLIC "s failed, ret = %" LOG_PUBLIC "d", userProcess, ret)
761 #ifdef L2_STANDARD
762         (void)DeleteUidPath(processInfo);
763 #endif
764     } while (0);
765     HKS_FREE(userData);
766     HKS_FREE(uidData);
767 }
768 
GetHksKeyAliasSet(const struct HksFileEntry * fileNameList,const uint32_t fileCount,struct HksKeyAliasSet ** outData)769 static int32_t GetHksKeyAliasSet(const struct HksFileEntry *fileNameList, const uint32_t fileCount,
770     struct HksKeyAliasSet **outData)
771 {
772     if (fileCount == 0) {
773         return HKS_SUCCESS;
774     }
775 
776     int32_t ret;
777     struct HksKeyAliasSet *tempAliasSet = (struct HksKeyAliasSet *)(HksMalloc(sizeof(struct HksKeyAliasSet)));
778     HKS_IF_NULL_LOGE_RETURN(tempAliasSet, HKS_ERROR_MALLOC_FAIL, "malloc key alias set failed")
779     tempAliasSet->aliasesCnt = fileCount;
780 
781     do {
782         tempAliasSet->aliases = (struct HksBlob *)HksMalloc(fileCount * sizeof(struct HksBlob));
783         if (tempAliasSet->aliases == NULL) {
784             HKS_LOG_E("malloc aliases fail");
785             ret = HKS_ERROR_MALLOC_FAIL;
786             break;
787         }
788 
789         for (uint32_t i = 0; i < fileCount; i++) {
790             uint32_t size = strlen(fileNameList[i].fileName);
791             tempAliasSet->aliases[i].size = size;
792             tempAliasSet->aliases[i].data = (uint8_t *)HksMalloc(size);
793             if (tempAliasSet->aliases[i].data == NULL) {
794                 HKS_LOG_E("malloc alias %" LOG_PUBLIC "d fail", i);
795                 ret = HKS_ERROR_MALLOC_FAIL;
796                 break;
797             }
798 
799             ret = ConstructBlob(fileNameList[i].fileName, &(tempAliasSet->aliases[i]));
800             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "construct blob failed, ret = %" LOG_PUBLIC "d", ret)
801         }
802     } while (0);
803 
804     if (ret != HKS_SUCCESS) {
805         HksFreeKeyAliasSet(tempAliasSet);
806         return ret;
807     }
808 
809     *outData = tempAliasSet;
810     return ret;
811 }
812 
GetHksFileEntry(const struct HksStoreFileInfo * fileInfo,struct HksFileEntry ** fileNameList,uint32_t * fileCnt)813 static int32_t GetHksFileEntry(const struct HksStoreFileInfo *fileInfo, struct HksFileEntry **fileNameList,
814     uint32_t *fileCnt)
815 {
816     uint32_t fileCount;
817     int32_t ret = GetFileCount(fileInfo->mainPath.path, &fileCount);
818     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get storage file count, ret = %" LOG_PUBLIC "d.", ret)
819     if (fileCount == 0) {
820         return HKS_SUCCESS;
821     }
822     if (fileCount > HKS_MAX_KEY_ALIAS_COUNT) {
823         HKS_LOG_E("file count too long, count = %" LOG_PUBLIC "u.", fileCount);
824         return HKS_ERROR_BUFFER_TOO_SMALL;
825     }
826 
827     struct HksFileEntry *tempFileNameList = NULL;
828     uint32_t realfileCount = fileCount;
829     do {
830         ret = FileNameListInit(&tempFileNameList, fileCount);
831         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "init file name list failed, ret = %" LOG_PUBLIC "d", ret)
832         ret = GetFileNameList(fileInfo->mainPath.path, tempFileNameList, &realfileCount);
833         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get file name list failed, ret = %" LOG_PUBLIC "d", ret)
834     } while (0);
835 
836     // case: do GetFileNameList, maybe realfileCount < fileCount
837     if (ret != HKS_SUCCESS || realfileCount < fileCount) {
838         FileNameListFree(&tempFileNameList, fileCount);
839         return ret;
840     }
841 
842     *fileCnt = fileCount;
843     *fileNameList = tempFileNameList;
844     return ret;
845 }
846 
HksListAliasesByProcessName(const struct HksStoreFileInfo * fileInfo,struct HksKeyAliasSet ** outData)847 int32_t HksListAliasesByProcessName(const struct HksStoreFileInfo *fileInfo, struct HksKeyAliasSet **outData)
848 {
849     int32_t ret;
850     struct HksFileEntry *fileNameList = NULL;
851     uint32_t fileCnt;
852     do {
853         ret = GetHksFileEntry(fileInfo, &fileNameList, &fileCnt);
854         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get file entry failed, ret = %" LOG_PUBLIC "d.", ret)
855 
856         // case success and has data
857         if (fileNameList != NULL) {
858             ret = GetHksKeyAliasSet(fileNameList, fileCnt, outData);
859             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get key alias set failed, ret = %" LOG_PUBLIC "d.", ret)
860         }
861     } while (0);
862 
863     if (fileNameList != NULL) {
864         FileNameListFree(&fileNameList, fileCnt);
865     }
866     return ret;
867 }
868 
869 #endif
870 
HksStoreRenameKeyAlias(const struct HksStoreFileInfo * oldFileInfo,const struct HksStoreFileInfo * newFileInfo,bool isCopy)871 int32_t HksStoreRenameKeyAlias(const struct HksStoreFileInfo *oldFileInfo,
872     const struct HksStoreFileInfo *newFileInfo, bool isCopy)
873 {
874     int32_t ret;
875     do {
876         ret = CopyKeyBlobFromSrc(oldFileInfo->mainPath.path, oldFileInfo->mainPath.fileName,
877             newFileInfo->mainPath.path, newFileInfo->mainPath.fileName);
878         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "hks copy old key blob failed, ret = %" LOG_PUBLIC "d.", ret)
879 #ifdef SUPPORT_STORAGE_BACKUP
880         ret = CopyKeyBlobFromSrc(oldFileInfo->bakPath.path, oldFileInfo->bakPath.fileName,
881             newFileInfo->bakPath.path, newFileInfo->bakPath.fileName);
882         if (ret != HKS_SUCCESS) {
883             HKS_LOG_I("Copy the old backup key failed, try to copy the new main key");
884             ret = CopyKeyBlobFromSrc(newFileInfo->mainPath.path, newFileInfo->mainPath.fileName,
885                 newFileInfo->bakPath.path, newFileInfo->bakPath.fileName);
886             if (ret != HKS_SUCCESS) {
887                 HKS_LOG_E("rename back key failed, try to delet the new main key. ret = %" LOG_PUBLIC "d.", ret);
888                 ret = HksStoreDeleteKeyBlob(newFileInfo);
889                 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "delet the new key failed, ret = %" LOG_PUBLIC "d.", ret)
890                 ret = HKS_ERROR_CORRUPT_FILE;
891                 break;
892             }
893         }
894 #endif
895         if (!isCopy) {
896             ret = HksStoreDeleteKeyBlob(oldFileInfo);
897             if (ret != HKS_SUCCESS) {
898                 HKS_LOG_I("Delete the old key failed, need to delete the new key");
899                 ret = HksStoreDeleteKeyBlob(newFileInfo);
900                 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "hks delete new key blob failed, ret = %" LOG_PUBLIC "d.", ret)
901                 ret = HKS_ERROR_REMOVE_FILE_FAIL;
902             }
903         }
904     } while (0);
905     return ret;
906 }
907 
908 #endif /* _CUT_AUTHENTICATE_ */
909