1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "all_in_one_func.h"
17
18 #include "securec.h"
19
20 #include "adaptor_algorithm.h"
21
22 static KeyPair *g_keyPair = NULL;
23 static Buffer *g_fwkPubKey = NULL;
24
GenerateResultTlv(Buffer * retTlv,int32_t resultCode,uint64_t scheduleId,uint64_t templateId,Buffer * rootSecret)25 static ResultCode GenerateResultTlv(
26 Buffer *retTlv, int32_t resultCode, uint64_t scheduleId, uint64_t templateId, Buffer *rootSecret)
27 {
28 Attribute *attribute = GetAttributeDataBase(scheduleId, REMOTE_PIN_MSG_NONE);
29 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_GENERAL_ERROR);
30
31 int32_t result = RESULT_GENERAL_ERROR;
32 if (!SetResultDataInfo(attribute, PinResultToFwkResult(resultCode), templateId, rootSecret)) {
33 LOG_ERROR("SetResultDataInfo fail");
34 goto EXIT;
35 }
36
37 uint32_t tlvSize = retTlv->maxSize;
38 result = FormatTlvMsg(attribute, g_keyPair, retTlv->buf, &tlvSize);
39 if (result != RESULT_SUCCESS) {
40 LOG_ERROR("FormatTlvMsg fail");
41 goto EXIT;
42 }
43 retTlv->contentSize = tlvSize;
44
45 EXIT:
46 FreeAttribute(&attribute);
47 return result;
48 }
49
GenerateAuthResultTlv(Buffer * retTlv,int32_t resultCode,uint64_t scheduleId,uint64_t templateId,PinAuthFwkInfo * pinAuthFwkInfo)50 static ResultCode GenerateAuthResultTlv(Buffer *retTlv, int32_t resultCode, uint64_t scheduleId,
51 uint64_t templateId, PinAuthFwkInfo *pinAuthFwkInfo)
52 {
53 Attribute *attribute = GetAttributeDataBase(scheduleId, REMOTE_PIN_MSG_NONE);
54 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_GENERAL_ERROR);
55
56 int32_t result = RESULT_GENERAL_ERROR;
57 if (!SetResultDataInfo(attribute, PinResultToFwkResult(resultCode), templateId, pinAuthFwkInfo->rootSecret)) {
58 LOG_ERROR("SetResultDataInfo fail");
59 goto EXIT;
60 }
61
62 if (pinAuthFwkInfo->authIntent == ABANDONED_PIN_AUTH && pinAuthFwkInfo->oldRootSecret != NULL) {
63 if (SetBufferToAttribute(attribute, ATTR_OLD_ROOT_SECRET, pinAuthFwkInfo->oldRootSecret) != RESULT_SUCCESS) {
64 LOG_ERROR("SetBufferToAttribute old root secret fail");
65 goto EXIT;
66 }
67 }
68
69 uint32_t tlvSize = retTlv->maxSize;
70 result = FormatTlvMsg(attribute, g_keyPair, retTlv->buf, &tlvSize);
71 if (result != RESULT_SUCCESS) {
72 LOG_ERROR("FormatTlvMsg fail");
73 goto EXIT;
74 }
75 retTlv->contentSize = tlvSize;
76
77 EXIT:
78 FreeAttribute(&attribute);
79 return result;
80 }
81
GetAuthInfoFromFwk(PinAuthParam * pinAuthParam,Buffer * extraInfo,PinAuthFwkInfo * pinAuthFwkInfo)82 static ResultCode GetAuthInfoFromFwk(PinAuthParam *pinAuthParam, Buffer *extraInfo, PinAuthFwkInfo *pinAuthFwkInfo)
83 {
84 Attribute *fwkData = NULL;
85 int32_t ret = VerifyAndGetDataAttribute(pinAuthParam->scheduleId, &fwkData, g_fwkPubKey, extraInfo->buf,
86 extraInfo->contentSize);
87 if (ret != RESULT_SUCCESS) {
88 LOG_ERROR("VerifyAndGetDataAttribute failed.");
89 return ret;
90 }
91
92 ret = GetAttributeInt32(fwkData, ATTR_AUTH_PURPOSE, &(pinAuthFwkInfo->authIntent));
93 if (ret != RESULT_SUCCESS) {
94 LOG_ERROR("GetAttributeInt32 auth purpose failed.");
95 return ret;
96 }
97
98 pinAuthFwkInfo->rootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
99 if (!IsBufferValid(pinAuthFwkInfo->rootSecret)) {
100 LOG_ERROR("rootSecret is invalid.");
101 return RESULT_NO_MEMORY;
102 }
103
104 if (pinAuthFwkInfo->authIntent == ABANDONED_PIN_AUTH) {
105 pinAuthFwkInfo->oldRootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
106 if (!IsBufferValid(pinAuthFwkInfo->oldRootSecret)) {
107 LOG_ERROR("old rootSecret is invalid.");
108 DestroyBuffer(pinAuthFwkInfo->rootSecret);
109 return RESULT_NO_MEMORY;
110 }
111 }
112
113 return RESULT_SUCCESS;
114 }
115
SetFwkInfoRootSecret(uint64_t templateId,PinAuthFwkInfo * pinAuthFwkInfo)116 static ResultCode SetFwkInfoRootSecret(uint64_t templateId, PinAuthFwkInfo *pinAuthFwkInfo)
117 {
118 LOG_INFO("start.");
119 if (pinAuthFwkInfo == NULL) {
120 LOG_ERROR("bad param!");
121 return RESULT_BAD_PARAM;
122 }
123 if (pinAuthFwkInfo->authIntent == ABANDONED_PIN_AUTH) {
124 Buffer *newRootSecret = GenerateDecodeRootSecret(templateId, pinAuthFwkInfo->rootSecret);
125 if (newRootSecret == NULL) {
126 LOG_ERROR("GenerateDecodeRootSecret fail!");
127 return RESULT_GENERAL_ERROR;
128 }
129
130 if (!CheckBufferWithSize(newRootSecret, ROOT_SECRET_LEN)) {
131 LOG_ERROR("newRootSecret is invlaid!");
132 DestroyBuffer(newRootSecret);
133 return RESULT_GENERAL_ERROR;
134 }
135
136 if (memcpy_s(pinAuthFwkInfo->oldRootSecret->buf, pinAuthFwkInfo->oldRootSecret->maxSize,
137 pinAuthFwkInfo->rootSecret->buf, pinAuthFwkInfo->rootSecret->contentSize) != EOK) {
138 LOG_ERROR("copy old rootSecret fail!");
139 DestroyBuffer(newRootSecret);
140 return RESULT_BAD_COPY;
141 }
142 pinAuthFwkInfo->oldRootSecret->contentSize = pinAuthFwkInfo->rootSecret->contentSize;
143
144 if (memcpy_s(pinAuthFwkInfo->rootSecret->buf, pinAuthFwkInfo->rootSecret->maxSize,
145 newRootSecret->buf, newRootSecret->contentSize) != EOK) {
146 LOG_ERROR("copy rootSecret fail!");
147 DestroyBuffer(newRootSecret);
148 return RESULT_BAD_COPY;
149 }
150 pinAuthFwkInfo->rootSecret->contentSize = newRootSecret->contentSize;
151 DestroyBuffer(newRootSecret);
152 }
153 return RESULT_SUCCESS;
154 }
155
DoEnrollPin(PinEnrollParam * pinEnrollParam,Buffer * retTlv)156 ResultCode DoEnrollPin(PinEnrollParam *pinEnrollParam, Buffer *retTlv)
157 {
158 if (pinEnrollParam == NULL || !IsBufferValid(retTlv)) {
159 LOG_ERROR("get invalid params.");
160 return RESULT_BAD_PARAM;
161 }
162 uint64_t templateId = INVALID_TEMPLATE_ID;
163 Buffer *rootSecret = CreateBufferBySize(ROOT_SECRET_LEN);
164 if (!IsBufferValid(rootSecret)) {
165 LOG_ERROR("no memory.");
166 return RESULT_BAD_PARAM;
167 }
168 ResultCode ret = AddPin(pinEnrollParam, &templateId, rootSecret);
169 if (ret != RESULT_SUCCESS) {
170 LOG_ERROR("AddPin fail.");
171 DestroyBuffer(rootSecret);
172 return ret;
173 }
174
175 ret = GenerateResultTlv(retTlv, RESULT_SUCCESS, pinEnrollParam->scheduleId, templateId, rootSecret);
176 if (ret != RESULT_SUCCESS) {
177 LOG_ERROR("GenerateRetTlv DoEnrollPin fail.");
178 }
179
180 DestroyBuffer(rootSecret);
181 return ret;
182 }
183
DoAllInOneAuth(uint64_t scheduleId,uint64_t templateId,const uint8_t * extraInfo,uint32_t extraInfoSize,AlgoParamOut * algoParam)184 ResultCode DoAllInOneAuth(uint64_t scheduleId, uint64_t templateId,
185 const uint8_t *extraInfo, uint32_t extraInfoSize, AlgoParamOut *algoParam)
186 {
187 LOG_INFO("DoAllInOneAuth start %{public}x", (uint16_t)scheduleId);
188 if ((extraInfo == NULL) || (extraInfoSize == 0) || (extraInfoSize > MAX_EXECUTOR_MSG_LEN) || (algoParam == NULL)) {
189 LOG_ERROR("check param fail!");
190 return RESULT_BAD_PARAM;
191 }
192
193 ResultCode result = GetSubType(templateId, &(algoParam->subType));
194 if (result != RESULT_SUCCESS) {
195 LOG_ERROR("GetSubType fail!");
196 return result;
197 }
198 uint32_t algoParameterSize = CONST_SALT_LEN;
199 result = DoGetAlgoParameter(templateId, algoParam->algoParameter, &algoParameterSize, &(algoParam->algoVersion));
200 if (result != RESULT_SUCCESS) {
201 LOG_ERROR("DoGetAlgoParameter fail!");
202 }
203 return result;
204 }
205
DoAuthPin(PinAuthParam * pinAuthParam,Buffer * extraInfo,Buffer * retTlv,ResultCode * compareRet)206 ResultCode DoAuthPin(PinAuthParam *pinAuthParam, Buffer *extraInfo, Buffer *retTlv, ResultCode *compareRet)
207 {
208 LOG_INFO("start.");
209 if (!IsBufferValid(retTlv) || pinAuthParam == NULL || compareRet == NULL) {
210 LOG_ERROR("check param fail!");
211 return RESULT_BAD_PARAM;
212 }
213 *compareRet = RESULT_COMPARE_FAIL;
214
215 PinCredentialInfos pinCredentialInfo = {};
216 PinAuthFwkInfo pinAuthFwkInfo = {0};
217 ResultCode ret = GetAuthInfoFromFwk(pinAuthParam, extraInfo, &pinAuthFwkInfo);
218 if (ret != RESULT_SUCCESS) {
219 LOG_ERROR("GetAuthInfoFromFwk fail.");
220 return ret;
221 }
222
223 ret = DoQueryPinInfo(pinAuthParam->templateId, &pinCredentialInfo);
224 if (ret != RESULT_SUCCESS) {
225 LOG_ERROR("DoQueryPinInfo fail.");
226 goto EXIT;
227 }
228
229 if (pinCredentialInfo.freezeTime == 0) {
230 Buffer pinData = GetTmpBuffer(pinAuthParam->pinData, CONST_PIN_DATA_LEN, CONST_PIN_DATA_LEN);
231 ret = AuthPinById(&pinData, pinAuthParam->templateId, pinAuthParam->pinLength,
232 pinAuthFwkInfo.rootSecret, compareRet);
233 if (ret != RESULT_SUCCESS) {
234 LOG_ERROR("AuthPinById fail.");
235 goto EXIT;
236 }
237 } else {
238 LOG_ERROR("Pin is freezing.");
239 *compareRet = RESULT_PIN_FREEZE;
240 }
241
242 if (*compareRet == RESULT_SUCCESS) {
243 ret = SetFwkInfoRootSecret(pinAuthParam->templateId, &pinAuthFwkInfo);
244 if (ret != RESULT_SUCCESS) {
245 LOG_ERROR("SetFwkInfoRootSecret fail.");
246 goto EXIT;
247 }
248 }
249
250 ret = GenerateAuthResultTlv(retTlv, *compareRet, pinAuthParam->scheduleId, pinAuthParam->templateId,
251 &pinAuthFwkInfo);
252 if (ret != RESULT_SUCCESS) {
253 LOG_ERROR("GenerateRetTlv DoAuthPin fail.");
254 }
255
256 EXIT:
257 DestroyBuffer(pinAuthFwkInfo.rootSecret);
258 DestroyBuffer(pinAuthFwkInfo.oldRootSecret);
259 return ret;
260 }
261
DoDeleteTemplate(uint64_t templateId)262 ResultCode DoDeleteTemplate(uint64_t templateId)
263 {
264 ResultCode ret = DelPinById(templateId);
265 if (ret != RESULT_SUCCESS) {
266 LOG_ERROR("delete pin fail.");
267 return RESULT_BAD_DEL;
268 }
269 return RESULT_SUCCESS;
270 }
271
272 /* This is for example only, Should be implemented in trusted environment. */
GenerateAllInOneKeyPair(void)273 ResultCode GenerateAllInOneKeyPair(void)
274 {
275 DestroyKeyPair(g_keyPair);
276 g_keyPair = GenerateEd25519KeyPair();
277 if (g_keyPair == NULL) {
278 LOG_ERROR("GenerateEd25519Keypair fail!");
279 return RESULT_GENERAL_ERROR;
280 }
281 LOG_INFO("GenerateKeyPair success");
282 return RESULT_SUCCESS;
283 }
284
DestroyAllInOneKeyPair(void)285 void DestroyAllInOneKeyPair(void)
286 {
287 DestroyKeyPair(g_keyPair);
288 g_keyPair = NULL;
289 LOG_INFO("DestroyKeyPair success");
290 }
291
292 /* This is for example only, Should be implemented in trusted environment. */
DoGetAllInOneExecutorInfo(PinExecutorInfo * pinExecutorInfo)293 ResultCode DoGetAllInOneExecutorInfo(PinExecutorInfo *pinExecutorInfo)
294 {
295 if (pinExecutorInfo == NULL) {
296 LOG_ERROR("check param fail!");
297 return RESULT_BAD_PARAM;
298 }
299 if (!IsEd25519KeyPairValid(g_keyPair)) {
300 LOG_ERROR("key pair not init!");
301 return RESULT_NEED_INIT;
302 }
303 uint32_t pubKeyLen = ED25519_FIX_PUBKEY_BUFFER_SIZE;
304 if (GetBufferData(g_keyPair->pubKey, pinExecutorInfo->pubKey, &pubKeyLen) != RESULT_SUCCESS) {
305 LOG_ERROR("GetBufferData fail!");
306 return RESULT_UNKNOWN;
307 }
308 pinExecutorInfo->esl = PIN_EXECUTOR_SECURITY_LEVEL;
309 pinExecutorInfo->maxTemplateAcl = PIN_CAPABILITY_LEVEL;
310 return RESULT_SUCCESS;
311 }
312
DoSetAllInOneFwkParam(const uint64_t * templateIdList,uint32_t templateIdListLen,const uint8_t * fwkPubKey,uint32_t fwkPubKeySize)313 ResultCode DoSetAllInOneFwkParam(
314 const uint64_t *templateIdList, uint32_t templateIdListLen, const uint8_t *fwkPubKey, uint32_t fwkPubKeySize)
315 {
316 if (((templateIdListLen != 0) && (templateIdList == NULL)) ||
317 (fwkPubKey == NULL) || (fwkPubKeySize != ED25519_FIX_PUBKEY_BUFFER_SIZE)) {
318 LOG_ERROR("templateIdList should be not null, when templateIdListLen is not zero");
319 return RESULT_BAD_PARAM;
320 }
321 DestroyBuffer(g_fwkPubKey);
322 g_fwkPubKey = CreateBufferByData(fwkPubKey, fwkPubKeySize);
323 if (g_fwkPubKey == NULL) {
324 LOG_ERROR("DoSetAllInOneFwkParam create fwkPubKey fail!");
325 return RESULT_NO_MEMORY;
326 }
327 ResultCode ret = VerifyTemplateDataPin(templateIdList, templateIdListLen);
328 if (ret != RESULT_SUCCESS) {
329 LOG_ERROR("Verify TemplateDataPin fail.");
330 return ret;
331 }
332 return RESULT_SUCCESS;
333 }
334
DoWriteAntiBruteInfoToFile(uint64_t templateId)335 ResultCode DoWriteAntiBruteInfoToFile(uint64_t templateId)
336 {
337 ResultCode ret = RefreshAntiBruteInfoToFile(templateId);
338 if (ret != RESULT_SUCCESS) {
339 LOG_ERROR("RefreshAntiBruteInfoToFile fail.");
340 }
341 return ret;
342 }
343
GetRootSecretFromAttr(Attribute * fwkData,AttributeKey key,Buffer ** rootSecret)344 static int32_t GetRootSecretFromAttr(Attribute *fwkData, AttributeKey key, Buffer **rootSecret)
345 {
346 Uint8Array *array = CreateUint8ArrayBySize(ROOT_SECRET_LEN);
347 IF_TRUE_LOGE_AND_RETURN_VAL(array == NULL, RESULT_BAD_PARAM);
348
349 ResultCode ret = GetAttributeUint8Array(fwkData, key, array);
350 if (ret != RESULT_SUCCESS) {
351 LOG_ERROR("There is no rootSecret in this attribute.");
352 DestroyUint8Array(&array);
353 return RESULT_BAD_PARAM;
354 }
355
356 *rootSecret = CreateBufferByData(array->data, array->len);
357 if (!IsBufferValid(*rootSecret)) {
358 LOG_ERROR("CreateBufferByData failed.");
359 DestroyUint8Array(&array);
360 DestroyBuffer(*rootSecret);
361 *rootSecret = NULL;
362 return RESULT_GENERAL_ERROR;
363 }
364 DestroyUint8Array(&array);
365 return RESULT_SUCCESS;
366 }
367
GetRootSecretFromFwkInfo(uint64_t scheduleId,Buffer * extraInfo,PinAbandonExtraInfo * pinAbandonExtraInfo)368 static int32_t GetRootSecretFromFwkInfo(uint64_t scheduleId, Buffer *extraInfo,
369 PinAbandonExtraInfo *pinAbandonExtraInfo)
370 {
371 if (pinAbandonExtraInfo == NULL || !IsBufferValid(extraInfo)) {
372 LOG_ERROR("bad param.");
373 return RESULT_BAD_PARAM;
374 }
375 Attribute *fwkData = NULL;
376 int32_t ret = VerifyAndGetDataAttribute(scheduleId, &fwkData, g_fwkPubKey, extraInfo->buf,
377 extraInfo->contentSize);
378 if (ret != RESULT_SUCCESS) {
379 LOG_ERROR("VerifyAndGetDataAttribute failed.");
380 goto EXIT;
381 }
382
383 ret = GetRootSecretFromAttr(fwkData, ATTR_OLD_ROOT_SECRET, &(pinAbandonExtraInfo->oldRootSecret));
384 if (ret != RESULT_SUCCESS) {
385 LOG_ERROR("GetRootSecretFromAttr old rootSecret failed.");
386 goto EXIT;
387 }
388
389 ret = GetRootSecretFromAttr(fwkData, ATTR_ROOT_SECRET, &(pinAbandonExtraInfo->newRootSecret));
390 if (ret != RESULT_SUCCESS) {
391 LOG_ERROR("GetRootSecretFromAttr rootSecret failed.");
392 goto EXIT;
393 }
394
395 uint64_t templateIdIds[MAX_TEMPLATE_OF_SCHEDUAL];
396 Uint64Array buffer = {templateIdIds, MAX_TEMPLATE_OF_SCHEDUAL};
397 ret = GetAttributeUint64Array(fwkData, ATTR_TEMPLATE_ID_LIST, &buffer);
398 if (ret != RESULT_SUCCESS) {
399 LOG_ERROR("get templateIds failed.");
400 goto EXIT;
401 }
402
403 pinAbandonExtraInfo->oldTemplateId = templateIdIds[0];
404 pinAbandonExtraInfo->newTemplateId = templateIdIds[1];
405 EXIT:
406 FreeAttribute(&fwkData);
407 return ret;
408 }
409
DoAbandonPin(PinAbandonParam * pinAbandonParam,Buffer * extraInfo,Buffer * retTlv)410 ResultCode DoAbandonPin(PinAbandonParam *pinAbandonParam, Buffer *extraInfo, Buffer *retTlv)
411 {
412 if (pinAbandonParam == NULL || !IsBufferValid(extraInfo) || !IsBufferValid(retTlv)) {
413 LOG_ERROR("get invalid params.");
414 return RESULT_BAD_PARAM;
415 }
416
417 PinAbandonExtraInfo pinAbandonExtraInfo = {0};
418 ResultCode ret = GetRootSecretFromFwkInfo(pinAbandonParam->scheduleId, extraInfo, &pinAbandonExtraInfo);
419 if (ret != RESULT_SUCCESS) {
420 LOG_ERROR("GetRootSecretFromFwkInfo failed.");
421 goto EXIT;
422 }
423
424 if (pinAbandonExtraInfo.oldTemplateId != pinAbandonParam->templateId) {
425 LOG_ERROR("bad param");
426 ret = RESULT_BAD_PARAM;
427 goto EXIT;
428 }
429
430 if (pinAbandonExtraInfo.oldRootSecret == NULL || pinAbandonExtraInfo.newRootSecret == NULL) {
431 LOG_ERROR("bad param");
432 ret = RESULT_BAD_PARAM;
433 goto EXIT;
434 }
435
436 ret = Abandon(pinAbandonExtraInfo.oldTemplateId, pinAbandonExtraInfo.newTemplateId,
437 pinAbandonExtraInfo.oldRootSecret, pinAbandonExtraInfo.newRootSecret);
438 if (ret != RESULT_SUCCESS) {
439 LOG_ERROR("Abandon fail.");
440 goto EXIT;
441 }
442
443 ret = GenerateResultTlv(retTlv, RESULT_SUCCESS, pinAbandonParam->scheduleId, pinAbandonParam->templateId, NULL);
444 if (ret != RESULT_SUCCESS) {
445 LOG_ERROR("GenerateRetTlv DoAbandonPin fail.");
446 goto EXIT;
447 }
448
449 EXIT:
450 DestroyBuffer(pinAbandonExtraInfo.oldRootSecret);
451 DestroyBuffer(pinAbandonExtraInfo.newRootSecret);
452 return ret;
453 }
454
DoRestartLockoutDuration(int32_t userId)455 ResultCode DoRestartLockoutDuration(int32_t userId)
456 {
457 ResultCode ret = RestartLockoutDurationByUserId(userId);
458 if (ret != RESULT_SUCCESS) {
459 LOG_ERROR("RestartLockoutDurationByUserId fail.");
460 }
461 return ret;
462 }