• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include "pin_db_ops_v1.h"
17 
18 #include "securec.h"
19 
20 #include "adaptor_file.h"
21 #include "adaptor_log.h"
22 #include "adaptor_memory.h"
23 #include "file_operator.h"
24 #include "pin_db_ops_base.h"
25 
26 #define PIN_DB_TWO_PARAMS 2
27 
UpdatePinDbFrom0To1(void * pinDb)28 void *UpdatePinDbFrom0To1(void *pinDb)
29 {
30     PinDbV0 *pinDbV0 = pinDb;
31     if (pinDbV0 == NULL) {
32         LOG_ERROR("bad parameter.");
33         return NULL;
34     }
35     PinDbV1 *pinDbV1 = Malloc(sizeof(PinDbV1));
36     if (pinDbV1 == NULL) {
37         LOG_ERROR("get pinDbV1 fail.");
38         return NULL;
39     }
40     (void)memset_s(pinDbV1, sizeof(PinDbV1), 0, sizeof(PinDbV1));
41     pinDbV1->dbVersion = DB_VERSION_1;
42     if (pinDbV0->pinIndex == NULL || pinDbV0->pinIndexLen == 0) {
43         LOG_INFO("get empty pinDbV0.");
44         pinDbV1->pinIndex = NULL;
45         pinDbV1->pinIndexLen = 0;
46         return pinDbV1;
47     }
48 
49     pinDbV1->pinIndexLen = pinDbV0->pinIndexLen;
50     pinDbV1->pinIndex = Malloc(sizeof(PinIndexV1) * pinDbV1->pinIndexLen);
51     if (pinDbV1->pinIndex == NULL) {
52         LOG_ERROR("get pinIndex fail.");
53         Free(pinDbV1);
54         return NULL;
55     }
56     (void)memset_s(pinDbV1->pinIndex,
57         sizeof(PinIndexV1) * pinDbV1->pinIndexLen, 0, sizeof(PinIndexV1) * pinDbV1->pinIndexLen);
58     for (uint32_t i = 0; i < pinDbV1->pinIndexLen; i++) {
59         pinDbV1->pinIndex[i].antiBruteInfo = pinDbV0->pinIndex[i].antiBruteInfo;
60         pinDbV1->pinIndex[i].pinInfo.subType = pinDbV0->pinIndex[i].pinInfo.subType;
61         pinDbV1->pinIndex[i].pinInfo.templateId = pinDbV0->pinIndex[i].pinInfo.templateId;
62         pinDbV1->pinIndex[i].pinInfo.algoVersion = ALGORITHM_VERSION_0;
63         pinDbV1->pinIndex[i].pinInfo.pinLength = PIN_LENGTH_DEFAULT;
64     }
65     return pinDbV1;
66 }
67 
GetPinIndexV1(uint8_t * data,uint32_t dataLen,PinDbV1 * pinDbV1)68 static ResultCode GetPinIndexV1(uint8_t *data, uint32_t dataLen, PinDbV1 *pinDbV1)
69 {
70     if (sizeof(PinInfoV1) * pinDbV1->pinIndexLen != dataLen) {
71         LOG_ERROR("bad data length.");
72         return RESULT_GENERAL_ERROR;
73     }
74     pinDbV1->pinIndex = (PinIndexV1 *)Malloc(sizeof(PinIndexV1) * pinDbV1->pinIndexLen);
75     if (pinDbV1->pinIndex == NULL) {
76         LOG_ERROR("pinIndex malloc fail.");
77         return RESULT_NO_MEMORY;
78     }
79     (void)memset_s(pinDbV1->pinIndex,
80         sizeof(PinIndexV1) * pinDbV1->pinIndexLen, 0, sizeof(PinIndexV1) * pinDbV1->pinIndexLen);
81     uint8_t *temp = data;
82     uint32_t tempLen = dataLen;
83     for (uint32_t i = 0; i < pinDbV1->pinIndexLen; i++) {
84         if (GetDataFromBuf(&temp, &tempLen, (uint8_t *)(&(pinDbV1->pinIndex[i].pinInfo)),
85             sizeof(pinDbV1->pinIndex[i].pinInfo)) != RESULT_SUCCESS) {
86             LOG_ERROR("read pinInfo fail.");
87             Free(pinDbV1->pinIndex);
88             pinDbV1->pinIndex = NULL;
89             return RESULT_BAD_READ;
90         }
91         if (ReadPinFile((uint8_t *)(&(pinDbV1->pinIndex[i].antiBruteInfo)),
92             sizeof(pinDbV1->pinIndex[i].antiBruteInfo),
93             pinDbV1->pinIndex[i].pinInfo.templateId, ANTI_BRUTE_SUFFIX) != RESULT_SUCCESS) {
94             LOG_ERROR("read AntiBruteInfo fail.");
95             GetMaxLockedAntiBruteInfo(&(pinDbV1->pinIndex[i].antiBruteInfo));
96             (void)WritePinFile((uint8_t *)(&(pinDbV1->pinIndex[i].antiBruteInfo)),
97                 sizeof(pinDbV1->pinIndex[i].antiBruteInfo),
98                 pinDbV1->pinIndex[i].pinInfo.templateId, ANTI_BRUTE_SUFFIX);
99         }
100     }
101     return RESULT_SUCCESS;
102 }
103 
UnpackPinDbV1(uint8_t * data,uint32_t dataLen,PinDbV1 * pinDbV1)104 static bool UnpackPinDbV1(uint8_t *data, uint32_t dataLen, PinDbV1 *pinDbV1)
105 {
106     uint8_t *temp = data;
107     uint32_t tempLen = dataLen;
108     if (GetDataFromBuf(&temp, &tempLen, (uint8_t *)(&(pinDbV1->dbVersion)),
109         sizeof(pinDbV1->dbVersion)) != RESULT_SUCCESS) {
110         LOG_ERROR("read dbVersion fail.");
111         return false;
112     }
113     if (pinDbV1->dbVersion != DB_VERSION_1) {
114         LOG_ERROR("read version %{public}u.", pinDbV1->dbVersion);
115         return false;
116     }
117     if (GetDataFromBuf(&temp, &tempLen, (uint8_t *)(&(pinDbV1->pinIndexLen)),
118         sizeof(pinDbV1->pinIndexLen)) != RESULT_SUCCESS) {
119         LOG_ERROR("read pinIndexLen fail.");
120         return false;
121     }
122     if (pinDbV1->pinIndexLen > MAX_CRYPTO_INFO_SIZE) {
123         LOG_ERROR("pinIndexLen too large.");
124         return false;
125     }
126     if (pinDbV1->pinIndexLen == 0) {
127         pinDbV1->pinIndex = NULL;
128         return true;
129     }
130     if (GetPinIndexV1(temp, tempLen, pinDbV1) != RESULT_SUCCESS) {
131         pinDbV1->pinIndexLen = 0;
132         LOG_ERROR("GetPinIndexV1 fail.");
133         return false;
134     }
135     return true;
136 }
137 
GetPinDbV1(uint8_t * data,uint32_t dataLen)138 void *GetPinDbV1(uint8_t *data, uint32_t dataLen)
139 {
140     PinDbV1 *pinDbV1 = Malloc(sizeof(PinDbV1));
141     if (pinDbV1 == NULL) {
142         LOG_ERROR("get pinDbV1 fail");
143         return NULL;
144     }
145     (void)memset_s(pinDbV1, sizeof(PinDbV1), 0, sizeof(PinDbV1));
146     if (data == NULL || dataLen == 0) {
147         LOG_INFO("no data provided");
148         pinDbV1->dbVersion = DB_VERSION_1;
149         return pinDbV1;
150     }
151     if (!UnpackPinDbV1(data, dataLen, pinDbV1)) {
152         LOG_ERROR("UnpackPinDbV1 fail");
153         FreePinDbV1((void **)(&pinDbV1));
154         return NULL;
155     }
156     return pinDbV1;
157 }
158 
FreePinDbV1(void ** pinDb)159 void FreePinDbV1(void **pinDb)
160 {
161     if (pinDb == NULL) {
162         return;
163     }
164     PinDbV1 *pinDbV1 = *pinDb;
165     if (pinDbV1 == NULL) {
166         return;
167     }
168     if (pinDbV1->pinIndex != NULL) {
169         Free(pinDbV1->pinIndex);
170     }
171     Free(*pinDb);
172     *pinDb = NULL;
173 }
174 
WritePinInfo(uint8_t * data,uint32_t dataLen,PinDbV1 * pinDbV1)175 static ResultCode WritePinInfo(uint8_t *data, uint32_t dataLen, PinDbV1 *pinDbV1)
176 {
177     if (pinDbV1->pinIndexLen == 0) {
178         LOG_INFO("no pin data.");
179         return RESULT_SUCCESS;
180     }
181     uint8_t *temp = data;
182     uint32_t tempLen = dataLen;
183     for (uint32_t i = 0; i < pinDbV1->pinIndexLen; i++) {
184         if (GetBufFromData((uint8_t *)(&(pinDbV1->pinIndex[i].pinInfo)), sizeof(pinDbV1->pinIndex[i].pinInfo),
185             &temp, &tempLen) != RESULT_SUCCESS) {
186             LOG_ERROR("write pin info fail.");
187             return RESULT_BAD_WRITE;
188         }
189     }
190     return RESULT_SUCCESS;
191 }
192 
IsPinDbValid(PinDbV1 * pinDb)193 static bool IsPinDbValid(PinDbV1 *pinDb)
194 {
195     if (pinDb == NULL) {
196         LOG_ERROR("pinDb is NULL");
197         return false;
198     }
199     if (pinDb->dbVersion != DB_VERSION_1) {
200         LOG_ERROR("Db version is %{public}u.", pinDb->dbVersion);
201         return false;
202     }
203     if ((pinDb->pinIndexLen == 0) && (pinDb->pinIndex != NULL)) {
204         LOG_ERROR("pinIndexLen is 0");
205         return false;
206     }
207     if ((pinDb->pinIndexLen != 0) && (pinDb->pinIndex == NULL)) {
208         LOG_ERROR("pinIndex is NULL");
209         return false;
210     }
211     if (pinDb->pinIndexLen > MAX_CRYPTO_INFO_SIZE) {
212         LOG_ERROR("the number of current users exceeds the maximum number of users");
213         return false;
214     }
215     return true;
216 }
217 
WritePinDbV1(void * pinDb)218 ResultCode WritePinDbV1(void *pinDb)
219 {
220     PinDbV1 *pinDbV1 = pinDb;
221     if (!IsPinDbValid(pinDbV1)) {
222         LOG_ERROR("get invalid params.");
223         return RESULT_BAD_PARAM;
224     }
225     FileOperator *fileOp = GetFileOperator(DEFAULT_FILE_OPERATOR);
226     if (!IsFileOperatorValid(fileOp)) {
227         LOG_ERROR("fileOp invalid.");
228         return RESULT_GENERAL_ERROR;
229     }
230 
231     uint32_t dataLen = sizeof(PinInfoV1) * pinDbV1->pinIndexLen + sizeof(uint32_t) * PIN_DB_TWO_PARAMS;
232     uint8_t *data = Malloc(dataLen);
233     if (data == NULL) {
234         LOG_ERROR("malloc data fail.");
235         return RESULT_GENERAL_ERROR;
236     }
237     (void)memset_s(data, dataLen, 0, dataLen);
238     ResultCode ret = RESULT_BAD_WRITE;
239     uint8_t *temp = data;
240     uint32_t tempLen = dataLen;
241     if (GetBufFromData((uint8_t *)(&(pinDbV1->dbVersion)), sizeof(pinDbV1->dbVersion),
242         &temp, &tempLen) != RESULT_SUCCESS) {
243         LOG_ERROR("get version fail.");
244         goto EXIT;
245     }
246 
247     if (GetBufFromData((uint8_t *)(&(pinDbV1->pinIndexLen)), sizeof(pinDbV1->pinIndexLen),
248         &temp, &tempLen) != RESULT_SUCCESS) {
249         LOG_ERROR("get index len fail.");
250         goto EXIT;
251     }
252     ret = WritePinInfo(temp, tempLen, pinDbV1);
253     if (ret != RESULT_SUCCESS) {
254         LOG_ERROR("WritePinInfo failed.");
255         goto EXIT;
256     }
257 
258     if ((ResultCode)fileOp->writeFile(PIN_INDEX_NAME, data, dataLen) != RESULT_SUCCESS) {
259         LOG_ERROR("write_parcel_into_file failed.");
260         ret = RESULT_BAD_WRITE;
261         goto EXIT;
262     }
263     LOG_INFO("WritePinDb succ.");
264     ret = RESULT_SUCCESS;
265 
266 EXIT:
267     (void)memset_s(data, dataLen, 0, dataLen);
268     Free(data);
269     return ret;
270 }