1 /*
2  * Copyright (c) 2021-2024 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_service_ipc_serialization.h"
17 
18 #include "hks_log.h"
19 #include "hks_mem.h"
20 #include "hks_template.h"
21 
CopyUint32ToBuffer(uint32_t value,const struct HksBlob * destBlob,uint32_t * destOffset)22 static int32_t CopyUint32ToBuffer(uint32_t value, const struct HksBlob *destBlob, uint32_t *destOffset)
23 {
24     if (*destOffset > destBlob->size) {
25         return HKS_ERROR_BUFFER_TOO_SMALL;
26     }
27 
28     if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &(value), sizeof(value)) != EOK) {
29         return HKS_ERROR_INSUFFICIENT_MEMORY;
30     }
31 
32     *destOffset += sizeof(value);
33     return HKS_SUCCESS;
34 }
35 
CopyBlobToBuffer(const struct HksBlob * blob,const struct HksBlob * destBlob,uint32_t * destOffset)36 static int32_t CopyBlobToBuffer(const struct HksBlob *blob, const struct HksBlob *destBlob, uint32_t *destOffset)
37 {
38     HKS_IF_NOT_SUCC_RETURN(CheckBlob(blob), HKS_ERROR_INVALID_ARGUMENT)
39 
40     if ((*destOffset > destBlob->size) ||
41         ((destBlob->size - *destOffset) < (sizeof(blob->size) + ALIGN_SIZE(blob->size)))) {
42         return HKS_ERROR_BUFFER_TOO_SMALL;
43     }
44 
45     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &(blob->size), sizeof(blob->size));
46 
47     *destOffset += sizeof(blob->size);
48 
49     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, blob->data, blob->size);
50 
51     *destOffset += ALIGN_SIZE(blob->size);
52     return HKS_SUCCESS;
53 }
54 
CopyParamSetToBuffer(const struct HksParamSet * paramSet,const struct HksBlob * destBlob,uint32_t * destOffset)55 static int32_t CopyParamSetToBuffer(const struct HksParamSet *paramSet,
56     const struct HksBlob *destBlob, uint32_t *destOffset)
57 {
58     HKS_IF_NULL_RETURN(paramSet, HKS_ERROR_INVALID_ARGUMENT)
59 
60     if ((*destOffset > destBlob->size) || (destBlob->size - *destOffset < ALIGN_SIZE(paramSet->paramSetSize))) {
61         return HKS_ERROR_BUFFER_TOO_SMALL;
62     }
63 
64     if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, paramSet, paramSet->paramSetSize) != EOK) {
65         return HKS_ERROR_INSUFFICIENT_MEMORY;
66     }
67 
68     *destOffset += ALIGN_SIZE(paramSet->paramSetSize);
69     return HKS_SUCCESS;
70 }
71 
GetUint32FromBuffer(uint32_t * value,const struct HksBlob * srcBlob,uint32_t * srcOffset)72 static int32_t GetUint32FromBuffer(uint32_t *value, const struct HksBlob *srcBlob, uint32_t *srcOffset)
73 {
74     if ((*srcOffset > srcBlob->size) || (srcBlob->size - *srcOffset < sizeof(uint32_t))) {
75         return HKS_ERROR_BUFFER_TOO_SMALL;
76     }
77 
78     (void)memcpy_s(value, sizeof(*value), srcBlob->data + *srcOffset, sizeof(uint32_t));
79 
80     *srcOffset += sizeof(uint32_t);
81     return HKS_SUCCESS;
82 }
83 
GetBlobFromBuffer(struct HksBlob * blob,const struct HksBlob * srcBlob,uint32_t * srcOffset)84 int32_t GetBlobFromBuffer(struct HksBlob *blob, const struct HksBlob *srcBlob, uint32_t *srcOffset)
85 {
86     if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(uint32_t))) {
87         return HKS_ERROR_BUFFER_TOO_SMALL;
88     }
89 
90     uint32_t size = *((uint32_t *)(srcBlob->data + *srcOffset));
91     if (IsAdditionOverflow(size, DEFAULT_ALIGN_MASK_SIZE)) {
92         return HKS_ERROR_INVALID_ARGUMENT;
93     }
94     if (ALIGN_SIZE(size) > srcBlob->size - *srcOffset - sizeof(uint32_t)) {
95         return HKS_ERROR_BUFFER_TOO_SMALL;
96     }
97 
98     blob->size = size;
99     *srcOffset += sizeof(blob->size);
100     blob->data = (uint8_t *)(srcBlob->data + *srcOffset);
101     *srcOffset += ALIGN_SIZE(blob->size);
102     return HKS_SUCCESS;
103 }
104 
GetParamSetFromBuffer(struct HksParamSet ** paramSet,const struct HksBlob * srcBlob,uint32_t * srcOffset)105 static int32_t GetParamSetFromBuffer(struct HksParamSet **paramSet,
106     const struct HksBlob *srcBlob, uint32_t *srcOffset)
107 {
108     if (*srcOffset > srcBlob->size || ((srcBlob->size - *srcOffset) < sizeof(struct HksParamSet))) {
109         return HKS_ERROR_INVALID_ARGUMENT;
110     }
111 
112     *paramSet = (struct HksParamSet*)(srcBlob->data + *srcOffset);
113     if (IsAdditionOverflow((*paramSet)->paramSetSize, DEFAULT_ALIGN_MASK_SIZE)) {
114         return HKS_ERROR_INVALID_ARGUMENT;
115     }
116     if (ALIGN_SIZE((*paramSet)->paramSetSize) > (srcBlob->size - *srcOffset) ||
117         HksFreshParamSet(*paramSet, false) != HKS_SUCCESS) {
118         return HKS_ERROR_BUFFER_TOO_SMALL;
119     }
120 
121     *srcOffset += ALIGN_SIZE((*paramSet)->paramSetSize);
122     return HKS_SUCCESS;
123 }
124 
GetKeyAndParamSetFromBuffer(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet,uint32_t * offset)125 static int32_t GetKeyAndParamSetFromBuffer(const struct HksBlob *srcData, struct HksBlob *keyAlias,
126     struct HksParamSet **paramSet, uint32_t *offset)
127 {
128     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, offset);
129     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
130 
131     ret = GetParamSetFromBuffer(paramSet, srcData, offset);
132     HKS_IF_NOT_SUCC_LOGE(ret, "get paramSet failed")
133 
134     return ret;
135 }
136 
MallocBlobFromBuffer(const struct HksBlob * srcData,struct HksBlob * blob,uint32_t * offset)137 static int32_t MallocBlobFromBuffer(const struct HksBlob *srcData, struct HksBlob *blob, uint32_t *offset)
138 {
139     uint32_t blobSize = 0;
140     int32_t ret = GetUint32FromBuffer(&blobSize, srcData, offset);
141     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get blobSize failed")
142 
143     if (IsInvalidLength(blobSize)) {
144         HKS_LOG_E("get blobSize failed");
145         return HKS_ERROR_INVALID_ARGUMENT;
146     }
147 
148     uint8_t *blobData = (uint8_t *)HksMalloc(blobSize);
149     HKS_IF_NULL_RETURN(blobData, HKS_ERROR_MALLOC_FAIL)
150 
151     blob->data = blobData;
152     blob->size = blobSize;
153     return HKS_SUCCESS;
154 }
155 
MallocParamSetFromBuffer(const struct HksBlob * srcData,struct HksParamSet ** paramSet,uint32_t * offset)156 static int32_t MallocParamSetFromBuffer(const struct HksBlob *srcData, struct HksParamSet **paramSet, uint32_t *offset)
157 {
158     uint32_t paramSetOutSize = 0;
159     int32_t ret = GetUint32FromBuffer(&paramSetOutSize, srcData, offset);
160     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSetOutSize failed")
161 
162     if (IsInvalidLength(paramSetOutSize) || paramSetOutSize < sizeof(struct HksParamSet)) {
163         HKS_LOG_E("get paramSetOutSize failed");
164         return HKS_ERROR_INVALID_ARGUMENT;
165     }
166 
167     *paramSet = (struct HksParamSet *)HksMalloc(paramSetOutSize);
168     HKS_IF_NULL_RETURN(*paramSet, HKS_ERROR_MALLOC_FAIL)
169 
170     (*paramSet)->paramSetSize = paramSetOutSize;
171     return HKS_SUCCESS;
172 }
173 
HksGenerateKeyUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSetIn,struct HksBlob * keyOut)174 int32_t HksGenerateKeyUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias,
175     struct HksParamSet **paramSetIn, struct HksBlob *keyOut)
176 {
177     uint32_t offset = 0;
178     int32_t ret = GetKeyAndParamSetFromBuffer(srcData, keyAlias, paramSetIn, &offset);
179     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetKeyAndParamSetFromBuffer failed")
180 
181     uint32_t keyOutSize = 0;
182     ret = GetUint32FromBuffer(&keyOutSize, srcData, &offset);
183     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyOutSize failed")
184 
185     if (keyOutSize > MAX_OUT_BLOB_SIZE) {
186         HKS_LOG_E("keyOutSize out of range %" LOG_PUBLIC "u", keyOutSize);
187         return HKS_ERROR_INVALID_ARGUMENT;
188     }
189 
190     /* no allocate memory when keyOutSize is 0 */
191     if (keyOutSize > 0) {
192         uint8_t *keyData = (uint8_t *)HksMalloc(keyOutSize);
193         HKS_IF_NULL_RETURN(keyData, HKS_ERROR_MALLOC_FAIL)
194 
195         keyOut->data = keyData;
196         keyOut->size = keyOutSize;
197     }
198 
199     return HKS_SUCCESS;
200 }
201 
HksImportKeyUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet,struct HksBlob * key)202 int32_t HksImportKeyUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias, struct HksParamSet **paramSet,
203     struct HksBlob *key)
204 {
205     uint32_t offset = 0;
206     int32_t ret = GetKeyAndParamSetFromBuffer(srcData, keyAlias, paramSet, &offset);
207     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetKeyAndParamSetFromBuffer failed")
208 
209     return GetBlobFromBuffer(key, srcData, &offset);
210 }
211 
HksImportWrappedKeyUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksBlob * wrappingKeyAlias,struct HksParamSet ** paramSet,struct HksBlob * wrappedKeyData)212 int32_t HksImportWrappedKeyUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias,
213     struct HksBlob *wrappingKeyAlias, struct HksParamSet **paramSet, struct HksBlob *wrappedKeyData)
214 {
215     uint32_t offset = 0;
216     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
217     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
218 
219     ret = GetBlobFromBuffer(wrappingKeyAlias, srcData, &offset);
220     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get wrappingKeyAlias failed")
221 
222     ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
223     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
224 
225     return GetBlobFromBuffer(wrappedKeyData, srcData, &offset);
226 }
227 
HksDeleteKeyUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet)228 int32_t HksDeleteKeyUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias, struct HksParamSet **paramSet)
229 {
230     uint32_t offset = 0;
231     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
232     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
233 
234     if (offset == srcData->size) {
235         return HKS_SUCCESS;
236     }
237 
238     ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
239     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
240 
241     return HKS_SUCCESS;
242 }
243 
HksExportPublicKeyUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet,struct HksBlob * key)244 int32_t HksExportPublicKeyUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias, struct HksParamSet **paramSet,
245     struct HksBlob *key)
246 {
247     uint32_t offset = 0;
248     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
249     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
250 
251     ret = MallocBlobFromBuffer(srcData, key, &offset);
252     HKS_IF_NOT_SUCC_LOGE(ret, "malloc key data failed")
253 
254     if (offset == srcData->size) {
255         return HKS_SUCCESS;
256     }
257 
258     ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
259     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
260     return ret;
261 }
262 
HksGetKeyParamSetUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSetIn,struct HksParamSet ** paramSetOut)263 int32_t HksGetKeyParamSetUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias,
264     struct HksParamSet **paramSetIn, struct HksParamSet **paramSetOut)
265 {
266     uint32_t offset = 0;
267     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
268     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
269 
270     ret = MallocParamSetFromBuffer(srcData, paramSetOut, &offset);
271     HKS_IF_NOT_SUCC_LOGE(ret, "malloc paramSet failed")
272 
273     if (offset == srcData->size) {
274         return HKS_SUCCESS;
275     }
276 
277     ret = GetParamSetFromBuffer(paramSetIn, srcData, &offset);
278     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
279     return ret;
280 }
281 
HksKeyExistUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet)282 int32_t HksKeyExistUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias, struct HksParamSet **paramSet)
283 {
284     uint32_t offset = 0;
285     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
286     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
287 
288     if (offset == srcData->size) {
289         return HKS_SUCCESS;
290     }
291 
292     ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
293     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
294 
295     return HKS_SUCCESS;
296 }
297 
SignVerifyMacUnpack(const struct HksBlob * srcData,struct HksBlob * key,struct HksParamSet ** paramSet,struct HksBlob * inputData,uint32_t * offset)298 static int32_t SignVerifyMacUnpack(const struct HksBlob *srcData, struct HksBlob *key, struct HksParamSet **paramSet,
299     struct HksBlob *inputData, uint32_t *offset)
300 {
301     int32_t ret = GetKeyAndParamSetFromBuffer(srcData, key, paramSet, offset);
302     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetKeyAndParamSetFromBuffer failed")
303 
304     ret = GetBlobFromBuffer(inputData, srcData, offset);
305     HKS_IF_NOT_SUCC_LOGE(ret, "get unsignedData failed")
306 
307     return ret;
308 }
309 
HksSignUnpack(const struct HksBlob * srcData,struct HksBlob * key,struct HksParamSet ** paramSet,struct HksBlob * unsignedData,struct HksBlob * signature)310 int32_t HksSignUnpack(const struct HksBlob *srcData, struct HksBlob *key, struct HksParamSet **paramSet,
311     struct HksBlob *unsignedData, struct HksBlob *signature)
312 {
313     uint32_t offset = 0;
314     int32_t ret = SignVerifyMacUnpack(srcData, key, paramSet, unsignedData, &offset);
315     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerifyMacUnpack failed")
316 
317     ret = MallocBlobFromBuffer(srcData, signature, &offset);
318     HKS_IF_NOT_SUCC_LOGE(ret, "malloc signature data failed")
319 
320     return ret;
321 }
322 
HksVerifyUnpack(const struct HksBlob * srcData,struct HksBlob * key,struct HksParamSet ** paramSet,struct HksBlob * unsignedData,struct HksBlob * signature)323 int32_t HksVerifyUnpack(const struct HksBlob *srcData, struct HksBlob *key, struct HksParamSet **paramSet,
324     struct HksBlob *unsignedData, struct HksBlob *signature)
325 {
326     uint32_t offset = 0;
327     int32_t ret = SignVerifyMacUnpack(srcData, key, paramSet, unsignedData, &offset);
328     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerifyMacUnpack failed")
329 
330     return GetBlobFromBuffer(signature, srcData, &offset);
331 }
332 
HksEncryptDecryptUnpack(const struct HksBlob * srcData,struct HksBlob * key,struct HksParamSet ** paramSet,struct HksBlob * inputText,struct HksBlob * outputText)333 int32_t HksEncryptDecryptUnpack(const struct HksBlob *srcData, struct HksBlob *key,
334     struct HksParamSet **paramSet, struct HksBlob *inputText, struct HksBlob *outputText)
335 {
336     uint32_t offset = 0;
337     int32_t ret = GetKeyAndParamSetFromBuffer(srcData, key, paramSet, &offset);
338     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "getKeyAndParamSetFromBuffer failed")
339 
340     ret = GetBlobFromBuffer(inputText, srcData, &offset);
341     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get inputText failed")
342 
343     ret = MallocBlobFromBuffer(srcData, outputText, &offset);
344     HKS_IF_NOT_SUCC_LOGE(ret, "malloc outputText data failed")
345 
346     return ret;
347 }
348 
HksAgreeKeyUnpack(const struct HksBlob * srcData,struct HksParamSet ** paramSet,struct HksBlob * privateKey,struct HksBlob * peerPublicKey,struct HksBlob * agreedKey)349 int32_t HksAgreeKeyUnpack(const struct HksBlob *srcData, struct HksParamSet **paramSet, struct HksBlob *privateKey,
350     struct HksBlob *peerPublicKey, struct HksBlob *agreedKey)
351 {
352     uint32_t offset = 0;
353     int32_t ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
354     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
355 
356     ret = GetBlobFromBuffer(privateKey, srcData, &offset);
357     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get privateKey failed")
358 
359     ret = GetBlobFromBuffer(peerPublicKey, srcData, &offset);
360     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get peerPublicKey failed")
361 
362     ret = MallocBlobFromBuffer(srcData, agreedKey, &offset);
363     HKS_IF_NOT_SUCC_LOGE(ret, "malloc agreedKey data failed")
364 
365     return ret;
366 }
367 
HksDeriveKeyUnpack(const struct HksBlob * srcData,struct HksParamSet ** paramSet,struct HksBlob * kdfKey,struct HksBlob * derivedKey)368 int32_t HksDeriveKeyUnpack(const struct HksBlob *srcData, struct HksParamSet **paramSet, struct HksBlob *kdfKey,
369     struct HksBlob *derivedKey)
370 {
371     uint32_t offset = 0;
372     int32_t ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
373     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
374 
375     ret = GetBlobFromBuffer(kdfKey, srcData, &offset);
376     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get kdfKey failed")
377 
378     ret = MallocBlobFromBuffer(srcData, derivedKey, &offset);
379     HKS_IF_NOT_SUCC_LOGE(ret, "malloc derivedKey data failed")
380 
381     return ret;
382 }
383 
HksHmacUnpack(const struct HksBlob * srcData,struct HksBlob * key,struct HksParamSet ** paramSet,struct HksBlob * inputData,struct HksBlob * mac)384 int32_t HksHmacUnpack(const struct HksBlob *srcData, struct HksBlob *key, struct HksParamSet **paramSet,
385     struct HksBlob *inputData, struct HksBlob *mac)
386 {
387     uint32_t offset = 0;
388     int32_t ret = SignVerifyMacUnpack(srcData, key, paramSet, inputData, &offset);
389     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerifyMacUnpack failed")
390 
391     ret = MallocBlobFromBuffer(srcData, mac, &offset);
392     HKS_IF_NOT_SUCC_LOGE(ret, "malloc mac data failed")
393 
394     return ret;
395 }
396 
KeyInfoListInit(struct HksKeyInfo * keyInfoList,uint32_t listCount,const struct HksBlob * srcData,uint32_t * offset)397 static int32_t KeyInfoListInit(struct HksKeyInfo *keyInfoList, uint32_t listCount,
398     const struct HksBlob *srcData, uint32_t *offset)
399 {
400     uint32_t i = 0;
401     int32_t ret = HKS_SUCCESS;
402     for (; i < listCount; ++i) {
403         ret = MallocBlobFromBuffer(srcData, &keyInfoList[i].alias, offset);
404         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "malloc keyInfoList alias failed")
405 
406         ret = MallocParamSetFromBuffer(srcData, &keyInfoList[i].paramSet, offset);
407         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "malloc keyInfoList paramSetSize failed")
408     }
409 
410     if (ret != HKS_SUCCESS) {
411         for (uint32_t j = 0; j <= i; ++j) {
412             HKS_FREE_BLOB(keyInfoList[j].alias);
413             HKS_FREE(keyInfoList[j].paramSet);
414         }
415     }
416     return ret;
417 }
418 
HksGetKeyInfoListUnpack(const struct HksBlob * srcData,struct HksParamSet ** paramSet,uint32_t * listCount,struct HksKeyInfo ** keyInfoList)419 int32_t HksGetKeyInfoListUnpack(const struct HksBlob *srcData, struct HksParamSet **paramSet, uint32_t *listCount,
420     struct HksKeyInfo **keyInfoList)
421 {
422     uint32_t offset = 0;
423     int32_t ret = GetUint32FromBuffer(listCount, srcData, &offset);
424     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get count failed")
425 
426     enum {
427         HKS_GET_KEY_LIST_MAX_COUNT = 2048U,
428     };
429     if (*listCount == 0 || *listCount > HKS_GET_KEY_LIST_MAX_COUNT) {
430         HKS_LOG_E("invalid listCount %" LOG_PUBLIC "u", *listCount);
431         return HKS_ERROR_INSUFFICIENT_MEMORY;
432     }
433 
434     uint32_t keyInfoListSize = (*listCount) * sizeof(struct HksKeyInfo);
435     if (IsInvalidLength(keyInfoListSize)) {
436         HKS_LOG_E("keyInfoListSize too big %" LOG_PUBLIC "u", keyInfoListSize);
437         return HKS_ERROR_INSUFFICIENT_MEMORY;
438     }
439 
440     *keyInfoList = (struct HksKeyInfo *)HksMalloc(keyInfoListSize);
441     HKS_IF_NULL_LOGE_RETURN(*keyInfoList, HKS_ERROR_MALLOC_FAIL, "*keyInfoList is NULL")
442 
443     (void)memset_s(*keyInfoList, keyInfoListSize, 0, keyInfoListSize);
444 
445     ret = KeyInfoListInit(*keyInfoList, *listCount, srcData, &offset);
446     if (ret != HKS_SUCCESS) {
447         HKS_LOG_E("KeyInfoListInit failed");
448         HKS_FREE(*keyInfoList);
449     }
450 
451     if (offset == srcData->size) {
452         return HKS_SUCCESS;
453     }
454 
455     ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
456     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
457     return ret;
458 }
459 
HksGetKeyInfoListPackFromService(struct HksBlob * destData,uint32_t listCount,const struct HksKeyInfo * keyInfoList)460 int32_t HksGetKeyInfoListPackFromService(struct HksBlob *destData, uint32_t listCount,
461     const struct HksKeyInfo *keyInfoList)
462 {
463     uint32_t offset = 0;
464     int32_t ret = CopyUint32ToBuffer(listCount, destData, &offset);
465     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy CopyUint32ToBuffer failed")
466 
467     for (uint32_t i = 0; i < listCount; ++i) {
468         ret = CopyBlobToBuffer(&keyInfoList[i].alias, destData, &offset);
469         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy alias failed")
470 
471         ret = CopyParamSetToBuffer(keyInfoList[i].paramSet, destData, &offset);
472         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
473     }
474 
475     return HKS_SUCCESS;
476 }
477 
HksCertificateChainUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** paramSet,struct HksBlob * certChainBlob)478 int32_t HksCertificateChainUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias,
479     struct HksParamSet **paramSet, struct HksBlob *certChainBlob)
480 {
481     uint32_t offset = 0;
482     int32_t ret = GetKeyAndParamSetFromBuffer(srcData, keyAlias, paramSet, &offset);
483     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetKeyAndParamSetFromBuffer failed")
484 
485     ret = MallocBlobFromBuffer(srcData, certChainBlob, &offset);
486     HKS_IF_NOT_SUCC_LOGE(ret, "malloc certChainBlob data failed")
487 
488     return ret;
489 }
490 
GetNullBlobParam(const struct HksParamSet * paramSet,struct HksParamOut * outParams)491 static int32_t GetNullBlobParam(const struct HksParamSet *paramSet, struct HksParamOut *outParams)
492 {
493     if (GetTagType(outParams->tag) != HKS_TAG_TYPE_BYTES) {
494         HKS_LOG_E("get param tag[0x%" LOG_PUBLIC "x] from ipc buffer failed", outParams->tag);
495         return HKS_ERROR_PARAM_NOT_EXIST;
496     }
497 
498     struct HksParam *param = NULL;
499     int32_t ret = HksGetParam(paramSet, outParams->tag + HKS_PARAM_BUFFER_NULL_INTERVAL, &param);
500     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get param tag[0x%" LOG_PUBLIC "x] from ipc buffer failed",
501             outParams->tag + HKS_PARAM_BUFFER_NULL_INTERVAL)
502 
503     outParams->blob->data = NULL;
504     outParams->blob->size = 0;
505     return HKS_SUCCESS;
506 }
507 
GetNormalParam(const struct HksParam * param,struct HksParamOut * outParams)508 static int32_t GetNormalParam(const struct HksParam *param, struct HksParamOut *outParams)
509 {
510     switch (GetTagType(outParams->tag)) {
511         case HKS_TAG_TYPE_INT:
512             *(outParams->int32Param) = param->int32Param;
513             break;
514         case HKS_TAG_TYPE_UINT:
515             *(outParams->uint32Param) = param->uint32Param;
516             break;
517         case HKS_TAG_TYPE_ULONG:
518             *(outParams->uint64Param) = param->uint64Param;
519             break;
520         case HKS_TAG_TYPE_BOOL:
521             *(outParams->boolParam) = param->boolParam;
522             break;
523         case HKS_TAG_TYPE_BYTES:
524             *(outParams->blob) = param->blob;
525             break;
526         default:
527             HKS_LOG_I("invalid tag type:%" LOG_PUBLIC "x", GetTagType(outParams->tag));
528             return HKS_ERROR_INVALID_ARGUMENT;
529     }
530     return HKS_SUCCESS;
531 }
532 
HksParamSetToParams(const struct HksParamSet * paramSet,struct HksParamOut * outParams,uint32_t cnt)533 int32_t HksParamSetToParams(const struct HksParamSet *paramSet, struct HksParamOut *outParams, uint32_t cnt)
534 {
535     struct HksParam *param = NULL;
536     for (uint32_t i = 0; i < cnt; i++) {
537         int32_t ret = HksGetParam(paramSet, outParams[i].tag, &param);
538         if (ret == HKS_SUCCESS) {
539             ret = GetNormalParam(param, &outParams[i]);
540         } else {
541             ret = GetNullBlobParam(paramSet, &outParams[i]);
542         }
543         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get param failed, ret = %" LOG_PUBLIC "d", ret)
544     }
545     return HKS_SUCCESS;
546 }
547 
HksListAliasesUnpack(const struct HksBlob * srcData,struct HksParamSet ** paramSet)548 int32_t HksListAliasesUnpack(const struct HksBlob *srcData, struct HksParamSet **paramSet)
549 {
550     uint32_t offset = 0;
551     int32_t ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
552     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
553     return ret;
554 }
555 
HksCopyBlobsAndCntToBlob(const struct HksBlob * srcBlob,uint32_t cnt,struct HksBlob * destBlob)556 static int32_t HksCopyBlobsAndCntToBlob(const struct HksBlob *srcBlob, uint32_t cnt, struct HksBlob *destBlob)
557 {
558     uint32_t offset = 0;
559     int32_t ret = CopyUint32ToBuffer(cnt, destBlob, &offset);
560     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy CopyUint32ToBuffer failed, ret = %" LOG_PUBLIC "d", ret)
561 
562     for (uint32_t i = 0; i < cnt; ++i) {
563         ret = CopyBlobToBuffer(&srcBlob[i], destBlob, &offset);
564         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy CopyBlobToBuffer failed")
565     }
566     return HKS_SUCCESS;
567 }
568 
HksListAliasesPackFromService(const struct HksKeyAliasSet * aliasSet,struct HksBlob * destData)569 int32_t HksListAliasesPackFromService(const struct HksKeyAliasSet *aliasSet, struct HksBlob *destData)
570 {
571     if (destData == NULL || destData->size != 0) {
572         HKS_LOG_E("HksListAliasesPackFromService invalid param");
573         return HKS_ERROR_INVALID_ARGUMENT;
574     }
575     if (aliasSet == NULL || aliasSet->aliasesCnt == 0) {
576         return HKS_SUCCESS;
577     }
578 
579     destData->size = sizeof(aliasSet->aliasesCnt);
580     for (uint32_t i = 0; i < aliasSet->aliasesCnt; ++i) {
581         destData->size += sizeof(aliasSet->aliases[i].size) + ALIGN_SIZE(aliasSet->aliases[i].size);
582     }
583     destData->data = (uint8_t *)HksMalloc(destData->size);
584     HKS_IF_NULL_RETURN(destData->data, HKS_ERROR_MALLOC_FAIL)
585 
586     return HksCopyBlobsAndCntToBlob(aliasSet->aliases, aliasSet->aliasesCnt, destData);
587 }
588 
HksRenameKeyAliasUnpack(const struct HksBlob * srcData,struct HksBlob * oldKeyAlias,struct HksBlob * newKeyAlias,struct HksParamSet ** paramSet)589 int32_t HksRenameKeyAliasUnpack(const struct HksBlob *srcData, struct HksBlob *oldKeyAlias,
590     struct HksBlob *newKeyAlias, struct HksParamSet **paramSet)
591 {
592     uint32_t offset = 0;
593     int32_t ret;
594     do {
595         ret = GetBlobFromBuffer(oldKeyAlias, srcData, &offset);
596         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get oldKeyAlias failed!");
597 
598         ret = GetBlobFromBuffer(newKeyAlias, srcData, &offset);
599         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get newKeyAlias failed!");
600 
601         ret = GetParamSetFromBuffer(paramSet, srcData, &offset);
602         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get paramSet failed!");
603     } while (0);
604     return ret;
605 }
606 
HksChangeStorageLevelUnpack(const struct HksBlob * srcData,struct HksBlob * keyAlias,struct HksParamSet ** srcParamSet,struct HksParamSet ** destParamSet)607 int32_t HksChangeStorageLevelUnpack(const struct HksBlob *srcData, struct HksBlob *keyAlias,
608     struct HksParamSet **srcParamSet, struct HksParamSet **destParamSet)
609 {
610     uint32_t offset = 0;
611     int32_t ret = GetBlobFromBuffer(keyAlias, srcData, &offset);
612     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyAlias failed")
613 
614     ret = GetParamSetFromBuffer(srcParamSet, srcData, &offset);
615     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get srcParamSet failed")
616 
617     ret = GetParamSetFromBuffer(destParamSet, srcData, &offset);
618     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get destParamSet failed")
619 
620     return HKS_SUCCESS;
621 }