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