1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 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 "verifier_func.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include "securec.h"
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_ci#include "adaptor_algorithm.h"
21094332d3Sopenharmony_ci#include "adaptor_log.h"
22094332d3Sopenharmony_ci#include "adaptor_memory.h"
23094332d3Sopenharmony_ci#include "attribute.h"
24094332d3Sopenharmony_ci#include "buffer.h"
25094332d3Sopenharmony_ci#include "pin_db.h"
26094332d3Sopenharmony_ci
27094332d3Sopenharmony_citypedef enum VerifierState {
28094332d3Sopenharmony_ci    VERIFIER_STATE_INIT = 0,
29094332d3Sopenharmony_ci    VERIFIER_STATE_WAIT_SYNC = 1,
30094332d3Sopenharmony_ci    VERIFIER_STATE_WAIT_ACK = 2,
31094332d3Sopenharmony_ci    VERIFIER_STATE_FINISH = 3,
32094332d3Sopenharmony_ci} VerifierState;
33094332d3Sopenharmony_ci
34094332d3Sopenharmony_citypedef struct VerifierSchedule {
35094332d3Sopenharmony_ci    uint64_t scheduleId;
36094332d3Sopenharmony_ci    uint64_t templateId;
37094332d3Sopenharmony_ci    uint64_t timeStamp;
38094332d3Sopenharmony_ci    Buffer *selfUdid;
39094332d3Sopenharmony_ci    Buffer *peerUdid;
40094332d3Sopenharmony_ci    Buffer *peerPubKey;
41094332d3Sopenharmony_ci    Buffer *salt;
42094332d3Sopenharmony_ci    VerifierState state;
43094332d3Sopenharmony_ci} VerifierSchedule;
44094332d3Sopenharmony_ci
45094332d3Sopenharmony_cistatic KeyPair *g_keyPair = NULL;
46094332d3Sopenharmony_cistatic Buffer *g_fwkPubKey = NULL;
47094332d3Sopenharmony_cistatic VerifierSchedule *g_verifierSchedule = NULL;
48094332d3Sopenharmony_ci
49094332d3Sopenharmony_ci/* This is for example only, Should be implemented in trusted environment. */
50094332d3Sopenharmony_ciResultCode GenerateVerifierKeyPair(void)
51094332d3Sopenharmony_ci{
52094332d3Sopenharmony_ci    DestroyKeyPair(g_keyPair);
53094332d3Sopenharmony_ci    g_keyPair = GenerateEd25519KeyPair();
54094332d3Sopenharmony_ci    if (g_keyPair == NULL) {
55094332d3Sopenharmony_ci        LOG_ERROR("GenerateVerifierKeyPair fail!");
56094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
57094332d3Sopenharmony_ci    }
58094332d3Sopenharmony_ci    LOG_INFO("GenerateVerifierKeyPair success");
59094332d3Sopenharmony_ci    return RESULT_SUCCESS;
60094332d3Sopenharmony_ci}
61094332d3Sopenharmony_ci
62094332d3Sopenharmony_civoid DestroyVerifierKeyPair(void)
63094332d3Sopenharmony_ci{
64094332d3Sopenharmony_ci    LOG_INFO("DestroyVerifierKeyPair");
65094332d3Sopenharmony_ci    DestroyKeyPair(g_keyPair);
66094332d3Sopenharmony_ci    g_keyPair = NULL;
67094332d3Sopenharmony_ci}
68094332d3Sopenharmony_ci
69094332d3Sopenharmony_ci/* This is for example only, Should be implemented in trusted environment. */
70094332d3Sopenharmony_ciResultCode DoGetVerifierExecutorInfo(PinExecutorInfo *pinExecutorInfo)
71094332d3Sopenharmony_ci{
72094332d3Sopenharmony_ci    if (pinExecutorInfo == NULL) {
73094332d3Sopenharmony_ci        LOG_ERROR("check param fail!");
74094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
75094332d3Sopenharmony_ci    }
76094332d3Sopenharmony_ci    if (!IsEd25519KeyPairValid(g_keyPair)) {
77094332d3Sopenharmony_ci        LOG_ERROR("key pair not init!");
78094332d3Sopenharmony_ci        return RESULT_NEED_INIT;
79094332d3Sopenharmony_ci    }
80094332d3Sopenharmony_ci    uint32_t pubKeyLen = ED25519_FIX_PUBKEY_BUFFER_SIZE;
81094332d3Sopenharmony_ci    if (GetBufferData(g_keyPair->pubKey, pinExecutorInfo->pubKey, &pubKeyLen) != RESULT_SUCCESS) {
82094332d3Sopenharmony_ci        LOG_ERROR("GetBufferData fail!");
83094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
84094332d3Sopenharmony_ci    }
85094332d3Sopenharmony_ci    pinExecutorInfo->esl = PIN_EXECUTOR_SECURITY_LEVEL;
86094332d3Sopenharmony_ci    pinExecutorInfo->maxTemplateAcl = PIN_CAPABILITY_LEVEL;
87094332d3Sopenharmony_ci    return RESULT_SUCCESS;
88094332d3Sopenharmony_ci}
89094332d3Sopenharmony_ci
90094332d3Sopenharmony_ciint32_t DoSetVerifierFwkParam(const uint8_t *fwkPubKey, uint32_t fwkPubKeySize)
91094332d3Sopenharmony_ci{
92094332d3Sopenharmony_ci    if ((fwkPubKey == NULL) || (fwkPubKeySize != ED25519_FIX_PUBKEY_BUFFER_SIZE)) {
93094332d3Sopenharmony_ci        LOG_ERROR("DoSetVerifierFwkParam check param fail!");
94094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
95094332d3Sopenharmony_ci    }
96094332d3Sopenharmony_ci    DestroyBuffer(g_fwkPubKey);
97094332d3Sopenharmony_ci    g_fwkPubKey = CreateBufferByData(fwkPubKey, fwkPubKeySize);
98094332d3Sopenharmony_ci    if (g_fwkPubKey == NULL) {
99094332d3Sopenharmony_ci        LOG_ERROR("DoSetVerifierFwkParam create fwkPubKey fail!");
100094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
101094332d3Sopenharmony_ci    }
102094332d3Sopenharmony_ci    return RESULT_SUCCESS;
103094332d3Sopenharmony_ci}
104094332d3Sopenharmony_ci
105094332d3Sopenharmony_cistatic void DestroyVerifierSchedule(void)
106094332d3Sopenharmony_ci{
107094332d3Sopenharmony_ci    if (g_verifierSchedule == NULL) {
108094332d3Sopenharmony_ci        return;
109094332d3Sopenharmony_ci    }
110094332d3Sopenharmony_ci    DestroyBuffer(g_verifierSchedule->selfUdid);
111094332d3Sopenharmony_ci    DestroyBuffer(g_verifierSchedule->peerUdid);
112094332d3Sopenharmony_ci    DestroyBuffer(g_verifierSchedule->peerPubKey);
113094332d3Sopenharmony_ci    DestroyBuffer(g_verifierSchedule->salt);
114094332d3Sopenharmony_ci    Free(g_verifierSchedule);
115094332d3Sopenharmony_ci    g_verifierSchedule= NULL;
116094332d3Sopenharmony_ci}
117094332d3Sopenharmony_ci
118094332d3Sopenharmony_cistatic bool InitVerifierSchedule(uint64_t scheduleId)
119094332d3Sopenharmony_ci{
120094332d3Sopenharmony_ci    g_verifierSchedule = Malloc(sizeof(VerifierSchedule));
121094332d3Sopenharmony_ci    if (g_verifierSchedule == NULL) {
122094332d3Sopenharmony_ci        LOG_ERROR("malloc VerifierSchedule fail!");
123094332d3Sopenharmony_ci        return false;
124094332d3Sopenharmony_ci    }
125094332d3Sopenharmony_ci    (void)memset_s(g_verifierSchedule, sizeof(VerifierSchedule), 0, sizeof(VerifierSchedule));
126094332d3Sopenharmony_ci    g_verifierSchedule->scheduleId = scheduleId;
127094332d3Sopenharmony_ci    return true;
128094332d3Sopenharmony_ci}
129094332d3Sopenharmony_ci
130094332d3Sopenharmony_cistatic int32_t GetAuthInfoFromSchedule(uint64_t scheduleId, const uint8_t *extraInfo, uint32_t extraInfoSize)
131094332d3Sopenharmony_ci{
132094332d3Sopenharmony_ci    Attribute *attribute = NULL;
133094332d3Sopenharmony_ci    int32_t result = VerifyAndGetDataAttribute(scheduleId, &attribute, g_fwkPubKey, extraInfo, extraInfoSize);
134094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(result != RESULT_SUCCESS, result);
135094332d3Sopenharmony_ci
136094332d3Sopenharmony_ci    result = RESULT_GENERAL_ERROR;
137094332d3Sopenharmony_ci    g_verifierSchedule->selfUdid = GetBufferFromAttribute(attribute, ATTR_LOCAL_UDID, CONST_FWK_UDID_SIZE);
138094332d3Sopenharmony_ci    if (g_verifierSchedule->selfUdid == NULL) {
139094332d3Sopenharmony_ci        LOG_ERROR("get self udid fail!");
140094332d3Sopenharmony_ci        goto EXIT;
141094332d3Sopenharmony_ci    }
142094332d3Sopenharmony_ci    g_verifierSchedule->peerUdid = GetBufferFromAttribute(attribute, ATTR_PEER_UDID, CONST_FWK_UDID_SIZE);
143094332d3Sopenharmony_ci    if (g_verifierSchedule->peerUdid == NULL) {
144094332d3Sopenharmony_ci        LOG_ERROR("get peer udid fail!");
145094332d3Sopenharmony_ci        goto EXIT;
146094332d3Sopenharmony_ci    }
147094332d3Sopenharmony_ci    g_verifierSchedule->peerPubKey = GetBufferFromAttribute(
148094332d3Sopenharmony_ci        attribute, ATTR_PUBLIC_KEY, ED25519_FIX_PUBKEY_BUFFER_SIZE);
149094332d3Sopenharmony_ci    if (g_verifierSchedule->peerPubKey == NULL) {
150094332d3Sopenharmony_ci        LOG_ERROR("get peer public key fail!");
151094332d3Sopenharmony_ci        goto EXIT;
152094332d3Sopenharmony_ci    }
153094332d3Sopenharmony_ci    result = RESULT_SUCCESS;
154094332d3Sopenharmony_ci
155094332d3Sopenharmony_ciEXIT:
156094332d3Sopenharmony_ci    FreeAttribute(&attribute);
157094332d3Sopenharmony_ci    return result;
158094332d3Sopenharmony_ci}
159094332d3Sopenharmony_ci
160094332d3Sopenharmony_cistatic bool SetVerifyAckDataSalt(Attribute *attribute)
161094332d3Sopenharmony_ci{
162094332d3Sopenharmony_ci    if (g_verifierSchedule->salt != NULL) {
163094332d3Sopenharmony_ci        LOG_ERROR("get non null salt!");
164094332d3Sopenharmony_ci        return false;
165094332d3Sopenharmony_ci    }
166094332d3Sopenharmony_ci    g_verifierSchedule->salt = CreateBufferBySize(CONST_KEK_SALT_SIZE);
167094332d3Sopenharmony_ci    if (g_verifierSchedule->salt == NULL) {
168094332d3Sopenharmony_ci        LOG_ERROR("create salt fail!");
169094332d3Sopenharmony_ci        return false;
170094332d3Sopenharmony_ci    }
171094332d3Sopenharmony_ci    int32_t result = SecureRandom(g_verifierSchedule->salt->buf, g_verifierSchedule->salt->maxSize);
172094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
173094332d3Sopenharmony_ci        LOG_ERROR("random salt fail!");
174094332d3Sopenharmony_ci        return false;
175094332d3Sopenharmony_ci    }
176094332d3Sopenharmony_ci    g_verifierSchedule->salt->contentSize = g_verifierSchedule->salt->maxSize;
177094332d3Sopenharmony_ci    if (SetBufferToAttribute(attribute, PIN_ATTR_KEK_SALT, g_verifierSchedule->salt) != RESULT_SUCCESS) {
178094332d3Sopenharmony_ci        LOG_ERROR("set salt fail!");
179094332d3Sopenharmony_ci        return false;
180094332d3Sopenharmony_ci    }
181094332d3Sopenharmony_ci    return true;
182094332d3Sopenharmony_ci}
183094332d3Sopenharmony_ci
184094332d3Sopenharmony_cistatic bool SetVerifyAckDataPinParam(Attribute *attribute)
185094332d3Sopenharmony_ci{
186094332d3Sopenharmony_ci    uint64_t subType = 0;
187094332d3Sopenharmony_ci    if (GetSubType(g_verifierSchedule->templateId, &subType) != RESULT_SUCCESS) {
188094332d3Sopenharmony_ci        LOG_ERROR("GetSubType fail!");
189094332d3Sopenharmony_ci        return false;
190094332d3Sopenharmony_ci    }
191094332d3Sopenharmony_ci    if (SetAttributeUint64(attribute, ATTR_PIN_SUB_TYPE, subType) != RESULT_SUCCESS) {
192094332d3Sopenharmony_ci        LOG_ERROR("set sub type fail!");
193094332d3Sopenharmony_ci        return false;
194094332d3Sopenharmony_ci    }
195094332d3Sopenharmony_ci
196094332d3Sopenharmony_ci    Buffer *algoParam = CreateBufferBySize(CONST_SALT_LEN);
197094332d3Sopenharmony_ci    if (algoParam == NULL) {
198094332d3Sopenharmony_ci        LOG_ERROR("create algoParam fail!");
199094332d3Sopenharmony_ci        return false;
200094332d3Sopenharmony_ci    }
201094332d3Sopenharmony_ci    algoParam->contentSize = algoParam->maxSize;
202094332d3Sopenharmony_ci    uint32_t algoVersion = 0;
203094332d3Sopenharmony_ci    int32_t result = DoGetAlgoParameter(
204094332d3Sopenharmony_ci        g_verifierSchedule->templateId, algoParam->buf, &(algoParam->contentSize), &algoVersion);
205094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
206094332d3Sopenharmony_ci        LOG_ERROR("DoGetAlgoParameter fail!");
207094332d3Sopenharmony_ci        DestroyBuffer(algoParam);
208094332d3Sopenharmony_ci        return false;
209094332d3Sopenharmony_ci    }
210094332d3Sopenharmony_ci    if (SetBufferToAttribute(attribute, PIN_ATTR_ALGO_PARAM, algoParam) != RESULT_SUCCESS) {
211094332d3Sopenharmony_ci        LOG_ERROR("set algo param fail!");
212094332d3Sopenharmony_ci        DestroyBuffer(algoParam);
213094332d3Sopenharmony_ci        return false;
214094332d3Sopenharmony_ci    }
215094332d3Sopenharmony_ci    DestroyBuffer(algoParam);
216094332d3Sopenharmony_ci    if (SetAttributeUint32(attribute, PIN_ATTR_ALGO_VERSION, algoVersion) != RESULT_SUCCESS) {
217094332d3Sopenharmony_ci        LOG_ERROR("set algo version fail!");
218094332d3Sopenharmony_ci        return false;
219094332d3Sopenharmony_ci    }
220094332d3Sopenharmony_ci    return true;
221094332d3Sopenharmony_ci}
222094332d3Sopenharmony_ci
223094332d3Sopenharmony_cistatic Attribute *GetVerifyAckData()
224094332d3Sopenharmony_ci{
225094332d3Sopenharmony_ci    Attribute *attribute = GetAttributeDataBase(g_verifierSchedule->scheduleId, REMOTE_PIN_VERIFIER_ACK);
226094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
227094332d3Sopenharmony_ci
228094332d3Sopenharmony_ci    if (!SetVerifyAckDataSalt(attribute)) {
229094332d3Sopenharmony_ci        LOG_ERROR("SetVerifyAckDataSalt fail!");
230094332d3Sopenharmony_ci        goto ERROR;
231094332d3Sopenharmony_ci    }
232094332d3Sopenharmony_ci
233094332d3Sopenharmony_ci    if (!SetVerifyAckDataPinParam(attribute)) {
234094332d3Sopenharmony_ci        LOG_ERROR("SetVerifyAckDataPinParam fail!");
235094332d3Sopenharmony_ci        goto ERROR;
236094332d3Sopenharmony_ci    }
237094332d3Sopenharmony_ci
238094332d3Sopenharmony_ci    return attribute;
239094332d3Sopenharmony_ci
240094332d3Sopenharmony_ciERROR:
241094332d3Sopenharmony_ci    FreeAttribute(&attribute);
242094332d3Sopenharmony_ci    return NULL;
243094332d3Sopenharmony_ci}
244094332d3Sopenharmony_ci
245094332d3Sopenharmony_cistatic int32_t GetResultTlv(VerifierMsg *verifierMsg)
246094332d3Sopenharmony_ci{
247094332d3Sopenharmony_ci    Attribute *attribute = GetAttributeDataBase(g_verifierSchedule->scheduleId, REMOTE_PIN_MSG_NONE);
248094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_GENERAL_ERROR);
249094332d3Sopenharmony_ci
250094332d3Sopenharmony_ci    int32_t result = RESULT_GENERAL_ERROR;
251094332d3Sopenharmony_ci    if (!SetResultDataInfo(
252094332d3Sopenharmony_ci        attribute, PinResultToFwkResult(verifierMsg->authResult), g_verifierSchedule->templateId, NULL)) {
253094332d3Sopenharmony_ci        LOG_ERROR("SetResultDataInfo fail");
254094332d3Sopenharmony_ci        goto EXIT;
255094332d3Sopenharmony_ci    }
256094332d3Sopenharmony_ci
257094332d3Sopenharmony_ci    result = FormatTlvMsg(attribute, g_keyPair, verifierMsg->msgOut, &(verifierMsg->msgOutSize));
258094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
259094332d3Sopenharmony_ci        LOG_ERROR("FormatTlvMsg fail");
260094332d3Sopenharmony_ci        goto EXIT;
261094332d3Sopenharmony_ci    }
262094332d3Sopenharmony_ci
263094332d3Sopenharmony_ciEXIT:
264094332d3Sopenharmony_ci    FreeAttribute(&attribute);
265094332d3Sopenharmony_ci    return result;
266094332d3Sopenharmony_ci}
267094332d3Sopenharmony_ci
268094332d3Sopenharmony_cistatic bool IsVeriferMsgValid(VerifierMsg *verifierMsg)
269094332d3Sopenharmony_ci{
270094332d3Sopenharmony_ci    if (verifierMsg == NULL) {
271094332d3Sopenharmony_ci        LOG_ERROR("verifierMsg is null");
272094332d3Sopenharmony_ci        return false;
273094332d3Sopenharmony_ci    }
274094332d3Sopenharmony_ci    if ((verifierMsg->msgIn == NULL) || (verifierMsg->msgInSize == 0)) {
275094332d3Sopenharmony_ci        LOG_ERROR("verifierMsg msgIn is invalid");
276094332d3Sopenharmony_ci        return false;
277094332d3Sopenharmony_ci    }
278094332d3Sopenharmony_ci    if ((verifierMsg->msgOut == NULL) || (verifierMsg->msgOutSize == 0)) {
279094332d3Sopenharmony_ci        LOG_ERROR("verifierMsg msgOut is invalid");
280094332d3Sopenharmony_ci        return false;
281094332d3Sopenharmony_ci    }
282094332d3Sopenharmony_ci    return true;
283094332d3Sopenharmony_ci}
284094332d3Sopenharmony_ci
285094332d3Sopenharmony_ciint32_t DoVerifierAuth(uint64_t scheduleId, uint64_t templateId, VerifierMsg *verifierMsg)
286094332d3Sopenharmony_ci{
287094332d3Sopenharmony_ci    LOG_INFO("DoVerifierAuth start %{public}x", (uint16_t)scheduleId);
288094332d3Sopenharmony_ci    if (!IsVeriferMsgValid(verifierMsg)) {
289094332d3Sopenharmony_ci        LOG_ERROR("check param fail!");
290094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
291094332d3Sopenharmony_ci    }
292094332d3Sopenharmony_ci    DestroyVerifierSchedule();
293094332d3Sopenharmony_ci    if (!InitVerifierSchedule(scheduleId)) {
294094332d3Sopenharmony_ci        LOG_ERROR("InitVerifierSchedule fail!");
295094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
296094332d3Sopenharmony_ci    }
297094332d3Sopenharmony_ci    int32_t result = GetAuthInfoFromSchedule(scheduleId, verifierMsg->msgIn, verifierMsg->msgInSize);
298094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
299094332d3Sopenharmony_ci        LOG_ERROR("GetAuthInfoFromSchedule fail!");
300094332d3Sopenharmony_ci        goto ERROR;
301094332d3Sopenharmony_ci    }
302094332d3Sopenharmony_ci    g_verifierSchedule->templateId = templateId;
303094332d3Sopenharmony_ci    g_verifierSchedule->state = VERIFIER_STATE_WAIT_SYNC;
304094332d3Sopenharmony_ci
305094332d3Sopenharmony_ci    PinCredentialInfos pinCredentialInfo;
306094332d3Sopenharmony_ci    result = DoQueryPinInfo(templateId, &pinCredentialInfo);
307094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
308094332d3Sopenharmony_ci        LOG_ERROR("DoQueryPinInfo fail!");
309094332d3Sopenharmony_ci        goto ERROR;
310094332d3Sopenharmony_ci    }
311094332d3Sopenharmony_ci    if (pinCredentialInfo.freezeTime == 0) {
312094332d3Sopenharmony_ci        LOG_INFO("DoVerifierAuth success");
313094332d3Sopenharmony_ci        verifierMsg->authResult = RESULT_SUCCESS;
314094332d3Sopenharmony_ci        verifierMsg->msgOutSize = 0;
315094332d3Sopenharmony_ci        return RESULT_SUCCESS;
316094332d3Sopenharmony_ci    }
317094332d3Sopenharmony_ci
318094332d3Sopenharmony_ci    LOG_ERROR("DoVerifierAuth locked");
319094332d3Sopenharmony_ci    verifierMsg->authResult = RESULT_PIN_FREEZE;
320094332d3Sopenharmony_ci    result = GetResultTlv(verifierMsg);
321094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
322094332d3Sopenharmony_ci        LOG_ERROR("GetResultTlv fail!");
323094332d3Sopenharmony_ci        goto ERROR;
324094332d3Sopenharmony_ci    }
325094332d3Sopenharmony_ci    return RESULT_SUCCESS;
326094332d3Sopenharmony_ci
327094332d3Sopenharmony_ciERROR:
328094332d3Sopenharmony_ci    DestroyVerifierSchedule();
329094332d3Sopenharmony_ci    return result;
330094332d3Sopenharmony_ci}
331094332d3Sopenharmony_ci
332094332d3Sopenharmony_ciint32_t DoCancelVerifierAuth()
333094332d3Sopenharmony_ci{
334094332d3Sopenharmony_ci    LOG_INFO("DoCancelVerifierAuth start");
335094332d3Sopenharmony_ci    DestroyVerifierSchedule();
336094332d3Sopenharmony_ci    return RESULT_SUCCESS;
337094332d3Sopenharmony_ci}
338094332d3Sopenharmony_ci
339094332d3Sopenharmony_cistatic bool CheckCurrentSchedule(uint64_t scheduleId)
340094332d3Sopenharmony_ci{
341094332d3Sopenharmony_ci    if (g_verifierSchedule == NULL) {
342094332d3Sopenharmony_ci        LOG_ERROR("schedule not exist");
343094332d3Sopenharmony_ci        return false;
344094332d3Sopenharmony_ci    }
345094332d3Sopenharmony_ci    if (g_verifierSchedule->scheduleId != scheduleId) {
346094332d3Sopenharmony_ci        LOG_ERROR("schedule:%{public}x not match current:%{public}x",
347094332d3Sopenharmony_ci            (uint16_t)scheduleId, (uint16_t)(g_verifierSchedule->scheduleId));
348094332d3Sopenharmony_ci        return false;
349094332d3Sopenharmony_ci    }
350094332d3Sopenharmony_ci    return true;
351094332d3Sopenharmony_ci}
352094332d3Sopenharmony_ci
353094332d3Sopenharmony_cistatic int32_t DoHandleCollectorSync(VerifierMsg *verifierMsg)
354094332d3Sopenharmony_ci{
355094332d3Sopenharmony_ci    verifierMsg->isAuthEnd = false;
356094332d3Sopenharmony_ci    Attribute *dataIn = NULL;
357094332d3Sopenharmony_ci    int32_t result = VerifyAndGetDataAttribute(g_verifierSchedule->scheduleId,
358094332d3Sopenharmony_ci        &dataIn, g_verifierSchedule->peerPubKey, verifierMsg->msgIn, verifierMsg->msgInSize);
359094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
360094332d3Sopenharmony_ci        LOG_ERROR("VerifyAndGetDataAttribute fail");
361094332d3Sopenharmony_ci        return result;
362094332d3Sopenharmony_ci    }
363094332d3Sopenharmony_ci
364094332d3Sopenharmony_ci    result = CheckAttributeDataBase(
365094332d3Sopenharmony_ci        dataIn, g_verifierSchedule->scheduleId, REMOTE_PIN_COLLECTOR_SYNC, &(g_verifierSchedule->timeStamp));
366094332d3Sopenharmony_ci    FreeAttribute(&dataIn);
367094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
368094332d3Sopenharmony_ci        LOG_ERROR("CheckAttributeDataBase fail");
369094332d3Sopenharmony_ci        return result;
370094332d3Sopenharmony_ci    }
371094332d3Sopenharmony_ci
372094332d3Sopenharmony_ci    Attribute *dataOut = GetVerifyAckData();
373094332d3Sopenharmony_ci    if (dataOut == NULL) {
374094332d3Sopenharmony_ci        LOG_ERROR("GetVerifyAckData fail!");
375094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
376094332d3Sopenharmony_ci    }
377094332d3Sopenharmony_ci    result = FormatTlvMsg(dataOut, g_keyPair, verifierMsg->msgOut, &(verifierMsg->msgOutSize));
378094332d3Sopenharmony_ci    FreeAttribute(&dataOut);
379094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
380094332d3Sopenharmony_ci        LOG_ERROR("FormatTlvMsg fail!");
381094332d3Sopenharmony_ci        return result;
382094332d3Sopenharmony_ci    }
383094332d3Sopenharmony_ci    g_verifierSchedule->state = VERIFIER_STATE_WAIT_ACK;
384094332d3Sopenharmony_ci    return result;
385094332d3Sopenharmony_ci}
386094332d3Sopenharmony_ci
387094332d3Sopenharmony_cistatic void DestroyAesGcmParam(AesGcmParam *aesGcmParam)
388094332d3Sopenharmony_ci{
389094332d3Sopenharmony_ci    DestroyBuffer(aesGcmParam->key);
390094332d3Sopenharmony_ci    aesGcmParam->key = NULL;
391094332d3Sopenharmony_ci    DestroyBuffer(aesGcmParam->iv);
392094332d3Sopenharmony_ci    aesGcmParam->iv = NULL;
393094332d3Sopenharmony_ci    DestroyBuffer(aesGcmParam->aad);
394094332d3Sopenharmony_ci    aesGcmParam->aad = NULL;
395094332d3Sopenharmony_ci}
396094332d3Sopenharmony_ci
397094332d3Sopenharmony_cistatic bool GetAesGcmParam(AesGcmParam *aesGcmParam, const Attribute *attribute)
398094332d3Sopenharmony_ci{
399094332d3Sopenharmony_ci    (void)memset_s(aesGcmParam, sizeof(AesGcmParam), 0, sizeof(AesGcmParam));
400094332d3Sopenharmony_ci    aesGcmParam->aad = CreateBufferByData((const uint8_t *)CONST_KEK_AAD, CONST_KEK_AAD_SIZE);
401094332d3Sopenharmony_ci    if (aesGcmParam->aad == NULL) {
402094332d3Sopenharmony_ci        LOG_ERROR("create aad buffer fail");
403094332d3Sopenharmony_ci        goto ERROR;
404094332d3Sopenharmony_ci    }
405094332d3Sopenharmony_ci    aesGcmParam->iv = GetBufferFromAttribute(attribute, PIN_ATTR_KEK_IV, AES_GCM_256_IV_SIZE);
406094332d3Sopenharmony_ci    if (aesGcmParam->iv == NULL) {
407094332d3Sopenharmony_ci        LOG_ERROR("create iv buffer fail");
408094332d3Sopenharmony_ci        goto ERROR;
409094332d3Sopenharmony_ci    }
410094332d3Sopenharmony_ci    if (GetDistributeKey(g_verifierSchedule->peerUdid, g_verifierSchedule->salt, &(aesGcmParam->key)) !=
411094332d3Sopenharmony_ci        RESULT_SUCCESS) {
412094332d3Sopenharmony_ci        LOG_ERROR("GetDistributeKey fail");
413094332d3Sopenharmony_ci        goto ERROR;
414094332d3Sopenharmony_ci    }
415094332d3Sopenharmony_ci    return true;
416094332d3Sopenharmony_ci
417094332d3Sopenharmony_ciERROR:
418094332d3Sopenharmony_ci    DestroyAesGcmParam(aesGcmParam);
419094332d3Sopenharmony_ci    return false;
420094332d3Sopenharmony_ci}
421094332d3Sopenharmony_ci
422094332d3Sopenharmony_cistatic Buffer *GetPinData(const Attribute *attribute)
423094332d3Sopenharmony_ci{
424094332d3Sopenharmony_ci    AesGcmParam aesGcmParam = {};
425094332d3Sopenharmony_ci    if (!GetAesGcmParam(&aesGcmParam, attribute)) {
426094332d3Sopenharmony_ci        LOG_ERROR("GetAesGcmParam fail");
427094332d3Sopenharmony_ci        return NULL;
428094332d3Sopenharmony_ci    }
429094332d3Sopenharmony_ci    int32_t result = RESULT_GENERAL_ERROR;
430094332d3Sopenharmony_ci    Buffer *plainText = NULL;
431094332d3Sopenharmony_ci    Buffer *tag = NULL;
432094332d3Sopenharmony_ci    Buffer *cipherText = GetBufferFromAttribute(attribute, PIN_ATTR_KEK_SECRET, CONST_PIN_DATA_LEN);
433094332d3Sopenharmony_ci    if (cipherText == NULL) {
434094332d3Sopenharmony_ci        LOG_ERROR("GetBufferFromAttribute secret fail");
435094332d3Sopenharmony_ci        goto EXIT;
436094332d3Sopenharmony_ci    }
437094332d3Sopenharmony_ci    tag = GetBufferFromAttribute(attribute, PIN_ATTR_KEK_TAG, AES_GCM_256_TAG_SIZE);
438094332d3Sopenharmony_ci    if (tag == NULL) {
439094332d3Sopenharmony_ci        LOG_ERROR("GetBufferFromAttribute tag fail");
440094332d3Sopenharmony_ci        goto EXIT;
441094332d3Sopenharmony_ci    }
442094332d3Sopenharmony_ci    result = AesGcm256Decrypt(cipherText, &aesGcmParam, tag, &plainText);
443094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
444094332d3Sopenharmony_ci        LOG_ERROR("AesGcm256Decrypt fail");
445094332d3Sopenharmony_ci        goto EXIT;
446094332d3Sopenharmony_ci    }
447094332d3Sopenharmony_ci
448094332d3Sopenharmony_ciEXIT:
449094332d3Sopenharmony_ci    DestroyAesGcmParam(&aesGcmParam);
450094332d3Sopenharmony_ci    DestroyBuffer(cipherText);
451094332d3Sopenharmony_ci    DestroyBuffer(tag);
452094332d3Sopenharmony_ci    return plainText;
453094332d3Sopenharmony_ci}
454094332d3Sopenharmony_ci
455094332d3Sopenharmony_cistatic int32_t AuthPin(VerifierMsg *verifierMsg, Buffer *pinDataBuf)
456094332d3Sopenharmony_ci{
457094332d3Sopenharmony_ci    LOG_INFO("start");
458094332d3Sopenharmony_ci    verifierMsg->isAuthEnd = true;
459094332d3Sopenharmony_ci    verifierMsg->authResult = RESULT_GENERAL_ERROR;
460094332d3Sopenharmony_ci
461094332d3Sopenharmony_ci    PinCredentialInfos pinCredentialInfo = {};
462094332d3Sopenharmony_ci    ResultCode ret = DoQueryPinInfo(g_verifierSchedule->templateId, &pinCredentialInfo);
463094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
464094332d3Sopenharmony_ci        LOG_ERROR("DoQueryPinInfo fail.");
465094332d3Sopenharmony_ci        verifierMsg->msgOutSize = 0;
466094332d3Sopenharmony_ci        return RESULT_SUCCESS;
467094332d3Sopenharmony_ci    }
468094332d3Sopenharmony_ci
469094332d3Sopenharmony_ci    if (pinCredentialInfo.freezeTime == 0) {
470094332d3Sopenharmony_ci        ResultCode compareRet = RESULT_COMPARE_FAIL;
471094332d3Sopenharmony_ci        ResultCode result = AuthPinById(pinDataBuf, g_verifierSchedule->templateId, NULL, &compareRet);
472094332d3Sopenharmony_ci        if (result != RESULT_SUCCESS) {
473094332d3Sopenharmony_ci            LOG_ERROR("AuthPinById fail!");
474094332d3Sopenharmony_ci        }
475094332d3Sopenharmony_ci        verifierMsg->authResult = result != RESULT_SUCCESS ? result : compareRet;
476094332d3Sopenharmony_ci    } else {
477094332d3Sopenharmony_ci        LOG_ERROR("Pin is freezing.");
478094332d3Sopenharmony_ci        verifierMsg->authResult = RESULT_PIN_FREEZE;
479094332d3Sopenharmony_ci    }
480094332d3Sopenharmony_ci
481094332d3Sopenharmony_ci    ret = GetResultTlv(verifierMsg);
482094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
483094332d3Sopenharmony_ci        LOG_ERROR("GetResultTlv fail!");
484094332d3Sopenharmony_ci        verifierMsg->msgOutSize = 0;
485094332d3Sopenharmony_ci    }
486094332d3Sopenharmony_ci    return RESULT_SUCCESS;
487094332d3Sopenharmony_ci}
488094332d3Sopenharmony_ci
489094332d3Sopenharmony_cistatic int32_t DoHandleCollectorAck(VerifierMsg *verifierMsg)
490094332d3Sopenharmony_ci{
491094332d3Sopenharmony_ci    Attribute *dataIn = NULL;
492094332d3Sopenharmony_ci    int32_t result = VerifyAndGetDataAttribute(g_verifierSchedule->scheduleId,
493094332d3Sopenharmony_ci        &dataIn, g_verifierSchedule->peerPubKey, verifierMsg->msgIn, verifierMsg->msgInSize);
494094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
495094332d3Sopenharmony_ci        LOG_ERROR("VerifyAndGetDataAttribute fail");
496094332d3Sopenharmony_ci        return result;
497094332d3Sopenharmony_ci    }
498094332d3Sopenharmony_ci
499094332d3Sopenharmony_ci    result = CheckAttributeDataBase(
500094332d3Sopenharmony_ci        dataIn, g_verifierSchedule->scheduleId, REMOTE_PIN_COLLECTOR_ACK, &(g_verifierSchedule->timeStamp));
501094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
502094332d3Sopenharmony_ci        LOG_ERROR("CheckAttributeDataBase fail");
503094332d3Sopenharmony_ci        FreeAttribute(&dataIn);
504094332d3Sopenharmony_ci        return result;
505094332d3Sopenharmony_ci    }
506094332d3Sopenharmony_ci
507094332d3Sopenharmony_ci    Buffer *pinData = GetPinData(dataIn);
508094332d3Sopenharmony_ci    FreeAttribute(&dataIn);
509094332d3Sopenharmony_ci    if (pinData == NULL) {
510094332d3Sopenharmony_ci        LOG_ERROR("GetPinData fail");
511094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
512094332d3Sopenharmony_ci    }
513094332d3Sopenharmony_ci
514094332d3Sopenharmony_ci    result = AuthPin(verifierMsg, pinData);
515094332d3Sopenharmony_ci    DestroyBuffer(pinData);
516094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
517094332d3Sopenharmony_ci        LOG_ERROR("AuthPin fail");
518094332d3Sopenharmony_ci    }
519094332d3Sopenharmony_ci    DestroyVerifierSchedule();
520094332d3Sopenharmony_ci    return result;
521094332d3Sopenharmony_ci}
522094332d3Sopenharmony_ci
523094332d3Sopenharmony_ciint32_t DoSendMessageToVerifier(uint64_t scheduleId, VerifierMsg *verifierMsg)
524094332d3Sopenharmony_ci{
525094332d3Sopenharmony_ci    LOG_INFO("DoSendMessageToVerifier start schedule:%{public}x", (uint16_t)scheduleId);
526094332d3Sopenharmony_ci    if (!CheckCurrentSchedule(scheduleId) || !IsVeriferMsgValid(verifierMsg)) {
527094332d3Sopenharmony_ci        LOG_ERROR("check param fail!");
528094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
529094332d3Sopenharmony_ci    }
530094332d3Sopenharmony_ci    LOG_INFO("DoSendMessageToVerifier current state:%{public}d", g_verifierSchedule->state);
531094332d3Sopenharmony_ci    if (g_verifierSchedule->state == VERIFIER_STATE_WAIT_SYNC) {
532094332d3Sopenharmony_ci        return DoHandleCollectorSync(verifierMsg);
533094332d3Sopenharmony_ci    }
534094332d3Sopenharmony_ci    if (g_verifierSchedule->state == VERIFIER_STATE_WAIT_ACK) {
535094332d3Sopenharmony_ci        return DoHandleCollectorAck(verifierMsg);
536094332d3Sopenharmony_ci    }
537094332d3Sopenharmony_ci    return RESULT_GENERAL_ERROR;
538094332d3Sopenharmony_ci}
539