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