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_client_ipc.h"
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21
22 #include "hks_common_check.h"
23 #include "hks_ipc_check.h"
24 #include "hks_ipc_serialization.h"
25 #include "hks_ipc_slice.h"
26 #include "hks_log.h"
27 #include "hks_mem.h"
28 #include "hks_param.h"
29 #include "hks_request.h"
30 #include "hks_template.h"
31 #include "hks_type.h"
32 #include "hks_type_inner.h"
33 #include "securec.h"
34
HksClientInitialize(void)35 int32_t HksClientInitialize(void)
36 {
37 return HKS_SUCCESS;
38 }
39
HksClientRefreshKeyInfo(void)40 int32_t HksClientRefreshKeyInfo(void)
41 {
42 return HKS_SUCCESS;
43 }
44
HksClientGenerateKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn,struct HksParamSet * paramSetOut)45 int32_t HksClientGenerateKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSetIn,
46 struct HksParamSet *paramSetOut)
47 {
48 int32_t ret = HksCheckIpcGenerateKey(keyAlias, paramSetIn);
49 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcGenerateKey fail")
50
51 struct HksBlob inBlob = { 0, NULL };
52 struct HksBlob outBlob = { 0, NULL };
53 inBlob.size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSetIn->paramSetSize) +
54 sizeof(outBlob.size);
55 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
56 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
57 if (paramSetOut != NULL) {
58 outBlob.size = paramSetOut->paramSetSize;
59 outBlob.data = (uint8_t *)paramSetOut;
60 }
61
62 do {
63 ret = HksGenerateKeyPack(&inBlob, keyAlias, paramSetIn, &outBlob);
64 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksGenerateKeyPack fail")
65
66 ret = HksSendRequest(HKS_MSG_GEN_KEY, &inBlob, &outBlob, paramSetIn);
67 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksSendRequest fail, ret = %" LOG_PUBLIC "d", ret)
68
69 if (paramSetOut != NULL) {
70 ret = HksFreshParamSet(paramSetOut, false);
71 HKS_IF_NOT_SUCC_LOGE(ret, "FreshParamSet fail, ret = %" LOG_PUBLIC "d", ret)
72 }
73 } while (0);
74
75 HKS_FREE_BLOB(inBlob);
76 return ret;
77 }
78
HksClientImportKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)79 int32_t HksClientImportKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
80 const struct HksBlob *key)
81 {
82 int32_t ret = HksCheckIpcImportKey(keyAlias, paramSet, key);
83 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcImportKey fail")
84
85 struct HksBlob inBlob = { 0, NULL };
86 inBlob.size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
87 sizeof(key->size) + ALIGN_SIZE(key->size);
88 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
89 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
90
91 do {
92 ret = HksImportKeyPack(&inBlob, keyAlias, paramSet, key);
93 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksImportKeyPack fail")
94
95 ret = HksSendRequest(HKS_MSG_IMPORT_KEY, &inBlob, NULL, paramSet);
96 } while (0);
97
98 HKS_FREE_BLOB(inBlob);
99 return ret;
100 }
101
HksClientExportPublicKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksBlob * key)102 int32_t HksClientExportPublicKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
103 struct HksBlob *key)
104 {
105 int32_t ret = HksCheckIpcExportPublicKey(keyAlias, key);
106 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcExportPublicKey fail")
107
108 struct HksBlob inBlob = { 0, NULL };
109 inBlob.size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(key->size);
110 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
111 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
112
113 do {
114 ret = HksExportPublicKeyPack(&inBlob, keyAlias, key);
115 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksExportPublicKeyPack fail")
116
117 ret = HksSendRequest(HKS_MSG_EXPORT_PUBLIC_KEY, &inBlob, key, paramSet);
118 } while (0);
119
120 HKS_FREE_BLOB(inBlob);
121 return ret;
122 }
123
HksClientImportWrappedKey(const struct HksBlob * keyAlias,const struct HksBlob * wrappingKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKeyData)124 int32_t HksClientImportWrappedKey(const struct HksBlob *keyAlias, const struct HksBlob *wrappingKeyAlias,
125 const struct HksParamSet *paramSet, const struct HksBlob *wrappedKeyData)
126 {
127 int32_t ret = HksCheckIpcImportWrappedKey(keyAlias, wrappingKeyAlias, paramSet, wrappedKeyData);
128 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksClientImportWrappedKey fail")
129
130 struct HksBlob inBlob = { 0, NULL };
131 inBlob.size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
132 sizeof(wrappingKeyAlias->size) + ALIGN_SIZE(wrappingKeyAlias->size) +
133 ALIGN_SIZE(paramSet->paramSetSize) +
134 sizeof(wrappedKeyData->size) + ALIGN_SIZE(wrappedKeyData->size);
135 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
136 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
137
138 do {
139 ret = HksImportWrappedKeyPack(&inBlob, keyAlias, wrappingKeyAlias, paramSet, wrappedKeyData);
140 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksImportWrappedKeyPack fail")
141
142 ret = HksSendRequest(HKS_MSG_IMPORT_WRAPPED_KEY, &inBlob, NULL, paramSet);
143 } while (0);
144
145 HKS_FREE_BLOB(inBlob);
146 return ret;
147 }
148
HksClientDeleteKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet)149 int32_t HksClientDeleteKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet)
150 {
151 HKS_IF_NOT_SUCC_RETURN(CheckBlob(keyAlias), HKS_ERROR_INVALID_ARGUMENT)
152 if (keyAlias->size > MAX_PROCESS_SIZE) {
153 HKS_LOG_E("CheckDeleteKeyParam fail");
154 return HKS_ERROR_INVALID_ARGUMENT;
155 }
156 return HksSendRequest(HKS_MSG_DELETE_KEY, keyAlias, NULL, paramSet);
157 }
158
HksClientGetKeyParamSet(const struct HksBlob * keyAlias,struct HksParamSet * paramSetOut)159 int32_t HksClientGetKeyParamSet(const struct HksBlob *keyAlias, struct HksParamSet *paramSetOut)
160 {
161 int32_t ret = HksCheckIpcGetKeyParamSet(keyAlias, paramSetOut);
162 HKS_IF_NOT_SUCC_RETURN(ret, ret)
163
164 struct HksBlob inBlob = { 0, NULL };
165 struct HksBlob outBlob = { paramSetOut->paramSetSize, (uint8_t *)paramSetOut };
166 inBlob.size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(paramSetOut->paramSetSize);
167 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
168 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
169
170 do {
171 ret = HksGetKeyParamSetPack(&inBlob, keyAlias, &outBlob);
172 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksGenerateKeyPack fail")
173
174 ret = HksSendRequest(HKS_MSG_GET_KEY_PARAMSET, &inBlob, &outBlob, NULL);
175 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksSendRequest fail, ret = %" LOG_PUBLIC "d", ret)
176
177 ret = HksFreshParamSet(paramSetOut, false);
178 HKS_IF_NOT_SUCC_LOGE(ret, "FreshParamSet fail, ret = %" LOG_PUBLIC "d", ret)
179 } while (0);
180
181 HKS_FREE_BLOB(inBlob);
182 return ret;
183 }
184
HksClientKeyExist(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet)185 int32_t HksClientKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet)
186 {
187 HKS_IF_NOT_SUCC_RETURN(CheckBlob(keyAlias), HKS_ERROR_INVALID_ARGUMENT)
188 if (keyAlias->size > MAX_PROCESS_SIZE) {
189 HKS_LOG_E("CheckKeyExistParam fail");
190 return HKS_ERROR_INVALID_ARGUMENT;
191 }
192 return HksSendRequest(HKS_MSG_KEY_EXIST, keyAlias, NULL, paramSet);
193 }
194
HksClientGenerateRandom(struct HksBlob * random,const struct HksParamSet * paramSet)195 int32_t HksClientGenerateRandom(struct HksBlob *random, const struct HksParamSet *paramSet)
196 {
197 HKS_IF_NOT_SUCC_RETURN(CheckBlob(random), HKS_ERROR_INVALID_ARGUMENT)
198 struct HksBlob inBlob = { sizeof(random->size), (uint8_t *)&(random->size) };
199 return HksSendRequest(HKS_MSG_GENERATE_RANDOM, &inBlob, random, paramSet);
200 }
201
HksClientSign(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * signature)202 int32_t HksClientSign(const struct HksBlob *key, const struct HksParamSet *paramSet,
203 const struct HksBlob *srcData, struct HksBlob *signature)
204 {
205 int32_t ret = HksCheckBlob3AndParamSet(key, srcData, signature, paramSet);
206 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check in and out data failed")
207
208 struct HksBlob tmpInData = *srcData;
209 struct HksBlob tmpOutData = *signature;
210 ret = HksSliceDataEntry(HKS_MSG_SIGN, key, paramSet, &tmpInData, &tmpOutData);
211 if (ret != HKS_SUCCESS) {
212 HKS_LOG_E("HksClientSign fail");
213 } else {
214 signature->size = tmpOutData.size;
215 }
216 return ret;
217 }
218
HksClientVerify(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,const struct HksBlob * signature)219 int32_t HksClientVerify(const struct HksBlob *key, const struct HksParamSet *paramSet,
220 const struct HksBlob *srcData, const struct HksBlob *signature)
221 {
222 int32_t ret = HksCheckBlob3AndParamSet(key, srcData, signature, paramSet);
223 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check in and out data failed")
224
225 struct HksBlob tmpInData = *srcData;
226 struct HksBlob tmpOutData = *signature;
227 ret = HksSliceDataEntry(HKS_MSG_VERIFY, key, paramSet, &tmpInData, &tmpOutData);
228 HKS_IF_NOT_SUCC_LOGE(ret, "HksClientVerify fail")
229 return ret;
230 }
231
AddAeTag(struct HksParamSet * paramSet,const struct HksBlob * inText,bool isEncrypt)232 static int32_t AddAeTag(struct HksParamSet *paramSet, const struct HksBlob *inText, bool isEncrypt)
233 {
234 int32_t ret;
235 if (!isEncrypt) {
236 if (inText->size <= HKS_AE_TAG_LEN) {
237 HKS_LOG_E("too small inText size");
238 return HKS_ERROR_INVALID_ARGUMENT;
239 }
240
241 struct HksParam aeParam;
242 aeParam.tag = HKS_TAG_AE_TAG;
243 aeParam.blob.data = inText->data + inText->size - HKS_AE_TAG_LEN;
244 aeParam.blob.size = HKS_AE_TAG_LEN;
245 ret = HksAddParams(paramSet, &aeParam, 1);
246 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "decrypt add ae params failed")
247 }
248
249 struct HksParam payloadParam;
250 payloadParam.tag = HKS_TAG_PAYLOAD_LEN;
251 payloadParam.uint32Param = inText->size;
252 ret = HksAddParams(paramSet, &payloadParam, 1);
253 HKS_IF_NOT_SUCC_LOGE(ret, "add payload param failed")
254 return ret;
255 }
256
AddAesTag(const struct HksParamSet * paramSet,struct HksParamSet * newParamSet,struct HksBlob * inText,bool isEncrypt)257 static int32_t AddAesTag(const struct HksParamSet *paramSet, struct HksParamSet *newParamSet,
258 struct HksBlob *inText, bool isEncrypt)
259 {
260 bool isAeMode = false;
261 bool isAes = false;
262 int32_t ret = HksCheckAesAeMode(paramSet, &isAes, &isAeMode);
263 HKS_IF_NOT_SUCC_RETURN(ret, ret)
264
265 /* Except for AES GCM and CCM mode, no need add tag, return success */
266 if ((!isAes) || (!isAeMode)) {
267 HKS_LOG_I("Not AES CCM or GCM mode!");
268 return HKS_SUCCESS;
269 }
270 return AddAeTag(newParamSet, inText, isEncrypt);
271 }
272
AppendToNewParamSet(const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)273 static int32_t AppendToNewParamSet(const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
274 {
275 struct HksParamSet *newParamSet = NULL;
276 int32_t ret = HksInitParamSet(&newParamSet);
277 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append init operation param set fail")
278
279 ret = HksAddParams(newParamSet, paramSet->params, paramSet->paramsCnt);
280 if (ret != HKS_SUCCESS) {
281 HKS_LOG_E("append add in params fail");
282 HksFreeParamSet(&newParamSet);
283 return ret;
284 }
285
286 *outParamSet = newParamSet;
287 return HKS_SUCCESS;
288 }
289
AppendCipherTag(const struct HksParamSet * paramSet,const struct HksBlob * inText,bool isEncrypt,struct HksParamSet ** outParamSet)290 static int32_t AppendCipherTag(const struct HksParamSet *paramSet, const struct HksBlob *inText, bool isEncrypt,
291 struct HksParamSet **outParamSet)
292 {
293 struct HksParamSet *newParamSet = NULL;
294 int32_t ret = AppendToNewParamSet(paramSet, &newParamSet);
295 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append cipher client service tag fail")
296
297 do {
298 ret = AddAesTag(paramSet, newParamSet, (struct HksBlob *)inText, isEncrypt);
299 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "append add Aes Tag fail")
300
301 ret = HksBuildParamSet(&newParamSet);
302 HKS_IF_NOT_SUCC_LOGE(ret, "append build paramset fail")
303 } while (0);
304 if (ret != HKS_SUCCESS) {
305 HksFreeParamSet(&newParamSet);
306 return ret;
307 }
308
309 *outParamSet = newParamSet;
310 return HKS_SUCCESS;
311 }
312
HksClientEncrypt(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * plainText,struct HksBlob * cipherText)313 int32_t HksClientEncrypt(const struct HksBlob *key, const struct HksParamSet *paramSet,
314 const struct HksBlob *plainText, struct HksBlob *cipherText)
315 {
316 int32_t ret = HksCheckBlob3AndParamSet(key, plainText, cipherText, paramSet);
317 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check in and out data failed")
318
319 struct HksParamSet *newParamSet = NULL;
320 ret = AppendCipherTag(paramSet, plainText, true, &newParamSet);
321 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "AppendCipherTag fail, ret = %" LOG_PUBLIC "d", ret)
322
323 struct HksBlob tmpInData = *plainText;
324 struct HksBlob tmpOutData = *cipherText;
325 ret = HksSliceDataEntry(HKS_MSG_ENCRYPT, key, newParamSet, &tmpInData, &tmpOutData);
326 if (ret != HKS_SUCCESS) {
327 HKS_LOG_E("HksClientEncrypt fail");
328 } else {
329 cipherText->size = tmpOutData.size;
330 }
331
332 HksFreeParamSet(&newParamSet);
333 return ret;
334 }
335
HksClientDecrypt(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * cipherText,struct HksBlob * plainText)336 int32_t HksClientDecrypt(const struct HksBlob *key, const struct HksParamSet *paramSet,
337 const struct HksBlob *cipherText, struct HksBlob *plainText)
338 {
339 int32_t ret = HksCheckBlob3AndParamSet(key, plainText, cipherText, paramSet);
340 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check in and out data failed")
341
342 struct HksParamSet *newParamSet = NULL;
343 struct HksBlob tmpCipherText = *cipherText;
344 ret = AppendCipherTag(paramSet, &tmpCipherText, false, &newParamSet);
345 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "AppendCipherTag fail, ret = %" LOG_PUBLIC "d", ret)
346
347 struct HksBlob tmpOutData = *plainText;
348 ret = HksSliceDataEntry(HKS_MSG_DECRYPT, key, newParamSet, &tmpCipherText, &tmpOutData);
349 if (ret != HKS_SUCCESS) {
350 HKS_LOG_E("HksClientDecrypt fail");
351 } else {
352 plainText->size = tmpOutData.size;
353 }
354
355 HksFreeParamSet(&newParamSet);
356 return ret;
357 }
358
HksClientAgreeKey(const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,struct HksBlob * agreedKey)359 int32_t HksClientAgreeKey(const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
360 const struct HksBlob *peerPublicKey, struct HksBlob *agreedKey)
361 {
362 int32_t ret = HksCheckIpcAgreeKey(paramSet, privateKey, peerPublicKey, agreedKey);
363 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcAgreeKey fail")
364
365 struct HksBlob inBlob = { 0, NULL };
366 inBlob.size = ALIGN_SIZE(paramSet->paramSetSize) + sizeof(privateKey->size) + ALIGN_SIZE(privateKey->size) +
367 sizeof(peerPublicKey->size) + ALIGN_SIZE(peerPublicKey->size) + sizeof(agreedKey->size);
368 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
369 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
370
371 do {
372 ret = HksAgreeKeyPack(&inBlob, paramSet, privateKey, peerPublicKey, agreedKey);
373 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksAgreeKeyPack fail")
374
375 ret = HksSendRequest(HKS_MSG_AGREE_KEY, &inBlob, agreedKey, paramSet);
376 } while (0);
377
378 HKS_FREE_BLOB(inBlob);
379 return ret;
380 }
381
HksClientDeriveKey(const struct HksParamSet * paramSet,const struct HksBlob * mainKey,struct HksBlob * derivedKey)382 int32_t HksClientDeriveKey(const struct HksParamSet *paramSet, const struct HksBlob *mainKey,
383 struct HksBlob *derivedKey)
384 {
385 int32_t ret = HksCheckIpcDeriveKey(paramSet, mainKey, derivedKey);
386 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcDeriveKey fail")
387
388 struct HksBlob inBlob = { 0, NULL };
389 inBlob.size = ALIGN_SIZE(paramSet->paramSetSize) + sizeof(mainKey->size) + ALIGN_SIZE(mainKey->size) +
390 sizeof(derivedKey->size);
391 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
392 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
393
394 do {
395 ret = HksDeriveKeyPack(&inBlob, paramSet, mainKey, derivedKey);
396 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksDeriveKeyPack fail")
397
398 ret = HksSendRequest(HKS_MSG_DERIVE_KEY, &inBlob, derivedKey, paramSet);
399 } while (0);
400
401 HKS_FREE_BLOB(inBlob);
402 return ret;
403 }
404
HksClientMac(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * mac)405 int32_t HksClientMac(const struct HksBlob *key, const struct HksParamSet *paramSet, const struct HksBlob *srcData,
406 struct HksBlob *mac)
407 {
408 int32_t ret = HksCheckBlob3AndParamSet(key, srcData, mac, paramSet);
409 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check in and out data failed")
410
411 struct HksBlob tmpInData = *srcData;
412 struct HksBlob tmpOutData = *mac;
413 ret = HksSliceDataEntry(HKS_MSG_MAC, key, paramSet, &tmpInData, &tmpOutData);
414 if (ret != HKS_SUCCESS) {
415 HKS_LOG_E("HksClientMac fail");
416 } else {
417 mac->size = tmpOutData.size;
418 }
419 return ret;
420 }
421
HksClientGetKeyInfoList(struct HksKeyInfo * keyInfoList,uint32_t * listCount)422 int32_t HksClientGetKeyInfoList(struct HksKeyInfo *keyInfoList, uint32_t *listCount)
423 {
424 int32_t ret = HksCheckIpcGetKeyInfoList(keyInfoList, *listCount);
425 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcGetKeyInfoList fail")
426
427 struct HksBlob inBlob = { 0, NULL };
428 inBlob.size = sizeof(*listCount) + (sizeof(keyInfoList->alias.size) +
429 sizeof(keyInfoList->paramSet->paramSetSize)) * (*listCount);
430 inBlob.data = (uint8_t *)HksMalloc(inBlob.size);
431 HKS_IF_NULL_RETURN(inBlob.data, HKS_ERROR_MALLOC_FAIL)
432
433 struct HksBlob outBlob = { 0, NULL };
434 outBlob.size += sizeof(*listCount);
435 for (uint32_t i = 0; i < *listCount; ++i) {
436 outBlob.size += sizeof(keyInfoList[i].alias.size) + ALIGN_SIZE(keyInfoList[i].alias.size) +
437 ALIGN_SIZE(keyInfoList[i].paramSet->paramSetSize);
438 }
439
440 outBlob.data = (uint8_t *)HksMalloc(outBlob.size);
441 if (outBlob.data == NULL) {
442 HKS_FREE_BLOB(inBlob);
443 return HKS_ERROR_MALLOC_FAIL;
444 }
445
446 do {
447 ret = HksGetKeyInfoListPack(&inBlob, *listCount, keyInfoList);
448 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksGetKeyInfoListPack fail")
449
450 ret = HksSendRequest(HKS_MSG_GET_KEY_INFO_LIST, &inBlob, &outBlob, NULL);
451 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksSendRequest result is fail")
452
453 ret = HksGetKeyInfoListUnpackFromService(&outBlob, listCount, keyInfoList);
454 } while (0);
455
456 HKS_FREE_BLOB(inBlob);
457 HKS_FREE_BLOB(outBlob);
458 return ret;
459 }
460
CertificateChainInitBlob(struct HksBlob * inBlob,struct HksBlob * outBlob,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksCertChain * certChain)461 static int32_t CertificateChainInitBlob(struct HksBlob *inBlob, struct HksBlob *outBlob, const struct HksBlob *keyAlias,
462 const struct HksParamSet *paramSet, const struct HksCertChain *certChain)
463 {
464 int32_t ret = HksCheckIpcCertificateChain(keyAlias, paramSet, certChain);
465 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckIpcCertificateChain fail")
466
467 uint32_t certBufSize = sizeof(certChain->certsCount);
468 for (uint32_t i = 0; i < certChain->certsCount; ++i) {
469 certBufSize += sizeof(certChain->certs[i].size) + ALIGN_SIZE(certChain->certs[i].size);
470 }
471
472 inBlob->size = sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
473 sizeof(certBufSize);
474 inBlob->data = (uint8_t *)HksMalloc(inBlob->size);
475 HKS_IF_NULL_RETURN(inBlob->data, HKS_ERROR_MALLOC_FAIL)
476
477 outBlob->size = certBufSize;
478 outBlob->data = (uint8_t *)HksMalloc(certBufSize);
479 if (outBlob->data == NULL) {
480 HKS_FREE_BLOB(*inBlob);
481 return HKS_ERROR_MALLOC_FAIL;
482 }
483
484 return HKS_SUCCESS;
485 }
486
CertificateChainGetOrAttest(enum HksMessage type,const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksCertChain * certChain)487 static int32_t CertificateChainGetOrAttest(enum HksMessage type, const struct HksBlob *keyAlias,
488 const struct HksParamSet *paramSet, struct HksCertChain *certChain)
489 {
490 struct HksBlob inBlob = { 0, NULL };
491 struct HksBlob outBlob = { 0, NULL };
492
493 int32_t ret = CertificateChainInitBlob(&inBlob, &outBlob, keyAlias, paramSet, certChain);
494 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CertificateChainInitBlob fail")
495
496 do {
497 struct HksParam *isBase64Param = NULL;
498 bool isBase64 = false;
499 ret = HksGetParam(paramSet, HKS_TAG_ATTESTATION_BASE64, &isBase64Param);
500 if (ret == HKS_SUCCESS) {
501 isBase64 = isBase64Param->boolParam;
502 }
503 ret = HksCertificateChainPack(&inBlob, keyAlias, paramSet, &outBlob);
504 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksCertificateChainPack fail")
505
506 ret = HksSendRequest(type, &inBlob, &outBlob, paramSet);
507 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "CertificateChainGetOrAttest request fail")
508 ret = HksCertificateChainUnpackFromService(&outBlob, isBase64, certChain);
509 } while (0);
510
511 HKS_FREE_BLOB(inBlob);
512 HKS_FREE_BLOB(outBlob);
513 return ret;
514 }
515
HksClientAttestKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksCertChain * certChain)516 int32_t HksClientAttestKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
517 struct HksCertChain *certChain)
518 {
519 return CertificateChainGetOrAttest(HKS_MSG_ATTEST_KEY, keyAlias, paramSet, certChain);
520 }
521
CopyData(const uint8_t * data,const uint32_t size,struct HksBlob * out)522 static int32_t CopyData(const uint8_t *data, const uint32_t size, struct HksBlob *out)
523 {
524 if (size == 0) {
525 out->size = 0;
526 return HKS_SUCCESS;
527 }
528
529 if (out->size < size) {
530 HKS_LOG_E("out size[%" LOG_PUBLIC "u] smaller than [%" LOG_PUBLIC "u]", out->size, size);
531 return HKS_ERROR_BUFFER_TOO_SMALL;
532 }
533 (void)memcpy_s(out->data, out->size, data, size);
534 out->size = size;
535 return HKS_SUCCESS;
536 }
537
ClientInit(const struct HksBlob * inData,const struct HksParamSet * paramSet,struct HksBlob * handle,struct HksBlob * token)538 static int32_t ClientInit(const struct HksBlob *inData, const struct HksParamSet *paramSet,
539 struct HksBlob *handle, struct HksBlob *token)
540 {
541 uint8_t *tmpOut = (uint8_t *)HksMalloc(HANDLE_SIZE + TOKEN_SIZE);
542 HKS_IF_NULL_LOGE_RETURN(tmpOut, HKS_ERROR_MALLOC_FAIL, "malloc ipc tmp out failed")
543 struct HksBlob outBlob = { HANDLE_SIZE + TOKEN_SIZE, tmpOut };
544
545 int32_t ret;
546 do {
547 ret = HksSendRequest(HKS_MSG_INIT, inData, &outBlob, paramSet);
548 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "client init send fail")
549
550 if (outBlob.size < HANDLE_SIZE) {
551 HKS_LOG_E("invalid out size[%" LOG_PUBLIC "u]", outBlob.size);
552 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
553 break;
554 }
555 ret = CopyData(outBlob.data, HANDLE_SIZE, handle);
556 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy handle failed")
557
558 if (token != NULL) {
559 if (outBlob.size < (HANDLE_SIZE + TOKEN_SIZE)) {
560 HKS_LOG_W("client init success without out token");
561 token->size = 0;
562 break;
563 }
564 if (token->size < TOKEN_SIZE) {
565 HKS_LOG_E("copy token failed");
566 ret = HKS_ERROR_BUFFER_TOO_SMALL;
567 break;
568 }
569
570 ret = CopyData(outBlob.data + HANDLE_SIZE, TOKEN_SIZE, token);
571 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy token failed")
572 }
573 } while (0);
574
575 HKS_FREE_PTR(tmpOut);
576 return ret;
577 }
578
HksClientInit(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksBlob * handle,struct HksBlob * token)579 int32_t HksClientInit(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
580 struct HksBlob *handle, struct HksBlob *token)
581 {
582 struct HksParamSet *sendParamSet = NULL;
583
584 struct HksParam params[] = {
585 { .tag = HKS_TAG_PARAM0_BUFFER,
586 .blob = *keyAlias },
587 { .tag = HKS_TAG_PARAM1_BUFFER,
588 .blob = { paramSet->paramSetSize,
589 (uint8_t *)paramSet } },
590 };
591
592 int32_t ret = HksParamsToParamSet(params, HKS_ARRAY_SIZE(params), &sendParamSet);
593 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksParamsToParamSet fail")
594
595 struct HksBlob parcelBlob = {
596 .size = sendParamSet->paramSetSize,
597 .data = (uint8_t *)sendParamSet
598 };
599
600 ret = ClientInit(&parcelBlob, paramSet, handle, token);
601 HksFreeParamSet(&sendParamSet);
602 return ret;
603 }
604
HksClientUpdate(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)605 int32_t HksClientUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet,
606 const struct HksBlob *inData, struct HksBlob *outData)
607 {
608 struct HksParamSet *sendParamSet = NULL;
609
610 struct HksParam params[] = {
611 { .tag = HKS_TAG_PARAM0_BUFFER,
612 .blob = { paramSet->paramSetSize,
613 (uint8_t *)paramSet } },
614 { .tag = HKS_TAG_PARAM1_BUFFER,
615 .blob = *handle },
616 { .tag = HKS_TAG_PARAM2_BUFFER,
617 .blob = *inData },
618 };
619
620 int32_t ret = HksParamsToParamSet(params, HKS_ARRAY_SIZE(params), &sendParamSet);
621 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksParamSetPack fail")
622
623 struct HksBlob parcelBlob = {
624 .size = sendParamSet->paramSetSize,
625 .data = (uint8_t *)sendParamSet
626 };
627 ret = HksSendRequest(HKS_MSG_UPDATE, &parcelBlob, outData, paramSet);
628 if (ret != HKS_SUCCESS) {
629 HKS_LOG_E("HksParamSet send fail");
630 HksFreeParamSet(&sendParamSet);
631 return ret;
632 }
633
634 HksFreeParamSet(&sendParamSet);
635 return ret;
636 }
637
HksClientFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)638 int32_t HksClientFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
639 const struct HksBlob *inData, struct HksBlob *outData)
640 {
641 struct HksParamSet *sendParamSet = NULL;
642 struct HksParam params[] = {
643 { .tag = HKS_TAG_PARAM0_BUFFER,
644 .blob = { paramSet->paramSetSize,
645 (uint8_t *)paramSet } },
646 { .tag = HKS_TAG_PARAM1_BUFFER,
647 .blob = *handle },
648 { .tag = HKS_TAG_PARAM2_BUFFER,
649 .blob = *inData },
650 { .tag = HKS_TAG_PARAM3_BUFFER,
651 .blob = *outData },
652 };
653
654 int32_t ret = HksParamsToParamSet(params, HKS_ARRAY_SIZE(params), &sendParamSet);
655 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksParamSetPack fail")
656
657 struct HksBlob parcelBlob = {
658 .size = sendParamSet->paramSetSize,
659 .data = (uint8_t *)sendParamSet
660 };
661 ret = HksSendRequest(HKS_MSG_FINISH, &parcelBlob, outData, paramSet);
662 if (ret != HKS_SUCCESS) {
663 HKS_LOG_E("HksParamSet send fail");
664 HksFreeParamSet(&sendParamSet);
665 return ret;
666 }
667
668 HksFreeParamSet(&sendParamSet);
669 return ret;
670 }
671
HksClientAbort(const struct HksBlob * handle,const struct HksParamSet * paramSet)672 int32_t HksClientAbort(const struct HksBlob *handle, const struct HksParamSet *paramSet)
673 {
674 struct HksParamSet *sendParamSet = NULL;
675 struct HksParam params[] = {
676 { .tag = HKS_TAG_PARAM0_BUFFER,
677 .blob = { paramSet->paramSetSize,
678 (uint8_t *)paramSet } },
679 { .tag = HKS_TAG_PARAM1_BUFFER,
680 .blob = *handle },
681 };
682
683 int32_t ret = HksParamsToParamSet(params, HKS_ARRAY_SIZE(params), &sendParamSet);
684 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksParamSetPack fail")
685
686 struct HksBlob parcelBlob = {
687 .size = sendParamSet->paramSetSize,
688 .data = (uint8_t *)sendParamSet
689 };
690 ret = HksSendRequest(HKS_MSG_ABORT, &parcelBlob, NULL, paramSet);
691 if (ret != HKS_SUCCESS) {
692 HKS_LOG_E("HksParamSet send fail");
693 HksFreeParamSet(&sendParamSet);
694 return ret;
695 }
696
697 HksFreeParamSet(&sendParamSet);
698 return ret;
699 }
700