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