1 /*
2 * Copyright (c) 2022 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 "hks_test_adapt_for_de.h"
17 #include "hks_three_stage_test_common.h"
18
InitParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramcount)19 int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramcount)
20 {
21 int32_t ret = HksInitParamSet(paramSet);
22 if (ret != HKS_SUCCESS) {
23 HKS_LOG_E("HksInitParamSet failed");
24 return ret;
25 }
26
27 ret = HksAddParams(*paramSet, params, paramcount);
28 if (ret != HKS_SUCCESS) {
29 HksFreeParamSet(paramSet);
30 return ret;
31 }
32
33 ret = HksBuildParamSet(paramSet);
34 if (ret != HKS_SUCCESS) {
35 HksFreeParamSet(paramSet);
36 return ret;
37 }
38
39 return ret;
40 }
41
TestLessThanMaxSeg(const struct HksBlob * handle,const struct HksParamSet * paramSet,uint32_t purpose,const struct HksBlob * inData,struct HksBlob * outData)42 static int32_t TestLessThanMaxSeg(const struct HksBlob *handle, const struct HksParamSet *paramSet,
43 uint32_t purpose, const struct HksBlob *inData, struct HksBlob *outData)
44 {
45 struct HksBlob tmpOutData = {
46 .size = MAX_OUTDATA_SIZE,
47 .data = NULL
48 };
49 if (MallocAndCheckBlobData(&tmpOutData, tmpOutData.size) != HKS_SUCCESS) {
50 return HKS_FAILURE;
51 }
52 int32_t ret = HksUpdateForDe(handle, paramSet, inData, &tmpOutData);
53 HKS_FREE(tmpOutData.data);
54 if (ret != HKS_SUCCESS) {
55 return HKS_FAILURE;
56 }
57 struct HksBlob tmpInData = {
58 .size = 0,
59 .data = NULL
60 };
61 if (MallocAndCheckBlobData(&tmpInData, MAX_UPDATE_SIZE) != HKS_SUCCESS) {
62 return HKS_FAILURE;
63 }
64
65 if (purpose == HKS_KEY_PURPOSE_VERIFY) {
66 ret = HksFinishForDe(handle, paramSet, outData, &tmpInData);
67 } else {
68 ret = HksFinishForDe(handle, paramSet, &tmpInData, outData);
69 }
70 HKS_FREE(tmpInData.data);
71 if (ret != HKS_SUCCESS) {
72 return HKS_FAILURE;
73 }
74 return HKS_SUCCESS;
75 }
76
HksTestUpdate(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData)77 int32_t HksTestUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, const struct HksBlob *inData)
78 {
79 struct HksBlob inDataSeg = *inData;
80 inDataSeg.size = MAX_UPDATE_SIZE;
81
82 uint8_t *lastPtr = inData->data + inData->size - 1;
83 struct HksBlob outDataSeg = {
84 .size = MAX_OUTDATA_SIZE,
85 .data = NULL
86 };
87
88 bool isFinished = false;
89
90 while (inDataSeg.data <= lastPtr) {
91 if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
92 outDataSeg.size = MAX_OUTDATA_SIZE;
93 } else {
94 isFinished = true;
95 inDataSeg.size = lastPtr - inDataSeg.data + 1;
96 outDataSeg.size = inDataSeg.size + MAX_UPDATE_SIZE;
97 }
98 if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
99 return HKS_FAILURE;
100 }
101 if (HksUpdateForDe(handle, paramSet, &inDataSeg, &outDataSeg) != HKS_SUCCESS) {
102 HKS_LOG_E("HksUpdate Failed.");
103 HKS_FREE(outDataSeg.data);
104 return HKS_FAILURE;
105 }
106 HKS_FREE(outDataSeg.data);
107 if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
108 return HKS_SUCCESS;
109 }
110 inDataSeg.data += MAX_UPDATE_SIZE;
111 }
112 return HKS_SUCCESS;
113 }
114
TestBatchUpdateLoopFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)115 int32_t TestBatchUpdateLoopFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
116 const struct HksBlob *inData, struct HksBlob *outData)
117 {
118 struct HksBlob inDataSeg = *inData;
119 uint8_t *lastPtr = inData->data + inData->size - 1;
120 struct HksBlob outDataSeg = { MAX_OUTDATA_SIZE, NULL };
121 uint8_t *cur = outData->data;
122 uint32_t curSize = outData->size;
123 outData->size = 0;
124
125 inDataSeg.size = MAX_UPDATE_SIZE;
126
127 bool isFinished = false;
128
129 isFinished = true;
130 inDataSeg.size = lastPtr - inDataSeg.data + 1;
131
132 if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
133 return HKS_FAILURE;
134 }
135
136 int32_t ret = HksUpdateForDe(handle, paramSet, &inDataSeg, &outDataSeg);
137 if (ret != HKS_SUCCESS) {
138 HKS_LOG_E("HksUpdate Failed.");
139 HKS_FREE(outDataSeg.data);
140 return ret;
141 }
142 (void)memcpy_s(cur, outDataSeg.size, outDataSeg.data, outDataSeg.size);
143 cur += outDataSeg.size;
144 outData->size += outDataSeg.size;
145 HKS_FREE(outDataSeg.data);
146 if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
147 return HKS_FAILURE;
148 }
149 inDataSeg.data += MAX_UPDATE_SIZE;
150
151 struct HksBlob outDataFinish = { inDataSeg.size * TIMES, NULL };
152 if (MallocAndCheckBlobData(&outDataFinish, outDataFinish.size) != HKS_SUCCESS) {
153 return HKS_FAILURE;
154 }
155
156 if (HksFinishForDe(handle, paramSet, &inDataSeg, &outDataFinish) != HKS_SUCCESS) {
157 HKS_FREE(outDataFinish.data);
158 return HKS_FAILURE;
159 }
160
161 if (memcpy_s(cur, curSize, outDataFinish.data, outDataFinish.size) != EOK) {
162 HKS_FREE(outDataFinish.data);
163 return HKS_ERROR_BUFFER_TOO_SMALL;
164 }
165 outData->size += outDataFinish.size;
166 HKS_FREE(outDataFinish.data);
167
168 return HKS_SUCCESS;
169 }
170
TestUpdateLoopFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)171 int32_t TestUpdateLoopFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
172 const struct HksBlob *inData, struct HksBlob *outData)
173 {
174 struct HksBlob inDataSeg = *inData;
175 uint8_t *lastPtr = inData->data + inData->size - 1;
176 struct HksBlob outDataSeg = { MAX_OUTDATA_SIZE, NULL };
177 uint8_t *cur = outData->data;
178 uint32_t curSize = outData->size;
179 outData->size = 0;
180
181 inDataSeg.size = MAX_UPDATE_SIZE;
182
183 bool isFinished = false;
184
185 while (inDataSeg.data <= lastPtr) {
186 if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
187 outDataSeg.size = MAX_OUTDATA_SIZE;
188 } else {
189 isFinished = true;
190 inDataSeg.size = lastPtr - inDataSeg.data + 1;
191 break;
192 }
193 if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
194 return HKS_FAILURE;
195 }
196 if (HksUpdateForDe(handle, paramSet, &inDataSeg, &outDataSeg) != HKS_SUCCESS) {
197 HKS_LOG_E("HksUpdate Failed.");
198 HKS_FREE(outDataSeg.data);
199 return HKS_FAILURE;
200 }
201 (void)memcpy_s(cur, outDataSeg.size, outDataSeg.data, outDataSeg.size);
202 cur += outDataSeg.size;
203 outData->size += outDataSeg.size;
204 HKS_FREE(outDataSeg.data);
205 if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
206 return HKS_FAILURE;
207 }
208 inDataSeg.data += MAX_UPDATE_SIZE;
209 }
210
211 struct HksBlob outDataFinish = { inDataSeg.size * TIMES, NULL };
212 if (MallocAndCheckBlobData(&outDataFinish, outDataFinish.size) != HKS_SUCCESS) {
213 return HKS_FAILURE;
214 }
215
216 if (HksFinishForDe(handle, paramSet, &inDataSeg, &outDataFinish) != HKS_SUCCESS) {
217 HKS_FREE(outDataFinish.data);
218 return HKS_FAILURE;
219 }
220
221 if (memcpy_s(cur, curSize, outDataFinish.data, outDataFinish.size) != EOK) {
222 HKS_FREE(outDataFinish.data);
223 return HKS_ERROR_BUFFER_TOO_SMALL;
224 }
225 outData->size += outDataFinish.size;
226 HKS_FREE(outDataFinish.data);
227
228 return HKS_SUCCESS;
229 }
230
TestUpdateFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,uint32_t purpose,const struct HksBlob * inData,struct HksBlob * outData)231 int32_t TestUpdateFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
232 uint32_t purpose, const struct HksBlob *inData, struct HksBlob *outData)
233 {
234 struct HksBlob inDataSeg = *inData;
235 inDataSeg.size = MAX_UPDATE_SIZE;
236
237 uint8_t *lastPtr = inData->data + inData->size - 1;
238 struct HksBlob outDataSeg = { MAX_OUTDATA_SIZE, NULL };
239
240 bool isFinished = false;
241
242 if (inData->size <= MAX_UPDATE_SIZE) {
243 return TestLessThanMaxSeg(handle, paramSet, purpose, inData, outData);
244 }
245
246 while (inDataSeg.data <= lastPtr) {
247 if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
248 outDataSeg.size = MAX_OUTDATA_SIZE;
249 if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
250 return HKS_FAILURE;
251 }
252 } else {
253 isFinished = true;
254 inDataSeg.size = lastPtr - inDataSeg.data + 1;
255 break;
256 }
257 if (HksUpdateForDe(handle, paramSet, &inDataSeg, &outDataSeg) != HKS_SUCCESS) {
258 HKS_LOG_E("HksUpdate Failed.");
259 HKS_FREE(outDataSeg.data);
260 return HKS_FAILURE;
261 }
262 HKS_FREE(outDataSeg.data);
263 if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
264 return HKS_FAILURE;
265 }
266 inDataSeg.data += MAX_UPDATE_SIZE;
267 }
268
269 if (purpose != HKS_KEY_PURPOSE_VERIFY) {
270 if (HksFinishForDe(handle, paramSet, &inDataSeg, outData) != HKS_SUCCESS) {
271 HKS_LOG_E("HksFinish Failed.");
272 return HKS_FAILURE;
273 }
274 } else {
275 uint8_t tmp[] = "temp";
276 struct HksBlob tempBlob = { sizeof(tmp), tmp };
277 if (HksUpdateForDe(handle, paramSet, &inDataSeg, &tempBlob) != HKS_SUCCESS) {
278 HKS_LOG_E("HksUpdate Failed.");
279 return HKS_FAILURE;
280 }
281 if (HksFinishForDe(handle, paramSet, outData, &tempBlob) != HKS_SUCCESS) {
282 HKS_LOG_E("HksFinish Failed.");
283 return HKS_FAILURE;
284 }
285 }
286 return HKS_SUCCESS;
287 }
288
MallocAndCheckBlobData(struct HksBlob * blob,const uint32_t blobSize)289 int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize)
290 {
291 blob->data = (uint8_t *)HksMalloc(blobSize);
292 if (blob->data == NULL) {
293 HKS_LOG_E("could not alloc memory");
294 return HKS_FAILURE;
295 }
296 return HKS_SUCCESS;
297 }
298
TestCmpKeyAliasHash(const struct HksBlob * srcData1,const struct HksBlob * srcData2)299 int32_t TestCmpKeyAliasHash(const struct HksBlob *srcData1, const struct HksBlob *srcData2)
300 {
301 struct HksParam hashParam = {
302 .tag = HKS_TAG_DIGEST,
303 .uint32Param = HKS_DIGEST_SHA256
304 };
305 struct HksParamSet *hashParamSet = NULL;
306 int32_t ret = InitParamSet(&hashParamSet, &hashParam, sizeof(hashParam) / sizeof(struct HksParam));
307 if (ret != HKS_SUCCESS) {
308 return HKS_FAILURE;
309 }
310
311 struct HksBlob hash1 = { MAX_OUTDATA_SIZE, NULL };
312 if (MallocAndCheckBlobData(&hash1, hash1.size) != HKS_SUCCESS) {
313 HksFreeParamSet(&hashParamSet);
314 return HKS_FAILURE;
315 }
316 ret = HksHash(hashParamSet, srcData1, &hash1);
317 if (ret != HKS_SUCCESS) {
318 HksFreeParamSet(&hashParamSet);
319 HKS_FREE(hash1.data);
320 return HKS_FAILURE;
321 }
322
323 struct HksBlob hash2 = { MAX_OUTDATA_SIZE, NULL };
324 if (MallocAndCheckBlobData(&hash2, hash2.size) != HKS_SUCCESS) {
325 HKS_FREE(hash1.data);
326 HksFreeParamSet(&hashParamSet);
327 return HKS_FAILURE;
328 }
329 ret = HksHash(hashParamSet, srcData2, &hash2);
330 if (ret != HKS_SUCCESS) {
331 HksFreeParamSet(&hashParamSet);
332 HKS_FREE(hash1.data);
333 HKS_FREE(hash2.data);
334 return HKS_FAILURE;
335 }
336
337 ret = HksMemCmp(hash1.data, hash2.data, hash2.size);
338 HksFreeParamSet(&hashParamSet);
339 HKS_FREE(hash1.data);
340 HKS_FREE(hash2.data);
341
342 return ret;
343 }
344