• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_ipc_serialization.h"
17 
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21 
22 #include "hks_log.h"
23 #include "hks_mem.h"
24 #include "hks_param.h"
25 #include "hks_template.h"
26 #include "securec.h"
27 
28 #define NUM_TWO        2
29 
30 static const uint8_t g_base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31 
CopyUint32ToBuffer(uint32_t value,const struct HksBlob * destBlob,uint32_t * destOffset)32 int32_t CopyUint32ToBuffer(uint32_t value, const struct HksBlob *destBlob, uint32_t *destOffset)
33 {
34     if ((*destOffset > destBlob->size) || ((destBlob->size - *destOffset) < sizeof(value))) {
35         return HKS_ERROR_BUFFER_TOO_SMALL;
36     }
37 
38     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &value, sizeof(value));
39     *destOffset += sizeof(value);
40 
41     return HKS_SUCCESS;
42 }
43 
CopyBlobToBuffer(const struct HksBlob * blob,const struct HksBlob * destBlob,uint32_t * destOffset)44 static int32_t CopyBlobToBuffer(const struct HksBlob *blob, const struct HksBlob *destBlob, uint32_t *destOffset)
45 {
46     if ((*destOffset > destBlob->size) ||
47         ((destBlob->size - *destOffset) < (sizeof(blob->size) + ALIGN_SIZE(blob->size)))) {
48         return HKS_ERROR_BUFFER_TOO_SMALL;
49     }
50 
51     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &(blob->size), sizeof(blob->size));
52     *destOffset += sizeof(blob->size);
53 
54     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, blob->data, blob->size);
55     *destOffset += ALIGN_SIZE(blob->size);
56 
57     return HKS_SUCCESS;
58 }
59 
CopyParamSetToBuffer(const struct HksParamSet * paramSet,const struct HksBlob * destBlob,uint32_t * destOffset)60 static int32_t CopyParamSetToBuffer(const struct HksParamSet *paramSet,
61     const struct HksBlob *destBlob, uint32_t *destOffset)
62 {
63     if ((*destOffset > destBlob->size) || (destBlob->size - *destOffset < ALIGN_SIZE(paramSet->paramSetSize))) {
64         return HKS_ERROR_BUFFER_TOO_SMALL;
65     }
66 
67     (void)memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, paramSet, paramSet->paramSetSize);
68     *destOffset += ALIGN_SIZE(paramSet->paramSetSize);
69 
70     return HKS_SUCCESS;
71 }
72 
GetUint32FromBuffer(uint32_t * value,const struct HksBlob * srcBlob,uint32_t * srcOffset)73 static int32_t GetUint32FromBuffer(uint32_t *value, const struct HksBlob *srcBlob, uint32_t *srcOffset)
74 {
75     if ((*srcOffset > srcBlob->size) || (srcBlob->size - *srcOffset < sizeof(*value))) {
76         return HKS_ERROR_BUFFER_TOO_SMALL;
77     }
78 
79     *value = *((uint32_t *)(srcBlob->data + *srcOffset));
80     *srcOffset += sizeof(*value);
81     return HKS_SUCCESS;
82 }
83 
GetBlobFromBuffer(struct HksBlob * blob,const struct HksBlob * srcBlob,uint32_t * srcOffset)84 static int32_t GetBlobFromBuffer(struct HksBlob *blob, const struct HksBlob *srcBlob, uint32_t *srcOffset)
85 {
86     if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(blob->size))) {
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(blob->size))) {
95         return HKS_ERROR_BUFFER_TOO_SMALL;
96     }
97     blob->size = size;
98     *srcOffset += sizeof(blob->size);
99     blob->data = (uint8_t *)(srcBlob->data + *srcOffset);
100     *srcOffset += ALIGN_SIZE(blob->size);
101 
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_BUFFER_TOO_SMALL;
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         return HKS_ERROR_BUFFER_TOO_SMALL;
118     }
119     *srcOffset += ALIGN_SIZE((*paramSet)->paramSetSize);
120 
121     return HKS_SUCCESS;
122 }
123 
HksGenerateKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn,const struct HksBlob * keyOut)124 int32_t HksGenerateKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
125     const struct HksParamSet *paramSetIn, const struct HksBlob *keyOut)
126 {
127     uint32_t offset = 0;
128     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
129     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
130 
131     ret = CopyParamSetToBuffer(paramSetIn, destData, &offset);
132     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSetIn failed")
133     return CopyUint32ToBuffer(keyOut->size, destData, &offset);
134 }
135 
HksImportKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)136 int32_t HksImportKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
137     const struct HksBlob *key)
138 {
139     uint32_t offset = 0;
140     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
141     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
142 
143     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
144     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
145     return CopyBlobToBuffer(key, destData, &offset);
146 }
147 
HksImportWrappedKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksBlob * wrappingKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKeyData)148 int32_t HksImportWrappedKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
149     const struct HksBlob *wrappingKeyAlias, const struct HksParamSet *paramSet, const struct HksBlob *wrappedKeyData)
150 {
151     uint32_t offset = 0;
152     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
153     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
154 
155     ret = CopyBlobToBuffer(wrappingKeyAlias, destData, &offset);
156     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy wrappingKeyAlias failed")
157 
158     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
159     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
160     return CopyBlobToBuffer(wrappedKeyData, destData, &offset);
161 }
162 
HksExportPublicKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksBlob * key)163 int32_t HksExportPublicKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias, const struct HksBlob *key)
164 {
165     uint32_t offset = 0;
166     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
167     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
168     return CopyUint32ToBuffer(key->size, destData, &offset);
169 }
170 
HksGetKeyParamSetPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksBlob * keyOut)171 int32_t HksGetKeyParamSetPack(struct HksBlob *destData, const struct HksBlob *keyAlias, const struct HksBlob *keyOut)
172 {
173     uint32_t offset = 0;
174     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
175     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
176     return CopyUint32ToBuffer(keyOut->size, destData, &offset);
177 }
178 
HksOnceParamPack(struct HksBlob * destData,const struct HksBlob * key,const struct HksParamSet * paramSet,uint32_t * offset)179 int32_t HksOnceParamPack(struct HksBlob *destData, const struct HksBlob *key, const struct HksParamSet *paramSet,
180     uint32_t *offset)
181 {
182     int32_t ret = CopyBlobToBuffer(key, destData, offset);
183     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy key failed")
184 
185     return CopyParamSetToBuffer(paramSet, destData, offset);
186 }
187 
HksOnceDataPack(struct HksBlob * destData,const struct HksBlob * inputData,const struct HksBlob * rsvData,const struct HksBlob * outputData,uint32_t * offset)188 int32_t HksOnceDataPack(struct HksBlob *destData, const struct HksBlob *inputData, const struct HksBlob *rsvData,
189     const struct HksBlob *outputData, uint32_t *offset)
190 {
191     int32_t ret = CopyBlobToBuffer(inputData, destData, offset);
192     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy inputData failed")
193 
194     if (rsvData != NULL) {
195         ret = CopyBlobToBuffer(rsvData, destData, offset);
196         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy rsvData failed")
197     }
198 
199     if (outputData != NULL) {
200         ret = CopyUint32ToBuffer(outputData->size, destData, offset);
201     }
202     return ret;
203 }
204 
HksAgreeKeyPack(struct HksBlob * destData,const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,const struct HksBlob * agreedKey)205 int32_t HksAgreeKeyPack(struct HksBlob *destData, const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
206     const struct HksBlob *peerPublicKey, const struct HksBlob *agreedKey)
207 {
208     uint32_t offset = 0;
209     int32_t ret = CopyParamSetToBuffer(paramSet, destData, &offset);
210     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
211 
212     ret = CopyBlobToBuffer(privateKey, destData, &offset);
213     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy privateKey failed")
214 
215     ret = CopyBlobToBuffer(peerPublicKey, destData, &offset);
216     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy peerPublicKey failed")
217     return CopyUint32ToBuffer(agreedKey->size, destData, &offset);
218 }
219 
HksDeriveKeyPack(struct HksBlob * destData,const struct HksParamSet * paramSet,const struct HksBlob * kdfKey,const struct HksBlob * derivedKey)220 int32_t HksDeriveKeyPack(struct HksBlob *destData, const struct HksParamSet *paramSet, const struct HksBlob *kdfKey,
221     const struct HksBlob *derivedKey)
222 {
223     uint32_t offset = 0;
224     int32_t ret = CopyParamSetToBuffer(paramSet, destData, &offset);
225     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
226 
227     ret = CopyBlobToBuffer(kdfKey, destData, &offset);
228     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy kdfKey failed")
229     return CopyUint32ToBuffer(derivedKey->size, destData, &offset);
230 }
231 
HksGetKeyInfoListPack(struct HksBlob * destData,uint32_t listCount,const struct HksKeyInfo * keyInfoList)232 int32_t HksGetKeyInfoListPack(struct HksBlob *destData, uint32_t listCount, const struct HksKeyInfo *keyInfoList)
233 {
234     uint32_t offset = 0;
235     int32_t ret = CopyUint32ToBuffer(listCount, destData, &offset);
236     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy listCount failed")
237 
238     for (uint32_t i = 0; i < listCount; ++i) {
239         ret = CopyUint32ToBuffer(keyInfoList[i].alias.size, destData, &offset);
240         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy alias failed")
241 
242         ret = CopyUint32ToBuffer(keyInfoList[i].paramSet->paramSetSize, destData, &offset);
243         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSetSize failed")
244     }
245     return HKS_SUCCESS;
246 }
247 
HksGetKeyInfoListUnpackFromService(const struct HksBlob * srcData,uint32_t * listCount,struct HksKeyInfo * keyInfoList)248 int32_t HksGetKeyInfoListUnpackFromService(const struct HksBlob *srcData, uint32_t *listCount,
249     struct HksKeyInfo *keyInfoList)
250 {
251     uint32_t offset = 0;
252     uint32_t countFromBuffer;
253     int32_t ret = GetUint32FromBuffer(&countFromBuffer, srcData, &offset);
254     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get listCount failed")
255 
256     if (countFromBuffer > *listCount) {
257         HKS_LOG_E("listCount from buffer is invalid");
258         return HKS_ERROR_INVALID_ARGUMENT;
259     }
260     *listCount = countFromBuffer;
261 
262     struct HksBlob alias = { 0, NULL };
263     struct HksParamSet *paramSet = NULL;
264     for (uint32_t i = 0; i < countFromBuffer; ++i) {
265         ret = GetBlobFromBuffer(&alias, srcData, &offset);
266         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get alias failed")
267 
268         if (memcpy_s(keyInfoList[i].alias.data, keyInfoList[i].alias.size, alias.data, alias.size) != EOK) {
269             HKS_LOG_E("memcpy alias failed");
270             return ret;
271         }
272         keyInfoList[i].alias.size = alias.size;
273 
274         ret = GetParamSetFromBuffer(&paramSet, srcData, &offset);
275         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
276 
277         if (memcpy_s(keyInfoList[i].paramSet, keyInfoList[i].paramSet->paramSetSize,
278             paramSet, paramSet->paramSetSize) != EOK) {
279             HKS_LOG_E("memcpy paramSet failed");
280             return ret;
281         }
282 
283         ret = HksFreshParamSet(keyInfoList[i].paramSet, false);
284         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "FreshParamSet fail, ret = %" LOG_PUBLIC "d", ret)
285     }
286 
287     return HKS_SUCCESS;
288 }
289 
HksCertificateChainPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * certChainBlob)290 int32_t HksCertificateChainPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
291     const struct HksParamSet *paramSet, const struct HksBlob *certChainBlob)
292 {
293     uint32_t offset = 0;
294     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
295     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
296 
297     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
298     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
299 
300     return CopyUint32ToBuffer(certChainBlob->size, destData, &offset);
301 }
302 
Base64Encode(const uint8_t * srcData,const uint32_t srcDataSize,uint8_t * outData,const uint32_t outDataSize)303 static int32_t Base64Encode(const uint8_t *srcData, const uint32_t srcDataSize,
304     uint8_t *outData, const uint32_t outDataSize)
305 {
306     /*
307      * outDataSize is already calculated on the outside.
308      * Base64 encode like this:
309      * <------------ byte ------------>
310      * <------><-src1-><-src2-><-src3->
311      * +------------------------------+
312      * |      24      16      08      |
313      * +------------------------------+
314      *         <out1><out2><out3><out4>
315      */
316     uint32_t j = 0;
317     uint32_t i = 0;
318     while (i < srcDataSize) {
319         uint32_t a = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
320         ++i;
321         uint32_t b = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
322         ++i;
323         uint32_t c = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
324         ++i;
325         /* srcData each character takes up 8 bits. 1, 2 and 3 is offset */
326         uint32_t byte = (a << (8 * 2)) + (b << (8 * 1)) + (c << (8 * 0));
327 
328         /* outData each character takes up 6 bits */
329         outData[j++] = g_base64Table[(byte >> (6 * 3)) & 0b00111111]; /* 3 and 6 is offset */
330         outData[j++] = g_base64Table[(byte >> (6 * 2)) & 0b00111111]; /* 2 and 6 is offset */
331         outData[j++] = g_base64Table[(byte >> (6 * 1)) & 0b00111111]; /* 1 and 6 is offset */
332         outData[j++] = g_base64Table[(byte >> (6 * 0)) & 0b00111111]; /* 0 and 6 is offset */
333     }
334 
335     const int32_t padding = srcDataSize % 3; /* 3 in each group */
336     if (padding == 0) {
337         return HKS_SUCCESS;
338     } else {
339         outData[outDataSize - 1] = '='; /* 1: padding last character with '=' */
340     }
341     if (padding == 1) {
342         outData[outDataSize - 2] = '='; /* 2: padding penultimate character with '=' */
343     }
344 
345     return HKS_SUCCESS;
346 }
347 
CheckAndCalculateSize(const uint32_t inSize,const uint32_t extraSize,uint32_t * outSize)348 static int32_t CheckAndCalculateSize(const uint32_t inSize, const uint32_t extraSize, uint32_t *outSize)
349 {
350     /*
351      * 2: fill it up to a multiple of three
352      * 3 and 4: every three original characters is converted to four base64 characters
353      */
354     if (inSize > UINT32_MAX - NUM_TWO) {
355         return HKS_ERROR_INVALID_ARGUMENT;
356     }
357     /* 3 and 4: every three original characters is converted to four base64 characters */
358     if (((inSize + 2) / 3) > (UINT32_MAX / 4)) { // 2: fill it up to a multiple of three
359         return HKS_ERROR_INVALID_ARGUMENT;
360     }
361     /* 3 and 4: every three original characters is converted to four base64 characters */
362     if ((((inSize + 2) / 3) * 4) > UINT32_MAX - extraSize) { // 2: fill it up to a multiple of three
363         return HKS_ERROR_INVALID_ARGUMENT;
364     }
365     /* 3 and 4: every three original characters is converted to four base64 characters */
366     *outSize = (((inSize + 2) / 3) * 4) + extraSize; // 2: fill it up to a multiple of three
367     return HKS_SUCCESS;
368 }
369 
EncodeCertChain(const struct HksBlob * inBlob,struct HksBlob * outBlob)370 static int32_t EncodeCertChain(const struct HksBlob *inBlob, struct HksBlob *outBlob)
371 {
372     const char begin[] = "-----BEGIN CERTIFICATE-----\n";
373     const char end[] = "\n-----END CERTIFICATE-----";
374 
375     const uint32_t beginLen = strlen(begin);
376     const uint32_t endLen = strlen(end);
377 
378     uint32_t tmpSize;
379     int32_t ret = CheckAndCalculateSize(inBlob->size, beginLen + endLen, &tmpSize);
380     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check inBlob size fail")
381 
382     struct HksBlob tmpBlob = { tmpSize, NULL };
383     tmpBlob.data = (uint8_t *)HksMalloc(tmpSize);
384     HKS_IF_NULL_LOGE_RETURN(tmpBlob.data, HKS_ERROR_MALLOC_FAIL, "malloc certEncoded fail")
385 
386     do {
387         if (memcpy_s(tmpBlob.data, tmpSize, begin, beginLen) != EOK) {
388             HKS_LOG_E("memcpy_s cert begin fail");
389             ret = HKS_ERROR_BUFFER_TOO_SMALL;
390             break;
391         }
392 
393         if (memcpy_s(tmpBlob.data + tmpSize - endLen, endLen, end, endLen) != EOK) {
394             HKS_LOG_E("memcpy_s cert end fail");
395             ret = HKS_ERROR_BUFFER_TOO_SMALL;
396             break;
397         }
398 
399         ret = Base64Encode(inBlob->data, inBlob->size, tmpBlob.data + beginLen, tmpSize - beginLen - endLen);
400         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Base64Encode fail")
401 
402         if (memcpy_s(outBlob->data, outBlob->size, tmpBlob.data, tmpBlob.size) != EOK) {
403             HKS_LOG_E("copy certs encoded fail");
404             ret = HKS_ERROR_BUFFER_TOO_SMALL;
405             break;
406         }
407         outBlob->size = tmpBlob.size;
408     } while (0);
409 
410     HksFree(tmpBlob.data);
411     return ret;
412 }
413 
HksCertificateChainUnpackFromService(const struct HksBlob * srcData,bool needEncode,struct HksCertChain * certChain)414 int32_t HksCertificateChainUnpackFromService(const struct HksBlob *srcData, bool needEncode,
415     struct HksCertChain *certChain)
416 {
417     if (srcData->size < sizeof(certChain->certsCount)) {
418         HKS_LOG_E("invalid certs buffer");
419         return HKS_ERROR_BUFFER_TOO_SMALL;
420     }
421     uint32_t certsCount = *(uint32_t *)(srcData->data);
422     if (certsCount > certChain->certsCount) {
423         HKS_LOG_E("not enough output certs, real count %" LOG_PUBLIC "u, output count %" LOG_PUBLIC "u",
424             certsCount, certChain->certsCount);
425         return HKS_ERROR_INSUFFICIENT_DATA;
426     }
427     uint32_t offset = sizeof(certsCount);
428 
429     struct HksBlob tmp = { 0, NULL };
430     for (uint32_t i = 0; i < certsCount; ++i) {
431         HKS_IF_NOT_SUCC_LOGE_RETURN(GetBlobFromBuffer(&tmp, srcData, &offset),
432             HKS_ERROR_IPC_MSG_FAIL, "get certs %" LOG_PUBLIC "d fail", i)
433         if (memcpy_s(certChain->certs[i].data, certChain->certs[i].size, tmp.data, tmp.size)) {
434             HKS_LOG_E("copy certs %" LOG_PUBLIC "d fail", i);
435             return HKS_ERROR_INSUFFICIENT_DATA;
436         }
437 
438         if (needEncode) {
439             struct HksBlob inBlob = { tmp.size, certChain->certs[i].data };
440             int32_t ret = EncodeCertChain(&inBlob, &certChain->certs[i]);
441             HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "EncodeCertChain fail, ret = %" LOG_PUBLIC "d", ret)
442         } else {
443             certChain->certs[i].size = tmp.size;
444         }
445     }
446     certChain->certsCount = certsCount;
447     return HKS_SUCCESS;
448 }
449 
HksParamsToParamSet(struct HksParam * params,uint32_t cnt,struct HksParamSet ** outParamSet)450 int32_t HksParamsToParamSet(struct HksParam *params, uint32_t cnt, struct HksParamSet **outParamSet)
451 {
452     struct HksParamSet *newParamSet = NULL;
453 
454     int32_t ret = HksInitParamSet(&newParamSet);
455     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init param set failed")
456 
457     do {
458         uint8_t tmpData = 0;
459         struct HksBlob tmpBlob = { sizeof(tmpData), &tmpData };
460 
461         for (uint32_t i = 0; i < cnt; ++i) {
462             if ((GetTagType(params[i].tag) == HKS_TAG_TYPE_BYTES) &&
463                 (params[i].blob.size == 0 || params[i].blob.data == NULL)) {
464                 params[i].tag += HKS_PARAM_BUFFER_NULL_INTERVAL;
465                 params[i].blob = tmpBlob;
466             }
467         }
468         ret = HksAddParams(newParamSet, params, cnt);
469         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add in params failed")
470 
471         ret = HksBuildParamSet(&newParamSet);
472         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build paramset failed!")
473     } while (0);
474     if (ret != HKS_SUCCESS) {
475         HksFreeParamSet(&newParamSet);
476         return ret;
477     }
478 
479     *outParamSet = newParamSet;
480 
481     return ret;
482 }
483