1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "pin_db.h"
17 #include "adaptor_algorithm.h"
18 #include "adaptor_memory.h"
19 #include "adaptor_time.h"
20 #include "defines.h"
21 #include "file_operator.h"
22 #include "securec.h"
23
24 static PinDb g_pinDbOp = {CURRENT_VERSION, 0, NULL, false};
25
GetDataFromBuf(uint8_t ** src,uint32_t * srcLen,uint8_t * dest,uint32_t destLen)26 static ResultCode GetDataFromBuf(uint8_t **src, uint32_t *srcLen, uint8_t *dest, uint32_t destLen)
27 {
28 if (destLen > *srcLen) {
29 LOG_ERROR("bad len.");
30 return RESULT_BAD_PARAM;
31 }
32 if (memcpy_s(dest, destLen, *src, destLen) != EOK) {
33 LOG_ERROR("copy fail.");
34 return RESULT_BAD_COPY;
35 }
36
37 *src = *src + destLen;
38 *srcLen = *srcLen - destLen;
39 return RESULT_SUCCESS;
40 }
41
UnpackPinDb(uint8_t * data,uint32_t dataLen)42 static ResultCode UnpackPinDb(uint8_t *data, uint32_t dataLen)
43 {
44 if (data == NULL || dataLen == 0) {
45 LOG_ERROR("param is invalid.");
46 return RESULT_BAD_PARAM;
47 }
48
49 uint8_t *temp = data;
50 uint32_t tempLen = dataLen;
51 if (GetDataFromBuf(&temp, &tempLen, (uint8_t *)&(g_pinDbOp.version), sizeof(g_pinDbOp.version)) != RESULT_SUCCESS) {
52 LOG_ERROR("read version fail.");
53 goto ERROR;
54 }
55 if (GetDataFromBuf(&temp, &tempLen, (uint8_t *)&(g_pinDbOp.pinIndexLen),
56 sizeof(g_pinDbOp.pinIndexLen)) != RESULT_SUCCESS) {
57 LOG_ERROR("read pinIndexLen fail.");
58 goto ERROR;
59 }
60 if (g_pinDbOp.pinIndexLen > MAX_CRYPTO_INFO_SIZE) {
61 LOG_ERROR("pinIndexLen too large.");
62 goto ERROR;
63 }
64 if (g_pinDbOp.pinIndexLen == 0) {
65 g_pinDbOp.pinIndex = NULL;
66 return RESULT_SUCCESS;
67 }
68 uint32_t mallocSize = sizeof(PinIndex) * g_pinDbOp.pinIndexLen;
69 g_pinDbOp.pinIndex = (PinIndex *)Malloc(mallocSize);
70 if (g_pinDbOp.pinIndex == NULL) {
71 LOG_ERROR("pinIndex malloc fail.");
72 goto ERROR;
73 }
74 if (mallocSize != tempLen) {
75 LOG_ERROR("pinIndexLen too large.");
76 goto ERROR;
77 }
78 if (memcpy_s(g_pinDbOp.pinIndex, mallocSize, temp, tempLen) != EOK) {
79 LOG_ERROR("read pinIndex fail.");
80 goto ERROR;
81 }
82 return RESULT_SUCCESS;
83
84 ERROR:
85 DestroyPinDb();
86 return RESULT_BAD_READ;
87 }
88
LoadPinDb()89 static ResultCode LoadPinDb()
90 {
91 if (g_pinDbOp.isLoaded) {
92 return RESULT_SUCCESS;
93 }
94 FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
95 if (!IsFileOperatorValid(fileOp)) {
96 LOG_ERROR("fileOp invalid.");
97 return RESULT_GENERAL_ERROR;
98 }
99
100 if (!fileOp->isFileExist(PIN_INDEX_NAME)) {
101 g_pinDbOp.isLoaded = true;
102 return RESULT_SUCCESS;
103 }
104
105 uint32_t dataLen = 0;
106 ResultCode ret = (ResultCode)(fileOp->getFileLen(PIN_INDEX_NAME, &dataLen));
107 if (ret != RESULT_SUCCESS) {
108 LOG_ERROR("get filelen failed");
109 return RESULT_BAD_READ;
110 }
111
112 uint8_t *data = Malloc(dataLen);
113 if (data == NULL) {
114 LOG_ERROR("parcel create failed");
115 return RESULT_GENERAL_ERROR;
116 }
117 ret = fileOp->readFile(PIN_INDEX_NAME, data, dataLen);
118 if (ret != RESULT_SUCCESS) {
119 LOG_ERROR("read_parcel_from_file failed.");
120 goto EXIT;
121 }
122
123 ret = UnpackPinDb(data, dataLen);
124 if (ret != RESULT_SUCCESS) {
125 LOG_ERROR("unpack db failed.");
126 goto EXIT;
127 }
128 g_pinDbOp.isLoaded = true;
129 LOG_INFO("LoadPinDb succ.");
130
131 EXIT:
132 (void)memset_s(data, dataLen, 0, dataLen);
133 Free(data);
134 return ret;
135 }
136
InitPinDb(void)137 void InitPinDb(void)
138 {
139 ResultCode ret = LoadPinDb();
140 if (ret != RESULT_SUCCESS) {
141 LOG_ERROR("LoadPinDb fail.");
142 }
143 LOG_INFO("InitPinDb succ.");
144 }
145
DestroyPinDb(void)146 void DestroyPinDb(void)
147 {
148 if (g_pinDbOp.pinIndex != NULL) {
149 Free(g_pinDbOp.pinIndex);
150 }
151 g_pinDbOp.version = CURRENT_VERSION;
152 g_pinDbOp.pinIndexLen = 0;
153 g_pinDbOp.pinIndex = NULL;
154 g_pinDbOp.isLoaded = false;
155 LOG_INFO("DestroyPinDb succ.");
156 }
157
CopyDataToBuf(uint8_t * data,uint32_t dataLen,uint8_t ** buf,uint32_t * bufLen)158 static ResultCode CopyDataToBuf(uint8_t *data, uint32_t dataLen, uint8_t **buf, uint32_t *bufLen)
159 {
160 if (memcpy_s(*buf, *bufLen, data, dataLen) != EOK) {
161 LOG_ERROR("CopyFileName fail.");
162 return RESULT_BAD_COPY;
163 }
164
165 *buf = *buf + dataLen;
166 *bufLen = *bufLen - dataLen;
167 return RESULT_SUCCESS;
168 }
169
Uint2Str(uint64_t number,char * out,uint32_t length)170 static bool Uint2Str(uint64_t number, char *out, uint32_t length)
171 {
172 if ((out == NULL) || (length != MAX_UINT_LEN)) {
173 return false;
174 }
175 if (memset_s(out, length, 0, length) != EOK) {
176 return false;
177 }
178 /* when number is zero, return string "0" directly */
179 if (number == 0) {
180 out[0] = '0';
181 return true;
182 }
183 char outTemp[MAX_UINT_LEN] = {0};
184 uint64_t temp = number;
185 uint32_t index = 0;
186 while (temp != 0) {
187 outTemp[index] = temp % 10; /* 10 means decimal */
188 temp = temp / 10; /* 10 means decimal */
189 index++;
190 }
191 for (uint32_t i = 0; i < index; i++) {
192 out[i] = outTemp[index - 1 - i] + '0'; /* trans number to ascii by add '0' */
193 }
194
195 return true;
196 }
197
GenerateFileName(uint64_t templateId,const char * prefix,const char * suffix,char * fileName,uint32_t fileNameLen)198 static ResultCode GenerateFileName(uint64_t templateId, const char *prefix, const char *suffix,
199 char *fileName, uint32_t fileNameLen)
200 {
201 if (memset_s(fileName, fileNameLen, 0, fileNameLen) != EOK) {
202 return RESULT_PIN_FAIL;
203 }
204 char *buf = fileName;
205 uint32_t bufLen = fileNameLen;
206 if (CopyDataToBuf((uint8_t *)prefix, strlen(prefix), (uint8_t **)&buf, &bufLen) != RESULT_SUCCESS) {
207 LOG_ERROR("copy prefix fail.");
208 return RESULT_BAD_COPY;
209 }
210 char templateIdStr[MAX_UINT_LEN] = {'\0'};
211 if (!Uint2Str(templateId, templateIdStr, sizeof(templateIdStr))) {
212 LOG_ERROR("Uint2Str error.");
213 return RESULT_UNKNOWN;
214 }
215 if (CopyDataToBuf((uint8_t *)templateIdStr, strlen(templateIdStr), (uint8_t **)&buf, &bufLen) != RESULT_SUCCESS) {
216 LOG_ERROR("copy templateIdStr fail.");
217 return RESULT_BAD_COPY;
218 }
219 if (CopyDataToBuf((uint8_t *)suffix, strlen(suffix), (uint8_t **)&buf, &bufLen) != RESULT_SUCCESS) {
220 LOG_ERROR("copy suffix fail.");
221 return RESULT_BAD_COPY;
222 }
223 if (bufLen == 0) {
224 LOG_ERROR("no space for endl.");
225 return RESULT_BAD_COPY;
226 }
227
228 LOG_INFO("GenerateFileName succ.");
229 return RESULT_SUCCESS;
230 }
231
232 /* This is for example only, Should be implemented in trusted environment. */
ReadPinFile(uint8_t * data,uint32_t dataLen,uint64_t templateId,const char * suffix)233 static ResultCode ReadPinFile(uint8_t *data, uint32_t dataLen, uint64_t templateId, const char *suffix)
234 {
235 FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
236 if (!IsFileOperatorValid(fileOp)) {
237 LOG_ERROR("fileOp invalid.");
238 return RESULT_GENERAL_ERROR;
239 }
240
241 char fileName[MAX_FILE_NAME_LEN] = {'\0'};
242 ResultCode ret = GenerateFileName(templateId, DEFAULT_FILE_HEAD, suffix, fileName, MAX_FILE_NAME_LEN);
243 if (ret != RESULT_SUCCESS) {
244 LOG_ERROR("ReadPinFile Generate Pin FileName fail.");
245 return RESULT_GENERAL_ERROR;
246 }
247 ret = fileOp->readFile(fileName, data, dataLen);
248 if (ret != RESULT_SUCCESS) {
249 LOG_ERROR("read pin file fail.");
250 return ret;
251 }
252
253 return RESULT_SUCCESS;
254 }
255
256 /* This is for example only, Should be implemented in trusted environment. */
WritePinFile(const uint8_t * data,uint32_t dataLen,uint64_t templateId,const char * suffix)257 static ResultCode WritePinFile(const uint8_t *data, uint32_t dataLen, uint64_t templateId, const char *suffix)
258 {
259 FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
260 if (!IsFileOperatorValid(fileOp)) {
261 LOG_ERROR("fileOp invalid.");
262 return RESULT_GENERAL_ERROR;
263 }
264
265 char fileName[MAX_FILE_NAME_LEN] = {'\0'};
266 ResultCode ret = GenerateFileName(templateId, DEFAULT_FILE_HEAD, suffix, fileName, MAX_FILE_NAME_LEN);
267 if (ret != RESULT_SUCCESS) {
268 LOG_ERROR("WritePinFile Generate Pin FileName fail.");
269 return RESULT_GENERAL_ERROR;
270 }
271 ret = fileOp->writeFile(fileName, data, dataLen);
272 if (ret != RESULT_SUCCESS) {
273 LOG_ERROR("WritePinFile fail.");
274 return ret;
275 }
276 LOG_INFO("WritePinFile succ.");
277
278 return RESULT_SUCCESS;
279 }
280
CoverData(const char * fileName,const FileOperator * fileOp)281 static ResultCode CoverData(const char *fileName, const FileOperator *fileOp)
282 {
283 uint32_t fileLen = 0;
284 ResultCode ret = (ResultCode)fileOp->getFileLen(fileName, &fileLen);
285 /* The maximum length of the fileName is CONST_PIN_DATA_EXPAND_LEN */
286 if (ret != RESULT_SUCCESS || fileLen > CONST_PIN_DATA_EXPAND_LEN) {
287 LOG_ERROR("getFileLen fail.");
288 return ret;
289 }
290 uint8_t *data = Malloc(fileLen);
291 if (data == NULL) {
292 LOG_ERROR("no memory.");
293 return RESULT_NO_MEMORY;
294 }
295 (void)memset_s(data, fileLen, 0, fileLen);
296 ret = fileOp->writeFile(fileName, data, fileLen);
297 Free(data);
298 if (ret != RESULT_SUCCESS) {
299 LOG_ERROR("WritePinFile fail.");
300 return ret;
301 }
302
303 return RESULT_SUCCESS;
304 }
305
306 /* This is for example only, Should be implemented in trusted environment. */
RemovePinFile(const uint64_t templateId,const char * suffix,bool needCover)307 static ResultCode RemovePinFile(const uint64_t templateId, const char *suffix, bool needCover)
308 {
309 FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
310 if (!IsFileOperatorValid(fileOp)) {
311 LOG_ERROR("fileOp invalid.");
312 return RESULT_GENERAL_ERROR;
313 }
314 char fileName[MAX_FILE_NAME_LEN] = {'\0'};
315 ResultCode ret = GenerateFileName(templateId, DEFAULT_FILE_HEAD, suffix, fileName, MAX_FILE_NAME_LEN);
316 if (ret != RESULT_SUCCESS) {
317 LOG_ERROR("GenerateCryptoFileName fail.");
318 return RESULT_UNKNOWN;
319 }
320
321 /* Write data zeros before deleting data, In addition to anti-brute-force cracking */
322 if (needCover) {
323 ret = CoverData(fileName, fileOp);
324 if (ret != RESULT_SUCCESS) {
325 LOG_ERROR("cover data fail.");
326 return RESULT_GENERAL_ERROR;
327 }
328 }
329 if (fileOp->deleteFile(fileName) != RESULT_SUCCESS) {
330 LOG_ERROR("file remove fail.");
331 return RESULT_BAD_DEL;
332 }
333
334 LOG_INFO("RemovePinFile succ.");
335 return ret;
336 }
337
RemoveAllFile(const uint64_t templateId)338 static ResultCode RemoveAllFile(const uint64_t templateId)
339 {
340 /* This is for example only, Anti-brute-force cracking files must have an anti-rollback zone */
341 ResultCode ret = RemovePinFile(templateId, ANTI_BRUTE_SUFFIX, false);
342 if (ret != RESULT_SUCCESS) {
343 LOG_ERROR("RemovePinAntiBrute fail.");
344 }
345 ret = RemovePinFile(templateId, CRYPTO_SUFFIX, true);
346 if (ret != RESULT_SUCCESS) {
347 LOG_ERROR("RemovePinCrypto fail.");
348 return ret;
349 }
350 ret = RemovePinFile(templateId, SALT_SUFFIX, true);
351 if (ret != RESULT_SUCCESS) {
352 LOG_ERROR("RemovePinSalt fail.");
353 }
354 ret = RemovePinFile(templateId, SECRET_SUFFIX, true);
355 if (ret != RESULT_SUCCESS) {
356 LOG_ERROR("RemovePinSecret fail.");
357 }
358
359 LOG_INFO("RemoveAllFile succ.");
360 return RESULT_SUCCESS;
361 }
362
GeneratePinTemplateId()363 static uint64_t GeneratePinTemplateId()
364 {
365 for (uint32_t i = 0; i < MAX_RANDOM_TIME; i++) {
366 uint64_t templateId = INVALID_TEMPLATE_ID;
367 SecureRandom((uint8_t *)&templateId, sizeof(templateId));
368 if (templateId == INVALID_TEMPLATE_ID) {
369 continue;
370 }
371 uint32_t j = 0;
372 for (; j < g_pinDbOp.pinIndexLen; j++) {
373 if (templateId == g_pinDbOp.pinIndex[i].templateId) {
374 break;
375 }
376 }
377 if (j == g_pinDbOp.pinIndexLen) {
378 return templateId;
379 }
380 }
381 LOG_ERROR("fail generate pin templateid.");
382 return INVALID_TEMPLATE_ID;
383 }
384
SearchPinById(const uint64_t templateId)385 static uint32_t SearchPinById(const uint64_t templateId)
386 {
387 if (g_pinDbOp.pinIndexLen == 0) {
388 LOG_ERROR("no pin exist.");
389 return MAX_CRYPTO_INFO_SIZE;
390 }
391 for (uint32_t index = 0; index < g_pinDbOp.pinIndexLen; index++) {
392 if (g_pinDbOp.pinIndex[index].templateId == templateId) {
393 LOG_INFO("SearchPinById succ.");
394 return index;
395 }
396 }
397 LOG_ERROR("no pin match.");
398 return MAX_CRYPTO_INFO_SIZE;
399 }
400
DelPin(const uint32_t index)401 static ResultCode DelPin(const uint32_t index)
402 {
403 /* This is for example only, Should be implemented in trusted environment. */
404 ResultCode ret = RemoveAllFile(g_pinDbOp.pinIndex[index].templateId);
405 if (ret != RESULT_SUCCESS) {
406 LOG_ERROR("Remove pin file fail.");
407 return ret;
408 }
409
410 LOG_INFO("DelPin succ.");
411 return RESULT_SUCCESS;
412 }
413
IsPinDbValid(PinDb * pinDb)414 static bool IsPinDbValid(PinDb *pinDb)
415 {
416 if (pinDb == NULL) {
417 return false;
418 }
419 if (pinDb->version != CURRENT_VERSION) {
420 return false;
421 }
422 if ((pinDb->pinIndexLen == 0) && (pinDb->pinIndex != NULL)) {
423 return false;
424 }
425 if ((pinDb->pinIndexLen != 0) && (pinDb->pinIndex == NULL)) {
426 return false;
427 }
428 if (pinDb->pinIndexLen > MAX_CRYPTO_INFO_SIZE) {
429 return false;
430 }
431 return true;
432 }
433
GetBufFromData(uint8_t * src,uint32_t srcLen,uint8_t ** dest,uint32_t * destLen)434 static ResultCode GetBufFromData(uint8_t *src, uint32_t srcLen, uint8_t **dest, uint32_t *destLen)
435 {
436 if (srcLen > *destLen) {
437 LOG_ERROR("bad len.");
438 return RESULT_BAD_PARAM;
439 }
440 if (memcpy_s(*dest, *destLen, src, srcLen) != EOK) {
441 LOG_ERROR("copy fail.");
442 return RESULT_BAD_COPY;
443 }
444
445 *dest = *dest + srcLen;
446 *destLen = *destLen - srcLen;
447 return RESULT_SUCCESS;
448 }
449
WritePinDb()450 static ResultCode WritePinDb()
451 {
452 if (!IsPinDbValid(&g_pinDbOp)) {
453 LOG_ERROR("get invalid params.");
454 return RESULT_BAD_PARAM;
455 }
456 ResultCode ret = RESULT_SUCCESS;
457 FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
458 if (!IsFileOperatorValid(fileOp)) {
459 LOG_ERROR("fileOp invalid.");
460 return RESULT_GENERAL_ERROR;
461 }
462
463 uint32_t dataLen = sizeof(PinIndex) * g_pinDbOp.pinIndexLen + sizeof(uint32_t) * PIN_DB_TWO_PARAMS;
464 uint8_t *data = Malloc(dataLen);
465 if (data == NULL) {
466 LOG_ERROR("malloc data fail.");
467 return RESULT_GENERAL_ERROR;
468 }
469 uint8_t *temp = data;
470 uint32_t tempLen = dataLen;
471 if (GetBufFromData((uint8_t *)&(g_pinDbOp.version), sizeof(g_pinDbOp.version), &temp, &tempLen) != RESULT_SUCCESS) {
472 ret = RESULT_BAD_WRITE;
473 goto ERROR;
474 }
475
476 if (GetBufFromData((uint8_t *)&(g_pinDbOp.pinIndexLen), sizeof(g_pinDbOp.pinIndexLen),
477 &temp, &tempLen) != RESULT_SUCCESS) {
478 ret = RESULT_BAD_WRITE;
479 goto ERROR;
480 }
481 if (g_pinDbOp.pinIndexLen != 0) {
482 if (memcpy_s(temp, tempLen, g_pinDbOp.pinIndex, (sizeof(PinIndex) * g_pinDbOp.pinIndexLen)) != EOK) {
483 ret = RESULT_BAD_WRITE;
484 goto ERROR;
485 }
486 }
487
488 if (fileOp->writeFile(PIN_INDEX_NAME, data, dataLen) != RESULT_SUCCESS) {
489 LOG_ERROR("write_parcel_into_file failed.");
490 ret = RESULT_BAD_WRITE;
491 goto ERROR;
492 }
493 LOG_INFO("WritePinDb succ.");
494
495 ERROR:
496 (void)memset_s(data, dataLen, 0, dataLen);
497 Free(data);
498 return ret;
499 }
500
DelPinInDb(const uint32_t index)501 static ResultCode DelPinInDb(const uint32_t index)
502 {
503 uint32_t pinIndexLen = g_pinDbOp.pinIndexLen - 1;
504 if (pinIndexLen == 0) {
505 (void)memset_s(g_pinDbOp.pinIndex,
506 g_pinDbOp.pinIndexLen * sizeof(PinIndex), 0, g_pinDbOp.pinIndexLen * sizeof(PinIndex));
507 Free(g_pinDbOp.pinIndex);
508 g_pinDbOp.pinIndex = NULL;
509 } else {
510 uint32_t size = pinIndexLen * sizeof(PinIndex);
511 PinIndex *pinIndex = (PinIndex *)Malloc(size);
512 if (pinIndex == NULL) {
513 LOG_ERROR("PinIndex malloc fail.");
514 return RESULT_NO_MEMORY;
515 }
516 (void)memset_s(pinIndex, size, 0, size);
517 for (uint32_t i = 0, j = 0; i < g_pinDbOp.pinIndexLen; i++) {
518 if (i != index) {
519 pinIndex[j] = g_pinDbOp.pinIndex[i];
520 j++;
521 }
522 }
523 (void)memset_s(g_pinDbOp.pinIndex,
524 g_pinDbOp.pinIndexLen * sizeof(PinIndex), 0, g_pinDbOp.pinIndexLen * sizeof(PinIndex));
525 Free(g_pinDbOp.pinIndex);
526 g_pinDbOp.pinIndex = pinIndex;
527 }
528 g_pinDbOp.pinIndexLen = pinIndexLen;
529 ResultCode ret = WritePinDb();
530 if (ret != RESULT_SUCCESS) {
531 LOG_ERROR("WritePinDb fail.");
532 }
533
534 LOG_INFO("DelPinInDb succ.");
535 return ret;
536 }
537
DelPinById(const uint64_t templateId)538 ResultCode DelPinById(const uint64_t templateId)
539 {
540 ResultCode ret = LoadPinDb();
541 if (ret != RESULT_SUCCESS) {
542 LOG_ERROR("LoadPinDb fail.");
543 return ret;
544 }
545 uint32_t index = SearchPinById(templateId);
546 if (index == MAX_CRYPTO_INFO_SIZE) {
547 LOG_ERROR("no pin match.");
548 return RESULT_BAD_MATCH;
549 }
550
551 ret = DelPin(index);
552 if (ret != RESULT_SUCCESS) {
553 LOG_ERROR(" DelPin fail.");
554 return ret;
555 }
556 ret = DelPinInDb(index);
557 if (ret != RESULT_SUCCESS) {
558 LOG_ERROR("DelPinInDb fail.");
559 return ret;
560 }
561 LOG_INFO("DelPinById succ.");
562 /* ignore index file remove result, return success when crypto file remove success */
563 return ret;
564 }
565
InitPinIndex(PinIndex * pinIndex,uint64_t templateId,uint64_t subType)566 static void InitPinIndex(PinIndex *pinIndex, uint64_t templateId, uint64_t subType)
567 {
568 pinIndex->templateId = templateId;
569 pinIndex->subType = subType;
570 }
571
AddPinInDb(uint64_t templateId,uint64_t subType)572 static ResultCode AddPinInDb(uint64_t templateId, uint64_t subType)
573 {
574 if (g_pinDbOp.pinIndexLen + 1 > MAX_CRYPTO_INFO_SIZE) {
575 LOG_ERROR("pinIndexLen too large.");
576 return RESULT_BAD_PARAM;
577 }
578 uint32_t size = (g_pinDbOp.pinIndexLen + 1) * sizeof(PinIndex);
579 PinIndex *pinIndex = (PinIndex *)Malloc(size);
580 if (pinIndex == NULL) {
581 LOG_ERROR("PinIndex malloc fail.");
582 return RESULT_NO_MEMORY;
583 }
584 (void)memset_s(pinIndex, size, 0, size);
585 if (g_pinDbOp.pinIndexLen != 0) {
586 if (memcpy_s(pinIndex, size,
587 g_pinDbOp.pinIndex, g_pinDbOp.pinIndexLen * sizeof(PinIndex)) != EOK) {
588 LOG_ERROR("PinIndex copy fail.");
589 (void)memset_s(pinIndex, size, 0, size);
590 Free(pinIndex);
591 return RESULT_NO_MEMORY;
592 }
593 }
594 InitPinIndex(&pinIndex[g_pinDbOp.pinIndexLen], templateId, subType);
595 if (g_pinDbOp.pinIndex != NULL) {
596 Free(g_pinDbOp.pinIndex);
597 }
598 g_pinDbOp.pinIndex = pinIndex;
599 g_pinDbOp.pinIndexLen++;
600 ResultCode ret = WritePinDb();
601 if (ret != RESULT_SUCCESS) {
602 LOG_ERROR("WritePinDb fail.");
603 }
604
605 LOG_INFO("AddPinInDb succ.");
606 return ret;
607 }
608
RefreshPinDb(uint64_t * templateId,uint64_t subType)609 static ResultCode RefreshPinDb(uint64_t *templateId, uint64_t subType)
610 {
611 ResultCode ret = LoadPinDb();
612 if (ret != RESULT_SUCCESS) {
613 LOG_ERROR("LoadPinDb fail.");
614 return ret;
615 }
616 *templateId = GeneratePinTemplateId();
617 if (*templateId == INVALID_TEMPLATE_ID) {
618 LOG_ERROR("GeneratePinTemplateId fail.");
619 return RESULT_UNKNOWN;
620 }
621 ret = AddPinInDb(*templateId, subType);
622 if (ret != RESULT_SUCCESS) {
623 LOG_ERROR("AddPinDb fail.");
624 return ret;
625 }
626
627 LOG_INFO("RefreshPinDb succ.");
628 return ret;
629 }
630
InitAntiBruteInfo(AntiBruteInfo * info)631 static ResultCode InitAntiBruteInfo(AntiBruteInfo *info)
632 {
633 info->authErrorConut = INIT_AUTH_ERROR_COUNT;
634 info->startFreezeTime = INIT_START_FREEZE_TIMES;
635 return RESULT_SUCCESS;
636 }
637
WriteAddPinInfo(const Buffer * secret,const Buffer * pinCredentialData,const uint8_t * salt,uint32_t saltLen,const uint64_t templateId)638 static ResultCode WriteAddPinInfo(const Buffer *secret, const Buffer *pinCredentialData, const uint8_t *salt,
639 uint32_t saltLen, const uint64_t templateId)
640 {
641 ResultCode ret = WritePinFile(pinCredentialData->buf, pinCredentialData->contentSize, templateId, CRYPTO_SUFFIX);
642 if (ret != RESULT_SUCCESS) {
643 LOG_ERROR("WriteCryptoFile fail.");
644 return ret;
645 }
646
647 ret = WritePinFile(salt, saltLen, templateId, SALT_SUFFIX);
648 if (ret != RESULT_SUCCESS) {
649 LOG_ERROR("WriteSaltFile fail.");
650 return ret;
651 }
652
653 ret = WritePinFile(secret->buf, secret->contentSize, templateId, SECRET_SUFFIX);
654 if (ret != RESULT_SUCCESS) {
655 LOG_ERROR("WriteSecretFile fail.");
656 return ret;
657 }
658 AntiBruteInfo *initAntiBrute = Malloc(sizeof(AntiBruteInfo));
659 if (initAntiBrute == NULL) {
660 LOG_ERROR("malloc PAntiBruteInfo data fail.");
661 return RESULT_GENERAL_ERROR;
662 }
663 ret = InitAntiBruteInfo(initAntiBrute);
664 if (ret != RESULT_SUCCESS) {
665 LOG_ERROR("InitAntiBruteInfo fail.");
666 goto EXIT;
667 }
668 ret = WritePinFile((uint8_t *)initAntiBrute, sizeof(AntiBruteInfo), templateId, ANTI_BRUTE_SUFFIX);
669 if (ret != RESULT_SUCCESS) {
670 LOG_ERROR("WriteAntiBruteFile fail.");
671 goto EXIT;
672 }
673
674 EXIT:
675 Free(initAntiBrute);
676 return ret;
677 }
678
GenerateExpandData(const char * str,const uint8_t * data,const uint32_t dataLen)679 static Buffer *GenerateExpandData(const char *str, const uint8_t *data, const uint32_t dataLen)
680 {
681 /* CONST_EXPAND_DATA_LEN is twice the size of dataLen */
682 if (strlen(str) > dataLen || (CONST_EXPAND_DATA_LEN / 2) != dataLen) {
683 LOG_ERROR("bad param.");
684 return NULL;
685 }
686 Buffer *outBuff = CreateBufferBySize(CONST_EXPAND_DATA_LEN);
687 if (!IsBufferValid(outBuff)) {
688 LOG_ERROR("create buffer fail.");
689 return NULL;
690 }
691 (void)memset_s(outBuff->buf, outBuff->maxSize, 0, outBuff->maxSize);
692 outBuff->contentSize = outBuff->maxSize;
693 uint8_t *temp = outBuff->buf;
694 if (memcpy_s(temp, outBuff->maxSize, (uint8_t *)str, strlen(str)) != EOK) {
695 LOG_ERROR("copy str fail.");
696 DestoryBuffer(outBuff);
697 return NULL;
698 }
699
700 temp += dataLen;
701 if (memcpy_s(temp, outBuff->maxSize - dataLen, data, dataLen) != EOK) {
702 LOG_ERROR("copy data fail.");
703 DestoryBuffer(outBuff);
704 return NULL;
705 }
706
707 return outBuff;
708 }
709
GenerateRootSecret(const Buffer * deviceKey,const uint8_t * pinData,const uint32_t pinDataLen)710 static Buffer *GenerateRootSecret(const Buffer *deviceKey, const uint8_t *pinData, const uint32_t pinDataLen)
711 {
712 Buffer *expandData = GenerateExpandData(SALT_PREFIX, pinData, pinDataLen);
713 if (!IsBufferValid(expandData)) {
714 LOG_ERROR("generate expand data fail.");
715 return NULL;
716 }
717
718 Buffer *hkdfSalt = Sha256Adaptor(expandData);
719 if (!IsBufferValid(hkdfSalt)) {
720 LOG_ERROR("generate sha256 fail.");
721 DestoryBuffer(expandData);
722 return NULL;
723 }
724 Buffer *rootSecret = Hkdf(hkdfSalt, deviceKey);
725 DestoryBuffer(expandData);
726 DestoryBuffer(hkdfSalt);
727 if (!IsBufferValid(rootSecret)) {
728 LOG_ERROR("generate rootSecret fail.");
729 return NULL;
730 }
731
732 return rootSecret;
733 }
734
GenerateEncryptionKey(const Buffer * deviceKey)735 static Buffer *GenerateEncryptionKey(const Buffer *deviceKey)
736 {
737 Buffer *keyStrBuffer = CreateBufferBySize(CONST_CREDENTIAL_PREFIX_LEN);
738 if (!IsBufferValid(keyStrBuffer)) {
739 LOG_ERROR("generate expand data fail.");
740 return NULL;
741 }
742 (void)memset_s(keyStrBuffer->buf, keyStrBuffer->maxSize, 0, keyStrBuffer->maxSize);
743 if (memcpy_s(keyStrBuffer->buf, keyStrBuffer->maxSize,
744 (uint8_t *)CREDENTIAL_PREFIX, strlen(CREDENTIAL_PREFIX)) != EOK) {
745 LOG_ERROR("copy CREDENTIAL_PREFIX fail.");
746 DestoryBuffer(keyStrBuffer);
747 return NULL;
748 }
749 keyStrBuffer->contentSize = keyStrBuffer->maxSize;
750 Buffer *encryptionKey = Hkdf(keyStrBuffer, deviceKey);
751 DestoryBuffer(keyStrBuffer);
752 if (!IsBufferValid(encryptionKey)) {
753 LOG_ERROR("generate encryptionKey fail.");
754 return NULL;
755 }
756
757 return encryptionKey;
758 }
759
ProcessAddPin(const Buffer * deviceKey,const Buffer * secret,PinEnrollParam * pinEnrollParam,uint64_t templateId)760 static ResultCode ProcessAddPin(const Buffer *deviceKey, const Buffer *secret, PinEnrollParam *pinEnrollParam,
761 uint64_t templateId)
762 {
763 Buffer *encryptionKey = GenerateEncryptionKey(deviceKey);
764 if (!IsBufferValid(encryptionKey)) {
765 LOG_ERROR("generate encryptionKey fail.");
766 return RESULT_GENERAL_ERROR;
767 }
768 Buffer *pinDataBuffer = CreateBufferByData(pinEnrollParam->pinData, CONST_PIN_DATA_LEN);
769 if (!IsBufferValid(pinDataBuffer)) {
770 LOG_ERROR("generate pinDataBuffer fail.");
771 DestoryBuffer(encryptionKey);
772 return RESULT_GENERAL_ERROR;
773 }
774 Buffer *pinCredCiphertext = Aes256GcmEncryptNoPadding(pinDataBuffer, encryptionKey);
775 if (!IsBufferValid(pinCredCiphertext)) {
776 LOG_ERROR("generate pinCredCiphertext fail.");
777 DestoryBuffer(encryptionKey);
778 DestoryBuffer(pinDataBuffer);
779 return RESULT_GENERAL_ERROR;
780 }
781
782 ResultCode ret = WriteAddPinInfo(secret, pinCredCiphertext, pinEnrollParam->salt, CONST_SALT_LEN, templateId);
783 DestoryBuffer(encryptionKey);
784 DestoryBuffer(pinDataBuffer);
785 DestoryBuffer(pinCredCiphertext);
786 if (ret != RESULT_SUCCESS) {
787 LOG_ERROR("write add pin info fail.");
788 }
789
790 return ret;
791 }
792
793 /* This is for example only, Should be implemented in trusted environment. */
AddPin(PinEnrollParam * pinEnrollParam,uint64_t * templateId,Buffer * outRootSecret)794 ResultCode AddPin(PinEnrollParam *pinEnrollParam, uint64_t *templateId, Buffer *outRootSecret)
795 {
796 if (pinEnrollParam == NULL || templateId == NULL || !IsBufferValid(outRootSecret)) {
797 LOG_ERROR("get invalid params.");
798 return RESULT_BAD_PARAM;
799 }
800 ResultCode ret = RefreshPinDb(templateId, pinEnrollParam->subType);
801 if (ret != RESULT_SUCCESS) {
802 LOG_ERROR("refresh pinDb fail.");
803 return ret;
804 }
805 Buffer *secret = CreateBufferBySize(SECRET_SIZE);
806 if (!IsBufferValid(secret) || SecureRandom(secret->buf, secret->maxSize) != RESULT_SUCCESS) {
807 LOG_ERROR("generate secure random number fail.");
808 DestoryBuffer(secret);
809 return RESULT_GENERAL_ERROR;
810 }
811 secret->contentSize = secret->maxSize;
812 Buffer *deviceKey = DeriveDeviceKey(secret);
813 if (!IsBufferValid(deviceKey)) {
814 LOG_ERROR("generate deviceKey fail.");
815 DestoryBuffer(secret);
816 return RESULT_GENERAL_ERROR;
817 }
818 Buffer *temp = GenerateRootSecret(deviceKey, pinEnrollParam->pinData, CONST_PIN_DATA_LEN);
819 if (!IsBufferValid(temp)) {
820 LOG_ERROR("generate rootSecret fail.");
821 DestoryBuffer(secret);
822 DestoryBuffer(deviceKey);
823 return RESULT_GENERAL_ERROR;
824 }
825 if (memcpy_s(outRootSecret->buf, outRootSecret->maxSize, temp->buf, temp->contentSize) != EOK) {
826 LOG_ERROR("copy temp buffer fail.");
827 ret = RESULT_GENERAL_ERROR;
828 goto ERROR;
829 }
830 outRootSecret->contentSize = temp->contentSize;
831 ret = ProcessAddPin(deviceKey, secret, pinEnrollParam, *templateId);
832 if (ret != RESULT_SUCCESS) {
833 LOG_ERROR("process add pin fail.");
834 goto ERROR;
835 }
836 LOG_INFO("AddPin succ.");
837
838 ERROR:
839 DestoryBuffer(secret);
840 DestoryBuffer(deviceKey);
841 DestoryBuffer(temp);
842 return ret;
843 }
844
DoGetSalt(const uint64_t templateId,uint8_t * salt,uint32_t * saltLen)845 ResultCode DoGetSalt(const uint64_t templateId, uint8_t *salt, uint32_t *saltLen)
846 {
847 if (salt == NULL || saltLen == NULL || templateId == INVALID_TEMPLATE_ID) {
848 LOG_ERROR("get invalid salt params.");
849 return RESULT_BAD_PARAM;
850 }
851
852 uint32_t index = SearchPinById(templateId);
853 if (index == MAX_CRYPTO_INFO_SIZE) {
854 LOG_ERROR(" no pin match.");
855 return RESULT_BAD_MATCH;
856 }
857
858 ResultCode ret = ReadPinFile(salt, *saltLen, templateId, SALT_SUFFIX);
859 if (ret != RESULT_SUCCESS) {
860 LOG_ERROR("salt file read fail.");
861 return ret;
862 }
863 LOG_INFO("DoGetSalt succ.");
864 return RESULT_SUCCESS;
865 }
866
GetAntiBruteCountById(uint64_t templateId,uint32_t * count)867 static ResultCode GetAntiBruteCountById(uint64_t templateId, uint32_t *count)
868 {
869 ResultCode ret = LoadPinDb();
870 if (ret != RESULT_SUCCESS) {
871 LOG_ERROR("LoadPinDb fail.");
872 return ret;
873 }
874
875 uint32_t index = SearchPinById(templateId);
876 if (index == MAX_CRYPTO_INFO_SIZE) {
877 LOG_ERROR("no pin index match.");
878 return RESULT_BAD_MATCH;
879 }
880
881 AntiBruteInfo initAntiBrute = {INIT_AUTH_ERROR_COUNT, INIT_START_FREEZE_TIMES};
882 ret = ReadPinFile((uint8_t *)&initAntiBrute, sizeof(AntiBruteInfo), templateId, ANTI_BRUTE_SUFFIX);
883 if (ret != RESULT_SUCCESS) {
884 LOG_ERROR("read AntiBrute startFreezeTime fail.");
885 return ret;
886 }
887 *count = initAntiBrute.authErrorConut;
888
889 return ret;
890 }
891
SetAntiBruteInfoById(uint64_t templateId,uint32_t count,uint64_t startFreezeTime)892 static ResultCode SetAntiBruteInfoById(uint64_t templateId, uint32_t count, uint64_t startFreezeTime)
893 {
894 ResultCode ret = LoadPinDb();
895 if (ret != RESULT_SUCCESS) {
896 LOG_ERROR("LoadPinDb fail.");
897 return ret;
898 }
899
900 uint32_t index = SearchPinById(templateId);
901 if (index == MAX_CRYPTO_INFO_SIZE) {
902 LOG_ERROR(" no pin match.");
903 return RESULT_BAD_MATCH;
904 }
905
906 AntiBruteInfo initAntiBrute = {count, startFreezeTime};
907 ret = WritePinFile((uint8_t *)&initAntiBrute, sizeof(AntiBruteInfo), templateId, ANTI_BRUTE_SUFFIX);
908 if (ret != RESULT_SUCCESS) {
909 LOG_ERROR("write AntiBruteFileName fail.");
910 return ret;
911 }
912 return ret;
913 }
914
GetSubType(uint64_t templateId,uint64_t * subType)915 ResultCode GetSubType(uint64_t templateId, uint64_t *subType)
916 {
917 if (templateId == INVALID_TEMPLATE_ID) {
918 LOG_ERROR("check param fail!");
919 return RESULT_BAD_PARAM;
920 }
921
922 uint32_t index = SearchPinById(templateId);
923 if (index == MAX_CRYPTO_INFO_SIZE) {
924 LOG_ERROR("no pin match.");
925 return RESULT_BAD_MATCH;
926 }
927 *subType = g_pinDbOp.pinIndex[index].subType;
928
929 LOG_INFO("GetSubType succ.");
930 return RESULT_SUCCESS;
931 }
932
GetAntiBruteInfo(uint64_t templateId,uint32_t * authErrorConut,uint64_t * startFreezeTime)933 ResultCode GetAntiBruteInfo(uint64_t templateId, uint32_t *authErrorConut, uint64_t *startFreezeTime)
934 {
935 if (authErrorConut == NULL || startFreezeTime == NULL || templateId == INVALID_TEMPLATE_ID) {
936 LOG_ERROR("check GetAntiBruteInfo param fail!");
937 return RESULT_BAD_PARAM;
938 }
939
940 uint32_t index = SearchPinById(templateId);
941 if (index == MAX_CRYPTO_INFO_SIZE) {
942 LOG_ERROR("no pin match.");
943 return RESULT_BAD_MATCH;
944 }
945
946 AntiBruteInfo initAntiBrute = {INIT_AUTH_ERROR_COUNT, INIT_START_FREEZE_TIMES};
947 ResultCode ret = ReadPinFile((uint8_t *)&initAntiBrute, sizeof(AntiBruteInfo), templateId, ANTI_BRUTE_SUFFIX);
948 if (ret != RESULT_SUCCESS) {
949 LOG_ERROR("read AntiBrute startFreezeTime fail.");
950 return ret;
951 }
952 *authErrorConut = initAntiBrute.authErrorConut;
953 *startFreezeTime = initAntiBrute.startFreezeTime;
954
955 LOG_INFO("GetAntiBruteInfo succ.");
956 return ret;
957 }
958
ExponentialFuncTime(uint32_t authErrorConut)959 static uint64_t ExponentialFuncTime(uint32_t authErrorConut)
960 {
961 uint32_t ret = DEFAULT_VALUE;
962 uint32_t exp = (authErrorConut - FIRST_EXPONENTIAL_PARA) / THIRD_EXPONENTIAL_PARA;
963 for (uint32_t index = 0; index < exp; ++index) {
964 ret *= SECOND_EXPONENTIAL_PARA;
965 }
966 return FIRST_EXPONENTIAL_PARA * ret;
967 }
968
GetWaitTime(const uint32_t authErrorConut)969 static uint64_t GetWaitTime(const uint32_t authErrorConut)
970 {
971 if (authErrorConut < FIRST_ANTI_BRUTE_COUNT) {
972 return 0;
973 }
974 if (authErrorConut < ATTI_BRUTE_FIRST_STAGE) {
975 if (authErrorConut == FIRST_ANTI_BRUTE_COUNT) {
976 return ONE_MIN_TIME * MS_OF_S;
977 }
978 if (authErrorConut == SECOND_ANTI_BRUTE_COUNT) {
979 return TEN_MIN_TIME * MS_OF_S;
980 }
981 if (authErrorConut == THIRD_ANTI_BRUTE_COUNT) {
982 return THIRTY_MIN_TIME * MS_OF_S;
983 }
984 if (((authErrorConut - FIRST_ANTI_BRUTE_COUNT) % ANTI_BRUTE_COUNT_FREQUENCY) == 0) {
985 return ONE_HOUR_TIME * MS_OF_S;
986 }
987 return 0;
988 }
989 if (authErrorConut > ATTI_BRUTE_SECOND_STAGE) {
990 return ONE_DAY_TIME * MS_OF_S;
991 }
992 return ExponentialFuncTime(authErrorConut) * MS_OF_S;
993 }
994
ComputeFreezeTime(uint64_t templateId,uint32_t * freezeTime,uint32_t count,uint64_t startFreezeTime)995 ResultCode ComputeFreezeTime(uint64_t templateId, uint32_t *freezeTime, uint32_t count, uint64_t startFreezeTime)
996 {
997 if (templateId == INVALID_TEMPLATE_ID || freezeTime == NULL) {
998 LOG_ERROR("check ComputeFreezeTime param fail!");
999 return RESULT_BAD_PARAM;
1000 }
1001 uint64_t timeValue = GetRtcTime();
1002 uint64_t waitTime = GetWaitTime(count);
1003 if (timeValue >= startFreezeTime) {
1004 uint64_t usedTime = timeValue - startFreezeTime;
1005 if (usedTime >= waitTime) {
1006 *freezeTime = 0;
1007 } else {
1008 *freezeTime = waitTime - usedTime;
1009 }
1010 } else {
1011 /* rtc time is reset, we should update startFreezeTime to timeValue */
1012 if (SetAntiBruteInfoById(templateId, count, timeValue) != RESULT_SUCCESS) {
1013 LOG_ERROR("SetAntiBruteInfoById fail.");
1014 return RESULT_BAD_PARAM;
1015 }
1016 *freezeTime = waitTime;
1017 }
1018
1019 LOG_INFO("ComputeFreezeTime succ.");
1020 return RESULT_SUCCESS;
1021 }
1022
ComputeRemainingTimes(const uint32_t errorCount)1023 static uint32_t ComputeRemainingTimes(const uint32_t errorCount)
1024 {
1025 if (errorCount < FIRST_ANTI_BRUTE_COUNT) {
1026 return FIRST_ANTI_BRUTE_COUNT - errorCount;
1027 }
1028 if (errorCount >= ATTI_BRUTE_FIRST_STAGE) {
1029 return REMAINING_TIMES_FREEZE;
1030 }
1031 return ANTI_BRUTE_COUNT_FREQUENCY - (errorCount - FIRST_ANTI_BRUTE_COUNT) % ANTI_BRUTE_COUNT_FREQUENCY;
1032 }
1033
GetRemainTimes(uint64_t templateId,uint32_t * remainingAuthTimes,uint32_t authErrorConut)1034 ResultCode GetRemainTimes(uint64_t templateId, uint32_t *remainingAuthTimes, uint32_t authErrorConut)
1035 {
1036 if (templateId == INVALID_TEMPLATE_ID || remainingAuthTimes == NULL) {
1037 LOG_ERROR("check GetRemainTimes param fail!");
1038 return RESULT_BAD_PARAM;
1039 }
1040 *remainingAuthTimes = ComputeRemainingTimes(authErrorConut);
1041 return RESULT_SUCCESS;
1042 }
1043
ClearAntiBruteInfoById(uint64_t templateId)1044 static ResultCode ClearAntiBruteInfoById(uint64_t templateId)
1045 {
1046 uint32_t index = SearchPinById(templateId);
1047 if (index == MAX_CRYPTO_INFO_SIZE) {
1048 LOG_ERROR(" no pin match.");
1049 return RESULT_BAD_MATCH;
1050 }
1051 ResultCode ret = SetAntiBruteInfoById(templateId, 0, INIT_START_FREEZE_TIMES);
1052 if (ret != RESULT_SUCCESS) {
1053 LOG_ERROR("SetAntiBruteInfoById fail.");
1054 }
1055 return ret;
1056 }
1057
UpdateAntiBruteFile(uint64_t templateId,bool authResultSucc)1058 static ResultCode UpdateAntiBruteFile(uint64_t templateId, bool authResultSucc)
1059 {
1060 if (templateId == INVALID_TEMPLATE_ID) {
1061 LOG_ERROR("check param fail.");
1062 return RESULT_BAD_PARAM;
1063 }
1064
1065 if (authResultSucc) {
1066 ResultCode ret = ClearAntiBruteInfoById(templateId);
1067 if (ret != RESULT_SUCCESS) {
1068 LOG_ERROR("ClearAntiBruteInfoById fail.");
1069 }
1070 return ret;
1071 }
1072
1073 uint64_t nowTime = GetRtcTime();
1074 uint32_t errorCount = 0;
1075 ResultCode ret = GetAntiBruteCountById(templateId, &errorCount);
1076 if (ret != RESULT_SUCCESS) {
1077 LOG_ERROR("GetAntiBruteCountById fail.");
1078 return ret;
1079 }
1080 if (errorCount < ATTI_BRUTE_SECOND_STAGE) {
1081 errorCount++;
1082 }
1083 ret = SetAntiBruteInfoById(templateId, errorCount, nowTime);
1084 if (ret != RESULT_SUCCESS) {
1085 LOG_ERROR("SetAntiBruteInfoById fail.");
1086 }
1087 return ret;
1088 }
1089
CompareData(const uint8_t * inputData,const uint32_t inputDataLen,const uint8_t * storeData,const uint32_t storeDataLen)1090 static ResultCode CompareData(const uint8_t *inputData, const uint32_t inputDataLen, const uint8_t *storeData,
1091 const uint32_t storeDataLen)
1092 {
1093 if (inputDataLen != storeDataLen) {
1094 LOG_ERROR("get false len.");
1095 return RESULT_COMPARE_FAIL;
1096 }
1097 if (memcmp(inputData, storeData, inputDataLen) == 0) {
1098 LOG_INFO("auth pin success.");
1099 return RESULT_SUCCESS;
1100 }
1101 LOG_ERROR("auth pin fail.");
1102 return RESULT_COMPARE_FAIL;
1103 }
1104
GenerateDecodeCredential(const Buffer * deviceKey,const Buffer * pinData)1105 static Buffer *GenerateDecodeCredential(const Buffer *deviceKey, const Buffer *pinData)
1106 {
1107 Buffer *encryptionKey = GenerateEncryptionKey(deviceKey);
1108 if (!IsBufferValid(encryptionKey)) {
1109 LOG_ERROR("generate encryptionKey fail.");
1110 return NULL;
1111 }
1112
1113 Buffer *pinDecodeCredential = Aes256GcmDecryptNoPadding(pinData, encryptionKey);
1114 DestoryBuffer(encryptionKey);
1115 if (!IsBufferValid(pinDecodeCredential)) {
1116 LOG_ERROR("generate pinDeCredCiphertext fail.");
1117 return NULL;
1118 }
1119
1120 return pinDecodeCredential;
1121 }
1122
ProcessAuthPin(const Buffer * storeData,const uint8_t * inputData,const uint32_t inputDataLen,uint64_t templateId,Buffer * outRootSecret)1123 static Buffer *ProcessAuthPin(const Buffer *storeData, const uint8_t *inputData, const uint32_t inputDataLen,
1124 uint64_t templateId, Buffer *outRootSecret)
1125 {
1126 Buffer *secret = CreateBufferBySize(SECRET_SIZE);
1127 if (!IsBufferValid(secret)) {
1128 LOG_ERROR("generate secret fail.");
1129 return NULL;
1130 }
1131 if (ReadPinFile(secret->buf, secret->maxSize, templateId, SECRET_SUFFIX) != RESULT_SUCCESS) {
1132 LOG_ERROR("read pin secret file fail.");
1133 DestoryBuffer(secret);
1134 return NULL;
1135 }
1136 secret->contentSize = secret->maxSize;
1137 Buffer *deviceKey = DeriveDeviceKey(secret);
1138 if (!IsBufferValid(deviceKey)) {
1139 LOG_ERROR("generate deviceKey fail.");
1140 DestoryBuffer(secret);
1141 return NULL;
1142 }
1143 Buffer *temp = GenerateRootSecret(deviceKey, inputData, inputDataLen);
1144 if (!IsBufferValid(temp)) {
1145 LOG_ERROR("generate rootSecret fail.");
1146 DestoryBuffer(secret);
1147 DestoryBuffer(deviceKey);
1148 return NULL;
1149 }
1150 if (memcpy_s(outRootSecret->buf, outRootSecret->maxSize, temp->buf, temp->contentSize) != EOK) {
1151 LOG_ERROR("copy temp buffer fail");
1152 DestoryBuffer(secret);
1153 DestoryBuffer(deviceKey);
1154 DestoryBuffer(temp);
1155 return NULL;
1156 }
1157 outRootSecret->contentSize = temp->contentSize;
1158 Buffer *pinDecodeCredential = GenerateDecodeCredential(deviceKey, storeData);
1159 DestoryBuffer(secret);
1160 DestoryBuffer(deviceKey);
1161 DestoryBuffer(temp);
1162 if (!IsBufferValid(pinDecodeCredential)) {
1163 LOG_ERROR("generate pinDecodeCredential fail.");
1164 return NULL;
1165 }
1166
1167 return pinDecodeCredential;
1168 }
1169
1170 /* This is for example only, Should be implemented in trusted environment. */
AuthPinById(const uint8_t * inputData,const uint32_t inputDataLen,uint64_t templateId,Buffer * outRootSecret)1171 ResultCode AuthPinById(const uint8_t *inputData, const uint32_t inputDataLen, uint64_t templateId,
1172 Buffer *outRootSecret)
1173 {
1174 if (inputData == NULL || inputDataLen == 0 || templateId == INVALID_TEMPLATE_ID || !IsBufferValid(outRootSecret)) {
1175 LOG_ERROR("get invalid params.");
1176 return RESULT_BAD_PARAM;
1177 }
1178 if (SearchPinById(templateId) == MAX_CRYPTO_INFO_SIZE) {
1179 LOG_ERROR("no pin match.");
1180 return RESULT_BAD_MATCH;
1181 }
1182 /* Update anti-brute-force information with authentication failure first */
1183 if (UpdateAntiBruteFile(templateId, false) != RESULT_SUCCESS) {
1184 LOG_ERROR("update antiBrute file fail.");
1185 return RESULT_GENERAL_ERROR;
1186 }
1187 Buffer *storeData = CreateBufferBySize(CONST_PIN_DATA_EXPAND_LEN);
1188 if (!IsBufferValid(storeData)) {
1189 LOG_ERROR("generate storeData fail.");
1190 return RESULT_GENERAL_ERROR;
1191 }
1192 ResultCode ret = ReadPinFile(storeData->buf, storeData->maxSize, templateId, CRYPTO_SUFFIX);
1193 if (ret != RESULT_SUCCESS) {
1194 LOG_ERROR("read pin store file fail.");
1195 DestoryBuffer(storeData);
1196 return RESULT_BAD_READ;
1197 }
1198 storeData->contentSize = storeData->maxSize;
1199 Buffer *pinDecodeCredential = ProcessAuthPin(storeData, inputData, inputDataLen, templateId, outRootSecret);
1200 if (!IsBufferValid(pinDecodeCredential)) {
1201 LOG_ERROR("process auth pin fail.");
1202 ret = RESULT_GENERAL_ERROR;
1203 goto EXIT;
1204 }
1205 ResultCode compareRet = CompareData(pinDecodeCredential->buf, pinDecodeCredential->contentSize,
1206 inputData, inputDataLen);
1207 if (compareRet == RESULT_SUCCESS) {
1208 ret = UpdateAntiBruteFile(templateId, true);
1209 if (ret != RESULT_SUCCESS) {
1210 LOG_ERROR("UpdateAntiBruteFile fail.");
1211 goto EXIT;
1212 }
1213 } else {
1214 LOG_ERROR("CompareData fail.");
1215 ret = compareRet;
1216 }
1217 LOG_INFO("AuthPinById end.");
1218
1219 EXIT:
1220 DestoryBuffer(storeData);
1221 DestoryBuffer(pinDecodeCredential);
1222 return ret;
1223 }
1224
FindTemplateIdFromList(uint64_t storeTemplateId,const uint64_t * templateIdList,uint32_t templateIdListLen)1225 static bool FindTemplateIdFromList(uint64_t storeTemplateId, const uint64_t *templateIdList, uint32_t templateIdListLen)
1226 {
1227 for (uint32_t i = 0; i < templateIdListLen; ++i) {
1228 if (templateIdList[i] == storeTemplateId) {
1229 return true;
1230 }
1231 }
1232
1233 return false;
1234 }
1235
VerifyTemplateDataPin(const uint64_t * templateIdList,uint32_t templateIdListLen)1236 ResultCode VerifyTemplateDataPin(const uint64_t *templateIdList, uint32_t templateIdListLen)
1237 {
1238 if (templateIdListLen != 0 && templateIdList == NULL) {
1239 LOG_ERROR("templateIdList should be not null, when templateIdListLen is not zero");
1240 return RESULT_BAD_PARAM;
1241 }
1242 uint32_t i = 0;
1243 for (; i < g_pinDbOp.pinIndexLen; i++) {
1244 if (FindTemplateIdFromList(g_pinDbOp.pinIndex[i].templateId, templateIdList, templateIdListLen)) {
1245 continue;
1246 }
1247 ResultCode ret = DelPinById(g_pinDbOp.pinIndex[i].templateId);
1248 if (ret != RESULT_SUCCESS) {
1249 LOG_ERROR("delete pin file fail.");
1250 return RESULT_BAD_DEL;
1251 }
1252 }
1253 LOG_INFO("VerifyTemplateDataPin succ.");
1254 return RESULT_SUCCESS;
1255 }
1256