1 /*
2 * Copyright (c) 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 "executor_func_common.h"
17
18 #include <inttypes.h>
19
20 #include "securec.h"
21
22 #include "adaptor_algorithm.h"
23 #include "adaptor_log.h"
24 #include "adaptor_memory.h"
25 #include "adaptor_time.h"
26 #include "attribute.h"
27
SetBufferToAttribute(Attribute * attribute,AttributeKey key,Buffer * buf)28 int32_t SetBufferToAttribute(Attribute *attribute, AttributeKey key, Buffer *buf)
29 {
30 if ((attribute == NULL) || !IsBufferValid(buf)) {
31 LOG_ERROR("SetBufferToAttribute bad param!");
32 return RESULT_BAD_PARAM;
33 }
34 Uint8Array uint8Array = {
35 .data = buf->buf,
36 .len = buf->contentSize,
37 };
38 return SetAttributeUint8Array(attribute, key, uint8Array);
39 }
40
GetBufferFromAttributeBase(const Attribute * attribute,AttributeKey key,bool checkSize,uint32_t size)41 static Buffer *GetBufferFromAttributeBase(const Attribute *attribute, AttributeKey key, bool checkSize, uint32_t size)
42 {
43 if (attribute == NULL) {
44 LOG_ERROR("GetBufferFromAttributeBase bad param!");
45 return NULL;
46 }
47 uint32_t len = 0;
48 int32_t result = GetAttributeLength(attribute, key, &len);
49 if ((result != RESULT_SUCCESS) || (checkSize && (len != size))) {
50 LOG_ERROR("get attribute:%{public}d length:%{public}u fail!", key, len);
51 return NULL;
52 }
53
54 Buffer *buffer = CreateBufferBySize(len);
55 IF_TRUE_LOGE_AND_RETURN_VAL(buffer == NULL, NULL);
56
57 Uint8Array uint8Array = {
58 .data = buffer->buf,
59 .len = buffer->maxSize,
60 };
61 result = GetAttributeUint8Array(attribute, key, &uint8Array);
62 if (result != RESULT_SUCCESS) {
63 LOG_ERROR("get attrbute %{public}d fail!", key);
64 DestroyBuffer(buffer);
65 return NULL;
66 }
67 buffer->contentSize = uint8Array.len;
68 return buffer;
69 }
70
GetBufferFromAttribute(const Attribute * attribute,AttributeKey key,uint32_t size)71 Buffer *GetBufferFromAttribute(const Attribute *attribute, AttributeKey key, uint32_t size)
72 {
73 return GetBufferFromAttributeBase(attribute, key, true, size);
74 }
75
GetAttributeDataBase(uint64_t scheduleId,RemotePinMsgId msgId)76 Attribute *GetAttributeDataBase(uint64_t scheduleId, RemotePinMsgId msgId)
77 {
78 Attribute *attribute = CreateEmptyAttribute();
79 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
80
81 int32_t result = SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, scheduleId);
82 if (result != RESULT_SUCCESS) {
83 LOG_ERROR("set schedule id fail!");
84 FreeAttribute(&attribute);
85 return NULL;
86 }
87
88 if (msgId != REMOTE_PIN_MSG_NONE) {
89 result = SetAttributeUint64(attribute, ATTR_TIME_STAMP, GetRtcTime());
90 if (result != RESULT_SUCCESS) {
91 LOG_ERROR("set time stamp fail!");
92 FreeAttribute(&attribute);
93 return NULL;
94 }
95
96 result = SetAttributeUint32(attribute, PIN_ATTR_MSG_ID, msgId);
97 if (result != RESULT_SUCCESS) {
98 LOG_ERROR("set msg id fail!");
99 FreeAttribute(&attribute);
100 return NULL;
101 }
102 }
103
104 return attribute;
105 }
106
GetRootMsg(const Attribute * data,const KeyPair * keyPair,Uint8Array * rootMsg)107 static int32_t GetRootMsg(const Attribute *data, const KeyPair *keyPair, Uint8Array *rootMsg)
108 {
109 Uint8Array dataMsg = {
110 .data = rootMsg->data,
111 .len = rootMsg->len
112 };
113 int32_t result = GetAttributeSerializedMsg(data, &dataMsg);
114 if (result != RESULT_SUCCESS) {
115 LOG_ERROR("GetAttributeSerializedMsg fail!");
116 return result;
117 }
118
119 Buffer dataBuf = GetTmpBuffer(dataMsg.data, dataMsg.len, dataMsg.len);
120 Buffer *sign = NULL;
121 Attribute *attribute = NULL;
122 result = Ed25519Sign(keyPair, &dataBuf, &sign);
123 if (result != RESULT_SUCCESS) {
124 LOG_ERROR("Ed25519Sign fail!");
125 goto EXIT;
126 }
127 attribute = CreateEmptyAttribute();
128 if (attribute == NULL) {
129 LOG_ERROR("get root fail!");
130 result = RESULT_GENERAL_ERROR;
131 goto EXIT;
132 }
133
134 result = SetBufferToAttribute(attribute, ATTR_DATA, &dataBuf);
135 if (result != RESULT_SUCCESS) {
136 LOG_ERROR("set data fail!");
137 goto EXIT;
138 }
139 result = SetBufferToAttribute(attribute, ATTR_SIGNATURE, sign);
140 if (result != RESULT_SUCCESS) {
141 LOG_ERROR("set sign fail!");
142 goto EXIT;
143 }
144
145 result = GetAttributeSerializedMsg(attribute, rootMsg);
146 if (result != RESULT_SUCCESS) {
147 LOG_ERROR("get serialized root fail!");
148 goto EXIT;
149 }
150
151 EXIT:
152 DestroyBuffer(sign);
153 FreeAttribute(&attribute);
154 return result;
155 }
156
FormatTlvMsg(const Attribute * data,const KeyPair * keyPair,uint8_t * msg,uint32_t * msgSize)157 int32_t FormatTlvMsg(const Attribute *data, const KeyPair *keyPair, uint8_t *msg, uint32_t *msgSize)
158 {
159 if ((data == NULL) || !IsEd25519KeyPairValid(keyPair) || (msg == NULL) || (msgSize == NULL)) {
160 LOG_ERROR("FormatTlvMsg check param fail!");
161 return RESULT_BAD_PARAM;
162 }
163 Uint8Array uint8Array = {
164 .data = msg,
165 .len = *msgSize,
166 };
167 int32_t result = GetRootMsg(data, keyPair, &uint8Array);
168 if (result != RESULT_SUCCESS) {
169 LOG_ERROR("GetRootMsg fail!");
170 return result;
171 }
172 Attribute *attribute = CreateEmptyAttribute();
173 if (attribute == NULL) {
174 LOG_ERROR("create root attribute fail!");
175 result = RESULT_GENERAL_ERROR;
176 goto EXIT;
177 }
178 result = SetAttributeUint8Array(attribute, ATTR_ROOT, uint8Array);
179 if (result != RESULT_SUCCESS) {
180 LOG_ERROR("set root fail!");
181 goto EXIT;
182 }
183
184 uint8Array.data = msg;
185 uint8Array.len = *msgSize;
186 result = GetAttributeSerializedMsg(attribute, &uint8Array);
187 if (result != RESULT_SUCCESS) {
188 LOG_ERROR("get serialized tlv fail!");
189 goto EXIT;
190 }
191 *msgSize = uint8Array.len;
192
193 EXIT:
194 FreeAttribute(&attribute);
195 return result;
196 }
197
GetRootAttributeFromTlv(const uint8_t * msg,uint32_t msgSize)198 static Attribute *GetRootAttributeFromTlv(const uint8_t *msg, uint32_t msgSize)
199 {
200 Uint8Array uint8Array = {
201 .data = (uint8_t *)msg,
202 .len = msgSize,
203 };
204 Attribute *attributeTlv = CreateAttributeFromSerializedMsg(uint8Array);
205 if (attributeTlv == NULL) {
206 LOG_ERROR("create root tlv fail!");
207 return NULL;
208 }
209 Buffer *root = GetBufferFromAttributeBase(attributeTlv, ATTR_ROOT, false, 0);
210 FreeAttribute(&attributeTlv);
211 if (root == NULL) {
212 LOG_ERROR("get root buffer fail!");
213 return NULL;
214 }
215
216 uint8Array.data = root->buf;
217 uint8Array.len = root->contentSize;
218 Attribute *attributeRoot = CreateAttributeFromSerializedMsg(uint8Array);
219 DestroyBuffer(root);
220 return attributeRoot;
221 }
222
CheckScheduleIdOfAttribute(uint64_t scheduleId,const Attribute * data)223 static bool CheckScheduleIdOfAttribute(uint64_t scheduleId, const Attribute *data)
224 {
225 uint64_t dataScheduleId = 0;
226 int32_t result = GetAttributeUint64(data, ATTR_SCHEDULE_ID, &dataScheduleId);
227 if (result != RESULT_SUCCESS) {
228 LOG_ERROR("get schedule id fail");
229 return false;
230 }
231 if (dataScheduleId != scheduleId) {
232 LOG_ERROR("data schedule:%{public}x not match current schedule:%{public}x",
233 (uint16_t)dataScheduleId, (uint16_t)scheduleId);
234 return false;
235 }
236 return true;
237 }
238
VerifyAndGetDataAttribute(uint64_t scheduleId,Attribute ** data,const Buffer * pubKey,const uint8_t * msg,uint32_t msgSize)239 int32_t VerifyAndGetDataAttribute(
240 uint64_t scheduleId, Attribute **data, const Buffer *pubKey, const uint8_t *msg, uint32_t msgSize)
241 {
242 if ((data == NULL) || !IsBufferValid(pubKey) || (msg == NULL)) {
243 LOG_ERROR("VerifyAndGetDataAttribute check param fail!");
244 return RESULT_BAD_PARAM;
245 }
246
247 Attribute *attributeRoot = GetRootAttributeFromTlv(msg, msgSize);
248 if (attributeRoot == NULL) {
249 LOG_ERROR("get root fail!");
250 return RESULT_GENERAL_ERROR;
251 }
252
253 Buffer *dataBuf = GetBufferFromAttributeBase(attributeRoot, ATTR_DATA, false, 0);
254 Buffer *signBuf = GetBufferFromAttributeBase(attributeRoot, ATTR_SIGNATURE, false, 0);
255 FreeAttribute(&attributeRoot);
256 if ((dataBuf == NULL) || (signBuf == NULL)) {
257 LOG_ERROR("get data or sign buffer fail!");
258 DestroyBuffer(dataBuf);
259 DestroyBuffer(signBuf);
260 return RESULT_GENERAL_ERROR;
261 }
262
263 int32_t result = Ed25519Verify(pubKey, dataBuf, signBuf);
264 DestroyBuffer(signBuf);
265 if (result != RESULT_SUCCESS) {
266 LOG_ERROR("verify data signature fail!");
267 DestroyBuffer(dataBuf);
268 return RESULT_GENERAL_ERROR;
269 }
270
271 Uint8Array uint8Array = {
272 .data = dataBuf->buf,
273 .len = dataBuf->contentSize,
274 };
275 *data = CreateAttributeFromSerializedMsg(uint8Array);
276 DestroyBuffer(dataBuf);
277 if ((*data) == NULL) {
278 LOG_ERROR("create data fail!");
279 return RESULT_GENERAL_ERROR;
280 }
281
282 if (!CheckScheduleIdOfAttribute(scheduleId, *data)) {
283 LOG_ERROR("CheckScheduleIdOfAttribute fail!");
284 FreeAttribute(data);
285 *data = NULL;
286 return RESULT_GENERAL_ERROR;
287 }
288
289 return RESULT_SUCCESS;
290 }
291
CheckAttributeDataBase(const Attribute * data,uint64_t scheduleId,RemotePinMsgId msgId,uint64_t * timeStamp)292 int32_t CheckAttributeDataBase(const Attribute *data, uint64_t scheduleId, RemotePinMsgId msgId, uint64_t *timeStamp)
293 {
294 if ((data == NULL) || (timeStamp == NULL)) {
295 LOG_ERROR("CheckAttributeDataBase check param fail!");
296 return RESULT_BAD_PARAM;
297 }
298
299 if (!CheckScheduleIdOfAttribute(scheduleId, data)) {
300 LOG_ERROR("CheckScheduleIdOfAttribute fail!");
301 return RESULT_BAD_MATCH;
302 }
303
304 uint32_t dataMsgId = 0;
305 int32_t result = GetAttributeUint32(data, PIN_ATTR_MSG_ID, &dataMsgId);
306 if (result != RESULT_SUCCESS) {
307 LOG_ERROR("get msg id fail");
308 return result;
309 }
310 if (dataMsgId != msgId) {
311 LOG_ERROR("data msgId:%{public}u not match current msgId:%{public}u", dataMsgId, msgId);
312 return RESULT_BAD_MATCH;
313 }
314
315 uint64_t dataTimeStamp = 0;
316 result = GetAttributeUint64(data, ATTR_TIME_STAMP, &dataTimeStamp);
317 if (result != RESULT_SUCCESS) {
318 LOG_ERROR("get time stamp fail");
319 return result;
320 }
321 if (dataTimeStamp <= (*timeStamp)) {
322 LOG_ERROR("data time:%{public}" PRIu64 " not match current time:%{public}" PRIu64,
323 dataTimeStamp, (*timeStamp));
324 return RESULT_BAD_MATCH;
325 }
326 (*timeStamp) = dataTimeStamp;
327
328 return RESULT_SUCCESS;
329 }
330
GetSubTypeAndFreezeTime(uint64_t * subType,uint64_t templateId,uint32_t * freezeTime,uint32_t * count)331 static ResultCode GetSubTypeAndFreezeTime(
332 uint64_t *subType, uint64_t templateId, uint32_t *freezeTime, uint32_t *count)
333 {
334 ResultCode ret = GetSubType(templateId, subType);
335 if (ret != RESULT_SUCCESS) {
336 LOG_ERROR("GetSubType fail.");
337 return ret;
338 }
339 uint64_t startFreezeTime = INIT_START_FREEZE_TIMES;
340 ret = GetAntiBruteInfo(templateId, count, &startFreezeTime);
341 if (ret != RESULT_SUCCESS) {
342 LOG_ERROR("GetAntiBruteInfo fail.");
343 return ret;
344 }
345
346 ret = ComputeFreezeTime(templateId, freezeTime, *count, startFreezeTime);
347 if (ret != RESULT_SUCCESS) {
348 LOG_ERROR("ComputeFreezeTime fail.");
349 return ret;
350 }
351 return RESULT_SUCCESS;
352 }
353
DoQueryPinInfo(uint64_t templateId,PinCredentialInfos * pinCredentialInfo)354 int32_t DoQueryPinInfo(uint64_t templateId, PinCredentialInfos *pinCredentialInfo)
355 {
356 if (pinCredentialInfo == NULL || templateId == INVALID_TEMPLATE_ID) {
357 LOG_ERROR("check DoQueryPin param fail!");
358 return RESULT_BAD_PARAM;
359 }
360 uint32_t authErrorCount = INIT_AUTH_ERROR_COUNT;
361 ResultCode ret = GetSubTypeAndFreezeTime(&(pinCredentialInfo->subType), templateId,
362 &(pinCredentialInfo->freezeTime), &authErrorCount);
363 if (ret != RESULT_SUCCESS) {
364 LOG_ERROR("GetSubTypeAndFreezeTime fail.");
365 return ret;
366 }
367 pinCredentialInfo->nextFailLockoutDuration = GetNextFailLockoutDuration(authErrorCount);
368 if (pinCredentialInfo->freezeTime > 0) {
369 pinCredentialInfo->remainTimes = 0;
370 } else {
371 ret = GetRemainTimes(templateId, &(pinCredentialInfo->remainTimes), authErrorCount);
372 if (ret != RESULT_SUCCESS) {
373 LOG_ERROR("GetRemainTimes fail.");
374 return ret;
375 }
376 }
377 return ret;
378 }
379
SetResultDataInfo(Attribute * attribute,int32_t resultCode,uint64_t templateId,Buffer * rootSecret)380 bool SetResultDataInfo(Attribute *attribute, int32_t resultCode, uint64_t templateId, Buffer *rootSecret)
381 {
382 if ((attribute == NULL) || ((rootSecret != NULL) && !IsBufferValid(rootSecret))) {
383 LOG_ERROR("SetResultDataInfo check param fail");
384 return false;
385 }
386
387 PinCredentialInfos pinCredentialInfo;
388 int32_t queryPinResult = DoQueryPinInfo(templateId, &pinCredentialInfo);
389 IF_TRUE_LOGE_AND_RETURN_VAL(queryPinResult != RESULT_SUCCESS, false);
390
391 int32_t setResultCodeResult = SetAttributeInt32(attribute, ATTR_RESULT_CODE, resultCode);
392 IF_TRUE_LOGE_AND_RETURN_VAL(setResultCodeResult != RESULT_SUCCESS, false);
393
394 int32_t setTemplateIdResult = SetAttributeUint64(attribute, ATTR_TEMPLATE_ID, templateId);
395 IF_TRUE_LOGE_AND_RETURN_VAL(setTemplateIdResult != RESULT_SUCCESS, false);
396
397 int32_t setSubTypeResult = SetAttributeUint64(attribute, ATTR_PIN_SUB_TYPE, pinCredentialInfo.subType);
398 IF_TRUE_LOGE_AND_RETURN_VAL(setSubTypeResult != RESULT_SUCCESS, false);
399
400 if (pinCredentialInfo.remainTimes > INT32_MAX) {
401 pinCredentialInfo.remainTimes = 0;
402 }
403 int32_t setRemainAttempts = SetAttributeInt32(
404 attribute, ATTR_REMAIN_ATTEMPTS, (int32_t)pinCredentialInfo.remainTimes);
405 IF_TRUE_LOGE_AND_RETURN_VAL(setRemainAttempts != RESULT_SUCCESS, false);
406
407 if (pinCredentialInfo.freezeTime > INT32_MAX) {
408 pinCredentialInfo.freezeTime = INT32_MAX;
409 }
410 int32_t setLockoutDuration = SetAttributeInt32(
411 attribute, ATTR_LOCKOUT_DURATION, (int32_t)pinCredentialInfo.freezeTime);
412 IF_TRUE_LOGE_AND_RETURN_VAL(setLockoutDuration != RESULT_SUCCESS, false);
413
414 int32_t setAcl = SetAttributeUint32(attribute, ATTR_ACL, PIN_CAPABILITY_LEVEL);
415 IF_TRUE_LOGE_AND_RETURN_VAL(setAcl != RESULT_SUCCESS, false);
416
417 if (rootSecret != NULL) {
418 int32_t setRootSecret = SetBufferToAttribute(attribute, ATTR_ROOT_SECRET, rootSecret);
419 IF_TRUE_LOGE_AND_RETURN_VAL(setRootSecret != RESULT_SUCCESS, false);
420 }
421
422 return true;
423 }
424
PinResultToFwkResult(int32_t pinResult)425 int32_t PinResultToFwkResult(int32_t pinResult)
426 {
427 switch (pinResult) {
428 case RESULT_SUCCESS:
429 return SUCCESS;
430 case RESULT_BAD_PARAM:
431 return INVALID_PARAMETERS;
432 case RESULT_COMPARE_FAIL:
433 return FAIL;
434 case RESULT_BUSY:
435 return BUSY;
436 case RESULT_PIN_FREEZE:
437 return LOCKED;
438 default:
439 return GENERAL_ERROR;
440 }
441 }
442