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, ¶m, &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, ¶m, &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 }