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