• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }