• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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