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