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 (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 if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, paramSet, paramSet->paramSetSize) != EOK) {
68 return HKS_ERROR_INSUFFICIENT_MEMORY;
69 }
70 *destOffset += ALIGN_SIZE(paramSet->paramSetSize);
71
72 return HKS_SUCCESS;
73 }
74
GetUint32FromBuffer(uint32_t * value,const struct HksBlob * srcBlob,uint32_t * srcOffset)75 static int32_t GetUint32FromBuffer(uint32_t *value, const struct HksBlob *srcBlob, uint32_t *srcOffset)
76 {
77 if ((*srcOffset > srcBlob->size) || (srcBlob->size - *srcOffset < sizeof(*value))) {
78 return HKS_ERROR_BUFFER_TOO_SMALL;
79 }
80
81 *value = *((uint32_t *)(srcBlob->data + *srcOffset));
82 *srcOffset += sizeof(*value);
83 return HKS_SUCCESS;
84 }
85
GetBlobFromBuffer(struct HksBlob * blob,const struct HksBlob * srcBlob,uint32_t * srcOffset)86 static int32_t GetBlobFromBuffer(struct HksBlob *blob, const struct HksBlob *srcBlob, uint32_t *srcOffset)
87 {
88 if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(blob->size))) {
89 return HKS_ERROR_BUFFER_TOO_SMALL;
90 }
91
92 uint32_t size = *((uint32_t *)(srcBlob->data + *srcOffset));
93 if (IsAdditionOverflow(size, DEFAULT_ALIGN_MASK_SIZE)) {
94 return HKS_ERROR_INVALID_ARGUMENT;
95 }
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 if (IsAdditionOverflow((*paramSet)->paramSetSize, DEFAULT_ALIGN_MASK_SIZE)) {
116 return HKS_ERROR_INVALID_ARGUMENT;
117 }
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 if (countFromBuffer > *listCount) {
293 HKS_LOG_E("listCount from buffer is invalid");
294 return HKS_ERROR_INVALID_ARGUMENT;
295 }
296 *listCount = countFromBuffer;
297
298 struct HksBlob alias = { 0, NULL };
299 struct HksParamSet *paramSet = NULL;
300 for (uint32_t i = 0; i < countFromBuffer; ++i) {
301 ret = GetBlobFromBuffer(&alias, srcData, &offset);
302 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get alias failed")
303
304 if (memcpy_s(keyInfoList[i].alias.data, keyInfoList[i].alias.size, alias.data, alias.size) != EOK) {
305 HKS_LOG_E("memcpy alias failed");
306 return ret;
307 }
308 keyInfoList[i].alias.size = alias.size;
309
310 ret = GetParamSetFromBuffer(¶mSet, srcData, &offset);
311 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get paramSet failed")
312
313 if (memcpy_s(keyInfoList[i].paramSet, keyInfoList[i].paramSet->paramSetSize,
314 paramSet, paramSet->paramSetSize) != EOK) {
315 HKS_LOG_E("memcpy paramSet failed");
316 return ret;
317 }
318
319 ret = HksFreshParamSet(keyInfoList[i].paramSet, false);
320 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "FreshParamSet fail, ret = %" LOG_PUBLIC "d", ret)
321 }
322
323 return HKS_SUCCESS;
324 }
325
HksCertificateChainPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * certChainBlob)326 int32_t HksCertificateChainPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
327 const struct HksParamSet *paramSet, const struct HksBlob *certChainBlob)
328 {
329 uint32_t offset = 0;
330 int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
331 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
332
333 ret = CopyParamSetToBuffer(paramSet, destData, &offset);
334 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
335
336 return CopyUint32ToBuffer(certChainBlob->size, destData, &offset);
337 }
338
Base64Encode(const uint8_t * srcData,const uint32_t srcDataSize,uint8_t * outData,const uint32_t outDataSize)339 static int32_t Base64Encode(const uint8_t *srcData, const uint32_t srcDataSize,
340 uint8_t *outData, const uint32_t outDataSize)
341 {
342 /*
343 * outDataSize is already calculated on the outside.
344 * Base64 encode like this:
345 * <------------ byte ------------>
346 * <------><-src1-><-src2-><-src3->
347 * +------------------------------+
348 * | 24 16 08 |
349 * +------------------------------+
350 * <out1><out2><out3><out4>
351 */
352 uint32_t j = 0;
353 uint32_t i = 0;
354 while (i < srcDataSize) {
355 uint32_t a = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
356 ++i;
357 uint32_t b = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
358 ++i;
359 uint32_t c = (i < srcDataSize) ? (uint8_t)srcData[i] : 0;
360 ++i;
361 /* srcData each character takes up 8 bits. 1, 2 and 3 is offset */
362 uint32_t byte = (a << (8 * 2)) + (b << (8 * 1)) + (c << (8 * 0));
363
364 /* outData each character takes up 6 bits */
365 outData[j++] = BASE64_TABLE[(byte >> (6 * 3)) & 0b00111111]; /* 3 and 6 is offset */
366 outData[j++] = BASE64_TABLE[(byte >> (6 * 2)) & 0b00111111]; /* 2 and 6 is offset */
367 outData[j++] = BASE64_TABLE[(byte >> (6 * 1)) & 0b00111111]; /* 1 and 6 is offset */
368 outData[j++] = BASE64_TABLE[(byte >> (6 * 0)) & 0b00111111]; /* 0 and 6 is offset */
369 }
370
371 const int32_t padding = srcDataSize % 3; /* 3 in each group */
372 if (padding == 0) {
373 return HKS_SUCCESS;
374 } else {
375 outData[outDataSize - 1] = '='; /* 1: padding last character with '=' */
376 }
377 if (padding == 1) {
378 outData[outDataSize - 2] = '='; /* 2: padding penultimate character with '=' */
379 }
380
381 return HKS_SUCCESS;
382 }
383
CheckAndCalculateSize(const uint32_t inSize,const uint32_t extraSize,uint32_t * outSize)384 static int32_t CheckAndCalculateSize(const uint32_t inSize, const uint32_t extraSize, uint32_t *outSize)
385 {
386 /*
387 * 2: fill it up to a multiple of three
388 * 3 and 4: every three original characters is converted to four base64 characters
389 */
390 if (inSize > UINT32_MAX - NUM_TWO) {
391 return HKS_ERROR_INVALID_ARGUMENT;
392 }
393 /* 3 and 4: every three original characters is converted to four base64 characters */
394 if (((inSize + 2) / 3) > (UINT32_MAX / 4)) { // 2: fill it up to a multiple of three
395 return HKS_ERROR_INVALID_ARGUMENT;
396 }
397 /* 3 and 4: every three original characters is converted to four base64 characters */
398 if ((((inSize + 2) / 3) * 4) > UINT32_MAX - extraSize) { // 2: fill it up to a multiple of three
399 return HKS_ERROR_INVALID_ARGUMENT;
400 }
401 /* 3 and 4: every three original characters is converted to four base64 characters */
402 *outSize = (((inSize + 2) / 3) * 4) + extraSize; // 2: fill it up to a multiple of three
403 return HKS_SUCCESS;
404 }
405
EncodeCertChain(const struct HksBlob * inBlob,struct HksBlob * outBlob)406 int32_t EncodeCertChain(const struct HksBlob *inBlob, struct HksBlob *outBlob)
407 {
408 const char begin[] = "-----BEGIN CERTIFICATE-----\n";
409 const char end[] = "\n-----END CERTIFICATE-----";
410
411 const uint32_t beginLen = strlen(begin);
412 const uint32_t endLen = strlen(end);
413
414 uint32_t tmpSize;
415 int32_t ret = CheckAndCalculateSize(inBlob->size, beginLen + endLen, &tmpSize);
416 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check inBlob size fail")
417
418 struct HksBlob tmpBlob = { tmpSize, NULL };
419 tmpBlob.data = (uint8_t *)HksMalloc(tmpSize);
420 HKS_IF_NULL_LOGE_RETURN(tmpBlob.data, HKS_ERROR_MALLOC_FAIL, "malloc certEncoded fail")
421
422 do {
423 if (memcpy_s(tmpBlob.data, tmpSize, begin, beginLen) != EOK) {
424 HKS_LOG_E("memcpy_s cert begin fail");
425 ret = HKS_ERROR_BUFFER_TOO_SMALL;
426 break;
427 }
428
429 if (memcpy_s(tmpBlob.data + tmpSize - endLen, endLen, end, endLen) != EOK) {
430 HKS_LOG_E("memcpy_s cert end fail");
431 ret = HKS_ERROR_BUFFER_TOO_SMALL;
432 break;
433 }
434
435 ret = Base64Encode(inBlob->data, inBlob->size, tmpBlob.data + beginLen, tmpSize - beginLen - endLen);
436 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Base64Encode fail")
437
438 if (memcpy_s(outBlob->data, outBlob->size, tmpBlob.data, tmpBlob.size) != EOK) {
439 HKS_LOG_E("copy certs encoded fail");
440 ret = HKS_ERROR_BUFFER_TOO_SMALL;
441 break;
442 }
443 outBlob->size = tmpBlob.size;
444 } while (0);
445
446 HKS_FREE(tmpBlob.data);
447 return ret;
448 }
449
HksCertificateChainUnpackFromService(const struct HksBlob * srcData,bool needEncode,struct HksCertChain * certChain)450 int32_t HksCertificateChainUnpackFromService(const struct HksBlob *srcData, bool needEncode,
451 struct HksCertChain *certChain)
452 {
453 if (srcData->size < sizeof(certChain->certsCount)) {
454 HKS_LOG_E("invalid certs buffer");
455 return HKS_ERROR_BUFFER_TOO_SMALL;
456 }
457 uint32_t certsCount = *(uint32_t *)(srcData->data);
458 if (certsCount > certChain->certsCount) {
459 HKS_LOG_E("not enough output certs, real count %" LOG_PUBLIC "u, output count %" LOG_PUBLIC "u",
460 certsCount, certChain->certsCount);
461 return HKS_ERROR_INSUFFICIENT_DATA;
462 }
463 uint32_t offset = sizeof(certsCount);
464
465 struct HksBlob tmp = { 0, NULL };
466 for (uint32_t i = 0; i < certsCount; ++i) {
467 HKS_IF_NOT_SUCC_LOGE_RETURN(GetBlobFromBuffer(&tmp, srcData, &offset),
468 HKS_ERROR_IPC_MSG_FAIL, "get certs %" LOG_PUBLIC "d fail", i)
469 if (memcpy_s(certChain->certs[i].data, certChain->certs[i].size, tmp.data, tmp.size)) {
470 HKS_LOG_E("copy certs %" LOG_PUBLIC "d fail", i);
471 return HKS_ERROR_INSUFFICIENT_DATA;
472 }
473
474 if (needEncode) {
475 struct HksBlob inBlob = { tmp.size, certChain->certs[i].data };
476 int32_t ret = EncodeCertChain(&inBlob, &certChain->certs[i]);
477 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "EncodeCertChain fail, ret = %" LOG_PUBLIC "d", ret)
478 } else {
479 certChain->certs[i].size = tmp.size;
480 }
481 }
482 certChain->certsCount = certsCount;
483 return HKS_SUCCESS;
484 }
485
HksParamsToParamSet(struct HksParam * params,uint32_t cnt,struct HksParamSet ** outParamSet)486 int32_t HksParamsToParamSet(struct HksParam *params, uint32_t cnt, struct HksParamSet **outParamSet)
487 {
488 struct HksParamSet *newParamSet = NULL;
489
490 int32_t ret = HksInitParamSet(&newParamSet);
491 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init param set failed")
492
493 do {
494 uint8_t tmpData = 0;
495 struct HksBlob tmpBlob = { sizeof(tmpData), &tmpData };
496
497 for (uint32_t i = 0; i < cnt; ++i) {
498 if ((GetTagType(params[i].tag) == HKS_TAG_TYPE_BYTES) &&
499 (params[i].blob.size == 0 || params[i].blob.data == NULL)) {
500 params[i].tag += HKS_PARAM_BUFFER_NULL_INTERVAL;
501 params[i].blob = tmpBlob;
502 }
503 }
504 ret = HksAddParams(newParamSet, params, cnt);
505 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add in params failed")
506
507 ret = HksBuildParamSet(&newParamSet);
508 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build paramset failed!")
509 } while (0);
510 if (ret != HKS_SUCCESS) {
511 HksFreeParamSet(&newParamSet);
512 return ret;
513 }
514
515 *outParamSet = newParamSet;
516
517 return ret;
518 }
519
HksListAliasesPack(const struct HksParamSet * srcParamSet,struct HksBlob * destData)520 int32_t HksListAliasesPack(const struct HksParamSet *srcParamSet, struct HksBlob *destData)
521 {
522 uint32_t offset = 0;
523 int32_t ret = CopyParamSetToBuffer(srcParamSet, destData, &offset);
524 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy paramSet failed")
525 return HKS_SUCCESS;
526 }
527
HksListAliasesUnpackFromService(const struct HksBlob * srcBlob,struct HksKeyAliasSet ** destData)528 int32_t HksListAliasesUnpackFromService(const struct HksBlob *srcBlob, struct HksKeyAliasSet **destData)
529 {
530 if (srcBlob->size == 0) {
531 return HKS_SUCCESS;
532 }
533 int32_t ret = 0;
534 uint32_t offset = 0;
535 uint32_t cntFromBuffer;
536
537 ret = GetUint32FromBuffer(&cntFromBuffer, srcBlob, &offset);
538 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get cnt failed")
539 HKS_IF_NOT_TRUE_LOGE_RETURN((cntFromBuffer <= HKS_MAX_KEY_ALIAS_COUNT), HKS_ERROR_BUFFER_TOO_SMALL);
540
541 struct HksKeyAliasSet *tempAliasSet = (struct HksKeyAliasSet *)(HksMalloc(sizeof(struct HksKeyAliasSet)));
542 HKS_IF_NULL_LOGE_RETURN(tempAliasSet, HKS_ERROR_MALLOC_FAIL, "malloc HksKeyAliasSet fail")
543
544 tempAliasSet->aliasesCnt = cntFromBuffer;
545 struct HksBlob tmpBlob = { 0, NULL };
546 do {
547 tempAliasSet->aliases = (struct HksBlob *)(HksMalloc(cntFromBuffer * sizeof(struct HksBlob)));
548 if (tempAliasSet->aliases == NULL) {
549 HKS_LOG_E("malloc HksKeyAliasSet aliases fail");
550 ret = HKS_ERROR_MALLOC_FAIL;
551 break;
552 }
553 for (uint32_t i = 0; i < cntFromBuffer; ++i) {
554 ret = GetBlobFromBuffer(&tmpBlob, srcBlob, &offset);
555 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get aliases %" LOG_PUBLIC "d fail", i)
556
557 tempAliasSet->aliases[i].size = tmpBlob.size;
558 tempAliasSet->aliases[i].data = (uint8_t *)HksMalloc(tempAliasSet->aliases[i].size);
559 if (tempAliasSet->aliases[i].data == NULL) {
560 HKS_LOG_E("malloc alias %" LOG_PUBLIC "d fail", i);
561 ret = HKS_ERROR_MALLOC_FAIL;
562 break;
563 }
564 if (memcpy_s(tempAliasSet->aliases[i].data, tempAliasSet->aliases[i].size, tmpBlob.data, tmpBlob.size)) {
565 HKS_LOG_E("copy blob %" LOG_PUBLIC "d fail", i);
566 ret = HKS_ERROR_BUFFER_TOO_SMALL;
567 break;
568 }
569 }
570 } while (0);
571 if (ret != HKS_SUCCESS) {
572 HksFreeKeyAliasSet(tempAliasSet);
573 return ret;
574 }
575 *destData = tempAliasSet;
576 return ret;
577 }
578
HksRenameKeyAliasPack(const struct HksBlob * oldKeyAlias,const struct HksBlob * newKeyAlias,const struct HksParamSet * paramSet,struct HksBlob * destData)579 int32_t HksRenameKeyAliasPack(const struct HksBlob *oldKeyAlias, const struct HksBlob *newKeyAlias,
580 const struct HksParamSet *paramSet, struct HksBlob *destData)
581 {
582 uint32_t offset = 0;
583 int32_t ret;
584 do {
585 ret = CopyBlobToBuffer(oldKeyAlias, destData, &offset);
586 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy oldKeyAlias failed");
587
588 ret = CopyBlobToBuffer(newKeyAlias, destData, &offset);
589 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy newKeyAlias failed");
590
591 ret = CopyParamSetToBuffer(paramSet, destData, &offset);
592 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy paramSet failed");
593 } while (0);
594 return ret;
595 }
HksChangeStorageLevelPack(struct HksBlob * destData,const struct HksBlob * keyAlias,const struct HksParamSet * srcParamSet,const struct HksParamSet * destParamSet)596 int32_t HksChangeStorageLevelPack(struct HksBlob *destData, const struct HksBlob *keyAlias,
597 const struct HksParamSet *srcParamSet, const struct HksParamSet *destParamSet)
598 {
599 uint32_t offset = 0;
600 int32_t ret = CopyBlobToBuffer(keyAlias, destData, &offset);
601 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy keyAlias failed")
602
603 ret = CopyParamSetToBuffer(srcParamSet, destData, &offset);
604 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy srcParamSet failed")
605
606 ret = CopyParamSetToBuffer(destParamSet, destData, &offset);
607 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "copy destParamSet failed")
608 return HKS_SUCCESS;
609 }