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