1 /*
2  * Copyright (c) 2020-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 #ifndef _CUT_AUTHENTICATE_
17 
18 #ifdef _STORAGE_LITE_
19 
20 #include "hks_storage.h"
21 
22 #include "hks_file_operator.h"
23 #include "hks_log.h"
24 #include "hks_mem.h"
25 #include "hks_param.h"
26 #include "hks_storage_adapter.h"
27 #include "hks_template.h"
28 
29 #include "huks_access.h"
30 
31 #define HKS_FILE_OFFSET_BASE 0
32 #define MAX_STORAGE_SIZE 5120
33 #define MAX_BUF_SIZE 65536
34 #define BUF_SIZE_ADDEND_PER_TIME 1024
35 #define HKS_STORAGE_VERSION 1
36 #define HKS_STORAGE_RESERVED_SEALING_ALG 0xFEDCBA98
37 
38 struct HksBlob g_storageImageBuffer = { 0, NULL };
39 
HksGetStoreFileOffset(void)40 static uint32_t HksGetStoreFileOffset(void)
41 {
42     return HKS_FILE_OFFSET_BASE;
43 }
44 
ConstructCalcMacParamSet(struct HksParamSet ** paramSet)45 static int32_t ConstructCalcMacParamSet(struct HksParamSet **paramSet)
46 {
47     struct HksParamSet *outputParamSet = NULL;
48     int32_t ret = HksInitParamSet(&outputParamSet);
49     HKS_IF_NOT_SUCC_RETURN(ret, ret)
50 
51     do {
52         struct HksParam digestParam = {
53             .tag = HKS_TAG_DIGEST,
54             .uint32Param = HKS_DIGEST_SHA512
55         };
56 
57         ret = HksAddParams(outputParamSet, &digestParam, 1); /* 1: param count */
58         HKS_IF_NOT_SUCC_BREAK(ret)
59 
60         ret = HksBuildParamSet(&outputParamSet);
61     } while (0);
62 
63     if (ret != HKS_SUCCESS) {
64         HksFreeParamSet(&outputParamSet);
65         return ret;
66     }
67 
68     *paramSet = outputParamSet;
69     return ret;
70 }
71 
CalcHeaderMac(const struct HksBlob * salt,const uint8_t * buf,const uint32_t srcSize,struct HksBlob * mac)72 static int32_t CalcHeaderMac(const struct HksBlob *salt, const uint8_t *buf,
73     const uint32_t srcSize, struct HksBlob *mac)
74 {
75     if (srcSize == 0) {
76         return HKS_ERROR_INVALID_ARGUMENT;
77     }
78 
79     struct HksBlob srcData = { srcSize, NULL };
80     srcData.data = (uint8_t *)HksMalloc(srcData.size);
81     HKS_IF_NULL_RETURN(srcData.data, HKS_ERROR_MALLOC_FAIL)
82 
83     int32_t ret;
84     struct HksParamSet *paramSet = NULL;
85     do {
86         if (memcpy_s(srcData.data, srcData.size, buf, srcSize) != EOK) {
87             ret = HKS_ERROR_INSUFFICIENT_MEMORY;
88             break;
89         }
90 
91         ret = ConstructCalcMacParamSet(&paramSet);
92         HKS_IF_NOT_SUCC_BREAK(ret)
93 
94         ret = HuksAccessCalcHeaderMac(paramSet, salt, &srcData, mac);
95         HKS_IF_NOT_SUCC_LOGE(ret, "access calc header mac failed, ret = %" LOG_PUBLIC "d.", ret)
96     } while (0);
97 
98     HKS_FREE_BLOB(srcData);
99     HksFreeParamSet(&paramSet);
100     return ret;
101 }
102 
InitImageBuffer(void)103 static int32_t InitImageBuffer(void)
104 {
105     /* caller func ensure g_storageImageBuffer.size is larger than sizeof(*keyInfoHead) */
106     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
107     keyInfoHead->version = HKS_STORAGE_VERSION;
108     keyInfoHead->keyCount = 0;
109     keyInfoHead->totalLen = sizeof(*keyInfoHead);
110     keyInfoHead->sealingAlg = HKS_STORAGE_RESERVED_SEALING_ALG;
111 
112     struct HksBlob salt = { HKS_DERIVE_DEFAULT_SALT_LEN, keyInfoHead->salt };
113     int32_t ret = HuksAccessGenerateRandom(NULL, &salt);
114     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "generate random failed, ret = %" LOG_PUBLIC "d", ret)
115 
116     struct HksBlob mac = { HKS_HMAC_DIGEST_SHA512_LEN, keyInfoHead->hmac };
117     uint16_t size = sizeof(*keyInfoHead) - HKS_HMAC_DIGEST_SHA512_LEN;
118 
119     return CalcHeaderMac(&salt, g_storageImageBuffer.data, size, &mac);
120 }
121 
CleanImageBuffer(void)122 static void CleanImageBuffer(void)
123 {
124     if (g_storageImageBuffer.data == NULL) {
125         return;
126     }
127     (void)memset_s(g_storageImageBuffer.data, g_storageImageBuffer.size, 0, g_storageImageBuffer.size);
128 }
129 
ApplyImageBuffer(uint32_t size)130 static int32_t ApplyImageBuffer(uint32_t size)
131 {
132     if (g_storageImageBuffer.data != NULL) {
133         return HKS_SUCCESS;
134     }
135 
136     if ((size == 0) || (size > MAX_BUF_SIZE)) {
137         HKS_LOG_E("invalid size = %" LOG_PUBLIC "u", size);
138         return HKS_ERROR_INVALID_ARGUMENT;
139     }
140 
141     g_storageImageBuffer.data = (uint8_t *)HksMalloc(size);
142     HKS_IF_NULL_RETURN(g_storageImageBuffer.data, HKS_ERROR_MALLOC_FAIL)
143 
144     g_storageImageBuffer.size = size;
145 
146     return HKS_SUCCESS;
147 }
148 
FreeImageBuffer(void)149 static void FreeImageBuffer(void)
150 {
151     CleanImageBuffer();
152     HKS_FREE_BLOB(g_storageImageBuffer);
153 }
154 
FreshImageBuffer(const char * fileName)155 static int32_t FreshImageBuffer(const char *fileName)
156 {
157     /* caller func ensure g_storageImageBuffer.size is larger than sizeof(*keyInfoHead) */
158     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
159     uint32_t totalLen = keyInfoHead->totalLen;
160 
161     /* check totalLen */
162     if ((totalLen < sizeof(*keyInfoHead)) || (totalLen > MAX_STORAGE_SIZE)) {
163         return HKS_ERROR_INVALID_KEY_FILE;
164     }
165 
166     if (totalLen == sizeof(*keyInfoHead)) {
167         return HKS_SUCCESS;
168     }
169 
170     uint32_t offset = HksGetStoreFileOffset();
171     uint32_t fileLen = HksFileSize(HKS_KEY_STORE_PATH, fileName);
172     if (fileLen < (totalLen + offset)) { /* keyfile len at least totalLen + offset */
173         HKS_LOG_E("total Len: %" LOG_PUBLIC "u, invalid file size: %" LOG_PUBLIC "u", totalLen, fileLen);
174         return HKS_ERROR_INVALID_KEY_FILE;
175     }
176 
177     uint8_t *buf = (uint8_t *)HksMalloc(totalLen);
178     HKS_IF_NULL_RETURN(buf, HKS_ERROR_MALLOC_FAIL)
179 
180     struct HksBlob blob = { .size = totalLen, .data = buf };
181 
182     int32_t ret = HksFileRead(HKS_KEY_STORE_PATH, fileName, offset, &blob, &fileLen);
183     if (ret != HKS_SUCCESS) {
184         HKS_FREE(buf);
185         return HKS_ERROR_READ_FILE_FAIL;
186     }
187 
188     FreeImageBuffer();
189     g_storageImageBuffer.data = buf;
190     g_storageImageBuffer.size = totalLen;
191 
192     return HKS_SUCCESS;
193 }
194 
CheckKeyInfoHeaderValid(void)195 static int32_t CheckKeyInfoHeaderValid(void)
196 {
197     /* caller func ensure g_storageImageBuffer.size is larger than sizeof(*keyInfoHead) */
198     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
199 
200     uint8_t mac512[HKS_HMAC_DIGEST_SHA512_LEN] = {0};
201     struct HksBlob mac = { HKS_HMAC_DIGEST_SHA512_LEN, mac512 };
202     struct HksBlob salt = { HKS_DERIVE_DEFAULT_SALT_LEN, keyInfoHead->salt };
203     uint16_t size = sizeof(*keyInfoHead) - HKS_HMAC_DIGEST_SHA512_LEN;
204 
205     int32_t ret = CalcHeaderMac(&salt, g_storageImageBuffer.data, size, &mac);
206     HKS_IF_NOT_SUCC_RETURN(ret, ret)
207 
208     if (HksMemCmp(mac.data, keyInfoHead->hmac, HKS_HMAC_DIGEST_SHA512_LEN) != 0) {
209         HKS_LOG_E("hmac value not match");
210         return HKS_ERROR_INVALID_KEY_FILE;
211     }
212 
213     return HKS_SUCCESS;
214 }
215 
RefreshKeyInfoHeaderHmac(struct HksStoreHeaderInfo * keyInfoHead)216 static int32_t RefreshKeyInfoHeaderHmac(struct HksStoreHeaderInfo *keyInfoHead)
217 {
218     struct HksBlob mac = { HKS_HMAC_DIGEST_SHA512_LEN, keyInfoHead->hmac };
219     struct HksBlob salt = { HKS_DERIVE_DEFAULT_SALT_LEN, keyInfoHead->salt };
220     uint16_t size = sizeof(*keyInfoHead) - HKS_HMAC_DIGEST_SHA512_LEN;
221 
222     uint8_t *buffer = (uint8_t *)HksMalloc(sizeof(*keyInfoHead));
223     HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
224 
225     (void)memcpy_s(buffer, sizeof(*keyInfoHead), keyInfoHead, sizeof(*keyInfoHead));
226 
227     int32_t ret = CalcHeaderMac(&salt, buffer, size, &mac);
228     HKS_FREE(buffer);
229     return ret;
230 }
231 
HksGetImageBuffer(void)232 static struct HksBlob HksGetImageBuffer(void)
233 {
234     return g_storageImageBuffer;
235 }
236 
LoadFileToBuffer(const char * fileName)237 static int32_t LoadFileToBuffer(const char *fileName)
238 {
239     /* 1. read key info header */
240     uint32_t offset = HksGetStoreFileOffset();
241     uint32_t len = 0;
242     int32_t ret = HksFileRead(HKS_KEY_STORE_PATH, fileName, offset,
243         &g_storageImageBuffer, &len);
244 
245     do {
246         /* 2. file not exist or read nothing, init image */
247         if (ret != HKS_SUCCESS) {
248             HKS_LOG_I("file not exist, init buffer.");
249             ret = InitImageBuffer();
250             HKS_IF_NOT_SUCC_BREAK(ret) /* init fail, need free global buf */
251             return ret;
252         }
253 
254         /* 3. read header success, check keyinfo header */
255         HKS_LOG_I("file exist, check buffer.");
256         ret = CheckKeyInfoHeaderValid();
257         HKS_IF_NOT_SUCC_BREAK(ret)
258 
259         /* 4. check success, load full buffer */
260         ret = FreshImageBuffer(fileName);
261     } while (0);
262 
263     if (ret != HKS_SUCCESS) {
264         FreeImageBuffer();
265     }
266 
267     return ret;
268 }
269 
HksLoadFileToBuffer(void)270 int32_t HksLoadFileToBuffer(void)
271 {
272     if (g_storageImageBuffer.data != NULL) {
273         return HKS_SUCCESS;
274     }
275 
276     /* 1. malloc keyinfo header size buffer */
277     int32_t ret = ApplyImageBuffer(sizeof(struct HksStoreHeaderInfo));
278     HKS_IF_NOT_SUCC_RETURN(ret, ret)
279 
280     CleanImageBuffer();
281 
282     /* 2. read file to buffer */
283     return LoadFileToBuffer(HKS_KEY_STORE_FILE_NAME);
284 }
285 
CleanStorageKeyInfo(const char * fileName)286 static int32_t CleanStorageKeyInfo(const char *fileName)
287 {
288     int32_t ret = InitImageBuffer();
289     if (ret != HKS_SUCCESS) {
290         FreeImageBuffer();
291         return ret;
292     }
293 
294     /* write to file */
295     uint32_t totalLen = sizeof(struct HksStoreHeaderInfo);
296     uint32_t fileOffset = HksGetStoreFileOffset();
297     ret = HksFileWrite(HKS_KEY_STORE_PATH, fileName, fileOffset, g_storageImageBuffer.data, totalLen);
298     if (ret != HKS_SUCCESS) {
299         HKS_LOG_E("write file failed when hks refresh file buffer");
300         FreeImageBuffer();
301     }
302     return ret;
303 }
304 
HksFileBufferRefresh(void)305 int32_t HksFileBufferRefresh(void)
306 {
307     /* malloc keyinfo header size buffer */
308     int32_t ret = ApplyImageBuffer(sizeof(struct HksStoreHeaderInfo));
309     HKS_IF_NOT_SUCC_RETURN(ret, ret)
310 
311     CleanImageBuffer();
312 
313     return CleanStorageKeyInfo(HKS_KEY_STORE_FILE_NAME);
314 }
315 
316 /*
317  * Storage format:
318  * keyInfoHeader + keyInfo1 + keyInfo2 + ... + keyInfoN
319  *
320  *                +--------------------------------------------------------------+
321  * KeyInfoHeader: | version | keyCount | totalLen | sealingAlg |  salt  |  hmac  |
322  *                | 2bytes  |  2bytes  |  4bytes  |   4bytes   |16bytes |64bytes |
323  *                +--------------------------------------------------------------+
324  *
325  *          +---------------------------------------------------------------------+
326  * KeyInfo: | keyInfoLen | keySize |  nonce  |  flag  | keyAlg | keyMode | digest |
327  *          |   2bytes   | 2bytes  | 16bytes | 1bytes | 1bytes | 1bytes  | 1bytes |
328  *          +---------------------------------------------------------------------+
329  *          | padding |  rsv   | keyLen | purpose |  role  | domain  | aliasSize |
330  *          | 1bytes  | 1bytes | 2bytes | 4bytes  | 4bytes | 21bytes |  1bytes   |
331  *          +--------------------------------------------------------------------+
332  *          | AuthIdSize |  keyAlias   |  keyAuthId  |         key          |
333  *          |   1bytes   | max 64bytes | max 64bytes | max keyMaterial size |
334  *          +---------------------------------------------------------------+
335  */
GetKeyOffsetByKeyAlias(const struct HksBlob * keyAlias,uint32_t * keyOffset)336 static int32_t GetKeyOffsetByKeyAlias(const struct HksBlob *keyAlias, uint32_t *keyOffset)
337 {
338     struct HksBlob storageBuf = HksGetImageBuffer();
339     if (storageBuf.size < sizeof(struct HksStoreHeaderInfo)) {
340         HKS_LOG_E("invalid keyinfo buffer size %" LOG_PUBLIC "u.", storageBuf.size);
341         return HKS_ERROR_INVALID_KEY_FILE;
342     }
343 
344     /* 1. get imageBuffer total Len */
345     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)storageBuf.data;
346     uint32_t keyCount = keyInfoHead->keyCount;
347     uint32_t totalLen = keyInfoHead->totalLen;
348     if (keyCount == 0) {
349         return HKS_ERROR_NOT_EXIST;
350     }
351     if (totalLen > storageBuf.size) {
352         HKS_LOG_E("storageBuf size invalid");
353         return HKS_ERROR_INVALID_KEY_FILE;
354     }
355 
356     /* 2. traverse imageBuffer to search for keyAlias */
357     uint32_t offset = sizeof(*keyInfoHead);
358     for (uint32_t i = 0; i < keyCount; ++i) {
359         if ((totalLen < offset) || ((totalLen - offset) < sizeof(struct HksStoreKeyInfo))) {
360             HKS_LOG_E("invalid keyinfo size.");
361             return HKS_ERROR_INVALID_KEY_FILE;
362         }
363 
364         uint8_t *tmpBuf = storageBuf.data + offset;
365         struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)tmpBuf;
366         if (HksIsKeyInfoLenInvalid(keyInfo) || (keyInfo->keyInfoLen > (totalLen - offset))) {
367             HKS_LOG_E("invalid keyinfo len");
368             return HKS_ERROR_INVALID_KEY_FILE;
369         }
370 
371         if (keyInfo->aliasSize == keyAlias->size) {
372             if (HksMemCmp(keyAlias->data, tmpBuf + sizeof(*keyInfo), keyAlias->size) == 0) {
373                 *keyOffset = offset;
374                 return HKS_SUCCESS;
375             }
376         }
377 
378         offset += keyInfo->keyInfoLen;
379     }
380 
381     return HKS_ERROR_NOT_EXIST;
382 }
383 
AdjustImageBuffer(uint32_t totalLenAdded,const struct HksBlob * keyBlob)384 static int32_t AdjustImageBuffer(uint32_t totalLenAdded, const struct HksBlob *keyBlob)
385 {
386     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
387 
388     /* buffer has been checked will not overflow */
389     uint32_t newBufLen = g_storageImageBuffer.size +
390         ((keyBlob->size > BUF_SIZE_ADDEND_PER_TIME) ? keyBlob->size : BUF_SIZE_ADDEND_PER_TIME);
391     uint8_t *buf = (uint8_t *)HksMalloc(newBufLen);
392     HKS_IF_NULL_RETURN(buf, HKS_ERROR_MALLOC_FAIL)
393 
394     (void)memset_s(buf, newBufLen, 0, newBufLen);
395 
396     /* copy old imagebuf to new malloc buf */
397     if (memcpy_s(buf, newBufLen, g_storageImageBuffer.data, keyInfoHead->totalLen) != EOK) {
398         HKS_FREE(buf);
399         return HKS_ERROR_INSUFFICIENT_MEMORY;
400     }
401 
402     /* append new add key buffer to the end */
403     if (memcpy_s(buf + keyInfoHead->totalLen, newBufLen - keyInfoHead->totalLen,
404         keyBlob->data, keyBlob->size) != EOK) {
405         HKS_FREE(buf);
406         return HKS_ERROR_INSUFFICIENT_MEMORY;
407     }
408 
409     struct HksStoreHeaderInfo *newHead = (struct HksStoreHeaderInfo *)buf;
410     newHead->totalLen = totalLenAdded;
411     newHead->keyCount += 1;
412 
413     FreeImageBuffer();
414     g_storageImageBuffer.data = buf;
415     g_storageImageBuffer.size = newBufLen;
416 
417     return HKS_SUCCESS;
418 }
419 
AppendNewKey(const struct HksBlob * keyBlob)420 static int32_t AppendNewKey(const struct HksBlob *keyBlob)
421 {
422     struct HksBlob storageBuf = HksGetImageBuffer();
423     if (storageBuf.size < sizeof(struct HksStoreHeaderInfo)) {
424         HKS_LOG_E("invalid keyinfo buffer size %" LOG_PUBLIC "u.", storageBuf.size);
425         return HKS_ERROR_INVALID_KEY_FILE;
426     }
427 
428     /* 1. get imagebuf total Len */
429     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)storageBuf.data;
430 
431     if (IsAdditionOverflow(keyInfoHead->totalLen, keyBlob->size)) {
432         return HKS_ERROR_INSUFFICIENT_MEMORY;
433     }
434 
435     uint32_t totalLenAdded = keyInfoHead->totalLen + keyBlob->size;
436     if (totalLenAdded > MAX_STORAGE_SIZE) {
437         HKS_LOG_E("after add, buffer too big to store");
438         return HKS_ERROR_STORAGE_FAILURE;
439     }
440 
441     /* imagebuf is enough to append new keyinfo */
442     if (storageBuf.size >= totalLenAdded) {
443         if (memcpy_s(storageBuf.data + keyInfoHead->totalLen, storageBuf.size - keyInfoHead->totalLen,
444             keyBlob->data, keyBlob->size) != EOK) {
445             return HKS_ERROR_INSUFFICIENT_MEMORY;
446         }
447         keyInfoHead->totalLen = totalLenAdded;
448         keyInfoHead->keyCount += 1;
449         return HKS_SUCCESS;
450     }
451 
452     /* need malloc new buffer */
453     return AdjustImageBuffer(totalLenAdded, keyBlob);
454 }
455 
GetLenAfterAddKey(const struct HksBlob * keyBlob,uint32_t totalLen,uint32_t * totalLenAdded)456 static int32_t GetLenAfterAddKey(const struct HksBlob *keyBlob, uint32_t totalLen, uint32_t *totalLenAdded)
457 {
458     if (IsAdditionOverflow(totalLen, keyBlob->size)) {
459         return HKS_ERROR_INSUFFICIENT_MEMORY;
460     }
461 
462     uint32_t newTotalLen = totalLen + keyBlob->size;
463     if (newTotalLen > MAX_STORAGE_SIZE) {
464         HKS_LOG_E("after add, buffer too big to store");
465         return HKS_ERROR_STORAGE_FAILURE;
466     }
467 
468     *totalLenAdded = newTotalLen;
469     return HKS_SUCCESS;
470 }
471 
DeleteKey(uint32_t keyOffset)472 static int32_t DeleteKey(uint32_t keyOffset)
473 {
474     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
475     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)(g_storageImageBuffer.data + keyOffset);
476 
477     uint32_t keyInfoLen = keyInfo->keyInfoLen;
478     uint32_t nextKeyOffset = keyOffset + keyInfoLen;
479     if (nextKeyOffset > keyInfoHead->totalLen) {
480         return HKS_ERROR_INVALID_KEY_FILE;
481     }
482 
483     (void)memset_s(keyInfo, keyInfoLen, 0, keyInfoLen);
484 
485     /* If key to delete is not the last key, need to be move image buffer */
486     if (nextKeyOffset < keyInfoHead->totalLen) {
487         if (memmove_s(keyInfo, keyInfoHead->totalLen - keyOffset, g_storageImageBuffer.data + nextKeyOffset,
488             keyInfoHead->totalLen - nextKeyOffset) != EOK) {
489             HKS_LOG_E("memmove image buffer failed");
490             return HKS_ERROR_INSUFFICIENT_MEMORY;
491         }
492         /* clear the last buffer */
493         (void)memset_s(g_storageImageBuffer.data + keyInfoHead->totalLen - keyInfoLen, keyInfoLen, 0, keyInfoLen);
494     }
495     keyInfoHead->keyCount -= 1;
496     keyInfoHead->totalLen -= keyInfoLen;
497 
498     return HKS_SUCCESS;
499 }
500 
StoreKeyBlob(bool needDeleteKey,uint32_t offset,const struct HksBlob * keyBlob)501 static int32_t StoreKeyBlob(bool needDeleteKey, uint32_t offset, const struct HksBlob *keyBlob)
502 {
503     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
504     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)(g_storageImageBuffer.data + offset);
505 
506     struct HksStoreHeaderInfo newkeyInfoHead;
507     if (memcpy_s(&newkeyInfoHead, sizeof(newkeyInfoHead), keyInfoHead, sizeof(*keyInfoHead)) != EOK) {
508         return HKS_ERROR_INSUFFICIENT_MEMORY;
509     }
510 
511     uint32_t totalLenAdded = 0;
512     int32_t ret;
513 
514     /* 1. check storage buffer enough for store new key */
515     if (needDeleteKey) {
516         ret = GetLenAfterAddKey(keyBlob, keyInfoHead->totalLen - keyInfo->keyInfoLen, &totalLenAdded);
517     } else {
518         newkeyInfoHead.keyCount += 1,
519         ret = GetLenAfterAddKey(keyBlob, keyInfoHead->totalLen, &totalLenAdded);
520     }
521     HKS_IF_NOT_SUCC_RETURN(ret, ret)
522 
523     /* 2. calc temp hmac */
524     newkeyInfoHead.totalLen = totalLenAdded;
525     ret = RefreshKeyInfoHeaderHmac(&newkeyInfoHead);
526     HKS_IF_NOT_SUCC_RETURN(ret, ret)
527 
528     /* 3. delete key if keyExist */
529     if (needDeleteKey) {
530         ret = DeleteKey(offset);
531         HKS_IF_NOT_SUCC_RETURN(ret, ret)
532     }
533 
534     /* 4. append key */
535     ret = AppendNewKey(keyBlob);
536     HKS_IF_NOT_SUCC_RETURN(ret, ret)
537 
538     /* 5. replace header */
539     if (memcpy_s(g_storageImageBuffer.data, sizeof(newkeyInfoHead), &newkeyInfoHead, sizeof(newkeyInfoHead)) != EOK) {
540         HKS_LOG_E("replace header memcpy failed");
541         return HKS_ERROR_INSUFFICIENT_MEMORY;
542     }
543     return HKS_SUCCESS;
544 }
545 
GetFileName(const struct HksBlob * name,char ** fileName)546 static int32_t GetFileName(const struct HksBlob *name, char **fileName)
547 {
548     char *tmpName = (char *)HksMalloc(name->size + 1); /* \0 at the end */
549     HKS_IF_NULL_RETURN(tmpName, HKS_ERROR_MALLOC_FAIL)
550 
551     (void)memcpy_s(tmpName, name->size, name->data, name->size);
552     tmpName[name->size] = '\0';
553     *fileName = tmpName;
554     return HKS_SUCCESS;
555 }
556 
StoreRootMaterial(const struct HksBlob * name,const struct HksBlob * buffer)557 static int32_t StoreRootMaterial(const struct HksBlob *name, const struct HksBlob *buffer)
558 {
559     char *fileName = NULL;
560     int32_t ret = GetFileName(name, &fileName);
561     HKS_IF_NOT_SUCC_RETURN(ret, ret)
562 
563     ret = HksFileWrite(HKS_KEY_STORE_PATH, fileName, 0, buffer->data, buffer->size);
564     HKS_FREE(fileName);
565     return ret;
566 }
567 
IsRootMaterialExist(const struct HksBlob * name)568 static int32_t IsRootMaterialExist(const struct HksBlob *name)
569 {
570     char *fileName = NULL;
571     int32_t ret = GetFileName(name, &fileName);
572     HKS_IF_NOT_SUCC_RETURN(ret, ret)
573 
574     ret = HksIsFileExist(HKS_KEY_STORE_PATH, fileName);
575     HKS_FREE(fileName);
576     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_NOT_EXIST, "file not exist")
577 
578     return ret;
579 }
580 
GetRootMaterial(const struct HksBlob * name,struct HksBlob * buffer)581 static int32_t GetRootMaterial(const struct HksBlob *name, struct HksBlob *buffer)
582 {
583     char *fileName = NULL;
584     int32_t ret = GetFileName(name, &fileName);
585     HKS_IF_NOT_SUCC_RETURN(ret, ret)
586 
587     uint32_t len = 0;
588     ret = HksFileRead(HKS_KEY_STORE_PATH, fileName, 0, buffer, &len);
589     HKS_FREE(fileName);
590     if (ret != HKS_SUCCESS) {
591         return HKS_ERROR_READ_FILE_FAIL;
592     }
593     return HKS_SUCCESS;
594 }
595 
HksStoreKeyBlob(const struct HksStoreFileInfo * fileInfo,const struct HksBlob * keyAlias,uint32_t storageType,const struct HksBlob * keyBlob)596 int32_t HksStoreKeyBlob(const struct HksStoreFileInfo *fileInfo, const struct HksBlob *keyAlias,
597     uint32_t storageType, const struct HksBlob *keyBlob)
598 {
599     (void)fileInfo;
600     if (storageType == HKS_STORAGE_TYPE_ROOT_KEY) {
601         return StoreRootMaterial(keyAlias, keyBlob);
602     }
603 
604     /* 1. check key exist or not */
605     uint32_t offset = 0;
606     int32_t ret = GetKeyOffsetByKeyAlias(keyAlias, &offset);
607     if ((ret != HKS_SUCCESS) && (ret != HKS_ERROR_NOT_EXIST)) {
608         return ret;
609     }
610 
611     /* 2. store key blob */
612     bool needDeleteKey = (ret == HKS_SUCCESS);
613     ret = StoreKeyBlob(needDeleteKey, offset, keyBlob);
614     HKS_IF_NOT_SUCC_RETURN(ret, ret)
615 
616     /* 3. write to file */
617     uint32_t totalLen = 0;
618     ret = HksStoreGetToatalSize(&totalLen);
619     HKS_IF_NOT_SUCC_RETURN(ret, ret)
620 
621     uint32_t fileOffset = HksGetStoreFileOffset();
622     return HksFileWrite(HKS_KEY_STORE_PATH, HKS_KEY_STORE_FILE_NAME, fileOffset, g_storageImageBuffer.data, totalLen);
623 }
624 
HksStoreDeleteKeyBlob(const struct HksStoreFileInfo * fileInfo,const struct HksBlob * keyAlias,uint32_t storageType)625 int32_t HksStoreDeleteKeyBlob(const struct HksStoreFileInfo *fileInfo,
626     const struct HksBlob *keyAlias, uint32_t storageType)
627 {
628     (void)fileInfo;
629     (void)storageType;
630 
631     /* 1. check key exist or not */
632     uint32_t offset = 0;
633     int32_t ret = GetKeyOffsetByKeyAlias(keyAlias, &offset);
634     HKS_IF_NOT_SUCC_RETURN(ret, ret)
635 
636     /* 2. calc tmp header hmac */
637     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
638     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)(g_storageImageBuffer.data + offset);
639     struct HksStoreHeaderInfo newkeyInfoHead;
640     if (memcpy_s(&newkeyInfoHead, sizeof(newkeyInfoHead), keyInfoHead, sizeof(*keyInfoHead)) != EOK) {
641         return HKS_ERROR_INSUFFICIENT_MEMORY;
642     }
643     newkeyInfoHead.totalLen -= keyInfo->keyInfoLen;
644     newkeyInfoHead.keyCount -= 1;
645 
646     ret = RefreshKeyInfoHeaderHmac(&newkeyInfoHead);
647     HKS_IF_NOT_SUCC_RETURN(ret, ret)
648 
649     /* 3. delete key */
650     ret = DeleteKey(offset);
651     HKS_IF_NOT_SUCC_RETURN(ret, ret)
652 
653     /* 4. replace header */
654     if (memcpy_s(keyInfoHead, sizeof(*keyInfoHead), &newkeyInfoHead, sizeof(newkeyInfoHead)) != EOK) {
655         return HKS_ERROR_INSUFFICIENT_MEMORY;
656     }
657 
658     uint32_t fileOffset = HksGetStoreFileOffset();
659     return HksFileWrite(HKS_KEY_STORE_PATH, HKS_KEY_STORE_FILE_NAME, fileOffset,
660         g_storageImageBuffer.data, keyInfoHead->totalLen);
661 }
662 
HksStoreIsKeyBlobExist(const struct HksStoreFileInfo * fileInfo,const struct HksBlob * keyAlias,uint32_t storageType)663 int32_t HksStoreIsKeyBlobExist(const struct HksStoreFileInfo *fileInfo,
664     const struct HksBlob *keyAlias, uint32_t storageType)
665 {
666     (void)fileInfo;
667     if (storageType == HKS_STORAGE_TYPE_ROOT_KEY) {
668         return IsRootMaterialExist(keyAlias);
669     }
670 
671     uint32_t offset = 0;
672     return GetKeyOffsetByKeyAlias(keyAlias, &offset);
673 }
674 
HksStoreGetKeyBlob(const struct HksStoreInfo * fileInfoPath,const struct HksBlob * keyAlias,uint32_t storageType,struct HksBlob * keyBlob)675 int32_t HksStoreGetKeyBlob(const struct HksStoreInfo *fileInfoPath,
676     const struct HksBlob *keyAlias, uint32_t storageType, struct HksBlob *keyBlob)
677 {
678     (void)fileInfoPath;
679     if (storageType == HKS_STORAGE_TYPE_ROOT_KEY) {
680         return GetRootMaterial(keyAlias, keyBlob);
681     }
682 
683     uint32_t offset = 0;
684     int32_t ret = GetKeyOffsetByKeyAlias(keyAlias, &offset);
685     HKS_IF_NOT_SUCC_RETURN(ret, ret)
686 
687     /* get offset success, len has been check valid */
688     uint8_t *tmpBuf = g_storageImageBuffer.data + offset;
689     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)tmpBuf;
690 
691     keyBlob->data = (uint8_t *)HksMalloc(keyInfo->keyInfoLen); /* need be freed by caller functions */
692     HKS_IF_NULL_RETURN(keyBlob->data, HKS_ERROR_MALLOC_FAIL)
693 
694     keyBlob->size = keyInfo->keyInfoLen;
695 
696     if (memcpy_s(keyBlob->data, keyBlob->size, tmpBuf, keyInfo->keyInfoLen) != EOK) {
697         HKS_LOG_E("memcpy to key blob failed.");
698         HKS_FREE(keyBlob->data);
699         return HKS_ERROR_INSUFFICIENT_MEMORY;
700     }
701 
702     return HKS_SUCCESS;
703 }
704 
HksStoreGetKeyBlobSize(const struct HksBlob * processName,const struct HksBlob * keyAlias,uint32_t storageType,uint32_t * keyBlobSize)705 int32_t HksStoreGetKeyBlobSize(const struct HksBlob *processName,
706     const struct HksBlob *keyAlias, uint32_t storageType, uint32_t *keyBlobSize)
707 {
708     (void)processName;
709     (void)storageType;
710 
711     uint32_t offset = 0;
712     int32_t ret = GetKeyOffsetByKeyAlias(keyAlias, &offset);
713     HKS_IF_NOT_SUCC_RETURN(ret, ret)
714 
715     /* get offset success, len has been check valid */
716     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)(g_storageImageBuffer.data + offset);
717     *keyBlobSize = keyInfo->keyInfoLen;
718     return HKS_SUCCESS;
719 }
720 
HksGetKeyCountByProcessName(const struct HksBlob * processName,uint32_t * keyCount)721 int32_t HksGetKeyCountByProcessName(const struct HksBlob *processName, uint32_t *keyCount)
722 {
723     (void)processName;
724     if (g_storageImageBuffer.size < sizeof(struct HksStoreHeaderInfo)) {
725         HKS_LOG_E("invalid keyinfo buffer size %" LOG_PUBLIC "u.", g_storageImageBuffer.size);
726         return HKS_ERROR_INVALID_KEY_FILE;
727     }
728 
729     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
730     *keyCount = keyInfoHead->keyCount;
731     return HKS_SUCCESS;
732 }
733 
HksStoreGetToatalSize(uint32_t * size)734 int32_t HksStoreGetToatalSize(uint32_t *size)
735 {
736     if (g_storageImageBuffer.size < sizeof(struct HksStoreHeaderInfo)) {
737         HKS_LOG_E("invalid keyinfo buffer size %" LOG_PUBLIC "u.", g_storageImageBuffer.size);
738         return HKS_ERROR_INVALID_KEY_FILE;
739     }
740 
741     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)g_storageImageBuffer.data;
742     *size = keyInfoHead->totalLen;
743     return HKS_SUCCESS;
744 }
745 
GetKeyInfoList(struct HksKeyInfo * keyInfoList,const struct HksBlob * keyInfoBlob)746 static int32_t GetKeyInfoList(struct HksKeyInfo *keyInfoList, const struct HksBlob *keyInfoBlob)
747 {
748     struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)keyInfoBlob->data;
749 
750     if (keyInfoList->alias.size < keyInfo->aliasSize) {
751         return HKS_ERROR_BUFFER_TOO_SMALL;
752     }
753 
754     if (memcpy_s(keyInfoList->alias.data, keyInfoList->alias.size,
755         keyInfoBlob->data + sizeof(*keyInfo), keyInfo->aliasSize) != EOK) {
756         HKS_LOG_E("memcpy keyAlias failed");
757         return HKS_ERROR_INSUFFICIENT_MEMORY;
758     }
759     keyInfoList->alias.size = keyInfo->aliasSize;
760 
761     struct HksParamSet *paramSet = NULL;
762     int32_t ret = TranslateKeyInfoBlobToParamSet(NULL, keyInfoBlob, &paramSet);
763     HKS_IF_NOT_SUCC_RETURN(ret, ret)
764 
765     if (keyInfoList->paramSet->paramSetSize < paramSet->paramSetSize) {
766         HksFreeParamSet(&paramSet);
767         return HKS_ERROR_BUFFER_TOO_SMALL;
768     }
769     if (memcpy_s(keyInfoList->paramSet, keyInfoList->paramSet->paramSetSize,
770         paramSet, paramSet->paramSetSize) != EOK) {
771         HKS_LOG_E("memcpy paramSet failed.");
772         HksFreeParamSet(&paramSet);
773         return HKS_ERROR_INSUFFICIENT_MEMORY;
774     }
775 
776     HksFreeParamSet(&paramSet);
777     return HKS_SUCCESS;
778 }
779 
GetAndCheckKeyCount(uint32_t * inputCount,uint32_t * keyCount)780 static int32_t GetAndCheckKeyCount(uint32_t *inputCount, uint32_t *keyCount)
781 {
782     struct HksBlob storageBuf = HksGetImageBuffer();
783     if (storageBuf.size < sizeof(struct HksStoreHeaderInfo)) {
784         HKS_LOG_E("invalid keyinfo buffer size %" LOG_PUBLIC "u.", storageBuf.size);
785         return HKS_ERROR_INVALID_KEY_FILE;
786     }
787 
788     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)storageBuf.data;
789     *keyCount = keyInfoHead->keyCount;
790     if (*keyCount == 0) {
791         *inputCount = 0;
792         return HKS_SUCCESS;
793     }
794 
795     if (storageBuf.size < keyInfoHead->totalLen) {
796         HKS_LOG_E("storageBuf size invalid");
797         return HKS_ERROR_INVALID_KEY_FILE;
798     }
799 
800     if (*inputCount < *keyCount) {
801         HKS_LOG_E("listCount space not enough");
802         return HKS_ERROR_BUFFER_TOO_SMALL;
803     }
804     return HKS_SUCCESS;
805 }
806 
HksStoreGetKeyInfoList(struct HksKeyInfo * keyInfoList,uint32_t * listCount)807 int32_t HksStoreGetKeyInfoList(struct HksKeyInfo *keyInfoList, uint32_t *listCount)
808 {
809     uint32_t keyCount;
810     int32_t ret = GetAndCheckKeyCount(listCount, &keyCount);
811     HKS_IF_NOT_SUCC_RETURN(ret, ret)
812 
813     /* 2. traverse ImageBuffer to search for keyAlias */
814     struct HksBlob storageBuf = HksGetImageBuffer();
815     struct HksStoreHeaderInfo *keyInfoHead = (struct HksStoreHeaderInfo *)storageBuf.data;
816     uint32_t totalLen = keyInfoHead->totalLen;
817     uint32_t num = 0;
818     uint32_t offset = sizeof(*keyInfoHead);
819     for (uint32_t i = 0; i < keyCount; ++i) {
820         if ((totalLen < offset) || ((totalLen - offset) < sizeof(struct HksStoreKeyInfo))) {
821             HKS_LOG_E("invalid keyinfo size.");
822             return HKS_ERROR_INVALID_KEY_FILE;
823         }
824 
825         uint8_t *tmpBuf = storageBuf.data + offset; /* storageBuf.size has been checked */
826         struct HksStoreKeyInfo *keyInfo = (struct HksStoreKeyInfo *)tmpBuf;
827 
828         if (HksIsKeyInfoLenInvalid(keyInfo) || ((totalLen - offset) < keyInfo->keyInfoLen)) {
829             HKS_LOG_E("invalid keyinfo len");
830             return HKS_ERROR_INVALID_KEY_FILE;
831         }
832 
833         struct HksBlob keyInfoBlob = { keyInfo->keyInfoLen, tmpBuf };
834         ret = GetKeyInfoList(&keyInfoList[i], &keyInfoBlob);
835         HKS_IF_NOT_SUCC_RETURN(ret, ret)
836 
837         num++;
838         offset += keyInfo->keyInfoLen;
839     }
840 
841     *listCount = num;
842     return HKS_SUCCESS;
843 }
844 
845 #ifdef HKS_ENABLE_CLEAN_FILE
CleanFile(const char * path,const char * fileName)846 static int32_t CleanFile(const char *path, const char *fileName)
847 {
848     uint32_t size = HksFileSize(path, fileName);
849     if (size == 0 || size > HKS_MAX_FILE_SIZE) {
850         HKS_LOG_E("storage lite get file size failed, ret = %" LOG_PUBLIC "u.", size);
851         return HKS_ERROR_FILE_SIZE_FAIL;
852     }
853 
854     int32_t ret = HKS_SUCCESS;
855     uint8_t *buf;
856     do {
857         buf = (uint8_t *)HksMalloc(size);
858         if (buf == NULL) {
859             HKS_LOG_E("storage lite malloc buf failed!");
860             ret = HKS_ERROR_MALLOC_FAIL;
861             break;
862         }
863 
864         (void)memset_s(buf, size, 0, size);
865         ret = HksFileWrite(path, fileName, 0, buf, size);
866         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file 0 failed!")
867 
868         (void)memset_s(buf, size, 1, size);
869         ret = HksFileWrite(path, fileName, 0, buf, size);
870         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file 1 failed!")
871 
872         struct HksBlob bufBlob = { .size = size, .data = buf };
873         ret = HuksAccessGenerateRandom(NULL, &bufBlob);
874         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "fill buf random failed!")
875 
876         ret = HksFileWrite(path, fileName, 0, buf, size);
877         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "write file random failed!")
878     } while (0);
879     HKS_FREE(buf);
880     return ret;
881 }
882 #endif
883 
RemoveFile(const char * path,const char * fileName)884 static int32_t RemoveFile(const char *path, const char *fileName)
885 {
886 #ifdef HKS_ENABLE_CLEAN_FILE
887     if (CleanFile(path, fileName) != HKS_SUCCESS) {
888         HKS_LOG_E("clean file failed");
889     }
890 #endif
891 
892     if (HksFileRemove(path, fileName) != HKS_SUCCESS) {
893         HKS_LOG_E("remove file failed");
894     }
895     return HKS_SUCCESS;
896 }
897 
HksStoreDestroy(const struct HksBlob * processName)898 int32_t HksStoreDestroy(const struct HksBlob *processName)
899 {
900     (void)processName;
901     /* only record log, continue delete */
902 
903     if (RemoveFile(HKS_KEY_STORE_PATH, HKS_KEY_STORE_FILE_NAME) != HKS_SUCCESS) {
904         HKS_LOG_E("remove key store file failed");
905     }
906 
907     if (RemoveFile(HKS_KEY_STORE_PATH, "info1.data") != HKS_SUCCESS) {
908         HKS_LOG_E("remove info1 file failed");
909     }
910 
911     if (RemoveFile(HKS_KEY_STORE_PATH, "info2.data") != HKS_SUCCESS) {
912         HKS_LOG_E("remove info2 file failed");
913     }
914     return HKS_SUCCESS;
915 }
916 #endif /* _STORAGE_LITE_ */
917 
918 #endif /* _CUT_AUTHENTICATE_ */
919