• 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 "v3_0/user_auth_interface_service.h"
17 
18 #include <cinttypes>
19 #include <mutex>
20 #include <hdf_base.h>
21 #include "securec.h"
22 #include <set>
23 #include <string>
24 
25 #include "iam_logger.h"
26 #include "iam_para2str.h"
27 #include "iam_ptr.h"
28 
29 #include "adaptor_time.h"
30 #include "useriam_common.h"
31 #include "auth_level.h"
32 #include "buffer.h"
33 #include "coauth_funcs.h"
34 #include "executor_message.h"
35 #include "hmac_key.h"
36 #include "identify_funcs.h"
37 #include "idm_database.h"
38 #include "idm_session.h"
39 #include "ed25519_key.h"
40 #include "udid_manager.h"
41 #include "user_auth_hdi.h"
42 #include "user_auth_funcs.h"
43 #include "user_idm_funcs.h"
44 #include "user_sign_centre.h"
45 #include "enroll_specification_check.h"
46 
47 #undef LOG_TAG
48 #define LOG_TAG "USER_AUTH_HDI"
49 
50 namespace OHOS {
51 namespace HDI {
52 namespace UserAuth {
53 namespace {
54 static std::mutex g_mutex;
55 static std::string g_localUdid;
56 constexpr uint32_t INVALID_CAPABILITY_LEVEL = 100;
57 const std::string SETTRINGS_NAME = "settings";
58 constexpr uint32_t MAX_TOKEN_ALLOWABLE_DURATION = 24 * 60 * 60 * 1000;
59 
60 enum UserAuthCallerType : int32_t {
61     TOKEN_INVALID = -1,
62     TOKEN_HAP = 0,
63     TOKEN_NATIVE,
64 };
65 const uint32_t PUBLIC_KEY_STR_LEN = 33;
FormatHexString(uint8_t * data,int32_t dataSize,char * outBuffer,int32_t outBufferSize)66 void FormatHexString(uint8_t* data, int32_t dataSize, char* outBuffer, int32_t outBufferSize)
67 {
68     int32_t writeIndex = 0;
69     do {
70         for (int i = 0; i < dataSize; i++) {
71             int ret = sprintf_s(outBuffer + writeIndex, outBufferSize - writeIndex, "%X", data[i]);
72             if (ret < 0) {
73                 writeIndex = 0;
74                 break;
75             }
76             writeIndex += ret;
77         }
78     } while (0);
79 
80     if (writeIndex == 0) {
81         memset_s(outBuffer, outBufferSize, 0, outBufferSize);
82     }
83 }
84 } // namespace
85 
86 using namespace std;
87 
UserAuthInterfaceImplGetInstance(void)88 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
89 {
90     auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
91     if (userAuthInterfaceService == nullptr) {
92         IAM_LOGE("userAuthInterfaceService is nullptr");
93         return nullptr;
94     }
95     std::lock_guard<std::mutex> lock(g_mutex);
96     OHOS::UserIam::Common::Init();
97     return userAuthInterfaceService;
98 }
99 
Init(const std::string & deviceUdid)100 int32_t UserAuthInterfaceService::Init(const std::string &deviceUdid)
101 {
102     IAM_LOGI("start");
103     std::lock_guard<std::mutex> lock(g_mutex);
104     g_localUdid = deviceUdid;
105     bool ret = SetLocalUdid(g_localUdid.c_str());
106     IF_TRUE_LOGE_AND_RETURN_VAL(!ret, HDF_FAILURE);
107     OHOS::UserIam::Common::Close();
108     return OHOS::UserIam::Common::Init();
109 }
110 
CopyScheduleInfo(const CoAuthSchedule * in,HdiScheduleInfo * out)111 static bool CopyScheduleInfo(const CoAuthSchedule *in, HdiScheduleInfo *out)
112 {
113     IAM_LOGI("start");
114     if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
115         IAM_LOGE("executorSize is zero");
116         return false;
117     }
118     out->executorIndexes.clear();
119     out->templateIds.clear();
120     out->scheduleId = in->scheduleId;
121     out->authType = static_cast<AuthType>(in->authType);
122     for (uint32_t i = 0; i < in->templateIds.len; ++i) {
123         out->templateIds.push_back(in->templateIds.data[i]);
124     }
125     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
126     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
127     for (uint32_t i = 0; i < in->executorSize; ++i) {
128         out->executorIndexes.push_back(in->executors[i].executorIndex);
129     }
130     out->executorMessages.clear();
131     return true;
132 }
133 
SetAttributeToCoAuthExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Attribute * attribute)134 static int32_t SetAttributeToCoAuthExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
135     Uint8Array publicKey, Attribute *attribute)
136 {
137     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
138 
139     if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
140         IAM_LOGE("SetAttributeUint64 scheduleId failed");
141         return RESULT_GENERAL_ERROR;
142     }
143 
144     Uint8Array localUdidIn = { paramHal.localUdid, sizeof(paramHal.localUdid) };
145     if (SetAttributeUint8Array(attribute, ATTR_VERIFIER_UDID, localUdidIn) != RESULT_SUCCESS) {
146         IAM_LOGE("SetAttributeUint8Array verifierUdid failed");
147         return RESULT_GENERAL_ERROR;
148     }
149     if (SetAttributeUint8Array(attribute, ATTR_LOCAL_UDID, localUdidIn) != RESULT_SUCCESS) {
150         IAM_LOGE("SetAttributeUint8Array localUdid failed");
151         return RESULT_GENERAL_ERROR;
152     }
153     Uint8Array peerUdidIn = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
154     if (SetAttributeUint8Array(attribute, ATTR_COLLECTOR_UDID, peerUdidIn) != RESULT_SUCCESS) {
155         IAM_LOGE("SetAttributeUint8Array collectorUdid failed");
156         return RESULT_GENERAL_ERROR;
157     }
158     if (SetAttributeUint8Array(attribute, ATTR_PEER_UDID, peerUdidIn) != RESULT_SUCCESS) {
159         IAM_LOGE("SetAttributeUint8Array peerUdid failed");
160         return RESULT_GENERAL_ERROR;
161     }
162     char publicKeyStrBuffer[PUBLIC_KEY_STR_LEN] = {0};
163     FormatHexString(&publicKey.data[0], publicKey.len, publicKeyStrBuffer, PUBLIC_KEY_STR_LEN);
164     IAM_LOGI("public key: %{public}s", publicKeyStrBuffer);
165     if (SetAttributeUint8Array(attribute, ATTR_PUBLIC_KEY, publicKey) != RESULT_SUCCESS) {
166         IAM_LOGE("SetAttributeUint8Array publicKey failed");
167         return RESULT_GENERAL_ERROR;
168     }
169     Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
170     if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
171         IAM_LOGE("SetAttributeUint8Array challenge failed");
172         return RESULT_GENERAL_ERROR;
173     }
174 
175     return RESULT_SUCCESS;
176 }
177 
SetAttributeToCollectorExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)178 static int32_t SetAttributeToCollectorExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
179     Uint8Array publicKey, Uint8Array *retExtraInfo)
180 {
181     Attribute *attribute = CreateEmptyAttribute();
182     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
183 
184     ResultCode ret = RESULT_GENERAL_ERROR;
185     do {
186         if (SetAttributeUint32(attribute, ATTR_TYPE, paramHal.authType) != RESULT_SUCCESS) {
187             IAM_LOGE("SetAttributeUint32 authType failed");
188             break;
189         }
190         if (SetAttributeUint32(attribute, ATTR_EXECUTOR_MATCHER, info.executorMatcher) != RESULT_SUCCESS) {
191             IAM_LOGE("SetAttributeUint64 executorMatcher failed");
192             break;
193         }
194         if (SetAttributeInt32(attribute, ATTR_SCHEDULE_MODE, info.scheduleMode) != RESULT_SUCCESS) {
195             IAM_LOGE("SetAttributeUint64 scheduleMode failed");
196             break;
197         }
198         if (SetAttributeUint32(attribute, ATTR_EXECUTOR_ROLE, COLLECTOR) != RESULT_SUCCESS) {
199             IAM_LOGE("SetAttributeUint32 executorRole failed");
200             break;
201         }
202         if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
203             IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
204             break;
205         }
206 
207         SignParam signParam = {
208             .needSignature = true,
209             .keyType = KEY_TYPE_CROSS_DEVICE,
210             .peerUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) }
211         };
212         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
213             IAM_LOGE("GetAttributeExecutorMsg failed");
214             break;
215         }
216         ret = RESULT_SUCCESS;
217     } while (0);
218 
219     FreeAttribute(&attribute);
220     return ret;
221 }
222 
GetCapabilityLevel(int32_t userId,HdiScheduleInfo & info,uint32_t & capabilityLevel)223 static int32_t GetCapabilityLevel(int32_t userId, HdiScheduleInfo &info, uint32_t &capabilityLevel)
224 {
225     capabilityLevel = INVALID_CAPABILITY_LEVEL;
226     LinkedList *credList = nullptr;
227     int32_t ret = QueryCredentialFunc(userId, info.authType, &credList);
228     if (ret != RESULT_SUCCESS) {
229         IAM_LOGE("query credential failed");
230         return ret;
231     }
232     LinkedListNode *temp = credList->head;
233     while (temp != nullptr) {
234         if (temp->data == nullptr) {
235             IAM_LOGE("list node is invalid");
236             DestroyLinkedList(credList);
237             return RESULT_UNKNOWN;
238         }
239         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
240         // Only the lowest acl is returned
241         capabilityLevel = (capabilityLevel < credentialHal->capabilityLevel) ?
242             capabilityLevel : credentialHal->capabilityLevel;
243         temp = temp->next;
244     }
245 
246     DestroyLinkedList(credList);
247     return RESULT_SUCCESS;
248 }
249 
GetExpiredSysTime(AuthParamHal paramHal)250 static uint64_t GetExpiredSysTime(AuthParamHal paramHal)
251 {
252     UserAuthContext *context = GetContext(paramHal.contextId);
253     if (context == NULL) {
254         IAM_LOGE("context is null");
255         return NO_CHECK_PIN_EXPIRED_PERIOD;
256     }
257 
258     if (!context->isExpiredReturnSuccess) {
259         return context->authExpiredSysTime;
260     }
261 
262     return NO_CHECK_PIN_EXPIRED_PERIOD;
263 }
264 
SetAttributeToVerifierExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)265 static int32_t SetAttributeToVerifierExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
266     Uint8Array publicKey, Uint8Array *retExtraInfo)
267 {
268     Attribute *attribute = CreateEmptyAttribute();
269     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
270 
271     ResultCode ret = RESULT_GENERAL_ERROR;
272     do {
273         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
274         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
275             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
276             break;
277         }
278         uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
279         int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
280         if (result != RESULT_SUCCESS) {
281             IAM_LOGE("GetCapabilityLevel fail");
282             return result;
283         }
284         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
285             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
286             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
287             break;
288         }
289         if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
290             IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
291             break;
292         }
293         if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
294             IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
295             break;
296         }
297 
298         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
299         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
300             IAM_LOGE("GetAttributeExecutorMsg failed");
301             break;
302         }
303         ret = RESULT_SUCCESS;
304     } while (0);
305 
306     FreeAttribute(&attribute);
307     return ret;
308 }
309 
SetAttributeToExtraInfo(HdiScheduleInfo & info,uint32_t capabilityLevel,uint64_t scheduleId)310 static int32_t SetAttributeToExtraInfo(HdiScheduleInfo &info, uint32_t capabilityLevel, uint64_t scheduleId)
311 {
312     Attribute *attribute = CreateEmptyAttribute();
313     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
314 
315     ResultCode ret = RESULT_GENERAL_ERROR;
316     do {
317         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
318         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
319             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
320             break;
321         }
322         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
323             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
324             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
325             break;
326         }
327         if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, scheduleId) != RESULT_SUCCESS) {
328             IAM_LOGE("SetAttributeUint64 scheduleId failed");
329             break;
330         }
331 
332         info.executorMessages.resize(1);
333         info.executorMessages[0].resize(MAX_EXECUTOR_MSG_LEN);
334         Uint8Array retExtraInfo = { info.executorMessages[0].data(), MAX_EXECUTOR_MSG_LEN };
335         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
336         if (GetAttributeExecutorMsg(attribute, &retExtraInfo, signParam) != RESULT_SUCCESS) {
337             IAM_LOGE("GetAttributeExecutorMsg failed");
338             info.executorMessages.clear();
339             break;
340         }
341         info.executorMessages[0].resize(retExtraInfo.len);
342         ret = RESULT_SUCCESS;
343     } while (0);
344 
345     FreeAttribute(&attribute);
346     return ret;
347 }
348 
SetAttributeToAllInOneExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array * retExtraInfo)349 static int32_t SetAttributeToAllInOneExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info, Uint8Array *retExtraInfo)
350 {
351     uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
352     int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
353     if (result != RESULT_SUCCESS) {
354         IAM_LOGE("GetCapabilityLevel fail");
355         return result;
356     }
357 
358     Attribute *attribute = CreateEmptyAttribute();
359     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
360 
361     ResultCode ret = RESULT_GENERAL_ERROR;
362     do {
363         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
364         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
365             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
366             break;
367         }
368         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
369             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
370             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
371             break;
372         }
373         if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
374             IAM_LOGE("SetAttributeUint64 scheduleId failed");
375             break;
376         }
377 
378         if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
379             IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
380             break;
381         }
382 
383         Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
384         if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
385             IAM_LOGE("SetAttributeUint8Array challenge failed");
386             break;
387         }
388 
389         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
390         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
391             IAM_LOGE("GetAttributeExecutorMsg failed");
392             break;
393         }
394         ret = RESULT_SUCCESS;
395     } while (0);
396 
397     FreeAttribute(&attribute);
398     return ret;
399 }
400 
GetAuthExecutorMsg(uint32_t executorRole,AuthParamHal paramHal,Uint8Array publicKey,HdiScheduleInfo & info,Uint8Array * retMsg)401 static int32_t GetAuthExecutorMsg(uint32_t executorRole, AuthParamHal paramHal,
402     Uint8Array publicKey, HdiScheduleInfo &info, Uint8Array *retMsg)
403 {
404     if (executorRole == COLLECTOR) {
405         if (SetAttributeToCollectorExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
406             IAM_LOGE("SetAttributeToCollectorExecMsg failed");
407             return RESULT_GENERAL_ERROR;
408         }
409     } else if (executorRole == VERIFIER) {
410         if (SetAttributeToVerifierExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
411             IAM_LOGE("SetAttributeToVerifierExecMsg failed");
412             return RESULT_GENERAL_ERROR;
413         }
414     } else if (executorRole == ALL_IN_ONE) {
415         if (SetAttributeToAllInOneExecMsg(paramHal, info, retMsg) != RESULT_SUCCESS) {
416             IAM_LOGE("SetAttributeToAllInOneExecMsg fail");
417             return RESULT_GENERAL_ERROR;
418         }
419     } else {
420         IAM_LOGE("Unsupported executorRole %{public}u", executorRole);
421         return RESULT_GENERAL_ERROR;
422     }
423     return RESULT_SUCCESS;
424 }
425 
CopyAuthScheduleInfo(AuthParamHal paramHal,const CoAuthSchedule * in,HdiScheduleInfo * out)426 static bool CopyAuthScheduleInfo(AuthParamHal paramHal, const CoAuthSchedule *in, HdiScheduleInfo *out)
427 {
428     IAM_LOGI("CopyAuthScheduleInfo start");
429     if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
430         IAM_LOGE("executorSize is zero");
431         return false;
432     }
433     out->executorIndexes.clear();
434     out->templateIds.clear();
435     out->scheduleId = in->scheduleId;
436     out->authType = static_cast<AuthType>(in->authType);
437     for (uint32_t i = 0; i < in->templateIds.len; ++i) {
438         out->templateIds.push_back(in->templateIds.data[i]);
439     }
440     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
441     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
442 
443     out->executorIndexes.resize(in->executorSize);
444     out->executorMessages.resize(in->executorSize);
445     for (uint32_t i = 0; i < in->executorSize; ++i) {
446         out->executorIndexes[i] = in->executors[i].executorIndex;
447         out->executorMessages[i].resize(MAX_EXECUTOR_MSG_LEN);
448         Uint8Array retExtraInfo = { out->executorMessages[i].data(), MAX_EXECUTOR_MSG_LEN };
449         uint32_t executorRoleTemp = static_cast<ExecutorRole>(in->executors[i].executorRole);
450         Uint8Array publicKeyInfo = { (uint8_t *)in->executors[1 - i].pubKey, PUBLIC_KEY_LEN };
451         if (GetAuthExecutorMsg(executorRoleTemp, paramHal, publicKeyInfo, *out, &retExtraInfo) != RESULT_SUCCESS) {
452             IAM_LOGE("GetAuthExecutorMsg failed");
453             out->executorIndexes.clear();
454             out->templateIds.clear();
455             out->executorMessages.clear();
456             return false;
457         }
458         out->executorMessages[i].resize(retExtraInfo.len);
459     }
460     return true;
461 }
462 
CopyAuthParamToHal(uint64_t contextId,const HdiAuthParam & param,AuthParamHal & paramHal)463 static int32_t CopyAuthParamToHal(uint64_t contextId, const HdiAuthParam &param,
464     AuthParamHal &paramHal)
465 {
466     paramHal.contextId = contextId;
467     paramHal.userId = param.baseParam.userId;
468     paramHal.authType = static_cast<int32_t>(param.authType);
469     paramHal.authTrustLevel = param.baseParam.authTrustLevel;
470     if (!param.baseParam.challenge.empty() && memcpy_s(paramHal.challenge, CHALLENGE_LEN,
471         param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
472         IAM_LOGE("challenge copy failed");
473         return RESULT_BAD_COPY;
474     }
475     paramHal.authIntent = param.authIntent;
476     paramHal.isExpiredReturnSuccess = false;
477     if (param.baseParam.callerType == TOKEN_HAP &&
478         (param.baseParam.callerName.find(SETTRINGS_NAME) != std::string::npos ||
479         param.authIntent == HdiAuthIntent::UNLOCK)) {
480         paramHal.isExpiredReturnSuccess = true;
481     }
482     if (!param.collectorUdid.empty()) {
483         if (memcpy_s(paramHal.collectorUdid, sizeof(paramHal.collectorUdid),
484             (uint8_t *)param.collectorUdid.c_str(), param.collectorUdid.length()) != EOK) {
485             IAM_LOGE("collectorUdid copy failed");
486             return RESULT_BAD_COPY;
487         }
488     } else {
489         Uint8Array collectorUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
490         if (!GetLocalUdid(&collectorUdid)) {
491             IAM_LOGE("fill collector udid by local udid failed");
492             return RESULT_GENERAL_ERROR;
493         }
494     }
495     Uint8Array localUdid = { paramHal.localUdid, sizeof(paramHal.localUdid) };
496     if (!GetLocalUdid(&localUdid)) {
497         IAM_LOGE("GetLocalUdid failed");
498         return RESULT_GENERAL_ERROR;
499     }
500     return RESULT_SUCCESS;
501 }
502 
BeginAuthentication(uint64_t contextId,const HdiAuthParam & param,std::vector<HdiScheduleInfo> & infos)503 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const HdiAuthParam &param,
504     std::vector<HdiScheduleInfo> &infos)
505 {
506     IAM_LOGI("start");
507     infos.clear();
508     AuthParamHal paramHal = {};
509     int32_t ret = CopyAuthParamToHal(contextId, param, paramHal);
510     if (ret != RESULT_SUCCESS) {
511         IAM_LOGE("copy CopyAuthParamToHal failed %{public}d", ret);
512         return ret;
513     }
514     std::lock_guard<std::mutex> lock(g_mutex);
515     LinkedList *schedulesGet = nullptr;
516     ret = GenerateSolutionFunc(paramHal, &schedulesGet);
517     if (ret != RESULT_SUCCESS) {
518         IAM_LOGE("generate solution failed %{public}d", ret);
519         return ret;
520     }
521     if (schedulesGet == nullptr) {
522         IAM_LOGE("get null schedule");
523         return RESULT_GENERAL_ERROR;
524     }
525     LinkedListNode *tempNode = schedulesGet->head;
526     while (tempNode != nullptr) {
527         if (tempNode->data == nullptr) {
528             IAM_LOGE("node data is invalid");
529             DestroyLinkedList(schedulesGet);
530             return RESULT_UNKNOWN;
531         }
532         HdiScheduleInfo temp = {};
533         auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
534         if (!CopyAuthScheduleInfo(paramHal, coAuthSchedule, &temp)) {
535             infos.clear();
536             IAM_LOGE("copy schedule info failed");
537             DestroyLinkedList(schedulesGet);
538             return RESULT_GENERAL_ERROR;
539         }
540         infos.push_back(temp);
541         tempNode = tempNode->next;
542     }
543     DestroyLinkedList(schedulesGet);
544     return ret;
545 }
546 
GetAllUserInfo(std::vector<UserInfo> & userInfos)547 int32_t UserAuthInterfaceService::GetAllUserInfo(std::vector<UserInfo> &userInfos)
548 {
549     IAM_LOGI("GetAllUserInfo mock start");
550     static_cast<void>(userInfos);
551 
552     return RESULT_SUCCESS;
553 }
554 
CreateExecutorCommand(int32_t userId,HdiAuthResultInfo & info)555 static int32_t CreateExecutorCommand(int32_t userId, HdiAuthResultInfo &info)
556 {
557     LinkedList *executorSendMsg = nullptr;
558     AuthPropertyMode authPropMode;
559     if (info.result == RESULT_SUCCESS) {
560         authPropMode = PROPERTY_MODE_UNFREEZE;
561     } else if (info.remainAttempts == 0) {
562         authPropMode = PROPERTY_MODE_FREEZE;
563     } else {
564         return RESULT_SUCCESS;
565     }
566     ResultCode ret = GetExecutorMsgList(userId, authPropMode, &executorSendMsg);
567     if (ret != RESULT_SUCCESS) {
568         IAM_LOGE("get executor msg failed");
569         return ret;
570     }
571 
572     LinkedListNode *temp = executorSendMsg->head;
573     while (temp != nullptr) {
574         if (temp->data == nullptr) {
575             IAM_LOGE("list node is invalid");
576             DestroyLinkedList(executorSendMsg);
577             return RESULT_UNKNOWN;
578         }
579         auto nodeData = static_cast<ExecutorMsg *>(temp->data);
580         Buffer *nodeMsgBuffer = nodeData->msg;
581         if (!IsBufferValid(nodeMsgBuffer)) {
582             IAM_LOGE("node's buffer invalid");
583             DestroyLinkedList(executorSendMsg);
584             return RESULT_UNKNOWN;
585         }
586         HdiExecutorSendMsg msg = {};
587         msg.executorIndex = nodeData->executorIndex;
588         msg.commandId = static_cast<int32_t>(authPropMode);
589         msg.msg.resize(nodeMsgBuffer->contentSize);
590         if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
591             IAM_LOGE("copy failed");
592             msg.msg.clear();
593             DestroyLinkedList(executorSendMsg);
594             return RESULT_BAD_COPY;
595         }
596         info.msgs.push_back(msg);
597         temp = temp->next;
598     }
599     DestroyLinkedList(executorSendMsg);
600     return RESULT_SUCCESS;
601 }
602 
CopyAuthResult(AuthResult & infoIn,UserAuthTokenHal & authTokenIn,HdiAuthResultInfo & infoOut,HdiEnrolledState & enrolledStateOut)603 static int32_t CopyAuthResult(AuthResult &infoIn, UserAuthTokenHal &authTokenIn, HdiAuthResultInfo &infoOut,
604     HdiEnrolledState &enrolledStateOut)
605 {
606     IAM_LOGI("start");
607     infoOut.result = infoIn.result;
608     infoOut.remainAttempts = infoIn.remainTimes;
609     infoOut.lockoutDuration = infoIn.freezingTime;
610     enrolledStateOut.credentialDigest = infoIn.credentialDigest;
611     enrolledStateOut.credentialCount = infoIn.credentialCount;
612     infoOut.pinExpiredInfo = infoIn.pinExpiredInfo;
613     if (infoOut.result == RESULT_SUCCESS) {
614         infoOut.userId = infoIn.userId;
615         infoOut.credentialId = infoIn.credentialId;
616         IAM_LOGI("matched userId: %{public}d, credentialId: %{public}s.",
617             infoOut.userId, GET_MASKED_STRING(infoOut.credentialId).c_str());
618         infoOut.token.resize(sizeof(UserAuthTokenHal));
619         if (memcpy_s(infoOut.token.data(), infoOut.token.size(), &authTokenIn, sizeof(UserAuthTokenHal)) != EOK) {
620                 IAM_LOGE("copy authToken failed");
621                 infoOut.token.clear();
622                 return RESULT_BAD_COPY;
623         }
624         if (infoIn.rootSecret != nullptr) {
625             infoOut.rootSecret.resize(infoIn.rootSecret->contentSize);
626             if (memcpy_s(infoOut.rootSecret.data(), infoOut.rootSecret.size(),
627                 infoIn.rootSecret->buf, infoIn.rootSecret->contentSize) != EOK) {
628                 IAM_LOGE("copy secret failed");
629                 infoOut.rootSecret.clear();
630                 infoOut.token.clear();
631                 return RESULT_BAD_COPY;
632             }
633         }
634     }
635     if (infoIn.remoteAuthResultMsg != nullptr) {
636         infoOut.remoteAuthResultMsg.resize(infoIn.remoteAuthResultMsg->contentSize);
637         if (memcpy_s(infoOut.remoteAuthResultMsg.data(), infoOut.remoteAuthResultMsg.size(),
638             infoIn.remoteAuthResultMsg->buf, infoIn.remoteAuthResultMsg->contentSize) != EOK) {
639             IAM_LOGE("copy remoteAuthResultMsg failed");
640             infoOut.remoteAuthResultMsg.clear();
641             infoOut.rootSecret.clear();
642             infoOut.token.clear();
643             return RESULT_BAD_COPY;
644         }
645     }
646     infoOut.userId = infoIn.userId;
647     IAM_LOGI("matched userId: %{public}d.", infoOut.userId);
648     return RESULT_SUCCESS;
649 }
650 
UpdateAuthenticationResultInner(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)651 static int32_t UpdateAuthenticationResultInner(uint64_t contextId,
652     const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
653 {
654     IAM_LOGI("start");
655     if (scheduleResult.size() == 0) {
656         IAM_LOGE("param is invalid");
657         DestroyContextbyId(contextId);
658         return RESULT_BAD_PARAM;
659     }
660     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
661     if (!IsBufferValid(scheduleResultBuffer)) {
662         IAM_LOGE("scheduleTokenBuffer is invalid");
663         DestroyContextbyId(contextId);
664         return RESULT_NO_MEMORY;
665     }
666     std::lock_guard<std::mutex> lock(g_mutex);
667     UserAuthTokenHal authTokenHal = {};
668     AuthResult authResult = {};
669     int32_t funcRet = RESULT_GENERAL_ERROR;
670     do {
671         int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
672         DestoryBuffer(scheduleResultBuffer);
673         if (ret != RESULT_SUCCESS) {
674             IAM_LOGE("execute func failed");
675             break;
676         }
677         ret = CopyAuthResult(authResult, authTokenHal, info, enrolledState);
678         if (ret != RESULT_SUCCESS) {
679             IAM_LOGE("Copy auth result failed");
680             break;
681         }
682         if (authResult.authType != PIN_AUTH) {
683             IAM_LOGI("type not pin");
684         } else {
685             IAM_LOGI("type pin");
686             ret = CreateExecutorCommand(authResult.userId, info);
687             if (ret != RESULT_SUCCESS) {
688                 IAM_LOGE("create executor command failed");
689                 break;
690             }
691         }
692         funcRet = RESULT_SUCCESS;
693     } while (0);
694 
695     DestroyAuthResult(&authResult);
696     return funcRet;
697 }
698 
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)699 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
700     const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
701 {
702     IAM_LOGI("start");
703     return UpdateAuthenticationResultInner(contextId, scheduleResult, info, enrolledState);
704 }
705 
CancelAuthentication(uint64_t contextId)706 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
707 {
708     IAM_LOGI("start");
709     std::lock_guard<std::mutex> lock(g_mutex);
710     return DestroyContextbyId(contextId);
711 }
712 
BeginIdentification(uint64_t contextId,int32_t authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,HdiScheduleInfo & scheduleInfo)713 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, int32_t authType,
714     const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, HdiScheduleInfo &scheduleInfo)
715 {
716     IAM_LOGI("start");
717     if (authType == PIN) {
718         IAM_LOGE("param is invalid");
719         return RESULT_BAD_PARAM;
720     }
721     IdentifyParam param = {};
722     param.contextId = contextId;
723     param.authType = static_cast<uint32_t>(authType);
724     param.executorSensorHint = executorSensorHint;
725     if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
726         IAM_LOGE("challenge copy failed");
727         return RESULT_BAD_COPY;
728     }
729     std::lock_guard<std::mutex> lock(g_mutex);
730     LinkedList *scheduleGet = nullptr;
731     int32_t ret = DoIdentify(param, &scheduleGet);
732     if (ret != RESULT_SUCCESS) {
733         IAM_LOGE("generate solution failed");
734         return ret;
735     }
736     if (scheduleGet == nullptr) {
737         IAM_LOGE("get null schedule");
738         return RESULT_GENERAL_ERROR;
739     }
740     if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
741         IAM_LOGE("scheduleGet is invalid");
742         DestroyLinkedList(scheduleGet);
743         return RESULT_UNKNOWN;
744     }
745     auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
746     if (!CopyScheduleInfo(data, &scheduleInfo)) {
747         IAM_LOGE("copy schedule failed");
748         ret = RESULT_BAD_COPY;
749     }
750     DestroyLinkedList(scheduleGet);
751     return ret;
752 }
753 
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)754 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
755     const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
756 {
757     IAM_LOGI("start");
758     if (scheduleResult.size() == 0) {
759         IAM_LOGE("param is invalid");
760         return RESULT_BAD_PARAM;
761     }
762     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
763     if (!IsBufferValid(scheduleResultBuffer)) {
764         IAM_LOGE("scheduleTokenBuffer is invalid");
765         return RESULT_NO_MEMORY;
766     }
767     std::lock_guard<std::mutex> lock(g_mutex);
768     UserAuthTokenHal token = {};
769     int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
770     DestoryBuffer(scheduleResultBuffer);
771     if (ret != RESULT_SUCCESS) {
772         IAM_LOGE("DoUpdateIdentify failed");
773         return ret;
774     }
775     if (info.result == RESULT_SUCCESS) {
776         info.token.resize(sizeof(UserAuthTokenHal));
777         if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
778             IAM_LOGE("copy authToken failed");
779             info.token.clear();
780             return RESULT_BAD_COPY;
781         }
782     }
783     return RESULT_SUCCESS;
784 }
785 
CancelIdentification(uint64_t contextId)786 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
787 {
788     IAM_LOGI("start");
789     std::lock_guard<std::mutex> lock(g_mutex);
790     return DestroyContextbyId(contextId);
791 }
792 
GetAvailableStatus(int32_t userId,int32_t authType,uint32_t authTrustLevel,int32_t & checkResult)793 int32_t UserAuthInterfaceService::GetAvailableStatus(int32_t userId, int32_t authType, uint32_t authTrustLevel,
794     int32_t &checkResult)
795 {
796     IAM_LOGI("start");
797     std::lock_guard<std::mutex> lock(g_mutex);
798     checkResult = GetAvailableStatusFunc(userId, authType, authTrustLevel);
799     if (checkResult != RESULT_SUCCESS) {
800         IAM_LOGE("GetAvailableStatusFunc failed");
801     }
802     return RESULT_SUCCESS;
803 }
804 
GetValidSolution(int32_t userId,const std::vector<int32_t> & authTypes,uint32_t authTrustLevel,std::vector<int32_t> & validTypes)805 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<int32_t> &authTypes,
806     uint32_t authTrustLevel, std::vector<int32_t> &validTypes)
807 {
808     IAM_LOGI("start userId:%{public}d authTrustLevel:%{public}u", userId, authTrustLevel);
809     static int32_t resultPriority[] = {RESULT_GENERAL_ERROR, RESULT_TYPE_NOT_SUPPORT, RESULT_TRUST_LEVEL_NOT_SUPPORT,
810         RESULT_NOT_ENROLLED, RESULT_PIN_EXPIRED};
811     int32_t result = RESULT_GENERAL_ERROR;
812     validTypes.clear();
813     std::lock_guard<std::mutex> lock(g_mutex);
814     for (auto &authType : authTypes) {
815         int32_t checkRet = GetAvailableStatusFunc(userId, authType, authTrustLevel);
816         if (checkRet == RESULT_SUCCESS) {
817             IAM_LOGI("get valid authType:%{public}d", authType);
818             validTypes.push_back(authType);
819             continue;
820         }
821         bool isResultFound = false;
822         for (uint32_t i = 0; i < sizeof(resultPriority) / sizeof(int32_t); i++) {
823             if (resultPriority[i] == result) {
824                 isResultFound = true;
825             }
826             if (resultPriority[i] == checkRet && isResultFound) {
827                 IAM_LOGI("checkRet:%{public}d higher priority than result:%{public}d", checkRet, result);
828                 result = checkRet;
829                 break;
830             }
831         }
832     }
833     if (validTypes.empty()) {
834         IAM_LOGE("no auth type valid");
835         return result;
836     }
837     return RESULT_SUCCESS;
838 }
839 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)840 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
841 {
842     IAM_LOGI("start");
843     std::lock_guard<std::mutex> lock(g_mutex);
844     challenge.resize(CHALLENGE_LEN);
845     int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
846     if (ret != RESULT_SUCCESS) {
847         IAM_LOGE("failed to open session");
848         challenge.clear();
849     }
850     return ret;
851 }
852 
CloseSession(int32_t userId)853 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
854 {
855     IAM_LOGI("start");
856     std::lock_guard<std::mutex> lock(g_mutex);
857     return CloseEditSession();
858 }
859 
BeginEnrollment(const std::vector<uint8_t> & authToken,const HdiEnrollParam & param,HdiScheduleInfo & info)860 int32_t UserAuthInterfaceService::BeginEnrollment(
861     const std::vector<uint8_t> &authToken, const HdiEnrollParam &param, HdiScheduleInfo &info)
862 {
863     IAM_LOGI("start");
864     if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
865         IAM_LOGE("authToken len is invalid");
866         return RESULT_BAD_PARAM;
867     }
868     PermissionCheckParam checkParam = {};
869     if (authToken.size() == sizeof(UserAuthTokenHal) &&
870         memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
871         return RESULT_BAD_COPY;
872     }
873     checkParam.authType = param.authType;
874     checkParam.userId = param.userId;
875     checkParam.executorSensorHint = param.executorSensorHint;
876     checkParam.userType = param.userType;
877     std::lock_guard<std::mutex> lock(g_mutex);
878     uint64_t scheduleId;
879     int32_t ret;
880     if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
881         ret = CheckUpdatePermission(checkParam, &scheduleId);
882         if (ret != RESULT_SUCCESS) {
883             IAM_LOGE("check update permission failed");
884             return ret;
885         }
886     } else {
887         ret = CheckEnrollPermission(checkParam, &scheduleId);
888         if (ret != RESULT_SUCCESS) {
889             IAM_LOGE("check enroll permission failed");
890             return ret;
891         }
892     }
893     const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
894     if (scheduleInfo == nullptr) {
895         IAM_LOGE("get schedule info failed");
896         return RESULT_UNKNOWN;
897     }
898     if (!CopyScheduleInfo(scheduleInfo, &info)) {
899         IAM_LOGE("copy schedule info failed");
900         return RESULT_BAD_COPY;
901     }
902     ret = SetAttributeToExtraInfo(info, INVALID_CAPABILITY_LEVEL, scheduleId);
903     if (ret != RESULT_SUCCESS) {
904         IAM_LOGE("SetAttributeToExtraInfo failed");
905     }
906 
907     IAM_LOGI("end");
908     return ret;
909 }
910 
CancelEnrollment(int32_t userId)911 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
912 {
913     IAM_LOGI("start");
914     std::lock_guard<std::mutex> lock(g_mutex);
915     BreakOffCoauthSchedule();
916     return RESULT_SUCCESS;
917 }
918 
CopyCredentialInfo(const CredentialInfoHal & in,HdiCredentialInfo & out)919 static void CopyCredentialInfo(const CredentialInfoHal &in, HdiCredentialInfo &out)
920 {
921     out.authType = static_cast<AuthType>(in.authType);
922     out.authSubType = in.credentialType;
923     out.credentialId = in.credentialId;
924     out.templateId = in.templateId;
925     out.executorMatcher = in.executorMatcher;
926     out.executorSensorHint = in.executorSensorHint;
927     out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
928 }
929 
GetUpdateResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)930 static int32_t GetUpdateResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
931 {
932     UpdateCredentialOutput output = {};
933     int32_t ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &output);
934     if (ret == RESULT_SUCCESS) {
935         /* Only update pin have oldRootSecret and rootSecret */
936         info.rootSecret.resize(ROOT_SECRET_LEN);
937         if (memcpy_s(info.rootSecret.data(), ROOT_SECRET_LEN, output.rootSecret->buf, ROOT_SECRET_LEN) != EOK) {
938             IAM_LOGE("failed to copy rootSecret");
939             ret = RESULT_BAD_COPY;
940             goto ERROR;
941         }
942         info.oldRootSecret.resize(ROOT_SECRET_LEN);
943         if (memcpy_s(info.oldRootSecret.data(), ROOT_SECRET_LEN, output.oldRootSecret->buf, ROOT_SECRET_LEN) != EOK) {
944             IAM_LOGE("failed to copy oldRootSecret");
945             ret = RESULT_BAD_COPY;
946             goto ERROR;
947         }
948         info.authToken.resize(AUTH_TOKEN_LEN);
949         if (memcpy_s(info.authToken.data(), AUTH_TOKEN_LEN, output.authToken->buf, AUTH_TOKEN_LEN) != EOK) {
950             IAM_LOGE("failed to copy authToken");
951             ret = RESULT_BAD_COPY;
952             goto ERROR;
953         }
954         info.credentialId = output.credentialId;
955         CopyCredentialInfo(output.deletedCredential, info.oldInfo);
956         goto EXIT;
957     }
958 
959 ERROR:
960     (void)memset_s(info.rootSecret.data(), info.rootSecret.size(), 0, info.rootSecret.size());
961     info.rootSecret.clear();
962     (void)memset_s(info.oldRootSecret.data(), info.oldRootSecret.size(), 0, info.oldRootSecret.size());
963     info.oldRootSecret.clear();
964     (void)memset_s(info.authToken.data(), info.authToken.size(), 0, info.authToken.size());
965     info.authToken.clear();
966 
967 EXIT:
968     DestoryBuffer(output.rootSecret);
969     DestoryBuffer(output.oldRootSecret);
970     DestoryBuffer(output.authToken);
971     return ret;
972 }
973 
GetEnrollResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)974 static int32_t GetEnrollResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
975 {
976     Buffer *authToken = nullptr;
977     Buffer *rootSecret = nullptr;
978     int32_t ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret, &authToken);
979     if (ret == RESULT_SUCCESS) {
980         /* Only enroll pin have authToken and rootSecret */
981         if (authToken != nullptr) {
982             info.authToken.resize(authToken->contentSize);
983             if (memcpy_s(info.authToken.data(), info.authToken.size(), authToken->buf, authToken->contentSize) != EOK) {
984                 IAM_LOGE("failed to copy authToken");
985                 info.authToken.clear();
986                 DestoryBuffer(authToken);
987                 DestoryBuffer(rootSecret);
988                 return RESULT_BAD_COPY;
989             }
990         }
991         if (rootSecret != nullptr) {
992             info.rootSecret.resize(rootSecret->contentSize);
993             if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf,
994                 rootSecret->contentSize) != EOK) {
995                 IAM_LOGE("failed to copy rootSecret");
996                 info.rootSecret.clear();
997                 ret = RESULT_BAD_COPY;
998             }
999         }
1000     }
1001     DestoryBuffer(authToken);
1002     DestoryBuffer(rootSecret);
1003     return ret;
1004 }
1005 
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,HdiEnrollResultInfo & info)1006 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
1007     HdiEnrollResultInfo &info)
1008 {
1009     IAM_LOGI("start");
1010     if (scheduleResult.size() == 0) {
1011         IAM_LOGE("enrollToken is invalid");
1012         return RESULT_BAD_PARAM;
1013     }
1014     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
1015     if (scheduleResultBuffer == nullptr) {
1016         IAM_LOGE("scheduleTokenBuffer is null");
1017         return RESULT_NO_MEMORY;
1018     }
1019     std::lock_guard<std::mutex> lock(g_mutex);
1020     bool isUpdate;
1021     int32_t ret = GetIsUpdate(&isUpdate);
1022     if (ret != RESULT_SUCCESS) {
1023         IAM_LOGE("get isUpdate failed");
1024         DestoryBuffer(scheduleResultBuffer);
1025         return ret;
1026     }
1027     if (isUpdate) {
1028         ret = GetUpdateResult(userId, info, scheduleResultBuffer);
1029         if (ret != RESULT_SUCCESS) {
1030             IAM_LOGE("GetUpdateResult failed");
1031         }
1032     } else {
1033         ret = GetEnrollResult(userId, info, scheduleResultBuffer);
1034         if (ret != RESULT_SUCCESS) {
1035             IAM_LOGE("GetEnrollResult failed");
1036         }
1037     }
1038 
1039     DestoryBuffer(scheduleResultBuffer);
1040     return ret;
1041 }
1042 
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)1043 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
1044     const std::vector<uint8_t> &authToken, CredentialInfo &info)
1045 {
1046     IAM_LOGI("start");
1047     if (authToken.size() != sizeof(UserAuthTokenHal)) {
1048         IAM_LOGE("authToken len is invalid");
1049         return RESULT_BAD_PARAM;
1050     }
1051     std::lock_guard<std::mutex> lock(g_mutex);
1052     CredentialDeleteParam param = {};
1053     if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
1054         IAM_LOGE("param token copy failed");
1055         return RESULT_BAD_COPY;
1056     }
1057     param.userId = userId;
1058     param.credentialId = credentialId;
1059     CredentialInfoHal credentialInfoHal = {};
1060     int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
1061     if (ret != RESULT_SUCCESS) {
1062         IAM_LOGE("delete credential failed");
1063         return ret;
1064     }
1065     CopyCredentialInfo(credentialInfoHal, info);
1066     return RESULT_SUCCESS;
1067 }
1068 
GetCredential(int32_t userId,int32_t authType,std::vector<CredentialInfo> & infos)1069 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, int32_t authType, std::vector<CredentialInfo> &infos)
1070 {
1071     IAM_LOGI("start");
1072     std::lock_guard<std::mutex> lock(g_mutex);
1073     LinkedList *credList = nullptr;
1074     int32_t ret = QueryCredentialFunc(userId, authType, &credList);
1075     if (ret != RESULT_SUCCESS) {
1076         IAM_LOGE("query credential failed");
1077         return ret;
1078     }
1079     infos.reserve(credList->getSize(credList));
1080     LinkedListNode *temp = credList->head;
1081     while (temp != nullptr) {
1082         if (temp->data == nullptr) {
1083             IAM_LOGE("list node is invalid");
1084             DestroyLinkedList(credList);
1085             return RESULT_UNKNOWN;
1086         }
1087         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1088         CredentialInfo credentialInfo = {};
1089         CopyCredentialInfo(*credentialHal, credentialInfo);
1090         infos.push_back(credentialInfo);
1091         temp = temp->next;
1092     }
1093     DestroyLinkedList(credList);
1094     return RESULT_SUCCESS;
1095 }
1096 
GetUserInfo(int32_t userId,uint64_t & secureUid,int32_t & pinSubType,std::vector<EnrolledInfo> & infos)1097 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, int32_t &pinSubType,
1098     std::vector<EnrolledInfo> &infos)
1099 {
1100     IAM_LOGI("start");
1101     std::lock_guard<std::mutex> lock(g_mutex);
1102     EnrolledInfoHal *enrolledInfoHals = nullptr;
1103     uint32_t num = 0;
1104     uint64_t pinSubTypeGet;
1105     int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
1106     if (ret == RESULT_NOT_FOUND) {
1107         IAM_LOGE("user not found");
1108         return RESULT_SUCCESS;
1109     }
1110     if (ret != RESULT_SUCCESS) {
1111         IAM_LOGE("get user info failed");
1112         return ret;
1113     }
1114     pinSubType = static_cast<PinSubType>(pinSubTypeGet);
1115     for (uint32_t i = 0; i < num; ++i) {
1116         EnrolledInfo enrolledInfo = {};
1117         enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
1118         enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
1119         infos.push_back(enrolledInfo);
1120     }
1121     free(enrolledInfoHals);
1122     return RESULT_SUCCESS;
1123 }
1124 
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos,std::vector<uint8_t> & rootSecret)1125 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
1126     std::vector<CredentialInfo> &deletedInfos, std::vector<uint8_t> &rootSecret)
1127 {
1128     IAM_LOGI("start");
1129     if (authToken.size() != sizeof(UserAuthTokenHal)) {
1130         IAM_LOGE("authToken is invalid");
1131         return RESULT_VERIFY_TOKEN_FAIL;
1132     }
1133     UserAuthTokenHal authTokenStruct = {};
1134     if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
1135         IAM_LOGE("authTokenStruct copy failed");
1136         return RESULT_BAD_COPY;
1137     }
1138     int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
1139     if (ret != RESULT_SUCCESS) {
1140         IAM_LOGE("failed to verify token");
1141         return RESULT_VERIFY_TOKEN_FAIL;
1142     }
1143     ret = EnforceDeleteUser(userId, deletedInfos);
1144     if (ret != RESULT_SUCCESS) {
1145         IAM_LOGE("oldRootSecret is invalid");
1146         return RESULT_GENERAL_ERROR;
1147     }
1148 
1149     rootSecret.resize(ROOT_SECRET_LEN);
1150     Buffer *oldRootSecret = GetCacheRootSecret(userId);
1151     if (!IsBufferValid(oldRootSecret)) {
1152         IAM_LOGE("get GetCacheRootSecret failed");
1153         return RESULT_SUCCESS;
1154     }
1155     if (memcpy_s(rootSecret.data(), rootSecret.size(), oldRootSecret->buf, oldRootSecret->contentSize) != EOK) {
1156         IAM_LOGE("rootSecret copy failed");
1157         ret = RESULT_BAD_COPY;
1158     }
1159 
1160     DestoryBuffer(oldRootSecret);
1161     return ret;
1162 }
1163 
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)1164 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
1165 {
1166     IAM_LOGI("start");
1167     std::lock_guard<std::mutex> lock(g_mutex);
1168     LinkedList *credList = nullptr;
1169     int32_t ret = DeleteUserInfo(userId, &credList);
1170     if (ret != RESULT_SUCCESS) {
1171         IAM_LOGE("query credential failed");
1172         return ret;
1173     }
1174     RefreshValidTokenTime();
1175     LinkedListNode *temp = credList->head;
1176     while (temp != nullptr) {
1177         if (temp->data == nullptr) {
1178             IAM_LOGE("list node is invalid");
1179             DestroyLinkedList(credList);
1180             return RESULT_UNKNOWN;
1181         }
1182         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1183         CredentialInfo credentialInfo = {};
1184         CopyCredentialInfo(*credentialHal, credentialInfo);
1185         deletedInfos.push_back(credentialInfo);
1186         temp = temp->next;
1187     }
1188     DestroyLinkedList(credList);
1189     return RESULT_SUCCESS;
1190 }
1191 
verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1192 static bool verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1193 {
1194     Buffer *execInfoMsg = CreateBufferByData(&in.signedRemoteExecutorInfo[0], in.signedRemoteExecutorInfo.size());
1195     if (!IsBufferValid(execInfoMsg)) {
1196         IAM_LOGE("execInfoMsg is invalid");
1197         return false;
1198     }
1199 
1200     bool isOk = CheckRemoteExecutorInfo(execInfoMsg, &out);
1201     DestoryBuffer(execInfoMsg);
1202     return isOk;
1203 }
1204 
CopyExecutorInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1205 static bool CopyExecutorInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1206 {
1207     out.authType = in.authType;
1208     out.executorMatcher = in.executorMatcher;
1209     out.esl = in.esl;
1210     out.maxTemplateAcl = in.maxTemplateAcl;
1211     out.executorRole = in.executorRole;
1212     out.executorSensorHint = in.executorSensorHint;
1213     if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
1214         IAM_LOGE("memcpy failed");
1215         return false;
1216     }
1217 
1218     std::string deviceUdid = in.deviceUdid;
1219     if (deviceUdid.empty()) {
1220         deviceUdid = g_localUdid;
1221     }
1222 
1223     if (memcpy_s(out.deviceUdid, sizeof(out.deviceUdid), deviceUdid.c_str(), deviceUdid.length()) != EOK) {
1224         IAM_LOGE("memcpy failed");
1225         return false;
1226     }
1227 
1228     if (g_localUdid != deviceUdid) {
1229         IAM_LOGI("verify remote executor register info");
1230         if (!verifyExecutorRegisterInfo(in, out)) {
1231             IAM_LOGE("verifyExecutorRegisterInfo failed");
1232             return false;
1233         }
1234         IAM_LOGI("add remote executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1235     } else {
1236         IAM_LOGI("add local executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1237     }
1238     return true;
1239 }
1240 
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)1241 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
1242 {
1243     CredentialCondition condition = {};
1244     SetCredentialConditionAuthType(&condition, authType);
1245     SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
1246     SetCredentiaConditionNeedCachePin(&condition);
1247     LinkedList *credList = QueryCredentialLimit(&condition);
1248     if (credList == nullptr) {
1249         IAM_LOGE("query credential failed");
1250         return RESULT_NOT_FOUND;
1251     }
1252     LinkedListNode *temp = credList->head;
1253     while (temp != nullptr) {
1254         if (temp->data == nullptr) {
1255             IAM_LOGE("list node is invalid");
1256             DestroyLinkedList(credList);
1257             return RESULT_UNKNOWN;
1258         }
1259         auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
1260         templateIds.push_back(credentialInfo->templateId);
1261         temp = temp->next;
1262     }
1263     DestroyLinkedList(credList);
1264     return RESULT_SUCCESS;
1265 }
1266 
AddExecutor(const HdiExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)1267 int32_t UserAuthInterfaceService::AddExecutor(const HdiExecutorRegisterInfo &info, uint64_t &index,
1268     std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
1269 {
1270     IAM_LOGI("start");
1271     if (info.publicKey.size() != PUBLIC_KEY_LEN) {
1272         IAM_LOGE("invalid info");
1273         return RESULT_BAD_PARAM;
1274     }
1275     templateIds.clear();
1276     const Buffer *frameworkPubKey = GetPubKey();
1277     if (!IsBufferValid(frameworkPubKey)) {
1278         IAM_LOGE("get public key failed");
1279         return RESULT_UNKNOWN;
1280     }
1281     publicKey.resize(PUBLIC_KEY_LEN);
1282     if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
1283         IAM_LOGE("copy public key failed");
1284         publicKey.clear();
1285         return RESULT_UNKNOWN;
1286     }
1287     std::lock_guard<std::mutex> lock(g_mutex);
1288     ExecutorInfoHal executorInfoHal = {};
1289     bool copyRet = CopyExecutorInfo(info, executorInfoHal);
1290     if (!copyRet) {
1291         IAM_LOGE("copy executor info failed");
1292         return RESULT_UNKNOWN;
1293     }
1294     int32_t ret = RegisterExecutor(&executorInfoHal, &index);
1295     if (ret != RESULT_SUCCESS) {
1296         IAM_LOGE("register executor failed");
1297         return ret;
1298     }
1299     if (info.executorRole == ALL_IN_ONE) {
1300         return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
1301     }
1302     return RESULT_SUCCESS;
1303 }
1304 
DeleteExecutor(uint64_t index)1305 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
1306 {
1307     IAM_LOGI("start");
1308     std::lock_guard<std::mutex> lock(g_mutex);
1309     return UnRegisterExecutor(index);
1310 }
1311 
GetAllExtUserInfo(std::vector<ExtUserInfo> & userInfos)1312 int32_t UserAuthInterfaceService::GetAllExtUserInfo(std::vector<ExtUserInfo> &userInfos)
1313 {
1314     IAM_LOGI("start");
1315     UserInfoResult *userInfoResult = (UserInfoResult *)Malloc(sizeof(UserInfoResult) * MAX_USER);
1316     if (userInfoResult == NULL) {
1317         IAM_LOGE("malloc failed");
1318         return RESULT_GENERAL_ERROR;
1319     }
1320     uint32_t userInfoCount = 0;
1321     ResultCode ret = QueryAllExtUserInfoFunc(userInfoResult, MAX_USER, &userInfoCount);
1322     if (ret != RESULT_SUCCESS) {
1323         Free(userInfoResult);
1324         IAM_LOGE("QueryAllExtUserInfoFunc failed");
1325         return RESULT_GENERAL_ERROR;
1326     }
1327 
1328     for (uint32_t i = 0; i < userInfoCount; i++) {
1329         ExtUserInfo info = {};
1330         info.userId = userInfoResult[i].userId;
1331         info.userInfo.secureUid = userInfoResult[i].secUid;
1332         info.userInfo.pinSubType = static_cast<PinSubType>(userInfoResult[i].pinSubType);
1333         for (uint32_t j = 0; j < userInfoResult[i].enrollNum; j++) {
1334             EnrolledInfo enrolledInfo = {};
1335             enrolledInfo.authType = static_cast<AuthType>(userInfoResult[i].enrolledInfo[j].authType);
1336             enrolledInfo.enrolledId = userInfoResult[i].enrolledInfo[j].enrolledId;
1337             info.userInfo.enrolledInfos.push_back(enrolledInfo);
1338         }
1339         userInfos.push_back(info);
1340     }
1341 
1342     Free(userInfoResult);
1343     return RESULT_SUCCESS;
1344 }
1345 
GetEnrolledState(int32_t userId,int32_t authType,HdiEnrolledState & enrolledState)1346 int32_t UserAuthInterfaceService::GetEnrolledState(int32_t userId, int32_t authType, HdiEnrolledState &enrolledState)
1347 {
1348     IAM_LOGI("start");
1349     EnrolledStateHal *enrolledStateHal = (EnrolledStateHal *) Malloc(sizeof(EnrolledStateHal));
1350     if (enrolledStateHal == NULL) {
1351         IAM_LOGE("malloc failed");
1352         return RESULT_GENERAL_ERROR;
1353     }
1354     int32_t ret = GetEnrolledStateFunc(userId, authType, enrolledStateHal);
1355     if (ret != RESULT_SUCCESS) {
1356         Free(enrolledStateHal);
1357         IAM_LOGE("GetEnrolledState failed");
1358         return ret;
1359     }
1360     enrolledState.credentialDigest = enrolledStateHal->credentialDigest;
1361     enrolledState.credentialCount = enrolledStateHal->credentialCount;
1362 
1363     Free(enrolledStateHal);
1364     return RESULT_SUCCESS;
1365 }
1366 
CheckReuseUnlockResult(const ReuseUnlockParam & param,ReuseUnlockInfo & info)1367 int32_t UserAuthInterfaceService::CheckReuseUnlockResult(const ReuseUnlockParam& param,
1368     ReuseUnlockInfo& info)
1369 {
1370     IAM_LOGI("start reuseMode: %{public}u, reuseDuration: %{public}" PRIu64 ".", param.reuseUnlockResultMode,
1371         param.reuseUnlockResultDuration);
1372     if (param.authTypes.empty() || param.authTypes.size() > MAX_AUTH_TYPE_LEN ||
1373         param.reuseUnlockResultDuration == 0 || param.reuseUnlockResultDuration > REUSED_UNLOCK_TOKEN_PERIOD ||
1374         (param.reuseUnlockResultMode != AUTH_TYPE_RELEVANT && param.reuseUnlockResultMode != AUTH_TYPE_IRRELEVANT &&
1375         param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT &&
1376         param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT)) {
1377         IAM_LOGE("checkReuseUnlockResult bad param");
1378         return RESULT_BAD_PARAM;
1379     }
1380     ReuseUnlockParamHal paramHal = {};
1381     paramHal.userId = param.baseParam.userId;
1382     paramHal.authTrustLevel = param.baseParam.authTrustLevel;
1383     paramHal.reuseUnlockResultDuration = param.reuseUnlockResultDuration;
1384     paramHal.reuseUnlockResultMode = param.reuseUnlockResultMode;
1385     if (!param.baseParam.challenge.empty() &&
1386         memcpy_s(paramHal.challenge, CHALLENGE_LEN,
1387             param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
1388         IAM_LOGE("challenge copy failed");
1389         return RESULT_BAD_COPY;
1390     }
1391     paramHal.authTypeSize = param.authTypes.size();
1392     for (uint32_t i = 0; i < param.authTypes.size(); i++) {
1393         paramHal.authTypes[i] = static_cast<uint32_t>(param.authTypes[i]);
1394     }
1395     ReuseUnlockResult reuseResult = {};
1396     int32_t ret = CheckReuseUnlockResultFunc(&paramHal, &reuseResult);
1397     if (ret != RESULT_SUCCESS) {
1398         info.token.clear();
1399         IAM_LOGE("check reuse unlock result failed, ret:%{public}d", ret);
1400         return ret;
1401     }
1402     info.authType = reuseResult.authType;
1403     info.enrolledState.credentialDigest = reuseResult.enrolledState.credentialDigest;
1404     info.enrolledState.credentialCount = reuseResult.enrolledState.credentialCount;
1405     info.token.resize(AUTH_TOKEN_LEN);
1406     if (memcpy_s(info.token.data(), info.token.size(), reuseResult.token, AUTH_TOKEN_LEN) != EOK) {
1407         IAM_LOGE("copy authToken failed");
1408         info.token.clear();
1409         return RESULT_BAD_COPY;
1410     }
1411     IAM_LOGI("check reuse unlock result finish success");
1412     return RESULT_SUCCESS;
1413 }
1414 
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)1415 int32_t UserAuthInterfaceService::SendMessage(uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t>& msg)
1416 {
1417     static_cast<void>(scheduleId);
1418     static_cast<void>(srcRole);
1419     static_cast<void>(msg);
1420     return HDF_SUCCESS;
1421 }
1422 
RegisterMessageCallback(const sptr<IMessageCallback> & messageCallback)1423 int32_t UserAuthInterfaceService::RegisterMessageCallback(const sptr<IMessageCallback>& messageCallback)
1424 {
1425     static_cast<void>(messageCallback);
1426     return HDF_SUCCESS;
1427 }
1428 
PrepareRemoteAuth(const std::string & remoteUdid)1429 int32_t UserAuthInterfaceService::PrepareRemoteAuth(const std::string &remoteUdid)
1430 {
1431     IAM_LOGI("PrepareRemoteAuth");
1432     return RESULT_SUCCESS;
1433 }
1434 
CopyHdiScheduleInfo(const ScheduleInfoParam * in,HdiScheduleInfo * out)1435 static bool CopyHdiScheduleInfo(const ScheduleInfoParam *in, HdiScheduleInfo *out)
1436 {
1437     IAM_LOGI("CopyHdiScheduleInfo start");
1438     out->executorIndexes.clear();
1439     out->templateIds.clear();
1440     out->executorMessages.clear();
1441     out->scheduleId = in->scheduleId;
1442     out->authType = static_cast<AuthType>(in->authType);
1443     out->executorMatcher = static_cast<uint32_t>(in->executorMatcher);
1444     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
1445     out->executorIndexes.push_back(in->executorIndex);
1446     out->executorMessages.resize(1);
1447     out->executorMessages[0].resize(in->executorMessages->contentSize);
1448     if (memcpy_s(out->executorMessages[0].data(), out->executorMessages[0].size(),
1449         in->executorMessages->buf, in->executorMessages->contentSize) != EOK) {
1450         IAM_LOGE("copy executorMessages failed");
1451         out->executorMessages.clear();
1452         out->executorIndexes.clear();
1453         return false;
1454     }
1455     return true;
1456 }
1457 
DestroyScheduleInfoParam(ScheduleInfoParam * result)1458 static void DestroyScheduleInfoParam(ScheduleInfoParam *result)
1459 {
1460     if (result == NULL) {
1461         return;
1462     }
1463     if (result->executorMessages != NULL) {
1464         DestoryBuffer(result->executorMessages);
1465     }
1466     Free(result);
1467 }
1468 
GetLocalScheduleFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiScheduleInfo & scheduleInfo)1469 int32_t UserAuthInterfaceService::GetLocalScheduleFromMessage(const std::string &remoteUdid,
1470     const std::vector<uint8_t> &message, HdiScheduleInfo& scheduleInfo)
1471 {
1472     IAM_LOGI("GetLocalScheduleFromMessage start");
1473     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1474         IAM_LOGE("param is invalid");
1475         return RESULT_BAD_PARAM;
1476     }
1477     Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1478     if (!IsBufferValid(messageBuffer)) {
1479         IAM_LOGE("messageBuffer is invalid");
1480         return RESULT_NO_MEMORY;
1481     }
1482     std::lock_guard<std::mutex> lock(g_mutex);
1483     ScheduleInfoParam *scheduleParam = (ScheduleInfoParam *)Malloc(sizeof(ScheduleInfoParam));
1484     if (scheduleParam == NULL) {
1485         IAM_LOGE("schedule is null");
1486         DestoryBuffer(messageBuffer);
1487         return RESULT_GENERAL_ERROR;
1488     }
1489 
1490     int32_t funcRet = RESULT_GENERAL_ERROR;
1491     int32_t ret = RESULT_GENERAL_ERROR;
1492     Uint8Array remoteUdidArray = {};
1493     if (memcpy_s(scheduleParam->localUdid, sizeof(scheduleParam->localUdid), g_localUdid.c_str(),
1494         g_localUdid.length()) != EOK) {
1495         IAM_LOGE("localUdid copy failed");
1496         goto FAIL;
1497     }
1498 
1499     if (memcpy_s(scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid), remoteUdid.c_str(),
1500         remoteUdid.length()) != EOK) {
1501         IAM_LOGE("remoteUdid copy failed");
1502         goto FAIL;
1503     }
1504 
1505     remoteUdidArray = { scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid) };
1506 
1507     ret = GenerateScheduleFunc(messageBuffer, remoteUdidArray, scheduleParam);
1508     if (ret != RESULT_SUCCESS) {
1509         IAM_LOGE("GenerateScheduleFunc failed");
1510         goto FAIL;
1511     }
1512     if (!CopyHdiScheduleInfo(scheduleParam, &scheduleInfo)) {
1513         IAM_LOGE("copy schedule info failed");
1514         goto FAIL;
1515     }
1516 
1517     funcRet = RESULT_SUCCESS;
1518 FAIL:
1519     DestoryBuffer(messageBuffer);
1520     DestroyScheduleInfoParam(scheduleParam);
1521     return funcRet;
1522 }
1523 
DestroyExecutorInfo(void * data)1524 static void DestroyExecutorInfo(void *data)
1525 {
1526     if (data == nullptr) {
1527         IAM_LOGE("data is null");
1528         return;
1529     }
1530     Free(data);
1531 }
1532 
GetSignedExecutorInfo(const std::vector<int32_t> & authTypes,int32_t executorRole,const std::string & remoteUdid,std::vector<uint8_t> & signedExecutorInfo)1533 int32_t UserAuthInterfaceService::GetSignedExecutorInfo(const std::vector<int32_t>& authTypes, int32_t executorRole,
1534     const std::string& remoteUdid, std::vector<uint8_t>& signedExecutorInfo)
1535 {
1536     IAM_LOGI("GetSignedExecutorInfo start");
1537     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (authTypes.size() == 0)) {
1538         IAM_LOGE("param is invalid");
1539         return RESULT_BAD_PARAM;
1540     }
1541     ResultCode result = RESULT_GENERAL_ERROR;
1542     LinkedList *linkedList = CreateLinkedList(DestroyExecutorInfo);
1543     if (linkedList == NULL) {
1544         IAM_LOGE("create linkedList failed");
1545         return result;
1546     }
1547     std::lock_guard<std::mutex> lock(g_mutex);
1548     for (uint32_t i = 0; i < authTypes.size(); i++) {
1549         result = GetExecutorInfoLinkedList(authTypes[i], executorRole, linkedList);
1550         if (result != RESULT_SUCCESS) {
1551             IAM_LOGE("GetExecutorInfo failed");
1552             DestroyLinkedList(linkedList);
1553             return result;
1554         }
1555     }
1556     uint8_t remoteUdidData[UDID_LEN] = {};
1557     if (memcpy_s(remoteUdidData, UDID_LEN, remoteUdid.c_str(), remoteUdid.length()) != EOK) {
1558         IAM_LOGE("remoteUdidData copy failed");
1559         DestroyLinkedList(linkedList);
1560         return RESULT_BAD_COPY;
1561     }
1562 
1563     Uint8Array remoteUdidArray = { remoteUdidData, sizeof(remoteUdidData) };
1564     Buffer *signInfo = GetSignExecutorInfoFunc(remoteUdidArray, linkedList);
1565     if (!IsBufferValid(signInfo)) {
1566         IAM_LOGE("signInfo is invalid");
1567         DestroyLinkedList(linkedList);
1568         return RESULT_NO_MEMORY;
1569     }
1570     signedExecutorInfo.resize(signInfo->contentSize);
1571     if (memcpy_s(&signedExecutorInfo[0], signedExecutorInfo.size(), signInfo->buf, signInfo->contentSize) != EOK) {
1572         IAM_LOGE("sign copy failed");
1573         result = RESULT_BAD_COPY;
1574     }
1575     DestoryBuffer(signInfo);
1576     DestroyLinkedList(linkedList);
1577     return result;
1578 }
1579 
CopyHdiAuthResultInfo(const AuthResultParam * in,HdiAuthResultInfo * out,const std::vector<uint8_t> & message)1580 static bool CopyHdiAuthResultInfo(const AuthResultParam *in, HdiAuthResultInfo *out,
1581     const std::vector<uint8_t>& message)
1582 {
1583     IAM_LOGI("CopyHdiAuthResultInfo start");
1584     out->token.clear();
1585     out->rootSecret.clear();
1586     out->remoteAuthResultMsg.clear();
1587     out->result = in->result;
1588     out->lockoutDuration = in->lockoutDuration;
1589     out->remainAttempts = in->remainAttempts;
1590     out->userId = in->userId;
1591 
1592     out->token.resize(in->token->contentSize);
1593     if (memcpy_s(out->token.data(), out->token.size(), in->token->buf, in->token->contentSize) != EOK) {
1594         IAM_LOGE("copy token failed");
1595         return false;
1596     }
1597 
1598     out->remoteAuthResultMsg.resize(message.size());
1599     if (memcpy_s(out->remoteAuthResultMsg.data(), out->remoteAuthResultMsg.size(),
1600         message.data(), message.size()) != EOK) {
1601         IAM_LOGE("copy remoteAuthResultMsg failed");
1602         return false;
1603     }
1604     return true;
1605 }
1606 
DestroyAuthResultParam(AuthResultParam * result)1607 static void DestroyAuthResultParam(AuthResultParam *result)
1608 {
1609     if (result == NULL) {
1610         return;
1611     }
1612     if (result->token != NULL) {
1613         DestoryBuffer(result->token);
1614     }
1615     if (result->remoteAuthResultMsg != NULL) {
1616         DestoryBuffer(result->remoteAuthResultMsg);
1617     }
1618     Free(result);
1619 }
1620 
GetAuthResultFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiAuthResultInfo & authResultInfo)1621 int32_t UserAuthInterfaceService::GetAuthResultFromMessage(const std::string& remoteUdid,
1622     const std::vector<uint8_t>& message, HdiAuthResultInfo& authResultInfo)
1623 {
1624     IAM_LOGI("GetAuthResultFromMessage start");
1625     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1626         IAM_LOGE("param is invalid");
1627         return RESULT_BAD_PARAM;
1628     }
1629     Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1630     if (!IsBufferValid(messageBuffer)) {
1631         IAM_LOGE("messageBuffer is invalid");
1632         return RESULT_NO_MEMORY;
1633     }
1634     std::lock_guard<std::mutex> lock(g_mutex);
1635     AuthResultParam *authResultParam = (AuthResultParam *)Malloc(sizeof(AuthResultParam));
1636     if (authResultParam == NULL) {
1637         IAM_LOGE("authResultParam is null");
1638         DestoryBuffer(messageBuffer);
1639         return RESULT_GENERAL_ERROR;
1640     }
1641 
1642     int32_t funcRet = RESULT_GENERAL_ERROR;
1643     int32_t ret = RESULT_GENERAL_ERROR;
1644     if (memcpy_s(authResultParam->localUdid, sizeof(authResultParam->localUdid), g_localUdid.c_str(),
1645         g_localUdid.length()) != EOK) {
1646         IAM_LOGE("localUdid copy failed");
1647         goto FAIL;
1648     }
1649 
1650     if (memcpy_s(authResultParam->remoteUdid, sizeof(authResultParam->remoteUdid), remoteUdid.c_str(),
1651         remoteUdid.length()) != EOK) {
1652         IAM_LOGE("remoteUdid copy failed");
1653         goto FAIL;
1654     }
1655 
1656     ret = GenerateAuthResultFunc(messageBuffer, authResultParam);
1657     if (ret != RESULT_SUCCESS) {
1658         IAM_LOGE("GenerateAuthResultFunc failed");
1659         goto FAIL;
1660     }
1661     if (!CopyHdiAuthResultInfo(authResultParam, &authResultInfo, message)) {
1662         IAM_LOGE("copy authResult info failed");
1663         goto FAIL;
1664     }
1665     ret = CreateExecutorCommand(authResultInfo.userId, authResultInfo);
1666     if (ret != RESULT_SUCCESS) {
1667         IAM_LOGE("CreateExecutorCommand failed");
1668         goto FAIL;
1669     }
1670 
1671     funcRet = RESULT_SUCCESS;
1672 FAIL:
1673     DestoryBuffer(messageBuffer);
1674     DestroyAuthResultParam(authResultParam);
1675     return ret;
1676 }
1677 
CopyGlobalConfigParam(const HdiGlobalConfigParam & param,GlobalConfigParamHal & paramHal)1678 static int32_t CopyGlobalConfigParam(const HdiGlobalConfigParam &param, GlobalConfigParamHal &paramHal)
1679 {
1680     switch (param.type) {
1681         case PIN_EXPIRED_PERIOD:
1682             paramHal.value.pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1683             if (param.value.pinExpiredPeriod > 0) {
1684                 paramHal.value.pinExpiredPeriod = param.value.pinExpiredPeriod;
1685             }
1686             break;
1687         case ENABLE_STATUS:
1688             paramHal.value.enableStatus = param.value.enableStatus;
1689             break;
1690         default:
1691             IAM_LOGE("bad global config type");
1692             return RESULT_BAD_PARAM;
1693     }
1694     paramHal.type = static_cast<GlobalConfigTypeHal>(param.type);
1695 
1696     for (uint32_t i = 0; i < param.userIds.size(); i++) {
1697         paramHal.userIds[i] = param.userIds[i];
1698     }
1699     paramHal.userIdNum = param.userIds.size();
1700     for (uint32_t i = 0; i < param.authTypes.size(); i++) {
1701         paramHal.authTypes[i] = static_cast<uint32_t>(param.authTypes[i]);
1702     }
1703     paramHal.authTypeNum = param.authTypes.size();
1704     return RESULT_SUCCESS;
1705 }
1706 
SetGlobalConfigParam(const HdiGlobalConfigParam & param)1707 int32_t UserAuthInterfaceService::SetGlobalConfigParam(const HdiGlobalConfigParam &param)
1708 {
1709     IAM_LOGI("start, global config type is %{public}d, userIds size %{public}zu, authTypes size %{public}zu",
1710         param.type, param.userIds.size(), param.authTypes.size());
1711     if (param.authTypes.size() > MAX_AUTH_TYPE_LEN || param.authTypes.size() == 0 ||
1712         param.userIds.size() > MAX_USER) {
1713         IAM_LOGE("SetGlobalConfigParam bad param");
1714         return RESULT_BAD_PARAM;
1715     }
1716     GlobalConfigParamHal paramHal = {};
1717     int32_t ret = CopyGlobalConfigParam(param, paramHal);
1718     if (ret != RESULT_SUCCESS) {
1719         IAM_LOGE("CopyGlobalConfigParam failed");
1720         return ret;
1721     }
1722 
1723     ret = SetGlobalConfigParamFunc(&paramHal);
1724     if (ret != RESULT_SUCCESS) {
1725         IAM_LOGE("SetGlobalConfigParamFunc failed");
1726     }
1727     return ret;
1728 }
1729 
GetCredentialById(uint64_t credentialId,HdiCredentialInfo & info)1730 int32_t UserAuthInterfaceService::GetCredentialById(uint64_t credentialId, HdiCredentialInfo &info)
1731 {
1732     IAM_LOGI("start");
1733     std::lock_guard<std::mutex> lock(g_mutex);
1734     LinkedList *credList = nullptr;
1735     int32_t ret = QueryCredentialByIdFunc(credentialId, &credList);
1736     if (ret != RESULT_SUCCESS || credList == NULL) {
1737         IAM_LOGE("query credential failed");
1738         return RESULT_GENERAL_ERROR;
1739     }
1740     if (credList->head == NULL || credList->head->data == NULL) {
1741         IAM_LOGE("credential is null");
1742         DestroyLinkedList(credList);
1743         return RESULT_NOT_ENROLLED;
1744     }
1745     auto credentialHal = static_cast<CredentialInfoHal *>(credList->head->data);
1746     CopyCredentialInfo(*credentialHal, info);
1747     DestroyLinkedList(credList);
1748     return RESULT_SUCCESS;
1749 }
1750 
CopyAuthTokenPlainHal(const UserAuthTokenPlainHal & tokenIn,HdiUserAuthTokenPlain & tokenOut)1751 static bool CopyAuthTokenPlainHal(const UserAuthTokenPlainHal &tokenIn, HdiUserAuthTokenPlain &tokenOut)
1752 {
1753     tokenOut.userId = tokenIn.tokenDataToEncrypt.userId;
1754     tokenOut.challenge.resize(CHALLENGE_LEN);
1755     if (tokenOut.challenge.size() != 0 && memcpy_s(tokenOut.challenge.data(), CHALLENGE_LEN,
1756         tokenIn.tokenDataPlain.challenge, CHALLENGE_LEN) != EOK) {
1757         IAM_LOGE("copy challenge fail");
1758         return RESULT_BAD_COPY;
1759     }
1760     uint64_t currentTime = GetSystemTime();
1761     if (currentTime < tokenIn.tokenDataPlain.time) {
1762         LOG_ERROR("bad time, current:%" PRIu64 ", tokenTime:%" PRIu64, currentTime, tokenIn.tokenDataPlain.time);
1763         return RESULT_GENERAL_ERROR;
1764     }
1765     tokenOut.timeInterval = currentTime - tokenIn.tokenDataPlain.time;
1766     tokenOut.authTrustLevel = tokenIn.tokenDataPlain.authTrustLevel;
1767     tokenOut.authType = tokenIn.tokenDataPlain.authType;
1768     tokenOut.authMode = tokenIn.tokenDataPlain.authMode;
1769     tokenOut.securityLevel = tokenIn.tokenDataPlain.securityLevel;
1770     tokenOut.tokenType = tokenIn.tokenDataPlain.tokenType;
1771     tokenOut.secureUid = tokenIn.tokenDataToEncrypt.secureUid;
1772     tokenOut.enrolledId = tokenIn.tokenDataToEncrypt.enrolledId;
1773     tokenOut.credentialId = tokenIn.tokenDataToEncrypt.credentialId;
1774     tokenOut.collectorUdid.resize(UDID_LEN);
1775     if (tokenOut.collectorUdid.length() != 0 && memcpy_s(tokenOut.collectorUdid.data(), UDID_LEN,
1776         tokenIn.tokenDataToEncrypt.collectorUdid, UDID_LEN) != EOK) {
1777         IAM_LOGE("copy collectorUdid fail");
1778         return RESULT_BAD_COPY;
1779     }
1780     tokenOut.verifierUdid.resize(UDID_LEN);
1781     if (tokenOut.verifierUdid.length() != 0 && memcpy_s(tokenOut.verifierUdid.data(), UDID_LEN,
1782         tokenIn.tokenDataToEncrypt.verifierUdid, UDID_LEN) != EOK) {
1783         IAM_LOGE("copy verifierUdid fail");
1784         return RESULT_BAD_COPY;
1785     }
1786     return RESULT_SUCCESS;
1787 }
1788 
ConvertResultCode(const int32_t in)1789 static int32_t ConvertResultCode(const int32_t in)
1790 {
1791     static const std::map<ResultCode, InnerKitResultCode> data = {
1792         {ResultCode::RESULT_TOKEN_TIMEOUT, InnerKitResultCode::INNER_RESULT_AUTH_TOKEN_EXPIRED},
1793         {ResultCode::RESULT_VERIFY_TOKEN_FAIL, InnerKitResultCode::INNER_RESULT_AUTH_TOKEN_CHECK_FAILED},
1794     };
1795     auto iter = data.find(static_cast<ResultCode>(in));
1796     if (iter != data.end()) {
1797         return iter->second;
1798     }
1799     return in;
1800 }
1801 
GetRootSecret(const UserAuthTokenPlainHal & token,std::vector<uint8_t> & rootSecret)1802 static void GetRootSecret(const UserAuthTokenPlainHal &token, std::vector<uint8_t> &rootSecret)
1803 {
1804     rootSecret.resize(0);
1805     if (CheckSessionTimeout() != RESULT_SUCCESS) {
1806         LOG_ERROR("CheckSessionTimeout fail");
1807         return;
1808     }
1809     if (!IsValidTokenTime(token.tokenDataPlain.time)) {
1810         LOG_ERROR("check token time failed, token is invalid");
1811         return;
1812     }
1813     if (CheckChallenge(token.tokenDataPlain.challenge, CHALLENGE_LEN) != RESULT_SUCCESS) {
1814         LOG_ERROR("check challenge failed, token is invalid");
1815         return;
1816     }
1817     if (token.tokenDataPlain.authType != PIN_AUTH) {
1818         LOG_ERROR("token authType is not pin");
1819         return;
1820     }
1821 
1822     Buffer *rootSecretBuffer = GetCacheRootSecret(token.tokenDataToEncrypt.userId);
1823     if (!IsBufferValid(rootSecretBuffer)) {
1824         IAM_LOGE("get GetCacheRootSecret failed");
1825         DestoryBuffer(rootSecretBuffer);
1826         return;
1827     }
1828     rootSecret.resize(ROOT_SECRET_LEN);
1829     if (memcpy_s(rootSecret.data(), rootSecret.size(), rootSecretBuffer->buf, rootSecretBuffer->contentSize) != EOK) {
1830         IAM_LOGE("rootSecret copy failed");
1831         (void)memset_s(rootSecret.data(), rootSecret.size(), 0, rootSecret.size());
1832         rootSecret.clear();
1833     }
1834 
1835     DestoryBuffer(rootSecretBuffer);
1836     return;
1837 }
1838 
VerifyAuthToken(const std::vector<uint8_t> & tokenIn,uint64_t allowableDuration,HdiUserAuthTokenPlain & tokenPlainOut,std::vector<uint8_t> & rootSecret)1839 int32_t UserAuthInterfaceService::VerifyAuthToken(const std::vector<uint8_t> &tokenIn, uint64_t allowableDuration,
1840     HdiUserAuthTokenPlain &tokenPlainOut, std::vector<uint8_t> &rootSecret)
1841 {
1842     IAM_LOGI("start, allowableDuration:%{public}" PRIu64, allowableDuration);
1843     if (tokenIn.size() != sizeof(UserAuthTokenHal) || tokenIn.data() == NULL ||
1844         allowableDuration > MAX_TOKEN_ALLOWABLE_DURATION) {
1845         IAM_LOGE("VerifyAuthToken bad param");
1846         return RESULT_BAD_PARAM;
1847     }
1848     UserAuthTokenPlainHal tokenPlain = {};
1849     int32_t result = UserAuthTokenVerify((UserAuthTokenHal *)(tokenIn.data()), allowableDuration, &tokenPlain);
1850     if (result != RESULT_SUCCESS) {
1851         IAM_LOGE("UserAuthTokenVerify failed");
1852         return ConvertResultCode(result);
1853     }
1854     GetRootSecret(tokenPlain, rootSecret);
1855     result = CopyAuthTokenPlainHal(tokenPlain, tokenPlainOut);
1856     if (result != RESULT_SUCCESS) {
1857         IAM_LOGE("CopyAuthTokenPlainHal failed");
1858         return result;
1859     }
1860     return result;
1861 }
1862 } // Userauth
1863 } // HDI
1864 } // OHOS