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(¶mSet);
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(¶mSet);
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, ¶mSet);
763 HKS_IF_NOT_SUCC_RETURN(ret, ret)
764
765 if (keyInfoList->paramSet->paramSetSize < paramSet->paramSetSize) {
766 HksFreeParamSet(¶mSet);
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(¶mSet);
773 return HKS_ERROR_INSUFFICIENT_MEMORY;
774 }
775
776 HksFreeParamSet(¶mSet);
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