• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_client_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 "hks_type_enum.h"
27 #include "securec.h"
28 
29 #define NUM_TWO        2
30 
31 static const uint8_t BASE64_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
32 
CopyUint32ToBuffer(uint32_t value,const struct HksBlob * destBlob,uint32_t * destOffset)33 int32_t CopyUint32ToBuffer(uint32_t value, const struct HksBlob *destBlob, uint32_t *destOffset)
34 {
35     if ((*destOffset > destBlob->size) || ((destBlob->size - *destOffset) < sizeof(value))) {
36         return HKS_ERROR_BUFFER_TOO_SMALL;
37     }
38 
39     HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &value,
40         sizeof(value)), HKS_ERROR_INSUFFICIENT_MEMORY, "copy destBlob data failed!")
41     *destOffset += sizeof(value);
42 
43     return HKS_SUCCESS;
44 }
45 
CopyBlobToBuffer(const struct HksBlob * blob,const struct HksBlob * destBlob,uint32_t * destOffset)46 static int32_t CopyBlobToBuffer(const struct HksBlob *blob, const struct HksBlob *destBlob, uint32_t *destOffset)
47 {
48     if ((*destOffset > destBlob->size) ||
49         ((destBlob->size - *destOffset) < (sizeof(blob->size) + ALIGN_SIZE(blob->size)))) {
50         return HKS_ERROR_BUFFER_TOO_SMALL;
51     }
52 
53     HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &(blob->size),
54         sizeof(blob->size)), HKS_ERROR_INSUFFICIENT_MEMORY, "copy destBlob data failed!")
55     *destOffset += sizeof(blob->size);
56 
57     HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, blob->data,
58         blob->size), HKS_ERROR_INSUFFICIENT_MEMORY, "copy destBlob data failed!")
59     *destOffset += ALIGN_SIZE(blob->size);
60 
61     return HKS_SUCCESS;
62 }
63 
CopyParamSetToBuffer(const struct HksParamSet * paramSet,const struct HksBlob * destBlob,uint32_t * destOffset)64 static int32_t CopyParamSetToBuffer(const struct HksParamSet *paramSet,
65     const struct HksBlob *destBlob, uint32_t *destOffset)
66 {
67     if ((*destOffset > destBlob->size) || (destBlob->size - *destOffset < ALIGN_SIZE(paramSet->paramSetSize))) {
68         return HKS_ERROR_BUFFER_TOO_SMALL;
69     }
70 
71     HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, paramSet,
72         paramSet->paramSetSize), HKS_ERROR_INSUFFICIENT_MEMORY, "copy destBlob data failed!");
73     *destOffset += ALIGN_SIZE(paramSet->paramSetSize);
74 
75     return HKS_SUCCESS;
76 }
77 
GetUint32FromBuffer(uint32_t * value,const struct HksBlob * srcBlob,uint32_t * srcOffset)78 static int32_t GetUint32FromBuffer(uint32_t *value, const struct HksBlob *srcBlob, uint32_t *srcOffset)
79 {
80     if ((*srcOffset > srcBlob->size) || (srcBlob->size - *srcOffset < sizeof(*value))) {
81         return HKS_ERROR_BUFFER_TOO_SMALL;
82     }
83 
84     *value = *((uint32_t *)(srcBlob->data + *srcOffset));
85     *srcOffset += sizeof(*value);
86     return HKS_SUCCESS;
87 }
88 
GetBlobFromBuffer(struct HksBlob * blob,const struct HksBlob * srcBlob,uint32_t * srcOffset)89 static int32_t GetBlobFromBuffer(struct HksBlob *blob, const struct HksBlob *srcBlob, uint32_t *srcOffset)
90 {
91     if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(blob->size))) {
92         return HKS_ERROR_BUFFER_TOO_SMALL;
93     }
94 
95     uint32_t size = *((uint32_t *)(srcBlob->data + *srcOffset));
96     HKS_IF_TRUE_RETURN(IsAdditionOverflow(size, DEFAULT_ALIGN_MASK_SIZE), HKS_ERROR_INVALID_ARGUMENT)
97     if (ALIGN_SIZE(size) > (srcBlob->size - *srcOffset - sizeof(blob->size))) {
98         return HKS_ERROR_BUFFER_TOO_SMALL;
99     }
100     blob->size = size;
101     *srcOffset += sizeof(blob->size);
102     blob->data = (uint8_t *)(srcBlob->data + *srcOffset);
103     *srcOffset += ALIGN_SIZE(blob->size);
104 
105     return HKS_SUCCESS;
106 }
107 
GetParamSetFromBuffer(struct HksParamSet ** paramSet,const struct HksBlob * srcBlob,uint32_t * srcOffset)108 static int32_t GetParamSetFromBuffer(struct HksParamSet **paramSet,
109     const struct HksBlob *srcBlob, uint32_t *srcOffset)
110 {
111     if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(struct HksParamSet))) {
112         return HKS_ERROR_BUFFER_TOO_SMALL;
113     }
114 
115     *paramSet = (struct HksParamSet *)(srcBlob->data + *srcOffset);
116     HKS_IF_TRUE_RETURN(IsAdditionOverflow((*paramSet)->paramSetSize, DEFAULT_ALIGN_MASK_SIZE),
117         HKS_ERROR_INVALID_ARGUMENT)
118     if (ALIGN_SIZE((*paramSet)->paramSetSize) > (srcBlob->size - *srcOffset)) {
119         return HKS_ERROR_BUFFER_TOO_SMALL;
120     }
121     *srcOffset += ALIGN_SIZE((*paramSet)->paramSetSize);
122 
123     return HKS_SUCCESS;
124 }
125 
HksGenerateKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn,const struct HksBlob * keyOut)126 int32_t HksGenerateKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
127     const struct HksParamSet *paramSetIn, const struct HksBlob *keyOut)
128 {
129     uint32_t offset = 0;
130     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
131     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
132 
133     ret = CopyParamSetToBuffer(paramSetIn, destData, &offset);
134     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSetIn failed")
135     return CopyUint32ToBuffer(keyOut->size, destData, &offset);
136 }
137 
HksImportKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)138 int32_t HksImportKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
139     const struct HksBlob *key)
140 {
141     uint32_t offset = 0;
142     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
143     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
144 
145     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
146     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
147     return CopyBlobToBuffer(key, destData, &offset);
148 }
149 
HksImportWrappedKeyPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksBlob * wrappingKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKeyData)150 int32_t HksImportWrappedKeyPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
151     const struct HksBlob *wrappingKeyAlias, const struct HksParamSet *paramSet, const struct HksBlob *wrappedKeyData)
152 {
153     uint32_t offset = 0;
154     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
155     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
156 
157     ret = CopyBlobToBuffer(wrappingKeyAlias, destData, &offset);
158     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy wrappingKeyAlias failed")
159 
160     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
161     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
162     return CopyBlobToBuffer(wrappedKeyData, destData, &offset);
163 }
164 
HksDeleteKeyPack(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksBlob * destData)165 int32_t HksDeleteKeyPack(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, struct HksBlob *destData)
166 {
167     uint32_t offset = 0;
168     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
169     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
170 
171     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
172     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
173     return HKS_SUCCESS;
174 }
175 
HksExportPublicKeyPack(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key,struct HksBlob * destData)176 int32_t HksExportPublicKeyPack(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
177     const struct HksBlob *key, struct HksBlob *destData)
178 {
179     uint32_t offset = 0;
180     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
181     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
182 
183     ret = CopyUint32ToBuffer(key->size, destData, &offset);
184     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keysize failed")
185     return CopyParamSetToBuffer(paramSet, destData, &offset);
186 }
187 
HksGetKeyParamSetPack(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * keyOut,struct HksBlob * destData)188 int32_t HksGetKeyParamSetPack(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
189     const struct HksBlob *keyOut, struct HksBlob *destData)
190 {
191     uint32_t offset = 0;
192     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
193     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
194 
195     ret = CopyUint32ToBuffer(keyOut->size, destData, &offset);
196     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyOutSize failed")
197     return CopyParamSetToBuffer(paramSet, destData, &offset);
198 }
199 
HksKeyExistPack(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksBlob * destData)200 int32_t HksKeyExistPack(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, struct HksBlob *destData)
201 {
202     uint32_t offset = 0;
203     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
204     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
205 
206     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
207     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
208     return HKS_SUCCESS;
209 }
210 
HksOnceParamPack(struct HksBlob * destData,const struct HksBlob * key,const struct HksParamSet * paramSet,uint32_t * offset)211 int32_t HksOnceParamPack(struct HksBlob *destData, const struct HksBlob *key, const struct HksParamSet *paramSet,
212     uint32_t *offset)
213 {
214     int32_t ret = CopyBlobToBuffer(key, destData, offset);
215     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy key failed")
216 
217     return CopyParamSetToBuffer(paramSet, destData, offset);
218 }
219 
HksOnceDataPack(struct HksBlob * destData,const struct HksBlob * inputData,const struct HksBlob * rsvData,const struct HksBlob * outputData,uint32_t * offset)220 int32_t HksOnceDataPack(struct HksBlob *destData, const struct HksBlob *inputData, const struct HksBlob *rsvData,
221     const struct HksBlob *outputData, uint32_t *offset)
222 {
223     int32_t ret = CopyBlobToBuffer(inputData, destData, offset);
224     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy inputData failed")
225 
226     if (rsvData != NULL) {
227         ret = CopyBlobToBuffer(rsvData, destData, offset);
228         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy rsvData failed")
229     }
230 
231     if (outputData != NULL) {
232         ret = CopyUint32ToBuffer(outputData->size, destData, offset);
233     }
234     return ret;
235 }
236 
HksAgreeKeyPack(struct HksBlob * destData,const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,const struct HksBlob * agreedKey)237 int32_t HksAgreeKeyPack(struct HksBlob *destData, const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
238     const struct HksBlob *peerPublicKey, const struct HksBlob *agreedKey)
239 {
240     uint32_t offset = 0;
241     int32_t ret = CopyParamSetToBuffer(paramSet, destData, &offset);
242     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
243 
244     ret = CopyBlobToBuffer(privateKey, destData, &offset);
245     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy privateKey failed")
246 
247     ret = CopyBlobToBuffer(peerPublicKey, destData, &offset);
248     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy peerPublicKey failed")
249     return CopyUint32ToBuffer(agreedKey->size, destData, &offset);
250 }
251 
HksDeriveKeyPack(struct HksBlob * destData,const struct HksParamSet * paramSet,const struct HksBlob * kdfKey,const struct HksBlob * derivedKey)252 int32_t HksDeriveKeyPack(struct HksBlob *destData, const struct HksParamSet *paramSet, const struct HksBlob *kdfKey,
253     const struct HksBlob *derivedKey)
254 {
255     uint32_t offset = 0;
256     int32_t ret = CopyParamSetToBuffer(paramSet, destData, &offset);
257     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
258 
259     ret = CopyBlobToBuffer(kdfKey, destData, &offset);
260     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy kdfKey failed")
261     return CopyUint32ToBuffer(derivedKey->size, destData, &offset);
262 }
263 
HksGetKeyInfoListPack(const struct HksParamSet * paramSet,const struct HksKeyInfo * keyInfoList,struct HksBlob * destData,uint32_t listCount)264 int32_t HksGetKeyInfoListPack(const struct HksParamSet *paramSet, const struct HksKeyInfo *keyInfoList,
265     struct HksBlob *destData, uint32_t listCount)
266 {
267     uint32_t offset = 0;
268     int32_t ret = CopyUint32ToBuffer(listCount, destData, &offset);
269     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy listCount failed")
270 
271     for (uint32_t i = 0; i < listCount; ++i) {
272         ret = CopyUint32ToBuffer(keyInfoList[i].alias.size, destData, &offset);
273         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy alias failed")
274 
275         ret = CopyUint32ToBuffer(keyInfoList[i].paramSet->paramSetSize, destData, &offset);
276         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSetSize failed")
277     }
278 
279     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
280     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
281     return HKS_SUCCESS;
282 }
283 
HksGetKeyInfoListUnpackFromService(const struct HksBlob * srcData,uint32_t * listCount,struct HksKeyInfo * keyInfoList)284 int32_t HksGetKeyInfoListUnpackFromService(const struct HksBlob *srcData, uint32_t *listCount,
285     struct HksKeyInfo *keyInfoList)
286 {
287     uint32_t offset = 0;
288     uint32_t countFromBuffer;
289     int32_t ret = GetUint32FromBuffer(&countFromBuffer, srcData, &offset);
290     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get listCount failed")
291 
292     HKS_IF_TRUE_LOGE_RETURN(countFromBuffer > *listCount, HKS_ERROR_INVALID_ARGUMENT,
293         "listCount from buffer is invalid")
294     *listCount = countFromBuffer;
295 
296     struct HksBlob alias = { 0, NULL };
297     struct HksParamSet *paramSet = NULL;
298     for (uint32_t i = 0; i < countFromBuffer; ++i) {
299         ret = GetBlobFromBuffer(&alias, srcData, &offset);
300         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get alias failed")
301 
302         HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(keyInfoList[i].alias.data, keyInfoList[i].alias.size, alias.data,
303             alias.size), ret, "memcpy alias failed")
304         keyInfoList[i].alias.size = alias.size;
305 
306         ret = GetParamSetFromBuffer(&paramSet, srcData, &offset);
307         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
308 
309         HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(keyInfoList[i].paramSet, keyInfoList[i].paramSet->paramSetSize, paramSet,
310             paramSet->paramSetSize), ret, "memcpy paramSet failed")
311 
312         ret = HksFreshParamSet(keyInfoList[i].paramSet, false);
313         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "FreshParamSet fail, ret = %" LOG_PUBLIC "d", ret)
314     }
315 
316     return HKS_SUCCESS;
317 }
318 
HksCertificateChainPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * certChainBlob)319 int32_t HksCertificateChainPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
320     const struct HksParamSet *paramSet, const struct HksBlob *certChainBlob)
321 {
322     uint32_t offset = 0;
323     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
324     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
325 
326     ret = CopyParamSetToBuffer(paramSet, destData, &offset);
327     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
328 
329     return CopyUint32ToBuffer(certChainBlob->size, destData, &offset);
330 }
331 
Base64Encode(const uint8_t * srcData,const uint32_t srcDataSize,uint8_t * outData,const uint32_t outDataSize)332 static int32_t Base64Encode(const uint8_t *srcData, const uint32_t srcDataSize,
333     uint8_t *outData, const uint32_t outDataSize)
334 {
335     /*
336      * outDataSize is already calculated on the outside.
337      * Base64 encode like this:
338      * <------------ byte ------------>
339      * <------><-src1-><-src2-><-src3->
340      * +------------------------------+
341      * |      24      16      08      |
342      * +------------------------------+
343      *         <out1><out2><out3><out4>
344      */
345     uint32_t j = 0;
346     uint32_t i = 0;
347     while (i < srcDataSize) {
348         uint32_t a = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
349         ++i;
350         uint32_t b = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
351         ++i;
352         uint32_t c = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
353         ++i;
354         /* srcData each character takes up 8 bits. 1, 2 and 3 is offset */
355         uint32_t byte = (a << (8 * 2)) + (b << (8 * 1)) + (c << (8 * 0));
356 
357         /* outData each character takes up 6 bits */
358         outData[j++] = BASE64_TABLE[(byte >> (6 * 3)) & 0b00111111]; /* 3 and 6 is offset */
359         outData[j++] = BASE64_TABLE[(byte >> (6 * 2)) & 0b00111111]; /* 2 and 6 is offset */
360         outData[j++] = BASE64_TABLE[(byte >> (6 * 1)) & 0b00111111]; /* 1 and 6 is offset */
361         outData[j++] = BASE64_TABLE[(byte >> (6 * 0)) & 0b00111111]; /* 0 and 6 is offset */
362     }
363 
364     const int32_t padding = srcDataSize % 3; /* 3 in each group */
365     if (padding == 0) {
366         return HKS_SUCCESS;
367     } else {
368         outData[outDataSize - 1] = '='; /* 1: padding last character with '=' */
369     }
370     if (padding == 1) {
371         outData[outDataSize - 2] = '='; /* 2: padding penultimate character with '=' */
372     }
373 
374     return HKS_SUCCESS;
375 }
376 
CheckAndCalculateSize(const uint32_t inSize,const uint32_t extraSize,uint32_t * outSize)377 static int32_t CheckAndCalculateSize(const uint32_t inSize, const uint32_t extraSize, uint32_t *outSize)
378 {
379     /*
380      * 2: fill it up to a multiple of three
381      * 3 and 4: every three original characters is converted to four base64 characters
382      */
383     if (inSize > UINT32_MAX - NUM_TWO) {
384         return HKS_ERROR_INVALID_ARGUMENT;
385     }
386     /* 3 and 4: every three original characters is converted to four base64 characters */
387     if (((inSize + 2) / 3) > (UINT32_MAX / 4)) { // 2: fill it up to a multiple of three
388         return HKS_ERROR_INVALID_ARGUMENT;
389     }
390     /* 3 and 4: every three original characters is converted to four base64 characters */
391     if ((((inSize + 2) / 3) * 4) > UINT32_MAX - extraSize) { // 2: fill it up to a multiple of three
392         return HKS_ERROR_INVALID_ARGUMENT;
393     }
394     /* 3 and 4: every three original characters is converted to four base64 characters */
395     *outSize = (((inSize + 2) / 3) * 4) + extraSize; // 2: fill it up to a multiple of three
396     return HKS_SUCCESS;
397 }
398 
EncodeCertChain(const struct HksBlob * inBlob,struct HksBlob * outBlob)399 int32_t EncodeCertChain(const struct HksBlob *inBlob, struct HksBlob *outBlob)
400 {
401     const char begin[] = "-----BEGIN CERTIFICATE-----\n";
402     const char end[] = "\n-----END CERTIFICATE-----";
403 
404     const uint32_t beginLen = strlen(begin);
405     const uint32_t endLen = strlen(end);
406 
407     uint32_t tmpSize;
408     int32_t ret = CheckAndCalculateSize(inBlob->size, beginLen + endLen, &tmpSize);
409     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check inBlob size fail")
410 
411     struct HksBlob tmpBlob = { tmpSize, NULL };
412     tmpBlob.data = (uint8_t *)HksMalloc(tmpSize);
413     HKS_IF_NULL_LOGE_RETURN(tmpBlob.data, HKS_ERROR_MALLOC_FAIL, "malloc certEncoded fail")
414 
415     do {
416         if (memcpy_s(tmpBlob.data, tmpSize, begin, beginLen) != EOK) {
417             HKS_LOG_E("memcpy_s cert begin fail");
418             ret = HKS_ERROR_BUFFER_TOO_SMALL;
419             break;
420         }
421 
422         if (memcpy_s(tmpBlob.data + tmpSize - endLen, endLen, end, endLen) != EOK) {
423             HKS_LOG_E("memcpy_s cert end fail");
424             ret = HKS_ERROR_BUFFER_TOO_SMALL;
425             break;
426         }
427 
428         ret = Base64Encode(inBlob->data, inBlob->size, tmpBlob.data + beginLen, tmpSize - beginLen - endLen);
429         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Base64Encode fail")
430 
431         if (memcpy_s(outBlob->data, outBlob->size, tmpBlob.data, tmpBlob.size) != EOK) {
432             HKS_LOG_E("copy certs encoded fail");
433             ret = HKS_ERROR_BUFFER_TOO_SMALL;
434             break;
435         }
436         outBlob->size = tmpBlob.size;
437     } while (0);
438 
439     HKS_FREE(tmpBlob.data);
440     return ret;
441 }
442 
HksCertificateChainUnpackFromService(const struct HksBlob * srcData,bool needEncode,struct HksCertChain * certChain)443 int32_t HksCertificateChainUnpackFromService(const struct HksBlob *srcData, bool needEncode,
444     struct HksCertChain *certChain)
445 {
446     if (srcData->size < sizeof(certChain->certsCount)) {
447         HKS_LOG_E("invalid certs buffer");
448         return HKS_ERROR_BUFFER_TOO_SMALL;
449     }
450     uint32_t certsCount = *(uint32_t *)(srcData->data);
451     if (certsCount > certChain->certsCount) {
452         HKS_LOG_E("not enough output certs, real count %" LOG_PUBLIC "u, output count %" LOG_PUBLIC "u",
453             certsCount, certChain->certsCount);
454         return HKS_ERROR_INSUFFICIENT_DATA;
455     }
456     uint32_t offset = sizeof(certsCount);
457 
458     struct HksBlob tmp = { 0, NULL };
459     for (uint32_t i = 0; i < certsCount; ++i) {
460         HKS_IF_NOT_SUCC_LOGE_RETURN(GetBlobFromBuffer(&tmp, srcData, &offset),
461             HKS_ERROR_IPC_MSG_FAIL, "get certs %" LOG_PUBLIC "d fail", i)
462         HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(certChain->certs[i].data, certChain->certs[i].size, tmp.data, tmp.size),
463             HKS_ERROR_INSUFFICIENT_DATA, "copy certs %" LOG_PUBLIC "d fail", i)
464 
465         if (needEncode) {
466             struct HksBlob inBlob = { tmp.size, certChain->certs[i].data };
467             int32_t ret = EncodeCertChain(&inBlob, &certChain->certs[i]);
468             HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "EncodeCertChain fail, ret = %" LOG_PUBLIC "d", ret)
469         } else {
470             certChain->certs[i].size = tmp.size;
471         }
472     }
473     certChain->certsCount = certsCount;
474     return HKS_SUCCESS;
475 }
476 
HksParamsToParamSet(struct HksParam * params,uint32_t cnt,struct HksParamSet ** outParamSet)477 int32_t HksParamsToParamSet(struct HksParam *params, uint32_t cnt, struct HksParamSet **outParamSet)
478 {
479     struct HksParamSet *newParamSet = NULL;
480 
481     int32_t ret = HksInitParamSet(&newParamSet);
482     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init param set failed")
483 
484     do {
485         uint8_t tmpData = 0;
486         struct HksBlob tmpBlob = { sizeof(tmpData), &tmpData };
487 
488         for (uint32_t i = 0; i < cnt; ++i) {
489             if ((GetTagType(params[i].tag) == HKS_TAG_TYPE_BYTES) &&
490                 (params[i].blob.size == 0 || params[i].blob.data == NULL)) {
491                 params[i].tag += HKS_PARAM_BUFFER_NULL_INTERVAL;
492                 params[i].blob = tmpBlob;
493             }
494         }
495         ret = HksAddParams(newParamSet, params, cnt);
496         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add in params failed")
497 
498         ret = HksBuildParamSet(&newParamSet);
499         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build paramset failed!")
500     } while (0);
501     if (ret != HKS_SUCCESS) {
502         HksFreeParamSet(&newParamSet);
503         return ret;
504     }
505 
506     *outParamSet = newParamSet;
507 
508     return ret;
509 }
510 
HksListAliasesPack(const struct HksParamSet * srcParamSet,struct HksBlob * destData)511 int32_t HksListAliasesPack(const struct HksParamSet *srcParamSet, struct HksBlob *destData)
512 {
513     uint32_t offset = 0;
514     int32_t ret = CopyParamSetToBuffer(srcParamSet, destData, &offset);
515     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
516     return HKS_SUCCESS;
517 }
518 
HksListAliasesUnpackFromService(const struct HksBlob * srcBlob,struct HksKeyAliasSet ** destData)519 int32_t HksListAliasesUnpackFromService(const struct HksBlob *srcBlob, struct HksKeyAliasSet **destData)
520 {
521     HKS_IF_TRUE_RETURN(srcBlob->size == 0, HKS_SUCCESS)
522     int32_t ret = 0;
523     uint32_t offset = 0;
524     uint32_t cntFromBuffer;
525 
526     ret = GetUint32FromBuffer(&cntFromBuffer, srcBlob, &offset);
527     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get cnt failed")
528     HKS_IF_NOT_TRUE_RETURN((cntFromBuffer <= HKS_MAX_KEY_ALIAS_COUNT), HKS_ERROR_BUFFER_TOO_SMALL);
529 
530     struct HksKeyAliasSet *tempAliasSet = (struct HksKeyAliasSet *)(HksMalloc(sizeof(struct HksKeyAliasSet)));
531     HKS_IF_NULL_LOGE_RETURN(tempAliasSet, HKS_ERROR_MALLOC_FAIL, "malloc HksKeyAliasSet fail")
532 
533     tempAliasSet->aliasesCnt = cntFromBuffer;
534     struct HksBlob tmpBlob = { 0, NULL };
535     do {
536         tempAliasSet->aliases = (struct HksBlob *)(HksMalloc(cntFromBuffer * sizeof(struct HksBlob)));
537         if (tempAliasSet->aliases == NULL) {
538             HKS_LOG_E("malloc HksKeyAliasSet aliases fail");
539             ret = HKS_ERROR_MALLOC_FAIL;
540             break;
541         }
542         for (uint32_t i = 0; i < cntFromBuffer; ++i) {
543             ret = GetBlobFromBuffer(&tmpBlob, srcBlob, &offset);
544             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get aliases %" LOG_PUBLIC "d fail", i)
545 
546             tempAliasSet->aliases[i].size = tmpBlob.size;
547             tempAliasSet->aliases[i].data = (uint8_t *)HksMalloc(tempAliasSet->aliases[i].size);
548             if (tempAliasSet->aliases[i].data == NULL) {
549                 HKS_LOG_E("malloc alias %" LOG_PUBLIC "d fail", i);
550                 ret = HKS_ERROR_MALLOC_FAIL;
551                 break;
552             }
553             if (memcpy_s(tempAliasSet->aliases[i].data, tempAliasSet->aliases[i].size, tmpBlob.data, tmpBlob.size)) {
554                 HKS_LOG_E("copy blob %" LOG_PUBLIC "d fail", i);
555                 ret = HKS_ERROR_BUFFER_TOO_SMALL;
556                 break;
557             }
558         }
559     } while (0);
560     if (ret != HKS_SUCCESS) {
561         HksFreeKeyAliasSet(tempAliasSet);
562         return ret;
563     }
564     *destData = tempAliasSet;
565     return ret;
566 }
567 
HksRenameKeyAliasPack(const struct HksBlob * oldKeyAlias,const struct HksBlob * newKeyAlias,const struct HksParamSet * paramSet,struct HksBlob * destData)568 int32_t HksRenameKeyAliasPack(const struct HksBlob *oldKeyAlias, const struct HksBlob *newKeyAlias,
569     const struct HksParamSet *paramSet, struct HksBlob *destData)
570 {
571     uint32_t offset = 0;
572     int32_t ret;
573     do {
574         ret = CopyBlobToBuffer(oldKeyAlias, destData, &offset);
575         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy oldKeyAlias failed");
576 
577         ret = CopyBlobToBuffer(newKeyAlias, destData, &offset);
578         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy newKeyAlias failed");
579 
580         ret = CopyParamSetToBuffer(paramSet, destData, &offset);
581         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy paramSet failed");
582     } while (0);
583     return ret;
584 }
585 
HksChangeStorageLevelPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * srcParamSet,const struct HksParamSet * destParamSet)586 int32_t HksChangeStorageLevelPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
587     const struct HksParamSet *srcParamSet, const struct HksParamSet *destParamSet)
588 {
589     uint32_t offset = 0;
590     int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
591     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
592 
593     ret = CopyParamSetToBuffer(srcParamSet, destData, &offset);
594     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy srcParamSet failed")
595 
596     ret = CopyParamSetToBuffer(destParamSet, destData, &offset);
597     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy destParamSet failed")
598     return HKS_SUCCESS;
599 }
600 
HksWrapKeyPack(struct HksBlob * inBlob,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksBlob * wrappedKey)601 int32_t HksWrapKeyPack(struct HksBlob *inBlob, const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
602     struct HksBlob *wrappedKey)
603 {
604     uint32_t offset = 0;
605     int32_t ret = CopyBlobToBuffer(keyAlias, inBlob, &offset);
606     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias fail")
607 
608     ret = CopyParamSetToBuffer(paramSet, inBlob, &offset);
609     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet fail")
610 
611     return CopyUint32ToBuffer(wrappedKey->size, inBlob, &offset);
612 }
613 
HksUnwrapKeyPack(struct HksBlob * inBlob,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKey)614 int32_t HksUnwrapKeyPack(struct HksBlob *inBlob, const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
615     const struct HksBlob *wrappedKey)
616 {
617     uint32_t offset = 0;
618     int32_t ret = CopyBlobToBuffer(keyAlias, inBlob, &offset);
619     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias fail")
620 
621     ret = CopyParamSetToBuffer(paramSet, inBlob, &offset);
622     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet fail")
623 
624     ret = CopyBlobToBuffer(wrappedKey, inBlob, &offset);
625     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy wrappedKey fail")
626 
627     return HKS_SUCCESS;
628 }
629