• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hks_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