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