1 /*
2 * Copyright (c) 2022 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 "pin_auth.h"
17 #include <map>
18 #include <sys/stat.h>
19 #include <vector>
20 #include <unistd.h>
21 #include "pthread.h"
22 #include "adaptor_memory.h"
23 #include "adaptor_log.h"
24 #include "pin_func.h"
25 #include "securec.h"
26
27 namespace OHOS {
28 namespace UserIam {
29 namespace PinAuth {
30 std::map<int32_t, ResultCodeForCoAuth> g_convertResult = {
31 {RESULT_SUCCESS, ResultCodeForCoAuth::SUCCESS},
32 {RESULT_BAD_PARAM, ResultCodeForCoAuth::INVALID_PARAMETERS},
33 {RESULT_COMPARE_FAIL, ResultCodeForCoAuth::FAIL},
34 {RESULT_BUSY, ResultCodeForCoAuth::BUSY},
35 {RESULT_PIN_FREEZE, ResultCodeForCoAuth::LOCKED},
36 };
37
38 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
39
PinAuth()40 PinAuth::PinAuth() { }
41
42 /* This is for example only, Should be implemented in trusted environment. */
Init()43 int32_t PinAuth::Init()
44 {
45 if (pthread_mutex_lock(&g_mutex) != 0) {
46 LOG_ERROR("pthread_mutex_lock fail!");
47 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
48 }
49 LOG_INFO("start InIt pinAuth.");
50 InitPinDb();
51 if (GenerateKeyPair() != RESULT_SUCCESS) {
52 LOG_ERROR("GenerateKeyPair fail!");
53 static_cast<void>(pthread_mutex_unlock(&g_mutex));
54 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
55 }
56 if (pthread_mutex_unlock(&g_mutex) != 0) {
57 LOG_ERROR("pthread_mutex_unlock fail!");
58 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
59 }
60 LOG_INFO("InIt pinAuth succ");
61
62 return RESULT_SUCCESS;
63 }
64
65 /* This is for example only, Should be implemented in trusted environment. */
Close()66 int32_t PinAuth::Close()
67 {
68 if (pthread_mutex_lock(&g_mutex) != 0) {
69 LOG_ERROR("pthread_mutex_lock fail!");
70 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
71 }
72 LOG_INFO("start Close pinAuth");
73 DestroyPinDb();
74 if (pthread_mutex_unlock(&g_mutex) != 0) {
75 LOG_ERROR("pthread_mutex_unlock fail!");
76 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
77 }
78 LOG_INFO("Close pinAuth succ");
79
80 return RESULT_SUCCESS;
81 }
82
83 /* This is for example only, Should be implemented in trusted environment. */
PinResultToCoAuthResult(int resultCode)84 int32_t PinAuth::PinResultToCoAuthResult(int resultCode)
85 {
86 LOG_INFO("PinAuth::PinResultToCoAuthResult enter");
87 if (g_convertResult.count(resultCode) == 0) {
88 LOG_ERROR("PinResult and CoauthResult not match, convert GENERAL_ERROR");
89 return ResultCodeForCoAuth::GENERAL_ERROR;
90 } else {
91 return g_convertResult[resultCode];
92 }
93 }
94
InitPinEnrollParam(PinEnrollParam * pinEnrollParam,uint64_t scheduleId,uint64_t subType,std::vector<uint8_t> & salt,const std::vector<uint8_t> & pinData)95 static ResultCode InitPinEnrollParam(PinEnrollParam *pinEnrollParam, uint64_t scheduleId, uint64_t subType,
96 std::vector<uint8_t> &salt, const std::vector<uint8_t> &pinData)
97 {
98 pinEnrollParam->scheduleId= scheduleId;
99 pinEnrollParam->subType = subType;
100 if (memcpy_s(&(pinEnrollParam->salt[0]), CONST_SALT_LEN, &salt[0], CONST_SALT_LEN) != EOK) {
101 LOG_ERROR("copy salt to pinEnrollParam fail!");
102 return RESULT_GENERAL_ERROR;
103 }
104 if (memcpy_s(&(pinEnrollParam->pinData[0]), CONST_PIN_DATA_LEN, &pinData[0], CONST_PIN_DATA_LEN) != EOK) {
105 LOG_ERROR("copy pinData to pinEnrollParam fail!");
106 return RESULT_GENERAL_ERROR;
107 }
108
109 return RESULT_SUCCESS;
110 }
111
SetResultTlv(Buffer * retTlv,std::vector<uint8_t> & resultTlv)112 static ResultCode SetResultTlv(Buffer *retTlv, std::vector<uint8_t> &resultTlv)
113 {
114 resultTlv.resize(retTlv->contentSize);
115 if (memcpy_s(&resultTlv[0], retTlv->contentSize, retTlv->buf, retTlv->contentSize) != EOK) {
116 LOG_ERROR("copy retTlv to resultTlv fail!");
117 return RESULT_GENERAL_ERROR;
118 }
119
120 return RESULT_SUCCESS;
121 }
122
123 /* This is for example only, Should be implemented in trusted environment. */
EnrollPin(uint64_t scheduleId,uint64_t subType,std::vector<uint8_t> & salt,const std::vector<uint8_t> & pinData,std::vector<uint8_t> & resultTlv)124 int32_t PinAuth::EnrollPin(uint64_t scheduleId, uint64_t subType, std::vector<uint8_t> &salt,
125 const std::vector<uint8_t> &pinData, std::vector<uint8_t> &resultTlv)
126 {
127 if (pthread_mutex_lock(&g_mutex) != 0) {
128 LOG_ERROR("pthread_mutex_lock fail!");
129 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
130 }
131 if (salt.size() != CONST_SALT_LEN || pinData.size() != CONST_PIN_DATA_LEN) {
132 LOG_ERROR("get bad params!");
133 static_cast<void>(pthread_mutex_unlock(&g_mutex));
134 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
135 }
136 PinEnrollParam *pinEnrollParam = new (std::nothrow) PinEnrollParam();
137 if (pinEnrollParam == nullptr) {
138 LOG_ERROR("generate pinEnrollParam fail!");
139 static_cast<void>(pthread_mutex_unlock(&g_mutex));
140 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
141 }
142 ResultCode result = InitPinEnrollParam(pinEnrollParam, scheduleId, subType, salt, pinData);
143 if (result != RESULT_SUCCESS) {
144 LOG_ERROR("InitPinEnrollParam fail!");
145 static_cast<void>(pthread_mutex_unlock(&g_mutex));
146 delete pinEnrollParam;
147 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
148 }
149 Buffer *retTlv = CreateBufferBySize(RESULT_TLV_LEN);
150 result = DoEnrollPin(pinEnrollParam, retTlv);
151 if (result != RESULT_SUCCESS) {
152 LOG_ERROR("DoEnrollPin fail!");
153 goto ERROR;
154 }
155 result = SetResultTlv(retTlv, resultTlv);
156 if (result != RESULT_SUCCESS) {
157 LOG_ERROR("SetRsultTlv fail!");
158 goto ERROR;
159 }
160
161 ERROR:
162 if (pthread_mutex_unlock(&g_mutex) != 0) {
163 LOG_ERROR("pthread_mutex_unlock fail!");
164 result = RESULT_GENERAL_ERROR;
165 }
166 DestoryBuffer(retTlv);
167 delete pinEnrollParam;
168 return PinResultToCoAuthResult(result);
169 }
170
171 /* This is for example only, Should be implemented in trusted environment. */
GetSalt(uint64_t templateId,std::vector<uint8_t> & salt)172 int32_t PinAuth::GetSalt(uint64_t templateId, std::vector<uint8_t> &salt)
173 {
174 if (pthread_mutex_lock(&g_mutex) != 0) {
175 LOG_ERROR("pthread_mutex_lock fail!");
176 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
177 }
178 salt.resize(CONST_SALT_LEN);
179 if (salt.size() != CONST_SALT_LEN) {
180 LOG_ERROR("salt resize fail!");
181 static_cast<void>(pthread_mutex_unlock(&g_mutex));
182 return PinResultToCoAuthResult(RESULT_UNKNOWN);
183 }
184 uint32_t satLen = CONST_SALT_LEN;
185 ResultCode result = DoGetSalt(templateId, &salt[0], &satLen);
186 if (result != RESULT_SUCCESS) {
187 LOG_ERROR("DoGetSalt fail!");
188 static_cast<void>(pthread_mutex_unlock(&g_mutex));
189 return PinResultToCoAuthResult(result);
190 }
191 if (pthread_mutex_unlock(&g_mutex) != RESULT_SUCCESS) {
192 LOG_ERROR("pthread_mutex_unlock fail!");
193 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
194 }
195
196 return RESULT_SUCCESS;
197 }
198
199 /* This is for example only, Should be implemented in trusted environment. */
AuthPin(uint64_t scheduleId,uint64_t templateId,const std::vector<uint8_t> & pinData,std::vector<uint8_t> & resultTlv)200 int32_t PinAuth::AuthPin(uint64_t scheduleId, uint64_t templateId, const std::vector<uint8_t> &pinData,
201 std::vector<uint8_t> &resultTlv)
202 {
203 if (pthread_mutex_lock(&g_mutex) != 0) {
204 LOG_ERROR("pthread_mutex_lock fail!");
205 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
206 }
207 if (pinData.size() != CONST_PIN_DATA_LEN) {
208 LOG_ERROR("bad pidData len!");
209 static_cast<void>(pthread_mutex_unlock(&g_mutex));
210 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
211 }
212
213 PinAuthParam *pinAuthParam = new (std::nothrow) PinAuthParam();
214 if (pinAuthParam == nullptr) {
215 LOG_ERROR("pinAuthParam is nullptr!");
216 static_cast<void>(pthread_mutex_unlock(&g_mutex));
217 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
218 }
219 pinAuthParam->scheduleId = scheduleId;
220 pinAuthParam->templateId = templateId;
221 if (memcpy_s(&(pinAuthParam->pinData[0]), CONST_PIN_DATA_LEN, &pinData[0], pinData.size()) != EOK) {
222 LOG_ERROR("mem copy pinData to pinAuthParam fail!");
223 static_cast<void>(pthread_mutex_unlock(&g_mutex));
224 delete pinAuthParam;
225 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
226 }
227 Buffer *retTlv = CreateBufferBySize(RESULT_TLV_LEN);
228 ResultCode result = DoAuthPin(pinAuthParam, retTlv);
229 if (result != RESULT_SUCCESS) {
230 LOG_ERROR("DoAuthPin fail!");
231 }
232 ResultCode setRet = SetResultTlv(retTlv, resultTlv);
233 if (setRet != RESULT_SUCCESS) {
234 LOG_ERROR("SetRsultTlv fail!");
235 result = setRet;
236 resultTlv.clear();
237 goto ERROR;
238 }
239
240 ERROR:
241 if (pthread_mutex_unlock(&g_mutex) != 0) {
242 LOG_ERROR("pthread_mutex_unlock fail!");
243 result = RESULT_GENERAL_ERROR;
244 }
245 DestoryBuffer(retTlv);
246 delete pinAuthParam;
247 return PinResultToCoAuthResult(result);
248 }
249
250 /* This is for example only, Should be implemented in trusted environment. */
QueryPinInfo(uint64_t templateId,PinCredentialInfo & pinCredentialInfoRet)251 int32_t PinAuth::QueryPinInfo(uint64_t templateId, PinCredentialInfo &pinCredentialInfoRet)
252 {
253 if (pthread_mutex_lock(&g_mutex) != 0) {
254 LOG_ERROR("pthread_mutex_lock fail!");
255 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
256 }
257 PinCredentialInfos *pinCredentialInfosRet = new (std::nothrow) PinCredentialInfos();
258 if (pinCredentialInfosRet == nullptr) {
259 LOG_ERROR("pinCredentialInfosRet is nullptr!");
260 static_cast<void>(pthread_mutex_unlock(&g_mutex));
261 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
262 }
263 ResultCode result = DoQueryPinInfo(templateId, pinCredentialInfosRet);
264 if (result != RESULT_SUCCESS) {
265 LOG_ERROR("DoQueryPinInfo fail!");
266 goto ERROR;
267 }
268
269 pinCredentialInfoRet.subType = pinCredentialInfosRet->subType;
270 pinCredentialInfoRet.remainTimes = pinCredentialInfosRet->remainTimes;
271 pinCredentialInfoRet.freezingTime = pinCredentialInfosRet->freezeTime;
272
273 ERROR:
274 if (pthread_mutex_unlock(&g_mutex) != 0) {
275 LOG_ERROR("pthread_mutex_unlock fail!");
276 result = RESULT_GENERAL_ERROR;
277 }
278 delete pinCredentialInfosRet;
279 return PinResultToCoAuthResult(result);
280 }
281
282 /* This is for example only, Should be implemented in trusted environment. */
DeleteTemplate(uint64_t templateId)283 int32_t PinAuth::DeleteTemplate(uint64_t templateId)
284 {
285 if (pthread_mutex_lock(&g_mutex) != 0) {
286 LOG_ERROR("pthread_mutex_lock fail!");
287 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
288 }
289 ResultCode result = DoDeleteTemplate(templateId);
290 if (result != RESULT_SUCCESS) {
291 LOG_ERROR("DoDeleteTemplate fail!");
292 static_cast<void>(pthread_mutex_unlock(&g_mutex));
293 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
294 }
295 if (pthread_mutex_unlock(&g_mutex) != 0) {
296 LOG_ERROR("pthread_mutex_unlock fail!");
297 result = RESULT_GENERAL_ERROR;
298 }
299
300 return PinResultToCoAuthResult(result);
301 }
302
303 /* This is for example only, Should be implemented in trusted environment. */
GetExecutorInfo(std::vector<uint8_t> & pubKey,uint32_t & esl)304 int32_t PinAuth::GetExecutorInfo(std::vector<uint8_t> &pubKey, uint32_t &esl)
305 {
306 if (pthread_mutex_lock(&g_mutex) != 0) {
307 LOG_ERROR("pthread_mutex_lock fail!");
308 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
309 }
310 PinExecutorInfo *pinExecutorInfo = new (std::nothrow) PinExecutorInfo();
311 if (pinExecutorInfo == nullptr) {
312 LOG_ERROR("pinExecutorInfo is nullptr!");
313 static_cast<void>(pthread_mutex_unlock(&g_mutex));
314 return PinResultToCoAuthResult(RESULT_GENERAL_ERROR);
315 }
316 ResultCode result = DoGetExecutorInfo(pinExecutorInfo);
317 if (result != RESULT_SUCCESS) {
318 LOG_ERROR("DoGetExecutorInfo fail!");
319 goto ERROR;
320 }
321 esl = pinExecutorInfo->esl;
322 pubKey.resize(CONST_PUB_KEY_LEN);
323 if (memcpy_s(&pubKey[0], CONST_PUB_KEY_LEN, &(pinExecutorInfo->pubKey[0]), CONST_PUB_KEY_LEN) != EOK) {
324 LOG_ERROR("copy pinExecutorInfo to pubKey fail!");
325 result = RESULT_GENERAL_ERROR;
326 goto ERROR;
327 }
328
329 ERROR:
330 if (pthread_mutex_unlock(&g_mutex) != 0) {
331 LOG_ERROR("pthread_mutex_unlock fail!");
332 result = RESULT_GENERAL_ERROR;
333 }
334 static_cast<void>(memset_s(&(pinExecutorInfo->pubKey[0]), CONST_PUB_KEY_LEN, 0, CONST_PUB_KEY_LEN));
335 delete pinExecutorInfo;
336 return PinResultToCoAuthResult(result);
337 }
338
339 /* This is for example only, Should be implemented in trusted environment. */
VerifyTemplateData(std::vector<uint64_t> templateIdList)340 int32_t PinAuth::VerifyTemplateData(std::vector<uint64_t> templateIdList)
341 {
342 if (pthread_mutex_lock(&g_mutex) != 0) {
343 LOG_ERROR("pthread_mutex_lock fail!");
344 return PinResultToCoAuthResult(RESULT_BAD_PARAM);
345 }
346 uint32_t templateIdListLen = templateIdList.size();
347 ResultCode result = DoVerifyTemplateData(&templateIdList[0], templateIdListLen);
348 if (result != RESULT_SUCCESS) {
349 LOG_ERROR("DoVerifyTemplateData fail!");
350 }
351 if (pthread_mutex_unlock(&g_mutex) != 0) {
352 LOG_ERROR("pthread_mutex_unlock fail!");
353 result = RESULT_GENERAL_ERROR;
354 }
355 return PinResultToCoAuthResult(result);
356 }
357 } // namespace PinAuth
358 } // namespace UserIam
359 } // namespace OHOS
360