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 }