1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "pin_db.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include "securec.h" 19094332d3Sopenharmony_ci 20094332d3Sopenharmony_ci#include "adaptor_algorithm.h" 21094332d3Sopenharmony_ci#include "adaptor_memory.h" 22094332d3Sopenharmony_ci#include "adaptor_time.h" 23094332d3Sopenharmony_ci#include "defines.h" 24094332d3Sopenharmony_ci#include "file_operator.h" 25094332d3Sopenharmony_ci#include "pin_db_ops.h" 26094332d3Sopenharmony_ci 27094332d3Sopenharmony_ci#define MAX_RANDOM_TIME 10 28094332d3Sopenharmony_ci#define CRYPTO_SUFFIX "_CryptoInfo" 29094332d3Sopenharmony_ci#define SALT_SUFFIX "_salt" 30094332d3Sopenharmony_ci#define SECRET_SUFFIX "_secret" 31094332d3Sopenharmony_ci#define SALT_PREFIX "hkdf_salt" 32094332d3Sopenharmony_ci#define CREDENTIAL_PREFIX "template_encryption_key" 33094332d3Sopenharmony_ci#define DEFAULT_VALUE 1 34094332d3Sopenharmony_ci#define REMAINING_TIMES_FREEZE 1 35094332d3Sopenharmony_ci#define FIRST_ANTI_BRUTE_COUNT 5 36094332d3Sopenharmony_ci#define SECOND_ANTI_BRUTE_COUNT 8 37094332d3Sopenharmony_ci#define THIRD_ANTI_BRUTE_COUNT 11 38094332d3Sopenharmony_ci#define ANTI_BRUTE_COUNT_FREQUENCY 3 39094332d3Sopenharmony_ci#define ONE_MIN_TIME 60 40094332d3Sopenharmony_ci#define TEN_MIN_TIME 600 41094332d3Sopenharmony_ci#define THIRTY_MIN_TIME 1800 42094332d3Sopenharmony_ci#define ONE_HOUR_TIME 3600 43094332d3Sopenharmony_ci#define ONE_DAY_TIME 86400 44094332d3Sopenharmony_ci#define FIRST_EXPONENTIAL_PARA 30 45094332d3Sopenharmony_ci#define SECOND_EXPONENTIAL_PARA 2 46094332d3Sopenharmony_ci#define THIRD_EXPONENTIAL_PARA 10 47094332d3Sopenharmony_ci#define MS_OF_S 1000uLL 48094332d3Sopenharmony_ci#define CONST_PIN_DATA_EXPAND_LEN 92U 49094332d3Sopenharmony_ci#define CONST_CREDENTIAL_PREFIX_LEN 32U 50094332d3Sopenharmony_ci#define CONST_EXPAND_DATA_LEN 128U 51094332d3Sopenharmony_ci#define SOURCE_DATA_LENGTH 97 52094332d3Sopenharmony_ci#define DEVICE_UUID_LENGTH 65 53094332d3Sopenharmony_ci#define SALT_RANDOM_LENGTH 32 54094332d3Sopenharmony_ci 55094332d3Sopenharmony_cistatic PinDbV1 *g_pinDbOp = NULL; 56094332d3Sopenharmony_ci 57094332d3Sopenharmony_cibool LoadPinDb(void) 58094332d3Sopenharmony_ci{ 59094332d3Sopenharmony_ci if (g_pinDbOp != NULL) { 60094332d3Sopenharmony_ci return true; 61094332d3Sopenharmony_ci } 62094332d3Sopenharmony_ci g_pinDbOp = ReadPinDb(); 63094332d3Sopenharmony_ci if (g_pinDbOp == NULL) { 64094332d3Sopenharmony_ci LOG_ERROR("ReadPinDb fail."); 65094332d3Sopenharmony_ci return false; 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci 68094332d3Sopenharmony_ci LOG_INFO("LoadPinDb succ."); 69094332d3Sopenharmony_ci return true; 70094332d3Sopenharmony_ci} 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_civoid DestroyPinDb(void) 73094332d3Sopenharmony_ci{ 74094332d3Sopenharmony_ci if (g_pinDbOp == NULL) { 75094332d3Sopenharmony_ci LOG_INFO("g_pinDbOp is null."); 76094332d3Sopenharmony_ci return; 77094332d3Sopenharmony_ci } 78094332d3Sopenharmony_ci 79094332d3Sopenharmony_ci FreePinDb(&g_pinDbOp); 80094332d3Sopenharmony_ci LOG_INFO("DestroyPinDb succ."); 81094332d3Sopenharmony_ci} 82094332d3Sopenharmony_ci 83094332d3Sopenharmony_cistatic ResultCode CoverData(const char *fileName, const FileOperator *fileOp) 84094332d3Sopenharmony_ci{ 85094332d3Sopenharmony_ci uint32_t fileLen = 0; 86094332d3Sopenharmony_ci ResultCode ret = (ResultCode)fileOp->getFileLen(fileName, &fileLen); 87094332d3Sopenharmony_ci /* The maximum length of the fileName is CONST_PIN_DATA_EXPAND_LEN */ 88094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 89094332d3Sopenharmony_ci LOG_ERROR("getFileLen fail."); 90094332d3Sopenharmony_ci return ret; 91094332d3Sopenharmony_ci } 92094332d3Sopenharmony_ci if (fileLen > CONST_PIN_DATA_EXPAND_LEN) { 93094332d3Sopenharmony_ci LOG_ERROR("Filelen is larger than pin data expand len"); 94094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci uint8_t *data = Malloc(fileLen); 97094332d3Sopenharmony_ci if (data == NULL) { 98094332d3Sopenharmony_ci LOG_ERROR("no memory."); 99094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 100094332d3Sopenharmony_ci } 101094332d3Sopenharmony_ci (void)memset_s(data, fileLen, 0, fileLen); 102094332d3Sopenharmony_ci ret = (ResultCode)fileOp->writeFile(fileName, data, fileLen); 103094332d3Sopenharmony_ci Free(data); 104094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 105094332d3Sopenharmony_ci LOG_ERROR("WritePinFile fail."); 106094332d3Sopenharmony_ci return ret; 107094332d3Sopenharmony_ci } 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ci return RESULT_SUCCESS; 110094332d3Sopenharmony_ci} 111094332d3Sopenharmony_ci 112094332d3Sopenharmony_ci/* This is for example only, Should be implemented in trusted environment. */ 113094332d3Sopenharmony_cistatic ResultCode RemovePinFile(const uint64_t templateId, const char *suffix, bool needCover) 114094332d3Sopenharmony_ci{ 115094332d3Sopenharmony_ci FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR); 116094332d3Sopenharmony_ci if (!IsFileOperatorValid(fileOp)) { 117094332d3Sopenharmony_ci LOG_ERROR("fileOp invalid."); 118094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 119094332d3Sopenharmony_ci } 120094332d3Sopenharmony_ci char fileName[MAX_FILE_NAME_LEN] = {'\0'}; 121094332d3Sopenharmony_ci ResultCode ret = GenerateFileName(templateId, DEFAULT_FILE_HEAD, suffix, fileName, MAX_FILE_NAME_LEN); 122094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 123094332d3Sopenharmony_ci LOG_ERROR("GenerateCryptoFileName fail."); 124094332d3Sopenharmony_ci return RESULT_UNKNOWN; 125094332d3Sopenharmony_ci } 126094332d3Sopenharmony_ci 127094332d3Sopenharmony_ci /* Write data zeros before deleting data, In addition to anti-brute-force cracking */ 128094332d3Sopenharmony_ci if (needCover) { 129094332d3Sopenharmony_ci ret = CoverData(fileName, fileOp); 130094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 131094332d3Sopenharmony_ci LOG_ERROR("cover data fail."); 132094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 133094332d3Sopenharmony_ci } 134094332d3Sopenharmony_ci } 135094332d3Sopenharmony_ci if ((ResultCode)fileOp->deleteFile(fileName) != RESULT_SUCCESS) { 136094332d3Sopenharmony_ci LOG_ERROR("file remove fail."); 137094332d3Sopenharmony_ci return RESULT_BAD_DEL; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci 140094332d3Sopenharmony_ci LOG_INFO("RemovePinFile succ."); 141094332d3Sopenharmony_ci return ret; 142094332d3Sopenharmony_ci} 143094332d3Sopenharmony_ci 144094332d3Sopenharmony_cistatic ResultCode RemoveAllFile(uint64_t templateId) 145094332d3Sopenharmony_ci{ 146094332d3Sopenharmony_ci /* This is for example only, Anti-brute-force cracking files must have an anti-rollback zone */ 147094332d3Sopenharmony_ci ResultCode ret = RemovePinFile(templateId, ANTI_BRUTE_SUFFIX, false); 148094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 149094332d3Sopenharmony_ci LOG_ERROR("RemovePinAntiBrute fail."); 150094332d3Sopenharmony_ci } 151094332d3Sopenharmony_ci ret = RemovePinFile(templateId, CRYPTO_SUFFIX, true); 152094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 153094332d3Sopenharmony_ci LOG_ERROR("RemovePinCrypto fail."); 154094332d3Sopenharmony_ci } 155094332d3Sopenharmony_ci ret = RemovePinFile(templateId, SALT_SUFFIX, true); 156094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 157094332d3Sopenharmony_ci LOG_ERROR("RemovePinSalt fail."); 158094332d3Sopenharmony_ci } 159094332d3Sopenharmony_ci ret = RemovePinFile(templateId, SECRET_SUFFIX, true); 160094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 161094332d3Sopenharmony_ci LOG_ERROR("RemovePinSecret fail."); 162094332d3Sopenharmony_ci } 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ci LOG_INFO("RemoveAllFile end."); 165094332d3Sopenharmony_ci return RESULT_SUCCESS; 166094332d3Sopenharmony_ci} 167094332d3Sopenharmony_ci 168094332d3Sopenharmony_cistatic uint64_t GeneratePinTemplateId(void) 169094332d3Sopenharmony_ci{ 170094332d3Sopenharmony_ci for (uint32_t i = 0; i < MAX_RANDOM_TIME; i++) { 171094332d3Sopenharmony_ci uint64_t templateId = INVALID_TEMPLATE_ID; 172094332d3Sopenharmony_ci SecureRandom((uint8_t *)&templateId, sizeof(templateId)); 173094332d3Sopenharmony_ci if (templateId == INVALID_TEMPLATE_ID) { 174094332d3Sopenharmony_ci continue; 175094332d3Sopenharmony_ci } 176094332d3Sopenharmony_ci uint32_t j = 0; 177094332d3Sopenharmony_ci for (; j < g_pinDbOp->pinIndexLen; j++) { 178094332d3Sopenharmony_ci if (templateId == g_pinDbOp->pinIndex[i].pinInfo.templateId) { 179094332d3Sopenharmony_ci break; 180094332d3Sopenharmony_ci } 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci if (j == g_pinDbOp->pinIndexLen) { 183094332d3Sopenharmony_ci return templateId; 184094332d3Sopenharmony_ci } 185094332d3Sopenharmony_ci } 186094332d3Sopenharmony_ci LOG_ERROR("fail generate pin templateid."); 187094332d3Sopenharmony_ci return INVALID_TEMPLATE_ID; 188094332d3Sopenharmony_ci} 189094332d3Sopenharmony_ci 190094332d3Sopenharmony_cistatic ResultCode DelPin(uint64_t templateId) 191094332d3Sopenharmony_ci{ 192094332d3Sopenharmony_ci /* This is for example only, Should be implemented in trusted environment. */ 193094332d3Sopenharmony_ci ResultCode ret = RemoveAllFile(templateId); 194094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 195094332d3Sopenharmony_ci LOG_ERROR("Remove pin file fail."); 196094332d3Sopenharmony_ci return ret; 197094332d3Sopenharmony_ci } 198094332d3Sopenharmony_ci 199094332d3Sopenharmony_ci LOG_INFO("DelPin succ."); 200094332d3Sopenharmony_ci return RESULT_SUCCESS; 201094332d3Sopenharmony_ci} 202094332d3Sopenharmony_ci 203094332d3Sopenharmony_cistatic ResultCode DelPinInDb(uint32_t index) 204094332d3Sopenharmony_ci{ 205094332d3Sopenharmony_ci uint32_t pinIndexLen = g_pinDbOp->pinIndexLen - 1; 206094332d3Sopenharmony_ci if (pinIndexLen == 0) { 207094332d3Sopenharmony_ci (void)memset_s(g_pinDbOp->pinIndex, 208094332d3Sopenharmony_ci g_pinDbOp->pinIndexLen * sizeof(PinIndexV1), 0, g_pinDbOp->pinIndexLen * sizeof(PinIndexV1)); 209094332d3Sopenharmony_ci Free(g_pinDbOp->pinIndex); 210094332d3Sopenharmony_ci g_pinDbOp->pinIndex = NULL; 211094332d3Sopenharmony_ci } else { 212094332d3Sopenharmony_ci uint32_t size = pinIndexLen * sizeof(PinIndexV1); 213094332d3Sopenharmony_ci PinIndexV1 *pinIndex = (PinIndexV1 *)Malloc(size); 214094332d3Sopenharmony_ci if (pinIndex == NULL) { 215094332d3Sopenharmony_ci LOG_ERROR("PinIndexV1 malloc fail."); 216094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 217094332d3Sopenharmony_ci } 218094332d3Sopenharmony_ci (void)memset_s(pinIndex, size, 0, size); 219094332d3Sopenharmony_ci for (uint32_t i = 0, j = 0; i < g_pinDbOp->pinIndexLen; i++) { 220094332d3Sopenharmony_ci if (i != index) { 221094332d3Sopenharmony_ci pinIndex[j] = g_pinDbOp->pinIndex[i]; 222094332d3Sopenharmony_ci j++; 223094332d3Sopenharmony_ci } 224094332d3Sopenharmony_ci } 225094332d3Sopenharmony_ci (void)memset_s(g_pinDbOp->pinIndex, 226094332d3Sopenharmony_ci g_pinDbOp->pinIndexLen * sizeof(PinIndexV1), 0, g_pinDbOp->pinIndexLen * sizeof(PinIndexV1)); 227094332d3Sopenharmony_ci Free(g_pinDbOp->pinIndex); 228094332d3Sopenharmony_ci g_pinDbOp->pinIndex = pinIndex; 229094332d3Sopenharmony_ci } 230094332d3Sopenharmony_ci LOG_INFO("%{public}u left after del.", pinIndexLen); 231094332d3Sopenharmony_ci g_pinDbOp->pinIndexLen = pinIndexLen; 232094332d3Sopenharmony_ci ResultCode ret = WritePinDb(g_pinDbOp); 233094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 234094332d3Sopenharmony_ci LOG_ERROR("WritePinDb fail."); 235094332d3Sopenharmony_ci return ret; 236094332d3Sopenharmony_ci } 237094332d3Sopenharmony_ci 238094332d3Sopenharmony_ci LOG_INFO("DelPinInDb succ."); 239094332d3Sopenharmony_ci return ret; 240094332d3Sopenharmony_ci} 241094332d3Sopenharmony_ci 242094332d3Sopenharmony_cistatic ResultCode SearchPinIndex(uint64_t templateId, uint32_t *index) 243094332d3Sopenharmony_ci{ 244094332d3Sopenharmony_ci if (!LoadPinDb()) { 245094332d3Sopenharmony_ci LOG_ERROR("SearchPinIndex load pinDb fail."); 246094332d3Sopenharmony_ci return RESULT_NEED_INIT; 247094332d3Sopenharmony_ci } 248094332d3Sopenharmony_ci 249094332d3Sopenharmony_ci if (g_pinDbOp->pinIndexLen == 0) { 250094332d3Sopenharmony_ci LOG_ERROR("SearchPinIndex no pin exist."); 251094332d3Sopenharmony_ci return RESULT_BAD_MATCH; 252094332d3Sopenharmony_ci } 253094332d3Sopenharmony_ci for (uint32_t i = 0; i < g_pinDbOp->pinIndexLen; i++) { 254094332d3Sopenharmony_ci if (g_pinDbOp->pinIndex[i].pinInfo.templateId == templateId) { 255094332d3Sopenharmony_ci LOG_INFO("SearchPinIndex succ."); 256094332d3Sopenharmony_ci (*index) = i; 257094332d3Sopenharmony_ci return RESULT_SUCCESS; 258094332d3Sopenharmony_ci } 259094332d3Sopenharmony_ci } 260094332d3Sopenharmony_ci LOG_ERROR("SearchPinIndex no pin match."); 261094332d3Sopenharmony_ci return RESULT_BAD_MATCH; 262094332d3Sopenharmony_ci} 263094332d3Sopenharmony_ci 264094332d3Sopenharmony_ciResultCode DelPinById(uint64_t templateId) 265094332d3Sopenharmony_ci{ 266094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 267094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 268094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 269094332d3Sopenharmony_ci return ret; 270094332d3Sopenharmony_ci } 271094332d3Sopenharmony_ci 272094332d3Sopenharmony_ci ret = DelPinInDb(index); 273094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 274094332d3Sopenharmony_ci LOG_ERROR("DelPinInDb fail."); 275094332d3Sopenharmony_ci return ret; 276094332d3Sopenharmony_ci } 277094332d3Sopenharmony_ci 278094332d3Sopenharmony_ci ret = DelPin(templateId); 279094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 280094332d3Sopenharmony_ci LOG_ERROR(" DelPin fail."); 281094332d3Sopenharmony_ci } 282094332d3Sopenharmony_ci 283094332d3Sopenharmony_ci LOG_INFO("DelPinById succ."); 284094332d3Sopenharmony_ci /* ignore pin file remove result, return success when index file remove success */ 285094332d3Sopenharmony_ci return RESULT_SUCCESS; 286094332d3Sopenharmony_ci} 287094332d3Sopenharmony_ci 288094332d3Sopenharmony_cistatic void InitPinInfo(PinInfoV1 *pinInfo, uint64_t templateId, uint64_t subType) 289094332d3Sopenharmony_ci{ 290094332d3Sopenharmony_ci pinInfo->templateId = templateId; 291094332d3Sopenharmony_ci pinInfo->subType = subType; 292094332d3Sopenharmony_ci pinInfo->algoVersion = ALGORITHM_VERSION_0; 293094332d3Sopenharmony_ci} 294094332d3Sopenharmony_ci 295094332d3Sopenharmony_cistatic void InitAntiBruteInfo(AntiBruteInfoV0 *info) 296094332d3Sopenharmony_ci{ 297094332d3Sopenharmony_ci info->authErrorCount = INIT_AUTH_ERROR_COUNT; 298094332d3Sopenharmony_ci info->startFreezeTime = INIT_START_FREEZE_TIMES; 299094332d3Sopenharmony_ci} 300094332d3Sopenharmony_ci 301094332d3Sopenharmony_cistatic void InitPinIndex(PinIndexV1 *pinIndex, uint64_t templateId, uint64_t subType) 302094332d3Sopenharmony_ci{ 303094332d3Sopenharmony_ci InitPinInfo(&(pinIndex->pinInfo), templateId, subType); 304094332d3Sopenharmony_ci InitAntiBruteInfo(&(pinIndex->antiBruteInfo)); 305094332d3Sopenharmony_ci} 306094332d3Sopenharmony_ci 307094332d3Sopenharmony_cistatic ResultCode AddPinInDb(uint64_t templateId, uint64_t subType) 308094332d3Sopenharmony_ci{ 309094332d3Sopenharmony_ci if (g_pinDbOp->pinIndexLen > MAX_CRYPTO_INFO_SIZE - 1) { 310094332d3Sopenharmony_ci LOG_ERROR("pinIndexLen too large."); 311094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 312094332d3Sopenharmony_ci } 313094332d3Sopenharmony_ci uint32_t size = (g_pinDbOp->pinIndexLen + 1) * sizeof(PinIndexV1); 314094332d3Sopenharmony_ci PinIndexV1 *pinIndex = (PinIndexV1 *)Malloc(size); 315094332d3Sopenharmony_ci if (pinIndex == NULL) { 316094332d3Sopenharmony_ci LOG_ERROR("PinIndexV1 malloc fail."); 317094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 318094332d3Sopenharmony_ci } 319094332d3Sopenharmony_ci (void)memset_s(pinIndex, size, 0, size); 320094332d3Sopenharmony_ci if (g_pinDbOp->pinIndexLen != 0) { 321094332d3Sopenharmony_ci if (memcpy_s(pinIndex, size, 322094332d3Sopenharmony_ci g_pinDbOp->pinIndex, g_pinDbOp->pinIndexLen * sizeof(PinIndexV1)) != EOK) { 323094332d3Sopenharmony_ci LOG_ERROR("PinIndexV1 copy fail."); 324094332d3Sopenharmony_ci (void)memset_s(pinIndex, size, 0, size); 325094332d3Sopenharmony_ci Free(pinIndex); 326094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 327094332d3Sopenharmony_ci } 328094332d3Sopenharmony_ci } 329094332d3Sopenharmony_ci InitPinIndex(&pinIndex[g_pinDbOp->pinIndexLen], templateId, subType); 330094332d3Sopenharmony_ci if (g_pinDbOp->pinIndex != NULL) { 331094332d3Sopenharmony_ci Free(g_pinDbOp->pinIndex); 332094332d3Sopenharmony_ci } 333094332d3Sopenharmony_ci g_pinDbOp->pinIndex = pinIndex; 334094332d3Sopenharmony_ci g_pinDbOp->pinIndexLen++; 335094332d3Sopenharmony_ci ResultCode ret = WritePinDb(g_pinDbOp); 336094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 337094332d3Sopenharmony_ci LOG_ERROR("WritePinDb fail."); 338094332d3Sopenharmony_ci return ret; 339094332d3Sopenharmony_ci } 340094332d3Sopenharmony_ci 341094332d3Sopenharmony_ci LOG_INFO("AddPinInDb succ."); 342094332d3Sopenharmony_ci return RESULT_SUCCESS; 343094332d3Sopenharmony_ci} 344094332d3Sopenharmony_ci 345094332d3Sopenharmony_cistatic ResultCode WriteAddPinInfo(const Buffer *secret, const Buffer *pinCredentialData, uint8_t *salt, 346094332d3Sopenharmony_ci uint32_t saltLen, const uint64_t templateId) 347094332d3Sopenharmony_ci{ 348094332d3Sopenharmony_ci ResultCode ret = WritePinFile(pinCredentialData->buf, pinCredentialData->contentSize, templateId, CRYPTO_SUFFIX); 349094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 350094332d3Sopenharmony_ci LOG_ERROR("WriteCryptoFile fail."); 351094332d3Sopenharmony_ci return ret; 352094332d3Sopenharmony_ci } 353094332d3Sopenharmony_ci 354094332d3Sopenharmony_ci ret = WritePinFile(salt, saltLen, templateId, SALT_SUFFIX); 355094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 356094332d3Sopenharmony_ci LOG_ERROR("WriteSaltFile fail."); 357094332d3Sopenharmony_ci return ret; 358094332d3Sopenharmony_ci } 359094332d3Sopenharmony_ci 360094332d3Sopenharmony_ci ret = WritePinFile(secret->buf, secret->contentSize, templateId, SECRET_SUFFIX); 361094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 362094332d3Sopenharmony_ci LOG_ERROR("WriteSecretFile fail."); 363094332d3Sopenharmony_ci return ret; 364094332d3Sopenharmony_ci } 365094332d3Sopenharmony_ci AntiBruteInfoV0 initAntiBrute = {}; 366094332d3Sopenharmony_ci InitAntiBruteInfo(&initAntiBrute); 367094332d3Sopenharmony_ci ret = WritePinFile((uint8_t *)(&initAntiBrute), sizeof(AntiBruteInfoV0), templateId, ANTI_BRUTE_SUFFIX); 368094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 369094332d3Sopenharmony_ci LOG_ERROR("WriteAntiBruteFile fail."); 370094332d3Sopenharmony_ci return ret; 371094332d3Sopenharmony_ci } 372094332d3Sopenharmony_ci 373094332d3Sopenharmony_ci LOG_INFO("WriteAddPinInfo succ."); 374094332d3Sopenharmony_ci return RESULT_SUCCESS; 375094332d3Sopenharmony_ci} 376094332d3Sopenharmony_ci 377094332d3Sopenharmony_cistatic Buffer *GenerateExpandData(char *str, const uint8_t *data, const uint32_t dataLen) 378094332d3Sopenharmony_ci{ 379094332d3Sopenharmony_ci /* CONST_EXPAND_DATA_LEN is twice the size of dataLen */ 380094332d3Sopenharmony_ci if (dataLen < strlen(str) || dataLen != (CONST_EXPAND_DATA_LEN / 2)) { 381094332d3Sopenharmony_ci LOG_ERROR("bad param."); 382094332d3Sopenharmony_ci return NULL; 383094332d3Sopenharmony_ci } 384094332d3Sopenharmony_ci Buffer *outBuff = CreateBufferBySize(CONST_EXPAND_DATA_LEN); 385094332d3Sopenharmony_ci if (!IsBufferValid(outBuff)) { 386094332d3Sopenharmony_ci LOG_ERROR("create buffer fail."); 387094332d3Sopenharmony_ci return NULL; 388094332d3Sopenharmony_ci } 389094332d3Sopenharmony_ci (void)memset_s(outBuff->buf, outBuff->maxSize, 0, outBuff->maxSize); 390094332d3Sopenharmony_ci outBuff->contentSize = outBuff->maxSize; 391094332d3Sopenharmony_ci uint8_t *temp = outBuff->buf; 392094332d3Sopenharmony_ci if (memcpy_s(temp, outBuff->maxSize, (uint8_t *)str, strlen(str)) != EOK) { 393094332d3Sopenharmony_ci LOG_ERROR("copy str fail."); 394094332d3Sopenharmony_ci DestroyBuffer(outBuff); 395094332d3Sopenharmony_ci return NULL; 396094332d3Sopenharmony_ci } 397094332d3Sopenharmony_ci 398094332d3Sopenharmony_ci temp += dataLen; 399094332d3Sopenharmony_ci if (memcpy_s(temp, outBuff->maxSize - dataLen, data, dataLen) != EOK) { 400094332d3Sopenharmony_ci LOG_ERROR("copy data fail."); 401094332d3Sopenharmony_ci DestroyBuffer(outBuff); 402094332d3Sopenharmony_ci return NULL; 403094332d3Sopenharmony_ci } 404094332d3Sopenharmony_ci 405094332d3Sopenharmony_ci return outBuff; 406094332d3Sopenharmony_ci} 407094332d3Sopenharmony_ci 408094332d3Sopenharmony_cistatic ResultCode GenerateRootSecret(const Buffer *deviceKey, const Buffer *pinData, Buffer *outRootSecret) 409094332d3Sopenharmony_ci{ 410094332d3Sopenharmony_ci Buffer *expandData = GenerateExpandData(SALT_PREFIX, pinData->buf, pinData->contentSize); 411094332d3Sopenharmony_ci if (!IsBufferValid(expandData)) { 412094332d3Sopenharmony_ci LOG_ERROR("generate expand data fail."); 413094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 414094332d3Sopenharmony_ci } 415094332d3Sopenharmony_ci 416094332d3Sopenharmony_ci Buffer *hkdfSalt = Sha256Adaptor(expandData); 417094332d3Sopenharmony_ci if (!IsBufferValid(hkdfSalt)) { 418094332d3Sopenharmony_ci LOG_ERROR("generate sha256 fail."); 419094332d3Sopenharmony_ci DestroyBuffer(expandData); 420094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 421094332d3Sopenharmony_ci } 422094332d3Sopenharmony_ci Buffer *rootSecret = Hkdf(hkdfSalt, deviceKey); 423094332d3Sopenharmony_ci DestroyBuffer(expandData); 424094332d3Sopenharmony_ci DestroyBuffer(hkdfSalt); 425094332d3Sopenharmony_ci if (!IsBufferValid(rootSecret)) { 426094332d3Sopenharmony_ci LOG_ERROR("generate rootSecret fail."); 427094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 428094332d3Sopenharmony_ci } 429094332d3Sopenharmony_ci if (memcpy_s(outRootSecret->buf, outRootSecret->maxSize, rootSecret->buf, rootSecret->contentSize) != EOK) { 430094332d3Sopenharmony_ci LOG_ERROR("copy root secret fail."); 431094332d3Sopenharmony_ci DestroyBuffer(rootSecret); 432094332d3Sopenharmony_ci return RESULT_BAD_COPY; 433094332d3Sopenharmony_ci } 434094332d3Sopenharmony_ci 435094332d3Sopenharmony_ci outRootSecret->contentSize = rootSecret->contentSize; 436094332d3Sopenharmony_ci DestroyBuffer(rootSecret); 437094332d3Sopenharmony_ci return RESULT_SUCCESS; 438094332d3Sopenharmony_ci} 439094332d3Sopenharmony_ci 440094332d3Sopenharmony_cistatic Buffer *GenerateEncryptionKey(const Buffer *deviceKey) 441094332d3Sopenharmony_ci{ 442094332d3Sopenharmony_ci Buffer *keyStrBuffer = CreateBufferBySize(CONST_CREDENTIAL_PREFIX_LEN); 443094332d3Sopenharmony_ci if (!IsBufferValid(keyStrBuffer)) { 444094332d3Sopenharmony_ci LOG_ERROR("generate expand data fail."); 445094332d3Sopenharmony_ci return NULL; 446094332d3Sopenharmony_ci } 447094332d3Sopenharmony_ci (void)memset_s(keyStrBuffer->buf, keyStrBuffer->maxSize, 0, keyStrBuffer->maxSize); 448094332d3Sopenharmony_ci if (memcpy_s(keyStrBuffer->buf, keyStrBuffer->maxSize, 449094332d3Sopenharmony_ci (uint8_t *)CREDENTIAL_PREFIX, strlen(CREDENTIAL_PREFIX)) != EOK) { 450094332d3Sopenharmony_ci LOG_ERROR("copy CREDENTIAL_PREFIX fail."); 451094332d3Sopenharmony_ci DestroyBuffer(keyStrBuffer); 452094332d3Sopenharmony_ci return NULL; 453094332d3Sopenharmony_ci } 454094332d3Sopenharmony_ci keyStrBuffer->contentSize = keyStrBuffer->maxSize; 455094332d3Sopenharmony_ci Buffer *encryptionKey = Hkdf(keyStrBuffer, deviceKey); 456094332d3Sopenharmony_ci DestroyBuffer(keyStrBuffer); 457094332d3Sopenharmony_ci if (!IsBufferValid(encryptionKey)) { 458094332d3Sopenharmony_ci LOG_ERROR("generate encryptionKey fail."); 459094332d3Sopenharmony_ci return NULL; 460094332d3Sopenharmony_ci } 461094332d3Sopenharmony_ci 462094332d3Sopenharmony_ci return encryptionKey; 463094332d3Sopenharmony_ci} 464094332d3Sopenharmony_ci 465094332d3Sopenharmony_cistatic Buffer *SplicePinCiperInfo(const Buffer *iv, const Buffer *tag, const Buffer *ciphertext) 466094332d3Sopenharmony_ci{ 467094332d3Sopenharmony_ci Buffer *cipherInfo = CreateBufferBySize(iv->contentSize + tag->contentSize + ciphertext->contentSize); 468094332d3Sopenharmony_ci if (cipherInfo == NULL) { 469094332d3Sopenharmony_ci LOG_ERROR("create cipherInfo fail"); 470094332d3Sopenharmony_ci return NULL; 471094332d3Sopenharmony_ci } 472094332d3Sopenharmony_ci if (memcpy_s(cipherInfo->buf, cipherInfo->maxSize, iv->buf, iv->contentSize) != EOK) { 473094332d3Sopenharmony_ci LOG_ERROR("failed to copy iv"); 474094332d3Sopenharmony_ci goto ERROR; 475094332d3Sopenharmony_ci } 476094332d3Sopenharmony_ci cipherInfo->contentSize += iv->contentSize; 477094332d3Sopenharmony_ci if (memcpy_s(cipherInfo->buf + cipherInfo->contentSize, cipherInfo->maxSize - cipherInfo->contentSize, 478094332d3Sopenharmony_ci tag->buf, tag->contentSize) != EOK) { 479094332d3Sopenharmony_ci LOG_ERROR("failed to copy tag"); 480094332d3Sopenharmony_ci goto ERROR; 481094332d3Sopenharmony_ci } 482094332d3Sopenharmony_ci cipherInfo->contentSize += tag->contentSize; 483094332d3Sopenharmony_ci if (memcpy_s(cipherInfo->buf + cipherInfo->contentSize, cipherInfo->maxSize - cipherInfo->contentSize, 484094332d3Sopenharmony_ci ciphertext->buf, ciphertext->contentSize) != EOK) { 485094332d3Sopenharmony_ci LOG_ERROR("failed to copy ciphertext"); 486094332d3Sopenharmony_ci goto ERROR; 487094332d3Sopenharmony_ci } 488094332d3Sopenharmony_ci cipherInfo->contentSize += ciphertext->contentSize; 489094332d3Sopenharmony_ci return cipherInfo; 490094332d3Sopenharmony_ci 491094332d3Sopenharmony_ciERROR: 492094332d3Sopenharmony_ci DestroyBuffer(cipherInfo); 493094332d3Sopenharmony_ci return NULL; 494094332d3Sopenharmony_ci} 495094332d3Sopenharmony_ci 496094332d3Sopenharmony_cistatic Buffer *GetPinCiperInfo(Buffer *key, Buffer *pinData) 497094332d3Sopenharmony_ci{ 498094332d3Sopenharmony_ci Buffer *cipherText = NULL; 499094332d3Sopenharmony_ci Buffer *tag = NULL; 500094332d3Sopenharmony_ci Buffer *cipherInfo = NULL; 501094332d3Sopenharmony_ci AesGcmParam param = {}; 502094332d3Sopenharmony_ci param.key = key; 503094332d3Sopenharmony_ci param.iv = CreateBufferBySize(AES_GCM_256_IV_SIZE); 504094332d3Sopenharmony_ci if (!IsBufferValid(param.iv)) { 505094332d3Sopenharmony_ci LOG_ERROR("create iv fail."); 506094332d3Sopenharmony_ci goto EXIT; 507094332d3Sopenharmony_ci } 508094332d3Sopenharmony_ci if (SecureRandom(param.iv->buf, param.iv->maxSize) != RESULT_SUCCESS) { 509094332d3Sopenharmony_ci LOG_ERROR("random iv fail."); 510094332d3Sopenharmony_ci goto EXIT; 511094332d3Sopenharmony_ci } 512094332d3Sopenharmony_ci param.iv->contentSize = param.iv->maxSize; 513094332d3Sopenharmony_ci if (AesGcm256Encrypt(pinData, ¶m, &cipherText, &tag) != RESULT_SUCCESS) { 514094332d3Sopenharmony_ci LOG_ERROR("AesGcmEncrypt fail."); 515094332d3Sopenharmony_ci goto EXIT; 516094332d3Sopenharmony_ci } 517094332d3Sopenharmony_ci 518094332d3Sopenharmony_ci cipherInfo = SplicePinCiperInfo(param.iv, tag, cipherText); 519094332d3Sopenharmony_ci if (cipherInfo == NULL) { 520094332d3Sopenharmony_ci LOG_ERROR("SplicePinCiperInfo fail."); 521094332d3Sopenharmony_ci goto EXIT; 522094332d3Sopenharmony_ci } 523094332d3Sopenharmony_ci 524094332d3Sopenharmony_ciEXIT: 525094332d3Sopenharmony_ci DestroyBuffer(param.iv); 526094332d3Sopenharmony_ci DestroyBuffer(cipherText); 527094332d3Sopenharmony_ci DestroyBuffer(tag); 528094332d3Sopenharmony_ci 529094332d3Sopenharmony_ci return cipherInfo; 530094332d3Sopenharmony_ci} 531094332d3Sopenharmony_ci 532094332d3Sopenharmony_cistatic Buffer *CreateSecretBuffer() 533094332d3Sopenharmony_ci{ 534094332d3Sopenharmony_ci Buffer *secret = CreateBufferBySize(SECRET_SIZE); 535094332d3Sopenharmony_ci if (!IsBufferValid(secret)) { 536094332d3Sopenharmony_ci LOG_ERROR("generate buffer fail."); 537094332d3Sopenharmony_ci return secret; 538094332d3Sopenharmony_ci } 539094332d3Sopenharmony_ci if (SecureRandom(secret->buf, secret->maxSize) != RESULT_SUCCESS) { 540094332d3Sopenharmony_ci LOG_ERROR("generate secure random number fail."); 541094332d3Sopenharmony_ci DestroyBuffer(secret); 542094332d3Sopenharmony_ci return NULL; 543094332d3Sopenharmony_ci } 544094332d3Sopenharmony_ci secret->contentSize = secret->maxSize; 545094332d3Sopenharmony_ci return secret; 546094332d3Sopenharmony_ci} 547094332d3Sopenharmony_ci 548094332d3Sopenharmony_cistatic ResultCode ProcessAddPin(const Buffer *deviceKey, const Buffer *secret, PinEnrollParam *pinEnrollParam, 549094332d3Sopenharmony_ci uint64_t *templateId) 550094332d3Sopenharmony_ci{ 551094332d3Sopenharmony_ci *templateId = GeneratePinTemplateId(); 552094332d3Sopenharmony_ci if (*templateId == INVALID_TEMPLATE_ID) { 553094332d3Sopenharmony_ci LOG_ERROR("GeneratePinTemplateId fail."); 554094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 555094332d3Sopenharmony_ci } 556094332d3Sopenharmony_ci 557094332d3Sopenharmony_ci Buffer *key = GenerateEncryptionKey(deviceKey); 558094332d3Sopenharmony_ci if (!IsBufferValid(key)) { 559094332d3Sopenharmony_ci LOG_ERROR("GenerateEncryptionKey fail."); 560094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 561094332d3Sopenharmony_ci } 562094332d3Sopenharmony_ci Buffer pinDataBuffer = GetTmpBuffer(pinEnrollParam->pinData, CONST_PIN_DATA_LEN, CONST_PIN_DATA_LEN); 563094332d3Sopenharmony_ci Buffer *cipherInfo = GetPinCiperInfo(key, &pinDataBuffer); 564094332d3Sopenharmony_ci DestroyBuffer(key); 565094332d3Sopenharmony_ci if (cipherInfo == NULL) { 566094332d3Sopenharmony_ci LOG_ERROR("GetPinCiperInfo fail."); 567094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 568094332d3Sopenharmony_ci } 569094332d3Sopenharmony_ci 570094332d3Sopenharmony_ci ResultCode ret = WriteAddPinInfo(secret, cipherInfo, pinEnrollParam->salt, CONST_SALT_LEN, *templateId); 571094332d3Sopenharmony_ci DestroyBuffer(cipherInfo); 572094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 573094332d3Sopenharmony_ci LOG_ERROR("write add pin info fail."); 574094332d3Sopenharmony_ci (void)RemoveAllFile(*templateId); 575094332d3Sopenharmony_ci return ret; 576094332d3Sopenharmony_ci } 577094332d3Sopenharmony_ci 578094332d3Sopenharmony_ci ret = AddPinInDb(*templateId, pinEnrollParam->subType); 579094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 580094332d3Sopenharmony_ci LOG_ERROR("AddPinDb fail."); 581094332d3Sopenharmony_ci (void)RemoveAllFile(*templateId); 582094332d3Sopenharmony_ci return ret; 583094332d3Sopenharmony_ci } 584094332d3Sopenharmony_ci return ret; 585094332d3Sopenharmony_ci} 586094332d3Sopenharmony_ci 587094332d3Sopenharmony_ci/* This is for example only, Should be implemented in trusted environment. */ 588094332d3Sopenharmony_ciResultCode AddPin(PinEnrollParam *pinEnrollParam, uint64_t *templateId, Buffer *outRootSecret) 589094332d3Sopenharmony_ci{ 590094332d3Sopenharmony_ci if (!LoadPinDb()) { 591094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 592094332d3Sopenharmony_ci return RESULT_NEED_INIT; 593094332d3Sopenharmony_ci } 594094332d3Sopenharmony_ci if (pinEnrollParam == NULL || templateId == NULL || !IsBufferValid(outRootSecret)) { 595094332d3Sopenharmony_ci LOG_ERROR("get invalid params."); 596094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 597094332d3Sopenharmony_ci } 598094332d3Sopenharmony_ci ResultCode ret = RESULT_GENERAL_ERROR; 599094332d3Sopenharmony_ci Buffer pinCredData = GetTmpBuffer(pinEnrollParam->pinData, CONST_PIN_DATA_LEN, CONST_PIN_DATA_LEN); 600094332d3Sopenharmony_ci Buffer *secret = CreateSecretBuffer(); 601094332d3Sopenharmony_ci Buffer *deviceKey = NULL; 602094332d3Sopenharmony_ci if (!IsBufferValid(secret)) { 603094332d3Sopenharmony_ci LOG_ERROR("generate buffer fail."); 604094332d3Sopenharmony_ci ret = RESULT_NO_MEMORY; 605094332d3Sopenharmony_ci goto ERROR; 606094332d3Sopenharmony_ci } 607094332d3Sopenharmony_ci deviceKey = DeriveDeviceKey(&pinCredData, secret); 608094332d3Sopenharmony_ci if (!IsBufferValid(deviceKey)) { 609094332d3Sopenharmony_ci LOG_ERROR("generate deviceKey fail."); 610094332d3Sopenharmony_ci ret = RESULT_GENERAL_ERROR; 611094332d3Sopenharmony_ci goto ERROR; 612094332d3Sopenharmony_ci } 613094332d3Sopenharmony_ci ret = GenerateRootSecret(deviceKey, &pinCredData, outRootSecret); 614094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 615094332d3Sopenharmony_ci LOG_ERROR("generate rootSecret fail."); 616094332d3Sopenharmony_ci goto ERROR; 617094332d3Sopenharmony_ci } 618094332d3Sopenharmony_ci ret = ProcessAddPin(deviceKey, secret, pinEnrollParam, templateId); 619094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 620094332d3Sopenharmony_ci LOG_ERROR("process add pin fail."); 621094332d3Sopenharmony_ci goto ERROR; 622094332d3Sopenharmony_ci } 623094332d3Sopenharmony_ci LOG_INFO("AddPin succ."); 624094332d3Sopenharmony_ci 625094332d3Sopenharmony_ciERROR: 626094332d3Sopenharmony_ci DestroyBuffer(deviceKey); 627094332d3Sopenharmony_ci DestroyBuffer(secret); 628094332d3Sopenharmony_ci return ret; 629094332d3Sopenharmony_ci} 630094332d3Sopenharmony_ci 631094332d3Sopenharmony_ciResultCode DoGetAlgoParameter(uint64_t templateId, uint8_t *salt, uint32_t *saltLen, uint32_t *algoVersion) 632094332d3Sopenharmony_ci{ 633094332d3Sopenharmony_ci if (salt == NULL || saltLen == NULL || templateId == INVALID_TEMPLATE_ID || algoVersion == NULL) { 634094332d3Sopenharmony_ci LOG_ERROR("get invalid algorithm params."); 635094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 636094332d3Sopenharmony_ci } 637094332d3Sopenharmony_ci if (!LoadPinDb()) { 638094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 639094332d3Sopenharmony_ci return RESULT_NEED_INIT; 640094332d3Sopenharmony_ci } 641094332d3Sopenharmony_ci 642094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 643094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 644094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 645094332d3Sopenharmony_ci return ret; 646094332d3Sopenharmony_ci } 647094332d3Sopenharmony_ci 648094332d3Sopenharmony_ci ret = ReadPinFile(salt, *saltLen, templateId, SALT_SUFFIX); 649094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 650094332d3Sopenharmony_ci LOG_ERROR("salt file read fail."); 651094332d3Sopenharmony_ci return ret; 652094332d3Sopenharmony_ci } 653094332d3Sopenharmony_ci 654094332d3Sopenharmony_ci *algoVersion = g_pinDbOp->pinIndex[index].pinInfo.algoVersion; 655094332d3Sopenharmony_ci LOG_INFO("DoGetAlgoParameter succ."); 656094332d3Sopenharmony_ci return RESULT_SUCCESS; 657094332d3Sopenharmony_ci} 658094332d3Sopenharmony_ci 659094332d3Sopenharmony_cistatic ResultCode GetAntiBruteCountById(uint64_t templateId, uint32_t *count) 660094332d3Sopenharmony_ci{ 661094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 662094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 663094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 664094332d3Sopenharmony_ci return ret; 665094332d3Sopenharmony_ci } 666094332d3Sopenharmony_ci *count = g_pinDbOp->pinIndex[index].antiBruteInfo.authErrorCount; 667094332d3Sopenharmony_ci return RESULT_SUCCESS; 668094332d3Sopenharmony_ci} 669094332d3Sopenharmony_ci 670094332d3Sopenharmony_ciResultCode RefreshAntiBruteInfoToFile(uint64_t templateId) 671094332d3Sopenharmony_ci{ 672094332d3Sopenharmony_ci if (!LoadPinDb()) { 673094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 674094332d3Sopenharmony_ci return RESULT_NEED_INIT; 675094332d3Sopenharmony_ci } 676094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 677094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 678094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 679094332d3Sopenharmony_ci return ret; 680094332d3Sopenharmony_ci } 681094332d3Sopenharmony_ci ret = WritePinFile((uint8_t *)(&(g_pinDbOp->pinIndex[index].antiBruteInfo)), sizeof(AntiBruteInfoV0), 682094332d3Sopenharmony_ci templateId, ANTI_BRUTE_SUFFIX); 683094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 684094332d3Sopenharmony_ci LOG_ERROR("write anti brute fail."); 685094332d3Sopenharmony_ci } 686094332d3Sopenharmony_ci 687094332d3Sopenharmony_ci return ret; 688094332d3Sopenharmony_ci} 689094332d3Sopenharmony_ci 690094332d3Sopenharmony_cistatic ResultCode SetAntiBruteInfoById(uint64_t templateId, uint32_t count, uint64_t startFreezeTime) 691094332d3Sopenharmony_ci{ 692094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 693094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 694094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 695094332d3Sopenharmony_ci return ret; 696094332d3Sopenharmony_ci } 697094332d3Sopenharmony_ci g_pinDbOp->pinIndex[index].antiBruteInfo.authErrorCount = count; 698094332d3Sopenharmony_ci g_pinDbOp->pinIndex[index].antiBruteInfo.startFreezeTime = startFreezeTime; 699094332d3Sopenharmony_ci ret = WritePinFile((uint8_t *)(&(g_pinDbOp->pinIndex[index].antiBruteInfo)), sizeof(AntiBruteInfoV0), 700094332d3Sopenharmony_ci templateId, ANTI_BRUTE_SUFFIX); 701094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 702094332d3Sopenharmony_ci LOG_ERROR("write anti brute fail."); 703094332d3Sopenharmony_ci return ret; 704094332d3Sopenharmony_ci } 705094332d3Sopenharmony_ci return ret; 706094332d3Sopenharmony_ci} 707094332d3Sopenharmony_ci 708094332d3Sopenharmony_ciResultCode GetSubType(uint64_t templateId, uint64_t *subType) 709094332d3Sopenharmony_ci{ 710094332d3Sopenharmony_ci if (templateId == INVALID_TEMPLATE_ID) { 711094332d3Sopenharmony_ci LOG_ERROR("check param fail!"); 712094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 713094332d3Sopenharmony_ci } 714094332d3Sopenharmony_ci if (!LoadPinDb()) { 715094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 716094332d3Sopenharmony_ci return RESULT_NEED_INIT; 717094332d3Sopenharmony_ci } 718094332d3Sopenharmony_ci 719094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 720094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 721094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 722094332d3Sopenharmony_ci return ret; 723094332d3Sopenharmony_ci } 724094332d3Sopenharmony_ci *subType = g_pinDbOp->pinIndex[index].pinInfo.subType; 725094332d3Sopenharmony_ci 726094332d3Sopenharmony_ci LOG_INFO("GetSubType succ."); 727094332d3Sopenharmony_ci return RESULT_SUCCESS; 728094332d3Sopenharmony_ci} 729094332d3Sopenharmony_ci 730094332d3Sopenharmony_ciResultCode GetAntiBruteInfo(uint64_t templateId, uint32_t *authErrorCount, uint64_t *startFreezeTime) 731094332d3Sopenharmony_ci{ 732094332d3Sopenharmony_ci if (authErrorCount == NULL || startFreezeTime == NULL || templateId == INVALID_TEMPLATE_ID) { 733094332d3Sopenharmony_ci LOG_ERROR("check GetAntiBruteInfo param fail!"); 734094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 735094332d3Sopenharmony_ci } 736094332d3Sopenharmony_ci if (!LoadPinDb()) { 737094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 738094332d3Sopenharmony_ci return RESULT_NEED_INIT; 739094332d3Sopenharmony_ci } 740094332d3Sopenharmony_ci 741094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 742094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 743094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 744094332d3Sopenharmony_ci return ret; 745094332d3Sopenharmony_ci } 746094332d3Sopenharmony_ci *authErrorCount = g_pinDbOp->pinIndex[index].antiBruteInfo.authErrorCount; 747094332d3Sopenharmony_ci *startFreezeTime = g_pinDbOp->pinIndex[index].antiBruteInfo.startFreezeTime; 748094332d3Sopenharmony_ci 749094332d3Sopenharmony_ci LOG_INFO("GetAntiBruteInfo succ."); 750094332d3Sopenharmony_ci return RESULT_SUCCESS; 751094332d3Sopenharmony_ci} 752094332d3Sopenharmony_ci 753094332d3Sopenharmony_cistatic uint64_t ExponentialFuncTime(uint32_t authErrorCount) 754094332d3Sopenharmony_ci{ 755094332d3Sopenharmony_ci uint32_t ret = DEFAULT_VALUE; 756094332d3Sopenharmony_ci uint32_t exp = (authErrorCount - FIRST_EXPONENTIAL_PARA) / THIRD_EXPONENTIAL_PARA; 757094332d3Sopenharmony_ci for (uint32_t index = 0; index < exp; ++index) { 758094332d3Sopenharmony_ci ret *= SECOND_EXPONENTIAL_PARA; 759094332d3Sopenharmony_ci } 760094332d3Sopenharmony_ci return FIRST_EXPONENTIAL_PARA * ret; 761094332d3Sopenharmony_ci} 762094332d3Sopenharmony_ci 763094332d3Sopenharmony_cistatic uint64_t GetWaitTime(uint32_t authErrorCount) 764094332d3Sopenharmony_ci{ 765094332d3Sopenharmony_ci if (authErrorCount < FIRST_ANTI_BRUTE_COUNT) { 766094332d3Sopenharmony_ci return 0; 767094332d3Sopenharmony_ci } 768094332d3Sopenharmony_ci if (authErrorCount < ATTI_BRUTE_FIRST_STAGE) { 769094332d3Sopenharmony_ci if (authErrorCount == FIRST_ANTI_BRUTE_COUNT) { 770094332d3Sopenharmony_ci return ONE_MIN_TIME * MS_OF_S; 771094332d3Sopenharmony_ci } 772094332d3Sopenharmony_ci if (authErrorCount == SECOND_ANTI_BRUTE_COUNT) { 773094332d3Sopenharmony_ci return TEN_MIN_TIME * MS_OF_S; 774094332d3Sopenharmony_ci } 775094332d3Sopenharmony_ci if (authErrorCount == THIRD_ANTI_BRUTE_COUNT) { 776094332d3Sopenharmony_ci return THIRTY_MIN_TIME * MS_OF_S; 777094332d3Sopenharmony_ci } 778094332d3Sopenharmony_ci if (((authErrorCount - FIRST_ANTI_BRUTE_COUNT) % ANTI_BRUTE_COUNT_FREQUENCY) == 0) { 779094332d3Sopenharmony_ci return ONE_HOUR_TIME * MS_OF_S; 780094332d3Sopenharmony_ci } 781094332d3Sopenharmony_ci return 0; 782094332d3Sopenharmony_ci } 783094332d3Sopenharmony_ci if (authErrorCount >= ATTI_BRUTE_SECOND_STAGE) { 784094332d3Sopenharmony_ci return ONE_DAY_TIME * MS_OF_S; 785094332d3Sopenharmony_ci } 786094332d3Sopenharmony_ci return ExponentialFuncTime(authErrorCount) * MS_OF_S; 787094332d3Sopenharmony_ci} 788094332d3Sopenharmony_ci 789094332d3Sopenharmony_ciint32_t GetNextFailLockoutDuration(uint32_t authErrorCount) 790094332d3Sopenharmony_ci{ 791094332d3Sopenharmony_ci if (authErrorCount < FIRST_ANTI_BRUTE_COUNT) { 792094332d3Sopenharmony_ci return ONE_MIN_TIME * MS_OF_S; 793094332d3Sopenharmony_ci } 794094332d3Sopenharmony_ci if (authErrorCount < SECOND_ANTI_BRUTE_COUNT) { 795094332d3Sopenharmony_ci return TEN_MIN_TIME * MS_OF_S; 796094332d3Sopenharmony_ci } 797094332d3Sopenharmony_ci if (authErrorCount < THIRD_ANTI_BRUTE_COUNT) { 798094332d3Sopenharmony_ci return THIRTY_MIN_TIME * MS_OF_S; 799094332d3Sopenharmony_ci } 800094332d3Sopenharmony_ci if (authErrorCount < ATTI_BRUTE_FIRST_STAGE - 801094332d3Sopenharmony_ci (ATTI_BRUTE_FIRST_STAGE - FIRST_ANTI_BRUTE_COUNT) % ANTI_BRUTE_COUNT_FREQUENCY) { 802094332d3Sopenharmony_ci return ONE_HOUR_TIME * MS_OF_S; 803094332d3Sopenharmony_ci } 804094332d3Sopenharmony_ci if (authErrorCount < ATTI_BRUTE_FIRST_STAGE) { 805094332d3Sopenharmony_ci return (int32_t)ExponentialFuncTime(ATTI_BRUTE_FIRST_STAGE) * MS_OF_S; 806094332d3Sopenharmony_ci } 807094332d3Sopenharmony_ci if (authErrorCount < ATTI_BRUTE_SECOND_STAGE - 1) { 808094332d3Sopenharmony_ci return (int32_t)ExponentialFuncTime(authErrorCount + 1) * MS_OF_S; 809094332d3Sopenharmony_ci } 810094332d3Sopenharmony_ci return ONE_DAY_TIME * MS_OF_S; 811094332d3Sopenharmony_ci} 812094332d3Sopenharmony_ci 813094332d3Sopenharmony_ciResultCode ComputeFreezeTime(uint64_t templateId, uint32_t *freezeTime, uint32_t count, uint64_t startFreezeTime) 814094332d3Sopenharmony_ci{ 815094332d3Sopenharmony_ci if (templateId == INVALID_TEMPLATE_ID || freezeTime == NULL) { 816094332d3Sopenharmony_ci LOG_ERROR("check ComputeFreezeTime param fail!"); 817094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 818094332d3Sopenharmony_ci } 819094332d3Sopenharmony_ci if (!LoadPinDb()) { 820094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 821094332d3Sopenharmony_ci return RESULT_NEED_INIT; 822094332d3Sopenharmony_ci } 823094332d3Sopenharmony_ci uint64_t timeValue = GetRtcTime(); 824094332d3Sopenharmony_ci uint64_t waitTime = GetWaitTime(count); 825094332d3Sopenharmony_ci if (timeValue >= startFreezeTime) { 826094332d3Sopenharmony_ci uint64_t usedTime = timeValue - startFreezeTime; 827094332d3Sopenharmony_ci if (usedTime >= waitTime) { 828094332d3Sopenharmony_ci *freezeTime = 0; 829094332d3Sopenharmony_ci } else { 830094332d3Sopenharmony_ci *freezeTime = (waitTime - usedTime) & 0xffffffff; 831094332d3Sopenharmony_ci } 832094332d3Sopenharmony_ci } else { 833094332d3Sopenharmony_ci /* rtc time is reset, we should update startFreezeTime to timeValue */ 834094332d3Sopenharmony_ci if (SetAntiBruteInfoById(templateId, count, timeValue) != RESULT_SUCCESS) { 835094332d3Sopenharmony_ci LOG_ERROR("SetAntiBruteInfoById fail."); 836094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 837094332d3Sopenharmony_ci } 838094332d3Sopenharmony_ci *freezeTime = waitTime & 0xffffffff; 839094332d3Sopenharmony_ci } 840094332d3Sopenharmony_ci 841094332d3Sopenharmony_ci LOG_INFO("ComputeFreezeTime succ."); 842094332d3Sopenharmony_ci return RESULT_SUCCESS; 843094332d3Sopenharmony_ci} 844094332d3Sopenharmony_ci 845094332d3Sopenharmony_cistatic uint32_t ComputeRemainingTimes(uint32_t errorCount) 846094332d3Sopenharmony_ci{ 847094332d3Sopenharmony_ci if (errorCount < FIRST_ANTI_BRUTE_COUNT) { 848094332d3Sopenharmony_ci return FIRST_ANTI_BRUTE_COUNT - errorCount; 849094332d3Sopenharmony_ci } 850094332d3Sopenharmony_ci if (errorCount >= ATTI_BRUTE_FIRST_STAGE) { 851094332d3Sopenharmony_ci return REMAINING_TIMES_FREEZE; 852094332d3Sopenharmony_ci } 853094332d3Sopenharmony_ci return ANTI_BRUTE_COUNT_FREQUENCY - (errorCount - FIRST_ANTI_BRUTE_COUNT) % ANTI_BRUTE_COUNT_FREQUENCY; 854094332d3Sopenharmony_ci} 855094332d3Sopenharmony_ci 856094332d3Sopenharmony_ciResultCode GetRemainTimes(uint64_t templateId, uint32_t *remainingAuthTimes, uint32_t authErrorCount) 857094332d3Sopenharmony_ci{ 858094332d3Sopenharmony_ci if (templateId == INVALID_TEMPLATE_ID || remainingAuthTimes == NULL) { 859094332d3Sopenharmony_ci LOG_ERROR("check GetRemainTimes param fail!"); 860094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 861094332d3Sopenharmony_ci } 862094332d3Sopenharmony_ci if (!LoadPinDb()) { 863094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 864094332d3Sopenharmony_ci return RESULT_NEED_INIT; 865094332d3Sopenharmony_ci } 866094332d3Sopenharmony_ci *remainingAuthTimes = ComputeRemainingTimes(authErrorCount); 867094332d3Sopenharmony_ci return RESULT_SUCCESS; 868094332d3Sopenharmony_ci} 869094332d3Sopenharmony_ci 870094332d3Sopenharmony_cistatic ResultCode ClearAntiBruteInfoById(uint64_t templateId) 871094332d3Sopenharmony_ci{ 872094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 873094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 874094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 875094332d3Sopenharmony_ci return ret; 876094332d3Sopenharmony_ci } 877094332d3Sopenharmony_ci InitAntiBruteInfo(&(g_pinDbOp->pinIndex[index].antiBruteInfo)); 878094332d3Sopenharmony_ci return RESULT_SUCCESS; 879094332d3Sopenharmony_ci} 880094332d3Sopenharmony_ci 881094332d3Sopenharmony_cistatic ResultCode UpdateAntiBruteFile(uint64_t templateId, bool authResultSucc) 882094332d3Sopenharmony_ci{ 883094332d3Sopenharmony_ci if (templateId == INVALID_TEMPLATE_ID) { 884094332d3Sopenharmony_ci LOG_ERROR("check param fail."); 885094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 886094332d3Sopenharmony_ci } 887094332d3Sopenharmony_ci 888094332d3Sopenharmony_ci if (authResultSucc) { 889094332d3Sopenharmony_ci ResultCode ret = ClearAntiBruteInfoById(templateId); 890094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 891094332d3Sopenharmony_ci LOG_ERROR("ClearAntiBruteInfoById fail."); 892094332d3Sopenharmony_ci } 893094332d3Sopenharmony_ci return ret; 894094332d3Sopenharmony_ci } 895094332d3Sopenharmony_ci 896094332d3Sopenharmony_ci uint64_t nowTime = GetRtcTime(); 897094332d3Sopenharmony_ci uint32_t errorCount = 0; 898094332d3Sopenharmony_ci ResultCode ret = GetAntiBruteCountById(templateId, &errorCount); 899094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 900094332d3Sopenharmony_ci LOG_ERROR("GetAntiBruteCountById fail."); 901094332d3Sopenharmony_ci return ret; 902094332d3Sopenharmony_ci } 903094332d3Sopenharmony_ci if (errorCount < ATTI_BRUTE_SECOND_STAGE) { 904094332d3Sopenharmony_ci errorCount++; 905094332d3Sopenharmony_ci } 906094332d3Sopenharmony_ci ret = SetAntiBruteInfoById(templateId, errorCount, nowTime); 907094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 908094332d3Sopenharmony_ci LOG_ERROR("SetAntiBruteInfoById fail."); 909094332d3Sopenharmony_ci } 910094332d3Sopenharmony_ci return ret; 911094332d3Sopenharmony_ci} 912094332d3Sopenharmony_ci 913094332d3Sopenharmony_cistatic Buffer *GenerateDecodeCredential(const Buffer *deviceKey, const Buffer *pinData) 914094332d3Sopenharmony_ci{ 915094332d3Sopenharmony_ci if (pinData->contentSize <= AES_GCM_256_IV_SIZE + AES_GCM_256_TAG_SIZE) { 916094332d3Sopenharmony_ci LOG_ERROR("check pin data cipher info fail"); 917094332d3Sopenharmony_ci return NULL; 918094332d3Sopenharmony_ci } 919094332d3Sopenharmony_ci 920094332d3Sopenharmony_ci AesGcmParam param = {}; 921094332d3Sopenharmony_ci Buffer iv = GetTmpBuffer(pinData->buf, AES_GCM_256_IV_SIZE, AES_GCM_256_IV_SIZE); 922094332d3Sopenharmony_ci param.iv = &iv; 923094332d3Sopenharmony_ci param.key = GenerateEncryptionKey(deviceKey); 924094332d3Sopenharmony_ci if (param.key == NULL) { 925094332d3Sopenharmony_ci LOG_ERROR("GenerateEncryptionKey fail"); 926094332d3Sopenharmony_ci return NULL; 927094332d3Sopenharmony_ci } 928094332d3Sopenharmony_ci Buffer tag = GetTmpBuffer(pinData->buf + AES_GCM_256_IV_SIZE, AES_GCM_256_TAG_SIZE, AES_GCM_256_TAG_SIZE); 929094332d3Sopenharmony_ci uint32_t cipherTextSize = pinData->contentSize - AES_GCM_256_IV_SIZE - AES_GCM_256_TAG_SIZE; 930094332d3Sopenharmony_ci Buffer cipherText = GetTmpBuffer( 931094332d3Sopenharmony_ci pinData->buf + AES_GCM_256_IV_SIZE + AES_GCM_256_TAG_SIZE, cipherTextSize, cipherTextSize); 932094332d3Sopenharmony_ci Buffer *plainText = NULL; 933094332d3Sopenharmony_ci int32_t result = AesGcm256Decrypt(&cipherText, ¶m, &tag, &plainText); 934094332d3Sopenharmony_ci DestroyBuffer(param.key); 935094332d3Sopenharmony_ci if (result != RESULT_SUCCESS) { 936094332d3Sopenharmony_ci LOG_ERROR("Aes256GcmDecrypt fail"); 937094332d3Sopenharmony_ci return NULL; 938094332d3Sopenharmony_ci } 939094332d3Sopenharmony_ci 940094332d3Sopenharmony_ci return plainText; 941094332d3Sopenharmony_ci} 942094332d3Sopenharmony_ci 943094332d3Sopenharmony_cistatic ResultCode ProcessAuthPin( 944094332d3Sopenharmony_ci const Buffer *storeData, const Buffer *inputData, uint64_t templateId, Buffer *outRootSecret) 945094332d3Sopenharmony_ci{ 946094332d3Sopenharmony_ci Buffer *secret = CreateBufferBySize(SECRET_SIZE); 947094332d3Sopenharmony_ci Buffer *deviceKey = NULL; 948094332d3Sopenharmony_ci Buffer *pinDecodeCredential = NULL; 949094332d3Sopenharmony_ci ResultCode ret = RESULT_COMPARE_FAIL; 950094332d3Sopenharmony_ci if (!IsBufferValid(secret)) { 951094332d3Sopenharmony_ci LOG_ERROR("create buffer fail."); 952094332d3Sopenharmony_ci goto EXIT; 953094332d3Sopenharmony_ci } 954094332d3Sopenharmony_ci if (ReadPinFile(secret->buf, secret->maxSize, templateId, SECRET_SUFFIX) != RESULT_SUCCESS) { 955094332d3Sopenharmony_ci LOG_ERROR("read pin secret file fail."); 956094332d3Sopenharmony_ci goto EXIT; 957094332d3Sopenharmony_ci } 958094332d3Sopenharmony_ci secret->contentSize = secret->maxSize; 959094332d3Sopenharmony_ci deviceKey = DeriveDeviceKey(inputData, secret); 960094332d3Sopenharmony_ci if (!IsBufferValid(deviceKey)) { 961094332d3Sopenharmony_ci LOG_ERROR("generate deviceKey fail."); 962094332d3Sopenharmony_ci goto EXIT; 963094332d3Sopenharmony_ci } 964094332d3Sopenharmony_ci if ((outRootSecret != NULL) && 965094332d3Sopenharmony_ci GenerateRootSecret(deviceKey, inputData, outRootSecret) != RESULT_SUCCESS) { 966094332d3Sopenharmony_ci LOG_ERROR("generate rootSecret fail."); 967094332d3Sopenharmony_ci goto EXIT; 968094332d3Sopenharmony_ci } 969094332d3Sopenharmony_ci pinDecodeCredential = GenerateDecodeCredential(deviceKey, storeData); 970094332d3Sopenharmony_ci if (!CheckBufferWithSize(pinDecodeCredential, inputData->contentSize)) { 971094332d3Sopenharmony_ci LOG_ERROR("generate pinDecodeCredential fail."); 972094332d3Sopenharmony_ci goto EXIT; 973094332d3Sopenharmony_ci } 974094332d3Sopenharmony_ci if (CompareBuffer(inputData, pinDecodeCredential)) { 975094332d3Sopenharmony_ci LOG_INFO("auth pin success."); 976094332d3Sopenharmony_ci ret = RESULT_SUCCESS; 977094332d3Sopenharmony_ci goto EXIT; 978094332d3Sopenharmony_ci } 979094332d3Sopenharmony_ci LOG_ERROR("auth pin fail."); 980094332d3Sopenharmony_ci 981094332d3Sopenharmony_ciEXIT: 982094332d3Sopenharmony_ci DestroyBuffer(pinDecodeCredential); 983094332d3Sopenharmony_ci DestroyBuffer(deviceKey); 984094332d3Sopenharmony_ci DestroyBuffer(secret); 985094332d3Sopenharmony_ci return ret; 986094332d3Sopenharmony_ci} 987094332d3Sopenharmony_ci 988094332d3Sopenharmony_ci/* This is for example only, Should be implemented in trusted environment. */ 989094332d3Sopenharmony_ciResultCode AuthPinById(const Buffer *inputPinData, uint64_t templateId, Buffer *outRootSecret, ResultCode *compareRet) 990094332d3Sopenharmony_ci{ 991094332d3Sopenharmony_ci if (!CheckBufferWithSize(inputPinData, CONST_PIN_DATA_LEN) || 992094332d3Sopenharmony_ci templateId == INVALID_TEMPLATE_ID || compareRet == NULL) { 993094332d3Sopenharmony_ci LOG_ERROR("get invalid params."); 994094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 995094332d3Sopenharmony_ci } 996094332d3Sopenharmony_ci if (!LoadPinDb()) { 997094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 998094332d3Sopenharmony_ci return RESULT_NEED_INIT; 999094332d3Sopenharmony_ci } 1000094332d3Sopenharmony_ci *compareRet = RESULT_COMPARE_FAIL; 1001094332d3Sopenharmony_ci uint32_t index = MAX_CRYPTO_INFO_SIZE; 1002094332d3Sopenharmony_ci ResultCode ret = SearchPinIndex(templateId, &index); 1003094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1004094332d3Sopenharmony_ci return ret; 1005094332d3Sopenharmony_ci } 1006094332d3Sopenharmony_ci /* Update anti-brute-force information with authentication failure first */ 1007094332d3Sopenharmony_ci if (UpdateAntiBruteFile(templateId, false) != RESULT_SUCCESS) { 1008094332d3Sopenharmony_ci LOG_ERROR("update antiBrute file fail."); 1009094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1010094332d3Sopenharmony_ci } 1011094332d3Sopenharmony_ci Buffer *storeData = CreateBufferBySize(CONST_PIN_DATA_EXPAND_LEN); 1012094332d3Sopenharmony_ci if (!IsBufferValid(storeData)) { 1013094332d3Sopenharmony_ci LOG_ERROR("generate storeData fail."); 1014094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1015094332d3Sopenharmony_ci } 1016094332d3Sopenharmony_ci ret = ReadPinFile(storeData->buf, storeData->maxSize, templateId, CRYPTO_SUFFIX); 1017094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1018094332d3Sopenharmony_ci LOG_ERROR("read pin store file fail."); 1019094332d3Sopenharmony_ci DestroyBuffer(storeData); 1020094332d3Sopenharmony_ci return RESULT_BAD_READ; 1021094332d3Sopenharmony_ci } 1022094332d3Sopenharmony_ci storeData->contentSize = storeData->maxSize; 1023094332d3Sopenharmony_ci *compareRet = ProcessAuthPin(storeData, inputPinData, templateId, outRootSecret); 1024094332d3Sopenharmony_ci if ((*compareRet) == RESULT_SUCCESS) { 1025094332d3Sopenharmony_ci ret = UpdateAntiBruteFile(templateId, true); 1026094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1027094332d3Sopenharmony_ci LOG_ERROR("UpdateAntiBruteFile fail."); 1028094332d3Sopenharmony_ci goto EXIT; 1029094332d3Sopenharmony_ci } 1030094332d3Sopenharmony_ci } 1031094332d3Sopenharmony_ci LOG_INFO("AuthPinById end."); 1032094332d3Sopenharmony_ci 1033094332d3Sopenharmony_ciEXIT: 1034094332d3Sopenharmony_ci DestroyBuffer(storeData); 1035094332d3Sopenharmony_ci return ret; 1036094332d3Sopenharmony_ci} 1037094332d3Sopenharmony_ci 1038094332d3Sopenharmony_cistatic bool FindTemplateIdFromList(uint64_t storeTemplateId, const uint64_t *templateIdList, uint32_t templateIdListLen) 1039094332d3Sopenharmony_ci{ 1040094332d3Sopenharmony_ci for (uint32_t i = 0; i < templateIdListLen; ++i) { 1041094332d3Sopenharmony_ci if (templateIdList[i] == storeTemplateId) { 1042094332d3Sopenharmony_ci return true; 1043094332d3Sopenharmony_ci } 1044094332d3Sopenharmony_ci } 1045094332d3Sopenharmony_ci 1046094332d3Sopenharmony_ci return false; 1047094332d3Sopenharmony_ci} 1048094332d3Sopenharmony_ci 1049094332d3Sopenharmony_ciResultCode VerifyTemplateDataPin(const uint64_t *templateIdList, uint32_t templateIdListLen) 1050094332d3Sopenharmony_ci{ 1051094332d3Sopenharmony_ci if (templateIdListLen != 0 && templateIdList == NULL) { 1052094332d3Sopenharmony_ci LOG_ERROR("templateIdList should be not null, when templateIdListLen is not zero"); 1053094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1054094332d3Sopenharmony_ci } 1055094332d3Sopenharmony_ci if (!LoadPinDb()) { 1056094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 1057094332d3Sopenharmony_ci return RESULT_NEED_INIT; 1058094332d3Sopenharmony_ci } 1059094332d3Sopenharmony_ci uint32_t i = 0; 1060094332d3Sopenharmony_ci for (; i < g_pinDbOp->pinIndexLen; i++) { 1061094332d3Sopenharmony_ci if (FindTemplateIdFromList(g_pinDbOp->pinIndex[i].pinInfo.templateId, templateIdList, templateIdListLen)) { 1062094332d3Sopenharmony_ci continue; 1063094332d3Sopenharmony_ci } 1064094332d3Sopenharmony_ci ResultCode ret = DelPinById(g_pinDbOp->pinIndex[i].pinInfo.templateId); 1065094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1066094332d3Sopenharmony_ci LOG_ERROR("delete pin file fail."); 1067094332d3Sopenharmony_ci return RESULT_BAD_DEL; 1068094332d3Sopenharmony_ci } 1069094332d3Sopenharmony_ci } 1070094332d3Sopenharmony_ci LOG_INFO("VerifyTemplateDataPin succ."); 1071094332d3Sopenharmony_ci return RESULT_SUCCESS; 1072094332d3Sopenharmony_ci} 1073094332d3Sopenharmony_ci 1074094332d3Sopenharmony_cistatic ResultCode GenerateSalt(uint8_t *algoParameter, uint32_t *algoParameterLength, 1075094332d3Sopenharmony_ci uint8_t *localDeviceId, uint32_t deviceUuidLength) 1076094332d3Sopenharmony_ci{ 1077094332d3Sopenharmony_ci uint8_t sourceDataTemp[SOURCE_DATA_LENGTH] = { 0 }; 1078094332d3Sopenharmony_ci if (memcpy_s(sourceDataTemp, SOURCE_DATA_LENGTH, localDeviceId, deviceUuidLength) != EOK) { 1079094332d3Sopenharmony_ci LOG_ERROR("memcpy_s localDeviceId to sourceDataTemp failed"); 1080094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1081094332d3Sopenharmony_ci } 1082094332d3Sopenharmony_ci if (SecureRandom(&(sourceDataTemp[deviceUuidLength]), SALT_RANDOM_LENGTH) != RESULT_SUCCESS) { 1083094332d3Sopenharmony_ci LOG_ERROR("Generate random number failed"); 1084094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1085094332d3Sopenharmony_ci } 1086094332d3Sopenharmony_ci Buffer sourceData = GetTmpBuffer(sourceDataTemp, SOURCE_DATA_LENGTH, SOURCE_DATA_LENGTH); 1087094332d3Sopenharmony_ci if (!IsBufferValid(&sourceData)) { 1088094332d3Sopenharmony_ci LOG_ERROR("sourceData is invalid"); 1089094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1090094332d3Sopenharmony_ci } 1091094332d3Sopenharmony_ci Buffer *resultSha256 = Sha256Adaptor(&sourceData); 1092094332d3Sopenharmony_ci if (!IsBufferValid(resultSha256)) { 1093094332d3Sopenharmony_ci LOG_ERROR("result is invalid"); 1094094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1095094332d3Sopenharmony_ci } 1096094332d3Sopenharmony_ci if (memcpy_s(algoParameter, *algoParameterLength, resultSha256->buf, resultSha256->contentSize) != EOK) { 1097094332d3Sopenharmony_ci LOG_ERROR("memcpy_s result to algoParameter failed"); 1098094332d3Sopenharmony_ci DestroyBuffer(resultSha256); 1099094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1100094332d3Sopenharmony_ci } 1101094332d3Sopenharmony_ci *algoParameterLength = resultSha256->contentSize; 1102094332d3Sopenharmony_ci 1103094332d3Sopenharmony_ci DestroyBuffer(resultSha256); 1104094332d3Sopenharmony_ci LOG_INFO("GenerateAlgoParameterInner succ"); 1105094332d3Sopenharmony_ci return RESULT_SUCCESS; 1106094332d3Sopenharmony_ci} 1107094332d3Sopenharmony_ci 1108094332d3Sopenharmony_ciResultCode DoGenerateAlgoParameter(uint8_t *algoParameter, uint32_t *algoParameterLength, uint32_t *algoVersion, 1109094332d3Sopenharmony_ci uint8_t *localDeviceId, uint32_t deviceUuidLength) 1110094332d3Sopenharmony_ci{ 1111094332d3Sopenharmony_ci LOG_INFO("start"); 1112094332d3Sopenharmony_ci if (algoParameter == NULL || algoParameterLength == NULL || localDeviceId == NULL || algoVersion == NULL || 1113094332d3Sopenharmony_ci deviceUuidLength != DEVICE_UUID_LENGTH) { 1114094332d3Sopenharmony_ci LOG_ERROR("bad parameter"); 1115094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1116094332d3Sopenharmony_ci } 1117094332d3Sopenharmony_ci if (!LoadPinDb()) { 1118094332d3Sopenharmony_ci LOG_ERROR("LoadPinDb fail."); 1119094332d3Sopenharmony_ci return RESULT_NEED_INIT; 1120094332d3Sopenharmony_ci } 1121094332d3Sopenharmony_ci 1122094332d3Sopenharmony_ci if (GenerateSalt(algoParameter, algoParameterLength, localDeviceId, deviceUuidLength) != RESULT_SUCCESS) { 1123094332d3Sopenharmony_ci LOG_ERROR("Generate salt failed"); 1124094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1125094332d3Sopenharmony_ci } 1126094332d3Sopenharmony_ci *algoVersion = ALGORITHM_VERSION_0; 1127094332d3Sopenharmony_ci 1128094332d3Sopenharmony_ci LOG_INFO("gen algo succ size is [%{public}u] and version is [%{public}u]", *algoParameterLength, *algoVersion); 1129094332d3Sopenharmony_ci return RESULT_SUCCESS; 1130094332d3Sopenharmony_ci}