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