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