1 /*
2 * Copyright (c) 2022-2023 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 #include "authentication_impl.h"
16
17 #include "hdi_wrapper.h"
18 #include "iam_hitrace_helper.h"
19 #include "iam_logger.h"
20 #include "resource_node_utils.h"
21 #include "schedule_node_helper.h"
22
23 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
24 namespace OHOS {
25 namespace UserIam {
26 namespace UserAuth {
AuthenticationImpl(uint64_t contextId,int32_t userId,AuthType authType,AuthTrustLevel atl)27 AuthenticationImpl::AuthenticationImpl(uint64_t contextId, int32_t userId, AuthType authType, AuthTrustLevel atl)
28 : contextId_(contextId),
29 userId_(userId),
30 authType_(authType),
31 atl_(atl)
32 {
33 }
34
~AuthenticationImpl()35 AuthenticationImpl::~AuthenticationImpl()
36 {
37 Cancel();
38 }
39
SetLatestError(int32_t error)40 void AuthenticationImpl::SetLatestError(int32_t error)
41 {
42 if (error != ResultCode::SUCCESS) {
43 latestError_ = error;
44 }
45 }
46
GetLatestError() const47 int32_t AuthenticationImpl::GetLatestError() const
48 {
49 return latestError_;
50 }
51
SetExecutor(uint32_t executorIndex)52 void AuthenticationImpl::SetExecutor(uint32_t executorIndex)
53 {
54 executorIndex_ = executorIndex;
55 }
56
SetChallenge(const std::vector<uint8_t> & challenge)57 void AuthenticationImpl::SetChallenge(const std::vector<uint8_t> &challenge)
58 {
59 challenge_ = challenge;
60 }
61
SetAccessTokenId(uint32_t tokenId)62 void AuthenticationImpl::SetAccessTokenId(uint32_t tokenId)
63 {
64 tokenId_ = tokenId;
65 }
66
SetEndAfterFirstFail(bool endAfterFirstFail)67 void AuthenticationImpl::SetEndAfterFirstFail(bool endAfterFirstFail)
68 {
69 endAfterFirstFail_ = endAfterFirstFail;
70 }
71
GetAccessTokenId() const72 uint32_t AuthenticationImpl::GetAccessTokenId() const
73 {
74 return tokenId_;
75 }
76
Start(std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)77 bool AuthenticationImpl::Start(std::vector<std::shared_ptr<ScheduleNode>> &scheduleList,
78 std::shared_ptr<ScheduleNodeCallback> callback)
79 {
80 auto hdi = HdiWrapper::GetHdiInstance();
81 if (!hdi) {
82 IAM_LOGE("bad hdi");
83 return false;
84 }
85 HdiAuthSolution solution = {
86 .userId = userId_,
87 .authTrustLevel = atl_,
88 .authType = static_cast<HdiAuthType>(authType_),
89 .executorSensorHint = executorSensorHint,
90 .challenge = challenge_,
91 };
92 std::vector<HdiScheduleInfo> infos;
93 IamHitraceHelper traceHelper("hdi BeginAuthentication");
94 auto result = hdi->BeginAuthenticationV1_1(contextId_, solution, infos);
95 if (result != HDF_SUCCESS) {
96 IAM_LOGE("hdi BeginAuthentication failed, err is %{public}d", result);
97 SetLatestError(result);
98 return false;
99 }
100 if (infos.empty()) {
101 IAM_LOGE("hdi BeginAuthentication failed, infos is empty");
102 return false;
103 }
104
105 ScheduleNodeHelper::NodeOptionalPara para;
106 para.tokenId = tokenId_;
107 para.endAfterFirstFail = endAfterFirstFail_;
108
109 if (!ScheduleNodeHelper::BuildFromHdi(infos, callback, scheduleList, para)) {
110 IAM_LOGE("BuildFromHdi failed");
111 return false;
112 }
113
114 running_ = true;
115 return true;
116 }
117
Update(const std::vector<uint8_t> & scheduleResult,AuthResultInfo & resultInfo)118 bool AuthenticationImpl::Update(const std::vector<uint8_t> &scheduleResult, AuthResultInfo &resultInfo)
119 {
120 auto hdi = HdiWrapper::GetHdiInstance();
121 if (!hdi) {
122 IAM_LOGE("bad hdi");
123 return false;
124 }
125
126 HdiAuthResultInfo info;
127 auto result = hdi->UpdateAuthenticationResult(contextId_, scheduleResult, info);
128 if (result != HDF_SUCCESS) {
129 IAM_LOGE("hdi UpdateAuthenticationResult failed, err is %{public}d", result);
130 SetLatestError(result);
131 }
132
133 for (auto &[executorIndex, commandId, msg] : info.msgs) {
134 ResourceNodeUtils::SendMsgToExecutor(executorIndex, commandId, msg);
135 }
136
137 resultInfo.result = static_cast<decltype(resultInfo.result)>(info.result);
138 resultInfo.freezingTime = info.lockoutDuration;
139 resultInfo.remainTimes = info.remainAttempts;
140 resultInfo.token = info.token;
141 resultInfo.rootSecret = info.rootSecret;
142
143 if (resultInfo.result != SUCCESS) {
144 SetLatestError(resultInfo.result);
145 }
146
147 return result == HDF_SUCCESS && resultInfo.result == SUCCESS;
148 }
149
Cancel()150 bool AuthenticationImpl::Cancel()
151 {
152 if (!running_) {
153 return false;
154 }
155 running_ = false;
156
157 auto hdi = HdiWrapper::GetHdiInstance();
158 if (!hdi) {
159 IAM_LOGE("bad hdi");
160 return false;
161 }
162
163 auto result = hdi->CancelAuthentication(contextId_);
164 if (result != HDF_SUCCESS) {
165 IAM_LOGE("hdi CancelAuthentication failed, err is %{public}d", result);
166 SetLatestError(result);
167 return false;
168 }
169 return true;
170 }
171 } // namespace UserAuth
172 } // namespace UserIam
173 } // namespace OHOS