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 }